added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.rfxcom-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-binding-rfxcom" description="RFXCOM Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<feature>openhab-transport-serial</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.rfxcom/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
import org.openhab.binding.rfxcom.internal.messages.RFXComDeviceMessage;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
|
||||
/**
|
||||
* The {@link DeviceMessageListener} is notified when a message is received.
|
||||
*
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public interface DeviceMessageListener {
|
||||
|
||||
/**
|
||||
* This method is called whenever the message is received from the bridge.
|
||||
*
|
||||
* @param bridge The RFXCom bridge where message is received.
|
||||
* @param message The message which received.
|
||||
*/
|
||||
void onDeviceMessageReceived(ThingUID bridge, RFXComDeviceMessage message) throws RFXComException;
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.PacketType;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link RFXComBindingConstants} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RFXComBindingConstants {
|
||||
|
||||
public static final String BINDING_ID = "rfxcom";
|
||||
|
||||
// List of all Bridge Type UIDs
|
||||
public static final String BRIDGE_TYPE_MANUAL_BRIDGE = "bridge";
|
||||
public static final String BRIDGE_TYPE_TCP_BRIDGE = "tcpbridge";
|
||||
public static final String BRIDGE_TYPE_RFXTRX433 = "RFXtrx433";
|
||||
public static final String BRIDGE_TYPE_RFXTRX315 = "RFXtrx315";
|
||||
public static final String BRIDGE_TYPE_RFXREC433 = "RFXrec433";
|
||||
|
||||
public static final ThingTypeUID BRIDGE_MANUAL = new ThingTypeUID(BINDING_ID, BRIDGE_TYPE_MANUAL_BRIDGE);
|
||||
public static final ThingTypeUID BRIDGE_TCP = new ThingTypeUID(BINDING_ID, BRIDGE_TYPE_TCP_BRIDGE);
|
||||
public static final ThingTypeUID BRIDGE_RFXTRX443 = new ThingTypeUID(BINDING_ID, BRIDGE_TYPE_RFXTRX433);
|
||||
public static final ThingTypeUID BRIDGE_RFXTRX315 = new ThingTypeUID(BINDING_ID, BRIDGE_TYPE_RFXTRX315);
|
||||
public static final ThingTypeUID BRIDGE_RFXREC443 = new ThingTypeUID(BINDING_ID, BRIDGE_TYPE_RFXREC433);
|
||||
|
||||
/**
|
||||
* Presents all supported Bridge types by RFXCOM binding.
|
||||
*/
|
||||
public static final Set<ThingTypeUID> SUPPORTED_BRIDGE_THING_TYPES_UIDS = Collections
|
||||
.unmodifiableSet(Stream.of(BRIDGE_MANUAL, BRIDGE_TCP, BRIDGE_RFXTRX443, BRIDGE_RFXTRX315, BRIDGE_RFXREC443)
|
||||
.collect(Collectors.toSet()));
|
||||
|
||||
/**
|
||||
* Presents all discoverable Bridge types by RFXCOM binding.
|
||||
*/
|
||||
public static final Set<ThingTypeUID> DISCOVERABLE_BRIDGE_THING_TYPES_UIDS = Collections.unmodifiableSet(
|
||||
Stream.of(BRIDGE_RFXTRX443, BRIDGE_RFXTRX315, BRIDGE_RFXREC443).collect(Collectors.toSet()));
|
||||
|
||||
// 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_SHUTTER = "shutter";
|
||||
public static final String CHANNEL_VENETIAN_BLIND = "venetianBlind";
|
||||
public static final String CHANNEL_SUN_WIND_DETECTOR = "sunWindDetector";
|
||||
public static final String CHANNEL_COMMAND = "command";
|
||||
public static final String CHANNEL_COMMAND_SECOND = "command2nd";
|
||||
public static final String CHANNEL_CONTROL = "control";
|
||||
public static final String CHANNEL_PROGRAM = "program";
|
||||
public static final String CHANNEL_COMMAND_ID = "commandId";
|
||||
public static final String CHANNEL_COMMAND_STRING = "commandString";
|
||||
public static final String CHANNEL_MOOD = "mood";
|
||||
public static final String CHANNEL_SIGNAL_LEVEL = "signalLevel";
|
||||
public static final String CHANNEL_DIMMING_LEVEL = "dimmingLevel";
|
||||
public static final String CHANNEL_UV = "uv";
|
||||
public static final String CHANNEL_FAN_LIGHT = "fanLight";
|
||||
public static final String CHANNEL_FAN_SPEED = "fanSpeed";
|
||||
public static final String CHANNEL_TEMPERATURE = "temperature";
|
||||
public static final String CHANNEL_FOOD_TEMPERATURE = "foodTemperature";
|
||||
public static final String CHANNEL_BBQ_TEMPERATURE = "bbqTemperature";
|
||||
public static final String CHANNEL_CHILL_TEMPERATURE = "chillTemperature";
|
||||
public static final String CHANNEL_HUMIDITY = "humidity";
|
||||
public static final String CHANNEL_HUMIDITY_STATUS = "humidityStatus";
|
||||
public static final String CHANNEL_BATTERY_LEVEL = "batteryLevel";
|
||||
public static final String CHANNEL_LOW_BATTERY = "lowBattery";
|
||||
public static final String CHANNEL_PRESSURE = "pressure";
|
||||
public static final String CHANNEL_FORECAST = "forecast";
|
||||
public static final String CHANNEL_RAIN_RATE = "rainRate";
|
||||
public static final String CHANNEL_RAIN_TOTAL = "rainTotal";
|
||||
public static final String CHANNEL_WIND_DIRECTION = "windDirection";
|
||||
public static final String CHANNEL_WIND_SPEED = "windSpeed";
|
||||
public static final String CHANNEL_AVG_WIND_SPEED = "avgWindSpeed";
|
||||
public static final String CHANNEL_INSTANT_POWER = "instantPower";
|
||||
public static final String CHANNEL_TOTAL_USAGE = "totalUsage";
|
||||
public static final String CHANNEL_INSTANT_AMPS = "instantAmp";
|
||||
public static final String CHANNEL_TOTAL_AMP_HOUR = "totalAmpHour";
|
||||
public static final String CHANNEL_CHANNEL1_AMPS = "channel1Amps";
|
||||
public static final String CHANNEL_CHANNEL2_AMPS = "channel2Amps";
|
||||
public static final String CHANNEL_CHANNEL3_AMPS = "channel3Amps";
|
||||
public static final String CHANNEL_STATUS = "status";
|
||||
public static final String CHANNEL_MOTION = "motion";
|
||||
public static final String CHANNEL_CONTACT = "contact";
|
||||
public static final String CHANNEL_CONTACT_1 = "contact1";
|
||||
public static final String CHANNEL_CONTACT_2 = "contact2";
|
||||
public static final String CHANNEL_CONTACT_3 = "contact3";
|
||||
public static final String CHANNEL_VOLTAGE = "voltage";
|
||||
public static final String CHANNEL_REFERENCE_VOLTAGE = "referenceVoltage";
|
||||
public static final String CHANNEL_SET_POINT = "setpoint";
|
||||
public static final String CHANNEL_DATE_TIME = "dateTime";
|
||||
public static final String CHANNEL_CHIME_SOUND = "chimeSound";
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
private static final ThingTypeUID THING_TYPE_BAROMETRIC = new ThingTypeUID(BINDING_ID, "barometric");
|
||||
private static final ThingTypeUID THING_TYPE_BBQ_TEMPERATURE = new ThingTypeUID(BINDING_ID, "bbqtemperature");
|
||||
private static final ThingTypeUID THING_TYPE_BLINDS1 = new ThingTypeUID(BINDING_ID, "blinds1");
|
||||
private static final ThingTypeUID THING_TYPE_CAMERA1 = new ThingTypeUID(BINDING_ID, "camera1");
|
||||
private static final ThingTypeUID THING_TYPE_CHIME = new ThingTypeUID(BINDING_ID, "chime");
|
||||
private static final ThingTypeUID THING_TYPE_CURRENT = new ThingTypeUID(BINDING_ID, "current");
|
||||
private static final ThingTypeUID THING_TYPE_CURRENT_ENERGY = new ThingTypeUID(BINDING_ID, "currentenergy");
|
||||
private static final ThingTypeUID THING_TYPE_CURTAIN1 = new ThingTypeUID(BINDING_ID, "curtain1");
|
||||
private static final ThingTypeUID THING_TYPE_DATE_TIME = new ThingTypeUID(BINDING_ID, "datetime");
|
||||
private static final ThingTypeUID THING_TYPE_ENERGY = new ThingTypeUID(BINDING_ID, "energy");
|
||||
private static final ThingTypeUID THING_TYPE_FAN = new ThingTypeUID(BINDING_ID, "fan");
|
||||
private static final ThingTypeUID THING_TYPE_FAN_SF01 = new ThingTypeUID(BINDING_ID, "fan_sf01");
|
||||
private static final ThingTypeUID THING_TYPE_FAN_ITHO = new ThingTypeUID(BINDING_ID, "fan_itho");
|
||||
private static final ThingTypeUID THING_TYPE_FAN_SEAV = new ThingTypeUID(BINDING_ID, "fan_seav");
|
||||
private static final ThingTypeUID THING_TYPE_FAN_LUCCI_DC = new ThingTypeUID(BINDING_ID, "fan_lucci_dc");
|
||||
private static final ThingTypeUID THING_TYPE_FAN_FT1211R = new ThingTypeUID(BINDING_ID, "fan_ft1211r");
|
||||
private static final ThingTypeUID THING_TYPE_FAN_FALMEC = new ThingTypeUID(BINDING_ID, "fan_falmec");
|
||||
private static final ThingTypeUID THING_TYPE_FAN_LUCCI_DC_II = new ThingTypeUID(BINDING_ID, "fan_lucci_dc_ii");
|
||||
private static final ThingTypeUID THING_TYPE_FS20 = new ThingTypeUID(BINDING_ID, "fs20");
|
||||
private static final ThingTypeUID THING_TYPE_GAS_USAGE = new ThingTypeUID(BINDING_ID, "gasusage");
|
||||
private static final ThingTypeUID THING_TYPE_HOME_CONFORT = new ThingTypeUID(BINDING_ID, "homeconfort");
|
||||
private static final ThingTypeUID THING_TYPE_HUMIDITY = new ThingTypeUID(BINDING_ID, "humidity");
|
||||
private static final ThingTypeUID THING_TYPE_IO_LINES = new ThingTypeUID(BINDING_ID, "iolines");
|
||||
private static final ThingTypeUID THING_TYPE_LIGHTNING1 = new ThingTypeUID(BINDING_ID, "lighting1");
|
||||
private static final ThingTypeUID THING_TYPE_LIGHTNING2 = new ThingTypeUID(BINDING_ID, "lighting2");
|
||||
private static final ThingTypeUID THING_TYPE_LIGHTNING3 = new ThingTypeUID(BINDING_ID, "lighting3");
|
||||
private static final ThingTypeUID THING_TYPE_LIGHTNING4 = new ThingTypeUID(BINDING_ID, "lighting4");
|
||||
private static final ThingTypeUID THING_TYPE_LIGHTNING5 = new ThingTypeUID(BINDING_ID, "lighting5");
|
||||
private static final ThingTypeUID THING_TYPE_LIGHTNING6 = new ThingTypeUID(BINDING_ID, "lighting6");
|
||||
private static final ThingTypeUID THING_TYPE_POWER = new ThingTypeUID(BINDING_ID, "power");
|
||||
private static final ThingTypeUID THING_TYPE_RADIATOR1 = new ThingTypeUID(BINDING_ID, "radiator1");
|
||||
private static final ThingTypeUID THING_TYPE_RAIN = new ThingTypeUID(BINDING_ID, "rain");
|
||||
private static final ThingTypeUID THING_TYPE_REMOTE_CONTROL = new ThingTypeUID(BINDING_ID, "remotecontrol");
|
||||
private static final ThingTypeUID THING_TYPE_RFX_METER = new ThingTypeUID(BINDING_ID, "rfxmeter");
|
||||
private static final ThingTypeUID THING_TYPE_RFX_SENSOR = new ThingTypeUID(BINDING_ID, "rfxsensor");
|
||||
private static final ThingTypeUID THING_TYPE_RFY = new ThingTypeUID(BINDING_ID, "rfy");
|
||||
private static final ThingTypeUID THING_TYPE_SECURITY1 = new ThingTypeUID(BINDING_ID, "security1");
|
||||
private static final ThingTypeUID THING_TYPE_SECURITY2 = new ThingTypeUID(BINDING_ID, "security2");
|
||||
private static final ThingTypeUID THING_TYPE_TEMPERATURE = new ThingTypeUID(BINDING_ID, "temperature");
|
||||
private static final ThingTypeUID THING_TYPE_TEMPERATURE_HUMIDITY = new ThingTypeUID(BINDING_ID,
|
||||
"temperaturehumidity");
|
||||
private static final ThingTypeUID THING_TYPE_TEMPERATURE_HUMIDITY_BAROMETRIC = new ThingTypeUID(BINDING_ID,
|
||||
"temperaturehumiditybarometric");
|
||||
private static final ThingTypeUID THING_TYPE_TEMPERATURE_RAIN = new ThingTypeUID(BINDING_ID, "temperaturerain");
|
||||
private static final ThingTypeUID THING_TYPE_THERMOSTAT1 = new ThingTypeUID(BINDING_ID, "thermostat1");
|
||||
private static final ThingTypeUID THING_TYPE_THERMOSTAT2 = new ThingTypeUID(BINDING_ID, "thermostat2");
|
||||
private static final ThingTypeUID THING_TYPE_THERMOSTAT3 = new ThingTypeUID(BINDING_ID, "thermostat3");
|
||||
private static final ThingTypeUID THING_TYPE_UNDECODED = new ThingTypeUID(BINDING_ID, "undecoded");
|
||||
private static final ThingTypeUID THING_TYPE_UV = new ThingTypeUID(BINDING_ID, "uv");
|
||||
private static final ThingTypeUID THING_TYPE_WATER_USAGE = new ThingTypeUID(BINDING_ID, "waterusage");
|
||||
private static final ThingTypeUID THING_TYPE_WEIGHTING_SCALE = new ThingTypeUID(BINDING_ID, "weightingscale");
|
||||
private static final ThingTypeUID THING_TYPE_WIND = new ThingTypeUID(BINDING_ID, "wind");
|
||||
|
||||
/**
|
||||
* Presents all supported Thing types by RFXCOM binding.
|
||||
*/
|
||||
public static final Set<ThingTypeUID> SUPPORTED_DEVICE_THING_TYPES_UIDS = Collections.unmodifiableSet(Stream.of(
|
||||
THING_TYPE_BAROMETRIC, THING_TYPE_BBQ_TEMPERATURE, THING_TYPE_BLINDS1, THING_TYPE_CAMERA1, THING_TYPE_CHIME,
|
||||
THING_TYPE_CURRENT, THING_TYPE_CURRENT_ENERGY, THING_TYPE_CURTAIN1, THING_TYPE_DATE_TIME, THING_TYPE_ENERGY,
|
||||
THING_TYPE_FAN, THING_TYPE_FAN_SF01, THING_TYPE_FAN_ITHO, THING_TYPE_FAN_SEAV, THING_TYPE_FAN_LUCCI_DC,
|
||||
THING_TYPE_FAN_FT1211R, THING_TYPE_FAN_FALMEC, THING_TYPE_FAN_LUCCI_DC_II, THING_TYPE_GAS_USAGE,
|
||||
THING_TYPE_HOME_CONFORT, THING_TYPE_HUMIDITY, THING_TYPE_IO_LINES, THING_TYPE_LIGHTNING1,
|
||||
THING_TYPE_LIGHTNING2, THING_TYPE_LIGHTNING3, THING_TYPE_LIGHTNING4, THING_TYPE_LIGHTNING5,
|
||||
THING_TYPE_LIGHTNING6, THING_TYPE_POWER, THING_TYPE_RADIATOR1, THING_TYPE_RAIN, THING_TYPE_REMOTE_CONTROL,
|
||||
THING_TYPE_RFX_METER, THING_TYPE_RFX_SENSOR, THING_TYPE_RFY, THING_TYPE_SECURITY1, THING_TYPE_SECURITY2,
|
||||
THING_TYPE_TEMPERATURE, THING_TYPE_TEMPERATURE_HUMIDITY, THING_TYPE_TEMPERATURE_HUMIDITY_BAROMETRIC,
|
||||
THING_TYPE_TEMPERATURE_RAIN, THING_TYPE_THERMOSTAT1, THING_TYPE_THERMOSTAT2, THING_TYPE_THERMOSTAT3,
|
||||
THING_TYPE_UNDECODED, THING_TYPE_UV, THING_TYPE_WATER_USAGE, THING_TYPE_WEIGHTING_SCALE, THING_TYPE_WIND)
|
||||
.collect(Collectors.toSet()));
|
||||
|
||||
/**
|
||||
* Map RFXCOM packet types to RFXCOM Thing types and vice versa.
|
||||
*/
|
||||
public static final Map<PacketType, ThingTypeUID> PACKET_TYPE_THING_TYPE_UID_MAP = Collections
|
||||
.unmodifiableMap(new HashMap<PacketType, ThingTypeUID>() {
|
||||
{
|
||||
put(PacketType.BAROMETRIC, RFXComBindingConstants.THING_TYPE_BAROMETRIC);
|
||||
put(PacketType.BBQ, RFXComBindingConstants.THING_TYPE_BBQ_TEMPERATURE);
|
||||
put(PacketType.BLINDS1, RFXComBindingConstants.THING_TYPE_BLINDS1);
|
||||
put(PacketType.CAMERA1, RFXComBindingConstants.THING_TYPE_CAMERA1);
|
||||
put(PacketType.CHIME, RFXComBindingConstants.THING_TYPE_CHIME);
|
||||
put(PacketType.CURRENT, RFXComBindingConstants.THING_TYPE_CURRENT);
|
||||
put(PacketType.CURRENT_ENERGY, RFXComBindingConstants.THING_TYPE_CURRENT_ENERGY);
|
||||
put(PacketType.CURTAIN1, RFXComBindingConstants.THING_TYPE_CURTAIN1);
|
||||
put(PacketType.DATE_TIME, RFXComBindingConstants.THING_TYPE_DATE_TIME);
|
||||
put(PacketType.ENERGY, RFXComBindingConstants.THING_TYPE_ENERGY);
|
||||
put(PacketType.FAN, RFXComBindingConstants.THING_TYPE_FAN);
|
||||
put(PacketType.FAN_SF01, RFXComBindingConstants.THING_TYPE_FAN_SF01);
|
||||
put(PacketType.FAN_ITHO, RFXComBindingConstants.THING_TYPE_FAN_ITHO);
|
||||
put(PacketType.FAN_SEAV, RFXComBindingConstants.THING_TYPE_FAN_SEAV);
|
||||
put(PacketType.FAN_LUCCI_DC, RFXComBindingConstants.THING_TYPE_FAN_LUCCI_DC);
|
||||
put(PacketType.FAN_FT1211R, RFXComBindingConstants.THING_TYPE_FAN_FT1211R);
|
||||
put(PacketType.FAN_FALMEC, RFXComBindingConstants.THING_TYPE_FAN_FALMEC);
|
||||
put(PacketType.FAN_LUCCI_DC_II, RFXComBindingConstants.THING_TYPE_FAN_LUCCI_DC_II);
|
||||
put(PacketType.FS20, RFXComBindingConstants.THING_TYPE_FS20);
|
||||
put(PacketType.GAS, RFXComBindingConstants.THING_TYPE_GAS_USAGE);
|
||||
put(PacketType.HOME_CONFORT, RFXComBindingConstants.THING_TYPE_HOME_CONFORT);
|
||||
put(PacketType.HUMIDITY, RFXComBindingConstants.THING_TYPE_HUMIDITY);
|
||||
put(PacketType.IO_LINES, RFXComBindingConstants.THING_TYPE_IO_LINES);
|
||||
put(PacketType.LIGHTING1, RFXComBindingConstants.THING_TYPE_LIGHTNING1);
|
||||
put(PacketType.LIGHTING2, RFXComBindingConstants.THING_TYPE_LIGHTNING2);
|
||||
put(PacketType.LIGHTING3, RFXComBindingConstants.THING_TYPE_LIGHTNING3);
|
||||
put(PacketType.LIGHTING4, RFXComBindingConstants.THING_TYPE_LIGHTNING4);
|
||||
put(PacketType.LIGHTING5, RFXComBindingConstants.THING_TYPE_LIGHTNING5);
|
||||
put(PacketType.LIGHTING6, RFXComBindingConstants.THING_TYPE_LIGHTNING6);
|
||||
put(PacketType.POWER, RFXComBindingConstants.THING_TYPE_POWER);
|
||||
put(PacketType.RADIATOR1, RFXComBindingConstants.THING_TYPE_RADIATOR1);
|
||||
put(PacketType.RAIN, RFXComBindingConstants.THING_TYPE_RAIN);
|
||||
put(PacketType.REMOTE_CONTROL, RFXComBindingConstants.THING_TYPE_REMOTE_CONTROL);
|
||||
put(PacketType.RFXMETER, RFXComBindingConstants.THING_TYPE_RFX_METER);
|
||||
put(PacketType.RFXSENSOR, RFXComBindingConstants.THING_TYPE_RFX_SENSOR);
|
||||
put(PacketType.RFY, RFXComBindingConstants.THING_TYPE_RFY);
|
||||
put(PacketType.SECURITY1, RFXComBindingConstants.THING_TYPE_SECURITY1);
|
||||
put(PacketType.SECURITY2, RFXComBindingConstants.THING_TYPE_SECURITY2);
|
||||
put(PacketType.TEMPERATURE, RFXComBindingConstants.THING_TYPE_TEMPERATURE);
|
||||
put(PacketType.TEMPERATURE_HUMIDITY, RFXComBindingConstants.THING_TYPE_TEMPERATURE_HUMIDITY);
|
||||
put(PacketType.TEMPERATURE_HUMIDITY_BAROMETRIC,
|
||||
RFXComBindingConstants.THING_TYPE_TEMPERATURE_HUMIDITY_BAROMETRIC);
|
||||
put(PacketType.TEMPERATURE_RAIN, RFXComBindingConstants.THING_TYPE_TEMPERATURE_RAIN);
|
||||
put(PacketType.THERMOSTAT1, RFXComBindingConstants.THING_TYPE_THERMOSTAT1);
|
||||
put(PacketType.THERMOSTAT2, RFXComBindingConstants.THING_TYPE_THERMOSTAT2);
|
||||
put(PacketType.THERMOSTAT3, RFXComBindingConstants.THING_TYPE_THERMOSTAT3);
|
||||
put(PacketType.UNDECODED_RF_MESSAGE, RFXComBindingConstants.THING_TYPE_UNDECODED);
|
||||
put(PacketType.UV, RFXComBindingConstants.THING_TYPE_UV);
|
||||
put(PacketType.WATER, RFXComBindingConstants.THING_TYPE_WATER_USAGE);
|
||||
put(PacketType.WEIGHT, RFXComBindingConstants.THING_TYPE_WEIGHTING_SCALE);
|
||||
put(PacketType.WIND, RFXComBindingConstants.THING_TYPE_WIND);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.rfxcom.internal.discovery.RFXComDeviceDiscoveryService;
|
||||
import org.openhab.binding.rfxcom.internal.handler.RFXComBridgeHandler;
|
||||
import org.openhab.binding.rfxcom.internal.handler.RFXComHandler;
|
||||
import org.openhab.core.config.discovery.DiscoveryService;
|
||||
import org.openhab.core.io.transport.serial.SerialPortManager;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* The {@link RFXComHandlerFactory} is responsible for creating things and thing
|
||||
* handlers.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.rfxcom")
|
||||
public class RFXComHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Stream
|
||||
.concat(RFXComBindingConstants.SUPPORTED_DEVICE_THING_TYPES_UIDS.stream(),
|
||||
RFXComBindingConstants.SUPPORTED_BRIDGE_THING_TYPES_UIDS.stream())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
/**
|
||||
* Service registration map
|
||||
*/
|
||||
private final Map<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>();
|
||||
|
||||
private final SerialPortManager serialPortManager;
|
||||
|
||||
@Activate
|
||||
public RFXComHandlerFactory(final @Reference SerialPortManager serialPortManager) {
|
||||
this.serialPortManager = serialPortManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (RFXComBindingConstants.SUPPORTED_BRIDGE_THING_TYPES_UIDS.contains(thingTypeUID)) {
|
||||
RFXComBridgeHandler handler = new RFXComBridgeHandler((Bridge) thing, serialPortManager);
|
||||
registerDeviceDiscoveryService(handler);
|
||||
return handler;
|
||||
} else if (supportsThingType(thingTypeUID)) {
|
||||
return new RFXComHandler(thing);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeHandler(ThingHandler thingHandler) {
|
||||
if (thingHandler instanceof RFXComBridgeHandler) {
|
||||
unregisterDeviceDiscoveryService(thingHandler.getThing());
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void registerDeviceDiscoveryService(RFXComBridgeHandler handler) {
|
||||
RFXComDeviceDiscoveryService discoveryService = new RFXComDeviceDiscoveryService(handler);
|
||||
discoveryService.activate();
|
||||
this.discoveryServiceRegs.put(handler.getThing().getUID(),
|
||||
bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>()));
|
||||
}
|
||||
|
||||
private synchronized void unregisterDeviceDiscoveryService(Thing thing) {
|
||||
ServiceRegistration<?> serviceReg = discoveryServiceRegs.remove(thing.getUID());
|
||||
if (serviceReg != null) {
|
||||
RFXComDeviceDiscoveryService service = (RFXComDeviceDiscoveryService) bundleContext
|
||||
.getService(serviceReg.getReference());
|
||||
serviceReg.unregister();
|
||||
if (service != null) {
|
||||
service.deactivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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 RFXComBaseConnector device.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public class RFXComBridgeConfiguration {
|
||||
public static final String SERIAL_PORT = "serialPort";
|
||||
public static final String BRIDGE_ID = "bridgeId";
|
||||
|
||||
// Serial port for manual configuration
|
||||
public String serialPort;
|
||||
|
||||
// Configuration for discovered bridge devices
|
||||
public String bridgeId;
|
||||
|
||||
// Host for using RFXCOM over TCP/IP
|
||||
public String host;
|
||||
|
||||
// Port for using RFXCOM over TCP/IP
|
||||
public int port;
|
||||
|
||||
public String transceiverType;
|
||||
|
||||
// Prevent unknown devices from being added to the inbox
|
||||
public boolean disableDiscovery;
|
||||
|
||||
public int transmitPower;
|
||||
|
||||
// Won't configure protocols to RFXCOM transceiver
|
||||
public boolean ignoreConfig;
|
||||
|
||||
public String setMode;
|
||||
|
||||
// Enabled protocols
|
||||
public boolean enableUndecoded;
|
||||
public boolean enableImagintronixOpus;
|
||||
public boolean enableByronSX;
|
||||
public boolean enableRSL;
|
||||
public boolean enableLighting4;
|
||||
public boolean enableFineOffsetViking;
|
||||
public boolean enableRubicson;
|
||||
public boolean enableAEBlyss;
|
||||
public boolean enableBlindsT1T2T3T4;
|
||||
public boolean enableBlindsT0;
|
||||
public boolean enableProGuard;
|
||||
public boolean enableFS20;
|
||||
public boolean enableLaCrosse;
|
||||
public boolean enableHidekiUPM;
|
||||
public boolean enableADLightwaveRF;
|
||||
public boolean enableMertik;
|
||||
public boolean enableVisonic;
|
||||
public boolean enableATI;
|
||||
public boolean enableOregonScientific;
|
||||
public boolean enableMeiantech;
|
||||
public boolean enableHomeEasyEU;
|
||||
public boolean enableAC;
|
||||
public boolean enableARC;
|
||||
public boolean enableX10;
|
||||
public boolean enableHomeConfort;
|
||||
public boolean enableKEELOQ;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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 RfxcomBinding device.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.connector;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* RFXCOM connector for serial port communication.
|
||||
*
|
||||
* @author James Hewitt-Thomas - Initial contribution
|
||||
*/
|
||||
public abstract class RFXComBaseConnector implements RFXComConnectorInterface {
|
||||
private final Logger logger = LoggerFactory.getLogger(RFXComBaseConnector.class);
|
||||
|
||||
private List<RFXComEventListener> listeners = new ArrayList<>();
|
||||
protected InputStream in;
|
||||
|
||||
@Override
|
||||
public synchronized void addEventListener(RFXComEventListener rfxComEventListener) {
|
||||
if (!listeners.contains(rfxComEventListener)) {
|
||||
listeners.add(rfxComEventListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void removeEventListener(RFXComEventListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
void sendMsgToListeners(byte[] msg) {
|
||||
try {
|
||||
for (RFXComEventListener listener : listeners) {
|
||||
listener.packetReceived(msg);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Event listener invoking error", e);
|
||||
}
|
||||
}
|
||||
|
||||
void sendErrorToListeners(String error) {
|
||||
try {
|
||||
for (RFXComEventListener listener : listeners) {
|
||||
listener.errorOccurred(error);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Event listener invoking error", e);
|
||||
}
|
||||
}
|
||||
|
||||
int read(byte[] buffer, int offset, int length) throws IOException {
|
||||
return in.read(buffer, offset, length);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.connector;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.config.RFXComBridgeConfiguration;
|
||||
|
||||
/**
|
||||
* This interface defines interface to communicate RFXCOM controller.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public interface RFXComConnectorInterface {
|
||||
|
||||
/**
|
||||
* Procedure for connecting to RFXCOM controller.
|
||||
*
|
||||
* @param device Controller connection parameters (e.g. serial port name or IP address).
|
||||
*/
|
||||
void connect(RFXComBridgeConfiguration device) throws Exception;
|
||||
|
||||
/**
|
||||
* Procedure for disconnecting to RFXCOM controller.
|
||||
*
|
||||
*/
|
||||
void disconnect();
|
||||
|
||||
/**
|
||||
* Procedure for send raw data to RFXCOM controller.
|
||||
*
|
||||
* @param data raw bytes.
|
||||
*/
|
||||
void sendMessage(byte[] data) throws IOException;
|
||||
|
||||
/**
|
||||
* Procedure for register event listener.
|
||||
*
|
||||
* @param listener Event listener instance to handle events.
|
||||
*/
|
||||
void addEventListener(RFXComEventListener listener);
|
||||
|
||||
/**
|
||||
* Procedure for remove event listener.
|
||||
*
|
||||
* @param listener Event listener instance to remove.
|
||||
*/
|
||||
void removeEventListener(RFXComEventListener listener);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.connector;
|
||||
|
||||
/**
|
||||
* This interface defines interface to receive data from RFXCOM controller.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public interface RFXComEventListener {
|
||||
|
||||
/**
|
||||
* Procedure for receive raw data from RFXCOM controller.
|
||||
*
|
||||
* @param data Received raw data.
|
||||
*/
|
||||
void packetReceived(byte[] data);
|
||||
|
||||
/**
|
||||
* Procedure for receiving information fatal error.
|
||||
*
|
||||
* @param error Error occurred.
|
||||
*/
|
||||
void errorOccurred(String error);
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.connector;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.config.RFXComBridgeConfiguration;
|
||||
import org.openhab.core.util.HexUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jd2xx.JD2XX;
|
||||
import jd2xx.JD2XXInputStream;
|
||||
import jd2xx.JD2XXOutputStream;
|
||||
|
||||
/**
|
||||
* RFXCOM connector for direct access via D2XX driver.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public class RFXComJD2XXConnector extends RFXComBaseConnector {
|
||||
private final Logger logger = LoggerFactory.getLogger(RFXComJD2XXConnector.class);
|
||||
|
||||
private JD2XX serialPort;
|
||||
private JD2XXOutputStream out;
|
||||
|
||||
private final String readerThreadName;
|
||||
private Thread readerThread;
|
||||
|
||||
public RFXComJD2XXConnector(String readerThreadName) {
|
||||
super();
|
||||
this.readerThreadName = readerThreadName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(RFXComBridgeConfiguration device) throws IOException {
|
||||
logger.info("Connecting to RFXCOM device '{}' using JD2XX.", device.bridgeId);
|
||||
|
||||
if (serialPort == null) {
|
||||
serialPort = new JD2XX();
|
||||
}
|
||||
serialPort.openBySerialNumber(device.bridgeId);
|
||||
serialPort.setBaudRate(38400);
|
||||
serialPort.setDataCharacteristics(8, JD2XX.STOP_BITS_1, JD2XX.PARITY_NONE);
|
||||
serialPort.setFlowControl(JD2XX.FLOW_NONE, 0, 0);
|
||||
serialPort.setTimeouts(100, 100);
|
||||
|
||||
in = new JD2XXInputStream(serialPort);
|
||||
out = new JD2XXOutputStream(serialPort);
|
||||
|
||||
out.flush();
|
||||
if (in.markSupported()) {
|
||||
in.reset();
|
||||
}
|
||||
|
||||
readerThread = new RFXComStreamReader(this, readerThreadName);
|
||||
readerThread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
logger.debug("Disconnecting");
|
||||
|
||||
if (readerThread != null) {
|
||||
logger.debug("Interrupt serial listener");
|
||||
readerThread.interrupt();
|
||||
try {
|
||||
readerThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (out != null) {
|
||||
logger.debug("Close serial out stream");
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
logger.debug("Error while closing the out stream: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
if (in != null) {
|
||||
logger.debug("Close serial in stream");
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
logger.debug("Error while closing the in stream: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (serialPort != null) {
|
||||
logger.debug("Close serial port");
|
||||
try {
|
||||
serialPort.close();
|
||||
} catch (IOException e) {
|
||||
logger.debug("Serial port closing error: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
readerThread = null;
|
||||
serialPort = null;
|
||||
out = null;
|
||||
in = null;
|
||||
|
||||
logger.debug("Closed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(byte[] data) throws IOException {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send data (len={}): {}", data.length, HexUtils.bytesToHex(data));
|
||||
}
|
||||
out.write(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.connector;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.TooManyListenersException;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.config.RFXComBridgeConfiguration;
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
import org.openhab.core.io.transport.serial.PortInUseException;
|
||||
import org.openhab.core.io.transport.serial.SerialPort;
|
||||
import org.openhab.core.io.transport.serial.SerialPortEvent;
|
||||
import org.openhab.core.io.transport.serial.SerialPortEventListener;
|
||||
import org.openhab.core.io.transport.serial.SerialPortIdentifier;
|
||||
import org.openhab.core.io.transport.serial.SerialPortManager;
|
||||
import org.openhab.core.io.transport.serial.UnsupportedCommOperationException;
|
||||
import org.openhab.core.util.HexUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* RFXCOM connector for serial port communication.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public class RFXComSerialConnector extends RFXComBaseConnector implements SerialPortEventListener {
|
||||
private final Logger logger = LoggerFactory.getLogger(RFXComSerialConnector.class);
|
||||
|
||||
private OutputStream out;
|
||||
private SerialPort serialPort;
|
||||
private final SerialPortManager serialPortManager;
|
||||
|
||||
private final String readerThreadName;
|
||||
private Thread readerThread;
|
||||
|
||||
public RFXComSerialConnector(SerialPortManager serialPortManager, String readerThreadName) {
|
||||
super();
|
||||
this.serialPortManager = serialPortManager;
|
||||
this.readerThreadName = readerThreadName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(RFXComBridgeConfiguration device)
|
||||
throws RFXComException, PortInUseException, UnsupportedCommOperationException, IOException {
|
||||
SerialPortIdentifier portIdentifier = serialPortManager.getIdentifier(device.serialPort);
|
||||
if (portIdentifier == null) {
|
||||
logger.debug("No serial port {}", device.serialPort);
|
||||
throw new RFXComException("No serial port " + device.serialPort);
|
||||
}
|
||||
|
||||
SerialPort commPort = portIdentifier.open(this.getClass().getName(), 2000);
|
||||
|
||||
serialPort = commPort;
|
||||
serialPort.setSerialPortParams(38400, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
|
||||
serialPort.enableReceiveThreshold(1);
|
||||
serialPort.enableReceiveTimeout(100); // In ms. Small values mean faster shutdown but more cpu usage.
|
||||
|
||||
in = serialPort.getInputStream();
|
||||
out = serialPort.getOutputStream();
|
||||
|
||||
out.flush();
|
||||
if (in.markSupported()) {
|
||||
in.reset();
|
||||
}
|
||||
|
||||
// RXTX serial port library causes high CPU load
|
||||
// Start event listener, which will just sleep and slow down event loop
|
||||
try {
|
||||
serialPort.addEventListener(this);
|
||||
serialPort.notifyOnDataAvailable(true);
|
||||
logger.debug("Serial port event listener started");
|
||||
} catch (TooManyListenersException e) {
|
||||
}
|
||||
|
||||
readerThread = new RFXComStreamReader(this, readerThreadName);
|
||||
readerThread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
logger.debug("Disconnecting");
|
||||
|
||||
if (serialPort != null) {
|
||||
serialPort.removeEventListener();
|
||||
logger.debug("Serial port event listener stopped");
|
||||
}
|
||||
|
||||
if (readerThread != null) {
|
||||
logger.debug("Interrupt serial listener");
|
||||
readerThread.interrupt();
|
||||
try {
|
||||
readerThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (out != null) {
|
||||
logger.debug("Close serial out stream");
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
logger.debug("Error while closing the out stream: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
if (in != null) {
|
||||
logger.debug("Close serial in stream");
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
logger.debug("Error while closing the in stream: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (serialPort != null) {
|
||||
logger.debug("Close serial port");
|
||||
serialPort.close();
|
||||
}
|
||||
|
||||
readerThread = null;
|
||||
serialPort = null;
|
||||
out = null;
|
||||
in = null;
|
||||
|
||||
logger.debug("Closed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(byte[] data) throws IOException {
|
||||
if (out == null) {
|
||||
throw new IOException("Not connected sending messages is not possible");
|
||||
}
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send data (len={}): {}", data.length, HexUtils.bytesToHex(data));
|
||||
}
|
||||
|
||||
out.write(data);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialEvent(SerialPortEvent arg0) {
|
||||
try {
|
||||
/*
|
||||
* See more details from
|
||||
* https://github.com/NeuronRobotics/nrjavaserial/issues/22
|
||||
*/
|
||||
logger.trace("RXTX library CPU load workaround, sleep forever");
|
||||
Thread.sleep(Long.MAX_VALUE);
|
||||
} catch (InterruptedException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.connector;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComTimeoutException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* RFXCOM stream reader to parse RFXCOM output into messages.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
* @author James Hewitt-Thomas - New class
|
||||
* @author Mike Jagdis - Interruptible read loop
|
||||
* @author Martin van Wingerden - Slight refactoring for read loop for TCP connector
|
||||
*/
|
||||
public class RFXComStreamReader extends Thread {
|
||||
private final Logger logger = LoggerFactory.getLogger(RFXComStreamReader.class);
|
||||
private static final int MAX_READ_TIMEOUTS = 4;
|
||||
private static final int MAX_RFXCOM_MESSAGE_LEN = 256;
|
||||
|
||||
private RFXComBaseConnector connector;
|
||||
|
||||
private class ExceptionHandler implements Thread.UncaughtExceptionHandler {
|
||||
@Override
|
||||
public void uncaughtException(Thread thread, Throwable throwable) {
|
||||
logger.debug("Connector died: ", throwable);
|
||||
connector.sendErrorToListeners("Connector died: " + throwable.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public RFXComStreamReader(RFXComBaseConnector connector, String threadName) {
|
||||
super(threadName);
|
||||
this.connector = connector;
|
||||
setUncaughtExceptionHandler(new ExceptionHandler());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
logger.debug("Data listener started");
|
||||
byte[] buf = new byte[MAX_RFXCOM_MESSAGE_LEN];
|
||||
|
||||
// The stream has (or SHOULD have) a read timeout set. Taking a
|
||||
// read timeout (read returns 0) between packets gives us a chance
|
||||
// to check if we've been interrupted. Read interrupts during a
|
||||
// packet are ignored but if too many timeouts occur we take it as
|
||||
// meaning the RFXCOM has become missing presumed dead.
|
||||
try {
|
||||
while (!Thread.interrupted()) {
|
||||
// First byte tells us how long the packet is
|
||||
int bytesRead = connector.read(buf, 0, 1);
|
||||
int packetLength = buf[0];
|
||||
|
||||
if (bytesRead > 0 && packetLength > 0) {
|
||||
logger.trace("Message length is {} bytes", packetLength);
|
||||
processMessage(buf, packetLength);
|
||||
connector.sendMsgToListeners(Arrays.copyOfRange(buf, 0, packetLength + 1));
|
||||
} else if (bytesRead == -1) {
|
||||
throw new IOException("End of stream");
|
||||
}
|
||||
}
|
||||
} catch (IOException | RFXComTimeoutException e) {
|
||||
logger.debug("Received exception, will report it to listeners", e);
|
||||
connector.sendErrorToListeners(e.getMessage());
|
||||
}
|
||||
|
||||
logger.debug("Data listener stopped");
|
||||
}
|
||||
|
||||
private void processMessage(byte[] buf, int packetLength) throws IOException, RFXComTimeoutException {
|
||||
// Now read the rest of the packet
|
||||
int bufferIndex = 1;
|
||||
int readTimeoutCount = 1;
|
||||
while (bufferIndex <= packetLength) {
|
||||
int bytesRemaining = packetLength - bufferIndex + 1;
|
||||
logger.trace("Waiting remaining {} bytes from the message", bytesRemaining);
|
||||
int bytesRead = connector.read(buf, bufferIndex, bytesRemaining);
|
||||
if (bytesRead > 0) {
|
||||
logger.trace("Received {} bytes from the message", bytesRead);
|
||||
bufferIndex += bytesRead;
|
||||
readTimeoutCount = 1;
|
||||
} else if (readTimeoutCount++ == MAX_READ_TIMEOUTS) {
|
||||
throw new RFXComTimeoutException("Timeout during packet read");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.connector;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.config.RFXComBridgeConfiguration;
|
||||
import org.openhab.core.util.HexUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* RFXCOM connector for TCP/IP communication.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
* @author Ivan F. Martinez, James Hewitt-Thomas - Implementation
|
||||
*/
|
||||
public class RFXComTcpConnector extends RFXComBaseConnector {
|
||||
private final Logger logger = LoggerFactory.getLogger(RFXComTcpConnector.class);
|
||||
|
||||
private OutputStream out;
|
||||
private Socket socket;
|
||||
|
||||
private final String readerThreadName;
|
||||
private Thread readerThread;
|
||||
|
||||
public RFXComTcpConnector(String readerThreadName) {
|
||||
super();
|
||||
this.readerThreadName = readerThreadName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(RFXComBridgeConfiguration device) throws IOException {
|
||||
logger.info("Connecting to RFXCOM at {}:{} over TCP/IP", device.host, device.port);
|
||||
socket = new Socket(device.host, device.port);
|
||||
socket.setSoTimeout(100); // In ms. Small values mean faster shutdown but more cpu usage.
|
||||
in = socket.getInputStream();
|
||||
out = socket.getOutputStream();
|
||||
|
||||
out.flush();
|
||||
if (in.markSupported()) {
|
||||
in.reset();
|
||||
}
|
||||
|
||||
readerThread = new RFXComStreamReader(this, readerThreadName);
|
||||
readerThread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
logger.debug("Disconnecting");
|
||||
|
||||
if (readerThread != null) {
|
||||
logger.debug("Interrupt stream listener");
|
||||
readerThread.interrupt();
|
||||
try {
|
||||
readerThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (socket != null) {
|
||||
logger.debug("Close socket");
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
logger.debug("Error while closing the socket: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
readerThread = null;
|
||||
socket = null;
|
||||
out = null;
|
||||
in = null;
|
||||
|
||||
logger.debug("Closed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(byte[] data) throws IOException {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send data (len={}): {}", data.length, HexUtils.bytesToHex(data));
|
||||
}
|
||||
out.write(data);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
int read(byte[] buffer, int offset, int length) throws IOException {
|
||||
try {
|
||||
return super.read(buffer, offset, length);
|
||||
} catch (SocketTimeoutException ignore) {
|
||||
// ignore this exception, instead return 0 to behave like the serial read
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.discovery;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.RFXComBindingConstants;
|
||||
import org.openhab.binding.rfxcom.internal.config.RFXComBridgeConfiguration;
|
||||
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.config.discovery.DiscoveryService;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jd2xx.JD2XX;
|
||||
|
||||
/**
|
||||
* The {@link RFXComBridgeDiscovery} is responsible for discovering new RFXCOM
|
||||
* transceivers.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*
|
||||
*/
|
||||
@Component(service = DiscoveryService.class, immediate = true, configurationPid = "discovery.rfxcom")
|
||||
public class RFXComBridgeDiscovery extends AbstractDiscoveryService {
|
||||
private static final long REFRESH_INTERVAL_IN_SECONDS = 600;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(RFXComBridgeDiscovery.class);
|
||||
|
||||
private boolean unsatisfiedLinkErrorLogged = false;
|
||||
|
||||
private ScheduledFuture<?> discoveryJob;
|
||||
|
||||
public RFXComBridgeDiscovery() {
|
||||
super(RFXComBindingConstants.DISCOVERABLE_BRIDGE_THING_TYPES_UIDS, 10, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ThingTypeUID> getSupportedThingTypes() {
|
||||
return RFXComBindingConstants.DISCOVERABLE_BRIDGE_THING_TYPES_UIDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startScan() {
|
||||
logger.debug("Start discovery scan for RFXCOM transceivers");
|
||||
discoverRfxcom();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startBackgroundDiscovery() {
|
||||
logger.debug("Start background discovery for RFXCOM transceivers");
|
||||
discoveryJob = scheduler.scheduleWithFixedDelay(this::discoverRfxcom, 0, REFRESH_INTERVAL_IN_SECONDS,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stopBackgroundDiscovery() {
|
||||
logger.debug("Stop background discovery for RFXCOM transceivers");
|
||||
if (discoveryJob != null && !discoveryJob.isCancelled()) {
|
||||
discoveryJob.cancel(true);
|
||||
discoveryJob = null;
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void discoverRfxcom() {
|
||||
try {
|
||||
JD2XX jd2xx = new JD2XX();
|
||||
logger.debug("Discovering RFXCOM transceiver devices by JD2XX version {}", jd2xx.getLibraryVersion());
|
||||
String[] devDescriptions = (String[]) jd2xx.listDevicesByDescription();
|
||||
String[] devSerialNumbers = (String[]) jd2xx.listDevicesBySerialNumber();
|
||||
logger.debug("Discovered {} FTDI device(s)", devDescriptions.length);
|
||||
|
||||
for (int i = 0; i < devSerialNumbers.length; ++i) {
|
||||
if (devDescriptions.length > 0) {
|
||||
switch (devDescriptions[i]) {
|
||||
case RFXComBindingConstants.BRIDGE_TYPE_RFXTRX433:
|
||||
addBridge(RFXComBindingConstants.BRIDGE_RFXTRX443, devSerialNumbers[i]);
|
||||
break;
|
||||
case RFXComBindingConstants.BRIDGE_TYPE_RFXTRX315:
|
||||
addBridge(RFXComBindingConstants.BRIDGE_RFXTRX315, devSerialNumbers[i]);
|
||||
break;
|
||||
case RFXComBindingConstants.BRIDGE_TYPE_RFXREC433:
|
||||
addBridge(RFXComBindingConstants.BRIDGE_RFXREC443, devSerialNumbers[i]);
|
||||
break;
|
||||
default:
|
||||
logger.trace("Ignore unknown device '{}'", devDescriptions[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug("Discovery done");
|
||||
|
||||
} catch (IOException e) {
|
||||
logger.error("Error occurred during discovery", e);
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
if (unsatisfiedLinkErrorLogged) {
|
||||
logger.debug(
|
||||
"Error occurred when trying to load native library for OS '{}' version '{}', processor '{}'",
|
||||
System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch"),
|
||||
e);
|
||||
} else {
|
||||
logger.error(
|
||||
"Error occurred when trying to load native library for OS '{}' version '{}', processor '{}'",
|
||||
System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch"),
|
||||
e);
|
||||
unsatisfiedLinkErrorLogged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addBridge(ThingTypeUID bridgeType, String bridgeId) {
|
||||
logger.debug("Discovered RFXCOM transceiver, bridgeType='{}', bridgeId='{}'", bridgeType, bridgeId);
|
||||
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put(RFXComBridgeConfiguration.BRIDGE_ID, bridgeId);
|
||||
|
||||
ThingUID uid = new ThingUID(bridgeType, bridgeId);
|
||||
DiscoveryResult result = DiscoveryResultBuilder.create(uid).withProperties(properties)
|
||||
.withLabel("RFXCOM transceiver").build();
|
||||
thingDiscovered(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.discovery;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.ID_DELIMITER;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.DeviceMessageListener;
|
||||
import org.openhab.binding.rfxcom.internal.RFXComBindingConstants;
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
import org.openhab.binding.rfxcom.internal.handler.RFXComBridgeHandler;
|
||||
import org.openhab.binding.rfxcom.internal.messages.RFXComDeviceMessage;
|
||||
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link RFXComDeviceDiscoveryService} class is used to discover RFXCOM
|
||||
* devices that send messages to RFXCOM bridge.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public class RFXComDeviceDiscoveryService extends AbstractDiscoveryService implements DeviceMessageListener {
|
||||
private final Logger logger = LoggerFactory.getLogger(RFXComDeviceDiscoveryService.class);
|
||||
private final int DISCOVERY_TTL = 3600;
|
||||
|
||||
private RFXComBridgeHandler bridgeHandler;
|
||||
|
||||
public RFXComDeviceDiscoveryService(RFXComBridgeHandler rfxcomBridgeHandler) {
|
||||
super(null, 1, false);
|
||||
this.bridgeHandler = rfxcomBridgeHandler;
|
||||
}
|
||||
|
||||
public void activate() {
|
||||
bridgeHandler.registerDeviceStatusListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate() {
|
||||
bridgeHandler.unregisterDeviceStatusListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ThingTypeUID> getSupportedThingTypes() {
|
||||
return RFXComBindingConstants.SUPPORTED_DEVICE_THING_TYPES_UIDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startScan() {
|
||||
// this can be ignored here as we discover devices from received messages
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceMessageReceived(ThingUID bridge, RFXComDeviceMessage message) throws RFXComException {
|
||||
logger.trace("Received: bridge: {} message: {}", bridge, message);
|
||||
|
||||
String id = message.getDeviceId();
|
||||
ThingTypeUID uid = RFXComBindingConstants.PACKET_TYPE_THING_TYPE_UID_MAP.get(message.getPacketType());
|
||||
ThingUID thingUID = new ThingUID(uid, bridge, id.replace(ID_DELIMITER, "_"));
|
||||
|
||||
if (!bridgeHandler.getConfiguration().disableDiscovery) {
|
||||
logger.trace("Adding new RFXCOM {} with id '{}' to smarthome inbox", thingUID, id);
|
||||
DiscoveryResultBuilder discoveryResultBuilder = DiscoveryResultBuilder.create(thingUID).withBridge(bridge)
|
||||
.withTTL(DISCOVERY_TTL);
|
||||
message.addDevicePropertiesTo(discoveryResultBuilder);
|
||||
|
||||
thingDiscovered(discoveryResultBuilder.build());
|
||||
} else {
|
||||
logger.trace("Ignoring RFXCOM {} with id '{}' - discovery disabled", thingUID, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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 RFXCOM errors.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public class RFXComException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 2975102966905930260L;
|
||||
|
||||
public RFXComException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public RFXComException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public RFXComException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public RFXComException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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 RFXCOM errors.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public class RFXComMessageNotImplementedException extends RFXComException {
|
||||
|
||||
private static final long serialVersionUID = 5958462009164173495L;
|
||||
|
||||
public RFXComMessageNotImplementedException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public RFXComMessageNotImplementedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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 are too long for the spec.
|
||||
*
|
||||
* @author James Hewitt-Thomas - Initial contribution
|
||||
*/
|
||||
public class RFXComMessageTooLongException extends RFXComException {
|
||||
|
||||
private static final long serialVersionUID = -3352067410289719335L;
|
||||
|
||||
public RFXComMessageTooLongException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public RFXComMessageTooLongException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public RFXComMessageTooLongException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public RFXComMessageTooLongException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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 device has a timeout while processing a message
|
||||
*
|
||||
* @author Martin van Wingerden - Initial contribution
|
||||
*/
|
||||
public class RFXComTimeoutException extends RFXComException {
|
||||
public RFXComTimeoutException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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 to indicate that a request was received for an unsupported channel
|
||||
*
|
||||
* @author Martin van Wingerden - Initial contribution
|
||||
*/
|
||||
public class RFXComUnsupportedChannelException extends RFXComException {
|
||||
public RFXComUnsupportedChannelException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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 RFXComUnsupportedValueException extends RFXComException {
|
||||
|
||||
private static final long serialVersionUID = 402781611495845169L;
|
||||
|
||||
public RFXComUnsupportedValueException(Class<?> enumeration, String value) {
|
||||
super("Unsupported value '" + value + "' for " + enumeration.getSimpleName());
|
||||
}
|
||||
|
||||
public RFXComUnsupportedValueException(Class<?> enumeration, int value) {
|
||||
this(enumeration, String.valueOf(value));
|
||||
}
|
||||
|
||||
public RFXComUnsupportedValueException(Class<?> enumeration, int value, Object subType) {
|
||||
super("Unsupported value '" + value + "' with subtype " + subType + " for " + enumeration.getSimpleName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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 org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* Add support for a device state to be stored and retrieved later one
|
||||
*
|
||||
* @author Martin van Wingerden - Initial contribution
|
||||
*/
|
||||
public interface DeviceState {
|
||||
Type getLastState(String channelId);
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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 java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.openhab.binding.rfxcom.internal.DeviceMessageListener;
|
||||
import org.openhab.binding.rfxcom.internal.config.RFXComBridgeConfiguration;
|
||||
import org.openhab.binding.rfxcom.internal.connector.RFXComConnectorInterface;
|
||||
import org.openhab.binding.rfxcom.internal.connector.RFXComEventListener;
|
||||
import org.openhab.binding.rfxcom.internal.connector.RFXComJD2XXConnector;
|
||||
import org.openhab.binding.rfxcom.internal.connector.RFXComSerialConnector;
|
||||
import org.openhab.binding.rfxcom.internal.connector.RFXComTcpConnector;
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComMessageNotImplementedException;
|
||||
import org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage;
|
||||
import org.openhab.binding.rfxcom.internal.messages.RFXComDeviceMessage;
|
||||
import org.openhab.binding.rfxcom.internal.messages.RFXComInterfaceControlMessage;
|
||||
import org.openhab.binding.rfxcom.internal.messages.RFXComInterfaceMessage;
|
||||
import org.openhab.binding.rfxcom.internal.messages.RFXComInterfaceMessage.Commands;
|
||||
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.RFXComTransmitterMessage;
|
||||
import org.openhab.core.io.transport.serial.SerialPortManager;
|
||||
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.binding.BaseBridgeHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.util.HexUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* {@link RFXComBridgeHandler} is the handler for a RFXCOM transceivers. All
|
||||
* {@link RFXComHandler}s use the {@link RFXComBridgeHandler} to execute the
|
||||
* actual commands.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public class RFXComBridgeHandler extends BaseBridgeHandler {
|
||||
private Logger logger = LoggerFactory.getLogger(RFXComBridgeHandler.class);
|
||||
|
||||
private RFXComConnectorInterface connector = null;
|
||||
private MessageListener eventListener = new MessageListener();
|
||||
|
||||
private List<DeviceMessageListener> deviceStatusListeners = new CopyOnWriteArrayList<>();
|
||||
|
||||
private RFXComBridgeConfiguration configuration = null;
|
||||
private ScheduledFuture<?> connectorTask;
|
||||
|
||||
private SerialPortManager serialPortManager;
|
||||
|
||||
private class TransmitQueue {
|
||||
private Queue<RFXComBaseMessage> queue = new LinkedBlockingQueue<>();
|
||||
|
||||
public synchronized void enqueue(RFXComBaseMessage msg) throws IOException {
|
||||
boolean wasEmpty = queue.isEmpty();
|
||||
if (queue.offer(msg)) {
|
||||
if (wasEmpty) {
|
||||
send();
|
||||
}
|
||||
} else {
|
||||
logger.error("Transmit queue overflow. Lost message: {}", msg);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void sendNext() throws IOException {
|
||||
queue.poll();
|
||||
send();
|
||||
}
|
||||
|
||||
public synchronized void send() throws IOException {
|
||||
while (!queue.isEmpty()) {
|
||||
RFXComBaseMessage msg = queue.peek();
|
||||
|
||||
try {
|
||||
logger.debug("Transmitting message '{}'", msg);
|
||||
byte[] data = msg.decodeMessage();
|
||||
connector.sendMessage(data);
|
||||
break;
|
||||
} catch (RFXComException rfxe) {
|
||||
logger.error("Error during send of {}", msg, rfxe);
|
||||
queue.poll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private TransmitQueue transmitQueue = new TransmitQueue();
|
||||
|
||||
public RFXComBridgeHandler(@NonNull Bridge br, SerialPortManager serialPortManager) {
|
||||
super(br);
|
||||
this.serialPortManager = serialPortManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
logger.debug("Bridge commands not supported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void dispose() {
|
||||
logger.debug("Handler disposed.");
|
||||
|
||||
for (DeviceMessageListener deviceStatusListener : deviceStatusListeners) {
|
||||
unregisterDeviceStatusListener(deviceStatusListener);
|
||||
}
|
||||
|
||||
if (connector != null) {
|
||||
connector.removeEventListener(eventListener);
|
||||
connector.disconnect();
|
||||
connector = null;
|
||||
}
|
||||
|
||||
if (connectorTask != null && !connectorTask.isCancelled()) {
|
||||
connectorTask.cancel(true);
|
||||
connectorTask = null;
|
||||
}
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
logger.debug("Initializing RFXCOM bridge handler");
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
|
||||
configuration = getConfigAs(RFXComBridgeConfiguration.class);
|
||||
|
||||
if (configuration.serialPort != null && configuration.serialPort.startsWith("rfc2217")) {
|
||||
logger.debug("Please use the Transceiver over TCP/IP bridge type for a serial over IP connection.");
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||
"Please use the Transceiver over TCP/IP bridge type for a serial over IP connection.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (connectorTask == null || connectorTask.isCancelled()) {
|
||||
connectorTask = scheduler.scheduleWithFixedDelay(() -> {
|
||||
logger.trace("Checking RFXCOM transceiver connection, thing status = {}", thing.getStatus());
|
||||
if (thing.getStatus() != ThingStatus.ONLINE) {
|
||||
connect();
|
||||
}
|
||||
}, 0, 60, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void connect() {
|
||||
logger.debug("Connecting to RFXCOM transceiver");
|
||||
|
||||
try {
|
||||
String readerThreadName = "OH-binding-" + getThing().getUID().getAsString();
|
||||
if (configuration.serialPort != null) {
|
||||
if (connector == null) {
|
||||
connector = new RFXComSerialConnector(serialPortManager, readerThreadName);
|
||||
}
|
||||
} else if (configuration.bridgeId != null) {
|
||||
if (connector == null) {
|
||||
connector = new RFXComJD2XXConnector(readerThreadName);
|
||||
}
|
||||
} else if (configuration.host != null) {
|
||||
if (connector == null) {
|
||||
connector = new RFXComTcpConnector(readerThreadName);
|
||||
}
|
||||
}
|
||||
|
||||
if (connector != null) {
|
||||
connector.disconnect();
|
||||
connector.connect(configuration);
|
||||
|
||||
logger.debug("Reset controller");
|
||||
connector.sendMessage(RFXComMessageFactory.CMD_RESET);
|
||||
|
||||
// controller does not response immediately after reset,
|
||||
// so wait a while
|
||||
Thread.sleep(300);
|
||||
|
||||
connector.addEventListener(eventListener);
|
||||
|
||||
logger.debug("Get status of controller");
|
||||
connector.sendMessage(RFXComMessageFactory.CMD_GET_STATUS);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error("Connection to RFXCOM transceiver failed", e);
|
||||
if ("device not opened (3)".equalsIgnoreCase(e.getMessage())) {
|
||||
if (connector instanceof RFXComJD2XXConnector) {
|
||||
logger.info("Automatically Discovered RFXCOM bridges use FTDI chip driver (D2XX)."
|
||||
+ " Reason for this error normally is related to operating system native FTDI drivers,"
|
||||
+ " which prevent D2XX driver to open device."
|
||||
+ " To solve this problem, uninstall OS FTDI native drivers or add manually universal bridge 'RFXCOM USB Transceiver',"
|
||||
+ " which use normal serial port driver rather than D2XX.");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Connection to RFXCOM transceiver failed", e);
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
logger.error("Error occurred when trying to load native library for OS '{}' version '{}', processor '{}'",
|
||||
System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch"), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMessage(RFXComMessage msg) {
|
||||
try {
|
||||
RFXComBaseMessage baseMsg = (RFXComBaseMessage) msg;
|
||||
transmitQueue.enqueue(baseMsg);
|
||||
} catch (IOException e) {
|
||||
logger.error("I/O Error", e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private class MessageListener implements RFXComEventListener {
|
||||
|
||||
@Override
|
||||
public void packetReceived(byte[] packet) {
|
||||
try {
|
||||
RFXComMessage message = RFXComMessageFactory.createMessage(packet);
|
||||
logger.debug("Message received: {}", message);
|
||||
|
||||
if (message instanceof RFXComInterfaceMessage) {
|
||||
RFXComInterfaceMessage msg = (RFXComInterfaceMessage) message;
|
||||
if (msg.subType == SubType.RESPONSE) {
|
||||
if (msg.command == Commands.GET_STATUS) {
|
||||
logger.debug("RFXCOM transceiver/receiver type: {}, hw version: {}.{}, fw version: {}",
|
||||
msg.transceiverType, msg.hardwareVersion1, msg.hardwareVersion2,
|
||||
msg.firmwareVersion);
|
||||
thing.setProperty(Thing.PROPERTY_HARDWARE_VERSION,
|
||||
msg.hardwareVersion1 + "." + msg.hardwareVersion2);
|
||||
thing.setProperty(Thing.PROPERTY_FIRMWARE_VERSION, Integer.toString(msg.firmwareVersion));
|
||||
|
||||
if (configuration.ignoreConfig) {
|
||||
logger.debug("Ignoring transceiver configuration");
|
||||
} else {
|
||||
byte[] setMode = null;
|
||||
|
||||
if (configuration.setMode != null && !configuration.setMode.isEmpty()) {
|
||||
try {
|
||||
setMode = HexUtils.hexToBytes(configuration.setMode);
|
||||
if (setMode.length != 14) {
|
||||
logger.warn("Invalid RFXCOM transceiver mode configuration");
|
||||
setMode = null;
|
||||
}
|
||||
} catch (IllegalArgumentException ee) {
|
||||
logger.warn("Failed to parse setMode data", ee);
|
||||
}
|
||||
} else {
|
||||
RFXComInterfaceControlMessage modeMsg = new RFXComInterfaceControlMessage(
|
||||
msg.transceiverType, configuration);
|
||||
setMode = modeMsg.decodeMessage();
|
||||
}
|
||||
|
||||
if (setMode != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Setting RFXCOM mode using: {}", HexUtils.bytesToHex(setMode));
|
||||
}
|
||||
connector.sendMessage(setMode);
|
||||
}
|
||||
}
|
||||
|
||||
// No need to wait for a response to any set mode. We start
|
||||
// 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);
|
||||
}
|
||||
} else if (msg.subType == SubType.START_RECEIVER) {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
logger.debug("Start TX of any queued messages");
|
||||
transmitQueue.send();
|
||||
} else {
|
||||
logger.debug("Interface response received: {}", msg);
|
||||
transmitQueue.sendNext();
|
||||
}
|
||||
} else if (message instanceof RFXComTransmitterMessage) {
|
||||
RFXComTransmitterMessage resp = (RFXComTransmitterMessage) message;
|
||||
|
||||
logger.debug("Transmitter response received: {}", resp);
|
||||
|
||||
transmitQueue.sendNext();
|
||||
} else if (message instanceof RFXComDeviceMessage) {
|
||||
for (DeviceMessageListener deviceStatusListener : deviceStatusListeners) {
|
||||
try {
|
||||
deviceStatusListener.onDeviceMessageReceived(getThing().getUID(),
|
||||
(RFXComDeviceMessage) message);
|
||||
} catch (Exception e) {
|
||||
// catch all exceptions give all handlers a fair chance of handling the messages
|
||||
logger.error("An exception occurred while calling the DeviceStatusListener", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.warn("The received message cannot be processed, please create an "
|
||||
+ "issue at the relevant tracker. Received message: {}", message);
|
||||
}
|
||||
} catch (RFXComMessageNotImplementedException e) {
|
||||
logger.debug("Message not supported, data: {}", HexUtils.bytesToHex(packet));
|
||||
} catch (RFXComException e) {
|
||||
logger.error("Error occurred during packet receiving, data: {}", HexUtils.bytesToHex(packet), e);
|
||||
} catch (IOException e) {
|
||||
errorOccurred("I/O error");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void errorOccurred(String error) {
|
||||
logger.error("Error occurred: {}", error);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean registerDeviceStatusListener(DeviceMessageListener deviceStatusListener) {
|
||||
if (deviceStatusListener == null) {
|
||||
throw new IllegalArgumentException("It's not allowed to pass a null deviceStatusListener.");
|
||||
}
|
||||
return !deviceStatusListeners.contains(deviceStatusListener) && deviceStatusListeners.add(deviceStatusListener);
|
||||
}
|
||||
|
||||
public boolean unregisterDeviceStatusListener(DeviceMessageListener deviceStatusListener) {
|
||||
if (deviceStatusListener == null) {
|
||||
throw new IllegalArgumentException("It's not allowed to pass a null deviceStatusListener.");
|
||||
}
|
||||
return deviceStatusListeners.remove(deviceStatusListener);
|
||||
}
|
||||
|
||||
public RFXComBridgeConfiguration getConfiguration() {
|
||||
return configuration;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.openhab.binding.rfxcom.internal.DeviceMessageListener;
|
||||
import org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration;
|
||||
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;
|
||||
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.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.thing.Channel;
|
||||
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.ThingUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link RFXComHandler} is responsible for handling commands, which are
|
||||
* sent to one of the channels.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public class RFXComHandler extends BaseThingHandler implements DeviceMessageListener, DeviceState {
|
||||
private static final int LOW_BATTERY_LEVEL = 1;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(RFXComHandler.class);
|
||||
|
||||
private final Map<String, Type> stateMap = new ConcurrentHashMap<>();
|
||||
|
||||
private RFXComBridgeHandler bridgeHandler;
|
||||
private RFXComDeviceConfiguration config;
|
||||
|
||||
public RFXComHandler(@NonNull Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
logger.debug("Received channel: {}, command: {}", channelUID, command);
|
||||
|
||||
if (bridgeHandler != null) {
|
||||
if (command instanceof RefreshType) {
|
||||
logger.trace("Received unsupported Refresh command");
|
||||
} else {
|
||||
try {
|
||||
PacketType packetType = RFXComMessageFactory
|
||||
.convertPacketType(getThing().getThingTypeUID().getId().toUpperCase());
|
||||
|
||||
RFXComMessage msg = RFXComMessageFactory.createMessage(packetType);
|
||||
|
||||
msg.setConfig(config);
|
||||
msg.convertFromState(channelUID.getId(), command);
|
||||
|
||||
bridgeHandler.sendMessage(msg);
|
||||
} catch (RFXComMessageNotImplementedException e) {
|
||||
logger.error("Message not supported", 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());
|
||||
|
||||
stateMap.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
|
||||
logger.debug("bridgeStatusChanged {} for thing {}", bridgeStatusInfo, getThing().getUID());
|
||||
initializeBridge((getBridge() == null) ? null : getBridge().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);
|
||||
|
||||
if (bridgeStatus == ThingStatus.ONLINE) {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
||||
}
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
logger.debug("Thing {} disposed.", getThing().getUID());
|
||||
if (bridgeHandler != null) {
|
||||
bridgeHandler.unregisterDeviceStatusListener(this);
|
||||
}
|
||||
bridgeHandler = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceMessageReceived(ThingUID bridge, RFXComDeviceMessage message) {
|
||||
try {
|
||||
String id = message.getDeviceId();
|
||||
if (config.deviceId.equals(id)) {
|
||||
String receivedId = PACKET_TYPE_THING_TYPE_UID_MAP.get(message.getPacketType()).getId();
|
||||
logger.debug("Received message from bridge: {} message: {}", bridge, message);
|
||||
|
||||
if (receivedId.equals(getThing().getThingTypeUID().getId())) {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
|
||||
for (Channel channel : getThing().getChannels()) {
|
||||
ChannelUID uid = channel.getUID();
|
||||
String channelId = uid.getId();
|
||||
|
||||
try {
|
||||
switch (channelId) {
|
||||
case CHANNEL_COMMAND:
|
||||
case CHANNEL_CHIME_SOUND:
|
||||
case CHANNEL_MOOD:
|
||||
postNullableCommand(uid, message.convertToCommand(channelId, this));
|
||||
break;
|
||||
|
||||
case CHANNEL_LOW_BATTERY:
|
||||
updateNullableState(uid,
|
||||
isLowBattery(message.convertToState(CHANNEL_BATTERY_LEVEL, this)));
|
||||
break;
|
||||
|
||||
default:
|
||||
updateNullableState(uid, message.convertToState(channelId, this));
|
||||
break;
|
||||
}
|
||||
} catch (RFXComException e) {
|
||||
logger.trace("{} does not handle {}", channelId, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Error occurred during message receiving", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateNullableState(ChannelUID uid, State state) {
|
||||
if (state == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
stateMap.put(uid.getId(), state);
|
||||
updateState(uid, state);
|
||||
}
|
||||
|
||||
private void postNullableCommand(ChannelUID uid, Command command) {
|
||||
if (command == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
stateMap.put(uid.getId(), command);
|
||||
postCommand(uid, command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getLastState(String channelId) {
|
||||
return stateMap.get(channelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if battery level is below low battery threshold level.
|
||||
*
|
||||
* @param batteryLevel Internal battery level
|
||||
* @return OnOffType
|
||||
*/
|
||||
private State isLowBattery(State batteryLevel) {
|
||||
int level = ((DecimalType) batteryLevel).intValue();
|
||||
if (level <= LOW_BATTERY_LEVEL) {
|
||||
return OnOffType.ON;
|
||||
} else {
|
||||
return OnOffType.OFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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 org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedValueException;
|
||||
|
||||
/**
|
||||
* An Utility class to handle {@link ByteEnumWrapper} instances
|
||||
*
|
||||
* @author Martin van Wingerden - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ByteEnumUtil {
|
||||
private ByteEnumUtil() {
|
||||
// deliberately empty
|
||||
}
|
||||
|
||||
public static <T extends ByteEnumWrapper> T fromByte(Class<T> typeClass, int input)
|
||||
throws RFXComUnsupportedValueException {
|
||||
for (T enumValue : typeClass.getEnumConstants()) {
|
||||
if (enumValue.toByte() == input) {
|
||||
return enumValue;
|
||||
}
|
||||
}
|
||||
|
||||
throw new RFXComUnsupportedValueException(typeClass, input);
|
||||
}
|
||||
|
||||
public static <T extends ByteEnumWrapper> T convertSubType(Class<T> typeClass, String subType)
|
||||
throws RFXComUnsupportedValueException {
|
||||
for (T enumValue : typeClass.getEnumConstants()) {
|
||||
if (enumValue.toString().equals(subType)) {
|
||||
return enumValue;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
int byteValue = Integer.parseInt(subType);
|
||||
return fromByte(typeClass, byteValue);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new RFXComUnsupportedValueException(typeClass, subType);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends ByteEnumWrapperWithSupportedSubTypes<?>> T fromByte(Class<T> typeClass, int input,
|
||||
Object subType) throws RFXComUnsupportedValueException {
|
||||
for (T enumValue : typeClass.getEnumConstants()) {
|
||||
if (enumValue.toByte() == input && enumValue.supportedBySubTypes().contains(subType)) {
|
||||
return enumValue;
|
||||
}
|
||||
}
|
||||
|
||||
throw new RFXComUnsupportedValueException(RFXComLighting5Message.Commands.class, input, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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;
|
||||
|
||||
/**
|
||||
* An interface for all enums wrapping / mapping bytes
|
||||
*
|
||||
* @author Martin van Wingerden - Initial contribution
|
||||
*/
|
||||
interface ByteEnumWrapper {
|
||||
byte toByte();
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.util.List;
|
||||
|
||||
/**
|
||||
* An interface for all enums wrapping / mapping bytes
|
||||
*
|
||||
* @author Martin van Wingerden - Initial contribution
|
||||
*/
|
||||
interface ByteEnumWrapperWithSupportedSubTypes<T extends ByteEnumWrapper> extends ByteEnumWrapper {
|
||||
List<T> supportedBySubTypes();
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DecimalType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for BBQ temperature message.
|
||||
*
|
||||
* @author Mike Jagdis - Initial contribution
|
||||
*/
|
||||
public class RFXComBBQTemperatureMessage extends RFXComBatteryDeviceMessage<RFXComBBQTemperatureMessage.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
BBQ1(1); // Maverick ET-732
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public double foodTemperature;
|
||||
public double bbqTemperature;
|
||||
public byte signalLevel;
|
||||
public byte batteryLevel;
|
||||
|
||||
public RFXComBBQTemperatureMessage() {
|
||||
super(PacketType.BBQ);
|
||||
}
|
||||
|
||||
public RFXComBBQTemperatureMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + ", Sub type = " + subType + ", Device Id = " + getDeviceId() + ", Food temperature = "
|
||||
+ foodTemperature + ", BBQ temperature = " + bbqTemperature + ", Signal level = " + signalLevel
|
||||
+ ", Battery level = " + batteryLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
|
||||
|
||||
foodTemperature = (data[6] & 0x7F) << 8 | (data[7] & 0xFF);
|
||||
if ((data[6] & 0x80) != 0) {
|
||||
foodTemperature = -foodTemperature;
|
||||
}
|
||||
|
||||
bbqTemperature = (data[8] & 0x7F) << 8 | (data[9] & 0xFF);
|
||||
if ((data[8] & 0x80) != 0) {
|
||||
bbqTemperature = -bbqTemperature;
|
||||
}
|
||||
|
||||
signalLevel = (byte) ((data[10] & 0xF0) >> 4);
|
||||
batteryLevel = (byte) (data[10] & 0x0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[11];
|
||||
|
||||
data[0] = 0x0A;
|
||||
data[1] = RFXComBaseMessage.PacketType.BBQ.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) ((sensorId & 0xFF00) >> 8);
|
||||
data[5] = (byte) (sensorId & 0x00FF);
|
||||
|
||||
short temp = (short) Math.abs(foodTemperature);
|
||||
data[6] = (byte) ((temp >> 8) & 0x7F);
|
||||
data[7] = (byte) (temp & 0xFF);
|
||||
if (foodTemperature < 0) {
|
||||
data[6] |= 0x80;
|
||||
}
|
||||
|
||||
temp = (short) Math.abs(bbqTemperature);
|
||||
data[8] = (byte) ((temp >> 8) & 0x7F);
|
||||
data[9] = (byte) (temp & 0xFF);
|
||||
if (bbqTemperature < 0) {
|
||||
data[8] |= 0x80;
|
||||
}
|
||||
|
||||
data[10] = (byte) (((signalLevel & 0x0F) << 4) | (batteryLevel & 0x0F));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
if (CHANNEL_FOOD_TEMPERATURE.equals(channelId)) {
|
||||
return new DecimalType(foodTemperature);
|
||||
} else if (CHANNEL_BBQ_TEMPERATURE.equals(channelId)) {
|
||||
return new DecimalType(bbqTemperature);
|
||||
} else {
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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 org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration;
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedValueException;
|
||||
import org.openhab.core.util.HexUtils;
|
||||
|
||||
/**
|
||||
* Base class for RFXCOM data classes. All other data classes should extend this class.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public abstract class RFXComBaseMessage implements RFXComMessage {
|
||||
|
||||
public static final String ID_DELIMITER = ".";
|
||||
|
||||
public enum PacketType implements ByteEnumWrapper {
|
||||
INTERFACE_CONTROL(0),
|
||||
INTERFACE_MESSAGE(1),
|
||||
TRANSMITTER_MESSAGE(2),
|
||||
UNDECODED_RF_MESSAGE(3),
|
||||
LIGHTING1(16),
|
||||
LIGHTING2(17),
|
||||
LIGHTING3(18),
|
||||
LIGHTING4(19),
|
||||
LIGHTING5(20),
|
||||
LIGHTING6(21),
|
||||
CHIME(22),
|
||||
FAN(23, RFXComFanMessage.SubType.LUCCI_AIR_FAN, RFXComFanMessage.SubType.WESTINGHOUSE_7226640,
|
||||
RFXComFanMessage.SubType.CASAFAN),
|
||||
FAN_SF01(23, RFXComFanMessage.SubType.SF01),
|
||||
FAN_ITHO(23, RFXComFanMessage.SubType.CVE_RFT),
|
||||
FAN_LUCCI_DC(23, RFXComFanMessage.SubType.LUCCI_AIR_DC),
|
||||
FAN_LUCCI_DC_II(23, RFXComFanMessage.SubType.LUCCI_AIR_DC_II),
|
||||
FAN_SEAV(23, RFXComFanMessage.SubType.SEAV_TXS4),
|
||||
FAN_FT1211R(23, RFXComFanMessage.SubType.FT1211R),
|
||||
FAN_FALMEC(23, RFXComFanMessage.SubType.FALMEC),
|
||||
CURTAIN1(24),
|
||||
BLINDS1(25),
|
||||
RFY(26),
|
||||
HOME_CONFORT(27),
|
||||
EDISIO(28),
|
||||
SECURITY1(32),
|
||||
SECURITY2(33),
|
||||
CAMERA1(40),
|
||||
REMOTE_CONTROL(48),
|
||||
THERMOSTAT1(64),
|
||||
THERMOSTAT2(65),
|
||||
THERMOSTAT3(66),
|
||||
THERMOSTAT4(67),
|
||||
RADIATOR1(72),
|
||||
BBQ(78),
|
||||
TEMPERATURE_RAIN(79),
|
||||
TEMPERATURE(80),
|
||||
HUMIDITY(81),
|
||||
TEMPERATURE_HUMIDITY(82),
|
||||
BAROMETRIC(83),
|
||||
TEMPERATURE_HUMIDITY_BAROMETRIC(84),
|
||||
RAIN(85),
|
||||
WIND(86),
|
||||
UV(87),
|
||||
DATE_TIME(88),
|
||||
CURRENT(89),
|
||||
ENERGY(90),
|
||||
CURRENT_ENERGY(91),
|
||||
POWER(92),
|
||||
WEIGHT(93),
|
||||
GAS(94),
|
||||
WATER(95),
|
||||
CARTELECTRONIC(96),
|
||||
RFXSENSOR(112),
|
||||
RFXMETER(113),
|
||||
FS20(114),
|
||||
IO_LINES(128);
|
||||
|
||||
private final int packetType;
|
||||
private final ByteEnumWrapper[] subTypes;
|
||||
|
||||
PacketType(int packetType, ByteEnumWrapper... subTypes) {
|
||||
this.packetType = packetType;
|
||||
this.subTypes = subTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) packetType;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] rawMessage;
|
||||
private PacketType packetType;
|
||||
public byte packetId;
|
||||
public byte subType;
|
||||
public byte seqNbr;
|
||||
public byte id1;
|
||||
public byte id2;
|
||||
|
||||
public RFXComBaseMessage() {
|
||||
}
|
||||
|
||||
public RFXComBaseMessage(PacketType packetType) {
|
||||
this.packetType = packetType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
rawMessage = data;
|
||||
|
||||
packetId = data[1];
|
||||
packetType = fromByte(data[1], data[2]);
|
||||
subType = data[2];
|
||||
seqNbr = data[3];
|
||||
id1 = data[4];
|
||||
|
||||
if (data.length > 5) {
|
||||
id2 = data[5];
|
||||
}
|
||||
}
|
||||
|
||||
private PacketType fromByte(byte packetId, byte subType) throws RFXComUnsupportedValueException {
|
||||
for (PacketType enumValue : PacketType.values()) {
|
||||
if (enumValue.toByte() == packetId) {
|
||||
// if there are no subtypes?
|
||||
if (enumValue.subTypes.length == 0) {
|
||||
return enumValue;
|
||||
}
|
||||
// otherwise check for the matching subType
|
||||
for (ByteEnumWrapper e : enumValue.subTypes) {
|
||||
if (e.toByte() == subType) {
|
||||
return enumValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new RFXComUnsupportedValueException(PacketType.class, packetId);
|
||||
}
|
||||
|
||||
public PacketType getPacketType() {
|
||||
return packetType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str;
|
||||
|
||||
if (rawMessage == null) {
|
||||
str = "Raw data = unknown";
|
||||
} else {
|
||||
str = "Raw data = " + HexUtils.bytesToHex(rawMessage);
|
||||
}
|
||||
|
||||
str += ", Packet type = " + packetType;
|
||||
str += ", Seq number = " + (short) (seqNbr & 0xFF);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfig(RFXComDeviceConfiguration deviceConfiguration) throws RFXComException {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.CHANNEL_BATTERY_LEVEL;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedChannelException;
|
||||
import org.openhab.binding.rfxcom.internal.handler.DeviceState;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.types.State;
|
||||
|
||||
/**
|
||||
* A base class for all battery device messages
|
||||
*
|
||||
* @author Martin van Wingerden - Initial contribution
|
||||
*/
|
||||
abstract class RFXComBatteryDeviceMessage<T> extends RFXComDeviceMessageImpl<T> {
|
||||
int batteryLevel;
|
||||
|
||||
RFXComBatteryDeviceMessage(PacketType packetType) {
|
||||
super(packetType);
|
||||
}
|
||||
|
||||
RFXComBatteryDeviceMessage() {
|
||||
// deliberately empty
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_BATTERY_LEVEL:
|
||||
return convertBatteryLevelToSystemWideLevel(batteryLevel);
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert internal battery level (0-9) to system wide battery level (0-100%).
|
||||
*
|
||||
* @param batteryLevel Internal battery level
|
||||
* @return Battery level in system wide level
|
||||
*/
|
||||
private State convertBatteryLevelToSystemWideLevel(int batteryLevel) {
|
||||
int ohLevel = (batteryLevel + 1) * 10;
|
||||
return new DecimalType(ohLevel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.OpenClosedType;
|
||||
import org.openhab.core.library.types.StopMoveType;
|
||||
import org.openhab.core.library.types.UpDownType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for blinds1 message.
|
||||
*
|
||||
* @author Peter Janson / Pål Edman - Initial contribution
|
||||
* @author Pauli Anttila - Migration to OH2
|
||||
* @author Fabien Le Bars - Added support for Cherubini blinds
|
||||
*/
|
||||
public class RFXComBlinds1Message extends RFXComBatteryDeviceMessage<RFXComBlinds1Message.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
T0(0), // Hasta new/RollerTrol
|
||||
T1(1),
|
||||
T2(2),
|
||||
T3(3),
|
||||
T4(4), // Additional commands.
|
||||
T5(5), // MEDIA MOUNT have different direction commands than the rest!! Needs to be fixed.
|
||||
T6(6),
|
||||
T7(7),
|
||||
T8(8), // Chamberlain CS4330
|
||||
T9(9), // Sunpery/BTX
|
||||
T10(10), // Dolat DLM-1, Topstar
|
||||
T11(11), // ASP
|
||||
T12(12), // Confexx CNF24-2435
|
||||
T13(13), // Screenline
|
||||
T18(18); // Cherubini
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Commands implements ByteEnumWrapper {
|
||||
OPEN(0), // MediaMount DOWN(0),
|
||||
CLOSE(1), // MediaMount UPP(1),
|
||||
STOP(2),
|
||||
CONFIRM(3),
|
||||
SET_LIMIT(4), // YR1326 SET_UPPER_LIMIT(4),
|
||||
SET_LOWER_LIMIT(5), // YR1326
|
||||
DELETE_LIMITS(6), // YR1326
|
||||
CHANGE_DIRECTON(7); // YR1326
|
||||
|
||||
private final int command;
|
||||
|
||||
Commands(int command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) command;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public byte unitCode;
|
||||
public Commands command;
|
||||
|
||||
public RFXComBlinds1Message() {
|
||||
super(PacketType.BLINDS1);
|
||||
}
|
||||
|
||||
public RFXComBlinds1Message(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + getDeviceId();
|
||||
str += ", Command = " + command;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
str += ", Battery level = " + batteryLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
|
||||
if (subType == SubType.T6) {
|
||||
sensorId = (data[4] & 0xFF) << 20 | (data[5] & 0xFF) << 12 | (data[6] & 0xFF) << 4 | (data[7] & 0xF0) >> 4;
|
||||
unitCode = (byte) (data[7] & 0x0F);
|
||||
} else {
|
||||
sensorId = (data[4] & 0xFF) << 16 | (data[5] & 0xFF) << 8 | (data[6] & 0xFF);
|
||||
unitCode = data[7];
|
||||
}
|
||||
|
||||
command = fromByte(Commands.class, data[8]);
|
||||
|
||||
signalLevel = (byte) ((data[9] & 0xF0) >> 4);
|
||||
batteryLevel = (byte) (data[9] & 0x0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
// Example data
|
||||
// BLINDS1 09 19 00 06 00 B1 8F 01 00 70
|
||||
|
||||
byte[] data = new byte[10];
|
||||
|
||||
data[0] = 0x09;
|
||||
data[1] = RFXComBaseMessage.PacketType.BLINDS1.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
|
||||
if (subType == SubType.T6) {
|
||||
data[4] = (byte) ((sensorId >>> 20) & 0xFF);
|
||||
data[5] = (byte) ((sensorId >>> 12) & 0xFF);
|
||||
data[6] = (byte) ((sensorId >>> 4) & 0xFF);
|
||||
data[7] = (byte) (((sensorId & 0x0F) << 4) | (unitCode & 0x0F));
|
||||
} else {
|
||||
data[4] = (byte) ((sensorId >> 16) & 0xFF);
|
||||
data[5] = (byte) ((sensorId >> 8) & 0xFF);
|
||||
data[6] = (byte) (sensorId & 0xFF);
|
||||
data[7] = unitCode;
|
||||
}
|
||||
|
||||
data[8] = command.toByte();
|
||||
data[9] = (byte) (((signalLevel & 0x0F) << 4) | (batteryLevel & 0x0F));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return sensorId + ID_DELIMITER + unitCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
if (CHANNEL_COMMAND.equals(channelId)) {
|
||||
return (command == Commands.CLOSE ? OpenClosedType.CLOSED : OpenClosedType.OPEN);
|
||||
} else {
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) throws RFXComException {
|
||||
String[] ids = deviceId.split("\\" + ID_DELIMITER);
|
||||
if (ids.length != 2) {
|
||||
throw new RFXComException("Invalid device id '" + deviceId + "'");
|
||||
}
|
||||
|
||||
sensorId = Integer.parseInt(ids[0]);
|
||||
unitCode = Byte.parseByte(ids[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
if (CHANNEL_SHUTTER.equals(channelId)) {
|
||||
if (type instanceof OpenClosedType) {
|
||||
command = (type == OpenClosedType.CLOSED ? Commands.CLOSE : Commands.OPEN);
|
||||
} else if (type instanceof UpDownType) {
|
||||
command = (type == UpDownType.UP ? Commands.OPEN : Commands.CLOSE);
|
||||
} else if (type instanceof StopMoveType) {
|
||||
command = Commands.STOP;
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.CHANNEL_CHIME_SOUND;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DecimalType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for chime messages.
|
||||
*
|
||||
* @author Mike Jagdis - Initial contribution
|
||||
*/
|
||||
public class RFXComChimeMessage extends RFXComDeviceMessageImpl<RFXComChimeMessage.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
BYRONSX(0),
|
||||
BYRONMP001(1),
|
||||
SELECTPLUS(2),
|
||||
SELECTPLUS3(3),
|
||||
ENVIVO(4);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public int chimeSound;
|
||||
|
||||
public RFXComChimeMessage() {
|
||||
super(PacketType.CHIME);
|
||||
}
|
||||
|
||||
public RFXComChimeMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + getDeviceId();
|
||||
str += ", Chime Sound = " + chimeSound;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
|
||||
switch (subType) {
|
||||
case BYRONSX:
|
||||
sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
|
||||
chimeSound = data[6];
|
||||
break;
|
||||
case BYRONMP001:
|
||||
case SELECTPLUS:
|
||||
case SELECTPLUS3:
|
||||
case ENVIVO:
|
||||
sensorId = (data[4] & 0xFF) << 16 | (data[5] & 0xFF) << 8 | (data[6] & 0xFF);
|
||||
chimeSound = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
signalLevel = (byte) ((data[7] & 0xF0) >> 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[8];
|
||||
|
||||
data[0] = 0x07;
|
||||
data[1] = getPacketType().toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
|
||||
switch (subType) {
|
||||
case BYRONSX:
|
||||
data[4] = (byte) ((sensorId & 0xFF00) >> 8);
|
||||
data[5] = (byte) (sensorId & 0x00FF);
|
||||
data[6] = (byte) chimeSound;
|
||||
break;
|
||||
case BYRONMP001:
|
||||
case SELECTPLUS:
|
||||
case SELECTPLUS3:
|
||||
case ENVIVO:
|
||||
data[4] = (byte) ((sensorId & 0xFF0000) >> 16);
|
||||
data[5] = (byte) ((sensorId & 0x00FF00) >> 8);
|
||||
data[6] = (byte) ((sensorId & 0x0000FF));
|
||||
break;
|
||||
}
|
||||
|
||||
data[7] = (byte) ((signalLevel & 0x0F) << 4);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
if (CHANNEL_CHIME_SOUND.equals(channelId)) {
|
||||
return new DecimalType(chimeSound);
|
||||
} else {
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String sensorId) {
|
||||
this.sensorId = Integer.parseInt(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
if (CHANNEL_CHIME_SOUND.equals(channelId)) {
|
||||
if (type instanceof DecimalType) {
|
||||
chimeSound = ((DecimalType) type).intValue();
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DecimalType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for Current and Energy message.
|
||||
*
|
||||
* @author Damien Servant - Initial contribution
|
||||
*/
|
||||
public class RFXComCurrentEnergyMessage extends RFXComBatteryDeviceMessage<RFXComCurrentEnergyMessage.SubType> {
|
||||
private static final float TOTAL_USAGE_CONVERSION_FACTOR = 223.666F;
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
ELEC4(1); // OWL - CM180i
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public byte count;
|
||||
public double channel1Amps;
|
||||
public double channel2Amps;
|
||||
public double channel3Amps;
|
||||
public double totalUsage;
|
||||
|
||||
public RFXComCurrentEnergyMessage() {
|
||||
super(PacketType.CURRENT_ENERGY);
|
||||
}
|
||||
|
||||
public RFXComCurrentEnergyMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Id = " + sensorId;
|
||||
str += ", Count = " + count;
|
||||
str += ", Channel1 Amps = " + channel1Amps;
|
||||
str += ", Channel2 Amps = " + channel2Amps;
|
||||
str += ", Channel3 Amps = " + channel3Amps;
|
||||
str += ", Total Usage = " + totalUsage;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
str += ", Battery level = " + batteryLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
|
||||
count = data[6];
|
||||
|
||||
// Current = Field / 10
|
||||
channel1Amps = ((data[7] & 0xFF) << 8 | (data[8] & 0xFF)) / 10.0;
|
||||
channel2Amps = ((data[9] & 0xFF) << 8 | (data[10] & 0xFF)) / 10.0;
|
||||
channel3Amps = ((data[11] & 0xFF) << 8 | (data[12] & 0xFF)) / 10.0;
|
||||
|
||||
totalUsage = ((long) (data[13] & 0xFF) << 40 | (long) (data[14] & 0xFF) << 32 | (data[15] & 0xFF) << 24
|
||||
| (data[16] & 0xFF) << 16 | (data[17] & 0xFF) << 8 | (data[18] & 0xFF));
|
||||
totalUsage = totalUsage / TOTAL_USAGE_CONVERSION_FACTOR;
|
||||
|
||||
signalLevel = (byte) ((data[19] & 0xF0) >> 4);
|
||||
batteryLevel = (byte) (data[19] & 0x0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[20];
|
||||
|
||||
data[0] = (byte) (data.length - 1);
|
||||
data[1] = RFXComBaseMessage.PacketType.CURRENT_ENERGY.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
|
||||
data[4] = (byte) ((sensorId & 0xFF00) >> 8);
|
||||
data[5] = (byte) (sensorId & 0x00FF);
|
||||
data[6] = count;
|
||||
|
||||
data[7] = (byte) (((int) (channel1Amps * 10.0) >> 8) & 0xFF);
|
||||
data[8] = (byte) ((int) (channel1Amps * 10.0) & 0xFF);
|
||||
data[9] = (byte) (((int) (channel2Amps * 10.0) >> 8) & 0xFF);
|
||||
data[10] = (byte) ((int) (channel2Amps * 10.0) & 0xFF);
|
||||
data[11] = (byte) (((int) (channel3Amps * 10.0) >> 8) & 0xFF);
|
||||
data[12] = (byte) ((int) (channel3Amps * 10.0) & 0xFF);
|
||||
|
||||
long totalUsageLoc = (long) (totalUsage * TOTAL_USAGE_CONVERSION_FACTOR);
|
||||
|
||||
data[13] = (byte) ((totalUsageLoc >> 40) & 0xFF);
|
||||
data[14] = (byte) ((totalUsageLoc >> 32) & 0xFF);
|
||||
data[15] = (byte) ((totalUsageLoc >> 24) & 0xFF);
|
||||
data[16] = (byte) ((totalUsageLoc >> 16) & 0xFF);
|
||||
data[17] = (byte) ((totalUsageLoc >> 8) & 0xFF);
|
||||
data[18] = (byte) (totalUsageLoc & 0xFF);
|
||||
|
||||
data[19] = (byte) (((signalLevel & 0x0F) << 4) | (batteryLevel & 0x0F));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_CHANNEL1_AMPS:
|
||||
return new DecimalType(channel1Amps);
|
||||
|
||||
case CHANNEL_CHANNEL2_AMPS:
|
||||
return new DecimalType(channel2Amps);
|
||||
|
||||
case CHANNEL_CHANNEL3_AMPS:
|
||||
return new DecimalType(channel3Amps);
|
||||
|
||||
case CHANNEL_TOTAL_USAGE:
|
||||
return new DecimalType(totalUsage);
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DecimalType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for current message.
|
||||
*
|
||||
* @author Ben Jones - Initial contribution
|
||||
* @author Pauli Anttila - for the Similar RFXComEnergyMessage code
|
||||
* @author Jordan Cook - Added support for CURRENT devices, such as OWL CM113
|
||||
* @author Martin van Wingerden - Updated CurrentMessage code to new style
|
||||
*/
|
||||
public class RFXComCurrentMessage extends RFXComBatteryDeviceMessage<RFXComCurrentMessage.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
ELEC1(1);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public byte count;
|
||||
public double channel1Amps;
|
||||
public double channel2Amps;
|
||||
public double channel3Amps;
|
||||
|
||||
public RFXComCurrentMessage() {
|
||||
super(PacketType.CURRENT);
|
||||
}
|
||||
|
||||
public RFXComCurrentMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + sensorId;
|
||||
str += ", Count = " + count;
|
||||
str += ", Channel 1 Amps = " + channel1Amps;
|
||||
str += ", Channel 2 Amps = " + channel2Amps;
|
||||
str += ", Channel 3 Amps = " + channel3Amps;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
str += ", Battery level = " + batteryLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
|
||||
sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
|
||||
count = data[6];
|
||||
|
||||
channel1Amps = ((data[7] & 0xFF) << 8 | (data[8] & 0xFF)) / 10.0;
|
||||
channel2Amps = ((data[9] & 0xFF) << 8 | (data[10] & 0xFF)) / 10.0;
|
||||
channel3Amps = ((data[11] & 0xFF) << 8 | (data[12] & 0xFF)) / 10.0;
|
||||
|
||||
signalLevel = (byte) ((data[13] & 0xF0) >> 4);
|
||||
batteryLevel = (byte) (data[13] & 0x0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[14];
|
||||
|
||||
data[0] = 0x0D;
|
||||
data[1] = PacketType.CURRENT.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
|
||||
data[4] = (byte) ((sensorId & 0xFF00) >> 8);
|
||||
data[5] = (byte) (sensorId & 0x00FF);
|
||||
data[6] = count;
|
||||
|
||||
data[7] = (byte) (((int) (channel1Amps * 10) >> 8) & 0xFF);
|
||||
data[8] = (byte) ((int) (channel1Amps * 10) & 0xFF);
|
||||
|
||||
data[9] = (byte) (((int) (channel2Amps * 10) >> 8) & 0xFF);
|
||||
data[10] = (byte) ((int) (channel2Amps * 10) & 0xFF);
|
||||
|
||||
data[11] = (byte) (((int) (channel3Amps * 10) >> 8) & 0xFF);
|
||||
data[12] = (byte) ((int) (channel3Amps * 10) & 0xFF);
|
||||
|
||||
data[13] = (byte) (((signalLevel & 0x0F) << 4) | (batteryLevel & 0x0F));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_CHANNEL1_AMPS:
|
||||
return new DecimalType(channel1Amps);
|
||||
|
||||
case CHANNEL_CHANNEL2_AMPS:
|
||||
return new DecimalType(channel2Amps);
|
||||
|
||||
case CHANNEL_CHANNEL3_AMPS:
|
||||
return new DecimalType(channel3Amps);
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.OpenClosedType;
|
||||
import org.openhab.core.library.types.StopMoveType;
|
||||
import org.openhab.core.library.types.UpDownType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for curtain1 message. See Harrison.
|
||||
*
|
||||
* @author Evert van Es - Initial contribution
|
||||
* @author Pauli Anttila - Migrated to OH2
|
||||
*/
|
||||
public class RFXComCurtain1Message extends RFXComBatteryDeviceMessage<RFXComCurtain1Message.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
HARRISON(0);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Commands implements ByteEnumWrapper {
|
||||
OPEN(0),
|
||||
CLOSE(1),
|
||||
STOP(2),
|
||||
PROGRAM(3);
|
||||
|
||||
private final int command;
|
||||
|
||||
Commands(int command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) command;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public char sensorId;
|
||||
public byte unitCode;
|
||||
public Commands command;
|
||||
|
||||
public RFXComCurtain1Message() {
|
||||
super(PacketType.CURTAIN1);
|
||||
}
|
||||
|
||||
public RFXComCurtain1Message(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + getDeviceId();
|
||||
str += ", Command = " + command;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
str += ", Battery level = " + batteryLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (char) data[4];
|
||||
unitCode = data[5];
|
||||
command = fromByte(Commands.class, data[6]);
|
||||
|
||||
signalLevel = (byte) ((data[7] & 0xF0) >> 4);
|
||||
batteryLevel = (byte) ((data[7] & 0x0F));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
// Example data 07 18 00 00 65 01 00 00
|
||||
// 07 18 00 00 65 02 00 00
|
||||
|
||||
byte[] data = new byte[8];
|
||||
|
||||
data[0] = 0x07;
|
||||
data[1] = 0x18;
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) sensorId;
|
||||
data[5] = unitCode;
|
||||
data[6] = command.toByte();
|
||||
data[7] = (byte) (((signalLevel & 0x0F) << 4) + batteryLevel);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return sensorId + ID_DELIMITER + unitCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
if (channelId.equals(CHANNEL_COMMAND)) {
|
||||
return (command == Commands.CLOSE ? OpenClosedType.CLOSED : OpenClosedType.OPEN);
|
||||
} else {
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) throws RFXComException {
|
||||
String[] ids = deviceId.split("\\" + ID_DELIMITER);
|
||||
if (ids.length != 2) {
|
||||
throw new RFXComException("Invalid device id '" + deviceId + "'");
|
||||
}
|
||||
|
||||
sensorId = ids[0].charAt(0);
|
||||
unitCode = Byte.parseByte(ids[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
if (channelId.equals(CHANNEL_SHUTTER)) {
|
||||
if (type instanceof OpenClosedType) {
|
||||
command = (type == OpenClosedType.CLOSED ? Commands.CLOSE : Commands.OPEN);
|
||||
} else if (type instanceof UpDownType) {
|
||||
command = (type == UpDownType.UP ? Commands.CLOSE : Commands.OPEN);
|
||||
} else if (type instanceof StopMoveType) {
|
||||
command = Commands.STOP;
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.CHANNEL_DATE_TIME;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DateTimeType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for Date and Time message.
|
||||
*
|
||||
* @author Damien Servant - Initial contribution
|
||||
*/
|
||||
public class RFXComDateTimeMessage extends RFXComBatteryDeviceMessage<RFXComDateTimeMessage.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
RTGR328N(1);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
String dateTime;
|
||||
private int year;
|
||||
private int month;
|
||||
private int day;
|
||||
private int dayOfWeek;
|
||||
private int hour;
|
||||
private int minute;
|
||||
private int second;
|
||||
|
||||
public RFXComDateTimeMessage() {
|
||||
super(PacketType.DATE_TIME);
|
||||
}
|
||||
|
||||
public RFXComDateTimeMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = super.toString();
|
||||
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Id = " + sensorId;
|
||||
str += ", Date Time = " + dateTime;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
str += ", Battery level = " + batteryLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
|
||||
sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
|
||||
|
||||
year = data[6] & 0xFF;
|
||||
month = data[7] & 0xFF;
|
||||
day = data[8] & 0xFF;
|
||||
dayOfWeek = data[9] & 0xFF;
|
||||
hour = data[10] & 0xFF;
|
||||
minute = data[11] & 0xFF;
|
||||
second = data[12] & 0xFF;
|
||||
|
||||
dateTime = String.format("20%02d-%02d-%02dT%02d:%02d:%02d", year, month, day, hour, minute, second);
|
||||
|
||||
signalLevel = (byte) ((data[13] & 0xF0) >> 4);
|
||||
batteryLevel = (byte) (data[13] & 0x0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[14];
|
||||
|
||||
data[0] = (byte) (data.length - 1);
|
||||
data[1] = RFXComBaseMessage.PacketType.DATE_TIME.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) ((sensorId & 0xFF00) >> 8);
|
||||
data[5] = (byte) (sensorId & 0x00FF);
|
||||
data[6] = (byte) (year & 0x00FF);
|
||||
data[7] = (byte) (month & 0x00FF);
|
||||
data[8] = (byte) (day & 0x00FF);
|
||||
data[9] = (byte) (dayOfWeek & 0x00FF);
|
||||
data[10] = (byte) (hour & 0x00FF);
|
||||
data[11] = (byte) (minute & 0x00FF);
|
||||
data[12] = (byte) (second & 0x00FF);
|
||||
data[13] = (byte) (((signalLevel & 0x0F) << 4) | (batteryLevel & 0x0F));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
if (channelId.equals(CHANNEL_DATE_TIME)) {
|
||||
return new DateTimeType(dateTime);
|
||||
} else {
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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 org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration;
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
|
||||
/**
|
||||
* An interface for message about devices, so interface message do not (have to) implement this
|
||||
*
|
||||
* @author Martin van Wingerden - Initial contribution
|
||||
*/
|
||||
public interface RFXComDeviceMessage<T> extends RFXComMessage {
|
||||
/**
|
||||
* Procedure for converting RFXCOM value to openHAB command.
|
||||
*
|
||||
* @param channelId id of the channel
|
||||
* @param deviceState
|
||||
* @return openHAB command.
|
||||
* @throws RFXComUnsupportedChannelException if the channel is not supported
|
||||
*/
|
||||
Command convertToCommand(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException;
|
||||
|
||||
/**
|
||||
* Procedure for converting RFXCOM value to openHAB state.
|
||||
*
|
||||
* @param channelId id of the channel
|
||||
* @param deviceState
|
||||
* @return openHAB state.
|
||||
* @throws RFXComUnsupportedChannelException if the channel is not supported
|
||||
*/
|
||||
State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException;
|
||||
|
||||
/**
|
||||
* Procedure to get device id.
|
||||
*
|
||||
* @return device Id.
|
||||
*/
|
||||
String getDeviceId();
|
||||
|
||||
/**
|
||||
* Get the packet type for this device message
|
||||
*
|
||||
* @return the message its packet type
|
||||
*/
|
||||
RFXComBaseMessage.PacketType getPacketType();
|
||||
|
||||
/**
|
||||
* Given a DiscoveryResultBuilder add any new properties to the builder for the given message
|
||||
*
|
||||
* @param discoveryResultBuilder existing builder containing some early details
|
||||
* @throws RFXComException
|
||||
*/
|
||||
void addDevicePropertiesTo(DiscoveryResultBuilder discoveryResultBuilder) throws RFXComException;
|
||||
|
||||
/**
|
||||
* Procedure for converting sub type as string to sub type object.
|
||||
*
|
||||
* @param subType
|
||||
* @return sub type object.
|
||||
* @throws RFXComUnsupportedValueException if the given subType cannot be converted
|
||||
*/
|
||||
T convertSubType(String subType) throws RFXComUnsupportedValueException;
|
||||
|
||||
/**
|
||||
* Procedure to set sub type.
|
||||
*
|
||||
* @param subType
|
||||
*/
|
||||
void setSubType(T subType);
|
||||
|
||||
/**
|
||||
* Procedure to set device id.
|
||||
*
|
||||
* @param deviceId
|
||||
* @throws RFXComException
|
||||
*/
|
||||
void setDeviceId(String deviceId) throws RFXComException;
|
||||
|
||||
/**
|
||||
* Set the config to be applied to this message
|
||||
*
|
||||
* @param config
|
||||
* @throws RFXComException
|
||||
*/
|
||||
@Override
|
||||
void setConfig(RFXComDeviceConfiguration config) throws RFXComException;
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.CHANNEL_SIGNAL_LEVEL;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration;
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedChannelException;
|
||||
import org.openhab.binding.rfxcom.internal.handler.DeviceState;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
|
||||
/**
|
||||
* A base class for all device messages, so this is not about things as interface messages
|
||||
*
|
||||
* @author Martin van Wingerden - Initial contribution
|
||||
*/
|
||||
abstract class RFXComDeviceMessageImpl<T> extends RFXComBaseMessage implements RFXComDeviceMessage<T> {
|
||||
byte signalLevel;
|
||||
|
||||
RFXComDeviceMessageImpl(PacketType packetType) {
|
||||
super(packetType);
|
||||
}
|
||||
|
||||
RFXComDeviceMessageImpl() {
|
||||
// deliberately empty
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfig(RFXComDeviceConfiguration config) throws RFXComException {
|
||||
this.setSubType(convertSubType(config.subType));
|
||||
this.setDeviceId(config.deviceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Command convertToCommand(String channelId, DeviceState deviceState)
|
||||
throws RFXComUnsupportedChannelException {
|
||||
return (Command) convertToState(channelId, deviceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_SIGNAL_LEVEL:
|
||||
return convertSignalLevelToSystemWideLevel(signalLevel);
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Nothing relevant for " + channelId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDevicePropertiesTo(DiscoveryResultBuilder discoveryResultBuilder) throws RFXComException {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert internal signal level (0-15) to system wide signal level (0-4).
|
||||
*
|
||||
* @param signalLevel Internal signal level
|
||||
* @return Signal level in system wide level
|
||||
*/
|
||||
private State convertSignalLevelToSystemWideLevel(int signalLevel) {
|
||||
int newLevel;
|
||||
|
||||
/*
|
||||
* RFXCOM signal levels are always between 0-15.
|
||||
*
|
||||
* Use switch case to make level adaption easier in future if needed.
|
||||
*/
|
||||
|
||||
switch (signalLevel) {
|
||||
case 0:
|
||||
case 1:
|
||||
newLevel = 0;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
newLevel = 1;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
newLevel = 2;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
newLevel = 3;
|
||||
break;
|
||||
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
default:
|
||||
newLevel = 4;
|
||||
}
|
||||
|
||||
return new DecimalType(newLevel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DecimalType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for energy message.
|
||||
*
|
||||
* @author Unknown - Initial contribution
|
||||
* @author Pauli Anttila
|
||||
*/
|
||||
public class RFXComEnergyMessage extends RFXComBatteryDeviceMessage<RFXComEnergyMessage.SubType> {
|
||||
|
||||
private static final double TOTAL_USAGE_CONVERSION_FACTOR = 223.666d;
|
||||
private static final double WATTS_TO_AMPS_CONVERSION_FACTOR = 230d;
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
ELEC2(1),
|
||||
ELEC3(2);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public byte count;
|
||||
public double instantAmp;
|
||||
public double totalAmpHour;
|
||||
public double instantPower;
|
||||
public double totalUsage;
|
||||
|
||||
public RFXComEnergyMessage() {
|
||||
super(PacketType.ENERGY);
|
||||
}
|
||||
|
||||
public RFXComEnergyMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + getDeviceId();
|
||||
str += ", Count = " + count;
|
||||
str += ", Instant Amps = " + instantAmp;
|
||||
str += ", Total Amp Hours = " + totalAmpHour;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
str += ", Battery level = " + batteryLevel;
|
||||
str += ", Instant Power = " + instantPower;
|
||||
str += ", Total Usage = " + totalUsage;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
|
||||
count = data[6];
|
||||
|
||||
// all usage is reported in Watts based on 230V
|
||||
instantPower = ((data[7] & 0xFF) << 24 | (data[8] & 0xFF) << 16 | (data[9] & 0xFF) << 8 | (data[10] & 0xFF));
|
||||
totalUsage = ((long) (data[11] & 0xFF) << 40 | (long) (data[12] & 0xFF) << 32 | (data[13] & 0xFF) << 24
|
||||
| (data[14] & 0xFF) << 16 | (data[15] & 0xFF) << 8 | (data[16] & 0xFF)) / TOTAL_USAGE_CONVERSION_FACTOR;
|
||||
|
||||
// convert to amps so external code can determine the watts based on local voltage
|
||||
instantAmp = instantPower / WATTS_TO_AMPS_CONVERSION_FACTOR;
|
||||
totalAmpHour = totalUsage / WATTS_TO_AMPS_CONVERSION_FACTOR;
|
||||
|
||||
signalLevel = (byte) ((data[17] & 0xF0) >> 4);
|
||||
batteryLevel = (byte) (data[17] & 0x0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[18];
|
||||
|
||||
data[0] = 0x11;
|
||||
data[1] = RFXComBaseMessage.PacketType.ENERGY.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
|
||||
data[4] = (byte) ((sensorId & 0xFF00) >> 8);
|
||||
data[5] = (byte) (sensorId & 0x00FF);
|
||||
data[6] = count;
|
||||
|
||||
// convert our 'amp' values back into Watts since this is what comes back
|
||||
long instantUsage = (long) (instantAmp * WATTS_TO_AMPS_CONVERSION_FACTOR);
|
||||
long totalUsage = (long) (totalAmpHour * WATTS_TO_AMPS_CONVERSION_FACTOR * TOTAL_USAGE_CONVERSION_FACTOR);
|
||||
|
||||
data[7] = (byte) ((instantUsage >> 24) & 0xFF);
|
||||
data[8] = (byte) ((instantUsage >> 16) & 0xFF);
|
||||
data[9] = (byte) ((instantUsage >> 8) & 0xFF);
|
||||
data[10] = (byte) (instantUsage & 0xFF);
|
||||
|
||||
data[11] = (byte) ((totalUsage >> 40) & 0xFF);
|
||||
data[12] = (byte) ((totalUsage >> 32) & 0xFF);
|
||||
data[13] = (byte) ((totalUsage >> 24) & 0xFF);
|
||||
data[14] = (byte) ((totalUsage >> 16) & 0xFF);
|
||||
data[15] = (byte) ((totalUsage >> 8) & 0xFF);
|
||||
data[16] = (byte) (totalUsage & 0xFF);
|
||||
|
||||
data[17] = (byte) (((signalLevel & 0x0F) << 4) | (batteryLevel & 0x0F));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_INSTANT_POWER:
|
||||
return new DecimalType(instantPower);
|
||||
|
||||
case CHANNEL_TOTAL_USAGE:
|
||||
return new DecimalType(totalUsage);
|
||||
|
||||
case CHANNEL_INSTANT_AMPS:
|
||||
return new DecimalType(instantAmp);
|
||||
|
||||
case CHANNEL_TOTAL_AMP_HOUR:
|
||||
return new DecimalType(totalAmpHour);
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,444 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.RFXComFanMessage.Commands.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.RFXComFanMessage.SubType.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DecimalType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.library.types.UpDownType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for fan message.
|
||||
*
|
||||
* @author Martin van Wingerden - initial contribution
|
||||
*/
|
||||
public class RFXComFanMessage extends RFXComDeviceMessageImpl<RFXComFanMessage.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
SF01(0),
|
||||
CVE_RFT(1),
|
||||
LUCCI_AIR_FAN(2),
|
||||
SEAV_TXS4(3),
|
||||
WESTINGHOUSE_7226640(4),
|
||||
LUCCI_AIR_DC(5),
|
||||
CASAFAN(6),
|
||||
FT1211R(7),
|
||||
FALMEC(8),
|
||||
LUCCI_AIR_DC_II(9);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Commands implements ByteEnumWrapperWithSupportedSubTypes<SubType> {
|
||||
HI(1, WESTINGHOUSE_7226640, CASAFAN, LUCCI_AIR_FAN),
|
||||
MED(2, WESTINGHOUSE_7226640, CASAFAN, LUCCI_AIR_FAN),
|
||||
LOW(3, WESTINGHOUSE_7226640, CASAFAN, LUCCI_AIR_FAN),
|
||||
OFF(4, WESTINGHOUSE_7226640, CASAFAN, LUCCI_AIR_FAN),
|
||||
LIGHT(5, WESTINGHOUSE_7226640, CASAFAN, LUCCI_AIR_FAN),
|
||||
|
||||
FALMEC_POWER_OFF(1, 0, FALMEC),
|
||||
FALMEC_SPEED_1(2, 1, FALMEC),
|
||||
FALMEC_SPEED_2(3, 2, FALMEC),
|
||||
FALMEC_SPEED_3(4, 3, FALMEC),
|
||||
FALMEC_SPEED_4(5, 4, FALMEC),
|
||||
FALMEC_TIMER_1(6, FALMEC),
|
||||
FALMEC_TIMER_2(7, FALMEC),
|
||||
FALMEC_TIMER_3(8, FALMEC),
|
||||
FALMEC_TIMER_4(9, FALMEC),
|
||||
FALMEC_LIGHT_ON(10, FALMEC),
|
||||
FALMEC_LIGHT_OFF(11, FALMEC),
|
||||
|
||||
FT1211R_POWER(1, 0, FT1211R),
|
||||
FT1211R_LIGHT(2, FT1211R),
|
||||
FT1211R_SPEED_1(3, 1, FT1211R),
|
||||
FT1211R_SPEED_2(4, 2, FT1211R),
|
||||
FT1211R_SPEED_3(5, 3, FT1211R),
|
||||
FT1211R_SPEED_4(6, 4, FT1211R),
|
||||
FT1211R_SPEED_5(7, 5, FT1211R),
|
||||
FT1211R_FORWARD_REVERSE(8, FT1211R),
|
||||
FT1211R_TIMER_1H(9, FT1211R),
|
||||
FT1211R_TIMER_4H(10, FT1211R),
|
||||
FT1211R_TIMER_8H(11, FT1211R),
|
||||
|
||||
LUCCI_AIR_DC_POWER(1, LUCCI_AIR_DC),
|
||||
LUCCI_AIR_DC_UP(2, LUCCI_AIR_DC),
|
||||
LUCCI_AIR_DC_DOWN(3, LUCCI_AIR_DC),
|
||||
LUCCI_AIR_DC_LIGHT(4, LUCCI_AIR_DC),
|
||||
LUCCI_AIR_DC_REVERSE(5, LUCCI_AIR_DC),
|
||||
LUCCI_AIR_DC_NATURAL_FLOW(6, LUCCI_AIR_DC),
|
||||
LUCCI_AIR_DC_PAIR(7, LUCCI_AIR_DC),
|
||||
|
||||
LUCCI_AIR_DC_II_POWER_OFF(1, 0, LUCCI_AIR_DC_II),
|
||||
LUCCI_AIR_DC_II_SPEED_1(2, 1, LUCCI_AIR_DC_II),
|
||||
LUCCI_AIR_DC_II_SPEED_2(3, 2, LUCCI_AIR_DC_II),
|
||||
LUCCI_AIR_DC_II_SPEED_3(4, 3, LUCCI_AIR_DC_II),
|
||||
LUCCI_AIR_DC_II_SPEED_4(5, 4, LUCCI_AIR_DC_II),
|
||||
LUCCI_AIR_DC_II_SPEED_5(6, 5, LUCCI_AIR_DC_II),
|
||||
LUCCI_AIR_DC_II_SPEED_6(7, 6, LUCCI_AIR_DC_II),
|
||||
LUCCI_AIR_DC_II_LIGHT(8, LUCCI_AIR_DC_II),
|
||||
LUCCI_AIR_DC_II_REVERSE(9, LUCCI_AIR_DC_II);
|
||||
|
||||
private final int command;
|
||||
private final Integer speed;
|
||||
private final List<SubType> supportedBySubTypes;
|
||||
|
||||
Commands(int command, SubType... supportedSubType) {
|
||||
this(command, null, supportedSubType);
|
||||
}
|
||||
|
||||
Commands(int command, Integer speed, SubType... supportedSubType) {
|
||||
this.command = command;
|
||||
this.speed = speed;
|
||||
this.supportedBySubTypes = Arrays.asList(supportedSubType);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Commands bySpeed(SubType subType, int speed) {
|
||||
for (Commands value : values()) {
|
||||
if (value.supportedBySubTypes.contains(subType) && value.speed == speed) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) command;
|
||||
}
|
||||
|
||||
public Integer getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SubType> supportedBySubTypes() {
|
||||
return supportedBySubTypes;
|
||||
}
|
||||
}
|
||||
|
||||
private static final List<SubType> GENERIC_SUB_TYPES = Arrays.asList(WESTINGHOUSE_7226640, CASAFAN, LUCCI_AIR_FAN);
|
||||
|
||||
private static final List<Commands> LIGHT_ON_COMMANDS = Arrays.asList(LIGHT, LUCCI_AIR_DC_LIGHT,
|
||||
LUCCI_AIR_DC_II_LIGHT, FALMEC_LIGHT_ON);
|
||||
private static final List<Commands> ON_COMMANDS = Arrays.asList(Commands.HI, MED, LOW, FALMEC_SPEED_1,
|
||||
FALMEC_SPEED_2, FALMEC_SPEED_3, FALMEC_SPEED_4, LUCCI_AIR_DC_II_SPEED_1, LUCCI_AIR_DC_II_SPEED_2,
|
||||
LUCCI_AIR_DC_II_SPEED_3, LUCCI_AIR_DC_II_SPEED_4, LUCCI_AIR_DC_II_SPEED_5, LUCCI_AIR_DC_II_SPEED_6);
|
||||
private static final List<Commands> OFF_COMMANDS = Arrays.asList(OFF, FALMEC_POWER_OFF, LUCCI_AIR_DC_II_POWER_OFF);
|
||||
|
||||
private SubType subType;
|
||||
private int sensorId;
|
||||
private Commands command;
|
||||
|
||||
public RFXComFanMessage() {
|
||||
super(PacketType.FAN);
|
||||
}
|
||||
|
||||
public RFXComFanMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketType getPacketType() {
|
||||
switch (subType) {
|
||||
case LUCCI_AIR_FAN:
|
||||
case CASAFAN:
|
||||
case WESTINGHOUSE_7226640:
|
||||
return PacketType.FAN;
|
||||
case SF01:
|
||||
return PacketType.FAN_SF01;
|
||||
case CVE_RFT:
|
||||
return PacketType.FAN_ITHO;
|
||||
case SEAV_TXS4:
|
||||
return PacketType.FAN_SEAV;
|
||||
case LUCCI_AIR_DC:
|
||||
return PacketType.FAN_LUCCI_DC;
|
||||
case FT1211R:
|
||||
return PacketType.FAN_FT1211R;
|
||||
case FALMEC:
|
||||
return PacketType.FAN_FALMEC;
|
||||
case LUCCI_AIR_DC_II:
|
||||
return PacketType.FAN_LUCCI_DC_II;
|
||||
}
|
||||
return super.getPacketType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (data[4] & 0xFF) << 16 | (data[5] & 0xFF) << 8 | (data[6] & 0xFF);
|
||||
command = fromByte(Commands.class, data[7], subType);
|
||||
|
||||
signalLevel = (byte) (data[8] & 0x0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[9];
|
||||
|
||||
data[0] = 0x08;
|
||||
data[1] = PacketType.FAN.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
|
||||
data[4] = (byte) ((sensorId >> 16) & 0xFF);
|
||||
data[5] = (byte) ((sensorId >> 8) & 0xFF);
|
||||
data[6] = (byte) (sensorId & 0xFF);
|
||||
|
||||
data[7] = command.toByte();
|
||||
|
||||
data[8] = (byte) (signalLevel & 0x0F);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
sensorId = Integer.parseInt(deviceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_FAN_LIGHT:
|
||||
return handleLightChannel();
|
||||
|
||||
case CHANNEL_FAN_SPEED:
|
||||
return handleFanSpeedChannel();
|
||||
|
||||
case CHANNEL_COMMAND:
|
||||
return handleCommandChannel();
|
||||
|
||||
case CHANNEL_COMMAND_STRING:
|
||||
return handleCommandStringChannel();
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
private State handleCommandStringChannel() {
|
||||
if (command == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return StringType.valueOf(command.toString().replace(subType.name() + "_", ""));
|
||||
}
|
||||
|
||||
private State handleLightChannel() {
|
||||
if (LIGHT_ON_COMMANDS.contains(command)) {
|
||||
return OnOffType.ON;
|
||||
} else if (command == Commands.FALMEC_LIGHT_OFF) {
|
||||
return OnOffType.OFF;
|
||||
} else {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
}
|
||||
|
||||
private State handleFanSpeedChannel() {
|
||||
switch (command) {
|
||||
case HI:
|
||||
case MED:
|
||||
case LOW:
|
||||
case OFF:
|
||||
return StringType.valueOf(command.toString());
|
||||
|
||||
case FALMEC_POWER_OFF:
|
||||
case FALMEC_SPEED_1:
|
||||
case FALMEC_SPEED_2:
|
||||
case FALMEC_SPEED_3:
|
||||
case FALMEC_SPEED_4:
|
||||
case FT1211R_POWER:
|
||||
case FT1211R_SPEED_1:
|
||||
case FT1211R_SPEED_2:
|
||||
case FT1211R_SPEED_3:
|
||||
case FT1211R_SPEED_4:
|
||||
case FT1211R_SPEED_5:
|
||||
case LUCCI_AIR_DC_II_POWER_OFF:
|
||||
case LUCCI_AIR_DC_II_SPEED_1:
|
||||
case LUCCI_AIR_DC_II_SPEED_2:
|
||||
case LUCCI_AIR_DC_II_SPEED_3:
|
||||
case LUCCI_AIR_DC_II_SPEED_4:
|
||||
case LUCCI_AIR_DC_II_SPEED_5:
|
||||
case LUCCI_AIR_DC_II_SPEED_6:
|
||||
return new DecimalType(command.getSpeed());
|
||||
|
||||
case LUCCI_AIR_DC_DOWN:
|
||||
return UpDownType.DOWN;
|
||||
|
||||
case LUCCI_AIR_DC_UP:
|
||||
return UpDownType.UP;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private State handleCommandChannel() {
|
||||
if (ON_COMMANDS.contains(command)) {
|
||||
return OnOffType.ON;
|
||||
} else if (OFF_COMMANDS.contains(command)) {
|
||||
return OnOffType.OFF;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_COMMAND:
|
||||
command = handleCommand(channelId, type);
|
||||
break;
|
||||
|
||||
case CHANNEL_FAN_SPEED:
|
||||
command = handleFanSpeedCommand(channelId, type);
|
||||
break;
|
||||
|
||||
case CHANNEL_FAN_LIGHT:
|
||||
command = handleFanLightCommand(channelId, type);
|
||||
break;
|
||||
|
||||
case CHANNEL_COMMAND_STRING:
|
||||
command = handleCommandString(channelId, type);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
|
||||
}
|
||||
}
|
||||
|
||||
private Commands handleCommandString(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
if (type instanceof StringType) {
|
||||
String stringCommand = type.toString();
|
||||
switch (stringCommand) {
|
||||
case "POWER":
|
||||
case "POWER_OFF":
|
||||
case "UP":
|
||||
case "DOWN":
|
||||
case "LIGHT":
|
||||
case "REVERSE":
|
||||
case "NATURAL_FLOW":
|
||||
case "PAIR":
|
||||
case "SPEED_1":
|
||||
case "SPEED_2":
|
||||
case "SPEED_3":
|
||||
case "SPEED_4":
|
||||
case "SPEED_5":
|
||||
case "SPEED_6":
|
||||
return Commands.valueOf(subType.name() + "_" + stringCommand);
|
||||
}
|
||||
}
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
|
||||
private Commands handleCommand(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
if (type instanceof OnOffType) {
|
||||
if (GENERIC_SUB_TYPES.contains(subType)) {
|
||||
return (type == OnOffType.ON ? Commands.MED : Commands.OFF);
|
||||
} else if (subType == FALMEC) {
|
||||
return (type == OnOffType.ON ? Commands.FALMEC_SPEED_2 : Commands.FALMEC_POWER_OFF);
|
||||
} else if (subType == LUCCI_AIR_DC_II) {
|
||||
return (type == OnOffType.ON ? LUCCI_AIR_DC_II_SPEED_3 : LUCCI_AIR_DC_II_POWER_OFF);
|
||||
}
|
||||
}
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
|
||||
private Commands handleFanSpeedCommand(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
if (type instanceof StringType) {
|
||||
String stringCommand = type.toString();
|
||||
switch (stringCommand) {
|
||||
case "HI":
|
||||
case "MED":
|
||||
case "LOW":
|
||||
case "OFF":
|
||||
return Commands.valueOf(stringCommand);
|
||||
}
|
||||
} else if (type instanceof DecimalType) {
|
||||
Commands speedCommand = Commands.bySpeed(subType, ((DecimalType) type).intValue());
|
||||
if (speedCommand != null) {
|
||||
return speedCommand;
|
||||
}
|
||||
} else if (type instanceof UpDownType && subType == LUCCI_AIR_DC) {
|
||||
if (UpDownType.UP == type) {
|
||||
return Commands.LUCCI_AIR_DC_UP;
|
||||
} else {
|
||||
return Commands.LUCCI_AIR_DC_DOWN;
|
||||
}
|
||||
}
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
|
||||
private Commands handleFanLightCommand(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
if (type == OnOffType.ON) {
|
||||
switch (subType) {
|
||||
case LUCCI_AIR_FAN:
|
||||
case CASAFAN:
|
||||
case WESTINGHOUSE_7226640:
|
||||
case LUCCI_AIR_DC:
|
||||
return LIGHT;
|
||||
|
||||
case FALMEC:
|
||||
return FALMEC_LIGHT_ON;
|
||||
|
||||
case LUCCI_AIR_DC_II:
|
||||
return LUCCI_AIR_DC_II_LIGHT;
|
||||
}
|
||||
} else if (type == OnOffType.OFF && subType == FALMEC) {
|
||||
return Commands.FALMEC_LIGHT_OFF;
|
||||
}
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.CHANNEL_COMMAND;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for HomeConfort message.
|
||||
*
|
||||
* @author Mike Jagdis - Initial contribution
|
||||
*/
|
||||
public class RFXComHomeConfortMessage extends RFXComDeviceMessageImpl<RFXComHomeConfortMessage.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
TEL_010(0);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Commands implements ByteEnumWrapper {
|
||||
OFF(0),
|
||||
ON(1),
|
||||
GROUP_OFF(2),
|
||||
GROUP_ON(3);
|
||||
|
||||
private final int command;
|
||||
|
||||
Commands(int command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) command;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int deviceId;
|
||||
public char houseCode;
|
||||
public byte unitCode;
|
||||
public Commands command;
|
||||
|
||||
public RFXComHomeConfortMessage() {
|
||||
super(PacketType.HOME_CONFORT);
|
||||
}
|
||||
|
||||
public RFXComHomeConfortMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + ", Sub type = " + subType + ", Device Id = " + getDeviceId() + ", Command = "
|
||||
+ command + ", Signal level = " + signalLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
deviceId = (((data[4] << 8) | data[5]) << 8) | data[6];
|
||||
houseCode = (char) data[7];
|
||||
unitCode = data[8];
|
||||
command = fromByte(Commands.class, data[9]);
|
||||
if (command == Commands.GROUP_ON || command == Commands.GROUP_OFF) {
|
||||
unitCode = 0;
|
||||
}
|
||||
signalLevel = (byte) ((data[12] & 0xF0) >> 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[13];
|
||||
|
||||
data[0] = 0x0C;
|
||||
data[1] = PacketType.HOME_CONFORT.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) ((deviceId >> 16) & 0xff);
|
||||
data[5] = (byte) ((deviceId >> 8) & 0xff);
|
||||
data[6] = (byte) (deviceId & 0xff);
|
||||
data[7] = (byte) houseCode;
|
||||
data[8] = unitCode;
|
||||
data[9] = command.toByte();
|
||||
data[10] = 0;
|
||||
data[11] = 0;
|
||||
data[12] = (byte) ((signalLevel & 0x0F) << 4);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return deviceId + ID_DELIMITER + houseCode + ID_DELIMITER + unitCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
if (channelId.equals(CHANNEL_COMMAND)) {
|
||||
return (command == Commands.OFF || command == Commands.GROUP_OFF ? OnOffType.OFF : OnOffType.ON);
|
||||
} else {
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) throws RFXComException {
|
||||
String[] ids = deviceId.split("\\" + ID_DELIMITER);
|
||||
if (ids.length != 3) {
|
||||
throw new RFXComException("Invalid device id '" + deviceId + "'");
|
||||
}
|
||||
|
||||
this.deviceId = Integer.parseInt(ids[0]);
|
||||
houseCode = ids[1].charAt(0);
|
||||
unitCode = Byte.parseByte(ids[2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
if (CHANNEL_COMMAND.equals(channelId)) {
|
||||
if (type instanceof OnOffType) {
|
||||
if (unitCode == 0) {
|
||||
command = (type == OnOffType.ON ? Commands.GROUP_ON : Commands.GROUP_OFF);
|
||||
|
||||
} else {
|
||||
command = (type == OnOffType.ON ? Commands.ON : Commands.OFF);
|
||||
}
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DecimalType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for humidity message.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public class RFXComHumidityMessage extends RFXComBatteryDeviceMessage<RFXComHumidityMessage.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
HUM1(1),
|
||||
HUM2(2),
|
||||
HUM3(3);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public enum HumidityStatus implements ByteEnumWrapper {
|
||||
NORMAL(0),
|
||||
COMFORT(1),
|
||||
DRY(2),
|
||||
WET(3);
|
||||
|
||||
private final int humidityStatus;
|
||||
|
||||
HumidityStatus(int humidityStatus) {
|
||||
this.humidityStatus = humidityStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) humidityStatus;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public byte humidity;
|
||||
public HumidityStatus humidityStatus;
|
||||
|
||||
public RFXComHumidityMessage() {
|
||||
super(PacketType.HUMIDITY);
|
||||
}
|
||||
|
||||
public RFXComHumidityMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + getDeviceId();
|
||||
str += ", Humidity = " + humidity;
|
||||
str += ", Humidity status = " + humidityStatus;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
str += ", Battery level = " + batteryLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
|
||||
humidity = data[6];
|
||||
humidityStatus = fromByte(HumidityStatus.class, data[7]);
|
||||
signalLevel = (byte) ((data[8] & 0xF0) >> 4);
|
||||
batteryLevel = (byte) (data[8] & 0x0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[9];
|
||||
|
||||
data[0] = 0x08;
|
||||
data[1] = RFXComBaseMessage.PacketType.HUMIDITY.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) ((sensorId & 0xFF00) >> 8);
|
||||
data[5] = (byte) (sensorId & 0x00FF);
|
||||
data[6] = humidity;
|
||||
data[7] = humidityStatus.toByte();
|
||||
data[8] = (byte) (((signalLevel & 0x0F) << 4) | (batteryLevel & 0x0F));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_HUMIDITY:
|
||||
return new DecimalType(humidity);
|
||||
|
||||
case CHANNEL_HUMIDITY_STATUS:
|
||||
return new StringType(humidityStatus.toString());
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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 org.openhab.binding.rfxcom.internal.config.RFXComBridgeConfiguration;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for control message.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
* @author Mike Jagdis
|
||||
*/
|
||||
public class RFXComInterfaceControlMessage extends RFXComBaseMessage {
|
||||
private byte[] data = new byte[14];
|
||||
|
||||
public RFXComInterfaceControlMessage(RFXComInterfaceMessage.TransceiverType transceiverType,
|
||||
RFXComBridgeConfiguration configuration) {
|
||||
data[0] = 0x0D;
|
||||
data[1] = RFXComBaseMessage.PacketType.INTERFACE_CONTROL.toByte();
|
||||
data[2] = 0;
|
||||
data[3] = 2;
|
||||
data[4] = RFXComInterfaceMessage.Commands.SET_MODE.toByte();
|
||||
data[5] = transceiverType.toByte();
|
||||
data[6] = (byte) (configuration.transmitPower + 18);
|
||||
|
||||
//@formatter:off
|
||||
data[7] = (byte) (
|
||||
(configuration.enableUndecoded ? 0x80 : 0x00)
|
||||
| (configuration.enableImagintronixOpus ? 0x40 : 0x00)
|
||||
| (configuration.enableByronSX ? 0x20 : 0x00)
|
||||
| (configuration.enableRSL ? 0x10 : 0x00)
|
||||
| (configuration.enableLighting4 ? 0x08 : 0x00)
|
||||
| (configuration.enableFineOffsetViking ? 0x04 : 0x00)
|
||||
| (configuration.enableRubicson ? 0x02 : 0x00)
|
||||
| (configuration.enableAEBlyss ? 0x01 : 0x00));
|
||||
|
||||
data[8] = (byte) (
|
||||
(configuration.enableBlindsT1T2T3T4 ? 0x80 : 0x00)
|
||||
| (configuration.enableBlindsT0 ? 0x40 : 0x00)
|
||||
| (configuration.enableProGuard ? 0x20 : 0x00)
|
||||
| (configuration.enableFS20 ? 0x10 : 0x00)
|
||||
| (configuration.enableLaCrosse ? 0x08 : 0x00)
|
||||
| (configuration.enableHidekiUPM ? 0x04 : 0x00)
|
||||
| (configuration.enableADLightwaveRF ? 0x02 : 0x00)
|
||||
| (configuration.enableMertik ? 0x01 : 0x00));
|
||||
|
||||
data[9] = (byte) (
|
||||
(configuration.enableVisonic ? 0x80 : 0x00)
|
||||
| (configuration.enableATI ? 0x40 : 0x00)
|
||||
| (configuration.enableOregonScientific ? 0x20 : 0x00)
|
||||
| (configuration.enableMeiantech ? 0x10 : 0x00)
|
||||
| (configuration.enableHomeEasyEU ? 0x08 : 0x00)
|
||||
| (configuration.enableAC ? 0x04 : 0x00)
|
||||
| (configuration.enableARC ? 0x02 : 0x00)
|
||||
| (configuration.enableX10 ? 0x01 : 0x00));
|
||||
|
||||
data[10] = (byte) (
|
||||
(configuration.enableHomeConfort ? 0x02 : 0x00)
|
||||
| (configuration.enableKEELOQ ? 0x01 : 0x00));
|
||||
|
||||
data[11] = 0;
|
||||
data[12] = 0;
|
||||
data[13] = 0;
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
public RFXComInterfaceControlMessage(byte[] data) {
|
||||
// We should never receive control messages
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for interface message.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
* @author Ivan Martinez - Older firmware support (OH1)
|
||||
*/
|
||||
public class RFXComInterfaceMessage extends RFXComBaseMessage {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
UNKNOWN_COMMAND(-1),
|
||||
RESPONSE(0),
|
||||
UNKNOWN_RTS_REMOTE(1),
|
||||
NO_EXTENDED_HW_PRESENT(2),
|
||||
LIST_RFY_REMOTES(3),
|
||||
LIST_ASA_REMOTES(4),
|
||||
START_RECEIVER(7);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Commands implements ByteEnumWrapper {
|
||||
RESET(0), // Reset the receiver/transceiver. No answer is transmitted!
|
||||
GET_STATUS(2), // Get Status, return firmware versions and configuration of the interface
|
||||
SET_MODE(3), // Set mode msg1-msg5, return firmware versions and configuration of the interface
|
||||
ENABLE_ALL(4), // Enable all receiving modes of the receiver/transceiver
|
||||
ENABLE_UNDECODED_PACKETS(5), // Enable reporting of undecoded packets
|
||||
SAVE_RECEIVING_MODES(6), // Save receiving modes of the receiver/transceiver in non-volatile memory
|
||||
START_RECEIVER(7), // Start RFXtrx receiver
|
||||
T1(8), // For internal use by RFXCOM
|
||||
T2(9), // For internal use by RFXCOM
|
||||
|
||||
UNSUPPORTED_COMMAND(-1); // wrong command received from the application
|
||||
|
||||
private final int command;
|
||||
|
||||
Commands(int command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) command;
|
||||
}
|
||||
}
|
||||
|
||||
public enum TransceiverType implements ByteEnumWrapper {
|
||||
_310MHZ(80),
|
||||
_315MHZ(81),
|
||||
_433_92MHZ_RECEIVER_ONLY(82),
|
||||
_433_92MHZ_TRANSCEIVER(83),
|
||||
_868_00MHZ(85),
|
||||
_868_00MHZ_FSK(86),
|
||||
_868_30MHZ(87),
|
||||
_868_30MHZ_FSK(88),
|
||||
_868_35MHZ(89),
|
||||
_868_35MHZ_FSK(90),
|
||||
_868_95MHZ_FSK(91);
|
||||
|
||||
private final int type;
|
||||
|
||||
TransceiverType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) type;
|
||||
}
|
||||
}
|
||||
|
||||
public enum FirmwareType implements ByteEnumWrapper {
|
||||
TYPE1_RX_ONLY(0),
|
||||
TYPE1(1),
|
||||
TYPE2(2),
|
||||
EXT(3),
|
||||
EXT2(4);
|
||||
|
||||
private final int type;
|
||||
|
||||
FirmwareType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) type;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public Commands command;
|
||||
public String text = "";
|
||||
|
||||
public TransceiverType transceiverType;
|
||||
public int firmwareVersion;
|
||||
|
||||
public boolean enableUndecodedPackets; // 0x80 - Undecoded packets
|
||||
public boolean enableImagintronixOpusPackets; // 0x40 - Imagintronix/Opus (433.92)
|
||||
public boolean enableByronSXPackets; // 0x20 - Byron SX (433.92)
|
||||
public boolean enableRSLPackets; // 0x10 - RSL (433.92)
|
||||
public boolean enableLighting4Packets; // 0x08 - Lighting4 (433.92)
|
||||
public boolean enableFineOffsetPackets; // 0x04 - FineOffset / Viking (433.92)
|
||||
public boolean enableRubicsonPackets; // 0x02 - Rubicson (433.92)
|
||||
public boolean enableAEPackets; // 0x01 - AE (433.92)
|
||||
|
||||
public boolean enableBlindsT1T2T3T4Packets; // 0x80 - BlindsT1/T2/T3/T4 (433.92)
|
||||
public boolean enableBlindsT0Packets; // 0x40 - BlindsT0 (433.92)
|
||||
public boolean enableProGuardPackets; // 0x20 - ProGuard (868.35 FSK)
|
||||
public boolean enableFS20Packets; // 0x10 - FS20 (868.35)
|
||||
public boolean enableLaCrossePackets; // 0x08 - La Crosse (433.92/868.30)
|
||||
public boolean enableHidekiUPMPackets; // 0x04 - Hideki/UPM (433.92)
|
||||
public boolean enableADPackets; // 0x02 - AD LightwaveRF (433.92)
|
||||
public boolean enableMertikPackets; // 0x01 - Mertik (433.92)
|
||||
|
||||
public boolean enableVisonicPackets; // 0x80 - Visonic (315/868.95)
|
||||
public boolean enableATIPackets; // 0x40 - ATI (433.92)
|
||||
public boolean enableOregonPackets; // 0x20 - Oregon Scientific (433.92)
|
||||
public boolean enableMeiantechPackets; // 0x10 - Meiantech (433.92)
|
||||
public boolean enableHomeEasyPackets; // 0x08 - HomeEasy EU (433.92)
|
||||
public boolean enableACPackets; // 0x04 - AC (433.92)
|
||||
public boolean enableARCPackets; // 0x02 - ARC (433.92)
|
||||
public boolean enableX10Packets; // 0x01 - X10 (310/433.92)
|
||||
|
||||
public boolean enableHomeConfortPackets; // 0x02 - HomeConfort (433.92)
|
||||
public boolean enableKEELOQPackets; // 0x01 - KEELOQ (433.92)
|
||||
|
||||
public byte hardwareVersion1;
|
||||
public byte hardwareVersion2;
|
||||
|
||||
public int outputPower; // -18dBm to +13dBm. N.B. maximum allowed is +10dBm
|
||||
|
||||
public FirmwareType firmwareType;
|
||||
|
||||
public RFXComInterfaceMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Command = " + command;
|
||||
|
||||
if (subType == SubType.RESPONSE) {
|
||||
str += ", Transceiver type = " + transceiverType;
|
||||
str += ", Hardware version = " + hardwareVersion1 + "." + hardwareVersion2;
|
||||
str += ", Firmware type = " + (firmwareType != null ? firmwareType : "unknown");
|
||||
str += ", Firmware version = " + firmwareVersion;
|
||||
str += ", Output power = " + outputPower + "dBm";
|
||||
str += ", Undecoded packets = " + enableUndecodedPackets;
|
||||
str += ", RFU6 packets = " + enableImagintronixOpusPackets;
|
||||
str += ", Byron SX packets packets (433.92) = " + enableByronSXPackets;
|
||||
str += ", RSL packets packets (433.92) = " + enableRSLPackets;
|
||||
str += ", Lighting4 packets (433.92) = " + enableLighting4Packets;
|
||||
str += ", FineOffset / Viking (433.92) packets = " + enableFineOffsetPackets;
|
||||
str += ", Rubicson (433.92) packets = " + enableRubicsonPackets;
|
||||
str += ", AE (433.92) packets = " + enableAEPackets;
|
||||
|
||||
str += ", BlindsT1/T2/T3 (433.92) packets = " + enableBlindsT1T2T3T4Packets;
|
||||
str += ", BlindsT0 (433.92) packets = " + enableBlindsT0Packets;
|
||||
str += ", ProGuard (868.35 FSK) packets = " + enableProGuardPackets;
|
||||
str += ", FS20/Legrand CAD (868.35/433.92) packets = " + enableFS20Packets;
|
||||
str += ", La Crosse (433.92/868.30) packets = " + enableLaCrossePackets;
|
||||
str += ", Hideki/UPM (433.92) packets = " + enableHidekiUPMPackets;
|
||||
str += ", AD LightwaveRF (433.92) packets = " + enableADPackets;
|
||||
str += ", Mertik (433.92) packets = " + enableMertikPackets;
|
||||
|
||||
str += ", Visonic (315/868.95) packets = " + enableVisonicPackets;
|
||||
str += ", ATI (433.92) packets = " + enableATIPackets;
|
||||
str += ", Oregon Scientific (433.92) packets = " + enableOregonPackets;
|
||||
str += ", Meiantech (433.92) packets = " + enableMeiantechPackets;
|
||||
str += ", HomeEasy EU (433.92) packets = " + enableHomeEasyPackets;
|
||||
str += ", AC (433.92) packets = " + enableACPackets;
|
||||
str += ", ARC (433.92) packets = " + enableARCPackets;
|
||||
str += ", X10 (310/433.92) packets = " + enableX10Packets;
|
||||
|
||||
str += ", HomeConfort (433.92) packets = " + enableHomeConfortPackets;
|
||||
str += ", KEELOQ (433.92/868.95) packets = " + enableKEELOQPackets;
|
||||
} else if (subType == SubType.START_RECEIVER) {
|
||||
str += ", Text = " + text;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
|
||||
if (subType == SubType.RESPONSE) {
|
||||
command = fromByte(Commands.class, data[4]);
|
||||
transceiverType = fromByte(TransceiverType.class, data[5]);
|
||||
|
||||
firmwareVersion = data[6] & 0xFF;
|
||||
|
||||
enableUndecodedPackets = (data[7] & 0x80) != 0;
|
||||
enableImagintronixOpusPackets = (data[7] & 0x40) != 0;
|
||||
enableByronSXPackets = (data[7] & 0x20) != 0;
|
||||
enableRSLPackets = (data[7] & 0x10) != 0;
|
||||
enableLighting4Packets = (data[7] & 0x08) != 0;
|
||||
enableFineOffsetPackets = (data[7] & 0x04) != 0;
|
||||
enableRubicsonPackets = (data[7] & 0x02) != 0;
|
||||
enableAEPackets = (data[7] & 0x01) != 0;
|
||||
|
||||
enableBlindsT1T2T3T4Packets = (data[8] & 0x80) != 0;
|
||||
enableBlindsT0Packets = (data[8] & 0x40) != 0;
|
||||
enableProGuardPackets = (data[8] & 0x20) != 0;
|
||||
enableFS20Packets = (data[8] & 0x10) != 0;
|
||||
enableLaCrossePackets = (data[8] & 0x08) != 0;
|
||||
enableHidekiUPMPackets = (data[8] & 0x04) != 0;
|
||||
enableADPackets = (data[8] & 0x02) != 0;
|
||||
enableMertikPackets = (data[8] & 0x01) != 0;
|
||||
|
||||
enableVisonicPackets = (data[9] & 0x80) != 0;
|
||||
enableATIPackets = (data[9] & 0x40) != 0;
|
||||
enableOregonPackets = (data[9] & 0x20) != 0;
|
||||
enableMeiantechPackets = (data[9] & 0x10) != 0;
|
||||
enableHomeEasyPackets = (data[9] & 0x08) != 0;
|
||||
enableACPackets = (data[9] & 0x04) != 0;
|
||||
enableARCPackets = (data[9] & 0x02) != 0;
|
||||
enableX10Packets = (data[9] & 0x01) != 0;
|
||||
|
||||
/*
|
||||
* Different firmware versions have slightly different message formats.
|
||||
* The firmware version numbering is unique to each hardware version
|
||||
* but the location of the hardware version in the message is one of
|
||||
* those things whose position varies. So we have to just look at the
|
||||
* firmware version and pray. This condition below is taken from the
|
||||
* openhab1-addons binding.
|
||||
*/
|
||||
if ((firmwareVersion >= 95 && firmwareVersion <= 100) || (firmwareVersion >= 195 && firmwareVersion <= 200)
|
||||
|| (firmwareVersion >= 251)) {
|
||||
enableHomeConfortPackets = (data[10] & 0x02) != 0;
|
||||
enableKEELOQPackets = (data[10] & 0x01) != 0;
|
||||
|
||||
hardwareVersion1 = data[11];
|
||||
hardwareVersion2 = data[12];
|
||||
|
||||
outputPower = data[13] - 18;
|
||||
firmwareType = fromByte(FirmwareType.class, data[14]);
|
||||
} else {
|
||||
hardwareVersion1 = data[10];
|
||||
hardwareVersion2 = data[11];
|
||||
}
|
||||
|
||||
text = "";
|
||||
} else if (subType == SubType.START_RECEIVER) {
|
||||
command = fromByte(Commands.class, data[4]);
|
||||
|
||||
final int len = 16;
|
||||
final int dataOffset = 5;
|
||||
|
||||
byte[] byteArray = new byte[len];
|
||||
|
||||
for (int i = dataOffset; i < (dataOffset + len); i++) {
|
||||
byteArray[i - dataOffset] += data[i];
|
||||
}
|
||||
|
||||
text = new String(byteArray, StandardCharsets.US_ASCII);
|
||||
} else {
|
||||
// We don't handle the other subTypes but to avoid null pointer
|
||||
// exceptions we set command to something. It doesn't really
|
||||
// matter what but it may b printed in log messages so...
|
||||
command = Commands.UNSUPPORTED_COMMAND;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.IncreaseDecreaseType;
|
||||
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.Command;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for lighting1 message. See X10, ARC, etc..
|
||||
*
|
||||
* @author Evert van Es, Cycling Engineer - Initial contribution
|
||||
* @author Pauli Anttila
|
||||
*/
|
||||
public class RFXComLighting1Message extends RFXComDeviceMessageImpl<RFXComLighting1Message.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
X10(0),
|
||||
ARC(1),
|
||||
AB400D(2),
|
||||
WAVEMAN(3),
|
||||
EMW200(4),
|
||||
IMPULS(5),
|
||||
RISINGSUN(6),
|
||||
PHILIPS(7),
|
||||
ENERGENIE(8),
|
||||
ENERGENIE_5(9),
|
||||
COCO(10),
|
||||
HQ_COCO20(11);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Commands implements ByteEnumWrapper {
|
||||
OFF(0),
|
||||
ON(1),
|
||||
DIM(2),
|
||||
BRIGHT(3),
|
||||
GROUP_OFF(5),
|
||||
GROUP_ON(6),
|
||||
CHIME(7);
|
||||
|
||||
private final int command;
|
||||
|
||||
Commands(int command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) command;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public char houseCode;
|
||||
public byte unitCode;
|
||||
public Commands command;
|
||||
public boolean group;
|
||||
|
||||
private static byte[] lastUnit = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
public RFXComLighting1Message() {
|
||||
super(PacketType.LIGHTING1);
|
||||
}
|
||||
|
||||
public RFXComLighting1Message(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + getDeviceId();
|
||||
str += ", Command = " + command;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = ByteEnumUtil.fromByte(SubType.class, super.subType);
|
||||
houseCode = (char) data[4];
|
||||
command = ByteEnumUtil.fromByte(Commands.class, data[6]);
|
||||
|
||||
if ((command == Commands.GROUP_ON) || (command == Commands.GROUP_OFF)) {
|
||||
unitCode = 0;
|
||||
} else if ((data[5] == 0) && ((command == Commands.DIM) || (command == Commands.BRIGHT))) {
|
||||
// SS13 switches broadcast DIM/BRIGHT to X0 and the dimmers ignore
|
||||
// the message unless the last X<n> ON they saw was for them. So we
|
||||
// redirect an incoming broadcast DIM/BRIGHT to the correct item
|
||||
// based on the last X<n> we saw or sent.
|
||||
unitCode = lastUnit[(int) houseCode - (int) 'A'];
|
||||
} else {
|
||||
unitCode = data[5];
|
||||
if (command == Commands.ON) {
|
||||
lastUnit[(int) houseCode - (int) 'A'] = unitCode;
|
||||
}
|
||||
}
|
||||
|
||||
signalLevel = (byte) ((data[7] & 0xF0) >> 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
// Example data 07 10 01 00 42 01 01 70
|
||||
// 07 10 01 00 42 10 06 70
|
||||
|
||||
byte[] data = new byte[8];
|
||||
|
||||
data[0] = 0x07;
|
||||
data[1] = PacketType.LIGHTING1.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) houseCode;
|
||||
data[5] = unitCode;
|
||||
data[6] = command.toByte();
|
||||
data[7] = (byte) ((signalLevel & 0x0F) << 4);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return houseCode + ID_DELIMITER + unitCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Command convertToCommand(String channelId, DeviceState deviceState)
|
||||
throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_COMMAND:
|
||||
switch (command) {
|
||||
case OFF:
|
||||
case GROUP_OFF:
|
||||
return OnOffType.OFF;
|
||||
|
||||
case ON:
|
||||
case GROUP_ON:
|
||||
return OnOffType.ON;
|
||||
|
||||
case DIM:
|
||||
return IncreaseDecreaseType.DECREASE;
|
||||
|
||||
case BRIGHT:
|
||||
return IncreaseDecreaseType.INCREASE;
|
||||
|
||||
case CHIME:
|
||||
return OnOffType.ON;
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException(
|
||||
"Channel " + channelId + " does not accept " + command);
|
||||
}
|
||||
|
||||
default:
|
||||
return super.convertToCommand(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_COMMAND:
|
||||
switch (command) {
|
||||
case OFF:
|
||||
case GROUP_OFF:
|
||||
case DIM:
|
||||
return OnOffType.OFF;
|
||||
|
||||
case ON:
|
||||
case GROUP_ON:
|
||||
case BRIGHT:
|
||||
case CHIME:
|
||||
return OnOffType.ON;
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException(
|
||||
"Channel " + channelId + " does not accept " + command);
|
||||
}
|
||||
|
||||
case CHANNEL_COMMAND_STRING:
|
||||
return command == null ? UnDefType.UNDEF : StringType.valueOf(command.toString());
|
||||
|
||||
case CHANNEL_CONTACT:
|
||||
switch (command) {
|
||||
case OFF:
|
||||
case GROUP_OFF:
|
||||
case DIM:
|
||||
return OpenClosedType.CLOSED;
|
||||
|
||||
case ON:
|
||||
case GROUP_ON:
|
||||
case BRIGHT:
|
||||
case CHIME:
|
||||
return OpenClosedType.OPEN;
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException(
|
||||
"Channel " + channelId + " does not accept " + command);
|
||||
}
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) throws RFXComException {
|
||||
String[] ids = deviceId.split("\\" + ID_DELIMITER);
|
||||
if (ids.length != 2) {
|
||||
throw new RFXComException("Invalid device id '" + deviceId + "'");
|
||||
}
|
||||
|
||||
houseCode = ids[0].charAt(0);
|
||||
|
||||
// Get unitcode, 0 means group
|
||||
unitCode = Byte.parseByte(ids[1]);
|
||||
if (unitCode == 0) {
|
||||
unitCode = 1;
|
||||
group = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_COMMAND:
|
||||
if (type instanceof OnOffType) {
|
||||
if (group) {
|
||||
command = (type == OnOffType.ON ? Commands.GROUP_ON : Commands.GROUP_OFF);
|
||||
|
||||
} else {
|
||||
command = (type == OnOffType.ON ? Commands.ON : Commands.OFF);
|
||||
}
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
case CHANNEL_COMMAND_STRING:
|
||||
command = Commands.valueOf(type.toString().toUpperCase());
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.PacketType.LIGHTING2;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.RFXComLighting2Message.Commands.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.IncreaseDecreaseType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.OpenClosedType;
|
||||
import org.openhab.core.library.types.PercentType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for lighting2 message.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public class RFXComLighting2Message extends RFXComDeviceMessageImpl<RFXComLighting2Message.SubType> {
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
AC(0),
|
||||
HOME_EASY_EU(1),
|
||||
ANSLUT(2),
|
||||
KAMBROOK(3);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Commands implements ByteEnumWrapper {
|
||||
OFF(0),
|
||||
ON(1),
|
||||
SET_LEVEL(2),
|
||||
GROUP_OFF(3),
|
||||
GROUP_ON(4),
|
||||
SET_GROUP_LEVEL(5);
|
||||
|
||||
private final int command;
|
||||
|
||||
Commands(int command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) command;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public byte unitCode;
|
||||
public Commands command;
|
||||
public byte dimmingLevel;
|
||||
public boolean group;
|
||||
|
||||
public RFXComLighting2Message() {
|
||||
super(PacketType.LIGHTING2);
|
||||
}
|
||||
|
||||
public RFXComLighting2Message(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + getDeviceId();
|
||||
str += ", Command = " + command;
|
||||
str += ", Dim level = " + dimmingLevel;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (data[4] & 0xFF) << 24 | (data[5] & 0xFF) << 16 | (data[6] & 0xFF) << 8 | (data[7] & 0xFF);
|
||||
command = fromByte(Commands.class, data[9]);
|
||||
|
||||
if ((command == Commands.GROUP_ON) || (command == Commands.GROUP_OFF)) {
|
||||
unitCode = 0;
|
||||
} else {
|
||||
unitCode = data[8];
|
||||
}
|
||||
|
||||
dimmingLevel = data[10];
|
||||
signalLevel = (byte) ((data[11] & 0xF0) >> 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[12];
|
||||
|
||||
data[0] = 0x0B;
|
||||
data[1] = LIGHTING2.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) ((sensorId >> 24) & 0xFF);
|
||||
data[5] = (byte) ((sensorId >> 16) & 0xFF);
|
||||
data[6] = (byte) ((sensorId >> 8) & 0xFF);
|
||||
data[7] = (byte) (sensorId & 0xFF);
|
||||
|
||||
data[8] = unitCode;
|
||||
data[9] = command.toByte();
|
||||
data[10] = dimmingLevel;
|
||||
data[11] = (byte) ((signalLevel & 0x0F) << 4);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return sensorId + ID_DELIMITER + unitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a 0-15 scale value to a percent type.
|
||||
*
|
||||
* @param pt percent type to convert
|
||||
* @return converted value 0-15
|
||||
*/
|
||||
public static int getDimLevelFromPercentType(PercentType pt) {
|
||||
return pt.toBigDecimal().multiply(BigDecimal.valueOf(15))
|
||||
.divide(PercentType.HUNDRED.toBigDecimal(), 0, BigDecimal.ROUND_UP).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a 0-15 scale value to a percent type.
|
||||
*
|
||||
* @param value percent type to convert
|
||||
* @return converted value 0-15
|
||||
*/
|
||||
public static PercentType getPercentTypeFromDimLevel(int value) {
|
||||
value = Math.min(value, 15);
|
||||
|
||||
return new PercentType(BigDecimal.valueOf(value).multiply(BigDecimal.valueOf(100))
|
||||
.divide(BigDecimal.valueOf(15), 0, BigDecimal.ROUND_UP).intValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_DIMMING_LEVEL:
|
||||
return RFXComLighting2Message.getPercentTypeFromDimLevel(dimmingLevel);
|
||||
|
||||
case CHANNEL_COMMAND:
|
||||
switch (command) {
|
||||
case OFF:
|
||||
case GROUP_OFF:
|
||||
return OnOffType.OFF;
|
||||
|
||||
case ON:
|
||||
case GROUP_ON:
|
||||
return OnOffType.ON;
|
||||
|
||||
case SET_GROUP_LEVEL:
|
||||
case SET_LEVEL:
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Can't convert " + command + " for " + channelId);
|
||||
}
|
||||
|
||||
case CHANNEL_CONTACT:
|
||||
switch (command) {
|
||||
case OFF:
|
||||
case GROUP_OFF:
|
||||
return OpenClosedType.CLOSED;
|
||||
|
||||
case ON:
|
||||
case GROUP_ON:
|
||||
return OpenClosedType.OPEN;
|
||||
|
||||
case SET_GROUP_LEVEL:
|
||||
case SET_LEVEL:
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Can't convert " + command + " for " + channelId);
|
||||
}
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) throws RFXComException {
|
||||
String[] ids = deviceId.split("\\" + ID_DELIMITER);
|
||||
if (ids.length != 2) {
|
||||
throw new RFXComException("Invalid device id '" + deviceId + "'");
|
||||
}
|
||||
|
||||
sensorId = Integer.parseInt(ids[0]);
|
||||
|
||||
// Get unitcode, 0 means group
|
||||
unitCode = Byte.parseByte(ids[1]);
|
||||
if (unitCode == 0) {
|
||||
unitCode = 1;
|
||||
group = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_COMMAND:
|
||||
if (type instanceof OnOffType) {
|
||||
if (group) {
|
||||
command = (type == OnOffType.ON ? GROUP_ON : GROUP_OFF);
|
||||
|
||||
} else {
|
||||
command = (type == OnOffType.ON ? Commands.ON : Commands.OFF);
|
||||
}
|
||||
|
||||
dimmingLevel = 0;
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
case CHANNEL_DIMMING_LEVEL:
|
||||
if (type instanceof OnOffType) {
|
||||
command = (type == OnOffType.ON ? Commands.ON : Commands.OFF);
|
||||
dimmingLevel = 0;
|
||||
|
||||
} else if (type instanceof PercentType) {
|
||||
command = Commands.SET_LEVEL;
|
||||
dimmingLevel = (byte) getDimLevelFromPercentType((PercentType) type);
|
||||
|
||||
if (dimmingLevel == 0) {
|
||||
command = Commands.OFF;
|
||||
}
|
||||
} else if (type instanceof IncreaseDecreaseType) {
|
||||
command = Commands.SET_LEVEL;
|
||||
// Evert: I do not know how to get previous object state...
|
||||
dimmingLevel = 5;
|
||||
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,289 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration;
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.OpenClosedType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for lighting4 message.
|
||||
*
|
||||
* a Lighting4 Base command is composed of 24 bit DATA plus PULSE information
|
||||
*
|
||||
* DATA:
|
||||
* Code = 014554
|
||||
* S1- S24 = <0000 0001 0100 0101 0101> <0100>
|
||||
* first 20 are DeviceID last 4 are for Command
|
||||
*
|
||||
* PULSE:
|
||||
* default 350
|
||||
*
|
||||
* Tested on a PT2262 remote PlugIn module
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* Switch TESTout "TestOut" (All) {rfxcom=">83205.350:LIGHTING4.PT2262:Command"}
|
||||
* (SendCommand DeviceID(int).Pulse(int):LIGHTING4.Subtype:Command )
|
||||
*
|
||||
* Switch TESTin "TestIn" (All) {rfxcom="<83205:Command"}
|
||||
* (ReceiveCommand ON/OFF Command )
|
||||
*
|
||||
* @author Alessandro Ballini (ITA) - Initial contribution
|
||||
* @author Pauli Anttila - Migrated to OH2
|
||||
* @author Martin van Wingerden - Extended support for more complex PT2262 devices
|
||||
*/
|
||||
public class RFXComLighting4Message extends RFXComDeviceMessageImpl<RFXComLighting4Message.SubType> {
|
||||
// this logger is used from a static context, so is static as well
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RFXComLighting4Message.class);
|
||||
|
||||
private static final byte DEFAULT_OFF_COMMAND_ID = Commands.OFF_4.toByte();
|
||||
private static final byte DEFAULT_ON_COMMAND_ID = Commands.ON_1.toByte();
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
PT2262(0);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Commands implements ByteEnumWrapper {
|
||||
OFF_0(0, false),
|
||||
ON_1(1, true),
|
||||
OFF_2(2, false),
|
||||
ON_3(3, true),
|
||||
OFF_4(4, false),
|
||||
ON_5(5, true),
|
||||
ON_6(6, true),
|
||||
ON_7(7, true),
|
||||
ON_8(8, true),
|
||||
ON_9(9, true),
|
||||
ON_10(10, true),
|
||||
ON_11(11, true),
|
||||
ON_12(12, true),
|
||||
OFF_14(14, false),
|
||||
ON_15(15, true),
|
||||
UNKNOWN(-1, false);
|
||||
|
||||
private final int command;
|
||||
private final boolean on;
|
||||
|
||||
Commands(int command, boolean on) {
|
||||
this.command = command;
|
||||
this.on = on;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) command;
|
||||
}
|
||||
|
||||
public boolean isOn() {
|
||||
return on;
|
||||
}
|
||||
|
||||
public static Commands fromByte(int input) {
|
||||
for (Commands c : Commands.values()) {
|
||||
if (c.command == input) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
LOGGER.info(
|
||||
"A not completely supported command with value {} was received, we can send it but please report "
|
||||
+ "it as an issue including what the command means, this helps to extend the binding with better support.",
|
||||
input);
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
private SubType subType;
|
||||
private int sensorId;
|
||||
private int pulse;
|
||||
private Commands command;
|
||||
private int commandId;
|
||||
private int offCommandId;
|
||||
private int onCommandId;
|
||||
|
||||
public RFXComLighting4Message() {
|
||||
super(PacketType.LIGHTING4);
|
||||
}
|
||||
|
||||
public RFXComLighting4Message(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + getDeviceId();
|
||||
str += ", Command = " + command + "(" + commandId + ")";
|
||||
str += ", Pulse = " + pulse;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (data[4] & 0xFF) << 12 | (data[5] & 0xFF) << 4 | (data[6] & 0xF0) >> 4;
|
||||
|
||||
commandId = (data[6] & 0x0F);
|
||||
command = Commands.fromByte(commandId);
|
||||
onCommandId = command.isOn() ? commandId : DEFAULT_ON_COMMAND_ID;
|
||||
offCommandId = command.isOn() ? DEFAULT_OFF_COMMAND_ID : commandId;
|
||||
|
||||
pulse = (data[7] & 0xFF) << 8 | (data[8] & 0xFF);
|
||||
|
||||
signalLevel = (byte) ((data[9] & 0xF0) >> 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[10];
|
||||
|
||||
data[0] = 0x09;
|
||||
data[1] = PacketType.LIGHTING4.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
|
||||
// SENSOR_ID + COMMAND
|
||||
data[4] = (byte) ((sensorId >> 12) & 0xFF);
|
||||
data[5] = (byte) ((sensorId >> 4) & 0xFF);
|
||||
data[6] = (byte) ((sensorId << 4 & 0xF0) | (commandId & 0x0F));
|
||||
|
||||
// PULSE
|
||||
data[7] = (byte) (pulse >> 8 & 0xFF);
|
||||
data[8] = (byte) (pulse & 0xFF);
|
||||
|
||||
// SIGNAL
|
||||
data[9] = (byte) ((signalLevel & 0x0F) << 4);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_COMMAND:
|
||||
case CHANNEL_MOTION:
|
||||
return command.isOn() ? OnOffType.ON : OnOffType.OFF;
|
||||
|
||||
case CHANNEL_CONTACT:
|
||||
return command.isOn() ? OpenClosedType.OPEN : OpenClosedType.CLOSED;
|
||||
|
||||
case CHANNEL_COMMAND_ID:
|
||||
return new DecimalType(commandId);
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
sensorId = Integer.parseInt(deviceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_COMMAND:
|
||||
if (type instanceof OnOffType) {
|
||||
command = Commands.fromByte(type == OnOffType.ON ? onCommandId : offCommandId);
|
||||
commandId = command.toByte();
|
||||
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
case CHANNEL_COMMAND_ID:
|
||||
if (type instanceof DecimalType) {
|
||||
commandId = ((DecimalType) type).toBigDecimal().byteValue();
|
||||
command = Commands.fromByte(commandId);
|
||||
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDevicePropertiesTo(DiscoveryResultBuilder discoveryResultBuilder) throws RFXComException {
|
||||
super.addDevicePropertiesTo(discoveryResultBuilder);
|
||||
discoveryResultBuilder.withProperty(PULSE_LABEL, pulse);
|
||||
discoveryResultBuilder.withProperty(ON_COMMAND_ID_LABEL, onCommandId);
|
||||
discoveryResultBuilder.withProperty(OFF_COMMAND_ID_LABEL, offCommandId);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
private int valueOrDefault(Integer commandId, byte defaultValue) {
|
||||
if (commandId != null) {
|
||||
return commandId;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,363 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.RFXComLighting5Message.SubType.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DecimalType;
|
||||
import org.openhab.core.library.types.IncreaseDecreaseType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.OpenClosedType;
|
||||
import org.openhab.core.library.types.PercentType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for lighting5 message.
|
||||
*
|
||||
* @author Paul Hampson, Neil Renaud - Initial contribution
|
||||
* @author Pauli Anttila
|
||||
* @author Martin van Wingerden - added support for IT and some other subtypes
|
||||
*/
|
||||
public class RFXComLighting5Message extends RFXComDeviceMessageImpl<RFXComLighting5Message.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
LIGHTWAVERF(0),
|
||||
EMW100(1),
|
||||
BBSB_NEW(2),
|
||||
MDREMOTE(3),
|
||||
CONRAD_RSL2(4),
|
||||
LIVOLO(5),
|
||||
RGB_TRC02(6),
|
||||
AOKE(7),
|
||||
RGB_TRC02_2(8),
|
||||
EURODOMEST(9),
|
||||
LIVOLO_APPLIANCE(10),
|
||||
MDREMOTE_107(12),
|
||||
AVANTEK(14),
|
||||
IT(15),
|
||||
MDREMOTE_108(16),
|
||||
KANGTAI(17);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: for the lighting5 commands, some command are only supported for certain sub types and
|
||||
* command-bytes might even have a different meaning for another sub type.
|
||||
*
|
||||
* If no sub types are specified for a command, its supported by all sub types.
|
||||
* An example is the command OFF which is represented by the byte 0x00 for all subtypes.
|
||||
*
|
||||
* Otherwise the list of sub types after the command-bytes indicates the sub types
|
||||
* which support this command with this byte.
|
||||
* Example byte value 0x03 means GROUP_ON for IT and some others while it means MOOD1 for LIGHTWAVERF
|
||||
*/
|
||||
public enum Commands implements ByteEnumWrapperWithSupportedSubTypes<SubType> {
|
||||
OFF(0x00),
|
||||
ON(0x01),
|
||||
GROUP_OFF(0x02, LIGHTWAVERF, BBSB_NEW, CONRAD_RSL2, EURODOMEST, AVANTEK, IT, KANGTAI),
|
||||
LEARN(0x02, EMW100),
|
||||
GROUP_ON(0x03, BBSB_NEW, CONRAD_RSL2, EURODOMEST, AVANTEK, IT, KANGTAI),
|
||||
MOOD1(0x03, LIGHTWAVERF),
|
||||
MOOD2(0x04, LIGHTWAVERF),
|
||||
MOOD3(0x05, LIGHTWAVERF),
|
||||
MOOD4(0x06, LIGHTWAVERF),
|
||||
MOOD5(0x07, LIGHTWAVERF),
|
||||
RESERVED1(0x08, LIGHTWAVERF),
|
||||
RESERVED2(0x09, LIGHTWAVERF),
|
||||
UNLOCK(0x0A, LIGHTWAVERF),
|
||||
LOCK(0x0B, LIGHTWAVERF),
|
||||
ALL_LOCK(0x0C, LIGHTWAVERF),
|
||||
CLOSE_RELAY(0x0D, LIGHTWAVERF),
|
||||
STOP_RELAY(0x0E, LIGHTWAVERF),
|
||||
OPEN_RELAY(0x0F, LIGHTWAVERF),
|
||||
SET_LEVEL(0x10, LIGHTWAVERF, IT),
|
||||
COLOUR_PALETTE(0x11, LIGHTWAVERF),
|
||||
COLOUR_TONE(0x12, LIGHTWAVERF),
|
||||
COLOUR_CYCLE(0x13, LIGHTWAVERF),
|
||||
TOGGLE_1(0x01, LIVOLO_APPLIANCE),
|
||||
TOGGLE_2(0x02, LIVOLO_APPLIANCE),
|
||||
TOGGLE_3(0x03, LIVOLO_APPLIANCE),
|
||||
TOGGLE_4(0x04, LIVOLO_APPLIANCE),
|
||||
TOGGLE_5(0x07, LIVOLO_APPLIANCE),
|
||||
TOGGLE_6(0x0B, LIVOLO_APPLIANCE),
|
||||
TOGGLE_7(0x06, LIVOLO_APPLIANCE),
|
||||
TOGGLE_8(0x0A, LIVOLO_APPLIANCE),
|
||||
TOGGLE_9(0x05, LIVOLO_APPLIANCE);
|
||||
|
||||
private final int command;
|
||||
private final List<SubType> supportedBySubTypes;
|
||||
|
||||
Commands(int command) {
|
||||
this(command, SubType.values());
|
||||
}
|
||||
|
||||
Commands(int command, SubType... supportedBySubTypes) {
|
||||
this.command = command;
|
||||
this.supportedBySubTypes = Arrays.asList(supportedBySubTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SubType> supportedBySubTypes() {
|
||||
return supportedBySubTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) command;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public byte unitCode;
|
||||
public Commands command;
|
||||
public byte dimmingLevel;
|
||||
|
||||
public RFXComLighting5Message() {
|
||||
super(PacketType.LIGHTING5);
|
||||
}
|
||||
|
||||
public RFXComLighting5Message(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + getDeviceId();
|
||||
str += ", Command = " + command;
|
||||
str += ", Dim level = " + dimmingLevel;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
|
||||
sensorId = (data[4] & 0xFF) << 16 | (data[5] & 0xFF) << 8 | (data[6] & 0xFF);
|
||||
unitCode = data[7];
|
||||
|
||||
command = fromByte(Commands.class, data[8], subType);
|
||||
|
||||
dimmingLevel = data[9];
|
||||
signalLevel = (byte) ((data[10] & 0xF0) >> 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[11];
|
||||
|
||||
data[0] = 0x0A;
|
||||
data[1] = RFXComBaseMessage.PacketType.LIGHTING5.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) ((sensorId >> 16) & 0xFF);
|
||||
data[5] = (byte) ((sensorId >> 8) & 0xFF);
|
||||
data[6] = (byte) (sensorId & 0xFF);
|
||||
|
||||
data[7] = unitCode;
|
||||
data[8] = command.toByte();
|
||||
data[9] = dimmingLevel;
|
||||
data[10] = (byte) ((signalLevel & 0x0F) << 4);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return sensorId + ID_DELIMITER + unitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a 0-31 scale value to a percent type.
|
||||
*
|
||||
* @param pt percent type to convert
|
||||
* @return converted value 0-31
|
||||
*/
|
||||
public static int getDimLevelFromPercentType(PercentType pt) {
|
||||
return pt.toBigDecimal().multiply(BigDecimal.valueOf(31))
|
||||
.divide(PercentType.HUNDRED.toBigDecimal(), 0, BigDecimal.ROUND_UP).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a 0-31 scale value to a percent type.
|
||||
*
|
||||
* @param value percent type to convert
|
||||
* @return converted value 0-31
|
||||
*/
|
||||
public static PercentType getPercentTypeFromDimLevel(int value) {
|
||||
value = Math.min(value, 31);
|
||||
|
||||
return new PercentType(BigDecimal.valueOf(value).multiply(BigDecimal.valueOf(100))
|
||||
.divide(BigDecimal.valueOf(31), 0, BigDecimal.ROUND_UP).intValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_MOOD:
|
||||
switch (command) {
|
||||
case GROUP_OFF:
|
||||
return new DecimalType(0);
|
||||
case MOOD1:
|
||||
return new DecimalType(1);
|
||||
case MOOD2:
|
||||
return new DecimalType(2);
|
||||
case MOOD3:
|
||||
return new DecimalType(3);
|
||||
case MOOD4:
|
||||
return new DecimalType(4);
|
||||
case MOOD5:
|
||||
return new DecimalType(5);
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException(
|
||||
"Unexpected mood command: " + command + " for " + channelId);
|
||||
}
|
||||
|
||||
case CHANNEL_DIMMING_LEVEL:
|
||||
return RFXComLighting5Message.getPercentTypeFromDimLevel(dimmingLevel);
|
||||
|
||||
case CHANNEL_COMMAND:
|
||||
switch (command) {
|
||||
case OFF:
|
||||
case GROUP_OFF:
|
||||
return OnOffType.OFF;
|
||||
|
||||
case ON:
|
||||
case GROUP_ON:
|
||||
return OnOffType.ON;
|
||||
|
||||
case SET_LEVEL:
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Can't convert " + command + " for " + channelId);
|
||||
}
|
||||
|
||||
case CHANNEL_COMMAND_STRING:
|
||||
return command == null ? UnDefType.UNDEF : StringType.valueOf(command.toString());
|
||||
|
||||
case CHANNEL_CONTACT:
|
||||
switch (command) {
|
||||
case OFF:
|
||||
case GROUP_OFF:
|
||||
return OpenClosedType.CLOSED;
|
||||
|
||||
case ON:
|
||||
case GROUP_ON:
|
||||
return OpenClosedType.OPEN;
|
||||
|
||||
case SET_LEVEL:
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Can't convert " + command + " for " + channelId);
|
||||
}
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) throws RFXComException {
|
||||
String[] ids = deviceId.split("\\" + ID_DELIMITER);
|
||||
if (ids.length != 2) {
|
||||
throw new RFXComException("Invalid device id '" + deviceId + "'");
|
||||
}
|
||||
|
||||
sensorId = Integer.parseInt(ids[0]);
|
||||
unitCode = Byte.parseByte(ids[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_COMMAND:
|
||||
if (type instanceof OnOffType) {
|
||||
command = (type == OnOffType.ON ? Commands.ON : Commands.OFF);
|
||||
dimmingLevel = 0;
|
||||
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
case CHANNEL_COMMAND_STRING:
|
||||
command = Commands.valueOf(type.toString().toUpperCase());
|
||||
break;
|
||||
|
||||
case CHANNEL_DIMMING_LEVEL:
|
||||
if (type instanceof OnOffType) {
|
||||
command = (type == OnOffType.ON ? Commands.ON : Commands.OFF);
|
||||
dimmingLevel = 0;
|
||||
|
||||
} else if (type instanceof PercentType) {
|
||||
command = Commands.SET_LEVEL;
|
||||
dimmingLevel = (byte) getDimLevelFromPercentType((PercentType) type);
|
||||
|
||||
if (dimmingLevel == 0) {
|
||||
command = Commands.OFF;
|
||||
}
|
||||
|
||||
} else if (type instanceof IncreaseDecreaseType) {
|
||||
command = Commands.SET_LEVEL;
|
||||
// Evert: I do not know how to get previous object state...
|
||||
dimmingLevel = 5;
|
||||
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for lighting6 message. See Blyss.
|
||||
*
|
||||
* @author Damien Servant - Initial contribution
|
||||
* @author Pauli Anttila - Migrated for OH2
|
||||
*/
|
||||
public class RFXComLighting6Message extends RFXComDeviceMessageImpl<RFXComLighting6Message.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
BLYSS(0);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Commands implements ByteEnumWrapper {
|
||||
ON(0),
|
||||
OFF(1),
|
||||
GROUP_ON(2),
|
||||
GROUP_OFF(3);
|
||||
|
||||
private final int command;
|
||||
|
||||
Commands(int command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) command;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public char groupCode;
|
||||
public byte unitCode;
|
||||
public Commands command;
|
||||
|
||||
public RFXComLighting6Message() {
|
||||
super(PacketType.LIGHTING6);
|
||||
}
|
||||
|
||||
public RFXComLighting6Message(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + getDeviceId();
|
||||
str += ", Command = " + command;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
|
||||
groupCode = (char) data[6];
|
||||
unitCode = data[7];
|
||||
command = fromByte(Commands.class, data[8]);
|
||||
|
||||
signalLevel = (byte) ((data[11] & 0xF0) >> 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
// Example data 0B 15 00 02 01 01 41 01 00 04 8E 00
|
||||
// 0B 15 00 02 01 01 41 01 01 04 8E 00
|
||||
|
||||
byte[] data = new byte[12];
|
||||
|
||||
data[0] = 0x0B;
|
||||
data[1] = RFXComBaseMessage.PacketType.LIGHTING6.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) ((sensorId >> 8) & 0xFF);
|
||||
data[5] = (byte) (sensorId & 0xFF);
|
||||
data[6] = (byte) groupCode;
|
||||
data[7] = unitCode;
|
||||
data[8] = command.toByte();
|
||||
data[9] = 0x00; // CmdSeqNbr1 - 0 to 4 - Useless for a Blyss Switch
|
||||
data[10] = 0x00; // CmdSeqNbr2 - 0 to 145 - Useless for a Blyss Switch
|
||||
data[11] = (byte) ((signalLevel & 0x0F) << 4);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return sensorId + ID_DELIMITER + groupCode + ID_DELIMITER + unitCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_COMMAND:
|
||||
switch (command) {
|
||||
case OFF:
|
||||
case GROUP_OFF:
|
||||
return OnOffType.OFF;
|
||||
|
||||
case ON:
|
||||
case GROUP_ON:
|
||||
return OnOffType.ON;
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Can't convert " + command + " for " + channelId);
|
||||
}
|
||||
|
||||
case CHANNEL_CONTACT:
|
||||
switch (command) {
|
||||
case OFF:
|
||||
case GROUP_OFF:
|
||||
return OpenClosedType.CLOSED;
|
||||
|
||||
case ON:
|
||||
case GROUP_ON:
|
||||
return OpenClosedType.OPEN;
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Can't convert " + command + " for " + channelId);
|
||||
}
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) throws RFXComException {
|
||||
String[] ids = deviceId.split("\\" + ID_DELIMITER);
|
||||
if (ids.length != 3) {
|
||||
throw new RFXComException("Invalid device id '" + deviceId + "'");
|
||||
}
|
||||
|
||||
sensorId = Integer.parseInt(ids[0]);
|
||||
groupCode = ids[1].charAt(0);
|
||||
unitCode = Byte.parseByte(ids[2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_COMMAND:
|
||||
if (type instanceof OnOffType) {
|
||||
command = (type == OnOffType.ON ? Commands.ON : Commands.OFF);
|
||||
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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 org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration;
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedChannelException;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* This interface defines interface which every message class should implement.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public interface RFXComMessage {
|
||||
|
||||
/**
|
||||
* Procedure for encode raw data.
|
||||
*
|
||||
* @param data Raw data.
|
||||
*/
|
||||
void encodeMessage(byte[] data) throws RFXComException;
|
||||
|
||||
/**
|
||||
* Procedure for decode object to raw data.
|
||||
*
|
||||
* @return raw data.
|
||||
*/
|
||||
byte[] decodeMessage() throws RFXComException;
|
||||
|
||||
/**
|
||||
* Procedure for converting openHAB state to RFXCOM object.
|
||||
*/
|
||||
void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException;
|
||||
|
||||
/**
|
||||
* Procedure to pass configuration to a message
|
||||
*
|
||||
* @param deviceConfiguration configuration about the device
|
||||
* @throws RFXComException if the configuration could not be handled properly
|
||||
*/
|
||||
void setConfig(RFXComDeviceConfiguration deviceConfiguration) throws RFXComException;
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
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.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.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;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown packet type " + packetType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static java.math.BigDecimal.*;
|
||||
import static java.math.RoundingMode.HALF_DOWN;
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DecimalType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
import org.openhab.core.util.HexUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Add support for the rfx-sensor
|
||||
*
|
||||
* @author Martin van Wingerden - Initial contribution
|
||||
*/
|
||||
public class RFXComRFXSensorMessage extends RFXComDeviceMessageImpl<RFXComRFXSensorMessage.SubType> {
|
||||
private final Logger logger = LoggerFactory.getLogger(RFXComRFXSensorMessage.class);
|
||||
|
||||
private static final BigDecimal PRESSURE_ADDITION = new BigDecimal("0.095");
|
||||
private static final BigDecimal PRESSURE_DIVIDER = new BigDecimal("0.0009");
|
||||
|
||||
private static final BigDecimal HUMIDITY_VOLTAGE_SUBTRACTION = new BigDecimal("0.16");
|
||||
private static final BigDecimal HUMIDITY_VOLTAGE_DIVIDER = new BigDecimal("0.0062");
|
||||
private static final BigDecimal HUMIDITY_TEMPERATURE_CORRECTION = new BigDecimal("1.0546");
|
||||
private static final BigDecimal HUMIDITY_TEMPERATURE_MULTIPLIER = new BigDecimal("0.00216");
|
||||
|
||||
private static final BigDecimal ONE_HUNDRED = BigDecimal.valueOf(100);
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
TEMPERATURE(0),
|
||||
A_D(1),
|
||||
VOLTAGE(2),
|
||||
MESSAGE(3);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
|
||||
public int sensorId;
|
||||
private Double temperature;
|
||||
private BigDecimal miliVoltageTimesTen;
|
||||
public byte signalLevel;
|
||||
|
||||
public RFXComRFXSensorMessage() {
|
||||
super(PacketType.RFXSENSOR);
|
||||
}
|
||||
|
||||
public RFXComRFXSensorMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = super.toString();
|
||||
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + getDeviceId();
|
||||
str += ", Temperature = " + temperature;
|
||||
str += ", Voltage = " + getVoltage();
|
||||
str += ", Signal level = " + signalLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
|
||||
sensorId = (data[4] & 0xFF);
|
||||
|
||||
byte msg1 = data[5];
|
||||
byte msg2 = data[6];
|
||||
|
||||
switch (subType) {
|
||||
case TEMPERATURE:
|
||||
encodeTemperatureMessage(msg1, msg2);
|
||||
break;
|
||||
case A_D:
|
||||
case VOLTAGE:
|
||||
encodeVoltageMessage(msg1, msg2);
|
||||
break;
|
||||
case MESSAGE:
|
||||
encodeStatusMessage(msg2);
|
||||
break;
|
||||
}
|
||||
|
||||
signalLevel = (byte) ((data[7] & 0xF0) >> 4);
|
||||
}
|
||||
|
||||
private void encodeTemperatureMessage(byte msg1, byte msg2) {
|
||||
temperature = (short) ((msg1 & 0x7F) << 8 | (msg2 & 0xFF)) * 0.01;
|
||||
if ((msg1 & 0x80) != 0) {
|
||||
temperature = -temperature;
|
||||
}
|
||||
}
|
||||
|
||||
private void encodeVoltageMessage(byte msg1, byte msg2) {
|
||||
miliVoltageTimesTen = BigDecimal.valueOf((short) ((msg1 & 0xFF) << 8 | (msg2 & 0xFF)));
|
||||
}
|
||||
|
||||
private void encodeStatusMessage(byte msg2) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[8];
|
||||
|
||||
data[0] = 0x07;
|
||||
data[1] = PacketType.RFXSENSOR.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) (sensorId & 0x00FF);
|
||||
|
||||
if (subType == SubType.TEMPERATURE) {
|
||||
decodeTemperatureMessage(data);
|
||||
} else if (subType == SubType.A_D) {
|
||||
decodeVoltageMessage(data);
|
||||
} else if (subType == SubType.VOLTAGE) {
|
||||
decodeVoltageMessage(data);
|
||||
} else if (subType == SubType.MESSAGE) {
|
||||
decodeStatusMessage(data);
|
||||
}
|
||||
|
||||
data[7] = (byte) ((signalLevel & 0x0F) << 4);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private void decodeTemperatureMessage(byte[] data) {
|
||||
short temp = (short) Math.abs(temperature * 100);
|
||||
data[5] = (byte) ((temp >> 8) & 0xFF);
|
||||
data[6] = (byte) (temp & 0xFF);
|
||||
if (temperature < 0) {
|
||||
data[5] |= 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
private void decodeVoltageMessage(byte[] data) {
|
||||
short miliVoltageTimesTenShort = this.miliVoltageTimesTen.shortValueExact();
|
||||
data[5] = (byte) ((miliVoltageTimesTenShort >> 8) & 0xFF);
|
||||
data[6] = (byte) (miliVoltageTimesTenShort & 0xFF);
|
||||
}
|
||||
|
||||
private void decodeStatusMessage(byte[] data) {
|
||||
logger.info("A status message was received {}", HexUtils.bytesToHex(data));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_TEMPERATURE:
|
||||
return subType == SubType.TEMPERATURE ? getTemperature() : null;
|
||||
|
||||
case CHANNEL_VOLTAGE:
|
||||
return subType == SubType.A_D ? handleVoltage() : null;
|
||||
|
||||
case CHANNEL_REFERENCE_VOLTAGE:
|
||||
return subType == SubType.VOLTAGE ? handleVoltage() : null;
|
||||
|
||||
case CHANNEL_HUMIDITY:
|
||||
return subType == SubType.A_D ? handleHumidity(deviceState) : null;
|
||||
|
||||
case CHANNEL_PRESSURE:
|
||||
return subType == SubType.A_D ? handlePressure(deviceState) : null;
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
private State getTemperature() {
|
||||
if (temperature != null) {
|
||||
return new DecimalType(temperature);
|
||||
} else {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
}
|
||||
|
||||
private State handleVoltage() {
|
||||
if (miliVoltageTimesTen != null) {
|
||||
return new DecimalType(getVoltage());
|
||||
} else {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
}
|
||||
|
||||
private State handleHumidity(DeviceState deviceState) {
|
||||
DecimalType temperatureState = (DecimalType) deviceState.getLastState(CHANNEL_TEMPERATURE);
|
||||
Type referenceVoltageState = deviceState.getLastState(CHANNEL_REFERENCE_VOLTAGE);
|
||||
BigDecimal adVoltage = getVoltage();
|
||||
|
||||
if (temperatureState == null || referenceVoltageState == null || adVoltage == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!(referenceVoltageState instanceof DecimalType)) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
|
||||
BigDecimal temperature = temperatureState.toBigDecimal();
|
||||
BigDecimal supplyVoltage = ((DecimalType) referenceVoltageState).toBigDecimal();
|
||||
|
||||
// RH = (((A/D voltage / supply voltage) - 0.16) / 0.0062) / (1.0546 - 0.00216 * temperature)
|
||||
BigDecimal belowTheDivider = adVoltage.divide(supplyVoltage, 4, ROUND_HALF_DOWN)
|
||||
.subtract(HUMIDITY_VOLTAGE_SUBTRACTION).divide(HUMIDITY_VOLTAGE_DIVIDER, 4, ROUND_HALF_DOWN);
|
||||
BigDecimal underTheDivider = HUMIDITY_TEMPERATURE_CORRECTION
|
||||
.subtract(HUMIDITY_TEMPERATURE_MULTIPLIER.multiply(temperature));
|
||||
|
||||
return new DecimalType(belowTheDivider.divide(underTheDivider, 4, ROUND_HALF_DOWN));
|
||||
}
|
||||
|
||||
private State handlePressure(DeviceState deviceState) {
|
||||
DecimalType referenceVoltageState = (DecimalType) deviceState.getLastState(CHANNEL_REFERENCE_VOLTAGE);
|
||||
BigDecimal adVoltage = getVoltage();
|
||||
|
||||
if (referenceVoltageState == null || adVoltage == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
BigDecimal supplyVoltage = referenceVoltageState.toBigDecimal();
|
||||
|
||||
// hPa = ((A/D voltage / supply voltage) + 0.095) / 0.0009
|
||||
return new DecimalType((adVoltage.divide(supplyVoltage, 4, HALF_DOWN).add(PRESSURE_ADDITION))
|
||||
.divide(PRESSURE_DIVIDER, 4, ROUND_HALF_DOWN));
|
||||
}
|
||||
|
||||
private BigDecimal getVoltage() {
|
||||
if (miliVoltageTimesTen == null) {
|
||||
return null;
|
||||
}
|
||||
return miliVoltageTimesTen.divide(ONE_HUNDRED, 100, ROUND_CEILING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) throws RFXComException {
|
||||
throw new RFXComException("Not supported");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DecimalType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for temperature and humidity message.
|
||||
*
|
||||
* @author Marc SAUVEUR - Initial contribution
|
||||
* @author Pauli Anttila - Migrated for OH2
|
||||
*/
|
||||
public class RFXComRainMessage extends RFXComBatteryDeviceMessage<RFXComRainMessage.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
RAIN1(1),
|
||||
RAIN2(2),
|
||||
RAIN3(3),
|
||||
RAIN4(4),
|
||||
RAIN5(5),
|
||||
RAIN6(6),
|
||||
RAIN7(7);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public double rainRate;
|
||||
public double rainTotal;
|
||||
|
||||
public RFXComRainMessage() {
|
||||
super(PacketType.RAIN);
|
||||
}
|
||||
|
||||
public RFXComRainMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + getDeviceId();
|
||||
str += ", Rain rate = " + rainRate;
|
||||
str += ", Rain total = " + rainTotal;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
str += ", Battery level = " + batteryLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
|
||||
|
||||
rainRate = (short) ((data[6] & 0xFF) << 8 | (data[7] & 0xFF));
|
||||
if (subType == SubType.RAIN2) {
|
||||
rainRate *= 0.01;
|
||||
}
|
||||
|
||||
if (subType == SubType.RAIN6) {
|
||||
rainTotal = (short) ((data[10] & 0xFF)) * 0.266;
|
||||
} else {
|
||||
rainTotal = (short) ((data[8] & 0xFF) << 8 | (data[9] & 0xFF) << 8 | (data[10] & 0xFF)) * 0.1;
|
||||
}
|
||||
|
||||
signalLevel = (byte) ((data[11] & 0xF0) >> 4);
|
||||
batteryLevel = (byte) (data[11] & 0x0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[12];
|
||||
|
||||
data[0] = 0x0B;
|
||||
data[1] = RFXComBaseMessage.PacketType.RAIN.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) ((sensorId & 0xFF00) >> 8);
|
||||
data[5] = (byte) (sensorId & 0x00FF);
|
||||
|
||||
short rainR = (short) Math.abs(rainRate * 100);
|
||||
data[6] = (byte) ((rainR >> 8) & 0xFF);
|
||||
data[7] = (byte) (rainR & 0xFF);
|
||||
|
||||
short rainT = (short) Math.abs(rainTotal * 10);
|
||||
data[8] = (byte) ((rainT >> 16) & 0xFF);
|
||||
data[9] = (byte) ((rainT >> 8) & 0xFF);
|
||||
data[10] = (byte) (rainT & 0xFF);
|
||||
|
||||
data[11] = (byte) (((signalLevel & 0x0F) << 4) | (batteryLevel & 0x0F));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_RAIN_RATE:
|
||||
return new DecimalType(rainRate);
|
||||
|
||||
case CHANNEL_RAIN_TOTAL:
|
||||
return new DecimalType(rainTotal);
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.IncreaseDecreaseType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.OpenClosedType;
|
||||
import org.openhab.core.library.types.StopMoveType;
|
||||
import org.openhab.core.library.types.UpDownType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for RFY (Somfy RTS) message.
|
||||
*
|
||||
* @author Jürgen Richtsfeld - Initial contribution
|
||||
* @author Pauli Anttila - Ported from OpenHAB1
|
||||
* @author Mike Jagdis - Added venetian support and sun+wind detector
|
||||
*/
|
||||
public class RFXComRfyMessage extends RFXComDeviceMessageImpl<RFXComRfyMessage.SubType> {
|
||||
|
||||
public enum Commands implements ByteEnumWrapper {
|
||||
STOP(0x00),
|
||||
UP(0x01),
|
||||
DOWN(0x03),
|
||||
PROGRAM(0x07),
|
||||
UP_SHORT(0x0F),
|
||||
DOWN_SHORT(0x10),
|
||||
UP_LONG(0x11),
|
||||
DOWN_LONG(0x12),
|
||||
ENABLE_SUN_WIND_DETECTOR(0x13),
|
||||
DISABLE_SUN_DETECTOR(0x14);
|
||||
|
||||
private final int command;
|
||||
|
||||
Commands(int command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) command;
|
||||
}
|
||||
}
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
RFY(0),
|
||||
RFY_EXT(1),
|
||||
RESERVED(2),
|
||||
ASA(3);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int unitId;
|
||||
public byte unitCode;
|
||||
public Commands command;
|
||||
|
||||
public RFXComRfyMessage() {
|
||||
super(PacketType.RFY);
|
||||
}
|
||||
|
||||
public RFXComRfyMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + ", Sub type = " + subType + ", Unit Id = " + getDeviceId() + ", Unit Code = "
|
||||
+ unitCode + ", Command = " + command + ", Signal level = " + signalLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
|
||||
unitId = (data[4] & 0xFF) << 16 | (data[5] & 0xFF) << 8 | (data[6] & 0xFF);
|
||||
unitCode = data[7];
|
||||
|
||||
command = fromByte(Commands.class, data[8]);
|
||||
signalLevel = (byte) ((data[12] & 0xF0) >> 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
final byte[] data = new byte[13];
|
||||
|
||||
data[0] = 12;
|
||||
data[1] = RFXComBaseMessage.PacketType.RFY.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) ((unitId >> 16) & 0xFF);
|
||||
data[5] = (byte) ((unitId >> 8) & 0xFF);
|
||||
data[6] = (byte) (unitId & 0xFF);
|
||||
data[7] = unitCode;
|
||||
data[8] = command.toByte();
|
||||
data[12] = (byte) ((signalLevel & 0x0F) << 4);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return unitId + ID_DELIMITER + unitCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_COMMAND:
|
||||
return (command == Commands.DOWN ? OpenClosedType.CLOSED : OpenClosedType.OPEN);
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) throws RFXComException {
|
||||
String[] ids = deviceId.split("\\" + ID_DELIMITER);
|
||||
if (ids.length != 2) {
|
||||
throw new RFXComException("Invalid device id '" + deviceId + "'");
|
||||
}
|
||||
|
||||
this.unitId = Integer.parseInt(ids[0]);
|
||||
this.unitCode = Byte.parseByte(ids[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_SHUTTER:
|
||||
if (type instanceof OpenClosedType) {
|
||||
this.command = (type == OpenClosedType.CLOSED ? Commands.DOWN : Commands.UP);
|
||||
|
||||
} else if (type instanceof UpDownType) {
|
||||
this.command = (type == UpDownType.DOWN ? Commands.DOWN : Commands.UP);
|
||||
|
||||
} else if (type instanceof StopMoveType) {
|
||||
this.command = Commands.STOP;
|
||||
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
case CHANNEL_PROGRAM:
|
||||
if (type == OnOffType.ON) {
|
||||
this.command = Commands.PROGRAM;
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Can't convert " + type + " to Command");
|
||||
}
|
||||
break;
|
||||
|
||||
case CHANNEL_SUN_WIND_DETECTOR:
|
||||
if (type instanceof OnOffType) {
|
||||
this.command = (type == OnOffType.ON ? Commands.ENABLE_SUN_WIND_DETECTOR
|
||||
: Commands.DISABLE_SUN_DETECTOR);
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Can't convert " + type + " to Command");
|
||||
}
|
||||
break;
|
||||
|
||||
case CHANNEL_VENETIAN_BLIND:
|
||||
if (type instanceof OpenClosedType) {
|
||||
this.command = (type == OpenClosedType.CLOSED ? Commands.DOWN_SHORT : Commands.UP_SHORT);
|
||||
|
||||
} else if (type instanceof OnOffType) {
|
||||
this.command = (type == OnOffType.ON ? Commands.DOWN_SHORT : Commands.UP_SHORT);
|
||||
|
||||
} else if (type instanceof IncreaseDecreaseType) {
|
||||
this.command = (type == IncreaseDecreaseType.INCREASE ? Commands.DOWN_LONG : Commands.UP_LONG);
|
||||
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Can't convert " + type + " to Command");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for Security1 message.
|
||||
* (i.e. X10 Security, Visonic PowerCode, Meiantech, etc.)
|
||||
*
|
||||
* @author David Kalff - Initial contribution
|
||||
* @author Pauli Anttila
|
||||
*/
|
||||
public class RFXComSecurity1Message extends RFXComBatteryDeviceMessage<RFXComSecurity1Message.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
X10_SECURITY(0),
|
||||
X10_SECURITY_MOTION(1),
|
||||
X10_SECURITY_REMOTE(2),
|
||||
KD101(3),
|
||||
VISONIC_POWERCODE_SENSOR_PRIMARY_CONTACT(4),
|
||||
VISONIC_POWERCODE_MOTION(5),
|
||||
VISONIC_CODESECURE(6),
|
||||
VISONIC_POWERCODE_SENSOR_AUX_CONTACT(7),
|
||||
MEIANTECH(8),
|
||||
SA30(9), // Also SA33
|
||||
RM174RF(10);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Status implements ByteEnumWrapper {
|
||||
NORMAL(0),
|
||||
NORMAL_DELAYED(1),
|
||||
ALARM(2),
|
||||
ALARM_DELAYED(3),
|
||||
MOTION(4),
|
||||
NO_MOTION(5),
|
||||
PANIC(6),
|
||||
END_PANIC(7),
|
||||
IR(8),
|
||||
ARM_AWAY(9),
|
||||
ARM_AWAY_DELAYED(10),
|
||||
ARM_HOME(11),
|
||||
ARM_HOME_DELAYED(12),
|
||||
DISARM(13),
|
||||
LIGHT_1_OFF(16),
|
||||
LIGHT_1_ON(17),
|
||||
LIGHT_2_OFF(18),
|
||||
LIGHT_2_ON(19),
|
||||
DARK_DETECTED(20),
|
||||
LIGHT_DETECTED(21),
|
||||
BATLOW(22),
|
||||
PAIR_KD101(23),
|
||||
NORMAL_TAMPER(128),
|
||||
NORMAL_DELAYED_TAMPER(129),
|
||||
ALARM_TAMPER(130),
|
||||
ALARM_DELAYED_TAMPER(131),
|
||||
MOTION_TAMPER(132),
|
||||
NO_MOTION_TAMPER(133);
|
||||
|
||||
private final int status;
|
||||
|
||||
Status(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Added item for ContactTypes */
|
||||
public enum Contact implements ByteEnumWrapper {
|
||||
NORMAL(0),
|
||||
NORMAL_DELAYED(1),
|
||||
ALARM(2),
|
||||
ALARM_DELAYED(3),
|
||||
NORMAL_TAMPER(128),
|
||||
NORMAL_DELAYED_TAMPER(129),
|
||||
ALARM_TAMPER(130),
|
||||
ALARM_DELAYED_TAMPER(131),
|
||||
|
||||
UNKNOWN(255);
|
||||
|
||||
private final int contact;
|
||||
|
||||
Contact(int contact) {
|
||||
this.contact = contact;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) contact;
|
||||
}
|
||||
|
||||
public static Contact fromByte(int input) {
|
||||
for (Contact status : Contact.values()) {
|
||||
if (status.contact == input) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return Contact.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Added item for MotionTypes */
|
||||
public enum Motion implements ByteEnumWrapper {
|
||||
MOTION(4),
|
||||
NO_MOTION(5),
|
||||
MOTION_TAMPER(132),
|
||||
NO_MOTION_TAMPER(133),
|
||||
|
||||
UNKNOWN(255);
|
||||
|
||||
private final int motion;
|
||||
|
||||
Motion(int motion) {
|
||||
this.motion = motion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) motion;
|
||||
}
|
||||
|
||||
public static Motion fromByte(int input) {
|
||||
for (Motion motion : Motion.values()) {
|
||||
if (motion.motion == input) {
|
||||
return motion;
|
||||
}
|
||||
}
|
||||
|
||||
return Motion.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public Status status;
|
||||
public Contact contact;
|
||||
public Motion motion;
|
||||
|
||||
public RFXComSecurity1Message() {
|
||||
super(PacketType.SECURITY1);
|
||||
}
|
||||
|
||||
public RFXComSecurity1Message(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + getDeviceId();
|
||||
str += ", Status = " + status;
|
||||
str += ", Battery level = " + batteryLevel;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (data[4] & 0xFF) << 16 | (data[5] & 0xFF) << 8 | (data[6] & 0xFF);
|
||||
|
||||
status = fromByte(Status.class, data[7]);
|
||||
batteryLevel = (byte) ((data[8] & 0xF0) >> 4);
|
||||
signalLevel = (byte) (data[8] & 0x0F);
|
||||
|
||||
contact = Contact.fromByte(data[7]);
|
||||
motion = Motion.fromByte(data[7]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[9];
|
||||
|
||||
data[0] = 0x08;
|
||||
data[1] = RFXComBaseMessage.PacketType.SECURITY1.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) ((sensorId >> 16) & 0xFF);
|
||||
data[5] = (byte) ((sensorId >> 8) & 0xFF);
|
||||
data[6] = (byte) (sensorId & 0xFF);
|
||||
data[7] = status.toByte();
|
||||
data[8] = (byte) (((batteryLevel & 0x0F) << 4) | (signalLevel & 0x0F));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_MOTION:
|
||||
switch (status) {
|
||||
case MOTION:
|
||||
return OnOffType.ON;
|
||||
case NO_MOTION:
|
||||
return OnOffType.OFF;
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Can't convert " + status + " for " + channelId);
|
||||
}
|
||||
|
||||
case CHANNEL_CONTACT:
|
||||
switch (status) {
|
||||
case NORMAL:
|
||||
return OpenClosedType.CLOSED;
|
||||
case NORMAL_DELAYED:
|
||||
return OpenClosedType.CLOSED;
|
||||
case ALARM:
|
||||
return OpenClosedType.OPEN;
|
||||
case ALARM_DELAYED:
|
||||
return OpenClosedType.OPEN;
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Can't convert " + status + " for " + channelId);
|
||||
}
|
||||
|
||||
case CHANNEL_STATUS:
|
||||
return new StringType(status.toString());
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
sensorId = Integer.parseInt(deviceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_COMMAND:
|
||||
if ((type instanceof OnOffType) && (subType == SubType.X10_SECURITY_REMOTE)) {
|
||||
status = (type == OnOffType.ON ? Status.ARM_AWAY_DELAYED : Status.DISARM);
|
||||
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
case CHANNEL_STATUS:
|
||||
if (type instanceof StringType) {
|
||||
status = Status.valueOf(type.toString());
|
||||
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.OpenClosedType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for Security2 message.
|
||||
* (i.e. KEELOQ.)
|
||||
*
|
||||
* @author Mike Jagdis - Initial contribution
|
||||
*/
|
||||
public class RFXComSecurity2Message extends RFXComBatteryDeviceMessage<RFXComSecurity2Message.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
RAW_CLASSIC_KEELOQ(0),
|
||||
ROLLING_CODE_PACKET(1),
|
||||
RAW_AES_KEELOQ(2),
|
||||
RAW_CLASS_KEELOQ_WITH_REPEATS(3);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public int buttonStatus;
|
||||
|
||||
private static final int BUTTON_0_BIT = 0x02;
|
||||
private static final int BUTTON_1_BIT = 0x04;
|
||||
private static final int BUTTON_2_BIT = 0x08;
|
||||
private static final int BUTTON_3_BIT = 0x01;
|
||||
|
||||
public RFXComSecurity2Message() {
|
||||
super(PacketType.SECURITY2);
|
||||
}
|
||||
|
||||
public RFXComSecurity2Message(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + ", Sub type = " + subType + ", Device Id = " + getDeviceId() + ", Button status = "
|
||||
+ buttonStatus + ", Battery level = " + batteryLevel + ", Signal level = " + signalLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
|
||||
sensorId = (data[11] & 0x0F) << 24 | (data[10] & 0xFF) << 16 | (data[9] & 0xFF) << 8 | (data[8] & 0xFF);
|
||||
|
||||
buttonStatus = (data[11] & 0xF0) >> 4;
|
||||
|
||||
batteryLevel = (byte) ((data[28] & 0xF0) >> 4);
|
||||
signalLevel = (byte) (data[28] & 0x0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[29];
|
||||
|
||||
Arrays.fill(data, (byte) 0);
|
||||
|
||||
data[0] = 0x1C;
|
||||
data[1] = RFXComBaseMessage.PacketType.SECURITY2.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
|
||||
data[8] = (byte) (sensorId & 0xFF);
|
||||
data[9] = (byte) ((sensorId >> 8) & 0xFF);
|
||||
data[10] = (byte) ((sensorId >> 16) & 0xFF);
|
||||
data[11] = (byte) ((buttonStatus & 0x0f) << 4 | (sensorId >> 24) & 0x0F);
|
||||
|
||||
data[28] = (byte) (((batteryLevel & 0x0F) << 4) | (signalLevel & 0x0F));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_CONTACT:
|
||||
return ((buttonStatus & BUTTON_0_BIT) == 0) ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
|
||||
|
||||
case CHANNEL_CONTACT_1:
|
||||
return ((buttonStatus & BUTTON_1_BIT) == 0) ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
|
||||
|
||||
case CHANNEL_CONTACT_2:
|
||||
return ((buttonStatus & BUTTON_2_BIT) == 0) ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
|
||||
|
||||
case CHANNEL_CONTACT_3:
|
||||
return ((buttonStatus & BUTTON_3_BIT) == 0) ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
sensorId = Integer.parseInt(deviceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_CONTACT:
|
||||
if (type instanceof OpenClosedType) {
|
||||
if (type == OpenClosedType.CLOSED) {
|
||||
buttonStatus |= BUTTON_0_BIT;
|
||||
} else {
|
||||
buttonStatus &= ~BUTTON_0_BIT;
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
case CHANNEL_CONTACT_1:
|
||||
if (type instanceof OpenClosedType) {
|
||||
if (type == OpenClosedType.CLOSED) {
|
||||
buttonStatus |= BUTTON_1_BIT;
|
||||
} else {
|
||||
buttonStatus &= ~BUTTON_1_BIT;
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
case CHANNEL_CONTACT_2:
|
||||
if (type instanceof OpenClosedType) {
|
||||
if (type == OpenClosedType.CLOSED) {
|
||||
buttonStatus |= BUTTON_2_BIT;
|
||||
} else {
|
||||
buttonStatus &= ~BUTTON_2_BIT;
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
case CHANNEL_CONTACT_3:
|
||||
if (type instanceof OpenClosedType) {
|
||||
if (type == OpenClosedType.CLOSED) {
|
||||
buttonStatus |= BUTTON_3_BIT;
|
||||
} else {
|
||||
buttonStatus &= ~BUTTON_3_BIT;
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DecimalType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for temperature, humidity and barometric message.
|
||||
*
|
||||
* @author Damien Servant - Initial contribution
|
||||
* @author Martin van Wingerden - ported to openHAB 2.0
|
||||
*/
|
||||
public class RFXComTemperatureHumidityBarometricMessage
|
||||
extends RFXComBatteryDeviceMessage<RFXComTemperatureHumidityBarometricMessage.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
THB1(1), // BTHR918, BTHGN129
|
||||
THB2(2); // BTHR918N, BTHR968
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public enum HumidityStatus implements ByteEnumWrapper {
|
||||
NORMAL(0),
|
||||
COMFORT(1),
|
||||
DRY(2),
|
||||
WET(3);
|
||||
|
||||
private final int humidityStatus;
|
||||
|
||||
HumidityStatus(int humidityStatus) {
|
||||
this.humidityStatus = humidityStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) humidityStatus;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ForecastStatus implements ByteEnumWrapper {
|
||||
NO_INFO_AVAILABLE(0),
|
||||
SUNNY(1),
|
||||
PARTLY_CLOUDY(2),
|
||||
CLOUDY(3),
|
||||
RAIN(4);
|
||||
|
||||
private final int forecastStatus;
|
||||
|
||||
ForecastStatus(int forecastStatus) {
|
||||
this.forecastStatus = forecastStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) forecastStatus;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public double temperature;
|
||||
public byte humidity;
|
||||
public HumidityStatus humidityStatus;
|
||||
public double pressure;
|
||||
public ForecastStatus forecastStatus;
|
||||
|
||||
public RFXComTemperatureHumidityBarometricMessage() {
|
||||
super(PacketType.TEMPERATURE_HUMIDITY_BAROMETRIC);
|
||||
}
|
||||
|
||||
public RFXComTemperatureHumidityBarometricMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + sensorId;
|
||||
str += ", Temperature = " + temperature;
|
||||
str += ", Humidity = " + humidity;
|
||||
str += ", Humidity status = " + humidityStatus;
|
||||
str += ", Pressure = " + pressure;
|
||||
str += ", Forecast = " + forecastStatus;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
str += ", Battery level = " + batteryLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
|
||||
|
||||
temperature = (short) ((data[6] & 0x7F) << 8 | (data[7] & 0xFF)) * 0.1;
|
||||
if ((data[6] & 0x80) != 0) {
|
||||
temperature = -temperature;
|
||||
}
|
||||
|
||||
humidity = data[8];
|
||||
humidityStatus = fromByte(HumidityStatus.class, data[9]);
|
||||
|
||||
pressure = (data[10] & 0xFF) << 8 | (data[11] & 0xFF);
|
||||
forecastStatus = fromByte(ForecastStatus.class, data[12]);
|
||||
|
||||
signalLevel = (byte) ((data[13] & 0xF0) >> 4);
|
||||
batteryLevel = (byte) (data[13] & 0x0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[14];
|
||||
|
||||
data[0] = 0x0D;
|
||||
data[1] = RFXComBaseMessage.PacketType.TEMPERATURE_HUMIDITY_BAROMETRIC.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) ((sensorId & 0xFF00) >> 8);
|
||||
data[5] = (byte) (sensorId & 0x00FF);
|
||||
|
||||
short temp = (short) Math.abs(temperature * 10);
|
||||
data[6] = (byte) ((temp >> 8) & 0xFF);
|
||||
data[7] = (byte) (temp & 0xFF);
|
||||
if (temperature < 0) {
|
||||
data[6] |= 0x80;
|
||||
}
|
||||
|
||||
data[8] = humidity;
|
||||
data[9] = humidityStatus.toByte();
|
||||
|
||||
temp = (short) (pressure);
|
||||
data[10] = (byte) ((temp >> 8) & 0xFF);
|
||||
data[11] = (byte) (temp & 0xFF);
|
||||
|
||||
data[12] = forecastStatus.toByte();
|
||||
|
||||
data[13] = (byte) (((signalLevel & 0x0F) << 4) | (batteryLevel & 0x0F));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_TEMPERATURE:
|
||||
return new DecimalType(temperature);
|
||||
|
||||
case CHANNEL_HUMIDITY:
|
||||
return new DecimalType(humidity);
|
||||
|
||||
case CHANNEL_PRESSURE:
|
||||
return new DecimalType(pressure);
|
||||
|
||||
case CHANNEL_HUMIDITY_STATUS:
|
||||
return new StringType(humidityStatus.toString());
|
||||
|
||||
case CHANNEL_FORECAST:
|
||||
return new StringType(forecastStatus.toString());
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DecimalType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for temperature and humidity message.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public class RFXComTemperatureHumidityMessage
|
||||
extends RFXComBatteryDeviceMessage<RFXComTemperatureHumidityMessage.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
TH1(1),
|
||||
TH2(2),
|
||||
TH3(3),
|
||||
TH4(4),
|
||||
TH5(5),
|
||||
TH6(6),
|
||||
TH7(7),
|
||||
TH8(8),
|
||||
TH9(9),
|
||||
TH10(10),
|
||||
TH11(11),
|
||||
TH12(12),
|
||||
TH13(13),
|
||||
TH14(14);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public enum HumidityStatus implements ByteEnumWrapper {
|
||||
NORMAL(0),
|
||||
COMFORT(1),
|
||||
DRY(2),
|
||||
WET(3);
|
||||
|
||||
private final int humidityStatus;
|
||||
|
||||
HumidityStatus(int humidityStatus) {
|
||||
this.humidityStatus = humidityStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) humidityStatus;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public double temperature;
|
||||
public byte humidity;
|
||||
public HumidityStatus humidityStatus;
|
||||
|
||||
public RFXComTemperatureHumidityMessage() {
|
||||
super(PacketType.TEMPERATURE_HUMIDITY);
|
||||
}
|
||||
|
||||
public RFXComTemperatureHumidityMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + getDeviceId();
|
||||
str += ", Temperature = " + temperature;
|
||||
str += ", Humidity = " + humidity;
|
||||
str += ", Humidity status = " + humidityStatus;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
str += ", Battery level = " + batteryLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
|
||||
|
||||
temperature = (short) ((data[6] & 0x7F) << 8 | (data[7] & 0xFF)) * 0.1;
|
||||
if ((data[6] & 0x80) != 0) {
|
||||
temperature = -temperature;
|
||||
}
|
||||
|
||||
humidity = data[8];
|
||||
humidityStatus = fromByte(HumidityStatus.class, data[9]);
|
||||
|
||||
signalLevel = (byte) ((data[10] & 0xF0) >> 4);
|
||||
batteryLevel = (byte) (data[10] & 0x0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[11];
|
||||
|
||||
data[0] = 0x0A;
|
||||
data[1] = RFXComBaseMessage.PacketType.TEMPERATURE_HUMIDITY.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) ((sensorId & 0xFF00) >> 8);
|
||||
data[5] = (byte) (sensorId & 0x00FF);
|
||||
|
||||
short temp = (short) Math.abs(temperature * 10);
|
||||
data[6] = (byte) ((temp >> 8) & 0xFF);
|
||||
data[7] = (byte) (temp & 0xFF);
|
||||
if (temperature < 0) {
|
||||
data[6] |= 0x80;
|
||||
}
|
||||
|
||||
data[8] = humidity;
|
||||
data[9] = humidityStatus.toByte();
|
||||
data[10] = (byte) (((signalLevel & 0x0F) << 4) | (batteryLevel & 0x0F));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_TEMPERATURE:
|
||||
return new DecimalType(temperature);
|
||||
|
||||
case CHANNEL_HUMIDITY:
|
||||
return new DecimalType(humidity);
|
||||
|
||||
case CHANNEL_HUMIDITY_STATUS:
|
||||
return new StringType(humidityStatus.toString());
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.CHANNEL_TEMPERATURE;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DecimalType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for temperature and humidity message.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public class RFXComTemperatureMessage extends RFXComBatteryDeviceMessage<RFXComTemperatureMessage.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
TEMP1(1),
|
||||
TEMP2(2),
|
||||
TEMP3(3),
|
||||
TEMP4(4),
|
||||
TEMP5(5),
|
||||
TEMP6(6),
|
||||
TEMP7(7),
|
||||
TEMP8(8),
|
||||
TEMP9(9),
|
||||
TEMP10(10),
|
||||
TEMP11(11);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public double temperature;
|
||||
|
||||
public RFXComTemperatureMessage() {
|
||||
super(PacketType.TEMPERATURE);
|
||||
}
|
||||
|
||||
public RFXComTemperatureMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + getDeviceId();
|
||||
str += ", Temperature = " + temperature;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
str += ", Battery level = " + batteryLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
|
||||
|
||||
temperature = (short) ((data[6] & 0x7F) << 8 | (data[7] & 0xFF)) * 0.1;
|
||||
if ((data[6] & 0x80) != 0) {
|
||||
temperature = -temperature;
|
||||
}
|
||||
|
||||
signalLevel = (byte) ((data[8] & 0xF0) >> 4);
|
||||
batteryLevel = (byte) (data[8] & 0x0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[9];
|
||||
|
||||
data[0] = 0x08;
|
||||
data[1] = RFXComBaseMessage.PacketType.TEMPERATURE.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) ((sensorId & 0xFF00) >> 8);
|
||||
data[5] = (byte) (sensorId & 0x00FF);
|
||||
|
||||
short temp = (short) Math.abs(temperature * 10);
|
||||
data[6] = (byte) ((temp >> 8) & 0xFF);
|
||||
data[7] = (byte) (temp & 0xFF);
|
||||
if (temperature < 0) {
|
||||
data[6] |= 0x80;
|
||||
}
|
||||
|
||||
data[8] = (byte) (((signalLevel & 0x0F) << 4) | (batteryLevel & 0x0F));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_TEMPERATURE:
|
||||
return new DecimalType(temperature);
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DecimalType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for Temperature and Rain message.
|
||||
*
|
||||
* @author Damien Servant - Initial contribution
|
||||
* @author Martin van Wingerden - ported to openHAB 2.0
|
||||
*/
|
||||
public class RFXComTemperatureRainMessage extends RFXComBatteryDeviceMessage<RFXComTemperatureRainMessage.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
WS1200(1);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public double temperature;
|
||||
public double rainTotal;
|
||||
|
||||
public RFXComTemperatureRainMessage() {
|
||||
super(PacketType.TEMPERATURE_RAIN);
|
||||
}
|
||||
|
||||
public RFXComTemperatureRainMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + sensorId;
|
||||
str += ", Temperature = " + temperature;
|
||||
str += ", Rain total = " + rainTotal;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
str += ", Battery level = " + batteryLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
|
||||
|
||||
temperature = ((data[6] & 0x7F) << 8 | (data[7] & 0xFF)) * 0.1;
|
||||
if ((data[6] & 0x80) != 0) {
|
||||
temperature = -temperature;
|
||||
}
|
||||
rainTotal = ((data[8] & 0xFF) << 8 | (data[9] & 0xFF)) * 0.1;
|
||||
signalLevel = (byte) ((data[10] & 0xF0) >> 4);
|
||||
batteryLevel = (byte) (data[10] & 0x0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[11];
|
||||
|
||||
data[0] = (byte) (data.length - 1);
|
||||
data[1] = RFXComBaseMessage.PacketType.TEMPERATURE_RAIN.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) ((sensorId & 0xFF00) >> 8);
|
||||
data[5] = (byte) (sensorId & 0x00FF);
|
||||
|
||||
short temp = (short) Math.abs(temperature * 10);
|
||||
data[6] = (byte) ((temp >> 8) & 0xFF);
|
||||
data[7] = (byte) (temp & 0xFF);
|
||||
if (temperature < 0) {
|
||||
data[6] |= 0x80;
|
||||
}
|
||||
|
||||
short rainT = (short) Math.abs(rainTotal * 10);
|
||||
data[8] = (byte) ((rainT >> 8) & 0xFF);
|
||||
data[9] = (byte) (rainT & 0xFF);
|
||||
data[10] = (byte) (((signalLevel & 0x0F) << 4) | (batteryLevel & 0x0F));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_TEMPERATURE:
|
||||
return new DecimalType(temperature);
|
||||
|
||||
case CHANNEL_RAIN_TOTAL:
|
||||
return new DecimalType(rainTotal);
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DecimalType;
|
||||
import org.openhab.core.library.types.OpenClosedType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for thermostat1 message.
|
||||
* Digimax 210 Thermostat RF sensor operational
|
||||
*
|
||||
* @author Les Ashworth - Initial contribution
|
||||
* @author Pauli Anttila - Migrated for OH2
|
||||
*/
|
||||
public class RFXComThermostat1Message extends RFXComDeviceMessageImpl<RFXComThermostat1Message.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
DIGIMAX(0),
|
||||
DIGIMAX_SHORT(1);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
/* Added item for ContactTypes */
|
||||
public enum Status implements ByteEnumWrapper {
|
||||
NO_STATUS(0),
|
||||
DEMAND(1),
|
||||
NO_DEMAND(2),
|
||||
INITIALIZING(3);
|
||||
|
||||
private final int status;
|
||||
|
||||
Status(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Operating mode */
|
||||
public enum Mode implements ByteEnumWrapper {
|
||||
HEATING(0),
|
||||
COOLING(1);
|
||||
|
||||
private final int mode;
|
||||
|
||||
Mode(int mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) mode;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public byte temperature;
|
||||
public byte set;
|
||||
public Mode mode;
|
||||
public Status status;
|
||||
|
||||
public RFXComThermostat1Message() {
|
||||
super(PacketType.THERMOSTAT1);
|
||||
}
|
||||
|
||||
public RFXComThermostat1Message(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + getDeviceId();
|
||||
str += ", Temperature = " + temperature;
|
||||
str += ", Set = " + set;
|
||||
str += ", Mode = " + mode;
|
||||
str += ", Status = " + status;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
|
||||
temperature = data[6];
|
||||
set = data[7];
|
||||
mode = fromByte(Mode.class, (data[8] & 0xF0) >> 7);
|
||||
|
||||
status = fromByte(Status.class, data[8] & 0x03);
|
||||
signalLevel = (byte) ((data[9] & 0xF0) >> 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[10];
|
||||
|
||||
data[0] = 0x09;
|
||||
data[1] = RFXComBaseMessage.PacketType.THERMOSTAT1.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) ((sensorId & 0xFF00) >> 8);
|
||||
data[5] = (byte) (sensorId & 0x00FF);
|
||||
data[6] = (temperature);
|
||||
data[7] = (set);
|
||||
data[8] = (byte) ((mode.toByte() << 7) | (status.toByte() & 0xFF));
|
||||
data[9] = (byte) (signalLevel << 4);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_TEMPERATURE:
|
||||
return new DecimalType(temperature);
|
||||
|
||||
case CHANNEL_SET_POINT:
|
||||
return new DecimalType(set);
|
||||
|
||||
case CHANNEL_CONTACT:
|
||||
switch (status) {
|
||||
case DEMAND:
|
||||
return OpenClosedType.CLOSED;
|
||||
case NO_DEMAND:
|
||||
return OpenClosedType.OPEN;
|
||||
default:
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.RFXComThermostat3Message.SubType.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.PercentType;
|
||||
import org.openhab.core.library.types.StopMoveType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.library.types.UpDownType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for thermostat3message.
|
||||
*
|
||||
* Mertik G6R-XXX Thermostat RF sensor operational
|
||||
*
|
||||
* @author Sander Biesenbeek - Initial contribution
|
||||
* @author Ruud Beukema - Initial contribution (parallel development)
|
||||
* @author Martin van Wingerden - Joined contribution of Sander & Ruud
|
||||
*/
|
||||
public class RFXComThermostat3Message extends RFXComDeviceMessageImpl<RFXComThermostat3Message.SubType> {
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
MERTIK__G6R_H4T1(0),
|
||||
MERTIK__G6R_H4TB__G6R_H4T__G6R_H4T21_Z22(1),
|
||||
MERTIK__G6R_H4TD__G6R_H4T16(2),
|
||||
MERTIK__G6R_H4S_TRANSMIT_ONLY(3);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Commands implements ByteEnumWrapperWithSupportedSubTypes<SubType> {
|
||||
OFF(0),
|
||||
ON(1),
|
||||
UP(2),
|
||||
DOWN(3),
|
||||
RUN_UP(4, MERTIK__G6R_H4T1),
|
||||
SECOND_OFF(4, MERTIK__G6R_H4TB__G6R_H4T__G6R_H4T21_Z22),
|
||||
RUN_DOWN(5, MERTIK__G6R_H4T1),
|
||||
SECOND_ON(5, MERTIK__G6R_H4TB__G6R_H4T__G6R_H4T21_Z22),
|
||||
STOP(6, MERTIK__G6R_H4T1);
|
||||
|
||||
private final int command;
|
||||
private final List<SubType> supportedBySubTypes;
|
||||
|
||||
Commands(int command) {
|
||||
this(command, SubType.values());
|
||||
}
|
||||
|
||||
Commands(int command, SubType... supportedBySubTypes) {
|
||||
this.command = command;
|
||||
this.supportedBySubTypes = Arrays.asList(supportedBySubTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SubType> supportedBySubTypes() {
|
||||
return supportedBySubTypes;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
private int unitId;
|
||||
public Commands command;
|
||||
|
||||
public RFXComThermostat3Message() {
|
||||
super(PacketType.THERMOSTAT3);
|
||||
}
|
||||
|
||||
public RFXComThermostat3Message(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Device Id = " + getDeviceId();
|
||||
str += ", Command = " + command;
|
||||
str += ", Signal level = " + signalLevel;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(unitId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
unitId = (data[4] & 0xFF) << 16 | (data[5] & 0xFF) << 8 | (data[6] & 0xFF);
|
||||
command = fromByte(Commands.class, data[7], subType);
|
||||
signalLevel = (byte) ((data[8] & 0xF0) >> 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[9];
|
||||
|
||||
data[0] = 0x08;
|
||||
data[1] = RFXComBaseMessage.PacketType.THERMOSTAT3.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) ((unitId >> 16) & 0xFF);
|
||||
data[5] = (byte) ((unitId >> 8) & 0xFF);
|
||||
data[6] = (byte) (unitId & 0xFF);
|
||||
data[7] = command.toByte();
|
||||
data[8] = (byte) ((signalLevel & 0x0F) << 4);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_COMMAND:
|
||||
switch (command) {
|
||||
case RUN_DOWN:
|
||||
case OFF:
|
||||
return OnOffType.OFF;
|
||||
case ON:
|
||||
case RUN_UP:
|
||||
case UP:
|
||||
return OnOffType.ON;
|
||||
case SECOND_ON:
|
||||
case SECOND_OFF:
|
||||
return null;
|
||||
default:
|
||||
return UnDefType.UNDEF;
|
||||
|
||||
}
|
||||
case CHANNEL_CONTROL:
|
||||
switch (command) {
|
||||
case ON:
|
||||
return OnOffType.ON;
|
||||
case UP:
|
||||
case RUN_UP:
|
||||
return UpDownType.UP;
|
||||
case OFF:
|
||||
return OnOffType.OFF;
|
||||
case DOWN:
|
||||
case RUN_DOWN:
|
||||
return UpDownType.DOWN;
|
||||
case SECOND_ON:
|
||||
case SECOND_OFF:
|
||||
case STOP:
|
||||
return null;
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Can't convert " + command + " for " + channelId);
|
||||
}
|
||||
case CHANNEL_COMMAND_SECOND:
|
||||
switch (command) {
|
||||
case SECOND_OFF:
|
||||
return OnOffType.OFF;
|
||||
case SECOND_ON:
|
||||
return OnOffType.ON;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
case CHANNEL_COMMAND_STRING:
|
||||
return command == null ? UnDefType.UNDEF : StringType.valueOf(command.toString());
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_COMMAND:
|
||||
if (type instanceof OnOffType) {
|
||||
command = (type == OnOffType.ON ? Commands.ON : Commands.OFF);
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
case CHANNEL_COMMAND_SECOND:
|
||||
if (type instanceof OnOffType) {
|
||||
command = (type == OnOffType.ON ? Commands.SECOND_ON : Commands.SECOND_OFF);
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
case CHANNEL_CONTROL:
|
||||
if (type instanceof UpDownType) {
|
||||
command = (type == UpDownType.UP ? Commands.UP : Commands.DOWN);
|
||||
} else if (type == StopMoveType.STOP) {
|
||||
command = Commands.STOP;
|
||||
} else if (type instanceof PercentType) {
|
||||
command = ((PercentType) type).as(UpDownType.class) == UpDownType.UP ? Commands.UP : Commands.DOWN;
|
||||
} else {
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
|
||||
}
|
||||
break;
|
||||
|
||||
case CHANNEL_COMMAND_STRING:
|
||||
command = Commands.valueOf(type.toString().toUpperCase());
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
this.unitId = Integer.parseInt(deviceId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for transmitter message.
|
||||
*
|
||||
* @author Pauli Anttila - Initial contribution
|
||||
*/
|
||||
public class RFXComTransmitterMessage extends RFXComBaseMessage {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
ERROR_RECEIVER_DID_NOT_LOCK(0),
|
||||
RESPONSE(1);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Response implements ByteEnumWrapper {
|
||||
ACK(0), // ACK, transmit OK
|
||||
ACK_DELAYED(1), // ACK, but transmit started after 3 seconds delay
|
||||
// anyway with RF receive data
|
||||
NAK(2), // NAK, transmitter did not lock on the requested transmit
|
||||
// frequency
|
||||
NAK_INVALID_AC_ADDRESS(3); // NAK, AC address zero in id1-id4 not
|
||||
// allowed
|
||||
|
||||
private final int response;
|
||||
|
||||
Response(int response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) response;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public Response response;
|
||||
|
||||
public RFXComTransmitterMessage() {
|
||||
super(PacketType.TRANSMITTER_MESSAGE);
|
||||
}
|
||||
|
||||
public RFXComTransmitterMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
|
||||
str += super.toString();
|
||||
|
||||
if (subType == SubType.RESPONSE) {
|
||||
str += ", Sub type = " + subType;
|
||||
str += ", Response = " + response;
|
||||
} else {
|
||||
str += ", Sub type = " + subType;
|
||||
// Response not used
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
response = fromByte(Response.class, data[4]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[5];
|
||||
|
||||
data[0] = 0x04;
|
||||
data[1] = RFXComBaseMessage.PacketType.TRANSMITTER_MESSAGE.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = response.toByte();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DecimalType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for UV and temperature message.
|
||||
*
|
||||
* @author Damien Servant - OpenHAB1 version
|
||||
* @author Mike Jagdis - Initial contribution, OpenHAB2 version
|
||||
*/
|
||||
public class RFXComUVMessage extends RFXComBatteryDeviceMessage<RFXComUVMessage.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
UV1(1), // UVN128, UV138
|
||||
UV2(2), // UVN800
|
||||
UV3(3); // TFA
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public double uv;
|
||||
public double temperature;
|
||||
|
||||
public RFXComUVMessage() {
|
||||
super(PacketType.UV);
|
||||
}
|
||||
|
||||
public RFXComUVMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
//@formatter:off
|
||||
return super.toString()
|
||||
+ ", Sub type = " + subType
|
||||
+ ", Device Id = " + getDeviceId()
|
||||
+ ", UV = " + uv
|
||||
+ ", Temperature = " + temperature
|
||||
+ ", Signal level = " + signalLevel
|
||||
+ ", Battery level = " + batteryLevel;
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
|
||||
|
||||
uv = (data[6] & 0xFF) * 0.1;
|
||||
|
||||
temperature = (short) ((data[7] & 0x7F) << 8 | (data[8] & 0xFF)) * 0.1;
|
||||
if ((data[7] & 0x80) != 0) {
|
||||
temperature = -temperature;
|
||||
}
|
||||
|
||||
signalLevel = (byte) ((data[9] & 0xF0) >> 4);
|
||||
batteryLevel = (byte) (data[9] & 0x0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[10];
|
||||
|
||||
data[0] = 0x09;
|
||||
data[1] = RFXComBaseMessage.PacketType.UV.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
|
||||
data[4] = (byte) ((sensorId & 0xFF00) >> 8);
|
||||
data[5] = (byte) (sensorId & 0x00FF);
|
||||
|
||||
data[6] = (byte) (((short) (uv * 10)) & 0xFF);
|
||||
|
||||
short temp = (short) Math.abs(temperature * 10);
|
||||
data[7] = (byte) ((temp >> 8) & 0xFF);
|
||||
data[8] = (byte) (temp & 0xFF);
|
||||
if (temperature < 0) {
|
||||
data[7] |= 0x80;
|
||||
}
|
||||
|
||||
data[9] = (byte) (((signalLevel & 0x0F) << 4) | (batteryLevel & 0x0F));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_UV:
|
||||
return new DecimalType(uv);
|
||||
|
||||
case CHANNEL_TEMPERATURE:
|
||||
return (subType == SubType.UV3 ? new DecimalType(temperature) : UnDefType.UNDEF);
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.PacketType.UNDECODED_RF_MESSAGE;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComMessageTooLongException;
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedChannelException;
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedValueException;
|
||||
import org.openhab.binding.rfxcom.internal.handler.DeviceState;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
import org.openhab.core.util.HexUtils;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for undecoded messages.
|
||||
*
|
||||
* @author Ivan Martinez - Initial contribution
|
||||
* @author James Hewitt-Thomas - Migrated for OH2
|
||||
*/
|
||||
public class RFXComUndecodedRFMessage extends RFXComDeviceMessageImpl<RFXComUndecodedRFMessage.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
AC(0x00),
|
||||
ARC(0x01),
|
||||
ATI(0x02),
|
||||
HIDEKI_UPM(0x03),
|
||||
LACROSSE_VIKING(0x04),
|
||||
AD(0x05),
|
||||
MERTIK(0x06),
|
||||
OREGON1(0x07),
|
||||
OREGON2(0x08),
|
||||
OREGON3(0x09),
|
||||
PROGUARD(0x0A),
|
||||
VISONIC(0x0B),
|
||||
NEC(0x0C),
|
||||
FS20(0x0D),
|
||||
RESERVED(0x0E),
|
||||
BLINDS(0x0F),
|
||||
RUBICSON(0x10),
|
||||
AE(0x11),
|
||||
FINE_OFFSET(0x12),
|
||||
RGB(0x13),
|
||||
RTS(0x14),
|
||||
SELECT_PLUS(0x15),
|
||||
HOME_CONFORT(0x16),
|
||||
|
||||
UNKNOWN(0xFF);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
|
||||
public static SubType fromByte(int input) {
|
||||
for (SubType c : SubType.values()) {
|
||||
if (c.subType == input) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
return SubType.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public byte[] rawPayload = new byte[0];
|
||||
|
||||
public RFXComUndecodedRFMessage() {
|
||||
super(UNDECODED_RF_MESSAGE);
|
||||
}
|
||||
|
||||
public RFXComUndecodedRFMessage(byte[] message) throws RFXComException {
|
||||
encodeMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = super.toString();
|
||||
|
||||
str += ", Sub type = " + subType;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] message) throws RFXComException {
|
||||
super.encodeMessage(message);
|
||||
|
||||
subType = SubType.fromByte(super.subType);
|
||||
rawPayload = Arrays.copyOfRange(rawMessage, 4, rawMessage.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() throws RFXComException {
|
||||
if (rawPayload.length > 33) {
|
||||
throw new RFXComMessageTooLongException("Longest payload according to RFXCOM spec is 33 bytes.");
|
||||
}
|
||||
|
||||
final int rawPayloadLen = rawPayload.length;
|
||||
byte[] data = new byte[4 + rawPayloadLen];
|
||||
|
||||
data[0] = (byte) (data.length - 1);
|
||||
data[1] = UNDECODED_RF_MESSAGE.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
|
||||
System.arraycopy(rawPayload, 0, data, 4, rawPayloadLen);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return "UNDECODED";
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_RAW_MESSAGE:
|
||||
return new StringType(HexUtils.bytesToHex(rawMessage));
|
||||
|
||||
case CHANNEL_RAW_PAYLOAD:
|
||||
return new StringType(HexUtils.bytesToHex(rawPayload));
|
||||
|
||||
default:
|
||||
throw new RFXComUnsupportedChannelException("Nothing relevant for " + channelId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.rfxcom.internal.messages;
|
||||
|
||||
import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
|
||||
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
|
||||
|
||||
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
|
||||
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.DecimalType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
|
||||
/**
|
||||
* RFXCOM data class for temperature and humidity message.
|
||||
*
|
||||
* @author Marc SAUVEUR - Initial contribution
|
||||
* @author Pauli Anttila - Migrated for OH2
|
||||
* @author Mike Jagdis - Support all available data from sensors
|
||||
*/
|
||||
public class RFXComWindMessage extends RFXComBatteryDeviceMessage<RFXComWindMessage.SubType> {
|
||||
|
||||
public enum SubType implements ByteEnumWrapper {
|
||||
WIND1(1),
|
||||
WIND2(2),
|
||||
WIND3(3),
|
||||
WIND4(4),
|
||||
WIND5(5),
|
||||
WIND6(6),
|
||||
WIND7(7);
|
||||
|
||||
private final int subType;
|
||||
|
||||
SubType(int subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte toByte() {
|
||||
return (byte) subType;
|
||||
}
|
||||
}
|
||||
|
||||
public SubType subType;
|
||||
public int sensorId;
|
||||
public double windDirection;
|
||||
public double windSpeed;
|
||||
public double avgWindSpeed;
|
||||
public double temperature;
|
||||
public double chillTemperature;
|
||||
|
||||
public RFXComWindMessage() {
|
||||
super(PacketType.WIND);
|
||||
}
|
||||
|
||||
public RFXComWindMessage(byte[] data) throws RFXComException {
|
||||
encodeMessage(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
//@formatter:off
|
||||
return super.toString()
|
||||
+ ", Sub type = " + subType
|
||||
+ ", Device Id = " + getDeviceId()
|
||||
+ ", Wind direction = " + windDirection
|
||||
+ ", Wind gust = " + windSpeed
|
||||
+ ", Average wind speed = " + avgWindSpeed
|
||||
+ ", Temperature = " + temperature
|
||||
+ ", Chill temperature = " + chillTemperature
|
||||
+ ", Signal level = " + signalLevel
|
||||
+ ", Battery level = " + batteryLevel;
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeMessage(byte[] data) throws RFXComException {
|
||||
super.encodeMessage(data);
|
||||
|
||||
subType = fromByte(SubType.class, super.subType);
|
||||
sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
|
||||
|
||||
windDirection = (short) ((data[6] & 0xFF) << 8 | (data[7] & 0xFF));
|
||||
|
||||
if (subType != SubType.WIND5) {
|
||||
avgWindSpeed = (short) ((data[8] & 0xFF) << 8 | (data[9] & 0xFF)) * 0.1;
|
||||
}
|
||||
|
||||
windSpeed = (short) ((data[10] & 0xFF) << 8 | (data[11] & 0xFF)) * 0.1;
|
||||
|
||||
if (subType == SubType.WIND4) {
|
||||
temperature = (short) ((data[12] & 0x7F) << 8 | (data[13] & 0xFF)) * 0.1;
|
||||
if ((data[12] & 0x80) != 0) {
|
||||
temperature = -temperature;
|
||||
}
|
||||
|
||||
chillTemperature = (short) ((data[14] & 0x7F) << 8 | (data[15] & 0xFF)) * 0.1;
|
||||
if ((data[14] & 0x80) != 0) {
|
||||
chillTemperature = -chillTemperature;
|
||||
}
|
||||
}
|
||||
|
||||
signalLevel = (byte) ((data[16] & 0xF0) >> 4);
|
||||
batteryLevel = (byte) (data[16] & 0x0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeMessage() {
|
||||
byte[] data = new byte[17];
|
||||
|
||||
data[0] = 0x10;
|
||||
data[1] = PacketType.WIND.toByte();
|
||||
data[2] = subType.toByte();
|
||||
data[3] = seqNbr;
|
||||
data[4] = (byte) ((sensorId & 0xFF00) >> 8);
|
||||
data[5] = (byte) (sensorId & 0x00FF);
|
||||
|
||||
short absWindDirection = (short) Math.abs(windDirection);
|
||||
data[6] = (byte) ((absWindDirection >> 8) & 0xFF);
|
||||
data[7] = (byte) (absWindDirection & 0xFF);
|
||||
|
||||
if (subType != SubType.WIND5) {
|
||||
int absAvgWindSpeedTimesTen = (short) Math.abs(avgWindSpeed) * 10;
|
||||
data[8] = (byte) ((absAvgWindSpeedTimesTen >> 8) & 0xFF);
|
||||
data[9] = (byte) (absAvgWindSpeedTimesTen & 0xFF);
|
||||
}
|
||||
|
||||
int absWindSpeedTimesTen = (short) Math.abs(windSpeed) * 10;
|
||||
data[10] = (byte) ((absWindSpeedTimesTen >> 8) & 0xFF);
|
||||
data[11] = (byte) (absWindSpeedTimesTen & 0xFF);
|
||||
|
||||
if (subType == SubType.WIND4) {
|
||||
int temp = (short) Math.abs(temperature) * 10;
|
||||
data[12] = (byte) ((temp >> 8) & 0x7F);
|
||||
data[13] = (byte) (temp & 0xFF);
|
||||
if (temperature < 0) {
|
||||
data[12] |= 0x80;
|
||||
}
|
||||
|
||||
int chill = (short) Math.abs(chillTemperature) * 10;
|
||||
data[14] = (byte) ((chill >> 8) & 0x7F);
|
||||
data[15] = (byte) (chill & 0xFF);
|
||||
if (chillTemperature < 0) {
|
||||
data[14] |= 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
data[16] = (byte) (((signalLevel & 0x0F) << 4) | (batteryLevel & 0x0F));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceId() {
|
||||
return String.valueOf(sensorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
|
||||
switch (channelId) {
|
||||
case CHANNEL_WIND_DIRECTION:
|
||||
return new DecimalType(windDirection);
|
||||
|
||||
case CHANNEL_AVG_WIND_SPEED:
|
||||
return new DecimalType(avgWindSpeed);
|
||||
|
||||
case CHANNEL_WIND_SPEED:
|
||||
return new DecimalType(windSpeed);
|
||||
|
||||
case CHANNEL_TEMPERATURE:
|
||||
return new DecimalType(temperature);
|
||||
|
||||
case CHANNEL_CHILL_TEMPERATURE:
|
||||
return new DecimalType(chillTemperature);
|
||||
|
||||
default:
|
||||
return super.convertToState(channelId, deviceState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubType(SubType subType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeviceId(String deviceId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertFromState(String channelId, Type type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
|
||||
return ByteEnumUtil.convertSubType(SubType.class, subType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="rfxcom" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
|
||||
|
||||
<name>RFXCOM Binding</name>
|
||||
<description>This is the binding for RFXCOM transceivers.</description>
|
||||
<author>Pauli Anttila</author>
|
||||
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,163 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<bridge-type id="RFXrec433">
|
||||
<label>RFXrec433 USB 433.92MHz Receiver</label>
|
||||
<description>This is an RFXCOM 433.92MHz receiver bridge.</description>
|
||||
|
||||
<config-description>
|
||||
<parameter name="bridgeId" type="text" required="true">
|
||||
<label>Serial Number</label>
|
||||
<description>Serial number of the RFXCOM (FTDI) device</description>
|
||||
</parameter>
|
||||
<parameter name="disableDiscovery" type="boolean" required="true">
|
||||
<label>Disable Discovery of Unknown Devices</label>
|
||||
<description>These RF protocols are prone to noise. If you find a lot of unknown devices showing up in your inbox
|
||||
enabling this will stop devices being added to your inbox.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="ignoreConfig" type="boolean">
|
||||
<label>Skip Transceiver Configuration</label>
|
||||
<description>Fully skip and ignore RFXCOM transceiver configuration. Binding assume that RFXCOM transceiver is
|
||||
preconfigured e.g. via RFXcom Manager. When this is enabled, both set mode command and individual message
|
||||
configurations are ignored.</description>
|
||||
<default>true</default>
|
||||
</parameter>
|
||||
<parameter name="setMode" type="text">
|
||||
<label>RFXCOM Transceiver Mode</label>
|
||||
<description>RFXCOM transceiver set mode command. Command should be in hexadecimal string format and 28 characters
|
||||
(14 bytes) long. If set mode command is given, individual message configurations are ignored.</description>
|
||||
</parameter>
|
||||
<parameter name="transmitPower" type="integer" min="-18" max="10">
|
||||
<label>Transmit Power</label>
|
||||
<description>Transmit power in dBm, between -18dBm and +10dBm.</description>
|
||||
<default>-18</default>
|
||||
</parameter>
|
||||
<parameter name="enableUndecoded" type="boolean">
|
||||
<label>Undecoded Messages</label>
|
||||
<description>Enable display of unencoded messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableImagintronixOpus" type="boolean">
|
||||
<label>Imagintronix/Opus Messages</label>
|
||||
<description>Enable Imagintronix/Opus messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableByronSX" type="boolean">
|
||||
<label>Byron SX Messages</label>
|
||||
<description>Enable Byron SX messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableRSL" type="boolean">
|
||||
<label>RSL Messages</label>
|
||||
<description>Enable RSL messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableLighting4" type="boolean">
|
||||
<label>Lighting4 Messages</label>
|
||||
<description>Enable Lighting4 messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableFineOffsetViking" type="boolean">
|
||||
<label>FineOffset/Viking Messages</label>
|
||||
<description>Enable FineOffset/Viking messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableRubicson" type="boolean">
|
||||
<label>Rubicson Messages</label>
|
||||
<description>Enable Rubicson messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableAEBlyss" type="boolean">
|
||||
<label>AE Blyss Messages</label>
|
||||
<description>Enable AE Blyss messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableBlindsT1T2T3T4" type="boolean">
|
||||
<label>BlindsT1/T2/T3/T4 Messages</label>
|
||||
<description>Enable BlindsT1/T2/T3/T4 messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableBlindsT0" type="boolean">
|
||||
<label>BlindsT0 Messages</label>
|
||||
<description>Enable BlindsT0 messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableFS20" type="boolean">
|
||||
<label>FS20/Legrand CAD Messages</label>
|
||||
<description>Enable FS20/Legrand CAD messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableLaCrosse" type="boolean">
|
||||
<label>La Crosse Messages</label>
|
||||
<description>Enable La Crosse messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableHidekiUPM" type="boolean">
|
||||
<label>Hideki/UPM Messages</label>
|
||||
<description>Enable Hideki/UPM messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableADLightwaveRF" type="boolean">
|
||||
<label>AD LightwaveRF Messages</label>
|
||||
<description>Enable AD LightwaveRF messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableMertik" type="boolean">
|
||||
<label>Mertik Messages</label>
|
||||
<description>Enable Mertik messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableATI" type="boolean">
|
||||
<label>ATI Messages</label>
|
||||
<description>Enable ATI messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableOregonScientific" type="boolean">
|
||||
<label>Oregon Scientific Messages</label>
|
||||
<description>Enable Oregon Scientific messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableMeiantech" type="boolean">
|
||||
<label>Meiantech Messages</label>
|
||||
<description>Enable Meiantech messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableHomeEasyEU" type="boolean">
|
||||
<label>HomeEasy EU Messages</label>
|
||||
<description>Enable HomeEasy EU messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableAC" type="boolean">
|
||||
<label>AC Messages</label>
|
||||
<description>Enable AC messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableARC" type="boolean">
|
||||
<label>ARC Messages</label>
|
||||
<description>Enable ARC messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableX10" type="boolean">
|
||||
<label>X10 Messages</label>
|
||||
<description>Enable X10 messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableHomeConfort" type="boolean">
|
||||
<label>HomeConfort Messages</label>
|
||||
<description>Enable HomeConfort messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableKEELOQ" type="boolean">
|
||||
<label>KEELOQ Messages</label>
|
||||
<description>Enable KEELOQ messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
|
||||
</config-description>
|
||||
</bridge-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<bridge-type id="RFXtrx315">
|
||||
<label>RFXtrx315 USB 315MHz Transceiver</label>
|
||||
<description>This is an RFXCOM 315MHz transceiver bridge.</description>
|
||||
|
||||
<config-description>
|
||||
<parameter name="bridgeId" type="text" required="true">
|
||||
<label>Serial Number</label>
|
||||
<description>Serial number of the RFXCOM (FTDI) device</description>
|
||||
</parameter>
|
||||
<parameter name="disableDiscovery" type="boolean" required="true">
|
||||
<label>Disable Discovery of Unknown Devices</label>
|
||||
<description>These RF protocols are prone to noise. If you find a lot of unknown devices showing up in your inbox
|
||||
enabling this will stop devices being added to your inbox.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="ignoreConfig" type="boolean">
|
||||
<label>Skip Transceiver Configuration</label>
|
||||
<description>Fully skip and ignore RFXCOM transceiver configuration. Binding assume that RFXCOM transceiver is
|
||||
preconfigured e.g. via RFXcom Manager. When this is enabled, both set mode command and individual message
|
||||
configurations are ignored.</description>
|
||||
<default>true</default>
|
||||
</parameter>
|
||||
<parameter name="setMode" type="text">
|
||||
<label>RFXCOM Transceiver Mode</label>
|
||||
<description>RFXCOM transceiver set mode command. Command should be in hexadecimal string format and 28 characters
|
||||
(14 bytes) long. If set mode command is given, individual message configurations are ignored.</description>
|
||||
</parameter>
|
||||
<parameter name="transceiverType" type="text">
|
||||
<label>RFXCOM Transceiver Type</label>
|
||||
<description>RFXCOM transceiver type.</description>
|
||||
<default>315MHz</default>
|
||||
<options>
|
||||
<option value="310MHz">310MHz</option>
|
||||
<option value="315MHz">315MHz</option>
|
||||
</options>
|
||||
</parameter>
|
||||
<parameter name="transmitPower" type="integer" min="-18" max="10">
|
||||
<label>Transmit Power</label>
|
||||
<description>Transmit power in dBm, between -18dBm and +10dBm.</description>
|
||||
<default>-18</default>
|
||||
</parameter>
|
||||
<parameter name="enableUndecoded" type="boolean">
|
||||
<label>Undecoded Messages</label>
|
||||
<description>Enable display of unencoded messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableVisonic" type="boolean">
|
||||
<label>Visonic Messages</label>
|
||||
<description>Enable Visonic messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableX10" type="boolean">
|
||||
<label>X10 Messages</label>
|
||||
<description>Enable X10 messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
|
||||
</config-description>
|
||||
</bridge-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,163 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<bridge-type id="RFXtrx433">
|
||||
<label>RFXtrx433E USB 433.92MHz Transceiver</label>
|
||||
<description>This is an RFXCOM 433.92MHz transceiver bridge.</description>
|
||||
|
||||
<config-description>
|
||||
<parameter name="bridgeId" type="text" required="true">
|
||||
<label>Serial Number</label>
|
||||
<description>Serial number of the RFXCOM (FTDI) device</description>
|
||||
</parameter>
|
||||
<parameter name="disableDiscovery" type="boolean" required="true">
|
||||
<label>Disable Discovery of Unknown Devices</label>
|
||||
<description>These RF protocols are prone to noise. If you find a lot of unknown devices showing up in your inbox
|
||||
enabling this will stop devices being added to your inbox.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="ignoreConfig" type="boolean">
|
||||
<label>Skip Transceiver Configuration</label>
|
||||
<description>Fully skip and ignore RFXCOM transceiver configuration. Binding assume that RFXCOM transceiver is
|
||||
preconfigured e.g. via RFXcom Manager. When this is enabled, both set mode command and individual message
|
||||
configurations are ignored.</description>
|
||||
<default>true</default>
|
||||
</parameter>
|
||||
<parameter name="setMode" type="text">
|
||||
<label>RFXCOM Transceiver Mode</label>
|
||||
<description>RFXCOM transceiver set mode command. Command should be in hexadecimal string format and 28 characters
|
||||
(14 bytes) long. If set mode command is given, individual message configurations are ignored.</description>
|
||||
</parameter>
|
||||
<parameter name="transmitPower" type="integer" min="-18" max="10">
|
||||
<label>Transmit Power</label>
|
||||
<description>Transmit power in dBm, between -18dBm and +10dBm.</description>
|
||||
<default>-18</default>
|
||||
</parameter>
|
||||
<parameter name="enableUndecoded" type="boolean">
|
||||
<label>Undecoded Messages</label>
|
||||
<description>Enable display of unencoded messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableImagintronixOpus" type="boolean">
|
||||
<label>Imagintronix/Opus Messages</label>
|
||||
<description>Enable Imagintronix/Opus messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableByronSX" type="boolean">
|
||||
<label>Byron SX Messages</label>
|
||||
<description>Enable Byron SX messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableRSL" type="boolean">
|
||||
<label>RSL Messages</label>
|
||||
<description>Enable RSL messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableLighting4" type="boolean">
|
||||
<label>Lighting4 Messages</label>
|
||||
<description>Enable Lighting4 messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableFineOffsetViking" type="boolean">
|
||||
<label>FineOffset/Viking Messages</label>
|
||||
<description>Enable FineOffset/Viking messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableRubicson" type="boolean">
|
||||
<label>Rubicson Messages</label>
|
||||
<description>Enable Rubicson messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableAEBlyss" type="boolean">
|
||||
<label>AE Blyss Messages</label>
|
||||
<description>Enable AE Blyss messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableBlindsT1T2T3T4" type="boolean">
|
||||
<label>BlindsT1/T2/T3/T4 Messages</label>
|
||||
<description>Enable BlindsT1/T2/T3/T4 messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableBlindsT0" type="boolean">
|
||||
<label>BlindsT0 Messages</label>
|
||||
<description>Enable BlindsT0 messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableFS20" type="boolean">
|
||||
<label>FS20/Legrand CAD Messages</label>
|
||||
<description>Enable FS20/Legrand CAD messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableLaCrosse" type="boolean">
|
||||
<label>La Crosse Messages</label>
|
||||
<description>Enable La Crosse messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableHidekiUPM" type="boolean">
|
||||
<label>Hideki/UPM Messages</label>
|
||||
<description>Enable Hideki/UPM messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableADLightwaveRF" type="boolean">
|
||||
<label>AD LightwaveRF Messages</label>
|
||||
<description>Enable AD LightwaveRF messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableMertik" type="boolean">
|
||||
<label>Mertik Messages</label>
|
||||
<description>Enable Mertik messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableATI" type="boolean">
|
||||
<label>ATI Messages</label>
|
||||
<description>Enable ATI messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableOregonScientific" type="boolean">
|
||||
<label>Oregon Scientific Messages</label>
|
||||
<description>Enable Oregon Scientific messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableMeiantech" type="boolean">
|
||||
<label>Meiantech Messages</label>
|
||||
<description>Enable Meiantech messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableHomeEasyEU" type="boolean">
|
||||
<label>HomeEasy EU Messages</label>
|
||||
<description>Enable HomeEasy EU messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableAC" type="boolean">
|
||||
<label>AC Messages</label>
|
||||
<description>Enable AC messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableARC" type="boolean">
|
||||
<label>ARC Messages</label>
|
||||
<description>Enable ARC messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableX10" type="boolean">
|
||||
<label>X10 Messages</label>
|
||||
<description>Enable X10 messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableHomeConfort" type="boolean">
|
||||
<label>HomeConfort Messages</label>
|
||||
<description>Enable HomeConfort messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableKEELOQ" type="boolean">
|
||||
<label>KEELOQ Messages</label>
|
||||
<description>Enable KEELOQ messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
|
||||
</config-description>
|
||||
</bridge-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="bbqtemperature">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM BBQ Temperature Sensor</label>
|
||||
<description>A BBQ Temperature device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="foodTemperature" typeId="foodTemperature"/>
|
||||
<channel id="bbqTemperature" typeId="bbqTemperature"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
<channel id="batteryLevel" typeId="system.battery-level"/>
|
||||
<channel id="lowBattery" typeId="system.low-battery"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Sensor Id. Example 56923</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="blinds1">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Blinds1 Actuator</label>
|
||||
<description>A Blinds1 device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="command" typeId="command"/>
|
||||
<channel id="shutter" typeId="shutter"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
<channel id="batteryLevel" typeId="system.battery-level"/>
|
||||
<channel id="lowBattery" typeId="system.low-battery"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Sensor Id + unit code, separated by dot. Example 23455.1</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="T0">RollerTrol, Hasta new</option>
|
||||
<option value="T1">Hasta old</option>
|
||||
<option value="T2">A-OK RF01</option>
|
||||
<option value="T3">A-OK AC114/AC123</option>
|
||||
<option value="T4">Raex YR1326</option>
|
||||
<option value="T5">Media Mount</option>
|
||||
<option value="T6">DC106/Rohrmotor24-RMF/Yooda</option>
|
||||
<option value="T7">Forest</option>
|
||||
<option value="T8">Chamberlain CS4330CN</option>
|
||||
<option value="T11">ASP</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,188 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<bridge-type id="bridge">
|
||||
<label>RFXCOM USB Transceiver</label>
|
||||
<description>This is universal RFXCOM transceiver bridge for manual configuration purposes.</description>
|
||||
|
||||
<config-description>
|
||||
<parameter name="serialPort" type="text" required="true">
|
||||
<label>Serial Port</label>
|
||||
<context>serial-port</context>
|
||||
<limitToOptions>false</limitToOptions>
|
||||
<description>Serial port where RFXCOM transceiver is connected.</description>
|
||||
</parameter>
|
||||
<parameter name="disableDiscovery" type="boolean" required="true">
|
||||
<label>Disable Discovery of Unknown Devices</label>
|
||||
<description>These RF protocols are prone to noise. If you find a lot of unknown devices showing up in your inbox
|
||||
enabling this will stop devices being added to your inbox.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="ignoreConfig" type="boolean" required="true">
|
||||
<label>Skip Transceiver Configuration</label>
|
||||
<description>Fully skip and ignore RFXCOM transceiver configuration. Binding assume that RFXCOM transceiver is
|
||||
preconfigured e.g. via RFXcom Manager. When this is enabled, both set mode command and individual message
|
||||
configurations are ignored.
|
||||
</description>
|
||||
<default>true</default>
|
||||
</parameter>
|
||||
<parameter name="setMode" type="text">
|
||||
<label>RFXCOM Transceiver Mode</label>
|
||||
<description>RFXCOM transceiver set mode command. Command should be in hexadecimal string format and 28 characters
|
||||
(14 bytes) long. If set mode command is given, individual message configurations are ignored.
|
||||
</description>
|
||||
</parameter>
|
||||
<parameter name="transceiverType" type="text">
|
||||
<label>RFXCOM Transceiver Type</label>
|
||||
<description>RFXCOM transceiver type.</description>
|
||||
<default>433.92MHz</default>
|
||||
<options>
|
||||
<option value="310MHz">310MHz</option>
|
||||
<option value="315MHz">315MHz</option>
|
||||
<option value="433.92MHz receiver only">433.92MHz receiver only</option>
|
||||
<option value="433.92MHz">433.92MHz</option>
|
||||
</options>
|
||||
</parameter>
|
||||
<parameter name="transmitPower" type="integer" min="-18" max="10">
|
||||
<label>Transmit Power</label>
|
||||
<description>Transmit power in dBm, between -18dBm and +10dBm.</description>
|
||||
<default>-18</default>
|
||||
</parameter>
|
||||
<parameter name="enableUndecoded" type="boolean">
|
||||
<label>Undecoded Messages</label>
|
||||
<description>Enable display of unencoded messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableImagintronixOpus" type="boolean">
|
||||
<label>Imagintronix/Opus Messages</label>
|
||||
<description>Enable Imagintronix/Opus messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableByronSX" type="boolean">
|
||||
<label>Byron SX Messages</label>
|
||||
<description>Enable Byron SX messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableRSL" type="boolean">
|
||||
<label>RSL Messages</label>
|
||||
<description>Enable RSL messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableLighting4" type="boolean">
|
||||
<label>Lighting4 Messages</label>
|
||||
<description>Enable Lighting4 messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableFineOffsetViking" type="boolean">
|
||||
<label>FineOffset/Viking Messages</label>
|
||||
<description>Enable FineOffset/Viking messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableRubicson" type="boolean">
|
||||
<label>Rubicson Messages</label>
|
||||
<description>Enable Rubicson messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableAEBlyss" type="boolean">
|
||||
<label>AE Blyss Messages</label>
|
||||
<description>Enable AE Blyss messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableBlindsT1T2T3T4" type="boolean">
|
||||
<label>BlindsT1/T2/T3/T4 Messages</label>
|
||||
<description>Enable BlindsT1/T2/T3/T4 messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableBlindsT0" type="boolean">
|
||||
<label>BlindsT0 Messages</label>
|
||||
<description>Enable BlindsT0 messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableProGuard" type="boolean">
|
||||
<label>ProGuard Messages</label>
|
||||
<description>Enable ProGuard messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableFS20" type="boolean">
|
||||
<label>FS20/Legrand CAD Messages</label>
|
||||
<description>Enable FS20/Legrand CAD messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableLaCrosse" type="boolean">
|
||||
<label>La Crosse Messages</label>
|
||||
<description>Enable La Crosse messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableHidekiUPM" type="boolean">
|
||||
<label>Hideki/UPM Messages</label>
|
||||
<description>Enable Hideki/UPM messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableADLightwaveRF" type="boolean">
|
||||
<label>AD LightwaveRF Messages</label>
|
||||
<description>Enable AD LightwaveRF messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableMertik" type="boolean">
|
||||
<label>Mertik Messages</label>
|
||||
<description>Enable Mertik messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableVisonic" type="boolean">
|
||||
<label>Visonic Messages</label>
|
||||
<description>Enable Visonic messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableATI" type="boolean">
|
||||
<label>ATI Messages</label>
|
||||
<description>Enable ATI messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableOregonScientific" type="boolean">
|
||||
<label>Oregon Scientific Messages</label>
|
||||
<description>Enable Oregon Scientific messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableMeiantech" type="boolean">
|
||||
<label>Meiantech Messages</label>
|
||||
<description>Enable Meiantech messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableHomeEasyEU" type="boolean">
|
||||
<label>HomeEasy EU Messages</label>
|
||||
<description>Enable HomeEasy EU messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableAC" type="boolean">
|
||||
<label>AC Messages</label>
|
||||
<description>Enable AC messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableARC" type="boolean">
|
||||
<label>ARC Messages</label>
|
||||
<description>Enable ARC messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableX10" type="boolean">
|
||||
<label>X10 Messages</label>
|
||||
<description>Enable X10 messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableHomeConfort" type="boolean">
|
||||
<label>HomeConfort Messages</label>
|
||||
<description>Enable HomeConfort messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableKEELOQ" type="boolean">
|
||||
<label>KEELOQ Messages</label>
|
||||
<description>Enable KEELOQ messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
|
||||
</config-description>
|
||||
</bridge-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,283 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<!-- Channel definitions -->
|
||||
|
||||
<channel-type id="rawmessage">
|
||||
<item-type>String</item-type>
|
||||
<label>Raw Message</label>
|
||||
<description>Hexadecimal representation of undecoded RFXCOM messages including header and payload</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="rawpayload">
|
||||
<item-type>String</item-type>
|
||||
<label>Raw Payload</label>
|
||||
<description>Hexadecimal representation of payload of undecoded RFXCOM messages</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="command">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Command</label>
|
||||
<description>Command channel</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="commandId">
|
||||
<item-type>Number</item-type>
|
||||
<label>Command ID</label>
|
||||
<description>Command channel, ID of the command</description>
|
||||
<state min="0" max="255" step="1" pattern="%d" readOnly="false"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="commandString">
|
||||
<item-type>String</item-type>
|
||||
<label>Command String</label>
|
||||
<description>Command channel, Name of the command</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="contact">
|
||||
<item-type>Contact</item-type>
|
||||
<label>Contact</label>
|
||||
<description>Contact channel</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="datetime">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>DateTime</label>
|
||||
<description>DateTime channel</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="dimminglevel">
|
||||
<item-type>Dimmer</item-type>
|
||||
<label>Dimming Level</label>
|
||||
<description>Dimming level channel</description>
|
||||
<state min="0" max="100" step="1" readOnly="false"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="fanspeed">
|
||||
<item-type>Number</item-type>
|
||||
<label>Fan Speed</label>
|
||||
<description>Speed of fan</description>
|
||||
<state min="1" max="6" step="1" readOnly="false"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="fanspeedcontrol">
|
||||
<item-type>Rollershutter</item-type>
|
||||
<label>Global Speed Control</label>
|
||||
<description>Requested speed setting, UP, DOWN</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="fanspeedstring">
|
||||
<item-type>String</item-type>
|
||||
<label>Fan Speed</label>
|
||||
<description>Speed of fan</description>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="HI">Hi</option>
|
||||
<option value="MED">Med</option>
|
||||
<option value="LOW">Low</option>
|
||||
<option value="OFF">Off</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="fanreverse">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Reverse Fan</label>
|
||||
<description>Reverse direction of the Fan</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="mood">
|
||||
<item-type>Number</item-type>
|
||||
<label>Mood</label>
|
||||
<description>Mood channel</description>
|
||||
<state min="1" max="5" step="1" readOnly="false"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="status">
|
||||
<item-type>String</item-type>
|
||||
<label>Status</label>
|
||||
<description>Status channel</description>
|
||||
<state readOnly="false"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="setpoint">
|
||||
<item-type>Number</item-type>
|
||||
<label>Set-point</label>
|
||||
<description>Requested temperature</description>
|
||||
<state min="0" max="255" step="1" pattern="%d °C" readOnly="false"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="tempcontrol">
|
||||
<item-type>Rollershutter</item-type>
|
||||
<label>Global Temperature Control</label>
|
||||
<description>Requested temperature setting, UP, DOWN, STOP</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="motion">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Motion</label>
|
||||
<description>Motion detection sensor state</description>
|
||||
<state readOnly="false"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="rainrate">
|
||||
<item-type>Number</item-type>
|
||||
<label>Rain Rate</label>
|
||||
<description>Rain fall rate in millimeters per hour</description>
|
||||
<state pattern="%d mm/h" readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="raintotal">
|
||||
<item-type>Number</item-type>
|
||||
<label>Rain Total</label>
|
||||
<description>Total rain in millimeters</description>
|
||||
<state pattern="%.1f mm" readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="shutter">
|
||||
<item-type>Rollershutter</item-type>
|
||||
<label>Shutter</label>
|
||||
<description>Open/Close shutter/blind</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="venetianBlind">
|
||||
<item-type>Dimmer</item-type>
|
||||
<label>Venetian Blind</label>
|
||||
<description>Open/close and adjust angle of venetian blind</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="voltage">
|
||||
<item-type>Number</item-type>
|
||||
<label>Voltage</label>
|
||||
<description>Measured voltage</description>
|
||||
<state pattern="%d V" readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="instantpower">
|
||||
<item-type>Number</item-type>
|
||||
<label>Instant Power</label>
|
||||
<description>Instant power consumption in Watts</description>
|
||||
<state pattern="%d W" readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="totalusage">
|
||||
<item-type>Number</item-type>
|
||||
<label>Total Usage</label>
|
||||
<description>Used energy in Watt hours</description>
|
||||
<state pattern="%d Wh" readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="instantamp" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Instant Amp</label>
|
||||
<description>Instant current in Amperes</description>
|
||||
<state pattern="%.2f A" readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="totalamphour" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Total Ampere-hours</label>
|
||||
<description>Used "energy" in ampere-hours</description>
|
||||
<state pattern="%.2f Ah" readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="uv">
|
||||
<item-type>Number</item-type>
|
||||
<label>UV</label>
|
||||
<description>Current UV level</description>
|
||||
<state pattern="%.1f" readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="temperature">
|
||||
<item-type>Number</item-type>
|
||||
<label>Temperature</label>
|
||||
<description>Current temperature in degree Celsius</description>
|
||||
<category>Temperature</category>
|
||||
<state pattern="%.1f °C" readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="foodTemperature">
|
||||
<item-type>Number</item-type>
|
||||
<label>Food Temperature</label>
|
||||
<description>Current food temperature in degrees Celsius</description>
|
||||
<category>Temperature</category>
|
||||
<state pattern="%.1f °C" readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="bbqTemperature">
|
||||
<item-type>Number</item-type>
|
||||
<label>BBQ Temperature</label>
|
||||
<description>Current BBQ temperature in degrees Celsius</description>
|
||||
<category>Temperature</category>
|
||||
<state pattern="%.1f °C" readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="humidity">
|
||||
<item-type>Number</item-type>
|
||||
<label>Humidity</label>
|
||||
<description>Relative humidity level in percentages</description>
|
||||
<category>Humidity</category>
|
||||
<state min="0" max="100" step="1" pattern="%d %%" readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="humiditystatus" advanced="true">
|
||||
<item-type>String</item-type>
|
||||
<label>Humidity Status</label>
|
||||
<description>Current humidity status</description>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="NORMAL">Normal</option>
|
||||
<option value="COMFORT">Comfort</option>
|
||||
<option value="DRY">Dry</option>
|
||||
<option value="WET">Wet</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="pressure">
|
||||
<item-type>Number</item-type>
|
||||
<label>Pressure</label>
|
||||
<description>Barometric value in hPa.</description>
|
||||
<category>Pressure</category>
|
||||
<state min="0" max="2000" step="1" pattern="%d hPa." readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="forecast">
|
||||
<item-type>String</item-type>
|
||||
<label>Forecast</label>
|
||||
<description>Weather forecast from device</description>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="NO_INFO_AVAILABLE">No information available</option>
|
||||
<option value="SUNNY">Sunny</option>
|
||||
<option value="PARTLY_CLOUDY">Partly cloudy</option>
|
||||
<option value="CLOUDY">Cloudy</option>
|
||||
<option value="RAIN">Rain</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="windspeed">
|
||||
<item-type>Number</item-type>
|
||||
<label>Wind Speed</label>
|
||||
<description>Average wind speed in meters per second</description>
|
||||
<state pattern="%d m/s" readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="winddirection">
|
||||
<item-type>Number</item-type>
|
||||
<label>Wind Direction</label>
|
||||
<description>Wind direction in degrees</description>
|
||||
<state min="0" max="360" step="1" readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="chimesound">
|
||||
<item-type>Number</item-type>
|
||||
<label>Chime Sound</label>
|
||||
<description>Chime Sound (not all devices support multiple sounds)</description>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="chime">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Chime</label>
|
||||
<description>A Chime device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="chimeSound" typeId="chimesound"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Sensor Id. Example 2983</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="BYRONSX">Byron SX</option>
|
||||
<option value="BYRONMP001">Byron MP001</option>
|
||||
<option value="SELECTPLUS">SelectPlus</option>
|
||||
<option value="SELECTPLUS3">SelectPlus3</option>
|
||||
<option value="ENVIVO">Envivo</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="current">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Current Sensor</label>
|
||||
<description>A Current sensing device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="channel1Amps" typeId="instantamp"/>
|
||||
<channel id="channel2Amps" typeId="instantamp"/>
|
||||
<channel id="channel3Amps" typeId="instantamp"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
<channel id="batteryLevel" typeId="system.battery-level"/>
|
||||
<channel id="lowBattery" typeId="system.low-battery"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Sensor Id. Example 5693</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="ELEC1">CM113</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="currentenergy">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM CurrentEnergy Actuator</label>
|
||||
<description>A CurrentEnergy device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="channel1Amps" typeId="instantamp"/>
|
||||
<channel id="channel2Amps" typeId="instantamp"/>
|
||||
<channel id="channel3Amps" typeId="instantamp"/>
|
||||
<channel id="totalUsage" typeId="totalusage"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
<channel id="batteryLevel" typeId="system.battery-level"/>
|
||||
<channel id="lowBattery" typeId="system.low-battery"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Sensor Id. Example 47104</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="ELEC4">OWL - CM180i</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="curtain1">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Curtain1 Actuator</label>
|
||||
<description>A Curtain1 device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="command" typeId="command"/>
|
||||
<channel id="shutter" typeId="shutter"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
<channel id="batteryLevel" typeId="system.battery-level"/>
|
||||
<channel id="lowBattery" typeId="system.low-battery"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>House code + unit code, separated by dot. Example A.1</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="HARRISON">Harrison Curtain</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="datetime">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Date/time Sensor</label>
|
||||
<description>A DateTime device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="dateTime" typeId="datetime"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
<channel id="batteryLevel" typeId="system.battery-level"/>
|
||||
<channel id="lowBattery" typeId="system.low-battery"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Device id, example 47360</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="RTGR328N">Oregon RTGR328N</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="energy">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Energy Sensor</label>
|
||||
<description>A Energy device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="instantPower" typeId="instantpower"/>
|
||||
<channel id="totalUsage" typeId="totalusage"/>
|
||||
<channel id="instantAmp" typeId="instantamp"/>
|
||||
<channel id="totalAmpHour" typeId="totalamphour"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
<channel id="batteryLevel" typeId="system.battery-level"/>
|
||||
<channel id="lowBattery" typeId="system.low-battery"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Sensor Id. Example 5693</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="ELEC2">CM119/160</option>
|
||||
<option value="ELEC3">CM180</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="fan">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Fan Device</label>
|
||||
<description>A generic fan device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="command" typeId="command"/>
|
||||
<channel id="fanSpeed" typeId="fanspeedstring"/>
|
||||
<channel id="fanLight" typeId="command"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Unit Id. Example 'B', '7' or 'D'</description>
|
||||
<options>
|
||||
<option value="00">0</option>
|
||||
<option value="01">1</option>
|
||||
<option value="02">2</option>
|
||||
<option value="03">3</option>
|
||||
<option value="04">4</option>
|
||||
<option value="05">5</option>
|
||||
<option value="06">6</option>
|
||||
<option value="07">7</option>
|
||||
<option value="08">8</option>
|
||||
<option value="09">9</option>
|
||||
<option value="10">A</option>
|
||||
<option value="11">B</option>
|
||||
<option value="12">C</option>
|
||||
<option value="13">D</option>
|
||||
<option value="14">E</option>
|
||||
<option value="15">F</option>
|
||||
</options>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="LUCCI_AIR_FAN">Lucci Air fan</option>
|
||||
<option value="CASAFAN">Casafan</option>
|
||||
<option value="WESTINGHOUSE_7226640">Westinghouse 7226640</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="fan_falmec">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Fan Device - Falmec</label>
|
||||
<description>A Falmec fan device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="command" typeId="command"/>
|
||||
<channel id="fanSpeed" typeId="fanspeed"/>
|
||||
<channel id="fanLight" typeId="command"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Unit Id. Example 1000</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="FALMEC">Falmec</option>
|
||||
</options>
|
||||
<default>FALMEC</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="fan_lucci_dc">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Fan Device - Lucci Air DC</label>
|
||||
<description>A Lucci Air DC fan device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="commandString" typeId="commandString"/>
|
||||
<channel id="fanSpeed" typeId="fanspeedcontrol"/>
|
||||
<channel id="fanLight" typeId="command"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Unit Id. Example 1000</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="LUCCI_AIR_DC">Lucci Air DC</option>
|
||||
</options>
|
||||
<default>LUCCI_AIR_DC</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="fan_lucci_dc_ii">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Fan Device - Lucci Air DC II</label>
|
||||
<description>A Lucci Air DC II fan device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="command" typeId="command"/>
|
||||
<channel id="commandString" typeId="commandString"/>
|
||||
<channel id="fanSpeed" typeId="fanspeed"/>
|
||||
<channel id="fanLight" typeId="command"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Unit Id. Example 1000</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="LUCCI_AIR_DC_II">Lucci Air DC II</option>
|
||||
</options>
|
||||
<default>LUCCI_AIR_DC_II</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="homeconfort">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx315"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Home Confort Remote</label>
|
||||
<description>A Home Confort device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="command" typeId="command"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Device Id. Unit ID + house code + unit code, each separated by dot. Example 1234.A.1</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="humidity">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Humidity Sensor</label>
|
||||
<description>A Humidity device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="humidity" typeId="humidity"/>
|
||||
<channel id="humidityStatus" typeId="humiditystatus"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
<channel id="batteryLevel" typeId="system.battery-level"/>
|
||||
<channel id="lowBattery" typeId="system.low-battery"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Sensor Id. Example 5693</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="HUM1">LaCrosse TX3</option>
|
||||
<option value="HUM2">LaCrosse WS2300</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="lighting1">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx315"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Lighting1 Actuator</label>
|
||||
<description>A Lighting1 device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="command" typeId="command"/>
|
||||
<channel id="commandString" typeId="commandString"/>
|
||||
<channel id="contact" typeId="contact"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Device Id. House code + unit code, separated by dot. Example A.1</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="X10">X10 lighting</option>
|
||||
<option value="ARC">ARC</option>
|
||||
<option value="AB400D">ELRO AB400D (Flamingo)</option>
|
||||
<option value="WAVEMAN">Waveman</option>
|
||||
<option value="EMW200">Chacon EMW200</option>
|
||||
<option value="IMPULS">IMPULS</option>
|
||||
<option value="RISINGSUN">RisingSun</option>
|
||||
<option value="PHILIPS">Philips SBC</option>
|
||||
<option value="ENERGENIE">Energenie ENER010</option>
|
||||
<option value="ENERGENIE_5">Energenie 5-gang</option>
|
||||
<option value="COCO">COCO GDR2-2000R</option>
|
||||
<option value="HQ_COCO20">HQ COCO-20</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="lighting2">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Lighting2 Actuator</label>
|
||||
<description>A Lighting2 device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="command" typeId="command"/>
|
||||
<channel id="contact" typeId="contact"/>
|
||||
<channel id="dimmingLevel" typeId="dimminglevel"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Remote/switch/unit Id + unit code, separated by dot. Example 8773718.10</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="AC">AC</option>
|
||||
<option value="HOME_EASY_EU">HomeEasy EU</option>
|
||||
<option value="ANSLUT">ANSLUT</option>
|
||||
<option value="KAMBROOK">Kambrook RF3672</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="lighting4">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Lighting4 Actuator</label>
|
||||
<description>A Lighting4 device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="command" typeId="command"/>
|
||||
<channel id="commandId" typeId="commandId"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Device Id. Example 3456</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="PT2262">PT2262</option>
|
||||
</options>
|
||||
</parameter>
|
||||
<parameter name="pulse" type="integer" min="100" max="800">
|
||||
<label>Pulse Length</label>
|
||||
<description>Pulse length of the device</description>
|
||||
<default>350</default>
|
||||
</parameter>
|
||||
<parameter name="onCommandId" type="integer" required="true">
|
||||
<label>On Command</label>
|
||||
<description>Specifies command to be send when ON must be transmitted</description>
|
||||
<options>
|
||||
<option value="0">OFF (value 0)</option>
|
||||
<option value="1">ON (value 1)</option>
|
||||
<option value="2">OFF (value 2)</option>
|
||||
<option value="3">ON (value 3)</option>
|
||||
<option value="4">OFF (value 4)</option>
|
||||
<option value="5">ON (value 5)</option>
|
||||
<option value="6">value 5</option>
|
||||
<option value="7">ON (value 7)</option>
|
||||
<option value="8">value 8</option>
|
||||
<option value="9">ON (value 9)</option>
|
||||
<option value="10">ON (value 10)</option>
|
||||
<option value="11">ON (value 11)</option>
|
||||
<option value="12">ON (value 12)</option>
|
||||
<option value="13">value 13</option>
|
||||
<option value="14">OFF (value 14)</option>
|
||||
<option value="15">value 15</option>
|
||||
</options>
|
||||
<default>1</default>
|
||||
</parameter>
|
||||
<parameter name="offCommandId" type="integer" required="true">
|
||||
<label>Off Command</label>
|
||||
<description>Specifies command to be send when OFF must be transmitted</description>
|
||||
<options>
|
||||
<option value="0">OFF (value 0)</option>
|
||||
<option value="1">ON (value 1)</option>
|
||||
<option value="2">OFF (value 2)</option>
|
||||
<option value="3">ON (value 3)</option>
|
||||
<option value="4">OFF (value 4)</option>
|
||||
<option value="5">ON (value 5)</option>
|
||||
<option value="6">value 5</option>
|
||||
<option value="7">ON (value 7)</option>
|
||||
<option value="8">value 8</option>
|
||||
<option value="9">ON (value 9)</option>
|
||||
<option value="10">ON (value 10)</option>
|
||||
<option value="11">ON (value 11)</option>
|
||||
<option value="12">ON (value 12)</option>
|
||||
<option value="13">value 13</option>
|
||||
<option value="14">OFF (value 14)</option>
|
||||
<option value="15">value 15</option>
|
||||
</options>
|
||||
<default>4</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="lighting5">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Lighting5 Actuator</label>
|
||||
<description>A Lighting5 device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="command" typeId="command"/>
|
||||
<channel id="contact" typeId="contact"/>
|
||||
<channel id="dimmingLevel" typeId="dimminglevel"/>
|
||||
<channel id="mood" typeId="mood"/>
|
||||
<channel id="commandString" typeId="commandString"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Remote/switch/unit Id + unit code, separated by dot. Example 10001.1</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="AOKE">Aoke Relay</option>
|
||||
<option value="AVANTEK">Avantek</option>
|
||||
<option value="BBSB_NEW">BBSB new types</option>
|
||||
<option value="CONRAD_RSL2">Conrad RSL2</option>
|
||||
<option value="EMW100">EMW100 GAO/Everflourish</option>
|
||||
<option value="EURODOMEST">Eurodomest</option>
|
||||
<option value="IT">IT</option>
|
||||
<option value="KANGTAI">Kangtai, Cotech</option>
|
||||
<option value="LIGHTWAVERF">LightwaveRF, Siemens</option>
|
||||
<option value="LIVOLO">Livolo Dimmer or On/Off 1-3</option>
|
||||
<option value="LIVOLO_APPLIANCE">Livolo Appliance On/Off 1-10</option>
|
||||
<option value="MDREMOTE">MDREMOTE LED dimmer v106</option>
|
||||
<option value="MDREMOTE_107">MDREMOTE v107</option>
|
||||
<option value="MDREMOTE_108">MDREMOTE v108, EKAB-10KRF</option>
|
||||
<option value="RGB_TRC02">RGB TRC02 (2 batt)</option>
|
||||
<option value="RGB_TRC02_2">RGB TRC02_2 (3 batt)</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="lighting6">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Lighting6 Actuator</label>
|
||||
<description>A Lighting6 device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="command" typeId="command"/>
|
||||
<channel id="contact" typeId="contact"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Remote/switch/unit Id + group code + unit code, separated by dot. Example 100.A.1</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="BLYSS">Blyss</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="rain">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Rain Sensor</label>
|
||||
<description>A Rain device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="rainRate" typeId="rainrate"/>
|
||||
<channel id="rainTotal" typeId="raintotal"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
<channel id="batteryLevel" typeId="system.battery-level"/>
|
||||
<channel id="lowBattery" typeId="system.low-battery"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Sensor Id. Example 56923</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="RAIN1">RGR126/682/918/928</option>
|
||||
<option value="RAIN2">PCR800</option>
|
||||
<option value="RAIN3">TFA</option>
|
||||
<option value="RAIN4">UPM RG700</option>
|
||||
<option value="RAIN5">WS2300</option>
|
||||
<option value="RAIN6">La Crosse TX5</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="rfxsensor">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM RFXSensor</label>
|
||||
<description>A RFXSensor device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="temperature" typeId="temperature"/>
|
||||
<channel id="referenceVoltage" typeId="voltage"/>
|
||||
<channel id="voltage" typeId="voltage"/>
|
||||
<channel id="humidity" typeId="humidity"/>
|
||||
<channel id="pressure" typeId="pressure"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Sensor Id. Example 8</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="rfy">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Rfy Actuator</label>
|
||||
<description>A Rfy device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="command" typeId="command"/>
|
||||
<channel id="program" typeId="command">
|
||||
<label>Send Program Command</label>
|
||||
<description>Sends a program command to pair with a device when switched from off to on.</description>
|
||||
</channel>
|
||||
<channel id="shutter" typeId="shutter"/>
|
||||
<channel id="venetianBlind" typeId="venetianBlind"/>
|
||||
<channel id="sunWindDetector" typeId="command">
|
||||
<label>Sun+Wind Detector</label>
|
||||
<description>Enable the sun+wind detector.</description>
|
||||
</channel>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Unit Id + unit code, separated by dot. Example 100.1</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="RFY">RFY</option>
|
||||
<option value="RFY_EXT">RFY Ext</option>
|
||||
<option value="ASA">ASA</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="security1">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXtrx315"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Security1 Sensor</label>
|
||||
<description>A Security1 device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="status" typeId="status"/>
|
||||
<channel id="contact" typeId="contact"/>
|
||||
<channel id="motion" typeId="motion"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
<channel id="batteryLevel" typeId="system.battery-level"/>
|
||||
<channel id="lowBattery" typeId="system.low-battery"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Remote/sensor Id. Example 10001</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="X10_SECURITY">X10 security door/window sensor</option>
|
||||
<option value="X10_SECURITY_MOTION">X10 security motion sensor</option>
|
||||
<option value="X10_SECURITY_REMOTE">X10 security remote (no alive packets)</option>
|
||||
<option value="KD101">KD101 (no alive packets)</option>
|
||||
<option value="VISONIC_POWERCODE_SENSOR_PRIMARY_CONTACT">Visonic PowerCode door/window sensor – primary contact (with alive packets)</option>
|
||||
<option value="VISONIC_POWERCODE_MOTION">Visonic PowerCode motion sensor (with alive packets)</option>
|
||||
<option value="VISONIC_CODESECURE">Visonic CodeSecure (no alive packets)</option>
|
||||
<option value="VISONIC_POWERCODE_SENSOR_AUX_CONTACT">Visonic PowerCode door/window sensor – auxiliary contact (no alive packets)</option>
|
||||
<option value="MEIANTECH">Meiantech</option>
|
||||
<option value="SA30">SA30 (no alive packets)</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="security2">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXtrx315"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Security2 Sensor</label>
|
||||
<description>A Security2 device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="contact" typeId="contact"/>
|
||||
<channel id="contact1" typeId="contact"/>
|
||||
<channel id="contact2" typeId="contact"/>
|
||||
<channel id="contact3" typeId="contact"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
<channel id="batteryLevel" typeId="system.battery-level"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Remote/sensor Id. Example 10001</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,190 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<bridge-type id="tcpbridge">
|
||||
<label>RFXCOM USB Transceiver over TCP/IP</label>
|
||||
<description>This is universal RFXCOM transceiver bridge for using RFXCOM devices over a TCP/IP connection.</description>
|
||||
|
||||
<config-description>
|
||||
<parameter name="host" type="text" required="true">
|
||||
<label>Host</label>
|
||||
<description>Host where RFXCOM transceiver is connected.</description>
|
||||
<context>network-address</context>
|
||||
</parameter>
|
||||
<parameter name="port" type="integer" required="true">
|
||||
<label>Port</label>
|
||||
<description>Port where RFXCOM transceiver is connected.</description>
|
||||
<default>10001</default>
|
||||
</parameter>
|
||||
<parameter name="disableDiscovery" type="boolean" required="true">
|
||||
<label>Disable Discovery of Unknown Devices</label>
|
||||
<description>These RF protocols are prone to noise. If you find a lot of unknown devices showing up in your inbox
|
||||
enabling this will stop devices being added to your inbox.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="ignoreConfig" type="boolean" required="true">
|
||||
<label>Skip Transceiver Configuration</label>
|
||||
<description>Fully skip and ignore RFXCOM transceiver configuration. Binding assume that RFXCOM transceiver is
|
||||
preconfigured e.g. via RFXcom Manager. When this is enabled, both set mode command and individual message
|
||||
configurations are ignored.</description>
|
||||
<default>true</default>
|
||||
</parameter>
|
||||
<parameter name="setMode" type="text">
|
||||
<label>RFXCOM Transceiver Mode</label>
|
||||
<description>RFXCOM transceiver set mode command. Command should be in hexadecimal string format and 28 characters
|
||||
(14 bytes) long. If set mode command is given, individual message configurations are ignored.</description>
|
||||
</parameter>
|
||||
<parameter name="transceiverType" type="text">
|
||||
<label>RFXCOM Transceiver Type</label>
|
||||
<description>RFXCOM transceiver type.</description>
|
||||
<default>433.92MHz</default>
|
||||
<options>
|
||||
<option value="310MHz">310MHz</option>
|
||||
<option value="315MHz">315MHz</option>
|
||||
<option value="433.92MHz receiver only">433.92MHz receiver only</option>
|
||||
<option value="433.92MHz">433.92MHz</option>
|
||||
</options>
|
||||
</parameter>
|
||||
<parameter name="transmitPower" type="integer" min="-18" max="10">
|
||||
<label>Transmit Power</label>
|
||||
<description>Transmit power in dBm, between -18dBm and +10dBm.</description>
|
||||
<default>-18</default>
|
||||
</parameter>
|
||||
<parameter name="enableUndecoded" type="boolean">
|
||||
<label>Undecoded Messages</label>
|
||||
<description>Enable display of unencoded messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableImagintronixOpus" type="boolean">
|
||||
<label>Imagintronix/Opus Messages</label>
|
||||
<description>Enable Imagintronix/Opus messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableByronSX" type="boolean">
|
||||
<label>Byron SX Messages</label>
|
||||
<description>Enable Byron SX messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableRSL" type="boolean">
|
||||
<label>RSL Messages</label>
|
||||
<description>Enable RSL messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableLighting4" type="boolean">
|
||||
<label>Lighting4 Messages</label>
|
||||
<description>Enable Lighting4 messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableFineOffsetViking" type="boolean">
|
||||
<label>FineOffset/Viking Messages</label>
|
||||
<description>Enable FineOffset/Viking messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableRubicson" type="boolean">
|
||||
<label>Rubicson Messages</label>
|
||||
<description>Enable Rubicson messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableAEBlyss" type="boolean">
|
||||
<label>AE Blyss Messages</label>
|
||||
<description>Enable AE Blyss messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableBlindsT1T2T3T4" type="boolean">
|
||||
<label>BlindsT1/T2/T3/T4 Messages</label>
|
||||
<description>Enable BlindsT1/T2/T3/T4 messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableBlindsT0" type="boolean">
|
||||
<label>BlindsT0 Messages</label>
|
||||
<description>Enable BlindsT0 messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableProGuard" type="boolean">
|
||||
<label>ProGuard Messages</label>
|
||||
<description>Enable ProGuard messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableFS20" type="boolean">
|
||||
<label>FS20/Legrand CAD Messages</label>
|
||||
<description>Enable FS20/Legrand CAD messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableLaCrosse" type="boolean">
|
||||
<label>La Crosse Messages</label>
|
||||
<description>Enable La Crosse messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableHidekiUPM" type="boolean">
|
||||
<label>Hideki/UPM Messages</label>
|
||||
<description>Enable Hideki/UPM messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableADLightwaveRF" type="boolean">
|
||||
<label>AD LightwaveRF Messages</label>
|
||||
<description>Enable AD LightwaveRF messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableMertik" type="boolean">
|
||||
<label>Mertik Messages</label>
|
||||
<description>Enable Mertik messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableVisonic" type="boolean">
|
||||
<label>Visonic Messages</label>
|
||||
<description>Enable Visonic messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableATI" type="boolean">
|
||||
<label>ATI Messages</label>
|
||||
<description>Enable ATI messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableOregonScientific" type="boolean">
|
||||
<label>Oregon Scientific Messages</label>
|
||||
<description>Enable Oregon Scientific messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableMeiantech" type="boolean">
|
||||
<label>Meiantech Messages</label>
|
||||
<description>Enable Meiantech messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableHomeEasyEU" type="boolean">
|
||||
<label>HomeEasy EU Messages</label>
|
||||
<description>Enable HomeEasy EU messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableAC" type="boolean">
|
||||
<label>AC Messages</label>
|
||||
<description>Enable AC messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableARC" type="boolean">
|
||||
<label>ARC Messages</label>
|
||||
<description>Enable ARC messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableX10" type="boolean">
|
||||
<label>X10 Messages</label>
|
||||
<description>Enable X10 messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableHomeConfort" type="boolean">
|
||||
<label>HomeConfort Messages</label>
|
||||
<description>Enable HomeConfort messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="enableKEELOQ" type="boolean">
|
||||
<label>KEELOQ Messages</label>
|
||||
<description>Enable KEELOQ messages to RFXCOM transceiver.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
|
||||
</config-description>
|
||||
</bridge-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="temperature">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Temperature Sensor</label>
|
||||
<description>A Temperature device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="temperature" typeId="temperature"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
<channel id="batteryLevel" typeId="system.battery-level"/>
|
||||
<channel id="lowBattery" typeId="system.low-battery"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Sensor Id. Example 56923</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="TEMP1">THR128/138, THC138</option>
|
||||
<option value="TEMP2">THC238/268,THN132,THWR288,THRN122,THN122,AW129/131</option>
|
||||
<option value="TEMP3">THWR800</option>
|
||||
<option value="TEMP4">RTHN318</option>
|
||||
<option value="TEMP5">La Crosse TX2, TX3, TX4, TX17</option>
|
||||
<option value="TEMP6">TS15C. UPM temp only</option>
|
||||
<option value="TEMP7">Viking 02811, Proove TSS330, 311346</option>
|
||||
<option value="TEMP8">La Crosse WS2300</option>
|
||||
<option value="TEMP9">Rubicson</option>
|
||||
<option value="TEMP10">TFA 30.3133</option>
|
||||
<option value="TEMP11">WT0122</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="temperaturehumidity">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Temperature-Humidity Sensor</label>
|
||||
<description>A Temperature-Humidity device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="temperature" typeId="temperature"/>
|
||||
<channel id="humidity" typeId="humidity"/>
|
||||
<channel id="humidityStatus" typeId="humiditystatus"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
<channel id="batteryLevel" typeId="system.battery-level"/>
|
||||
<channel id="lowBattery" typeId="system.low-battery"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Sensor Id. Example 56923</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="TH1">THGN122/123, THGN132, THGR122/228/238/268</option>
|
||||
<option value="TH2">THGR810, THGN800</option>
|
||||
<option value="TH3">RTGR328</option>
|
||||
<option value="TH4">THGR328</option>
|
||||
<option value="TH5">WTGR800</option>
|
||||
<option value="TH6">THGR918/928, THGRN228, THGN500</option>
|
||||
<option value="TH7">TFA TS34C, Cresta</option>
|
||||
<option value="TH8">WT260,WT260H,WT440H,WT450,WT450H</option>
|
||||
<option value="TH9">Viking 02035,02038 (02035 has no humidity), Proove TSS320, 311501</option>
|
||||
<option value="TH10">Rubicson</option>
|
||||
<option value="TH11">EW109</option>
|
||||
<option value="TH12">Imagintronix/Opus XT300 Soil sensor</option>
|
||||
<option value="TH13">Alecto WS1700 and compatibles</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="rfxcom"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="temperaturehumiditybarometric">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
<bridge-type-ref id="tcpbridge"/>
|
||||
<bridge-type-ref id="RFXtrx433"/>
|
||||
<bridge-type-ref id="RFXrec433"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>RFXCOM Temperature-Humidity-Barometric Sensor</label>
|
||||
<description>A Temperature-Humidity-Barometric device.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="temperature" typeId="temperature"/>
|
||||
<channel id="humidity" typeId="humidity"/>
|
||||
<channel id="humidityStatus" typeId="humiditystatus"/>
|
||||
<channel id="pressure" typeId="pressure"/>
|
||||
<channel id="forecast" typeId="forecast"/>
|
||||
<channel id="signalLevel" typeId="system.signal-strength"/>
|
||||
<channel id="batteryLevel" typeId="system.battery-level"/>
|
||||
<channel id="lowBattery" typeId="system.low-battery"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="deviceId" type="text" required="true">
|
||||
<label>Device Id</label>
|
||||
<description>Sensor Id. Example 59648</description>
|
||||
</parameter>
|
||||
<parameter name="subType" type="text" required="true">
|
||||
<label>Sub Type</label>
|
||||
<description>Specifies device sub type.</description>
|
||||
<options>
|
||||
<option value="THB1">BTHR918, BTHGN129</option>
|
||||
<option value="THB2">BTHR918N, BTHR968</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user