2 * Copyright (c) 2010-2020 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.zway.internal.handler;
15 import static org.openhab.binding.zway.internal.ZWayBindingConstants.*;
17 import java.text.DateFormat;
18 import java.text.SimpleDateFormat;
19 import java.util.Calendar;
20 import java.util.concurrent.TimeUnit;
22 import org.apache.commons.lang3.StringUtils;
23 import org.openhab.binding.zway.internal.config.ZWayZAutomationDeviceConfiguration;
24 import org.openhab.core.thing.Thing;
25 import org.openhab.core.thing.ThingStatus;
26 import org.openhab.core.thing.ThingStatusDetail;
27 import org.openhab.core.thing.ThingStatusInfo;
28 import org.openhab.core.thing.ThingTypeUID;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
32 import de.fh_zwickau.informatik.sensor.model.devices.Device;
33 import de.fh_zwickau.informatik.sensor.model.devices.DeviceList;
36 * The {@link ZWayZAutomationDeviceHandler} is responsible for handling commands, which are
37 * sent to one of the channels.
39 * @author Patrick Hecker - Initial contribution
41 public class ZWayZAutomationDeviceHandler extends ZWayDeviceHandler {
42 public static final ThingTypeUID SUPPORTED_THING_TYPE = THING_TYPE_VIRTUAL_DEVICE;
44 private final Logger logger = LoggerFactory.getLogger(getClass());
46 private ZWayZAutomationDeviceConfiguration mConfig;
48 private class Initializer implements Runnable {
52 ZWayBridgeHandler zwayBridgeHandler = getZWayBridgeHandler();
53 if (zwayBridgeHandler != null && zwayBridgeHandler.getThing().getStatus().equals(ThingStatus.ONLINE)) {
54 ThingStatusInfo statusInfo = zwayBridgeHandler.getThing().getStatusInfo();
56 logger.debug("Change Z-Way device status to bridge status: {}", statusInfo.getStatus());
58 // Set thing status to bridge status
59 updateStatus(statusInfo.getStatus(), statusInfo.getStatusDetail(), statusInfo.getDescription());
61 // Add all available channels
62 DeviceList deviceList = getZWayBridgeHandler().getZWayApi().getDevices();
63 if (deviceList != null) {
64 logger.debug("Z-Way devices loaded ({} virtual devices)", deviceList.getDevices().size());
66 // https://community.openhab.org/t/oh2-major-bug-with-scheduled-jobs/12350/11
67 // If any execution of the task encounters an exception, subsequent executions are
68 // suppressed. Otherwise, the task will only terminate via cancellation or
69 // termination of the executor.
71 Device device = deviceList.getDeviceById(mConfig.getDeviceId());
74 logger.debug("Add channel for virtual device: {}", device.getMetrics().getTitle());
76 addDeviceAsChannel(device);
78 // Starts polling job and register all linked items
79 completeInitialization();
81 logger.warn("Initializing Z-Way device handler failed (virtual device not found): {}",
82 getThing().getLabel());
83 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR,
84 "Z-Way virtual device with id " + mConfig.getDeviceId() + " not found.");
86 } catch (Throwable t) {
87 if (t instanceof Exception) {
88 logger.error("{}", t.getMessage());
89 } else if (t instanceof Error) {
90 logger.error("{}", t.getMessage());
92 logger.error("Unexpected error");
94 if (getThing().getStatus() == ThingStatus.ONLINE) {
95 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR,
96 "Error occurred when adding device as channel.");
100 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR,
101 "Devices not loaded");
104 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR,
105 "Z-Way bridge handler not found or not ONLINE.");
110 public ZWayZAutomationDeviceHandler(Thing thing) {
115 public void initialize() {
116 logger.debug("Initializing Z-Way ZAutomation device handler ...");
118 // Set thing status to a valid status
119 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_PENDING,
120 "Checking configuration and bridge...");
122 // Configuration - thing status update with a error message
123 mConfig = loadAndCheckConfiguration();
125 if (mConfig != null) {
126 logger.debug("Configuration complete: {}", mConfig);
128 // Start an extra thread to check the connection, because it takes sometimes more
129 // than 5000 milliseconds and the handler will suspend (ThingStatus.UNINITIALIZED).
130 scheduler.schedule(new Initializer(), 2, TimeUnit.SECONDS);
132 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Z-Way device id required!");
136 private void completeInitialization() {
137 super.initialize(); // starts polling job and register all linked items
140 private ZWayZAutomationDeviceConfiguration loadAndCheckConfiguration() {
141 ZWayZAutomationDeviceConfiguration config = getConfigAs(ZWayZAutomationDeviceConfiguration.class);
143 if (StringUtils.trimToNull(config.getDeviceId()) == null) {
144 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
145 "Z-Wave device couldn't create, because the device id is missing.");
153 public void dispose() {
154 logger.debug("Dispose Z-Way ZAutomation handler ...");
156 if (mConfig.getDeviceId() != null) {
157 mConfig.setDeviceId(null);
164 protected void refreshLastUpdate() {
165 logger.debug("Refresh last update for virtual device");
167 // Check Z-Way bridge handler
168 ZWayBridgeHandler zwayBridgeHandler = getZWayBridgeHandler();
169 if (zwayBridgeHandler == null || !zwayBridgeHandler.getThing().getStatus().equals(ThingStatus.ONLINE)) {
170 logger.debug("Z-Way bridge handler not found or not ONLINE.");
174 // Load and check device from Z-Way server
175 DeviceList deviceList = zwayBridgeHandler.getZWayApi().getDevices();
176 if (deviceList != null) {
177 Device device = deviceList.getDeviceById(mConfig.getDeviceId());
178 if (device == null) {
179 logger.debug("ZAutomation device not found.");
183 Calendar lastUpdateOfDevice = Calendar.getInstance();
184 lastUpdateOfDevice.setTimeInMillis(new Long(device.getUpdateTime()) * 1000);
186 if (lastUpdate == null || lastUpdateOfDevice.after(lastUpdate)) {
187 lastUpdate = lastUpdateOfDevice;
190 DateFormat formatter = new SimpleDateFormat("dd.MM.yyyy hh:mm:ss");
191 updateProperty(DEVICE_PROP_LAST_UPDATE, formatter.format(lastUpdate.getTime()));