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.tankerkoenig.internal.handler;
15 import static org.openhab.binding.tankerkoenig.internal.TankerkoenigBindingConstants.*;
17 import java.util.concurrent.ScheduledFuture;
18 import java.util.concurrent.TimeUnit;
19 import java.util.regex.Pattern;
21 import org.openhab.binding.tankerkoenig.internal.TankerkoenigBindingConstants;
22 import org.openhab.binding.tankerkoenig.internal.data.TankerkoenigService;
23 import org.openhab.binding.tankerkoenig.internal.dto.LittleStation;
24 import org.openhab.binding.tankerkoenig.internal.dto.OpeningTimes;
25 import org.openhab.binding.tankerkoenig.internal.dto.TankerkoenigDetailResult;
26 import org.openhab.core.config.core.Configuration;
27 import org.openhab.core.library.types.DecimalType;
28 import org.openhab.core.library.types.OpenClosedType;
29 import org.openhab.core.thing.Bridge;
30 import org.openhab.core.thing.ChannelUID;
31 import org.openhab.core.thing.Thing;
32 import org.openhab.core.thing.ThingStatus;
33 import org.openhab.core.thing.ThingStatusDetail;
34 import org.openhab.core.thing.ThingStatusInfo;
35 import org.openhab.core.thing.binding.BaseThingHandler;
36 import org.openhab.core.types.Command;
37 import org.openhab.core.types.UnDefType;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
42 * The {@link StationHandler} is responsible for handling commands, which are
43 * sent to one of the channels.
45 * @author Dennis Dollinger - Initial contribution
46 * @author Jürgen Baginski - Initial contribution
48 public class StationHandler extends BaseThingHandler {
49 private static final Pattern IS_NUMERIC_PATTERN = Pattern.compile("\\d+(\\.\\d+)?");
51 private final Logger logger = LoggerFactory.getLogger(StationHandler.class);
53 private String apiKey;
54 private boolean modeOpeningTime;
55 private String locationID;
56 private OpeningTimes openingTimes;
57 private String userAgent;
58 private final TankerkoenigService service = new TankerkoenigService();
59 private TankerkoenigDetailResult result;
61 private ScheduledFuture<?> pollingJob;
63 public StationHandler(Thing thing) {
68 public void handleCommand(ChannelUID channelUID, Command command) {
73 public void initialize() {
74 logger.debug("Initializing Tankerkoenig handler '{}'", getThing().getUID());
75 Configuration config = getThing().getConfiguration();
76 setLocationID((String) config.get(TankerkoenigBindingConstants.CONFIG_LOCATION_ID));
77 setApiKey((String) config.get(TankerkoenigBindingConstants.CONFIG_API_KEY));
78 Bridge b = getBridge();
80 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE,
81 "Could not find bridge (tankerkoenig config). Did you select one?");
84 WebserviceHandler handler = (WebserviceHandler) b.getHandler();
85 userAgent = handler.getUserAgent();
86 setApiKey(handler.getApiKey());
87 setModeOpeningTime(handler.isModeOpeningTime());
88 if (b.getThings().size() > 10) {
89 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
90 "The limitation of station things for one tankerkoenig webservice (the bridge) is limited to 10.");
93 updateStatus(ThingStatus.UNKNOWN);
95 pollingJob = scheduler.scheduleWithFixedDelay(() -> {
97 logger.debug("Try to refresh detail data");
99 } catch (RuntimeException r) {
100 logger.debug("Caught exception in ScheduledExecutorService of TankerkoenigHandler", r);
101 // no status change, since in case of error in here,
102 // the old values for opening time will be continue to be used
104 }, 15, 86400, TimeUnit.SECONDS);// 24*60*60 = 86400, a whole day in seconds!
105 logger.debug("Refresh job scheduled to run every 24 hours for '{}'", getThing().getUID());
109 public void dispose() {
110 if (pollingJob != null) {
111 pollingJob.cancel(true);
117 public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
118 logger.debug("Bridge Status updated to {} for device: {}", bridgeStatusInfo.getStatus(), getThing().getUID());
119 if (bridgeStatusInfo.getStatus() != ThingStatus.ONLINE) {
120 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, bridgeStatusInfo.getDescription());
125 * Updates the channels of a station item
129 public void updateData(LittleStation station) {
130 logger.debug("Update Tankerkoenig data '{}'", getThing().getUID());
131 if (station.isOpen()) {
132 logger.debug("Checked Station is open! '{}'", getThing().getUID());
133 updateState(CHANNEL_STATION_OPEN, OpenClosedType.OPEN);
134 if (station.getDiesel() != null) {
135 if (IS_NUMERIC_PATTERN.matcher(station.getDiesel()).matches()) {
136 DecimalType diesel = new DecimalType(station.getDiesel());
137 updateState(CHANNEL_DIESEL, diesel);
139 updateState(CHANNEL_DIESEL, UnDefType.UNDEF);
142 updateState(CHANNEL_DIESEL, UnDefType.UNDEF);
144 if (station.getE10() != null) {
145 if (IS_NUMERIC_PATTERN.matcher(station.getE10()).matches()) {
146 DecimalType e10 = new DecimalType(station.getE10());
147 updateState(CHANNEL_E10, e10);
149 updateState(CHANNEL_E10, UnDefType.UNDEF);
152 updateState(CHANNEL_E10, UnDefType.UNDEF);
154 if (station.getE10() != null) {
155 if (IS_NUMERIC_PATTERN.matcher(station.getE5()).matches()) {
156 DecimalType e5 = new DecimalType(station.getE5());
157 updateState(CHANNEL_E5, e5);
159 updateState(CHANNEL_E5, UnDefType.UNDEF);
162 updateState(CHANNEL_E5, UnDefType.UNDEF);
165 logger.debug("Checked Station is closed!");
166 updateState(CHANNEL_STATION_OPEN, OpenClosedType.CLOSED);
168 updateStatus(ThingStatus.ONLINE);
172 * Updates the detail-data from tankerkoenig api, actually only the opening times are used.
174 public void updateDetailData() {
175 result = service.getStationDetailData(getApiKey(), locationID, userAgent);
178 setOpeningTimes(result.getOpeningTimes());
179 LittleStation s = result.getLittleStation();
181 logger.debug("Station with id {} is not updated!", getLocationID());
185 updateStatus(ThingStatus.ONLINE);
186 WebserviceHandler handler = (WebserviceHandler) getBridge().getHandler();
187 handler.updateStatus(ThingStatus.ONLINE);
188 logger.debug("updateDetailData openingTimes: {}", openingTimes);
190 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, result.getMessage());
194 public String getLocationID() {
198 public void setLocationID(String locationID) {
199 this.locationID = locationID;
202 public String getApiKey() {
206 public void setApiKey(String apiKey) {
207 this.apiKey = apiKey;
210 public boolean isModeOpeningTime() {
211 return modeOpeningTime;
214 public void setModeOpeningTime(boolean modeOpeningTime) {
215 this.modeOpeningTime = modeOpeningTime;
218 public OpeningTimes getOpeningTimes() {
222 public void setOpeningTimes(OpeningTimes openingTimes) {
223 this.openingTimes = openingTimes;