]> git.basschouten.com Git - openhab-addons.git/blob
c7d501bda2257808a45f89806e35a990e81219d1
[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.pushover.internal.handler;
14
15 import static org.openhab.binding.pushover.internal.PushoverBindingConstants.*;
16
17 import java.util.Collection;
18 import java.util.List;
19 import java.util.Set;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.eclipse.jetty.client.HttpClient;
24 import org.openhab.binding.pushover.internal.actions.PushoverActions;
25 import org.openhab.binding.pushover.internal.config.PushoverAccountConfiguration;
26 import org.openhab.binding.pushover.internal.config.PushoverConfigOptionProvider;
27 import org.openhab.binding.pushover.internal.connection.PushoverAPIConnection;
28 import org.openhab.binding.pushover.internal.connection.PushoverMessageBuilder;
29 import org.openhab.binding.pushover.internal.dto.Sound;
30 import org.openhab.core.i18n.CommunicationException;
31 import org.openhab.core.i18n.ConfigurationException;
32 import org.openhab.core.thing.ChannelUID;
33 import org.openhab.core.thing.Thing;
34 import org.openhab.core.thing.ThingStatus;
35 import org.openhab.core.thing.ThingStatusDetail;
36 import org.openhab.core.thing.binding.BaseThingHandler;
37 import org.openhab.core.thing.binding.ThingHandlerService;
38 import org.openhab.core.types.Command;
39
40 /**
41  * The {@link PushoverAccountHandler} is responsible for handling commands, which are sent to one of the channels.
42  *
43  * @author Christoph Weitkamp - Initial contribution
44  */
45 @NonNullByDefault
46 public class PushoverAccountHandler extends BaseThingHandler {
47
48     private static final Collection<Class<? extends ThingHandlerService>> SUPPORTED_THING_ACTIONS = Set
49             .of(PushoverActions.class, PushoverConfigOptionProvider.class);
50
51     private final HttpClient httpClient;
52
53     private PushoverAccountConfiguration config = new PushoverAccountConfiguration();
54     private @Nullable PushoverAPIConnection connection;
55
56     public PushoverAccountHandler(Thing thing, HttpClient httpClient) {
57         super(thing);
58         this.httpClient = httpClient;
59     }
60
61     @Override
62     public void handleCommand(ChannelUID channelUID, Command command) {
63         // nothing
64     }
65
66     @Override
67     public void initialize() {
68         config = getConfigAs(PushoverAccountConfiguration.class);
69
70         boolean configValid = true;
71         final String apikey = config.apikey;
72         if (apikey == null || apikey.isBlank()) {
73             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
74                     TEXT_OFFLINE_CONF_ERROR_MISSING_APIKEY);
75             configValid = false;
76         }
77         final String user = config.user;
78         if (user == null || user.isBlank()) {
79             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
80                     TEXT_OFFLINE_CONF_ERROR_MISSING_USER);
81             configValid = false;
82         }
83
84         if (configValid) {
85             updateStatus(ThingStatus.UNKNOWN);
86
87             connection = new PushoverAPIConnection(httpClient, config);
88             scheduler.submit(this::asyncValidateUser);
89         }
90     }
91
92     @Override
93     public Collection<Class<? extends ThingHandlerService>> getServices() {
94         return SUPPORTED_THING_ACTIONS;
95     }
96
97     /**
98      * Retrieves the list of current sounds and their descriptions from the Pushover API.
99      *
100      * @return a list of {@link Sound}s
101      */
102     public List<Sound> getSounds() {
103         try {
104             PushoverAPIConnection connection = this.connection;
105             if (connection != null) {
106                 List<Sound> sounds = connection.getSounds();
107                 if (sounds != null) {
108                     return sounds;
109                 }
110             }
111         } catch (CommunicationException e) {
112             // do nothing, causing exception is already logged
113         } catch (ConfigurationException e) {
114             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getRawMessage());
115         }
116         return PushoverAccountConfiguration.DEFAULT_SOUNDS;
117     }
118
119     /**
120      * Returns a preconfigured {@link PushoverMessageBuilder}.
121      *
122      * @param message the message
123      * @return a {@link PushoverMessageBuilder} instance
124      */
125     public PushoverMessageBuilder getDefaultPushoverMessageBuilder(String message) {
126         PushoverMessageBuilder builder = PushoverMessageBuilder.getInstance(config.apikey, config.user)
127                 .withMessage(message) //
128                 .withTitle(config.title) //
129                 .withRetry(config.retry) //
130                 .withExpire(config.expire);
131         // specify format if defined
132         switch (config.format) {
133             case PushoverMessageBuilder.MESSAGE_KEY_HTML:
134                 builder.withHtmlFormatting();
135                 break;
136             case PushoverMessageBuilder.MESSAGE_KEY_MONOSPACE:
137                 builder.withMonospaceFormatting();
138             default:
139                 break;
140         }
141         // add sound, if defined
142         if (!DEFAULT_SOUND.equals(config.sound)) {
143             builder.withSound(config.sound);
144         }
145         return builder;
146     }
147
148     public boolean sendMessage(PushoverMessageBuilder messageBuilder) {
149         PushoverAPIConnection connection = this.connection;
150         if (connection != null) {
151             try {
152                 return connection.sendMessage(messageBuilder);
153             } catch (CommunicationException e) {
154                 // do nothing, causing exception is already logged
155             } catch (ConfigurationException e) {
156                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getRawMessage());
157             }
158             return false;
159         } else {
160             throw new IllegalArgumentException("PushoverAPIConnection is null!");
161         }
162     }
163
164     public String sendPriorityMessage(PushoverMessageBuilder messageBuilder) {
165         PushoverAPIConnection connection = this.connection;
166         if (connection != null) {
167             try {
168                 return connection.sendPriorityMessage(messageBuilder);
169             } catch (CommunicationException e) {
170                 // do nothing, causing exception is already logged
171             } catch (ConfigurationException e) {
172                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getRawMessage());
173             }
174             return "";
175         } else {
176             throw new IllegalArgumentException("PushoverAPIConnection is null!");
177         }
178     }
179
180     public boolean cancelPriorityMessage(String receipt) {
181         PushoverAPIConnection connection = this.connection;
182         if (connection != null) {
183             try {
184                 return connection.cancelPriorityMessage(receipt);
185             } catch (CommunicationException e) {
186                 // do nothing, causing exception is already logged
187             } catch (ConfigurationException e) {
188                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getRawMessage());
189             }
190             return false;
191         } else {
192             throw new IllegalArgumentException("PushoverAPIConnection is null!");
193         }
194     }
195
196     @SuppressWarnings("null")
197     private void asyncValidateUser() {
198         try {
199             connection.validateUser();
200             updateStatus(ThingStatus.ONLINE);
201         } catch (CommunicationException | ConfigurationException e) {
202             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getRawMessage());
203         }
204     }
205 }