]> git.basschouten.com Git - openhab-addons.git/blob
8bb308c60464916aeefa50b44ee4072a54dc6874
[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.digiplex.internal.handler;
14
15 import static org.openhab.binding.digiplex.internal.DigiplexBindingConstants.*;
16 import static org.openhab.binding.digiplex.internal.handler.TypeUtils.openClosedFromBoolean;
17
18 import java.time.ZonedDateTime;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.binding.digiplex.internal.DigiplexBindingConstants;
23 import org.openhab.binding.digiplex.internal.communication.DigiplexMessageHandler;
24 import org.openhab.binding.digiplex.internal.communication.DigiplexRequest;
25 import org.openhab.binding.digiplex.internal.communication.ZoneStatusRequest;
26 import org.openhab.binding.digiplex.internal.communication.ZoneStatusResponse;
27 import org.openhab.binding.digiplex.internal.communication.events.ZoneEvent;
28 import org.openhab.binding.digiplex.internal.communication.events.ZoneEventType;
29 import org.openhab.binding.digiplex.internal.communication.events.ZoneStatusEvent;
30 import org.openhab.core.library.types.DateTimeType;
31 import org.openhab.core.library.types.OpenClosedType;
32 import org.openhab.core.library.types.StringType;
33 import org.openhab.core.thing.Bridge;
34 import org.openhab.core.thing.ChannelUID;
35 import org.openhab.core.thing.Thing;
36 import org.openhab.core.thing.ThingStatus;
37 import org.openhab.core.thing.ThingStatusDetail;
38 import org.openhab.core.thing.ThingStatusInfo;
39 import org.openhab.core.thing.binding.BaseThingHandler;
40 import org.openhab.core.types.Command;
41 import org.openhab.core.types.RefreshType;
42 import org.openhab.core.types.State;
43 import org.openhab.core.types.UnDefType;
44
45 /**
46  * The {@link DigiplexZoneHandler} is responsible for handling commands, which are
47  * sent to one of the channels.
48  *
49  * @author Robert Michalak - Initial contribution
50  */
51 @NonNullByDefault
52 public class DigiplexZoneHandler extends BaseThingHandler {
53
54     private @Nullable DigiplexBridgeHandler bridgeHandler;
55     private DigiplexZoneMessageHandler messageHandler = new DigiplexZoneMessageHandler();
56     private int zoneNo;
57     private int areaNo = 0; // not known at the beginning (protocol limitation)
58     private OpenClosedType status = OpenClosedType.CLOSED;
59     private StringType extendedStatus = new StringType("CLOSED");
60     private OpenClosedType alarm = OpenClosedType.CLOSED;
61     private OpenClosedType fireAlarm = OpenClosedType.CLOSED;
62     private OpenClosedType supervisionLost = OpenClosedType.CLOSED;
63     private OpenClosedType lowBattery = OpenClosedType.CLOSED;
64     private State lastTriggered = UnDefType.NULL;
65
66     public DigiplexZoneHandler(Thing thing) {
67         super(thing);
68     }
69
70     @Override
71     public void handleCommand(ChannelUID channelUID, Command command) {
72         switch (channelUID.getId()) {
73             case ZONE_STATUS:
74                 if (command == RefreshType.REFRESH) {
75                     updateState(ZONE_STATUS, status);
76                 }
77                 break;
78             case ZONE_EXTENDED_STATUS:
79                 if (command == RefreshType.REFRESH) {
80                     updateState(ZONE_EXTENDED_STATUS, extendedStatus);
81                 }
82                 break;
83             case ZONE_ALARM:
84                 if (command == RefreshType.REFRESH) {
85                     updateState(ZONE_ALARM, alarm);
86                 }
87                 break;
88             case ZONE_FIRE_ALARM:
89                 if (command == RefreshType.REFRESH) {
90                     updateState(ZONE_FIRE_ALARM, fireAlarm);
91                 }
92                 break;
93             case ZONE_SUPERVISION_LOST:
94                 if (command == RefreshType.REFRESH) {
95                     updateState(ZONE_SUPERVISION_LOST, supervisionLost);
96                 }
97                 break;
98             case ZONE_LOW_BATTERY:
99                 if (command == RefreshType.REFRESH) {
100                     updateState(ZONE_LOW_BATTERY, lowBattery);
101                 }
102                 break;
103             case ZONE_LAST_TRIGGERED:
104                 if (command == RefreshType.REFRESH) {
105                     if (lastTriggered != UnDefType.NULL) {
106                         updateState(ZONE_LAST_TRIGGERED, lastTriggered);
107                     }
108                 }
109                 break;
110         }
111     }
112
113     @SuppressWarnings("null")
114     @Override
115     public void initialize() {
116         Bridge bridge = getBridge();
117         if (bridge == null) {
118             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
119             return;
120         }
121         this.bridgeHandler = (DigiplexBridgeHandler) bridge.getHandler();
122
123         String nodeParm = getThing().getProperties().get(DigiplexBindingConstants.PROPERTY_ZONE_NO);
124         zoneNo = Integer.parseInt(nodeParm);
125         String areaParm = getThing().getProperties().get(DigiplexBindingConstants.PROPERTY_AREA_NO);
126         if (areaParm != null) {
127             areaNo = Integer.parseInt(areaParm);
128         }
129
130         bridgeHandler.registerMessageHandler(messageHandler);
131
132         DigiplexRequest request = new ZoneStatusRequest(zoneNo);
133         bridgeHandler.sendRequest(request);
134
135         updateStatus(ThingStatus.ONLINE);
136     }
137
138     private void updateChannels(boolean allChannels) {
139         updateState(ZONE_STATUS, status);
140         updateState(ZONE_EXTENDED_STATUS, extendedStatus);
141         if (lastTriggered != UnDefType.NULL) {
142             updateState(ZONE_LAST_TRIGGERED, lastTriggered);
143         }
144         if (allChannels) {
145             updateState(ZONE_ALARM, alarm);
146             updateState(ZONE_FIRE_ALARM, fireAlarm);
147             updateState(ZONE_SUPERVISION_LOST, supervisionLost);
148             updateState(ZONE_LOW_BATTERY, lowBattery);
149         }
150     }
151
152     @SuppressWarnings("null")
153     @Override
154     public void handleRemoval() {
155         if (messageHandler != null) {
156             bridgeHandler.unregisterMessageHandler(messageHandler);
157         }
158         super.handleRemoval();
159     }
160
161     @SuppressWarnings("null")
162     @Override
163     public void bridgeStatusChanged(ThingStatusInfo thingStatusInfo) {
164         if (thingStatusInfo.getStatus() == ThingStatus.OFFLINE) {
165             updateStatus(ThingStatus.OFFLINE, thingStatusInfo.getStatusDetail());
166         } else if (thingStatusInfo.getStatus() == ThingStatus.ONLINE) {
167             updateStatus(ThingStatus.ONLINE);
168             DigiplexRequest request = new ZoneStatusRequest(zoneNo);
169             bridgeHandler.sendRequest(request);
170         }
171     }
172
173     private void updateAreaNo(int areaNo) {
174         if (this.areaNo == 0) {
175             this.areaNo = areaNo;
176             getThing().setProperty(DigiplexBindingConstants.PROPERTY_AREA_NO, Integer.toString(areaNo));
177         }
178     }
179
180     private class DigiplexZoneMessageHandler implements DigiplexMessageHandler {
181
182         @Override
183         public void handleZoneStatusResponse(ZoneStatusResponse response) {
184             if (response.zoneNo == DigiplexZoneHandler.this.zoneNo) {
185                 status = response.status.toOpenClosedType();
186                 extendedStatus = new StringType(response.status.toString());
187                 alarm = openClosedFromBoolean(response.alarm);
188                 fireAlarm = openClosedFromBoolean(response.fireAlarm);
189                 supervisionLost = openClosedFromBoolean(response.supervisionLost);
190                 lowBattery = openClosedFromBoolean(response.lowBattery);
191                 updateChannels(true);
192             }
193         }
194
195         @Override
196         public void handleZoneStatusEvent(ZoneStatusEvent event) {
197             if (event.getZoneNo() == DigiplexZoneHandler.this.zoneNo) {
198                 status = event.getStatus().toOpenClosedType();
199                 extendedStatus = new StringType(event.getStatus().toString());
200                 lastTriggered = new DateTimeType(ZonedDateTime.now());
201                 updateChannels(false);
202                 updateAreaNo(event.getAreaNo());
203             }
204         }
205
206         @Override
207         public void handleZoneEvent(ZoneEvent event) {
208             if (event.getZoneNo() == DigiplexZoneHandler.this.zoneNo) {
209                 switch (event.getType()) {
210                     case ALARM:
211                     case ALARM_RESTORE:
212                         alarm = openClosedFromBoolean(event.getType() == ZoneEventType.ALARM);
213                         updateState(ZONE_ALARM, alarm);
214                         break;
215                     case FIRE_ALARM:
216                     case FIRE_ALARM_RESTORE:
217                         fireAlarm = openClosedFromBoolean(event.getType() == ZoneEventType.FIRE_ALARM);
218                         updateState(ZONE_FIRE_ALARM, fireAlarm);
219                         break;
220                     case LOW_BATTERY:
221                     case LOW_BATTERY_RESTORE:
222                         lowBattery = openClosedFromBoolean(event.getType() == ZoneEventType.LOW_BATTERY);
223                         updateState(ZONE_LOW_BATTERY, lowBattery);
224                         break;
225                     case SUPERVISION_TROUBLE:
226                     case SUPERVISION_TROUBLE_RESTORE:
227                         supervisionLost = openClosedFromBoolean(event.getType() == ZoneEventType.SUPERVISION_TROUBLE);
228                         updateState(ZONE_SUPERVISION_LOST, supervisionLost);
229                         break;
230                     default:
231                         break;
232
233                 }
234                 updateAreaNo(event.getAreaNo());
235             }
236         }
237     }
238 }