]> git.basschouten.com Git - openhab-addons.git/blob
6166fc6b428213e4ee272e74dd06dd1c71c2a8e8
[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         }
123     }
124
125     private void updateChannels() {
126         NhcThermostatEvent handler = eventHandler;
127         if (handler != null) {
128             logger.debug("update channels for {}", id);
129             handler.thermostatEvent(measured, setpoint, mode, overrule, demand);
130         }
131     }
132
133     /**
134      * This method should be called when an object implementing the {@NhcThermostatEvent} interface is initialized.
135      * It keeps a record of the event handler in that object so it can be updated when the action receives an update
136      * from the Niko Home Control IP-interface.
137      *
138      * @param eventHandler
139      */
140     public void setEventHandler(NhcThermostatEvent eventHandler) {
141         this.eventHandler = eventHandler;
142     }
143
144     /**
145      * Get id of the thermostat.
146      *
147      * @return id
148      */
149     public String getId() {
150         return id;
151     }
152
153     /**
154      * Get name of thermostat.
155      *
156      * @return thermostat name
157      */
158     public String getName() {
159         return name;
160     }
161
162     /**
163      * Set name of thermostat.
164      *
165      * @param name thermostat name
166      */
167     public void setName(String name) {
168         this.name = name;
169     }
170
171     /**
172      * Get location name of thermostat.
173      *
174      * @return location name
175      */
176     public @Nullable String getLocation() {
177         return location;
178     }
179
180     /**
181      * Set location name of thermostat.
182      *
183      * @param location thermostat location name
184      */
185     public void setLocation(@Nullable String location) {
186         this.location = location;
187     }
188
189     /**
190      * Get measured temperature.
191      *
192      * @return measured temperature in 0.1°C multiples
193      */
194     public int getMeasured() {
195         return measured;
196     }
197
198     private void setMeasured(int measured) {
199         this.measured = measured;
200     }
201
202     /**
203      * @return the setpoint temperature in 0.1°C multiples
204      */
205     public int getSetpoint() {
206         return setpoint;
207     }
208
209     private void setSetpoint(int setpoint) {
210         this.setpoint = setpoint;
211     }
212
213     /**
214      * Get the thermostat mode.
215      *
216      * @return the mode:
217      *         0 = day, 1 = night, 2 = eco, 3 = off, 4 = cool, 5 = prog 1, 6 = prog 2, 7 = prog 3
218      */
219     public int getMode() {
220         return mode;
221     }
222
223     private void setMode(int mode) {
224         this.mode = mode;
225     }
226
227     /**
228      * Get the overrule temperature.
229      *
230      * @return the overrule temperature in 0.1°C multiples
231      */
232     public int getOverrule() {
233         if (overrule > 0) {
234             return overrule;
235         } else {
236             return setpoint;
237         }
238     }
239
240     private void setOverrule(int overrule) {
241         this.overrule = overrule;
242     }
243
244     /**
245      * Get the duration for an overrule temperature
246      *
247      * @return the overruletime in minutes
248      */
249     public int getOverruletime() {
250         return overruletime;
251     }
252
253     /**
254      * Set the duration for an overrule temperature
255      *
256      * @param overruletime the overruletime in minutes
257      */
258     private void setOverruletime(int overruletime) {
259         if (overruletime <= 0) {
260             stopOverrule();
261         } else if (overruletime != this.overruletime) {
262             startOverrule();
263         }
264         this.overruletime = overruletime;
265     }
266
267     /**
268      * @return the ecosave mode
269      */
270     public int getEcosave() {
271         return ecosave;
272     }
273
274     /**
275      * @param ecosave the ecosave mode to set
276      */
277     private void setEcosave(int ecosave) {
278         this.ecosave = ecosave;
279     }
280
281     /**
282      * @return the heating/cooling demand: 0 if no demand, >0 if heating, <0 if cooling
283      */
284     public int getDemand() {
285         return demand;
286     }
287
288     /**
289      * @param demand set the heating/cooling demand
290      */
291     private void setDemand(int demand) {
292         this.demand = demand;
293     }
294
295     /**
296      * Sends thermostat mode to Niko Home Control. This method is implemented in {@link NhcThermostat1} and
297      * {@link NhcThermostat2}.
298      *
299      * @param mode
300      */
301     public abstract void executeMode(int mode);
302
303     /**
304      * Sends thermostat setpoint to Niko Home Control. This method is implemented in {@link NhcThermostat1} and
305      * {@link NhcThermostat2}.
306      *
307      * @param overrule temperature to overrule the setpoint in 0.1°C multiples
308      * @param time time duration in min for overrule
309      */
310     public abstract void executeOverrule(int overrule, int overruletime);
311
312     /**
313      * @return remaining overrule time in minutes
314      */
315     public int getRemainingOverruletime() {
316         if (overruleStart == null) {
317             return 0;
318         } else {
319             // overruletime time max 23h59min, therefore can safely cast to int
320             return overruletime - (int) ChronoUnit.MINUTES.between(overruleStart, LocalDateTime.now());
321         }
322     }
323
324     /**
325      * Start a new overrule, this method is used to be able to calculate the remaining overrule time
326      */
327     private void startOverrule() {
328         overruleStart = LocalDateTime.now();
329     }
330
331     /**
332      * Reset overrule start
333      */
334     private void stopOverrule() {
335         overruleStart = null;
336     }
337 }