From d4c2925b8cfe904ed64296121e5942d5dca7027a Mon Sep 17 00:00:00 2001 From: Josef Date: Mon, 23 Sep 2024 15:06:13 +0200 Subject: [PATCH 1/3] Implement a new ElementToChannelConverter SCALE_FACTOR_MINUS_2_AND_INVERT_IF_TRUE --- .../modbus/api/ElementToChannelConverter.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/io.openems.edge.bridge.modbus/src/io/openems/edge/bridge/modbus/api/ElementToChannelConverter.java b/io.openems.edge.bridge.modbus/src/io/openems/edge/bridge/modbus/api/ElementToChannelConverter.java index 4ab8f28fb73..e8c8cb68a0f 100644 --- a/io.openems.edge.bridge.modbus/src/io/openems/edge/bridge/modbus/api/ElementToChannelConverter.java +++ b/io.openems.edge.bridge.modbus/src/io/openems/edge/bridge/modbus/api/ElementToChannelConverter.java @@ -175,6 +175,19 @@ public static final ElementToChannelConverter SCALE_FACTOR_MINUS_1_AND_INVERT_IF // CHECKSTYLE:ON return chain(SCALE_FACTOR_MINUS_1, INVERT_IF_TRUE(invert)); } + + /** + * Applies {@link ElementToChannelConverter#SCALE_FACTOR_MINUS_2} and + * INVERT_IF_TRUE. + * + * @param invert input value for {@link #INVERT_IF_TRUE(boolean)} + * @return the {@link ElementToChannelConverter} + */ + // CHECKSTYLE:OFF + public static final ElementToChannelConverter SCALE_FACTOR_MINUS_2_AND_INVERT_IF_TRUE(boolean invert) { + // CHECKSTYLE:ON + return chain(SCALE_FACTOR_MINUS_2, INVERT_IF_TRUE(invert)); + } private final Function elementToChannel; private final Function channelToElement; From 9afe1c426d8b59f506a8f78a16fa2e95b76c5ddd Mon Sep 17 00:00:00 2001 From: Josef Date: Mon, 23 Sep 2024 15:24:34 +0200 Subject: [PATCH 2/3] Implement the invert task of Siemens PAC 1600 and corrected the production and consumption energy register. These were swapped. --- .../edge/meter/siemens/pac1600/Config.java | 3 + .../pac1600/MeterSiemensPac1600Impl.java | 142 ++++++++++++------ .../pac1600/MeterSiemensPac1600ImplTest.java | 1 + .../edge/meter/siemens/pac1600/MyConfig.java | 11 ++ 4 files changed, 109 insertions(+), 48 deletions(-) diff --git a/io.openems.edge.meter.siemens/src/io/openems/edge/meter/siemens/pac1600/Config.java b/io.openems.edge.meter.siemens/src/io/openems/edge/meter/siemens/pac1600/Config.java index 0143777c75b..eb63365ddac 100644 --- a/io.openems.edge.meter.siemens/src/io/openems/edge/meter/siemens/pac1600/Config.java +++ b/io.openems.edge.meter.siemens/src/io/openems/edge/meter/siemens/pac1600/Config.java @@ -27,6 +27,9 @@ @AttributeDefinition(name = "Modbus Unit-ID", description = "The Unit-ID of the Modbus device.") int modbusUnitId() default 1; + + @AttributeDefinition(name = "Invert Power", description = "Inverts all Power values, inverts current values, swaps production and consumption energy, i.e. Power is multiplied with -1.") + boolean invert() default false; @AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID'.") String Modbus_target() default "(enabled=true)"; diff --git a/io.openems.edge.meter.siemens/src/io/openems/edge/meter/siemens/pac1600/MeterSiemensPac1600Impl.java b/io.openems.edge.meter.siemens/src/io/openems/edge/meter/siemens/pac1600/MeterSiemensPac1600Impl.java index dbe1c463ce1..f73d6be27d3 100644 --- a/io.openems.edge.meter.siemens/src/io/openems/edge/meter/siemens/pac1600/MeterSiemensPac1600Impl.java +++ b/io.openems.edge.meter.siemens/src/io/openems/edge/meter/siemens/pac1600/MeterSiemensPac1600Impl.java @@ -39,6 +39,8 @@ public class MeterSiemensPac1600Impl extends AbstractOpenemsModbusComponent implements MeterSiemensPac1600, ElectricityMeter, ModbusComponent, OpenemsComponent, ModbusSlave { private MeterType meterType = MeterType.GRID; + /** Invert power values. */ + private boolean invert = false; @Reference protected ConfigurationAdmin cm; @@ -63,6 +65,7 @@ protected void setModbus(BridgeModbus modbus) { @Activate private void activate(ComponentContext context, Config config) throws OpenemsException { this.meterType = config.type(); + this.invert = config.invert(); if (super.activate(context, config.id(), config.alias(), config.enabled(), config.modbusUnitId(), this.cm, "Modbus", config.modbus_id())) { @@ -82,7 +85,7 @@ public MeterType getMeterType() { @Override protected ModbusProtocol defineModbusProtocol() { - return new ModbusProtocol(this, // + var modbusProtocol = new ModbusProtocol(this, // new FC3ReadRegistersTask(1, Priority.HIGH, // m(ElectricityMeter.ChannelId.VOLTAGE_L1, new UnsignedDoublewordElement(1), ElementToChannelConverter.SCALE_FACTOR_1), @@ -105,19 +108,19 @@ protected ModbusProtocol defineModbusProtocol() { m(MeterSiemensPac1600.ChannelId.VOLTAGE_L3L1, new UnsignedDoublewordElement(17), ElementToChannelConverter.SCALE_FACTOR_1), - m(ElectricityMeter.ChannelId.ACTIVE_POWER_L1, new SignedDoublewordElement(19), - ElementToChannelConverter.SCALE_FACTOR_MINUS_2), + m(ElectricityMeter.ChannelId.ACTIVE_POWER_L1, new SignedDoublewordElement(19), + ElementToChannelConverter.SCALE_FACTOR_MINUS_2_AND_INVERT_IF_TRUE(this.invert)), m(ElectricityMeter.ChannelId.ACTIVE_POWER_L2, new SignedDoublewordElement(21), - ElementToChannelConverter.SCALE_FACTOR_MINUS_2), + ElementToChannelConverter.SCALE_FACTOR_MINUS_2_AND_INVERT_IF_TRUE(this.invert)), m(ElectricityMeter.ChannelId.ACTIVE_POWER_L3, new SignedDoublewordElement(23), - ElementToChannelConverter.SCALE_FACTOR_MINUS_2), + ElementToChannelConverter.SCALE_FACTOR_MINUS_2_AND_INVERT_IF_TRUE(this.invert)), m(ElectricityMeter.ChannelId.REACTIVE_POWER_L1, new SignedDoublewordElement(25), - ElementToChannelConverter.SCALE_FACTOR_MINUS_2), + ElementToChannelConverter.SCALE_FACTOR_MINUS_2_AND_INVERT_IF_TRUE(this.invert)), m(ElectricityMeter.ChannelId.REACTIVE_POWER_L2, new SignedDoublewordElement(27), - ElementToChannelConverter.SCALE_FACTOR_MINUS_2), + ElementToChannelConverter.SCALE_FACTOR_MINUS_2_AND_INVERT_IF_TRUE(this.invert)), m(ElectricityMeter.ChannelId.REACTIVE_POWER_L3, new SignedDoublewordElement(29), - ElementToChannelConverter.SCALE_FACTOR_MINUS_2)), + ElementToChannelConverter.SCALE_FACTOR_MINUS_2_AND_INVERT_IF_TRUE(this.invert))), new FC3ReadRegistersTask(49, Priority.HIGH, // DummyRegisterElement didn`t work here m(ElectricityMeter.ChannelId.FREQUENCY, new SignedDoublewordElement(49), @@ -128,47 +131,90 @@ protected ModbusProtocol defineModbusProtocol() { ElementToChannelConverter.SCALE_FACTOR_1), new DummyRegisterElement(55, 56), // m(ElectricityMeter.ChannelId.ACTIVE_POWER, new SignedDoublewordElement(57), - ElementToChannelConverter.SCALE_FACTOR_MINUS_2), + ElementToChannelConverter.SCALE_FACTOR_MINUS_2_AND_INVERT_IF_TRUE(this.invert)), m(ElectricityMeter.ChannelId.REACTIVE_POWER, new SignedDoublewordElement(59), - ElementToChannelConverter.SCALE_FACTOR_MINUS_2)), - - new FC3ReadRegistersTask(6687, Priority.LOW, - m(ElectricityMeter.ChannelId.ACTIVE_CONSUMPTION_ENERGY, new UnsignedDoublewordElement(6687), - ElementToChannelConverter.DIRECT_1_TO_1), - m(ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY, new UnsignedDoublewordElement(6689), - ElementToChannelConverter.DIRECT_1_TO_1), - m(MeterSiemensPac1600.ChannelId.REACTIVE_CONSUMPTION_ENERGY, - new UnsignedDoublewordElement(6691), ElementToChannelConverter.DIRECT_1_TO_1), - m(MeterSiemensPac1600.ChannelId.REACTIVE_PRODUCTION_ENERGY, new UnsignedDoublewordElement(6693), - ElementToChannelConverter.DIRECT_1_TO_1), - new DummyRegisterElement(6695, 6706), - m(ElectricityMeter.ChannelId.ACTIVE_CONSUMPTION_ENERGY_L1, new UnsignedDoublewordElement(6707), - ElementToChannelConverter.DIRECT_1_TO_1), - m(ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY_L1, new UnsignedDoublewordElement(6709), - ElementToChannelConverter.DIRECT_1_TO_1), - m(MeterSiemensPac1600.ChannelId.REACTIVE_CONSUMPTION_ENERGY_L1, - new UnsignedDoublewordElement(6711), ElementToChannelConverter.DIRECT_1_TO_1), - m(MeterSiemensPac1600.ChannelId.REACTIVE_PRODUCTION_ENERGY_L1, - new UnsignedDoublewordElement(6713), ElementToChannelConverter.DIRECT_1_TO_1)), - - new FC3ReadRegistersTask(6727, Priority.LOW, // DummyRegisterElement didn`t work here - m(ElectricityMeter.ChannelId.ACTIVE_CONSUMPTION_ENERGY_L2, new UnsignedDoublewordElement(6727), - ElementToChannelConverter.DIRECT_1_TO_1), - m(ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY_L2, new UnsignedDoublewordElement(6729), - ElementToChannelConverter.DIRECT_1_TO_1), - m(MeterSiemensPac1600.ChannelId.REACTIVE_CONSUMPTION_ENERGY_L2, - new UnsignedDoublewordElement(6731), ElementToChannelConverter.DIRECT_1_TO_1), - m(MeterSiemensPac1600.ChannelId.REACTIVE_PRODUCTION_ENERGY_L2, - new UnsignedDoublewordElement(6733), ElementToChannelConverter.DIRECT_1_TO_1), - new DummyRegisterElement(6735, 6746), - m(ElectricityMeter.ChannelId.ACTIVE_CONSUMPTION_ENERGY_L3, new UnsignedDoublewordElement(6747), - ElementToChannelConverter.DIRECT_1_TO_1), - m(ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY_L3, new UnsignedDoublewordElement(6749), - ElementToChannelConverter.DIRECT_1_TO_1), - m(MeterSiemensPac1600.ChannelId.REACTIVE_CONSUMPTION_ENERGY_L3, - new UnsignedDoublewordElement(6751), ElementToChannelConverter.DIRECT_1_TO_1), - m(MeterSiemensPac1600.ChannelId.REACTIVE_PRODUCTION_ENERGY_L3, - new UnsignedDoublewordElement(6753), ElementToChannelConverter.DIRECT_1_TO_1))); + ElementToChannelConverter.SCALE_FACTOR_MINUS_2_AND_INVERT_IF_TRUE(this.invert)))); + if (this.invert) { + modbusProtocol.addTask(new FC3ReadRegistersTask(6687, Priority.LOW, + m(ElectricityMeter.ChannelId.ACTIVE_CONSUMPTION_ENERGY, new UnsignedDoublewordElement(6687), + ElementToChannelConverter.DIRECT_1_TO_1), + m(ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY, new UnsignedDoublewordElement(6689), + ElementToChannelConverter.DIRECT_1_TO_1), + m(MeterSiemensPac1600.ChannelId.REACTIVE_CONSUMPTION_ENERGY, + new UnsignedDoublewordElement(6691), ElementToChannelConverter.DIRECT_1_TO_1), + m(MeterSiemensPac1600.ChannelId.REACTIVE_PRODUCTION_ENERGY, new UnsignedDoublewordElement(6693), + ElementToChannelConverter.DIRECT_1_TO_1), + new DummyRegisterElement(6695, 6706), + m(ElectricityMeter.ChannelId.ACTIVE_CONSUMPTION_ENERGY_L1, new UnsignedDoublewordElement(6707), + ElementToChannelConverter.DIRECT_1_TO_1), + m(ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY_L1, new UnsignedDoublewordElement(6709), + ElementToChannelConverter.DIRECT_1_TO_1), + m(MeterSiemensPac1600.ChannelId.REACTIVE_CONSUMPTION_ENERGY_L1, + new UnsignedDoublewordElement(6711), ElementToChannelConverter.DIRECT_1_TO_1), + m(MeterSiemensPac1600.ChannelId.REACTIVE_PRODUCTION_ENERGY_L1, + new UnsignedDoublewordElement(6713), ElementToChannelConverter.DIRECT_1_TO_1))); + + modbusProtocol.addTask(new FC3ReadRegistersTask(6727, Priority.LOW, // DummyRegisterElement didn`t work here + m(ElectricityMeter.ChannelId.ACTIVE_CONSUMPTION_ENERGY_L2, new UnsignedDoublewordElement(6727), + ElementToChannelConverter.DIRECT_1_TO_1), + m(ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY_L2, new UnsignedDoublewordElement(6729), + ElementToChannelConverter.DIRECT_1_TO_1), + m(MeterSiemensPac1600.ChannelId.REACTIVE_CONSUMPTION_ENERGY_L2, + new UnsignedDoublewordElement(6731), ElementToChannelConverter.DIRECT_1_TO_1), + m(MeterSiemensPac1600.ChannelId.REACTIVE_PRODUCTION_ENERGY_L2, + new UnsignedDoublewordElement(6733), ElementToChannelConverter.DIRECT_1_TO_1), + new DummyRegisterElement(6735, 6746), + m(ElectricityMeter.ChannelId.ACTIVE_CONSUMPTION_ENERGY_L3, new UnsignedDoublewordElement(6747), + ElementToChannelConverter.DIRECT_1_TO_1), + m(ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY_L3, new UnsignedDoublewordElement(6749), + ElementToChannelConverter.DIRECT_1_TO_1), + m(MeterSiemensPac1600.ChannelId.REACTIVE_CONSUMPTION_ENERGY_L3, + new UnsignedDoublewordElement(6751), ElementToChannelConverter.DIRECT_1_TO_1), + m(MeterSiemensPac1600.ChannelId.REACTIVE_PRODUCTION_ENERGY_L3, + new UnsignedDoublewordElement(6753), ElementToChannelConverter.DIRECT_1_TO_1))); + } + else { + modbusProtocol.addTask(new FC3ReadRegistersTask(6687, Priority.LOW, + m(ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY, new UnsignedDoublewordElement(6687), + ElementToChannelConverter.DIRECT_1_TO_1), + m(ElectricityMeter.ChannelId.ACTIVE_CONSUMPTION_ENERGY, new UnsignedDoublewordElement(6689), + ElementToChannelConverter.DIRECT_1_TO_1), + m(MeterSiemensPac1600.ChannelId.REACTIVE_PRODUCTION_ENERGY, + new UnsignedDoublewordElement(6691), ElementToChannelConverter.DIRECT_1_TO_1), + m(MeterSiemensPac1600.ChannelId.REACTIVE_CONSUMPTION_ENERGY, new UnsignedDoublewordElement(6693), + ElementToChannelConverter.DIRECT_1_TO_1), + new DummyRegisterElement(6695, 6706), + m(ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY_L1, new UnsignedDoublewordElement(6707), + ElementToChannelConverter.DIRECT_1_TO_1), + m(ElectricityMeter.ChannelId.ACTIVE_CONSUMPTION_ENERGY_L1, new UnsignedDoublewordElement(6709), + ElementToChannelConverter.DIRECT_1_TO_1), + m(MeterSiemensPac1600.ChannelId.REACTIVE_PRODUCTION_ENERGY_L1, + new UnsignedDoublewordElement(6711), ElementToChannelConverter.DIRECT_1_TO_1), + m(MeterSiemensPac1600.ChannelId.REACTIVE_CONSUMPTION_ENERGY_L1, + new UnsignedDoublewordElement(6713), ElementToChannelConverter.DIRECT_1_TO_1))); + + modbusProtocol.addTask(new FC3ReadRegistersTask(6727, Priority.LOW, // DummyRegisterElement didn`t work here + m(ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY_L2, new UnsignedDoublewordElement(6727), + ElementToChannelConverter.DIRECT_1_TO_1), + m(ElectricityMeter.ChannelId.ACTIVE_CONSUMPTION_ENERGY_L2, new UnsignedDoublewordElement(6729), + ElementToChannelConverter.DIRECT_1_TO_1), + m(MeterSiemensPac1600.ChannelId.REACTIVE_PRODUCTION_ENERGY_L2, + new UnsignedDoublewordElement(6731), ElementToChannelConverter.DIRECT_1_TO_1), + m(MeterSiemensPac1600.ChannelId.REACTIVE_CONSUMPTION_ENERGY_L2, + new UnsignedDoublewordElement(6733), ElementToChannelConverter.DIRECT_1_TO_1), + new DummyRegisterElement(6735, 6746), + m(ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY_L3, new UnsignedDoublewordElement(6747), + ElementToChannelConverter.DIRECT_1_TO_1), + m(ElectricityMeter.ChannelId.ACTIVE_CONSUMPTION_ENERGY_L3, new UnsignedDoublewordElement(6749), + ElementToChannelConverter.DIRECT_1_TO_1), + m(MeterSiemensPac1600.ChannelId.REACTIVE_PRODUCTION_ENERGY_L3, + new UnsignedDoublewordElement(6751), ElementToChannelConverter.DIRECT_1_TO_1), + m(MeterSiemensPac1600.ChannelId.REACTIVE_CONSUMPTION_ENERGY_L3, + new UnsignedDoublewordElement(6753), ElementToChannelConverter.DIRECT_1_TO_1))); + } + + + return modbusProtocol; } @Override diff --git a/io.openems.edge.meter.siemens/test/io/openems/edge/meter/siemens/pac1600/MeterSiemensPac1600ImplTest.java b/io.openems.edge.meter.siemens/test/io/openems/edge/meter/siemens/pac1600/MeterSiemensPac1600ImplTest.java index 98707507163..f9f6d731f39 100644 --- a/io.openems.edge.meter.siemens/test/io/openems/edge/meter/siemens/pac1600/MeterSiemensPac1600ImplTest.java +++ b/io.openems.edge.meter.siemens/test/io/openems/edge/meter/siemens/pac1600/MeterSiemensPac1600ImplTest.java @@ -21,6 +21,7 @@ public void test() throws Exception { .setId(METER_ID) // .setModbusId(MODBUS_ID) // .setType(MeterType.GRID) // + .setInvert(false) // .build()) // ; } diff --git a/io.openems.edge.meter.siemens/test/io/openems/edge/meter/siemens/pac1600/MyConfig.java b/io.openems.edge.meter.siemens/test/io/openems/edge/meter/siemens/pac1600/MyConfig.java index 52cc1aa53da..c236898f081 100644 --- a/io.openems.edge.meter.siemens/test/io/openems/edge/meter/siemens/pac1600/MyConfig.java +++ b/io.openems.edge.meter.siemens/test/io/openems/edge/meter/siemens/pac1600/MyConfig.java @@ -12,6 +12,7 @@ protected static class Builder { private String modbusId; private int modbusUnitId; private MeterType type; + private boolean invert; private Builder() { } @@ -30,6 +31,11 @@ public Builder setType(MeterType type) { this.type = type; return this; } + + public Builder setInvert(boolean invert) { + this.invert = invert; + return this; + } public MyConfig build() { return new MyConfig(this); @@ -72,4 +78,9 @@ public MeterType type() { return this.builder.type; } + @Override + public boolean invert() { + return this.builder.invert; + } + } \ No newline at end of file From 90774835ddf4a8478ec114585addba300a771634 Mon Sep 17 00:00:00 2001 From: JosefRick <93322344+JosefRick@users.noreply.github.com> Date: Fri, 27 Sep 2024 11:02:14 +0200 Subject: [PATCH 3/3] Update MeterSiemensPac1600Impl.java Changes the position of a bracket because it caused an error in the build check. --- .../edge/meter/siemens/pac1600/MeterSiemensPac1600Impl.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/io.openems.edge.meter.siemens/src/io/openems/edge/meter/siemens/pac1600/MeterSiemensPac1600Impl.java b/io.openems.edge.meter.siemens/src/io/openems/edge/meter/siemens/pac1600/MeterSiemensPac1600Impl.java index f73d6be27d3..db377178708 100644 --- a/io.openems.edge.meter.siemens/src/io/openems/edge/meter/siemens/pac1600/MeterSiemensPac1600Impl.java +++ b/io.openems.edge.meter.siemens/src/io/openems/edge/meter/siemens/pac1600/MeterSiemensPac1600Impl.java @@ -172,8 +172,7 @@ protected ModbusProtocol defineModbusProtocol() { new UnsignedDoublewordElement(6751), ElementToChannelConverter.DIRECT_1_TO_1), m(MeterSiemensPac1600.ChannelId.REACTIVE_PRODUCTION_ENERGY_L3, new UnsignedDoublewordElement(6753), ElementToChannelConverter.DIRECT_1_TO_1))); - } - else { + } else { modbusProtocol.addTask(new FC3ReadRegistersTask(6687, Priority.LOW, m(ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY, new UnsignedDoublewordElement(6687), ElementToChannelConverter.DIRECT_1_TO_1), @@ -228,4 +227,4 @@ public ModbusSlaveTable getModbusSlaveTable(AccessMode accessMode) { OpenemsComponent.getModbusSlaveNatureTable(accessMode), // ElectricityMeter.getModbusSlaveNatureTable(accessMode)); } -} \ No newline at end of file +}