Skip to content

Commit

Permalink
[tapocontrol] new communication protocol integration / code revision (o…
Browse files Browse the repository at this point in the history
…penhab#15725)

* [tapocontrol] new tapo klap-protocol integration

Signed-off-by: Christian Wild <christian@wildclan.de>
  • Loading branch information
wildcs authored and lo92fr committed Apr 30, 2024
1 parent 34f8834 commit b7c2edd
Show file tree
Hide file tree
Showing 120 changed files with 10,531 additions and 5,607 deletions.
100 changes: 68 additions & 32 deletions bundles/org.openhab.binding.tapocontrol/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,24 @@ This binding adds support to control Tapo (Copyright © TP-Link Corporation Limi

The following Tapo-Devices are supported. For precise channel-description look at `channels-table` below

| DeviceType | ThingType | Description |
|------------------------------------|-------------|---------------------------------------------|
| SmartPlug (Wi-Fi) | P100 | Smart Socket |
| | P105 | Smart Mini Socket |
| EnergyMonitoring SmartPlug (Wi-Fi) | P110 | Energy Monitoring Smart Socket |
| | P115 | Energy Monitoring Mini Smart Socket |
| Power Strip (Wi-Fi) | P300 | Smart Wi-Fi Power Strip - 3 sockets |
| Dimmable SmartBulb (Wi-Fi) | L510 | Dimmable White-Light Smart-Bulb (E27) |
| | L610 | Dimmable White-Light Smart-Spot (GU10) |
| MultiColor SmartBulb (Wi-Fi) | L530 | Multicolor Smart-Bulb (E27) |
| | L630 | Multicolor Smart-Spot (GU10) |
| MultiColor LightStrip (Wi-Fi) | L900 | Multicolor RGB Dimmable LightStrip (5m) |
| | L920 | Multicolor RGB-IC ColorZone LightStrip (5m) |
| | L930 | Multicolor RGBW-IC 50-Zone LightStrip (5m) |
| DeviceType | ThingType | Description |
|------------------------------------|-------------|----------------------------------------------|
| SmartPlug (Wi-Fi) | P100 | Smart Socket |
| | P105 | Smart Mini Socket |
| EnergyMonitoring SmartPlug (Wi-Fi) | P110 | Energy Monitoring Smart Socket |
| | P115 | Energy Monitoring Mini Smart Socket |
| Power Strip (Wi-Fi) | P300 | Smart Wi-Fi Power Strip - 3 sockets |
| Dimmable SmartBulb (Wi-Fi) | L510 | Dimmable White-Light Smart-Bulb (E27) |
| | L610 | Dimmable White-Light Smart-Spot (GU10) |
| MultiColor SmartBulb (Wi-Fi) | L530 | Multicolor Smart-Bulb (E27) |
| | L630 | Multicolor Smart-Spot (GU10) |
| MultiColor LightStrip (Wi-Fi) | L900 | Multicolor RGB Dimmable LightStrip (5m) |
| | L920 | Multicolor RGB-IC ColorZone LightStrip (5m) |
| | L930 | Multicolor RGBW-IC 50-Zone LightStrip (5m) |
| Smart Hub (Wi-Fi / RF) | H100 | Smart Hub with Chime to control Child Devices|
| 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 |

## Prerequisites

Expand All @@ -32,9 +36,22 @@ To satisfy this requirement while keeping the device isolated, your router shoul

## Discovery

Discovery is done by connecting to the Tapo-Cloud Service.
All devices stored in your cloud account will be detected even if they are not in your network.
You need to know the IP-Adress of your device. This must be set manually in the thing configuration
For Wi-Fi-Devices, discovery is done by connecting to the Tapo-Cloud-Service or use local udp-discovery.
If enabled, all devices stored in your cloud account will be detected even if they are not in your local network.
From cloud you can get more informations such as "Device-Alias" as from udp-discovery.
But you need to know the IP-Adress of your device. This must be set manually in the thing configuration.

UDP-Discovery can find only devices which are online in your local network and get less informations as from cloud.
But therefore it set's device-ip and protocol automaticly.
If you have problems with udp-discovery, try to set the advanced setting 'broadcastAddress' to your local subnet ('e.g. 192.168.0.255').
Default is '255.255.255.255'

You can combine both discovery methods to get any informations from local devices.
If you enable setting 'onlyLocalOnlineDevices' results will only generated for local online devices but with the combined data of cloud discovery.
RF-Devices will be discovered by the hub they are connected to.
You can discover them manually or use ´backgroundDiscovery´

RF-Devices will be discovered by the hub they are connected to. You can discover them manually or use ´backgroundDiscovery´

## Bridge Configuration

Expand All @@ -43,21 +60,32 @@ This is used for device discovery and to create a handshake (cookie) to act with

The thing has the following configuration parameters:

| Parameter | Description |
|--------------------|----------------------------------------------------------------------|
| username | Username (eMail) of your Tapo-Cloud |
| password | Password of your Tapo-Cloud |
| Parameter | Description |
|------------------------|----------------------------------------------------------------------------------------------------------------|
| username | Username (eMail) of your Tapo-Cloud |
| password | Password of your Tapo-Cloud |
| cloudDiscovery | Use Cloud Discovery-Service to get all in Tapo-App registered devices. Includes DeviceName. IP-Address and Encryption has to set manually |
| udpDiscovery | Use UDP Discovery-Service to discover online devices in the local network. Includes Encryption and IP-Address. Results will be merged with cloud discovery |
| onlyLocalOnlineDevices | [advanced] Uses Cloud and UPD-Discovery to get more informations but will only discover online devices via UDP |
| broadcastAddress | [advanced] Set broadcast address to your local subnet if you have problems with default address |
| discoveryInterval | [advanced] Interval in minutes when a background device scan should be executed. Default is 60 |


## Thing Configuration

The thing needs to be configured with `ipAddress`.
WiFi-based things needs to be configured with `ipAddress`.
RF-based things need a SmartHub(WiFi-Device) to operate.

The thing has the following configuration parameters:
The things has the following configuration parameters:

| Parameter | Description | Things supporting parameter |
|--------------------|-----------------------------------------------------------------------|-----------------------------|
| ipAddress | IP Address of the device. | Any Wi-Fi-Device |
| pollingInterval | [optional] Refresh interval in seconds. The default is 30 seconds | Any Wi-Fi-Device |
| httpPort | [optional] HTTP-Communication Port. Default is 80 | Any Wi-Fi-Device |
| protocol | [optional] Used Communication Protocol (AES/KLAP/'') Default 'AES' | Any Wi-Fi-Device |
| backgroundDiscovery| [optional] RF-Devices will be discovered after every polling request | SmartHub |

| Parameter | Description |
|--------------------|----------------------------------------------------------------------|
| ipAddress | IP Address of the device. |
| pollingInterval | Refresh interval in seconds. Optional. The default is 30 seconds |

## Channels

Expand All @@ -72,12 +100,20 @@ All devices support some of the following channels:
| | brightness | Dimmer | Brightness 0-100% | L510, L530, L610, L630, L900, L920 |
| | colorTemperature | Number | White-Color-Temp 2500-6500K | L510, L530, L610, L630, L900, L920 |
| | color | Color | Color | L530, L630, L900, L920 |
| effects | fxName | String | Active lightning effect | L530 |
| 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

Expand All @@ -90,10 +126,10 @@ To minimize network traffic the default refresh-rate is set to 30 seconds. This

```java
tapocontrol:bridge:myTapoBridge "Cloud-Login" [ username="you@yourpovider.com", password="verysecret" ]
tapocontrol:P100:myTapoBridge:mySocket "My-Socket" (tapocontrol:bridge:myTapoBridge) [ ipAddress="192.168.178.150", pollingInterval=30 ]
tapocontrol:L510:myTapoBridge:whiteBulb "white-light" (tapocontrol:bridge:myTapoBridge) [ ipAddress="192.168.178.151", pollingInterval=30 ]
tapocontrol:L530:myTapoBridge:colorBulb "color-light" (tapocontrol:bridge:myTapoBridge) [ ipAddress="192.168.178.152", pollingInterval=30 ]
tapocontrol:L900:myTapoBridge:myLightStrip "light-strip" (tapocontrol:bridge:myTapoBridge) [ ipAddress="192.168.178.153", pollingInterval=30 ]
tapocontrol:P100:myTapoBridge:mySocket "My-Socket" (tapocontrol:bridge:myTapoBridge) [ ipAddress="192.168.178.150" ]
tapocontrol:L510:myTapoBridge:whiteBulb "white-light" (tapocontrol:bridge:myTapoBridge) [ ipAddress="192.168.178.151", httpPort=80, pollingInterval=30, protocol="AES" ]
tapocontrol:L530:myTapoBridge:colorBulb "color-light" (tapocontrol:bridge:myTapoBridge) [ ipAddress="192.168.178.152", pollingInterval=30, protocol="KLAP" ]
tapocontrol:L900:myTapoBridge:myLightStrip "light-strip" (tapocontrol:bridge:myTapoBridge) [ ipAddress="192.168.178.153", pollingInterval=30, protocol="" ]

Bridge tapocontrol:bridge:secondBridgeExample "Cloud-Login" [ username="youtoo@anyprovider.com", password="verysecret" ] {
Thing P110 mySocket "My-Socket" [ ipAddress="192.168.101.51", pollingInterval=30 ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,15 @@
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.openhab.binding.tapocontrol.internal.device.TapoBridgeHandler;
import org.openhab.binding.tapocontrol.internal.device.TapoLightStrip;
import org.openhab.binding.tapocontrol.internal.device.TapoSmartBulb;
import org.openhab.binding.tapocontrol.internal.device.TapoSmartPlug;
import org.openhab.binding.tapocontrol.internal.device.TapoUniversalDevice;
import org.openhab.binding.tapocontrol.internal.devices.bridge.TapoBridgeHandler;
import org.openhab.binding.tapocontrol.internal.devices.rf.smartcontact.TapoSmartContactHandler;
import org.openhab.binding.tapocontrol.internal.devices.rf.wheatersensor.TapoWheaterSensorHandler;
import org.openhab.binding.tapocontrol.internal.devices.wifi.TapoUniversalDeviceHandler;
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.socket.TapoSocketHandler;
import org.openhab.binding.tapocontrol.internal.devices.wifi.socket.TapoSocketStripHandler;
import org.openhab.core.io.net.http.HttpClientFactory;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
Expand All @@ -42,15 +46,20 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

/**
* The {@link ThingHandler} is responsible for handling commands, which are
* The {@link TapoControlHandlerFactory} is responsible for handling commands, which are
* sent to one of the channels.
*
* @author Christian Wild - Initial contribution
*/
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.tapocontrol")
@NonNullByDefault
public class TapoControlHandlerFactory extends BaseThingHandlerFactory {
public static final Gson GSON = new GsonBuilder().disableHtmlEscaping().excludeFieldsWithoutExposeAnnotation()
.create();
private final Logger logger = LoggerFactory.getLogger(TapoControlHandlerFactory.class);
private final Set<TapoBridgeHandler> accountHandlers = new HashSet<>();
private final HttpClient httpClient;
Expand Down Expand Up @@ -102,16 +111,24 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) {
TapoBridgeHandler bridgeHandler = new TapoBridgeHandler((Bridge) thing, httpClient);
accountHandlers.add(bridgeHandler);
return bridgeHandler;
} else if (SUPPORTED_SMART_PLUG_UIDS.contains(thingTypeUID)) {
return new TapoSmartPlug(thing);
} else if (SUPPORTED_HUB_UIDS.contains(thingTypeUID)) {
return new TapoHubHandler(thing);
} else if (SUPPORTED_SOCKET_UIDS.contains(thingTypeUID)) {
return new TapoSocketHandler(thing);
} else if (SUPPORTED_SOCKET_STRIP_UIDS.contains(thingTypeUID)) {
return new TapoSocketStripHandler(thing);
} else if (SUPPORTED_WHITE_BULB_UIDS.contains(thingTypeUID)) {
return new TapoSmartBulb(thing);
return new TapoBulbHandler(thing);
} else if (SUPPORTED_COLOR_BULB_UIDS.contains(thingTypeUID)) {
return new TapoSmartBulb(thing);
return new TapoBulbHandler(thing);
} else if (SUPPORTED_LIGHT_STRIP_UIDS.contains(thingTypeUID)) {
return new TapoLightStrip(thing);
return new TapoLightStripHandler(thing);
} else if (SUPPORTED_SMART_CONTACTS.contains(thingTypeUID)) {
return new TapoSmartContactHandler(thing);
} else if (SUPPORTED_WHEATHER_SENSORS.contains(thingTypeUID)) {
return new TapoWheaterSensorHandler(thing);
} else if (thingTypeUID.equals(UNIVERSAL_THING_TYPE)) {
return new TapoUniversalDevice(thing);
return new TapoUniversalDeviceHandler(thing);
}
return null;
}
Expand Down
Loading

0 comments on commit b7c2edd

Please sign in to comment.