]> git.basschouten.com Git - openhab-addons.git/blob
96ab01cbe63adda59ccccb9af1f6886210c350ce
[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.miio.internal.handler;
14
15 import java.time.Instant;
16
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.openhab.binding.miio.internal.MiIoBindingConfiguration;
20 import org.openhab.binding.miio.internal.MiIoSendCommand;
21 import org.openhab.binding.miio.internal.basic.BasicChannelTypeProvider;
22 import org.openhab.binding.miio.internal.basic.MiIoBasicDevice;
23 import org.openhab.binding.miio.internal.basic.MiIoDatabaseWatchService;
24 import org.openhab.binding.miio.internal.cloud.CloudConnector;
25 import org.openhab.core.i18n.LocaleProvider;
26 import org.openhab.core.i18n.TranslationProvider;
27 import org.openhab.core.thing.Bridge;
28 import org.openhab.core.thing.Thing;
29 import org.openhab.core.thing.ThingStatus;
30 import org.openhab.core.thing.ThingStatusDetail;
31 import org.openhab.core.thing.type.ChannelTypeRegistry;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 /**
36  * The {@link MiIoLumiHandler} is responsible for handling commands, which are
37  * sent to one of the channels.
38  *
39  * @author Marcel Verpaalen - Initial contribution
40  */
41 @NonNullByDefault
42 public class MiIoLumiHandler extends MiIoBasicHandler {
43
44     private final Logger logger = LoggerFactory.getLogger(MiIoLumiHandler.class);
45     private @Nullable MiIoGatewayHandler bridgeHandler;
46
47     public MiIoLumiHandler(Thing thing, MiIoDatabaseWatchService miIoDatabaseWatchService,
48             CloudConnector cloudConnector, ChannelTypeRegistry channelTypeRegistry,
49             BasicChannelTypeProvider basicChannelTypeProvider, TranslationProvider i18nProvider,
50             LocaleProvider localeProvider) {
51         super(thing, miIoDatabaseWatchService, cloudConnector, channelTypeRegistry, basicChannelTypeProvider,
52                 i18nProvider, localeProvider);
53     }
54
55     @Override
56     public void initialize() {
57         super.initialize();
58         isIdentified = false;
59         updateStatus(ThingStatus.UNKNOWN);
60
61         final MiIoBindingConfiguration config = this.configuration;
62         if (config != null && config.deviceId.isBlank()) {
63             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Missing required deviceId");
64             return;
65         }
66         Bridge bridge = getBridge();
67         if (bridge == null) {
68             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
69                     "No device bridge has been configured");
70             return;
71         } else {
72             logger.debug("Bridge for {} {} = {} {} ({})", getThing().getUID(), getThing().getLabel(),
73                     bridge.getBridgeUID(), bridge.getLabel(), bridge.getHandler());
74         }
75         bridgeHandler = null;
76     }
77
78     @Nullable
79     MiIoGatewayHandler getBridgeHandler() {
80         if (bridgeHandler == null) {
81             Bridge bridge = getBridge();
82             if (bridge != null) {
83                 final MiIoGatewayHandler bridgeHandler = (MiIoGatewayHandler) bridge.getHandler();
84                 if (bridgeHandler != null) {
85                     if (!bridgeHandler.childDevices.containsKey(getThing())) {
86                         logger.warn(("Child device {} missing at bridge {}. We should not see this"),
87                                 getThing().getUID(), bridgeHandler.getThing().getUID());
88                         bridgeHandler.childDevices.forEach((k, v) -> logger.debug("Devices in bridge: {} : {}", k, v));
89                     }
90                     this.bridgeHandler = bridgeHandler;
91                     return bridgeHandler;
92                 } else {
93                     logger.debug("Bridge is defined, but bridge handler not found for {} {}.", getThing().getUID(),
94                             getThing().getLabel());
95                 }
96             }
97             logger.debug("Bridge is missing for {} {}", getThing().getUID(), getThing().getLabel());
98         }
99         return this.bridgeHandler;
100     }
101
102     @Override
103     public String getCloudServer() {
104         final MiIoGatewayHandler bh = this.bridgeHandler;
105         if (bh != null) {
106             return bh.getCloudServer();
107         } else {
108             final MiIoBindingConfiguration config = this.configuration;
109             return config != null ? config.cloudServer : "";
110         }
111     }
112
113     // Override to inject the sender
114     @Override
115     protected int sendCommand(String command, String params, String cloudServer, String sender) {
116         final MiIoGatewayHandler bridge = getBridgeHandler();
117         if (bridge != null) {
118             logger.debug("Send via bridge {} {} (Cloudserver {})", command, params, cloudServer);
119             return bridge.sendCommand(command, params, cloudServer, getThing().getUID().getAsString());
120         } else {
121             logger.debug("Bridge handler is null. This is unexpected and prevents sending the update");
122         }
123         return 0;
124     }
125
126     @Override
127     protected synchronized void updateData() {
128         logger.debug("Periodic update for '{}' ({})", getThing().getUID(), getThing().getThingTypeUID());
129         try {
130             checkChannelStructure();
131             final MiIoBindingConfiguration config = this.configuration;
132             final MiIoBasicDevice midevice = miioDevice;
133             if (midevice != null && configuration != null && config != null) {
134                 Bridge bridge = getBridge();
135                 if (bridge == null || !bridge.getStatus().equals(ThingStatus.ONLINE)) {
136                     logger.debug("Bridge {} offline, skipping regular refresh for {}", getThing().getBridgeUID(),
137                             getThing().getUID());
138                     refreshCustomProperties(midevice, true);
139                     return;
140                 }
141                 deviceVariables.put(TIMESTAMP, Instant.now().getEpochSecond());
142                 logger.debug("Refresh properties for child device {}", getThing().getLabel());
143                 refreshProperties(midevice, config.deviceId);
144                 logger.debug("Refresh custom commands for child device {}", getThing().getLabel());
145                 refreshCustomProperties(midevice, false);
146             } else {
147                 logger.debug("Null value occured for device {}: {}", midevice, config);
148             }
149         } catch (Exception e) {
150             logger.debug("Error while performing periodic refresh for '{}': {}", getThing().getUID(), e.getMessage());
151         }
152     }
153
154     @Override
155     public void onMessageReceived(MiIoSendCommand response) {
156         super.onMessageReceived(response);
157         if (!response.isError() && (!response.getSender().isBlank()
158                 && response.getSender().contentEquals(getThing().getUID().getAsString()))) {
159             updateStatus(ThingStatus.ONLINE);
160         }
161     }
162 }