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.nikohomecontrol.internal.protocol;
15 import java.time.LocalDateTime;
16 import java.time.temporal.ChronoUnit;
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;
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}.
30 * @author Mark Herwege - Initial Contribution
33 public abstract class NhcThermostat {
35 private final Logger logger = LoggerFactory.getLogger(NhcThermostat.class);
37 protected NikoHomeControlCommunication nhcComm;
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;
50 private @Nullable LocalDateTime overruleStart;
52 private @Nullable NhcThermostatEvent eventHandler;
54 protected NhcThermostat(String id, String name, @Nullable String location, NikoHomeControlCommunication nhcComm) {
57 this.location = location;
58 this.nhcComm = nhcComm;
62 * Update all values of the thermostat without touching the thermostat definition (id, name and location) and
63 * without changing the ThingHandler callback.
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 =
69 * @param overrule the overrule temperature in 0.1°C multiples
70 * @param overruletime in minutes
72 * @param demand 0 if no demand, > 0 if heating, < 0 if cooling
74 public void updateState(int measured, int setpoint, int mode, int overrule, int overruletime, int ecosave,
76 setMeasured(measured);
77 setSetpoint(setpoint);
79 setOverrule(overrule);
80 setOverruletime(overruletime);
88 * Update overrule values of the thermostat without touching the thermostat definition (id, name and location) and
89 * without changing the ThingHandler callback.
91 * @param overrule the overrule temperature in 0.1°C multiples
92 * @param overruletime in minutes
94 public void updateState(int overrule, int overruletime) {
95 setOverrule(overrule);
96 setOverruletime(overruletime);
102 * Update overrule values of the thermostat without touching the thermostat definition (id, name and location) and
103 * without changing the ThingHandler callback.
105 * @param overrule the overrule temperature in 0.1°C multiples
106 * @param overruletime in minutes
108 public void updateState(int mode) {
115 * Method called when thermostat is removed from the Niko Home Control Controller.
117 public void thermostatRemoved() {
118 logger.debug("action removed {}, {}", id, name);
119 NhcThermostatEvent eventHandler = this.eventHandler;
120 if (eventHandler != null) {
121 eventHandler.thermostatRemoved();
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);
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.
139 * @param eventHandler
141 public void setEventHandler(NhcThermostatEvent eventHandler) {
142 this.eventHandler = eventHandler;
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.
150 public void unsetEventHandler() {
151 this.eventHandler = null;
155 * Get id of the thermostat.
159 public String getId() {
164 * Get name of thermostat.
166 * @return thermostat name
168 public String getName() {
173 * Set name of thermostat.
175 * @param name thermostat name
177 public void setName(String name) {
182 * Get location name of thermostat.
184 * @return location name
186 public @Nullable String getLocation() {
191 * Set location name of thermostat.
193 * @param location thermostat location name
195 public void setLocation(@Nullable String location) {
196 this.location = location;
200 * Get measured temperature.
202 * @return measured temperature in 0.1°C multiples
204 public int getMeasured() {
208 private void setMeasured(int measured) {
209 this.measured = measured;
213 * @return the setpoint temperature in 0.1°C multiples
215 public int getSetpoint() {
219 private void setSetpoint(int setpoint) {
220 this.setpoint = setpoint;
224 * Get the thermostat mode.
227 * 0 = day, 1 = night, 2 = eco, 3 = off, 4 = cool, 5 = prog 1, 6 = prog 2, 7 = prog 3
229 public int getMode() {
233 private void setMode(int mode) {
238 * Get the overrule temperature.
240 * @return the overrule temperature in 0.1°C multiples
242 public int getOverrule() {
250 private void setOverrule(int overrule) {
251 this.overrule = overrule;
255 * Get the duration for an overrule temperature
257 * @return the overruletime in minutes
259 public int getOverruletime() {
264 * Set the duration for an overrule temperature
266 * @param overruletime the overruletime in minutes
268 private void setOverruletime(int overruletime) {
269 if (overruletime <= 0) {
271 } else if (overruletime != this.overruletime) {
274 this.overruletime = overruletime;
278 * @return the ecosave mode
280 public int getEcosave() {
285 * @param ecosave the ecosave mode to set
287 private void setEcosave(int ecosave) {
288 this.ecosave = ecosave;
292 * @return the heating/cooling demand: 0 if no demand, >0 if heating, <0 if cooling
294 public int getDemand() {
299 * @param demand set the heating/cooling demand
301 private void setDemand(int demand) {
302 this.demand = demand;
306 * Sends thermostat mode to Niko Home Control. This method is implemented in {@link NhcThermostat1} and
307 * {@link NhcThermostat2}.
311 public abstract void executeMode(int mode);
314 * Sends thermostat setpoint to Niko Home Control. This method is implemented in {@link NhcThermostat1} and
315 * {@link NhcThermostat2}.
317 * @param overrule temperature to overrule the setpoint in 0.1°C multiples
318 * @param time time duration in min for overrule
320 public abstract void executeOverrule(int overrule, int overruletime);
323 * @return remaining overrule time in minutes
325 public int getRemainingOverruletime() {
326 if (overruleStart == null) {
329 // overruletime time max 23h59min, therefore can safely cast to int
330 return overruletime - (int) ChronoUnit.MINUTES.between(overruleStart, LocalDateTime.now());
335 * Start a new overrule, this method is used to be able to calculate the remaining overrule time
337 private void startOverrule() {
338 overruleStart = LocalDateTime.now();
342 * Reset overrule start
344 private void stopOverrule() {
345 overruleStart = null;