]> git.basschouten.com Git - openhab-addons.git/blob
202135e92ef9af2d2875624e15beb2ca55297c1c
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.astro.internal.action;
14
15 import java.lang.reflect.Method;
16 import java.lang.reflect.Proxy;
17 import java.time.ZonedDateTime;
18
19 import javax.measure.quantity.Angle;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.binding.astro.internal.AstroBindingConstants;
24 import org.openhab.binding.astro.internal.handler.AstroThingHandler;
25 import org.openhab.binding.astro.internal.handler.SunHandler;
26 import org.openhab.binding.astro.internal.model.SunPhaseName;
27 import org.openhab.core.automation.annotation.ActionInput;
28 import org.openhab.core.automation.annotation.ActionOutput;
29 import org.openhab.core.automation.annotation.RuleAction;
30 import org.openhab.core.library.types.QuantityType;
31 import org.openhab.core.thing.binding.ThingActions;
32 import org.openhab.core.thing.binding.ThingActionsScope;
33 import org.openhab.core.thing.binding.ThingHandler;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 /**
38  * The {AstroActions } defines rule actions for the Astro binding.
39  * <p>
40  * <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
41  * the test <i>actions instanceof AstroActions</i> fails. This test can fail
42  * due to an issue in openHAB core v2.5.0 where the {@link AstroActions} class
43  * can be loaded by a different classloader than the <i>actions</i> instance.
44  *
45  * @author GaĆ«l L'hopital - Initial contribution
46  */
47 @ThingActionsScope(name = "astro")
48 @NonNullByDefault
49 public class AstroActions implements ThingActions, IAstroActions {
50
51     private final Logger logger = LoggerFactory.getLogger(AstroActions.class);
52     protected @Nullable AstroThingHandler handler;
53
54     public AstroActions() {
55         logger.debug("Astro actions service instanciated");
56     }
57
58     @Override
59     public void setThingHandler(@Nullable ThingHandler handler) {
60         if (handler instanceof AstroThingHandler) {
61             this.handler = (AstroThingHandler) handler;
62         }
63     }
64
65     @Override
66     public @Nullable ThingHandler getThingHandler() {
67         return this.handler;
68     }
69
70     @Override
71     @RuleAction(label = "Astro : Get Azimuth", description = "Get the azimuth of the sun for a given time")
72     public @Nullable @ActionOutput(name = "getAzimuth", label = "Azimuth", type = "org.openhab.core.library.types.QuantityType<javax.measure.quantity.Angle>") QuantityType<Angle> getAzimuth(
73             @ActionInput(name = "date", label = "Date", required = false, description = "Considered date") @Nullable ZonedDateTime date) {
74         logger.debug("Astro action 'getAzimuth' called");
75         AstroThingHandler theHandler = this.handler;
76         if (theHandler != null) {
77             return theHandler.getAzimuth(date != null ? date : ZonedDateTime.now());
78         } else {
79             logger.info("Astro Action service ThingHandler is null!");
80         }
81         return null;
82     }
83
84     @Override
85     @RuleAction(label = "Astro : Get Elevation", description = "Get the Elevation of the sun for a given time")
86     public @Nullable @ActionOutput(name = "getElevation", label = "Elevation", type = "org.openhab.core.library.types.QuantityType<javax.measure.quantity.Angle>") QuantityType<Angle> getElevation(
87             @ActionInput(name = "date", label = "Date", required = false, description = "Considered date") @Nullable ZonedDateTime date) {
88         logger.debug("Astro action 'getElevation' called");
89         AstroThingHandler theHandler = this.handler;
90         if (theHandler != null) {
91             return theHandler.getElevation(date != null ? date : ZonedDateTime.now());
92         } else {
93             logger.info("Astro Action service ThingHandler is null!");
94         }
95         return null;
96     }
97
98     @Override
99     @RuleAction(label = "Sun : Get Event Time", description = "Get the date time of a given planet event")
100     public @Nullable @ActionOutput(name = "getEventTime", type = "java.time.ZonedDateTime") ZonedDateTime getEventTime(
101             @ActionInput(name = "phaseName", label = "Phase", required = true, description = "Requested phase") String phaseName,
102             @ActionInput(name = "date", label = "Date", required = false, description = "Considered date") @Nullable ZonedDateTime date,
103             @ActionInput(name = "moment", label = "Moment", required = false, defaultValue = "START", description = "Either START or END") @Nullable String moment) {
104         logger.debug("Sun action 'getEventTime' called");
105         try {
106             AstroThingHandler theHandler = this.handler;
107             if (theHandler != null) {
108                 if (theHandler instanceof SunHandler) {
109                     SunHandler handler = (SunHandler) theHandler;
110                     SunPhaseName phase = SunPhaseName.valueOf(phaseName.toUpperCase());
111                     return handler.getEventTime(phase, date != null ? date : ZonedDateTime.now(),
112                             moment == null || AstroBindingConstants.EVENT_START.equalsIgnoreCase(moment));
113                 } else {
114                     logger.info("Astro Action service ThingHandler is not a SunHandler!");
115                 }
116             } else {
117                 logger.info("Astro Action service ThingHandler is null!");
118             }
119         } catch (IllegalArgumentException e) {
120             logger.info("Parameter {} is not a valid phase name", phaseName);
121         }
122         return null;
123     }
124
125     public static @Nullable QuantityType<Angle> getElevation(@Nullable ThingActions actions,
126             @Nullable ZonedDateTime date) {
127         return invokeMethodOf(actions).getElevation(date);
128     }
129
130     public static @Nullable QuantityType<Angle> getAzimuth(@Nullable ThingActions actions,
131             @Nullable ZonedDateTime date) {
132         return invokeMethodOf(actions).getAzimuth(date);
133     }
134
135     public static @Nullable ZonedDateTime getEventTime(@Nullable ThingActions actions, @Nullable String phaseName,
136             @Nullable ZonedDateTime date, @Nullable String moment) {
137         if (phaseName != null) {
138             return invokeMethodOf(actions).getEventTime(phaseName, date, moment);
139         } else {
140             throw new IllegalArgumentException("phaseName can not be null");
141         }
142     }
143
144     private static IAstroActions invokeMethodOf(@Nullable ThingActions actions) {
145         if (actions == null) {
146             throw new IllegalArgumentException("actions cannot be null");
147         }
148         if (actions.getClass().getName().equals(AstroActions.class.getName())) {
149             if (actions instanceof IAstroActions) {
150                 return (IAstroActions) actions;
151             } else {
152                 return (IAstroActions) Proxy.newProxyInstance(IAstroActions.class.getClassLoader(),
153                         new Class[] { IAstroActions.class }, (Object proxy, Method method, Object[] args) -> {
154                             Method m = actions.getClass().getDeclaredMethod(method.getName(),
155                                     method.getParameterTypes());
156                             return m.invoke(actions, args);
157                         });
158             }
159         }
160         throw new IllegalArgumentException("Actions is not an instance of AstroActions");
161     }
162 }