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.max.internal.message;
15 import java.time.ZoneId;
16 import java.time.ZonedDateTime;
17 import java.util.Date;
18 import java.util.HashMap;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.openhab.binding.max.internal.Utils;
23 import org.slf4j.Logger;
26 * The H message contains information about the MAX! Cube.
28 * @author Andreas Heil - Initial contribution
29 * @author Marcel Verpaalen - Details parsing, OH2 version
32 public final class HMessage extends Message {
34 private ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.systemDefault());
35 public Map<String, Object> properties = new HashMap<>();
37 private String rawSerialNumber;
38 private String rawRFAddress;
39 private String rawFirmwareVersion;
40 private String rawConnectionId;
41 private String rawDutyCycle;
42 private String rawFreeMemorySlots;
43 private String rawCubeTimeState;
44 private String rawNTPCounter;
47 private String rawUnknownfield4;
49 public HMessage(String raw) {
52 String[] tokens = this.getPayload().split(Message.DELIMETER);
54 if (tokens.length < 11) {
55 throw new ArrayIndexOutOfBoundsException("MAX!Cube raw H Message corrupt");
58 rawSerialNumber = tokens[0];
59 rawRFAddress = tokens[1];
60 rawFirmwareVersion = tokens[2].substring(0, 2) + "." + tokens[2].substring(2, 4);
61 rawUnknownfield4 = tokens[3];
62 rawConnectionId = tokens[4];
63 rawDutyCycle = Integer.toString(Utils.fromHex(tokens[5]));
64 rawFreeMemorySlots = Integer.toString(Utils.fromHex(tokens[6]));
66 setDateTime(tokens[7], tokens[8]);
68 rawCubeTimeState = tokens[9];
69 rawNTPCounter = Integer.toString(Utils.fromHex(tokens[10]));
70 properties.put("Serial number", rawSerialNumber);
71 properties.put("RF address (HEX)", rawRFAddress);
72 properties.put("Firmware version", rawFirmwareVersion);
73 properties.put("Connection ID", rawConnectionId);
74 properties.put("Unknown", rawUnknownfield4);
75 properties.put("Duty Cycle", rawDutyCycle);
76 properties.put("FreeMemorySlots", rawFreeMemorySlots);
77 properties.put("CubeTimeState", rawCubeTimeState);
78 properties.put("NTPCounter", rawNTPCounter);
81 public String getSerialNumber() {
82 return rawSerialNumber;
85 public String getRFAddress() {
89 public String getFirmwareVersion() {
90 return rawFirmwareVersion;
93 public String getConnectionId() {
94 return rawConnectionId;
97 public int getDutyCycle() {
98 return Integer.parseInt(rawDutyCycle);
101 public int getFreeMemorySlots() {
102 return Integer.parseInt(rawFreeMemorySlots);
105 public String getCubeTimeState() {
106 return rawCubeTimeState;
109 public String getNTPCounter() {
110 return rawNTPCounter;
113 private final void setDateTime(String hexDate, String hexTime) {
114 // we have to add 2000, otherwise we get a wrong timestamp
115 int year = 2000 + Utils.fromHex(hexDate.substring(0, 2));
116 int month = Utils.fromHex(hexDate.substring(2, 4));
117 int dayOfMonth = Utils.fromHex(hexDate.substring(4, 6));
119 int hours = Utils.fromHex(hexTime.substring(0, 2));
120 int minutes = Utils.fromHex(hexTime.substring(2, 4));
122 zonedDateTime = ZonedDateTime.of(year, month, dayOfMonth, hours, minutes, 0, 0, ZoneId.systemDefault());
125 public Date getDateTime() {
126 return Date.from(zonedDateTime.toInstant());
130 public void debug(Logger logger) {
131 logger.debug("=== H Message === ");
132 logger.trace("\tRAW: : {}", getPayload());
133 logger.trace("\tReading Time : {}", getDateTime());
134 for (String key : properties.keySet()) {
135 logger.debug("\t{}: {}", key, properties.get(key));
140 public MessageType getType() {
141 return MessageType.H;