| mood | Number | Mood channel. |
| motion | Switch | Motion detection sensor state. |
| pressure | Number | Barometric value in hPa. |
+| pulses | String | Space separated decimal pulse lengths for a raw message in usec. |
| 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 |
* RAIN6 - La Crosse TX5
* RAIN9 - TFA 30.3233.1
+
### raw - RFXCOM Raw Messages
-Raw messages.
+Raw messages. These messages are included in the Pro firmware and represent messages
+for which the device does not understand the protocol. The raw message is a list of the
+length of the RF pulses before they have been interpreted as bytes.
+
+You can also send raw messages by recording the pulses of an incoming message and
+using them to configure a raw thing item.
#### Channels
|------------|---------------------------|-----------|-------------|
| rawMessage | [rawmessage](#channels) | String | |
| rawPayload | [rawpayload](#channels) | String | |
+| pulses | [pulses](#channels) | String | |
#### Configuration Options
* deviceId - Device Id
- * Raw items cannot provide a device ID, so this value is always RAW.
+ * Raw items cannot provide a device ID, so to receive RAW messages use
+ a Device Id of RAW. For transmit only devices, use any Device Id.
* subType - Sub Type
* Specifies message sub type.
* RAW_PACKET3
* RAW_PACKET4
+* repeat - Repeat
+ * Number of times to repeat message on transmit. Defaults to 5.
+
+* onPulses - On Pulses
+ * Pulses to send for an ON command. Space delimited pulse lengths
+ in usec. Must be an even number of pulse lengths, with a maximum
+ of 142 total pulses. Max pulse length is 65535. Pulses of value 0
+ will be transmitted as 10000. See the RFXtfx user guide for more
+ information.
+
+* offPulses - Off Pulses
+ * Pulses to send for an OFF command. Space delimited pulse lengths
+ in usec. Must be an even number of pulse lengths, with a maximum
+ of 142 total pulses. Max pulse length is 65535. Pulses of value 0
+ will be transmitted as 10000. See the RFXtfx user guide for more
+ information.
+
+* openPulses - Open Pulses
+ * Pulses to send for an OPEN command. Space delimited pulse lengths
+ in usec. Must be an even number of pulse lengths, with a maximum
+ of 142 total pulses. Max pulse length is 65535. Pulses of value 0
+ will be transmitted as 10000. See the RFXtfx user guide for more
+ information.
+
+* closedPulses - Closed Pulses
+ * Pulses to send for an CLOSED command. Space delimited pulse lengths
+ in usec. Must be an even number of pulse lengths, with a maximum
+ of 142 total pulses. Max pulse length is 65535. Pulses of value 0
+ will be transmitted as 10000. See the RFXtfx user guide for more
+ information.
+
+#### Examples
+
+This can be used to transmit raw messages.
+
+The first step is to work out the right pulses for the device. You can do this using RFXmngr, or
+you can do this using openhab:
+
+1. Set up a RAW thing to receive raw pulses:
+
+ ```
+ Bridge rfxcom:tcpbridge:rfxtrx0 [ host="192.168.42.10", port=10001, enableUndecoded=true ] {
+ Thing raw RAW [ deviceId="RAW", subType="RAW_PACKET1" ]
+ }
+ ```
+
+2. Add an item to see what the pulses are:
+
+ ```
+ String RawPulses { channel="rfxcom:raw:rfxtrx0:RAW:pulses" }
+ ```
+
+3. Activate the device and look at the pulses that are set. Look for a higher value in the pulses, that is
+ likely to be a gap for a repeat. Take the pulses from before the gap. Make sure there are an
+ even number, and if not, drop a 0 on the end.
+
+Now you have the pulses, set up a send device:
+
+1. Set up a RAW thing to send a command:
+
+ ```
+ Bridge rfxcom:tcpbridge:rfxtrx0 [ host="192.168.42.10", port=10001, enableUndecoded=true ] {
+ Thing raw MySwitch [ deviceId="MySwitch", subType="RAW_PACKET1", onPulses="100 200 300 0", offPulses="400 500 600 0" ]
+ }
+ ```
+
+2. Add an item to send the command:
+
+ ```
+ Switch MySwitch { channel="rfxcom:raw:rfxtrx0:MySwitch:command" }
+ ```
+
+3. Use the command to send the raw message.
### rfxsensor - RFXCOM RFXSensor
### undecoded - RFXCOM Undecoded RF Messages
-Any messages that RFXCOM can receive but not decode.
+Undecoded messages are messages where RFCOM understands the protocol and has converted
+the raw RF pulses into bytes, but has not attempted to decode the bytes into meaningful
+data.
+
+Undecoded message are receive only, there is not way to transmit an undecoded message.
+If you need to repeat an undecoded message, consider looking at Raw messages instead.
#### Channels
*/
package org.openhab.binding.rfxcom.internal;
+import java.util.AbstractMap;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration;
+import org.openhab.binding.rfxcom.internal.config.RFXComLighting4DeviceConfiguration;
+import org.openhab.binding.rfxcom.internal.config.RFXComRawDeviceConfiguration;
import org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.PacketType;
import org.openhab.core.thing.ThingTypeUID;
// List of all Channel ids
public static final String CHANNEL_RAW_MESSAGE = "rawMessage";
public static final String CHANNEL_RAW_PAYLOAD = "rawPayload";
+ public static final String CHANNEL_PULSES = "pulses";
public static final String CHANNEL_SHUTTER = "shutter";
public static final String CHANNEL_VENETIAN_BLIND = "venetianBlind";
public static final String CHANNEL_SUN_WIND_DETECTOR = "sunWindDetector";
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 Device ThingTypeUIDs to their Configuration class
+ */
+ public static final Map<ThingTypeUID, Class<? extends RFXComDeviceConfiguration>> THING_TYPE_UID_CONFIGURATION_CLASS_MAP = Map
+ .ofEntries(
+ new AbstractMap.SimpleEntry<ThingTypeUID, Class<? extends RFXComDeviceConfiguration>>(
+ THING_TYPE_RAW, RFXComRawDeviceConfiguration.class),
+ new AbstractMap.SimpleEntry<ThingTypeUID, Class<? extends RFXComDeviceConfiguration>>(
+ THING_TYPE_LIGHTNING4, RFXComLighting4DeviceConfiguration.class));
+
/**
* Map RFXCOM packet types to RFXCOM Thing types and vice versa.
*/
if (RFXComBindingConstants.SUPPORTED_BRIDGE_THING_TYPES_UIDS.contains(thingTypeUID)) {
return new RFXComBridgeHandler((Bridge) thing, serialPortManager);
- } else if (supportsThingType(thingTypeUID)) {
+ } else if (RFXComBindingConstants.SUPPORTED_DEVICE_THING_TYPES_UIDS.contains(thingTypeUID)) {
return new RFXComHandler(thing);
}
*/
package org.openhab.binding.rfxcom.internal.config;
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComInvalidParameterException;
+import org.openhab.binding.rfxcom.internal.messages.RFXComDeviceMessage;
+
/**
- * Configuration class for RfxcomBinding device.
+ * Configuration interface for RFXCom devices.
*
* @author Pauli Anttila - Initial contribution
+ * @author James Hewitt-Thomas - Convert to interface and add validation and matching
*/
+public interface RFXComDeviceConfiguration {
+ public void parseAndValidate() throws RFXComInvalidParameterException;
-public class RFXComDeviceConfiguration {
- public static final String DEVICE_ID_LABEL = "deviceId";
- public static final String SUB_TYPE_LABEL = "subType";
- public static final String PULSE_LABEL = "pulse";
- public static final String ON_COMMAND_ID_LABEL = "onCommandId";
- public static final String OFF_COMMAND_ID_LABEL = "offCommandId";
-
- public String deviceId;
- public String subType;
- public Integer pulse;
- public Integer onCommandId;
- public Integer offCommandId;
+ public boolean matchesMessage(RFXComDeviceMessage message);
}
--- /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.config;
+
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComInvalidParameterException;
+import org.openhab.binding.rfxcom.internal.messages.RFXComDeviceMessage;
+
+/**
+ * Configuration class for generic RFXCOM device.
+ *
+ * @author Pauli Anttila - Initial contribution
+ * @author James Hewitt-Thomas - Add validations and matching
+ */
+public class RFXComGenericDeviceConfiguration implements RFXComDeviceConfiguration {
+ public static final String DEVICE_ID_LABEL = "deviceId";
+ public static final String SUB_TYPE_LABEL = "subType";
+ public String deviceId;
+ public String subType;
+
+ @Override
+ public void parseAndValidate() throws RFXComInvalidParameterException {
+ if (deviceId == null) {
+ throw new RFXComInvalidParameterException("deviceId", null, "RFXCOM device missing deviceId");
+ }
+ if (subType == null) {
+ throw new RFXComInvalidParameterException("subType", null, "RFXCOM device missing subType");
+ }
+ }
+
+ @Override
+ public boolean matchesMessage(RFXComDeviceMessage message) {
+ return deviceId.equals(message.getDeviceId());
+ }
+}
--- /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.config;
+
+/**
+ * Configuration class for Lighting4 RFXCOM device.
+ *
+ * @author James Hewitt-Thomas - Initial contribution
+ */
+public class RFXComLighting4DeviceConfiguration extends RFXComGenericDeviceConfiguration {
+ public static final String PULSE_LABEL = "pulse";
+ public static final String ON_COMMAND_ID_LABEL = "onCommandId";
+ public static final String OFF_COMMAND_ID_LABEL = "offCommandId";
+ public Integer pulse;
+ public Integer onCommandId;
+ public Integer offCommandId;
+}
--- /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.config;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComInvalidParameterException;
+
+/**
+ * Configuration class for Raw RFXCOM device.
+ *
+ * @author James Hewitt-Thomas - Initial contribution
+ */
+@NonNullByDefault
+public class RFXComRawDeviceConfiguration extends RFXComGenericDeviceConfiguration {
+ public static final String REPEAT_LABEL = "repeat";
+ public int repeat;
+
+ public static final String ON_PULSES_LABEL = "onPulses";
+ public static final String OFF_PULSES_LABEL = "offPulses";
+ @Nullable
+ public String onPulses;
+ @Nullable
+ public String offPulses;
+ public short @Nullable [] onPulsesArray;
+ public short @Nullable [] offPulsesArray;
+
+ public static final String OPEN_PULSES_LABEL = "openPulses";
+ public static final String CLOSED_PULSES_LABEL = "closedPulses";
+ @Nullable
+ public String openPulses;
+ @Nullable
+ public String closedPulses;
+ public short @Nullable [] openPulsesArray;
+ public short @Nullable [] closedPulsesArray;
+
+ @Override
+ public void parseAndValidate() throws RFXComInvalidParameterException {
+ super.parseAndValidate();
+
+ onPulsesArray = parseAndValidatePulses("onPulses", onPulses);
+ offPulsesArray = parseAndValidatePulses("offPulses", offPulses);
+ openPulsesArray = parseAndValidatePulses("openPulses", openPulses);
+ closedPulsesArray = parseAndValidatePulses("closedPulses", closedPulses);
+ }
+
+ private static short @Nullable [] parseAndValidatePulses(String parameter, @Nullable String pulses)
+ throws RFXComInvalidParameterException {
+ if (pulses != null) {
+ return parseAndValidatePulsesNonNull(parameter, pulses);
+ } else {
+ return null;
+ }
+ }
+
+ private static short[] parseAndValidatePulsesNonNull(String parameter, String pulses)
+ throws RFXComInvalidParameterException {
+ String[] strings = pulses.trim().split("\\s+");
+
+ if (strings.length > 124) {
+ throw new RFXComInvalidParameterException(parameter, pulses, "Cannot have more than 124 pulses");
+ }
+
+ if (strings.length % 2 != 0) {
+ throw new RFXComInvalidParameterException(parameter, pulses, "Pulses must be in pairs");
+ }
+
+ try {
+ short[] shorts = new short[strings.length];
+ for (int i = 0; i < strings.length; i++) {
+ int pulse = Integer.parseInt(strings[i]);
+ if (pulse > 65535) {
+ throw new RFXComInvalidParameterException(parameter, pulses, "Cannot have pulse above 65535 usec");
+ } else if (pulse < 0) {
+ throw new RFXComInvalidParameterException(parameter, pulses, "Cannot have negative pulse");
+ } else if (pulse == 0) {
+ // The user guide suggests that received pulses of size 0 should be
+ // replaced with something above 8000, as they represent gaps.
+ shorts[i] = 10000;
+ } else {
+ shorts[i] = (short) pulse;
+ }
+ }
+ return shorts;
+ } catch (NumberFormatException e) {
+ throw new RFXComInvalidParameterException(parameter, pulses, e.getMessage(), e);
+ }
+ }
+}
--- /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.exceptions;
+
+/**
+ * Exception for when RFXCOM messages have a value that we don't understand.
+ *
+ * @author James Hewitt-Thomas - Initial contribution
+ */
+public class RFXComInvalidParameterException extends RFXComException {
+
+ private static final long serialVersionUID = -2778120072474013560L;
+
+ public RFXComInvalidParameterException(String parameter, String value) {
+ super("Invalid value '" + value + "' for parameter " + parameter);
+ }
+
+ public RFXComInvalidParameterException(String parameter, String value, String reason) {
+ super("Invalid value '" + value + "' for parameter " + parameter + ": " + reason);
+ }
+
+ public RFXComInvalidParameterException(String parameter, String value, Throwable cause) {
+ super("Invalid value '" + value + "' for parameter " + parameter, cause);
+ }
+
+ public RFXComInvalidParameterException(String parameter, String value, String reason, Throwable cause) {
+ super("Invalid value '" + value + "' for parameter " + parameter + ": " + reason, cause);
+ }
+}
--- /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.exceptions;
+
+/**
+ * Exception for when RFXCOM messages have a value that we don't understand.
+ *
+ * @author James Hewitt-Thomas - Initial contribution
+ */
+public class RFXComInvalidStateException extends RFXComException {
+
+ private static final long serialVersionUID = -2770653643474013560L;
+
+ public RFXComInvalidStateException(String channel, String state) {
+ super("Invalid state '" + state + "' for parameter " + channel);
+ }
+
+ public RFXComInvalidStateException(String channel, String state, String reason) {
+ super("Invalid state '" + state + "' for parameter " + channel + ": " + reason);
+ }
+}
import org.openhab.binding.rfxcom.internal.messages.RFXComInterfaceMessage.SubType;
import org.openhab.binding.rfxcom.internal.messages.RFXComMessage;
import org.openhab.binding.rfxcom.internal.messages.RFXComMessageFactory;
+import org.openhab.binding.rfxcom.internal.messages.RFXComMessageFactoryImpl;
import org.openhab.binding.rfxcom.internal.messages.RFXComTransmitterMessage;
import org.openhab.core.io.transport.serial.SerialPortManager;
import org.openhab.core.thing.Bridge;
private SerialPortManager serialPortManager;
+ private RFXComMessageFactory messageFactory;
+
private class TransmitQueue {
private Queue<RFXComBaseMessage> queue = new LinkedBlockingQueue<>();
public RFXComBridgeHandler(@NonNull Bridge br, SerialPortManager serialPortManager) {
super(br);
this.serialPortManager = serialPortManager;
+ this.messageFactory = RFXComMessageFactoryImpl.INSTANCE;
+ }
+
+ public RFXComBridgeHandler(@NonNull Bridge br, SerialPortManager serialPortManager,
+ RFXComMessageFactory messageFactory) {
+ super(br);
+ this.serialPortManager = serialPortManager;
+ this.messageFactory = messageFactory;
}
@Override
connector.connect(configuration);
logger.debug("Reset controller");
- connector.sendMessage(RFXComMessageFactory.CMD_RESET);
+ connector.sendMessage(RFXComInterfaceMessage.CMD_RESET);
// controller does not response immediately after reset,
// so wait a while
connector.addEventListener(eventListener);
logger.debug("Get status of controller");
- connector.sendMessage(RFXComMessageFactory.CMD_GET_STATUS);
+ connector.sendMessage(RFXComInterfaceMessage.CMD_GET_STATUS);
}
} catch (IOException e) {
logger.error("Connection to RFXCOM transceiver failed", e);
@Override
public void packetReceived(byte[] packet) {
try {
- RFXComMessage message = RFXComMessageFactory.createMessage(packet);
+ RFXComMessage message = messageFactory.createMessage(packet);
logger.debug("Message received: {}", message);
if (message instanceof RFXComInterfaceMessage) {
// regardless of whether it fails and the RFXCOM's buffer
// is big enough to queue up the command.
logger.debug("Start receiver");
- connector.sendMessage(RFXComMessageFactory.CMD_START_RECEIVER);
+ connector.sendMessage(RFXComInterfaceMessage.CMD_START_RECEIVER);
}
} else if (msg.subType == SubType.START_RECEIVER) {
updateStatus(ThingStatus.ONLINE);
import org.eclipse.jdt.annotation.NonNull;
import org.openhab.binding.rfxcom.internal.DeviceMessageListener;
+import org.openhab.binding.rfxcom.internal.RFXComBindingConstants;
import org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration;
+import org.openhab.binding.rfxcom.internal.config.RFXComGenericDeviceConfiguration;
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComInvalidParameterException;
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComInvalidStateException;
import org.openhab.binding.rfxcom.internal.exceptions.RFXComMessageNotImplementedException;
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedChannelException;
import org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.PacketType;
import org.openhab.binding.rfxcom.internal.messages.RFXComDeviceMessage;
import org.openhab.binding.rfxcom.internal.messages.RFXComMessage;
import org.openhab.binding.rfxcom.internal.messages.RFXComMessageFactory;
+import org.openhab.binding.rfxcom.internal.messages.RFXComMessageFactoryImpl;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
private final Map<String, Type> stateMap = new ConcurrentHashMap<>();
private RFXComBridgeHandler bridgeHandler;
+
+ private Class<? extends RFXComDeviceConfiguration> configType;
private RFXComDeviceConfiguration config;
+ private RFXComMessageFactory messageFactory;
+
public RFXComHandler(@NonNull Thing thing) {
+ this(thing, RFXComMessageFactoryImpl.INSTANCE);
+ }
+
+ public RFXComHandler(@NonNull Thing thing, RFXComMessageFactory messageFactory) {
super(thing);
+ this.messageFactory = messageFactory;
+
+ configType = RFXComBindingConstants.THING_TYPE_UID_CONFIGURATION_CLASS_MAP.getOrDefault(thing.getThingTypeUID(),
+ RFXComGenericDeviceConfiguration.class);
}
@Override
logger.trace("Received unsupported Refresh command");
} else {
try {
- PacketType packetType = RFXComMessageFactory
+ PacketType packetType = RFXComMessageFactoryImpl
.convertPacketType(getThing().getThingTypeUID().getId().toUpperCase());
- RFXComMessage msg = RFXComMessageFactory.createMessage(packetType);
+ RFXComMessage msg = messageFactory.createMessage(packetType);
msg.setConfig(config);
msg.convertFromState(channelUID.getId(), command);
bridgeHandler.sendMessage(msg);
} catch (RFXComMessageNotImplementedException e) {
logger.error("Message not supported", e);
+ } catch (RFXComUnsupportedChannelException e) {
+ logger.error("Channel not supported", e);
+ } catch (RFXComInvalidStateException e) {
+ logger.error("Invalid state supplied for channel", e);
} catch (RFXComException e) {
logger.error("Transmitting error", e);
}
@Override
public void initialize() {
logger.debug("Initializing thing {}", getThing().getUID());
- initializeBridge((getBridge() == null) ? null : getBridge().getHandler(),
- (getBridge() == null) ? null : getBridge().getStatus());
+
+ Bridge bridge = getBridge();
+
+ if (bridge == null) {
+ initializeBridge(null, null);
+ } else {
+ initializeBridge(bridge.getHandler(), bridge.getStatus());
+ }
stateMap.clear();
}
@Override
public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
logger.debug("bridgeStatusChanged {} for thing {}", bridgeStatusInfo, getThing().getUID());
- initializeBridge((getBridge() == null) ? null : getBridge().getHandler(), bridgeStatusInfo.getStatus());
+
+ Bridge bridge = getBridge();
+
+ if (bridge == null) {
+ initializeBridge(null, bridgeStatusInfo.getStatus());
+ } else {
+ initializeBridge(bridge.getHandler(), bridgeStatusInfo.getStatus());
+ }
}
private void initializeBridge(ThingHandler thingHandler, ThingStatus bridgeStatus) {
logger.debug("initializeBridge {} for thing {}", bridgeStatus, getThing().getUID());
- config = getConfigAs(RFXComDeviceConfiguration.class);
- if (config.deviceId == null || config.subType == null) {
- updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
- "RFXCOM device missing deviceId or subType");
- } else if (thingHandler != null && bridgeStatus != null) {
- bridgeHandler = (RFXComBridgeHandler) thingHandler;
- bridgeHandler.registerDeviceStatusListener(this);
+ try {
+ config = getConfigAs(configType);
+ config.parseAndValidate();
+ if (thingHandler != null && bridgeStatus != null) {
+ bridgeHandler = (RFXComBridgeHandler) thingHandler;
+ bridgeHandler.registerDeviceStatusListener(this);
- if (bridgeStatus == ThingStatus.ONLINE) {
- updateStatus(ThingStatus.ONLINE);
+ if (bridgeStatus == ThingStatus.ONLINE) {
+ updateStatus(ThingStatus.ONLINE);
+ } else {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
+ }
} else {
- updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED);
}
- } else {
- updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED);
+ } catch (RFXComInvalidParameterException e) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
}
}
@Override
public void onDeviceMessageReceived(ThingUID bridge, RFXComDeviceMessage message) {
try {
- String id = message.getDeviceId();
- if (config.deviceId.equals(id)) {
+ if (config.matchesMessage(message)) {
String receivedId = PACKET_TYPE_THING_TYPE_UID_MAP.get(message.getPacketType()).getId();
logger.debug("Received message from bridge: {} message: {}", bridge, message);
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.CHANNEL_SIGNAL_LEVEL;
import org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration;
+import org.openhab.binding.rfxcom.internal.config.RFXComGenericDeviceConfiguration;
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedChannelException;
import org.openhab.binding.rfxcom.internal.handler.DeviceState;
@Override
public void setConfig(RFXComDeviceConfiguration config) throws RFXComException {
- this.setSubType(convertSubType(config.subType));
- this.setDeviceId(config.deviceId);
+ RFXComGenericDeviceConfiguration genericConfig = (RFXComGenericDeviceConfiguration) config;
+ this.setSubType(convertSubType(genericConfig.subType));
+ this.setDeviceId(genericConfig.deviceId);
}
@Override
String subTypeString = convertSubType(String.valueOf(subType)).toString();
String label = getPacketType() + "-" + getDeviceId();
- discoveryResultBuilder.withLabel(label).withProperty(RFXComDeviceConfiguration.DEVICE_ID_LABEL, getDeviceId())
- .withProperty(RFXComDeviceConfiguration.SUB_TYPE_LABEL, subTypeString);
+ discoveryResultBuilder.withLabel(label)
+ .withProperty(RFXComGenericDeviceConfiguration.DEVICE_ID_LABEL, getDeviceId())
+ .withProperty(RFXComGenericDeviceConfiguration.SUB_TYPE_LABEL, subTypeString);
}
/**
public void convertFromState(String channelId, Type type) {
throw new UnsupportedOperationException();
}
+
+ /**
+ * Command to reset RFXCOM controller.
+ *
+ */
+ public static final byte[] CMD_RESET = new byte[] { 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00 };
+
+ /**
+ * Command to get RFXCOM controller status.
+ *
+ */
+ public static final byte[] CMD_GET_STATUS = new byte[] { 0x0D, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00 };
+
+ /**
+ * Command to save RFXCOM controller configuration.
+ *
+ */
+ public static final byte[] CMD_SAVE = new byte[] { 0x0D, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00 };
+
+ /**
+ * Command to start RFXCOM receiver.
+ *
+ */
+ public static final byte[] CMD_START_RECEIVER = new byte[] { 0x0D, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00 };
}
package org.openhab.binding.rfxcom.internal.messages;
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
-import static org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration.*;
+import static org.openhab.binding.rfxcom.internal.config.RFXComLighting4DeviceConfiguration.*;
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
import org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration;
+import org.openhab.binding.rfxcom.internal.config.RFXComLighting4DeviceConfiguration;
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedChannelException;
import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedValueException;
@Override
public void setConfig(RFXComDeviceConfiguration config) throws RFXComException {
- super.setConfig(config);
- this.pulse = config.pulse != null ? config.pulse : 350;
- this.onCommandId = valueOrDefault(config.onCommandId, DEFAULT_ON_COMMAND_ID);
- this.offCommandId = valueOrDefault(config.offCommandId, DEFAULT_OFF_COMMAND_ID);
+ RFXComLighting4DeviceConfiguration lighting4Config = (RFXComLighting4DeviceConfiguration) config;
+ super.setConfig(lighting4Config);
+ this.pulse = lighting4Config.pulse != null ? lighting4Config.pulse : 350;
+ this.onCommandId = valueOrDefault(lighting4Config.onCommandId, DEFAULT_ON_COMMAND_ID);
+ this.offCommandId = valueOrDefault(lighting4Config.offCommandId, DEFAULT_OFF_COMMAND_ID);
}
private int valueOrDefault(Integer commandId, byte defaultValue) {
import org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration;
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComInvalidStateException;
import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedChannelException;
import org.openhab.core.types.Type;
/**
* Procedure for converting openHAB state to RFXCOM object.
+ *
+ * @throws RFXComUnsupportedChannelException If we do not support setting this channel
+ * @throws RFXComInvalidStateException If the state (type) is invalid for the channel
*/
- void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException;
+ void convertFromState(String channelId, Type type)
+ throws RFXComUnsupportedChannelException, RFXComInvalidStateException;
/**
* Procedure to pass configuration to a message
*/
package org.openhab.binding.rfxcom.internal.messages;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
-import org.openhab.binding.rfxcom.internal.exceptions.RFXComMessageNotImplementedException;
import org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.PacketType;
/**
+ * Factory to create RFXCom messages from either bytes delivered by the RFXCom device
+ * or from openhab state to transmit.
*
* @author Pauli Anttila - Initial contribution
+ * @author James Hewitt-Thomas - Convert to interface to allow dependency injection
*/
-public class RFXComMessageFactory {
-
- @SuppressWarnings("serial")
- private static final Map<PacketType, Class<? extends RFXComMessage>> MESSAGE_CLASSES = Collections
- .unmodifiableMap(new HashMap<PacketType, Class<? extends RFXComMessage>>() {
- {
- put(PacketType.INTERFACE_CONTROL, RFXComInterfaceControlMessage.class);
- put(PacketType.INTERFACE_MESSAGE, RFXComInterfaceMessage.class);
- put(PacketType.TRANSMITTER_MESSAGE, RFXComTransmitterMessage.class);
- put(PacketType.UNDECODED_RF_MESSAGE, RFXComUndecodedRFMessage.class);
- put(PacketType.LIGHTING1, RFXComLighting1Message.class);
- put(PacketType.LIGHTING2, RFXComLighting2Message.class);
- // put(PacketType.LIGHTING3, RFXComLighting3Message.class);
- put(PacketType.LIGHTING4, RFXComLighting4Message.class);
- put(PacketType.LIGHTING5, RFXComLighting5Message.class);
- put(PacketType.LIGHTING6, RFXComLighting6Message.class);
- put(PacketType.CHIME, RFXComChimeMessage.class);
- put(PacketType.FAN, RFXComFanMessage.class);
- // put(PacketType.FAN_SF01, RFXComFanMessage.class);
- // put(PacketType.FAN_ITHO, RFXComFanMessage.class);
- // put(PacketType.FAN_SEAV, RFXComFanMessage.class);
- put(PacketType.FAN_LUCCI_DC, RFXComFanMessage.class);
- // put(PacketType.FAN_FT1211R, RFXComFanMessage.class);
- put(PacketType.FAN_FALMEC, RFXComFanMessage.class);
- put(PacketType.FAN_LUCCI_DC_II, RFXComFanMessage.class);
- put(PacketType.FAN_NOVY, RFXComFanMessage.class);
- put(PacketType.CURTAIN1, RFXComCurtain1Message.class);
- put(PacketType.BLINDS1, RFXComBlinds1Message.class);
- put(PacketType.RFY, RFXComRfyMessage.class);
- put(PacketType.HOME_CONFORT, RFXComHomeConfortMessage.class);
- put(PacketType.SECURITY1, RFXComSecurity1Message.class);
- put(PacketType.SECURITY2, RFXComSecurity2Message.class);
- // put(PacketType.CAMERA1, RFXComCamera1Message.class);
- // put(PacketType.REMOTE_CONTROL, RFXComRemoteControlMessage.class);
- put(PacketType.THERMOSTAT1, RFXComThermostat1Message.class);
- // put(PacketType.THERMOSTAT2, RFXComThermostat2Message.class);
- put(PacketType.THERMOSTAT3, RFXComThermostat3Message.class);
- // put(PacketType.RADIATOR1, RFXComRadiator1Message.class);
- put(PacketType.BBQ, RFXComBBQTemperatureMessage.class);
- put(PacketType.TEMPERATURE_RAIN, RFXComTemperatureRainMessage.class);
- put(PacketType.TEMPERATURE, RFXComTemperatureMessage.class);
- put(PacketType.HUMIDITY, RFXComHumidityMessage.class);
- put(PacketType.TEMPERATURE_HUMIDITY, RFXComTemperatureHumidityMessage.class);
- // put(PacketType.BAROMETRIC, RFXComBarometricMessage.class);
- put(PacketType.TEMPERATURE_HUMIDITY_BAROMETRIC, RFXComTemperatureHumidityBarometricMessage.class);
- put(PacketType.RAIN, RFXComRainMessage.class);
- put(PacketType.WIND, RFXComWindMessage.class);
- put(PacketType.UV, RFXComUVMessage.class);
- put(PacketType.DATE_TIME, RFXComDateTimeMessage.class);
- put(PacketType.CURRENT, RFXComCurrentMessage.class);
- put(PacketType.ENERGY, RFXComEnergyMessage.class);
- put(PacketType.CURRENT_ENERGY, RFXComCurrentEnergyMessage.class);
- // put(PacketType.POWER, RFXComPowerMessage.class);
- // put(PacketType.WEIGHT, RFXComWeightMessage.class);
- // put(PacketType.GAS, RFXComGasMessage.class);
- // put(PacketType.WATER, RFXComWaterMessage.class);
- 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);
- }
- });
-
- /**
- * Command to reset RFXCOM controller.
- *
- */
- public static final byte[] CMD_RESET = new byte[] { 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00 };
-
- /**
- * Command to get RFXCOM controller status.
- *
- */
- public static final byte[] CMD_GET_STATUS = new byte[] { 0x0D, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00 };
-
- /**
- * Command to save RFXCOM controller configuration.
- *
- */
- public static final byte[] CMD_SAVE = new byte[] { 0x0D, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00 };
-
- /**
- * Command to start RFXCOM receiver.
- *
- */
- public static final byte[] CMD_START_RECEIVER = new byte[] { 0x0D, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00 };
-
- public static RFXComMessage createMessage(PacketType packetType) throws RFXComException {
- try {
- Class<? extends RFXComMessage> cl = MESSAGE_CLASSES.get(packetType);
- if (cl == null) {
- throw new RFXComMessageNotImplementedException("Message " + packetType + " not implemented");
- }
- return cl.newInstance();
- } catch (IllegalAccessException | InstantiationException e) {
- throw new RFXComException(e);
- }
- }
-
- public static RFXComMessage createMessage(byte[] packet) throws RFXComException {
- PacketType packetType = ByteEnumUtil.fromByte(PacketType.class, packet[1]);
-
- try {
- Class<? extends RFXComMessage> cl = MESSAGE_CLASSES.get(packetType);
- if (cl == null) {
- throw new RFXComMessageNotImplementedException("Message " + packetType + " not implemented");
- }
- Constructor<?> c = cl.getConstructor(byte[].class);
- return (RFXComMessage) c.newInstance(packet);
- } catch (InvocationTargetException e) {
- if (e.getCause() instanceof RFXComException) {
- throw (RFXComException) e.getCause();
- } else {
- throw new RFXComException(e);
- }
- } catch (NoSuchMethodException | IllegalAccessException | InstantiationException e) {
- throw new RFXComException(e);
- }
- }
-
- public static PacketType convertPacketType(String packetType) throws IllegalArgumentException {
- for (PacketType p : PacketType.values()) {
- if (p.toString().replace("_", "").equals(packetType.replace("_", ""))) {
- return p;
- }
- }
+public interface RFXComMessageFactory {
+ public RFXComMessage createMessage(PacketType packetType) throws RFXComException;
- throw new IllegalArgumentException("Unknown packet type " + packetType);
- }
+ public RFXComMessage createMessage(byte[] packet) throws RFXComException;
}
--- /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 java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComMessageNotImplementedException;
+import org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.PacketType;
+
+/**
+ * Factory to create RFXCom messages from either bytes delivered by the RFXCom device
+ * or from openhab state to transmit.
+ *
+ * @author Pauli Anttila - Initial contribution
+ * @author James Hewitt-Thomas - Use the enum singleton pattern to allow dependency injection
+ */
+public enum RFXComMessageFactoryImpl implements RFXComMessageFactory {
+ INSTANCE();
+
+ @SuppressWarnings("serial")
+ private static final Map<PacketType, Class<? extends RFXComMessage>> MESSAGE_CLASSES = Collections
+ .unmodifiableMap(new HashMap<PacketType, Class<? extends RFXComMessage>>() {
+ {
+ put(PacketType.INTERFACE_CONTROL, RFXComInterfaceControlMessage.class);
+ put(PacketType.INTERFACE_MESSAGE, RFXComInterfaceMessage.class);
+ put(PacketType.TRANSMITTER_MESSAGE, RFXComTransmitterMessage.class);
+ put(PacketType.UNDECODED_RF_MESSAGE, RFXComUndecodedRFMessage.class);
+ put(PacketType.LIGHTING1, RFXComLighting1Message.class);
+ put(PacketType.LIGHTING2, RFXComLighting2Message.class);
+ // put(PacketType.LIGHTING3, RFXComLighting3Message.class);
+ put(PacketType.LIGHTING4, RFXComLighting4Message.class);
+ put(PacketType.LIGHTING5, RFXComLighting5Message.class);
+ put(PacketType.LIGHTING6, RFXComLighting6Message.class);
+ put(PacketType.CHIME, RFXComChimeMessage.class);
+ put(PacketType.FAN, RFXComFanMessage.class);
+ // put(PacketType.FAN_SF01, RFXComFanMessage.class);
+ // put(PacketType.FAN_ITHO, RFXComFanMessage.class);
+ // put(PacketType.FAN_SEAV, RFXComFanMessage.class);
+ put(PacketType.FAN_LUCCI_DC, RFXComFanMessage.class);
+ // put(PacketType.FAN_FT1211R, RFXComFanMessage.class);
+ put(PacketType.FAN_FALMEC, RFXComFanMessage.class);
+ put(PacketType.FAN_LUCCI_DC_II, RFXComFanMessage.class);
+ put(PacketType.FAN_NOVY, RFXComFanMessage.class);
+ put(PacketType.CURTAIN1, RFXComCurtain1Message.class);
+ put(PacketType.BLINDS1, RFXComBlinds1Message.class);
+ put(PacketType.RFY, RFXComRfyMessage.class);
+ put(PacketType.HOME_CONFORT, RFXComHomeConfortMessage.class);
+ put(PacketType.SECURITY1, RFXComSecurity1Message.class);
+ put(PacketType.SECURITY2, RFXComSecurity2Message.class);
+ // put(PacketType.CAMERA1, RFXComCamera1Message.class);
+ // put(PacketType.REMOTE_CONTROL, RFXComRemoteControlMessage.class);
+ put(PacketType.THERMOSTAT1, RFXComThermostat1Message.class);
+ // put(PacketType.THERMOSTAT2, RFXComThermostat2Message.class);
+ put(PacketType.THERMOSTAT3, RFXComThermostat3Message.class);
+ // put(PacketType.RADIATOR1, RFXComRadiator1Message.class);
+ put(PacketType.BBQ, RFXComBBQTemperatureMessage.class);
+ put(PacketType.TEMPERATURE_RAIN, RFXComTemperatureRainMessage.class);
+ put(PacketType.TEMPERATURE, RFXComTemperatureMessage.class);
+ put(PacketType.HUMIDITY, RFXComHumidityMessage.class);
+ put(PacketType.TEMPERATURE_HUMIDITY, RFXComTemperatureHumidityMessage.class);
+ // put(PacketType.BAROMETRIC, RFXComBarometricMessage.class);
+ put(PacketType.TEMPERATURE_HUMIDITY_BAROMETRIC, RFXComTemperatureHumidityBarometricMessage.class);
+ put(PacketType.RAIN, RFXComRainMessage.class);
+ put(PacketType.WIND, RFXComWindMessage.class);
+ put(PacketType.UV, RFXComUVMessage.class);
+ put(PacketType.DATE_TIME, RFXComDateTimeMessage.class);
+ put(PacketType.CURRENT, RFXComCurrentMessage.class);
+ put(PacketType.ENERGY, RFXComEnergyMessage.class);
+ put(PacketType.CURRENT_ENERGY, RFXComCurrentEnergyMessage.class);
+ // put(PacketType.POWER, RFXComPowerMessage.class);
+ // put(PacketType.WEIGHT, RFXComWeightMessage.class);
+ // put(PacketType.GAS, RFXComGasMessage.class);
+ // put(PacketType.WATER, RFXComWaterMessage.class);
+ 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);
+ }
+ });
+
+ /**
+ * Create message for transmission from the packet type associated with the thing.
+ */
+ @Override
+ public RFXComMessage createMessage(PacketType packetType) throws RFXComException {
+ try {
+ Class<? extends RFXComMessage> cl = MESSAGE_CLASSES.get(packetType);
+ if (cl == null) {
+ throw new RFXComMessageNotImplementedException("Message " + packetType + " not implemented");
+ }
+ return cl.getDeclaredConstructor().newInstance();
+ } catch (ReflectiveOperationException e) {
+ throw new RFXComException(e);
+ }
+ }
+
+ /**
+ * Create message from received bytes.
+ */
+ @Override
+ public RFXComMessage createMessage(byte[] packet) throws RFXComException {
+ PacketType packetType = ByteEnumUtil.fromByte(PacketType.class, packet[1]);
+
+ try {
+ Class<? extends RFXComMessage> cl = MESSAGE_CLASSES.get(packetType);
+ if (cl == null) {
+ throw new RFXComMessageNotImplementedException("Message " + packetType + " not implemented");
+ }
+ Constructor<?> c = cl.getConstructor(byte[].class);
+ return (RFXComMessage) c.newInstance(packet);
+ } catch (InvocationTargetException e) {
+ if (e.getCause() instanceof RFXComException) {
+ throw (RFXComException) e.getCause();
+ } else {
+ throw new RFXComException(e);
+ }
+ } catch (NoSuchMethodException | IllegalAccessException | InstantiationException e) {
+ throw new RFXComException(e);
+ }
+ }
+
+ public static PacketType convertPacketType(String packetType) throws IllegalArgumentException {
+ for (PacketType p : PacketType.values()) {
+ if (p.toString().replace("_", "").equals(packetType.replace("_", ""))) {
+ return p;
+ }
+ }
+
+ throw new IllegalArgumentException("Unknown packet type " + packetType);
+ }
+}
import static org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.PacketType.RAW;
import java.nio.ByteBuffer;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration;
+import org.openhab.binding.rfxcom.internal.config.RFXComRawDeviceConfiguration;
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComInvalidStateException;
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.OnOffType;
+import org.openhab.core.library.types.OpenClosedType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.types.State;
import org.openhab.core.types.Type;
public byte repeat;
public short[] pulses;
+ private RFXComRawDeviceConfiguration config;
+
public RFXComRawMessage() {
super(RAW);
pulses = new short[0];
data[1] = RAW.toByte();
data[2] = subType.toByte();
data[3] = seqNbr;
- data[4] = repeat;
+ data[4] = (byte) config.repeat;
ByteBuffer.wrap(data, 5, pulsesByteLen).asShortBuffer().put(pulses);
return "RAW";
}
+ @Override
+ public void setConfig(RFXComDeviceConfiguration config) throws RFXComException {
+ super.setConfig(config);
+ this.config = (RFXComRawDeviceConfiguration) config;
+ }
+
@Override
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
switch (channelId) {
ByteBuffer.wrap(payload).asShortBuffer().put(pulses);
return new StringType(HexUtils.bytesToHex(payload));
+ case CHANNEL_PULSES:
+ return new StringType(IntStream.range(0, pulses.length)
+ .mapToObj(s -> Integer.toString(Short.toUnsignedInt(pulses[s])))
+ .collect(Collectors.joining(" ")));
+
default:
throw new RFXComUnsupportedChannelException("Nothing relevant for " + channelId);
}
@Override
public void setSubType(SubType subType) {
- throw new UnsupportedOperationException();
+ this.subType = subType;
}
@Override
public void setDeviceId(String deviceId) {
- throw new UnsupportedOperationException();
+ // Nothing to do here
}
@Override
- public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
+ public void convertFromState(String channelId, Type type)
+ throws RFXComUnsupportedChannelException, RFXComInvalidStateException {
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");
+ case CHANNEL_RAW_PAYLOAD:
+ case CHANNEL_PULSES:
+ throw new RFXComUnsupportedChannelException("Cannot send on channel " + channelId);
+
+ case CHANNEL_COMMAND:
+ if (type instanceof OnOffType) {
+ if (type == OnOffType.ON) {
+ this.pulses = config.onPulsesArray;
+ } else {
+ this.pulses = config.offPulsesArray;
+ }
+ } else if (type instanceof OpenClosedType) {
+ if (type == OpenClosedType.OPEN) {
+ this.pulses = config.openPulsesArray;
+ } else {
+ this.pulses = config.closedPulsesArray;
+ }
} 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);
+ if (this.pulses == null) {
+ throw new RFXComInvalidStateException(channelId, null,
+ "No pulses provided in the device configuration for command" + type);
}
+ break;
+
default:
throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
}
<description>Hexadecimal representation of payload of raw and undecoded RFXCOM messages</description>
</channel-type>
+ <channel-type id="pulses">
+ <item-type>String</item-type>
+ <label>Pulses</label>
+ <description>Decimal representation of the pulse lengths for a raw message in usec.</description>
+ </channel-type>
+
<channel-type id="command">
<item-type>Switch</item-type>
<label>Command</label>
<channels>
<channel id="rawMessage" typeId="rawmessage"/>
<channel id="rawPayload" typeId="rawpayload"/>
+ <channel id="pulses" typeId="pulses"/>
+ <channel id="command" typeId="command"/>
</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>
+ <description>Received raw message cannot provide a device ID, so to receive raw messages the device id must be RAW.
+ For transmit-only things, use any device id.</description>
</parameter>
<parameter name="subType" type="text" required="true">
<label>Sub Type</label>
<option value="RAW_PACKET4">RAW_PACKET4</option>
</options>
</parameter>
+ <parameter name="repeat" type="integer" min="1" max="255">
+ <label>Repeat</label>
+ <description>Number of times to repeat. Defaults to 5.</description>
+ <default>5</default>
+ </parameter>
+ <parameter name="onPulses" type="text" required="false">
+ <label>On Pulses</label>
+ <description>Pulses to send for an ON command. Space delimited pulse lengths in usec. Must be an even number of
+ pulse lengths, with a maximum of 142 total pulses. Max pulse length is 65535. Pulses of value 0 will be transmitted
+ as 10000. See the RFXtfx user guide for more information.</description>
+ </parameter>
+ <parameter name="offPulses" type="text" required="false">
+ <label>Off Pulses</label>
+ <description>Pulses to send for an OFF command. Space delimited pulse lengths in usec. Must be an even number of
+ pulse lengths, with a maximum of 142 total pulses. Max pulse length is 65535. Pulses of value 0 will be transmitted
+ as 10000. See the RFXtfx user guide for more information.</description>
+ </parameter>
+ <parameter name="openPulses" type="text" required="false">
+ <label>Open Pulses</label>
+ <description>Pulses to send for an OPEN command. Space delimited pulse lengths in usec. Must be an even number of
+ pulse lengths, with a maximum of 142 total pulses. Max pulse length is 65535. Pulses of value 0 will be transmitted
+ as 10000. See the RFXtfx user guide for more information.</description>
+ </parameter>
+ <parameter name="closedPulses" type="text" required="false">
+ <label>Closed Pulses</label>
+ <description>Pulses to send for an CLOSED command. Space delimited pulse lengths in usec. Must be an even number of
+ pulse lengths, with a maximum of 142 total pulses. Max pulse length is 65535. Pulses of value 0 will be transmitted
+ as 10000. See the RFXtfx user guide for more information.</description>
+ </parameter>
</config-description>
</thing-type>
+++ /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.config;
-
-/**
- * Test helper for RFXCom-binding
- *
- * @author Martin van Wingerden - Initial contribution
- */
-public class RFXComDeviceConfigurationBuilder {
- private final RFXComDeviceConfiguration config;
-
- public RFXComDeviceConfigurationBuilder() {
- config = new RFXComDeviceConfiguration();
- }
-
- public RFXComDeviceConfigurationBuilder withDeviceId(String deviceId) {
- config.deviceId = deviceId;
- return this;
- }
-
- public RFXComDeviceConfigurationBuilder withSubType(String subType) {
- config.subType = subType;
- return this;
- }
-
- public RFXComDeviceConfigurationBuilder withPulse(Integer pulse) {
- config.pulse = pulse;
- return this;
- }
-
- public RFXComDeviceConfiguration build() {
- return config;
- }
-}
--- /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.config;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComInvalidParameterException;
+
+/**
+ * Configuration class for generic devices.
+ *
+ * @author James Hewitt-Thomas - Initial contribution
+ */
+@ExtendWith(MockitoExtension.class)
+public class RFXComGenericDeviceConfigurationTest {
+
+ private RFXComGenericDeviceConfiguration config;
+
+ @BeforeEach
+ public void before() {
+ config = new RFXComGenericDeviceConfiguration();
+ }
+
+ @Test
+ public void testNoDeviceId() {
+ config.subType = "PT2262";
+ assertThrows(RFXComInvalidParameterException.class, () -> config.parseAndValidate());
+ }
+
+ @Test
+ public void testNoSubType() {
+ config.deviceId = "90000";
+ assertThrows(RFXComInvalidParameterException.class, () -> config.parseAndValidate());
+ }
+
+ @Test
+ public void testValidConfig() {
+ config.deviceId = "90000";
+ config.subType = "PT2262";
+ assertDoesNotThrow(() -> config.parseAndValidate());
+ }
+}
--- /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.config;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+/**
+ * Configuration class for Lighting 4 devices.
+ *
+ * @author James Hewitt-Thomas - Initial contribution
+ */
+@ExtendWith(MockitoExtension.class)
+public class RFXComLighting4DeviceConfigurationTest {
+
+ private RFXComLighting4DeviceConfiguration config;
+
+ @BeforeEach
+ public void before() {
+ config = new RFXComLighting4DeviceConfiguration();
+ config.deviceId = "90000";
+ config.subType = "PT2262";
+ }
+
+ @Test
+ public void testConfig() {
+ assertDoesNotThrow(() -> config.parseAndValidate());
+ }
+}
--- /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.config;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComInvalidParameterException;
+
+/**
+ * Configuration class for Raw devices.
+ *
+ * @author James Hewitt-Thomas - Initial contribution
+ */
+@ExtendWith(MockitoExtension.class)
+public class RFXComRawDeviceConfigurationTest {
+
+ private RFXComRawDeviceConfiguration config;
+
+ @BeforeEach
+ public void before() {
+ config = new RFXComRawDeviceConfiguration();
+ config.deviceId = "RAW";
+ config.subType = "RAW_PACKET1";
+ }
+
+ @Test
+ public void testConfigWithoutPulses() {
+ assertDoesNotThrow(() -> config.parseAndValidate());
+ }
+
+ @Test
+ public void testConfigWithUnevenPulses() {
+ config.onPulses = "100 200 300";
+ assertThrows(RFXComInvalidParameterException.class, () -> config.parseAndValidate());
+ }
+
+ @Test
+ public void testConfigWithTooManyPulses() {
+ String pulses = IntStream.range(1, 126).mapToObj(Integer::toString).collect(Collectors.joining(" "));
+ config.offPulses = pulses;
+ assertThrows(RFXComInvalidParameterException.class, () -> config.parseAndValidate());
+ }
+
+ @Test
+ public void testConfigWithTooLargePulse() {
+ config.openPulses = "100000 200000";
+ assertThrows(RFXComInvalidParameterException.class, () -> config.parseAndValidate());
+ }
+
+ @Test
+ public void testConfigWithNaN() {
+ config.closedPulses = "abc def";
+ assertThrows(RFXComInvalidParameterException.class, () -> config.parseAndValidate());
+ }
+
+ @Test
+ public void testConfigWithValidPulses() {
+ config.onPulses = "100 200 300 400";
+ config.offPulses = "500 600 700 800";
+ assertDoesNotThrow(() -> config.parseAndValidate());
+ }
+}
--- /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.handler;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Map;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration;
+import org.openhab.binding.rfxcom.internal.config.RFXComGenericDeviceConfiguration;
+import org.openhab.binding.rfxcom.internal.config.RFXComRawDeviceConfiguration;
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
+import org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.PacketType;
+import org.openhab.binding.rfxcom.internal.messages.RFXComDeviceMessage;
+import org.openhab.binding.rfxcom.internal.messages.RFXComMessage;
+import org.openhab.binding.rfxcom.internal.messages.RFXComMessageFactory;
+import org.openhab.core.config.core.Configuration;
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.thing.Bridge;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusDetail;
+import org.openhab.core.thing.ThingStatusInfo;
+import org.openhab.core.thing.ThingTypeUID;
+import org.openhab.core.thing.ThingUID;
+import org.openhab.core.thing.binding.ThingHandlerCallback;
+import org.openhab.core.types.Command;
+
+/**
+ * The {@link RFXComRawHandler} is responsible for extra validation for Raw things.
+ *
+ * @author James Hewitt-Thomas - Initial contribution
+ */
+@ExtendWith(MockitoExtension.class)
+public class RFXComHandlerTest {
+
+ static ThingUID bridgeUID = new ThingUID("rfxcom", "tcpbridge", "rfxtrx0");
+ static ThingUID thingUID = new ThingUID("rfxcom", bridgeUID, "mocked");
+ static ThingTypeUID thingTypeUID = new ThingTypeUID("rfxcom", "raw");
+
+ @Mock
+ Bridge bridge;
+
+ @Mock
+ RFXComBridgeHandler bridgeHandler;
+
+ @Mock
+ Thing thing;
+
+ @Mock
+ ThingHandlerCallback callback;
+
+ @Mock
+ RFXComMessageFactory messageFactory;
+
+ @Mock
+ RFXComMessage message;
+
+ @Captor
+ ArgumentCaptor<ThingStatusInfo> thingStatusInfoCaptor;
+
+ @Captor
+ ArgumentCaptor<RFXComGenericDeviceConfiguration> deviceConfigurationCaptor;
+
+ @Captor
+ ArgumentCaptor<RFXComDeviceMessage> deviceMessageCaptor;
+
+ RFXComHandler handler;
+
+ private void initBridge() {
+ when(bridge.getHandler()).thenReturn(bridgeHandler);
+ when(thing.getBridgeUID()).thenReturn(bridgeUID);
+ when(callback.getBridge(bridgeUID)).thenReturn(bridge);
+ }
+
+ private void initOfflineBridge() {
+ initBridge();
+
+ when(bridge.getStatus()).thenReturn(ThingStatus.OFFLINE);
+ }
+
+ private void initOnlineBridge() {
+ initBridge();
+
+ when(bridge.getStatus()).thenReturn(ThingStatus.ONLINE);
+ }
+
+ private void verifyStatusUpdated(ThingStatus status, ThingStatusDetail thingStatusDetail) {
+ verify(callback).statusUpdated(eq(thing), thingStatusInfoCaptor.capture());
+ ThingStatusInfo tsi = thingStatusInfoCaptor.getValue();
+ assertEquals(status, tsi.getStatus());
+ assertEquals(thingStatusDetail, tsi.getStatusDetail());
+ }
+
+ private RFXComGenericDeviceConfiguration sendMessageToGetConfig(String channel, Command command)
+ throws RFXComException {
+ when(messageFactory.createMessage(any(PacketType.class))).thenReturn(message);
+ ChannelUID cuid = new ChannelUID(thing.getUID(), channel);
+ handler.handleCommand(cuid, command);
+ verify(message).setConfig(deviceConfigurationCaptor.capture());
+ return deviceConfigurationCaptor.getValue();
+ }
+
+ @BeforeEach
+ public void before() {
+ when(thing.getUID()).thenReturn(thingUID);
+ when(thing.getThingTypeUID()).thenReturn(thingTypeUID);
+
+ handler = new RFXComHandler(thing, messageFactory);
+ handler.setCallback(callback);
+ }
+
+ @Test
+ public void testValidConfig() {
+ initOnlineBridge();
+ when(thing.getConfiguration()).thenReturn(new Configuration(Map.of("deviceId", "1088338.11", "subType", "AC")));
+
+ handler.initialize();
+ verifyStatusUpdated(ThingStatus.ONLINE, ThingStatusDetail.NONE);
+ }
+
+ @Test
+ public void testInvalidConfig() {
+ initOnlineBridge();
+ when(thing.getConfiguration()).thenReturn(new Configuration(Map.of()));
+
+ handler.initialize();
+ verifyStatusUpdated(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR);
+ }
+
+ @Test
+ public void testOfflineBridge() {
+ initOfflineBridge();
+ when(thing.getConfiguration()).thenReturn(new Configuration(Map.of("deviceId", "1088338.11", "subType", "AC")));
+
+ handler.initialize();
+ verifyStatusUpdated(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
+ }
+
+ @Test
+ public void testUnititialisedBridge() {
+ initBridge();
+ when(thing.getConfiguration())
+ .thenReturn(new Configuration(Map.of("deviceId", "RAW", "subType", "RAW_PACKET1")));
+
+ handler.initialize();
+ verifyStatusUpdated(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED);
+ }
+
+ @Test
+ public void testWithoutBridge() {
+ when(thing.getConfiguration()).thenReturn(new Configuration(Map.of("deviceId", "1088338.11", "subType", "AC")));
+
+ handler.initialize();
+ verifyStatusUpdated(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED);
+ }
+
+ @Test
+ public void testConfigType() throws RFXComException {
+ initOnlineBridge();
+ when(thing.getConfiguration()).thenReturn(
+ new Configuration(Map.of("deviceId", "RAW", "subType", "RAW_PACKET1", "onPulses", "1 2 3 4")));
+
+ handler.initialize();
+ verifyStatusUpdated(ThingStatus.ONLINE, ThingStatusDetail.NONE);
+ RFXComDeviceConfiguration config = sendMessageToGetConfig("command", OnOffType.ON);
+ assertEquals(RFXComRawDeviceConfiguration.class, config.getClass());
+ }
+}
public void testSomeMessages() throws RFXComException {
String hexMessage = "0A4E012B2955001A002179";
byte[] message = HexUtils.hexToBytes(hexMessage);
- RFXComBBQTemperatureMessage msg = (RFXComBBQTemperatureMessage) RFXComMessageFactory.createMessage(message);
+ RFXComBBQTemperatureMessage msg = (RFXComBBQTemperatureMessage) RFXComMessageFactoryImpl.INSTANCE
+ .createMessage(message);
assertEquals(BBQ1, msg.subType, "SubType");
assertEquals(43, msg.seqNbr, "Seq Number");
assertEquals("10581", msg.getDeviceId(), "Sensor Id");
@Test
public void checkNotImplemented() {
assertThrows(RFXComMessageNotImplementedException.class,
- () -> RFXComMessageFactory.createMessage(PacketType.BAROMETRIC));
+ () -> RFXComMessageFactoryImpl.INSTANCE.createMessage(PacketType.BAROMETRIC));
}
}
public class RFXComBlinds1MessageTest {
private void testMessage(String hexMsg, SubType subType, int seqNbr, String deviceId, int signalLevel,
RFXComBlinds1Message.Commands command) throws RFXComException {
- final RFXComBlinds1Message msg = (RFXComBlinds1Message) RFXComMessageFactory
+ final RFXComBlinds1Message msg = (RFXComBlinds1Message) RFXComMessageFactoryImpl.INSTANCE
.createMessage(HexUtils.hexToBytes(hexMsg));
assertEquals(subType, msg.subType, "SubType");
assertEquals(seqNbr, (short) (msg.seqNbr & 0xFF), "Seq Number");
@Test
public void checkNotImplemented() {
assertThrows(RFXComMessageNotImplementedException.class,
- () -> RFXComMessageFactory.createMessage(PacketType.CAMERA1));
+ () -> RFXComMessageFactoryImpl.INSTANCE.createMessage(PacketType.CAMERA1));
}
}
public void testSomeMessages() throws RFXComException {
String hexMessage = "0716020900A1F350";
byte[] message = HexUtils.hexToBytes(hexMessage);
- RFXComChimeMessage msg = (RFXComChimeMessage) RFXComMessageFactory.createMessage(message);
+ RFXComChimeMessage msg = (RFXComChimeMessage) RFXComMessageFactoryImpl.INSTANCE.createMessage(message);
assertEquals(SubType.SELECTPLUS, msg.subType, "SubType");
assertEquals(9, msg.seqNbr, "Seq Number");
assertEquals("41459", msg.getDeviceId(), "Sensor Id");
private void testMessage(String hexMsg, RFXComCurrentEnergyMessage.SubType subType, int seqNbr, String deviceId,
int count, double channel1, double channel2, double channel3, double totalUsage, int signalLevel,
int batteryLevel) throws RFXComException {
- final RFXComCurrentEnergyMessage msg = (RFXComCurrentEnergyMessage) RFXComMessageFactory
+ final RFXComCurrentEnergyMessage msg = (RFXComCurrentEnergyMessage) RFXComMessageFactoryImpl.INSTANCE
.createMessage(HexUtils.hexToBytes(hexMsg));
assertEquals(subType, msg.subType, "SubType");
assertEquals(seqNbr, (short) (msg.seqNbr & 0xFF), "Seq Number");
public void testSomeMessages() throws RFXComException {
String message = "0D59010F860004001D0000000049";
- final RFXComCurrentMessage msg = (RFXComCurrentMessage) RFXComMessageFactory
+ final RFXComCurrentMessage msg = (RFXComCurrentMessage) RFXComMessageFactoryImpl.INSTANCE
.createMessage(HexUtils.hexToBytes(message));
assertEquals(SubType.ELEC1, msg.subType, "SubType");
assertEquals(15, (short) (msg.seqNbr & 0xFF), "Seq Number");
public class RFXComCurtain1MessageTest {
@Test
public void checkForSupportTest() throws RFXComException {
- RFXComMessageFactory.createMessage(CURTAIN1);
+ RFXComMessageFactoryImpl.INSTANCE.createMessage(CURTAIN1);
}
@Test
public void basicBoundaryCheck() throws RFXComException {
- RFXComCurtain1Message message = (RFXComCurtain1Message) RFXComMessageFactory.createMessage(CURTAIN1);
+ RFXComCurtain1Message message = (RFXComCurtain1Message) RFXComMessageFactoryImpl.INSTANCE
+ .createMessage(CURTAIN1);
message.subType = RFXComCurtain1Message.SubType.HARRISON;
message.command = RFXComCurtain1Message.Commands.OPEN;
public void testSomeMessages() throws RFXComException {
String hexMessage = "0D580117B90003041D030D150A69";
byte[] message = HexUtils.hexToBytes(hexMessage);
- RFXComDateTimeMessage msg = (RFXComDateTimeMessage) RFXComMessageFactory.createMessage(message);
+ RFXComDateTimeMessage msg = (RFXComDateTimeMessage) RFXComMessageFactoryImpl.INSTANCE.createMessage(message);
assertEquals(RFXComDateTimeMessage.SubType.RTGR328N, msg.subType, "SubType");
assertEquals(23, (short) (msg.seqNbr & 0xFF), "Seq Number");
assertEquals("47360", msg.getDeviceId(), "Sensor Id");
public class RFXComEdisioTest {
@Test
public void checkNotImplemented() {
- assertThrows(RFXComMessageNotImplementedException.class, () -> RFXComMessageFactory.createMessage(EDISIO));
+ assertThrows(RFXComMessageNotImplementedException.class,
+ () -> RFXComMessageFactoryImpl.INSTANCE.createMessage(EDISIO));
}
}
public void testSomeMessages() throws RFXComException {
String hexMessage = "115A01071A7300000003F600000000350B89";
byte[] message = HexUtils.hexToBytes(hexMessage);
- RFXComEnergyMessage msg = (RFXComEnergyMessage) RFXComMessageFactory.createMessage(message);
+ RFXComEnergyMessage msg = (RFXComEnergyMessage) RFXComMessageFactoryImpl.INSTANCE.createMessage(message);
assertEquals(ELEC2, msg.subType, "SubType");
assertEquals(7, msg.seqNbr, "Seq Number");
assertEquals("6771", msg.getDeviceId(), "Sensor Id");
@Test
public void checkNotImplemented() {
assertThrows(RFXComMessageNotImplementedException.class,
- () -> RFXComMessageFactory.createMessage(PacketType.FS20));
+ () -> RFXComMessageFactoryImpl.INSTANCE.createMessage(PacketType.FS20));
}
}
@Test
public void checkForSupportTest() throws RFXComException {
- RFXComMessageFactory.createMessage(FAN);
+ RFXComMessageFactoryImpl.INSTANCE.createMessage(FAN);
}
@Test
public void basicBoundaryCheck() throws RFXComException {
- RFXComFanMessage message = (RFXComFanMessage) RFXComMessageFactory.createMessage(FAN);
+ RFXComFanMessage message = (RFXComFanMessage) RFXComMessageFactoryImpl.INSTANCE.createMessage(FAN);
message.setSubType(RFXComFanMessage.SubType.CASAFAN);
message.convertFromState(CHANNEL_FAN_SPEED, StringType.valueOf("OFF"));
private void testMessage(String hexMsg, int seqNbr, String deviceId, int signalLevel,
@Nullable State expectedCommand, State expectedLightCommand, @Nullable State expectedFanSpeed,
RFXComBaseMessage.PacketType packetType) throws RFXComException {
- final RFXComFanMessage msg = (RFXComFanMessage) RFXComMessageFactory.createMessage(HexUtils.hexToBytes(hexMsg));
+ final RFXComFanMessage msg = (RFXComFanMessage) RFXComMessageFactoryImpl.INSTANCE
+ .createMessage(HexUtils.hexToBytes(hexMsg));
assertEquals(seqNbr, (short) (msg.seqNbr & 0xFF), "Seq Number");
assertEquals(deviceId, msg.getDeviceId(), "Sensor Id");
assertEquals(signalLevel, msg.signalLevel, "Signal Level");
@Test
public void checkNotImplemented() {
assertThrows(RFXComMessageNotImplementedException.class,
- () -> RFXComMessageFactory.createMessage(PacketType.GAS));
+ () -> RFXComMessageFactoryImpl.INSTANCE.createMessage(PacketType.GAS));
}
}
*/
package org.openhab.binding.rfxcom.internal.messages;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.PacketType.HOME_CONFORT;
import org.eclipse.jdt.annotation.NonNullByDefault;
@NonNullByDefault
public class RFXComHomeConfortTest {
private void testMessage(SubType subType, Commands command, String deviceId, String data) throws RFXComException {
- RFXComHomeConfortMessage message = (RFXComHomeConfortMessage) RFXComMessageFactory.createMessage(HOME_CONFORT);
+ RFXComHomeConfortMessage message = (RFXComHomeConfortMessage) RFXComMessageFactoryImpl.INSTANCE
+ .createMessage(HOME_CONFORT);
message.setSubType(subType);
message.command = command;
message.setDeviceId(deviceId);
public void testSomeMessages() throws RFXComException {
String hexMessage = "085101027700360189";
byte[] message = HexUtils.hexToBytes(hexMessage);
- RFXComHumidityMessage msg = (RFXComHumidityMessage) RFXComMessageFactory.createMessage(message);
+ RFXComHumidityMessage msg = (RFXComHumidityMessage) RFXComMessageFactoryImpl.INSTANCE.createMessage(message);
assertEquals(RFXComHumidityMessage.SubType.HUM1, msg.subType, "SubType");
assertEquals(2, (short) (msg.seqNbr & 0xFF), "Seq Number");
assertEquals("30464", msg.getDeviceId(), "Sensor Id");
@Test
public void checkNotImplemented() {
assertThrows(RFXComMessageNotImplementedException.class,
- () -> RFXComMessageFactory.createMessage(PacketType.IO_LINES));
+ () -> RFXComMessageFactoryImpl.INSTANCE.createMessage(PacketType.IO_LINES));
}
}
public class RFXComInterfaceMessageTest {
private RFXComInterfaceMessage testMessage(String hexMsg, SubType subType, int seqNbr, Commands command)
throws RFXComException {
- RFXComInterfaceMessage msg = (RFXComInterfaceMessage) RFXComMessageFactory
+ RFXComInterfaceMessage msg = (RFXComInterfaceMessage) RFXComMessageFactoryImpl.INSTANCE
.createMessage(HexUtils.hexToBytes(hexMsg));
assertEquals(subType, msg.subType, "SubType");
assertEquals(seqNbr, (short) (msg.seqNbr & 0xFF), "Seq Number");
@Test
public void testMessage() {
byte[] message = HexUtils.hexToBytes("07CC01271356ECC0");
- assertThrows(RFXComUnsupportedValueException.class, () -> RFXComMessageFactory.createMessage(message));
+ assertThrows(RFXComUnsupportedValueException.class,
+ () -> RFXComMessageFactoryImpl.INSTANCE.createMessage(message));
}
}
private void testMessage(String hexMsg, RFXComLighting1Message.SubType subType, int seqNbr, String deviceId,
byte signalLevel, Commands command, String commandString) throws RFXComException {
- final RFXComLighting1Message msg = (RFXComLighting1Message) RFXComMessageFactory
+ final RFXComLighting1Message msg = (RFXComLighting1Message) RFXComMessageFactoryImpl.INSTANCE
.createMessage(HexUtils.hexToBytes(hexMsg));
assertEquals(subType, msg.subType, "SubType");
assertEquals(seqNbr, (short) (msg.seqNbr & 0xFF), "Seq Number");
public void testSomeMessages() throws RFXComException {
String hexMessage = "0B11000600109B520B000080";
byte[] message = HexUtils.hexToBytes(hexMessage);
- RFXComLighting2Message msg = (RFXComLighting2Message) RFXComMessageFactory.createMessage(message);
+ RFXComLighting2Message msg = (RFXComLighting2Message) RFXComMessageFactoryImpl.INSTANCE.createMessage(message);
assertEquals(RFXComLighting2Message.SubType.AC, msg.subType, "SubType");
assertEquals(6, (short) (msg.seqNbr & 0xFF), "Seq Number");
assertEquals("1088338.11", msg.getDeviceId(), "Sensor Id");
public void checkNotImplemented() {
// TODO Note that this message is supported in the 1.9 binding
assertThrows(RFXComMessageNotImplementedException.class,
- () -> RFXComMessageFactory.createMessage(PacketType.LIGHTING3));
+ () -> RFXComMessageFactoryImpl.INSTANCE.createMessage(PacketType.LIGHTING3));
}
}
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.junit.jupiter.api.Test;
-import org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration;
-import org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfigurationBuilder;
+import org.openhab.binding.rfxcom.internal.config.RFXComLighting4DeviceConfiguration;
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.util.HexUtils;
public class RFXComLighting4MessageTest {
@Test
public void basicBoundaryCheck() throws RFXComException {
- RFXComLighting4Message message = (RFXComLighting4Message) RFXComMessageFactory.createMessage(LIGHTING4);
-
- RFXComDeviceConfiguration build = new RFXComDeviceConfigurationBuilder().withDeviceId("90000").withPulse(300)
- .withSubType("PT2262").build();
- message.setConfig(build);
+ RFXComLighting4Message message = (RFXComLighting4Message) RFXComMessageFactoryImpl.INSTANCE
+ .createMessage(LIGHTING4);
+
+ RFXComLighting4DeviceConfiguration config = new RFXComLighting4DeviceConfiguration();
+ config.deviceId = "90000";
+ config.subType = "PT2262";
+ config.pulse = 300;
+ message.setConfig(config);
message.convertFromState(CHANNEL_COMMAND, OnOffType.ON);
byte[] binaryMessage = message.decodeMessage();
- RFXComLighting4Message msg = (RFXComLighting4Message) RFXComMessageFactory.createMessage(binaryMessage);
+ RFXComLighting4Message msg = (RFXComLighting4Message) RFXComMessageFactoryImpl.INSTANCE
+ .createMessage(binaryMessage);
assertEquals("90000", msg.getDeviceId(), "Sensor Id");
}
private void testMessage(String hexMsg, RFXComLighting4Message.SubType subType, String deviceId,
@Nullable Integer pulse, byte commandByte, @Nullable Integer seqNbr, int signalLevel, int offCommand,
int onCommand) throws RFXComException {
- RFXComLighting4Message msg = (RFXComLighting4Message) RFXComMessageFactory
+ RFXComLighting4Message msg = (RFXComLighting4Message) RFXComMessageFactoryImpl.INSTANCE
.createMessage(HexUtils.hexToBytes(hexMsg));
assertEquals(deviceId, msg.getDeviceId(), "Sensor Id");
assertEquals(commandByte, RFXComTestHelper.getActualIntValue(msg, CHANNEL_COMMAND_ID), "Command");
@Test
public void convertFromStateItMessage() throws RFXComException {
- RFXComDeviceMessage itMessageObject = (RFXComDeviceMessage) RFXComMessageFactory.createMessage(LIGHTING5);
+ RFXComDeviceMessage itMessageObject = (RFXComDeviceMessage) RFXComMessageFactoryImpl.INSTANCE
+ .createMessage(LIGHTING5);
itMessageObject.setDeviceId("2061.1");
itMessageObject.setSubType(IT);
itMessageObject.convertFromState(CHANNEL_COMMAND, OnOffType.ON);
byte[] message = itMessageObject.decodeMessage();
String hexMessage = HexUtils.bytesToHex(message);
assertEquals("0A140F0000080D01010000", hexMessage, "Message is not as expected");
- RFXComLighting5Message msg = (RFXComLighting5Message) RFXComMessageFactory.createMessage(message);
+ RFXComLighting5Message msg = (RFXComLighting5Message) RFXComMessageFactoryImpl.INSTANCE.createMessage(message);
assertEquals(IT, msg.subType, "SubType");
assertEquals("2061.1", msg.getDeviceId(), "Sensor Id");
assertEquals(ON, msg.command, "Command");
@Test
public void basicBoundaryCheck() throws RFXComException {
- RFXComLighting5Message message = (RFXComLighting5Message) RFXComMessageFactory.createMessage(LIGHTING5);
+ RFXComLighting5Message message = (RFXComLighting5Message) RFXComMessageFactoryImpl.INSTANCE
+ .createMessage(LIGHTING5);
message.subType = RFXComLighting5Message.SubType.LIGHTWAVERF;
message.command = ON;
public void testSomeMessages() throws RFXComException {
String hexMessage = "0B150005D950450101011D80";
byte[] message = HexUtils.hexToBytes(hexMessage);
- RFXComLighting6Message msg = (RFXComLighting6Message) RFXComMessageFactory.createMessage(message);
+ RFXComLighting6Message msg = (RFXComLighting6Message) RFXComMessageFactoryImpl.INSTANCE.createMessage(message);
assertEquals(RFXComLighting6Message.SubType.BLYSS, msg.subType, "SubType");
assertEquals(5, (short) (msg.seqNbr & 0xFF), "Seq Number");
assertEquals("55632.E.1", msg.getDeviceId(), "Sensor Id");
public void checkNotImplemented() {
// TODO Note that this message is supported in the 1.9 binding
assertThrows(RFXComMessageNotImplementedException.class,
- () -> RFXComMessageFactory.createMessage(RFXComBaseMessage.PacketType.POWER));
+ () -> RFXComMessageFactoryImpl.INSTANCE.createMessage(RFXComBaseMessage.PacketType.POWER));
}
}
@Test
public void checkNotImplemented() {
assertThrows(RFXComMessageNotImplementedException.class,
- () -> RFXComMessageFactory.createMessage(PacketType.RFXMETER));
+ () -> RFXComMessageFactoryImpl.INSTANCE.createMessage(PacketType.RFXMETER));
}
}
@Nullable Double temperature, @Nullable Double voltage, @Nullable Double referenceVoltage,
@Nullable Double expectedPressure, @Nullable Double expectedHumidity, int signalLevel,
DeviceState deviceState) throws RFXComException {
- final RFXComRFXSensorMessage msg = (RFXComRFXSensorMessage) RFXComMessageFactory
+ final RFXComRFXSensorMessage msg = (RFXComRFXSensorMessage) RFXComMessageFactoryImpl.INSTANCE
.createMessage(DatatypeConverter.parseHexBinary(hexMsg));
assertEquals(subType, msg.subType, "SubType");
assertEquals(seqNbr, (short) (msg.seqNbr & 0xFF), "Seq Number");
public class RFXComRadiator1MessageTest {
@Test
public void checkNotImplemented() {
- assertThrows(RFXComMessageNotImplementedException.class, () -> RFXComMessageFactory.createMessage(RADIATOR1));
+ assertThrows(RFXComMessageNotImplementedException.class,
+ () -> RFXComMessageFactoryImpl.INSTANCE.createMessage(RADIATOR1));
}
}
public void testSomeMessages() throws RFXComException {
String hexMessage = "0B550217B6000000004D3C69";
byte[] message = HexUtils.hexToBytes(hexMessage);
- RFXComRainMessage msg = (RFXComRainMessage) RFXComMessageFactory.createMessage(message);
+ RFXComRainMessage msg = (RFXComRainMessage) RFXComMessageFactoryImpl.INSTANCE.createMessage(message);
assertEquals(RAIN2, msg.subType, "SubType");
assertEquals(23, msg.seqNbr, "Seq Number");
assertEquals("46592", msg.getDeviceId(), "Sensor Id");
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test;
+import org.openhab.binding.rfxcom.internal.RFXComBindingConstants;
+import org.openhab.binding.rfxcom.internal.config.RFXComRawDeviceConfiguration;
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
-import org.openhab.binding.rfxcom.internal.exceptions.RFXComMessageTooLongException;
+import org.openhab.binding.rfxcom.internal.exceptions.RFXComInvalidStateException;
import org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.PacketType;
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.types.Type;
import org.openhab.core.util.HexUtils;
/**
@NonNullByDefault
public class RFXComRawMessageTest {
- private void testMessage(String hexMsg, RFXComRawMessage.SubType subType, int seqNbr, int repeat, String pulses)
+ private void testMessageRx(String hexMsg, RFXComRawMessage.SubType subType, int seqNbr, int repeat, String pulses)
throws RFXComException {
- final RFXComRawMessage msg = (RFXComRawMessage) RFXComMessageFactory.createMessage(HexUtils.hexToBytes(hexMsg));
+ final RFXComRawMessage msg = (RFXComRawMessage) RFXComMessageFactoryImpl.INSTANCE
+ .createMessage(HexUtils.hexToBytes(hexMsg));
assertEquals(subType, msg.subType, "SubType");
assertEquals(seqNbr, (short) (msg.seqNbr & 0xFF), "Seq Number");
assertEquals("RAW", msg.getDeviceId(), "Device Id");
byte[] payload = new byte[msg.pulses.length * 2];
ByteBuffer.wrap(payload).asShortBuffer().put(msg.pulses);
assertEquals(pulses, HexUtils.bytesToHex(payload), "Pulses");
+ }
+
+ @Test
+ public void testSomeRxMessages() throws RFXComException {
+ testMessageRx("087F0027051356ECC0", RFXComRawMessage.SubType.RAW_PACKET1, 0x27, 5, "1356ECC0");
+ }
+ private void testMessageTx(RFXComRawDeviceConfiguration config, Type command, String hexMsg)
+ throws RFXComException {
+ RFXComRawMessage msg = (RFXComRawMessage) RFXComMessageFactoryImpl.INSTANCE.createMessage(PacketType.RAW);
+ msg.setConfig(config);
+ msg.convertFromState(RFXComBindingConstants.CHANNEL_COMMAND, command);
byte[] decoded = msg.decodeMessage();
- assertEquals(hexMsg, HexUtils.bytesToHex(decoded), "Message converted back");
+ assertEquals(hexMsg, HexUtils.bytesToHex(decoded), "Transmitted message");
}
@Test
- public void testSomeMessages() throws RFXComException {
- testMessage("087F0027051356ECC0", RFXComRawMessage.SubType.RAW_PACKET1, 0x27, 5, "1356ECC0");
+ public void testTxBasicPulses() throws RFXComException {
+ RFXComRawDeviceConfiguration config = new RFXComRawDeviceConfiguration();
+ config.deviceId = "RAW";
+ config.subType = "RAW_PACKET1";
+ config.repeat = 5;
+ config.onPulsesArray = new short[] { 0x10, 0x20, 0x30, 0x40 };
+
+ testMessageTx(config, OnOffType.ON, "0C7F0000050010002000300040");
}
@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];
+ public void testTxMissingPulses() throws RFXComException {
+ RFXComRawDeviceConfiguration config = new RFXComRawDeviceConfiguration();
+ config.deviceId = "RAW";
+ config.subType = "RAW_PACKET1";
+ config.repeat = 5;
+ config.onPulsesArray = new short[] { 0x10, 0x20, 0x30, 0x40 };
- assertThrows(RFXComMessageTooLongException.class, () -> msg.decodeMessage());
+ assertThrows(RFXComInvalidStateException.class,
+ () -> testMessageTx(config, OnOffType.OFF, "0C7F0000050010002000300040"));
}
}
@Test
public void checkNotImplemented() {
assertThrows(RFXComMessageNotImplementedException.class,
- () -> RFXComMessageFactory.createMessage(PacketType.REMOTE_CONTROL));
+ () -> RFXComMessageFactoryImpl.INSTANCE.createMessage(PacketType.REMOTE_CONTROL));
}
}
*/
package org.openhab.binding.rfxcom.internal.messages;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.PacketType.RFY;
import org.eclipse.jdt.annotation.NonNullByDefault;
@Test
public void basicBoundaryCheck() throws RFXComException {
- RFXComRfyMessage message = (RFXComRfyMessage) RFXComMessageFactory.createMessage(RFY);
+ RFXComRfyMessage message = (RFXComRfyMessage) RFXComMessageFactoryImpl.INSTANCE.createMessage(RFY);
message.subType = SubType.RFY;
message.command = Commands.UP;
}
private void testMessage(SubType subType, Commands command, String deviceId, String data) throws RFXComException {
- RFXComRfyMessage message = (RFXComRfyMessage) RFXComMessageFactory.createMessage(RFY);
+ RFXComRfyMessage message = (RFXComRfyMessage) RFXComMessageFactoryImpl.INSTANCE.createMessage(RFY);
message.setSubType(subType);
message.command = command;
message.setDeviceId(deviceId);
@Nullable String deviceId, int batteryLevel, @Nullable Contact contact, @Nullable Motion motion,
@Nullable Status status, int signalLevel) throws RFXComException {
byte[] message = HexUtils.hexToBytes(hexMessage);
- RFXComSecurity1Message msg = (RFXComSecurity1Message) RFXComMessageFactory.createMessage(message);
+ RFXComSecurity1Message msg = (RFXComSecurity1Message) RFXComMessageFactoryImpl.INSTANCE.createMessage(message);
assertEquals(subType, msg.subType, "SubType");
assertEquals(sequenceNumber, (short) (msg.seqNbr & 0xFF), "Seq Number");
assertEquals(deviceId, msg.getDeviceId(), "Sensor Id");
String hexMessage = "1C21020000000000131211C30000000000000000000000000000000045";
byte[] message = HexUtils.hexToBytes(hexMessage);
- RFXComSecurity2Message msg = (RFXComSecurity2Message) RFXComMessageFactory.createMessage(message);
+ RFXComSecurity2Message msg = (RFXComSecurity2Message) RFXComMessageFactoryImpl.INSTANCE.createMessage(message);
assertEquals(SubType.RAW_AES_KEELOQ, msg.subType, "SubType");
assertEquals(0, msg.seqNbr, "Seq Number");
assertEquals("51450387", msg.getDeviceId(), "Sensor Id");
public void testSomeMessages() throws RFXComException {
String hexMessage = "0D54020EE90000C9270203E70439";
byte[] message = HexUtils.hexToBytes(hexMessage);
- RFXComTemperatureHumidityBarometricMessage msg = (RFXComTemperatureHumidityBarometricMessage) RFXComMessageFactory
+ RFXComTemperatureHumidityBarometricMessage msg = (RFXComTemperatureHumidityBarometricMessage) RFXComMessageFactoryImpl.INSTANCE
.createMessage(message);
assertEquals(THB2, msg.subType, "SubType");
assertEquals(14, msg.seqNbr, "Seq Number");
double temperature, int humidity, HumidityStatus humidityStatus, int signalLevel, int batteryLevel)
throws RFXComException {
byte[] binaryMessage = HexUtils.hexToBytes(hexMsg);
- final RFXComTemperatureHumidityMessage msg = (RFXComTemperatureHumidityMessage) RFXComMessageFactory
+ final RFXComTemperatureHumidityMessage msg = (RFXComTemperatureHumidityMessage) RFXComMessageFactoryImpl.INSTANCE
.createMessage(binaryMessage);
assertEquals(subType, msg.subType, "SubType");
assertEquals(seqNbr, (short) (msg.seqNbr & 0xFF), "Seq Number");
public class RFXComTemperatureMessageTest {
private void testMessage(String hexMsg, RFXComTemperatureMessage.SubType subType, int seqNbr, String deviceId,
double temperature, int signalLevel, int bateryLevel) throws RFXComException {
- final RFXComTemperatureMessage msg = (RFXComTemperatureMessage) RFXComMessageFactory
+ final RFXComTemperatureMessage msg = (RFXComTemperatureMessage) RFXComMessageFactoryImpl.INSTANCE
.createMessage(HexUtils.hexToBytes(hexMsg));
assertEquals(subType, msg.subType, "SubType");
assertEquals(seqNbr, (short) (msg.seqNbr & 0xFF), "Seq Number");
public void testSomeMessages() throws RFXComException {
String hexMessage = "0A4F01CCF001004F03B759";
byte[] message = HexUtils.hexToBytes(hexMessage);
- RFXComTemperatureRainMessage msg = (RFXComTemperatureRainMessage) RFXComMessageFactory.createMessage(message);
+ RFXComTemperatureRainMessage msg = (RFXComTemperatureRainMessage) RFXComMessageFactoryImpl.INSTANCE
+ .createMessage(message);
assertEquals(WS1200, msg.subType, "SubType");
assertEquals(204, (short) (msg.seqNbr & 0xFF), "Seq Number");
assertEquals("61441", msg.getDeviceId(), "Sensor Id");
public void testSomeMessages() throws RFXComException {
String hexMessage = "0940001B6B1816150270";
byte[] message = HexUtils.hexToBytes(hexMessage);
- RFXComThermostat1Message msg = (RFXComThermostat1Message) RFXComMessageFactory.createMessage(message);
+ RFXComThermostat1Message msg = (RFXComThermostat1Message) RFXComMessageFactoryImpl.INSTANCE
+ .createMessage(message);
assertEquals(RFXComThermostat1Message.SubType.DIGIMAX, msg.subType, "SubType");
assertEquals(27, (short) (msg.seqNbr & 0xFF), "Seq Number");
assertEquals("27416", msg.getDeviceId(), "Sensor Id");
public void checkNotImplemented() {
// TODO Note that this message is supported in the 1.9 binding
assertThrows(RFXComMessageNotImplementedException.class,
- () -> RFXComMessageFactory.createMessage(PacketType.THERMOSTAT2));
+ () -> RFXComMessageFactoryImpl.INSTANCE.createMessage(PacketType.THERMOSTAT2));
}
}
@Test
public void checkForSupportTest() throws RFXComException {
- RFXComMessageFactory.createMessage(THERMOSTAT3);
+ RFXComMessageFactoryImpl.INSTANCE.createMessage(THERMOSTAT3);
}
@Test
public void basicBoundaryCheck() throws RFXComException {
- RFXComThermostat3Message message = (RFXComThermostat3Message) RFXComMessageFactory.createMessage(THERMOSTAT3);
+ RFXComThermostat3Message message = (RFXComThermostat3Message) RFXComMessageFactoryImpl.INSTANCE
+ .createMessage(THERMOSTAT3);
message.subType = RFXComThermostat3Message.SubType.MERTIK__G6R_H4S_TRANSMIT_ONLY;
message.command = RFXComThermostat3Message.Commands.ON;
@Nullable State secondCommandChannel, State controlChannel, State commandStringChannel)
throws RFXComException {
byte[] message = HexUtils.hexToBytes(hexMessage);
- RFXComThermostat3Message msg = (RFXComThermostat3Message) RFXComMessageFactory.createMessage(message);
+ RFXComThermostat3Message msg = (RFXComThermostat3Message) RFXComMessageFactoryImpl.INSTANCE
+ .createMessage(message);
assertEquals(subtype, msg.subType, "SubType");
assertEquals(sequenceNumber, (short) (msg.seqNbr & 0xFF), "Seq Number");
assertEquals(sensorId, msg.getDeviceId(), "Sensor Id");
public class RFXComThermostat4MessageTest {
@Test
public void checkNotImplemented() {
- assertThrows(RFXComMessageNotImplementedException.class, () -> RFXComMessageFactory.createMessage(THERMOSTAT4));
+ assertThrows(RFXComMessageNotImplementedException.class,
+ () -> RFXComMessageFactoryImpl.INSTANCE.createMessage(THERMOSTAT4));
}
}
@NonNullByDefault
public class RFXComTransmitterMessageTest {
private void testMessage(String hexMsg, Response response, SubType subType, int seqNbr) throws RFXComException {
- final RFXComTransmitterMessage msg = (RFXComTransmitterMessage) RFXComMessageFactory
+ final RFXComTransmitterMessage msg = (RFXComTransmitterMessage) RFXComMessageFactoryImpl.INSTANCE
.createMessage(HexUtils.hexToBytes(hexMsg));
assertEquals(subType, msg.subType, "SubType");
assertEquals(response, msg.response, "Response");
String hexMessage = "095703123421194731E9";
byte[] message = HexUtils.hexToBytes(hexMessage);
- RFXComUVMessage msg = (RFXComUVMessage) RFXComMessageFactory.createMessage(message);
+ RFXComUVMessage msg = (RFXComUVMessage) RFXComMessageFactoryImpl.INSTANCE.createMessage(message);
assertEquals(RFXComUVMessage.SubType.UV3, msg.subType, "SubType");
assertEquals(18, msg.seqNbr, "Seq Number");
String hexMessage = "09570312342119C731E9";
byte[] message = HexUtils.hexToBytes(hexMessage);
- RFXComUVMessage msg = (RFXComUVMessage) RFXComMessageFactory.createMessage(message);
+ RFXComUVMessage msg = (RFXComUVMessage) RFXComMessageFactoryImpl.INSTANCE.createMessage(message);
assertEquals(RFXComUVMessage.SubType.UV3, msg.subType, "SubType");
assertEquals(18, msg.seqNbr, "Seq Number");
private void testMessage(String hexMsg, RFXComUndecodedRFMessage.SubType subType, int seqNbr, String rawPayload)
throws RFXComException {
- final RFXComUndecodedRFMessage msg = (RFXComUndecodedRFMessage) RFXComMessageFactory
+ final RFXComUndecodedRFMessage msg = (RFXComUndecodedRFMessage) RFXComMessageFactoryImpl.INSTANCE
.createMessage(HexUtils.hexToBytes(hexMsg));
assertEquals(subType, msg.subType, "SubType");
assertEquals(seqNbr, (short) (msg.seqNbr & 0xFF), "Seq Number");
@Test
public void testLongMessage() throws RFXComException {
- RFXComUndecodedRFMessage msg = (RFXComUndecodedRFMessage) RFXComMessageFactory
+ RFXComUndecodedRFMessage msg = (RFXComUndecodedRFMessage) RFXComMessageFactoryImpl.INSTANCE
.createMessage(PacketType.UNDECODED_RF_MESSAGE);
msg.subType = RFXComUndecodedRFMessage.SubType.ARC;
msg.seqNbr = 1;
@Test
public void checkNotImplemented() {
assertThrows(RFXComMessageNotImplementedException.class,
- () -> RFXComMessageFactory.createMessage(PacketType.WATER));
+ () -> RFXComMessageFactoryImpl.INSTANCE.createMessage(PacketType.WATER));
}
}
public void checkNotImplemented() {
// TODO Note that this message is supported in the 1.9 binding
assertThrows(RFXComMessageNotImplementedException.class,
- () -> RFXComMessageFactory.createMessage(PacketType.WEIGHT));
+ () -> RFXComMessageFactoryImpl.INSTANCE.createMessage(PacketType.WEIGHT));
}
}
public void testSomeMessages() throws RFXComException {
String hexMessage = "105601122F000087000000140000000079";
byte[] message = HexUtils.hexToBytes(hexMessage);
- RFXComWindMessage msg = (RFXComWindMessage) RFXComMessageFactory.createMessage(message);
+ RFXComWindMessage msg = (RFXComWindMessage) RFXComMessageFactoryImpl.INSTANCE.createMessage(message);
assertEquals(WIND1, msg.subType, "SubType");
assertEquals(18, msg.seqNbr, "Seq Number");
assertEquals("12032", msg.getDeviceId(), "Sensor Id");