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.rfxcom.internal.messages;
15 import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
16 import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
18 import org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration;
19 import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
20 import org.openhab.binding.rfxcom.internal.exceptions.RFXComInvalidStateException;
21 import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedChannelException;
22 import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedValueException;
23 import org.openhab.binding.rfxcom.internal.handler.DeviceState;
24 import org.openhab.core.library.types.DecimalType;
25 import org.openhab.core.types.State;
26 import org.openhab.core.types.Type;
29 * RFXCOM data class for temperature and humidity message.
31 * @author Marc SAUVEUR - Initial contribution
32 * @author Pauli Anttila - Migrated for OH2
33 * @author Mike Jagdis - Support all available data from sensors
35 public class RFXComWindMessage extends RFXComBatteryDeviceMessage<RFXComWindMessage.SubType> {
37 public enum SubType implements ByteEnumWrapper {
46 private final int subType;
48 SubType(int subType) {
49 this.subType = subType;
53 public byte toByte() {
54 return (byte) subType;
58 public SubType subType;
60 public double windDirection;
61 public double windSpeed;
62 public double avgWindSpeed;
63 public double temperature;
64 public double chillTemperature;
66 public RFXComWindMessage() {
67 super(PacketType.WIND);
70 public RFXComWindMessage(byte[] data) throws RFXComException {
75 public String toString() {
77 return super.toString()
78 + ", Sub type = " + subType
79 + ", Device Id = " + getDeviceId()
80 + ", Wind direction = " + windDirection
81 + ", Wind gust = " + windSpeed
82 + ", Average wind speed = " + avgWindSpeed
83 + ", Temperature = " + temperature
84 + ", Chill temperature = " + chillTemperature
85 + ", Signal level = " + signalLevel
86 + ", Battery level = " + batteryLevel;
91 public void encodeMessage(byte[] data) throws RFXComException {
92 super.encodeMessage(data);
94 subType = fromByte(SubType.class, super.subType);
95 sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
97 windDirection = (short) ((data[6] & 0xFF) << 8 | (data[7] & 0xFF));
99 if (subType != SubType.WIND5) {
100 avgWindSpeed = (short) ((data[8] & 0xFF) << 8 | (data[9] & 0xFF)) * 0.1;
103 windSpeed = (short) ((data[10] & 0xFF) << 8 | (data[11] & 0xFF)) * 0.1;
105 if (subType == SubType.WIND4) {
106 temperature = (short) ((data[12] & 0x7F) << 8 | (data[13] & 0xFF)) * 0.1;
107 if ((data[12] & 0x80) != 0) {
108 temperature = -temperature;
111 chillTemperature = (short) ((data[14] & 0x7F) << 8 | (data[15] & 0xFF)) * 0.1;
112 if ((data[14] & 0x80) != 0) {
113 chillTemperature = -chillTemperature;
117 signalLevel = (byte) ((data[16] & 0xF0) >> 4);
118 batteryLevel = (byte) (data[16] & 0x0F);
122 public byte[] decodeMessage() {
123 byte[] data = new byte[17];
126 data[1] = PacketType.WIND.toByte();
127 data[2] = subType.toByte();
129 data[4] = (byte) ((sensorId & 0xFF00) >> 8);
130 data[5] = (byte) (sensorId & 0x00FF);
132 short absWindDirection = (short) Math.abs(windDirection);
133 data[6] = (byte) ((absWindDirection >> 8) & 0xFF);
134 data[7] = (byte) (absWindDirection & 0xFF);
136 if (subType != SubType.WIND5) {
137 int absAvgWindSpeedTimesTen = (short) Math.abs(avgWindSpeed) * 10;
138 data[8] = (byte) ((absAvgWindSpeedTimesTen >> 8) & 0xFF);
139 data[9] = (byte) (absAvgWindSpeedTimesTen & 0xFF);
142 int absWindSpeedTimesTen = (short) Math.abs(windSpeed) * 10;
143 data[10] = (byte) ((absWindSpeedTimesTen >> 8) & 0xFF);
144 data[11] = (byte) (absWindSpeedTimesTen & 0xFF);
146 if (subType == SubType.WIND4) {
147 int temp = (short) Math.abs(temperature) * 10;
148 data[12] = (byte) ((temp >> 8) & 0x7F);
149 data[13] = (byte) (temp & 0xFF);
150 if (temperature < 0) {
154 int chill = (short) Math.abs(chillTemperature) * 10;
155 data[14] = (byte) ((chill >> 8) & 0x7F);
156 data[15] = (byte) (chill & 0xFF);
157 if (chillTemperature < 0) {
162 data[16] = (byte) (((signalLevel & 0x0F) << 4) | (batteryLevel & 0x0F));
168 public String getDeviceId() {
169 return String.valueOf(sensorId);
173 public State convertToState(String channelId, RFXComDeviceConfiguration config, DeviceState deviceState)
174 throws RFXComUnsupportedChannelException, RFXComInvalidStateException {
176 case CHANNEL_WIND_DIRECTION:
177 return new DecimalType(windDirection);
179 case CHANNEL_AVG_WIND_SPEED:
180 return new DecimalType(avgWindSpeed);
182 case CHANNEL_WIND_SPEED:
183 return new DecimalType(windSpeed);
185 case CHANNEL_TEMPERATURE:
186 return new DecimalType(temperature);
188 case CHANNEL_CHILL_TEMPERATURE:
189 return new DecimalType(chillTemperature);
192 return super.convertToState(channelId, config, deviceState);
197 public void setSubType(SubType subType) {
198 throw new UnsupportedOperationException();
202 public void setDeviceId(String deviceId) {
203 throw new UnsupportedOperationException();
207 public void convertFromState(String channelId, Type type) {
208 throw new UnsupportedOperationException();
212 public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
213 return ByteEnumUtil.convertSubType(SubType.class, subType);