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.lametrictime.internal.handler;
15 import java.util.SortedMap;
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;
39 * The {@link AbstractLaMetricTimeAppHandler} is the parent of all app handlers for
40 * the LaMetric Time device.
42 * @author Gregory Moyer - Initial contribution
45 public abstract class AbstractLaMetricTimeAppHandler extends BaseThingHandler implements LaMetricTimeAppHandler {
47 private final Logger logger = LoggerFactory.getLogger(AbstractLaMetricTimeAppHandler.class);
50 private Widget widget;
52 public AbstractLaMetricTimeAppHandler(Thing thing) {
57 public void initialize() {
58 logger.debug("Verifying LaMetric Time device configuration");
60 Bridge bridge = getBridge();
62 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
63 "No device bridge has been configured");
67 if (ThingStatus.ONLINE != bridge.getStatus()) {
68 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
72 updateWidget(bridge.getHandler());
73 updateStatus(ThingStatus.ONLINE);
77 public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
78 super.bridgeStatusChanged(bridgeStatusInfo);
80 if (bridgeStatusInfo.getStatus() == ThingStatus.ONLINE) {
81 updateWidget(getBridge().getHandler());
85 private void updateWidget(@Nullable ThingHandler handler) {
86 if (!(handler instanceof LaMetricTimeHandler)) {
87 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Incorrect bridge thing found");
90 LaMetricTimeHandler deviceHandler = (LaMetricTimeHandler) handler;
92 logger.debug("Reading LaMetric Time app thing configuration");
93 LaMetricTimeAppConfiguration config = getConfigAs(LaMetricTimeAppConfiguration.class);
94 String packageName = getPackageName(config);
96 Application app = deviceHandler.getClock().getApplication(packageName);
98 SortedMap<String, Widget> widgets = app.getWidgets();
99 if (config.widgetId != null) {
100 widget = widgets.get(config.widgetId);
102 if (widget == null) {
103 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
104 "No widget found with package name " + packageName + " and widget ID " + config.widgetId);
108 widget = widgets.get(widgets.firstKey());
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);
118 protected void updateActiveAppOnDevice() {
119 String widgetId = new WidgetRef(widget.getPackageName(), widget.getId()).toString();
120 ((LaMetricTimeHandler) getBridge().getHandler()).updateActiveApp(widgetId);
123 protected @Nullable String getPackageName(LaMetricTimeAppConfiguration config) {
124 return config.packageName;
128 public void dispose() {
133 public @Nullable Widget getWidget() {
134 if (widget == null) {
135 getBridge().getHandler().initialize();
140 protected LaMetricTime getDevice() {
141 return ((LaMetricTimeHandler) getBridge().getHandler()).getClock();
145 public void handleCommand(ChannelUID channelUID, Command command) {
146 logger.debug("Received channel: {}, command: {}", channelUID, command);
149 if (command instanceof RefreshType) {
150 // verify communication
151 getDevice().getApplication(getWidget().getPackageName());
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());
162 protected abstract void handleAppCommand(ChannelUID channelUID, Command command);