From 71d95260e254a4cfd02bd76a312e9d645b175ca6 Mon Sep 17 00:00:00 2001 From: Thomas Lauterbach <2452988+DrRSatzteil@users.noreply.github.com> Date: Sat, 31 Jul 2021 12:24:10 +0200 Subject: [PATCH] [enocean] Adds support for the D2_06_50 EEP type (#10949) * Initial D2_06_20 EEP Implementation. Signed-off-by: Thomas Lauterbach * added data validation Signed-off-by: Thomas Lauterbach * added channels for calibration Signed-off-by: Thomas Lauterbach * added manufacturer ID for discovery Signed-off-by: Thomas Lauterbach * Revert "added data validation" This reverts commit 945101056b7d0a79b6d53985cfcef8e06bf0a8aa. Signed-off-by: Thomas Lauterbach * fixing discovery by setting manufacturerId Signed-off-by: Thomas Lauterbach * fix spotless Signed-off-by: Thomas Lauterbach * added calibration channels Signed-off-by: Thomas Lauterbach * removed validation override Signed-off-by: Thomas Lauterbach * added manufacturer suffix Signed-off-by: Thomas Lauterbach * channel description updated Signed-off-by: Thomas Lauterbach * added calibration channels Signed-off-by: Thomas Lauterbach * mentioning calibration channels in documentation Signed-off-by: Thomas Lauterbach * shortened thing label Signed-off-by: Thomas Lauterbach Co-authored-by: Thomas Lauterbach --- bundles/org.openhab.binding.enocean/README.md | 9 + .../internal/EnOceanBindingConstants.java | 25 ++- .../enocean/internal/eep/D2_06/D2_06_50.java | 160 ++++++++++++++++++ .../binding/enocean/internal/eep/EEPType.java | 6 + .../handler/EnOceanBaseSensorHandler.java | 3 +- .../OH-INF/thing/WindowSashHandleSensor.xml | 37 ++++ .../main/resources/OH-INF/thing/channels.xml | 58 +++++++ 7 files changed, 294 insertions(+), 4 deletions(-) create mode 100644 bundles/org.openhab.binding.enocean/src/main/java/org/openhab/binding/enocean/internal/eep/D2_06/D2_06_50.java create mode 100644 bundles/org.openhab.binding.enocean/src/main/resources/OH-INF/thing/WindowSashHandleSensor.xml diff --git a/bundles/org.openhab.binding.enocean/README.md b/bundles/org.openhab.binding.enocean/README.md index ba21f39f03d97..4f7e407c33478 100644 --- a/bundles/org.openhab.binding.enocean/README.md +++ b/bundles/org.openhab.binding.enocean/README.md @@ -67,6 +67,7 @@ This binding is developed on and tested with the following devices * Thermokon SR04 room control * Hoppe SecuSignal window handles * Rocker switches (NodOn, Eltako FT55 etc) + * Siegenia Senso Secure window sensors However, because of the standardized EnOcean protocol it is more important which EEP this binding supports. Hence if your device supports one of the following EEPs the chances are good that your device is also supported by this binding. @@ -89,6 +90,7 @@ Hence if your device supports one of the following EEPs the chances are good tha | centralCommand | A5-38 | 0x08 | dimmer, generalSwitch | Eltako FUD14, FSR14 | Teach-in | | 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,
totalusage, repeaterMode | NodOn In Wall Switch | Discovery | +| windowSashHandleSensor | D2-06 | 0x50 | windowHandleState, windowSashState, batteryLevel, batteryLow, windowBreachEvent, windowCalibrationState, windowCalibrationStep | Siegenia Senso Secure | 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 | @@ -225,6 +227,8 @@ If you change the SenderId of your thing, you have to pair again the thing with | | broadcastMessages | | true, false | | | pollingInterval | | Integer | | | suppressRepeating | | true, false | +| windowSashHandleSensor | receivingEEPId | | D2_06_50 | +| | enoceanId | | | | multiFunctionSmokeDetector | receivingEEPId | | F6_05_02, D2_14_30 | | | enoceanId | | | | heatRecoveryVentilation | senderIdOffset | | 1-127 | @@ -255,6 +259,9 @@ The channels of a thing are determined automatically based on the chosen EEP. | longPress | Trigger | Channel type system:rawbutton, emits PRESSED and RELEASED events | | rockerswitchA/B | Trigger | Channel type system:rawrocker, emits DIR1_PRESSED, DIR1_RELEASED, DIR2_PRESSED, DIR2_RELEASED events | | windowHandleState | String | Textual representation of handle position (OPEN, CLOSED, TILTED) | +| windowSashState | String | Textual representation of sash position (OPEN, CLOSED, TILTED) | +| windowCalibrationState | String | Textual representation of the calibration state (OK, ERROR, INVALID) | +| windowCalibrationStep | String | Textual representation of the next step that must be performed for calibrating the device (e.g. NONE, SASH CLOSED HANDLE CLOSED, SASH CLOSED HANDLE OPEN, SASH OPEN HANDLE TILTED, and so on) | | contact | Contact | State OPEN/CLOSED (tilted handle => OPEN) | | temperature | Number:Temperature | Temperature in degree Celsius | | humidity | Number | Relative humidity level in percentages | @@ -317,6 +324,8 @@ The channels of a thing are determined automatically based on the chosen EEP. | repeatCount | Number | Number of repeaters involved in the transmission of the telegram | | lastReceived | DateTime | Date and time the last telegram was received | | statusRequestEvent | Trigger | Emits event 'requestAnswer' | +| windowBreachEvent | Trigger | Emits event 'ALARM' | + Items linked to bi-directional actuators (actuator sends status messages back) should always disable the `autoupdate`. This is especially true for Eltako rollershutter, as their position is calculated out of the current position and the moving time. diff --git a/bundles/org.openhab.binding.enocean/src/main/java/org/openhab/binding/enocean/internal/EnOceanBindingConstants.java b/bundles/org.openhab.binding.enocean/src/main/java/org/openhab/binding/enocean/internal/EnOceanBindingConstants.java index c6b3814c5edbc..a6ab12c07a5ff 100644 --- a/bundles/org.openhab.binding.enocean/src/main/java/org/openhab/binding/enocean/internal/EnOceanBindingConstants.java +++ b/bundles/org.openhab.binding.enocean/src/main/java/org/openhab/binding/enocean/internal/EnOceanBindingConstants.java @@ -77,6 +77,8 @@ public class EnOceanBindingConstants { public static final ThingTypeUID THING_TYPE_HEATRECOVERYVENTILATION = new ThingTypeUID(BINDING_ID, "heatRecoveryVentilation"); + public static final ThingTypeUID THING_TYPE_WINDOWSASHHANDLESENSOR = new ThingTypeUID(BINDING_ID, + "windowSashHandleSensor"); public static final Set SUPPORTED_DEVICE_THING_TYPES_UIDS = Set.of(THING_TYPE_PUSHBUTTON, THING_TYPE_ROCKERSWITCH, THING_TYPE_CLASSICDEVICE, THING_TYPE_CENTRALCOMMAND, THING_TYPE_ROOMOPERATINGPANEL, @@ -84,7 +86,8 @@ public class EnOceanBindingConstants { 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); + THING_TYPE_MULTFUNCTIONSMOKEDETECTOR, THING_TYPE_HEATRECOVERYVENTILATION, + THING_TYPE_WINDOWSASHHANDLESENSOR); // 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 @@ -138,6 +141,10 @@ public class EnOceanBindingConstants { public static final String CHANNEL_ROCKERSWITCHLISTENER_START = "rockerswitchListener"; public static final String CHANNEL_WINDOWHANDLESTATE = "windowHandleState"; + public static final String CHANNEL_WINDOWSASHSTATE = "windowSashState"; + public static final String CHANNEL_WINDOWCALIBRATIONSTATE = "windowCalibrationState"; + public static final String CHANNEL_WINDOWCALIBRATIONSTEP = "windowCalibrationStep"; + public static final String CHANNEL_WINDOWBREACHEVENT = "windowBreachEvent"; public static final String CHANNEL_CONTACT = "contact"; public static final String CHANNEL_TEACHINCMD = "teachInCMD"; public static final String CHANNEL_INSTANTPOWER = "instantpower"; @@ -293,8 +300,7 @@ public class EnOceanBindingConstants { Map.entry(CHANNEL_INDOORAIRANALYSIS, new EnOceanChannelDescription(new ChannelTypeUID(BINDING_ID, CHANNEL_INDOORAIRANALYSIS), CoreItemFactory.STRING)), - Map.entry( - CHANNEL_SETPOINT, + Map.entry(CHANNEL_SETPOINT, new EnOceanChannelDescription(new ChannelTypeUID(BINDING_ID, CHANNEL_SETPOINT), CoreItemFactory.NUMBER)), Map.entry(CHANNEL_CONTACT, @@ -303,6 +309,19 @@ public class EnOceanBindingConstants { Map.entry(CHANNEL_WINDOWHANDLESTATE, new EnOceanChannelDescription(new ChannelTypeUID(BINDING_ID, CHANNEL_WINDOWHANDLESTATE), CoreItemFactory.STRING)), + Map.entry(CHANNEL_WINDOWSASHSTATE, + new EnOceanChannelDescription(new ChannelTypeUID(BINDING_ID, CHANNEL_WINDOWSASHSTATE), + CoreItemFactory.STRING)), + Map.entry(CHANNEL_WINDOWCALIBRATIONSTATE, + new EnOceanChannelDescription(new ChannelTypeUID(BINDING_ID, CHANNEL_WINDOWCALIBRATIONSTATE), + CoreItemFactory.STRING)), + Map.entry(CHANNEL_WINDOWCALIBRATIONSTEP, + new EnOceanChannelDescription(new ChannelTypeUID(BINDING_ID, CHANNEL_WINDOWCALIBRATIONSTEP), + CoreItemFactory.STRING)), + + Map.entry(CHANNEL_WINDOWBREACHEVENT, + new EnOceanChannelDescription(new ChannelTypeUID(BINDING_ID, CHANNEL_WINDOWBREACHEVENT), null, null, + false, true)), Map.entry( CHANNEL_BATTERY_VOLTAGE, new EnOceanChannelDescription( diff --git a/bundles/org.openhab.binding.enocean/src/main/java/org/openhab/binding/enocean/internal/eep/D2_06/D2_06_50.java b/bundles/org.openhab.binding.enocean/src/main/java/org/openhab/binding/enocean/internal/eep/D2_06/D2_06_50.java new file mode 100644 index 0000000000000..8e962ae64381e --- /dev/null +++ b/bundles/org.openhab.binding.enocean/src/main/java/org/openhab/binding/enocean/internal/eep/D2_06/D2_06_50.java @@ -0,0 +1,160 @@ +/** + * Copyright (c) 2010-2021 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.enocean.internal.eep.D2_06; + +import static org.openhab.binding.enocean.internal.EnOceanBindingConstants.*; + +import java.util.function.Function; + +import org.openhab.binding.enocean.internal.eep.Base._VLDMessage; +import org.openhab.binding.enocean.internal.messages.ERP1Message; +import org.openhab.core.config.core.Configuration; +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.types.State; +import org.openhab.core.types.UnDefType; + +/** + * + * @author Thomas Lauterbach - Initial contribution + */ +public class D2_06_50 extends _VLDMessage { + + public D2_06_50() { + super(); + } + + public D2_06_50(ERP1Message packet) { + super(packet); + } + + protected State getWindowSashState() { + int sashState = bytes[1] & 0x7f; + if (sashState == 0x00) { + return UnDefType.UNDEF; + } + if (sashState < 0x04) { + return new StringType("CLOSED"); + } else if (sashState < 0x07) { + return new StringType("OPEN"); + } else if (sashState < 0x0A) { + return new StringType("TILTED"); + } + + return UnDefType.UNDEF; + } + + protected State getWindowHandleState() { + int handleState = bytes[1] & 0x7f; + if (handleState == 0x01 || handleState == 0x04 || handleState == 0x07) { + return new StringType("CLOSED"); + } else if (handleState == 0x02 || handleState == 0x05 || handleState == 0x08) { + return new StringType("OPEN"); + } else if (handleState == 0x03 || handleState == 0x06 || handleState == 0x09) { + return new StringType("TILTED"); + } + + return UnDefType.UNDEF; + } + + protected State getCalibrationState() { + int calibrationState = bytes[1] >>> 6; + if (calibrationState == 0x00) { + return new StringType("OK"); + } else if (calibrationState == 0x01) { + return new StringType("ERROR"); + } else if (calibrationState == 0x02) { + return new StringType("INVALID"); + } + + return UnDefType.UNDEF; + } + + protected State getCalibrationStep() { + int calibrationStep = bytes[1] & 0x3F; + switch (calibrationStep) { + case 0x00: + return new StringType("NONE"); + case 0x01: + return new StringType("SASH CLOSED HANDLE CLOSED"); + case 0x02: + return new StringType("SASH CLOSED HANDLE OPEN"); + case 0x03: + return new StringType("SASH CLOSED HANDLE TILTED"); + case 0x04: + return new StringType("SASH OPEN HANDLE CLOSED"); + case 0x05: + return new StringType("SASH OPEN HANDLE OPEN"); + case 0x06: + return new StringType("SASH OPEN HANDLE TILTED"); + case 0x07: + return new StringType("SASH TILTED HANDLE CLOSED"); + case 0x08: + return new StringType("SASH TILTED HANDLE OPEN"); + case 0x09: + return new StringType("SASH TILTED HANDLE TILTED"); + case 0x0A: + return new StringType("FRAME MAGNET VALIDATION"); + } + + return UnDefType.UNDEF; + } + + @Override + protected String convertToEventImpl(String channelId, String channelTypeId, String lastEvent, + Configuration config) { + + // Alarm + if (bytes[0] == 0x02) { + switch (channelId) { + case CHANNEL_WINDOWBREACHEVENT: + if (bytes[1] == 0x01) { + return "ALARM"; + } + } + } + return null; + } + + @Override + public State convertToStateImpl(String channelId, String channelTypeId, Function getCurrentStateFunc, + Configuration config) { + + // Window status + if (bytes[0] == 0x01) { + switch (channelId) { + case CHANNEL_WINDOWSASHSTATE: + return getWindowSashState(); + case CHANNEL_WINDOWHANDLESTATE: + return getWindowHandleState(); + case CHANNEL_BATTERY_LEVEL: + return new DecimalType(bytes[6] & 0x7f); + case CHANNEL_BATTERYLOW: + return getBit(bytes[6], 7) ? OnOffType.ON : OnOffType.OFF; + } + } + + // Calibration + if (bytes[0] == 0x11) { + switch (channelId) { + case CHANNEL_WINDOWCALIBRATIONSTATE: + return getCalibrationState(); + case CHANNEL_WINDOWCALIBRATIONSTEP: + return getCalibrationStep(); + } + } + + return UnDefType.UNDEF; + } +} diff --git a/bundles/org.openhab.binding.enocean/src/main/java/org/openhab/binding/enocean/internal/eep/EEPType.java b/bundles/org.openhab.binding.enocean/src/main/java/org/openhab/binding/enocean/internal/eep/EEPType.java index 69acb5382a6d0..f7cb5623df469 100644 --- a/bundles/org.openhab.binding.enocean/src/main/java/org/openhab/binding/enocean/internal/eep/EEPType.java +++ b/bundles/org.openhab.binding.enocean/src/main/java/org/openhab/binding/enocean/internal/eep/EEPType.java @@ -137,6 +137,7 @@ import org.openhab.binding.enocean.internal.eep.D2_01.D2_01_12_NodON; import org.openhab.binding.enocean.internal.eep.D2_03.D2_03_0A; import org.openhab.binding.enocean.internal.eep.D2_05.D2_05_00; +import org.openhab.binding.enocean.internal.eep.D2_06.D2_06_50; import org.openhab.binding.enocean.internal.eep.D2_14.D2_14_30; import org.openhab.binding.enocean.internal.eep.D2_50.D2_50; import org.openhab.binding.enocean.internal.eep.D5_00.D5_00_01; @@ -464,6 +465,11 @@ public enum EEPType { Rollershutter_D2(RORG.VLD, 0x05, 0x00, true, D2_05_00.class, THING_TYPE_ROLLERSHUTTER, CHANNEL_ROLLERSHUTTER), + WindowSashHandleSensor_50(RORG.VLD, 0x06, 0x50, false, "Siegenia", 0x005D, D2_06_50.class, + THING_TYPE_WINDOWSASHHANDLESENSOR, CHANNEL_WINDOWHANDLESTATE, CHANNEL_WINDOWSASHSTATE, + CHANNEL_BATTERY_LEVEL, CHANNEL_BATTERYLOW, CHANNEL_WINDOWBREACHEVENT, CHANNEL_WINDOWCALIBRATIONSTATE, + CHANNEL_WINDOWCALIBRATIONSTEP), + MultiFunctionSensor_30(RORG.VLD, 0x14, 0x30, false, D2_14_30.class, THING_TYPE_MULTFUNCTIONSMOKEDETECTOR, CHANNEL_SMOKEDETECTION, CHANNEL_SENSORFAULT, CHANNEL_TIMESINCELASTMAINTENANCE, CHANNEL_BATTERY_LEVEL, CHANNEL_REMAININGPLT, CHANNEL_TEMPERATURE, CHANNEL_HUMIDITY, CHANNEL_HYGROCOMFORTINDEX, diff --git a/bundles/org.openhab.binding.enocean/src/main/java/org/openhab/binding/enocean/internal/handler/EnOceanBaseSensorHandler.java b/bundles/org.openhab.binding.enocean/src/main/java/org/openhab/binding/enocean/internal/handler/EnOceanBaseSensorHandler.java index 736b37be23671..66c9c28fa069b 100644 --- a/bundles/org.openhab.binding.enocean/src/main/java/org/openhab/binding/enocean/internal/handler/EnOceanBaseSensorHandler.java +++ b/bundles/org.openhab.binding.enocean/src/main/java/org/openhab/binding/enocean/internal/handler/EnOceanBaseSensorHandler.java @@ -55,7 +55,8 @@ public class EnOceanBaseSensorHandler extends EnOceanBaseThingHandler implements THING_TYPE_MECHANICALHANDLE, THING_TYPE_CONTACT, THING_TYPE_TEMPERATURESENSOR, THING_TYPE_TEMPERATUREHUMIDITYSENSOR, THING_TYPE_ROCKERSWITCH, THING_TYPE_OCCUPANCYSENSOR, THING_TYPE_LIGHTTEMPERATUREOCCUPANCYSENSOR, THING_TYPE_LIGHTSENSOR, THING_TYPE_PUSHBUTTON, - THING_TYPE_AUTOMATEDMETERSENSOR, THING_TYPE_ENVIRONMENTALSENSOR, THING_TYPE_MULTFUNCTIONSMOKEDETECTOR); + THING_TYPE_AUTOMATEDMETERSENSOR, THING_TYPE_ENVIRONMENTALSENSOR, THING_TYPE_MULTFUNCTIONSMOKEDETECTOR, + THING_TYPE_WINDOWSASHHANDLESENSOR); protected final Hashtable receivingEEPTypes = new Hashtable<>(); diff --git a/bundles/org.openhab.binding.enocean/src/main/resources/OH-INF/thing/WindowSashHandleSensor.xml b/bundles/org.openhab.binding.enocean/src/main/resources/OH-INF/thing/WindowSashHandleSensor.xml new file mode 100644 index 0000000000000..c38a7d5bd3bb2 --- /dev/null +++ b/bundles/org.openhab.binding.enocean/src/main/resources/OH-INF/thing/WindowSashHandleSensor.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + Combined sensor for window/door sash state and handle state + + + + + EnOceanId of device this thing belongs to + + + + EEP which is used by handle + + + + true + + + + false + + + + + + diff --git a/bundles/org.openhab.binding.enocean/src/main/resources/OH-INF/thing/channels.xml b/bundles/org.openhab.binding.enocean/src/main/resources/OH-INF/thing/channels.xml index 941eb0d76487a..ca28de25dd60e 100644 --- a/bundles/org.openhab.binding.enocean/src/main/resources/OH-INF/thing/channels.xml +++ b/bundles/org.openhab.binding.enocean/src/main/resources/OH-INF/thing/channels.xml @@ -158,6 +158,64 @@ + + String + + Describes the window sash state + + + + + + + + + + + String + + Describes the window calibration state + + + + + + + + + + + String + + Calibration step that should be performed next + + + + + + + + + + + + + + + + + + + trigger + + Is triggered 10 times in 5 seconds when the sensor detects a break-in attempt. + + + + + + + Number:Power