]> git.basschouten.com Git - openhab-addons.git/blob
681fceadbe4080ce7eaaf21b38793457ceef9f83
[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.solaredge.internal.handler;
14
15 import java.util.Map;
16 import java.util.concurrent.Future;
17 import java.util.concurrent.TimeUnit;
18 import java.util.concurrent.atomic.AtomicReference;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.eclipse.jetty.client.HttpClient;
23 import org.openhab.binding.solaredge.internal.AtomicReferenceTrait;
24 import org.openhab.binding.solaredge.internal.config.SolarEdgeConfiguration;
25 import org.openhab.binding.solaredge.internal.connector.WebInterface;
26 import org.openhab.core.thing.Channel;
27 import org.openhab.core.thing.ChannelUID;
28 import org.openhab.core.thing.Thing;
29 import org.openhab.core.thing.ThingStatus;
30 import org.openhab.core.thing.ThingStatusDetail;
31 import org.openhab.core.thing.binding.BaseThingHandler;
32 import org.openhab.core.types.Command;
33 import org.openhab.core.types.State;
34 import org.openhab.core.types.UnDefType;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 /**
39  * The {@link SolarEdgeBaseHandler} is responsible for handling commands, which are
40  * sent to one of the channels.
41  *
42  * @author Alexander Friese - initial contribution
43  */
44 @NonNullByDefault
45 public abstract class SolarEdgeBaseHandler extends BaseThingHandler implements SolarEdgeHandler, AtomicReferenceTrait {
46     private final Logger logger = LoggerFactory.getLogger(SolarEdgeBaseHandler.class);
47
48     private final long LIVE_POLLING_INITIAL_DELAY = 1;
49     private final long AGGREGATE_POLLING_INITIAL_DELAY = 2;
50
51     /**
52      * Interface object for querying the Solaredge web interface
53      */
54     private WebInterface webInterface;
55
56     /**
57      * Schedule for polling live data
58      */
59     private final AtomicReference<@Nullable Future<?>> liveDataPollingJobReference;
60
61     /**
62      * Schedule for polling aggregate data
63      */
64     private final AtomicReference<@Nullable Future<?>> aggregateDataPollingJobReference;
65
66     public SolarEdgeBaseHandler(Thing thing, HttpClient httpClient) {
67         super(thing);
68         this.webInterface = new WebInterface(scheduler, this, httpClient);
69         this.liveDataPollingJobReference = new AtomicReference<>(null);
70         this.aggregateDataPollingJobReference = new AtomicReference<>(null);
71     }
72
73     @Override
74     public void handleCommand(ChannelUID channelUID, Command command) {
75         logger.debug("command for {}: {}", channelUID, command);
76         // write access is not supported.
77     }
78
79     @Override
80     public void initialize() {
81         logger.debug("About to initialize SolarEdge");
82         SolarEdgeConfiguration config = getConfiguration();
83         logger.debug("Solaredge initialized with configuration: {}", config);
84
85         startPolling();
86         webInterface.start();
87         updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.NONE, "waiting for web api login");
88     }
89
90     /**
91      * Start the polling.
92      */
93     private void startPolling() {
94         updateJobReference(liveDataPollingJobReference,
95                 scheduler.scheduleWithFixedDelay(new SolarEdgeLiveDataPolling(this), LIVE_POLLING_INITIAL_DELAY,
96                         getConfiguration().getLiveDataPollingInterval(), TimeUnit.MINUTES));
97
98         updateJobReference(aggregateDataPollingJobReference,
99                 scheduler.scheduleWithFixedDelay(new SolarEdgeAggregateDataPolling(this),
100                         AGGREGATE_POLLING_INITIAL_DELAY, getConfiguration().getAggregateDataPollingInterval(),
101                         TimeUnit.MINUTES));
102     }
103
104     /**
105      * Disposes the bridge.
106      */
107     @Override
108     public void dispose() {
109         logger.debug("Handler disposed.");
110
111         cancelJobReference(liveDataPollingJobReference);
112         cancelJobReference(aggregateDataPollingJobReference);
113
114         webInterface.dispose();
115     }
116
117     @Override
118     public WebInterface getWebInterface() {
119         return webInterface;
120     }
121
122     /**
123      * will update all channels provided in the map
124      */
125     @Override
126     public void updateChannelStatus(Map<Channel, State> values) {
127         logger.debug("Handling channel update.");
128
129         for (Channel channel : values.keySet()) {
130             if (getChannels().contains(channel)) {
131                 State value = values.get(channel);
132                 if (value != null) {
133                     logger.debug("Channel is to be updated: {}: {}", channel.getUID().getAsString(), value);
134                     updateState(channel.getUID(), value);
135                 } else {
136                     logger.debug("Value is null or not provided by solaredge (channel: {})",
137                             channel.getUID().getAsString());
138                     updateState(channel.getUID(), UnDefType.UNDEF);
139                 }
140             } else {
141                 logger.debug("Could not identify channel: {} for model {}", channel.getUID().getAsString(),
142                         getThing().getThingTypeUID().getAsString());
143             }
144         }
145     }
146
147     @Override
148     public void setStatusInfo(ThingStatus status, ThingStatusDetail statusDetail, String description) {
149         super.updateStatus(status, statusDetail, description);
150     }
151
152     @Override
153     public SolarEdgeConfiguration getConfiguration() {
154         return this.getConfigAs(SolarEdgeConfiguration.class);
155     }
156 }