]> git.basschouten.com Git - openhab-addons.git/blob
4f715405a1238b14aeedae3c352239b0c0b33696
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.phc.internal.handler;
14
15 import static org.openhab.binding.phc.internal.PHCBindingConstants.*;
16
17 import java.math.BigDecimal;
18 import java.util.HashMap;
19 import java.util.Map;
20 import java.util.Map.Entry;
21
22 import org.openhab.core.config.core.Configuration;
23 import org.openhab.core.library.types.DecimalType;
24 import org.openhab.core.library.types.OnOffType;
25 import org.openhab.core.library.types.PercentType;
26 import org.openhab.core.library.types.StopMoveType;
27 import org.openhab.core.library.types.UpDownType;
28 import org.openhab.core.thing.Bridge;
29 import org.openhab.core.thing.ChannelUID;
30 import org.openhab.core.thing.Thing;
31 import org.openhab.core.thing.ThingStatus;
32 import org.openhab.core.thing.ThingStatusDetail;
33 import org.openhab.core.thing.binding.BaseThingHandler;
34 import org.openhab.core.thing.binding.ThingHandler;
35 import org.openhab.core.types.Command;
36 import org.openhab.core.types.State;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 /**
41  * The {@link PHCHandler} is responsible for handling commands, which are
42  * sent to one of the channels.
43  *
44  * @author Jonas Hohaus - Initial contribution
45  *
46  */
47 public class PHCHandler extends BaseThingHandler {
48
49     private final Logger logger = LoggerFactory.getLogger(PHCHandler.class);
50
51     private String moduleAddress; // like DIP switches
52     private byte module;
53     private final short[] times = new short[4];
54     private final Map<String, State> channelState = new HashMap<>();
55     private PHCBridgeHandler bridgeHandler;
56
57     public PHCHandler(Thing thing) {
58         super(thing);
59     }
60
61     @Override
62     public void initialize() {
63         moduleAddress = (String) getConfig().get(ADDRESS);
64
65         if (getPHCBridgeHandler() == null) {
66             return;
67         }
68
69         module = Byte.parseByte(new StringBuilder(moduleAddress).reverse().toString(), 2);
70
71         if (getThing().getThingTypeUID().equals(THING_TYPE_AM) || getThing().getThingTypeUID().equals(THING_TYPE_JRM)) {
72             module |= 0x40;
73         } else if (getThing().getThingTypeUID().equals(THING_TYPE_DIM)) {
74             module |= 0xA0;
75         }
76         getPHCBridgeHandler().addModule(module);
77
78         if (getThing().getThingTypeUID().equals(THING_TYPE_JRM)) {
79             times[0] = (short) (((BigDecimal) getConfig().get(UP_DOWN_TIME_1)).shortValue() * 10);
80             times[1] = (short) (((BigDecimal) getConfig().get(UP_DOWN_TIME_2)).shortValue() * 10);
81             times[2] = (short) (((BigDecimal) getConfig().get(UP_DOWN_TIME_3)).shortValue() * 10);
82             times[3] = (short) (((BigDecimal) getConfig().get(UP_DOWN_TIME_4)).shortValue() * 10);
83
84         } else if (getThing().getThingTypeUID().equals(THING_TYPE_DIM)) {
85             times[0] = (((BigDecimal) getConfig().get(DIM_TIME_1)).shortValue());
86             times[1] = (((BigDecimal) getConfig().get(DIM_TIME_2)).shortValue());
87         }
88
89         Bridge bridge = getBridge();
90         if (bridge != null && bridge.getStatus() == ThingStatus.ONLINE) {
91             updateStatus(ThingStatus.ONLINE);
92         } else {
93             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
94         }
95     }
96
97     public void handleIncoming(String channelId, OnOffType state) {
98         if (logger.isDebugEnabled()) {
99             logger.debug("EM command: {}, last: {}, in: {}", channelId, channelState.get(channelId), state);
100         }
101
102         if (!channelState.containsKey(channelId) || !channelState.get(channelId).equals(state)) {
103             postCommand(channelId, state);
104             channelState.put(channelId, state);
105         }
106     }
107
108     @Override
109     public void handleCommand(ChannelUID channelUID, Command command) {
110         final String groupId = channelUID.getGroupId();
111         if (getThing().getStatus().equals(ThingStatus.ONLINE)) {
112             if ((CHANNELS_JRM.equals(groupId) && (command instanceof UpDownType || command instanceof StopMoveType))
113                     || (CHANNELS_DIM.equals(groupId)
114                             && (command instanceof OnOffType || command instanceof PercentType))) {
115                 getPHCBridgeHandler().send(groupId, module & 0x1F, channelUID.getIdWithoutGroup(), command,
116                         times[Integer.parseInt(channelUID.getIdWithoutGroup())]);
117             } else if ((CHANNELS_AM.equals(groupId) || CHANNELS_EM_LED.equals(groupId))
118                     && command instanceof OnOffType) {
119                 getPHCBridgeHandler().send(groupId, module & 0x1F, channelUID.getIdWithoutGroup(), command, (short) 0);
120             }
121
122             logger.debug("send command: {}, {}", channelUID, command);
123         } else {
124             logger.info("The Thing {} is offline.", getThing().getUID());
125         }
126     }
127
128     @Override
129     public void handleUpdate(ChannelUID channelUID, State newState) {
130         if (CHANNELS_JRM_TIME.equals(channelUID.getGroupId())) {
131             times[Integer
132                     .parseInt(channelUID.getIdWithoutGroup())] = (short) (((DecimalType) newState).floatValue() * 10);
133         }
134     }
135
136     @Override
137     public void handleConfigurationUpdate(Map<String, Object> configurationParameters) {
138         if (isInitialized()) { // prevents change of address
139             validateConfigurationParameters(configurationParameters);
140
141             Configuration configuration = editConfiguration();
142             for (Entry<String, Object> configurationParmeter : configurationParameters.entrySet()) {
143                 if (!configurationParmeter.getKey().equals(ADDRESS)) {
144                     configuration.put(configurationParmeter.getKey(), configurationParmeter.getValue());
145                 } else {
146                     configuration.put(configurationParmeter.getKey(), moduleAddress);
147                 }
148             }
149
150             // persist new configuration and reinitialize handler
151             dispose();
152             updateConfiguration(configuration);
153             initialize();
154         } else {
155             super.handleConfigurationUpdate(configurationParameters);
156         }
157     }
158
159     private PHCBridgeHandler getPHCBridgeHandler() {
160         if (bridgeHandler == null) {
161             Bridge bridge = getBridge();
162             if (bridge == null) {
163                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_PENDING,
164                         "The Thing requires to select a Bridge");
165                 return null;
166             }
167
168             ThingHandler handler = bridge.getHandler();
169             if (handler instanceof PHCBridgeHandler) {
170                 bridgeHandler = (PHCBridgeHandler) handler;
171             } else {
172                 logger.debug("No available bridge handler for {}.", bridge.getUID());
173
174                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_MISSING_ERROR,
175                         "No available bridge handler.");
176
177                 return null;
178             }
179         }
180
181         return bridgeHandler;
182     }
183 }