2 * Copyright (c) 2010-2023 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.openhab.binding.zway.internal.config.ZWayZAutomationDeviceConfiguration;
23 import org.openhab.core.thing.Thing;
24 import org.openhab.core.thing.ThingStatus;
25 import org.openhab.core.thing.ThingStatusDetail;
26 import org.openhab.core.thing.ThingStatusInfo;
27 import org.openhab.core.thing.ThingTypeUID;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
31 import de.fh_zwickau.informatik.sensor.model.devices.Device;
32 import de.fh_zwickau.informatik.sensor.model.devices.DeviceList;
35 * The {@link ZWayZAutomationDeviceHandler} is responsible for handling commands, which are
36 * sent to one of the channels.
38 * @author Patrick Hecker - Initial contribution
40 public class ZWayZAutomationDeviceHandler extends ZWayDeviceHandler {
41 public static final ThingTypeUID SUPPORTED_THING_TYPE = THING_TYPE_VIRTUAL_DEVICE;
43 private final Logger logger = LoggerFactory.getLogger(getClass());
45 private ZWayZAutomationDeviceConfiguration mConfig;
47 private class Initializer implements Runnable {
51 ZWayBridgeHandler zwayBridgeHandler = getZWayBridgeHandler();
52 if (zwayBridgeHandler != null && zwayBridgeHandler.getThing().getStatus().equals(ThingStatus.ONLINE)) {
53 ThingStatusInfo statusInfo = zwayBridgeHandler.getThing().getStatusInfo();
55 logger.debug("Change Z-Way device status to bridge status: {}", statusInfo.getStatus());
57 // Set thing status to bridge status
58 updateStatus(statusInfo.getStatus(), statusInfo.getStatusDetail(), statusInfo.getDescription());
60 // Add all available channels
61 DeviceList deviceList = getZWayBridgeHandler().getZWayApi().getDevices();
62 if (deviceList != null) {
63 logger.debug("Z-Way devices loaded ({} virtual devices)", deviceList.getDevices().size());
65 // https://community.openhab.org/t/oh2-major-bug-with-scheduled-jobs/12350/11
66 // If any execution of the task encounters an exception, subsequent executions are
67 // suppressed. Otherwise, the task will only terminate via cancellation or
68 // termination of the executor.
70 Device device = deviceList.getDeviceById(mConfig.getDeviceId());
73 logger.debug("Add channel for virtual device: {}", device.getMetrics().getTitle());
75 addDeviceAsChannel(device);
77 // Starts polling job and register all linked items
78 completeInitialization();
80 logger.warn("Initializing Z-Way device handler failed (virtual device not found): {}",
81 getThing().getLabel());
82 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR,
83 "Z-Way virtual device with id " + mConfig.getDeviceId() + " not found.");
85 } catch (Throwable t) {
86 if (t instanceof Exception) {
87 logger.error("{}", t.getMessage());
88 } else if (t instanceof Error) {
89 logger.error("{}", t.getMessage());
91 logger.error("Unexpected error");
93 if (getThing().getStatus() == ThingStatus.ONLINE) {
94 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR,
95 "Error occurred when adding device as channel.");
99 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR,
100 "Devices not loaded");
103 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR,
104 "Z-Way bridge handler not found or not ONLINE.");
109 public ZWayZAutomationDeviceHandler(Thing thing) {
114 public void initialize() {
115 logger.debug("Initializing Z-Way ZAutomation device handler ...");
117 // Set thing status to a valid status
118 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_PENDING,
119 "Checking configuration and bridge...");
121 // Configuration - thing status update with an error message
122 mConfig = loadAndCheckConfiguration();
124 if (mConfig != null) {
125 logger.debug("Configuration complete: {}", mConfig);
127 // Start an extra thread to check the connection, because it takes sometimes more
128 // than 5000 milliseconds and the handler will suspend (ThingStatus.UNINITIALIZED).
129 scheduler.schedule(new Initializer(), 2, TimeUnit.SECONDS);
131 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Z-Way device id required!");
135 private void completeInitialization() {
136 super.initialize(); // starts polling job and register all linked items
139 private ZWayZAutomationDeviceConfiguration loadAndCheckConfiguration() {
140 ZWayZAutomationDeviceConfiguration config = getConfigAs(ZWayZAutomationDeviceConfiguration.class);
142 String deviceId = config.getDeviceId();
143 if (deviceId == null || deviceId.isBlank()) {
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(Long.valueOf(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()));