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.draytonwiser.internal.handler;
15 import static org.openhab.binding.draytonwiser.internal.DraytonWiserBindingConstants.*;
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.openhab.binding.draytonwiser.internal.DraytonWiserBindingConstants.BatteryLevel;
20 import org.openhab.binding.draytonwiser.internal.DraytonWiserBindingConstants.SignalStrength;
21 import org.openhab.binding.draytonwiser.internal.api.DraytonWiserApiException;
22 import org.openhab.binding.draytonwiser.internal.handler.TRVHandler.SmartValveData;
23 import org.openhab.binding.draytonwiser.internal.model.DeviceDTO;
24 import org.openhab.binding.draytonwiser.internal.model.DraytonWiserDTO;
25 import org.openhab.binding.draytonwiser.internal.model.SmartValveDTO;
26 import org.openhab.core.library.types.DecimalType;
27 import org.openhab.core.library.types.OnOffType;
28 import org.openhab.core.library.types.QuantityType;
29 import org.openhab.core.library.types.StringType;
30 import org.openhab.core.library.unit.SIUnits;
31 import org.openhab.core.library.unit.Units;
32 import org.openhab.core.thing.Thing;
33 import org.openhab.core.types.Command;
34 import org.openhab.core.types.State;
35 import org.openhab.core.types.UnDefType;
38 * The {@link TRVHandler} is responsible for handling commands, which are
39 * sent to one of the channels.
41 * @author Andrew Schofield - Initial contribution
42 * @author Hilbrand Bouwkamp - Simplified handler to handle null data
45 public class TRVHandler extends DraytonWiserThingHandler<SmartValveData> {
47 private String serialNumber = "";
49 public TRVHandler(final Thing thing) {
54 public void initialize() {
56 serialNumber = getConfig().get("serialNumber").toString();
60 protected void handleCommand(final String channelId, final Command command) throws DraytonWiserApiException {
61 if (command instanceof OnOffType && CHANNEL_DEVICE_LOCKED.equals(channelId)) {
62 setDeviceLocked(OnOffType.ON.equals(command));
67 protected void refresh() {
68 updateState(CHANNEL_CURRENT_TEMPERATURE, this::getTemperature);
69 updateState(CHANNEL_CURRENT_DEMAND, this::getDemand);
70 updateState(CHANNEL_CURRENT_SETPOINT, this::getSetPoint);
71 updateState(CHANNEL_CURRENT_SIGNAL_RSSI, this::getSignalRSSI);
72 updateState(CHANNEL_CURRENT_SIGNAL_LQI, this::getSignalLQI);
73 updateState(CHANNEL_CURRENT_BATTERY_VOLTAGE, this::getBatteryVoltage);
74 updateState(CHANNEL_CURRENT_WISER_SIGNAL_STRENGTH, this::getWiserSignalStrength);
75 updateState(CHANNEL_CURRENT_SIGNAL_STRENGTH, this::getSignalStrength);
76 updateState(CHANNEL_CURRENT_WISER_BATTERY_LEVEL, this::getWiserBatteryLevel);
77 updateState(CHANNEL_CURRENT_BATTERY_LEVEL, this::getBatteryLevel);
78 updateState(CHANNEL_ZIGBEE_CONNECTED, this::getZigbeeConnected);
79 updateState(CHANNEL_DEVICE_LOCKED, this::getDeviceLocked);
83 protected @Nullable SmartValveData collectData(final DraytonWiserDTO domainDTOProxy) {
84 final SmartValveDTO smartValve = domainDTOProxy.getSmartValve(serialNumber);
85 final DeviceDTO device = smartValve == null ? null
86 : domainDTOProxy.getExtendedDeviceProperties(smartValve.getId());
88 return smartValve == null || device == null ? null : new SmartValveData(smartValve, device);
91 private State getSetPoint() {
92 return new QuantityType<>(getData().smartValve.getSetPoint() / 10.0, SIUnits.CELSIUS);
95 private State getDemand() {
96 final Integer demand = getData().smartValve.getPercentageDemand();
97 return demand == null ? UnDefType.UNDEF : new QuantityType<>(demand, Units.PERCENT);
100 private State getTemperature() {
101 final int fullScaleTemp = getData().smartValve.getMeasuredTemperature();
103 return OFFLINE_TEMPERATURE == fullScaleTemp ? UnDefType.UNDEF
104 : new QuantityType<>(fullScaleTemp / 10.0, SIUnits.CELSIUS);
107 private State getSignalRSSI() {
108 final Integer rssi = getData().device.getRssi();
109 return rssi == null ? UnDefType.UNDEF : new QuantityType<>(rssi, Units.DECIBEL_MILLIWATTS);
112 private State getSignalLQI() {
113 final Integer lqi = getData().device.getLqi();
114 return lqi == null ? UnDefType.UNDEF : new DecimalType(lqi);
117 private State getWiserSignalStrength() {
118 return new StringType(getData().device.getDisplayedSignalStrength());
121 private State getSignalStrength() {
122 return SignalStrength.toSignalStrength(getData().device.getDisplayedSignalStrength());
125 private State getBatteryVoltage() {
126 final Integer voltage = getData().device.getBatteryVoltage();
127 return voltage == null ? UnDefType.UNDEF : new QuantityType<>(voltage / 10.0, Units.VOLT);
130 private State getWiserBatteryLevel() {
131 return new StringType(getData().device.getBatteryLevel());
134 private State getBatteryLevel() {
135 return BatteryLevel.toBatteryLevel(getData().device.getBatteryLevel());
138 private State getZigbeeConnected() {
139 return OnOffType.from(getData().smartValve.getMeasuredTemperature() != OFFLINE_TEMPERATURE);
142 private State getDeviceLocked() {
143 final Boolean locked = getData().device.getDeviceLockEnabled();
145 return locked == null ? UnDefType.UNDEF : OnOffType.from(locked);
148 private void setDeviceLocked(final Boolean state) throws DraytonWiserApiException {
149 getApi().setDeviceLocked(getData().device.getId(), state);
152 static class SmartValveData {
153 public final SmartValveDTO smartValve;
154 public final DeviceDTO device;
156 public SmartValveData(final SmartValveDTO smartValve, final DeviceDTO device) {
157 this.smartValve = smartValve;
158 this.device = device;