From ef17b063b7691ba6247238a95760580a95ac00a8 Mon Sep 17 00:00:00 2001 From: Michael Grill Date: Thu, 3 Mar 2022 09:56:48 +0100 Subject: [PATCH] Modbus/TCP: Add GridMode to Sum (#204) GridMode can now be read via Modbus Address `417`. Additionally: - Add new type `enum16` - Show `text` of Channels in Description - Improve texts for Channels Co-authored-by: FENECON\michael.grill Co-authored-by: Stefan Feilmeier Reviewed-on: https://git.intranet.fenecon.de/FENECON/fems/pulls/204 Reviewed-by: Stefan Feilmeier Co-authored-by: Michael Grill Co-committed-by: Michael Grill --- .../io/openems/common/OpenemsConstants.java | 2 - .../io/openems/common/types/OptionsEnum.java | 6 +- .../openems/edge/common/channel/EnumDoc.java | 19 + .../common/component/OpenemsComponent.java | 10 +- .../modbusslave/ModbusRecordChannel.java | 21 +- .../modbusslave/ModbusRecordFloat32.java | 2 +- .../modbusslave/ModbusRecordFloat64.java | 2 +- .../modbusslave/ModbusRecordString16.java | 2 +- .../modbusslave/ModbusRecordUint16.java | 2 +- .../modbusslave/ModbusRecordUint16Hash.java | 2 +- .../modbusslave/ModbusRecordUint32.java | 2 +- .../modbusslave/ModbusSlaveNatureTable.java | 1 + .../edge/common/modbusslave/ModbusType.java | 1 + .../src/io/openems/edge/common/sum/Sum.java | 62 +- .../GetModbusProtocolExportXlsxResponse.java | 17 +- .../openems/edge/ess/api/AsymmetricEss.java | 28 +- .../edge/ess/api/CalculateGridMode.java | 4 + .../io/openems/edge/ess/api/HybridEss.java | 4 +- .../io/openems/edge/ess/api/SymmetricEss.java | 6 +- .../edge/meter/api/SymmetricMeter.java | 5 +- .../simulator/evcs/AsymmetricMeterEvcs.java | 911 +++++++++--------- 21 files changed, 566 insertions(+), 543 deletions(-) diff --git a/io.openems.common/src/io/openems/common/OpenemsConstants.java b/io.openems.common/src/io/openems/common/OpenemsConstants.java index db4e441c2a0..a4cad1a4925 100644 --- a/io.openems.common/src/io/openems/common/OpenemsConstants.java +++ b/io.openems.common/src/io/openems/common/OpenemsConstants.java @@ -98,8 +98,6 @@ public class OpenemsConstants { */ public static final String MANUFACTURER_EMS_SERIAL_NUMBER = ""; - public static final String POWER_DOC_TEXT = "Negative values for Consumption; positive for Production"; - /* * Constants for Component properties */ diff --git a/io.openems.common/src/io/openems/common/types/OptionsEnum.java b/io.openems.common/src/io/openems/common/types/OptionsEnum.java index 2663c09b432..981b3880d82 100644 --- a/io.openems.common/src/io/openems/common/types/OptionsEnum.java +++ b/io.openems.common/src/io/openems/common/types/OptionsEnum.java @@ -9,21 +9,21 @@ public interface OptionsEnum { * * @return the int representation */ - int getValue(); + public int getValue(); /** * Gets this enums String representation. * * @return the String representation */ - String getName(); + public String getName(); /** * Gets the enum that is used for 'UNDEFINED' values. * * @return the UNDEFINED enum */ - OptionsEnum getUndefined(); + public OptionsEnum getUndefined(); /** * Gets the name in CamelCase format. diff --git a/io.openems.edge.common/src/io/openems/edge/common/channel/EnumDoc.java b/io.openems.edge.common/src/io/openems/edge/common/channel/EnumDoc.java index 0527ca8c07b..a0aaa761507 100644 --- a/io.openems.edge.common/src/io/openems/edge/common/channel/EnumDoc.java +++ b/io.openems.edge.common/src/io/openems/edge/common/channel/EnumDoc.java @@ -1,6 +1,8 @@ package io.openems.edge.common.channel; import java.util.Arrays; +import java.util.stream.Collectors; +import java.util.stream.Stream; import io.openems.common.channel.ChannelCategory; import io.openems.common.exceptions.OpenemsError; @@ -143,4 +145,21 @@ public String getOptionString(Integer value) { } return option.getName(); } + + @Override + public String getText() { + // If Doc has a Text, return it + var docText = super.getText(); + if (!docText.isBlank()) { + return docText; + } + // Otherwise generate Text from options without UNDEFINED option in the form + // ":, :". + return Stream.of(this.options) // + .filter(option -> !option.isUndefined()) // + .map(option -> { // + return option.getValue() + ":" + option.getName(); // + }) // + .collect(Collectors.joining(", ")); + } } diff --git a/io.openems.edge.common/src/io/openems/edge/common/component/OpenemsComponent.java b/io.openems.edge.common/src/io/openems/edge/common/component/OpenemsComponent.java index fa83d14e663..1279e161a0e 100644 --- a/io.openems.edge.common/src/io/openems/edge/common/component/OpenemsComponent.java +++ b/io.openems.edge.common/src/io/openems/edge/common/component/OpenemsComponent.java @@ -4,6 +4,8 @@ import java.util.Collection; import java.util.Dictionary; import java.util.Hashtable; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.osgi.framework.Constants; import org.osgi.service.cm.Configuration; @@ -187,6 +189,12 @@ default > T channel(io.openems.edge.common.channel.ChannelI public enum ChannelId implements io.openems.edge.common.channel.ChannelId { // Running State of the component. Keep values in sync with 'Level' enum! STATE(new StateCollectorChannelDoc() // + // Set Text to "0:Ok, 1:Info, 2:Warning, 3:Fault" + .text(Stream.of(Level.values()) // + .map(option -> { // + return option.getValue() + ":" + option.getName(); // + }) // + .collect(Collectors.joining(", "))) // .persistencePriority(PersistencePriority.VERY_HIGH)); private final Doc doc; @@ -210,7 +218,7 @@ public Doc doc() { */ public static ModbusSlaveNatureTable getModbusSlaveNatureTable(AccessMode accessMode) { return ModbusSlaveNatureTable.of(OpenemsComponent.class, accessMode, 80) // - .channel(0, ChannelId.STATE, ModbusType.UINT16) // + .channel(0, ChannelId.STATE, ModbusType.ENUM16) // .build(); } diff --git a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordChannel.java b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordChannel.java index 88065a3879a..6b2c198f89a 100644 --- a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordChannel.java +++ b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordChannel.java @@ -1,9 +1,7 @@ package io.openems.edge.common.modbusslave; import java.nio.ByteBuffer; -import java.util.Arrays; import java.util.function.Consumer; -import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -13,8 +11,6 @@ import io.openems.common.types.ChannelAddress; import io.openems.edge.common.channel.Channel; import io.openems.edge.common.channel.ChannelId; -import io.openems.edge.common.channel.Doc; -import io.openems.edge.common.channel.EnumDoc; import io.openems.edge.common.component.OpenemsComponent; public class ModbusRecordChannel extends ModbusRecord { @@ -49,6 +45,7 @@ public ModbusRecordChannel(int offset, ModbusType type, ChannelId channelId, Acc case STRING16: byteLength = ModbusRecordString16.BYTE_LENGTH; break; + case ENUM16: case UINT16: byteLength = ModbusRecordUint16.BYTE_LENGTH; break; @@ -141,6 +138,7 @@ public byte[] getValue(OpenemsComponent component) { case WRITE_ONLY: return ModbusRecordString16Reserved.UNDEFINED_VALUE; } + case ENUM16: case UINT16: switch (this.accessMode) { case READ_ONLY: @@ -211,6 +209,8 @@ public void writeValue(OpenemsComponent component, int index, byte byte1, byte b case STRING16: value = ""; // TODO implement String conversion break; + + case ENUM16: case UINT16: value = buff.getShort(); break; @@ -239,18 +239,7 @@ public Unit getUnit() { @Override public String getValueDescription() { - Doc doc = this.channelId.doc(); - if (doc instanceof EnumDoc) { - // List possible Options for this Enum - EnumDoc d = (EnumDoc) doc; - return Arrays.stream(d.getOptions()) // - .map(option -> { - return option.getValue() + ":" + option.getName(); - }) // - .collect(Collectors.joining(", ")); - } - - return ""; // TODO get some meaningful text from Doc(), like 'between 0 and 100 %' + return this.channelId.doc().getText(); } @Override diff --git a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordFloat32.java b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordFloat32.java index cb1046260b4..3db0a20833d 100644 --- a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordFloat32.java +++ b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordFloat32.java @@ -37,7 +37,7 @@ public static byte[] toByteArray(Object value) { @Override public String getValueDescription() { - return this.value != null ? this.value.toString() : ""; + return this.value != null ? "\"" + this.value.toString() + "\"" : ""; } } diff --git a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordFloat64.java b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordFloat64.java index 0f4c533c6c6..fef6ae080c7 100644 --- a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordFloat64.java +++ b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordFloat64.java @@ -38,7 +38,7 @@ public static byte[] toByteArray(Object value) { @Override public String getValueDescription() { - return this.value != null ? this.value.toString() : ""; + return this.value != null ? "\"" + this.value.toString() + "\"" : ""; } } diff --git a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordString16.java b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordString16.java index 7aa650a25e1..a31c0b4ed68 100644 --- a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordString16.java +++ b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordString16.java @@ -40,7 +40,7 @@ public static byte[] toByteArray(Object value) { @Override public String getValueDescription() { - return this.value != null ? this.value : ""; + return this.value != null ? "\"" + this.value.toString() + "\"" : ""; } } diff --git a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordUint16.java b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordUint16.java index ee97363f202..4f7bafbdf71 100644 --- a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordUint16.java +++ b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordUint16.java @@ -38,7 +38,7 @@ public static byte[] toByteArray(Object value) { @Override public String getValueDescription() { - return this.value != null ? Short.toString(this.value) : ""; + return this.value != null ? "\"" + Short.toString(this.value) + "\"" : ""; } } diff --git a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordUint16Hash.java b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordUint16Hash.java index eedcce0caf9..f713755fbe7 100644 --- a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordUint16Hash.java +++ b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordUint16Hash.java @@ -17,7 +17,7 @@ public String toString() { @Override public String getValueDescription() { - return "0x" + Integer.toHexString(this.value & 0xffff); + return "\"0x" + Integer.toHexString(this.value & 0xffff) + "\""; } } diff --git a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordUint32.java b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordUint32.java index 8b9e24aabbd..329c80067d8 100644 --- a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordUint32.java +++ b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusRecordUint32.java @@ -38,7 +38,7 @@ public static byte[] toByteArray(Object value) { @Override public String getValueDescription() { - return this.value != null ? Integer.toString(this.value) : ""; + return this.value != null ? "\"" + Integer.toString(this.value) + "\"" : ""; } } diff --git a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusSlaveNatureTable.java b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusSlaveNatureTable.java index c71f949af1b..e84968cca88 100644 --- a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusSlaveNatureTable.java +++ b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusSlaveNatureTable.java @@ -48,6 +48,7 @@ public Builder channel(int offset, ChannelId channelId, ModbusType type) { case STRING16: this.string16Reserved(offset); break; + case ENUM16: case UINT16: this.uint16Reserved(offset); break; diff --git a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusType.java b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusType.java index f1827a15f03..88f2067b89c 100644 --- a/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusType.java +++ b/io.openems.edge.common/src/io/openems/edge/common/modbusslave/ModbusType.java @@ -1,6 +1,7 @@ package io.openems.edge.common.modbusslave; public enum ModbusType { + ENUM16(1, "enum16"), // UINT16(1, "uint16"), // UINT32(2, "uint32"), // FLOAT32(2, "float32"), // diff --git a/io.openems.edge.common/src/io/openems/edge/common/sum/Sum.java b/io.openems.edge.common/src/io/openems/edge/common/sum/Sum.java index b67410dec1f..0368998f070 100644 --- a/io.openems.edge.common/src/io/openems/edge/common/sum/Sum.java +++ b/io.openems.edge.common/src/io/openems/edge/common/sum/Sum.java @@ -1,6 +1,5 @@ package io.openems.edge.common.sum; -import io.openems.common.OpenemsConstants; import io.openems.common.channel.AccessMode; import io.openems.common.channel.Level; import io.openems.common.channel.PersistencePriority; @@ -37,7 +36,8 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { */ ESS_SOC(Doc.of(OpenemsType.INTEGER) // .unit(Unit.PERCENT) // - .persistencePriority(PersistencePriority.VERY_HIGH)), + .persistencePriority(PersistencePriority.VERY_HIGH) // + .text("Range 0..100")), // /** * Ess: Active Power. * @@ -51,7 +51,9 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { ESS_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // .persistencePriority(PersistencePriority.VERY_HIGH) // - .text(OpenemsConstants.POWER_DOC_TEXT)), + .text("AC-side power of Energy Storage System. " // + + "Includes excess DC-PV production for hybrid inverters. " // + + "Negative values for charge; positive for discharge")), /** * Reactive Power. * @@ -59,14 +61,11 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { *
  • Interface: Ess Symmetric *
  • Type: Integer *
  • Unit: var - *
  • Range: negative values for Charge; positive for Discharge * */ ESS_REACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // .unit(Unit.VOLT_AMPERE_REACTIVE) // - .persistencePriority(PersistencePriority.VERY_HIGH) // - .text(OpenemsConstants.POWER_DOC_TEXT) // - ), + .persistencePriority(PersistencePriority.VERY_HIGH)), // /** * Ess: Active Power L1. * @@ -80,7 +79,9 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { ESS_ACTIVE_POWER_L1(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // .persistencePriority(PersistencePriority.VERY_HIGH) // - .text(OpenemsConstants.POWER_DOC_TEXT)), + .text("AC-side power of Energy Storage System on phase L1. " // + + "Includes excess DC-PV production for hybrid inverters. " // + + "Negative values for charge; positive for discharge")), /** * Ess: Active Power L2. * @@ -94,7 +95,9 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { ESS_ACTIVE_POWER_L2(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // .persistencePriority(PersistencePriority.VERY_HIGH) // - .text(OpenemsConstants.POWER_DOC_TEXT)), + .text("AC-side power of Energy Storage System on phase L2. " // + + "Includes excess DC-PV production for hybrid inverters. " // + + "Negative values for charge; positive for discharge")), /** * Ess: Active Power L3. * @@ -108,7 +111,9 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { ESS_ACTIVE_POWER_L3(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // .persistencePriority(PersistencePriority.VERY_HIGH) // - .text(OpenemsConstants.POWER_DOC_TEXT)), + .text("AC-side power of Energy Storage System on phase L3. " // + + "Includes excess DC-PV production for hybrid inverters. " // + + "Negative values for charge; positive for discharge")), /** * Ess: Discharge Power. * @@ -127,7 +132,8 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { ESS_DISCHARGE_POWER(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // .persistencePriority(PersistencePriority.VERY_HIGH) // - .text(OpenemsConstants.POWER_DOC_TEXT)), + .text("Actual AC-side battery discharge power of Energy Storage System. " // + + "Negative values for charge; positive for discharge")), /** * Ess: Capacity. * @@ -157,7 +163,8 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { GRID_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // .persistencePriority(PersistencePriority.VERY_HIGH) // - .text(OpenemsConstants.POWER_DOC_TEXT)), + .text("Grid exchange power. " // + + "Negative values for sell-to-grid; positive for buy-from-grid")), /** * Grid: Active Power L1. * @@ -173,7 +180,8 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { GRID_ACTIVE_POWER_L1(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // .persistencePriority(PersistencePriority.VERY_HIGH) // - .text(OpenemsConstants.POWER_DOC_TEXT)), + .text("Grid exchange power on phase L1. " // + + "Negative values for sell-to-grid; positive for buy-from-grid")), /** * Grid: Active Power L2. * @@ -189,7 +197,8 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { GRID_ACTIVE_POWER_L2(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // .persistencePriority(PersistencePriority.VERY_HIGH) // - .text(OpenemsConstants.POWER_DOC_TEXT)), + .text("Grid exchange power on phase L2. " // + + "Negative values for sell-to-grid; positive for buy-from-grid")), /** * Grid: Active Power L3. * @@ -205,7 +214,8 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { GRID_ACTIVE_POWER_L3(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // .persistencePriority(PersistencePriority.VERY_HIGH) // - .text(OpenemsConstants.POWER_DOC_TEXT)), + .text("Grid exchange power on phase L3. " // + + "Negative values for sell-to-grid; positive for buy-from-grid")), /** * Grid: Minimum Ever Active Power. * @@ -244,7 +254,8 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { */ PRODUCTION_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // - .persistencePriority(PersistencePriority.VERY_HIGH)), // + .persistencePriority(PersistencePriority.VERY_HIGH) // + .text("Total production; always positive")), /** * Production: AC Active Power. * @@ -257,7 +268,8 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { */ PRODUCTION_AC_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // - .persistencePriority(PersistencePriority.VERY_HIGH)), // + .persistencePriority(PersistencePriority.VERY_HIGH) // + .text("Production from AC source")), /** * Production: AC Active Power L1. * @@ -270,7 +282,8 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { */ PRODUCTION_AC_ACTIVE_POWER_L1(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // - .persistencePriority(PersistencePriority.VERY_HIGH)), // + .persistencePriority(PersistencePriority.VERY_HIGH) // + .text("Production from AC source on phase L1")), /** * Production: AC Active Power L2. * @@ -283,7 +296,8 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { */ PRODUCTION_AC_ACTIVE_POWER_L2(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // - .persistencePriority(PersistencePriority.VERY_HIGH)), // + .persistencePriority(PersistencePriority.VERY_HIGH) // + .text("Production from AC source on phase L2")), /** * Production: AC Active Power L3. * @@ -296,7 +310,8 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { */ PRODUCTION_AC_ACTIVE_POWER_L3(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // - .persistencePriority(PersistencePriority.VERY_HIGH)), // + .persistencePriority(PersistencePriority.VERY_HIGH) // + .text("Production from AC source on phase L3")), /** * Production: DC Actual Power. * @@ -309,7 +324,8 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { */ PRODUCTION_DC_ACTUAL_POWER(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // - .persistencePriority(PersistencePriority.VERY_HIGH)), // + .persistencePriority(PersistencePriority.VERY_HIGH) // + .text("Production from DC source")), /** * Production: Maximum Ever Active Power. * @@ -428,7 +444,7 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { *
      *
    • Interface: Sum (origin: SymmetricEss)) *
    • Type: Integer - *
    • Values: '0' = UNDEFINED, '1' = ON GRID, '2' = OFF GRID + *
    • Values: '-1' = UNDEFINED, '1' = On-Grid, '2' = Off-Grid *
    */ GRID_MODE(Doc.of(GridMode.values()) // @@ -550,7 +566,6 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { *
  • Unit: Wh * */ - // TODO rename to Actual_Energy PRODUCTION_DC_ACTIVE_ENERGY(Doc.of(OpenemsType.LONG) // .unit(Unit.WATT_HOURS) // .persistencePriority(PersistencePriority.VERY_HIGH)), // @@ -643,6 +658,7 @@ public static ModbusSlaveNatureTable getModbusSlaveNatureTable(AccessMode access .channel(109, ChannelId.CONSUMPTION_ACTIVE_POWER_L2, ModbusType.FLOAT32) // .channel(111, ChannelId.CONSUMPTION_ACTIVE_POWER_L3, ModbusType.FLOAT32) // .channel(113, ChannelId.ESS_DISCHARGE_POWER, ModbusType.FLOAT32) // + .channel(115, ChannelId.GRID_MODE, ModbusType.ENUM16) // .build(); } diff --git a/io.openems.edge.controller.api.modbus/src/io/openems/edge/controller/api/modbus/jsonrpc/GetModbusProtocolExportXlsxResponse.java b/io.openems.edge.controller.api.modbus/src/io/openems/edge/controller/api/modbus/jsonrpc/GetModbusProtocolExportXlsxResponse.java index 30e660a95e7..f400d9e6e35 100644 --- a/io.openems.edge.controller.api.modbus/src/io/openems/edge/controller/api/modbus/jsonrpc/GetModbusProtocolExportXlsxResponse.java +++ b/io.openems.edge.controller.api.modbus/src/io/openems/edge/controller/api/modbus/jsonrpc/GetModbusProtocolExportXlsxResponse.java @@ -44,9 +44,9 @@ public GetModbusProtocolExportXlsxResponse(UUID id, TreeMap com } private static final int COL_ADDRESS = 0; - private static final int COL_DESCRIPTION = 1; + private static final int COL_NAME = 1; private static final int COL_TYPE = 2; - private static final int COL_VALUE = 3; + private static final int COL_VALUE_DESCRIPTION = 3; private static final int COL_UNIT = 4; private static final int COL_ACCESS = 5; @@ -62,9 +62,9 @@ private static byte[] generatePayload(TreeMap components, TreeM ws = wb.newWorksheet("Modbus-Table"); ws.width(COL_ADDRESS, 10); - ws.width(COL_DESCRIPTION, 25); + ws.width(COL_NAME, 25); ws.width(COL_TYPE, 10); - ws.width(COL_VALUE, 35); + ws.width(COL_VALUE_DESCRIPTION, 150); ws.width(COL_UNIT, 20); ws.width(COL_ACCESS, 10); // Add headers @@ -115,9 +115,9 @@ private static byte[] generatePayload(TreeMap components, TreeM private static void addSheetHeader(Workbook workbook, Worksheet sheet) { sheet.value(0, COL_ADDRESS, "Address"); - sheet.value(0, COL_DESCRIPTION, "Description"); + sheet.value(0, COL_NAME, "Name"); sheet.value(0, COL_TYPE, "Type"); - sheet.value(0, COL_VALUE, "Value/Range"); + sheet.value(0, COL_VALUE_DESCRIPTION, "Value/Description"); sheet.value(0, COL_UNIT, "Unit"); sheet.value(0, COL_ACCESS, "Access"); sheet.style(0, 0).bold().fillColor(Color.GRAY5).borderStyle("thin"); @@ -130,9 +130,9 @@ private static void addComponentHeader(Worksheet sheet, String title, int rowCou private static void addRecord(Worksheet sheet, int address, ModbusRecord record, int rowCount) { sheet.value(rowCount, COL_ADDRESS, address); - sheet.value(rowCount, COL_DESCRIPTION, record.getName()); + sheet.value(rowCount, COL_NAME, record.getName()); sheet.value(rowCount, COL_TYPE, record.getType().toString()); - sheet.value(rowCount, COL_VALUE, record.getValueDescription()); + sheet.value(rowCount, COL_VALUE_DESCRIPTION, record.getValueDescription()); Unit unit = record.getUnit(); if (unit != Unit.NONE) { sheet.value(rowCount, COL_UNIT, unit.toString()); @@ -165,6 +165,7 @@ private static void addUndefinedSheet(Workbook wb) { case STRING16: value = ModbusRecordString16.UNDEFINED_VALUE; break; + case ENUM16: case UINT16: value = ModbusRecordUint16.UNDEFINED_VALUE; break; diff --git a/io.openems.edge.ess.api/src/io/openems/edge/ess/api/AsymmetricEss.java b/io.openems.edge.ess.api/src/io/openems/edge/ess/api/AsymmetricEss.java index 155e7511960..ebe9fb44e48 100644 --- a/io.openems.edge.ess.api/src/io/openems/edge/ess/api/AsymmetricEss.java +++ b/io.openems.edge.ess.api/src/io/openems/edge/ess/api/AsymmetricEss.java @@ -32,8 +32,9 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { ACTIVE_POWER_L1(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // .persistencePriority(PersistencePriority.HIGH) // - .text(POWER_DOC_TEXT) // - ), + .text("AC-side power of Energy Storage System on phase L1. " // + + "Includes excess DC-PV production for hybrid inverters. " // + + "Negative values for charge; positive for discharge")), /** * Active Power L2 * @@ -47,8 +48,9 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { ACTIVE_POWER_L2(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // .persistencePriority(PersistencePriority.HIGH) // - .text(POWER_DOC_TEXT) // - ), + .text("AC-side power of Energy Storage System on phase L2. " // + + "Includes excess DC-PV production for hybrid inverters. " // + + "Negative values for charge; positive for discharge")), /** * Active Power L3 * @@ -62,8 +64,9 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { ACTIVE_POWER_L3(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // .persistencePriority(PersistencePriority.HIGH) // - .text(POWER_DOC_TEXT) // - ), + .text("AC-side power of Energy Storage System on phase L3. " // + + "Includes excess DC-PV production for hybrid inverters. " // + + "Negative values for charge; positive for discharge")), /** * Reactive Power L1 * @@ -76,9 +79,7 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { */ REACTIVE_POWER_L1(Doc.of(OpenemsType.INTEGER) // .unit(Unit.VOLT_AMPERE_REACTIVE) // - .persistencePriority(PersistencePriority.HIGH) // - .text(POWER_DOC_TEXT) // - ), + .persistencePriority(PersistencePriority.HIGH)), // /** * Reactive Power L2 * @@ -91,9 +92,7 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { */ REACTIVE_POWER_L2(Doc.of(OpenemsType.INTEGER) // .unit(Unit.VOLT_AMPERE_REACTIVE) // - .persistencePriority(PersistencePriority.HIGH) // - .text(POWER_DOC_TEXT) // - ), + .persistencePriority(PersistencePriority.HIGH)), // /** * Reactive Power L3 * @@ -106,9 +105,8 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { */ REACTIVE_POWER_L3(Doc.of(OpenemsType.INTEGER) // .unit(Unit.VOLT_AMPERE_REACTIVE) // - .persistencePriority(PersistencePriority.HIGH) // - .text(POWER_DOC_TEXT) // - ); + .persistencePriority(PersistencePriority.HIGH)) // + ; private final Doc doc; diff --git a/io.openems.edge.ess.api/src/io/openems/edge/ess/api/CalculateGridMode.java b/io.openems.edge.ess.api/src/io/openems/edge/ess/api/CalculateGridMode.java index 4b03e2d94e1..abd95105d76 100644 --- a/io.openems.edge.ess.api/src/io/openems/edge/ess/api/CalculateGridMode.java +++ b/io.openems.edge.ess.api/src/io/openems/edge/ess/api/CalculateGridMode.java @@ -29,6 +29,10 @@ public void addValue(Channel channel) { * @return */ public GridMode calculate() { + if(this.values.isEmpty()) { + return GridMode.UNDEFINED; + } + int onGrids = 0; int offGrids = 0; for (GridMode gridMode : this.values) { diff --git a/io.openems.edge.ess.api/src/io/openems/edge/ess/api/HybridEss.java b/io.openems.edge.ess.api/src/io/openems/edge/ess/api/HybridEss.java index 681068beb1a..4e3f1dbcc2e 100644 --- a/io.openems.edge.ess.api/src/io/openems/edge/ess/api/HybridEss.java +++ b/io.openems.edge.ess.api/src/io/openems/edge/ess/api/HybridEss.java @@ -36,8 +36,8 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { DC_DISCHARGE_POWER(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // .persistencePriority(PersistencePriority.HIGH) // - .text(POWER_DOC_TEXT) // - ), + .text("Actual AC-side battery discharge power of Energy Storage System. " // + + "Negative values for charge; positive for discharge")), /** * DC Charge Energy. * diff --git a/io.openems.edge.ess.api/src/io/openems/edge/ess/api/SymmetricEss.java b/io.openems.edge.ess.api/src/io/openems/edge/ess/api/SymmetricEss.java index 0793c9841cf..9fff4b57d4f 100644 --- a/io.openems.edge.ess.api/src/io/openems/edge/ess/api/SymmetricEss.java +++ b/io.openems.edge.ess.api/src/io/openems/edge/ess/api/SymmetricEss.java @@ -19,8 +19,6 @@ @ProviderType public interface SymmetricEss extends OpenemsComponent { - public static final String POWER_DOC_TEXT = "Negative values for Charge; positive for Discharge"; - public enum ChannelId implements io.openems.edge.common.channel.ChannelId { /** * State of Charge. @@ -73,7 +71,7 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT) // .persistencePriority(PersistencePriority.HIGH) // - .text(POWER_DOC_TEXT) // + .text("Negative values for Charge; positive for Discharge") // ), /** * Reactive Power. @@ -82,13 +80,11 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { *
  • Interface: Ess Symmetric *
  • Type: Integer *
  • Unit: var - *
  • Range: negative values for Charge; positive for Discharge * */ REACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // .unit(Unit.VOLT_AMPERE_REACTIVE) // .persistencePriority(PersistencePriority.HIGH) // - .text(POWER_DOC_TEXT) // ), /** * Holds the currently maximum possible apparent power. This value is commonly diff --git a/io.openems.edge.meter.api/src/io/openems/edge/meter/api/SymmetricMeter.java b/io.openems.edge.meter.api/src/io/openems/edge/meter/api/SymmetricMeter.java index 4d1ec9891fa..8677d2126af 100644 --- a/io.openems.edge.meter.api/src/io/openems/edge/meter/api/SymmetricMeter.java +++ b/io.openems.edge.meter.api/src/io/openems/edge/meter/api/SymmetricMeter.java @@ -1,6 +1,5 @@ package io.openems.edge.meter.api; -import io.openems.common.OpenemsConstants; import io.openems.common.channel.AccessMode; import io.openems.common.channel.PersistencePriority; import io.openems.common.channel.Unit; @@ -87,7 +86,6 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { ACTIVE_POWER(new IntegerDoc() // .unit(Unit.WATT) // .persistencePriority(PersistencePriority.HIGH) // - .text(OpenemsConstants.POWER_DOC_TEXT) // .onInit(channel -> { channel.onSetNextValue(value -> { /* @@ -135,8 +133,7 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { */ REACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // .unit(Unit.VOLT_AMPERE_REACTIVE) // - .persistencePriority(PersistencePriority.HIGH) // - .text(OpenemsConstants.POWER_DOC_TEXT)), // + .persistencePriority(PersistencePriority.HIGH)), // /** * Active Production Energy. * diff --git a/io.openems.edge.simulator/src/io/openems/edge/simulator/evcs/AsymmetricMeterEvcs.java b/io.openems.edge.simulator/src/io/openems/edge/simulator/evcs/AsymmetricMeterEvcs.java index f1ffe00a9a9..c86d1127cb6 100644 --- a/io.openems.edge.simulator/src/io/openems/edge/simulator/evcs/AsymmetricMeterEvcs.java +++ b/io.openems.edge.simulator/src/io/openems/edge/simulator/evcs/AsymmetricMeterEvcs.java @@ -1,6 +1,5 @@ package io.openems.edge.simulator.evcs; -import io.openems.common.OpenemsConstants; import io.openems.common.channel.PersistencePriority; import io.openems.common.channel.Unit; import io.openems.common.types.OpenemsType; @@ -17,473 +16,469 @@ public interface AsymmetricMeterEvcs extends OpenemsComponent { - - public enum ChannelId implements io.openems.edge.common.channel.ChannelId { - /** - * Frequency. - * - *
      - *
    • Interface: Meter Symmetric - *
    • Type: Integer - *
    • Unit: mHz - *
    • Range: only positive values - *
    - */ - FREQUENCY(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIHERTZ) // - .persistencePriority(PersistencePriority.HIGH)), - /** - * Minimum Ever Active Power. - * - *
      - *
    • Interface: Meter Symmetric - *
    • Type: Integer - *
    • Unit: W - *
    • Range: negative or '0' - *
    • Implementation Note: value is automatically derived from ACTIVE_POWER - *
    - */ - MIN_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.WATT) // - .persistencePriority(PersistencePriority.HIGH)), - /** - * Maximum Ever Active Power. - * - *
      - *
    • Interface: Meter Symmetric - *
    • Type: Integer - *
    • Unit: W - *
    • Range: positive or '0' - *
    • Implementation Note: value is automatically derived from ACTIVE_POWER - *
    - */ - MAX_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.WATT) // - .persistencePriority(PersistencePriority.HIGH)), - /** - * Active Power. - * - *
      - *
    • Interface: Meter Symmetric - *
    • Type: Integer - *
    • Unit: W - *
    • Range: negative values for Consumption (power that is 'leaving the - * system', e.g. feed-to-grid); positive for Production (power that is 'entering - * the system') - *
    - */ - ACTIVE_POWER(new IntegerDoc() // - .unit(Unit.WATT) // - .persistencePriority(PersistencePriority.HIGH) // - .text(OpenemsConstants.POWER_DOC_TEXT) // - .onInit(channel -> { - channel.onSetNextValue(value -> { - /* - * Fill Min/Max Active Power channels - */ - if (value.isDefined()) { - int newValue = value.get(); - { - Channel minActivePowerChannel = channel.getComponent() - .channel(ChannelId.MIN_ACTIVE_POWER); - int minActivePower = minActivePowerChannel.value().orElse(0); - int minNextActivePower = minActivePowerChannel.getNextValue().orElse(0); - if (newValue < Math.min(minActivePower, minNextActivePower)) { - // avoid getting called too often -> round to 100 - newValue = IntUtils.roundToPrecision(newValue, Round.TOWARDS_ZERO, 100); - minActivePowerChannel.setNextValue(newValue); - } + public enum ChannelId implements io.openems.edge.common.channel.ChannelId { + /** + * Frequency. + * + *
      + *
    • Interface: Meter Symmetric + *
    • Type: Integer + *
    • Unit: mHz + *
    • Range: only positive values + *
    + */ + FREQUENCY(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIHERTZ) // + .persistencePriority(PersistencePriority.HIGH)), + /** + * Minimum Ever Active Power. + * + *
      + *
    • Interface: Meter Symmetric + *
    • Type: Integer + *
    • Unit: W + *
    • Range: negative or '0' + *
    • Implementation Note: value is automatically derived from ACTIVE_POWER + *
    + */ + MIN_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT) // + .persistencePriority(PersistencePriority.HIGH)), + /** + * Maximum Ever Active Power. + * + *
      + *
    • Interface: Meter Symmetric + *
    • Type: Integer + *
    • Unit: W + *
    • Range: positive or '0' + *
    • Implementation Note: value is automatically derived from ACTIVE_POWER + *
    + */ + MAX_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT) // + .persistencePriority(PersistencePriority.HIGH)), + /** + * Active Power. + * + *
      + *
    • Interface: Meter Symmetric + *
    • Type: Integer + *
    • Unit: W + *
    • Range: negative values for Consumption (power that is 'leaving the + * system', e.g. feed-to-grid); positive for Production (power that is 'entering + * the system') + *
    + */ + ACTIVE_POWER(new IntegerDoc() // + .unit(Unit.WATT) // + .persistencePriority(PersistencePriority.HIGH) // + .onInit(channel -> { + channel.onSetNextValue(value -> { + /* + * Fill Min/Max Active Power channels + */ + if (value.isDefined()) { + int newValue = value.get(); + { + Channel minActivePowerChannel = channel.getComponent() + .channel(ChannelId.MIN_ACTIVE_POWER); + int minActivePower = minActivePowerChannel.value().orElse(0); + int minNextActivePower = minActivePowerChannel.getNextValue().orElse(0); + if (newValue < Math.min(minActivePower, minNextActivePower)) { + // avoid getting called too often -> round to 100 + newValue = IntUtils.roundToPrecision(newValue, Round.TOWARDS_ZERO, 100); + minActivePowerChannel.setNextValue(newValue); } - { - Channel maxActivePowerChannel = channel.getComponent() - .channel(ChannelId.MAX_ACTIVE_POWER); - int maxActivePower = maxActivePowerChannel.value().orElse(0); - int maxNextActivePower = maxActivePowerChannel.getNextValue().orElse(0); - if (newValue > Math.max(maxActivePower, maxNextActivePower)) { - // avoid getting called too often -> round to 100 - newValue = IntUtils.roundToPrecision(newValue, Round.AWAY_FROM_ZERO, 100); - maxActivePowerChannel.setNextValue(newValue); - } + } + { + Channel maxActivePowerChannel = channel.getComponent() + .channel(ChannelId.MAX_ACTIVE_POWER); + int maxActivePower = maxActivePowerChannel.value().orElse(0); + int maxNextActivePower = maxActivePowerChannel.getNextValue().orElse(0); + if (newValue > Math.max(maxActivePower, maxNextActivePower)) { + // avoid getting called too often -> round to 100 + newValue = IntUtils.roundToPrecision(newValue, Round.AWAY_FROM_ZERO, 100); + maxActivePowerChannel.setNextValue(newValue); } } - }); - })), // - - /** - * Reactive Power. - * - *
      - *
    • Interface: Meter Symmetric - *
    • Type: Integer - *
    • Unit: var - *
    • Range: negative values for Consumption (power that is 'leaving the - * system', e.g. feed-to-grid); positive for Production (power that is 'entering - * the system') - *
    - */ - REACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.VOLT_AMPERE_REACTIVE) // - .persistencePriority(PersistencePriority.HIGH) // - .text(OpenemsConstants.POWER_DOC_TEXT)), // - /** - * Active Production Energy. - * - *
      - *
    • Interface: Meter Symmetric - *
    • Type: Integer - *
    • Unit: Wh - *
    - */ - ACTIVE_PRODUCTION_ENERGY(Doc.of(OpenemsType.LONG) // - .unit(Unit.WATT_HOURS) // - .persistencePriority(PersistencePriority.HIGH)), - /** - * Voltage. - * - *
      - *
    • Interface: Meter Symmetric - *
    • Type: Integer - *
    • Unit: mV - *
    - */ - VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT) // - .persistencePriority(PersistencePriority.HIGH)), - /** - * Current. - * - *
      - *
    • Interface: Meter Symmetric - *
    • Type: Integer - *
    • Unit: mA - *
    - */ - CURRENT(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIAMPERE) // - .persistencePriority(PersistencePriority.HIGH)); - - private final Doc doc; - - private ChannelId(Doc doc) { - this.doc = doc; - } - - public Doc doc() { - return this.doc; - } - } + } + }); + })), // /** - * Gets the type of this Meter. + * Reactive Power. * - * @return the MeterType - */ - MeterType getMeterType(); - - /** - * Gets the Channel for {@link ChannelId#FREQUENCY}. - * - * @return the Channel - */ - public default IntegerReadChannel getFrequencyChannel() { - return this.channel(ChannelId.FREQUENCY); - } - - /** - * Gets the Frequency in [mHz]. See {@link ChannelId#FREQUENCY}. - * - * @return the Channel {@link Value} - */ - public default Value getFrequency() { - return this.getFrequencyChannel().value(); - } - - /** - * Internal method to set the 'nextValue' on {@link ChannelId#FREQUENCY} - * Channel. - * - * @param value the next value - */ - public default void _setFrequency(Integer value) { - this.getFrequencyChannel().setNextValue(value); - } - - /** - * Internal method to set the 'nextValue' on {@link ChannelId#FREQUENCY} - * Channel. - * - * @param value the next value - */ - public default void _setFrequency(int value) { - this.getFrequencyChannel().setNextValue(value); - } - - /** - * Gets the Channel for {@link ChannelId#MIN_ACTIVE_POWER}. - * - * @return the Channel - */ - public default IntegerReadChannel getMinActivePowerChannel() { - return this.channel(ChannelId.MIN_ACTIVE_POWER); - } - - /** - * Gets the Minimum Ever Active Power in [W]. See - * {@link ChannelId#MIN_ACTIVE_POWER}. - * - * @return the Channel {@link Value} - */ - public default Value getMinActivePower() { - return this.getMinActivePowerChannel().value(); - } - - /** - * Internal method to set the 'nextValue' on {@link ChannelId#MIN_ACTIVE_POWER} - * Channel. - * - * @param value the next value - */ - public default void _setMinActivePower(Integer value) { - this.getMinActivePowerChannel().setNextValue(value); - } - - /** - * Internal method to set the 'nextValue' on {@link ChannelId#MIN_ACTIVE_POWER} - * Channel. - * - * @param value the next value - */ - public default void _setMinActivePower(int value) { - this.getMinActivePowerChannel().setNextValue(value); - } - - /** - * Gets the Channel for {@link ChannelId#MAX_ACTIVE_POWER}. - * - * @return the Channel - */ - public default IntegerReadChannel getMaxActivePowerChannel() { - return this.channel(ChannelId.MAX_ACTIVE_POWER); - } - - /** - * Gets the Maximum Ever Active Power in [W]. See - * {@link ChannelId#MAX_ACTIVE_POWER}. - * - * @return the Channel {@link Value} - */ - public default Value getMaxActivePower() { - return this.getMaxActivePowerChannel().value(); - } - - /** - * Internal method to set the 'nextValue' on {@link ChannelId#MAX_ACTIVE_POWER} - * Channel. - * - * @param value the next value - */ - public default void _setMaxActivePower(Integer value) { - this.getMaxActivePowerChannel().setNextValue(value); - } - - /** - * Internal method to set the 'nextValue' on {@link ChannelId#MAX_ACTIVE_POWER} - * Channel. - * - * @param value the next value - */ - public default void _setMaxActivePower(int value) { - this.getMaxActivePowerChannel().setNextValue(value); - } - - /** - * Gets the Channel for {@link ChannelId#ACTIVE_POWER}. - * - * @return the Channel - */ - public default IntegerReadChannel getActivePowerChannel() { - return this.channel(ChannelId.ACTIVE_POWER); - } - - /** - * Gets the Active Power in [W]. Negative values for Consumption (power that is - * 'leaving the system', e.g. feed-to-grid); positive for Production (power that - * is 'entering the system'). See {@link ChannelId#ACTIVE_POWER}. + *
      + *
    • Interface: Meter Symmetric + *
    • Type: Integer + *
    • Unit: var + *
    • Range: negative values for Consumption (power that is 'leaving the + * system', e.g. feed-to-grid); positive for Production (power that is 'entering + * the system') + *
    + */ + REACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.VOLT_AMPERE_REACTIVE) // + .persistencePriority(PersistencePriority.HIGH)), // + /** + * Active Production Energy. * - * @return the Channel {@link Value} + *
      + *
    • Interface: Meter Symmetric + *
    • Type: Integer + *
    • Unit: Wh + *
    */ - public default Value getActivePower() { - return this.getActivePowerChannel().value(); - } - + ACTIVE_PRODUCTION_ENERGY(Doc.of(OpenemsType.LONG) // + .unit(Unit.WATT_HOURS) // + .persistencePriority(PersistencePriority.HIGH)), /** - * Internal method to set the 'nextValue' on {@link ChannelId#ACTIVE_POWER} - * Channel. - * - * @param value the next value - */ - public default void _setActivePower(Integer value) { - this.getActivePowerChannel().setNextValue(value); - } - - /** - * Internal method to set the 'nextValue' on {@link ChannelId#ACTIVE_POWER} - * Channel. - * - * @param value the next value - */ - public default void _setActivePower(int value) { - this.getActivePowerChannel().setNextValue(value); - } - - /** - * Gets the Channel for {@link ChannelId#REACTIVE_POWER}. - * - * @return the Channel - */ - public default IntegerReadChannel getReactivePowerChannel() { - return this.channel(ChannelId.REACTIVE_POWER); - } - - /** - * Gets the Reactive Power in [var]. See {@link ChannelId#REACTIVE_POWER}. - * - * @return the Channel {@link Value} - */ - public default Value getReactivePower() { - return this.getReactivePowerChannel().value(); - } - - /** - * Internal method to set the 'nextValue' on {@link ChannelId#REACTIVE_POWER} - * Channel. - * - * @param value the next value - */ - public default void _setReactivePower(Integer value) { - this.getReactivePowerChannel().setNextValue(value); - } - - /** - * Internal method to set the 'nextValue' on {@link ChannelId#REACTIVE_POWER} - * Channel. - * - * @param value the next value - */ - public default void _setReactivePower(int value) { - this.getReactivePowerChannel().setNextValue(value); - } - - /** - * Gets the Channel for {@link ChannelId#ACTIVE_PRODUCTION_ENERGY}. - * - * @return the Channel - */ - public default LongReadChannel getActiveProductionEnergyChannel() { - return this.channel(ChannelId.ACTIVE_PRODUCTION_ENERGY); - } - - /** - * Gets the Active Production Energy in [Wh]. This relates to positive - * ACTIVE_POWER. See {@link ChannelId#ACTIVE_PRODUCTION_ENERGY}. - * - * @return the Channel {@link Value} - */ - public default Value getActiveProductionEnergy() { - return this.getActiveProductionEnergyChannel().value(); - } - - /** - * Internal method to set the 'nextValue' on - * {@link ChannelId#ACTIVE_PRODUCTION_ENERGY} Channel. - * - * @param value the next value - */ - public default void _setActiveProductionEnergy(Long value) { - this.getActiveProductionEnergyChannel().setNextValue(value); - } - - /** - * Internal method to set the 'nextValue' on - * {@link ChannelId#ACTIVE_PRODUCTION_ENERGY} Channel. - * - * @param value the next value - */ - public default void _setActiveProductionEnergy(long value) { - this.getActiveProductionEnergyChannel().setNextValue(value); - } - - /** - * Gets the Channel for {@link ChannelId#VOLTAGE}. - * - * @return the Channel - */ - public default IntegerReadChannel getVoltageChannel() { - return this.channel(ChannelId.VOLTAGE); - } - - /** - * Gets the Voltage in [mV]. See {@link ChannelId#VOLTAGE}. - * - * @return the Channel {@link Value} - */ - public default Value getVoltage() { - return this.getVoltageChannel().value(); - } - - /** - * Internal method to set the 'nextValue' on {@link ChannelId#VOLTAGE} Channel. - * - * @param value the next value - */ - public default void _setVoltage(Integer value) { - this.getVoltageChannel().setNextValue(value); - } - - /** - * Internal method to set the 'nextValue' on {@link ChannelId#VOLTAGE} Channel. - * - * @param value the next value - */ - public default void _setVoltage(int value) { - this.getVoltageChannel().setNextValue(value); - } - - /** - * Gets the Channel for {@link ChannelId#CURRENT}. - * - * @return the Channel - */ - public default IntegerReadChannel getCurrentChannel() { - return this.channel(ChannelId.CURRENT); - } - - /** - * Gets the Current in [mA]. See {@link ChannelId#CURRENT}. - * - * @return the Channel {@link Value} - */ - public default Value getCurrent() { - return this.getCurrentChannel().value(); - } - - /** - * Internal method to set the 'nextValue' on {@link ChannelId#CURRENT} Channel. - * - * @param value the next value + * Voltage. + * + *
      + *
    • Interface: Meter Symmetric + *
    • Type: Integer + *
    • Unit: mV + *
    */ - public default void _setCurrent(Integer value) { - this.getCurrentChannel().setNextValue(value); - } - + VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT) // + .persistencePriority(PersistencePriority.HIGH)), /** - * Internal method to set the 'nextValue' on {@link ChannelId#CURRENT} Channel. - * - * @param value the next value - */ - public default void _setCurrent(int value) { - this.getCurrentChannel().setNextValue(value); - } - + * Current. + * + *
      + *
    • Interface: Meter Symmetric + *
    • Type: Integer + *
    • Unit: mA + *
    + */ + CURRENT(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIAMPERE) // + .persistencePriority(PersistencePriority.HIGH)); + + private final Doc doc; + + private ChannelId(Doc doc) { + this.doc = doc; + } + + public Doc doc() { + return this.doc; + } + } + + /** + * Gets the type of this Meter. + * + * @return the MeterType + */ + MeterType getMeterType(); + + /** + * Gets the Channel for {@link ChannelId#FREQUENCY}. + * + * @return the Channel + */ + public default IntegerReadChannel getFrequencyChannel() { + return this.channel(ChannelId.FREQUENCY); + } + + /** + * Gets the Frequency in [mHz]. See {@link ChannelId#FREQUENCY}. + * + * @return the Channel {@link Value} + */ + public default Value getFrequency() { + return this.getFrequencyChannel().value(); + } + + /** + * Internal method to set the 'nextValue' on {@link ChannelId#FREQUENCY} + * Channel. + * + * @param value the next value + */ + public default void _setFrequency(Integer value) { + this.getFrequencyChannel().setNextValue(value); + } + + /** + * Internal method to set the 'nextValue' on {@link ChannelId#FREQUENCY} + * Channel. + * + * @param value the next value + */ + public default void _setFrequency(int value) { + this.getFrequencyChannel().setNextValue(value); + } + + /** + * Gets the Channel for {@link ChannelId#MIN_ACTIVE_POWER}. + * + * @return the Channel + */ + public default IntegerReadChannel getMinActivePowerChannel() { + return this.channel(ChannelId.MIN_ACTIVE_POWER); + } + + /** + * Gets the Minimum Ever Active Power in [W]. See + * {@link ChannelId#MIN_ACTIVE_POWER}. + * + * @return the Channel {@link Value} + */ + public default Value getMinActivePower() { + return this.getMinActivePowerChannel().value(); + } + + /** + * Internal method to set the 'nextValue' on {@link ChannelId#MIN_ACTIVE_POWER} + * Channel. + * + * @param value the next value + */ + public default void _setMinActivePower(Integer value) { + this.getMinActivePowerChannel().setNextValue(value); + } + + /** + * Internal method to set the 'nextValue' on {@link ChannelId#MIN_ACTIVE_POWER} + * Channel. + * + * @param value the next value + */ + public default void _setMinActivePower(int value) { + this.getMinActivePowerChannel().setNextValue(value); + } + + /** + * Gets the Channel for {@link ChannelId#MAX_ACTIVE_POWER}. + * + * @return the Channel + */ + public default IntegerReadChannel getMaxActivePowerChannel() { + return this.channel(ChannelId.MAX_ACTIVE_POWER); + } + + /** + * Gets the Maximum Ever Active Power in [W]. See + * {@link ChannelId#MAX_ACTIVE_POWER}. + * + * @return the Channel {@link Value} + */ + public default Value getMaxActivePower() { + return this.getMaxActivePowerChannel().value(); + } + + /** + * Internal method to set the 'nextValue' on {@link ChannelId#MAX_ACTIVE_POWER} + * Channel. + * + * @param value the next value + */ + public default void _setMaxActivePower(Integer value) { + this.getMaxActivePowerChannel().setNextValue(value); + } + + /** + * Internal method to set the 'nextValue' on {@link ChannelId#MAX_ACTIVE_POWER} + * Channel. + * + * @param value the next value + */ + public default void _setMaxActivePower(int value) { + this.getMaxActivePowerChannel().setNextValue(value); + } + + /** + * Gets the Channel for {@link ChannelId#ACTIVE_POWER}. + * + * @return the Channel + */ + public default IntegerReadChannel getActivePowerChannel() { + return this.channel(ChannelId.ACTIVE_POWER); + } + + /** + * Gets the Active Power in [W]. Negative values for Consumption (power that is + * 'leaving the system', e.g. feed-to-grid); positive for Production (power that + * is 'entering the system'). See {@link ChannelId#ACTIVE_POWER}. + * + * @return the Channel {@link Value} + */ + public default Value getActivePower() { + return this.getActivePowerChannel().value(); + } + + /** + * Internal method to set the 'nextValue' on {@link ChannelId#ACTIVE_POWER} + * Channel. + * + * @param value the next value + */ + public default void _setActivePower(Integer value) { + this.getActivePowerChannel().setNextValue(value); + } + + /** + * Internal method to set the 'nextValue' on {@link ChannelId#ACTIVE_POWER} + * Channel. + * + * @param value the next value + */ + public default void _setActivePower(int value) { + this.getActivePowerChannel().setNextValue(value); + } + + /** + * Gets the Channel for {@link ChannelId#REACTIVE_POWER}. + * + * @return the Channel + */ + public default IntegerReadChannel getReactivePowerChannel() { + return this.channel(ChannelId.REACTIVE_POWER); + } + + /** + * Gets the Reactive Power in [var]. See {@link ChannelId#REACTIVE_POWER}. + * + * @return the Channel {@link Value} + */ + public default Value getReactivePower() { + return this.getReactivePowerChannel().value(); + } + + /** + * Internal method to set the 'nextValue' on {@link ChannelId#REACTIVE_POWER} + * Channel. + * + * @param value the next value + */ + public default void _setReactivePower(Integer value) { + this.getReactivePowerChannel().setNextValue(value); + } + + /** + * Internal method to set the 'nextValue' on {@link ChannelId#REACTIVE_POWER} + * Channel. + * + * @param value the next value + */ + public default void _setReactivePower(int value) { + this.getReactivePowerChannel().setNextValue(value); + } + + /** + * Gets the Channel for {@link ChannelId#ACTIVE_PRODUCTION_ENERGY}. + * + * @return the Channel + */ + public default LongReadChannel getActiveProductionEnergyChannel() { + return this.channel(ChannelId.ACTIVE_PRODUCTION_ENERGY); + } + + /** + * Gets the Active Production Energy in [Wh]. This relates to positive + * ACTIVE_POWER. See {@link ChannelId#ACTIVE_PRODUCTION_ENERGY}. + * + * @return the Channel {@link Value} + */ + public default Value getActiveProductionEnergy() { + return this.getActiveProductionEnergyChannel().value(); + } + + /** + * Internal method to set the 'nextValue' on + * {@link ChannelId#ACTIVE_PRODUCTION_ENERGY} Channel. + * + * @param value the next value + */ + public default void _setActiveProductionEnergy(Long value) { + this.getActiveProductionEnergyChannel().setNextValue(value); + } + + /** + * Internal method to set the 'nextValue' on + * {@link ChannelId#ACTIVE_PRODUCTION_ENERGY} Channel. + * + * @param value the next value + */ + public default void _setActiveProductionEnergy(long value) { + this.getActiveProductionEnergyChannel().setNextValue(value); + } + + /** + * Gets the Channel for {@link ChannelId#VOLTAGE}. + * + * @return the Channel + */ + public default IntegerReadChannel getVoltageChannel() { + return this.channel(ChannelId.VOLTAGE); + } + + /** + * Gets the Voltage in [mV]. See {@link ChannelId#VOLTAGE}. + * + * @return the Channel {@link Value} + */ + public default Value getVoltage() { + return this.getVoltageChannel().value(); + } + + /** + * Internal method to set the 'nextValue' on {@link ChannelId#VOLTAGE} Channel. + * + * @param value the next value + */ + public default void _setVoltage(Integer value) { + this.getVoltageChannel().setNextValue(value); + } + + /** + * Internal method to set the 'nextValue' on {@link ChannelId#VOLTAGE} Channel. + * + * @param value the next value + */ + public default void _setVoltage(int value) { + this.getVoltageChannel().setNextValue(value); + } + + /** + * Gets the Channel for {@link ChannelId#CURRENT}. + * + * @return the Channel + */ + public default IntegerReadChannel getCurrentChannel() { + return this.channel(ChannelId.CURRENT); + } + + /** + * Gets the Current in [mA]. See {@link ChannelId#CURRENT}. + * + * @return the Channel {@link Value} + */ + public default Value getCurrent() { + return this.getCurrentChannel().value(); + } + + /** + * Internal method to set the 'nextValue' on {@link ChannelId#CURRENT} Channel. + * + * @param value the next value + */ + public default void _setCurrent(Integer value) { + this.getCurrentChannel().setNextValue(value); + } + + /** + * Internal method to set the 'nextValue' on {@link ChannelId#CURRENT} Channel. + * + * @param value the next value + */ + public default void _setCurrent(int value) { + this.getCurrentChannel().setNextValue(value); + } }