]> git.basschouten.com Git - openhab-addons.git/blob
dc29b641525109d1f2e268e6d4ab3421c35ab8b0
[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.groheondus.internal.handler;
14
15 import java.io.IOException;
16 import java.util.concurrent.TimeUnit;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.grohe.ondus.api.OndusService;
21 import org.grohe.ondus.api.model.BaseAppliance;
22 import org.grohe.ondus.api.model.Location;
23 import org.grohe.ondus.api.model.Room;
24 import org.openhab.binding.groheondus.internal.GroheOndusApplianceConfiguration;
25 import org.openhab.core.thing.Bridge;
26 import org.openhab.core.thing.ChannelUID;
27 import org.openhab.core.thing.Thing;
28 import org.openhab.core.thing.ThingStatus;
29 import org.openhab.core.thing.ThingStatusDetail;
30 import org.openhab.core.thing.binding.BaseThingHandler;
31 import org.openhab.core.thing.binding.BridgeHandler;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 /**
36  * @author Florian Schmidt - Initial contribution
37  */
38 @NonNullByDefault
39 public abstract class GroheOndusBaseHandler<T extends BaseAppliance, M> extends BaseThingHandler {
40     private final Logger logger = LoggerFactory.getLogger(GroheOndusBaseHandler.class);
41
42     protected @Nullable GroheOndusApplianceConfiguration config;
43
44     private final int applianceType;
45
46     public GroheOndusBaseHandler(Thing thing, int applianceType) {
47         super(thing);
48         this.applianceType = applianceType;
49     }
50
51     @Override
52     public void initialize() {
53         config = getConfigAs(GroheOndusApplianceConfiguration.class);
54
55         OndusService ondusService = getOndusService();
56         if (ondusService == null) {
57             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE,
58                     "No initialized OndusService available from bridge.");
59             return;
60         }
61
62         @Nullable
63         T appliance = getAppliance(ondusService);
64         if (appliance == null) {
65             updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.COMMUNICATION_ERROR, "Could not load appliance");
66             return;
67         }
68         int pollingInterval = getPollingInterval(appliance);
69         scheduler.scheduleWithFixedDelay(this::updateChannels, 0, pollingInterval, TimeUnit.SECONDS);
70
71         updateStatus(ThingStatus.UNKNOWN);
72     }
73
74     @Override
75     public void channelLinked(ChannelUID channelUID) {
76         super.channelLinked(channelUID);
77
78         OndusService ondusService = getOndusService();
79         if (ondusService == null) {
80             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE,
81                     "No initialized OndusService available from bridge.");
82             return;
83         }
84
85         @Nullable
86         T appliance = getAppliance(ondusService);
87         if (appliance == null) {
88             return;
89         }
90         updateChannel(channelUID, appliance, getLastDataPoint(appliance));
91     }
92
93     public void updateChannels() {
94         OndusService ondusService = getOndusService();
95         if (ondusService == null) {
96             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE,
97                     "No initialized OndusService available from bridge.");
98             return;
99         }
100
101         @Nullable
102         T appliance = getAppliance(ondusService);
103         if (appliance == null) {
104             return;
105         }
106
107         M measurement = getLastDataPoint(appliance);
108         getThing().getChannels().forEach(channel -> updateChannel(channel.getUID(), appliance, measurement));
109
110         updateStatus(ThingStatus.ONLINE);
111     }
112
113     protected abstract M getLastDataPoint(T appliance);
114
115     protected abstract void updateChannel(ChannelUID channelUID, T appliance, M measurement);
116
117     public @Nullable OndusService getOndusService() {
118         Bridge bridge = getBridge();
119         if (bridge == null) {
120             return null;
121         }
122         BridgeHandler handler = bridge.getHandler();
123         if (!(handler instanceof GroheOndusAccountHandler)) {
124             return null;
125         }
126         try {
127             return ((GroheOndusAccountHandler) handler).getService();
128         } catch (IllegalStateException e) {
129             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
130             return null;
131         }
132     }
133
134     protected Room getRoom() {
135         return new Room(config.roomId, getLocation());
136     }
137
138     protected Location getLocation() {
139         return new Location(config.locationId);
140     }
141
142     protected @Nullable T getAppliance(OndusService ondusService) {
143         try {
144             BaseAppliance appliance = ondusService.getAppliance(getRoom(), config.applianceId).orElse(null);
145             if (appliance.getType() != getType()) {
146                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
147                         "Thing is not a GROHE SENSE Guard device.");
148                 return null;
149             }
150             return (T) appliance;
151         } catch (IOException e) {
152             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
153             logger.debug("Could not load appliance", e);
154         }
155         return null;
156     }
157
158     protected abstract int getPollingInterval(T appliance);
159
160     private int getType() {
161         return this.applianceType;
162     }
163 }