2 * Copyright (c) 2010-2022 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.groheondus.internal.handler;
15 import static org.openhab.binding.groheondus.internal.GroheOndusBindingConstants.*;
17 import java.io.IOException;
18 import java.time.Instant;
19 import java.time.temporal.ChronoUnit;
20 import java.util.List;
21 import java.util.Optional;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.grohe.ondus.api.OndusService;
26 import org.grohe.ondus.api.model.ApplianceStatus;
27 import org.grohe.ondus.api.model.BaseApplianceData;
28 import org.grohe.ondus.api.model.sense.Appliance;
29 import org.grohe.ondus.api.model.sense.ApplianceData;
30 import org.grohe.ondus.api.model.sense.ApplianceData.Measurement;
31 import org.openhab.core.library.types.DecimalType;
32 import org.openhab.core.library.types.QuantityType;
33 import org.openhab.core.library.types.StringType;
34 import org.openhab.core.library.unit.SIUnits;
35 import org.openhab.core.library.unit.Units;
36 import org.openhab.core.thing.ChannelUID;
37 import org.openhab.core.thing.Thing;
38 import org.openhab.core.thing.ThingStatus;
39 import org.openhab.core.thing.ThingStatusDetail;
40 import org.openhab.core.types.Command;
41 import org.openhab.core.types.State;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
46 * @author Florian Schmidt - Initial contribution
49 public class GroheOndusSenseHandler<T, M> extends GroheOndusBaseHandler<Appliance, Measurement> {
51 private static final int DEFAULT_POLLING_INTERVAL = 900;
53 private final Logger logger = LoggerFactory.getLogger(GroheOndusSenseHandler.class);
55 public GroheOndusSenseHandler(Thing thing) {
56 super(thing, Appliance.TYPE);
60 protected int getPollingInterval(Appliance appliance) {
61 if (config.pollingInterval > 0) {
62 return config.pollingInterval;
64 return DEFAULT_POLLING_INTERVAL;
68 protected void updateChannel(ChannelUID channelUID, Appliance appliance, Measurement measurement) {
69 String channelId = channelUID.getIdWithoutGroup();
73 newState = new StringType(appliance.getName());
75 case CHANNEL_TEMPERATURE:
76 newState = new QuantityType<>(measurement.getTemperature(), SIUnits.CELSIUS);
78 case CHANNEL_HUMIDITY:
79 newState = new QuantityType<>(measurement.getHumidity(), Units.PERCENT);
82 newState = new DecimalType(getBatteryStatus(appliance));
85 throw new IllegalArgumentException("Channel " + channelUID + " not supported.");
87 if (newState != null) {
88 updateState(channelUID, newState);
93 protected Measurement getLastDataPoint(Appliance appliance) {
94 if (getOndusService() == null) {
95 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE,
96 "No initialized OndusService available from bridge.");
97 return new Measurement();
100 ApplianceData applianceData = getApplianceData(appliance);
101 if (applianceData == null) {
102 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Could not load data from API.");
103 return new Measurement();
105 List<Measurement> measurementList = applianceData.getData().getMeasurement();
107 return measurementList.isEmpty() ? new Measurement() : measurementList.get(measurementList.size() - 1);
110 private int getBatteryStatus(Appliance appliance) {
111 OndusService ondusService = getOndusService();
112 if (ondusService == null) {
113 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE,
114 "No initialized OndusService available from bridge.");
118 Optional<ApplianceStatus> applianceStatusOptional;
120 applianceStatusOptional = ondusService.applianceStatus(appliance);
121 if (!applianceStatusOptional.isPresent()) {
122 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
123 "Could not load data from API.");
127 return applianceStatusOptional.get().getBatteryStatus();
128 } catch (IOException e) {
129 logger.debug("Could not load appliance status", e);
134 private @Nullable ApplianceData getApplianceData(Appliance appliance) {
135 Instant yesterday = Instant.now().minus(1, ChronoUnit.DAYS);
136 Instant today = Instant.now();
137 OndusService service = getOndusService();
138 if (service == null) {
142 BaseApplianceData applianceData = service.applianceData(appliance, yesterday, today).orElse(null);
143 if (applianceData.getType() != Appliance.TYPE) {
144 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
145 "Thing is not a GROHE SENSE device.");
148 return (ApplianceData) applianceData;
149 } catch (IOException e) {
150 logger.debug("Could not load appliance data", e);
156 public void handleCommand(ChannelUID channelUID, Command command) {