From 16f3a3e85441e4d895106ee58f6a44dce3f011a8 Mon Sep 17 00:00:00 2001 From: Mark Herwege Date: Sat, 28 Jan 2023 21:30:12 +0100 Subject: [PATCH] [unifi] Guest wifi vouchers (#14284) * guest voucher support Signed-off-by: Mark Herwege --- bundles/org.openhab.binding.unifi/README.md | 26 +++-- .../unifi/internal/UniFiBindingConstants.java | 9 ++ .../internal/UniFiVoucherChannelConfig.java | 57 +++++++++++ .../unifi/internal/api/UniFiController.java | 41 +++++++- .../api/cache/UniFiControllerCache.java | 20 ++++ .../internal/api/cache/UniFiVoucherCache.java | 45 +++++++++ .../unifi/internal/api/dto/UniFiSite.java | 9 ++ .../unifi/internal/api/dto/UniFiVoucher.java | 98 +++++++++++++++++++ .../api/util/UniFiVoucherInstanceCreator.java | 48 +++++++++ .../handler/UniFiSiteThingHandler.java | 54 +++++++--- .../main/resources/OH-INF/config/config.xml | 30 ++++++ .../resources/OH-INF/thing/thing-types.xml | 21 ++++ 12 files changed, 440 insertions(+), 18 deletions(-) create mode 100644 bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/UniFiVoucherChannelConfig.java create mode 100644 bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/cache/UniFiVoucherCache.java create mode 100644 bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/dto/UniFiVoucher.java create mode 100644 bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/util/UniFiVoucherInstanceCreator.java diff --git a/bundles/org.openhab.binding.unifi/README.md b/bundles/org.openhab.binding.unifi/README.md index 8ac81e41c..fb812a2e2 100644 --- a/bundles/org.openhab.binding.unifi/README.md +++ b/bundles/org.openhab.binding.unifi/README.md @@ -113,12 +113,26 @@ The following table describes the `poePort` configuration parameters: The `site` information that is retrieved is available as these channels: -| Channel ID | Item Type | Description | Permissions | -|-----------------|-----------|--------------------------------------|-------------| -| totalClients | Number | Total number of clients connected | Read | -| wirelessClients | Number | Number of wireless clients connected | Read | -| wiredClients | Number | Number of wired clients connected | Read | -| guestClients | Number | Number of guest clients connected | Read | +| Channel ID | Item Type | Description | Permissions | +|-----------------------|-----------|------------------------------------------------------------------------|-------------| +| totalClients | Number | Total number of clients connected | Read | +| wirelessClients | Number | Number of wireless clients connected | Read | +| wiredClients | Number | Number of wired clients connected | Read | +| guestClients | Number | Number of guest clients connected | Read | +| guestVoucher | String | Guest voucher for access through the guest portal | Read | +| guestVouchersGenerate | String | Generate additional guest vouchers for access through the guest portal | Write | + +The `guestVouchersGenerate` string channel is a command only channel that will trigger voucher creation. +It has configuration parameters to tailor the vouchers created: + +| Parameter | Description | Config | Default | +| ------------------------ | --------------------------------------------------------------------------- |--------- | ------- | +| voucherCount | Number of vouchers to create | Optional | 1 | +| voucherExpiration | Minutes a voucher is valid after activation (default is 1 day) | Optional | 1440 | +| voucherUsers | Number of users for voucher, 0 for no limit | Optional | 1 | +| voucherUpLimit | Upload speed limit in kbps, no limit if not set | Optional | | +| voucherDownLimit | Download speed limit in kbps, no limit if not set | Optional | | +| voucherDataQuota | Data transfer quota in MB per user, no limit if not set | Optional | | ### `wlan` diff --git a/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/UniFiBindingConstants.java b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/UniFiBindingConstants.java index 23c70748d..7d36ef133 100644 --- a/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/UniFiBindingConstants.java +++ b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/UniFiBindingConstants.java @@ -24,6 +24,7 @@ import org.openhab.core.thing.ThingTypeUID; * @author Matthew Bowman - Initial contribution * @author Patrik Wimnell - Blocking / Unblocking client support * @author Hilbrand Bouwkamp - Added poePort + * @author Mark Herwege - Added guest vouchers */ @NonNullByDefault public final class UniFiBindingConstants { @@ -47,6 +48,8 @@ public final class UniFiBindingConstants { public static final String CHANNEL_WIRELESS_CLIENTS = "wirelessClients"; public static final String CHANNEL_WIRED_CLIENTS = "wiredClients"; public static final String CHANNEL_GUEST_CLIENTS = "guestClients"; + public static final String CHANNEL_GUEST_VOUCHER = "guestVoucher"; + public static final String CHANNEL_GUEST_VOUCHERS_GENERATE = "guestVouchersGenerate"; // List of wlan channels public static final String CHANNEL_SECURITY = "security"; @@ -98,6 +101,12 @@ public final class UniFiBindingConstants { public static final String PARAMETER_CID = "cid"; public static final String PARAMETER_SID = "sid"; public static final String PARAMETER_WID = "wid"; + public static final String PARAMETER_VOUCHER_COUNT = "voucherCount"; + public static final String PARAMETER_VOUCHER_EXPIRATION = "voucherExpiration"; + public static final String PARAMETER_VOUCHER_USERS = "voucherUsers"; + public static final String PARAMETER_VOUCHER_UP_LIMIT = "voucherUpLimit"; + public static final String PARAMETER_VOUCHER_DOWN_LIMIT = "voucherDownLimit"; + public static final String PARAMETER_VOUCHER_DATA_QUOTA = "voucherDataQuota"; public static final String PARAMETER_PORT_NUMBER = "portNumber"; public static final String PARAMETER_MAC_ADDRESS = "macAddress"; public static final String PARAMETER_WIFI_NAME = "wifi"; diff --git a/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/UniFiVoucherChannelConfig.java b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/UniFiVoucherChannelConfig.java new file mode 100644 index 000000000..5f8cc7a17 --- /dev/null +++ b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/UniFiVoucherChannelConfig.java @@ -0,0 +1,57 @@ +/** + * 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; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * The {@link UniFiVoucherChannelConfig} encapsulates all the configuration options for the guestVouchersGenerate + * channel on the UniFi Site thing. + * + * @author Mark Herwege - Initial contribution + */ +@NonNullByDefault +public class UniFiVoucherChannelConfig { + + private int voucherCount; + private int voucherExpiration; + private int voucherUsers; + private @Nullable Integer voucherUpLimit; + private @Nullable Integer voucherDownLimit; + private @Nullable Integer voucherDataQuota; + + public int getCount() { + return voucherCount; + } + + public int getExpiration() { + return voucherExpiration; + } + + public int getVoucherUsers() { + return voucherUsers; + } + + public @Nullable Integer getUpLimit() { + return voucherUpLimit; + } + + public @Nullable Integer getDownLimit() { + return voucherDownLimit; + } + + public @Nullable Integer getDataQuota() { + return voucherDataQuota; + } +} diff --git a/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/UniFiController.java b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/UniFiController.java index 09f363489..18467f9e6 100644 --- a/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/UniFiController.java +++ b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/UniFiController.java @@ -26,6 +26,7 @@ import org.openhab.binding.unifi.internal.api.dto.UniFiDevice; import org.openhab.binding.unifi.internal.api.dto.UniFiSite; import org.openhab.binding.unifi.internal.api.dto.UniFiSwitchPorts; import org.openhab.binding.unifi.internal.api.dto.UniFiUnknownClient; +import org.openhab.binding.unifi.internal.api.dto.UniFiVoucher; import org.openhab.binding.unifi.internal.api.dto.UniFiWiredClient; import org.openhab.binding.unifi.internal.api.dto.UniFiWirelessClient; import org.openhab.binding.unifi.internal.api.dto.UniFiWlan; @@ -34,6 +35,7 @@ import org.openhab.binding.unifi.internal.api.util.UniFiClientDeserializer; import org.openhab.binding.unifi.internal.api.util.UniFiClientInstanceCreator; import org.openhab.binding.unifi.internal.api.util.UniFiDeviceInstanceCreator; import org.openhab.binding.unifi.internal.api.util.UniFiSiteInstanceCreator; +import org.openhab.binding.unifi.internal.api.util.UniFiVoucherInstanceCreator; import org.openhab.binding.unifi.internal.api.util.UniFiWlanInstanceCreator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,6 +53,7 @@ import com.google.gson.JsonObject; * @author Patrik Wimnell - Blocking / Unblocking client support * @author Jacob Laursen - Fix online/blocked channels (broken by UniFi Controller 5.12.35) * @author Hilbrand Bouwkamp - Added POEPort support, moved generic cache related code to cache object + * @author Mark Herwege - Added guest vouchers */ @NonNullByDefault public class UniFiController { @@ -85,6 +88,7 @@ public class UniFiController { final UniFiWlanInstanceCreator wlanInstanceCreator = new UniFiWlanInstanceCreator(cache); final UniFiDeviceInstanceCreator deviceInstanceCreator = new UniFiDeviceInstanceCreator(cache); final UniFiClientInstanceCreator clientInstanceCreator = new UniFiClientInstanceCreator(cache); + final UniFiVoucherInstanceCreator voucherInstanceCreator = new UniFiVoucherInstanceCreator(cache); this.gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .registerTypeAdapter(UniFiSite.class, siteInstanceCreator) .registerTypeAdapter(UniFiWlan.class, wlanInstanceCreator) @@ -92,7 +96,8 @@ public class UniFiController { .registerTypeAdapter(UniFiClient.class, new UniFiClientDeserializer()) .registerTypeAdapter(UniFiUnknownClient.class, clientInstanceCreator) .registerTypeAdapter(UniFiWiredClient.class, clientInstanceCreator) - .registerTypeAdapter(UniFiWirelessClient.class, clientInstanceCreator).create(); + .registerTypeAdapter(UniFiWirelessClient.class, clientInstanceCreator) + .registerTypeAdapter(UniFiVoucher.class, voucherInstanceCreator).create(); this.poeGson = new GsonBuilder() .registerTypeAdapter(UnfiPortOverrideJsonObject.class, new UnfiPortOverrideJsonElementDeserializer()) .create(); @@ -146,6 +151,7 @@ public class UniFiController { refreshDevices(sites); refreshClients(sites); refreshInsights(sites); + refreshVouchers(sites); } } @@ -209,6 +215,27 @@ public class UniFiController { refresh(); } + public void generateGuestVouchers(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 req = newRequest(Void.class, HttpMethod.POST, gson); + req.setAPIPath(String.format("/api/s/%s/cmd/hotspot", site.getName())); + req.setBodyParameter("cmd", "create-voucher"); + req.setBodyParameter("expire", expiration); + req.setBodyParameter("n", count); + req.setBodyParameter("quota", users); + if (upLimit != null) { + req.setBodyParameter("up", upLimit); + } + if (downLimit != null) { + req.setBodyParameter("down", downLimit); + } + if (dataQuota != null) { + req.setBodyParameter("bytes", dataQuota); + } + executeRequest(req); + refresh(); + } + // Internal API private UniFiControllerRequest newRequest(final Class responseType, final HttpMethod method, @@ -284,6 +311,18 @@ public class UniFiController { return executeRequest(req); } + private void refreshVouchers(final Collection sites) throws UniFiException { + for (final UniFiSite site : sites) { + cache.putVouchers(getVouchers(site)); + } + } + + private UniFiVoucher @Nullable [] getVouchers(final UniFiSite site) throws UniFiException { + final UniFiControllerRequest req = newRequest(UniFiVoucher[].class, HttpMethod.GET, gson); + req.setAPIPath(String.format("/api/s/%s/stat/voucher", site.getName())); + return executeRequest(req); + } + private void refreshInsights(final Collection sites) throws UniFiException { for (final UniFiSite site : sites) { cache.putInsights(getInsights(site)); diff --git a/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/cache/UniFiControllerCache.java b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/cache/UniFiControllerCache.java index df0299f45..a38aeb4d0 100644 --- a/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/cache/UniFiControllerCache.java +++ b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/cache/UniFiControllerCache.java @@ -13,6 +13,7 @@ package org.openhab.binding.unifi.internal.api.cache; import java.util.Collection; +import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; @@ -27,6 +28,7 @@ import org.openhab.binding.unifi.internal.api.dto.UniFiDevice; import org.openhab.binding.unifi.internal.api.dto.UniFiPortTuple; import org.openhab.binding.unifi.internal.api.dto.UniFiSite; import org.openhab.binding.unifi.internal.api.dto.UniFiSwitchPorts; +import org.openhab.binding.unifi.internal.api.dto.UniFiVoucher; import org.openhab.binding.unifi.internal.api.dto.UniFiWlan; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,6 +38,7 @@ import org.slf4j.LoggerFactory; * * @author Matthew Bowman - Initial contribution * @author Hilbrand Bouwkamp - Moved cache to this dedicated class. + * @author Mark Herwege - Added guest vouchers */ @NonNullByDefault public class UniFiControllerCache { @@ -47,6 +50,7 @@ public class UniFiControllerCache { private final UniFiDeviceCache devicesCache = new UniFiDeviceCache(); private final UniFiClientCache clientsCache = new UniFiClientCache(); private final UniFiClientCache insightsCache = new UniFiClientCache(); + private final UniFiVoucherCache vouchersCache = new UniFiVoucherCache(); private final Map devicesToPortTables = new ConcurrentHashMap<>(); public void clear() { @@ -55,6 +59,7 @@ public class UniFiControllerCache { devicesCache.clear(); clientsCache.clear(); insightsCache.clear(); + vouchersCache.clear(); } // Sites Cache @@ -170,4 +175,19 @@ public class UniFiControllerCache { public void putInsights(final UniFiClient @Nullable [] insights) { insightsCache.putAll(insights); } + + // Vouchers Cache + + public void putVouchers(final UniFiVoucher @Nullable [] vouchers) { + vouchersCache.putAll(vouchers); + } + + public synchronized Stream getVoucherStreamForSite(final UniFiSite site) { + return vouchersCache.values().stream().filter(voucher -> voucher.getSite().equals(site)); + } + + public @Nullable UniFiVoucher getVoucher(final UniFiSite site) { + // Use one of the oldest vouchers first + return getVoucherStreamForSite(site).min(Comparator.comparing(UniFiVoucher::getCreateTime)).orElse(null); + } } diff --git a/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/cache/UniFiVoucherCache.java b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/cache/UniFiVoucherCache.java new file mode 100644 index 000000000..911f4389f --- /dev/null +++ b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/cache/UniFiVoucherCache.java @@ -0,0 +1,45 @@ +/** + * 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.api.cache; + +import static org.openhab.binding.unifi.internal.api.cache.UniFiCache.Prefix.ID; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.unifi.internal.api.dto.UniFiVoucher; + +/** + * The {@link UniFiVoucherCache} is a specific implementation of {@link UniFiCache} for the purpose of caching + * {@link UniFiVoucher} instances. + * + * The cache uses the following prefixes: id + * + * @author Mark Herwege - Initial contribution + */ +@NonNullByDefault +class UniFiVoucherCache extends UniFiCache { + + public UniFiVoucherCache() { + super(ID); + } + + @Override + protected @Nullable String getSuffix(final UniFiVoucher voucher, final Prefix prefix) { + switch (prefix) { + case ID: + return voucher.getId(); + default: + return null; + } + } +} diff --git a/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/dto/UniFiSite.java b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/dto/UniFiSite.java index 9eb04a656..9fc925195 100644 --- a/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/dto/UniFiSite.java +++ b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/dto/UniFiSite.java @@ -20,6 +20,7 @@ import com.google.gson.annotations.SerializedName; * The {@link UniFiSite} represents the data model of a UniFi site. * * @author Matthew Bowman - Initial contribution + * @author Mark Herwege - Added guest vouchers */ public class UniFiSite implements HasId { @@ -53,6 +54,14 @@ public class UniFiSite implements HasId { return cache; } + public String getVoucher() { + UniFiVoucher voucher = cache.getVoucher(this); + if (voucher == null) { + return null; + } + return voucher.getCode(); + } + public boolean isSite(final UniFiSite site) { return site != null && id.equals(site.getId()); } diff --git a/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/dto/UniFiVoucher.java b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/dto/UniFiVoucher.java new file mode 100644 index 000000000..5a62f6e2b --- /dev/null +++ b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/dto/UniFiVoucher.java @@ -0,0 +1,98 @@ +/** + * 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.api.dto; + +import java.time.Instant; + +import org.openhab.binding.unifi.internal.api.cache.UniFiControllerCache; +import org.openhab.binding.unifi.internal.api.util.UniFiTimestampDeserializer; + +import com.google.gson.annotations.JsonAdapter; +import com.google.gson.annotations.SerializedName; + +/** + * The {@link UniFiVoucher} is the base data model for a guest network voucher + * + * @author Mark Herwege - Initial contribution + */ +public class UniFiVoucher implements HasId { + + private final transient UniFiControllerCache cache; + + @SerializedName("_id") + private String id; + + private String siteId; + + private String code; + @JsonAdapter(UniFiTimestampDeserializer.class) + private Instant createTime; + private Integer duration; + private Integer quota; + private Integer used; + private boolean qosOverwrite; + private Integer qosUsageQuota; + private String status; + + public UniFiVoucher(final UniFiControllerCache cache) { + this.cache = cache; + } + + @Override + public String getId() { + return id; + } + + public String getCode() { + return code; + } + + public Instant getCreateTime() { + return createTime; + } + + public Integer getDuration() { + return duration; + } + + public Integer getQuota() { + return quota; + } + + public Integer getUsed() { + return used; + } + + public boolean isQosOverwrite() { + return qosOverwrite; + } + + public Integer getQosUsageQuota() { + return qosUsageQuota; + } + + public String getStatus() { + return status; + } + + public UniFiSite getSite() { + return cache.getSite(siteId); + } + + @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()); + } +} diff --git a/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/util/UniFiVoucherInstanceCreator.java b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/util/UniFiVoucherInstanceCreator.java new file mode 100644 index 000000000..d63c80e12 --- /dev/null +++ b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/util/UniFiVoucherInstanceCreator.java @@ -0,0 +1,48 @@ +/** + * 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.api.util; + +import java.lang.reflect.Type; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.unifi.internal.api.cache.UniFiControllerCache; +import org.openhab.binding.unifi.internal.api.dto.UniFiVoucher; + +import com.google.gson.InstanceCreator; +import com.google.gson.JsonSyntaxException; + +/** + * The {@link UniFiVoucherInstanceCreator} creates instances of {@link UniFiVoucher}s during the JSON unmarshalling of + * controller responses. + * + * @author Mark Herwege - Initial contribution + */ +@NonNullByDefault +public class UniFiVoucherInstanceCreator implements InstanceCreator { + + private final UniFiControllerCache cache; + + public UniFiVoucherInstanceCreator(final UniFiControllerCache cache) { + this.cache = cache; + } + + @Override + public UniFiVoucher createInstance(final @Nullable Type type) { + if (UniFiVoucher.class.equals(type)) { + return new UniFiVoucher(cache); + } else { + throw new JsonSyntaxException("Expected a UniFi Voucher type, but got " + type); + } + } +} diff --git a/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/handler/UniFiSiteThingHandler.java b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/handler/UniFiSiteThingHandler.java index 53ebb0969..2fa536349 100644 --- a/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/handler/UniFiSiteThingHandler.java +++ b/bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/handler/UniFiSiteThingHandler.java @@ -12,19 +12,23 @@ */ 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_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.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.api.UniFiController; import org.openhab.binding.unifi.internal.api.UniFiException; import org.openhab.binding.unifi.internal.api.cache.UniFiControllerCache; +import org.openhab.binding.unifi.internal.api.dto.UniFiClient; import org.openhab.binding.unifi.internal.api.dto.UniFiSite; import org.openhab.core.library.types.DecimalType; +import org.openhab.core.library.types.OnOffType; +import org.openhab.core.library.types.StringType; +import org.openhab.core.thing.Channel; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingStatus; @@ -39,6 +43,7 @@ import org.openhab.core.types.UnDefType; * * @author Matthew Bowman - Initial contribution * @author Hilbrand Bouwkamp - Initial contribution + * @author Mark Herwege - Added guest vouchers */ @NonNullByDefault public class UniFiSiteThingHandler extends UniFiBaseThingHandler { @@ -67,32 +72,59 @@ public class UniFiSiteThingHandler extends UniFiBaseThingHandler true); + state = countClients(site, c -> true); break; case CHANNEL_WIRELESS_CLIENTS: - count = cache.countClients(site, c -> c.isWireless()); + state = countClients(site, c -> c.isWireless()); break; case CHANNEL_WIRED_CLIENTS: - count = cache.countClients(site, c -> c.isWired()); + state = countClients(site, c -> c.isWired()); break; case CHANNEL_GUEST_CLIENTS: - count = cache.countClients(site, c -> c.isGuest()); + state = countClients(site, c -> c.isGuest()); + break; + case CHANNEL_GUEST_VOUCHER: + String voucher = site.getVoucher(); + state = (voucher != null) ? StringType.valueOf(voucher) : UnDefType.UNDEF; + break; + case CHANNEL_GUEST_VOUCHERS_GENERATE: + state = OnOffType.OFF; break; default: // Unsupported channel; nothing to update return UnDefType.NULL; } - return new DecimalType(count); + return state; + } + + private static State countClients(final UniFiSite site, final Predicate filter) { + return new DecimalType(site.getCache().countClients(site, filter)); } @Override protected boolean handleCommand(final UniFiController controller, final UniFiSite entity, final ChannelUID channelUID, final Command command) throws UniFiException { + final String channelID = channelUID.getId(); + + if (CHANNEL_GUEST_VOUCHERS_GENERATE.equals(channelID)) { + Channel channel = getThing().getChannel(CHANNEL_GUEST_VOUCHERS_GENERATE); + if (channel == null) { + return false; + } + UniFiVoucherChannelConfig config = channel.getConfiguration().as(UniFiVoucherChannelConfig.class); + final int count = config.getCount(); + final int expire = config.getExpiration(); + final int users = config.getVoucherUsers(); + final Integer upLimit = config.getUpLimit(); + final Integer downLimit = config.getDownLimit(); + final Integer dataQuota = config.getDataQuota(); + controller.generateGuestVouchers(entity, count, expire, users, upLimit, downLimit, dataQuota); + return true; + } return false; } } diff --git a/bundles/org.openhab.binding.unifi/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.binding.unifi/src/main/resources/OH-INF/config/config.xml index 1d5cc7881..fdd76010d 100644 --- a/bundles/org.openhab.binding.unifi/src/main/resources/OH-INF/config/config.xml +++ b/bundles/org.openhab.binding.unifi/src/main/resources/OH-INF/config/config.xml @@ -67,6 +67,36 @@ + + + + Number of vouchers to create + 1 + + + + Minutes a voucher is valid after activation + 1440 + + + + Number of users for voucher, 0 if no limit + 1 + + + + Upload speed limit in kbps, no limit if not set + + + + Download speed limit in kbps, no limit if not set + + + + Data transfer quota in MB per user, no limit if not set + + + diff --git a/bundles/org.openhab.binding.unifi/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.unifi/src/main/resources/OH-INF/thing/thing-types.xml index 132992cd5..640a10e51 100644 --- a/bundles/org.openhab.binding.unifi/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.unifi/src/main/resources/OH-INF/thing/thing-types.xml @@ -25,6 +25,8 @@ + + sid @@ -165,6 +167,25 @@ + + String + + Guest voucher for access through the guest portal + + + + + String + + Generate additional guest vouchers for access through the guest portal + + + + + + + + Switch