]> git.basschouten.com Git - openhab-addons.git/blob
afae188b4bcfdf867cbec4d3530f892ca8a17735
[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.nikohomecontrol.internal.protocol;
14
15 import java.time.LocalDateTime;
16 import java.time.temporal.ChronoUnit;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.openhab.binding.nikohomecontrol.internal.protocol.nhc1.NhcThermostat1;
21 import org.openhab.binding.nikohomecontrol.internal.protocol.nhc2.NhcThermostat2;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 /**
26  * The {@link NhcThermostat} class represents the thermostat Niko Home Control communication object. It contains all
27  * fields representing a Niko Home Control thermostat and has methods to set the thermostat in Niko Home Control and
28  * receive thermostat updates. Specific implementation are {@link NhcThermostat1} and {@link NhcThermostat2}.
29  *
30  * @author Mark Herwege - Initial Contribution
31  */
32 @NonNullByDefault
33 public abstract class NhcThermostat {
34
35     private final Logger logger = LoggerFactory.getLogger(NhcThermostat.class);
36
37     protected NikoHomeControlCommunication nhcComm;
38
39     protected String id;
40     protected String name;
41     protected @Nullable String location;
42     protected volatile int measured;
43     protected volatile int setpoint;
44     protected volatile int mode;
45     protected volatile int overrule;
46     protected volatile int overruletime;
47     protected volatile int ecosave;
48     protected volatile int demand;
49
50     private @Nullable LocalDateTime overruleStart;
51
52     private @Nullable NhcThermostatEvent eventHandler;
53
54     protected NhcThermostat(String id, String name, @Nullable String location, NikoHomeControlCommunication nhcComm) {
55         this.id = id;
56         this.name = name;
57         this.location = location;
58         this.nhcComm = nhcComm;
59     }
60
61     /**
62      * Update all values of the thermostat without touching the thermostat definition (id, name and location) and
63      * without changing the ThingHandler callback.
64      *
65      * @param measured current temperature in 0.1°C multiples
66      * @param setpoint the setpoint temperature in 0.1°C multiples
67      * @param mode thermostat mode 0 = day, 1 = night, 2 = eco, 3 = off, 4 = cool, 5 = prog1, 6 = prog2, 7 =
68      *            prog3
69      * @param overrule the overrule temperature in 0.1°C multiples
70      * @param overruletime in minutes
71      * @param ecosave
72      * @param demand 0 if no demand, > 0 if heating, < 0 if cooling
73      */
74     public void updateState(int measured, int setpoint, int mode, int overrule, int overruletime, int ecosave,
75             int demand) {
76         setMeasured(measured);
77         setSetpoint(setpoint);
78         setMode(mode);
79         setOverrule(overrule);
80         setOverruletime(overruletime);
81         setEcosave(ecosave);
82         setDemand(demand);
83
84         updateChannels();
85     }
86
87     /**
88      * Update overrule values of the thermostat without touching the thermostat definition (id, name and location) and
89      * without changing the ThingHandler callback.
90      *
91      * @param overrule the overrule temperature in 0.1°C multiples
92      * @param overruletime in minutes
93      */
94     public void updateState(int overrule, int overruletime) {
95         setOverrule(overrule);
96         setOverruletime(overruletime);
97
98         updateChannels();
99     }
100
101     /**
102      * Update overrule values of the thermostat without touching the thermostat definition (id, name and location) and
103      * without changing the ThingHandler callback.
104      *
105      * @param overrule the overrule temperature in 0.1°C multiples
106      * @param overruletime in minutes
107      */
108     public void updateState(int mode) {
109         setMode(mode);
110
111         updateChannels();
112     }
113
114     /**
115      * Method called when thermostat is removed from the Niko Home Control Controller.
116      */
117     public void thermostatRemoved() {
118         logger.debug("action removed {}, {}", id, name);
119         NhcThermostatEvent eventHandler = this.eventHandler;
120         if (eventHandler != null) {
121             eventHandler.thermostatRemoved();
122             unsetEventHandler();
123         }
124     }
125
126     private void updateChannels() {
127         NhcThermostatEvent handler = eventHandler;
128         if (handler != null) {
129             logger.debug("update channels for {}", id);
130             handler.thermostatEvent(measured, setpoint, mode, overrule, demand);
131         }
132     }
133
134     /**
135      * This method should be called when an object implementing the {@NhcThermostatEvent} interface is initialized.
136      * It keeps a record of the event handler in that object so it can be updated when the action receives an update
137      * from the Niko Home Control IP-interface.
138      *
139      * @param eventHandler
140      */
141     public void setEventHandler(NhcThermostatEvent eventHandler) {
142         this.eventHandler = eventHandler;
143     }
144
145     /**
146      * This method should be called when an object implementing the {@NhcThermostatEvent} interface is disposed.
147      * It resets the reference, so no updates go to the handler anymore.
148      *
149      */
150     public void unsetEventHandler() {
151         this.eventHandler = null;
152     }
153
154     /**
155      * Get id of the thermostat.
156      *
157      * @return id
158      */
159     public String getId() {
160         return id;
161     }
162
163     /**
164      * Get name of thermostat.
165      *
166      * @return thermostat name
167      */
168     public String getName() {
169         return name;
170     }
171
172     /**
173      * Set name of thermostat.
174      *
175      * @param name thermostat name
176      */
177     public void setName(String name) {
178         this.name = name;
179     }
180
181     /**
182      * Get location name of thermostat.
183      *
184      * @return location name
185      */
186     public @Nullable String getLocation() {
187         return location;
188     }
189
190     /**
191      * Set location name of thermostat.
192      *
193      * @param location thermostat location name
194      */
195     public void setLocation(@Nullable String location) {
196         this.location = location;
197     }
198
199     /**
200      * Get measured temperature.
201      *
202      * @return measured temperature in 0.1°C multiples
203      */
204     public int getMeasured() {
205         return measured;
206     }
207
208     private void setMeasured(int measured) {
209         this.measured = measured;
210     }
211
212     /**
213      * @return the setpoint temperature in 0.1°C multiples
214      */
215     public int getSetpoint() {
216         return setpoint;
217     }
218
219     private void setSetpoint(int setpoint) {
220         this.setpoint = setpoint;
221     }
222
223     /**
224      * Get the thermostat mode.
225      *
226      * @return the mode:
227      *         0 = day, 1 = night, 2 = eco, 3 = off, 4 = cool, 5 = prog 1, 6 = prog 2, 7 = prog 3
228      */
229     public int getMode() {
230         return mode;
231     }
232
233     private void setMode(int mode) {
234         this.mode = mode;
235     }
236
237     /**
238      * Get the overrule temperature.
239      *
240      * @return the overrule temperature in 0.1°C multiples
241      */
242     public int getOverrule() {
243         if (overrule > 0) {
244             return overrule;
245         } else {
246             return setpoint;
247         }
248     }
249
250     private void setOverrule(int overrule) {
251         this.overrule = overrule;
252     }
253
254     /**
255      * Get the duration for an overrule temperature
256      *
257      * @return the overruletime in minutes
258      */
259     public int getOverruletime() {
260         return overruletime;
261     }
262
263     /**
264      * Set the duration for an overrule temperature
265      *
266      * @param overruletime the overruletime in minutes
267      */
268     private void setOverruletime(int overruletime) {
269         if (overruletime <= 0) {
270             stopOverrule();
271         } else if (overruletime != this.overruletime) {
272             startOverrule();
273         }
274         this.overruletime = overruletime;
275     }
276
277     /**
278      * @return the ecosave mode
279      */
280     public int getEcosave() {
281         return ecosave;
282     }
283
284     /**
285      * @param ecosave the ecosave mode to set
286      */
287     private void setEcosave(int ecosave) {
288         this.ecosave = ecosave;
289     }
290
291     /**
292      * @return the heating/cooling demand: 0 if no demand, >0 if heating, <0 if cooling
293      */
294     public int getDemand() {
295         return demand;
296     }
297
298     /**
299      * @param demand set the heating/cooling demand
300      */
301     private void setDemand(int demand) {
302         this.demand = demand;
303     }
304
305     /**
306      * Sends thermostat mode to Niko Home Control. This method is implemented in {@link NhcThermostat1} and
307      * {@link NhcThermostat2}.
308      *
309      * @param mode
310      */
311     public abstract void executeMode(int mode);
312
313     /**
314      * Sends thermostat setpoint to Niko Home Control. This method is implemented in {@link NhcThermostat1} and
315      * {@link NhcThermostat2}.
316      *
317      * @param overrule temperature to overrule the setpoint in 0.1°C multiples
318      * @param time time duration in min for overrule
319      */
320     public abstract void executeOverrule(int overrule, int overruletime);
321
322     /**
323      * @return remaining overrule time in minutes
324      */
325     public int getRemainingOverruletime() {
326         if (overruleStart == null) {
327             return 0;
328         } else {
329             // overruletime time max 23h59min, therefore can safely cast to int
330             return overruletime - (int) ChronoUnit.MINUTES.between(overruleStart, LocalDateTime.now());
331         }
332     }
333
334     /**
335      * Start a new overrule, this method is used to be able to calculate the remaining overrule time
336      */
337     private void startOverrule() {
338         overruleStart = LocalDateTime.now();
339     }
340
341     /**
342      * Reset overrule start
343      */
344     private void stopOverrule() {
345         overruleStart = null;
346     }
347 }