Skip to content

Commit

Permalink
[tasmotaplug] Add energy monitor channels (#16494)
Browse files Browse the repository at this point in the history
* Add energy monitor channels

Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
  • Loading branch information
mlobstein committed Mar 10, 2024
1 parent b423933 commit 9ad3c66
Show file tree
Hide file tree
Showing 8 changed files with 458 additions and 28 deletions.
51 changes: 42 additions & 9 deletions bundles/org.openhab.binding.tasmotaplug/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# TasmotaPlug Binding

This binding connects Tasmota flashed smart plugs with 1, 2, 3 or 4 relay channels to openHAB.
The plug must report the status of the relay via the url `http://$PLUG_IP/cm?cmnd=Power` in order for the binding to work.
This binding connects Tasmota flashed smart plugs with 1, 2, 3 or 4 relay channels to openHAB.
The plug must report the status of the relay via the url `http://$PLUG_IP/cm?cmnd=Power` in order for the binding to work.
The energy monitoring channels can be used if the plug reports energy status via the url `http://$PLUG_IP/cm?cmnd=Status%2010`.
See the [Tasmota Supported Devices Repository](https://templates.blakadder.com/plug.html) for a list of supported plugs.

## Supported Things
Expand Down Expand Up @@ -34,12 +35,22 @@ Channels above the number specified are automatically removed.
Therefore `numChannels` cannot be changed upward after Thing creation.
If the number of channels must be increased, delete the Thing and re-create it with the correct number.

| Channel ID | Item Type | Description |
|------------|-----------|-----------------------------------------|
| power | Switch | Turns the smart plug relay #1 ON or OFF |
| power2 | Switch | Turns the smart plug relay #2 ON or OFF |
| power3 | Switch | Turns the smart plug relay #3 ON or OFF |
| power4 | Switch | Turns the smart plug relay #4 ON or OFF |
| Channel ID | Item Type | Description |
|----------------------|--------------------------|-------------------------------------------------|
| power | Switch | Turns the smart plug relay #1 ON or OFF |
| power2 | Switch | Turns the smart plug relay #2 ON or OFF |
| power3 | Switch | Turns the smart plug relay #3 ON or OFF |
| power4 | Switch | Turns the smart plug relay #4 ON or OFF |
| voltage | Number:ElectricPotential | Channel for output voltage measurement |
| current | Number:ElectricCurrent | Channel for output current measurement |
| watts | Number:Power | Channel for output power measurement |
| volt-ampere | Number:Power | Channel for output VA measurement |
| volt-ampere-reactive | Number:Power | Channel for output VAr measurement |
| power-factor | Number:Dimensionless | Channel for output power factor measurement |
| energy-today | Number:Energy | Channel for output energy today measurement |
| energy-yesterday | Number:Energy | Channel for output energy yesterday measurement |
| energy-total | Number:Energy | Channel for output energy total measurement |
| energy-total-start | DateTime | Channel for output energy total start date/time |

## Full Example

Expand All @@ -53,7 +64,17 @@ tasmotaplug:plug:plug2 "Plug 2" [ hostName="myplug2", refresh=30 ]
tasmotaplug.items:

```java
Switch Plug1 "Plug 1 Power" { channel="tasmotaplug:plug:plug1:power" }
Switch Plug1 "Plug 1 Power" { channel="tasmotaplug:plug:plug1:power" }
Number:ElectricPotential Voltage { channel="tasmotaplug:plug:plug1:voltage" }
Number:ElectricCurrent Current { channel="tasmotaplug:plug:plug1:current" }
Number:Power Watts { channel="tasmotaplug:plug:plug1:watts" }
Number:Power VoltAmpere { channel="tasmotaplug:plug:plug1:volt-ampere" }
Number:Power VoltAmpereReactive { channel="tasmotaplug:plug:plug1:volt-ampere-reactive" }
Number PowerFactor { channel="tasmotaplug:plug:plug1:power-factor" }
Number:Energy EnergyToday { channel="tasmotaplug:plug:plug1:energy-today" }
Number:Energy EnergyYesterday { channel="tasmotaplug:plug:plug1:energy-yesterday" }
Number:Energy EnergyTotal { channel="tasmotaplug:plug:plug1:energy-total" }
DateTime EnergyTotalStart "Total Start [%s]" { channel="tasmotaplug:plug:plug1:energy-total-start" }

Switch Plug2a "4ch Power 1" { channel="tasmotaplug:plug:plug2:power" }
Switch Plug2b "4ch Power 2" { channel="tasmotaplug:plug:plug2:power2" }
Expand All @@ -68,6 +89,18 @@ sitemap tasmotaplug label="My Tasmota Plugs" {
Frame label="Plugs" {
Switch item=Plug1

// Energy monitoring
Text item=Voltage
Text item=Current
Text item=Watts
Text item=VoltAmpere
Text item=VoltAmpereReactive
Text item=PowerFactor
Text item=EnergyToday
Text item=EnergyYesterday
Text item=EnergyTotal
Text item=EnergyTotalStart

Switch item=Plug2a
Switch item=Plug2b
Switch item=Plug2c
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/**
* Copyright (c) 2010-2024 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.tasmotaplug.dto;

import com.google.gson.annotations.SerializedName;

/**
* The {@link TasmotaDTO} is responsible for storing
* all of the JSON data objects retrieved from the Tasmota plug
*
* @author Michael Lobstein - Initial contribution
*/
public class TasmotaDTO {

@SerializedName("StatusSNS")
private TasmotaStatus status = new TasmotaStatus();

public TasmotaDTO() {
}

public TasmotaStatus getStatus() {
return status;
}

public void setStatus(TasmotaStatus status) {
this.status = status;
}

public class TasmotaStatus {

@SerializedName("Time")
private String time = "";

@SerializedName("ENERGY")
private Energy energy = new Energy();

public TasmotaStatus() {
}

public String getTime() {
return time;
}

public void setTime(String time) {
this.time = time;
}

public Energy getEnergy() {
return energy;
}

public void setEnergy(Energy energy) {
this.energy = energy;
}
}

public class Energy {

@SerializedName("Voltage")
private Integer voltage = 0;

@SerializedName("Current")
private Double current = 0d;

@SerializedName("Power")
private Integer activePower = 0;

@SerializedName("ApparentPower")
private Integer apparentPower = 0;

@SerializedName("ReactivePower")
private Integer reactivePower = 0;

@SerializedName("Factor")
private Double powerFactor = 0d;

@SerializedName("Today")
private Double energyToday = 0d;

@SerializedName("Yesterday")
private Double energyYesterday = 0d;

@SerializedName("Total")
private Double energyTotal = 0d;

@SerializedName("TotalStartTime")
private String energyTotalStart = "";

public Energy() {
}

public Integer getVoltage() {
return voltage;
}

public void setVoltage(Integer voltage) {
this.voltage = voltage;
}

public Double getCurrent() {
return current;
}

public void setCurrent(Double current) {
this.current = current;
}

public Integer getActivePower() {
return activePower;
}

public void setActivePower(Integer activePower) {
this.activePower = activePower;
}

public Integer getApparentPower() {
return apparentPower;
}

public void setApparentPower(Integer apparentPower) {
this.apparentPower = apparentPower;
}

public Integer getReactivePower() {
return reactivePower;
}

public void setReactivePower(Integer reactivePower) {
this.reactivePower = reactivePower;
}

public Double getPowerFactor() {
return powerFactor;
}

public void setPowerFactor(Double powerFactor) {
this.powerFactor = powerFactor;
}

public Double getEnergyToday() {
return energyToday;
}

public void setEnergyToday(Double energyToday) {
this.energyToday = energyToday;
}

public Double getEnergyYesterday() {
return energyYesterday;
}

public void setEnergyYesterday(Double energyYesterday) {
this.energyYesterday = energyYesterday;
}

public Double getEnergyTotal() {
return energyTotal;
}

public void setEnergyTotal(Double energyTotal) {
this.energyTotal = energyTotal;
}

public String getEnergyTotalStart() {
return energyTotalStart;
}

public void setEnergyTotalStart(String energyTotalStart) {
this.energyTotalStart = energyTotalStart;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public class TasmotaPlugBindingConstants {
public static final String CMD_URI = "/cm?cmnd=%s";
public static final String CMD_URI_AUTH = "/cm?user=%s&password=%s&cmnd=%s";

public static final String STATUS = "Status";
public static final String STATUS_CMD = "10";
public static final String ON = "ON";
public static final String OFF = "OFF";
public static final String BLANK = "";
Expand All @@ -46,7 +48,19 @@ public class TasmotaPlugBindingConstants {
public static final String POWER2 = "power2";
public static final String POWER3 = "power3";
public static final String POWER4 = "power4";
public static final String VOLTAGE = "voltage";
public static final String CURRENT = "current";
public static final String WATTS = "watts";
public static final String VOLT_AMPERE = "volt-ampere";
public static final String VOLT_AMPERE_REACTIVE = "volt-ampere-reactive";
public static final String POWER_FACTOR = "power-factor";
public static final String ENERGY_TODAY = "energy-today";
public static final String ENERGY_YESTERDAY = "energy-yesterday";
public static final String ENERGY_TOTAL = "energy-total";
public static final String ENERGY_TOTAL_START = "energy-total-start";

public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_PLUG);
public static final List<String> SUPPORTED_CHANNEL_IDS = List.of(POWER, POWER2, POWER3, POWER4);
public static final List<String> CONTROL_CHANNEL_IDS = List.of(POWER, POWER2, POWER3, POWER4);
public static final List<String> ENERGY_CHANNEL_IDS = List.of(VOLTAGE, CURRENT, WATTS, VOLT_AMPERE,
VOLT_AMPERE_REACTIVE, POWER_FACTOR, ENERGY_TODAY, ENERGY_YESTERDAY, ENERGY_TOTAL, ENERGY_TOTAL_START);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
*/
package org.openhab.binding.tasmotaplug.internal;

import static org.openhab.binding.tasmotaplug.internal.TasmotaPlugBindingConstants.THING_TYPE_PLUG;

import java.util.Set;
import static org.openhab.binding.tasmotaplug.internal.TasmotaPlugBindingConstants.SUPPORTED_THING_TYPES_UIDS;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
Expand All @@ -39,8 +37,6 @@
@NonNullByDefault
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.tasmotaplug")
public class TasmotaPlugHandlerFactory extends BaseThingHandlerFactory {

private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_PLUG);
private final HttpClient httpClient;

@Activate
Expand All @@ -55,7 +51,7 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) {

@Override
protected @Nullable ThingHandler createHandler(Thing thing) {
if (THING_TYPE_PLUG.equals(thing.getThingTypeUID())) {
if (SUPPORTED_THING_TYPES_UIDS.contains(thing.getThingTypeUID())) {
return new TasmotaPlugHandler(thing, httpClient);
}

Expand Down

0 comments on commit 9ad3c66

Please sign in to comment.