]> git.basschouten.com Git - openhab-addons.git/blob
801e2150ba35ab3cd5adea57124567fa6f569b74
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.netatmo.internal.station;
14
15 import static org.openhab.binding.netatmo.internal.ChannelTypeUtils.*;
16 import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;
17
18 import java.util.ArrayList;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Optional;
22 import java.util.concurrent.ConcurrentHashMap;
23
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.openhab.core.i18n.TimeZoneProvider;
26 import org.openhab.core.thing.Thing;
27 import org.openhab.core.types.State;
28 import org.openhab.binding.netatmo.internal.WeatherUtils;
29 import org.openhab.binding.netatmo.internal.handler.NetatmoDeviceHandler;
30 import org.openhab.binding.netatmo.internal.handler.NetatmoModuleHandler;
31
32 import io.swagger.client.model.NADashboardData;
33 import io.swagger.client.model.NAMain;
34
35 /**
36  * {@link NAMainHandler} is the base class for all current Netatmo
37  * weather station equipments (both modules and devices)
38  *
39  * @author GaĆ«l L'hopital - Initial contribution
40  * @author Rob Nielsen - Added day, week, and month measurements to the weather station and modules
41  *
42  */
43 @NonNullByDefault
44 public class NAMainHandler extends NetatmoDeviceHandler<NAMain> {
45     private Map<String, Float> channelMeasurements = new ConcurrentHashMap<>();
46
47     public NAMainHandler(Thing thing, final TimeZoneProvider timeZoneProvider) {
48         super(thing, timeZoneProvider);
49     }
50
51     @Override
52     protected Optional<NAMain> updateReadings() {
53         Optional<NAMain> result = getBridgeHandler().flatMap(handler -> handler.getStationsDataBody(getId()))
54                 .map(dataBody -> dataBody.getDevices().stream()
55                         .filter(device -> device.getId().equalsIgnoreCase(getId())).findFirst().orElse(null));
56         result.ifPresent(device -> {
57             device.getModules().forEach(child -> childs.put(child.getId(), child));
58         });
59
60         updateMeasurements();
61
62         childs.keySet().forEach((childId) -> {
63             findNAThing(childId).map(NetatmoModuleHandler.class::cast).ifPresent(naChildModule -> {
64                 naChildModule.updateMeasurements();
65             });
66         });
67
68         return result;
69     }
70
71     @Override
72     protected void updateProperties(NAMain deviceData) {
73         updateProperties(deviceData.getFirmware(), deviceData.getType());
74     }
75
76     @Override
77     public void updateMeasurements() {
78         updateDayMeasurements();
79         updateWeekMeasurements();
80         updateMonthMeasurements();
81     }
82
83     private void updateDayMeasurements() {
84         List<String> channels = new ArrayList<>();
85         List<String> types = new ArrayList<>();
86         addMeasurement(channels, types, CHANNEL_MIN_CO2, MIN_CO2);
87         addMeasurement(channels, types, CHANNEL_MAX_CO2, MAX_CO2);
88         addMeasurement(channels, types, CHANNEL_MIN_HUMIDITY, MIN_HUM);
89         addMeasurement(channels, types, CHANNEL_MAX_HUMIDITY, MAX_HUM);
90         addMeasurement(channels, types, CHANNEL_MIN_NOISE, MIN_NOISE);
91         addMeasurement(channels, types, CHANNEL_MAX_NOISE, MAX_NOISE);
92         addMeasurement(channels, types, CHANNEL_MIN_PRESSURE, MIN_PRESSURE);
93         addMeasurement(channels, types, CHANNEL_MAX_PRESSURE, MAX_PRESSURE);
94         addMeasurement(channels, types, CHANNEL_DATE_MIN_CO2, DATE_MIN_CO2);
95         addMeasurement(channels, types, CHANNEL_DATE_MAX_CO2, DATE_MAX_CO2);
96         addMeasurement(channels, types, CHANNEL_DATE_MIN_HUMIDITY, DATE_MIN_HUM);
97         addMeasurement(channels, types, CHANNEL_DATE_MAX_HUMIDITY, DATE_MAX_HUM);
98         addMeasurement(channels, types, CHANNEL_DATE_MIN_NOISE, DATE_MIN_NOISE);
99         addMeasurement(channels, types, CHANNEL_DATE_MAX_NOISE, DATE_MAX_NOISE);
100         addMeasurement(channels, types, CHANNEL_DATE_MIN_PRESSURE, DATE_MIN_PRESSURE);
101         addMeasurement(channels, types, CHANNEL_DATE_MAX_PRESSURE, DATE_MAX_PRESSURE);
102         if (!channels.isEmpty()) {
103             getMeasurements(getId(), null, ONE_DAY, types, channels, channelMeasurements);
104         }
105     }
106
107     private void updateWeekMeasurements() {
108         List<String> channels = new ArrayList<>();
109         List<String> types = new ArrayList<>();
110         addMeasurement(channels, types, CHANNEL_MIN_CO2_THIS_WEEK, MIN_CO2);
111         addMeasurement(channels, types, CHANNEL_MAX_CO2_THIS_WEEK, MAX_CO2);
112         addMeasurement(channels, types, CHANNEL_MIN_HUMIDITY_THIS_WEEK, MIN_HUM);
113         addMeasurement(channels, types, CHANNEL_MAX_HUMIDITY_THIS_WEEK, MAX_HUM);
114         addMeasurement(channels, types, CHANNEL_MIN_NOISE_THIS_WEEK, MIN_NOISE);
115         addMeasurement(channels, types, CHANNEL_MAX_NOISE_THIS_WEEK, MAX_NOISE);
116         addMeasurement(channels, types, CHANNEL_MIN_PRESSURE_THIS_WEEK, MIN_PRESSURE);
117         addMeasurement(channels, types, CHANNEL_MAX_PRESSURE_THIS_WEEK, MAX_PRESSURE);
118         addMeasurement(channels, types, CHANNEL_MIN_TEMP_THIS_WEEK, MIN_TEMP);
119         addMeasurement(channels, types, CHANNEL_MAX_TEMP_THIS_WEEK, MAX_TEMP);
120         addMeasurement(channels, types, CHANNEL_DATE_MIN_CO2_THIS_WEEK, DATE_MIN_CO2);
121         addMeasurement(channels, types, CHANNEL_DATE_MAX_CO2_THIS_WEEK, DATE_MAX_CO2);
122         addMeasurement(channels, types, CHANNEL_DATE_MIN_HUMIDITY_THIS_WEEK, DATE_MIN_HUM);
123         addMeasurement(channels, types, CHANNEL_DATE_MAX_HUMIDITY_THIS_WEEK, DATE_MAX_HUM);
124         addMeasurement(channels, types, CHANNEL_DATE_MIN_NOISE_THIS_WEEK, DATE_MIN_NOISE);
125         addMeasurement(channels, types, CHANNEL_DATE_MAX_NOISE_THIS_WEEK, DATE_MAX_NOISE);
126         addMeasurement(channels, types, CHANNEL_DATE_MIN_PRESSURE_THIS_WEEK, DATE_MIN_PRESSURE);
127         addMeasurement(channels, types, CHANNEL_DATE_MAX_PRESSURE_THIS_WEEK, DATE_MAX_PRESSURE);
128         addMeasurement(channels, types, CHANNEL_DATE_MIN_TEMP_THIS_WEEK, DATE_MIN_TEMP);
129         addMeasurement(channels, types, CHANNEL_DATE_MAX_TEMP_THIS_WEEK, DATE_MAX_TEMP);
130         if (!channels.isEmpty()) {
131             getMeasurements(getId(), null, ONE_WEEK, types, channels, channelMeasurements);
132         }
133     }
134
135     private void updateMonthMeasurements() {
136         List<String> channels = new ArrayList<>();
137         List<String> types = new ArrayList<>();
138         addMeasurement(channels, types, CHANNEL_MIN_CO2_THIS_MONTH, MIN_CO2);
139         addMeasurement(channels, types, CHANNEL_MAX_CO2_THIS_MONTH, MAX_CO2);
140         addMeasurement(channels, types, CHANNEL_MIN_HUMIDITY_THIS_MONTH, MIN_HUM);
141         addMeasurement(channels, types, CHANNEL_MAX_HUMIDITY_THIS_MONTH, MAX_HUM);
142         addMeasurement(channels, types, CHANNEL_MIN_NOISE_THIS_MONTH, MIN_NOISE);
143         addMeasurement(channels, types, CHANNEL_MAX_NOISE_THIS_MONTH, MAX_NOISE);
144         addMeasurement(channels, types, CHANNEL_MIN_PRESSURE_THIS_MONTH, MIN_PRESSURE);
145         addMeasurement(channels, types, CHANNEL_MAX_PRESSURE_THIS_MONTH, MAX_PRESSURE);
146         addMeasurement(channels, types, CHANNEL_MIN_TEMP_THIS_MONTH, MIN_TEMP);
147         addMeasurement(channels, types, CHANNEL_MAX_TEMP_THIS_MONTH, MAX_TEMP);
148         addMeasurement(channels, types, CHANNEL_DATE_MIN_CO2_THIS_MONTH, DATE_MIN_CO2);
149         addMeasurement(channels, types, CHANNEL_DATE_MAX_CO2_THIS_MONTH, DATE_MAX_CO2);
150         addMeasurement(channels, types, CHANNEL_DATE_MIN_HUMIDITY_THIS_MONTH, DATE_MIN_HUM);
151         addMeasurement(channels, types, CHANNEL_DATE_MAX_HUMIDITY_THIS_MONTH, DATE_MAX_HUM);
152         addMeasurement(channels, types, CHANNEL_DATE_MIN_NOISE_THIS_MONTH, DATE_MIN_NOISE);
153         addMeasurement(channels, types, CHANNEL_DATE_MAX_NOISE_THIS_MONTH, DATE_MAX_NOISE);
154         addMeasurement(channels, types, CHANNEL_DATE_MIN_PRESSURE_THIS_MONTH, DATE_MIN_PRESSURE);
155         addMeasurement(channels, types, CHANNEL_DATE_MAX_PRESSURE_THIS_MONTH, DATE_MAX_PRESSURE);
156         addMeasurement(channels, types, CHANNEL_DATE_MIN_TEMP_THIS_MONTH, DATE_MIN_TEMP);
157         addMeasurement(channels, types, CHANNEL_DATE_MAX_TEMP_THIS_MONTH, DATE_MAX_TEMP);
158         if (!channels.isEmpty()) {
159             getMeasurements(getId(), null, ONE_MONTH, types, channels, channelMeasurements);
160         }
161     }
162
163     @Override
164     protected State getNAThingProperty(String channelId) {
165         NADashboardData dashboardData = getDevice().map(d -> d.getDashboardData()).orElse(null);
166         if (dashboardData != null) {
167             switch (channelId) {
168                 case CHANNEL_CO2:
169                     return toQuantityType(dashboardData.getCO2(), API_CO2_UNIT);
170                 case CHANNEL_TEMPERATURE:
171                     return toQuantityType(dashboardData.getTemperature(), API_TEMPERATURE_UNIT);
172                 case CHANNEL_MIN_TEMP:
173                     return toQuantityType(dashboardData.getMinTemp(), API_TEMPERATURE_UNIT);
174                 case CHANNEL_MAX_TEMP:
175                     return toQuantityType(dashboardData.getMaxTemp(), API_TEMPERATURE_UNIT);
176                 case CHANNEL_TEMP_TREND:
177                     return toStringType(dashboardData.getTempTrend());
178                 case CHANNEL_NOISE:
179                     return toQuantityType(dashboardData.getNoise(), API_NOISE_UNIT);
180                 case CHANNEL_PRESSURE:
181                     return toQuantityType(dashboardData.getPressure(), API_PRESSURE_UNIT);
182                 case CHANNEL_PRESS_TREND:
183                     return toStringType(dashboardData.getPressureTrend());
184                 case CHANNEL_ABSOLUTE_PRESSURE:
185                     return toQuantityType(dashboardData.getAbsolutePressure(), API_PRESSURE_UNIT);
186                 case CHANNEL_TIMEUTC:
187                     return toDateTimeType(dashboardData.getTimeUtc(), timeZoneProvider.getTimeZone());
188                 case CHANNEL_DATE_MIN_TEMP:
189                     return toDateTimeType(dashboardData.getDateMinTemp(), timeZoneProvider.getTimeZone());
190                 case CHANNEL_DATE_MAX_TEMP:
191                     return toDateTimeType(dashboardData.getDateMaxTemp(), timeZoneProvider.getTimeZone());
192                 case CHANNEL_HUMIDITY:
193                     return toQuantityType(dashboardData.getHumidity(), API_HUMIDITY_UNIT);
194                 case CHANNEL_HUMIDEX:
195                     return toDecimalType(
196                             WeatherUtils.getHumidex(dashboardData.getTemperature(), dashboardData.getHumidity()));
197                 case CHANNEL_HEATINDEX:
198                     return toQuantityType(
199                             WeatherUtils.getHeatIndex(dashboardData.getTemperature(), dashboardData.getHumidity()),
200                             API_TEMPERATURE_UNIT);
201                 case CHANNEL_DEWPOINT:
202                     return toQuantityType(
203                             WeatherUtils.getDewPoint(dashboardData.getTemperature(), dashboardData.getHumidity()),
204                             API_TEMPERATURE_UNIT);
205                 case CHANNEL_DEWPOINTDEP:
206                     Double dewPoint = WeatherUtils.getDewPoint(dashboardData.getTemperature(),
207                             dashboardData.getHumidity());
208                     return toQuantityType(WeatherUtils.getDewPointDep(dashboardData.getTemperature(), dewPoint),
209                             API_TEMPERATURE_UNIT);
210             }
211         }
212
213         switch (channelId) {
214             case CHANNEL_MIN_CO2:
215             case CHANNEL_MIN_CO2_THIS_WEEK:
216             case CHANNEL_MIN_CO2_THIS_MONTH:
217             case CHANNEL_MAX_CO2:
218             case CHANNEL_MAX_CO2_THIS_WEEK:
219             case CHANNEL_MAX_CO2_THIS_MONTH:
220                 return toQuantityType(channelMeasurements.get(channelId), API_CO2_UNIT);
221             case CHANNEL_MIN_HUMIDITY:
222             case CHANNEL_MIN_HUMIDITY_THIS_WEEK:
223             case CHANNEL_MIN_HUMIDITY_THIS_MONTH:
224             case CHANNEL_MAX_HUMIDITY:
225             case CHANNEL_MAX_HUMIDITY_THIS_WEEK:
226             case CHANNEL_MAX_HUMIDITY_THIS_MONTH:
227                 return toQuantityType(channelMeasurements.get(channelId), API_HUMIDITY_UNIT);
228             case CHANNEL_MIN_NOISE:
229             case CHANNEL_MIN_NOISE_THIS_WEEK:
230             case CHANNEL_MIN_NOISE_THIS_MONTH:
231             case CHANNEL_MAX_NOISE:
232             case CHANNEL_MAX_NOISE_THIS_WEEK:
233             case CHANNEL_MAX_NOISE_THIS_MONTH:
234                 return toQuantityType(channelMeasurements.get(channelId), API_NOISE_UNIT);
235             case CHANNEL_MIN_PRESSURE:
236             case CHANNEL_MIN_PRESSURE_THIS_WEEK:
237             case CHANNEL_MIN_PRESSURE_THIS_MONTH:
238             case CHANNEL_MAX_PRESSURE:
239             case CHANNEL_MAX_PRESSURE_THIS_WEEK:
240             case CHANNEL_MAX_PRESSURE_THIS_MONTH:
241                 return toQuantityType(channelMeasurements.get(channelId), API_PRESSURE_UNIT);
242             case CHANNEL_MIN_TEMP_THIS_WEEK:
243             case CHANNEL_MIN_TEMP_THIS_MONTH:
244             case CHANNEL_MAX_TEMP_THIS_WEEK:
245             case CHANNEL_MAX_TEMP_THIS_MONTH:
246                 return toQuantityType(channelMeasurements.get(channelId), API_TEMPERATURE_UNIT);
247             case CHANNEL_DATE_MIN_CO2:
248             case CHANNEL_DATE_MIN_CO2_THIS_WEEK:
249             case CHANNEL_DATE_MIN_CO2_THIS_MONTH:
250             case CHANNEL_DATE_MAX_CO2:
251             case CHANNEL_DATE_MAX_CO2_THIS_WEEK:
252             case CHANNEL_DATE_MAX_CO2_THIS_MONTH:
253             case CHANNEL_DATE_MIN_NOISE:
254             case CHANNEL_DATE_MIN_NOISE_THIS_WEEK:
255             case CHANNEL_DATE_MIN_NOISE_THIS_MONTH:
256             case CHANNEL_DATE_MAX_NOISE:
257             case CHANNEL_DATE_MAX_NOISE_THIS_WEEK:
258             case CHANNEL_DATE_MAX_NOISE_THIS_MONTH:
259             case CHANNEL_DATE_MIN_HUMIDITY:
260             case CHANNEL_DATE_MIN_HUMIDITY_THIS_WEEK:
261             case CHANNEL_DATE_MIN_HUMIDITY_THIS_MONTH:
262             case CHANNEL_DATE_MAX_HUMIDITY:
263             case CHANNEL_DATE_MAX_HUMIDITY_THIS_WEEK:
264             case CHANNEL_DATE_MAX_HUMIDITY_THIS_MONTH:
265             case CHANNEL_DATE_MIN_PRESSURE:
266             case CHANNEL_DATE_MIN_PRESSURE_THIS_WEEK:
267             case CHANNEL_DATE_MIN_PRESSURE_THIS_MONTH:
268             case CHANNEL_DATE_MAX_PRESSURE:
269             case CHANNEL_DATE_MAX_PRESSURE_THIS_WEEK:
270             case CHANNEL_DATE_MAX_PRESSURE_THIS_MONTH:
271             case CHANNEL_DATE_MIN_TEMP_THIS_WEEK:
272             case CHANNEL_DATE_MIN_TEMP_THIS_MONTH:
273             case CHANNEL_DATE_MAX_TEMP_THIS_WEEK:
274             case CHANNEL_DATE_MAX_TEMP_THIS_MONTH:
275                 return toDateTimeType(channelMeasurements.get(channelId), timeZoneProvider.getTimeZone());
276         }
277
278         return super.getNAThingProperty(channelId);
279     }
280
281     @Override
282     protected Optional<Integer> getDataTimestamp() {
283         return getDevice().map(d -> d.getLastStatusStore());
284     }
285
286     @Override
287     protected boolean isReachable() {
288         boolean result = false;
289         Optional<NAMain> device = getDevice();
290         if (device.isPresent()) {
291             Boolean reachable = device.get().getReachable();
292             result = reachable != null ? reachable.booleanValue() : false;
293         }
294         return result;
295     }
296 }