]> git.basschouten.com Git - openhab-addons.git/blob
e04b95ce48c8f19f05103e7d5513d6ee7213b398
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.deutschebahn.internal;
14
15 import java.util.ArrayList;
16 import java.util.List;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.openhab.binding.deutschebahn.internal.timetable.dto.TimetableStop;
21 import org.openhab.core.thing.Channel;
22 import org.openhab.core.thing.ChannelUID;
23 import org.openhab.core.thing.Thing;
24 import org.openhab.core.thing.ThingStatus;
25 import org.openhab.core.thing.ThingStatusDetail;
26 import org.openhab.core.thing.binding.BaseThingHandler;
27 import org.openhab.core.types.Command;
28 import org.openhab.core.types.State;
29 import org.openhab.core.types.UnDefType;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 /**
34  * Handler for an Train-Thing in DeutscheBahn Binding.
35  *
36  * Represents an Train that arrives / departs at the station selected by the DeutscheBahnTimetable-Bridge.
37  *
38  * @author Sönke Küper - Initial contribution
39  */
40 @NonNullByDefault
41 public class DeutscheBahnTrainHandler extends BaseThingHandler {
42
43     /**
44      * Wraps the Channel-UID with the configured {@link AttributeSelection}.
45      */
46     private final class ChannelWithConfig {
47
48         private final ChannelUID channelUid;
49         private final AttributeSelection attributeSelection;
50
51         /**
52          * Creates an new ChannelWithConfig.
53          * 
54          * @param channelUid The UID of the channel
55          * @param configuration Configuration for the given channel.
56          * @param attributeSelection The attribute that provides the state that will be displayed.
57          */
58         public ChannelWithConfig( //
59                 final ChannelUID channelUid, //
60                 final AttributeSelection attributeSelection) {
61             this.channelUid = channelUid;
62             this.attributeSelection = attributeSelection;
63         }
64
65         /**
66          * Updates the value for the channel from given {@link TimetableStop}.
67          */
68         public void updateChannelValue(final TimetableStop stop) {
69             final State newState = this.determineState(stop);
70             if (newState != null) {
71                 DeutscheBahnTrainHandler.this.updateState(this.channelUid, newState);
72             } else {
73                 DeutscheBahnTrainHandler.this.updateState(this.channelUid, UnDefType.NULL);
74             }
75         }
76
77         @Nullable
78         private State determineState(final TimetableStop stop) {
79             return this.attributeSelection.getState(stop);
80         }
81
82         @Override
83         public String toString() {
84             return this.channelUid.toString();
85         }
86     }
87
88     private final Logger logger = LoggerFactory.getLogger(DeutscheBahnTrainHandler.class);
89     private final List<ChannelWithConfig> configuredChannels = new ArrayList<>();
90
91     /**
92      * Creates an new {@link DeutscheBahnTrainHandler}.
93      */
94     public DeutscheBahnTrainHandler(Thing thing) {
95         super(thing);
96     }
97
98     @Override
99     public void initialize() {
100         this.updateStatus(ThingStatus.UNKNOWN);
101
102         if (this.getBridge() == null) {
103             this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Please select bridge");
104             return;
105         }
106
107         this.createChannelMapping();
108         this.updateStatus(ThingStatus.ONLINE);
109     }
110
111     private void createChannelMapping() {
112         this.configuredChannels.clear();
113         for (Channel channel : this.getThing().getChannelsOfGroup("trip")) {
114             this.createTripChannelConfiguration(channel);
115         }
116         for (Channel channel : this.getThing().getChannelsOfGroup("arrival")) {
117             this.createEventChannelConfiguration(EventType.ARRIVAL, channel);
118         }
119         for (Channel channel : this.getThing().getChannelsOfGroup("departure")) {
120             this.createEventChannelConfiguration(EventType.DEPARTURE, channel);
121         }
122         this.logger.debug("Created {} configured channels for thing {}.", this.configuredChannels.size(),
123                 this.getThing().getUID());
124     }
125
126     /**
127      * Creates an {@link ChannelWithConfig} for an channel that represents an attribute of an
128      * {@link org.openhab.binding.deutschebahn.internal.timetable.dto.TripLabel}.
129      */
130     private void createTripChannelConfiguration(Channel channel) {
131         final ChannelUID channelUid = channel.getUID();
132         final String attributeName = getAttributeName(channelUid);
133         final TripLabelAttribute<?, ?> attribute = TripLabelAttribute.getByChannelName(attributeName);
134         if (attribute == null) {
135             this.logger.warn("Could not find trip attribute {} of channel: {} .", attribute, channelUid.getId());
136             return;
137         }
138         final ChannelWithConfig channelWithConfig = new ChannelWithConfig( //
139                 channelUid, //
140                 attribute);
141         this.configuredChannels.add(channelWithConfig);
142     }
143
144     /**
145      * Creates the {@link ChannelWithConfig} for an channel that represents an attribute of an
146      * {@link org.openhab.binding.deutschebahn.internal.timetable.dto.Event}.}
147      */
148     private void createEventChannelConfiguration(EventType eventType, Channel channel) {
149         final ChannelUID channelUid = channel.getUID();
150         final String attributeName = getAttributeName(channelUid);
151         final EventAttribute<?, ?> attribute = EventAttribute.getByChannelName(attributeName, eventType);
152         if (attribute == null) {
153             this.logger.warn("Could not find event attribute {} of channel: {} .", attribute, channelUid.getId());
154             return;
155         }
156         final ChannelWithConfig channelWithConfig = new ChannelWithConfig( //
157                 channelUid, //
158                 new EventAttributeSelection(eventType, attribute));
159         this.configuredChannels.add(channelWithConfig);
160     }
161
162     /**
163      * Strips the attribute name from the channel-UID.
164      */
165     private static String getAttributeName(ChannelUID channelUid) {
166         final String channelId = channelUid.getId();
167         int hashIndex = channelId.indexOf("#");
168         assert hashIndex > 0;
169         final String attributeName = channelId.substring(hashIndex + 1);
170         return attributeName;
171     }
172
173     /**
174      * Does not handle any commands.
175      */
176     @Override
177     public void handleCommand(ChannelUID channelUID, Command command) {
178     }
179
180     /**
181      * Updates the value for the channels of this train from the given {@link TimetableStop}.
182      */
183     void updateChannels(TimetableStop stop) {
184         for (ChannelWithConfig channel : this.configuredChannels) {
185             channel.updateChannelValue(stop);
186         }
187     }
188 }