]> git.basschouten.com Git - openhab-addons.git/blob
fa4173ccdb9a44d062e64399f7677be4a57aae16
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.zway.internal.handler;
14
15 import static org.openhab.binding.zway.internal.ZWayBindingConstants.*;
16
17 import java.text.DateFormat;
18 import java.text.SimpleDateFormat;
19 import java.util.Calendar;
20 import java.util.concurrent.TimeUnit;
21
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;
31
32 import de.fh_zwickau.informatik.sensor.model.devices.Device;
33 import de.fh_zwickau.informatik.sensor.model.devices.DeviceList;
34
35 /**
36  * The {@link ZWayZAutomationDeviceHandler} is responsible for handling commands, which are
37  * sent to one of the channels.
38  *
39  * @author Patrick Hecker - Initial contribution
40  */
41 public class ZWayZAutomationDeviceHandler extends ZWayDeviceHandler {
42     public static final ThingTypeUID SUPPORTED_THING_TYPE = THING_TYPE_VIRTUAL_DEVICE;
43
44     private final Logger logger = LoggerFactory.getLogger(getClass());
45
46     private ZWayZAutomationDeviceConfiguration mConfig;
47
48     private class Initializer implements Runnable {
49
50         @Override
51         public void run() {
52             ZWayBridgeHandler zwayBridgeHandler = getZWayBridgeHandler();
53             if (zwayBridgeHandler != null && zwayBridgeHandler.getThing().getStatus().equals(ThingStatus.ONLINE)) {
54                 ThingStatusInfo statusInfo = zwayBridgeHandler.getThing().getStatusInfo();
55
56                 logger.debug("Change Z-Way device status to bridge status: {}", statusInfo.getStatus());
57
58                 // Set thing status to bridge status
59                 updateStatus(statusInfo.getStatus(), statusInfo.getStatusDetail(), statusInfo.getDescription());
60
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());
65
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.
70                     try {
71                         Device device = deviceList.getDeviceById(mConfig.getDeviceId());
72
73                         if (device != null) {
74                             logger.debug("Add channel for virtual device: {}", device.getMetrics().getTitle());
75
76                             addDeviceAsChannel(device);
77
78                             // Starts polling job and register all linked items
79                             completeInitialization();
80                         } else {
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.");
85                         }
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());
91                         } else {
92                             logger.error("Unexpected error");
93                         }
94                         if (getThing().getStatus() == ThingStatus.ONLINE) {
95                             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR,
96                                     "Error occurred when adding device as channel.");
97                         }
98                     }
99                 } else {
100                     updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR,
101                             "Devices not loaded");
102                 }
103             } else {
104                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR,
105                         "Z-Way bridge handler not found or not ONLINE.");
106             }
107         }
108     }
109
110     public ZWayZAutomationDeviceHandler(Thing thing) {
111         super(thing);
112     }
113
114     @Override
115     public void initialize() {
116         logger.debug("Initializing Z-Way ZAutomation device handler ...");
117
118         // Set thing status to a valid status
119         updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_PENDING,
120                 "Checking configuration and bridge...");
121
122         // Configuration - thing status update with a error message
123         mConfig = loadAndCheckConfiguration();
124
125         if (mConfig != null) {
126             logger.debug("Configuration complete: {}", mConfig);
127
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);
131         } else {
132             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Z-Way device id required!");
133         }
134     }
135
136     private void completeInitialization() {
137         super.initialize(); // starts polling job and register all linked items
138     }
139
140     private ZWayZAutomationDeviceConfiguration loadAndCheckConfiguration() {
141         ZWayZAutomationDeviceConfiguration config = getConfigAs(ZWayZAutomationDeviceConfiguration.class);
142
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.");
146             return null;
147         }
148
149         return config;
150     }
151
152     @Override
153     public void dispose() {
154         logger.debug("Dispose Z-Way ZAutomation handler ...");
155
156         if (mConfig.getDeviceId() != null) {
157             mConfig.setDeviceId(null);
158         }
159
160         super.dispose();
161     }
162
163     @Override
164     protected void refreshLastUpdate() {
165         logger.debug("Refresh last update for virtual device");
166
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.");
171             return;
172         }
173
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.");
180                 return;
181             }
182
183             Calendar lastUpdateOfDevice = Calendar.getInstance();
184             lastUpdateOfDevice.setTimeInMillis(new Long(device.getUpdateTime()) * 1000);
185
186             if (lastUpdate == null || lastUpdateOfDevice.after(lastUpdate)) {
187                 lastUpdate = lastUpdateOfDevice;
188             }
189
190             DateFormat formatter = new SimpleDateFormat("dd.MM.yyyy hh:mm:ss");
191             updateProperty(DEVICE_PROP_LAST_UPDATE, formatter.format(lastUpdate.getTime()));
192         }
193     }
194 }