]> git.basschouten.com Git - openhab-addons.git/commitdiff
[tasmotaplug] Add energy monitor channels (#16494)
authormlobstein <michael.lobstein@gmail.com>
Sun, 10 Mar 2024 20:44:26 +0000 (15:44 -0500)
committerGitHub <noreply@github.com>
Sun, 10 Mar 2024 20:44:26 +0000 (21:44 +0100)
* Add energy monitor channels

Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
bundles/org.openhab.binding.tasmotaplug/README.md
bundles/org.openhab.binding.tasmotaplug/src/main/java/org/openhab/binding/tasmotaplug/dto/TasmotaDTO.java [new file with mode: 0644]
bundles/org.openhab.binding.tasmotaplug/src/main/java/org/openhab/binding/tasmotaplug/internal/TasmotaPlugBindingConstants.java
bundles/org.openhab.binding.tasmotaplug/src/main/java/org/openhab/binding/tasmotaplug/internal/TasmotaPlugHandlerFactory.java
bundles/org.openhab.binding.tasmotaplug/src/main/java/org/openhab/binding/tasmotaplug/internal/handler/TasmotaPlugHandler.java
bundles/org.openhab.binding.tasmotaplug/src/main/resources/OH-INF/i18n/tasmotaplug.properties
bundles/org.openhab.binding.tasmotaplug/src/main/resources/OH-INF/thing/thing-types.xml
bundles/org.openhab.binding.tasmotaplug/src/main/resources/OH-INF/update/update.xml [new file with mode: 0644]

index 9ef89d2d27fef8097637c875cc37b300b2074eed..30f6247f05a71abc20749afa8b57b7b0798172f7 100644 (file)
@@ -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
@@ -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
 
@@ -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" }
@@ -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
diff --git a/bundles/org.openhab.binding.tasmotaplug/src/main/java/org/openhab/binding/tasmotaplug/dto/TasmotaDTO.java b/bundles/org.openhab.binding.tasmotaplug/src/main/java/org/openhab/binding/tasmotaplug/dto/TasmotaDTO.java
new file mode 100644 (file)
index 0000000..549c242
--- /dev/null
@@ -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;
+        }
+    }
+}
index 55a59d6f70d65a2d943534d864ac68e22d65c33c..1d99e455903ab7db800897866c40af799ad27c05 100644 (file)
@@ -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 = "";
@@ -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);
 }
index 4a752a37c7a50bec3fa723749317d2b54f091e7c..51b52cc9ffdba2ad5c456eec7f702867b7534403 100644 (file)
@@ -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;
@@ -39,8 +37,6 @@ import org.osgi.service.component.annotations.Reference;
 @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
@@ -55,7 +51,7 @@ public class TasmotaPlugHandlerFactory extends BaseThingHandlerFactory {
 
     @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);
         }
 
index 3c09adba2183fb66fee0d5669fced86de61bd8fc..f745e9a19d0c843530ad8a272a91f723833fe2aa 100644 (file)
@@ -27,8 +27,14 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.client.api.ContentResponse;
+import org.openhab.binding.tasmotaplug.dto.TasmotaDTO;
+import org.openhab.binding.tasmotaplug.dto.TasmotaDTO.Energy;
 import org.openhab.binding.tasmotaplug.internal.TasmotaPlugConfiguration;
+import org.openhab.core.library.types.DateTimeType;
+import org.openhab.core.library.types.DecimalType;
 import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.unit.Units;
 import org.openhab.core.thing.Channel;
 import org.openhab.core.thing.ChannelUID;
 import org.openhab.core.thing.Thing;
