[unifi] Guest wifi vouchers (#14284)
* guest voucher support Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
This commit is contained in:
parent
aa7580965e
commit
16f3a3e854
|
@ -114,11 +114,25 @@ 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 |
|
||||
| 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`
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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<Void> 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 <T> UniFiControllerRequest<T> newRequest(final Class<T> responseType, final HttpMethod method,
|
||||
|
@ -284,6 +311,18 @@ public class UniFiController {
|
|||
return executeRequest(req);
|
||||
}
|
||||
|
||||
private void refreshVouchers(final Collection<UniFiSite> sites) throws UniFiException {
|
||||
for (final UniFiSite site : sites) {
|
||||
cache.putVouchers(getVouchers(site));
|
||||
}
|
||||
}
|
||||
|
||||
private UniFiVoucher @Nullable [] getVouchers(final UniFiSite site) throws UniFiException {
|
||||
final UniFiControllerRequest<UniFiVoucher[]> 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<UniFiSite> sites) throws UniFiException {
|
||||
for (final UniFiSite site : sites) {
|
||||
cache.putInsights(getInsights(site));
|
||||
|
|
|
@ -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<String, UniFiSwitchPorts> 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<UniFiVoucher> 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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: <code>id</code>
|
||||
*
|
||||
* @author Mark Herwege - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
class UniFiVoucherCache extends UniFiCache<UniFiVoucher> {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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<UniFiVoucher> {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<UniFiSite, UniFiSiteThingConfig> {
|
||||
|
@ -67,32 +72,59 @@ public class UniFiSiteThingHandler extends UniFiBaseThingHandler<UniFiSite, UniF
|
|||
|
||||
@Override
|
||||
protected State getChannelState(final UniFiSite site, final String channelId) {
|
||||
final UniFiControllerCache cache = site.getCache();
|
||||
final long count;
|
||||
final State state;
|
||||
|
||||
switch (channelId) {
|
||||
case CHANNEL_TOTAL_CLIENTS:
|
||||
count = cache.countClients(site, c -> 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<UniFiClient> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,36 @@
|
|||
</parameter>
|
||||
</config-description>
|
||||
|
||||
<config-description uri="channel-type:unifi:guestVouchersGenerate">
|
||||
<parameter name="voucherCount" type="integer">
|
||||
<label>Number</label>
|
||||
<description>Number of vouchers to create</description>
|
||||
<default>1</default>
|
||||
</parameter>
|
||||
<parameter name="voucherExpiration" type="integer" unit="min">
|
||||
<label>Expiration Time</label>
|
||||
<description>Minutes a voucher is valid after activation</description>
|
||||
<default>1440</default>
|
||||
</parameter>
|
||||
<parameter name="voucherUsers" type="integer">
|
||||
<label>Users</label>
|
||||
<description>Number of users for voucher, 0 if no limit</description>
|
||||
<default>1</default>
|
||||
</parameter>
|
||||
<parameter name="voucherUpLimit" type="integer">
|
||||
<label>Upload Speed Limit</label>
|
||||
<description>Upload speed limit in kbps, no limit if not set</description>
|
||||
</parameter>
|
||||
<parameter name="voucherDownLimit" type="integer">
|
||||
<label>Download Speed Limit</label>
|
||||
<description>Download speed limit in kbps, no limit if not set</description>
|
||||
</parameter>
|
||||
<parameter name="voucherDataQuota" type="integer">
|
||||
<label>Data Transfer Quota</label>
|
||||
<description>Data transfer quota in MB per user, no limit if not set</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
<config-description uri="thing-type:unifi:poePort">
|
||||
<parameter name="portNumber" type="integer" required="true">
|
||||
<label>Port Number</label>
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
<channel id="wirelessClients" typeId="wirelessClients"/>
|
||||
<channel id="wiredClients" typeId="wiredClients"/>
|
||||
<channel id="guestClients" typeId="guestClients"/>
|
||||
<channel id="guestVoucher" typeId="guestVoucher"/>
|
||||
<channel id="guestVouchersGenerate" typeId="guestVouchersGenerate"/>
|
||||
</channels>
|
||||
|
||||
<representation-property>sid</representation-property>
|
||||
|
@ -165,6 +167,25 @@
|
|||
<state readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="guestVoucher">
|
||||
<item-type>String</item-type>
|
||||
<label>Guest Voucher</label>
|
||||
<description>Guest voucher for access through the guest portal</description>
|
||||
<state readOnly="true"></state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="guestVouchersGenerate">
|
||||
<item-type>String</item-type>
|
||||
<label>Generate Guest Vouchers</label>
|
||||
<description>Generate additional guest vouchers for access through the guest portal</description>
|
||||
<command>
|
||||
<options>
|
||||
<option value="GENERATE">Generate</option>
|
||||
</options>
|
||||
</command>
|
||||
<config-description-ref uri="channel-type:unifi:guestVouchersGenerate"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="wlanEnable">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Enable</label>
|
||||
|
|
Loading…
Reference in New Issue