]> git.basschouten.com Git - openhab-addons.git/blob
59b7cfb376f4e214a2703176735d98d068c8cc92
[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.unifi.internal.action;
14
15 import java.util.List;
16 import java.util.regex.Pattern;
17 import java.util.stream.Collectors;
18 import java.util.stream.Stream;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.binding.unifi.internal.api.UniFiController;
23 import org.openhab.binding.unifi.internal.api.UniFiException;
24 import org.openhab.binding.unifi.internal.api.dto.UniFiSite;
25 import org.openhab.binding.unifi.internal.api.dto.UniFiVoucher;
26 import org.openhab.binding.unifi.internal.handler.UniFiSiteThingHandler;
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.thing.binding.ThingActions;
31 import org.openhab.core.thing.binding.ThingActionsScope;
32 import org.openhab.core.thing.binding.ThingHandler;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 import com.google.gson.Gson;
37
38 /**
39  * The {@link UniFiSiteActions} class defines rule actions for creating guest hotspot vouchers
40  *
41  * @author Mark Herwege - Initial contribution
42  */
43 @ThingActionsScope(name = "unifi")
44 @NonNullByDefault
45 public class UniFiSiteActions implements ThingActions {
46
47     private static final int DEFAULT_COUNT = 1;
48     private static final int DEFAULT_EXPIRE_MIN = 1440;
49     private static final int DEFAULT_USERS = 1;
50
51     private static final Pattern NON_DIGITS_PATTERN = Pattern.compile("\\D+");
52
53     private final Logger logger = LoggerFactory.getLogger(UniFiSiteActions.class);
54
55     private @Nullable UniFiSiteThingHandler handler;
56     private final Gson gson = new Gson();
57
58     @RuleAction(label = "@text/action.unifi.generateVouchers.label", description = "@text/action.unifi.generateVouchers.description")
59     public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean generateVoucher(
60     /* @formatter:off */
61             @ActionInput(name = "expire",
62                 label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherExpiration.label",
63                 description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherExpiration.description") @Nullable Integer expire,
64             @ActionInput(name = "users",
65                 label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherUsers.label",
66                 description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherUsers.description") @Nullable Integer users,
67             @ActionInput(name = "upLimit",
68                 label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherUpLimit.label",
69                 description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherUpLimit.description") @Nullable Integer upLimit,
70             @ActionInput(name = "downLimit",
71                 label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherDownLimit.label",
72                 description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherDownLimit.description") @Nullable Integer downLimit,
73             @ActionInput(name = "dataQuota",
74                 label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherDataQuota.label",
75                 description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherDataQuota.description") @Nullable Integer dataQuota) {
76     /* @formatter:on */
77         return generateVouchers(1, expire, users, upLimit, downLimit, dataQuota);
78     }
79
80     @RuleAction(label = "@text/action.unifi.generateVouchers.label", description = "@text/action.unifi.generateVouchers.description")
81     public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean generateVouchers(
82     /* @formatter:off */
83             @ActionInput(name = "count",
84                 label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherCount.label",
85                 description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherCount.description") @Nullable Integer count,
86             @ActionInput(name = "expire",
87                 label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherExpiration.label",
88                 description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherExpiration.description") @Nullable Integer expire,
89             @ActionInput(name = "users",
90                 label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherUsers.label",
91                 description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherUsers.description") @Nullable Integer users,
92             @ActionInput(name = "upLimit",
93                 label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherUpLimit.label",
94                 description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherUpLimit.description") @Nullable Integer upLimit,
95             @ActionInput(name = "downLimit",
96                 label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherDownLimit.label",
97                 description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherDownLimit.description") @Nullable Integer downLimit,
98             @ActionInput(name = "dataQuota",
99                 label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherDataQuota.label",
100                 description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherDataQuota.description") @Nullable Integer dataQuota) {
101     /* @formatter:on */
102         UniFiSiteThingHandler handler = this.handler;
103         if (handler == null) {
104             logger.debug("Could not create guest vouchers, site thing handler not set");
105             return false;
106         }
107         final @Nullable UniFiSite entity = handler.getEntity();
108         final UniFiController controller = handler.getController();
109         if (entity == null || controller == null) {
110             logger.debug("Could not create guest vouchers, site thing error");
111             return false;
112         }
113         try {
114             controller.generateVouchers(entity, ((count != null) && (count != 0)) ? count : DEFAULT_COUNT,
115                     (expire != null) ? expire : DEFAULT_EXPIRE_MIN, (users != null) ? users : DEFAULT_USERS, upLimit,
116                     downLimit, dataQuota);
117         } catch (UniFiException e) {
118             logger.debug("Could not create guest vouchers, uniFi exception", e);
119             return false;
120         }
121         return true;
122     }
123
124     public static boolean generateVoucher(ThingActions actions) {
125         return UniFiSiteActions.generateVoucher(actions, DEFAULT_EXPIRE_MIN);
126     }
127
128     public static boolean generateVoucher(ThingActions actions, @Nullable Integer expire) {
129         return UniFiSiteActions.generateVoucher(actions, expire, DEFAULT_USERS);
130     }
131
132     public static boolean generateVoucher(ThingActions actions, @Nullable Integer expire, @Nullable Integer users) {
133         return UniFiSiteActions.generateVoucher(actions, expire, users, null, null, null);
134     }
135
136     public static boolean generateVoucher(ThingActions actions, @Nullable Integer expire, @Nullable Integer users,
137             @Nullable Integer upLimit, @Nullable Integer downLimit, @Nullable Integer dataQuota) {
138         return ((UniFiSiteActions) actions).generateVoucher(expire, users, upLimit, downLimit, dataQuota);
139     }
140
141     public static boolean generateVouchers(ThingActions actions) {
142         return UniFiSiteActions.generateVouchers(actions, DEFAULT_COUNT);
143     }
144
145     public static boolean generateVouchers(ThingActions actions, @Nullable Integer count) {
146         return UniFiSiteActions.generateVouchers(actions, count, DEFAULT_EXPIRE_MIN);
147     }
148
149     public static boolean generateVouchers(ThingActions actions, @Nullable Integer count, @Nullable Integer expire) {
150         return UniFiSiteActions.generateVouchers(actions, count, expire, DEFAULT_USERS);
151     }
152
153     public static boolean generateVouchers(ThingActions actions, @Nullable Integer count, @Nullable Integer expire,
154             @Nullable Integer users) {
155         return UniFiSiteActions.generateVouchers(actions, count, expire, users, null, null, null);
156     }
157
158     public static boolean generateVouchers(ThingActions actions, @Nullable Integer count, @Nullable Integer expire,
159             @Nullable Integer users, @Nullable Integer upLimit, @Nullable Integer downLimit,
160             @Nullable Integer dataQuota) {
161         return ((UniFiSiteActions) actions).generateVouchers(count, expire, users, upLimit, downLimit, dataQuota);
162     }
163
164     @RuleAction(label = "@text/action.unifi.revokeVouchers.label", description = "@text/action.unifi.revokeVouchers.description")
165     public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean revokeVoucher(
166     /* @formatter:off */
167             @ActionInput(name = "voucherCodes", label = "@text/action.unifi.vouchersInputVoucherCodes.label",
168                 description = "@text/action.unifi.vouchersInputVoucherCodes.description") String voucherCode) {
169     /* @formatter:on */
170         return revokeVouchers(List.of(voucherCode));
171     }
172
173     @RuleAction(label = "@text/action.unifi.revokeVouchers.label", description = "@text/action.unifi.revokeVouchers.description")
174     public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean revokeVouchers(
175     /* @formatter:off */
176             @ActionInput(name = "voucherCodes", label = "@text/action.unifi.vouchersInputVoucherCodes.label",
177                 description = "@text/action.unifi.vouchersInputVoucherCodes.description") List<String> voucherCodes) {
178     /* @formatter:on */
179         UniFiSiteThingHandler handler = this.handler;
180         if (handler == null) {
181             logger.debug("Could not revoke guest vouchers, site thing handler not set");
182             return false;
183         }
184         final @Nullable UniFiSite entity = handler.getEntity();
185         final UniFiController controller = handler.getController();
186         if (entity == null || controller == null) {
187             logger.debug("Could not revoke guest vouchers, site thing error");
188             return false;
189         }
190
191         // Only keep digits in provided codes, so matching is done correctly. This makes blanks and dashes in the input
192         // possible, as shown in the UniFi voucher UI.
193         List<String> cleanCodes = voucherCodes.stream().map(c -> NON_DIGITS_PATTERN.matcher(c).replaceAll(""))
194                 .filter(c -> !c.isEmpty()).toList();
195         Stream<UniFiVoucher> voucherStream = entity.getCache().getVoucherStreamForSite(entity);
196         // If no codes provided, revoke all codes
197         List<UniFiVoucher> vouchers = (voucherCodes.isEmpty() ? voucherStream
198                 : voucherStream.filter(v -> cleanCodes.contains(v.getCode()))).toList();
199         try {
200             controller.revokeVouchers(entity, vouchers);
201         } catch (UniFiException e) {
202             logger.debug("Could not revoke guest vouchers, uniFi exception", e);
203             return false;
204         }
205         return true;
206     }
207
208     @RuleAction(label = "@text/action.unifi.revokeAllVouchers.label", description = "@text/action.unifi.revokeAllVouchers.description")
209     public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean revokeAllVouchers() {
210         return revokeVouchers(List.of());
211     }
212
213     public static boolean revokeVoucher(ThingActions actions, String voucherCode) {
214         return revokeVouchers(actions, List.of(voucherCode));
215     }
216
217     public static boolean revokeVouchers(ThingActions actions, List<String> voucherCodes) {
218         return ((UniFiSiteActions) actions).revokeVouchers(voucherCodes);
219     }
220
221     public static boolean revokeAllVouchers(ThingActions actions) {
222         return revokeVouchers(actions);
223     }
224
225     public static boolean revokeVouchers(ThingActions actions) {
226         return revokeVouchers(actions, List.of());
227     }
228
229     @RuleAction(label = "@text/action.unifi.listVouchers.label", description = "@text/action.unifi.listVouchers.description")
230     public @ActionOutput(name = "vouchers", type = "java.lang.String") String listVouchers() {
231         UniFiSiteThingHandler handler = this.handler;
232         if (handler == null) {
233             logger.debug("Could not list guest vouchers, site thing handler not set");
234             return "";
235         }
236         final @Nullable UniFiSite entity = handler.getEntity();
237         if (entity == null) {
238             logger.debug("Could not list guest vouchers, site thing error");
239             return "";
240         }
241
242         record Voucher(String code, String createTime, Integer duration, Integer quota, Integer used,
243                 Integer qosUsageQuota, Integer qosRateMaxUp, Integer qosRateMaxDown, Boolean qosOverwrite, String note,
244                 String status) {
245         }
246
247         return gson
248                 .toJson(entity.getCache().getVoucherStreamForSite(entity)
249                         .collect(Collectors.mapping(
250                                 v -> new Voucher(v.getCode(), v.getCreateTime().toString(), v.getDuration(),
251                                         v.getQuota(), v.getUsed(), v.getQosUsageQuota(), v.getQosRateMaxUp(),
252                                         v.getQosRateMaxDown(), v.isQosOverwrite(), v.getNote(), v.getStatus()),
253                                 Collectors.toList())));
254     }
255
256     public static String listVouchers(ThingActions actions) {
257         return ((UniFiSiteActions) actions).listVouchers();
258     }
259
260     @Override
261     public void setThingHandler(ThingHandler handler) {
262         if (handler instanceof UniFiSiteThingHandler) {
263             this.handler = (UniFiSiteThingHandler) handler;
264         }
265     }
266
267     @Override
268     public @Nullable ThingHandler getThingHandler() {
269         return handler;
270     }
271 }