]> git.basschouten.com Git - openhab-addons.git/blob
71006e95867c0254787b6bbcce16c8e06728cc84
[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.ambientweather.internal.handler;
14
15 import java.time.Instant;
16 import java.time.ZoneId;
17 import java.time.ZonedDateTime;
18 import java.time.format.DateTimeParseException;
19
20 import javax.measure.Unit;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.openhab.binding.ambientweather.internal.config.StationConfig;
25 import org.openhab.binding.ambientweather.internal.processor.ProcessorFactory;
26 import org.openhab.binding.ambientweather.internal.processor.ProcessorNotFoundException;
27 import org.openhab.core.common.AbstractUID;
28 import org.openhab.core.i18n.TimeZoneProvider;
29 import org.openhab.core.library.types.DateTimeType;
30 import org.openhab.core.library.types.DecimalType;
31 import org.openhab.core.library.types.QuantityType;
32 import org.openhab.core.library.types.StringType;
33 import org.openhab.core.thing.ChannelUID;
34 import org.openhab.core.thing.Thing;
35 import org.openhab.core.thing.ThingStatus;
36 import org.openhab.core.thing.ThingStatusDetail;
37 import org.openhab.core.thing.ThingStatusInfo;
38 import org.openhab.core.thing.binding.BaseThingHandler;
39 import org.openhab.core.types.Command;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 /**
44  * The {@link AmbientWeatherStationHandler} is responsible for processing
45  * info and weather data updates.
46  *
47  * @author Mark Hilbush - Initial contribution
48  */
49 @NonNullByDefault
50 public class AmbientWeatherStationHandler extends BaseThingHandler {
51     private final Logger logger = LoggerFactory.getLogger(AmbientWeatherStationHandler.class);
52
53     // MAC address for weather station handled by this thing handler
54     private @Nullable String macAddress;
55
56     // Short name for logging station type
57     private String station;
58
59     // Time zone provider representing time zone configured in openHAB config
60     TimeZoneProvider timeZoneProvider;
61
62     public AmbientWeatherStationHandler(Thing thing, TimeZoneProvider timeZoneProvider) {
63         super(thing);
64
65         this.timeZoneProvider = timeZoneProvider;
66
67         // Name of station thing type used in logging
68         String s = thing.getThingTypeUID().getAsString();
69         station = s.substring(s.indexOf(AbstractUID.SEPARATOR) + 1).toUpperCase();
70     }
71
72     @Override
73     public void initialize() {
74         macAddress = getConfigAs(StationConfig.class).macAddress;
75         logger.debug("Station {}: Initializing station handler for MAC {}", station, macAddress);
76         try {
77             ProcessorFactory.getProcessor(thing).setChannelGroupId();
78             ProcessorFactory.getProcessor(thing).setNumberOfSensors();
79         } catch (ProcessorNotFoundException e) {
80             logger.warn("Station {}: Unable to set channel group Id and/or number of sensors: {}", station,
81                     e.getMessage());
82             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR, e.getMessage());
83             return;
84         }
85         Thing bridge = getBridge();
86         if (bridge != null) {
87             logger.debug("Station {}: Set station status to match bridge status: {}", station, bridge.getStatus());
88             updateStatus(bridge.getStatus());
89         }
90     }
91
92     @Override
93     public void dispose() {
94         macAddress = getConfigAs(StationConfig.class).macAddress;
95         logger.debug("Station {}: Disposing station handler for MAC {}", station, macAddress);
96         updateStatus(ThingStatus.OFFLINE);
97     }
98
99     @Override
100     public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
101         ThingStatus bridgeStatus = bridgeStatusInfo.getStatus();
102         logger.debug("Station {}: Detected bridge status changed to '{}', Update my status", station, bridgeStatus);
103         if (bridgeStatus == ThingStatus.OFFLINE) {
104             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
105         } else if (bridgeStatus == ThingStatus.ONLINE) {
106             updateStatus(ThingStatus.ONLINE);
107         }
108     }
109
110     /*
111      * Handle an update to the station name and location
112      */
113     public void handleInfoEvent(String mac, String name, String location) {
114         logger.debug("Station {}: Update name={} and location={} for MAC {}", station, name, location, macAddress);
115         try {
116             ProcessorFactory.getProcessor(thing).processInfoUpdate(this, station, name, location);
117         } catch (ProcessorNotFoundException e) {
118             logger.debug("Unable to process info event: {}", e.getMessage());
119         }
120     }
121
122     /*
123      * Handle an update to the weather data.
124      */
125     public void handleWeatherDataEvent(String jsonData) {
126         logger.debug("Station {}: Processing data event for MAC {}", station, macAddress);
127         try {
128             ProcessorFactory.getProcessor(thing).processWeatherData(this, station, jsonData);
129         } catch (ProcessorNotFoundException e) {
130             logger.debug("Unable to process weather data event: {}", e.getMessage());
131         }
132     }
133
134     public void updateQuantity(String groupId, String channelId, @Nullable Number value, Unit<?> unit) {
135         String channel = groupId + "#" + channelId;
136         if (value != null && isLinked(channel)) {
137             updateState(channel, new QuantityType<>(value, unit));
138         }
139     }
140
141     public void updateString(String groupId, String channelId, @Nullable String value) {
142         String channel = groupId + "#" + channelId;
143         if (value != null && isLinked(channel)) {
144             updateState(channel, new StringType(value));
145         }
146     }
147
148     public void updateNumber(String groupId, String channelId, @Nullable Number value) {
149         String channel = groupId + "#" + channelId;
150         if (value != null && isLinked(channel)) {
151             if (value instanceof Integer) {
152                 updateState(channel, new DecimalType(value.intValue()));
153             } else if (value instanceof Double) {
154                 updateState(channel, new DecimalType(value.doubleValue()));
155             }
156         }
157     }
158
159     public void updateDate(String groupId, String channelId, @Nullable String date) {
160         String channel = groupId + "#" + channelId;
161         if (date != null && isLinked(channel)) {
162             updateState(channel, getLocalDateTimeType(date, getZoneId()));
163         }
164     }
165
166     private DateTimeType getLocalDateTimeType(String dateTimeString, ZoneId zoneId) {
167         DateTimeType dateTimeType;
168         try {
169             Instant instant = Instant.parse(dateTimeString);
170             ZonedDateTime localDateTime = instant.atZone(zoneId);
171             dateTimeType = new DateTimeType(localDateTime);
172         } catch (DateTimeParseException e) {
173             logger.debug("Error parsing date/time string: {}", e.getMessage());
174             dateTimeType = new DateTimeType();
175         } catch (IllegalArgumentException e) {
176             logger.debug("Error converting to DateTimeType: {}", e.getMessage());
177             dateTimeType = new DateTimeType();
178         }
179         return dateTimeType;
180     }
181
182     private ZoneId getZoneId() {
183         return timeZoneProvider.getTimeZone();
184     }
185
186     @Override
187     public void handleCommand(ChannelUID channelUID, Command command) {
188         // Handler doesn't support any commands
189     }
190 }