@@ -39,6 +45,10 @@ import org.openhab.core.types.Command;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonSyntaxException;
+
 /**
  * The {@link TasmotaPlugHandler} is responsible for handling commands, which are
  * sent to one of the channels.
@@ -52,6 +62,7 @@ public class TasmotaPlugHandler extends BaseThingHandler {
 
     private final Logger logger = LoggerFactory.getLogger(TasmotaPlugHandler.class);
     private final HttpClient httpClient;
+    private final Gson gson;
 
     private @Nullable ScheduledFuture<?> refreshJob;
 
@@ -65,6 +76,7 @@ public class TasmotaPlugHandler extends BaseThingHandler {
     public TasmotaPlugHandler(Thing thing, HttpClient httpClient) {
         super(thing);
         this.httpClient = httpClient;
+        gson = new GsonBuilder().serializeNulls().create();
     }
 
     @Override
@@ -93,10 +105,10 @@ public class TasmotaPlugHandler extends BaseThingHandler {
         plugHost = "http://" + hostName;
 
         // remove the channels we are not using
-        if (this.numChannels < SUPPORTED_CHANNEL_IDS.size()) {
+        if (this.numChannels < CONTROL_CHANNEL_IDS.size()) {
             List<Channel> channels = new ArrayList<>(this.getThing().getChannels());
 
-            List<Integer> channelsToRemove = IntStream.range(this.numChannels + 1, SUPPORTED_CHANNEL_IDS.size() + 1)
+            List<Integer> channelsToRemove = IntStream.range(this.numChannels + 1, CONTROL_CHANNEL_IDS.size() + 1)
                     .boxed().toList();
 
             channelsToRemove.forEach(channel -> {
@@ -124,12 +136,12 @@ public class TasmotaPlugHandler extends BaseThingHandler {
     public void handleCommand(ChannelUID channelUID, Command command) {
         if (channelUID.getId().contains(POWER)) {
             if (command instanceof OnOffType) {
-                getCommand(channelUID.getId(), command);
+                getCommand(channelUID.getId(), command.toString());
             } else {
                 updateChannelState(channelUID.getId());
             }
         } else {
-            logger.warn("Unsupported command: {}", command.toString());
+            logger.debug("Unsupported command: {}", command.toString());
         }
     }
 
@@ -141,9 +153,13 @@ public class TasmotaPlugHandler extends BaseThingHandler {
         if (refreshJob == null || refreshJob.isCancelled()) {
             refreshJob = null;
             this.refreshJob = scheduler.scheduleWithFixedDelay(() -> {
-                SUPPORTED_CHANNEL_IDS.stream().limit(numChannels).forEach(channelId -> {
+                CONTROL_CHANNEL_IDS.stream().limit(numChannels).forEach(channelId -> {
                     updateChannelState(channelId);
                 });
+
+                if (ENERGY_CHANNEL_IDS.stream().anyMatch(energyCh -> isLinked(energyCh))) {
+                    updateEnergyChannels();
+                }
             }, 0, refreshPeriod, TimeUnit.SECONDS);
         }
     }
@@ -157,18 +173,76 @@ public class TasmotaPlugHandler extends BaseThingHandler {
         }
     }
 
-    private String getCommand(String channelId, @Nullable Command command) {
-        final String plugChannel = channelId.substring(0, 1).toUpperCase() + channelId.substring(1);
-        String url;
+    private void updateEnergyChannels() {
+        final Energy energyDto;
+        final String json = getCommand(STATUS, STATUS_CMD);
+        if (!json.isBlank()) {
+            try {
+                final TasmotaDTO dto = gson.fromJson(json, TasmotaDTO.class);
+                if (dto != null) {
+                    energyDto = dto.getStatus().getEnergy();
+                } else {
+                    logger.debug("TasmotaDTO was null for JSON: '{}'", json);
+                    return;
+                }
+            } catch (JsonSyntaxException e) {
+                logger.debug("Error parsing Tasmota status JSON: '{}' Exception: {}", json, e.getMessage());
+                return;
+            }
+        } else {
+            return;
+        }
 
+        if (isLinked(VOLTAGE)) {
+            updateState(VOLTAGE, new QuantityType<>(energyDto.getVoltage(), Units.VOLT));
+        }
+        if (isLinked(CURRENT)) {
+            updateState(CURRENT, new QuantityType<>(energyDto.getCurrent(), Units.AMPERE));
+        }
+        if (isLinked(WATTS)) {
+            updateState(WATTS, new QuantityType<>(energyDto.getActivePower(), Units.WATT));
+        }
+        if (isLinked(VOLT_AMPERE)) {
+            updateState(VOLT_AMPERE, new QuantityType<>(energyDto.getApparentPower(), Units.VOLT_AMPERE));
+        }
+        if (isLinked(VOLT_AMPERE_REACTIVE)) {
+            updateState(VOLT_AMPERE_REACTIVE, new QuantityType<>(energyDto.getReactivePower(), Units.VAR));
+        }
+        if (isLinked(POWER_FACTOR)) {
+            updateState(POWER_FACTOR, new DecimalType(energyDto.getPowerFactor()));
+        }
+        if (isLinked(ENERGY_TODAY)) {
+            updateState(ENERGY_TODAY, new QuantityType<>(energyDto.getEnergyToday(), Units.KILOWATT_HOUR));
+        }
+        if (isLinked(ENERGY_YESTERDAY)) {
+            updateState(ENERGY_YESTERDAY, new QuantityType<>(energyDto.getEnergyYesterday(), Units.KILOWATT_HOUR));
+        }
+        if (isLinked(ENERGY_TOTAL)) {
+            updateState(ENERGY_TOTAL, new QuantityType<>(energyDto.getEnergyTotal(), Units.KILOWATT_HOUR));
+        }
+        if (isLinked(ENERGY_TOTAL_START) && !energyDto.getEnergyTotalStart().isBlank()) {
+            updateState(ENERGY_TOTAL_START, new DateTimeType(energyDto.getEnergyTotalStart()));
+        }
+    }
+
+    private String getCommand(String commmand, @Nullable String commandArg) {
+        final String tasmotaCommand;
+        if (STATUS.equals(commmand)) {
+            tasmotaCommand = commmand;
+        } else {
+            // uppercase the first character of the channel id
+            tasmotaCommand = commmand.substring(0, 1).toUpperCase() + commmand.substring(1);
+        }
+
+        String url;
         if (isAuth) {
-            url = String.format(CMD_URI_AUTH, user, pass, plugChannel);
+            url = String.format(CMD_URI_AUTH, user, pass, tasmotaCommand);
         } else {
-            url = String.format(CMD_URI, plugChannel);
+            url = String.format(CMD_URI, tasmotaCommand);
         }
 
-        if (command != null) {
-            url += "%20" + command;
+        if (commandArg != null) {
+            url += "%20" + commandArg;
         }
 
         try {
index c388401f09851678917f908374150584f0ba6aa3..63f7c3c0c1b08e4a0ba6ae690fb8a7e3ab10f242 100644 (file)
@@ -7,6 +7,12 @@ addon.tasmotaplug.description = Controls Wi-Fi Smart Plugs flashed with Tasmota
 
 thing-type.tasmotaplug.plug.label = Plug
 thing-type.tasmotaplug.plug.description = Tasmota Smart Plug
+thing-type.tasmotaplug.plug.channel.energy-today.label = Energy Today
+thing-type.tasmotaplug.plug.channel.energy-today.description = Energy consumed today (kWh)
+thing-type.tasmotaplug.plug.channel.energy-total.label = Energy Total
+thing-type.tasmotaplug.plug.channel.energy-total.description = Total energy consumed (kWh)
+thing-type.tasmotaplug.plug.channel.energy-yesterday.label = Energy Yesterday
+thing-type.tasmotaplug.plug.channel.energy-yesterday.description = Energy consumed yesterday (kWh)
 thing-type.tasmotaplug.plug.channel.power.label = Power
 thing-type.tasmotaplug.plug.channel.power.description = Controls the smart plug relay for the 1st channel
 thing-type.tasmotaplug.plug.channel.power2.label = Power 2
@@ -15,6 +21,8 @@ thing-type.tasmotaplug.plug.channel.power3.label = Power 3
 thing-type.tasmotaplug.plug.channel.power3.description = Controls the smart plug relay for the 3rd channel
 thing-type.tasmotaplug.plug.channel.power4.label = Power 4
 thing-type.tasmotaplug.plug.channel.power4.description = Controls the smart plug relay for the 4th channel
+thing-type.tasmotaplug.plug.channel.watts.label = Active Power
+thing-type.tasmotaplug.plug.channel.watts.description = Active Power (W)
 
 # thing types config
 
@@ -29,6 +37,17 @@ thing-type.config.tasmotaplug.plug.refresh.description = Specifies the refresh i
 thing-type.config.tasmotaplug.plug.username.label = Username
 thing-type.config.tasmotaplug.plug.username.description = Tasmota username
 
+# channel types
+
+channel-type.tasmotaplug.energy-total-start.label = Energy Total Start
+channel-type.tasmotaplug.energy-total-start.description = The date/time when the energy total measurement started
+channel-type.tasmotaplug.power-factor.label = Power Factor
+channel-type.tasmotaplug.power-factor.description = Power Factor (PF)
+channel-type.tasmotaplug.volt-ampere-reactive.label = Reactive Power
+channel-type.tasmotaplug.volt-ampere-reactive.description = Reactive Power (VAr)
+channel-type.tasmotaplug.volt-ampere.label = Apparent Power
+channel-type.tasmotaplug.volt-ampere.description = Apparent Power (VA)
+
 # thing status descriptions
 
 offline.communication-error.http-failure = Tasmota http response code was: {0}
index 1382b7cd44a4293e860921ad41781821997f356a..879580b7d3e4a9adf669321e5131585d8649d4c4 100644 (file)
                                <label>Power 4</label>
                                <description>Controls the smart plug relay for the 4th channel</description>
                        </channel>
+
+                       <!-- Energy Monitor Channels -->
+                       <channel id="voltage" typeId="system.electric-voltage"/>
+                       <channel id="current" typeId="system.electric-current"/>
+                       <channel id="watts" typeId="system.electric-power">
+                               <label>Active Power</label>
+                               <description>Active Power (W)</description>
+                       </channel>
+
+                       <channel id="volt-ampere" typeId="volt-ampere"/>
+                       <channel id="volt-ampere-reactive" typeId="volt-ampere-reactive"/>
+                       <channel id="power-factor" typeId="power-factor"/>
+
+                       <channel id="energy-today" typeId="system.electric-energy">
+                               <label>Energy Today</label>
+                               <description>Energy consumed today (kWh)</description>
+                       </channel>
+                       <channel id="energy-yesterday" typeId="system.electric-energy">
+                               <label>Energy Yesterday</label>
+                               <description>Energy consumed yesterday (kWh)</description>
+                       </channel>
+                       <channel id="energy-total" typeId="system.electric-energy">
+                               <label>Energy Total</label>
+                               <description>Total energy consumed (kWh)</description>
+                       </channel>
+
+                       <channel id="energy-total-start" typeId="energy-total-start"/>
                </channels>
 
+               <properties>
+                       <property name="thingTypeVersion">1</property>
+               </properties>
+
                <config-description>
                        <parameter name="hostName" type="text" required="true">
                                <context>network-address</context>
 
        </thing-type>
 
+       <channel-type id="volt-ampere">
+               <item-type>Number:Power</item-type>
+               <label>Apparent Power</label>
+               <description>Apparent Power (VA)</description>
+               <state readOnly="true" pattern="%d %unit%"/>
+       </channel-type>
+
+       <channel-type id="volt-ampere-reactive">
+               <item-type>Number:Power</item-type>
+               <label>Reactive Power</label>
+               <description>Reactive Power (VAr)</description>
+               <state readOnly="true" pattern="%d %unit%"/>
+       </channel-type>
+
+       <channel-type id="power-factor">
+               <item-type>Number:Dimensionless</item-type>
+               <label>Power Factor</label>
+               <description>Power Factor (PF)</description>
+               <state readOnly="true" pattern="%.1f %unit%"/>
+       </channel-type>
+
+       <channel-type id="energy-total-start">
+               <item-type>DateTime</item-type>
+               <label>Energy Total Start</label>
+               <description>The date/time when the energy total measurement started</description>
+               <category>Time</category>
+               <tags>
+                       <tag>Timestamp</tag>
+               </tags>
+               <state readOnly="true"/>
+       </channel-type>
+
 </thing:thing-descriptions>
diff --git a/bundles/org.openhab.binding.tasmotaplug/src/main/resources/OH-INF/update/update.xml b/bundles/org.openhab.binding.tasmotaplug/src/main/resources/OH-INF/update/update.xml
new file mode 100644 (file)
index 0000000..eeb3611
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<update:update-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">
+
+       <thing-type uid="tasmotaplug:plug">
+               <instruction-set targetVersion="1">
+                       <add-channel id="voltage">
+                               <type>system:electric-voltage</type>
+                       </add-channel>
+                       <add-channel id="current">
+                               <type>system:electric-current</type>
+                       </add-channel>
+                       <add-channel id="watts">
+                               <type>system:electric-power</type>
+                               <label>Active Power</label>
+                               <description>Active Power (W)</description>
+                       </add-channel>
+                       <add-channel id="volt-ampere">
+                               <type>tasmotaplug:volt-ampere</type>
+                       </add-channel>
+                       <add-channel id="volt-ampere-reactive">
+                               <type>tasmotaplug:volt-ampere-reactive</type>
+                       </add-channel>
+                       <add-channel id="power-factor">
+                               <type>tasmotaplug:power-factor</type>
+                       </add-channel>
+                       <add-channel id="energy-today">
+                               <type>system:electric-energy</type>
+                               <label>Energy Today</label>
+                               <description>Energy consumed today (kWh)</description>
+                       </add-channel>
+                       <add-channel id="energy-yesterday">
+                               <type>system:electric-energy</type>
+                               <label>Energy Yesterday</label>
+                               <description>Energy consumed yesterday (kWh)</description>
+                       </add-channel>
+                       <add-channel id="energy-total">
+                               <type>system:electric-energy</type>
+                               <label>Energy Total</label>
+                               <description>Total energy consumed (kWh)</description>
+                       </add-channel>
+                       <add-channel id="energy-total-start">
+                               <type>tasmotaplug:energy-total-start</type>
+                       </add-channel>
+               </instruction-set>
+       </thing-type>
+
+</update:update-descriptions>