2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.upb.internal.message;
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.openhab.core.util.HexUtils;
19 * Builder class for building UPB messages.
21 * @author cvanorman - Initial contribution
25 public final class MessageBuilder {
28 private byte source = -1;
29 private byte destination;
31 private byte[] args = new byte[0];
33 private boolean ackMessage;
35 private MessageBuilder(final Command cmd) {
36 this.command = cmd.toByte();
40 * @return a new MessageBuilder for the specified command
42 public static MessageBuilder forCommand(final Command cmd) {
43 return new MessageBuilder(cmd);
47 * Sets where this message is for a device or a link.
50 * set to true if this message is for a link.
51 * @return this builder
53 public MessageBuilder link(boolean link) {
59 * Sets the UPB network of the message.
62 * the network of the message.
63 * @return this builder
65 public MessageBuilder network(byte network) {
66 this.network = network;
71 * Sets the source id of the message (defaults to 0xFF).
74 * the source if of the message.
75 * @return this builder
77 public MessageBuilder source(byte source) {
83 * Sets the destination id of the message.
87 * @return this builder
89 public MessageBuilder destination(byte destination) {
90 this.destination = destination;
95 * Sets any command arguments.
97 * @param args the arguments (bytes following the command byte)
98 * @return this builder
100 public MessageBuilder args(byte... args) {
106 * Sets whether an Acknowledgement Response message should be requested
107 * (by setting the the MSG-bit in the control word).
109 * @param ackMessage {@code true} if the MSG-bit should be set
110 * @return this builder
112 public MessageBuilder ackMessage(final boolean ackMessage) {
113 this.ackMessage = ackMessage;
118 * Builds the message as a HEX string.
120 * @return a HEX string of the message.
122 public String build() {
123 ControlWord controlWord = new ControlWord();
125 int packetLength = args.length + 7;
127 controlWord.setPacketLength(packetLength);
128 controlWord.setAckPulse(true);
129 controlWord.setAckMessage(ackMessage);
130 controlWord.setLink(link);
132 byte[] bytes = new byte[packetLength];
133 bytes[0] = controlWord.getHi();
134 bytes[1] = controlWord.getLo();
136 bytes[3] = destination;
139 System.arraycopy(args, 0, bytes, 6, args.length);
141 // Calculate the checksum
142 // The checksum is the 2's complement of the sum.
144 for (byte b : bytes) {
148 bytes[bytes.length - 1] = (byte) (-sum >>> 0);
150 return HexUtils.bytesToHex(bytes);