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();
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 id of the thermostat.
149 public String getId() {
154 * Get name of thermostat.
156 * @return thermostat name
158 public String getName() {
163 * Set name of thermostat.
165 * @param name thermostat name
167 public void setName(String name) {
172 * Get location name of thermostat.
174 * @return location name
176 public @Nullable String getLocation() {
181 * Set location name of thermostat.
183 * @param location thermostat location name
185 public void setLocation(@Nullable String location) {
186 this.location = location;
190 * Get measured temperature.
192 * @return measured temperature in 0.1°C multiples
194 public int getMeasured() {
198 private void setMeasured(int measured) {
199 this.measured = measured;
203 * @return the setpoint temperature in 0.1°C multiples
205 public int getSetpoint() {
209 private void setSetpoint(int setpoint) {
210 this.setpoint = setpoint;
214 * Get the thermostat mode.
217 * 0 = day, 1 = night, 2 = eco, 3 = off, 4 = cool, 5 = prog 1, 6 = prog 2, 7 = prog 3
219 public int getMode() {
223 private void setMode(int mode) {
228 * Get the overrule temperature.
230 * @return the overrule temperature in 0.1°C multiples
232 public int getOverrule() {
240 private void setOverrule(int overrule) {
241 this.overrule = overrule;
245 * Get the duration for an overrule temperature
247 * @return the overruletime in minutes
249 public int getOverruletime() {
254 * Set the duration for an overrule temperature
256 * @param overruletime the overruletime in minutes
258 private void setOverruletime(int overruletime) {
259 if (overruletime <= 0) {
261 } else if (overruletime != this.overruletime) {
264 this.overruletime = overruletime;
268 * @return the ecosave mode
270 public int getEcosave() {
275 * @param ecosave the ecosave mode to set
277 private void setEcosave(int ecosave) {
278 this.ecosave = ecosave;
282 * @return the heating/cooling demand: 0 if no demand, >0 if heating, <0 if cooling
284 public int getDemand() {
289 * @param demand set the heating/cooling demand
291 private void setDemand(int demand) {
292 this.demand = demand;
296 * Sends thermostat mode to Niko Home Control. This method is implemented in {@link NhcThermostat1} and
297 * {@link NhcThermostat2}.
301 public abstract void executeMode(int mode);
304 * Sends thermostat setpoint to Niko Home Control. This method is implemented in {@link NhcThermostat1} and
305 * {@link NhcThermostat2}.
307 * @param overrule temperature to overrule the setpoint in 0.1°C multiples
308 * @param time time duration in min for overrule
310 public abstract void executeOverrule(int overrule, int overruletime);
313 * @return remaining overrule time in minutes
315 public int getRemainingOverruletime() {
316 if (overruleStart == null) {
319 // overruletime time max 23h59min, therefore can safely cast to int
320 return overruletime - (int) ChronoUnit.MINUTES.between(overruleStart, LocalDateTime.now());
325 * Start a new overrule, this method is used to be able to calculate the remaining overrule time
327 private void startOverrule() {
328 overruleStart = LocalDateTime.now();
332 * Reset overrule start
334 private void stopOverrule() {
335 overruleStart = null;