]> git.basschouten.com Git - openhab-addons.git/blob
7f70dc6bfa345c2bc9c738eaa6d06d08628e05c1
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.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;
30
31 import de.fh_zwickau.informatik.sensor.model.devices.Device;
32 import de.fh_zwickau.informatik.sensor.model.devices.DeviceList;
33
34 /**
35  * The {@link ZWayZAutomationDeviceHandler} is responsible for handling commands, which are
36  * sent to one of the channels.
37  *
38  * @author Patrick Hecker - Initial contribution
39  */
40 public class ZWayZAutomationDeviceHandler extends ZWayDeviceHandler {
41     public static final ThingTypeUID SUPPORTED_THING_TYPE = THING_TYPE_VIRTUAL_DEVICE;
42
43     private final Logger logger = LoggerFactory.getLogger(getClass());
44
45     private ZWayZAutomationDeviceConfiguration mConfig;
46
47     private class Initializer implements Runnable {
48
49         @Override
50         public void run() {
51             ZWayBridgeHandler zwayBridgeHandler = getZWayBridgeHandler();
52             if (zwayBridgeHandler != null && zwayBridgeHandler.getThing().getStatus().equals(ThingStatus.ONLINE)) {
53                 ThingStatusInfo statusInfo = zwayBridgeHandler.getThing().getStatusInfo();
54
55                 logger.debug("Change Z-Way device status to bridge status: {}", statusInfo.getStatus());
56
57                 // Set thing status to bridge status
58                 updateStatus(statusInfo.getStatus(), statusInfo.getStatusDetail(), statusInfo.getDescription());
59
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());
64
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.
69                     try {
70                         Device device = deviceList.getDeviceById(mConfig.getDeviceId());
71
72                         if (device != null) {
73                             logger.debug("Add channel for virtual device: {}", device.getMetrics().getTitle());
74
75                             addDeviceAsChannel(device);
76
77                             // Starts polling job and register all linked items
78                             completeInitialization();
79                         } else {
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.");
84                         }
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());
90                         } else {
91                             logger.error("Unexpected error");
92                         }
93                         if (getThing().getStatus() == ThingStatus.ONLINE) {
94                             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR,
95                                     "Error occurred when adding device as channel.");
96                         }
97                     }
98                 } else {
99                     updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR,
100                             "Devices not loaded");
101                 }
102             } else {
103                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR,
104                         "Z-Way bridge handler not found or not ONLINE.");
105             }
106         }
107     }
108
109     public ZWayZAutomationDeviceHandler(Thing thing) {
110         super(thing);
111     }
112
113     @Override
114     public void initialize() {
115         logger.debug("Initializing Z-Way ZAutomation device handler ...");
116
117         // Set thing status to a valid status
118         updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_PENDING,
119                 "Checking configuration and bridge...");
120
121         // Configuration - thing status update with an error message
122         mConfig = loadAndCheckConfiguration();
123
124         if (mConfig != null) {
125             logger.debug("Configuration complete: {}", mConfig);
126
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);
130         } else {
131             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Z-Way device id required!");
132         }
133     }
134
135     private void completeInitialization() {
136         super.initialize(); // starts polling job and register all linked items
137     }
138
139     private ZWayZAutomationDeviceConfiguration loadAndCheckConfiguration() {
140         ZWayZAutomationDeviceConfiguration config = getConfigAs(ZWayZAutomationDeviceConfiguration.class);
141
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.");
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(Long.valueOf(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 }