]> git.basschouten.com Git - openhab-addons.git/blob
346317b193d5ca758fee1e956eef73cbb1f04045
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.meater.internal.handler;
14
15 import static org.openhab.binding.meater.internal.MeaterBindingConstants.*;
16
17 import java.time.Instant;
18 import java.time.ZonedDateTime;
19
20 import javax.measure.quantity.Temperature;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.openhab.binding.meater.internal.MeaterConfiguration;
25 import org.openhab.binding.meater.internal.dto.MeaterProbeDTO.Cook;
26 import org.openhab.binding.meater.internal.dto.MeaterProbeDTO.Device;
27 import org.openhab.core.i18n.TimeZoneProvider;
28 import org.openhab.core.library.types.DateTimeType;
29 import org.openhab.core.library.types.QuantityType;
30 import org.openhab.core.library.types.StringType;
31 import org.openhab.core.library.unit.SIUnits;
32 import org.openhab.core.library.unit.Units;
33 import org.openhab.core.thing.Bridge;
34 import org.openhab.core.thing.Channel;
35 import org.openhab.core.thing.ChannelUID;
36 import org.openhab.core.thing.Thing;
37 import org.openhab.core.thing.ThingStatus;
38 import org.openhab.core.thing.ThingStatusDetail;
39 import org.openhab.core.thing.binding.BaseThingHandler;
40 import org.openhab.core.types.Command;
41 import org.openhab.core.types.State;
42 import org.openhab.core.types.UnDefType;
43
44 /**
45  * The {@link MeaterHandler} is responsible for handling commands, which are
46  * sent to one of the channels.
47  *
48  * @author Jan Gustafsson - Initial contribution
49  */
50 @NonNullByDefault
51 public class MeaterHandler extends BaseThingHandler {
52
53     private String deviceId = "";
54     private TimeZoneProvider timeZoneProvider;
55
56     public MeaterHandler(Thing thing, TimeZoneProvider timeZoneProvider) {
57         super(thing);
58         this.timeZoneProvider = timeZoneProvider;
59     }
60
61     @Override
62     public void handleCommand(ChannelUID channelUID, Command command) {
63     }
64
65     @Override
66     public void initialize() {
67         deviceId = getConfigAs(MeaterConfiguration.class).getDeviceId();
68         updateStatus(ThingStatus.UNKNOWN);
69
70         scheduler.execute(() -> {
71             update();
72         });
73     }
74
75     public void update() {
76         Device meaterProbe = getMeaterProbe();
77         if (meaterProbe != null) {
78             update(meaterProbe);
79         } else {
80             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
81                     "@text/offline.communication-error.description");
82         }
83     }
84
85     private @Nullable Device getMeaterProbe() {
86         Bridge bridge = getBridge();
87         if (bridge != null && bridge.getStatus() == ThingStatus.ONLINE) {
88             MeaterBridgeHandler bridgeHandler = (MeaterBridgeHandler) bridge.getHandler();
89             if (bridgeHandler != null) {
90                 return bridgeHandler.getMeaterThings().get(deviceId);
91             }
92         }
93         return null;
94     }
95
96     private void update(Device meaterProbe) {
97         // Update all channels from the updated data
98         getThing().getChannels().stream().map(Channel::getUID).filter(channelUID -> isLinked(channelUID))
99                 .forEach(channelUID -> {
100                     State state = getValue(channelUID.getId(), meaterProbe);
101                     updateState(channelUID, state);
102                 });
103         updateStatus(ThingStatus.ONLINE);
104     }
105
106     private State getValue(String channelId, Device meaterProbe) {
107         Cook cook = meaterProbe.cook;
108         switch (channelId) {
109             case CHANNEL_INTERNAL_TEMPERATURE:
110                 return new QuantityType<Temperature>(meaterProbe.temperature.internal, SIUnits.CELSIUS);
111             case CHANNEL_AMBIENT_TEMPERATURE:
112                 return new QuantityType<Temperature>(meaterProbe.temperature.ambient, SIUnits.CELSIUS);
113             case CHANNEL_COOK_TARGET_TEMPERATURE:
114                 if (cook != null) {
115                     return new QuantityType<Temperature>(cook.temperature.target, SIUnits.CELSIUS);
116                 }
117                 break;
118             case CHANNEL_COOK_PEAK_TEMPERATURE:
119                 if (cook != null) {
120                     return new QuantityType<Temperature>(cook.temperature.peak, SIUnits.CELSIUS);
121                 }
122                 break;
123             case CHANNEL_COOK_ELAPSED_TIME:
124                 if (cook != null) {
125                     return new QuantityType<>(cook.time.elapsed, Units.SECOND);
126                 }
127                 break;
128             case CHANNEL_COOK_REMAINING_TIME:
129                 if (cook != null) {
130                     return cook.time.remaining == -1 ? UnDefType.UNDEF
131                             : new QuantityType<>(cook.time.remaining, Units.SECOND);
132                 }
133                 break;
134             case CHANNEL_COOK_ID:
135                 if (cook != null) {
136                     return new StringType(cook.id);
137                 }
138                 break;
139             case CHANNEL_COOK_NAME:
140                 if (cook != null) {
141                     return new StringType(cook.name);
142                 }
143                 break;
144             case CHANNEL_COOK_STATE:
145                 if (cook != null) {
146                     return new StringType(cook.state);
147                 }
148                 break;
149             case CHANNEL_LAST_CONNECTION:
150                 Instant instant = meaterProbe.getLastConnection();
151                 if (instant != null) {
152                     return new DateTimeType(ZonedDateTime.ofInstant(instant, timeZoneProvider.getTimeZone()));
153                 }
154                 break;
155             case CHANNEL_COOK_ESTIMATED_END_TIME:
156                 if (cook != null) {
157                     if (cook.time.remaining > -1) {
158                         return new DateTimeType(
159                                 ZonedDateTime.now(timeZoneProvider.getTimeZone()).plusSeconds(cook.time.remaining));
160                     }
161                 }
162         }
163         return UnDefType.UNDEF;
164     }
165 }