]> git.basschouten.com Git - openhab-addons.git/blob
bbef06b0be2e8656c7cc2877ac7779dadb163619
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.upb.internal.message;
14
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.openhab.core.util.HexUtils;
17
18 /**
19  * Builder class for building UPB messages.
20  *
21  * @author cvanorman - Initial contribution
22  * @since 1.9.0
23  */
24 @NonNullByDefault
25 public final class MessageBuilder {
26
27     private byte network;
28     private byte source = -1;
29     private byte destination;
30     private byte command;
31     private byte[] args = new byte[0];
32     private boolean link;
33     private boolean ackMessage;
34
35     private MessageBuilder(final Command cmd) {
36         this.command = cmd.toByte();
37     }
38
39     /**
40      * @return a new MessageBuilder for the specified command
41      */
42     public static MessageBuilder forCommand(final Command cmd) {
43         return new MessageBuilder(cmd);
44     }
45
46     /**
47      * Sets where this message is for a device or a link.
48      *
49      * @param link
50      *            set to true if this message is for a link.
51      * @return this builder
52      */
53     public MessageBuilder link(boolean link) {
54         this.link = link;
55         return this;
56     }
57
58     /**
59      * Sets the UPB network of the message.
60      *
61      * @param network
62      *            the network of the message.
63      * @return this builder
64      */
65     public MessageBuilder network(byte network) {
66         this.network = network;
67         return this;
68     }
69
70     /**
71      * Sets the source id of the message (defaults to 0xFF).
72      *
73      * @param source
74      *            the source if of the message.
75      * @return this builder
76      */
77     public MessageBuilder source(byte source) {
78         this.source = source;
79         return this;
80     }
81
82     /**
83      * Sets the destination id of the message.
84      *
85      * @param destination
86      *            the destination id.
87      * @return this builder
88      */
89     public MessageBuilder destination(byte destination) {
90         this.destination = destination;
91         return this;
92     }
93
94     /**
95      * Sets any command arguments.
96      *
97      * @param args the arguments (bytes following the command byte)
98      * @return this builder
99      */
100     public MessageBuilder args(byte... args) {
101         this.args = args;
102         return this;
103     }
104
105     /**
106      * Sets whether an Acknowledgement Response message should be requested
107      * (by setting the the MSG-bit in the control word).
108      *
109      * @param ackMessage {@code true} if the MSG-bit should be set
110      * @return this builder
111      */
112     public MessageBuilder ackMessage(final boolean ackMessage) {
113         this.ackMessage = ackMessage;
114         return this;
115     }
116
117     /**
118      * Builds the message as a HEX string.
119      *
120      * @return a HEX string of the message.
121      */
122     public String build() {
123         ControlWord controlWord = new ControlWord();
124
125         int packetLength = args.length + 7;
126
127         controlWord.setPacketLength(packetLength);
128         controlWord.setAckPulse(true);
129         controlWord.setAckMessage(ackMessage);
130         controlWord.setLink(link);
131
132         byte[] bytes = new byte[packetLength];
133         bytes[0] = controlWord.getHi();
134         bytes[1] = controlWord.getLo();
135         bytes[2] = network;
136         bytes[3] = destination;
137         bytes[4] = source;
138         bytes[5] = command;
139         System.arraycopy(args, 0, bytes, 6, args.length);
140
141         // Calculate the checksum
142         // The checksum is the 2's complement of the sum.
143         int sum = 0;
144         for (byte b : bytes) {
145             sum += b;
146         }
147
148         bytes[bytes.length - 1] = (byte) (-sum >>> 0);
149
150         return HexUtils.bytesToHex(bytes);
151     }
152 }