]> git.basschouten.com Git - openhab-addons.git/blob
e4cb1a248198871d9ce77edf50a71f88565f017c
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.ZoneId;
16 import java.util.Map;
17 import java.util.concurrent.ConcurrentHashMap;
18 import java.util.concurrent.ScheduledExecutorService;
19 import java.util.concurrent.ScheduledFuture;
20 import java.util.concurrent.TimeUnit;
21
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;
28
29 /**
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.
33  * <ul>
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.
38  * </ul>
39  *
40  * @author Mark Herwege - Initial Contribution
41  */
42 @NonNullByDefault
43 public abstract class NikoHomeControlCommunication {
44
45     private final Logger logger = LoggerFactory.getLogger(NikoHomeControlCommunication.class);
46
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<>();
50
51     protected final NhcControllerEvent handler;
52
53     protected final ScheduledExecutorService scheduler;
54
55     // restart attempts
56     private volatile int delay = 0;
57     private volatile int attempt = 0;
58     protected volatile @Nullable ScheduledFuture<?> scheduledRestart = null;
59
60     protected NikoHomeControlCommunication(NhcControllerEvent handler, ScheduledExecutorService scheduler) {
61         this.handler = handler;
62         this.scheduler = scheduler;
63     }
64
65     /**
66      * Start Communication with Niko Home Control system.
67      */
68     public abstract void startCommunication();
69
70     /**
71      * Stop Communication with Niko Home Control system.
72      */
73     public void stopCommunication() {
74         stopScheduledRestart();
75
76         resetCommunication();
77     }
78
79     /**
80      * Stop Communication with Niko Home Control system, but keep reconnection attempts going.
81      */
82     public abstract void resetCommunication();
83
84     protected synchronized void stopScheduledRestart() {
85         ScheduledFuture<?> future = scheduledRestart;
86         if (future != null) {
87             future.cancel(true);
88         }
89         scheduledRestart = null;
90         delay = 0;
91         attempt = 0;
92     }
93
94     /**
95      * Close and restart communication with Niko Home Control system.
96      */
97     public synchronized void restartCommunication() {
98         resetCommunication();
99
100         logger.debug("restart communication from thread {}", Thread.currentThread().getId());
101
102         startCommunication();
103     }
104
105     private synchronized void checkAndRestartCommunication() {
106         restartCommunication();
107
108         // Try again if it didn't succeed
109         if (!communicationActive()) {
110             attempt++;
111             delay = ((attempt <= 5) ? 30 : 60);
112             logger.debug("schedule communication restart in {} seconds", delay);
113             scheduledRestart = scheduler.schedule(this::checkAndRestartCommunication, delay, TimeUnit.SECONDS);
114         } else {
115             stopScheduledRestart();
116         }
117     }
118
119     /**
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.
123      */
124     public synchronized void scheduleRestartCommunication() {
125         // Don't do this if we already scheduled to restart
126         if (scheduledRestart == null) {
127             delay = 0;
128             attempt = 0;
129             scheduledRestart = scheduler.schedule(this::checkAndRestartCommunication, 0, TimeUnit.SECONDS);
130         }
131     }
132
133     /**
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.
136      *
137      * @return True if active
138      */
139     public abstract boolean communicationActive();
140
141     /**
142      * Return the timezone for the system.
143      *
144      * @return zoneId
145      */
146     public ZoneId getTimeZone() {
147         return handler.getTimeZone();
148     }
149
150     /**
151      * Return all actions in the Niko Home Control Controller.
152      *
153      * @return <code>Map&lt;String, {@link NhcAction}></code>
154      */
155     public Map<String, NhcAction> getActions() {
156         return actions;
157     }
158
159     /**
160      * Return all thermostats in the Niko Home Control Controller.
161      *
162      * @return <code>Map&lt;String, {@link NhcThermostat}></code>
163      */
164     public Map<String, NhcThermostat> getThermostats() {
165         return thermostats;
166     }
167
168     /**
169      * Return all energyMeters meters in the Niko Home Control Controller.
170      *
171      * @return <code>Map&lt;String, {@link NhcEnergyMeter}></code>
172      */
173     public Map<String, NhcEnergyMeter> getEnergyMeters() {
174         return energyMeters;
175     }
176
177     /**
178      * Execute an action command by sending it to Niko Home Control.
179      *
180      * @param actionId
181      * @param value
182      */
183     public abstract void executeAction(String actionId, String value);
184
185     /**
186      * Execute a thermostat command by sending it to Niko Home Control.
187      *
188      * @param thermostatId
189      * @param mode
190      */
191     public abstract void executeThermostat(String thermostatId, String mode);
192
193     /**
194      * Execute a thermostat command by sending it to Niko Home Control.
195      *
196      * @param thermostatId
197      * @param overruleTemp
198      * @param overruleTime
199      */
200     public abstract void executeThermostat(String thermostatId, int overruleTemp, int overruleTime);
201
202     /**
203      * Start retrieving energy meter data from Niko Home Control.
204      *
205      */
206     public void startEnergyMeter(String energyMeterId) {
207     }
208
209     /**
210      * Stop retrieving energy meter data from Niko Home Control.
211      *
212      */
213     public void stopEnergyMeter(String energyMeterId) {
214     }
215 }