]> git.basschouten.com Git - openhab-addons.git/blob
43ca9be321a6880cced0016bd10c6f50cfde36f9
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.solarforecast.internal.actions;
14
15 import java.time.Instant;
16 import java.time.LocalDate;
17 import java.util.Iterator;
18 import java.util.List;
19 import java.util.Optional;
20
21 import javax.measure.MetricPrefix;
22 import javax.measure.quantity.Energy;
23 import javax.measure.quantity.Power;
24
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.eclipse.jdt.annotation.Nullable;
27 import org.openhab.binding.solarforecast.internal.utils.Utils;
28 import org.openhab.core.automation.annotation.ActionInput;
29 import org.openhab.core.automation.annotation.RuleAction;
30 import org.openhab.core.library.types.QuantityType;
31 import org.openhab.core.library.unit.Units;
32 import org.openhab.core.thing.binding.ThingActions;
33 import org.openhab.core.thing.binding.ThingActionsScope;
34 import org.openhab.core.thing.binding.ThingHandler;
35 import org.openhab.core.types.State;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * Actions to query forecast objects
41  *
42  * @author Bernd Weymann - Initial contribution
43  */
44 @ThingActionsScope(name = "solarforecast")
45 @NonNullByDefault
46 public class SolarForecastActions implements ThingActions {
47     private final Logger logger = LoggerFactory.getLogger(SolarForecastActions.class);
48     private Optional<ThingHandler> thingHandler = Optional.empty();
49
50     @RuleAction(label = "@text/actionDayLabel", description = "@text/actionDayDesc")
51     public QuantityType<Energy> getDay(
52             @ActionInput(name = "localDate", label = "@text/actionInputDayLabel", description = "@text/actionInputDayDesc") LocalDate localDate,
53             String... args) {
54         if (thingHandler.isPresent()) {
55             List<SolarForecast> l = ((SolarForecastProvider) thingHandler.get()).getSolarForecasts();
56             if (!l.isEmpty()) {
57                 QuantityType<Energy> measure = QuantityType.valueOf(0, Units.KILOWATT_HOUR);
58                 for (Iterator<SolarForecast> iterator = l.iterator(); iterator.hasNext();) {
59                     SolarForecast solarForecast = iterator.next();
60                     QuantityType<Energy> qt = solarForecast.getDay(localDate, args);
61                     if (qt.floatValue() >= 0) {
62                         measure = measure.add(qt);
63                     } else {
64                         // break in case of failure getting values to avoid ambiguous values
65                         logger.debug("Ambiguous measure {} found for {}", qt, localDate);
66                         return Utils.getEnergyState(-1);
67                     }
68                 }
69                 return measure;
70             } else {
71                 logger.debug("No forecasts found for {}", localDate);
72                 return Utils.getEnergyState(-1);
73             }
74         } else {
75             logger.trace("Handler missing");
76             return Utils.getEnergyState(-1);
77         }
78     }
79
80     @RuleAction(label = "@text/actionPowerLabel", description = "@text/actionPowerDesc")
81     public QuantityType<Power> getPower(
82             @ActionInput(name = "timestamp", label = "@text/actionInputDateTimeLabel", description = "@text/actionInputDateTimeDesc") Instant timestamp,
83             String... args) {
84         if (thingHandler.isPresent()) {
85             List<SolarForecast> l = ((SolarForecastProvider) thingHandler.get()).getSolarForecasts();
86             if (!l.isEmpty()) {
87                 QuantityType<Power> measure = QuantityType.valueOf(0, MetricPrefix.KILO(Units.WATT));
88                 for (Iterator<SolarForecast> iterator = l.iterator(); iterator.hasNext();) {
89                     SolarForecast solarForecast = iterator.next();
90                     QuantityType<Power> qt = solarForecast.getPower(timestamp, args);
91                     if (qt.floatValue() >= 0) {
92                         measure = measure.add(qt);
93                     } else {
94                         // break in case of failure getting values to avoid ambiguous values
95                         logger.debug("Ambiguous measure {} found for {}", qt, timestamp);
96                         return Utils.getPowerState(-1);
97                     }
98                 }
99                 return measure;
100             } else {
101                 logger.debug("No forecasts found for {}", timestamp);
102                 return Utils.getPowerState(-1);
103             }
104         } else {
105             logger.trace("Handler missing");
106             return Utils.getPowerState(-1);
107         }
108     }
109
110     @RuleAction(label = "@text/actionEnergyLabel", description = "@text/actionEnergyDesc")
111     public QuantityType<Energy> getEnergy(
112             @ActionInput(name = "start", label = "@text/actionInputDateTimeBeginLabel", description = "@text/actionInputDateTimeBeginDesc") Instant start,
113             @ActionInput(name = "end", label = "@text/actionInputDateTimeEndLabel", description = "@text/actionInputDateTimeEndDesc") Instant end,
114             String... args) {
115         if (thingHandler.isPresent()) {
116             List<SolarForecast> l = ((SolarForecastProvider) thingHandler.get()).getSolarForecasts();
117             if (!l.isEmpty()) {
118                 QuantityType<Energy> measure = QuantityType.valueOf(0, Units.KILOWATT_HOUR);
119                 for (Iterator<SolarForecast> iterator = l.iterator(); iterator.hasNext();) {
120                     SolarForecast solarForecast = iterator.next();
121                     QuantityType<Energy> qt = solarForecast.getEnergy(start, end, args);
122                     if (qt.floatValue() >= 0) {
123                         measure = measure.add(qt);
124                     } else {
125                         // break in case of failure getting values to avoid ambiguous values
126                         logger.debug("Ambiguous measure {} found between {} and {}", qt, start, end);
127                         return Utils.getEnergyState(-1);
128                     }
129                 }
130                 return measure;
131             } else {
132                 logger.debug("No forecasts found for between {} and {}", start, end);
133                 return Utils.getEnergyState(-1);
134             }
135         } else {
136             logger.trace("Handler missing");
137             return Utils.getEnergyState(-1);
138         }
139     }
140
141     @RuleAction(label = "@text/actionForecastBeginLabel", description = "@text/actionForecastBeginDesc")
142     public Instant getForecastBegin() {
143         if (thingHandler.isPresent()) {
144             List<SolarForecast> forecastObjectList = ((SolarForecastProvider) thingHandler.get()).getSolarForecasts();
145             return Utils.getCommonStartTime(forecastObjectList);
146         } else {
147             logger.trace("Handler missing - return invalid date MAX");
148             return Instant.MAX;
149         }
150     }
151
152     @RuleAction(label = "@text/actionForecastEndLabel", description = "@text/actionForecastEndDesc")
153     public Instant getForecastEnd() {
154         if (thingHandler.isPresent()) {
155             List<SolarForecast> forecastObjectList = ((SolarForecastProvider) thingHandler.get()).getSolarForecasts();
156             return Utils.getCommonEndTime(forecastObjectList);
157         } else {
158             logger.trace("Handler missing - return invalid date MIN");
159             return Instant.MIN;
160         }
161     }
162
163     @RuleAction(label = "@text/actionTriggerUpdateLabel", description = "@text/actionTriggerUpdateDesc")
164     public void triggerUpdate() {
165         if (thingHandler.isPresent()) {
166             List<SolarForecast> forecastObjectList = ((SolarForecastProvider) thingHandler.get()).getSolarForecasts();
167             forecastObjectList.forEach(forecast -> {
168                 forecast.triggerUpdate();
169             });
170         } else {
171             logger.trace("Handler missing");
172         }
173     }
174
175     public static State getDay(ThingActions actions, LocalDate ld, String... args) {
176         return ((SolarForecastActions) actions).getDay(ld, args);
177     }
178
179     public static State getPower(ThingActions actions, Instant dateTime, String... args) {
180         return ((SolarForecastActions) actions).getPower(dateTime, args);
181     }
182
183     public static State getEnergy(ThingActions actions, Instant begin, Instant end, String... args) {
184         return ((SolarForecastActions) actions).getEnergy(begin, end, args);
185     }
186
187     public static Instant getForecastBegin(ThingActions actions) {
188         return ((SolarForecastActions) actions).getForecastBegin();
189     }
190
191     public static Instant getForecastEnd(ThingActions actions) {
192         return ((SolarForecastActions) actions).getForecastEnd();
193     }
194
195     public static void triggerUpdate(ThingActions actions) {
196         ((SolarForecastActions) actions).triggerUpdate();
197     }
198
199     @Override
200     public void setThingHandler(ThingHandler handler) {
201         thingHandler = Optional.of(handler);
202     }
203
204     @Override
205     public @Nullable ThingHandler getThingHandler() {
206         if (thingHandler.isPresent()) {
207             return thingHandler.get();
208         }
209         return null;
210     }
211 }