| rainrate | Number | Rain fall rate in millimeters per hour. |
| raintotal | Number | Total rain in millimeters. |
| rawmessage | String | Hexadecimal representation of the raw RFXCOM msg incl. header and payload |
-| rawpayload | String | Hexadecimal representation of payload RFXCOM messages |
+| rawpayload | String | Hexadecimal representation of the payload of RFXCOM messages |
| setpoint | Number | Requested temperature. |
| shutter | Rollershutter | Shutter/blind channel. |
| status | String | Status channel. |
* [lighting5 - RFXCOM Lighting5 Actuator](#lighting5---rfxcom-lighting5-actuator)
* [lighting6 - RFXCOM Lighting6 Actuator](#lighting6---rfxcom-lighting6-actuator)
* [rain - RFXCOM Rain Sensor](#rain---rfxcom-rain-sensor)
+* [raw - RFXCOM Raw Messages](#raw---rfxcom-raw-messages)
* [rfxsensor - RFXCOM rfxsensor](#rfxsensor)
* [rfy - RFXCOM Rfy Actuator](#rfy---rfxcom-rfy-actuator)
* [security1 - RFXCOM Security1 Sensor](#security1---rfxcom-security1-sensor)
* RAIN6 - La Crosse TX5
* RAIN9 - TFA 30.3233.1
+### raw - RFXCOM Raw Messages
+
+Raw messages.
+
+#### Channels
+
+| Name | Channel Type | Item Type | Remarks |
+|------------|---------------------------|-----------|-------------|
+| rawMessage | [rawmessage](#channels) | String | |
+| rawPayload | [rawpayload](#channels) | String | |
+
+#### Configuration Options
+
+* deviceId - Device Id
+ * Raw items cannot provide a device ID, so this value is always RAW.
+
+* subType - Sub Type
+ * Specifies message sub type.
+
+ * RAW_PACKET1
+ * RAW_PACKET2
+ * RAW_PACKET3
+ * RAW_PACKET4
+
+
### rfxsensor - RFXCOM RFXSensor
A RFXSensor sensor
private static final ThingTypeUID THING_TYPE_POWER = new ThingTypeUID(BINDING_ID, "power");
private static final ThingTypeUID THING_TYPE_RADIATOR1 = new ThingTypeUID(BINDING_ID, "radiator1");
private static final ThingTypeUID THING_TYPE_RAIN = new ThingTypeUID(BINDING_ID, "rain");
+ private static final ThingTypeUID THING_TYPE_RAW = new ThingTypeUID(BINDING_ID, "raw");
private static final ThingTypeUID THING_TYPE_REMOTE_CONTROL = new ThingTypeUID(BINDING_ID, "remotecontrol");
private static final ThingTypeUID THING_TYPE_RFX_METER = new ThingTypeUID(BINDING_ID, "rfxmeter");
private static final ThingTypeUID THING_TYPE_RFX_SENSOR = new ThingTypeUID(BINDING_ID, "rfxsensor");
/**
* Presents all supported Thing types by RFXCOM binding.
*/
- public static final Set<ThingTypeUID> SUPPORTED_DEVICE_THING_TYPES_UIDS = Collections.unmodifiableSet(Stream.of(
- THING_TYPE_BAROMETRIC, THING_TYPE_BBQ_TEMPERATURE, THING_TYPE_BLINDS1, THING_TYPE_CAMERA1, THING_TYPE_CHIME,
- THING_TYPE_CURRENT, THING_TYPE_CURRENT_ENERGY, THING_TYPE_CURTAIN1, THING_TYPE_DATE_TIME, THING_TYPE_ENERGY,
- THING_TYPE_FAN, THING_TYPE_FAN_SF01, THING_TYPE_FAN_ITHO, THING_TYPE_FAN_SEAV, THING_TYPE_FAN_LUCCI_DC,
- THING_TYPE_FAN_FT1211R, THING_TYPE_FAN_FALMEC, THING_TYPE_FAN_LUCCI_DC_II, THING_TYPE_GAS_USAGE,
- THING_TYPE_HOME_CONFORT, THING_TYPE_HUMIDITY, THING_TYPE_IO_LINES, THING_TYPE_LIGHTNING1,
- THING_TYPE_LIGHTNING2, THING_TYPE_LIGHTNING3, THING_TYPE_LIGHTNING4, THING_TYPE_LIGHTNING5,
- THING_TYPE_LIGHTNING6, THING_TYPE_POWER, THING_TYPE_RADIATOR1, THING_TYPE_RAIN, THING_TYPE_REMOTE_CONTROL,
- THING_TYPE_RFX_METER, THING_TYPE_RFX_SENSOR, THING_TYPE_RFY, THING_TYPE_SECURITY1, THING_TYPE_SECURITY2,
- THING_TYPE_TEMPERATURE, THING_TYPE_TEMPERATURE_HUMIDITY, THING_TYPE_TEMPERATURE_HUMIDITY_BAROMETRIC,
- THING_TYPE_TEMPERATURE_RAIN, THING_TYPE_THERMOSTAT1, THING_TYPE_THERMOSTAT2, THING_TYPE_THERMOSTAT3,
- THING_TYPE_UNDECODED, THING_TYPE_UV, THING_TYPE_WATER_USAGE, THING_TYPE_WEIGHTING_SCALE, THING_TYPE_WIND)
- .collect(Collectors.toSet()));
+ public static final Set<ThingTypeUID> SUPPORTED_DEVICE_THING_TYPES_UIDS = Collections
+ .unmodifiableSet(Stream.of(THING_TYPE_BAROMETRIC, THING_TYPE_BBQ_TEMPERATURE, THING_TYPE_BLINDS1,
+ THING_TYPE_CAMERA1, THING_TYPE_CHIME, THING_TYPE_CURRENT, THING_TYPE_CURRENT_ENERGY,
+ THING_TYPE_CURTAIN1, THING_TYPE_DATE_TIME, THING_TYPE_ENERGY, THING_TYPE_FAN, THING_TYPE_FAN_SF01,
+ THING_TYPE_FAN_ITHO, THING_TYPE_FAN_SEAV, THING_TYPE_FAN_LUCCI_DC, THING_TYPE_FAN_FT1211R,
+ THING_TYPE_FAN_FALMEC, THING_TYPE_FAN_LUCCI_DC_II, THING_TYPE_GAS_USAGE, THING_TYPE_HOME_CONFORT,
+ THING_TYPE_HUMIDITY, THING_TYPE_IO_LINES, THING_TYPE_LIGHTNING1, THING_TYPE_LIGHTNING2,
+ THING_TYPE_LIGHTNING3, THING_TYPE_LIGHTNING4, THING_TYPE_LIGHTNING5, THING_TYPE_LIGHTNING6,
+ THING_TYPE_POWER, THING_TYPE_RADIATOR1, THING_TYPE_RAIN, THING_TYPE_RAW, THING_TYPE_REMOTE_CONTROL,
+ THING_TYPE_RFX_METER, THING_TYPE_RFX_SENSOR, THING_TYPE_RFY, THING_TYPE_SECURITY1,
+ THING_TYPE_SECURITY2, THING_TYPE_TEMPERATURE, THING_TYPE_TEMPERATURE_HUMIDITY,
+ THING_TYPE_TEMPERATURE_HUMIDITY_BAROMETRIC, THING_TYPE_TEMPERATURE_RAIN, THING_TYPE_THERMOSTAT1,
+ THING_TYPE_THERMOSTAT2, THING_TYPE_THERMOSTAT3, THING_TYPE_UNDECODED, THING_TYPE_UV,
+ THING_TYPE_WATER_USAGE, THING_TYPE_WEIGHTING_SCALE, THING_TYPE_WIND).collect(Collectors.toSet()));
/**
* Map RFXCOM packet types to RFXCOM Thing types and vice versa.
put(PacketType.POWER, RFXComBindingConstants.THING_TYPE_POWER);
put(PacketType.RADIATOR1, RFXComBindingConstants.THING_TYPE_RADIATOR1);
put(PacketType.RAIN, RFXComBindingConstants.THING_TYPE_RAIN);
+ put(PacketType.RAW, RFXComBindingConstants.THING_TYPE_RAW);
put(PacketType.REMOTE_CONTROL, RFXComBindingConstants.THING_TYPE_REMOTE_CONTROL);
put(PacketType.RFXMETER, RFXComBindingConstants.THING_TYPE_RFX_METER);
put(PacketType.RFXSENSOR, RFXComBindingConstants.THING_TYPE_RFX_SENSOR);
RFXSENSOR(112),
RFXMETER(113),
FS20(114),
+ RAW(127),
IO_LINES(128);
private final int packetType;
}
str += ", Packet type = " + packetType;
- str += ", Seq number = " + (short) (seqNbr & 0xFF);
+ str += ", Seq number = " + Byte.toUnsignedInt(seqNbr);
return str;
}
put(PacketType.RFXSENSOR, RFXComRFXSensorMessage.class);
// put(PacketType.RFXMETER, RFXComRFXMeterMessage.class);
// put(PacketType.FS20, RFXComFS20Message.class);
+ put(PacketType.RAW, RFXComRawMessage.class);
// put(PacketType.IO_LINES, RFXComIOLinesMessage.class);
}
});
--- /dev/null
+/**
+ * Copyright (c) 2010-2021 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.rfxcom.internal.messages;
+
+import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
+import static org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.PacketType.RAW;
+
+import java.nio.ByteBuffer;
+
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComMessageTooLongException;
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedChannelException;
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedValueException;
+import org.openhab.binding.rfxcom.internal.handler.DeviceState;
+import org.openhab.core.library.types.StringType;
+import org.openhab.core.types.State;
+import org.openhab.core.types.Type;
+import org.openhab.core.util.HexUtils;
+
+/**
+ * RFXCOM data class for raw messages.
+ *
+ * @author James Hewitt-Thomas - New addition to the PRO RFXCom firmware
+ */
+public class RFXComRawMessage extends RFXComDeviceMessageImpl<RFXComRawMessage.SubType> {
+
+ public enum SubType implements ByteEnumWrapper {
+ RAW_PACKET1(0x00),
+ RAW_PACKET2(0x01),
+ RAW_PACKET3(0x02),
+ RAW_PACKET4(0x03),
+
+ UNKNOWN(0xFF);
+
+ private final int subType;
+
+ SubType(int subType) {
+ this.subType = subType;
+ }
+
+ @Override
+ public byte toByte() {
+ return (byte) subType;
+ }
+
+ public static SubType fromByte(int input) {
+ for (SubType c : SubType.values()) {
+ if (c.subType == input) {
+ return c;
+ }
+ }
+
+ return SubType.UNKNOWN;
+ }
+ }
+
+ public SubType subType;
+ public byte repeat;
+ public short[] pulses;
+
+ public RFXComRawMessage() {
+ super(RAW);
+ pulses = new short[0];
+ }
+
+ public RFXComRawMessage(byte[] message) throws RFXComException {
+ encodeMessage(message);
+ }
+
+ @Override
+ public String toString() {
+ String str = super.toString();
+
+ str += ", Sub type = " + subType;
+
+ return str;
+ }
+
+ @Override
+ public void encodeMessage(byte[] message) throws RFXComException {
+ super.encodeMessage(message);
+
+ final int pulsesByteLen = rawMessage.length - 5;
+ if (pulsesByteLen % 4 != 0) {
+ throw new RFXComException("Incorrect byte length for pulses - must be divisible by 4");
+ }
+
+ subType = SubType.fromByte(super.subType);
+ repeat = rawMessage[4];
+ pulses = new short[pulsesByteLen / 2];
+ ByteBuffer.wrap(rawMessage, 5, rawMessage.length - 5).asShortBuffer().get(pulses);
+ }
+
+ @Override
+ public byte[] decodeMessage() throws RFXComException {
+ if (pulses.length > 124) {
+ throw new RFXComMessageTooLongException("Longest payload according to RFXtrx SDK is 124 shorts.");
+ }
+
+ final int pulsesByteLen = pulses.length * 2;
+ byte[] data = new byte[5 + pulsesByteLen];
+
+ data[0] = (byte) (data.length - 1);
+ data[1] = RAW.toByte();
+ data[2] = subType.toByte();
+ data[3] = seqNbr;
+ data[4] = repeat;
+
+ ByteBuffer.wrap(data, 5, pulsesByteLen).asShortBuffer().put(pulses);
+
+ return data;
+ }
+
+ @Override
+ public String getDeviceId() {
+ return "RAW";
+ }
+
+ @Override
+ public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
+ switch (channelId) {
+ case CHANNEL_RAW_MESSAGE:
+ return new StringType(HexUtils.bytesToHex(rawMessage));
+
+ case CHANNEL_RAW_PAYLOAD:
+ byte[] payload = new byte[pulses.length * 2];
+ ByteBuffer.wrap(payload).asShortBuffer().put(pulses);
+ return new StringType(HexUtils.bytesToHex(payload));
+
+ default:
+ throw new RFXComUnsupportedChannelException("Nothing relevant for " + channelId);
+ }
+ }
+
+ @Override
+ public void setSubType(SubType subType) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setDeviceId(String deviceId) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
+ switch (channelId) {
+ case CHANNEL_RAW_MESSAGE:
+ if (type instanceof StringType) {
+ // TODO: Check the raw message for validity (length, no more than 124 shorts, multiple of 4 bytes in
+ // payload)
+ throw new RFXComUnsupportedChannelException("Channel " + channelId + " inot yet implemented");
+ } else {
+ throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
+ }
+
+ case CHANNEL_RAW_PAYLOAD:
+ if (type instanceof StringType) {
+ // TODO: Check the payload for validity (no more than 124 shorts, multiple of 4 bytes
+ throw new RFXComUnsupportedChannelException("Channel " + channelId + " not yet implemented");
+ } else {
+ throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
+ }
+
+ default:
+ throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
+ }
+ }
+
+ @Override
+ public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
+ return ByteEnumUtil.convertSubType(SubType.class, subType);
+ }
+}
<channel-type id="rawmessage">
<item-type>String</item-type>
<label>Raw Message</label>
- <description>Hexadecimal representation of undecoded RFXCOM messages including header and payload</description>
+ <description>Hexadecimal representation of RFXCOM messages including header and payload</description>
</channel-type>
<channel-type id="rawpayload">
<item-type>String</item-type>
<label>Raw Payload</label>
- <description>Hexadecimal representation of payload of undecoded RFXCOM messages</description>
+ <description>Hexadecimal representation of payload of raw and undecoded RFXCOM messages</description>
</channel-type>
<channel-type id="command">
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="rfxcom"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+
+ <thing-type id="raw">
+ <supported-bridge-type-refs>
+ <bridge-type-ref id="bridge"/>
+ <bridge-type-ref id="tcpbridge"/>
+ <bridge-type-ref id="RFXtrx433"/>
+ <bridge-type-ref id="RFXrec433"/>
+ </supported-bridge-type-refs>
+
+ <label>RFXCOM Raw Messages</label>
+ <description>Raw messages.</description>
+
+ <channels>
+ <channel id="rawMessage" typeId="rawmessage"/>
+ <channel id="rawPayload" typeId="rawpayload"/>
+ </channels>
+
+ <config-description>
+ <parameter name="deviceId" type="text" required="true">
+ <label>Device Id</label>
+ <description>Raw items cannot provide a device ID, so this value is always RAW.</description>
+ </parameter>
+ <parameter name="subType" type="text" required="true">
+ <label>Sub Type</label>
+ <description>Specifies device sub type.</description>
+ <options>
+ <option value="RAW_PACKET1">RAW_PACKET1</option>
+ <option value="RAW_PACKET2">RAW_PACKET2</option>
+ <option value="RAW_PACKET3">RAW_PACKET3</option>
+ <option value="RAW_PACKET4">RAW_PACKET4</option>
+ </options>
+ </parameter>
+ </config-description>
+ </thing-type>
+
+</thing:thing-descriptions>
--- /dev/null
+/**
+ * Copyright (c) 2010-2021 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.rfxcom.internal.messages;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.nio.ByteBuffer;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComMessageTooLongException;
+import org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.PacketType;
+import org.openhab.core.util.HexUtils;
+
+/**
+ * Test for RFXCom-binding
+ *
+ * @author James Hewitt-Thomas - New addition to the PRO RFXCom firmware
+ */
+@NonNullByDefault
+public class RFXComRawMessageTest {
+
+ private void testMessage(String hexMsg, RFXComRawMessage.SubType subType, int seqNbr, int repeat, String pulses)
+ throws RFXComException {
+ final RFXComRawMessage msg = (RFXComRawMessage) RFXComMessageFactory.createMessage(HexUtils.hexToBytes(hexMsg));
+ assertEquals(subType, msg.subType, "SubType");
+ assertEquals(seqNbr, (short) (msg.seqNbr & 0xFF), "Seq Number");
+ assertEquals("RAW", msg.getDeviceId(), "Device Id");
+ assertEquals(repeat, msg.repeat, "Repeat");
+ byte[] payload = new byte[msg.pulses.length * 2];
+ ByteBuffer.wrap(payload).asShortBuffer().put(msg.pulses);
+ assertEquals(pulses, HexUtils.bytesToHex(payload), "Pulses");
+
+ byte[] decoded = msg.decodeMessage();
+
+ assertEquals(hexMsg, HexUtils.bytesToHex(decoded), "Message converted back");
+ }
+
+ @Test
+ public void testSomeMessages() throws RFXComException {
+ testMessage("087F0027051356ECC0", RFXComRawMessage.SubType.RAW_PACKET1, 0x27, 5, "1356ECC0");
+ }
+
+ @Test
+ public void testLongMessage() throws RFXComException {
+ RFXComRawMessage msg = (RFXComRawMessage) RFXComMessageFactory.createMessage(PacketType.RAW);
+ msg.subType = RFXComRawMessage.SubType.RAW_PACKET1;
+ msg.seqNbr = 1;
+ msg.repeat = 5;
+ msg.pulses = new short[125];
+
+ assertThrows(RFXComMessageTooLongException.class, () -> msg.decodeMessage());
+ }
+}