2 * Copyright (c) 2010-2023 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 a Train-Thing in DeutscheBahn Binding.
36 * Represents a 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 a new ChannelWithConfig.
54 * @param channelUid The UID of the channel
55 * @param attributeSelection The attribute that provides the state that will be displayed.
57 public ChannelWithConfig( //
58 final ChannelUID channelUid, //
59 final AttributeSelection attributeSelection) {
60 this.channelUid = channelUid;
61 this.attributeSelection = attributeSelection;
65 * Updates the value for the channel from given {@link TimetableStop}.
67 public void updateChannelValue(final TimetableStop stop) {
68 final State newState = this.determineState(stop);
69 if (newState != null) {
70 DeutscheBahnTrainHandler.this.updateState(this.channelUid, newState);
72 DeutscheBahnTrainHandler.this.updateState(this.channelUid, UnDefType.NULL);
77 private State determineState(final TimetableStop stop) {
78 return this.attributeSelection.getState(stop);
82 public String toString() {
83 return this.channelUid.toString();
87 private final Logger logger = LoggerFactory.getLogger(DeutscheBahnTrainHandler.class);
88 private final List<ChannelWithConfig> configuredChannels = new ArrayList<>();
91 * Creates a new {@link DeutscheBahnTrainHandler}.
93 public DeutscheBahnTrainHandler(Thing thing) {
98 public void initialize() {
99 this.updateStatus(ThingStatus.UNKNOWN);
101 if (this.getBridge() == null) {
102 this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Please select bridge");
106 this.createChannelMapping();
107 this.updateStatus(ThingStatus.ONLINE);
110 private void createChannelMapping() {
111 this.configuredChannels.clear();
112 for (Channel channel : this.getThing().getChannelsOfGroup("trip")) {
113 this.createTripChannelConfiguration(channel);
115 for (Channel channel : this.getThing().getChannelsOfGroup("arrival")) {
116 this.createEventChannelConfiguration(EventType.ARRIVAL, channel);
118 for (Channel channel : this.getThing().getChannelsOfGroup("departure")) {
119 this.createEventChannelConfiguration(EventType.DEPARTURE, channel);
121 this.logger.debug("Created {} configured channels for thing {}.", this.configuredChannels.size(),
122 this.getThing().getUID());
126 * Creates a {@link ChannelWithConfig} for a channel that represents an attribute of an
127 * {@link org.openhab.binding.deutschebahn.internal.timetable.dto.TripLabel}.
129 private void createTripChannelConfiguration(Channel channel) {
130 final ChannelUID channelUid = channel.getUID();
131 final String attributeName = getAttributeName(channelUid);
132 final TripLabelAttribute<?, ?> attribute = TripLabelAttribute.getByChannelName(attributeName);
133 if (attribute == null) {
134 this.logger.warn("Could not find trip attribute {} of channel: {} .", attribute, channelUid.getId());
137 final ChannelWithConfig channelWithConfig = new ChannelWithConfig( //
140 this.configuredChannels.add(channelWithConfig);
144 * Creates the {@link ChannelWithConfig} for a channel that represents an attribute of an
145 * {@link org.openhab.binding.deutschebahn.internal.timetable.dto.Event}.}
147 private void createEventChannelConfiguration(EventType eventType, Channel channel) {
148 final ChannelUID channelUid = channel.getUID();
149 final String attributeName = getAttributeName(channelUid);
150 final EventAttribute<?, ?> attribute = EventAttribute.getByChannelName(attributeName, eventType);
151 if (attribute == null) {
152 this.logger.warn("Could not find event attribute {} of channel: {} .", attribute, channelUid.getId());
155 final ChannelWithConfig channelWithConfig = new ChannelWithConfig( //
157 new EventAttributeSelection(eventType, attribute));
158 this.configuredChannels.add(channelWithConfig);
162 * Strips the attribute name from the channel-UID.
164 private static String getAttributeName(ChannelUID channelUid) {
165 final String channelId = channelUid.getId();
166 int hashIndex = channelId.indexOf("#");
167 assert hashIndex > 0;
168 return channelId.substring(hashIndex + 1);
172 * Does not handle any commands.
175 public void handleCommand(ChannelUID channelUID, Command command) {
179 * Updates the value for the channels of this train from the given {@link TimetableStop}.
181 void updateChannels(TimetableStop stop) {
182 for (ChannelWithConfig channel : this.configuredChannels) {
183 channel.updateChannelValue(stop);