2 * Copyright (c) 2010-2021 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();
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);
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.
138 * @param eventHandler
140 public void setEventHandler(NhcThermostatEvent eventHandler) {
141 this.eventHandler = eventHandler;
145 * Get the id of the thermostat.
149 public String getId() {
154 * Get name of thermostat.
156 * @return thermostat name
158 public String getName() {
163 * Get location name of action.
165 * @return location name
167 public @Nullable String getLocation() {
172 * Get measured temperature.
174 * @return measured temperature in 0.1°C multiples
176 public int getMeasured() {
180 private void setMeasured(int measured) {
181 this.measured = measured;
185 * @return the setpoint temperature in 0.1°C multiples
187 public int getSetpoint() {
191 private void setSetpoint(int setpoint) {
192 this.setpoint = setpoint;
196 * Get the thermostat mode.
199 * 0 = day, 1 = night, 2 = eco, 3 = off, 4 = cool, 5 = prog 1, 6 = prog 2, 7 = prog 3
201 public int getMode() {
205 private void setMode(int mode) {
210 * Get the overrule temperature.
212 * @return the overrule temperature in 0.1°C multiples
214 public int getOverrule() {
222 private void setOverrule(int overrule) {
223 this.overrule = overrule;
227 * Get the duration for an overrule temperature
229 * @return the overruletime in minutes
231 public int getOverruletime() {
236 * Set the duration for an overrule temperature
238 * @param overruletime the overruletime in minutes
240 private void setOverruletime(int overruletime) {
241 if (overruletime <= 0) {
243 } else if (overruletime != this.overruletime) {
246 this.overruletime = overruletime;
250 * @return the ecosave mode
252 public int getEcosave() {
257 * @param ecosave the ecosave mode to set
259 private void setEcosave(int ecosave) {
260 this.ecosave = ecosave;
264 * @return the heating/cooling demand: 0 if no demand, >0 if heating, <0 if cooling
266 public int getDemand() {
271 * @param demand set the heating/cooling demand
273 private void setDemand(int demand) {
274 this.demand = demand;
278 * Sends thermostat mode to Niko Home Control. This method is implemented in {@link NhcThermostat1} and
279 * {@link NhcThermostat2}.
283 public abstract void executeMode(int mode);
286 * Sends thermostat setpoint to Niko Home Control. This method is implemented in {@link NhcThermostat1} and
287 * {@link NhcThermostat2}.
289 * @param overrule temperature to overrule the setpoint in 0.1°C multiples
290 * @param time time duration in min for overrule
292 public abstract void executeOverrule(int overrule, int overruletime);
295 * @return remaining overrule time in minutes
297 public int getRemainingOverruletime() {
298 if (overruleStart == null) {
301 // overruletime time max 23h59min, therefore can safely cast to int
302 return overruletime - (int) ChronoUnit.MINUTES.between(overruleStart, LocalDateTime.now());
307 * Start a new overrule, this method is used to be able to calculate the remaining overrule time
309 private void startOverrule() {
310 overruleStart = LocalDateTime.now();
314 * Reset overrule start
316 private void stopOverrule() {
317 overruleStart = null;