2 * Copyright (c) 2010-2024 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.ZoneId;
17 import java.util.concurrent.ConcurrentHashMap;
18 import java.util.concurrent.ScheduledExecutorService;
19 import java.util.concurrent.ScheduledFuture;
20 import java.util.concurrent.TimeUnit;
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.openhab.binding.nikohomecontrol.internal.protocol.nhc1.NikoHomeControlCommunication1;
25 import org.openhab.binding.nikohomecontrol.internal.protocol.nhc2.NikoHomeControlCommunication2;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
30 * The {@link NikoHomeControlCommunication} class is an abstract class representing the communication objects with the
31 * Niko Home Control System. {@link NikoHomeControlCommunication1} or {@link NikoHomeControlCommunication2} should be
32 * used for the respective version of Niko Home Control.
34 * <li>Start and stop communication with the Niko Home Control System.
35 * <li>Read all setup and status information from the Niko Home Control Controller.
36 * <li>Execute Niko Home Control commands.
37 * <li>Listen to events from Niko Home Control.
40 * @author Mark Herwege - Initial Contribution
43 public abstract class NikoHomeControlCommunication {
45 private final Logger logger = LoggerFactory.getLogger(NikoHomeControlCommunication.class);
47 protected final Map<String, NhcAction> actions = new ConcurrentHashMap<>();
48 protected final Map<String, NhcThermostat> thermostats = new ConcurrentHashMap<>();
49 protected final Map<String, NhcEnergyMeter> energyMeters = new ConcurrentHashMap<>();
51 protected final NhcControllerEvent handler;
53 protected final ScheduledExecutorService scheduler;
56 private volatile int delay = 0;
57 private volatile int attempt = 0;
58 protected volatile @Nullable ScheduledFuture<?> scheduledRestart = null;
60 protected NikoHomeControlCommunication(NhcControllerEvent handler, ScheduledExecutorService scheduler) {
61 this.handler = handler;
62 this.scheduler = scheduler;
66 * Start Communication with Niko Home Control system.
68 public abstract void startCommunication();
71 * Stop Communication with Niko Home Control system.
73 public void stopCommunication() {
74 stopScheduledRestart();
80 * Stop Communication with Niko Home Control system, but keep reconnection attempts going.
82 public abstract void resetCommunication();
84 protected synchronized void stopScheduledRestart() {
85 ScheduledFuture<?> future = scheduledRestart;
89 scheduledRestart = null;
95 * Close and restart communication with Niko Home Control system.
97 public synchronized void restartCommunication() {
100 logger.debug("restart communication from thread {}", Thread.currentThread().getId());
102 startCommunication();
105 private synchronized void checkAndRestartCommunication() {
106 restartCommunication();
108 // Try again if it didn't succeed
109 if (!communicationActive()) {
111 delay = ((attempt <= 5) ? 30 : 60);
112 logger.debug("schedule communication restart in {} seconds", delay);
113 scheduledRestart = scheduler.schedule(this::checkAndRestartCommunication, delay, TimeUnit.SECONDS);
115 stopScheduledRestart();
120 * Close and restart communication with Niko Home Control system. This method will keep doing multiple reconnection
121 * attempts, starting immediately, then 5 times with 30 second intervals and every minute thereafter until the
122 * connection is re-established.
124 public synchronized void scheduleRestartCommunication() {
125 // Don't do this if we already scheduled to restart
126 if (scheduledRestart == null) {
129 scheduledRestart = scheduler.schedule(this::checkAndRestartCommunication, 0, TimeUnit.SECONDS);
134 * Method to check if communication with Niko Home Control is active. This method can be blocking for max 5s to wait
135 * for completion of startup.
137 * @return True if active
139 public abstract boolean communicationActive();
142 * Return the timezone for the system.
146 public ZoneId getTimeZone() {
147 return handler.getTimeZone();
151 * Return all actions in the Niko Home Control Controller.
153 * @return <code>Map<String, {@link NhcAction}></code>
155 public Map<String, NhcAction> getActions() {
160 * Return all thermostats in the Niko Home Control Controller.
162 * @return <code>Map<String, {@link NhcThermostat}></code>
164 public Map<String, NhcThermostat> getThermostats() {
169 * Return all energyMeters meters in the Niko Home Control Controller.
171 * @return <code>Map<String, {@link NhcEnergyMeter}></code>
173 public Map<String, NhcEnergyMeter> getEnergyMeters() {
178 * Execute an action command by sending it to Niko Home Control.
183 public abstract void executeAction(String actionId, String value);
186 * Execute a thermostat command by sending it to Niko Home Control.
188 * @param thermostatId
191 public abstract void executeThermostat(String thermostatId, String mode);
194 * Execute a thermostat command by sending it to Niko Home Control.
196 * @param thermostatId
197 * @param overruleTemp
198 * @param overruleTime
200 public abstract void executeThermostat(String thermostatId, int overruleTemp, int overruleTime);
203 * Start retrieving energy meter data from Niko Home Control.
206 public void startEnergyMeter(String energyMeterId) {
210 * Stop retrieving energy meter data from Niko Home Control.
213 public void stopEnergyMeter(String energyMeterId) {