2 * Copyright (c) 2010-2021 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.deutschebahn.internal;
15 import java.util.ArrayList;
16 import java.util.List;
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;
34 * Handler for an Train-Thing in DeutscheBahn Binding.
36 * Represents an Train that arrives / departs at the station selected by the DeutscheBahnTimetable-Bridge.
38 * @author Sönke Küper - Initial contribution
41 public class DeutscheBahnTrainHandler extends BaseThingHandler {
44 * Wraps the Channel-UID with the configured {@link AttributeSelection}.
46 private final class ChannelWithConfig {
48 private final ChannelUID channelUid;
49 private final AttributeSelection attributeSelection;
52 * Creates an new ChannelWithConfig.
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.
58 public ChannelWithConfig( //
59 final ChannelUID channelUid, //
60 final AttributeSelection attributeSelection) {
61 this.channelUid = channelUid;
62 this.attributeSelection = attributeSelection;
66 * Updates the value for the channel from given {@link TimetableStop}.
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);
73 DeutscheBahnTrainHandler.this.updateState(this.channelUid, UnDefType.NULL);
78 private State determineState(final TimetableStop stop) {
79 return this.attributeSelection.getState(stop);
83 public String toString() {
84 return this.channelUid.toString();
88 private final Logger logger = LoggerFactory.getLogger(DeutscheBahnTrainHandler.class);
89 private final List<ChannelWithConfig> configuredChannels = new ArrayList<>();
92 * Creates an new {@link DeutscheBahnTrainHandler}.
94 public DeutscheBahnTrainHandler(Thing thing) {
99 public void initialize() {
100 this.updateStatus(ThingStatus.UNKNOWN);
102 if (this.getBridge() == null) {
103 this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Please select bridge");
107 this.createChannelMapping();
108 this.updateStatus(ThingStatus.ONLINE);
111 private void createChannelMapping() {
112 this.configuredChannels.clear();
113 for (Channel channel : this.getThing().getChannelsOfGroup("trip")) {
114 this.createTripChannelConfiguration(channel);
116 for (Channel channel : this.getThing().getChannelsOfGroup("arrival")) {
117 this.createEventChannelConfiguration(EventType.ARRIVAL, channel);
119 for (Channel channel : this.getThing().getChannelsOfGroup("departure")) {
120 this.createEventChannelConfiguration(EventType.DEPARTURE, channel);
122 this.logger.debug("Created {} configured channels for thing {}.", this.configuredChannels.size(),
123 this.getThing().getUID());
127 * Creates an {@link ChannelWithConfig} for an channel that represents an attribute of an
128 * {@link org.openhab.binding.deutschebahn.internal.timetable.dto.TripLabel}.
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());
138 final ChannelWithConfig channelWithConfig = new ChannelWithConfig( //
141 this.configuredChannels.add(channelWithConfig);
145 * Creates the {@link ChannelWithConfig} for an channel that represents an attribute of an
146 * {@link org.openhab.binding.deutschebahn.internal.timetable.dto.Event}.}
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());
156 final ChannelWithConfig channelWithConfig = new ChannelWithConfig( //
158 new EventAttributeSelection(eventType, attribute));
159 this.configuredChannels.add(channelWithConfig);
163 * Strips the attribute name from the channel-UID.
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;
174 * Does not handle any commands.
177 public void handleCommand(ChannelUID channelUID, Command command) {
181 * Updates the value for the channels of this train from the given {@link TimetableStop}.
183 void updateChannels(TimetableStop stop) {
184 for (ChannelWithConfig channel : this.configuredChannels) {
185 channel.updateChannelValue(stop);