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