]> git.basschouten.com Git - openhab-addons.git/blob
ed4e8b98066d6a7f7f94c04fe42885d0b09f7ea0
[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.lametrictime.internal.handler;
14
15 import java.util.SortedMap;
16
17 import org.openhab.binding.lametrictime.api.LaMetricTime;
18 import org.openhab.binding.lametrictime.api.local.ApplicationNotFoundException;
19 import org.openhab.binding.lametrictime.api.local.model.Application;
20 import org.openhab.binding.lametrictime.api.local.model.Widget;
21 import org.openhab.binding.lametrictime.internal.WidgetRef;
22 import org.openhab.binding.lametrictime.internal.config.LaMetricTimeAppConfiguration;
23 import org.openhab.core.thing.Bridge;
24 import org.openhab.core.thing.ChannelUID;
25 import org.openhab.core.thing.Thing;
26 import org.openhab.core.thing.ThingStatus;
27 import org.openhab.core.thing.ThingStatusDetail;
28 import org.openhab.core.thing.ThingStatusInfo;
29 import org.openhab.core.thing.binding.BaseThingHandler;
30 import org.openhab.core.thing.binding.ThingHandler;
31 import org.openhab.core.types.Command;
32 import org.openhab.core.types.RefreshType;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 /**
37  * The {@link AbstractLaMetricTimeAppHandler} is the parent of all app handlers for
38  * the LaMetric Time device.
39  *
40  * @author Gregory Moyer - Initial contribution
41  */
42 public abstract class AbstractLaMetricTimeAppHandler extends BaseThingHandler implements LaMetricTimeAppHandler {
43
44     private final Logger logger = LoggerFactory.getLogger(AbstractLaMetricTimeAppHandler.class);
45
46     private Widget widget;
47
48     public AbstractLaMetricTimeAppHandler(Thing thing) {
49         super(thing);
50     }
51
52     @Override
53     public void initialize() {
54         logger.debug("Verifying LaMetric Time device configuration");
55
56         Bridge bridge = getBridge();
57         if (bridge == null) {
58             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
59                     "No device bridge has been configured");
60             return;
61         }
62
63         if (ThingStatus.ONLINE != bridge.getStatus()) {
64             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
65             return;
66         }
67
68         updateWidget(bridge.getHandler());
69         updateStatus(ThingStatus.ONLINE);
70     }
71
72     @Override
73     public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
74         super.bridgeStatusChanged(bridgeStatusInfo);
75
76         if (bridgeStatusInfo.getStatus() == ThingStatus.ONLINE) {
77             updateWidget(getBridge().getHandler());
78         }
79     }
80
81     private void updateWidget(ThingHandler handler) {
82         if (!(handler instanceof LaMetricTimeHandler)) {
83             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Incorrect bridge thing found");
84             return;
85         }
86         LaMetricTimeHandler deviceHandler = (LaMetricTimeHandler) handler;
87
88         logger.debug("Reading LaMetric Time app thing configuration");
89         LaMetricTimeAppConfiguration config = getConfigAs(LaMetricTimeAppConfiguration.class);
90         String packageName = getPackageName(config);
91         try {
92             Application app = deviceHandler.getClock().getApplication(packageName);
93
94             SortedMap<String, Widget> widgets = app.getWidgets();
95             if (config.widgetId != null) {
96                 widget = widgets.get(config.widgetId);
97
98                 if (widget == null) {
99                     updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
100                             "No widget found with package name " + packageName + " and widget ID " + config.widgetId);
101                     return;
102                 }
103             } else {
104                 widget = widgets.get(widgets.firstKey());
105             }
106         } catch (ApplicationNotFoundException e) {
107             logger.debug("LaMetric Time application not found", e);
108             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
109                     "No application found with package name " + packageName);
110             return;
111         }
112     }
113
114     protected void updateActiveAppOnDevice() {
115         String widgetId = new WidgetRef(widget.getPackageName(), widget.getId()).toString();
116         ((LaMetricTimeHandler) getBridge().getHandler()).updateActiveApp(widgetId);
117     }
118
119     protected String getPackageName(LaMetricTimeAppConfiguration config) {
120         return config.packageName;
121     }
122
123     @Override
124     public void dispose() {
125         widget = null;
126     }
127
128     @Override
129     public Widget getWidget() {
130         if (widget == null) {
131             getBridge().getHandler().initialize();
132         }
133         return widget;
134     }
135
136     protected LaMetricTime getDevice() {
137         return ((LaMetricTimeHandler) getBridge().getHandler()).getClock();
138     }
139
140     @Override
141     public void handleCommand(ChannelUID channelUID, Command command) {
142         logger.debug("Received channel: {}, command: {}", channelUID, command);
143
144         try {
145             if (command instanceof RefreshType) {
146                 // verify communication
147                 getDevice().getApplication(getWidget().getPackageName());
148                 return;
149             }
150
151             handleAppCommand(channelUID, command);
152         } catch (Exception e) {
153             logger.debug("Failed to communicate - taking app offline", e);
154             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
155         }
156     }
157
158     protected abstract void handleAppCommand(ChannelUID channelUID, Command command);
159 }