]> git.basschouten.com Git - openhab-addons.git/blob
02fb5657027be1244f86ad89e526362076af08a5
[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.plugwise.internal.handler;
14
15 import static org.openhab.binding.plugwise.internal.PlugwiseBindingConstants.*;
16
17 import java.time.Duration;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.binding.plugwise.internal.config.PlugwiseScanConfig;
22 import org.openhab.binding.plugwise.internal.protocol.AcknowledgementMessage;
23 import org.openhab.binding.plugwise.internal.protocol.LightCalibrationRequestMessage;
24 import org.openhab.binding.plugwise.internal.protocol.ScanParametersSetRequestMessage;
25 import org.openhab.binding.plugwise.internal.protocol.SleepSetRequestMessage;
26 import org.openhab.binding.plugwise.internal.protocol.field.DeviceType;
27 import org.openhab.binding.plugwise.internal.protocol.field.MACAddress;
28 import org.openhab.core.config.core.Configuration;
29 import org.openhab.core.thing.Thing;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 /**
34  * <p>
35  * The {@link PlugwiseScanHandler} handles channel updates and commands for a Plugwise Scan device.
36  * </p>
37  * <p>
38  * The Scan is a wireless PIR sensor that switches on groups of devices depending on the amount of daylight and whether
39  * motion is detected. When the daylight override setting is enabled on a Scan, the state of triggered behaves like that
40  * of a normal motion sensor.
41  * </p>
42  *
43  * @author Wouter Born - Initial contribution
44  */
45 @NonNullByDefault
46 public class PlugwiseScanHandler extends AbstractSleepingEndDeviceHandler {
47
48     private final Logger logger = LoggerFactory.getLogger(PlugwiseScanHandler.class);
49     private final DeviceType deviceType = DeviceType.SCAN;
50
51     private @NonNullByDefault({}) PlugwiseScanConfig configuration;
52     private @NonNullByDefault({}) MACAddress macAddress;
53
54     // Flags that keep track of the pending Scan configuration updates. When the corresponding Thing configuration
55     // parameters change a flag is set to true. When the Scan goes online the respective command is sent to update the
56     // device configuration. When the Scan acknowledges a command the respective flag is again set to false.
57     private boolean updateScanParameters;
58     private boolean updateSleepParameters;
59     private boolean recalibrate;
60
61     public PlugwiseScanHandler(Thing thing) {
62         super(thing);
63     }
64
65     @Override
66     protected MACAddress getMACAddress() {
67         return macAddress;
68     }
69
70     @Override
71     protected Duration getWakeupDuration() {
72         return configuration.getWakeupDuration();
73     }
74
75     @Override
76     protected void handleAcknowledgement(AcknowledgementMessage message) {
77         boolean oldConfigurationPending = isConfigurationPending();
78
79         switch (message.getExtensionCode()) {
80             case LIGHT_CALIBRATION_ACK:
81                 logger.debug("Received ACK for daylight override calibration of {} ({})", deviceType, macAddress);
82                 recalibrate = false;
83                 Configuration configuration = editConfiguration();
84                 configuration.put(CONFIG_PROPERTY_RECALIBRATE, Boolean.FALSE);
85                 updateConfiguration(configuration);
86                 break;
87             case SCAN_PARAMETERS_SET_ACK:
88                 logger.debug("Received ACK for parameters set of {} ({})", deviceType, macAddress);
89                 updateScanParameters = false;
90                 break;
91             case SCAN_PARAMETERS_SET_NACK:
92                 logger.debug("Received NACK for parameters set of {} ({})", deviceType, macAddress);
93                 break;
94             case SLEEP_SET_ACK:
95                 logger.debug("Received ACK for sleep set of {} ({})", deviceType, macAddress);
96                 updateSleepParameters = false;
97                 break;
98             default:
99                 logger.trace("Received unhandled {} message from {} ({})", message.getType(), deviceType, macAddress);
100                 break;
101         }
102
103         boolean newConfigurationPending = isConfigurationPending();
104
105         if (oldConfigurationPending != newConfigurationPending && !newConfigurationPending) {
106             Configuration newConfiguration = editConfiguration();
107             newConfiguration.put(CONFIG_PROPERTY_UPDATE_CONFIGURATION, false);
108             updateConfiguration(newConfiguration);
109         }
110
111         super.handleAcknowledgement(message);
112     }
113
114     @Override
115     public void initialize() {
116         configuration = getConfigAs(PlugwiseScanConfig.class);
117         macAddress = configuration.getMACAddress();
118         if (!isInitialized()) {
119             setUpdateCommandFlags(null, configuration);
120         }
121         super.initialize();
122     }
123
124     @Override
125     protected boolean isConfigurationPending() {
126         return updateScanParameters || updateSleepParameters || recalibrate;
127     }
128
129     @Override
130     protected void sendConfigurationUpdateCommands() {
131         logger.debug("Sending {} ({}) configuration update commands", deviceType, macAddress);
132
133         if (updateScanParameters) {
134             logger.debug("Sending command to update {} ({}) parameters", deviceType, macAddress);
135             sendCommandMessage(new ScanParametersSetRequestMessage(macAddress, configuration.getSensitivity(),
136                     configuration.isDaylightOverride(), configuration.getSwitchOffDelay()));
137         }
138         if (updateSleepParameters) {
139             logger.debug("Sending command to update {} ({}) sleep parameters", deviceType, macAddress);
140             sendCommandMessage(new SleepSetRequestMessage(macAddress, configuration.getWakeupDuration(),
141                     configuration.getWakeupInterval()));
142         }
143         if (recalibrate) {
144             logger.debug("Sending command to recalibrate {} ({}) daylight override", deviceType, macAddress);
145             sendCommandMessage(new LightCalibrationRequestMessage(macAddress));
146         }
147
148         super.sendConfigurationUpdateCommands();
149     }
150
151     private void setUpdateCommandFlags(@Nullable PlugwiseScanConfig oldConfiguration,
152             PlugwiseScanConfig newConfiguration) {
153         boolean fullUpdate = newConfiguration.isUpdateConfiguration() && !isConfigurationPending();
154         if (fullUpdate) {
155             logger.debug("Updating all configuration properties of {} ({})", deviceType, macAddress);
156         }
157
158         updateScanParameters = fullUpdate
159                 || (oldConfiguration != null && !oldConfiguration.equalScanParameters(newConfiguration));
160         if (updateScanParameters) {
161             logger.debug("Updating {} ({}) parameters when online", deviceType, macAddress);
162         }
163
164         updateSleepParameters = fullUpdate
165                 || (oldConfiguration != null && !oldConfiguration.equalSleepParameters(newConfiguration));
166         if (updateSleepParameters) {
167             logger.debug("Updating {} ({}) sleep parameters when online", deviceType, macAddress);
168         }
169
170         recalibrate = fullUpdate || newConfiguration.isRecalibrate();
171         if (recalibrate) {
172             logger.debug("Recalibrating {} ({}) daylight override when online", deviceType, macAddress);
173         }
174     }
175
176     @Override
177     protected void updateConfiguration(Configuration configuration) {
178         PlugwiseScanConfig oldConfiguration = this.configuration;
179         PlugwiseScanConfig newConfiguration = configuration.as(PlugwiseScanConfig.class);
180
181         setUpdateCommandFlags(oldConfiguration, newConfiguration);
182
183         configuration.put(CONFIG_PROPERTY_UPDATE_CONFIGURATION, isConfigurationPending());
184
185         super.updateConfiguration(configuration);
186     }
187 }