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 sensor) {
61 if (isFirstUpdateTouchWandUnitState) {
62 removeUnsupportedChannels(sensor);
63 isFirstUpdateTouchWandUnitState = false;
65 updateBatteryLevel(sensor);
66 updateIllumination(sensor);
67 updateChannelLeak(sensor);
68 updateChannelDoorWindow(sensor);
69 updateChannelMotion(sensor);
70 updateChannelTemperature(sensor);
72 logger.warn("updateTouchWandUnitState incompatible TouchWandUnitData instance");
77 void touchWandUnitHandleCommand(Command command) {
80 void updateBatteryLevel(TouchWandUnitDataAlarmSensor unitData) {
81 Integer battLevel = unitData.getCurrStatus().getBatt();
82 updateState(CHANNEL_BATTERY_LEVEL, new DecimalType(battLevel));
83 int lowThreshold = isBatteryLow ? BATT_LEVEL_LOW + BATT_LEVEL_LOW_HYS : BATT_LEVEL_LOW;
84 boolean lowBattery = (battLevel <= lowThreshold);
85 updateState(CHANNEL_BATTERY_LOW, OnOffType.from(lowBattery));
86 isBatteryLow = lowBattery;
89 void updateIllumination(TouchWandUnitDataAlarmSensor unitData) {
90 for (Sensor sensor : unitData.getCurrStatus().getSensorsStatus()) {
91 if (sensor.type == SENSOR_TYPE_LUMINANCE) {
92 updateState(CHANNEL_ILLUMINATION, new QuantityType<Illuminance>(sensor.value, Units.LUX));
97 void updateChannelLeak(TouchWandUnitDataAlarmSensor unitData) {
98 for (BinarySensorEvent bSensor : unitData.getCurrStatus().getbSensorsStatus()) {
99 if (bSensor.sensorType == SENSOR_TYPE_LEAK) {
100 boolean isLeak = bSensor.sensor.state;
101 updateState(CHANNEL_LEAK, OnOffType.from(isLeak));
106 void updateChannelDoorWindow(TouchWandUnitDataAlarmSensor unitData) {
107 for (BinarySensorEvent bSensor : unitData.getCurrStatus().getbSensorsStatus()) {
108 if (bSensor.sensorType == SENSOR_TYPE_DOOR_WINDOW) {
109 boolean isOpen = bSensor.sensor.state;
110 OpenClosedType myOpenClose;
111 myOpenClose = isOpen ? OpenClosedType.OPEN : OpenClosedType.CLOSED;
112 updateState(CHANNEL_DOORWINDOW, myOpenClose);
117 void updateChannelMotion(TouchWandUnitDataAlarmSensor unitData) {
118 for (BinarySensorEvent bSensor : unitData.getCurrStatus().getbSensorsStatus()) {
119 if (bSensor.sensorType == SENSOR_TYPE_MOTION) {
120 boolean hasMotion = bSensor.sensor.state;
121 updateState(CHANNEL_MOTION, OnOffType.from(hasMotion));
126 void updateChannelTemperature(TouchWandUnitDataAlarmSensor unitData) {
127 for (Sensor sensor : unitData.getCurrStatus().getSensorsStatus()) {
128 if (sensor.type == SENSOR_TYPE_TEMPERATURE) {
129 updateState(CHANNEL_TEMPERATURE, new QuantityType<Temperature>(sensor.value, SIUnits.CELSIUS));
134 void removeUnsupportedChannels(TouchWandUnitDataAlarmSensor unitData) {
135 ArrayList<Channel> toBeRemovedChannels = new ArrayList<>(thing.getChannels());
137 for (BinarySensorEvent bSensor : unitData.getCurrStatus().getbSensorsStatus()) {
138 switch (bSensor.sensorType) {
139 case SENSOR_TYPE_MOTION:
140 toBeRemovedChannels.remove(thing.getChannel(CHANNEL_MOTION));
142 case SENSOR_TYPE_DOOR_WINDOW:
143 toBeRemovedChannels.remove(thing.getChannel(CHANNEL_DOORWINDOW));
145 case SENSOR_TYPE_LEAK:
146 toBeRemovedChannels.remove(thing.getChannel(CHANNEL_LEAK));
151 for (Sensor sensor : unitData.getCurrStatus().getSensorsStatus()) {
152 switch (sensor.type) {
153 case SENSOR_TYPE_TEMPERATURE:
154 toBeRemovedChannels.remove(thing.getChannel(CHANNEL_TEMPERATURE));
156 case SENSOR_TYPE_LUMINANCE:
157 toBeRemovedChannels.remove(thing.getChannel(CHANNEL_ILLUMINATION));
162 if (unitData.getHasBattery()) {
163 toBeRemovedChannels.remove(thing.getChannel(CHANNEL_BATTERY_LEVEL));
164 toBeRemovedChannels.remove(thing.getChannel(CHANNEL_BATTERY_LOW));
167 ThingBuilder thingBuilder = editThing();
168 thingBuilder.withoutChannels(toBeRemovedChannels);
169 updateThing(thingBuilder.build());