]> git.basschouten.com Git - openhab-addons.git/blob
8822587f9bd78f2bcb42261bde53c10350563821
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.ecobee.internal.handler;
14
15 import static org.openhab.binding.ecobee.internal.EcobeeBindingConstants.*;
16
17 import java.util.Map;
18 import java.util.concurrent.ConcurrentHashMap;
19
20 import org.apache.commons.lang3.text.WordUtils;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.openhab.binding.ecobee.internal.config.EcobeeSensorConfiguration;
23 import org.openhab.binding.ecobee.internal.dto.thermostat.RemoteSensorCapabilityDTO;
24 import org.openhab.binding.ecobee.internal.dto.thermostat.RemoteSensorDTO;
25 import org.openhab.core.library.unit.Units;
26 import org.openhab.core.thing.Channel;
27 import org.openhab.core.thing.ChannelUID;
28 import org.openhab.core.thing.Thing;
29 import org.openhab.core.thing.ThingStatus;
30 import org.openhab.core.thing.ThingStatusDetail;
31 import org.openhab.core.thing.ThingStatusInfo;
32 import org.openhab.core.thing.binding.BaseThingHandler;
33 import org.openhab.core.thing.binding.builder.ChannelBuilder;
34 import org.openhab.core.thing.binding.builder.ThingBuilder;
35 import org.openhab.core.thing.type.ChannelTypeUID;
36 import org.openhab.core.types.Command;
37 import org.openhab.core.types.RefreshType;
38 import org.openhab.core.types.State;
39 import org.openhab.core.types.UnDefType;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 /**
44  * The {@link EcobeeSensorThingHandler} is responsible for updating the channels associated
45  * with an Ecobee remote sensor.
46  *
47  * @author Mark Hilbush - Initial contribution
48  */
49 @NonNullByDefault
50 public class EcobeeSensorThingHandler extends BaseThingHandler {
51
52     public static final String CAPABILITY_ADC = "adc";
53     public static final String CAPABILITY_CO2 = "co2";
54     public static final String CAPABILITY_DRY_CONTACT = "dryContact";
55     public static final String CAPABILITY_HUMIDITY = "humidity";
56     public static final String CAPABILITY_OCCUPANCY = "occupancy";
57     public static final String CAPABILITY_TEMPERATURE = "temperature";
58     public static final String CAPABILITY_UNKNOWN = "unknown";
59
60     private final Logger logger = LoggerFactory.getLogger(EcobeeSensorThingHandler.class);
61
62     private @NonNullByDefault({}) String sensorId;
63
64     private Map<String, State> stateCache = new ConcurrentHashMap<>();
65
66     public EcobeeSensorThingHandler(Thing thing) {
67         super(thing);
68     }
69
70     @Override
71     public void initialize() {
72         sensorId = getConfigAs(EcobeeSensorConfiguration.class).sensorId;
73         logger.debug("SensorThing: Initializing sensor '{}'", sensorId);
74         clearSavedState();
75         updateStatus(EcobeeUtils.isBridgeOnline(getBridge()) ? ThingStatus.ONLINE : ThingStatus.OFFLINE);
76     }
77
78     @Override
79     public void dispose() {
80         logger.debug("SensorThing: Disposing sensor '{}'", sensorId);
81     }
82
83     @Override
84     public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
85         if (bridgeStatusInfo.getStatus() == ThingStatus.ONLINE) {
86             updateStatus(ThingStatus.ONLINE);
87         } else {
88             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
89         }
90     }
91
92     @SuppressWarnings("null")
93     @Override
94     public void handleCommand(ChannelUID channelUID, Command command) {
95         if (command instanceof RefreshType) {
96             State state = stateCache.get(channelUID.getId());
97             if (state != null) {
98                 updateState(channelUID.getId(), state);
99             }
100             return;
101         }
102     }
103
104     public void updateChannels(RemoteSensorDTO sensor) {
105         logger.debug("SensorThing: Updating channels for sensor '{}({})'", sensor.id, sensor.name);
106         updateChannel(CH_SENSOR_ID, EcobeeUtils.undefOrString(sensor.id));
107         updateChannel(CH_SENSOR_NAME, EcobeeUtils.undefOrString(sensor.name));
108         updateChannel(CH_SENSOR_TYPE, EcobeeUtils.undefOrString(sensor.type));
109         updateChannel(CH_SENSOR_CODE, EcobeeUtils.undefOrString(sensor.code));
110         updateChannel(CH_SENSOR_IN_USE, EcobeeUtils.undefOrOnOff(sensor.inUse));
111         for (RemoteSensorCapabilityDTO capability : sensor.capability) {
112             updateCapabilityChannels(capability);
113         }
114     }
115
116     private void updateCapabilityChannels(RemoteSensorCapabilityDTO capability) {
117         ChannelUID uid = new ChannelUID(thing.getUID(), capability.type);
118         Channel channel = thing.getChannel(uid);
119         if (channel == null) {
120             logger.debug("SensorThing: Create channel '{}'", uid);
121             ThingBuilder thingBuilder;
122             thingBuilder = editThing();
123             channel = ChannelBuilder.create(uid, getAcceptedItemType(capability.type))
124                     .withLabel("Sensor " + WordUtils.capitalize(capability.type))
125                     .withType(getChannelTypeUID(capability.type)).build();
126             thingBuilder.withChannel(channel);
127             updateThing(thingBuilder.build());
128         }
129         logger.trace("Capability '{}' has type '{}' with value '{}'", capability.id, capability.type, capability.value);
130         updateCapabilityState(capability.type, capability.value);
131     }
132
133     // adc, co2, dryContact, humidity, temperature, occupancy, unknown.
134     private String getAcceptedItemType(String capabilityType) {
135         String acceptedItemType;
136         switch (capabilityType) {
137             case CAPABILITY_TEMPERATURE:
138                 acceptedItemType = "Number:Temperature";
139                 break;
140             case CAPABILITY_HUMIDITY:
141                 acceptedItemType = "Number:Dimensionless";
142                 break;
143             case CAPABILITY_OCCUPANCY:
144                 acceptedItemType = "Switch";
145                 break;
146             case CAPABILITY_ADC:
147             case CAPABILITY_CO2:
148             case CAPABILITY_DRY_CONTACT:
149             case CAPABILITY_UNKNOWN:
150             default:
151                 acceptedItemType = "String";
152                 break;
153         }
154         return acceptedItemType;
155     }
156
157     private ChannelTypeUID getChannelTypeUID(String capabilityType) {
158         ChannelTypeUID channelTypeUID;
159         switch (capabilityType) {
160             case CAPABILITY_TEMPERATURE:
161                 channelTypeUID = CHANNELTYPEUID_TEMPERATURE;
162                 break;
163             case CAPABILITY_HUMIDITY:
164                 channelTypeUID = CHANNELTYPEUID_HUMIDITY;
165                 break;
166             case CAPABILITY_OCCUPANCY:
167                 channelTypeUID = CHANNELTYPEUID_OCCUPANCY;
168                 break;
169             case CAPABILITY_ADC:
170             case CAPABILITY_CO2:
171             case CAPABILITY_DRY_CONTACT:
172             case CAPABILITY_UNKNOWN:
173             default:
174                 channelTypeUID = CHANNELTYPEUID_GENERIC;
175                 break;
176         }
177         return channelTypeUID;
178     }
179
180     private void updateCapabilityState(String capabilityType, String value) {
181         State state;
182         switch (capabilityType) {
183             case CAPABILITY_TEMPERATURE:
184                 try {
185                     state = EcobeeUtils.undefOrTemperature(Integer.parseInt(value));
186                 } catch (NumberFormatException e) {
187                     state = UnDefType.UNDEF;
188                 }
189                 break;
190             case CAPABILITY_HUMIDITY:
191                 try {
192                     state = EcobeeUtils.undefOrQuantity(Integer.parseInt(value), Units.PERCENT);
193                 } catch (NumberFormatException e) {
194                     state = UnDefType.UNDEF;
195                 }
196                 break;
197             case CAPABILITY_OCCUPANCY:
198                 state = EcobeeUtils.undefOrOnOff("true".equals(value));
199                 break;
200             case CAPABILITY_ADC:
201             case CAPABILITY_CO2:
202             case CAPABILITY_DRY_CONTACT:
203             case CAPABILITY_UNKNOWN:
204             default:
205                 state = EcobeeUtils.undefOrString(value);
206                 break;
207         }
208         updateChannel(capabilityType, state);
209     }
210
211     private void updateChannel(String channelId, State state) {
212         updateState(channelId, state);
213         stateCache.put(channelId, state);
214     }
215
216     private void clearSavedState() {
217         stateCache.clear();
218     }
219 }