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.handler;
15 import static org.openhab.binding.nikohomecontrol.internal.NikoHomeControlBindingConstants.*;
17 import java.net.InetAddress;
18 import java.net.UnknownHostException;
19 import java.time.ZoneId;
20 import java.util.Collection;
22 import java.util.Map.Entry;
24 import java.util.concurrent.ScheduledFuture;
25 import java.util.concurrent.TimeUnit;
27 import org.eclipse.jdt.annotation.NonNullByDefault;
28 import org.eclipse.jdt.annotation.Nullable;
29 import org.openhab.binding.nikohomecontrol.internal.discovery.NikoHomeControlDiscoveryService;
30 import org.openhab.binding.nikohomecontrol.internal.protocol.NhcControllerEvent;
31 import org.openhab.binding.nikohomecontrol.internal.protocol.NikoHomeControlCommunication;
32 import org.openhab.core.config.core.Configuration;
33 import org.openhab.core.i18n.TimeZoneProvider;
34 import org.openhab.core.thing.Bridge;
35 import org.openhab.core.thing.ChannelUID;
36 import org.openhab.core.thing.ThingStatus;
37 import org.openhab.core.thing.ThingStatusDetail;
38 import org.openhab.core.thing.binding.BaseBridgeHandler;
39 import org.openhab.core.thing.binding.ThingHandlerService;
40 import org.openhab.core.types.Command;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
45 * {@link NikoHomeControlBridgeHandler} is an abstract class representing a handler to all different interfaces to the
46 * Niko Home Control System. {@link NikoHomeControlBridgeHandler1} or {@link NikoHomeControlBridgeHandler2} should be
47 * used for the respective version of Niko Home Control.
49 * @author Mark Herwege - Initial Contribution
52 public abstract class NikoHomeControlBridgeHandler extends BaseBridgeHandler implements NhcControllerEvent {
54 private final Logger logger = LoggerFactory.getLogger(NikoHomeControlBridgeHandler.class);
56 protected @Nullable NikoHomeControlCommunication nhcComm;
58 private volatile @Nullable ScheduledFuture<?> refreshTimer;
60 protected final TimeZoneProvider timeZoneProvider;
62 public NikoHomeControlBridgeHandler(Bridge nikoHomeControlBridge, TimeZoneProvider timeZoneProvider) {
63 super(nikoHomeControlBridge);
64 this.timeZoneProvider = timeZoneProvider;
68 public void handleCommand(ChannelUID channelUID, Command command) {
69 // There is nothing to handle in the bridge handler
73 * Create communication object to Niko Home Control IP-interface and start communication.
74 * Trigger discovery when communication setup is successful.
76 protected void startCommunication() {
77 NikoHomeControlCommunication comm = nhcComm;
83 updateStatus(ThingStatus.UNKNOWN);
85 scheduler.submit(() -> {
86 comm.startCommunication();
88 int refreshInterval = getConfig().as(NikoHomeControlBridgeConfig.class).refresh;
89 setupRefreshTimer(refreshInterval);
91 if (!comm.communicationActive()) {
98 updateStatus(ThingStatus.ONLINE);
103 * Schedule future communication refresh.
105 * @param refreshInterval Time before refresh in minutes.
107 private void setupRefreshTimer(int refreshInterval) {
108 ScheduledFuture<?> timer = refreshTimer;
114 if (refreshInterval == 0) {
118 // This timer will restart the bridge connection periodically
119 logger.debug("restart bridge connection every {} min", refreshInterval);
120 refreshTimer = scheduler.scheduleWithFixedDelay(() -> {
121 logger.debug("restart communication at scheduled time");
123 NikoHomeControlCommunication comm = nhcComm;
125 comm.restartCommunication();
126 if (!comm.communicationActive()) {
133 updateStatus(ThingStatus.ONLINE);
135 }, refreshInterval, refreshInterval, TimeUnit.MINUTES);
139 * Take bridge offline when error in communication with Niko Home Control IP-interface.
141 protected void bridgeOffline() {
142 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
143 "@text/offline.communication-error");
147 * Put bridge online when error in communication resolved.
149 public void bridgeOnline() {
151 updateStatus(ThingStatus.ONLINE);
155 public void controllerOffline(String message) {
156 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, message);
160 public void controllerOnline() {
165 * Update bridge properties with properties returned from Niko Home Control Controller.
167 protected abstract void updateProperties();
170 public void dispose() {
171 ScheduledFuture<?> timer = refreshTimer;
177 NikoHomeControlCommunication comm = nhcComm;
179 comm.stopAllMeters();
180 comm.stopCommunication();
187 public void handleConfigurationUpdate(Map<String, Object> configurationParameters) {
188 NikoHomeControlCommunication comm = nhcComm;
189 // if the communication had not been started yet, just dispose and initialize again
191 super.handleConfigurationUpdate(configurationParameters);
195 Configuration configuration = editConfiguration();
196 for (Entry<String, Object> configurationParameter : configurationParameters.entrySet()) {
197 configuration.put(configurationParameter.getKey(), configurationParameter.getValue());
199 updateConfiguration(configuration);
201 scheduler.submit(() -> {
202 comm.restartCommunication();
203 if (!comm.communicationActive()) {
210 updateStatus(ThingStatus.ONLINE);
212 int refreshInterval = getConfig().as(NikoHomeControlBridgeConfig.class).refresh;
213 setupRefreshTimer(refreshInterval);
218 public void alarmEvent(String alarmText) {
219 logger.debug("triggering alarm channel with {}", alarmText);
220 triggerChannel(CHANNEL_ALARM, alarmText);
221 updateStatus(ThingStatus.ONLINE);
225 public void noticeEvent(String alarmText) {
226 logger.debug("triggering notice channel with {}", alarmText);
227 triggerChannel(CHANNEL_NOTICE, alarmText);
228 updateStatus(ThingStatus.ONLINE);
232 public void updatePropertiesEvent() {
237 * Get the Niko Home Control communication object.
239 * @return Niko Home Control communication object
241 public @Nullable NikoHomeControlCommunication getCommunication() {
246 public @Nullable InetAddress getAddr() {
247 InetAddress addr = null;
248 NikoHomeControlBridgeConfig config = getConfig().as(NikoHomeControlBridgeConfig.class);
250 addr = InetAddress.getByName(config.addr);
251 } catch (UnknownHostException e) {
252 logger.debug("Cannot resolve hostname {} to IP adress", config.addr);
258 public int getPort() {
259 return getConfig().as(NikoHomeControlBridgeConfig.class).port;
263 public ZoneId getTimeZone() {
264 return timeZoneProvider.getTimeZone();
268 public Collection<Class<? extends ThingHandlerService>> getServices() {
269 return Set.of(NikoHomeControlDiscoveryService.class);