Skip to content

Commit

Permalink
[enocean] Added support for Heat Recovery Ventilation devices (#9465)
Browse files Browse the repository at this point in the history
 * Implemented EEP family D2_50
 * Added new thing type (heatRecoveryVentilation) and channels for heat recovery ventilation units

Fixes #9465

Signed-off-by: Daniel Weber <[email protected]>
  • Loading branch information
fruggy83 committed Jan 29, 2021
1 parent 8494a0e commit ff3a31e
Show file tree
Hide file tree
Showing 12 changed files with 732 additions and 10 deletions.
30 changes: 30 additions & 0 deletions bundles/org.openhab.binding.enocean/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ Hence if your device supports one of the following EEPs the chances are good tha
| rollershutter | A5-3F/D2-05/A5-38 | 0x7F/00/08 | rollershutter | Eltako FSB14, NodOn SIN-2-RS-01| Teach-in/Discovery |
| measurementSwitch | D2-01 | 0x00-0F,11,12 | generalSwitch(/A/B), instantpower,<br/>totalusage, repeaterMode | NodOn In Wall Switch | Discovery |
| multiFunctionSmokeDetector | D2-14/F6-05 | 0x30/02 | smokeDetection, batteryLow | Insafe+, Afriso ASD | Discovery |
| heatRecoveryVentilation | D2-50 | 0x00,01,10,11 | a lot of different state channels | Dimplex DL WE2 | Discovery |
| classicDevice | F6-02 | 0x01-02 | virtualRockerswitchA, virtualRockerswitchB | - | Teach-in |

¹ Not all channels are supported by all devices, it depends which specific EEP type is used by the device, all thing types additionally support `rssi`, `repeatCount` and `lastReceived` channels
Expand Down Expand Up @@ -210,6 +211,12 @@ If you change the SenderId of your thing, you have to pair again the thing with
| | suppressRepeating | | true, false |
| multiFunctionSmokeDetector | receivingEEPId | | F6_05_02, D2_14_30 |
| | enoceanId | | |
| heatRecoveryVentilation | senderIdOffset | | 1-127 |
| | enoceanId | | |
| | sendingEEPId | | D2_50_00, D2_50_01,<br/>D2_50_10, D2_50_11 |
| | receivingEEPId | | D2_50_00, D2_50_01,<br/>D2_50_10, D2_50_11 |
| | broadcastMessages | | true, false |
| | suppressRepeating | | true, false |
| classicDevice | senderIdOffset | | 1-127 |
| | sendingEEPId | | F6_02_01, F6_02_02 |
| | broadcastMessages | | true, false |
Expand Down Expand Up @@ -267,6 +274,29 @@ The channels of a thing are determined automatically based on the chosen EEP.
| remainingPLT | Number:Time | Remaining product life time |
| hygroComfortIndex | String | Hygrothermal Comfort Index |
| indoorAirAnalysis | String | Indoor Air Analysis |
| ventilationOperationMode | String | Direct Operation Mode Control |
| fireplaceSafetyMode | Switch | Fireplace Safety Mode |
| heatExchangerBypassStatus | Contact | Heat Exchanger Bypass Status |
| supplyAirFlapStatus | Contact | Supply Air Flap Position |
| exhaustAirFlapStatus | Contact | Exhaust Air Flap Position |
| defrostMode | Switch | Defrost Mode |
| coolingProtectionMode | Switch | Cooling Protection Mode |
| outdoorAirHeaterStatus | Switch | Outdoor Air Heater Status |
| supplyAirHeaterStatus | Switch | Supply Air Heater Status |
| drainHeaterStatus | Switch | Drain Heater Status |
| timerOperationMode | Switch | Timer Operation Mode |
| weeklyTimerProgramStatus | Switch | Weekly Timer Program Status |
| roomTemperatureControlStatus | Switch | Room Temperature Control Status |
| airQualityValue1 | Number:Dimensionless | Air Quality Value in percent |
| airQualityValue2 | Number:Dimensionless | Air Quality Value in percent |
| outdoorAirTemperature | Number:Temperature | Outdoor Temperature |
| supplyAirTemperature | Number:Temperature | Supply Air Temperature |
| indoorAirTemperature | Number:Temperature | Indoor Temperature |
| exhaustAirTemperature | Number:Temperature | Exhaust Air Temperature |
| supplyAirFanAirFlowRate | Number:VolumetricFlowRate | Supply Air Fan Air Flow Rate |
| exhaustAirFanAirFlowRate | Number:VolumetricFlowRate | Exhaust Air Fan Air Flow Rate |
| supplyFanSpeed | Number:Dimensionless | Supply Fan Speed in rpm |
| exhaustFanSpeed | Number:Dimensionless | Exhaust Fan Speed |
| rssi | Number | Received Signal Strength Indication (dBm) of last received message |
| repeatCount | Number | Number of repeaters involved in the transmission of the telegram |
| lastReceived | DateTime | Date and time the last telegram was received |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.Set;

import javax.measure.quantity.Angle;
import javax.measure.quantity.Dimensionless;
import javax.measure.quantity.ElectricPotential;
import javax.measure.quantity.Energy;
import javax.measure.quantity.Illuminance;
Expand Down Expand Up @@ -78,13 +79,17 @@ public class EnOceanBindingConstants {
public static final ThingTypeUID THING_TYPE_MULTFUNCTIONSMOKEDETECTOR = new ThingTypeUID(BINDING_ID,
"multiFunctionSmokeDetector");

public static final Set<ThingTypeUID> SUPPORTED_DEVICE_THING_TYPES_UIDS = new HashSet<>(Arrays.asList(
THING_TYPE_PUSHBUTTON, THING_TYPE_ROCKERSWITCH, THING_TYPE_CLASSICDEVICE, THING_TYPE_CENTRALCOMMAND,
THING_TYPE_ROOMOPERATINGPANEL, THING_TYPE_MECHANICALHANDLE, THING_TYPE_CONTACT,
THING_TYPE_MEASUREMENTSWITCH, THING_TYPE_TEMPERATURESENSOR, THING_TYPE_TEMPERATUREHUMIDITYSENSOR,
THING_TYPE_GENERICTHING, THING_TYPE_ROLLERSHUTTER, THING_TYPE_OCCUPANCYSENSOR,
THING_TYPE_LIGHTTEMPERATUREOCCUPANCYSENSOR, THING_TYPE_LIGHTSENSOR, THING_TYPE_ENVIRONMENTALSENSOR,
THING_TYPE_AUTOMATEDMETERSENSOR, THING_TYPE_THERMOSTAT, THING_TYPE_MULTFUNCTIONSMOKEDETECTOR));
public static final ThingTypeUID THING_TYPE_HEATRECOVERYVENTILATION = new ThingTypeUID(BINDING_ID,
"heatRecoveryVentilation");

public static final Set<ThingTypeUID> SUPPORTED_DEVICE_THING_TYPES_UIDS = new HashSet<>(
Arrays.asList(THING_TYPE_PUSHBUTTON, THING_TYPE_ROCKERSWITCH, THING_TYPE_CLASSICDEVICE,
THING_TYPE_CENTRALCOMMAND, THING_TYPE_ROOMOPERATINGPANEL, THING_TYPE_MECHANICALHANDLE,
THING_TYPE_CONTACT, THING_TYPE_MEASUREMENTSWITCH, THING_TYPE_TEMPERATURESENSOR,
THING_TYPE_TEMPERATUREHUMIDITYSENSOR, THING_TYPE_GENERICTHING, THING_TYPE_ROLLERSHUTTER,
THING_TYPE_OCCUPANCYSENSOR, THING_TYPE_LIGHTTEMPERATUREOCCUPANCYSENSOR, THING_TYPE_LIGHTSENSOR,
THING_TYPE_ENVIRONMENTALSENSOR, THING_TYPE_AUTOMATEDMETERSENSOR, THING_TYPE_THERMOSTAT,
THING_TYPE_MULTFUNCTIONSMOKEDETECTOR, THING_TYPE_HEATRECOVERYVENTILATION));

// List of all Channel Type Ids, these type ids are also used as channel ids during dynamic creation of channels
// this makes it a lot easier as we do not have to manage a type id and an id, drawback long channel names
Expand Down Expand Up @@ -179,6 +184,30 @@ public class EnOceanBindingConstants {
public static final String CHANNEL_STATUS_REQUEST_EVENT = "statusRequestEvent";
public static final String CHANNEL_SEND_COMMAND = "sendCommand";

public static final String CHANNEL_VENTILATIONOPERATIONMODE = "ventilationOperationMode";
public static final String CHANNEL_FIREPLACESAFETYMODE = "fireplaceSafetyMode";
public static final String CHANNEL_HEATEXCHANGERBYPASSSTATUS = "heatExchangerBypassStatus";
public static final String CHANNEL_SUPPLYAIRFLAPSTATUS = "supplyAirFlapStatus";
public static final String CHANNEL_EXHAUSTAIRFLAPSTATUS = "exhaustAirFlapStatus";
public static final String CHANNEL_DEFROSTMODE = "defrostMode";
public static final String CHANNEL_COOLINGPROTECTIONMODE = "coolingProtectionMode";
public static final String CHANNEL_OUTDOORAIRHEATERSTATUS = "outdoorAirHeaterStatus";
public static final String CHANNEL_SUPPLYAIRHEATERSTATUS = "supplyAirHeaterStatus";
public static final String CHANNEL_DRAINHEATERSTATUS = "drainHeaterStatus";
public static final String CHANNEL_TIMEROPERATIONMODE = "timerOperationMode";
public static final String CHANNEL_WEEKLYTIMERPROGRAMSTATUS = "weeklyTimerProgramStatus";
public static final String CHANNEL_ROOMTEMPERATURECONTROLSTATUS = "roomTemperatureControlStatus";
public static final String CHANNEL_AIRQUALITYVALUE1 = "airQualityValue1";
public static final String CHANNEL_AIRQUALITYVALUE2 = "airQualityValue2";
public static final String CHANNEL_OUTDOORAIRTEMPERATURE = "outdoorAirTemperature";
public static final String CHANNEL_SUPPLYAIRTEMPERATURE = "supplyAirTemperature";
public static final String CHANNEL_INDOORAIRTEMPERATURE = "indoorAirTemperature";
public static final String CHANNEL_EXHAUSTAIRTEMPERATURE = "exhaustAirTemperature";
public static final String CHANNEL_SUPPLYAIRFANAIRFLOWRATE = "supplyAirFanAirFlowRate";
public static final String CHANNEL_EXHAUSTAIRFANAIRFLOWRATE = "exhaustAirFanAirFlowRate";
public static final String CHANNEL_SUPPLYFANSPEED = "supplyFanSpeed";
public static final String CHANNEL_EXHAUSTFANSPEED = "exhaustFanSpeed";

public static final Map<String, EnOceanChannelDescription> CHANNELID2CHANNELDESCRIPTION = Collections
.unmodifiableMap(new HashMap<String, EnOceanChannelDescription>() {
private static final long serialVersionUID = 1L;
Expand Down Expand Up @@ -384,6 +413,71 @@ public class EnOceanBindingConstants {
put(CHANNEL_SEND_COMMAND, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_SEND_COMMAND), CoreItemFactory.SWITCH));

put(CHANNEL_VENTILATIONOPERATIONMODE, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_VENTILATIONOPERATIONMODE), CoreItemFactory.STRING));
put(CHANNEL_FIREPLACESAFETYMODE, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_FIREPLACESAFETYMODE), CoreItemFactory.SWITCH));
put(CHANNEL_HEATEXCHANGERBYPASSSTATUS,
new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_HEATEXCHANGERBYPASSSTATUS),
CoreItemFactory.CONTACT));
put(CHANNEL_SUPPLYAIRFLAPSTATUS, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_SUPPLYAIRFLAPSTATUS), CoreItemFactory.CONTACT));
put(CHANNEL_EXHAUSTAIRFLAPSTATUS, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_EXHAUSTAIRFLAPSTATUS), CoreItemFactory.CONTACT));
put(CHANNEL_DEFROSTMODE, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_DEFROSTMODE), CoreItemFactory.SWITCH));
put(CHANNEL_COOLINGPROTECTIONMODE, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_COOLINGPROTECTIONMODE), CoreItemFactory.SWITCH));
put(CHANNEL_OUTDOORAIRHEATERSTATUS, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_OUTDOORAIRHEATERSTATUS), CoreItemFactory.SWITCH));
put(CHANNEL_SUPPLYAIRHEATERSTATUS, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_SUPPLYAIRHEATERSTATUS), CoreItemFactory.SWITCH));
put(CHANNEL_DRAINHEATERSTATUS, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_DRAINHEATERSTATUS), CoreItemFactory.SWITCH));
put(CHANNEL_TIMEROPERATIONMODE, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_TIMEROPERATIONMODE), CoreItemFactory.SWITCH));
put(CHANNEL_WEEKLYTIMERPROGRAMSTATUS, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_WEEKLYTIMERPROGRAMSTATUS), CoreItemFactory.SWITCH));
put(CHANNEL_ROOMTEMPERATURECONTROLSTATUS,
new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_ROOMTEMPERATURECONTROLSTATUS),
CoreItemFactory.SWITCH));
put(CHANNEL_AIRQUALITYVALUE1,
new EnOceanChannelDescription(new ChannelTypeUID(BINDING_ID, CHANNEL_AIRQUALITYVALUE1),
CoreItemFactory.NUMBER + ItemUtil.EXTENSION_SEPARATOR
+ Dimensionless.class.getSimpleName()));
put(CHANNEL_AIRQUALITYVALUE2,
new EnOceanChannelDescription(new ChannelTypeUID(BINDING_ID, CHANNEL_AIRQUALITYVALUE2),
CoreItemFactory.NUMBER + ItemUtil.EXTENSION_SEPARATOR
+ Dimensionless.class.getSimpleName()));
put(CHANNEL_OUTDOORAIRTEMPERATURE, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_OUTDOORAIRTEMPERATURE),
CoreItemFactory.NUMBER + ItemUtil.EXTENSION_SEPARATOR + Temperature.class.getSimpleName()));
put(CHANNEL_SUPPLYAIRTEMPERATURE, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_SUPPLYAIRTEMPERATURE),
CoreItemFactory.NUMBER + ItemUtil.EXTENSION_SEPARATOR + Temperature.class.getSimpleName()));
put(CHANNEL_INDOORAIRTEMPERATURE, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_INDOORAIRTEMPERATURE),
CoreItemFactory.NUMBER + ItemUtil.EXTENSION_SEPARATOR + Temperature.class.getSimpleName()));
put(CHANNEL_EXHAUSTAIRTEMPERATURE, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_EXHAUSTAIRTEMPERATURE),
CoreItemFactory.NUMBER + ItemUtil.EXTENSION_SEPARATOR + Temperature.class.getSimpleName()));
put(CHANNEL_SUPPLYAIRFANAIRFLOWRATE, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_SUPPLYAIRFANAIRFLOWRATE), CoreItemFactory.NUMBER
+ ItemUtil.EXTENSION_SEPARATOR + VolumetricFlowRate.class.getSimpleName()));
put(CHANNEL_EXHAUSTAIRFANAIRFLOWRATE, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_EXHAUSTAIRFANAIRFLOWRATE), CoreItemFactory.NUMBER
+ ItemUtil.EXTENSION_SEPARATOR + VolumetricFlowRate.class.getSimpleName()));
put(CHANNEL_SUPPLYFANSPEED,
new EnOceanChannelDescription(new ChannelTypeUID(BINDING_ID, CHANNEL_SUPPLYFANSPEED),
CoreItemFactory.NUMBER + ItemUtil.EXTENSION_SEPARATOR
+ Dimensionless.class.getSimpleName()));
put(CHANNEL_EXHAUSTFANSPEED,
new EnOceanChannelDescription(new ChannelTypeUID(BINDING_ID, CHANNEL_EXHAUSTFANSPEED),
CoreItemFactory.NUMBER + ItemUtil.EXTENSION_SEPARATOR
+ Dimensionless.class.getSimpleName()));

put(CHANNEL_REPEATERMODE, new EnOceanChannelDescription(
new ChannelTypeUID(BINDING_ID, CHANNEL_REPEATERMODE), CoreItemFactory.STRING));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,12 @@ public static byte[] concatAll(byte[] a, byte[]... rest) {
}
return result;
}

public static int tryParseInt(String value, int defaultValue) {
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
return defaultValue;
}
}
}
Loading

0 comments on commit ff3a31e

Please sign in to comment.