From 4291729c7ba0412cafa1d235c6af9cfdeb1d4702 Mon Sep 17 00:00:00 2001 From: Hans van den Bogert Date: Wed, 15 Dec 2021 09:20:21 +0100 Subject: [PATCH] [omnikinverter] feature: Add channels for voltage and current (#11645) Signed-off-by: Hans van den Bogert --- .../README.md | 47 ++++-- .../OmnikInverterBindingConstants.java | 11 ++ .../internal/OmnikInverterMessage.java | 158 ++++++++++++++++-- .../handler/OmnikInverterHandler.java | 36 +++- .../resources/OH-INF/thing/thing-types.xml | 65 ++++++- .../test/OmnikInverterMessageTest.java | 45 +++++ 6 files changed, 336 insertions(+), 26 deletions(-) diff --git a/bundles/org.openhab.binding.omnikinverter/README.md b/bundles/org.openhab.binding.omnikinverter/README.md index 1107246c0..4b8080624 100644 --- a/bundles/org.openhab.binding.omnikinverter/README.md +++ b/bundles/org.openhab.binding.omnikinverter/README.md @@ -21,11 +21,20 @@ No autodiscovery available ## Channels -| Channel Type Id | Item Type | Description | -| :---------------- | :---------- | :------------ | -| power | Number:Power | The instantaneous power generation | -| energyToday | Number:Energy | The amount of energy generated today | -| energyTotal | Number:Energy | The total amount of energy generated | +| Channel Type Id | Item Type | Description | +|:---------------|:--------------|:------------------------------------------------------------------------------------------------------------------| +| power | Number:Power | The instantaneous power generation for feed 1 to the grid, in Watt by default (**deprecated**; same as powerAC1) | +| powerAC1 | Number:Power | The instantaneous power generation for feed 1 to the grid, in Watt by default | +| powerAC2 | Number:Power | The instantaneous power generation for feed 2 to the grid, in Watt by default | +| powerAC3 | Number:Power | The instantaneous power generation for feed 3 to the grid, in Watt by default | +| currentPV1 | Number:Current | The current generation for input string 1, in ampere by default | +| currentPV2 | Number:Current | The current generation for input string 2, in ampere by default | +| currentPV3 | Number:Current | The current generation for input string 3, in ampere by default | +| voltagePV1 | Number:Voltage | The voltage on input string 1, in volt by default | +| voltagePV2 | Number:Voltage | The voltage on input string 2, in volt by default | +| voltagePV3 | Number:Voltage | The voltage on input string 3, in volt by default | +| energyToday | Number:Energy | The amount of energy generated today, in kWh by default | +| energyTotal | Number:Energy | The total amount of energy generated, in kWh by default | ## Full Example @@ -38,17 +47,35 @@ Thing omnikinverter:omnik:70ecb4f0 "Solar Inverter" [ hostname="igen-wifi.lan",s ### demo.items ``` -Number OmnikInverterBindingThing_InstantaneousPower "Solar Power" {channel="omnikinverter:omnik:70ecb4f0:power"} -Number OmnikInverterBindingThing_TotalGeneratedEnergyToday "Solar Energy Today" {channel="omnikinverter:omnik:70ecb4f0:energyToday"} -Number OmnikInverterBindingThing_TotalGeneratedEnergy "Solar Energy Total" {channel="omnikinverter:omnik:70ecb4f0:energyTotal"} +Number:Power OmnikInverterBindingThing_InstantaneousPower "Solar Power" {channel="omnikinverter:omnik:70ecb4f0:power"} +Number:Power OmnikInverterBindingThing_InstantaneousPower1 "Solar Power 1" {channel="omnikinverter:omnik:70ecb4f0:powerAC1"} +Number:Power OmnikInverterBindingThing_InstantaneousPower2 "Solar Power 2" {channel="omnikinverter:omnik:70ecb4f0:powerAC2"} +Number:Power OmnikInverterBindingThing_InstantaneousPower3 "Solar Power 3" {channel="omnikinverter:omnik:70ecb4f0:powerAC3"} +Number:Voltage OmnikInverterBindingThing_VoltagePV1 "PV Voltage 1" {channel="omnikinverter:omnik:70ecb4f0:voltagePV1"} +Number:Voltage OmnikInverterBindingThing_VoltagePV2 "PV Voltage 2" {channel="omnikinverter:omnik:70ecb4f0:voltagePV2"} +Number:Voltage OmnikInverterBindingThing_VoltagePV3 "PV Voltage 3" {channel="omnikinverter:omnik:70ecb4f0:voltagePV3"} +Number:Current OmnikInverterBindingThing_CurrentPV1 "PV current 1" {channel="omnikinverter:omnik:70ecb4f0:currentPV1"} +Number:Current OmnikInverterBindingThing_CurrentPV2 "PV current 2" {channel="omnikinverter:omnik:70ecb4f0:currentPV2"} +Number:Current OmnikInverterBindingThing_CurrentPV3 "PV current 3" {channel="omnikinverter:omnik:70ecb4f0:currentPV3"} +Number:Energy OmnikInverterBindingThing_TotalGeneratedEnergyToday "Solar Energy Today" {channel="omnikinverter:omnik:70ecb4f0:energyToday"} +Number:Energy OmnikInverterBindingThing_TotalGeneratedEnergy "Solar Energy Total" {channel="omnikinverter:omnik:70ecb4f0:energyTotal"} ``` ### Sitemap ``` Text item=OmnikInverterBindingThing_InstantaneousPower -Text item=OmnikInverterBindingThing_TotalGeneratedEnergyToday label="Today" -Text item=OmnikInverterBindingThing_TotalGeneratedEnergy label="Total" +Text item=OmnikInverterBindingThing_InstantaneousPower1 +Text item=OmnikInverterBindingThing_InstantaneousPower2 +Text item=OmnikInverterBindingThing_InstantaneousPower3 +Text item=OmnikInverterBindingThing_VoltagePV1 +Text item=OmnikInverterBindingThing_VoltagePV2 +Text item=OmnikInverterBindingThing_VoltagePV3 +Text item=OmnikInverterBindingThing_CurrentPV1 +Text item=OmnikInverterBindingThing_CurrentPV2 +Text item=OmnikInverterBindingThing_CurrentPV3 +Text item=OmnikInverterBindingThing_TotalGeneratedEnergyToday +Text item=OmnikInverterBindingThing_TotalGeneratedEnergy ``` ## References diff --git a/bundles/org.openhab.binding.omnikinverter/src/main/java/org/openhab/binding/omnikinverter/internal/OmnikInverterBindingConstants.java b/bundles/org.openhab.binding.omnikinverter/src/main/java/org/openhab/binding/omnikinverter/internal/OmnikInverterBindingConstants.java index 6716b0520..b7d45d063 100644 --- a/bundles/org.openhab.binding.omnikinverter/src/main/java/org/openhab/binding/omnikinverter/internal/OmnikInverterBindingConstants.java +++ b/bundles/org.openhab.binding.omnikinverter/src/main/java/org/openhab/binding/omnikinverter/internal/OmnikInverterBindingConstants.java @@ -30,7 +30,18 @@ public class OmnikInverterBindingConstants { public static final ThingTypeUID THING_TYPE_OMNIK = new ThingTypeUID(BINDING_ID, "omnik"); // List of all Channel ids + public static final String CHANNEL_CURRENT_PV1 = "currentPV1"; + public static final String CHANNEL_CURRENT_PV2 = "currentPV2"; + public static final String CHANNEL_CURRENT_PV3 = "currentPV3"; + + public static final String CHANNEL_VOLTAGE_PV1 = "voltagePV1"; + public static final String CHANNEL_VOLTAGE_PV2 = "voltagePV2"; + public static final String CHANNEL_VOLTAGE_PV3 = "voltagePV3"; + public static final String CHANNEL_POWER = "power"; + public static final String CHANNEL_POWER_AC1 = "powerAC1"; + public static final String CHANNEL_POWER_AC2 = "powerAC2"; + public static final String CHANNEL_POWER_AC3 = "powerAC3"; public static final String CHANNEL_ENERGY_TODAY = "energyToday"; diff --git a/bundles/org.openhab.binding.omnikinverter/src/main/java/org/openhab/binding/omnikinverter/internal/OmnikInverterMessage.java b/bundles/org.openhab.binding.omnikinverter/src/main/java/org/openhab/binding/omnikinverter/internal/OmnikInverterMessage.java index 9d778314f..dd8cb4122 100644 --- a/bundles/org.openhab.binding.omnikinverter/src/main/java/org/openhab/binding/omnikinverter/internal/OmnikInverterMessage.java +++ b/bundles/org.openhab.binding.omnikinverter/src/main/java/org/openhab/binding/omnikinverter/internal/OmnikInverterMessage.java @@ -30,11 +30,153 @@ public class OmnikInverterMessage { this.bytes = b; } - public double getPower() { + private double getShort(int offset, int compensationFactor) { ByteBuffer buf = ByteBuffer.allocate(2); - buf.put(bytes, 59, 2); + buf.put(bytes, offset, 2); buf.rewind(); - return buf.getShort(); + return (double) buf.getShort() / compensationFactor; + } + + private double getInt(int offset, int compensationFactor) { + ByteBuffer buf = ByteBuffer.allocate(4); + buf.put(bytes, offset, 4); + buf.rewind(); + return (double) buf.getInt() / compensationFactor; + } + + /** + * @return the voltage for PV1 + */ + public double getVoltagePV1() { + return getShort(33, 10); + } + + /** + * @return the voltage for PV2 + */ + public double getVoltagePV2() { + return getShort(35, 10); + } + + /** + * @return the voltage for PV3 + */ + public double getVoltagePV3() { + return getShort(37, 10); + } + + /** + * @return the amperage for PV1 + */ + public double getCurrentPV1() { + return getShort(39, 10); + } + + /** + * @return the amperage for PV2 + */ + public double getCurrentPV2() { + return getShort(41, 10); + } + + /** + * @return the amperage for PV3 + */ + public double getCurrentPV3() { + return getShort(43, 10); + } + + /** + * @return the amperage for AC1 + */ + public double getAmperageAC1() { + return getShort(45, 10); + } + + /** + * @return the amperage for AC2 + */ + public double getAmperageAC2() { + return getShort(47, 10); + } + + /** + * @return the amperage for AC3 + */ + public double getAmperageAC3() { + return getShort(49, 10); + } + + /** + * @return the voltage for AC1 + */ + public double getVoltageAC1() { + return getShort(51, 10); + } + + /** + * @return the voltage for AC2 + */ + public double getVoltageAC2() { + return getShort(53, 10); + } + + /** + * @return the voltage for AC3 + */ + public double getVoltageAC3() { + return getShort(55, 10); + } + + /** + * @return the Frequency for AC1 + */ + public double getFrequencyAC1() { + return getShort(57, 100); + } + + /** + * @return the power for AC1 + * + * @deprecated + */ + public double getPower() { + return getShort(59, 1); + } + + /** + * @return the power for AC1 + */ + public double getPowerAC1() { + return getShort(59, 1); + } + + /** + * @return the Frequency for AC2 + */ + public double getFrequencyAC2() { + return getShort(61, 100); + } + + /** + * @return the power for AC2 + */ + public double getPowerAC2() { + return getShort(63, 1); + } + + /** + * @return the Frequency for AC3 + */ + public double getFrequencyAC3() { + return getShort(65, 100); + } + + /** + * @return the power for AC3 + */ + public double getPowerAC3() { + return getShort(67, 1); } /** @@ -42,10 +184,7 @@ public class OmnikInverterMessage { * @return the total energy outputted this day in kWh */ public double getEnergyToday() { - ByteBuffer buf = ByteBuffer.allocate(2); - buf.put(bytes, 69, 2); - buf.rewind(); - return (buf.getShort() / 100.0); + return getShort(69, 100); } /** @@ -53,9 +192,6 @@ public class OmnikInverterMessage { * @return the total energy outputted in kWh */ public double getTotalEnergy() { - ByteBuffer buf = ByteBuffer.allocate(4); - buf.put(bytes, 71, 4); - buf.rewind(); - return buf.getInt() / 10.0; + return getInt(71, 10); } } diff --git a/bundles/org.openhab.binding.omnikinverter/src/main/java/org/openhab/binding/omnikinverter/internal/handler/OmnikInverterHandler.java b/bundles/org.openhab.binding.omnikinverter/src/main/java/org/openhab/binding/omnikinverter/internal/handler/OmnikInverterHandler.java index d8d2a3110..9fb37e019 100644 --- a/bundles/org.openhab.binding.omnikinverter/src/main/java/org/openhab/binding/omnikinverter/internal/handler/OmnikInverterHandler.java +++ b/bundles/org.openhab.binding.omnikinverter/src/main/java/org/openhab/binding/omnikinverter/internal/handler/OmnikInverterHandler.java @@ -19,6 +19,8 @@ import java.net.UnknownHostException; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import javax.measure.quantity.ElectricCurrent; +import javax.measure.quantity.ElectricPotential; import javax.measure.quantity.Power; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -58,10 +60,9 @@ public class OmnikInverterHandler extends BaseThingHandler { @Override public void handleCommand(ChannelUID channelUID, Command command) { - if (OmnikInverterBindingConstants.CHANNEL_POWER.equals(channelUID.getId())) { - if (command instanceof RefreshType) { - updateData(); - } + // All channels depend on data gotten from `updateData()` + if (command instanceof RefreshType) { + updateData(); } } @@ -94,6 +95,33 @@ public class OmnikInverterHandler extends BaseThingHandler { QuantityType powerQuantity = new QuantityType<>(message.getPower(), Units.WATT); updateState(OmnikInverterBindingConstants.CHANNEL_POWER, powerQuantity); + QuantityType powerQuantity1 = new QuantityType<>(message.getPowerAC1(), Units.WATT); + updateState(OmnikInverterBindingConstants.CHANNEL_POWER_AC1, powerQuantity1); + + QuantityType powerQuantity2 = new QuantityType<>(message.getPowerAC2(), Units.WATT); + updateState(OmnikInverterBindingConstants.CHANNEL_POWER_AC2, powerQuantity2); + + QuantityType powerQuantity3 = new QuantityType<>(message.getPowerAC3(), Units.WATT); + updateState(OmnikInverterBindingConstants.CHANNEL_POWER_AC3, powerQuantity3); + + QuantityType pvAmp1 = new QuantityType<>(message.getCurrentPV1(), Units.AMPERE); + updateState(OmnikInverterBindingConstants.CHANNEL_CURRENT_PV1, pvAmp1); + + QuantityType pvAmp2 = new QuantityType<>(message.getCurrentPV2(), Units.AMPERE); + updateState(OmnikInverterBindingConstants.CHANNEL_CURRENT_PV2, pvAmp2); + + QuantityType pvAmp3 = new QuantityType<>(message.getCurrentPV3(), Units.AMPERE); + updateState(OmnikInverterBindingConstants.CHANNEL_CURRENT_PV3, pvAmp3); + + QuantityType pvVoltage1 = new QuantityType<>(message.getVoltagePV1(), Units.VOLT); + updateState(OmnikInverterBindingConstants.CHANNEL_VOLTAGE_PV1, pvVoltage1); + + QuantityType pvVoltage2 = new QuantityType<>(message.getVoltagePV2(), Units.VOLT); + updateState(OmnikInverterBindingConstants.CHANNEL_VOLTAGE_PV2, pvVoltage2); + + QuantityType pvVoltage3 = new QuantityType<>(message.getVoltagePV3(), Units.VOLT); + updateState(OmnikInverterBindingConstants.CHANNEL_VOLTAGE_PV3, pvVoltage3); + updateState(OmnikInverterBindingConstants.CHANNEL_ENERGY_TODAY, new QuantityType<>(message.getEnergyToday(), Units.KILOWATT_HOUR)); diff --git a/bundles/org.openhab.binding.omnikinverter/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.omnikinverter/src/main/resources/OH-INF/thing/thing-types.xml index 12ec7a4de..21de16074 100644 --- a/bundles/org.openhab.binding.omnikinverter/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.omnikinverter/src/main/resources/OH-INF/thing/thing-types.xml @@ -10,6 +10,15 @@ + + + + + + + + + @@ -36,7 +45,61 @@ Number:Power - The instantaneous power generation + The instantaneous power generation for output 1 + + + + Number:Power + + The instantaneous power generation for output 1 + + + + Number:Power + + The instantaneous power generation for output 2 + + + + Number:Power + + The instantaneous power generation for output 3 + + + + Number:Current + + The current on input string 1 + + + + Number:Current + + The current on input string 2 + + + + Number:Current + + The current on input string 3 + + + + Number:Voltage + + The voltage on input string 1 + + + + Number:Voltage + + The voltage on input string 2 + + + + Number:Voltage + + The voltage PV3 diff --git a/bundles/org.openhab.binding.omnikinverter/src/test/java/org/openhab/binding/omnikinverter/internal/test/OmnikInverterMessageTest.java b/bundles/org.openhab.binding.omnikinverter/src/test/java/org/openhab/binding/omnikinverter/internal/test/OmnikInverterMessageTest.java index 8ae385449..54d4a1654 100644 --- a/bundles/org.openhab.binding.omnikinverter/src/test/java/org/openhab/binding/omnikinverter/internal/test/OmnikInverterMessageTest.java +++ b/bundles/org.openhab.binding.omnikinverter/src/test/java/org/openhab/binding/omnikinverter/internal/test/OmnikInverterMessageTest.java @@ -40,6 +40,51 @@ public class OmnikInverterMessageTest { assertEquals(137.0, message.getPower(), 0.01); } + @Test + public void testGetPowerAC1() { + assertEquals(137.0, message.getPowerAC1(), 0.01); + } + + @Test + public void testGetPowerAC2() { + assertEquals(-1.0, message.getPowerAC2(), 0.01); + } + + @Test + public void testGetPowerAC3() { + assertEquals(-1.0, message.getPowerAC3(), 0.01); + } + + @Test + public void testGetCurrentPV1() { + assertEquals(0.5, message.getCurrentPV1(), 0.01); + } + + @Test + public void testGetCurrentPV2() { + assertEquals(0.6, message.getCurrentPV2(), 0.01); + } + + @Test + public void testGetCurrentPV3() { + assertEquals(-0.1, message.getCurrentPV3(), 0.01); + } + + @Test + public void testGetVoltagePV1() { + assertEquals(160.0, message.getVoltagePV1(), 0.01); + } + + @Test + public void testGetVoltagePV2() { + assertEquals(131.9, message.getVoltagePV2(), 0.01); + } + + @Test + public void testGetVoltagePV3() { + assertEquals(-0.1, message.getVoltagePV3(), 0.01); + } + @Test public void testGetTotalEnergy() { assertEquals(12412.7, message.getTotalEnergy(), 0.01);