]> git.basschouten.com Git - openhab-addons.git/blob
d8d681794cf55d1730bf3cda9d275bdd78c79e9f
[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.avmfritz.internal.handler;
14
15 import static org.openhab.binding.avmfritz.internal.AVMFritzBindingConstants.*;
16
17 import java.time.Instant;
18 import java.time.ZoneId;
19 import java.time.ZonedDateTime;
20 import java.util.List;
21 import java.util.Optional;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.binding.avmfritz.internal.dto.AVMFritzBaseModel;
26 import org.openhab.binding.avmfritz.internal.dto.ButtonModel;
27 import org.openhab.binding.avmfritz.internal.dto.DeviceModel;
28 import org.openhab.core.library.types.DateTimeType;
29 import org.openhab.core.thing.Channel;
30 import org.openhab.core.thing.ChannelUID;
31 import org.openhab.core.thing.CommonTriggerEvents;
32 import org.openhab.core.thing.Thing;
33 import org.openhab.core.thing.ThingUID;
34 import org.openhab.core.types.UnDefType;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 /**
39  * Handler for a FRITZ! buttons. Handles commands, which are sent to one of the channels.
40  *
41  * @author Christoph Weitkamp - Initial contribution
42  */
43 @NonNullByDefault
44 public class AVMFritzButtonHandler extends DeviceHandler {
45
46     private static final String TOP_RIGHT_SUFFIX = "-1";
47     private static final String BOTTOM_RIGHT_SUFFIX = "-3";
48     private static final String BOTTOM_LEFT_SUFFIX = "-5";
49     private static final String TOP_LEFT_SUFFIX = "-7";
50
51     private final Logger logger = LoggerFactory.getLogger(AVMFritzButtonHandler.class);
52     /**
53      * keeps track of the last timestamp for handling trigger events
54      */
55     private Instant lastTimestamp;
56
57     /**
58      * Constructor
59      *
60      * @param thing Thing object representing a FRITZ! button
61      */
62     public AVMFritzButtonHandler(Thing thing) {
63         super(thing);
64         lastTimestamp = Instant.now();
65     }
66
67     @Override
68     public void onDeviceUpdated(ThingUID thingUID, AVMFritzBaseModel device) {
69         if (thing.getUID().equals(thingUID)) {
70             super.onDeviceUpdated(thingUID, device);
71
72             if (device instanceof DeviceModel) {
73                 DeviceModel deviceModel = (DeviceModel) device;
74                 if (deviceModel.isHANFUNButton()) {
75                     updateHANFUNButton(deviceModel.getButtons());
76                 }
77                 if (deviceModel.isButton()) {
78                     if (DECT400_THING_TYPE.equals(thing.getThingTypeUID())) {
79                         updateShortLongPressButton(deviceModel.getButtons());
80                     } else if (DECT440_THING_TYPE.equals(thing.getThingTypeUID())) {
81                         updateButtons(deviceModel.getButtons());
82                     }
83                     updateBattery(deviceModel);
84                 }
85             }
86         }
87     }
88
89     private void updateShortLongPressButton(List<ButtonModel> buttons) {
90         ButtonModel shortPressButton = buttons.size() > 0 ? buttons.get(0) : null;
91         ButtonModel longPressButton = buttons.size() > 1 ? buttons.get(1) : null;
92         ButtonModel lastPressedButton = shortPressButton != null && (longPressButton == null
93                 || shortPressButton.getLastpressedtimestamp() > longPressButton.getLastpressedtimestamp())
94                         ? shortPressButton
95                         : longPressButton;
96         if (lastPressedButton != null) {
97             updateButton(lastPressedButton,
98                     lastPressedButton.equals(shortPressButton) ? CommonTriggerEvents.SHORT_PRESSED
99                             : CommonTriggerEvents.LONG_PRESSED);
100         }
101     }
102
103     private void updateButtons(List<ButtonModel> buttons) {
104         Optional<ButtonModel> topLeft = buttons.stream().filter(b -> b.getIdentifier().endsWith(TOP_LEFT_SUFFIX))
105                 .findFirst();
106         if (topLeft.isPresent()) {
107             updateButton(topLeft.get(), CommonTriggerEvents.PRESSED, CHANNEL_GROUP_TOP_LEFT);
108         }
109         Optional<ButtonModel> bottomLeft = buttons.stream().filter(b -> b.getIdentifier().endsWith(BOTTOM_LEFT_SUFFIX))
110                 .findFirst();
111         if (bottomLeft.isPresent()) {
112             updateButton(bottomLeft.get(), CommonTriggerEvents.PRESSED, CHANNEL_GROUP_BOTTOM_LEFT);
113         }
114         Optional<ButtonModel> topRight = buttons.stream().filter(b -> b.getIdentifier().endsWith(TOP_RIGHT_SUFFIX))
115                 .findFirst();
116         if (topRight.isPresent()) {
117             updateButton(topRight.get(), CommonTriggerEvents.PRESSED, CHANNEL_GROUP_TOP_RIGHT);
118         }
119         Optional<ButtonModel> bottomRight = buttons.stream()
120                 .filter(b -> b.getIdentifier().endsWith(BOTTOM_RIGHT_SUFFIX)).findFirst();
121         if (bottomRight.isPresent()) {
122             updateButton(bottomRight.get(), CommonTriggerEvents.PRESSED, CHANNEL_GROUP_BOTTOM_RIGHT);
123         }
124     }
125
126     private void updateHANFUNButton(List<ButtonModel> buttons) {
127         if (!buttons.isEmpty()) {
128             updateButton(buttons.get(0), CommonTriggerEvents.PRESSED);
129         }
130     }
131
132     private void updateButton(ButtonModel buttonModel, String event) {
133         updateButton(buttonModel, event, null);
134     }
135
136     private void updateButton(ButtonModel buttonModel, String event, @Nullable String channelGroupId) {
137         int lastPressedTimestamp = buttonModel.getLastpressedtimestamp();
138         if (lastPressedTimestamp == 0) {
139             updateThingChannelState(
140                     channelGroupId == null ? CHANNEL_LAST_CHANGE
141                             : channelGroupId + ChannelUID.CHANNEL_GROUP_SEPARATOR + CHANNEL_LAST_CHANGE,
142                     UnDefType.UNDEF);
143         } else {
144             ZonedDateTime timestamp = ZonedDateTime.ofInstant(Instant.ofEpochSecond(lastPressedTimestamp),
145                     ZoneId.systemDefault());
146             Instant then = timestamp.toInstant();
147             // Avoid dispatching events if "lastpressedtimestamp" is older than now "lastTimestamp" (e.g. during
148             // restart)
149             if (then.isAfter(lastTimestamp)) {
150                 lastTimestamp = then;
151                 triggerThingChannel(channelGroupId == null ? CHANNEL_PRESS
152                         : channelGroupId + ChannelUID.CHANNEL_GROUP_SEPARATOR + CHANNEL_PRESS, event);
153             }
154             updateThingChannelState(
155                     channelGroupId == null ? CHANNEL_LAST_CHANGE
156                             : channelGroupId + ChannelUID.CHANNEL_GROUP_SEPARATOR + CHANNEL_LAST_CHANGE,
157                     new DateTimeType(timestamp));
158         }
159     }
160
161     /**
162      * Triggers thing channels.
163      *
164      * @param channelId ID of the channel to be triggered.
165      * @param event Event to emit
166      */
167     private void triggerThingChannel(String channelId, String event) {
168         Channel channel = thing.getChannel(channelId);
169         if (channel != null) {
170             triggerChannel(channel.getUID(), event);
171         } else {
172             logger.debug("Channel '{}' in thing '{}' does not exist.", channelId, thing.getUID());
173         }
174     }
175 }