]> git.basschouten.com Git - openhab-addons.git/blob
45e001911d25292edbc3ccc6350bb767534e35bd
[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.max.internal.message;
14
15 import java.nio.charset.StandardCharsets;
16 import java.util.ArrayList;
17 import java.util.Base64;
18 import java.util.List;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.openhab.binding.max.internal.Utils;
22 import org.openhab.binding.max.internal.device.DeviceInformation;
23 import org.openhab.binding.max.internal.device.DeviceType;
24 import org.openhab.binding.max.internal.device.RoomInformation;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 /**
29  * The M message contains metadata about the MAX! Cube setup.
30  *
31  * @author Andreas Heil - Initial contribution
32  * @author Marcel Verpaalen - Room details parse
33  */
34 @NonNullByDefault
35 public final class MMessage extends Message {
36     private final Logger logger = LoggerFactory.getLogger(MMessage.class);
37
38     public List<RoomInformation> rooms = new ArrayList<>();
39     public List<DeviceInformation> devices = new ArrayList<>();
40     private Boolean hasConfiguration;
41
42     public MMessage(String raw) {
43         super(raw);
44         hasConfiguration = false;
45
46         String[] tokens = this.getPayload().split(Message.DELIMETER);
47
48         if (tokens.length <= 1) {
49             logger.debug("No rooms defined. Configure your Max! Cube");
50             hasConfiguration = false;
51             return;
52         }
53         try {
54             byte[] bytes = Base64.getDecoder().decode(tokens[2].trim().getBytes(StandardCharsets.UTF_8));
55
56             hasConfiguration = true;
57             logger.trace("*** M Message trace**** ");
58             logger.trace("\tMagic? (expect 86) : {}", (int) bytes[0]);
59             logger.trace("\tVersion? (expect 2): {}", (int) bytes[1]);
60             logger.trace("\t#defined rooms in M: {}", (int) bytes[2]);
61
62             rooms = new ArrayList<>();
63             devices = new ArrayList<>();
64
65             int roomCount = bytes[2];
66
67             int byteOffset = 3; // start of rooms
68
69             /* process room */
70
71             for (int i = 0; i < roomCount; i++) {
72
73                 int position = bytes[byteOffset++];
74
75                 int nameLength = bytes[byteOffset++] & 0xff;
76                 byte[] data = new byte[nameLength];
77                 System.arraycopy(bytes, byteOffset, data, 0, nameLength);
78                 byteOffset += nameLength;
79                 String name = new String(data, StandardCharsets.UTF_8);
80
81                 String rfAddress = Utils.toHex((bytes[byteOffset] & 0xff), (bytes[byteOffset + 1] & 0xff),
82                         (bytes[byteOffset + 2] & 0xff));
83                 byteOffset += 3;
84
85                 rooms.add(new RoomInformation(position, name, rfAddress));
86             }
87
88             /* process devices */
89
90             int deviceCount = bytes[byteOffset++];
91
92             for (int deviceId = 0; deviceId < deviceCount; deviceId++) {
93                 DeviceType deviceType = DeviceType.create(bytes[byteOffset++]);
94
95                 String rfAddress = Utils.toHex((bytes[byteOffset] & 0xff), (bytes[byteOffset + 1] & 0xff),
96                         (bytes[byteOffset + 2] & 0xff));
97                 byteOffset += 3;
98
99                 final StringBuilder serialNumberBuilder = new StringBuilder(10);
100
101                 for (int i = 0; i < 10; i++) {
102                     serialNumberBuilder.append((char) bytes[byteOffset++]);
103                 }
104
105                 int nameLength = bytes[byteOffset++] & 0xff;
106                 byte[] data = new byte[nameLength];
107                 System.arraycopy(bytes, byteOffset, data, 0, nameLength);
108                 byteOffset += nameLength;
109                 String deviceName = new String(data, StandardCharsets.UTF_8);
110
111                 int roomId = bytes[byteOffset++] & 0xff;
112                 devices.add(new DeviceInformation(deviceType, serialNumberBuilder.toString(), rfAddress, deviceName,
113                         roomId));
114             }
115         } catch (Exception e) {
116             logger.debug("Unknown error parsing the M Message: {}", e.getMessage(), e);
117             logger.debug("\tRAW : {}", this.getPayload());
118         }
119     }
120
121     @Override
122     public void debug(Logger logger) {
123         logger.debug("=== M Message === ");
124         if (hasConfiguration) {
125             logger.trace("\tRAW : {}", this.getPayload());
126             for (RoomInformation room : rooms) {
127                 logger.debug("\t=== Rooms ===");
128                 logger.debug("\tRoom Pos   : {}", room.getPosition());
129                 logger.debug("\tRoom Name  : {}", room.getName());
130                 logger.debug("\tRoom RF Adr: {}", room.getRFAddress());
131                 for (DeviceInformation device : devices) {
132                     if (room.getPosition() == device.getRoomId()) {
133                         logger.debug("\t=== Devices ===");
134                         logger.debug("\tDevice Type    : {}", device.getDeviceType());
135                         logger.debug("\tDevice Name    : {}", device.getName());
136                         logger.debug("\tDevice Serialnr: {}", device.getSerialNumber());
137                         logger.debug("\tDevice RF Adr  : {}", device.getRFAddress());
138                         logger.debug("\tRoom Id        : {}", device.getRoomId());
139                     }
140                 }
141             }
142         } else {
143             logger.debug("M Message empty. No Configuration");
144         }
145     }
146
147     @Override
148     public MessageType getType() {
149         return MessageType.M;
150     }
151 }