2 * Copyright (c) 2010-2021 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;
20 import java.util.Map.Entry;
21 import java.util.concurrent.ScheduledFuture;
22 import java.util.concurrent.TimeUnit;
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.openhab.binding.nikohomecontrol.internal.discovery.NikoHomeControlDiscoveryService;
27 import org.openhab.binding.nikohomecontrol.internal.protocol.NhcControllerEvent;
28 import org.openhab.binding.nikohomecontrol.internal.protocol.NikoHomeControlCommunication;
29 import org.openhab.core.config.core.Configuration;
30 import org.openhab.core.thing.Bridge;
31 import org.openhab.core.thing.ChannelUID;
32 import org.openhab.core.thing.ThingStatus;
33 import org.openhab.core.thing.ThingStatusDetail;
34 import org.openhab.core.thing.binding.BaseBridgeHandler;
35 import org.openhab.core.types.Command;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 * {@link NikoHomeControlBridgeHandler} is an abstract class representing a handler to all different interfaces to the
41 * Niko Home Control System. {@link NikoHomeControlBridgeHandler1} or {@link NikoHomeControlBridgeHandler2} should be
42 * used for the respective
43 * version of Niko Home Control.
45 * @author Mark Herwege - Initial Contribution
48 public abstract class NikoHomeControlBridgeHandler extends BaseBridgeHandler implements NhcControllerEvent {
50 private final Logger logger = LoggerFactory.getLogger(NikoHomeControlBridgeHandler.class);
52 protected @NonNullByDefault({}) NikoHomeControlBridgeConfig config;
54 protected @Nullable NikoHomeControlCommunication nhcComm;
56 private volatile @Nullable ScheduledFuture<?> refreshTimer;
58 protected volatile @Nullable NikoHomeControlDiscoveryService nhcDiscovery;
60 public NikoHomeControlBridgeHandler(Bridge nikoHomeControlBridge) {
61 super(nikoHomeControlBridge);
65 public void handleCommand(ChannelUID channelUID, Command command) {
66 // There is nothing to handle in the bridge handler
70 * Create communication object to Niko Home Control IP-interface and start communication.
71 * Trigger discovery when communication setup is successful.
73 protected void startCommunication() {
74 NikoHomeControlCommunication comm = nhcComm;
80 updateStatus(ThingStatus.UNKNOWN);
82 scheduler.submit(() -> {
83 comm.startCommunication();
84 if (!comm.communicationActive()) {
91 updateStatus(ThingStatus.ONLINE);
93 int refreshInterval = config.refresh;
94 setupRefreshTimer(refreshInterval);
96 NikoHomeControlDiscoveryService discovery = nhcDiscovery;
97 if (discovery != null) {
98 discovery.discoverDevices();
100 logger.debug("cannot discover devices, discovery service not started");
106 * Schedule future communication refresh.
108 * @param interval_config Time before refresh in minutes.
110 private void setupRefreshTimer(int refreshInterval) {
111 ScheduledFuture<?> timer = refreshTimer;
117 if (refreshInterval == 0) {
121 // This timer will restart the bridge connection periodically
122 logger.debug("restart bridge connection every {} min", refreshInterval);
123 refreshTimer = scheduler.scheduleWithFixedDelay(() -> {
124 logger.debug("restart communication at scheduled time");
126 NikoHomeControlCommunication comm = nhcComm;
128 comm.restartCommunication();
129 if (!comm.communicationActive()) {
136 updateStatus(ThingStatus.ONLINE);
138 }, refreshInterval, refreshInterval, TimeUnit.MINUTES);
142 * Take bridge offline when error in communication with Niko Home Control IP-interface.
144 protected void bridgeOffline() {
145 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
146 "@text/offline.communication-error");
150 * Put bridge online when error in communication resolved.
152 public void bridgeOnline() {
154 updateStatus(ThingStatus.ONLINE);
158 public void controllerOffline(String message) {
159 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, message);
163 public void controllerOnline() {
166 int refreshInterval = config.refresh;
167 if (refreshTimer == null) {
168 setupRefreshTimer(refreshInterval);
173 * Update bridge properties with properties returned from Niko Home Control Controller.
175 protected abstract void updateProperties();
178 public void dispose() {
179 ScheduledFuture<?> timer = refreshTimer;
185 NikoHomeControlCommunication comm = nhcComm;
187 comm.stopCommunication();
193 public void handleConfigurationUpdate(Map<String, Object> configurationParameters) {
194 NikoHomeControlCommunication comm = nhcComm;
195 // if the communication had not been started yet, just dispose and initialize again
197 super.handleConfigurationUpdate(configurationParameters);
201 Configuration configuration = editConfiguration();
202 for (Entry<String, Object> configurationParmeter : configurationParameters.entrySet()) {
203 configuration.put(configurationParmeter.getKey(), configurationParmeter.getValue());
205 updateConfiguration(configuration);
209 scheduler.submit(() -> {
210 comm.restartCommunication();
211 if (!comm.communicationActive()) {
218 updateStatus(ThingStatus.ONLINE);
220 int refreshInterval = config.refresh;
221 setupRefreshTimer(refreshInterval);
226 * Set discovery service handler to be able to start discovery after bridge initialization.
228 * @param nhcDiscovery
230 public void setNhcDiscovery(@Nullable NikoHomeControlDiscoveryService nhcDiscovery) {
231 this.nhcDiscovery = nhcDiscovery;
235 public void alarmEvent(String alarmText) {
236 logger.debug("triggering alarm channel with {}", alarmText);
237 triggerChannel(CHANNEL_ALARM, alarmText);
238 updateStatus(ThingStatus.ONLINE);
242 public void noticeEvent(String alarmText) {
243 logger.debug("triggering notice channel with {}", alarmText);
244 triggerChannel(CHANNEL_NOTICE, alarmText);
245 updateStatus(ThingStatus.ONLINE);
249 public void updatePropertiesEvent() {
254 * Get the Niko Home Control communication object.
256 * @return Niko Home Control communication object
258 public @Nullable NikoHomeControlCommunication getCommunication() {
263 public @Nullable InetAddress getAddr() {
264 InetAddress addr = null;
266 addr = InetAddress.getByName(config.addr);
267 } catch (UnknownHostException e) {
268 logger.debug("Cannot resolve hostname {} to IP adress", config.addr);
274 public int getPort() {
278 protected synchronized void setConfig() {
279 config = getConfig().as(NikoHomeControlBridgeConfig.class);