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.velbus.internal;
15 import static org.openhab.binding.velbus.internal.VelbusBindingConstants.*;
17 import java.util.Arrays;
18 import java.util.HashMap;
20 import java.util.TreeMap;
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.openhab.binding.velbus.internal.handler.VelbusBridgeHandler;
25 import org.openhab.binding.velbus.internal.packets.VelbusChannelNameRequestPacket;
26 import org.openhab.core.thing.ThingTypeUID;
27 import org.openhab.core.thing.ThingUID;
30 * The {@link VelbusModule} represents a generic module and its basic properties
31 * in the Velbus system.
33 * @author Cedric Boon - Initial contribution
36 public class VelbusModule {
37 private final HashMap<Integer, String[]> channelNames = new HashMap<>();
39 private VelbusModuleAddress velbusModuleAddress;
40 private byte highByteOfSerialNumber;
41 private byte lowByteOfSerialNumber;
42 private byte memoryMapVersion;
43 private byte buildYear;
44 private byte buildWeek;
45 private int numberOfChannels;
47 private ThingTypeUID thingTypeUID;
49 public VelbusModule(VelbusModuleAddress velbusModuleAddress, byte moduleType, byte highByteOfSerialNumber,
50 byte lowByteOfSerialNumber, byte memoryMapVersion, byte buildYear, byte buildWeek,
51 ThingTypeUID thingTypeUID, int numberOfChannels) {
52 this.velbusModuleAddress = velbusModuleAddress;
53 this.highByteOfSerialNumber = highByteOfSerialNumber;
54 this.lowByteOfSerialNumber = lowByteOfSerialNumber;
55 this.memoryMapVersion = memoryMapVersion;
56 this.buildYear = buildYear;
57 this.buildWeek = buildWeek;
58 this.thingTypeUID = thingTypeUID;
59 this.numberOfChannels = numberOfChannels;
62 public VelbusModuleAddress getModuleAddress() {
63 return velbusModuleAddress;
66 public String getAddress() {
67 return String.format("%02X", velbusModuleAddress.getAddress());
70 public String getModuleSerialNumber() {
71 return String.format("%02X", highByteOfSerialNumber) + String.format("%02X", lowByteOfSerialNumber);
74 public String getMemoryMapVersion() {
75 return String.format("%02X", memoryMapVersion);
78 public String getModuleBuild() {
79 return String.format("%02X", buildYear) + String.format("%02X", buildWeek);
82 public ThingTypeUID getThingTypeUID() {
83 return this.thingTypeUID;
86 public ThingUID getThingUID(ThingUID bridgeUID) {
87 return new ThingUID(getThingTypeUID(), bridgeUID, getAddress());
90 public String getLabel() {
91 return getThingTypeUID() + " (Address " + getAddress() + ")";
94 protected String getChannelName(int channelIndex) {
95 String channelName = "";
97 Integer key = channelIndex;
98 if (channelNames.containsKey(key)) {
99 for (int i = 0; i < 3; i++) {
100 String channelNamePart = channelNames.get(key)[i];
101 if (channelNamePart != null) {
102 channelName = channelName + channelNamePart;
110 public void sendChannelNameRequests(@Nullable VelbusBridgeHandler bridgeHandler) {
111 if (bridgeHandler != null) {
112 VelbusChannelNameRequestPacket channelNameRequest = new VelbusChannelNameRequestPacket(
113 velbusModuleAddress.getAddress());
114 bridgeHandler.sendPacket(channelNameRequest.getBytes());
118 public void setChannelName(VelbusChannelIdentifier channelIdentifier, int namePartNumber, byte[] namePart) {
119 StringBuilder contents = new StringBuilder();
120 for (int i = 0; i < namePart.length; i++) {
121 byte currentChar = namePart[i];
122 if (currentChar != (byte) 0xFF) {
123 contents.append((char) currentChar);
127 Integer key = numberOfChannels <= 8 ? velbusModuleAddress.getChannelIndex(channelIdentifier)
128 : channelIdentifier.getChannelByte() - 1;
129 if (!channelNames.containsKey(key)) {
130 channelNames.put(key, new String[3]);
133 channelNames.get(key)[namePartNumber - 1] = contents.toString();
136 public Map<String, Object> getProperties() {
137 Map<String, Object> properties = new TreeMap<>();
139 properties.put(ADDRESS, getAddress());
140 properties.put(MODULE_SERIAL_NUMBER, getModuleSerialNumber());
141 properties.put(MODULE_MEMORY_MAP_VERSION, getMemoryMapVersion());
142 properties.put(MODULE_BUILD, getModuleBuild());
144 Integer[] keys = channelNames.keySet().toArray(new Integer[0]);
147 for (Integer key : keys) {
148 String channelName = getChannelName(key);
149 if (channelName.length() > 0) {
150 properties.put(CHANNEL + (key + 1), channelName);
154 byte[] subAddresses = velbusModuleAddress.getSubAddresses();
155 for (int i = 1; i <= subAddresses.length; i++) {
156 properties.put(SUB_ADDRESS + i, String.format("%02X", subAddresses[i - 1]));