mirror of
https://github.com/danieldemus/openhab-addons
synced 2026-07-29 12:34:21 +02:00
[tapocontrol] Add TP-Link HS200 Kasa Smart Wi-Fi Light Switch (#19924)
* Support TP-Link Smart Switches HS200 Signed-off-by: Simmon Yau <simmonyau@gmail.com>
This commit is contained in:
@@ -24,8 +24,9 @@ The following Tapo-Devices are supported. For precise channel-description look a
|
||||
| Smart Contact Sensor (RF) | T110 | Window/Door Smart Contact Sensor |
|
||||
| Smart Temperature Sensor (RF) | T310 | Temperature and Humidity Sensor |
|
||||
| | T315 | Temperature and Humidity Sensor with Display |
|
||||
| Smart Switch (RF) | S210 | Wall switch with 1 contact |
|
||||
| Smart Switch (RF) | S220 | Wall switch with 2 contacts |
|
||||
| Smart Switch (RF) | S210 | Wall switch with 1 contact |
|
||||
| Smart Switch (RF) | S220 | Wall switch with 2 contacts |
|
||||
| Smart Light Switch (Wi-Fi) | HS200 | Wall switch with 1 contact |
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -91,29 +92,29 @@ The things has the following configuration parameters:
|
||||
|
||||
All devices support some of the following channels:
|
||||
|
||||
| group | channel | type | description | things supporting this channel |
|
||||
|-----------|----------------- |------------------------|-------------------------------------|------------------------------------------------------------------|
|
||||
| actuator | output | Switch | Power device on or off | P100, P105, P110, P115, L510, L530, L610, L630, L900, L920, L930 |
|
||||
| | output1 | Switch | Power socket 1 on or off | P300 |
|
||||
| | output2 | Switch | Power socket 2 on or off | P300 |
|
||||
| | output3 | Switch | Power socket 3 on or off | P300 |
|
||||
| | brightness | Dimmer | Brightness 0-100% | L510, L530, L610, L630, L900, L920 |
|
||||
| | colorTemperature | Number:Temperature | Color Temperature in Kelvin | L530 (2500 K .. 6500 K), L630 (2200 K .. 6500 K) |
|
||||
| | color | Color | Color | L530, L630, L900, L920 |
|
||||
| sensor | isOpen | Switch | Contact (Door/Window) is Open | T110 |
|
||||
| | currentTemp | Number:Temperature | Current Temperature | T310, T315 |
|
||||
| | currentHumidity | Number:Dimensionless | Current relative humidity in % | T310, T315 |
|
||||
| effects | fxName | String | Active lightning effect | L530, L900, L920, L930 |
|
||||
| device | wifiSignal | Number | WiFi-quality-level | P100, P105, P110, P115, L510, L530, L610, L630, L900, L920, L930 |
|
||||
| | onTime | Number:Time | seconds output is on | P100, P105, P110, P115, L510, L530, L900, L920, L930 |
|
||||
| | signalStrength | Number | RF-quality-level | T110 |
|
||||
| | isOnline | Switch | Device is Online | T110 |
|
||||
| | batteryLow | Switch | Battery of device is low | T110 |
|
||||
| energy | actualPower | Number:Power | actual Power (Watt) | P110, P115 |
|
||||
| | todayEnergyUsage | Number:Energy | used energy today (Wh) | P110, P115 |
|
||||
| | todayRuntime | Number:Time | seconds output was on today | P110, P115 |
|
||||
| alarm | alarmActive | Switch | Alarm is currntly active | H100 |
|
||||
| | alarmSource | String | Source causes active alarm | H100 |
|
||||
| group | channel | type | description | things supporting this channel |
|
||||
|-----------|----------------- |------------------------|-------------------------------------|-------------------------------------------------------------------------|
|
||||
| actuator | output | Switch | Power device on or off | P100, P105, P110, P115, L510, L530, L610, L630, L900, L920, L930, HS200 |
|
||||
| | output1 | Switch | Power socket 1 on or off | P300 |
|
||||
| | output2 | Switch | Power socket 2 on or off | P300 |
|
||||
| | output3 | Switch | Power socket 3 on or off | P300 |
|
||||
| | brightness | Dimmer | Brightness 0-100% | L510, L530, L610, L630, L900, L920 |
|
||||
| | colorTemperature | Number:Temperature | Color Temperature in Kelvin | L530 (2500 K .. 6500 K), L630 (2200 K .. 6500 K) |
|
||||
| | color | Color | Color | L530, L630, L900, L920 |
|
||||
| sensor | isOpen | Switch | Contact (Door/Window) is Open | T110 |
|
||||
| | currentTemp | Number:Temperature | Current Temperature | T310, T315 |
|
||||
| | currentHumidity | Number:Dimensionless | Current relative humidity in % | T310, T315 |
|
||||
| effects | fxName | String | Active lightning effect | L530, L900, L920, L930 |
|
||||
| device | wifiSignal | Number | WiFi-quality-level | P100, P105, P110, P115, L510, L530, L610, L630, L900, L920, L930 |
|
||||
| | onTime | Number:Time | seconds output is on | P100, P105, P110, P115, L510, L530, L900, L920, L930 |
|
||||
| | signalStrength | Number | RF-quality-level | T110 |
|
||||
| | isOnline | Switch | Device is Online | T110 |
|
||||
| | batteryLow | Switch | Battery of device is low | T110 |
|
||||
| energy | actualPower | Number:Power | actual Power (Watt) | P110, P115 |
|
||||
| | todayEnergyUsage | Number:Energy | used energy today (Wh) | P110, P115 |
|
||||
| | todayRuntime | Number:Time | seconds output was on today | P110, P115 |
|
||||
| alarm | alarmActive | Switch | Alarm is currntly active | H100 |
|
||||
| | alarmSource | String | Source causes active alarm | H100 |
|
||||
|
||||
## Channel Refresh
|
||||
|
||||
|
||||
+3
@@ -30,6 +30,7 @@ import org.openhab.binding.tapocontrol.internal.devices.wifi.TapoUniversalDevice
|
||||
import org.openhab.binding.tapocontrol.internal.devices.wifi.bulb.TapoBulbHandler;
|
||||
import org.openhab.binding.tapocontrol.internal.devices.wifi.hub.TapoHubHandler;
|
||||
import org.openhab.binding.tapocontrol.internal.devices.wifi.lightstrip.TapoLightStripHandler;
|
||||
import org.openhab.binding.tapocontrol.internal.devices.wifi.lightswitch.TapoLightSwitchHandler;
|
||||
import org.openhab.binding.tapocontrol.internal.devices.wifi.socket.TapoSocketHandler;
|
||||
import org.openhab.binding.tapocontrol.internal.devices.wifi.socket.TapoSocketStripHandler;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
@@ -133,6 +134,8 @@ public class TapoControlHandlerFactory extends BaseThingHandlerFactory {
|
||||
return new TapoWeatherSensorHandler(thing);
|
||||
} else if (SUPPORTED_SMART_SWITCHES.contains(thingTypeUID)) {
|
||||
return new TapoSmartSwitchHandler(thing);
|
||||
} else if (SUPPORTED_LIGHT_SWITCH_UIDS.contains(thingTypeUID)) {
|
||||
return new TapoLightSwitchHandler(thing);
|
||||
} else if (thingTypeUID.equals(UNIVERSAL_THING_TYPE)) {
|
||||
return new TapoUniversalDeviceHandler(thing);
|
||||
}
|
||||
|
||||
+8
-3
@@ -35,6 +35,7 @@ public class TapoThingConstants {
|
||||
/*** LIST OF SUPPORTED DEVICE NAMES ***/
|
||||
public static final String DEVICE_BRIDGE = "bridge";
|
||||
public static final String DEVICE_H100 = "H100";
|
||||
public static final String DEVICE_HS200 = "HS200";
|
||||
public static final String DEVICE_P100 = "P100";
|
||||
public static final String DEVICE_P105 = "P105";
|
||||
public static final String DEVICE_P110 = "P110";
|
||||
@@ -66,10 +67,12 @@ public class TapoThingConstants {
|
||||
public static final String DEVICE_DESCRIPTION_MOTION_SENSOR = "Motion-Sensor";
|
||||
public static final String DEVICE_DESCRIPTION_TEMP_SENSOR = "Temperature-Sensor";
|
||||
public static final String DEVICE_DESCRIPTION_SMART_SWITCH = "Smart-Switch";
|
||||
public static final String DEVICE_DESCRIPTION_LIGHT_SWITCH = "Light-Switch";
|
||||
|
||||
/*** LIST OF SUPPORTED THING UIDS ***/
|
||||
public static final ThingTypeUID BRIDGE_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_BRIDGE);
|
||||
public static final ThingTypeUID H100_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_H100);
|
||||
public static final ThingTypeUID HS200_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_HS200);
|
||||
public static final ThingTypeUID P100_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_P100);
|
||||
public static final ThingTypeUID P105_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_P105);
|
||||
public static final ThingTypeUID P110_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_P110);
|
||||
@@ -107,13 +110,15 @@ public class TapoThingConstants {
|
||||
public static final Set<ThingTypeUID> SUPPORTED_MOTION_SENSORS = Set.of();
|
||||
public static final Set<ThingTypeUID> SUPPORTED_WEATHER_SENSORS = Set.of(T310_THING_TYPE, T315_THING_TYPE);
|
||||
public static final Set<ThingTypeUID> SUPPORTED_SMART_SWITCHES = Set.of(S210_THING_TYPE, S220_THING_TYPE);
|
||||
public static final Set<ThingTypeUID> SUPPORTED_LIGHT_SWITCH_UIDS = Set.of(HS200_THING_TYPE);
|
||||
|
||||
/*** SET OF ALL SUPPORTED THINGS ***/
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.unmodifiableSet(
|
||||
Stream.of(SUPPORTED_BRIDGE_UIDS, SUPPORTED_HUB_UIDS, SUPPORTED_SOCKET_UIDS, SUPPORTED_SOCKET_STRIP_UIDS,
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.unmodifiableSet(Stream
|
||||
.of(SUPPORTED_BRIDGE_UIDS, SUPPORTED_HUB_UIDS, SUPPORTED_SOCKET_UIDS, SUPPORTED_SOCKET_STRIP_UIDS,
|
||||
SUPPORTED_WHITE_BULB_UIDS, SUPPORTED_COLOR_BULB_UIDS, SUPPORTED_LIGHT_STRIP_UIDS,
|
||||
SUPPORTED_SMART_CONTACTS, SUPPORTED_MOTION_SENSORS, SUPPORTED_WEATHER_SENSORS,
|
||||
SUPPORTED_SMART_SWITCHES).flatMap(Set::stream).collect(Collectors.toSet()));
|
||||
SUPPORTED_SMART_SWITCHES, SUPPORTED_LIGHT_SWITCH_UIDS)
|
||||
.flatMap(Set::stream).collect(Collectors.toSet()));
|
||||
|
||||
/*** THINGS WITH ENERGY DATA ***/
|
||||
public static final Set<ThingTypeUID> SUPPORTED_ENERGY_DATA_UIDS = Set.of(P110_THING_TYPE, P115_THING_TYPE);
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.tapocontrol.internal.devices.wifi.lightswitch;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.tapocontrol.internal.devices.dto.TapoBaseDeviceData;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@NonNullByDefault
|
||||
public class TapoLightSwitchData extends TapoBaseDeviceData {
|
||||
@SerializedName("device_on")
|
||||
@Expose(serialize = true, deserialize = true)
|
||||
private boolean deviceOn = false;
|
||||
|
||||
public void switchOnOff(boolean on) {
|
||||
deviceOn = on;
|
||||
}
|
||||
|
||||
public boolean isOn() {
|
||||
return deviceOn;
|
||||
}
|
||||
|
||||
public boolean isOff() {
|
||||
return !deviceOn;
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.tapocontrol.internal.devices.wifi.lightswitch;
|
||||
|
||||
import static org.openhab.binding.tapocontrol.internal.constants.TapoComConstants.*;
|
||||
import static org.openhab.binding.tapocontrol.internal.constants.TapoThingConstants.*;
|
||||
import static org.openhab.binding.tapocontrol.internal.helpers.utils.TypeUtils.*;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.tapocontrol.internal.devices.wifi.TapoBaseDeviceHandler;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Tapo Light Switch Handler
|
||||
*
|
||||
* @author Simmon Yau - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class TapoLightSwitchHandler extends TapoBaseDeviceHandler {
|
||||
private final Logger logger = LoggerFactory.getLogger(TapoLightSwitchHandler.class);
|
||||
private TapoLightSwitchData lightSwitchData = new TapoLightSwitchData();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param thing Thing object representing device
|
||||
*/
|
||||
public TapoLightSwitchHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void newDataResult(String queryCommand) {
|
||||
super.newDataResult(queryCommand);
|
||||
if (DEVICE_CMD_GETINFO.equals(queryCommand)) {
|
||||
lightSwitchData = connector.getResponseData(TapoLightSwitchData.class);
|
||||
updateChannels(lightSwitchData);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
String channel = channelUID.getIdWithoutGroup();
|
||||
if (command instanceof RefreshType) {
|
||||
queryDeviceData();
|
||||
} else {
|
||||
switch (channel) {
|
||||
case CHANNEL_OUTPUT:
|
||||
handleOnOffCommand(command);
|
||||
break;
|
||||
default:
|
||||
logger.warn("({}) command type '{}' not supported for channel '{}'", uid, command,
|
||||
channelUID.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleOnOffCommand(Command command) {
|
||||
switchOnOff(command == OnOffType.ON ? Boolean.TRUE : Boolean.FALSE);
|
||||
}
|
||||
|
||||
protected void switchOnOff(boolean on) {
|
||||
lightSwitchData.switchOnOff(on);
|
||||
connector.sendCommandAndQuery(lightSwitchData, true);
|
||||
}
|
||||
|
||||
protected void updateChannels(TapoLightSwitchData deviceData) {
|
||||
updateState(getChannelID(CHANNEL_GROUP_ACTUATOR, CHANNEL_OUTPUT), getOnOffType(deviceData.isOn()));
|
||||
}
|
||||
}
|
||||
+9
-1
@@ -107,6 +107,7 @@ public class TapoUtils {
|
||||
* @return mac address without any division chars
|
||||
*/
|
||||
public static String unformatMac(String mac) {
|
||||
mac = mac.toLowerCase();
|
||||
mac = mac.replace("-", "");
|
||||
mac = mac.replace(":", "");
|
||||
mac = mac.replace(".", "");
|
||||
@@ -136,7 +137,12 @@ public class TapoUtils {
|
||||
deviceModel = deviceModel.replace("Series", "");
|
||||
deviceModel = deviceModel.trim();
|
||||
deviceModel = deviceModel.replace(" ", "_");
|
||||
deviceModel = deviceModel.substring(0, 4);
|
||||
if (deviceModel.startsWith(DEVICE_HS200)) {
|
||||
deviceModel = DEVICE_HS200;
|
||||
} else {
|
||||
// Keep legacy behavior of only first 4 characters
|
||||
deviceModel = deviceModel.substring(0, 4);
|
||||
}
|
||||
return deviceModel;
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
@@ -174,6 +180,8 @@ public class TapoUtils {
|
||||
deviceLabel = DEVICE_DESCRIPTION_MOTION_SENSOR;
|
||||
} else if (SUPPORTED_WEATHER_SENSORS.contains(deviceUID)) {
|
||||
deviceLabel = DEVICE_DESCRIPTION_TEMP_SENSOR;
|
||||
} else if (SUPPORTED_LIGHT_SWITCH_UIDS.contains(deviceUID)) {
|
||||
deviceLabel = DEVICE_DESCRIPTION_LIGHT_SWITCH;
|
||||
}
|
||||
if (alias.length() > 0) {
|
||||
return String.format("%s %s %s (%s)", DEVICE_VENDOR, deviceModel, deviceLabel, alias);
|
||||
|
||||
+2
@@ -7,6 +7,8 @@ addon.tapocontrol.description = Control your TAPO-SmartHome Devices
|
||||
|
||||
thing-type.tapocontrol.H100.label = Tapo Hub H100
|
||||
thing-type.tapocontrol.H100.description = Tapo SmartHub H100
|
||||
thing-type.tapocontrol.HS200.label = HS200 Smart Light Switch
|
||||
thing-type.tapocontrol.HS200.description = TP-Link HS200 Kasa Smart Wi-Fi Light Switch
|
||||
thing-type.tapocontrol.L510.label = L510 Series White-Bulb
|
||||
thing-type.tapocontrol.L510.description = Tapo Smart dimmable White-Light-Bulb
|
||||
thing-type.tapocontrol.L530.label = L530 Series Color-Bulb
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="tapocontrol"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<!-- HS200 THING-TYPE (LIGHT SWITCH) -->
|
||||
<thing-type id="HS200">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="bridge"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>HS200 Smart Light Switch</label>
|
||||
<description>TP-Link HS200 Kasa Smart Wi-Fi Light Switch</description>
|
||||
<semantic-equipment-tag>WallSwitch</semantic-equipment-tag>
|
||||
<channel-groups>
|
||||
<channel-group id="actuator" typeId="lightSwitch"/>
|
||||
</channel-groups>
|
||||
<representation-property>macAddress</representation-property>
|
||||
|
||||
<config-description-ref uri="thing-type:tapo:device"/>
|
||||
</thing-type>
|
||||
</thing:thing-descriptions>
|
||||
+9
@@ -145,4 +145,13 @@
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<!-- Light Switch -->
|
||||
<channel-group-type id="lightSwitch">
|
||||
<label>Light Switch</label>
|
||||
<description>Tapo Smart Light Switch</description>
|
||||
<channels>
|
||||
<channel id="output" typeId="lightOn"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
|
||||
Reference in New Issue
Block a user