]> git.basschouten.com Git - openhab-addons.git/blob
8d93c6e221c9b5d79b6d3017b7490377a38d8fde
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.tankerkoenig.internal.handler;
14
15 import static org.openhab.binding.tankerkoenig.internal.TankerkoenigBindingConstants.*;
16
17 import java.util.concurrent.ScheduledFuture;
18 import java.util.concurrent.TimeUnit;
19 import java.util.regex.Pattern;
20
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;
40
41 /**
42  * The {@link StationHandler} is responsible for handling commands, which are
43  * sent to one of the channels.
44  *
45  * @author Dennis Dollinger - Initial contribution
46  * @author Jürgen Baginski - Initial contribution
47  */
48 public class StationHandler extends BaseThingHandler {
49     private static final Pattern IS_NUMERIC_PATTERN = Pattern.compile("\\d+(\\.\\d+)?");
50
51     private final Logger logger = LoggerFactory.getLogger(StationHandler.class);
52
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;
60
61     private ScheduledFuture<?> pollingJob;
62
63     public StationHandler(Thing thing) {
64         super(thing);
65     }
66
67     @Override
68     public void handleCommand(ChannelUID channelUID, Command command) {
69         // no code needed.
70     }
71
72     @Override
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();
79         if (b == null) {
80             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE,
81                     "Could not find bridge (tankerkoenig config). Did you select one?");
82             return;
83         }
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.");
91             return;
92         }
93         updateStatus(ThingStatus.UNKNOWN);
94
95         pollingJob = scheduler.scheduleWithFixedDelay(() -> {
96             try {
97                 logger.debug("Try to refresh detail data");
98                 updateDetailData();
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
103             }
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());
106     }
107
108     @Override
109     public void dispose() {
110         if (pollingJob != null) {
111             pollingJob.cancel(true);
112         }
113         super.dispose();
114     }
115
116     @Override
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());
121         }
122     }
123
124     /***
125      * Updates the channels of a station item
126      *
127      * @param station
128      */
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);
138                 } else {
139                     updateState(CHANNEL_DIESEL, UnDefType.UNDEF);
140                 }
141             } else {
142                 updateState(CHANNEL_DIESEL, UnDefType.UNDEF);
143             }
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);
148                 } else {
149                     updateState(CHANNEL_E10, UnDefType.UNDEF);
150                 }
151             } else {
152                 updateState(CHANNEL_E10, UnDefType.UNDEF);
153             }
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);
158                 } else {
159                     updateState(CHANNEL_E5, UnDefType.UNDEF);
160                 }
161             } else {
162                 updateState(CHANNEL_E5, UnDefType.UNDEF);
163             }
164         } else {
165             logger.debug("Checked Station is closed!");
166             updateState(CHANNEL_STATION_OPEN, OpenClosedType.CLOSED);
167         }
168         updateStatus(ThingStatus.ONLINE);
169     }
170
171     /***
172      * Updates the detail-data from tankerkoenig api, actually only the opening times are used.
173      */
174     public void updateDetailData() {
175         result = service.getStationDetailData(getApiKey(), locationID, userAgent);
176
177         if (result.isOk()) {
178             setOpeningTimes(result.getOpeningTimes());
179             LittleStation s = result.getLittleStation();
180             if (s == null) {
181                 logger.debug("Station with id {} is not updated!", getLocationID());
182             } else {
183                 updateData(s);
184             }
185             updateStatus(ThingStatus.ONLINE);
186             WebserviceHandler handler = (WebserviceHandler) getBridge().getHandler();
187             handler.updateStatus(ThingStatus.ONLINE);
188             logger.debug("updateDetailData openingTimes: {}", openingTimes);
189         } else {
190             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, result.getMessage());
191         }
192     }
193
194     public String getLocationID() {
195         return locationID;
196     }
197
198     public void setLocationID(String locationID) {
199         this.locationID = locationID;
200     }
201
202     public String getApiKey() {
203         return apiKey;
204     }
205
206     public void setApiKey(String apiKey) {
207         this.apiKey = apiKey;
208     }
209
210     public boolean isModeOpeningTime() {
211         return modeOpeningTime;
212     }
213
214     public void setModeOpeningTime(boolean modeOpeningTime) {
215         this.modeOpeningTime = modeOpeningTime;
216     }
217
218     public OpeningTimes getOpeningTimes() {
219         return openingTimes;
220     }
221
222     public void setOpeningTimes(OpeningTimes openingTimes) {
223         this.openingTimes = openingTimes;
224     }
225 }