diff --git a/bundles/org.openhab.binding.tapocontrol/README.md b/bundles/org.openhab.binding.tapocontrol/README.md index 843f7cc5848..cd19010bcdf 100644 --- a/bundles/org.openhab.binding.tapocontrol/README.md +++ b/bundles/org.openhab.binding.tapocontrol/README.md @@ -6,12 +6,21 @@ This binding adds support to control Tapo (Copyright © TP-Link Corporation Limi The following Tapo-Devices are supported -### P100/P105/P110 SmartPlug (WiFi) +### P100/P105 SmartPlug (WiFi) * Power On/Off * Wi-Fi signal (SignalStrength) * On-Time (Time in seconds device is switched on) +### P110 EnergyMonitoring SmartPlug (WiFi) + +* Power On/Off +* Wi-Fi signal (SignalStrength) +* On-Time (Time in seconds device is switched on) +* actual PowerUsage (Watt) +* today EnergyUsage (Wh) +* today Runtime (Time in seconds device was on today) + ### L510(Series) dimmable SmartBulb (WiFi) * Light On/Off @@ -87,6 +96,9 @@ All devices support some of the following channels: | | color | Color | Color | L530, L900 | | device | wifiSignal | system.signal-strength | WiFi-quality-level | P100, P105, P110, L510, L530, L900, L920 | | | onTime | Number:Time | seconds output is on | P100, P105, P110, L510, L530, L900, L920 | +| energy | actualPower | Number:Power | actual Power (Watt) | P110 | +| | todayEnergyUsage | Number:Energy | used energy today (Wh) | P110 | +| | todayRuntime | Number:Time | seconds output was on today | P110 | ## Channel Refresh @@ -100,12 +112,16 @@ To minimize network traffic the default refresh-rate is set to 30 seconds. This ### tapocontrol.things: ``` -tapocontrol:bridge:myTapoBridge "Cloud-Login" [ username="you@yourpovider.com", password="verysecret" ] -tapocontrol:P100:myTapoBridge:mySocket "My-Socket" [ ipAddress="192.168.178.150", pollingInterval=30 ] -tapocontrol:L510:myTapoBridge:whiteBulb "white-light" [ ipAddress="192.168.178.151", pollingInterval=30 ] -tapocontrol:L530:myTapoBridge:colorBulb "color-light" [ ipAddress="192.168.178.152", pollingInterval=30 ] -tapocontrol:L900:myTapoBridge:myLightStrip "light-strip" [ ipAddress="192.168.178.153", pollingInterval=30 ] -``` +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 ] + +Bridge tapocontrol:bridge:secondBridgeExample "Cloud-Login" [ username="youtoo@anyprovider.com", password="verysecret" ] { + Thing tapocontrol:P110:secondBridgeExample:mySocket "My-Socket" [ ipAddress="192.168.101.51", pollingInterval=30 ] +} +``` ### tapocontrol.items: diff --git a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/api/TapoDeviceConnector.java b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/api/TapoDeviceConnector.java index ca3c000a002..55f82ff1507 100644 --- a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/api/TapoDeviceConnector.java +++ b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/api/TapoDeviceConnector.java @@ -14,6 +14,7 @@ package org.openhab.binding.tapocontrol.internal.api; import static org.openhab.binding.tapocontrol.internal.constants.TapoBindingSettings.*; import static org.openhab.binding.tapocontrol.internal.constants.TapoErrorConstants.*; +import static org.openhab.binding.tapocontrol.internal.constants.TapoThingConstants.*; import static org.openhab.binding.tapocontrol.internal.helpers.TapoUtils.*; import java.net.InetAddress; @@ -25,6 +26,7 @@ import org.openhab.binding.tapocontrol.internal.device.TapoDevice; import org.openhab.binding.tapocontrol.internal.helpers.PayloadBuilder; import org.openhab.binding.tapocontrol.internal.helpers.TapoErrorHandler; import org.openhab.binding.tapocontrol.internal.structures.TapoDeviceInfo; +import org.openhab.binding.tapocontrol.internal.structures.TapoEnergyData; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,6 +45,7 @@ public class TapoDeviceConnector extends TapoDeviceHttpApi { private final String uid; private final TapoDevice device; private TapoDeviceInfo deviceInfo; + private TapoEnergyData energyData; private Gson gson; private long lastQuery = 0L; private long lastSent = 0L; @@ -58,6 +61,7 @@ public class TapoDeviceConnector extends TapoDeviceHttpApi { this.device = device; this.gson = new Gson(); this.deviceInfo = new TapoDeviceInfo(); + this.energyData = new TapoEnergyData(); this.uid = device.getThingUID().getAsString(); } @@ -208,6 +212,20 @@ public class TapoDeviceConnector extends TapoDeviceHttpApi { } } + /** + * Get energy usage from device + */ + public void getEnergyUsage() { + logger.trace("({}) DeviceConnetor_getEnergyUsage from '{}'", uid, deviceURL); + + /* create payload */ + PayloadBuilder plBuilder = new PayloadBuilder(); + plBuilder.method = DEVICE_CMD_GETENERGY; + String payload = plBuilder.getPayload(); + + sendSecurePasstrhroug(payload, DEVICE_CMD_GETENERGY); + } + /** * SEND SECUREPASSTHROUGH * encprypt payload and send to device @@ -251,6 +269,7 @@ public class TapoDeviceConnector extends TapoDeviceHttpApi { } /** + * * handle JsonResponse (getDeviceInfo) * * @param responseBody String with responseBody from device @@ -258,7 +277,7 @@ public class TapoDeviceConnector extends TapoDeviceHttpApi { @Override protected void handleDeviceResult(String responseBody) { JsonObject jsnResult = getJsonFromResponse(responseBody); - if (jsnResult.has("device_id")) { + if (jsnResult.has(DEVICE_PROPERTY_ID)) { this.deviceInfo = new TapoDeviceInfo(jsnResult); this.device.setDeviceInfo(deviceInfo); } else { @@ -268,6 +287,23 @@ public class TapoDeviceConnector extends TapoDeviceHttpApi { this.device.responsePasstrough(responseBody); } + /** + * handle JsonResponse (getEnergyData) + * + * @param responseBody String with responseBody from device + */ + @Override + protected void handleEnergyResult(String responseBody) { + JsonObject jsnResult = getJsonFromResponse(responseBody); + if (jsnResult.has(ENERGY_PROPERTY_POWER)) { + this.energyData = new TapoEnergyData(jsnResult); + this.device.setEnergyData(energyData); + } else { + this.energyData = new TapoEnergyData(); + } + this.device.responsePasstrough(responseBody); + } + /** * handle custom response * diff --git a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/api/TapoDeviceHttpApi.java b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/api/TapoDeviceHttpApi.java index 90b15db2b80..eb4966f1620 100644 --- a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/api/TapoDeviceHttpApi.java +++ b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/api/TapoDeviceHttpApi.java @@ -93,6 +93,14 @@ public class TapoDeviceHttpApi { protected void handleDeviceResult(String responseBody) { } + /** + * handle JsonResponse (getEnergyData) + * + * @param responseBody String with responseBody from device + */ + protected void handleEnergyResult(String responseBody) { + } + /** * handle custom response * @@ -346,6 +354,9 @@ public class TapoDeviceHttpApi { case DEVICE_CMD_GETINFO: handleDeviceResult(rBody); break; + case DEVICE_CMD_GETENERGY: + handleEnergyResult(rBody); + break; case DEVICE_CMD_CUSTOM: handleCustomResponse(rBody); break; diff --git a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/constants/TapoBindingSettings.java b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/constants/TapoBindingSettings.java index 8cccffca655..08f97e56ab4 100644 --- a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/constants/TapoBindingSettings.java +++ b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/constants/TapoBindingSettings.java @@ -52,5 +52,6 @@ public class TapoBindingSettings { // LIST OF DEVICE-COMMANDS public static final String DEVICE_CMD_GETINFO = "get_device_info"; public static final String DEVICE_CMD_SETINFO = "set_device_info"; + public static final String DEVICE_CMD_GETENERGY = "get_energy_usage"; public static final String DEVICE_CMD_CUSTOM = "custom_command"; } diff --git a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/constants/TapoErrorConstants.java b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/constants/TapoErrorConstants.java index f2f2a64322a..12a00dc8bca 100644 --- a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/constants/TapoErrorConstants.java +++ b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/constants/TapoErrorConstants.java @@ -142,7 +142,7 @@ public class TapoErrorConstants { // List of Config-Error-Messages public static final String ERR_CONF_IP_MSG = "IP-Address not valid"; // 10001; public static final String ERR_CONF_CREDENTIALS_MSG = "credentials not set (bridge)"; // 10002; - public static final String ERR_NO_BRIDGE_MSG = "no brigde configured"; // 10003; + public static final String ERR_NO_BRIDGE_MSG = "no bridge configured"; // 10003; /**************************************** * ErrorTypes diff --git a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/constants/TapoThingConstants.java b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/constants/TapoThingConstants.java index 32c1f36ad10..1d7cbbd25ef 100644 --- a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/constants/TapoThingConstants.java +++ b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/constants/TapoThingConstants.java @@ -73,6 +73,8 @@ public class TapoThingConstants { .of(SUPPORTED_BRIDGE_UIDS, SUPPORTED_SMART_PLUG_UIDS, SUPPORTED_WHITE_BULB_UIDS, SUPPORTED_COLOR_BULB_UIDS, SUPPORTED_LIGHT_STRIP_UIDS) .flatMap(Set::stream).collect(Collectors.toSet())); + /*** THINGS WITH ENERGY DATA ***/ + public static final Set SUPPORTED_ENERGY_DATA_UIDS = Set.of(P110_THING_TYPE); /*** THINGS WITH CHANNEL GROUPS ***/ public static final Set CHANNEL_GROUP_THING_SET = Collections @@ -125,6 +127,16 @@ public class TapoThingConstants { public static final String PROPERTY_LIGHTNING_EFFECT_ENABLE = "enable"; public static final String PROPERTY_LIGHTNING_EFFECT_ID = "id"; public static final String PROPERTY_LIGHTNING_EFFECT_NAME = "name"; + // energy monitoring + public static final String ENERGY_PROPERTY_POWER = "current_power"; + public static final String ENERGY_PROPERTY_RUNTIME_TODAY = "today_runtime"; + public static final String ENERGY_PROPERTY_RUNTIME_MONTH = "month_runtime"; + public static final String ENERGY_PROPERTY_ENERGY_TODAY = "today_energy"; + public static final String ENERGY_PROPERTY_ENERGY_MONTH = "month_energy"; + public static final String ENERGY_PROPERTY_PAST24H = "past24h"; + public static final String ENERGY_PROPERTY_PAST7D = "past7d"; + public static final String ENERGY_PROPERTY_PAST30D = "past30d"; + public static final String ENERGY_PROPERTY_PAST1Y = "past1y"; /*** DEVICE SETTINGS ***/ public static final Integer BULB_MIN_COLORTEMP = 2500; @@ -143,6 +155,11 @@ public class TapoThingConstants { public static final String CHANNEL_ONTIME = "onTime"; public static final String CHANNEL_OVERHEAT = "overheated"; public static final String CHANNEL_WIFI_STRENGTH = "wifiSignal"; + // channel group energy monitor + public static final String CHANNEL_GROUP_ENERGY = "energy"; + public static final String CHANNEL_NRG_POWER = "actualPower"; + public static final String CHANNEL_NRG_USAGE_TODAY = "todayEnergyUsage"; + public static final String CHANNEL_NRG_RUNTIME_TODAY = "todayRuntime"; // channel group effect public static final String CHANNEL_GROUP_EFFECTS = "effect"; public static final String CHANNEL_FX_BRIGHTNESS = "brightness"; diff --git a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoDevice.java b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoDevice.java index 784f5b2d9cd..eb46638f7cc 100644 --- a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoDevice.java +++ b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoDevice.java @@ -28,6 +28,8 @@ import org.openhab.binding.tapocontrol.internal.api.TapoDeviceConnector; import org.openhab.binding.tapocontrol.internal.helpers.TapoErrorHandler; import org.openhab.binding.tapocontrol.internal.structures.TapoDeviceConfiguration; import org.openhab.binding.tapocontrol.internal.structures.TapoDeviceInfo; +import org.openhab.binding.tapocontrol.internal.structures.TapoEnergyData; +import org.openhab.core.library.unit.Units; import org.openhab.core.thing.Bridge; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; @@ -319,6 +321,10 @@ public abstract class TapoDevice extends BaseThingHandler { deviceError.reset(); if (connector.loggedIn()) { connector.queryInfo(ignoreGap); + // query energy usage + if (SUPPORTED_ENERGY_DATA_UIDS.contains(getThing().getThingTypeUID())) { + connector.getEnergyUsage(); + } } else { logger.debug("({}) tried to query DeviceInfo but not loggedIn", uid); connect(); @@ -342,6 +348,20 @@ public abstract class TapoDevice extends BaseThingHandler { } } + /** + * Set Device EnergyData to device + * + * @param energyData + */ + public void setEnergyData(TapoEnergyData energyData) { + publishState(getChannelID(CHANNEL_GROUP_ENERGY, CHANNEL_NRG_POWER), + getPowerType(energyData.getCurrentPower(), Units.WATT)); + publishState(getChannelID(CHANNEL_GROUP_ENERGY, CHANNEL_NRG_USAGE_TODAY), + getEnergyType(energyData.getTodayEnergy(), Units.WATT_HOUR)); + publishState(getChannelID(CHANNEL_GROUP_ENERGY, CHANNEL_NRG_RUNTIME_TODAY), + getTimeType(energyData.getTodayRuntime(), Units.MINUTE)); + } + /** * Handle full responsebody received from connector * @@ -474,6 +494,7 @@ public abstract class TapoDevice extends BaseThingHandler { channel = channel.replace(CHANNEL_GROUP_ACTUATOR + "#", ""); channel = channel.replace(CHANNEL_GROUP_DEVICE + "#", ""); channel = channel.replace(CHANNEL_GROUP_EFFECTS + "#", ""); + channel = channel.replace(CHANNEL_GROUP_ENERGY + "#", ""); return channel; } } diff --git a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoLightStrip.java b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoLightStrip.java index 0d8b06f7326..6f55e143e79 100644 --- a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoLightStrip.java +++ b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoLightStrip.java @@ -218,7 +218,7 @@ public class TapoLightStrip extends TapoDevice { publishState(getChannelID(CHANNEL_GROUP_DEVICE, CHANNEL_WIFI_STRENGTH), getDecimalType(deviceInfo.getSignalLevel())); publishState(getChannelID(CHANNEL_GROUP_DEVICE, CHANNEL_ONTIME), - getQuantityType(deviceInfo.getOnTime(), Units.SECOND)); + getTimeType(deviceInfo.getOnTime(), Units.SECOND)); publishState(getChannelID(CHANNEL_GROUP_DEVICE, CHANNEL_OVERHEAT), getOnOffType(deviceInfo.isOverheated())); // light effect publishState(getChannelID(CHANNEL_GROUP_EFFECTS, CHANNEL_FX_BRIGHTNESS), diff --git a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoSmartBulb.java b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoSmartBulb.java index c4af02651ea..985c005144b 100644 --- a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoSmartBulb.java +++ b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoSmartBulb.java @@ -163,7 +163,7 @@ public class TapoSmartBulb extends TapoDevice { publishState(getChannelID(CHANNEL_GROUP_DEVICE, CHANNEL_WIFI_STRENGTH), getDecimalType(deviceInfo.getSignalLevel())); publishState(getChannelID(CHANNEL_GROUP_DEVICE, CHANNEL_ONTIME), - getQuantityType(deviceInfo.getOnTime(), Units.SECOND)); + getTimeType(deviceInfo.getOnTime(), Units.SECOND)); publishState(getChannelID(CHANNEL_GROUP_DEVICE, CHANNEL_OVERHEAT), getOnOffType(deviceInfo.isOverheated())); } } diff --git a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoSmartPlug.java b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoSmartPlug.java index 10a5fef5cc4..f96bcacb074 100644 --- a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoSmartPlug.java +++ b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoSmartPlug.java @@ -86,7 +86,7 @@ public class TapoSmartPlug extends TapoDevice { publishState(getChannelID(CHANNEL_GROUP_DEVICE, CHANNEL_WIFI_STRENGTH), getDecimalType(deviceInfo.getSignalLevel())); publishState(getChannelID(CHANNEL_GROUP_DEVICE, CHANNEL_ONTIME), - getQuantityType(deviceInfo.getOnTime(), Units.SECOND)); + getTimeType(deviceInfo.getOnTime(), Units.SECOND)); publishState(getChannelID(CHANNEL_GROUP_DEVICE, CHANNEL_OVERHEAT), getOnOffType(deviceInfo.isOverheated())); } } diff --git a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoUniversalDevice.java b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoUniversalDevice.java index 3fcf88ddf2d..3b518106e4d 100644 --- a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoUniversalDevice.java +++ b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/device/TapoUniversalDevice.java @@ -196,7 +196,7 @@ public class TapoUniversalDevice extends TapoDevice { publishState(getChannelID(CHANNEL_GROUP_DEVICE, CHANNEL_WIFI_STRENGTH), getDecimalType(deviceInfo.getSignalLevel())); publishState(getChannelID(CHANNEL_GROUP_DEVICE, CHANNEL_ONTIME), - getQuantityType(deviceInfo.getOnTime(), Units.SECOND)); + getTimeType(deviceInfo.getOnTime(), Units.SECOND)); publishState(getChannelID(CHANNEL_GROUP_DEVICE, CHANNEL_OVERHEAT), getDecimalType(deviceInfo.isOverheated() ? 1 : 0)); } diff --git a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/helpers/TapoUtils.java b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/helpers/TapoUtils.java index 04ba34e3bac..90cd888f56a 100644 --- a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/helpers/TapoUtils.java +++ b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/helpers/TapoUtils.java @@ -13,6 +13,8 @@ package org.openhab.binding.tapocontrol.internal.helpers; import javax.measure.Unit; +import javax.measure.quantity.Energy; +import javax.measure.quantity.Power; import javax.measure.quantity.Time; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -340,9 +342,31 @@ public class TapoUtils { * * @param numVal Number with value * @param unit TimeUnit (Unit