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.handler;
15 import static org.openhab.binding.nikohomecontrol.internal.NikoHomeControlBindingConstants.*;
17 import java.net.InetAddress;
18 import java.net.UnknownHostException;
19 import java.util.Collection;
21 import java.util.Map.Entry;
23 import java.util.concurrent.ScheduledFuture;
24 import java.util.concurrent.TimeUnit;
26 import org.eclipse.jdt.annotation.NonNullByDefault;
27 import org.eclipse.jdt.annotation.Nullable;
28 import org.openhab.binding.nikohomecontrol.internal.discovery.NikoHomeControlDiscoveryService;
29 import org.openhab.binding.nikohomecontrol.internal.protocol.NhcControllerEvent;
30 import org.openhab.binding.nikohomecontrol.internal.protocol.NikoHomeControlCommunication;
31 import org.openhab.core.config.core.Configuration;
32 import org.openhab.core.thing.Bridge;
33 import org.openhab.core.thing.ChannelUID;
34 import org.openhab.core.thing.ThingStatus;
35 import org.openhab.core.thing.ThingStatusDetail;
36 import org.openhab.core.thing.binding.BaseBridgeHandler;
37 import org.openhab.core.thing.binding.ThingHandlerService;
38 import org.openhab.core.types.Command;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
43 * {@link NikoHomeControlBridgeHandler} is an abstract class representing a handler to all different interfaces to the
44 * Niko Home Control System. {@link NikoHomeControlBridgeHandler1} or {@link NikoHomeControlBridgeHandler2} should be
45 * used for the respective version of Niko Home Control.
47 * @author Mark Herwege - Initial Contribution
50 public abstract class NikoHomeControlBridgeHandler extends BaseBridgeHandler implements NhcControllerEvent {
52 private final Logger logger = LoggerFactory.getLogger(NikoHomeControlBridgeHandler.class);
54 protected @Nullable NikoHomeControlCommunication nhcComm;
56 private volatile @Nullable ScheduledFuture<?> refreshTimer;
58 public NikoHomeControlBridgeHandler(Bridge nikoHomeControlBridge) {
59 super(nikoHomeControlBridge);
63 public void handleCommand(ChannelUID channelUID, Command command) {
64 // There is nothing to handle in the bridge handler
68 * Create communication object to Niko Home Control IP-interface and start communication.
69 * Trigger discovery when communication setup is successful.
71 protected void startCommunication() {
72 NikoHomeControlCommunication comm = nhcComm;
78 updateStatus(ThingStatus.UNKNOWN);
80 scheduler.submit(() -> {
81 comm.startCommunication();
82 if (!comm.communicationActive()) {
89 updateStatus(ThingStatus.ONLINE);
91 int refreshInterval = getConfig().as(NikoHomeControlBridgeConfig.class).refresh;
92 setupRefreshTimer(refreshInterval);
97 * Schedule future communication refresh.
99 * @param refreshInterval Time before refresh in minutes.
101 private void setupRefreshTimer(int refreshInterval) {
102 ScheduledFuture<?> timer = refreshTimer;
108 if (refreshInterval == 0) {
112 // This timer will restart the bridge connection periodically
113 logger.debug("restart bridge connection every {} min", refreshInterval);
114 refreshTimer = scheduler.scheduleWithFixedDelay(() -> {
115 logger.debug("restart communication at scheduled time");
117 NikoHomeControlCommunication comm = nhcComm;
119 comm.restartCommunication();
120 if (!comm.communicationActive()) {
127 updateStatus(ThingStatus.ONLINE);
129 }, refreshInterval, refreshInterval, TimeUnit.MINUTES);
133 * Take bridge offline when error in communication with Niko Home Control IP-interface.
135 protected void bridgeOffline() {
136 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
137 "@text/offline.communication-error");
141 * Put bridge online when error in communication resolved.
143 public void bridgeOnline() {
145 updateStatus(ThingStatus.ONLINE);
149 public void controllerOffline(String message) {
150 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, message);
154 public void controllerOnline() {
157 int refreshInterval = getConfig().as(NikoHomeControlBridgeConfig.class).refresh;
158 if (refreshTimer == null) {
159 setupRefreshTimer(refreshInterval);
164 * Update bridge properties with properties returned from Niko Home Control Controller.
166 protected abstract void updateProperties();
169 public void dispose() {
170 ScheduledFuture<?> timer = refreshTimer;
176 NikoHomeControlCommunication comm = nhcComm;
178 comm.stopCommunication();
184 public void handleConfigurationUpdate(Map<String, Object> configurationParameters) {
185 NikoHomeControlCommunication comm = nhcComm;
186 // if the communication had not been started yet, just dispose and initialize again
188 super.handleConfigurationUpdate(configurationParameters);
192 Configuration configuration = editConfiguration();
193 for (Entry<String, Object> configurationParameter : configurationParameters.entrySet()) {
194 configuration.put(configurationParameter.getKey(), configurationParameter.getValue());
196 updateConfiguration(configuration);
198 scheduler.submit(() -> {
199 comm.restartCommunication();
200 if (!comm.communicationActive()) {
207 updateStatus(ThingStatus.ONLINE);
209 int refreshInterval = getConfig().as(NikoHomeControlBridgeConfig.class).refresh;
210 setupRefreshTimer(refreshInterval);
215 public void alarmEvent(String alarmText) {
216 logger.debug("triggering alarm channel with {}", alarmText);
217 triggerChannel(CHANNEL_ALARM, alarmText);
218 updateStatus(ThingStatus.ONLINE);
222 public void noticeEvent(String alarmText) {
223 logger.debug("triggering notice channel with {}", alarmText);
224 triggerChannel(CHANNEL_NOTICE, alarmText);
225 updateStatus(ThingStatus.ONLINE);
229 public void updatePropertiesEvent() {
234 * Get the Niko Home Control communication object.
236 * @return Niko Home Control communication object
238 public @Nullable NikoHomeControlCommunication getCommunication() {
243 public @Nullable InetAddress getAddr() {
244 InetAddress addr = null;
245 NikoHomeControlBridgeConfig config = getConfig().as(NikoHomeControlBridgeConfig.class);
247 addr = InetAddress.getByName(config.addr);
248 } catch (UnknownHostException e) {
249 logger.debug("Cannot resolve hostname {} to IP adress", config.addr);
255 public int getPort() {
256 return getConfig().as(NikoHomeControlBridgeConfig.class).port;
260 public Collection<Class<? extends ThingHandlerService>> getServices() {
261 return Set.of(NikoHomeControlDiscoveryService.class);