[unifi] guest voucher actions (#14303)
* guest voucher actions Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
This commit is contained in:
parent
bc6a027f9e
commit
fbbce11cf2
bundles/org.openhab.binding.unifi
README.md
src/main
java/org/openhab/binding/unifi/internal
resources/OH-INF/i18n
@ -230,21 +230,89 @@ The `poePort` information that is retrieved is available as these channels:
|
||||
The `enable` switch channel has a configuration parameter `mode` which is the value used to switch PoE on when the channel is switched to ON.
|
||||
The default mode value is `auto`.
|
||||
|
||||
## Rule Actions
|
||||
|
||||
As an alternative to using the `guestVoucher` and `guestVouchersGenerate` channels on the `site` thing, it is possible to use rule actions on the thing to generate, revoke and list guest vouchers.
|
||||
The following actions are available:
|
||||
|
||||
- `boolean success = generateVoucher(Integer expire, Integer users, Integer upLimit, Integer downLimit, Integer dataQuota)`
|
||||
- `boolean success = generateVouchers(Integer count, Integer expire, Integer users, Integer upLimit, Integer downLimit, Integer dataQuota)`
|
||||
- `boolean success = revokeVoucher(String voucherCode)`
|
||||
- `boolean success = revokeVouchers(List<String> voucherCodes)`
|
||||
- `boolean success = revokeAllVouchers()`
|
||||
- `String vouchers = listVouchers()`
|
||||
|
||||
Since there is a separate rule action instance for each `site` thing, this needs to be retrieved through `getActions(scope, thingUID)`.
|
||||
The first parameter always has to be `unifi` and the second is the full Thing UID of the site that should be used.
|
||||
Once this action instance is retrieved, you can invoke the action method on it.
|
||||
|
||||
Boolean return values for the actions indicate success or failure.
|
||||
|
||||
The `generateVoucher(s)` actions parameters match the configuration parameters for the `guestVouchersGenerate` channel.
|
||||
With the actions, these parameters can be controlled in a rule or script.
|
||||
`null` values for the parameters are allowed, and will set the parameter to the default value.
|
||||
|
||||
| Parameter | Description | Default |
|
||||
| ------------- | --------------------------------------------------------------------------- | ------- |
|
||||
| count | Number of vouchers to create | 1 |
|
||||
| expire | Minutes a voucher is valid after activation (default is 1 day) | 1440 |
|
||||
| users | Number of users for voucher, 0 for no limit | 1 |
|
||||
| upLimit | Upload speed limit in kbps, no limit if not set | |
|
||||
| downLimit | Download speed limit in kbps, no limit if not set | |
|
||||
| dataQuota | Data transfer quota in MB per user, no limit if not set | |
|
||||
|
||||
The `revoke...` actions allow you to revoke previously created vouchers.
|
||||
The parameter is the voucher code or a list of voucher codes to be revoked.
|
||||
|
||||
The `listVouchers` action will return a json string representing the currently available vouchers for the site.
|
||||
The json contains all parameters for the voucher, therefore it is possible to filter on these in a rule or script.
|
||||
For example, one could retrieve all vouchers created before a certain time and use the `revokeVouchers` action to delete these.
|
||||
The structure of the returned json is (depending on content, some fields may be missing):
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"code": "3867791284",
|
||||
"createTime": "2023-01-31T14:40:47Z",
|
||||
"duration": 1440,
|
||||
"quota": 2,
|
||||
"used": 0,
|
||||
"qosUsageQuota": 300,
|
||||
"qosRateMaxUp": 200,
|
||||
"qosRateMaxDown": 100,
|
||||
"qosOverwrite": true,
|
||||
"note": "I added a note when creating vouchers in the UniFi hotspot UI",
|
||||
"status": "VALID_MULTI"
|
||||
},
|
||||
{
|
||||
"code": "0021952641",
|
||||
"createTime": "2023-01-31T14:38:47Z",
|
||||
"duration": 1440,
|
||||
"quota": 1,
|
||||
"used": 0,
|
||||
"qosOverwrite": false,
|
||||
"status": "VALID_ONE"
|
||||
},
|
||||
{ ... }
|
||||
]
|
||||
```
|
||||
|
||||
## Full Example
|
||||
|
||||
things/unifi.things
|
||||
### `things/unifi.things`
|
||||
|
||||
```
|
||||
Bridge unifi:controller:home "UniFi Controller" [ host="unifi", port=8443, unifios=false, username="$username", password="$password", refresh=10 ] {
|
||||
Thing wirelessClient matthewsPhone "Matthew's iPhone" [ cid="$cid", site="default", considerHome=180 ]
|
||||
Thing site mysite "My Site" [ sid="$sid" ]
|
||||
}
|
||||
```
|
||||
|
||||
_Note: Usually on Unifi OS, the default port is 443_
|
||||
|
||||
Replace `$user`, `$password` and `$cid` accordingly.
|
||||
Replace `$user`, `$password`, `$cid` and `$sid` accordingly.
|
||||
|
||||
items/unifi.items
|
||||
### `items/unifi.items`
|
||||
|
||||
```
|
||||
Switch MatthewsPhone "Matthew's iPhone [MAP(unifi.map):%s]" { channel="unifi:wirelessClient:home:matthewsPhone:online" }
|
||||
@ -260,14 +328,14 @@ Switch MatthewsPhoneBlocked "Matthew's iPhone: Blocked"
|
||||
Switch MatthewsPhoneReconnect "Matthew's iPhone: Reconnect" { channel="unifi:wirelessClient:home:matthewsPhone:reconnect" }
|
||||
```
|
||||
|
||||
transform/unifi.map
|
||||
### `transform/unifi.map`
|
||||
|
||||
```
|
||||
ON=Home
|
||||
OFF=Away
|
||||
```
|
||||
|
||||
sitemaps/unifi.sitemap
|
||||
### `sitemaps/unifi.sitemap`
|
||||
|
||||
```
|
||||
sitemap unifi label="UniFi Binding"
|
||||
@ -287,3 +355,23 @@ sitemap unifi label="UniFi Binding"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `rule actions` for `site` thing
|
||||
|
||||
```java
|
||||
val uniFiActions = getActions("unifi","unifi:site:home:mysite")
|
||||
val success = uniFiActions.generateVoucher(null, null, null, 100, 500, 250)
|
||||
```
|
||||
|
||||
```java
|
||||
val uniFiActions = getActions("unifi","unifi:site:home:mysite")
|
||||
val vouchersJson = uniFiActions.listVouchers()
|
||||
```
|
||||
|
||||
```java
|
||||
import java.util.List
|
||||
|
||||
val List<String> voucherList = newArrayList("38677-91284", "46415-36104")
|
||||
val uniFiActions = getActions("unifi","unifi:site:home:mysite")
|
||||
val success = uniFiActions.revokeVouchers(voucherList)
|
||||
```
|
||||
|
@ -12,13 +12,7 @@
|
||||
*/
|
||||
package org.openhab.binding.unifi.internal;
|
||||
|
||||
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.ALL_THING_TYPE_SUPPORTED;
|
||||
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.THING_TYPE_CONTROLLER;
|
||||
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.THING_TYPE_POE_PORT;
|
||||
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.THING_TYPE_SITE;
|
||||
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.THING_TYPE_WIRED_CLIENT;
|
||||
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.THING_TYPE_WIRELESS_CLIENT;
|
||||
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.THING_TYPE_WLAN;
|
||||
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.*;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
271
bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/action/UniFiSiteActions.java
Normal file
271
bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/action/UniFiSiteActions.java
Normal file
@ -0,0 +1,271 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.unifi.internal.action;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.unifi.internal.api.UniFiController;
|
||||
import org.openhab.binding.unifi.internal.api.UniFiException;
|
||||
import org.openhab.binding.unifi.internal.api.dto.UniFiSite;
|
||||
import org.openhab.binding.unifi.internal.api.dto.UniFiVoucher;
|
||||
import org.openhab.binding.unifi.internal.handler.UniFiSiteThingHandler;
|
||||
import org.openhab.core.automation.annotation.ActionInput;
|
||||
import org.openhab.core.automation.annotation.ActionOutput;
|
||||
import org.openhab.core.automation.annotation.RuleAction;
|
||||
import org.openhab.core.thing.binding.ThingActions;
|
||||
import org.openhab.core.thing.binding.ThingActionsScope;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
/**
|
||||
* The {@link UniFiSiteActions} class defines rule actions for creating guest hotspot vouchers
|
||||
*
|
||||
* @author Mark Herwege - Initial contribution
|
||||
*/
|
||||
@ThingActionsScope(name = "unifi")
|
||||
@NonNullByDefault
|
||||
public class UniFiSiteActions implements ThingActions {
|
||||
|
||||
private static final int DEFAULT_COUNT = 1;
|
||||
private static final int DEFAULT_EXPIRE_MIN = 1440;
|
||||
private static final int DEFAULT_USERS = 1;
|
||||
|
||||
private static final Pattern NON_DIGITS_PATTERN = Pattern.compile("\\D+");
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(UniFiSiteActions.class);
|
||||
|
||||
private @Nullable UniFiSiteThingHandler handler;
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
@RuleAction(label = "@text/action.unifi.generateVouchers.label", description = "@text/action.unifi.generateVouchers.description")
|
||||
public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean generateVoucher(
|
||||
/* @formatter:off */
|
||||
@ActionInput(name = "expire",
|
||||
label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherExpiration.label",
|
||||
description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherExpiration.description") @Nullable Integer expire,
|
||||
@ActionInput(name = "users",
|
||||
label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherUsers.label",
|
||||
description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherUsers.description") @Nullable Integer users,
|
||||
@ActionInput(name = "upLimit",
|
||||
label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherUpLimit.label",
|
||||
description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherUpLimit.description") @Nullable Integer upLimit,
|
||||
@ActionInput(name = "downLimit",
|
||||
label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherDownLimit.label",
|
||||
description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherDownLimit.description") @Nullable Integer downLimit,
|
||||
@ActionInput(name = "dataQuota",
|
||||
label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherDataQuota.label",
|
||||
description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherDataQuota.description") @Nullable Integer dataQuota) {
|
||||
/* @formatter:on */
|
||||
return generateVouchers(1, expire, users, upLimit, downLimit, dataQuota);
|
||||
}
|
||||
|
||||
@RuleAction(label = "@text/action.unifi.generateVouchers.label", description = "@text/action.unifi.generateVouchers.description")
|
||||
public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean generateVouchers(
|
||||
/* @formatter:off */
|
||||
@ActionInput(name = "count",
|
||||
label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherCount.label",
|
||||
description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherCount.description") @Nullable Integer count,
|
||||
@ActionInput(name = "expire",
|
||||
label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherExpiration.label",
|
||||
description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherExpiration.description") @Nullable Integer expire,
|
||||
@ActionInput(name = "users",
|
||||
label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherUsers.label",
|
||||
description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherUsers.description") @Nullable Integer users,
|
||||
@ActionInput(name = "upLimit",
|
||||
label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherUpLimit.label",
|
||||
description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherUpLimit.description") @Nullable Integer upLimit,
|
||||
@ActionInput(name = "downLimit",
|
||||
label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherDownLimit.label",
|
||||
description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherDownLimit.description") @Nullable Integer downLimit,
|
||||
@ActionInput(name = "dataQuota",
|
||||
label = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherDataQuota.label",
|
||||
description = "@text/channel-type.config.unifi.guestVouchersGenerate.voucherDataQuota.description") @Nullable Integer dataQuota) {
|
||||
/* @formatter:on */
|
||||
UniFiSiteThingHandler handler = this.handler;
|
||||
if (handler == null) {
|
||||
logger.debug("Could not create guest vouchers, site thing handler not set");
|
||||
return false;
|
||||
}
|
||||
final @Nullable UniFiSite entity = handler.getEntity();
|
||||
final UniFiController controller = handler.getController();
|
||||
if (entity == null || controller == null) {
|
||||
logger.debug("Could not create guest vouchers, site thing error");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
controller.generateVouchers(entity, ((count != null) && (count != 0)) ? count : DEFAULT_COUNT,
|
||||
(expire != null) ? expire : DEFAULT_EXPIRE_MIN, (users != null) ? users : DEFAULT_USERS, upLimit,
|
||||
downLimit, dataQuota);
|
||||
} catch (UniFiException e) {
|
||||
logger.debug("Could not create guest vouchers, uniFi exception", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean generateVoucher(ThingActions actions) {
|
||||
return UniFiSiteActions.generateVoucher(actions, DEFAULT_EXPIRE_MIN);
|
||||
}
|
||||
|
||||
public static boolean generateVoucher(ThingActions actions, @Nullable Integer expire) {
|
||||
return UniFiSiteActions.generateVoucher(actions, expire, DEFAULT_USERS);
|
||||
}
|
||||
|
||||
public static boolean generateVoucher(ThingActions actions, @Nullable Integer expire, @Nullable Integer users) {
|
||||
return UniFiSiteActions.generateVoucher(actions, expire, users, null, null, null);
|
||||
}
|
||||
|
||||
public static boolean generateVoucher(ThingActions actions, @Nullable Integer expire, @Nullable Integer users,
|
||||
@Nullable Integer upLimit, @Nullable Integer downLimit, @Nullable Integer dataQuota) {
|
||||
return ((UniFiSiteActions) actions).generateVoucher(expire, users, upLimit, downLimit, dataQuota);
|
||||
}
|
||||
|
||||
public static boolean generateVouchers(ThingActions actions) {
|
||||
return UniFiSiteActions.generateVouchers(actions, DEFAULT_COUNT);
|
||||
}
|
||||
|
||||
public static boolean generateVouchers(ThingActions actions, @Nullable Integer count) {
|
||||
return UniFiSiteActions.generateVouchers(actions, count, DEFAULT_EXPIRE_MIN);
|
||||
}
|
||||
|
||||
public static boolean generateVouchers(ThingActions actions, @Nullable Integer count, @Nullable Integer expire) {
|
||||
return UniFiSiteActions.generateVouchers(actions, count, expire, DEFAULT_USERS);
|
||||
}
|
||||
|
||||
public static boolean generateVouchers(ThingActions actions, @Nullable Integer count, @Nullable Integer expire,
|
||||
@Nullable Integer users) {
|
||||
return UniFiSiteActions.generateVouchers(actions, count, expire, users, null, null, null);
|
||||
}
|
||||
|
||||
public static boolean generateVouchers(ThingActions actions, @Nullable Integer count, @Nullable Integer expire,
|
||||
@Nullable Integer users, @Nullable Integer upLimit, @Nullable Integer downLimit,
|
||||
@Nullable Integer dataQuota) {
|
||||
return ((UniFiSiteActions) actions).generateVouchers(count, expire, users, upLimit, downLimit, dataQuota);
|
||||
}
|
||||
|
||||
@RuleAction(label = "@text/action.unifi.revokeVouchers.label", description = "@text/action.unifi.revokeVouchers.description")
|
||||
public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean revokeVoucher(
|
||||
/* @formatter:off */
|
||||
@ActionInput(name = "voucherCodes", label = "@text/action.unifi.vouchersInputVoucherCodes.label",
|
||||
description = "@text/action.unifi.vouchersInputVoucherCodes.description") String voucherCode) {
|
||||
/* @formatter:on */
|
||||
return revokeVouchers(List.of(voucherCode));
|
||||
}
|
||||
|
||||
@RuleAction(label = "@text/action.unifi.revokeVouchers.label", description = "@text/action.unifi.revokeVouchers.description")
|
||||
public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean revokeVouchers(
|
||||
/* @formatter:off */
|
||||
@ActionInput(name = "voucherCodes", label = "@text/action.unifi.vouchersInputVoucherCodes.label",
|
||||
description = "@text/action.unifi.vouchersInputVoucherCodes.description") List<String> voucherCodes) {
|
||||
/* @formatter:on */
|
||||
UniFiSiteThingHandler handler = this.handler;
|
||||
if (handler == null) {
|
||||
logger.debug("Could not revoke guest vouchers, site thing handler not set");
|
||||
return false;
|
||||
}
|
||||
final @Nullable UniFiSite entity = handler.getEntity();
|
||||
final UniFiController controller = handler.getController();
|
||||
if (entity == null || controller == null) {
|
||||
logger.debug("Could not revoke guest vouchers, site thing error");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only keep digits in provided codes, so matching is done correctly. This makes blanks and dashes in the input
|
||||
// possible, as shown in the UniFi voucher UI.
|
||||
List<String> cleanCodes = voucherCodes.stream().map(c -> NON_DIGITS_PATTERN.matcher(c).replaceAll(""))
|
||||
.filter(c -> !c.isEmpty()).toList();
|
||||
Stream<UniFiVoucher> voucherStream = entity.getCache().getVoucherStreamForSite(entity);
|
||||
// If no codes provided, revoke all codes
|
||||
List<UniFiVoucher> vouchers = (voucherCodes.isEmpty() ? voucherStream
|
||||
: voucherStream.filter(v -> cleanCodes.contains(v.getCode()))).toList();
|
||||
try {
|
||||
controller.revokeVouchers(entity, vouchers);
|
||||
} catch (UniFiException e) {
|
||||
logger.debug("Could not revoke guest vouchers, uniFi exception", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@RuleAction(label = "@text/action.unifi.revokeAllVouchers.label", description = "@text/action.unifi.revokeAllVouchers.description")
|
||||
public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean revokeAllVouchers() {
|
||||
return revokeVouchers(List.of());
|
||||
}
|
||||
|
||||
public static boolean revokeVoucher(ThingActions actions, String voucherCode) {
|
||||
return revokeVouchers(actions, List.of(voucherCode));
|
||||
}
|
||||
|
||||
public static boolean revokeVouchers(ThingActions actions, List<String> voucherCodes) {
|
||||
return ((UniFiSiteActions) actions).revokeVouchers(voucherCodes);
|
||||
}
|
||||
|
||||
public static boolean revokeAllVouchers(ThingActions actions) {
|
||||
return revokeVouchers(actions);
|
||||
}
|
||||
|
||||
public static boolean revokeVouchers(ThingActions actions) {
|
||||
return revokeVouchers(actions, List.of());
|
||||
}
|
||||
|
||||
@RuleAction(label = "@text/action.unifi.listVouchers.label", description = "@text/action.unifi.listVouchers.description")
|
||||
public @ActionOutput(name = "vouchers", type = "java.lang.String") String listVouchers() {
|
||||
UniFiSiteThingHandler handler = this.handler;
|
||||
if (handler == null) {
|
||||
logger.debug("Could not list guest vouchers, site thing handler not set");
|
||||
return "";
|
||||
}
|
||||
final @Nullable UniFiSite entity = handler.getEntity();
|
||||
if (entity == null) {
|
||||
logger.debug("Could not list guest vouchers, site thing error");
|
||||
return "";
|
||||
}
|
||||
|
||||
record Voucher(String code, String createTime, Integer duration, Integer quota, Integer used,
|
||||
Integer qosUsageQuota, Integer qosRateMaxUp, Integer qosRateMaxDown, Boolean qosOverwrite, String note,
|
||||
String status) {
|
||||
}
|
||||
|
||||
return gson
|
||||
.toJson(entity.getCache().getVoucherStreamForSite(entity)
|
||||
.collect(Collectors.mapping(
|
||||
v -> new Voucher(v.getCode(), v.getCreateTime().toString(), v.getDuration(),
|
||||
v.getQuota(), v.getUsed(), v.getQosUsageQuota(), v.getQosRateMaxUp(),
|
||||
v.getQosRateMaxDown(), v.isQosOverwrite(), v.getNote(), v.getStatus()),
|
||||
Collectors.toList())));
|
||||
}
|
||||
|
||||
public static String listVouchers(ThingActions actions) {
|
||||
return ((UniFiSiteActions) actions).listVouchers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThingHandler(ThingHandler handler) {
|
||||
if (handler instanceof UniFiSiteThingHandler) {
|
||||
this.handler = (UniFiSiteThingHandler) handler;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ThingHandler getThingHandler() {
|
||||
return handler;
|
||||
}
|
||||
}
|
@ -215,7 +215,7 @@ public class UniFiController {
|
||||
refresh();
|
||||
}
|
||||
|
||||
public void generateGuestVouchers(final UniFiSite site, final int count, final int expiration, final int users,
|
||||
public void generateVouchers(final UniFiSite site, final int count, final int expiration, final int users,
|
||||
@Nullable Integer upLimit, @Nullable Integer downLimit, @Nullable Integer dataQuota) throws UniFiException {
|
||||
final UniFiControllerRequest<Void> req = newRequest(Void.class, HttpMethod.POST, gson);
|
||||
req.setAPIPath(String.format("/api/s/%s/cmd/hotspot", site.getName()));
|
||||
@ -236,6 +236,17 @@ public class UniFiController {
|
||||
refresh();
|
||||
}
|
||||
|
||||
public void revokeVouchers(final UniFiSite site, final List<UniFiVoucher> vouchers) throws UniFiException {
|
||||
for (UniFiVoucher voucher : vouchers) {
|
||||
final UniFiControllerRequest<Void> req = newRequest(Void.class, HttpMethod.POST, gson);
|
||||
req.setAPIPath(String.format("/api/s/%s/cmd/hotspot", site.getName()));
|
||||
req.setBodyParameter("cmd", "delete-voucher");
|
||||
req.setBodyParameter("_id", voucher.getId());
|
||||
executeRequest(req);
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
// Internal API
|
||||
|
||||
private <T> UniFiControllerRequest<T> newRequest(final Class<T> responseType, final HttpMethod method,
|
||||
|
@ -40,8 +40,11 @@ public class UniFiVoucher implements HasId {
|
||||
private Integer duration;
|
||||
private Integer quota;
|
||||
private Integer used;
|
||||
private boolean qosOverwrite;
|
||||
private Integer qosUsageQuota;
|
||||
private Integer qosRateMaxUp;
|
||||
private Integer qosRateMaxDown;
|
||||
private boolean qosOverwrite;
|
||||
private String note;
|
||||
private String status;
|
||||
|
||||
public UniFiVoucher(final UniFiControllerCache cache) {
|
||||
@ -73,12 +76,24 @@ public class UniFiVoucher implements HasId {
|
||||
return used;
|
||||
}
|
||||
|
||||
public Integer getQosUsageQuota() {
|
||||
return qosUsageQuota;
|
||||
}
|
||||
|
||||
public Integer getQosRateMaxUp() {
|
||||
return qosRateMaxUp;
|
||||
}
|
||||
|
||||
public Integer getQosRateMaxDown() {
|
||||
return qosRateMaxDown;
|
||||
}
|
||||
|
||||
public boolean isQosOverwrite() {
|
||||
return qosOverwrite;
|
||||
}
|
||||
|
||||
public Integer getQosUsageQuota() {
|
||||
return qosUsageQuota;
|
||||
public String getNote() {
|
||||
return note;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
@ -92,7 +107,9 @@ public class UniFiVoucher implements HasId {
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"UniFiVoucher{id: '%s', code: '%s', created: '%s', duration: '%s', quota: '%s', used: '%s', qosUsageQuota: '%s', status: '%s', site: %s}",
|
||||
id, code, createTime, duration, quota, used, qosUsageQuota, status, getSite());
|
||||
"UniFiVoucher{id: '%s', code: '%s', created: '%s', duration: '%s', quota: '%s', used: '%s', qosUsageQuota: '%s', "
|
||||
+ "qosRateMaxUp: '%s', qosRateMaxDown: '%s', qosOverwrite: '%s', note: '%s', status: '%s', site: %s}",
|
||||
id, code, createTime, duration, quota, used, qosUsageQuota, qosRateMaxUp, qosRateMaxDown, qosOverwrite,
|
||||
note, status, getSite());
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,7 @@
|
||||
*/
|
||||
package org.openhab.binding.unifi.internal.handler;
|
||||
|
||||
import static org.openhab.core.thing.ThingStatus.OFFLINE;
|
||||
import static org.openhab.core.thing.ThingStatus.ONLINE;
|
||||
import static org.openhab.core.thing.ThingStatus.*;
|
||||
import static org.openhab.core.types.RefreshType.REFRESH;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
@ -81,7 +80,7 @@ public abstract class UniFiBaseThingHandler<E, C> extends BaseThingHandler {
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("null")
|
||||
private final @Nullable UniFiController getController() {
|
||||
public final @Nullable UniFiController getController() {
|
||||
final Bridge bridge = getBridge();
|
||||
if (bridge != null && bridge.getHandler() != null
|
||||
&& (bridge.getHandler() instanceof UniFiControllerThingHandler)) {
|
||||
@ -90,7 +89,8 @@ public abstract class UniFiBaseThingHandler<E, C> extends BaseThingHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
private @Nullable E getEntity() {
|
||||
@Nullable
|
||||
public E getEntity() {
|
||||
final UniFiController controller = getController();
|
||||
return controller == null ? null : getEntity(controller.getCache());
|
||||
}
|
||||
|
@ -12,19 +12,17 @@
|
||||
*/
|
||||
package org.openhab.binding.unifi.internal.handler;
|
||||
|
||||
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_GUEST_CLIENTS;
|
||||
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_GUEST_VOUCHER;
|
||||
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_GUEST_VOUCHERS_GENERATE;
|
||||
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_TOTAL_CLIENTS;
|
||||
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_WIRED_CLIENTS;
|
||||
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_WIRELESS_CLIENTS;
|
||||
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.unifi.internal.UniFiSiteThingConfig;
|
||||
import org.openhab.binding.unifi.internal.UniFiVoucherChannelConfig;
|
||||
import org.openhab.binding.unifi.internal.action.UniFiSiteActions;
|
||||
import org.openhab.binding.unifi.internal.api.UniFiController;
|
||||
import org.openhab.binding.unifi.internal.api.UniFiException;
|
||||
import org.openhab.binding.unifi.internal.api.cache.UniFiControllerCache;
|
||||
@ -38,6 +36,7 @@ import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
@ -127,9 +126,14 @@ public class UniFiSiteThingHandler extends UniFiBaseThingHandler<UniFiSite, UniF
|
||||
final Integer upLimit = config.getUpLimit();
|
||||
final Integer downLimit = config.getDownLimit();
|
||||
final Integer dataQuota = config.getDataQuota();
|
||||
controller.generateGuestVouchers(entity, count, expire, users, upLimit, downLimit, dataQuota);
|
||||
controller.generateVouchers(entity, count, expire, users, upLimit, downLimit, dataQuota);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Class<? extends ThingHandlerService>> getServices() {
|
||||
return Collections.singleton(UniFiSiteActions.class);
|
||||
}
|
||||
}
|
||||
|
@ -150,6 +150,19 @@ channel-type.config.unifi.poeEnable.mode.description = The value to set when set
|
||||
channel-type.config.unifi.poeEnable.mode.option.auto = Auto
|
||||
channel-type.config.unifi.poeEnable.mode.option.pasv24 = 24V
|
||||
channel-type.config.unifi.poeEnable.mode.option.passthrough = Passthrough
|
||||
channel-type.config.unifi.guestVouchersGenerate.voucherCount.label = Number
|
||||
channel-type.config.unifi.guestVouchersGenerate.voucherCount.description = Number of vouchers to create
|
||||
channel-type.config.unifi.guestVouchersGenerate.voucherExpiration.label = Expiration Time
|
||||
channel-type.config.unifi.guestVouchersGenerate.voucherExpiration.description = Minutes a voucher is valid after activation
|
||||
channel-type.config.unifi.guestVouchersGenerate.voucherUsers.label = Users
|
||||
channel-type.config.unifi.guestVouchersGenerate.voucherUsers.description = Number of users for voucher, 0 if no limit
|
||||
channel-type.config.unifi.guestVouchersGenerate.voucherUpLimit.label = Upload Speed Limit
|
||||
channel-type.config.unifi.guestVouchersGenerate.voucherUpLimit.description = Upload speed limit in kbps, no limit if not set
|
||||
channel-type.config.unifi.guestVouchersGenerate.voucherDownLimit.label = Download Speed Limit
|
||||
channel-type.config.unifi.guestVouchersGenerate.voucherDownLimit.description = Download speed limit in kbps, no limit if not set
|
||||
channel-type.config.unifi.guestVouchersGenerate.voucherDataQuota.label = Data Transfer Quota
|
||||
channel-type.config.unifi.guestVouchersGenerate.voucherDataQuota.description = Data transfer quota in MB per user, no limit if not set
|
||||
channel-type.config.unifi.guestVouchersGenerate.option.GENERATE = Generate
|
||||
|
||||
# status messages
|
||||
|
||||
@ -164,3 +177,16 @@ error.thing.offline.configuration_error = You must choose a UniFi Controller for
|
||||
error.thing.poe.offline.configuration_error = The configuration parameter macAddress must be set and not be empty.
|
||||
error.thing.poe.offline.nodata_error = No data for the PoE port could be found in the UniFi API data. See TRACE log for actual API data.
|
||||
error.thing.site.offline.configuration_error = The configuration parameter sid must be set and not be empty.
|
||||
|
||||
# actions
|
||||
|
||||
action.unifi.generateVouchers.label = Generate
|
||||
action.unifi.generateVouchers.description = Generate guest voucher(s)
|
||||
action.unifi.revokeAllVouchers.label = Revoke All
|
||||
action.unifi.revokeAllVouchers.description = Revoke all guest vouchers
|
||||
action.unifi.revokeVouchers.label = Revoke
|
||||
action.unifi.revokeVouchers.description = Revoke guest voucher(s)
|
||||
action.unifi.vouchersInputVoucherCodes.label = Voucher Code(s)
|
||||
action.unifi.vouchersInputVoucherCodes.description = Code(s) of voucher(s) to revoke
|
||||
action.unifi.listVouchers.label = List Vouchers
|
||||
action.unifi.listVouchers.description = List available vouchers with their parameters and status
|
||||
|
Loading…
x
Reference in New Issue
Block a user