2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.touchwand.internal;
15 import static org.openhab.binding.touchwand.internal.TouchWandBindingConstants.*;
17 import java.util.ArrayList;
19 import javax.measure.quantity.Illuminance;
20 import javax.measure.quantity.Temperature;
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.openhab.binding.touchwand.internal.dto.TouchWandAlarmSensorCurrentStatus.BinarySensorEvent;
24 import org.openhab.binding.touchwand.internal.dto.TouchWandAlarmSensorCurrentStatus.Sensor;
25 import org.openhab.binding.touchwand.internal.dto.TouchWandUnitData;
26 import org.openhab.binding.touchwand.internal.dto.TouchWandUnitDataAlarmSensor;
27 import org.openhab.core.library.types.DecimalType;
28 import org.openhab.core.library.types.OnOffType;
29 import org.openhab.core.library.types.OpenClosedType;
30 import org.openhab.core.library.types.QuantityType;
31 import org.openhab.core.library.unit.SIUnits;
32 import org.openhab.core.library.unit.Units;
33 import org.openhab.core.thing.Channel;
34 import org.openhab.core.thing.Thing;
35 import org.openhab.core.thing.binding.builder.ThingBuilder;
36 import org.openhab.core.types.Command;
39 * The {@link TouchWandAlarmSensorHandler} is responsible for handling command for Alarm Sensor unit
42 * @author Roie Geron - Initial contribution
46 public class TouchWandAlarmSensorHandler extends TouchWandBaseUnitHandler {
48 private static final int BATT_LEVEL_LOW = 20;
49 private static final int BATT_LEVEL_LOW_HYS = 5;
51 private boolean isBatteryLow = false;
52 private boolean isFirstUpdateTouchWandUnitState = true;
54 public TouchWandAlarmSensorHandler(Thing thing) {
59 void updateTouchWandUnitState(TouchWandUnitData unitData) {
60 if (unitData instanceof TouchWandUnitDataAlarmSensor) {
61 TouchWandUnitDataAlarmSensor sensor = (TouchWandUnitDataAlarmSensor) unitData;
62 if (isFirstUpdateTouchWandUnitState) {
63 removeUnsupportedChannels(sensor);
64 isFirstUpdateTouchWandUnitState = false;
66 updateBatteryLevel(sensor);
67 updateIllumination(sensor);
68 updateChannelLeak(sensor);
69 updateChannelDoorWindow(sensor);
70 updateChannelMotion(sensor);
71 updateChannelTemperature(sensor);
73 logger.warn("updateTouchWandUnitState incompatible TouchWandUnitData instance");
78 void touchWandUnitHandleCommand(Command command) {
81 void updateBatteryLevel(TouchWandUnitDataAlarmSensor unitData) {
82 Integer battLevel = unitData.getCurrStatus().getBatt();
83 updateState(CHANNEL_BATTERY_LEVEL, new DecimalType(battLevel));
84 int lowThreshold = isBatteryLow ? BATT_LEVEL_LOW + BATT_LEVEL_LOW_HYS : BATT_LEVEL_LOW;
85 boolean lowBattery = (battLevel <= lowThreshold);
86 updateState(CHANNEL_BATTERY_LOW, OnOffType.from(lowBattery));
87 isBatteryLow = lowBattery;
90 void updateIllumination(TouchWandUnitDataAlarmSensor unitData) {
91 for (Sensor sensor : unitData.getCurrStatus().getSensorsStatus()) {
92 if (sensor.type == SENSOR_TYPE_LUMINANCE) {
93 updateState(CHANNEL_ILLUMINATION, new QuantityType<Illuminance>(sensor.value, Units.LUX));
98 void updateChannelLeak(TouchWandUnitDataAlarmSensor unitData) {
99 for (BinarySensorEvent bSensor : unitData.getCurrStatus().getbSensorsStatus()) {
100 if (bSensor.sensorType == SENSOR_TYPE_LEAK) {
101 boolean isLeak = bSensor.sensor.state;
102 updateState(CHANNEL_LEAK, OnOffType.from(isLeak));
107 void updateChannelDoorWindow(TouchWandUnitDataAlarmSensor unitData) {
108 for (BinarySensorEvent bSensor : unitData.getCurrStatus().getbSensorsStatus()) {
109 if (bSensor.sensorType == SENSOR_TYPE_DOOR_WINDOW) {
110 boolean isOpen = bSensor.sensor.state;
111 OpenClosedType myOpenClose;
112 myOpenClose = isOpen ? OpenClosedType.OPEN : OpenClosedType.CLOSED;
113 updateState(CHANNEL_DOORWINDOW, myOpenClose);
118 void updateChannelMotion(TouchWandUnitDataAlarmSensor unitData) {
119 for (BinarySensorEvent bSensor : unitData.getCurrStatus().getbSensorsStatus()) {
120 if (bSensor.sensorType == SENSOR_TYPE_MOTION) {
121 boolean hasMotion = bSensor.sensor.state;
122 updateState(CHANNEL_MOTION, OnOffType.from(hasMotion));
127 void updateChannelTemperature(TouchWandUnitDataAlarmSensor unitData) {
128 for (Sensor sensor : unitData.getCurrStatus().getSensorsStatus()) {
129 if (sensor.type == SENSOR_TYPE_TEMPERATURE) {
130 updateState(CHANNEL_TEMPERATURE, new QuantityType<Temperature>(sensor.value, SIUnits.CELSIUS));
135 void removeUnsupportedChannels(TouchWandUnitDataAlarmSensor unitData) {
136 ArrayList<Channel> toBeRemovedChannels = new ArrayList<>(thing.getChannels());
138 for (BinarySensorEvent bSensor : unitData.getCurrStatus().getbSensorsStatus()) {
139 switch (bSensor.sensorType) {
140 case SENSOR_TYPE_MOTION:
141 toBeRemovedChannels.remove(thing.getChannel(CHANNEL_MOTION));
143 case SENSOR_TYPE_DOOR_WINDOW:
144 toBeRemovedChannels.remove(thing.getChannel(CHANNEL_DOORWINDOW));
146 case SENSOR_TYPE_LEAK:
147 toBeRemovedChannels.remove(thing.getChannel(CHANNEL_LEAK));
152 for (Sensor sensor : unitData.getCurrStatus().getSensorsStatus()) {
153 switch (sensor.type) {
154 case SENSOR_TYPE_TEMPERATURE:
155 toBeRemovedChannels.remove(thing.getChannel(CHANNEL_TEMPERATURE));
157 case SENSOR_TYPE_LUMINANCE:
158 toBeRemovedChannels.remove(thing.getChannel(CHANNEL_ILLUMINATION));
163 if (unitData.getHasBattery()) {
164 toBeRemovedChannels.remove(thing.getChannel(CHANNEL_BATTERY_LEVEL));
165 toBeRemovedChannels.remove(thing.getChannel(CHANNEL_BATTERY_LOW));
168 ThingBuilder thingBuilder = editThing();
169 thingBuilder.withoutChannels(toBeRemovedChannels);
170 updateThing(thingBuilder.build());