From c2e240a73cccc6906c7f3c54fb02aa55e5fe8bb6 Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Wed, 14 Feb 2024 10:09:21 +0100 Subject: [PATCH 01/25] Start implement DEYE battery inverter --- io.openems.edge.application/EdgeApp.bndrun | 2 + .../.classpath | 12 + .../.gitignore | 2 + io.openems.edge.batteryinverter.deye/.project | 23 + .../org.eclipse.core.resources.prefs | 2 + io.openems.edge.batteryinverter.deye/bnd.bnd | 19 + .../readme.adoc | 7 + .../batteryinverter/BatteryInverterDeye.java | 949 ++++++++++++++++++ .../BatteryInverterDeyeImpl.java | 407 ++++++++ .../edge/deye/batteryinverter/Config.java | 41 + .../enums/ActivePowerControlMode.java | 34 + .../deye/batteryinverter/enums/Baudrate.java | 33 + .../batteryinverter/enums/BlackStartMode.java | 32 + .../enums/BmsProtocolSelection.java | 34 + .../batteryinverter/enums/CountryCode.java | 18 + .../deye/batteryinverter/enums/CpuType.java | 32 + .../batteryinverter/enums/DcVoltageLevel.java | 32 + .../batteryinverter/enums/EnableDisable.java | 17 + .../edge/deye/batteryinverter/enums/Epo.java | 33 + .../batteryinverter/enums/FrequencyLevel.java | 22 + .../enums/FrequencyVariationRate.java | 33 + .../enums/GridCodeSelection.java | 27 + .../batteryinverter/enums/InterfaceType.java | 32 + .../enums/InverterWiringTopology.java | 16 + .../enums/ModulePowerLevel.java | 34 + .../enums/PhaseAngleAbrupt.java | 33 + .../enums/PowerRisingMode.java | 32 + .../enums/ProtocolSelection.java | 32 + .../enums/ReactivePowerControlMode.java | 34 + .../enums/SinexcelGridMode.java | 32 + .../batteryinverter/enums/SinexcelState.java | 40 + .../enums/SinglePhaseMode.java | 33 + .../deye/batteryinverter/enums/StartMode.java | 32 + .../deye/batteryinverter/enums/Switch.java | 32 + .../batteryinverter/enums/VoltageLevel.java | 23 + .../batteryinverter/statemachine/Context.java | 24 + .../statemachine/ErrorHandler.java | 46 + .../statemachine/GoRunningHandler.java | 43 + .../statemachine/GoStoppedHandler.java | 23 + .../statemachine/RunningHandler.java | 44 + .../statemachine/StateMachine.java | 70 ++ .../statemachine/StoppedHandler.java | 19 + .../statemachine/UndefinedHandler.java | 36 + .../openems/edge/deye/gridmeter/Config.java | 35 + .../edge/deye/gridmeter/DeyeGridMeter.java | 23 + .../deye/gridmeter/DeyeGridMeterImpl.java | 105 ++ .../test/test/.gitignore | 0 47 files changed, 2684 insertions(+) create mode 100644 io.openems.edge.batteryinverter.deye/.classpath create mode 100644 io.openems.edge.batteryinverter.deye/.gitignore create mode 100644 io.openems.edge.batteryinverter.deye/.project create mode 100644 io.openems.edge.batteryinverter.deye/.settings/org.eclipse.core.resources.prefs create mode 100644 io.openems.edge.batteryinverter.deye/bnd.bnd create mode 100644 io.openems.edge.batteryinverter.deye/readme.adoc create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeye.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeyeImpl.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/Config.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ActivePowerControlMode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Baudrate.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BlackStartMode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BmsProtocolSelection.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CountryCode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CpuType.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/DcVoltageLevel.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/EnableDisable.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Epo.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyLevel.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyVariationRate.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/GridCodeSelection.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InterfaceType.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InverterWiringTopology.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ModulePowerLevel.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PhaseAngleAbrupt.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PowerRisingMode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ProtocolSelection.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ReactivePowerControlMode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelGridMode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelState.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinglePhaseMode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/StartMode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Switch.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/VoltageLevel.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/Context.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/ErrorHandler.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoRunningHandler.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoStoppedHandler.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/RunningHandler.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StateMachine.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StoppedHandler.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/UndefinedHandler.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeter.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java create mode 100644 io.openems.edge.batteryinverter.deye/test/test/.gitignore diff --git a/io.openems.edge.application/EdgeApp.bndrun b/io.openems.edge.application/EdgeApp.bndrun index 09c9967dc78..36d1ba7b0b5 100644 --- a/io.openems.edge.application/EdgeApp.bndrun +++ b/io.openems.edge.application/EdgeApp.bndrun @@ -131,6 +131,7 @@ bnd.identity;id='io.openems.edge.fenecon.mini',\ bnd.identity;id='io.openems.edge.fenecon.pro',\ bnd.identity;id='io.openems.edge.goodwe',\ + bnd.identity;id='io.openems.edge.batteryinverter.deye',\ bnd.identity;id='io.openems.edge.io.filipowski',\ bnd.identity;id='io.openems.edge.io.gpio',\ bnd.identity;id='io.openems.edge.io.kmtronic',\ @@ -298,6 +299,7 @@ io.openems.edge.fenecon.mini;version=snapshot,\ io.openems.edge.fenecon.pro;version=snapshot,\ io.openems.edge.goodwe;version=snapshot,\ + io.openems.edge.batteryinverter.deye;version=snapshot,\ io.openems.edge.io.api;version=snapshot,\ io.openems.edge.io.filipowski;version=snapshot,\ io.openems.edge.io.gpio;version=snapshot,\ diff --git a/io.openems.edge.batteryinverter.deye/.classpath b/io.openems.edge.batteryinverter.deye/.classpath new file mode 100644 index 00000000000..bbfbdbe40e7 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/.classpath @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/io.openems.edge.batteryinverter.deye/.gitignore b/io.openems.edge.batteryinverter.deye/.gitignore new file mode 100644 index 00000000000..36573722b7e --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/.gitignore @@ -0,0 +1,2 @@ +/generated/ +/bin_test/ diff --git a/io.openems.edge.batteryinverter.deye/.project b/io.openems.edge.batteryinverter.deye/.project new file mode 100644 index 00000000000..522ed9ee544 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/.project @@ -0,0 +1,23 @@ + + + io.openems.edge.batteryinverter.sinexcel + + + + + + org.eclipse.jdt.core.javabuilder + + + + + bndtools.core.bndbuilder + + + + + + org.eclipse.jdt.core.javanature + bndtools.core.bndnature + + diff --git a/io.openems.edge.batteryinverter.deye/.settings/org.eclipse.core.resources.prefs b/io.openems.edge.batteryinverter.deye/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000000..99f26c0203a --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/io.openems.edge.batteryinverter.deye/bnd.bnd b/io.openems.edge.batteryinverter.deye/bnd.bnd new file mode 100644 index 00000000000..8ff040a6be6 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/bnd.bnd @@ -0,0 +1,19 @@ +Bundle-Name: OpenEMS Edge ESS Deye +Bundle-Vendor: MaMoTec +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + com.ghgande.j2mod,\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.batteryinverter.api,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/readme.adoc b/io.openems.edge.batteryinverter.deye/readme.adoc new file mode 100644 index 00000000000..26abba966f4 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/readme.adoc @@ -0,0 +1,7 @@ += Sinexcel Battery Inverter + +Implemented Natures:: +- SymmetricEss +- ManagedSymmetricEss + +https://github.com/OpenEMS/openems/tree/develop/io.openems.edge.ess.sinexcel[Source Code icon:github[]] \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeye.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeye.java new file mode 100644 index 00000000000..dc188d6ab82 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeye.java @@ -0,0 +1,949 @@ +package io.openems.edge.deye.batteryinverter; + +import io.openems.common.channel.AccessMode; +import io.openems.common.channel.Debounce; +import io.openems.common.channel.Level; +import io.openems.common.channel.PersistencePriority; +import io.openems.common.channel.Unit; +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.common.types.OpenemsType; +import io.openems.edge.batteryinverter.api.ManagedSymmetricBatteryInverter; +import io.openems.edge.batteryinverter.api.OffGridBatteryInverter; +import io.openems.edge.batteryinverter.api.SymmetricBatteryInverter; +import io.openems.edge.common.channel.BooleanDoc; +import io.openems.edge.common.channel.BooleanWriteChannel; +import io.openems.edge.common.channel.Doc; +import io.openems.edge.common.channel.IntegerDoc; +import io.openems.edge.common.channel.IntegerReadChannel; +import io.openems.edge.common.channel.value.Value; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.common.modbusslave.ModbusSlave; +import io.openems.edge.common.startstop.StartStoppable; +import io.openems.edge.common.sum.GridMode; +import io.openems.edge.deye.batteryinverter.enums.ActivePowerControlMode; +import io.openems.edge.deye.batteryinverter.enums.Baudrate; +import io.openems.edge.deye.batteryinverter.enums.BlackStartMode; +import io.openems.edge.deye.batteryinverter.enums.CpuType; +import io.openems.edge.deye.batteryinverter.enums.DcVoltageLevel; +import io.openems.edge.deye.batteryinverter.enums.Epo; +import io.openems.edge.deye.batteryinverter.enums.FrequencyVariationRate; +import io.openems.edge.deye.batteryinverter.enums.InterfaceType; +import io.openems.edge.deye.batteryinverter.enums.ModulePowerLevel; +import io.openems.edge.deye.batteryinverter.enums.PhaseAngleAbrupt; +import io.openems.edge.deye.batteryinverter.enums.PowerRisingMode; +import io.openems.edge.deye.batteryinverter.enums.ProtocolSelection; +import io.openems.edge.deye.batteryinverter.enums.ReactivePowerControlMode; +import io.openems.edge.deye.batteryinverter.enums.SinexcelGridMode; +import io.openems.edge.deye.batteryinverter.enums.SinglePhaseMode; +import io.openems.edge.deye.batteryinverter.enums.StartMode; +import io.openems.edge.deye.batteryinverter.enums.Switch; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; + +public interface BatteryInverterDeye extends OffGridBatteryInverter, ManagedSymmetricBatteryInverter, SymmetricBatteryInverter, OpenemsComponent, StartStoppable, ModbusSlave { + + public enum ChannelId implements io.openems.edge.common.channel.ChannelId { + STATE_MACHINE(Doc.of(State.values()) // + .text("Current State of State-Machine")), // + RUN_FAILED(Doc.of(Level.FAULT) // + .text("Running the Logic failed")), // + SET_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)// + .unit(Unit.WATT)), // + SET_REACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)// + .unit(Unit.VOLT_AMPERE_REACTIVE)), // + CHARGE_MAX_CURRENT(new IntegerDoc() // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.AMPERE)), // + DISCHARGE_MAX_CURRENT(new IntegerDoc() // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.AMPERE)), // + CHARGE_MAX_CURRENT_READ(new IntegerDoc() // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.AMPERE)), // + DISCHARGE_MAX_CURRENT_READ(new IntegerDoc() // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.AMPERE)), // + CHARGE_MAX_VOLTAGE(new IntegerDoc() // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.VOLT)), // + DISCHARGE_MIN_VOLTAGE(new IntegerDoc() // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.VOLT)), // + + ACTIVE_DISCHARGE_ENERGY_VALUE_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), + ACTIVE_DISCHARGE_ENERGY_VALUE_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), + ACTIVE_CHARGE_ENERGY_VALUE_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), + ACTIVE_CHARGE_ENERGY_VALUE_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), + + // when implementing Lithium-ion batteries, these two registers MUST be set to + // the same + TOPPING_CHARGE_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.VOLT)), + // when implementing Lithium-ion batteries, these two registers MUST be set to + // the same + FLOAT_CHARGE_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.VOLT)), // + + MANUFACTURER_AND_MODEL_NUMBER(Doc.of(OpenemsType.STRING) // + .accessMode(AccessMode.READ_ONLY)), // + SERIAL_NUMBER(Doc.of(OpenemsType.STRING) // + .persistencePriority(PersistencePriority.HIGH) // + .accessMode(AccessMode.READ_ONLY)), // + FAULT_STATUS(Doc.of(Level.FAULT) // + .accessMode(AccessMode.READ_ONLY)), // + ALERT_STATUS(Doc.of(Level.WARNING) // + .accessMode(AccessMode.READ_ONLY)), // + BATTERY_INVERTER_STATE(new BooleanDoc() // + .debounce(5, Debounce.FALSE_VALUES_IN_A_ROW_TO_SET_FALSE) // + .onChannelChange((self, value) -> self._setInverterState(value.get()))), + + INVERTER_GRID_MODE(new BooleanDoc() // + .debounce(5, Debounce.FALSE_VALUES_IN_A_ROW_TO_SET_FALSE) // + .text("On Grid") // + .onChannelChange((self, value) -> { + final GridMode gridMode; + if (!value.isDefined()) { + gridMode = GridMode.UNDEFINED; + } else if (value.get()) { + gridMode = GridMode.ON_GRID; + } else { + gridMode = GridMode.OFF_GRID; + } + self._setGridMode(gridMode); + })), + + ISLAND_MODE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DERATING_STATUS(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + ALLOW_GRID_CONNECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + STANDBY_STATUS(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + OBTAIN_FAULT_RECORD_FLAG(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + WRITE_POWER_GENERATION_INTO_EEPROM(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + INITIALIZE_DSP_PARAMETERS(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + MASTER_SLAVE_MODE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AC_OVER_VOLTAGE_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AC_UNDER_VOLTAGE_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AC_OVER_FREQUENCY_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AC_UNDER_FREQUENCY_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + GRID_VOLTAGE_UNBALANCE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + GRID_PHASE_REVERSE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + INVERTER_ISLAND(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + ON_GRID_OFF_GRID_SWITCH_OVER_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + OUTPUT_GROUND_FAULT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + GRID_PHASE_LOCK_FAILED(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + INTERNAL_AIR_OVER_TEMPERATURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + GRID_CONNECTED_CONDITION_TIME_OUT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + MODULE_RENUMBER_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + // Monitor parallel use + CANB_COMMUNICATION_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + POWER_FREQUENCY_SYNCHRONIZATION_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + CARRIER_SYNCHRONIZATION_FALURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + EPO_ERROR(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + MONITOR_PARAMETER_MISMATCH(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DSP_VERSION_ABNORMAL(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + CPLD_VERSION_ERROR(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + HARDWARE_VERSION_ERROR(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + // Monitor to DSP + CANA_COMMUNICATION_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AUXILARY_POWER_FAULT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + FAN_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_OVER_VOLTAGE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_LOW_VOLTAGE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_VOLTAGE_UNBALANCED(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AC_RELAY_SHORT_CIRCUIT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + OUTPUT_VOLTAGE_ABNORMAL(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + OUTPUT_CURRENT_UNBALANCED(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + OVER_TEMPERATURE_OF_HEAT_SINK(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + OUTPUT_OVER_LOAD_TOT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + GRID_CONTINUE_OVER_VOLTAGE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AC_SOFT_START_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + INVERTER_START_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AC_RELAY_IS_OPEN(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + U2_BOARD_COMMUNICATION_IS_ABNORMAL(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AC_DC_COMPONENT_EXCESS(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + MASTER_SLAVE_SAMPLING_ABNORMALITY(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + PARAMETER_SETTING_ERROR(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + LOW_OFF_GRID_ENERGY(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + N_LINE_IS_NOT_CONNECTED(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + STANDBY_BUS_HEIGHT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + SINGLE_PHASE_WIRING_ERROR(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + EXCESSIVE_GRID_FREQUENCY_CHANGE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + ABRUPT_PHASE_ANGLE_FAULT_OF_POWER_GRID(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + GRID_CONNECTION_PARAMETER_CONFLICT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + EE_READING_ERROR_1(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + EE_READING_ERROR_2(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + FLASH_READING_ERROR(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + INVERTER_OVER_LOAD(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + BATTERY_PARAMETER_SETTING_ERROR(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + SLAVE_LOST_ALARM(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_CHARGING(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_DISCHARGING(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + BATTERY_FULLY_CHARGED(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + BATTERY_EMPTY(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_FAULT_STATUS(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_ALERT_STATUS(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_INPUT_OVER_VOLTAGE_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_INPUT_UNDER_VOLTAGE_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + BMS_ALERT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + BMS_COMMUNICATION_TIMEOUT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + EMS_COMMUNICATION_TIMEOUT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_SOFT_START_FAILED(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_RELAY_SHORT_CIRCUIT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_RELAY_SHORT_OPEN(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + BATTERY_POWEROVER_LOAD(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + BATTERY_POWER_OVER_LOAD(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_BUS_STARTING_FAILED(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_QUICK_CHECK_OVER_CURRENT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_OC(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + // AC L1-L2 RMS voltage + GRID_VOLTAGE_L1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIVOLT)), // + // AC L2-L3 RMS voltage + GRID_VOLTAGE_L2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIVOLT)), // + // AC L3-L1 RMS voltage + GRID_VOLTAGE_L3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIVOLT)), // + // AC L1 RMS current + GRID_CURRENT_L1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIAMPERE)), // + // AC L2 RMS current + GRID_CURRENT_L2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIAMPERE)), // + // AC L3 RMS current + GRID_CURRENT_L3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIAMPERE)), // + // AC frequency + FREQUENCY(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIHERTZ)), // + // AC L1 Active Power + ACTIVE_POWER_L1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.WATT)), // + // AC L2 Active Power + ACTIVE_POWER_L2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.WATT)), // + // AC L3 Active Power + ACTIVE_POWER_L3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.WATT)), // + // AC L1 Reactive Power + REACTIVE_POWER_L1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.VOLT_AMPERE_REACTIVE)), // + // AC L2 Reactive Power + REACTIVE_POWER_L2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.VOLT_AMPERE_REACTIVE)), // + // AC L3 Reactive Power + REACTIVE_POWER_L3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.VOLT_AMPERE_REACTIVE)), // + // AC L1 Apparent Power + APPERENT_POWER_L1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.VOLT_AMPERE)), // + // AC L2 Apparent Power + APPERENT_POWER_L2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.VOLT_AMPERE)), // + // AC L3 Apparent Power + APPERENT_POWER_L3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.VOLT_AMPERE)), // + // AC L1 Power Factor + COS_PHI_L1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_ONLY)), // + // AC L2 Power Factor + COS_PHI_L2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_ONLY)), // + // AC L3 Power Factor + COS_PHI_L3(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_ONLY)), // + // AC Apperent Power + APPARENT_POWER(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.VOLT_AMPERE)), // + // AC Power Factor + COS_PHI(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_ONLY)), // + + // Temperature of DC heat sink + TEMPERATURE_OF_AC_HEAT_SINK(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.DEGREE_CELSIUS)), // + // BUS+ side voltage + DC_VOLTAGE_POSITIVE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIVOLT)), // + // BUS- side voltage + DC_VOLTAGE_NEGATIVE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIVOLT)), // + // Target off-grid voltage bias + SET_OFF_GRID_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)// + .unit(Unit.MILLIVOLT)), // + // Target off-grid frequency bias + SET_OFF_GRID_FREQUENCY(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)// + .unit(Unit.MILLIHERTZ)), // + DC_POWER(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.WATT)), // + DC_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIVOLT)), // + DC_CURRENT(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIAMPERE)), // + DC_CHARGE_ENERGY(Doc.of(OpenemsType.LONG) // + .accessMode(AccessMode.READ_WRITE)// + .unit(Unit.CUMULATED_WATT_HOURS)), // + DC_DISCHARGE_ENERGY(Doc.of(OpenemsType.LONG) // + .accessMode(AccessMode.READ_WRITE)// + .unit(Unit.CUMULATED_WATT_HOURS)), // + TEMPERATURE_OF_DC_DC_HEAT_SINK(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.DEGREE_CELSIUS)), // + DC_RELAY_REAR_END_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.VOLT)), // + CHARGE_MAX_CURRENT_SETTING(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIAMPERE)), // + DISCHARGE_MAX_CURRENT_SETTING(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIAMPERE)), // + IP_ADDRESS_BLOCK_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + IP_ADDRESS_BLOCK_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + IP_ADDRESS_BLOCK_3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + IP_ADDRESS_BLOCK_4(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + NETMASK_BLOCK_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + NETMASK_BLOCK_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + NETMASK_BLOCK_3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + NETMASK_BLOCK_4(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + GATEWAY_IP_BLOCK_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + GATEWAY_IP_BLOCK_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + GATEWAY_IP_BLOCK_3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + GATEWAY_IP_BLOCK_4(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + MAC(Doc.of(OpenemsType.STRING) // + .accessMode(AccessMode.READ_WRITE)), // + MODBUS_UNIT_ID(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + BAUDRATE(Doc.of(Baudrate.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // default 1 + INTERFACE_TYPE(Doc.of(InterfaceType.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // Takes effect after hard reset,0-modbus + COMMUNICATION_PROTOCOL_SELECTION(Doc.of(ProtocolSelection.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // Prevent unexpected results of communication failures.when EMS timeout + // enabled, watchdog will work and even reading will feed the watchdog + EMS_TIMEOUT(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // Enable ONLY when remote Emergency Stop Button is needed + EPO_ENABLE(Doc.of(Epo.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // Enable ONLY when remote BMS-inverter connection is needed + BMS_TIMEOUT(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // Takes effect after hard reset,0-modbus + BMS_PROTOCOL_SELECTION(Doc.of(ProtocolSelection.values()) // + .accessMode(AccessMode.READ_WRITE)), // + SET_GRID_MODE(Doc.of(SinexcelGridMode.values()) // + .accessMode(AccessMode.READ_WRITE)), // + BUZZER_ENABLE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + RESTORE_FACTORY_SETTING(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // To Start operation, only 1 will be accepted. Reading back value makes no + // sense + START_INVERTER(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // To Stop operation, only 1 will be accepted. Reading back value makes no sense + STOP_INVERTER(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // clear failure flag,when fault occurs, the system will stop and indicates + // fault.starting is invalid until the fault source is actually removed and this + // register is written 1. Reading back value makes no sense + CLEAR_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.WRITE_ONLY)), // + // set the module to on grid mode. Reading back value makes no sense + SET_ON_GRID_MODE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // set the module to off grid mode. Reading back value makes no sense + SET_OFF_GRID_MODE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // set the module to standby mode,setpoint 0:IGBT switching ,setpoint 1:no IGBT + // switching,low consumption.let the inverter to halt the IGBT switching, to + // save the power consumption, but all relays are still closed. + // Reading back value makes no sense + SET_STANDBY_COMMAND(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + SET_SOFT_START(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + RESET_INSTRUCTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + GRID_STOP(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + VOLTAGE_LEVEL(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + FREQUENCY_LEVEL(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + INVERTER_WIRING_TOPOLOGY(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + SWITCHING_DEVICE_ACCESS_SETTING(Doc.of(Switch.values()) // + .accessMode(AccessMode.READ_WRITE)), // + MODULE_POWER_LEVEL(Doc.of(ModulePowerLevel.values()) // + .accessMode(AccessMode.READ_ONLY)), // + DC_VOLTAGE_LEVEL(Doc.of(DcVoltageLevel.values()) // + .accessMode(AccessMode.READ_ONLY)), // + CPU_TYPE(Doc.of(CpuType.values()) // + .accessMode(AccessMode.READ_WRITE)), // + OFF_GRID_AND_PARALLEL_ENABLE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + SET_DC_SOFT_START_EXTERNAL_CONTROL(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + GRID_OVER_VOLTAGE_PROTECTION_AMPLITUDE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_OVER_VOLTAGE_TRIP_TIME_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_OVER_VOLTAGE_TRIP_LEVEL_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_OVER_VOLTAGE_TRIP_TIME_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_VOLTAGE_TRIP_LEVEL_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_VOLTAGE_TRIP_TIME_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_VOLTAGE_TRIP_LEVEL_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_VOLTAGE_TRIP_TIME_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_VOLTAGE_TRIP_LEVEL_3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_VOLTAGE_TRIP_TIME_3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_OVER_FREQUENCY_TRIP_LEVEL_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_OVER_FREQUENCY_TRIP_TIME_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_OVER_FREQUENCY_TRIP_LEVEL_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_OVER_FREQUENCY_TRIP_TIME_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_FREQUENCY_TRIP_LEVEL_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_FREQUENCY_TRIP_TIME_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_FREQUENCY_TRIP_LEVEL_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_FREQUENCY_TRIP_TIME_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + RECONNECT_TIME(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // Anti-islanding is a CPUC RULE 21/HECO RULE14H/IEEE1547-requested function to + // make sure the inverter disconnect from the grid in case of blackout. + // This is to prevent the formation of an unintended island. The inverter design + // shall comply with the requirements of IEEE Std 1547 and UL 1741 standards (or + // latest versions) and be certified to have anti-islanding protection such that + // the synchronous inverter will automatically disconnect upon a utility system + // interruption + ANTI_ISLANDING(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // Frequency and Voltage Ride-Through. + // The ability to withstand voltage or frequency excursions outside defined + // limits without tripping or malfunctioning + FREQUENCY_VOLTAGE_RIDE_THROUGH(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // Grid-tied mode only, voltage and frequency setpoint the only setpoints + REACTIVE_POWER_CONTROL_MODE(Doc.of(ReactivePowerControlMode.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // To define how the power changes + POWER_RISING_MODE(Doc.of(PowerRisingMode.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // Grid-tied mode only, Volt/Watt control & Freq/Watt control means active power + // will be regulated by grid voltage/frequency following a curve/ramp rate given + // by HECO or CPUC or other local utility authority codes + ACTIVE_POWER_CONTROL_MODE(Doc.of(ActivePowerControlMode.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // Grid-tied mode only, voltage and frequency setpoint the only setpoints + GRID_VOLTAGE_ASYMMETRIC_DETECTON(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // Grid-tied mode only + CONTINUOUS_OVERVOLTAGE_DETECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // Grid-tied mode only,detect whether the grid is on-service at powered-up. + GRID_EXISTENCE_DETECTION_ON(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), + // Grid-tied mode only + NEUTRAL_FLOATING_DETECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // if disabled, the inverter will start the AC voltage, then close the relay. In + // some off-grid cases, such as there are inductive loads or transformer, the + // in rush exciting current will trip the inverter. Enabling this register, the + // inverter will close the relay first try to limit the current and start the + // voltage slowly + OFF_GRID_BLACKSTART_MODE(Doc.of(BlackStartMode.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // Grid tied mode only. take effect after power off. + GRID_CODE_SELECTION(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + GRID_CONNECTED_ACTIVE_CAPACITY_LIMITATION_FUNCTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + GRID_ACTIVE_POWER_CAPACITY_SETTING(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + // Single mode enable and select + SINGLE_PHASE_MODE_SELECTION(Doc.of(SinglePhaseMode.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // Overvoltage drop active enable (only for EN50549 certification) + OVER_VOLTAGE_DROP_ACTIVE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // 0-Manual start,1-Auto start,default:0 + START_UP_MODE(Doc.of(StartMode.values()) // + .accessMode(AccessMode.READ_WRITE)), // + LOCAL_ID_SETTING(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // when implementing Lithium-ion batteries,this register MUST be set to 0 + CURRENT_FROM_TOPPING_CHARGING_TO_FLOAT_CHARGING(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + BATTERY_VOLTAGE_PROTECTION_LIMIT(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.VOLT)), // + LEAKAGE_CURRENT_DC_COMPONENT_DETECTOR(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + RESUME_AND_LIMIT_FREQUENCY(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + RESTORE_LOWER_FREQUENCY_OF_GRID_CONNECTION(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + VOLTAGE_REACTIVE_REFERENCE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + + // ratio * rated voltage,Available only when reactive power regulation mode is + // set to Volt/Var(53626). + VOLTAGE_AND_REACTIVE_POWER_ADJUSTMENT_POINT_V1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + VOLTAGE_AND_REACTIVE_POWER_ADJUSTMENT_POINT_V2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + VOLTAGE_AND_REACTIVE_POWER_ADJUSTMENT_POINT_V3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + VOLTAGE_AND_REACTIVE_POWER_ADJUSTMENT_POINT_V4(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + + // refer to HECO RULE 14, keep default value if no aware of it + MAX_CAPACITIVE_REACTIVE_REGULATION_Q1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + INITIAL_CAPACITIVE_REACTIVE_REGULATION_Q2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + INITIAL_INDUCTIVE_REACTIVE_REGULATION_Q3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + MAX_INDUCTIVE_REACTIVE_REGULATION_Q4(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + VOLTAGE_AND_REACTIVE_RESPONSE_TIME(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + REACTIVE_FIRST_ORDER_RESPONSE_TIME(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + + // ratio * rated voltage, Available only when active power regulation + // mode(53636) is set to Volt/Watt and operating in discharge mode, follow the + // FVRT table given by HECO or CPUC or other local utility authority codes. + INITIAL_VOLTAGE_V_START(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + END_VOLTAGE_V_STOP(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + INITIAL_POWER_P_START(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + END_POWER_P_STOP(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + RETURN_TO_SERVICE_DELAY(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + VOLT_WATT_RESPONSE_TIME(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + + // Available only when active power regulation mode(53636) is set to Freq/Watt + // and operating in discharge mode. When the actual frequency is above the + // point, the active power will be regulated(lowered) with the ramp rate. In + // Australia, this register shall be fixed to 0.25Hz + START_OF_FREQUENY_DROP(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // The ramp rate is defined as multiple of set active power per hertz that above + // the above the Freq/Watt regulation point. Available only when active power + // regulation mode(53636) is set to Freq/Watt and operating in discharge mode. + // Example: Rated frequency is 60Hz, the target active power is set to 10kW, + // Freq/Watt regulation point is set to 2Hz, ramp rate is set as 0.5, If the + // actual frequency reaches 63Hz, the output active power will be + // 10kW-(63Hz-62Hz) x 0.5*(10kW/Hz) = 5kW + SLOPE_OF_FREQUENCY_DROP(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // AS4777 only, bias Bias from rated frequency + FREQUENCY_WATT_F_STOP_DISCHARGE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + FREQUENCY_WATT_F_STOP_CHARGE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // %Vrated,AS4777 only, ratio + VOLT_WATT_V_START_CHARGE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // SS takes effect when the inverter starts, or when the inverter is on "grid + // reconnection" after the trip caused by FVRT timeout + SOFT_START_RAMP_RATE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // RR takes effect in Volt-Watt or Freq-Watt mode when the grid is back to + // normal state and the inverter trying to go back to normal output. + // In other words, as long as the inverter does not trip, and the inverter had + // derated the output power, RR takes effect when the inverter tries to go back + // to normal output. Available only when Power rising mode is set to ramp + // mode(53626).If the value is 2.000, which means within 0.5 seconds the system + // can runs to full power output. + POWER_RAMP_RATE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // Available only when Constant PF is enabled,Negative inductive, positive + // capacitive + POWER_FACTOR_SETTING(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + // Available only when active power regulation mode(53636) is set to Freq/Watt + // and operating in discharge mode. When the actual frequency is above the + // point, the active power will be regulated(lowered) with the ramp rate + POWER_FACTOR_P1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + POWER_FACTOR_P2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + POWER_FACTOR_P3(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + POWER_FACTOR_P4(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + + // +(lagging), -(leading), + POWER_FACTOR_CURVE_MODE_P1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + POWER_FACTOR_CURVE_MODE_P2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + POWER_FACTOR_CURVE_MODE_P3(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + POWER_FACTOR_CURVE_MODE_P4(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + + // %Vrated + CONTINUOS_OVER_VOLTAGE_TRIP_THRESHOLD(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + FREQUENCY_VARIATION_RATE_TRIP_THRESHOLD(Doc.of(FrequencyVariationRate.values()) // + .accessMode(AccessMode.READ_WRITE)), // + PHASE_ANGLE_ABRUPT_TRIP_THRESHOLD(Doc.of(PhaseAngleAbrupt.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // Available only when Power rising mode is set to ramp mode . once tripped + // after FVRT timeout, the inverter can reconnect to the grid when frequency or + // voltage is back to the thresholds defined as "grid is back to service". In + // HECO14 /CPUC 21, this register is unnecessary to + GRID_RECONNECTION_VOLTAGE_UPPER_LIMIT(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + GRID_RECONNECTION_VOLTAGE_LOWER_LIMIT(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // Available only when Power rising mode is set to ramp mode once tripped after + // FVRT timeout, the inverter can reconnect to the grid when frequency or + // voltage is back to the thresholds defined as "grid is back to service" + GRID_RECONNECTION_FREQUENCY_UPPER_LIMIT(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // Bias from rated frequency + GRID_RECONNECTION_FREQUENCY_LOWER_LIMIT(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + LOW_FREQUENCY_RAMP_RATE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // TODO Values check Meter options !!!!!!!!!!!!!!!!!! + METER_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE).unit(Unit.WATT)), // + + GRID_VOLTAGE_CALIBRATION_L1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + GRID_VOLTAGE_CALIBRATION_L2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + GRID_VOLTAGE_CALIBRATION_L3(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INVERTER_VOLTAGE_CALIBRATION_L1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INVERTER_VOLTAGE_CALIBRATION_L2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INVERTER_VOLTAGE_CALIBRATION_L3(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INDUCTOR_CURRENT_CALIBRATION_L1_PARAMETERS_1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INDUCTOR_CURRENT_CALIBRATION_L2_PARAMETERS_1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INDUCTOR_CURRENT_CALIBRATION_L3_PARAMETERS_1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INDUCTOR_CURRENT_CALIBRATION_L1_PARAMETERS_2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INDUCTOR_CURRENT_CALIBRATION_L2_PARAMETERS_2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INDUCTOR_CURRENT_CALIBRATION_L3_PARAMETERS_2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + OUTPUT_CURRENT_CALIBRATION_L1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + OUTPUT_CURRENT_CALIBRATION_L2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + OUTPUT_CURRENT_CALIBRATION_L3(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + POSITIVE_BUS_VOLTAGE_CALIBRATION(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + NEGATIVE_BUS_VOLTAGE_CALIBRATION(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + DC_VOLTAGE_CALIBRATION(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + DC_CURRENT_CALIBRATION(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + DC_INDUCTOR_CURRENT_CALIBRATION(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + TIME_SETTING(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.WRITE_ONLY)), // + PASSWORD(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.WRITE_ONLY)), // + ACTIVE_POWER_1(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_ONLY)), + ACTIVE_POWER_2(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_ONLY) // + ),; + + private final Doc doc; + + private ChannelId(Doc doc) { + this.doc = doc; + } + + @Override + public Doc doc() { + return this.doc; + } + } + + /** + * Gets the Channel for {@link ChannelId#SET_ON_GRID_MODE}. + * + * @return the Channel + */ + public default BooleanWriteChannel getSetOnGridModeChannel() { + return this.channel(ChannelId.SET_ON_GRID_MODE); + } + + /** + * Gets the Set-On-Grid-Mode. See {@link ChannelId#SET_ON_GRID_MODE}. + * + * @return the Channel {@link Value} + */ + public default Value getSetOnGridMode() { + return this.getSetOnGridModeChannel().value(); + } + + /** + * Sets a the On-Grid-Mode. See {@link ChannelId#SET_ON_GRID_MODE}. + * + * @param value the next write value + * @throws OpenemsNamedException on error + */ + public default void setOnGridMode(Boolean value) throws OpenemsNamedException { + this.getSetOnGridModeChannel().setNextWriteValue(value); + } + + /** + * Gets the Channel for {@link SymmetricBatteryInverter.ChannelId#ACTIVE_POWER}. + * + * @return the Channel + */ + public default IntegerReadChannel getActive1PowerChannel() { + return this.channel(ChannelId.ACTIVE_POWER_1); + } + + /** + * Gets the Channel for {@link SymmetricBatteryInverter.ChannelId#ACTIVE_POWER}. + * + * @return the Channel + */ + public default IntegerReadChannel getActive2PowerChannel() { + return this.channel(ChannelId.ACTIVE_POWER_2); + } + + /** + * Gets the Channel for {@link ChannelId#SET_OFF_GRID_MODE}. + * + * @return the Channel + */ + public default BooleanWriteChannel getSetOffGridModeChannel() { + return this.channel(ChannelId.SET_OFF_GRID_MODE); + } + + /** + * Gets the Set-Off-Grid-Mode. See {@link ChannelId#SET_OFF_GRID_MODE}. + * + * @return the Channel {@link Value} + */ + public default Value getSetOffGridMode() { + return this.getSetOffGridModeChannel().value(); + } + + /** + * Sets a the Off-Grid-Mode. See {@link ChannelId#SET_OFF_GRID_MODE}. + * + * @param value the next write value + * @throws OpenemsNamedException on error + */ + public default void setOffGridMode(Boolean value) throws OpenemsNamedException { + this.getSetOffGridModeChannel().setNextWriteValue(value); + } + + /** + * Gets the Channel for {@link ChannelId#START_INVERTER}. + * + * @return the Channel + */ + public default BooleanWriteChannel getStartInverterChannel() { + return this.channel(ChannelId.START_INVERTER); + } + + /** + * Sends a START command to the inverter. See {@link ChannelId#START_INVERTER}. + * + * @throws OpenemsNamedException on error + */ + public default void setStartInverter() throws OpenemsNamedException { + this.getStartInverterChannel().setNextWriteValue(true); // true = START + } + + /** + * Gets the Channel for {@link ChannelId#STOP_INVERTER}. + * + * @return the Channel + */ + public default BooleanWriteChannel getStopInverterChannel() { + return this.channel(ChannelId.STOP_INVERTER); + } + + /** + * Sends a STOP command to the inverter. See {@link ChannelId#STOP_INVERTER}. + * + * @throws OpenemsNamedException on error + */ + public default void setStopInverter() throws OpenemsNamedException { + this.getStopInverterChannel().setNextWriteValue(true); // true = STOP + } + + /** + * Gets the Channel for {@link ChannelId#CLEAR_FAILURE}. + * + * @return the Channel + */ + public default BooleanWriteChannel getClearFailureChannel() { + return this.channel(ChannelId.CLEAR_FAILURE); + } + + /** + * Clear inverter failures. See {@link ChannelId#CLEAR_FAILURE}. + * + * @throws OpenemsNamedException on error + */ + public default void setClearFailure() throws OpenemsNamedException { + this.getClearFailureChannel().setNextWriteValue(true); + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeyeImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeyeImpl.java new file mode 100644 index 00000000000..9efd4a6f008 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeyeImpl.java @@ -0,0 +1,407 @@ +package io.openems.edge.deye.batteryinverter; + +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; + +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.ConfigurationPolicy; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; +import org.osgi.service.component.annotations.ReferencePolicyOption; +import org.osgi.service.event.propertytypes.EventTopics; +import org.osgi.service.metatype.annotations.Designate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.openems.common.channel.AccessMode; +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.common.exceptions.OpenemsException; +import io.openems.common.types.OptionsEnum; +import io.openems.edge.battery.api.Battery; +import io.openems.edge.batteryinverter.api.BatteryInverterConstraint; +import io.openems.edge.batteryinverter.api.ManagedSymmetricBatteryInverter; +import io.openems.edge.batteryinverter.api.OffGridBatteryInverter; +import io.openems.edge.batteryinverter.api.SymmetricBatteryInverter; +import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; +import io.openems.edge.bridge.modbus.api.BridgeModbus; +import io.openems.edge.bridge.modbus.api.ModbusComponent; +import io.openems.edge.bridge.modbus.api.ModbusProtocol; +import io.openems.edge.bridge.modbus.api.element.SignedWordElement; +import io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask; +import io.openems.edge.common.channel.BooleanWriteChannel; +import io.openems.edge.common.channel.IntegerWriteChannel; +import io.openems.edge.common.channel.WriteChannel; +import io.openems.edge.common.component.ComponentManager; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.common.event.EdgeEventConstants; +import io.openems.edge.common.modbusslave.ModbusSlaveTable; +import io.openems.edge.common.startstop.StartStop; +import io.openems.edge.common.startstop.StartStoppable; +import io.openems.edge.common.taskmanager.Priority; +import io.openems.edge.common.type.TypeUtils; +import io.openems.edge.deye.batteryinverter.enums.EnableDisable; +import io.openems.edge.deye.batteryinverter.enums.FrequencyLevel; +import io.openems.edge.deye.batteryinverter.enums.GridCodeSelection; +import io.openems.edge.deye.batteryinverter.enums.PowerRisingMode; +import io.openems.edge.deye.batteryinverter.enums.VoltageLevel; +import io.openems.edge.deye.batteryinverter.statemachine.Context; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; +import io.openems.edge.ess.power.api.Phase; +import io.openems.edge.ess.power.api.Pwr; +import io.openems.edge.ess.power.api.Relationship; +import io.openems.edge.timedata.api.Timedata; +import io.openems.edge.timedata.api.TimedataProvider; +import io.openems.edge.timedata.api.utils.CalculateEnergyFromPower; + +@Designate(ocd = Config.class, factory = true) +@Component(// + name = "Battery-Inverter.Deye", // + immediate = true, // + configurationPolicy = ConfigurationPolicy.REQUIRE // +) +@EventTopics({ // + EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE, // + EdgeEventConstants.TOPIC_CYCLE_BEFORE_PROCESS_IMAGE // +}) +public class BatteryInverterDeyeImpl extends AbstractOpenemsModbusComponent + implements BatteryInverterDeye, OffGridBatteryInverter, ManagedSymmetricBatteryInverter, + SymmetricBatteryInverter, ModbusComponent, OpenemsComponent, TimedataProvider, StartStoppable { + + public static final int DEFAULT_EMS_TIMEOUT = 60; + public static final int DEFAULT_BMS_TIMEOUT = 0; + public static final EnableDisable DEFAULT_GRID_EXISTENCE_DETECTION_ON = EnableDisable.DISABLE; + public static final PowerRisingMode DEFAULT_POWER_RISING_MODE = PowerRisingMode.STEP; + + private static final int MAX_CURRENT = 90; // [A] + private static final int MAX_TOPPING_CHARGE_VOLTAGE = 750; + + private final Logger log = LoggerFactory.getLogger(BatteryInverterDeyeImpl.class); + private final StateMachine stateMachine = new StateMachine(State.UNDEFINED); + + private final CalculateEnergyFromPower calculateChargeEnergy = new CalculateEnergyFromPower(this, + SymmetricBatteryInverter.ChannelId.ACTIVE_CHARGE_ENERGY); + private final CalculateEnergyFromPower calculateDischargeEnergy = new CalculateEnergyFromPower(this, + SymmetricBatteryInverter.ChannelId.ACTIVE_DISCHARGE_ENERGY); + + @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL) + private volatile Timedata timedata = null; + + @Reference + private ComponentManager componentManager; + + @Reference + private ConfigurationAdmin cm; + + @Override + @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) + protected void setModbus(BridgeModbus modbus) { + super.setModbus(modbus); + } + + protected Config config; + + public BatteryInverterDeyeImpl() throws OpenemsNamedException { + super(// + OpenemsComponent.ChannelId.values(), // + ModbusComponent.ChannelId.values(), // + SymmetricBatteryInverter.ChannelId.values(), // + ManagedSymmetricBatteryInverter.ChannelId.values(), // + StartStoppable.ChannelId.values(), // + OffGridBatteryInverter.ChannelId.values(), // + BatteryInverterDeye.ChannelId.values() // + ); + } + + @Override + protected ModbusProtocol defineModbusProtocol() throws OpenemsException { + return new ModbusProtocol(this, + new FC3ReadRegistersTask(672, Priority.HIGH, m(BatteryInverterDeye.ChannelId.ACTIVE_POWER_1, + new SignedWordElement(672)),m(BatteryInverterDeye.ChannelId.ACTIVE_POWER_2, + new SignedWordElement(673)))); + } + + @Activate + private void activate(ComponentContext context, Config config) throws OpenemsNamedException { + this.config = config; + if (super.activate(context, config.id(), config.alias(), config.enabled(), config.modbusUnitId(), this.cm, "Modbus", + config.modbus_id())) { + return; + } + } + + @Override + @Deactivate + protected void deactivate() { + super.deactivate(); + } + + @Override + public void run(Battery battery, int setActivePower, int setReactivePower) throws OpenemsNamedException { + // Store the current State + this.channel(BatteryInverterDeye.ChannelId.STATE_MACHINE).setNextValue(this.stateMachine.getCurrentState()); + + // Initialize 'Start-Stop' Channel + this._setStartStop(StartStop.UNDEFINED); + + // Set Default Settings + this.setDefaultSettings(); + + // Set Battery Limits + this.setBatteryLimits(battery); + + // Calculate the Energy values from ActivePower. + this.calculateEnergy(); + + // Prepare Context + var context = new Context(this, this.config, this.targetGridMode.get(), setActivePower, setReactivePower); + + // Call the StateMachine + try { + this.stateMachine.run(context); + + this.channel(BatteryInverterDeye.ChannelId.RUN_FAILED).setNextValue(false); + + } catch (OpenemsNamedException e) { + this.channel(BatteryInverterDeye.ChannelId.RUN_FAILED).setNextValue(true); + this.logError(this.log, "StateMachine failed: " + e.getMessage()); + } + } + + /** + * Updates the Channel if its current value is not equal to the new value. + * + * @param channelId Sinexcel Channel-Id + * @param value {@link OptionsEnum} value. + * @throws IllegalArgumentException on error + */ + private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, OptionsEnum value) + throws IllegalArgumentException, OpenemsNamedException { + this.updateIfNotEqual(channelId, value.getValue()); + } + + /** + * Updates the Channel if its current value is not equal to the new value. + * + * @param channelId Sinexcel Channel-Id + * @param newValue Integer value. + * @throws IllegalArgumentException on error + */ + private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, Integer newValue) + throws IllegalArgumentException { + WriteChannel channel = this.channel(channelId); + var currentValue = channel.value(); + if (currentValue.isDefined() && !Objects.equals(currentValue.get(), newValue)) { + try { + channel.setNextWriteValue(newValue); + } catch (OpenemsNamedException e) { + this.logWarn(this.log, "Unable to update Channel [" + channel.address() + "] from [" + currentValue + + "] to [" + newValue + "]"); + e.printStackTrace(); + } + } + } + + private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, VoltageLevel voltageLevel) + throws IllegalArgumentException, OpenemsNamedException { + IntegerWriteChannel channel = this.channel(channelId); + channel.setNextWriteValue(voltageLevel.getValue()); + } + + private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, FrequencyLevel frequencyLevel) + throws IllegalArgumentException, OpenemsNamedException { + IntegerWriteChannel channel = this.channel(channelId); + channel.setNextWriteValue(frequencyLevel.getValue()); + } + + private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, GridCodeSelection gridCodeSelection) + throws IllegalArgumentException, OpenemsNamedException { + IntegerWriteChannel channel = this.channel(channelId); + channel.setNextWriteValue(gridCodeSelection.getValue()); + } + + private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, EnableDisable value) + throws IllegalArgumentException, OpenemsNamedException { + BooleanWriteChannel channel = this.channel(channelId); + switch (value) { + case ENABLE: + channel.setNextWriteValue(true); + break; + case DISABLE: + channel.setNextWriteValue(false); + break; + } + } + + /** + * Sets some default settings on the inverter, like Timeout. + * + * @throws OpenemsNamedException on error + */ + private void setDefaultSettings() throws OpenemsNamedException { + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.EMS_TIMEOUT, DEFAULT_EMS_TIMEOUT); + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.BMS_TIMEOUT, DEFAULT_BMS_TIMEOUT); + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.GRID_EXISTENCE_DETECTION_ON, + DEFAULT_GRID_EXISTENCE_DETECTION_ON); + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.POWER_RISING_MODE, DEFAULT_POWER_RISING_MODE); + + switch (this.config.countryCode()) { + case AUSTRIA: + case GERMANY: + case SWITZERLAND: + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.VOLTAGE_LEVEL, VoltageLevel.V_400); + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.FREQUENCY_LEVEL, FrequencyLevel.HZ_50); + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.GRID_CODE_SELECTION, GridCodeSelection.VDE); + break; + } + + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.INVERTER_WIRING_TOPOLOGY, this.config.emergencyPower()); + } + + /** + * Sets the Battery Limits. + * + * @param battery the linked {@link Battery} + * @throws OpenemsNamedException on error + */ + private void setBatteryLimits(Battery battery) throws OpenemsNamedException { + // Upper voltage limit of battery protection >= Topping charge voltage >= Float + // charge voltage >= Lower voltage limit of battery protection (814 >= 809 >= + // 808 >= 813). + // Discharge Min Voltage + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.DISCHARGE_MIN_VOLTAGE, + battery.getDischargeMinVoltage().get()); + + // Charge Max Voltage + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.CHARGE_MAX_VOLTAGE, battery.getChargeMaxVoltage().get()); + + // Topping Charge Voltage + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.TOPPING_CHARGE_VOLTAGE, + TypeUtils.min(battery.getChargeMaxVoltage().get(), MAX_TOPPING_CHARGE_VOLTAGE)); + + // Float Charge Voltage + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.FLOAT_CHARGE_VOLTAGE, + TypeUtils.min(battery.getChargeMaxVoltage().get(), MAX_TOPPING_CHARGE_VOLTAGE)); + + // Discharge Max Current + // negative value is corrected as zero + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.DISCHARGE_MAX_CURRENT, + TypeUtils.fitWithin(0 /* enforce positive */, MAX_CURRENT, battery.getDischargeMaxCurrent().orElse(0))); + + // Charge Max Current + // negative value is corrected as zero + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.CHARGE_MAX_CURRENT, + TypeUtils.fitWithin(0 /* enforce positive */, MAX_CURRENT, battery.getChargeMaxCurrent().orElse(0))); + } + + @Override + public String debugLog() { + return "MOIN - L:" + this.getActivePower().asString(); + } + + private final AtomicReference startStopTarget = new AtomicReference<>(StartStop.UNDEFINED); + + @Override + public void setStartStop(StartStop value) { + if (this.startStopTarget.getAndSet(value) != value) { + // Set only if value changed + this.stateMachine.forceNextState(State.UNDEFINED); + } + } + + /** + * Gets the inverter start-stop target. + * + * @return {@link StartStop} + */ + public StartStop getStartStopTarget() { + switch (this.config.startStop()) { + case AUTO: + // read StartStop-Channel + return this.startStopTarget.get(); + + case START: + // force START + return StartStop.START; + + case STOP: + // force STOP + return StartStop.STOP; + } + + assert false; + return StartStop.UNDEFINED; // can never happen + } + + protected final AtomicReference targetGridMode = new AtomicReference<>(TargetGridMode.GO_ON_GRID); + + @Override + public void setTargetGridMode(TargetGridMode targetGridMode) { + if (this.targetGridMode.getAndSet(targetGridMode) != targetGridMode) { + // Set only if value changed + this.stateMachine.forceNextState(State.UNDEFINED); + } + } + + @Override + public BatteryInverterConstraint[] getStaticConstraints() throws OpenemsException { + if (this.stateMachine.getCurrentState() == State.RUNNING) { + return BatteryInverterConstraint.NO_CONSTRAINTS; + + } + // Block any power as long as we are not RUNNING + return new BatteryInverterConstraint[] { // + new BatteryInverterConstraint("Sinexcel inverter not ready", Phase.ALL, Pwr.REACTIVE, // + Relationship.EQUALS, 0d), // + new BatteryInverterConstraint("Sinexcel inverter not ready", Phase.ALL, Pwr.ACTIVE, // + Relationship.EQUALS, 0d) // + }; + } + + @Override + public int getPowerPrecision() { + return 100; + } + + @Override + public ModbusSlaveTable getModbusSlaveTable(AccessMode accessMode) { + return new ModbusSlaveTable(// + OpenemsComponent.getModbusSlaveNatureTable(accessMode), // + SymmetricBatteryInverter.getModbusSlaveNatureTable(accessMode), // + ManagedSymmetricBatteryInverter.getModbusSlaveNatureTable(accessMode) // + ); + } + + /** + * Calculate the Energy values from ActivePower. + */ + private void calculateEnergy() { + // Calculate Energy + var activePower1 = this.getActive1PowerChannel().value().get(); + var activePower2 = this.getActive2PowerChannel().value().get(); + var activePower = activePower1 + activePower2; + if (activePower1 == null && activePower2 == null) { + // Not available + this.calculateChargeEnergy.update(null); + this.calculateDischargeEnergy.update(null); + } else if (activePower > 0) { + // Buy-From-Grid + this.calculateChargeEnergy.update(0); + this.calculateDischargeEnergy.update(activePower); + } else { + // Sell-To-Grid + this.calculateChargeEnergy.update(activePower * -1); + this.calculateDischargeEnergy.update(0); + } + } + + @Override + public Timedata getTimedata() { + return this.timedata; + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/Config.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/Config.java new file mode 100644 index 00000000000..26202dff197 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/Config.java @@ -0,0 +1,41 @@ +package io.openems.edge.deye.batteryinverter; + +import io.openems.edge.deye.batteryinverter.enums.CountryCode; +import io.openems.edge.deye.batteryinverter.enums.EnableDisable; +import org.osgi.service.metatype.annotations.AttributeDefinition; +import org.osgi.service.metatype.annotations.ObjectClassDefinition; + +import io.openems.edge.common.startstop.StartStopConfig; + +@ObjectClassDefinition(// + name = "Battery-Inverter Deye", // + description = "Implements the Deye battery inverter.") +public @interface Config { + + @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") + String id() default "batteryInverter0"; + + @AttributeDefinition(name = "Alias", description = "Human-readable name of this Component; defaults to Component-ID") + String alias() default ""; + + @AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?") + boolean enabled() default true; + + @AttributeDefinition(name = "Start/stop behaviour?", description = "Should this Component be forced to start or stop?") + StartStopConfig startStop() default StartStopConfig.AUTO; + + @AttributeDefinition(name = "Modbus-ID", description = "ID of Modbus bridge.") + String modbus_id(); + + @AttributeDefinition(name = "Modbus Unit-ID", description = "The Unit-ID of the Modbus device.") + int modbusUnitId() default 1; + + @AttributeDefinition(name = "Country Code", description = "Selection of the country code.") CountryCode countryCode() default CountryCode.GERMANY; + + @AttributeDefinition(name = "Is emergency power enabled?", description = "Emergency power enable/disable.") EnableDisable emergencyPower() default EnableDisable.DISABLE; + + @AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID'.") + String Modbus_target() default "(enabled=true)"; + + String webconsole_configurationFactory_nameHint() default "Battery-Inverter Deye [{id}]"; +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ActivePowerControlMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ActivePowerControlMode.java new file mode 100644 index 00000000000..d9691bbba40 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ActivePowerControlMode.java @@ -0,0 +1,34 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum ActivePowerControlMode implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + CONTANT_ACTIVE_POWER(0, "Constant Active Power"), // + VOLT_WATT_ENABLED(1, "Volt watt enabled"), // + CONSTANT_PF(2, "Constant power factor"), // + WATT_PF_ENABLED(3, "Watt power factor enabled");// + + private final int value; + private final String name; + + private ActivePowerControlMode(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Baudrate.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Baudrate.java new file mode 100644 index 00000000000..74194f196a1 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Baudrate.java @@ -0,0 +1,33 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +//default 0 +public enum Baudrate implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + B_19200(0, "19200"), // + B_9600(1, "9600"); // + + private final int value; + private final String name; + + private Baudrate(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BlackStartMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BlackStartMode.java new file mode 100644 index 00000000000..1abb25b25b2 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BlackStartMode.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum BlackStartMode implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + NORMAL_STARTUP(0, "Normal Start Up"), // + BLACK_STARTUP(1, "Black Start Up");// + + private final int value; + private final String name; + + private BlackStartMode(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BmsProtocolSelection.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BmsProtocolSelection.java new file mode 100644 index 00000000000..ca7794a37ff --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BmsProtocolSelection.java @@ -0,0 +1,34 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum BmsProtocolSelection implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + ENERGY_PORT(0, "EP"), // + ALPHA(1, "Alpha-Ess"), // + PYLONTECH(2, "Pylontech"), // + BMSER(3, "Bmser"); // + + private final int value; + private final String name; + + private BmsProtocolSelection(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CountryCode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CountryCode.java new file mode 100644 index 00000000000..9c20f47ece2 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CountryCode.java @@ -0,0 +1,18 @@ +package io.openems.edge.deye.batteryinverter.enums; + +public enum CountryCode { + + GERMANY("Germany"), // + AUSTRIA("Austria"), // + SWITZERLAND("Switzerland"); + + private final String value; + + private CountryCode(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CpuType.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CpuType.java new file mode 100644 index 00000000000..38a5ae32b66 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CpuType.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum CpuType implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + SINGLE_CPU(0, "Single Cpu"), // + DOUBLE_CPU(1, "Double Cpu");// + + private final int value; + private final String name; + + private CpuType(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/DcVoltageLevel.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/DcVoltageLevel.java new file mode 100644 index 00000000000..47cc6fe8809 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/DcVoltageLevel.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum DcVoltageLevel implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + V_750(0, "750 V"), // + V_830(1, "830 V");// + + private final int value; + private final String name; + + private DcVoltageLevel(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/EnableDisable.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/EnableDisable.java new file mode 100644 index 00000000000..6687d51ff7a --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/EnableDisable.java @@ -0,0 +1,17 @@ +package io.openems.edge.deye.batteryinverter.enums; + +public enum EnableDisable { + + ENABLE("Enable"), // + DISABLE("Disable"); + + private final String value; + + private EnableDisable(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Epo.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Epo.java new file mode 100644 index 00000000000..4e041753ab6 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Epo.java @@ -0,0 +1,33 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum Epo implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + INVALID(0, "Modbus"), // + EPO(1, "Sunspec"), // + DRMO(2, "Sunspec");// + + private final int value; + private final String name; + + private Epo(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyLevel.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyLevel.java new file mode 100644 index 00000000000..c76850b1b1a --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyLevel.java @@ -0,0 +1,22 @@ +package io.openems.edge.deye.batteryinverter.enums; + +public enum FrequencyLevel { + HZ_50("50 Hz", 0), // + HZ_60("60 Hz", 1);// + + private final String name; + private final int value; + + private FrequencyLevel(String name, int value) { + this.name = name; + this.value = value; + } + + public String getName() { + return this.name; + } + + public int getValue() { + return this.value; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyVariationRate.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyVariationRate.java new file mode 100644 index 00000000000..bb86a05d727 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyVariationRate.java @@ -0,0 +1,33 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum FrequencyVariationRate implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + DISABLED(0, "Disabled"), // + RATE_0125(1, "Rate limit 0.125 Hz/s"), // + RATE_02(2, "Rate limit 0.2 Hz/s");// + + private final int value; + private final String name; + + private FrequencyVariationRate(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/GridCodeSelection.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/GridCodeSelection.java new file mode 100644 index 00000000000..429deb65b58 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/GridCodeSelection.java @@ -0,0 +1,27 @@ +package io.openems.edge.deye.batteryinverter.enums; + +public enum GridCodeSelection { + SA1741("SA1741", 0), // + VDE("VDE", 1), // + AUSTRALIAN("Australian", 2), // + G99("G99", 3), // + HAWAIIAN("Hawaiian", 4), // + EN50549("EN50549", 5), // + AUSTRIA_TYPEA("Austria Type A", 6);// + + private final String name; + private final int value; + + private GridCodeSelection(String name, int value) { + this.name = name; + this.value = value; + } + + public String getName() { + return this.name; + } + + public int getValue() { + return this.value; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InterfaceType.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InterfaceType.java new file mode 100644 index 00000000000..96d71d9ac4e --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InterfaceType.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum InterfaceType implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + RS_485(0, "RS-485"), // + ETHERNET(1, "Ethernet"); // + + private final int value; + private final String name; + + private InterfaceType(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InverterWiringTopology.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InverterWiringTopology.java new file mode 100644 index 00000000000..3d19ac3e156 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InverterWiringTopology.java @@ -0,0 +1,16 @@ +package io.openems.edge.deye.batteryinverter.enums; + +public enum InverterWiringTopology { + THREE_PHASE_FOUR_WIRE("3P4W"), // + THREE_PHASE_THREE_WIRE("3P3W or 3P3W+N"); // + + private final String value; + + private InverterWiringTopology(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ModulePowerLevel.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ModulePowerLevel.java new file mode 100644 index 00000000000..8df965bcd39 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ModulePowerLevel.java @@ -0,0 +1,34 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum ModulePowerLevel implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + TEN_KW(0, " 10 kW"), // + TWENTY_KW(1, "20 kW"), // + THIRTY_KW(2, "30 kW"), // + TWENTY_NINE_KW(3, "29 kW"); // + + private final int value; + private final String name; + + private ModulePowerLevel(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PhaseAngleAbrupt.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PhaseAngleAbrupt.java new file mode 100644 index 00000000000..b1160a7cad8 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PhaseAngleAbrupt.java @@ -0,0 +1,33 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum PhaseAngleAbrupt implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + DISABLED(0, "Disabled"), // + ANGLE_ABRUPT_LIMIT_12_DEGREE(1, "Angle abrupt limit 12 deg"), // + ANGLE_ABRUPT_LIMIT_6_DEGREE(2, "Angle abrupt limit 6 deg"); // + + private final int value; + private final String name; + + private PhaseAngleAbrupt(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PowerRisingMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PowerRisingMode.java new file mode 100644 index 00000000000..f0fba7ebd3d --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PowerRisingMode.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum PowerRisingMode implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + STEP(0, "Step Function"), // + RAMP(1, "Ramp Function");// + + private final int value; + private final String name; + + private PowerRisingMode(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ProtocolSelection.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ProtocolSelection.java new file mode 100644 index 00000000000..f527df7f2e8 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ProtocolSelection.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum ProtocolSelection implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + MODBUS(0, "Modbus"), // + SUNSPEC(1, "Sunspec"); // + + private final int value; + private final String name; + + private ProtocolSelection(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ReactivePowerControlMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ReactivePowerControlMode.java new file mode 100644 index 00000000000..e0a44553e4b --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ReactivePowerControlMode.java @@ -0,0 +1,34 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum ReactivePowerControlMode implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + CONSTANT_REACTIVE_POWER(0, "Constant Reactive Power"), // + VOLT_VAR_ENABLED(1, "Volt Var Enabled"), // + CONSTANT_PF(2, "Constanr Power Factor"), // + WATT_PF_ENABLED(3, "Watt Power Factor Enabled"); // + + private final int value; + private final String name; + + private ReactivePowerControlMode(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelGridMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelGridMode.java new file mode 100644 index 00000000000..a4a720775f2 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelGridMode.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum SinexcelGridMode implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + ON_GRID(0, "On Grid"), // + OFF_GRID(1, "Off Grid"); // + + private final int value; + private final String name; + + private SinexcelGridMode(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelState.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelState.java new file mode 100644 index 00000000000..144cc4f2c15 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelState.java @@ -0,0 +1,40 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum SinexcelState implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + OFF(1, "Off"), // + SLEEPING(2, "Sleeping"), // + STARTING(3, "Starting"), // + MPPT(4, "MPPT"), // + THROTTLED(5, "Throttled"), // + SHUTTINGDOWN(6, "Shutting Down"), // + FAULT(7, "Fault"), // + STANDBY(8, "Standby"), // + STARTED(9, "Started"); + + private final int value; + private final String option; + + private SinexcelState(int value, String option) { + this.value = value; + this.option = option; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.option; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } + +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinglePhaseMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinglePhaseMode.java new file mode 100644 index 00000000000..30396d97c81 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinglePhaseMode.java @@ -0,0 +1,33 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum SinglePhaseMode implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + DISABLE(0, "Disable"), // + SINGLE_PHASE_230V(1, "Single Phae 230V"), // + SINGLE_PHASE_480V(2, "Single Phase 480V");// + + private final int value; + private final String name; + + private SinglePhaseMode(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/StartMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/StartMode.java new file mode 100644 index 00000000000..b2d985d7cd5 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/StartMode.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum StartMode implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + MANUAL(0, "Manual Start"), // + AUTO(1, "Auto Start"); // + + private final int value; + private final String name; + + private StartMode(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Switch.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Switch.java new file mode 100644 index 00000000000..aedd0fa157c --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Switch.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum Switch implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + NO_SWITCH(0, "No Switch"), // + SWITCH(1, "Switch");// + + private final int value; + private final String name; + + private Switch(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/VoltageLevel.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/VoltageLevel.java new file mode 100644 index 00000000000..3a04e4106c8 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/VoltageLevel.java @@ -0,0 +1,23 @@ +package io.openems.edge.deye.batteryinverter.enums; + +public enum VoltageLevel { + V_380("380 V", 0), // + V_400("400 V", 1), // + V_480("480 V", 2); // + + private final String name; + private final int value; + + private VoltageLevel(String name, int value) { + this.name = name; + this.value = value; + } + + public String getName() { + return this.name; + } + + public int getValue() { + return this.value; + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/Context.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/Context.java new file mode 100644 index 00000000000..1e0e20c445b --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/Context.java @@ -0,0 +1,24 @@ +package io.openems.edge.deye.batteryinverter.statemachine; + +import io.openems.edge.batteryinverter.api.OffGridBatteryInverter; +import io.openems.edge.deye.batteryinverter.BatteryInverterDeyeImpl; +import io.openems.edge.deye.batteryinverter.Config; +import io.openems.edge.common.statemachine.AbstractContext; + +public class Context extends AbstractContext { + + protected final Config config; + protected final OffGridBatteryInverter.TargetGridMode targetGridMode; + protected final int setActivePower; + protected final int setReactivePower; + + public Context(BatteryInverterDeyeImpl parent, Config config, OffGridBatteryInverter.TargetGridMode targetGridMode, int setActivePower, + int setReactivePower) { + super(parent); + this.config = config; + this.targetGridMode = targetGridMode; + this.setActivePower = setActivePower; + this.setReactivePower = setReactivePower; + } + +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/ErrorHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/ErrorHandler.java new file mode 100644 index 00000000000..af24355c131 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/ErrorHandler.java @@ -0,0 +1,46 @@ +package io.openems.edge.deye.batteryinverter.statemachine; + +import java.time.Duration; +import java.time.Instant; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.edge.deye.batteryinverter.BatteryInverterDeye; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; +import io.openems.edge.common.channel.BooleanWriteChannel; +import io.openems.edge.common.statemachine.StateHandler; + +public class ErrorHandler extends StateHandler { + + private static final int WAIT_SECONDS = 120; + + private Instant entryAt = Instant.MIN; + + @Override + protected void onEntry(Context context) throws OpenemsNamedException { + this.entryAt = Instant.now(); + + // Clear Failures + this.setClearFailureCommand(context); + + // Try to stop systems + final var inverter = context.getParent(); + inverter.setStopInverter(); + } + + @Override + public State runAndGetNextState(Context context) throws OpenemsNamedException { + if (Duration.between(this.entryAt, Instant.now()).getSeconds() > WAIT_SECONDS) { + // Try again + return State.UNDEFINED; + } + + // Wait + return State.ERROR; + } + + private void setClearFailureCommand(Context context) throws OpenemsNamedException { + BooleanWriteChannel setClearFailureCmd = context.getParent() + .channel(BatteryInverterDeye.ChannelId.CLEAR_FAILURE); + setClearFailureCmd.setNextWriteValue(true); // 1: true, other: illegal + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoRunningHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoRunningHandler.java new file mode 100644 index 00000000000..34dd6333aed --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoRunningHandler.java @@ -0,0 +1,43 @@ +package io.openems.edge.deye.batteryinverter.statemachine; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; +import io.openems.edge.common.statemachine.StateHandler; + +public class GoRunningHandler extends StateHandler { + + @Override + public State runAndGetNextState(Context context) throws OpenemsNamedException { + final var inverter = context.getParent(); + + /* + * Be sure to set the correct target grid mode + */ + var setOnGridMode = inverter.getSetOnGridMode().get(); + var setOffGridMode = inverter.getSetOffGridMode().get(); + switch (context.targetGridMode) { + case GO_ON_GRID: + if (setOnGridMode == Boolean.FALSE || setOffGridMode == Boolean.TRUE) { + inverter.setOnGridMode(true); + return State.GO_RUNNING; + } + break; + case GO_OFF_GRID: + if (setOnGridMode == Boolean.TRUE || setOffGridMode == Boolean.FALSE) { + inverter.setOffGridMode(true); + return State.GO_RUNNING; + } + break; + } + + inverter.setStartInverter(); + + if (inverter.getInverterState().get() == Boolean.TRUE) { + // Inverter is ON + return State.RUNNING; + } + // Still waiting + return State.GO_RUNNING; + } + +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoStoppedHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoStoppedHandler.java new file mode 100644 index 00000000000..f570503c526 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoStoppedHandler.java @@ -0,0 +1,23 @@ +package io.openems.edge.deye.batteryinverter.statemachine; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; +import io.openems.edge.common.statemachine.StateHandler; + +public class GoStoppedHandler extends StateHandler { + + @Override + public State runAndGetNextState(Context context) throws OpenemsNamedException { + final var inverter = context.getParent(); + + inverter.setStopInverter(); + + if (inverter.getInverterState().get() == Boolean.FALSE) { + // Inverter is OFF + return State.STOPPED; + } + // Still waiting + return State.GO_STOPPED; + } + +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/RunningHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/RunningHandler.java new file mode 100644 index 00000000000..727206eaa19 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/RunningHandler.java @@ -0,0 +1,44 @@ +package io.openems.edge.deye.batteryinverter.statemachine; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.edge.deye.batteryinverter.BatteryInverterDeye; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; +import io.openems.edge.common.channel.IntegerWriteChannel; +import io.openems.edge.common.startstop.StartStop; +import io.openems.edge.common.statemachine.StateHandler; + +public class RunningHandler extends StateHandler { + + @Override + public State runAndGetNextState(Context context) throws OpenemsNamedException { + final var inverter = context.getParent(); + + if (inverter.hasFaults() || inverter.getInverterState().get() == Boolean.FALSE) { + return State.UNDEFINED; + } + + // Mark as started + inverter._setStartStop(StartStop.START); + + // Apply Active and Reactive Power Set-Points + this.applyPower(context); + + return State.RUNNING; + } + + /** + * Applies the Active and Reactive Power Set-Points. + * + * @param context the {@link Context} + * @throws OpenemsNamedException on error + */ + private void applyPower(Context context) throws OpenemsNamedException { + final var inverter = context.getParent(); + + IntegerWriteChannel setActivePower = inverter.channel(BatteryInverterDeye.ChannelId.SET_ACTIVE_POWER); + setActivePower.setNextWriteValue(context.setActivePower); + + IntegerWriteChannel setReactivePower = inverter.channel(BatteryInverterDeye.ChannelId.SET_REACTIVE_POWER); + setReactivePower.setNextWriteValue(context.setReactivePower); + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StateMachine.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StateMachine.java new file mode 100644 index 00000000000..815f79ab5a1 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StateMachine.java @@ -0,0 +1,70 @@ +package io.openems.edge.deye.batteryinverter.statemachine; + +import io.openems.common.types.OptionsEnum; +import io.openems.edge.common.statemachine.AbstractStateMachine; +import io.openems.edge.common.statemachine.StateHandler; + +public class StateMachine extends AbstractStateMachine { + + public enum State implements io.openems.edge.common.statemachine.State, OptionsEnum { + UNDEFINED(-1), // + + GO_RUNNING(10), // + RUNNING(11), // + + GO_STOPPED(20), // + STOPPED(21), // + + ERROR(30) // + ; + + private final int value; + + private State(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name(); + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } + + @Override + public State[] getStates() { + return State.values(); + } + } + + public StateMachine(State initialState) { + super(initialState); + } + + @Override + public StateHandler getStateHandler(State state) { + switch (state) { + case UNDEFINED: + return new UndefinedHandler(); + case GO_RUNNING: + return new GoRunningHandler(); + case RUNNING: + return new RunningHandler(); + case GO_STOPPED: + return new GoStoppedHandler(); + case STOPPED: + return new StoppedHandler(); + case ERROR: + return new ErrorHandler(); + } + throw new IllegalArgumentException("Unknown State [" + state + "]"); + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StoppedHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StoppedHandler.java new file mode 100644 index 00000000000..fdda56d3728 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StoppedHandler.java @@ -0,0 +1,19 @@ +package io.openems.edge.deye.batteryinverter.statemachine; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; +import io.openems.edge.common.startstop.StartStop; +import io.openems.edge.common.statemachine.StateHandler; + +public class StoppedHandler extends StateHandler { + + @Override + public State runAndGetNextState(Context context) throws OpenemsNamedException { + final var inverter = context.getParent(); + + // Mark as stopped + inverter._setStartStop(StartStop.STOP); + return State.STOPPED; + } + +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/UndefinedHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/UndefinedHandler.java new file mode 100644 index 00000000000..c932a3d993d --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/UndefinedHandler.java @@ -0,0 +1,36 @@ +package io.openems.edge.deye.batteryinverter.statemachine; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; +import io.openems.edge.common.statemachine.StateHandler; + +public class UndefinedHandler extends StateHandler { + + @Override + public State runAndGetNextState(Context context) throws OpenemsNamedException { + final var inverter = context.getParent(); + switch (inverter.getStartStopTarget()) { + case UNDEFINED: + // Stuck in UNDEFINED State + return State.UNDEFINED; + + case START: + // force START + if (inverter.hasFaults()) { + // Has Faults -> error handling + return State.ERROR; + } else { + // No Faults -> start + return State.GO_RUNNING; + } + + case STOP: + // force STOP + return State.GO_STOPPED; + } + + assert false; + return State.UNDEFINED; // can never happen + } + +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java new file mode 100644 index 00000000000..72c338749fe --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java @@ -0,0 +1,35 @@ +package io.openems.edge.deye.gridmeter; + +import org.osgi.service.metatype.annotations.AttributeDefinition; +import org.osgi.service.metatype.annotations.ObjectClassDefinition; + +import io.openems.edge.meter.api.MeterType; + +@ObjectClassDefinition(name = "Meter Deye", // + description = "Implements the Deye Meter.") +@interface Config { + + @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") + String id() default "meter0"; + + @AttributeDefinition(name = "Alias", description = "Human-readable name of this Component; defaults to Component-ID") + String alias() default ""; + + @AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?") + boolean enabled() default true; + + @AttributeDefinition(name = "Meter-Type", description = "What is measured by this Meter?") + MeterType type() default MeterType.GRID; + + @AttributeDefinition(name = "Modbus-ID", description = "ID of Modbus bridge.") + String modbus_id() default "modbus0"; + + @AttributeDefinition(name = "Modbus Unit-ID", description = "The Unit-ID of the Modbus device. ") + int modbusUnitId() default 1; + + @AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID'.") + String Modbus_target() default "(enabled=true)"; + + String webconsole_configurationFactory_nameHint() default "Meter Deye [{id}]"; + +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeter.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeter.java new file mode 100644 index 00000000000..5b517293aec --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeter.java @@ -0,0 +1,23 @@ +package io.openems.edge.deye.gridmeter; + +import io.openems.edge.bridge.modbus.api.ModbusComponent; +import io.openems.edge.common.channel.Doc; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.meter.api.ElectricityMeter; + +public interface DeyeGridMeter extends ElectricityMeter, ModbusComponent, OpenemsComponent { + + public enum ChannelId implements io.openems.edge.common.channel.ChannelId { + ; + private final Doc doc; + + private ChannelId(Doc doc) { + this.doc = doc; + } + + @Override + public Doc doc() { + return this.doc; + } + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java new file mode 100644 index 00000000000..77ace515c27 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java @@ -0,0 +1,105 @@ +package io.openems.edge.deye.gridmeter; + +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.ConfigurationPolicy; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; +import org.osgi.service.component.annotations.ReferencePolicyOption; +import org.osgi.service.event.propertytypes.EventTopics; +import org.osgi.service.metatype.annotations.Designate; + +import io.openems.common.exceptions.OpenemsException; +import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; +import io.openems.edge.bridge.modbus.api.BridgeModbus; +import io.openems.edge.bridge.modbus.api.ModbusComponent; +import io.openems.edge.bridge.modbus.api.ModbusProtocol; +import io.openems.edge.bridge.modbus.api.element.SignedWordElement; +import io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.common.event.EdgeEventConstants; +import io.openems.edge.common.taskmanager.Priority; +import io.openems.edge.deye.batteryinverter.BatteryInverterDeye; +import io.openems.edge.meter.api.ElectricityMeter; +import io.openems.edge.meter.api.MeterType; + +@Designate(ocd = Config.class, factory = true) +@Component(// + name = "Deye.Grid-Meter", // + immediate = true, // + configurationPolicy = ConfigurationPolicy.REQUIRE, // + property = { // + "type=GRID" // + }) +@EventTopics({ // + EdgeEventConstants.TOPIC_CYCLE_EXECUTE_WRITE // +}) +public class DeyeGridMeterImpl extends AbstractOpenemsModbusComponent + implements DeyeGridMeter, ElectricityMeter, ModbusComponent, OpenemsComponent { + + @Reference + private ConfigurationAdmin cm; + + @Override + @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) + protected void setModbus(BridgeModbus modbus) { + super.setModbus(modbus); + } + + private Config config; + + public DeyeGridMeterImpl() throws OpenemsException { + super(// + OpenemsComponent.ChannelId.values(), // + ModbusComponent.ChannelId.values(), // + ElectricityMeter.ChannelId.values(), // + DeyeGridMeter.ChannelId.values() // + ); + + ElectricityMeter.calculateSumActivePowerFromPhases(this); + } + + @Activate + private void activate(ComponentContext context, Config config) throws OpenemsException { + if (super.activate(context, config.id(), config.alias(), config.enabled(), config.modbusUnitId(), this.cm, + "Modbus", config.modbus_id())) { + return; + } + this.config = config; + } + + @Override + @Deactivate + protected void deactivate() { + super.deactivate(); + } + + @Override + public MeterType getMeterType() { + return this.config.type(); + } + + @Override + public void retryModbusCommunication() { + + } + + @Override + protected ModbusProtocol defineModbusProtocol() throws OpenemsException { + return new ModbusProtocol(this, + new FC3ReadRegistersTask(633, Priority.HIGH, + m(ElectricityMeter.ChannelId.ACTIVE_POWER_L1, new SignedWordElement(633)), + m(BatteryInverterDeye.ChannelId.ACTIVE_POWER_L2, new SignedWordElement(634)), + m(BatteryInverterDeye.ChannelId.ACTIVE_POWER_L3, new SignedWordElement(635)))); + } + + @Override + public String debugLog() { + return "GRID OUIDA L:" + this.getActivePower().asString(); + } + +} diff --git a/io.openems.edge.batteryinverter.deye/test/test/.gitignore b/io.openems.edge.batteryinverter.deye/test/test/.gitignore new file mode 100644 index 00000000000..e69de29bb2d From 10610e8b05ba88ec76c2de7ad0ee2b33437a80ee Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Thu, 15 Feb 2024 07:09:22 +0100 Subject: [PATCH 02/25] Start implement DEYE battery inverter --- .../readme.adoc | 8 +- .../batteryinverter/BatteryInverterDeye.java | 949 ------------------ .../BatteryInverterDeyeImpl.java | 407 -------- .../edge/deye/batteryinverter/Config.java | 41 - .../enums/ActivePowerControlMode.java | 34 - .../deye/batteryinverter/enums/Baudrate.java | 33 - .../batteryinverter/enums/BlackStartMode.java | 32 - .../enums/BmsProtocolSelection.java | 34 - .../batteryinverter/enums/CountryCode.java | 18 - .../deye/batteryinverter/enums/CpuType.java | 32 - .../batteryinverter/enums/DcVoltageLevel.java | 32 - .../batteryinverter/enums/EnableDisable.java | 17 - .../edge/deye/batteryinverter/enums/Epo.java | 33 - .../batteryinverter/enums/FrequencyLevel.java | 22 - .../enums/FrequencyVariationRate.java | 33 - .../enums/GridCodeSelection.java | 27 - .../batteryinverter/enums/InterfaceType.java | 32 - .../enums/InverterWiringTopology.java | 16 - .../enums/ModulePowerLevel.java | 34 - .../enums/PhaseAngleAbrupt.java | 33 - .../enums/PowerRisingMode.java | 32 - .../enums/ProtocolSelection.java | 32 - .../enums/ReactivePowerControlMode.java | 34 - .../enums/SinexcelGridMode.java | 32 - .../batteryinverter/enums/SinexcelState.java | 40 - .../enums/SinglePhaseMode.java | 33 - .../deye/batteryinverter/enums/StartMode.java | 32 - .../deye/batteryinverter/enums/Switch.java | 32 - .../batteryinverter/enums/VoltageLevel.java | 23 - .../batteryinverter/statemachine/Context.java | 24 - .../statemachine/ErrorHandler.java | 46 - .../statemachine/GoRunningHandler.java | 43 - .../statemachine/GoStoppedHandler.java | 23 - .../statemachine/RunningHandler.java | 44 - .../statemachine/StateMachine.java | 70 -- .../statemachine/StoppedHandler.java | 19 - .../statemachine/UndefinedHandler.java | 36 - .../openems/edge/deye/gridmeter/Config.java | 7 +- .../deye/gridmeter/DeyeGridMeterImpl.java | 35 +- .../io/openems/edge/deye/meter/Config.java | 31 + .../io/openems/edge/deye/meter/DeyeMeter.java | 23 + .../edge/deye/meter/DeyeMeterImpl.java | 100 ++ 42 files changed, 174 insertions(+), 2484 deletions(-) delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeye.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeyeImpl.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/Config.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ActivePowerControlMode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Baudrate.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BlackStartMode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BmsProtocolSelection.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CountryCode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CpuType.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/DcVoltageLevel.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/EnableDisable.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Epo.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyLevel.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyVariationRate.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/GridCodeSelection.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InterfaceType.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InverterWiringTopology.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ModulePowerLevel.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PhaseAngleAbrupt.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PowerRisingMode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ProtocolSelection.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ReactivePowerControlMode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelGridMode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelState.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinglePhaseMode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/StartMode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Switch.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/VoltageLevel.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/Context.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/ErrorHandler.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoRunningHandler.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoStoppedHandler.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/RunningHandler.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StateMachine.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StoppedHandler.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/UndefinedHandler.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/Config.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/DeyeMeter.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/DeyeMeterImpl.java diff --git a/io.openems.edge.batteryinverter.deye/readme.adoc b/io.openems.edge.batteryinverter.deye/readme.adoc index 26abba966f4..46ceaa16a92 100644 --- a/io.openems.edge.batteryinverter.deye/readme.adoc +++ b/io.openems.edge.batteryinverter.deye/readme.adoc @@ -1,7 +1 @@ -= Sinexcel Battery Inverter - -Implemented Natures:: -- SymmetricEss -- ManagedSymmetricEss - -https://github.com/OpenEMS/openems/tree/develop/io.openems.edge.ess.sinexcel[Source Code icon:github[]] \ No newline at end of file += Deye Battery Inverter diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeye.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeye.java deleted file mode 100644 index dc188d6ab82..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeye.java +++ /dev/null @@ -1,949 +0,0 @@ -package io.openems.edge.deye.batteryinverter; - -import io.openems.common.channel.AccessMode; -import io.openems.common.channel.Debounce; -import io.openems.common.channel.Level; -import io.openems.common.channel.PersistencePriority; -import io.openems.common.channel.Unit; -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.common.types.OpenemsType; -import io.openems.edge.batteryinverter.api.ManagedSymmetricBatteryInverter; -import io.openems.edge.batteryinverter.api.OffGridBatteryInverter; -import io.openems.edge.batteryinverter.api.SymmetricBatteryInverter; -import io.openems.edge.common.channel.BooleanDoc; -import io.openems.edge.common.channel.BooleanWriteChannel; -import io.openems.edge.common.channel.Doc; -import io.openems.edge.common.channel.IntegerDoc; -import io.openems.edge.common.channel.IntegerReadChannel; -import io.openems.edge.common.channel.value.Value; -import io.openems.edge.common.component.OpenemsComponent; -import io.openems.edge.common.modbusslave.ModbusSlave; -import io.openems.edge.common.startstop.StartStoppable; -import io.openems.edge.common.sum.GridMode; -import io.openems.edge.deye.batteryinverter.enums.ActivePowerControlMode; -import io.openems.edge.deye.batteryinverter.enums.Baudrate; -import io.openems.edge.deye.batteryinverter.enums.BlackStartMode; -import io.openems.edge.deye.batteryinverter.enums.CpuType; -import io.openems.edge.deye.batteryinverter.enums.DcVoltageLevel; -import io.openems.edge.deye.batteryinverter.enums.Epo; -import io.openems.edge.deye.batteryinverter.enums.FrequencyVariationRate; -import io.openems.edge.deye.batteryinverter.enums.InterfaceType; -import io.openems.edge.deye.batteryinverter.enums.ModulePowerLevel; -import io.openems.edge.deye.batteryinverter.enums.PhaseAngleAbrupt; -import io.openems.edge.deye.batteryinverter.enums.PowerRisingMode; -import io.openems.edge.deye.batteryinverter.enums.ProtocolSelection; -import io.openems.edge.deye.batteryinverter.enums.ReactivePowerControlMode; -import io.openems.edge.deye.batteryinverter.enums.SinexcelGridMode; -import io.openems.edge.deye.batteryinverter.enums.SinglePhaseMode; -import io.openems.edge.deye.batteryinverter.enums.StartMode; -import io.openems.edge.deye.batteryinverter.enums.Switch; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; - -public interface BatteryInverterDeye extends OffGridBatteryInverter, ManagedSymmetricBatteryInverter, SymmetricBatteryInverter, OpenemsComponent, StartStoppable, ModbusSlave { - - public enum ChannelId implements io.openems.edge.common.channel.ChannelId { - STATE_MACHINE(Doc.of(State.values()) // - .text("Current State of State-Machine")), // - RUN_FAILED(Doc.of(Level.FAULT) // - .text("Running the Logic failed")), // - SET_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)// - .unit(Unit.WATT)), // - SET_REACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)// - .unit(Unit.VOLT_AMPERE_REACTIVE)), // - CHARGE_MAX_CURRENT(new IntegerDoc() // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.AMPERE)), // - DISCHARGE_MAX_CURRENT(new IntegerDoc() // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.AMPERE)), // - CHARGE_MAX_CURRENT_READ(new IntegerDoc() // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.AMPERE)), // - DISCHARGE_MAX_CURRENT_READ(new IntegerDoc() // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.AMPERE)), // - CHARGE_MAX_VOLTAGE(new IntegerDoc() // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.VOLT)), // - DISCHARGE_MIN_VOLTAGE(new IntegerDoc() // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.VOLT)), // - - ACTIVE_DISCHARGE_ENERGY_VALUE_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), - ACTIVE_DISCHARGE_ENERGY_VALUE_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), - ACTIVE_CHARGE_ENERGY_VALUE_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), - ACTIVE_CHARGE_ENERGY_VALUE_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), - - // when implementing Lithium-ion batteries, these two registers MUST be set to - // the same - TOPPING_CHARGE_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.VOLT)), - // when implementing Lithium-ion batteries, these two registers MUST be set to - // the same - FLOAT_CHARGE_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.VOLT)), // - - MANUFACTURER_AND_MODEL_NUMBER(Doc.of(OpenemsType.STRING) // - .accessMode(AccessMode.READ_ONLY)), // - SERIAL_NUMBER(Doc.of(OpenemsType.STRING) // - .persistencePriority(PersistencePriority.HIGH) // - .accessMode(AccessMode.READ_ONLY)), // - FAULT_STATUS(Doc.of(Level.FAULT) // - .accessMode(AccessMode.READ_ONLY)), // - ALERT_STATUS(Doc.of(Level.WARNING) // - .accessMode(AccessMode.READ_ONLY)), // - BATTERY_INVERTER_STATE(new BooleanDoc() // - .debounce(5, Debounce.FALSE_VALUES_IN_A_ROW_TO_SET_FALSE) // - .onChannelChange((self, value) -> self._setInverterState(value.get()))), - - INVERTER_GRID_MODE(new BooleanDoc() // - .debounce(5, Debounce.FALSE_VALUES_IN_A_ROW_TO_SET_FALSE) // - .text("On Grid") // - .onChannelChange((self, value) -> { - final GridMode gridMode; - if (!value.isDefined()) { - gridMode = GridMode.UNDEFINED; - } else if (value.get()) { - gridMode = GridMode.ON_GRID; - } else { - gridMode = GridMode.OFF_GRID; - } - self._setGridMode(gridMode); - })), - - ISLAND_MODE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DERATING_STATUS(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - ALLOW_GRID_CONNECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - STANDBY_STATUS(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - OBTAIN_FAULT_RECORD_FLAG(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - WRITE_POWER_GENERATION_INTO_EEPROM(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - INITIALIZE_DSP_PARAMETERS(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - MASTER_SLAVE_MODE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AC_OVER_VOLTAGE_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AC_UNDER_VOLTAGE_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AC_OVER_FREQUENCY_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AC_UNDER_FREQUENCY_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - GRID_VOLTAGE_UNBALANCE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - GRID_PHASE_REVERSE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - INVERTER_ISLAND(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - ON_GRID_OFF_GRID_SWITCH_OVER_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - OUTPUT_GROUND_FAULT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - GRID_PHASE_LOCK_FAILED(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - INTERNAL_AIR_OVER_TEMPERATURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - GRID_CONNECTED_CONDITION_TIME_OUT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - MODULE_RENUMBER_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - // Monitor parallel use - CANB_COMMUNICATION_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - POWER_FREQUENCY_SYNCHRONIZATION_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - CARRIER_SYNCHRONIZATION_FALURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - EPO_ERROR(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - MONITOR_PARAMETER_MISMATCH(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DSP_VERSION_ABNORMAL(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - CPLD_VERSION_ERROR(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - HARDWARE_VERSION_ERROR(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - // Monitor to DSP - CANA_COMMUNICATION_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AUXILARY_POWER_FAULT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - FAN_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_OVER_VOLTAGE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_LOW_VOLTAGE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_VOLTAGE_UNBALANCED(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AC_RELAY_SHORT_CIRCUIT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - OUTPUT_VOLTAGE_ABNORMAL(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - OUTPUT_CURRENT_UNBALANCED(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - OVER_TEMPERATURE_OF_HEAT_SINK(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - OUTPUT_OVER_LOAD_TOT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - GRID_CONTINUE_OVER_VOLTAGE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AC_SOFT_START_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - INVERTER_START_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AC_RELAY_IS_OPEN(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - U2_BOARD_COMMUNICATION_IS_ABNORMAL(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AC_DC_COMPONENT_EXCESS(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - MASTER_SLAVE_SAMPLING_ABNORMALITY(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - PARAMETER_SETTING_ERROR(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - LOW_OFF_GRID_ENERGY(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - N_LINE_IS_NOT_CONNECTED(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - STANDBY_BUS_HEIGHT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - SINGLE_PHASE_WIRING_ERROR(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - EXCESSIVE_GRID_FREQUENCY_CHANGE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - ABRUPT_PHASE_ANGLE_FAULT_OF_POWER_GRID(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - GRID_CONNECTION_PARAMETER_CONFLICT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - EE_READING_ERROR_1(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - EE_READING_ERROR_2(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - FLASH_READING_ERROR(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - INVERTER_OVER_LOAD(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - BATTERY_PARAMETER_SETTING_ERROR(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - SLAVE_LOST_ALARM(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_CHARGING(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_DISCHARGING(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - BATTERY_FULLY_CHARGED(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - BATTERY_EMPTY(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_FAULT_STATUS(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_ALERT_STATUS(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_INPUT_OVER_VOLTAGE_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_INPUT_UNDER_VOLTAGE_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - BMS_ALERT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - BMS_COMMUNICATION_TIMEOUT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - EMS_COMMUNICATION_TIMEOUT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_SOFT_START_FAILED(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_RELAY_SHORT_CIRCUIT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_RELAY_SHORT_OPEN(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - BATTERY_POWEROVER_LOAD(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - BATTERY_POWER_OVER_LOAD(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_BUS_STARTING_FAILED(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_QUICK_CHECK_OVER_CURRENT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_OC(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - // AC L1-L2 RMS voltage - GRID_VOLTAGE_L1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIVOLT)), // - // AC L2-L3 RMS voltage - GRID_VOLTAGE_L2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIVOLT)), // - // AC L3-L1 RMS voltage - GRID_VOLTAGE_L3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIVOLT)), // - // AC L1 RMS current - GRID_CURRENT_L1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIAMPERE)), // - // AC L2 RMS current - GRID_CURRENT_L2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIAMPERE)), // - // AC L3 RMS current - GRID_CURRENT_L3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIAMPERE)), // - // AC frequency - FREQUENCY(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIHERTZ)), // - // AC L1 Active Power - ACTIVE_POWER_L1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.WATT)), // - // AC L2 Active Power - ACTIVE_POWER_L2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.WATT)), // - // AC L3 Active Power - ACTIVE_POWER_L3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.WATT)), // - // AC L1 Reactive Power - REACTIVE_POWER_L1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.VOLT_AMPERE_REACTIVE)), // - // AC L2 Reactive Power - REACTIVE_POWER_L2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.VOLT_AMPERE_REACTIVE)), // - // AC L3 Reactive Power - REACTIVE_POWER_L3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.VOLT_AMPERE_REACTIVE)), // - // AC L1 Apparent Power - APPERENT_POWER_L1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.VOLT_AMPERE)), // - // AC L2 Apparent Power - APPERENT_POWER_L2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.VOLT_AMPERE)), // - // AC L3 Apparent Power - APPERENT_POWER_L3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.VOLT_AMPERE)), // - // AC L1 Power Factor - COS_PHI_L1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_ONLY)), // - // AC L2 Power Factor - COS_PHI_L2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_ONLY)), // - // AC L3 Power Factor - COS_PHI_L3(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_ONLY)), // - // AC Apperent Power - APPARENT_POWER(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.VOLT_AMPERE)), // - // AC Power Factor - COS_PHI(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_ONLY)), // - - // Temperature of DC heat sink - TEMPERATURE_OF_AC_HEAT_SINK(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.DEGREE_CELSIUS)), // - // BUS+ side voltage - DC_VOLTAGE_POSITIVE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIVOLT)), // - // BUS- side voltage - DC_VOLTAGE_NEGATIVE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIVOLT)), // - // Target off-grid voltage bias - SET_OFF_GRID_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)// - .unit(Unit.MILLIVOLT)), // - // Target off-grid frequency bias - SET_OFF_GRID_FREQUENCY(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)// - .unit(Unit.MILLIHERTZ)), // - DC_POWER(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.WATT)), // - DC_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIVOLT)), // - DC_CURRENT(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIAMPERE)), // - DC_CHARGE_ENERGY(Doc.of(OpenemsType.LONG) // - .accessMode(AccessMode.READ_WRITE)// - .unit(Unit.CUMULATED_WATT_HOURS)), // - DC_DISCHARGE_ENERGY(Doc.of(OpenemsType.LONG) // - .accessMode(AccessMode.READ_WRITE)// - .unit(Unit.CUMULATED_WATT_HOURS)), // - TEMPERATURE_OF_DC_DC_HEAT_SINK(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.DEGREE_CELSIUS)), // - DC_RELAY_REAR_END_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.VOLT)), // - CHARGE_MAX_CURRENT_SETTING(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIAMPERE)), // - DISCHARGE_MAX_CURRENT_SETTING(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIAMPERE)), // - IP_ADDRESS_BLOCK_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - IP_ADDRESS_BLOCK_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - IP_ADDRESS_BLOCK_3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - IP_ADDRESS_BLOCK_4(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - NETMASK_BLOCK_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - NETMASK_BLOCK_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - NETMASK_BLOCK_3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - NETMASK_BLOCK_4(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - GATEWAY_IP_BLOCK_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - GATEWAY_IP_BLOCK_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - GATEWAY_IP_BLOCK_3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - GATEWAY_IP_BLOCK_4(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - MAC(Doc.of(OpenemsType.STRING) // - .accessMode(AccessMode.READ_WRITE)), // - MODBUS_UNIT_ID(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - BAUDRATE(Doc.of(Baudrate.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // default 1 - INTERFACE_TYPE(Doc.of(InterfaceType.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // Takes effect after hard reset,0-modbus - COMMUNICATION_PROTOCOL_SELECTION(Doc.of(ProtocolSelection.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // Prevent unexpected results of communication failures.when EMS timeout - // enabled, watchdog will work and even reading will feed the watchdog - EMS_TIMEOUT(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // Enable ONLY when remote Emergency Stop Button is needed - EPO_ENABLE(Doc.of(Epo.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // Enable ONLY when remote BMS-inverter connection is needed - BMS_TIMEOUT(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // Takes effect after hard reset,0-modbus - BMS_PROTOCOL_SELECTION(Doc.of(ProtocolSelection.values()) // - .accessMode(AccessMode.READ_WRITE)), // - SET_GRID_MODE(Doc.of(SinexcelGridMode.values()) // - .accessMode(AccessMode.READ_WRITE)), // - BUZZER_ENABLE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - RESTORE_FACTORY_SETTING(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // To Start operation, only 1 will be accepted. Reading back value makes no - // sense - START_INVERTER(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // To Stop operation, only 1 will be accepted. Reading back value makes no sense - STOP_INVERTER(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // clear failure flag,when fault occurs, the system will stop and indicates - // fault.starting is invalid until the fault source is actually removed and this - // register is written 1. Reading back value makes no sense - CLEAR_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.WRITE_ONLY)), // - // set the module to on grid mode. Reading back value makes no sense - SET_ON_GRID_MODE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // set the module to off grid mode. Reading back value makes no sense - SET_OFF_GRID_MODE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // set the module to standby mode,setpoint 0:IGBT switching ,setpoint 1:no IGBT - // switching,low consumption.let the inverter to halt the IGBT switching, to - // save the power consumption, but all relays are still closed. - // Reading back value makes no sense - SET_STANDBY_COMMAND(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - SET_SOFT_START(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - RESET_INSTRUCTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - GRID_STOP(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - VOLTAGE_LEVEL(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - FREQUENCY_LEVEL(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - INVERTER_WIRING_TOPOLOGY(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - SWITCHING_DEVICE_ACCESS_SETTING(Doc.of(Switch.values()) // - .accessMode(AccessMode.READ_WRITE)), // - MODULE_POWER_LEVEL(Doc.of(ModulePowerLevel.values()) // - .accessMode(AccessMode.READ_ONLY)), // - DC_VOLTAGE_LEVEL(Doc.of(DcVoltageLevel.values()) // - .accessMode(AccessMode.READ_ONLY)), // - CPU_TYPE(Doc.of(CpuType.values()) // - .accessMode(AccessMode.READ_WRITE)), // - OFF_GRID_AND_PARALLEL_ENABLE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - SET_DC_SOFT_START_EXTERNAL_CONTROL(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - GRID_OVER_VOLTAGE_PROTECTION_AMPLITUDE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_OVER_VOLTAGE_TRIP_TIME_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_OVER_VOLTAGE_TRIP_LEVEL_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_OVER_VOLTAGE_TRIP_TIME_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_VOLTAGE_TRIP_LEVEL_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_VOLTAGE_TRIP_TIME_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_VOLTAGE_TRIP_LEVEL_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_VOLTAGE_TRIP_TIME_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_VOLTAGE_TRIP_LEVEL_3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_VOLTAGE_TRIP_TIME_3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_OVER_FREQUENCY_TRIP_LEVEL_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_OVER_FREQUENCY_TRIP_TIME_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_OVER_FREQUENCY_TRIP_LEVEL_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_OVER_FREQUENCY_TRIP_TIME_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_FREQUENCY_TRIP_LEVEL_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_FREQUENCY_TRIP_TIME_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_FREQUENCY_TRIP_LEVEL_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_FREQUENCY_TRIP_TIME_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - RECONNECT_TIME(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // Anti-islanding is a CPUC RULE 21/HECO RULE14H/IEEE1547-requested function to - // make sure the inverter disconnect from the grid in case of blackout. - // This is to prevent the formation of an unintended island. The inverter design - // shall comply with the requirements of IEEE Std 1547 and UL 1741 standards (or - // latest versions) and be certified to have anti-islanding protection such that - // the synchronous inverter will automatically disconnect upon a utility system - // interruption - ANTI_ISLANDING(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // Frequency and Voltage Ride-Through. - // The ability to withstand voltage or frequency excursions outside defined - // limits without tripping or malfunctioning - FREQUENCY_VOLTAGE_RIDE_THROUGH(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // Grid-tied mode only, voltage and frequency setpoint the only setpoints - REACTIVE_POWER_CONTROL_MODE(Doc.of(ReactivePowerControlMode.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // To define how the power changes - POWER_RISING_MODE(Doc.of(PowerRisingMode.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // Grid-tied mode only, Volt/Watt control & Freq/Watt control means active power - // will be regulated by grid voltage/frequency following a curve/ramp rate given - // by HECO or CPUC or other local utility authority codes - ACTIVE_POWER_CONTROL_MODE(Doc.of(ActivePowerControlMode.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // Grid-tied mode only, voltage and frequency setpoint the only setpoints - GRID_VOLTAGE_ASYMMETRIC_DETECTON(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // Grid-tied mode only - CONTINUOUS_OVERVOLTAGE_DETECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // Grid-tied mode only,detect whether the grid is on-service at powered-up. - GRID_EXISTENCE_DETECTION_ON(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), - // Grid-tied mode only - NEUTRAL_FLOATING_DETECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // if disabled, the inverter will start the AC voltage, then close the relay. In - // some off-grid cases, such as there are inductive loads or transformer, the - // in rush exciting current will trip the inverter. Enabling this register, the - // inverter will close the relay first try to limit the current and start the - // voltage slowly - OFF_GRID_BLACKSTART_MODE(Doc.of(BlackStartMode.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // Grid tied mode only. take effect after power off. - GRID_CODE_SELECTION(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - GRID_CONNECTED_ACTIVE_CAPACITY_LIMITATION_FUNCTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - GRID_ACTIVE_POWER_CAPACITY_SETTING(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - // Single mode enable and select - SINGLE_PHASE_MODE_SELECTION(Doc.of(SinglePhaseMode.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // Overvoltage drop active enable (only for EN50549 certification) - OVER_VOLTAGE_DROP_ACTIVE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // 0-Manual start,1-Auto start,default:0 - START_UP_MODE(Doc.of(StartMode.values()) // - .accessMode(AccessMode.READ_WRITE)), // - LOCAL_ID_SETTING(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // when implementing Lithium-ion batteries,this register MUST be set to 0 - CURRENT_FROM_TOPPING_CHARGING_TO_FLOAT_CHARGING(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - BATTERY_VOLTAGE_PROTECTION_LIMIT(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.VOLT)), // - LEAKAGE_CURRENT_DC_COMPONENT_DETECTOR(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - RESUME_AND_LIMIT_FREQUENCY(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - RESTORE_LOWER_FREQUENCY_OF_GRID_CONNECTION(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - VOLTAGE_REACTIVE_REFERENCE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - - // ratio * rated voltage,Available only when reactive power regulation mode is - // set to Volt/Var(53626). - VOLTAGE_AND_REACTIVE_POWER_ADJUSTMENT_POINT_V1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - VOLTAGE_AND_REACTIVE_POWER_ADJUSTMENT_POINT_V2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - VOLTAGE_AND_REACTIVE_POWER_ADJUSTMENT_POINT_V3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - VOLTAGE_AND_REACTIVE_POWER_ADJUSTMENT_POINT_V4(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - - // refer to HECO RULE 14, keep default value if no aware of it - MAX_CAPACITIVE_REACTIVE_REGULATION_Q1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - INITIAL_CAPACITIVE_REACTIVE_REGULATION_Q2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - INITIAL_INDUCTIVE_REACTIVE_REGULATION_Q3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - MAX_INDUCTIVE_REACTIVE_REGULATION_Q4(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - VOLTAGE_AND_REACTIVE_RESPONSE_TIME(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - REACTIVE_FIRST_ORDER_RESPONSE_TIME(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - - // ratio * rated voltage, Available only when active power regulation - // mode(53636) is set to Volt/Watt and operating in discharge mode, follow the - // FVRT table given by HECO or CPUC or other local utility authority codes. - INITIAL_VOLTAGE_V_START(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - END_VOLTAGE_V_STOP(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - INITIAL_POWER_P_START(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - END_POWER_P_STOP(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - RETURN_TO_SERVICE_DELAY(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - VOLT_WATT_RESPONSE_TIME(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - - // Available only when active power regulation mode(53636) is set to Freq/Watt - // and operating in discharge mode. When the actual frequency is above the - // point, the active power will be regulated(lowered) with the ramp rate. In - // Australia, this register shall be fixed to 0.25Hz - START_OF_FREQUENY_DROP(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // The ramp rate is defined as multiple of set active power per hertz that above - // the above the Freq/Watt regulation point. Available only when active power - // regulation mode(53636) is set to Freq/Watt and operating in discharge mode. - // Example: Rated frequency is 60Hz, the target active power is set to 10kW, - // Freq/Watt regulation point is set to 2Hz, ramp rate is set as 0.5, If the - // actual frequency reaches 63Hz, the output active power will be - // 10kW-(63Hz-62Hz) x 0.5*(10kW/Hz) = 5kW - SLOPE_OF_FREQUENCY_DROP(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // AS4777 only, bias Bias from rated frequency - FREQUENCY_WATT_F_STOP_DISCHARGE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - FREQUENCY_WATT_F_STOP_CHARGE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // %Vrated,AS4777 only, ratio - VOLT_WATT_V_START_CHARGE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // SS takes effect when the inverter starts, or when the inverter is on "grid - // reconnection" after the trip caused by FVRT timeout - SOFT_START_RAMP_RATE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // RR takes effect in Volt-Watt or Freq-Watt mode when the grid is back to - // normal state and the inverter trying to go back to normal output. - // In other words, as long as the inverter does not trip, and the inverter had - // derated the output power, RR takes effect when the inverter tries to go back - // to normal output. Available only when Power rising mode is set to ramp - // mode(53626).If the value is 2.000, which means within 0.5 seconds the system - // can runs to full power output. - POWER_RAMP_RATE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // Available only when Constant PF is enabled,Negative inductive, positive - // capacitive - POWER_FACTOR_SETTING(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - // Available only when active power regulation mode(53636) is set to Freq/Watt - // and operating in discharge mode. When the actual frequency is above the - // point, the active power will be regulated(lowered) with the ramp rate - POWER_FACTOR_P1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - POWER_FACTOR_P2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - POWER_FACTOR_P3(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - POWER_FACTOR_P4(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - - // +(lagging), -(leading), - POWER_FACTOR_CURVE_MODE_P1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - POWER_FACTOR_CURVE_MODE_P2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - POWER_FACTOR_CURVE_MODE_P3(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - POWER_FACTOR_CURVE_MODE_P4(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - - // %Vrated - CONTINUOS_OVER_VOLTAGE_TRIP_THRESHOLD(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - FREQUENCY_VARIATION_RATE_TRIP_THRESHOLD(Doc.of(FrequencyVariationRate.values()) // - .accessMode(AccessMode.READ_WRITE)), // - PHASE_ANGLE_ABRUPT_TRIP_THRESHOLD(Doc.of(PhaseAngleAbrupt.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // Available only when Power rising mode is set to ramp mode . once tripped - // after FVRT timeout, the inverter can reconnect to the grid when frequency or - // voltage is back to the thresholds defined as "grid is back to service". In - // HECO14 /CPUC 21, this register is unnecessary to - GRID_RECONNECTION_VOLTAGE_UPPER_LIMIT(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - GRID_RECONNECTION_VOLTAGE_LOWER_LIMIT(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // Available only when Power rising mode is set to ramp mode once tripped after - // FVRT timeout, the inverter can reconnect to the grid when frequency or - // voltage is back to the thresholds defined as "grid is back to service" - GRID_RECONNECTION_FREQUENCY_UPPER_LIMIT(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // Bias from rated frequency - GRID_RECONNECTION_FREQUENCY_LOWER_LIMIT(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - LOW_FREQUENCY_RAMP_RATE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // TODO Values check Meter options !!!!!!!!!!!!!!!!!! - METER_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE).unit(Unit.WATT)), // - - GRID_VOLTAGE_CALIBRATION_L1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - GRID_VOLTAGE_CALIBRATION_L2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - GRID_VOLTAGE_CALIBRATION_L3(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INVERTER_VOLTAGE_CALIBRATION_L1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INVERTER_VOLTAGE_CALIBRATION_L2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INVERTER_VOLTAGE_CALIBRATION_L3(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INDUCTOR_CURRENT_CALIBRATION_L1_PARAMETERS_1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INDUCTOR_CURRENT_CALIBRATION_L2_PARAMETERS_1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INDUCTOR_CURRENT_CALIBRATION_L3_PARAMETERS_1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INDUCTOR_CURRENT_CALIBRATION_L1_PARAMETERS_2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INDUCTOR_CURRENT_CALIBRATION_L2_PARAMETERS_2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INDUCTOR_CURRENT_CALIBRATION_L3_PARAMETERS_2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - OUTPUT_CURRENT_CALIBRATION_L1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - OUTPUT_CURRENT_CALIBRATION_L2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - OUTPUT_CURRENT_CALIBRATION_L3(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - POSITIVE_BUS_VOLTAGE_CALIBRATION(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - NEGATIVE_BUS_VOLTAGE_CALIBRATION(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - DC_VOLTAGE_CALIBRATION(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - DC_CURRENT_CALIBRATION(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - DC_INDUCTOR_CURRENT_CALIBRATION(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - TIME_SETTING(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.WRITE_ONLY)), // - PASSWORD(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.WRITE_ONLY)), // - ACTIVE_POWER_1(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_ONLY)), - ACTIVE_POWER_2(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_ONLY) // - ),; - - private final Doc doc; - - private ChannelId(Doc doc) { - this.doc = doc; - } - - @Override - public Doc doc() { - return this.doc; - } - } - - /** - * Gets the Channel for {@link ChannelId#SET_ON_GRID_MODE}. - * - * @return the Channel - */ - public default BooleanWriteChannel getSetOnGridModeChannel() { - return this.channel(ChannelId.SET_ON_GRID_MODE); - } - - /** - * Gets the Set-On-Grid-Mode. See {@link ChannelId#SET_ON_GRID_MODE}. - * - * @return the Channel {@link Value} - */ - public default Value getSetOnGridMode() { - return this.getSetOnGridModeChannel().value(); - } - - /** - * Sets a the On-Grid-Mode. See {@link ChannelId#SET_ON_GRID_MODE}. - * - * @param value the next write value - * @throws OpenemsNamedException on error - */ - public default void setOnGridMode(Boolean value) throws OpenemsNamedException { - this.getSetOnGridModeChannel().setNextWriteValue(value); - } - - /** - * Gets the Channel for {@link SymmetricBatteryInverter.ChannelId#ACTIVE_POWER}. - * - * @return the Channel - */ - public default IntegerReadChannel getActive1PowerChannel() { - return this.channel(ChannelId.ACTIVE_POWER_1); - } - - /** - * Gets the Channel for {@link SymmetricBatteryInverter.ChannelId#ACTIVE_POWER}. - * - * @return the Channel - */ - public default IntegerReadChannel getActive2PowerChannel() { - return this.channel(ChannelId.ACTIVE_POWER_2); - } - - /** - * Gets the Channel for {@link ChannelId#SET_OFF_GRID_MODE}. - * - * @return the Channel - */ - public default BooleanWriteChannel getSetOffGridModeChannel() { - return this.channel(ChannelId.SET_OFF_GRID_MODE); - } - - /** - * Gets the Set-Off-Grid-Mode. See {@link ChannelId#SET_OFF_GRID_MODE}. - * - * @return the Channel {@link Value} - */ - public default Value getSetOffGridMode() { - return this.getSetOffGridModeChannel().value(); - } - - /** - * Sets a the Off-Grid-Mode. See {@link ChannelId#SET_OFF_GRID_MODE}. - * - * @param value the next write value - * @throws OpenemsNamedException on error - */ - public default void setOffGridMode(Boolean value) throws OpenemsNamedException { - this.getSetOffGridModeChannel().setNextWriteValue(value); - } - - /** - * Gets the Channel for {@link ChannelId#START_INVERTER}. - * - * @return the Channel - */ - public default BooleanWriteChannel getStartInverterChannel() { - return this.channel(ChannelId.START_INVERTER); - } - - /** - * Sends a START command to the inverter. See {@link ChannelId#START_INVERTER}. - * - * @throws OpenemsNamedException on error - */ - public default void setStartInverter() throws OpenemsNamedException { - this.getStartInverterChannel().setNextWriteValue(true); // true = START - } - - /** - * Gets the Channel for {@link ChannelId#STOP_INVERTER}. - * - * @return the Channel - */ - public default BooleanWriteChannel getStopInverterChannel() { - return this.channel(ChannelId.STOP_INVERTER); - } - - /** - * Sends a STOP command to the inverter. See {@link ChannelId#STOP_INVERTER}. - * - * @throws OpenemsNamedException on error - */ - public default void setStopInverter() throws OpenemsNamedException { - this.getStopInverterChannel().setNextWriteValue(true); // true = STOP - } - - /** - * Gets the Channel for {@link ChannelId#CLEAR_FAILURE}. - * - * @return the Channel - */ - public default BooleanWriteChannel getClearFailureChannel() { - return this.channel(ChannelId.CLEAR_FAILURE); - } - - /** - * Clear inverter failures. See {@link ChannelId#CLEAR_FAILURE}. - * - * @throws OpenemsNamedException on error - */ - public default void setClearFailure() throws OpenemsNamedException { - this.getClearFailureChannel().setNextWriteValue(true); - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeyeImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeyeImpl.java deleted file mode 100644 index 9efd4a6f008..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeyeImpl.java +++ /dev/null @@ -1,407 +0,0 @@ -package io.openems.edge.deye.batteryinverter; - -import java.util.Objects; -import java.util.concurrent.atomic.AtomicReference; - -import org.osgi.service.cm.ConfigurationAdmin; -import org.osgi.service.component.ComponentContext; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.ConfigurationPolicy; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.component.annotations.ReferencePolicyOption; -import org.osgi.service.event.propertytypes.EventTopics; -import org.osgi.service.metatype.annotations.Designate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.openems.common.channel.AccessMode; -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.common.exceptions.OpenemsException; -import io.openems.common.types.OptionsEnum; -import io.openems.edge.battery.api.Battery; -import io.openems.edge.batteryinverter.api.BatteryInverterConstraint; -import io.openems.edge.batteryinverter.api.ManagedSymmetricBatteryInverter; -import io.openems.edge.batteryinverter.api.OffGridBatteryInverter; -import io.openems.edge.batteryinverter.api.SymmetricBatteryInverter; -import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; -import io.openems.edge.bridge.modbus.api.BridgeModbus; -import io.openems.edge.bridge.modbus.api.ModbusComponent; -import io.openems.edge.bridge.modbus.api.ModbusProtocol; -import io.openems.edge.bridge.modbus.api.element.SignedWordElement; -import io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask; -import io.openems.edge.common.channel.BooleanWriteChannel; -import io.openems.edge.common.channel.IntegerWriteChannel; -import io.openems.edge.common.channel.WriteChannel; -import io.openems.edge.common.component.ComponentManager; -import io.openems.edge.common.component.OpenemsComponent; -import io.openems.edge.common.event.EdgeEventConstants; -import io.openems.edge.common.modbusslave.ModbusSlaveTable; -import io.openems.edge.common.startstop.StartStop; -import io.openems.edge.common.startstop.StartStoppable; -import io.openems.edge.common.taskmanager.Priority; -import io.openems.edge.common.type.TypeUtils; -import io.openems.edge.deye.batteryinverter.enums.EnableDisable; -import io.openems.edge.deye.batteryinverter.enums.FrequencyLevel; -import io.openems.edge.deye.batteryinverter.enums.GridCodeSelection; -import io.openems.edge.deye.batteryinverter.enums.PowerRisingMode; -import io.openems.edge.deye.batteryinverter.enums.VoltageLevel; -import io.openems.edge.deye.batteryinverter.statemachine.Context; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; -import io.openems.edge.ess.power.api.Phase; -import io.openems.edge.ess.power.api.Pwr; -import io.openems.edge.ess.power.api.Relationship; -import io.openems.edge.timedata.api.Timedata; -import io.openems.edge.timedata.api.TimedataProvider; -import io.openems.edge.timedata.api.utils.CalculateEnergyFromPower; - -@Designate(ocd = Config.class, factory = true) -@Component(// - name = "Battery-Inverter.Deye", // - immediate = true, // - configurationPolicy = ConfigurationPolicy.REQUIRE // -) -@EventTopics({ // - EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE, // - EdgeEventConstants.TOPIC_CYCLE_BEFORE_PROCESS_IMAGE // -}) -public class BatteryInverterDeyeImpl extends AbstractOpenemsModbusComponent - implements BatteryInverterDeye, OffGridBatteryInverter, ManagedSymmetricBatteryInverter, - SymmetricBatteryInverter, ModbusComponent, OpenemsComponent, TimedataProvider, StartStoppable { - - public static final int DEFAULT_EMS_TIMEOUT = 60; - public static final int DEFAULT_BMS_TIMEOUT = 0; - public static final EnableDisable DEFAULT_GRID_EXISTENCE_DETECTION_ON = EnableDisable.DISABLE; - public static final PowerRisingMode DEFAULT_POWER_RISING_MODE = PowerRisingMode.STEP; - - private static final int MAX_CURRENT = 90; // [A] - private static final int MAX_TOPPING_CHARGE_VOLTAGE = 750; - - private final Logger log = LoggerFactory.getLogger(BatteryInverterDeyeImpl.class); - private final StateMachine stateMachine = new StateMachine(State.UNDEFINED); - - private final CalculateEnergyFromPower calculateChargeEnergy = new CalculateEnergyFromPower(this, - SymmetricBatteryInverter.ChannelId.ACTIVE_CHARGE_ENERGY); - private final CalculateEnergyFromPower calculateDischargeEnergy = new CalculateEnergyFromPower(this, - SymmetricBatteryInverter.ChannelId.ACTIVE_DISCHARGE_ENERGY); - - @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL) - private volatile Timedata timedata = null; - - @Reference - private ComponentManager componentManager; - - @Reference - private ConfigurationAdmin cm; - - @Override - @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) - protected void setModbus(BridgeModbus modbus) { - super.setModbus(modbus); - } - - protected Config config; - - public BatteryInverterDeyeImpl() throws OpenemsNamedException { - super(// - OpenemsComponent.ChannelId.values(), // - ModbusComponent.ChannelId.values(), // - SymmetricBatteryInverter.ChannelId.values(), // - ManagedSymmetricBatteryInverter.ChannelId.values(), // - StartStoppable.ChannelId.values(), // - OffGridBatteryInverter.ChannelId.values(), // - BatteryInverterDeye.ChannelId.values() // - ); - } - - @Override - protected ModbusProtocol defineModbusProtocol() throws OpenemsException { - return new ModbusProtocol(this, - new FC3ReadRegistersTask(672, Priority.HIGH, m(BatteryInverterDeye.ChannelId.ACTIVE_POWER_1, - new SignedWordElement(672)),m(BatteryInverterDeye.ChannelId.ACTIVE_POWER_2, - new SignedWordElement(673)))); - } - - @Activate - private void activate(ComponentContext context, Config config) throws OpenemsNamedException { - this.config = config; - if (super.activate(context, config.id(), config.alias(), config.enabled(), config.modbusUnitId(), this.cm, "Modbus", - config.modbus_id())) { - return; - } - } - - @Override - @Deactivate - protected void deactivate() { - super.deactivate(); - } - - @Override - public void run(Battery battery, int setActivePower, int setReactivePower) throws OpenemsNamedException { - // Store the current State - this.channel(BatteryInverterDeye.ChannelId.STATE_MACHINE).setNextValue(this.stateMachine.getCurrentState()); - - // Initialize 'Start-Stop' Channel - this._setStartStop(StartStop.UNDEFINED); - - // Set Default Settings - this.setDefaultSettings(); - - // Set Battery Limits - this.setBatteryLimits(battery); - - // Calculate the Energy values from ActivePower. - this.calculateEnergy(); - - // Prepare Context - var context = new Context(this, this.config, this.targetGridMode.get(), setActivePower, setReactivePower); - - // Call the StateMachine - try { - this.stateMachine.run(context); - - this.channel(BatteryInverterDeye.ChannelId.RUN_FAILED).setNextValue(false); - - } catch (OpenemsNamedException e) { - this.channel(BatteryInverterDeye.ChannelId.RUN_FAILED).setNextValue(true); - this.logError(this.log, "StateMachine failed: " + e.getMessage()); - } - } - - /** - * Updates the Channel if its current value is not equal to the new value. - * - * @param channelId Sinexcel Channel-Id - * @param value {@link OptionsEnum} value. - * @throws IllegalArgumentException on error - */ - private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, OptionsEnum value) - throws IllegalArgumentException, OpenemsNamedException { - this.updateIfNotEqual(channelId, value.getValue()); - } - - /** - * Updates the Channel if its current value is not equal to the new value. - * - * @param channelId Sinexcel Channel-Id - * @param newValue Integer value. - * @throws IllegalArgumentException on error - */ - private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, Integer newValue) - throws IllegalArgumentException { - WriteChannel channel = this.channel(channelId); - var currentValue = channel.value(); - if (currentValue.isDefined() && !Objects.equals(currentValue.get(), newValue)) { - try { - channel.setNextWriteValue(newValue); - } catch (OpenemsNamedException e) { - this.logWarn(this.log, "Unable to update Channel [" + channel.address() + "] from [" + currentValue - + "] to [" + newValue + "]"); - e.printStackTrace(); - } - } - } - - private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, VoltageLevel voltageLevel) - throws IllegalArgumentException, OpenemsNamedException { - IntegerWriteChannel channel = this.channel(channelId); - channel.setNextWriteValue(voltageLevel.getValue()); - } - - private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, FrequencyLevel frequencyLevel) - throws IllegalArgumentException, OpenemsNamedException { - IntegerWriteChannel channel = this.channel(channelId); - channel.setNextWriteValue(frequencyLevel.getValue()); - } - - private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, GridCodeSelection gridCodeSelection) - throws IllegalArgumentException, OpenemsNamedException { - IntegerWriteChannel channel = this.channel(channelId); - channel.setNextWriteValue(gridCodeSelection.getValue()); - } - - private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, EnableDisable value) - throws IllegalArgumentException, OpenemsNamedException { - BooleanWriteChannel channel = this.channel(channelId); - switch (value) { - case ENABLE: - channel.setNextWriteValue(true); - break; - case DISABLE: - channel.setNextWriteValue(false); - break; - } - } - - /** - * Sets some default settings on the inverter, like Timeout. - * - * @throws OpenemsNamedException on error - */ - private void setDefaultSettings() throws OpenemsNamedException { - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.EMS_TIMEOUT, DEFAULT_EMS_TIMEOUT); - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.BMS_TIMEOUT, DEFAULT_BMS_TIMEOUT); - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.GRID_EXISTENCE_DETECTION_ON, - DEFAULT_GRID_EXISTENCE_DETECTION_ON); - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.POWER_RISING_MODE, DEFAULT_POWER_RISING_MODE); - - switch (this.config.countryCode()) { - case AUSTRIA: - case GERMANY: - case SWITZERLAND: - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.VOLTAGE_LEVEL, VoltageLevel.V_400); - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.FREQUENCY_LEVEL, FrequencyLevel.HZ_50); - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.GRID_CODE_SELECTION, GridCodeSelection.VDE); - break; - } - - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.INVERTER_WIRING_TOPOLOGY, this.config.emergencyPower()); - } - - /** - * Sets the Battery Limits. - * - * @param battery the linked {@link Battery} - * @throws OpenemsNamedException on error - */ - private void setBatteryLimits(Battery battery) throws OpenemsNamedException { - // Upper voltage limit of battery protection >= Topping charge voltage >= Float - // charge voltage >= Lower voltage limit of battery protection (814 >= 809 >= - // 808 >= 813). - // Discharge Min Voltage - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.DISCHARGE_MIN_VOLTAGE, - battery.getDischargeMinVoltage().get()); - - // Charge Max Voltage - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.CHARGE_MAX_VOLTAGE, battery.getChargeMaxVoltage().get()); - - // Topping Charge Voltage - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.TOPPING_CHARGE_VOLTAGE, - TypeUtils.min(battery.getChargeMaxVoltage().get(), MAX_TOPPING_CHARGE_VOLTAGE)); - - // Float Charge Voltage - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.FLOAT_CHARGE_VOLTAGE, - TypeUtils.min(battery.getChargeMaxVoltage().get(), MAX_TOPPING_CHARGE_VOLTAGE)); - - // Discharge Max Current - // negative value is corrected as zero - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.DISCHARGE_MAX_CURRENT, - TypeUtils.fitWithin(0 /* enforce positive */, MAX_CURRENT, battery.getDischargeMaxCurrent().orElse(0))); - - // Charge Max Current - // negative value is corrected as zero - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.CHARGE_MAX_CURRENT, - TypeUtils.fitWithin(0 /* enforce positive */, MAX_CURRENT, battery.getChargeMaxCurrent().orElse(0))); - } - - @Override - public String debugLog() { - return "MOIN - L:" + this.getActivePower().asString(); - } - - private final AtomicReference startStopTarget = new AtomicReference<>(StartStop.UNDEFINED); - - @Override - public void setStartStop(StartStop value) { - if (this.startStopTarget.getAndSet(value) != value) { - // Set only if value changed - this.stateMachine.forceNextState(State.UNDEFINED); - } - } - - /** - * Gets the inverter start-stop target. - * - * @return {@link StartStop} - */ - public StartStop getStartStopTarget() { - switch (this.config.startStop()) { - case AUTO: - // read StartStop-Channel - return this.startStopTarget.get(); - - case START: - // force START - return StartStop.START; - - case STOP: - // force STOP - return StartStop.STOP; - } - - assert false; - return StartStop.UNDEFINED; // can never happen - } - - protected final AtomicReference targetGridMode = new AtomicReference<>(TargetGridMode.GO_ON_GRID); - - @Override - public void setTargetGridMode(TargetGridMode targetGridMode) { - if (this.targetGridMode.getAndSet(targetGridMode) != targetGridMode) { - // Set only if value changed - this.stateMachine.forceNextState(State.UNDEFINED); - } - } - - @Override - public BatteryInverterConstraint[] getStaticConstraints() throws OpenemsException { - if (this.stateMachine.getCurrentState() == State.RUNNING) { - return BatteryInverterConstraint.NO_CONSTRAINTS; - - } - // Block any power as long as we are not RUNNING - return new BatteryInverterConstraint[] { // - new BatteryInverterConstraint("Sinexcel inverter not ready", Phase.ALL, Pwr.REACTIVE, // - Relationship.EQUALS, 0d), // - new BatteryInverterConstraint("Sinexcel inverter not ready", Phase.ALL, Pwr.ACTIVE, // - Relationship.EQUALS, 0d) // - }; - } - - @Override - public int getPowerPrecision() { - return 100; - } - - @Override - public ModbusSlaveTable getModbusSlaveTable(AccessMode accessMode) { - return new ModbusSlaveTable(// - OpenemsComponent.getModbusSlaveNatureTable(accessMode), // - SymmetricBatteryInverter.getModbusSlaveNatureTable(accessMode), // - ManagedSymmetricBatteryInverter.getModbusSlaveNatureTable(accessMode) // - ); - } - - /** - * Calculate the Energy values from ActivePower. - */ - private void calculateEnergy() { - // Calculate Energy - var activePower1 = this.getActive1PowerChannel().value().get(); - var activePower2 = this.getActive2PowerChannel().value().get(); - var activePower = activePower1 + activePower2; - if (activePower1 == null && activePower2 == null) { - // Not available - this.calculateChargeEnergy.update(null); - this.calculateDischargeEnergy.update(null); - } else if (activePower > 0) { - // Buy-From-Grid - this.calculateChargeEnergy.update(0); - this.calculateDischargeEnergy.update(activePower); - } else { - // Sell-To-Grid - this.calculateChargeEnergy.update(activePower * -1); - this.calculateDischargeEnergy.update(0); - } - } - - @Override - public Timedata getTimedata() { - return this.timedata; - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/Config.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/Config.java deleted file mode 100644 index 26202dff197..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/Config.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.openems.edge.deye.batteryinverter; - -import io.openems.edge.deye.batteryinverter.enums.CountryCode; -import io.openems.edge.deye.batteryinverter.enums.EnableDisable; -import org.osgi.service.metatype.annotations.AttributeDefinition; -import org.osgi.service.metatype.annotations.ObjectClassDefinition; - -import io.openems.edge.common.startstop.StartStopConfig; - -@ObjectClassDefinition(// - name = "Battery-Inverter Deye", // - description = "Implements the Deye battery inverter.") -public @interface Config { - - @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") - String id() default "batteryInverter0"; - - @AttributeDefinition(name = "Alias", description = "Human-readable name of this Component; defaults to Component-ID") - String alias() default ""; - - @AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?") - boolean enabled() default true; - - @AttributeDefinition(name = "Start/stop behaviour?", description = "Should this Component be forced to start or stop?") - StartStopConfig startStop() default StartStopConfig.AUTO; - - @AttributeDefinition(name = "Modbus-ID", description = "ID of Modbus bridge.") - String modbus_id(); - - @AttributeDefinition(name = "Modbus Unit-ID", description = "The Unit-ID of the Modbus device.") - int modbusUnitId() default 1; - - @AttributeDefinition(name = "Country Code", description = "Selection of the country code.") CountryCode countryCode() default CountryCode.GERMANY; - - @AttributeDefinition(name = "Is emergency power enabled?", description = "Emergency power enable/disable.") EnableDisable emergencyPower() default EnableDisable.DISABLE; - - @AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID'.") - String Modbus_target() default "(enabled=true)"; - - String webconsole_configurationFactory_nameHint() default "Battery-Inverter Deye [{id}]"; -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ActivePowerControlMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ActivePowerControlMode.java deleted file mode 100644 index d9691bbba40..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ActivePowerControlMode.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum ActivePowerControlMode implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - CONTANT_ACTIVE_POWER(0, "Constant Active Power"), // - VOLT_WATT_ENABLED(1, "Volt watt enabled"), // - CONSTANT_PF(2, "Constant power factor"), // - WATT_PF_ENABLED(3, "Watt power factor enabled");// - - private final int value; - private final String name; - - private ActivePowerControlMode(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Baudrate.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Baudrate.java deleted file mode 100644 index 74194f196a1..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Baudrate.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -//default 0 -public enum Baudrate implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - B_19200(0, "19200"), // - B_9600(1, "9600"); // - - private final int value; - private final String name; - - private Baudrate(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BlackStartMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BlackStartMode.java deleted file mode 100644 index 1abb25b25b2..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BlackStartMode.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum BlackStartMode implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - NORMAL_STARTUP(0, "Normal Start Up"), // - BLACK_STARTUP(1, "Black Start Up");// - - private final int value; - private final String name; - - private BlackStartMode(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BmsProtocolSelection.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BmsProtocolSelection.java deleted file mode 100644 index ca7794a37ff..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BmsProtocolSelection.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum BmsProtocolSelection implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - ENERGY_PORT(0, "EP"), // - ALPHA(1, "Alpha-Ess"), // - PYLONTECH(2, "Pylontech"), // - BMSER(3, "Bmser"); // - - private final int value; - private final String name; - - private BmsProtocolSelection(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CountryCode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CountryCode.java deleted file mode 100644 index 9c20f47ece2..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CountryCode.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -public enum CountryCode { - - GERMANY("Germany"), // - AUSTRIA("Austria"), // - SWITZERLAND("Switzerland"); - - private final String value; - - private CountryCode(String value) { - this.value = value; - } - - public String getValue() { - return this.value; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CpuType.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CpuType.java deleted file mode 100644 index 38a5ae32b66..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CpuType.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum CpuType implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - SINGLE_CPU(0, "Single Cpu"), // - DOUBLE_CPU(1, "Double Cpu");// - - private final int value; - private final String name; - - private CpuType(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/DcVoltageLevel.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/DcVoltageLevel.java deleted file mode 100644 index 47cc6fe8809..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/DcVoltageLevel.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum DcVoltageLevel implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - V_750(0, "750 V"), // - V_830(1, "830 V");// - - private final int value; - private final String name; - - private DcVoltageLevel(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/EnableDisable.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/EnableDisable.java deleted file mode 100644 index 6687d51ff7a..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/EnableDisable.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -public enum EnableDisable { - - ENABLE("Enable"), // - DISABLE("Disable"); - - private final String value; - - private EnableDisable(String value) { - this.value = value; - } - - public String getValue() { - return this.value; - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Epo.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Epo.java deleted file mode 100644 index 4e041753ab6..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Epo.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum Epo implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - INVALID(0, "Modbus"), // - EPO(1, "Sunspec"), // - DRMO(2, "Sunspec");// - - private final int value; - private final String name; - - private Epo(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyLevel.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyLevel.java deleted file mode 100644 index c76850b1b1a..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyLevel.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -public enum FrequencyLevel { - HZ_50("50 Hz", 0), // - HZ_60("60 Hz", 1);// - - private final String name; - private final int value; - - private FrequencyLevel(String name, int value) { - this.name = name; - this.value = value; - } - - public String getName() { - return this.name; - } - - public int getValue() { - return this.value; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyVariationRate.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyVariationRate.java deleted file mode 100644 index bb86a05d727..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyVariationRate.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum FrequencyVariationRate implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - DISABLED(0, "Disabled"), // - RATE_0125(1, "Rate limit 0.125 Hz/s"), // - RATE_02(2, "Rate limit 0.2 Hz/s");// - - private final int value; - private final String name; - - private FrequencyVariationRate(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/GridCodeSelection.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/GridCodeSelection.java deleted file mode 100644 index 429deb65b58..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/GridCodeSelection.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -public enum GridCodeSelection { - SA1741("SA1741", 0), // - VDE("VDE", 1), // - AUSTRALIAN("Australian", 2), // - G99("G99", 3), // - HAWAIIAN("Hawaiian", 4), // - EN50549("EN50549", 5), // - AUSTRIA_TYPEA("Austria Type A", 6);// - - private final String name; - private final int value; - - private GridCodeSelection(String name, int value) { - this.name = name; - this.value = value; - } - - public String getName() { - return this.name; - } - - public int getValue() { - return this.value; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InterfaceType.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InterfaceType.java deleted file mode 100644 index 96d71d9ac4e..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InterfaceType.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum InterfaceType implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - RS_485(0, "RS-485"), // - ETHERNET(1, "Ethernet"); // - - private final int value; - private final String name; - - private InterfaceType(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InverterWiringTopology.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InverterWiringTopology.java deleted file mode 100644 index 3d19ac3e156..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InverterWiringTopology.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -public enum InverterWiringTopology { - THREE_PHASE_FOUR_WIRE("3P4W"), // - THREE_PHASE_THREE_WIRE("3P3W or 3P3W+N"); // - - private final String value; - - private InverterWiringTopology(String value) { - this.value = value; - } - - public String getValue() { - return this.value; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ModulePowerLevel.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ModulePowerLevel.java deleted file mode 100644 index 8df965bcd39..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ModulePowerLevel.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum ModulePowerLevel implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - TEN_KW(0, " 10 kW"), // - TWENTY_KW(1, "20 kW"), // - THIRTY_KW(2, "30 kW"), // - TWENTY_NINE_KW(3, "29 kW"); // - - private final int value; - private final String name; - - private ModulePowerLevel(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PhaseAngleAbrupt.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PhaseAngleAbrupt.java deleted file mode 100644 index b1160a7cad8..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PhaseAngleAbrupt.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum PhaseAngleAbrupt implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - DISABLED(0, "Disabled"), // - ANGLE_ABRUPT_LIMIT_12_DEGREE(1, "Angle abrupt limit 12 deg"), // - ANGLE_ABRUPT_LIMIT_6_DEGREE(2, "Angle abrupt limit 6 deg"); // - - private final int value; - private final String name; - - private PhaseAngleAbrupt(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PowerRisingMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PowerRisingMode.java deleted file mode 100644 index f0fba7ebd3d..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PowerRisingMode.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum PowerRisingMode implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - STEP(0, "Step Function"), // - RAMP(1, "Ramp Function");// - - private final int value; - private final String name; - - private PowerRisingMode(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ProtocolSelection.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ProtocolSelection.java deleted file mode 100644 index f527df7f2e8..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ProtocolSelection.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum ProtocolSelection implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - MODBUS(0, "Modbus"), // - SUNSPEC(1, "Sunspec"); // - - private final int value; - private final String name; - - private ProtocolSelection(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ReactivePowerControlMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ReactivePowerControlMode.java deleted file mode 100644 index e0a44553e4b..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ReactivePowerControlMode.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum ReactivePowerControlMode implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - CONSTANT_REACTIVE_POWER(0, "Constant Reactive Power"), // - VOLT_VAR_ENABLED(1, "Volt Var Enabled"), // - CONSTANT_PF(2, "Constanr Power Factor"), // - WATT_PF_ENABLED(3, "Watt Power Factor Enabled"); // - - private final int value; - private final String name; - - private ReactivePowerControlMode(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelGridMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelGridMode.java deleted file mode 100644 index a4a720775f2..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelGridMode.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum SinexcelGridMode implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - ON_GRID(0, "On Grid"), // - OFF_GRID(1, "Off Grid"); // - - private final int value; - private final String name; - - private SinexcelGridMode(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelState.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelState.java deleted file mode 100644 index 144cc4f2c15..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelState.java +++ /dev/null @@ -1,40 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum SinexcelState implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - OFF(1, "Off"), // - SLEEPING(2, "Sleeping"), // - STARTING(3, "Starting"), // - MPPT(4, "MPPT"), // - THROTTLED(5, "Throttled"), // - SHUTTINGDOWN(6, "Shutting Down"), // - FAULT(7, "Fault"), // - STANDBY(8, "Standby"), // - STARTED(9, "Started"); - - private final int value; - private final String option; - - private SinexcelState(int value, String option) { - this.value = value; - this.option = option; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.option; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } - -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinglePhaseMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinglePhaseMode.java deleted file mode 100644 index 30396d97c81..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinglePhaseMode.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum SinglePhaseMode implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - DISABLE(0, "Disable"), // - SINGLE_PHASE_230V(1, "Single Phae 230V"), // - SINGLE_PHASE_480V(2, "Single Phase 480V");// - - private final int value; - private final String name; - - private SinglePhaseMode(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/StartMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/StartMode.java deleted file mode 100644 index b2d985d7cd5..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/StartMode.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum StartMode implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - MANUAL(0, "Manual Start"), // - AUTO(1, "Auto Start"); // - - private final int value; - private final String name; - - private StartMode(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Switch.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Switch.java deleted file mode 100644 index aedd0fa157c..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Switch.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum Switch implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - NO_SWITCH(0, "No Switch"), // - SWITCH(1, "Switch");// - - private final int value; - private final String name; - - private Switch(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/VoltageLevel.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/VoltageLevel.java deleted file mode 100644 index 3a04e4106c8..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/VoltageLevel.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -public enum VoltageLevel { - V_380("380 V", 0), // - V_400("400 V", 1), // - V_480("480 V", 2); // - - private final String name; - private final int value; - - private VoltageLevel(String name, int value) { - this.name = name; - this.value = value; - } - - public String getName() { - return this.name; - } - - public int getValue() { - return this.value; - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/Context.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/Context.java deleted file mode 100644 index 1e0e20c445b..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/Context.java +++ /dev/null @@ -1,24 +0,0 @@ -package io.openems.edge.deye.batteryinverter.statemachine; - -import io.openems.edge.batteryinverter.api.OffGridBatteryInverter; -import io.openems.edge.deye.batteryinverter.BatteryInverterDeyeImpl; -import io.openems.edge.deye.batteryinverter.Config; -import io.openems.edge.common.statemachine.AbstractContext; - -public class Context extends AbstractContext { - - protected final Config config; - protected final OffGridBatteryInverter.TargetGridMode targetGridMode; - protected final int setActivePower; - protected final int setReactivePower; - - public Context(BatteryInverterDeyeImpl parent, Config config, OffGridBatteryInverter.TargetGridMode targetGridMode, int setActivePower, - int setReactivePower) { - super(parent); - this.config = config; - this.targetGridMode = targetGridMode; - this.setActivePower = setActivePower; - this.setReactivePower = setReactivePower; - } - -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/ErrorHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/ErrorHandler.java deleted file mode 100644 index af24355c131..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/ErrorHandler.java +++ /dev/null @@ -1,46 +0,0 @@ -package io.openems.edge.deye.batteryinverter.statemachine; - -import java.time.Duration; -import java.time.Instant; - -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.edge.deye.batteryinverter.BatteryInverterDeye; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; -import io.openems.edge.common.channel.BooleanWriteChannel; -import io.openems.edge.common.statemachine.StateHandler; - -public class ErrorHandler extends StateHandler { - - private static final int WAIT_SECONDS = 120; - - private Instant entryAt = Instant.MIN; - - @Override - protected void onEntry(Context context) throws OpenemsNamedException { - this.entryAt = Instant.now(); - - // Clear Failures - this.setClearFailureCommand(context); - - // Try to stop systems - final var inverter = context.getParent(); - inverter.setStopInverter(); - } - - @Override - public State runAndGetNextState(Context context) throws OpenemsNamedException { - if (Duration.between(this.entryAt, Instant.now()).getSeconds() > WAIT_SECONDS) { - // Try again - return State.UNDEFINED; - } - - // Wait - return State.ERROR; - } - - private void setClearFailureCommand(Context context) throws OpenemsNamedException { - BooleanWriteChannel setClearFailureCmd = context.getParent() - .channel(BatteryInverterDeye.ChannelId.CLEAR_FAILURE); - setClearFailureCmd.setNextWriteValue(true); // 1: true, other: illegal - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoRunningHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoRunningHandler.java deleted file mode 100644 index 34dd6333aed..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoRunningHandler.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.openems.edge.deye.batteryinverter.statemachine; - -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; -import io.openems.edge.common.statemachine.StateHandler; - -public class GoRunningHandler extends StateHandler { - - @Override - public State runAndGetNextState(Context context) throws OpenemsNamedException { - final var inverter = context.getParent(); - - /* - * Be sure to set the correct target grid mode - */ - var setOnGridMode = inverter.getSetOnGridMode().get(); - var setOffGridMode = inverter.getSetOffGridMode().get(); - switch (context.targetGridMode) { - case GO_ON_GRID: - if (setOnGridMode == Boolean.FALSE || setOffGridMode == Boolean.TRUE) { - inverter.setOnGridMode(true); - return State.GO_RUNNING; - } - break; - case GO_OFF_GRID: - if (setOnGridMode == Boolean.TRUE || setOffGridMode == Boolean.FALSE) { - inverter.setOffGridMode(true); - return State.GO_RUNNING; - } - break; - } - - inverter.setStartInverter(); - - if (inverter.getInverterState().get() == Boolean.TRUE) { - // Inverter is ON - return State.RUNNING; - } - // Still waiting - return State.GO_RUNNING; - } - -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoStoppedHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoStoppedHandler.java deleted file mode 100644 index f570503c526..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoStoppedHandler.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.openems.edge.deye.batteryinverter.statemachine; - -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; -import io.openems.edge.common.statemachine.StateHandler; - -public class GoStoppedHandler extends StateHandler { - - @Override - public State runAndGetNextState(Context context) throws OpenemsNamedException { - final var inverter = context.getParent(); - - inverter.setStopInverter(); - - if (inverter.getInverterState().get() == Boolean.FALSE) { - // Inverter is OFF - return State.STOPPED; - } - // Still waiting - return State.GO_STOPPED; - } - -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/RunningHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/RunningHandler.java deleted file mode 100644 index 727206eaa19..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/RunningHandler.java +++ /dev/null @@ -1,44 +0,0 @@ -package io.openems.edge.deye.batteryinverter.statemachine; - -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.edge.deye.batteryinverter.BatteryInverterDeye; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; -import io.openems.edge.common.channel.IntegerWriteChannel; -import io.openems.edge.common.startstop.StartStop; -import io.openems.edge.common.statemachine.StateHandler; - -public class RunningHandler extends StateHandler { - - @Override - public State runAndGetNextState(Context context) throws OpenemsNamedException { - final var inverter = context.getParent(); - - if (inverter.hasFaults() || inverter.getInverterState().get() == Boolean.FALSE) { - return State.UNDEFINED; - } - - // Mark as started - inverter._setStartStop(StartStop.START); - - // Apply Active and Reactive Power Set-Points - this.applyPower(context); - - return State.RUNNING; - } - - /** - * Applies the Active and Reactive Power Set-Points. - * - * @param context the {@link Context} - * @throws OpenemsNamedException on error - */ - private void applyPower(Context context) throws OpenemsNamedException { - final var inverter = context.getParent(); - - IntegerWriteChannel setActivePower = inverter.channel(BatteryInverterDeye.ChannelId.SET_ACTIVE_POWER); - setActivePower.setNextWriteValue(context.setActivePower); - - IntegerWriteChannel setReactivePower = inverter.channel(BatteryInverterDeye.ChannelId.SET_REACTIVE_POWER); - setReactivePower.setNextWriteValue(context.setReactivePower); - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StateMachine.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StateMachine.java deleted file mode 100644 index 815f79ab5a1..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StateMachine.java +++ /dev/null @@ -1,70 +0,0 @@ -package io.openems.edge.deye.batteryinverter.statemachine; - -import io.openems.common.types.OptionsEnum; -import io.openems.edge.common.statemachine.AbstractStateMachine; -import io.openems.edge.common.statemachine.StateHandler; - -public class StateMachine extends AbstractStateMachine { - - public enum State implements io.openems.edge.common.statemachine.State, OptionsEnum { - UNDEFINED(-1), // - - GO_RUNNING(10), // - RUNNING(11), // - - GO_STOPPED(20), // - STOPPED(21), // - - ERROR(30) // - ; - - private final int value; - - private State(int value) { - this.value = value; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name(); - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } - - @Override - public State[] getStates() { - return State.values(); - } - } - - public StateMachine(State initialState) { - super(initialState); - } - - @Override - public StateHandler getStateHandler(State state) { - switch (state) { - case UNDEFINED: - return new UndefinedHandler(); - case GO_RUNNING: - return new GoRunningHandler(); - case RUNNING: - return new RunningHandler(); - case GO_STOPPED: - return new GoStoppedHandler(); - case STOPPED: - return new StoppedHandler(); - case ERROR: - return new ErrorHandler(); - } - throw new IllegalArgumentException("Unknown State [" + state + "]"); - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StoppedHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StoppedHandler.java deleted file mode 100644 index fdda56d3728..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StoppedHandler.java +++ /dev/null @@ -1,19 +0,0 @@ -package io.openems.edge.deye.batteryinverter.statemachine; - -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; -import io.openems.edge.common.startstop.StartStop; -import io.openems.edge.common.statemachine.StateHandler; - -public class StoppedHandler extends StateHandler { - - @Override - public State runAndGetNextState(Context context) throws OpenemsNamedException { - final var inverter = context.getParent(); - - // Mark as stopped - inverter._setStartStop(StartStop.STOP); - return State.STOPPED; - } - -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/UndefinedHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/UndefinedHandler.java deleted file mode 100644 index c932a3d993d..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/UndefinedHandler.java +++ /dev/null @@ -1,36 +0,0 @@ -package io.openems.edge.deye.batteryinverter.statemachine; - -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; -import io.openems.edge.common.statemachine.StateHandler; - -public class UndefinedHandler extends StateHandler { - - @Override - public State runAndGetNextState(Context context) throws OpenemsNamedException { - final var inverter = context.getParent(); - switch (inverter.getStartStopTarget()) { - case UNDEFINED: - // Stuck in UNDEFINED State - return State.UNDEFINED; - - case START: - // force START - if (inverter.hasFaults()) { - // Has Faults -> error handling - return State.ERROR; - } else { - // No Faults -> start - return State.GO_RUNNING; - } - - case STOP: - // force STOP - return State.GO_STOPPED; - } - - assert false; - return State.UNDEFINED; // can never happen - } - -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java index 72c338749fe..72d449f8374 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java @@ -5,8 +5,8 @@ import io.openems.edge.meter.api.MeterType; -@ObjectClassDefinition(name = "Meter Deye", // - description = "Implements the Deye Meter.") +@ObjectClassDefinition(name = "Grid Meter Deye", // + description = "Implements the Deye Meter - Grid") @interface Config { @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") @@ -18,9 +18,6 @@ @AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?") boolean enabled() default true; - @AttributeDefinition(name = "Meter-Type", description = "What is measured by this Meter?") - MeterType type() default MeterType.GRID; - @AttributeDefinition(name = "Modbus-ID", description = "ID of Modbus bridge.") String modbus_id() default "modbus0"; diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java index 77ace515c27..dd7d9117293 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java @@ -1,18 +1,5 @@ package io.openems.edge.deye.gridmeter; -import org.osgi.service.cm.ConfigurationAdmin; -import org.osgi.service.component.ComponentContext; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.ConfigurationPolicy; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.component.annotations.ReferencePolicyOption; -import org.osgi.service.event.propertytypes.EventTopics; -import org.osgi.service.metatype.annotations.Designate; - import io.openems.common.exceptions.OpenemsException; import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; import io.openems.edge.bridge.modbus.api.BridgeModbus; @@ -23,9 +10,20 @@ import io.openems.edge.common.component.OpenemsComponent; import io.openems.edge.common.event.EdgeEventConstants; import io.openems.edge.common.taskmanager.Priority; -import io.openems.edge.deye.batteryinverter.BatteryInverterDeye; import io.openems.edge.meter.api.ElectricityMeter; import io.openems.edge.meter.api.MeterType; +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.ConfigurationPolicy; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; +import org.osgi.service.component.annotations.ReferencePolicyOption; +import org.osgi.service.event.propertytypes.EventTopics; +import org.osgi.service.metatype.annotations.Designate; @Designate(ocd = Config.class, factory = true) @Component(// @@ -60,6 +58,7 @@ public DeyeGridMeterImpl() throws OpenemsException { DeyeGridMeter.ChannelId.values() // ); + // Automatically calculate sum values from L1/L2/L3 ElectricityMeter.calculateSumActivePowerFromPhases(this); } @@ -80,7 +79,7 @@ protected void deactivate() { @Override public MeterType getMeterType() { - return this.config.type(); + return MeterType.GRID; } @Override @@ -93,13 +92,13 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException { return new ModbusProtocol(this, new FC3ReadRegistersTask(633, Priority.HIGH, m(ElectricityMeter.ChannelId.ACTIVE_POWER_L1, new SignedWordElement(633)), - m(BatteryInverterDeye.ChannelId.ACTIVE_POWER_L2, new SignedWordElement(634)), - m(BatteryInverterDeye.ChannelId.ACTIVE_POWER_L3, new SignedWordElement(635)))); + m(ElectricityMeter.ChannelId.ACTIVE_POWER_L2, new SignedWordElement(634)), + m(ElectricityMeter.ChannelId.ACTIVE_POWER_L3, new SignedWordElement(635)))); } @Override public String debugLog() { - return "GRID OUIDA L:" + this.getActivePower().asString(); + return "GRID:" + this.getActivePower().asString(); } } diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/Config.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/Config.java new file mode 100644 index 00000000000..4679f641cd0 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/Config.java @@ -0,0 +1,31 @@ +package io.openems.edge.deye.meter; + +import io.openems.edge.meter.api.MeterType; +import org.osgi.service.metatype.annotations.AttributeDefinition; +import org.osgi.service.metatype.annotations.ObjectClassDefinition; + +@ObjectClassDefinition(name = "Production Meter Deye", // + description = "Implements the Deye Meter - Production") +@interface Config { + + @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") + String id() default "meter0"; + + @AttributeDefinition(name = "Alias", description = "Human-readable name of this Component; defaults to Component-ID") + String alias() default ""; + + @AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?") + boolean enabled() default true; + + @AttributeDefinition(name = "Modbus-ID", description = "ID of Modbus bridge.") + String modbus_id() default "modbus0"; + + @AttributeDefinition(name = "Modbus Unit-ID", description = "The Unit-ID of the Modbus device. ") + int modbusUnitId() default 1; + + @AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID'.") + String Modbus_target() default "(enabled=true)"; + + String webconsole_configurationFactory_nameHint() default "Meter Deye [{id}]"; + +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/DeyeMeter.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/DeyeMeter.java new file mode 100644 index 00000000000..83ecee1b363 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/DeyeMeter.java @@ -0,0 +1,23 @@ +package io.openems.edge.deye.meter; + +import io.openems.edge.bridge.modbus.api.ModbusComponent; +import io.openems.edge.common.channel.Doc; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.meter.api.ElectricityMeter; + +public interface DeyeMeter extends ElectricityMeter, ModbusComponent, OpenemsComponent { + + public enum ChannelId implements io.openems.edge.common.channel.ChannelId { + ; + private final Doc doc; + + private ChannelId(Doc doc) { + this.doc = doc; + } + + @Override + public Doc doc() { + return this.doc; + } + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/DeyeMeterImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/DeyeMeterImpl.java new file mode 100644 index 00000000000..1ff4ae67282 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/DeyeMeterImpl.java @@ -0,0 +1,100 @@ +package io.openems.edge.deye.meter; + +import io.openems.common.exceptions.OpenemsException; +import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; +import io.openems.edge.bridge.modbus.api.BridgeModbus; +import io.openems.edge.bridge.modbus.api.ElementToChannelConverter; +import io.openems.edge.bridge.modbus.api.ModbusComponent; +import io.openems.edge.bridge.modbus.api.ModbusProtocol; +import io.openems.edge.bridge.modbus.api.element.UnsignedDoublewordElement; +import io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.common.event.EdgeEventConstants; +import io.openems.edge.common.taskmanager.Priority; +import io.openems.edge.meter.api.ElectricityMeter; +import io.openems.edge.meter.api.MeterType; +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.ConfigurationPolicy; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; +import org.osgi.service.component.annotations.ReferencePolicyOption; +import org.osgi.service.event.propertytypes.EventTopics; +import org.osgi.service.metatype.annotations.Designate; + +@Designate(ocd = Config.class, factory = true) +@Component(// + name = "Deye.Meter", // + immediate = true, // + configurationPolicy = ConfigurationPolicy.REQUIRE, // + property = { // + "type=PRODUCTION" // + }) +@EventTopics({ // + EdgeEventConstants.TOPIC_CYCLE_EXECUTE_WRITE // +}) +public class DeyeMeterImpl extends AbstractOpenemsModbusComponent implements DeyeMeter, ElectricityMeter, ModbusComponent, OpenemsComponent { + + @Reference + private ConfigurationAdmin cm; + + @Override + @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) + protected void setModbus(BridgeModbus modbus) { + super.setModbus(modbus); + } + + private Config config; + + public DeyeMeterImpl() throws OpenemsException { + super(// + OpenemsComponent.ChannelId.values(), // + ModbusComponent.ChannelId.values(), // + ElectricityMeter.ChannelId.values(), // + DeyeMeter.ChannelId.values() // + ); + + // Automatically calculate sum values from L1/L2/L3 + ElectricityMeter.calculateSumActivePowerFromPhases(this); + } + + @Activate + private void activate(ComponentContext context, Config config) throws OpenemsException { + if (super.activate(context, config.id(), config.alias(), config.enabled(), config.modbusUnitId(), this.cm, "Modbus", config.modbus_id())) { + return; + } + this.config = config; + } + + @Override + @Deactivate + protected void deactivate() { + super.deactivate(); + } + + @Override + public MeterType getMeterType() { + return MeterType.PRODUCTION; + } + + @Override + public void retryModbusCommunication() { + + } + + @Override + protected ModbusProtocol defineModbusProtocol() throws OpenemsException { + return new ModbusProtocol(this, new FC3ReadRegistersTask(672, Priority.HIGH, + m(ElectricityMeter.ChannelId.ACTIVE_POWER, new UnsignedDoublewordElement(672), ElementToChannelConverter.DIRECT_1_TO_1))); + } + + @Override + public String debugLog() { + return "PRODUCTION:" + this.getActivePower().asString(); + } + +} From 1f8915b8549b1e2ea10ca7f5fe827e8f00940086 Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Wed, 14 Feb 2024 10:09:21 +0100 Subject: [PATCH 03/25] Start implement DEYE battery inverter --- .../readme.adoc | 6 + .../batteryinverter/BatteryInverterDeye.java | 949 ++++++++++++++++++ .../BatteryInverterDeyeImpl.java | 407 ++++++++ .../edge/deye/batteryinverter/Config.java | 41 + .../enums/ActivePowerControlMode.java | 34 + .../deye/batteryinverter/enums/Baudrate.java | 33 + .../batteryinverter/enums/BlackStartMode.java | 32 + .../enums/BmsProtocolSelection.java | 34 + .../batteryinverter/enums/CountryCode.java | 18 + .../deye/batteryinverter/enums/CpuType.java | 32 + .../batteryinverter/enums/DcVoltageLevel.java | 32 + .../batteryinverter/enums/EnableDisable.java | 17 + .../edge/deye/batteryinverter/enums/Epo.java | 33 + .../batteryinverter/enums/FrequencyLevel.java | 22 + .../enums/FrequencyVariationRate.java | 33 + .../enums/GridCodeSelection.java | 27 + .../batteryinverter/enums/InterfaceType.java | 32 + .../enums/InverterWiringTopology.java | 16 + .../enums/ModulePowerLevel.java | 34 + .../enums/PhaseAngleAbrupt.java | 33 + .../enums/PowerRisingMode.java | 32 + .../enums/ProtocolSelection.java | 32 + .../enums/ReactivePowerControlMode.java | 34 + .../enums/SinexcelGridMode.java | 32 + .../batteryinverter/enums/SinexcelState.java | 40 + .../enums/SinglePhaseMode.java | 33 + .../deye/batteryinverter/enums/StartMode.java | 32 + .../deye/batteryinverter/enums/Switch.java | 32 + .../batteryinverter/enums/VoltageLevel.java | 23 + .../batteryinverter/statemachine/Context.java | 24 + .../statemachine/ErrorHandler.java | 46 + .../statemachine/GoRunningHandler.java | 43 + .../statemachine/GoStoppedHandler.java | 23 + .../statemachine/RunningHandler.java | 44 + .../statemachine/StateMachine.java | 70 ++ .../statemachine/StoppedHandler.java | 19 + .../statemachine/UndefinedHandler.java | 36 + .../openems/edge/deye/gridmeter/Config.java | 3 + .../deye/gridmeter/DeyeGridMeterImpl.java | 14 + 39 files changed, 2477 insertions(+) create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeye.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeyeImpl.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/Config.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ActivePowerControlMode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Baudrate.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BlackStartMode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BmsProtocolSelection.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CountryCode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CpuType.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/DcVoltageLevel.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/EnableDisable.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Epo.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyLevel.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyVariationRate.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/GridCodeSelection.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InterfaceType.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InverterWiringTopology.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ModulePowerLevel.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PhaseAngleAbrupt.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PowerRisingMode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ProtocolSelection.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ReactivePowerControlMode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelGridMode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelState.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinglePhaseMode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/StartMode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Switch.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/VoltageLevel.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/Context.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/ErrorHandler.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoRunningHandler.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoStoppedHandler.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/RunningHandler.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StateMachine.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StoppedHandler.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/UndefinedHandler.java diff --git a/io.openems.edge.batteryinverter.deye/readme.adoc b/io.openems.edge.batteryinverter.deye/readme.adoc index 46ceaa16a92..362b84c4748 100644 --- a/io.openems.edge.batteryinverter.deye/readme.adoc +++ b/io.openems.edge.batteryinverter.deye/readme.adoc @@ -1 +1,7 @@ = Deye Battery Inverter + +Implemented Natures:: +- SymmetricEss +- ManagedSymmetricEss + +https://github.com/OpenEMS/openems/tree/develop/io.openems.edge.ess.sinexcel[Source Code icon:github[]] \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeye.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeye.java new file mode 100644 index 00000000000..dc188d6ab82 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeye.java @@ -0,0 +1,949 @@ +package io.openems.edge.deye.batteryinverter; + +import io.openems.common.channel.AccessMode; +import io.openems.common.channel.Debounce; +import io.openems.common.channel.Level; +import io.openems.common.channel.PersistencePriority; +import io.openems.common.channel.Unit; +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.common.types.OpenemsType; +import io.openems.edge.batteryinverter.api.ManagedSymmetricBatteryInverter; +import io.openems.edge.batteryinverter.api.OffGridBatteryInverter; +import io.openems.edge.batteryinverter.api.SymmetricBatteryInverter; +import io.openems.edge.common.channel.BooleanDoc; +import io.openems.edge.common.channel.BooleanWriteChannel; +import io.openems.edge.common.channel.Doc; +import io.openems.edge.common.channel.IntegerDoc; +import io.openems.edge.common.channel.IntegerReadChannel; +import io.openems.edge.common.channel.value.Value; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.common.modbusslave.ModbusSlave; +import io.openems.edge.common.startstop.StartStoppable; +import io.openems.edge.common.sum.GridMode; +import io.openems.edge.deye.batteryinverter.enums.ActivePowerControlMode; +import io.openems.edge.deye.batteryinverter.enums.Baudrate; +import io.openems.edge.deye.batteryinverter.enums.BlackStartMode; +import io.openems.edge.deye.batteryinverter.enums.CpuType; +import io.openems.edge.deye.batteryinverter.enums.DcVoltageLevel; +import io.openems.edge.deye.batteryinverter.enums.Epo; +import io.openems.edge.deye.batteryinverter.enums.FrequencyVariationRate; +import io.openems.edge.deye.batteryinverter.enums.InterfaceType; +import io.openems.edge.deye.batteryinverter.enums.ModulePowerLevel; +import io.openems.edge.deye.batteryinverter.enums.PhaseAngleAbrupt; +import io.openems.edge.deye.batteryinverter.enums.PowerRisingMode; +import io.openems.edge.deye.batteryinverter.enums.ProtocolSelection; +import io.openems.edge.deye.batteryinverter.enums.ReactivePowerControlMode; +import io.openems.edge.deye.batteryinverter.enums.SinexcelGridMode; +import io.openems.edge.deye.batteryinverter.enums.SinglePhaseMode; +import io.openems.edge.deye.batteryinverter.enums.StartMode; +import io.openems.edge.deye.batteryinverter.enums.Switch; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; + +public interface BatteryInverterDeye extends OffGridBatteryInverter, ManagedSymmetricBatteryInverter, SymmetricBatteryInverter, OpenemsComponent, StartStoppable, ModbusSlave { + + public enum ChannelId implements io.openems.edge.common.channel.ChannelId { + STATE_MACHINE(Doc.of(State.values()) // + .text("Current State of State-Machine")), // + RUN_FAILED(Doc.of(Level.FAULT) // + .text("Running the Logic failed")), // + SET_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)// + .unit(Unit.WATT)), // + SET_REACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)// + .unit(Unit.VOLT_AMPERE_REACTIVE)), // + CHARGE_MAX_CURRENT(new IntegerDoc() // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.AMPERE)), // + DISCHARGE_MAX_CURRENT(new IntegerDoc() // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.AMPERE)), // + CHARGE_MAX_CURRENT_READ(new IntegerDoc() // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.AMPERE)), // + DISCHARGE_MAX_CURRENT_READ(new IntegerDoc() // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.AMPERE)), // + CHARGE_MAX_VOLTAGE(new IntegerDoc() // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.VOLT)), // + DISCHARGE_MIN_VOLTAGE(new IntegerDoc() // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.VOLT)), // + + ACTIVE_DISCHARGE_ENERGY_VALUE_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), + ACTIVE_DISCHARGE_ENERGY_VALUE_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), + ACTIVE_CHARGE_ENERGY_VALUE_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), + ACTIVE_CHARGE_ENERGY_VALUE_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), + + // when implementing Lithium-ion batteries, these two registers MUST be set to + // the same + TOPPING_CHARGE_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.VOLT)), + // when implementing Lithium-ion batteries, these two registers MUST be set to + // the same + FLOAT_CHARGE_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.VOLT)), // + + MANUFACTURER_AND_MODEL_NUMBER(Doc.of(OpenemsType.STRING) // + .accessMode(AccessMode.READ_ONLY)), // + SERIAL_NUMBER(Doc.of(OpenemsType.STRING) // + .persistencePriority(PersistencePriority.HIGH) // + .accessMode(AccessMode.READ_ONLY)), // + FAULT_STATUS(Doc.of(Level.FAULT) // + .accessMode(AccessMode.READ_ONLY)), // + ALERT_STATUS(Doc.of(Level.WARNING) // + .accessMode(AccessMode.READ_ONLY)), // + BATTERY_INVERTER_STATE(new BooleanDoc() // + .debounce(5, Debounce.FALSE_VALUES_IN_A_ROW_TO_SET_FALSE) // + .onChannelChange((self, value) -> self._setInverterState(value.get()))), + + INVERTER_GRID_MODE(new BooleanDoc() // + .debounce(5, Debounce.FALSE_VALUES_IN_A_ROW_TO_SET_FALSE) // + .text("On Grid") // + .onChannelChange((self, value) -> { + final GridMode gridMode; + if (!value.isDefined()) { + gridMode = GridMode.UNDEFINED; + } else if (value.get()) { + gridMode = GridMode.ON_GRID; + } else { + gridMode = GridMode.OFF_GRID; + } + self._setGridMode(gridMode); + })), + + ISLAND_MODE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DERATING_STATUS(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + ALLOW_GRID_CONNECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + STANDBY_STATUS(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + OBTAIN_FAULT_RECORD_FLAG(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + WRITE_POWER_GENERATION_INTO_EEPROM(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + INITIALIZE_DSP_PARAMETERS(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + MASTER_SLAVE_MODE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AC_OVER_VOLTAGE_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AC_UNDER_VOLTAGE_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AC_OVER_FREQUENCY_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AC_UNDER_FREQUENCY_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + GRID_VOLTAGE_UNBALANCE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + GRID_PHASE_REVERSE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + INVERTER_ISLAND(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + ON_GRID_OFF_GRID_SWITCH_OVER_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + OUTPUT_GROUND_FAULT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + GRID_PHASE_LOCK_FAILED(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + INTERNAL_AIR_OVER_TEMPERATURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + GRID_CONNECTED_CONDITION_TIME_OUT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + MODULE_RENUMBER_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + // Monitor parallel use + CANB_COMMUNICATION_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + POWER_FREQUENCY_SYNCHRONIZATION_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + CARRIER_SYNCHRONIZATION_FALURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + EPO_ERROR(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + MONITOR_PARAMETER_MISMATCH(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DSP_VERSION_ABNORMAL(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + CPLD_VERSION_ERROR(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + HARDWARE_VERSION_ERROR(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + // Monitor to DSP + CANA_COMMUNICATION_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AUXILARY_POWER_FAULT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + FAN_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_OVER_VOLTAGE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_LOW_VOLTAGE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_VOLTAGE_UNBALANCED(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AC_RELAY_SHORT_CIRCUIT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + OUTPUT_VOLTAGE_ABNORMAL(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + OUTPUT_CURRENT_UNBALANCED(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + OVER_TEMPERATURE_OF_HEAT_SINK(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + OUTPUT_OVER_LOAD_TOT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + GRID_CONTINUE_OVER_VOLTAGE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AC_SOFT_START_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + INVERTER_START_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AC_RELAY_IS_OPEN(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + U2_BOARD_COMMUNICATION_IS_ABNORMAL(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + AC_DC_COMPONENT_EXCESS(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + MASTER_SLAVE_SAMPLING_ABNORMALITY(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + PARAMETER_SETTING_ERROR(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + LOW_OFF_GRID_ENERGY(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + N_LINE_IS_NOT_CONNECTED(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + STANDBY_BUS_HEIGHT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + SINGLE_PHASE_WIRING_ERROR(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + EXCESSIVE_GRID_FREQUENCY_CHANGE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + ABRUPT_PHASE_ANGLE_FAULT_OF_POWER_GRID(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + GRID_CONNECTION_PARAMETER_CONFLICT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + EE_READING_ERROR_1(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + EE_READING_ERROR_2(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + FLASH_READING_ERROR(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + INVERTER_OVER_LOAD(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + BATTERY_PARAMETER_SETTING_ERROR(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + SLAVE_LOST_ALARM(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_CHARGING(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_DISCHARGING(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + BATTERY_FULLY_CHARGED(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + BATTERY_EMPTY(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_FAULT_STATUS(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_ALERT_STATUS(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_INPUT_OVER_VOLTAGE_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_INPUT_UNDER_VOLTAGE_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + BMS_ALERT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + BMS_COMMUNICATION_TIMEOUT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + EMS_COMMUNICATION_TIMEOUT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_SOFT_START_FAILED(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_RELAY_SHORT_CIRCUIT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_RELAY_SHORT_OPEN(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + BATTERY_POWEROVER_LOAD(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + BATTERY_POWER_OVER_LOAD(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_BUS_STARTING_FAILED(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_QUICK_CHECK_OVER_CURRENT(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + DC_OC(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_ONLY)), // + // AC L1-L2 RMS voltage + GRID_VOLTAGE_L1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIVOLT)), // + // AC L2-L3 RMS voltage + GRID_VOLTAGE_L2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIVOLT)), // + // AC L3-L1 RMS voltage + GRID_VOLTAGE_L3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIVOLT)), // + // AC L1 RMS current + GRID_CURRENT_L1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIAMPERE)), // + // AC L2 RMS current + GRID_CURRENT_L2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIAMPERE)), // + // AC L3 RMS current + GRID_CURRENT_L3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIAMPERE)), // + // AC frequency + FREQUENCY(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIHERTZ)), // + // AC L1 Active Power + ACTIVE_POWER_L1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.WATT)), // + // AC L2 Active Power + ACTIVE_POWER_L2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.WATT)), // + // AC L3 Active Power + ACTIVE_POWER_L3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.WATT)), // + // AC L1 Reactive Power + REACTIVE_POWER_L1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.VOLT_AMPERE_REACTIVE)), // + // AC L2 Reactive Power + REACTIVE_POWER_L2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.VOLT_AMPERE_REACTIVE)), // + // AC L3 Reactive Power + REACTIVE_POWER_L3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.VOLT_AMPERE_REACTIVE)), // + // AC L1 Apparent Power + APPERENT_POWER_L1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.VOLT_AMPERE)), // + // AC L2 Apparent Power + APPERENT_POWER_L2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.VOLT_AMPERE)), // + // AC L3 Apparent Power + APPERENT_POWER_L3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.VOLT_AMPERE)), // + // AC L1 Power Factor + COS_PHI_L1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_ONLY)), // + // AC L2 Power Factor + COS_PHI_L2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_ONLY)), // + // AC L3 Power Factor + COS_PHI_L3(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_ONLY)), // + // AC Apperent Power + APPARENT_POWER(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.VOLT_AMPERE)), // + // AC Power Factor + COS_PHI(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_ONLY)), // + + // Temperature of DC heat sink + TEMPERATURE_OF_AC_HEAT_SINK(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.DEGREE_CELSIUS)), // + // BUS+ side voltage + DC_VOLTAGE_POSITIVE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIVOLT)), // + // BUS- side voltage + DC_VOLTAGE_NEGATIVE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIVOLT)), // + // Target off-grid voltage bias + SET_OFF_GRID_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)// + .unit(Unit.MILLIVOLT)), // + // Target off-grid frequency bias + SET_OFF_GRID_FREQUENCY(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)// + .unit(Unit.MILLIHERTZ)), // + DC_POWER(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.WATT)), // + DC_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIVOLT)), // + DC_CURRENT(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIAMPERE)), // + DC_CHARGE_ENERGY(Doc.of(OpenemsType.LONG) // + .accessMode(AccessMode.READ_WRITE)// + .unit(Unit.CUMULATED_WATT_HOURS)), // + DC_DISCHARGE_ENERGY(Doc.of(OpenemsType.LONG) // + .accessMode(AccessMode.READ_WRITE)// + .unit(Unit.CUMULATED_WATT_HOURS)), // + TEMPERATURE_OF_DC_DC_HEAT_SINK(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.DEGREE_CELSIUS)), // + DC_RELAY_REAR_END_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.VOLT)), // + CHARGE_MAX_CURRENT_SETTING(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIAMPERE)), // + DISCHARGE_MAX_CURRENT_SETTING(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_ONLY)// + .unit(Unit.MILLIAMPERE)), // + IP_ADDRESS_BLOCK_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + IP_ADDRESS_BLOCK_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + IP_ADDRESS_BLOCK_3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + IP_ADDRESS_BLOCK_4(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + NETMASK_BLOCK_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + NETMASK_BLOCK_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + NETMASK_BLOCK_3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + NETMASK_BLOCK_4(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + GATEWAY_IP_BLOCK_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + GATEWAY_IP_BLOCK_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + GATEWAY_IP_BLOCK_3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + GATEWAY_IP_BLOCK_4(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + MAC(Doc.of(OpenemsType.STRING) // + .accessMode(AccessMode.READ_WRITE)), // + MODBUS_UNIT_ID(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + BAUDRATE(Doc.of(Baudrate.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // default 1 + INTERFACE_TYPE(Doc.of(InterfaceType.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // Takes effect after hard reset,0-modbus + COMMUNICATION_PROTOCOL_SELECTION(Doc.of(ProtocolSelection.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // Prevent unexpected results of communication failures.when EMS timeout + // enabled, watchdog will work and even reading will feed the watchdog + EMS_TIMEOUT(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // Enable ONLY when remote Emergency Stop Button is needed + EPO_ENABLE(Doc.of(Epo.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // Enable ONLY when remote BMS-inverter connection is needed + BMS_TIMEOUT(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // Takes effect after hard reset,0-modbus + BMS_PROTOCOL_SELECTION(Doc.of(ProtocolSelection.values()) // + .accessMode(AccessMode.READ_WRITE)), // + SET_GRID_MODE(Doc.of(SinexcelGridMode.values()) // + .accessMode(AccessMode.READ_WRITE)), // + BUZZER_ENABLE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + RESTORE_FACTORY_SETTING(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // To Start operation, only 1 will be accepted. Reading back value makes no + // sense + START_INVERTER(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // To Stop operation, only 1 will be accepted. Reading back value makes no sense + STOP_INVERTER(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // clear failure flag,when fault occurs, the system will stop and indicates + // fault.starting is invalid until the fault source is actually removed and this + // register is written 1. Reading back value makes no sense + CLEAR_FAILURE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.WRITE_ONLY)), // + // set the module to on grid mode. Reading back value makes no sense + SET_ON_GRID_MODE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // set the module to off grid mode. Reading back value makes no sense + SET_OFF_GRID_MODE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // set the module to standby mode,setpoint 0:IGBT switching ,setpoint 1:no IGBT + // switching,low consumption.let the inverter to halt the IGBT switching, to + // save the power consumption, but all relays are still closed. + // Reading back value makes no sense + SET_STANDBY_COMMAND(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + SET_SOFT_START(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + RESET_INSTRUCTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + GRID_STOP(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + VOLTAGE_LEVEL(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + FREQUENCY_LEVEL(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + INVERTER_WIRING_TOPOLOGY(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + SWITCHING_DEVICE_ACCESS_SETTING(Doc.of(Switch.values()) // + .accessMode(AccessMode.READ_WRITE)), // + MODULE_POWER_LEVEL(Doc.of(ModulePowerLevel.values()) // + .accessMode(AccessMode.READ_ONLY)), // + DC_VOLTAGE_LEVEL(Doc.of(DcVoltageLevel.values()) // + .accessMode(AccessMode.READ_ONLY)), // + CPU_TYPE(Doc.of(CpuType.values()) // + .accessMode(AccessMode.READ_WRITE)), // + OFF_GRID_AND_PARALLEL_ENABLE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + SET_DC_SOFT_START_EXTERNAL_CONTROL(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + GRID_OVER_VOLTAGE_PROTECTION_AMPLITUDE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_OVER_VOLTAGE_TRIP_TIME_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_OVER_VOLTAGE_TRIP_LEVEL_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_OVER_VOLTAGE_TRIP_TIME_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_VOLTAGE_TRIP_LEVEL_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_VOLTAGE_TRIP_TIME_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_VOLTAGE_TRIP_LEVEL_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_VOLTAGE_TRIP_TIME_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_VOLTAGE_TRIP_LEVEL_3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_VOLTAGE_TRIP_TIME_3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_OVER_FREQUENCY_TRIP_LEVEL_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_OVER_FREQUENCY_TRIP_TIME_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_OVER_FREQUENCY_TRIP_LEVEL_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_OVER_FREQUENCY_TRIP_TIME_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_FREQUENCY_TRIP_LEVEL_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_FREQUENCY_TRIP_TIME_1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_FREQUENCY_TRIP_LEVEL_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + AC_UNDER_FREQUENCY_TRIP_TIME_2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + RECONNECT_TIME(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // Anti-islanding is a CPUC RULE 21/HECO RULE14H/IEEE1547-requested function to + // make sure the inverter disconnect from the grid in case of blackout. + // This is to prevent the formation of an unintended island. The inverter design + // shall comply with the requirements of IEEE Std 1547 and UL 1741 standards (or + // latest versions) and be certified to have anti-islanding protection such that + // the synchronous inverter will automatically disconnect upon a utility system + // interruption + ANTI_ISLANDING(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // Frequency and Voltage Ride-Through. + // The ability to withstand voltage or frequency excursions outside defined + // limits without tripping or malfunctioning + FREQUENCY_VOLTAGE_RIDE_THROUGH(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // Grid-tied mode only, voltage and frequency setpoint the only setpoints + REACTIVE_POWER_CONTROL_MODE(Doc.of(ReactivePowerControlMode.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // To define how the power changes + POWER_RISING_MODE(Doc.of(PowerRisingMode.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // Grid-tied mode only, Volt/Watt control & Freq/Watt control means active power + // will be regulated by grid voltage/frequency following a curve/ramp rate given + // by HECO or CPUC or other local utility authority codes + ACTIVE_POWER_CONTROL_MODE(Doc.of(ActivePowerControlMode.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // Grid-tied mode only, voltage and frequency setpoint the only setpoints + GRID_VOLTAGE_ASYMMETRIC_DETECTON(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // Grid-tied mode only + CONTINUOUS_OVERVOLTAGE_DETECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // Grid-tied mode only,detect whether the grid is on-service at powered-up. + GRID_EXISTENCE_DETECTION_ON(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), + // Grid-tied mode only + NEUTRAL_FLOATING_DETECTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // if disabled, the inverter will start the AC voltage, then close the relay. In + // some off-grid cases, such as there are inductive loads or transformer, the + // in rush exciting current will trip the inverter. Enabling this register, the + // inverter will close the relay first try to limit the current and start the + // voltage slowly + OFF_GRID_BLACKSTART_MODE(Doc.of(BlackStartMode.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // Grid tied mode only. take effect after power off. + GRID_CODE_SELECTION(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + GRID_CONNECTED_ACTIVE_CAPACITY_LIMITATION_FUNCTION(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + GRID_ACTIVE_POWER_CAPACITY_SETTING(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + // Single mode enable and select + SINGLE_PHASE_MODE_SELECTION(Doc.of(SinglePhaseMode.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // Overvoltage drop active enable (only for EN50549 certification) + OVER_VOLTAGE_DROP_ACTIVE(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + // 0-Manual start,1-Auto start,default:0 + START_UP_MODE(Doc.of(StartMode.values()) // + .accessMode(AccessMode.READ_WRITE)), // + LOCAL_ID_SETTING(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // when implementing Lithium-ion batteries,this register MUST be set to 0 + CURRENT_FROM_TOPPING_CHARGING_TO_FLOAT_CHARGING(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + BATTERY_VOLTAGE_PROTECTION_LIMIT(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.VOLT)), // + LEAKAGE_CURRENT_DC_COMPONENT_DETECTOR(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + RESUME_AND_LIMIT_FREQUENCY(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + RESTORE_LOWER_FREQUENCY_OF_GRID_CONNECTION(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + VOLTAGE_REACTIVE_REFERENCE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + + // ratio * rated voltage,Available only when reactive power regulation mode is + // set to Volt/Var(53626). + VOLTAGE_AND_REACTIVE_POWER_ADJUSTMENT_POINT_V1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + VOLTAGE_AND_REACTIVE_POWER_ADJUSTMENT_POINT_V2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + VOLTAGE_AND_REACTIVE_POWER_ADJUSTMENT_POINT_V3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + VOLTAGE_AND_REACTIVE_POWER_ADJUSTMENT_POINT_V4(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + + // refer to HECO RULE 14, keep default value if no aware of it + MAX_CAPACITIVE_REACTIVE_REGULATION_Q1(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + INITIAL_CAPACITIVE_REACTIVE_REGULATION_Q2(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + INITIAL_INDUCTIVE_REACTIVE_REGULATION_Q3(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + MAX_INDUCTIVE_REACTIVE_REGULATION_Q4(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + VOLTAGE_AND_REACTIVE_RESPONSE_TIME(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + REACTIVE_FIRST_ORDER_RESPONSE_TIME(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + + // ratio * rated voltage, Available only when active power regulation + // mode(53636) is set to Volt/Watt and operating in discharge mode, follow the + // FVRT table given by HECO or CPUC or other local utility authority codes. + INITIAL_VOLTAGE_V_START(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + END_VOLTAGE_V_STOP(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + INITIAL_POWER_P_START(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + END_POWER_P_STOP(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + RETURN_TO_SERVICE_DELAY(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + VOLT_WATT_RESPONSE_TIME(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + + // Available only when active power regulation mode(53636) is set to Freq/Watt + // and operating in discharge mode. When the actual frequency is above the + // point, the active power will be regulated(lowered) with the ramp rate. In + // Australia, this register shall be fixed to 0.25Hz + START_OF_FREQUENY_DROP(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // The ramp rate is defined as multiple of set active power per hertz that above + // the above the Freq/Watt regulation point. Available only when active power + // regulation mode(53636) is set to Freq/Watt and operating in discharge mode. + // Example: Rated frequency is 60Hz, the target active power is set to 10kW, + // Freq/Watt regulation point is set to 2Hz, ramp rate is set as 0.5, If the + // actual frequency reaches 63Hz, the output active power will be + // 10kW-(63Hz-62Hz) x 0.5*(10kW/Hz) = 5kW + SLOPE_OF_FREQUENCY_DROP(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // AS4777 only, bias Bias from rated frequency + FREQUENCY_WATT_F_STOP_DISCHARGE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + FREQUENCY_WATT_F_STOP_CHARGE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // %Vrated,AS4777 only, ratio + VOLT_WATT_V_START_CHARGE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // SS takes effect when the inverter starts, or when the inverter is on "grid + // reconnection" after the trip caused by FVRT timeout + SOFT_START_RAMP_RATE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // RR takes effect in Volt-Watt or Freq-Watt mode when the grid is back to + // normal state and the inverter trying to go back to normal output. + // In other words, as long as the inverter does not trip, and the inverter had + // derated the output power, RR takes effect when the inverter tries to go back + // to normal output. Available only when Power rising mode is set to ramp + // mode(53626).If the value is 2.000, which means within 0.5 seconds the system + // can runs to full power output. + POWER_RAMP_RATE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // Available only when Constant PF is enabled,Negative inductive, positive + // capacitive + POWER_FACTOR_SETTING(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + // Available only when active power regulation mode(53636) is set to Freq/Watt + // and operating in discharge mode. When the actual frequency is above the + // point, the active power will be regulated(lowered) with the ramp rate + POWER_FACTOR_P1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + POWER_FACTOR_P2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + POWER_FACTOR_P3(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + POWER_FACTOR_P4(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + + // +(lagging), -(leading), + POWER_FACTOR_CURVE_MODE_P1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + POWER_FACTOR_CURVE_MODE_P2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + POWER_FACTOR_CURVE_MODE_P3(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + POWER_FACTOR_CURVE_MODE_P4(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + + // %Vrated + CONTINUOS_OVER_VOLTAGE_TRIP_THRESHOLD(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + FREQUENCY_VARIATION_RATE_TRIP_THRESHOLD(Doc.of(FrequencyVariationRate.values()) // + .accessMode(AccessMode.READ_WRITE)), // + PHASE_ANGLE_ABRUPT_TRIP_THRESHOLD(Doc.of(PhaseAngleAbrupt.values()) // + .accessMode(AccessMode.READ_WRITE)), // + // Available only when Power rising mode is set to ramp mode . once tripped + // after FVRT timeout, the inverter can reconnect to the grid when frequency or + // voltage is back to the thresholds defined as "grid is back to service". In + // HECO14 /CPUC 21, this register is unnecessary to + GRID_RECONNECTION_VOLTAGE_UPPER_LIMIT(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + GRID_RECONNECTION_VOLTAGE_LOWER_LIMIT(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // Available only when Power rising mode is set to ramp mode once tripped after + // FVRT timeout, the inverter can reconnect to the grid when frequency or + // voltage is back to the thresholds defined as "grid is back to service" + GRID_RECONNECTION_FREQUENCY_UPPER_LIMIT(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // Bias from rated frequency + GRID_RECONNECTION_FREQUENCY_LOWER_LIMIT(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + LOW_FREQUENCY_RAMP_RATE(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + // TODO Values check Meter options !!!!!!!!!!!!!!!!!! + METER_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE).unit(Unit.WATT)), // + + GRID_VOLTAGE_CALIBRATION_L1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + GRID_VOLTAGE_CALIBRATION_L2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + GRID_VOLTAGE_CALIBRATION_L3(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INVERTER_VOLTAGE_CALIBRATION_L1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INVERTER_VOLTAGE_CALIBRATION_L2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INVERTER_VOLTAGE_CALIBRATION_L3(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INDUCTOR_CURRENT_CALIBRATION_L1_PARAMETERS_1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INDUCTOR_CURRENT_CALIBRATION_L2_PARAMETERS_1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INDUCTOR_CURRENT_CALIBRATION_L3_PARAMETERS_1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INDUCTOR_CURRENT_CALIBRATION_L1_PARAMETERS_2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INDUCTOR_CURRENT_CALIBRATION_L2_PARAMETERS_2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + INDUCTOR_CURRENT_CALIBRATION_L3_PARAMETERS_2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + OUTPUT_CURRENT_CALIBRATION_L1(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + OUTPUT_CURRENT_CALIBRATION_L2(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + OUTPUT_CURRENT_CALIBRATION_L3(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + POSITIVE_BUS_VOLTAGE_CALIBRATION(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + NEGATIVE_BUS_VOLTAGE_CALIBRATION(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + DC_VOLTAGE_CALIBRATION(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + DC_CURRENT_CALIBRATION(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + DC_INDUCTOR_CURRENT_CALIBRATION(Doc.of(OpenemsType.FLOAT) // + .accessMode(AccessMode.READ_WRITE)), // + TIME_SETTING(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.WRITE_ONLY)), // + PASSWORD(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.WRITE_ONLY)), // + ACTIVE_POWER_1(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_ONLY)), + ACTIVE_POWER_2(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_ONLY) // + ),; + + private final Doc doc; + + private ChannelId(Doc doc) { + this.doc = doc; + } + + @Override + public Doc doc() { + return this.doc; + } + } + + /** + * Gets the Channel for {@link ChannelId#SET_ON_GRID_MODE}. + * + * @return the Channel + */ + public default BooleanWriteChannel getSetOnGridModeChannel() { + return this.channel(ChannelId.SET_ON_GRID_MODE); + } + + /** + * Gets the Set-On-Grid-Mode. See {@link ChannelId#SET_ON_GRID_MODE}. + * + * @return the Channel {@link Value} + */ + public default Value getSetOnGridMode() { + return this.getSetOnGridModeChannel().value(); + } + + /** + * Sets a the On-Grid-Mode. See {@link ChannelId#SET_ON_GRID_MODE}. + * + * @param value the next write value + * @throws OpenemsNamedException on error + */ + public default void setOnGridMode(Boolean value) throws OpenemsNamedException { + this.getSetOnGridModeChannel().setNextWriteValue(value); + } + + /** + * Gets the Channel for {@link SymmetricBatteryInverter.ChannelId#ACTIVE_POWER}. + * + * @return the Channel + */ + public default IntegerReadChannel getActive1PowerChannel() { + return this.channel(ChannelId.ACTIVE_POWER_1); + } + + /** + * Gets the Channel for {@link SymmetricBatteryInverter.ChannelId#ACTIVE_POWER}. + * + * @return the Channel + */ + public default IntegerReadChannel getActive2PowerChannel() { + return this.channel(ChannelId.ACTIVE_POWER_2); + } + + /** + * Gets the Channel for {@link ChannelId#SET_OFF_GRID_MODE}. + * + * @return the Channel + */ + public default BooleanWriteChannel getSetOffGridModeChannel() { + return this.channel(ChannelId.SET_OFF_GRID_MODE); + } + + /** + * Gets the Set-Off-Grid-Mode. See {@link ChannelId#SET_OFF_GRID_MODE}. + * + * @return the Channel {@link Value} + */ + public default Value getSetOffGridMode() { + return this.getSetOffGridModeChannel().value(); + } + + /** + * Sets a the Off-Grid-Mode. See {@link ChannelId#SET_OFF_GRID_MODE}. + * + * @param value the next write value + * @throws OpenemsNamedException on error + */ + public default void setOffGridMode(Boolean value) throws OpenemsNamedException { + this.getSetOffGridModeChannel().setNextWriteValue(value); + } + + /** + * Gets the Channel for {@link ChannelId#START_INVERTER}. + * + * @return the Channel + */ + public default BooleanWriteChannel getStartInverterChannel() { + return this.channel(ChannelId.START_INVERTER); + } + + /** + * Sends a START command to the inverter. See {@link ChannelId#START_INVERTER}. + * + * @throws OpenemsNamedException on error + */ + public default void setStartInverter() throws OpenemsNamedException { + this.getStartInverterChannel().setNextWriteValue(true); // true = START + } + + /** + * Gets the Channel for {@link ChannelId#STOP_INVERTER}. + * + * @return the Channel + */ + public default BooleanWriteChannel getStopInverterChannel() { + return this.channel(ChannelId.STOP_INVERTER); + } + + /** + * Sends a STOP command to the inverter. See {@link ChannelId#STOP_INVERTER}. + * + * @throws OpenemsNamedException on error + */ + public default void setStopInverter() throws OpenemsNamedException { + this.getStopInverterChannel().setNextWriteValue(true); // true = STOP + } + + /** + * Gets the Channel for {@link ChannelId#CLEAR_FAILURE}. + * + * @return the Channel + */ + public default BooleanWriteChannel getClearFailureChannel() { + return this.channel(ChannelId.CLEAR_FAILURE); + } + + /** + * Clear inverter failures. See {@link ChannelId#CLEAR_FAILURE}. + * + * @throws OpenemsNamedException on error + */ + public default void setClearFailure() throws OpenemsNamedException { + this.getClearFailureChannel().setNextWriteValue(true); + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeyeImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeyeImpl.java new file mode 100644 index 00000000000..9efd4a6f008 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeyeImpl.java @@ -0,0 +1,407 @@ +package io.openems.edge.deye.batteryinverter; + +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; + +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.ConfigurationPolicy; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; +import org.osgi.service.component.annotations.ReferencePolicyOption; +import org.osgi.service.event.propertytypes.EventTopics; +import org.osgi.service.metatype.annotations.Designate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.openems.common.channel.AccessMode; +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.common.exceptions.OpenemsException; +import io.openems.common.types.OptionsEnum; +import io.openems.edge.battery.api.Battery; +import io.openems.edge.batteryinverter.api.BatteryInverterConstraint; +import io.openems.edge.batteryinverter.api.ManagedSymmetricBatteryInverter; +import io.openems.edge.batteryinverter.api.OffGridBatteryInverter; +import io.openems.edge.batteryinverter.api.SymmetricBatteryInverter; +import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; +import io.openems.edge.bridge.modbus.api.BridgeModbus; +import io.openems.edge.bridge.modbus.api.ModbusComponent; +import io.openems.edge.bridge.modbus.api.ModbusProtocol; +import io.openems.edge.bridge.modbus.api.element.SignedWordElement; +import io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask; +import io.openems.edge.common.channel.BooleanWriteChannel; +import io.openems.edge.common.channel.IntegerWriteChannel; +import io.openems.edge.common.channel.WriteChannel; +import io.openems.edge.common.component.ComponentManager; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.common.event.EdgeEventConstants; +import io.openems.edge.common.modbusslave.ModbusSlaveTable; +import io.openems.edge.common.startstop.StartStop; +import io.openems.edge.common.startstop.StartStoppable; +import io.openems.edge.common.taskmanager.Priority; +import io.openems.edge.common.type.TypeUtils; +import io.openems.edge.deye.batteryinverter.enums.EnableDisable; +import io.openems.edge.deye.batteryinverter.enums.FrequencyLevel; +import io.openems.edge.deye.batteryinverter.enums.GridCodeSelection; +import io.openems.edge.deye.batteryinverter.enums.PowerRisingMode; +import io.openems.edge.deye.batteryinverter.enums.VoltageLevel; +import io.openems.edge.deye.batteryinverter.statemachine.Context; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; +import io.openems.edge.ess.power.api.Phase; +import io.openems.edge.ess.power.api.Pwr; +import io.openems.edge.ess.power.api.Relationship; +import io.openems.edge.timedata.api.Timedata; +import io.openems.edge.timedata.api.TimedataProvider; +import io.openems.edge.timedata.api.utils.CalculateEnergyFromPower; + +@Designate(ocd = Config.class, factory = true) +@Component(// + name = "Battery-Inverter.Deye", // + immediate = true, // + configurationPolicy = ConfigurationPolicy.REQUIRE // +) +@EventTopics({ // + EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE, // + EdgeEventConstants.TOPIC_CYCLE_BEFORE_PROCESS_IMAGE // +}) +public class BatteryInverterDeyeImpl extends AbstractOpenemsModbusComponent + implements BatteryInverterDeye, OffGridBatteryInverter, ManagedSymmetricBatteryInverter, + SymmetricBatteryInverter, ModbusComponent, OpenemsComponent, TimedataProvider, StartStoppable { + + public static final int DEFAULT_EMS_TIMEOUT = 60; + public static final int DEFAULT_BMS_TIMEOUT = 0; + public static final EnableDisable DEFAULT_GRID_EXISTENCE_DETECTION_ON = EnableDisable.DISABLE; + public static final PowerRisingMode DEFAULT_POWER_RISING_MODE = PowerRisingMode.STEP; + + private static final int MAX_CURRENT = 90; // [A] + private static final int MAX_TOPPING_CHARGE_VOLTAGE = 750; + + private final Logger log = LoggerFactory.getLogger(BatteryInverterDeyeImpl.class); + private final StateMachine stateMachine = new StateMachine(State.UNDEFINED); + + private final CalculateEnergyFromPower calculateChargeEnergy = new CalculateEnergyFromPower(this, + SymmetricBatteryInverter.ChannelId.ACTIVE_CHARGE_ENERGY); + private final CalculateEnergyFromPower calculateDischargeEnergy = new CalculateEnergyFromPower(this, + SymmetricBatteryInverter.ChannelId.ACTIVE_DISCHARGE_ENERGY); + + @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL) + private volatile Timedata timedata = null; + + @Reference + private ComponentManager componentManager; + + @Reference + private ConfigurationAdmin cm; + + @Override + @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) + protected void setModbus(BridgeModbus modbus) { + super.setModbus(modbus); + } + + protected Config config; + + public BatteryInverterDeyeImpl() throws OpenemsNamedException { + super(// + OpenemsComponent.ChannelId.values(), // + ModbusComponent.ChannelId.values(), // + SymmetricBatteryInverter.ChannelId.values(), // + ManagedSymmetricBatteryInverter.ChannelId.values(), // + StartStoppable.ChannelId.values(), // + OffGridBatteryInverter.ChannelId.values(), // + BatteryInverterDeye.ChannelId.values() // + ); + } + + @Override + protected ModbusProtocol defineModbusProtocol() throws OpenemsException { + return new ModbusProtocol(this, + new FC3ReadRegistersTask(672, Priority.HIGH, m(BatteryInverterDeye.ChannelId.ACTIVE_POWER_1, + new SignedWordElement(672)),m(BatteryInverterDeye.ChannelId.ACTIVE_POWER_2, + new SignedWordElement(673)))); + } + + @Activate + private void activate(ComponentContext context, Config config) throws OpenemsNamedException { + this.config = config; + if (super.activate(context, config.id(), config.alias(), config.enabled(), config.modbusUnitId(), this.cm, "Modbus", + config.modbus_id())) { + return; + } + } + + @Override + @Deactivate + protected void deactivate() { + super.deactivate(); + } + + @Override + public void run(Battery battery, int setActivePower, int setReactivePower) throws OpenemsNamedException { + // Store the current State + this.channel(BatteryInverterDeye.ChannelId.STATE_MACHINE).setNextValue(this.stateMachine.getCurrentState()); + + // Initialize 'Start-Stop' Channel + this._setStartStop(StartStop.UNDEFINED); + + // Set Default Settings + this.setDefaultSettings(); + + // Set Battery Limits + this.setBatteryLimits(battery); + + // Calculate the Energy values from ActivePower. + this.calculateEnergy(); + + // Prepare Context + var context = new Context(this, this.config, this.targetGridMode.get(), setActivePower, setReactivePower); + + // Call the StateMachine + try { + this.stateMachine.run(context); + + this.channel(BatteryInverterDeye.ChannelId.RUN_FAILED).setNextValue(false); + + } catch (OpenemsNamedException e) { + this.channel(BatteryInverterDeye.ChannelId.RUN_FAILED).setNextValue(true); + this.logError(this.log, "StateMachine failed: " + e.getMessage()); + } + } + + /** + * Updates the Channel if its current value is not equal to the new value. + * + * @param channelId Sinexcel Channel-Id + * @param value {@link OptionsEnum} value. + * @throws IllegalArgumentException on error + */ + private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, OptionsEnum value) + throws IllegalArgumentException, OpenemsNamedException { + this.updateIfNotEqual(channelId, value.getValue()); + } + + /** + * Updates the Channel if its current value is not equal to the new value. + * + * @param channelId Sinexcel Channel-Id + * @param newValue Integer value. + * @throws IllegalArgumentException on error + */ + private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, Integer newValue) + throws IllegalArgumentException { + WriteChannel channel = this.channel(channelId); + var currentValue = channel.value(); + if (currentValue.isDefined() && !Objects.equals(currentValue.get(), newValue)) { + try { + channel.setNextWriteValue(newValue); + } catch (OpenemsNamedException e) { + this.logWarn(this.log, "Unable to update Channel [" + channel.address() + "] from [" + currentValue + + "] to [" + newValue + "]"); + e.printStackTrace(); + } + } + } + + private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, VoltageLevel voltageLevel) + throws IllegalArgumentException, OpenemsNamedException { + IntegerWriteChannel channel = this.channel(channelId); + channel.setNextWriteValue(voltageLevel.getValue()); + } + + private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, FrequencyLevel frequencyLevel) + throws IllegalArgumentException, OpenemsNamedException { + IntegerWriteChannel channel = this.channel(channelId); + channel.setNextWriteValue(frequencyLevel.getValue()); + } + + private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, GridCodeSelection gridCodeSelection) + throws IllegalArgumentException, OpenemsNamedException { + IntegerWriteChannel channel = this.channel(channelId); + channel.setNextWriteValue(gridCodeSelection.getValue()); + } + + private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, EnableDisable value) + throws IllegalArgumentException, OpenemsNamedException { + BooleanWriteChannel channel = this.channel(channelId); + switch (value) { + case ENABLE: + channel.setNextWriteValue(true); + break; + case DISABLE: + channel.setNextWriteValue(false); + break; + } + } + + /** + * Sets some default settings on the inverter, like Timeout. + * + * @throws OpenemsNamedException on error + */ + private void setDefaultSettings() throws OpenemsNamedException { + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.EMS_TIMEOUT, DEFAULT_EMS_TIMEOUT); + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.BMS_TIMEOUT, DEFAULT_BMS_TIMEOUT); + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.GRID_EXISTENCE_DETECTION_ON, + DEFAULT_GRID_EXISTENCE_DETECTION_ON); + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.POWER_RISING_MODE, DEFAULT_POWER_RISING_MODE); + + switch (this.config.countryCode()) { + case AUSTRIA: + case GERMANY: + case SWITZERLAND: + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.VOLTAGE_LEVEL, VoltageLevel.V_400); + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.FREQUENCY_LEVEL, FrequencyLevel.HZ_50); + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.GRID_CODE_SELECTION, GridCodeSelection.VDE); + break; + } + + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.INVERTER_WIRING_TOPOLOGY, this.config.emergencyPower()); + } + + /** + * Sets the Battery Limits. + * + * @param battery the linked {@link Battery} + * @throws OpenemsNamedException on error + */ + private void setBatteryLimits(Battery battery) throws OpenemsNamedException { + // Upper voltage limit of battery protection >= Topping charge voltage >= Float + // charge voltage >= Lower voltage limit of battery protection (814 >= 809 >= + // 808 >= 813). + // Discharge Min Voltage + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.DISCHARGE_MIN_VOLTAGE, + battery.getDischargeMinVoltage().get()); + + // Charge Max Voltage + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.CHARGE_MAX_VOLTAGE, battery.getChargeMaxVoltage().get()); + + // Topping Charge Voltage + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.TOPPING_CHARGE_VOLTAGE, + TypeUtils.min(battery.getChargeMaxVoltage().get(), MAX_TOPPING_CHARGE_VOLTAGE)); + + // Float Charge Voltage + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.FLOAT_CHARGE_VOLTAGE, + TypeUtils.min(battery.getChargeMaxVoltage().get(), MAX_TOPPING_CHARGE_VOLTAGE)); + + // Discharge Max Current + // negative value is corrected as zero + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.DISCHARGE_MAX_CURRENT, + TypeUtils.fitWithin(0 /* enforce positive */, MAX_CURRENT, battery.getDischargeMaxCurrent().orElse(0))); + + // Charge Max Current + // negative value is corrected as zero + this.updateIfNotEqual(BatteryInverterDeye.ChannelId.CHARGE_MAX_CURRENT, + TypeUtils.fitWithin(0 /* enforce positive */, MAX_CURRENT, battery.getChargeMaxCurrent().orElse(0))); + } + + @Override + public String debugLog() { + return "MOIN - L:" + this.getActivePower().asString(); + } + + private final AtomicReference startStopTarget = new AtomicReference<>(StartStop.UNDEFINED); + + @Override + public void setStartStop(StartStop value) { + if (this.startStopTarget.getAndSet(value) != value) { + // Set only if value changed + this.stateMachine.forceNextState(State.UNDEFINED); + } + } + + /** + * Gets the inverter start-stop target. + * + * @return {@link StartStop} + */ + public StartStop getStartStopTarget() { + switch (this.config.startStop()) { + case AUTO: + // read StartStop-Channel + return this.startStopTarget.get(); + + case START: + // force START + return StartStop.START; + + case STOP: + // force STOP + return StartStop.STOP; + } + + assert false; + return StartStop.UNDEFINED; // can never happen + } + + protected final AtomicReference targetGridMode = new AtomicReference<>(TargetGridMode.GO_ON_GRID); + + @Override + public void setTargetGridMode(TargetGridMode targetGridMode) { + if (this.targetGridMode.getAndSet(targetGridMode) != targetGridMode) { + // Set only if value changed + this.stateMachine.forceNextState(State.UNDEFINED); + } + } + + @Override + public BatteryInverterConstraint[] getStaticConstraints() throws OpenemsException { + if (this.stateMachine.getCurrentState() == State.RUNNING) { + return BatteryInverterConstraint.NO_CONSTRAINTS; + + } + // Block any power as long as we are not RUNNING + return new BatteryInverterConstraint[] { // + new BatteryInverterConstraint("Sinexcel inverter not ready", Phase.ALL, Pwr.REACTIVE, // + Relationship.EQUALS, 0d), // + new BatteryInverterConstraint("Sinexcel inverter not ready", Phase.ALL, Pwr.ACTIVE, // + Relationship.EQUALS, 0d) // + }; + } + + @Override + public int getPowerPrecision() { + return 100; + } + + @Override + public ModbusSlaveTable getModbusSlaveTable(AccessMode accessMode) { + return new ModbusSlaveTable(// + OpenemsComponent.getModbusSlaveNatureTable(accessMode), // + SymmetricBatteryInverter.getModbusSlaveNatureTable(accessMode), // + ManagedSymmetricBatteryInverter.getModbusSlaveNatureTable(accessMode) // + ); + } + + /** + * Calculate the Energy values from ActivePower. + */ + private void calculateEnergy() { + // Calculate Energy + var activePower1 = this.getActive1PowerChannel().value().get(); + var activePower2 = this.getActive2PowerChannel().value().get(); + var activePower = activePower1 + activePower2; + if (activePower1 == null && activePower2 == null) { + // Not available + this.calculateChargeEnergy.update(null); + this.calculateDischargeEnergy.update(null); + } else if (activePower > 0) { + // Buy-From-Grid + this.calculateChargeEnergy.update(0); + this.calculateDischargeEnergy.update(activePower); + } else { + // Sell-To-Grid + this.calculateChargeEnergy.update(activePower * -1); + this.calculateDischargeEnergy.update(0); + } + } + + @Override + public Timedata getTimedata() { + return this.timedata; + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/Config.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/Config.java new file mode 100644 index 00000000000..26202dff197 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/Config.java @@ -0,0 +1,41 @@ +package io.openems.edge.deye.batteryinverter; + +import io.openems.edge.deye.batteryinverter.enums.CountryCode; +import io.openems.edge.deye.batteryinverter.enums.EnableDisable; +import org.osgi.service.metatype.annotations.AttributeDefinition; +import org.osgi.service.metatype.annotations.ObjectClassDefinition; + +import io.openems.edge.common.startstop.StartStopConfig; + +@ObjectClassDefinition(// + name = "Battery-Inverter Deye", // + description = "Implements the Deye battery inverter.") +public @interface Config { + + @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") + String id() default "batteryInverter0"; + + @AttributeDefinition(name = "Alias", description = "Human-readable name of this Component; defaults to Component-ID") + String alias() default ""; + + @AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?") + boolean enabled() default true; + + @AttributeDefinition(name = "Start/stop behaviour?", description = "Should this Component be forced to start or stop?") + StartStopConfig startStop() default StartStopConfig.AUTO; + + @AttributeDefinition(name = "Modbus-ID", description = "ID of Modbus bridge.") + String modbus_id(); + + @AttributeDefinition(name = "Modbus Unit-ID", description = "The Unit-ID of the Modbus device.") + int modbusUnitId() default 1; + + @AttributeDefinition(name = "Country Code", description = "Selection of the country code.") CountryCode countryCode() default CountryCode.GERMANY; + + @AttributeDefinition(name = "Is emergency power enabled?", description = "Emergency power enable/disable.") EnableDisable emergencyPower() default EnableDisable.DISABLE; + + @AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID'.") + String Modbus_target() default "(enabled=true)"; + + String webconsole_configurationFactory_nameHint() default "Battery-Inverter Deye [{id}]"; +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ActivePowerControlMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ActivePowerControlMode.java new file mode 100644 index 00000000000..d9691bbba40 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ActivePowerControlMode.java @@ -0,0 +1,34 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum ActivePowerControlMode implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + CONTANT_ACTIVE_POWER(0, "Constant Active Power"), // + VOLT_WATT_ENABLED(1, "Volt watt enabled"), // + CONSTANT_PF(2, "Constant power factor"), // + WATT_PF_ENABLED(3, "Watt power factor enabled");// + + private final int value; + private final String name; + + private ActivePowerControlMode(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Baudrate.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Baudrate.java new file mode 100644 index 00000000000..74194f196a1 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Baudrate.java @@ -0,0 +1,33 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +//default 0 +public enum Baudrate implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + B_19200(0, "19200"), // + B_9600(1, "9600"); // + + private final int value; + private final String name; + + private Baudrate(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BlackStartMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BlackStartMode.java new file mode 100644 index 00000000000..1abb25b25b2 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BlackStartMode.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum BlackStartMode implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + NORMAL_STARTUP(0, "Normal Start Up"), // + BLACK_STARTUP(1, "Black Start Up");// + + private final int value; + private final String name; + + private BlackStartMode(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BmsProtocolSelection.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BmsProtocolSelection.java new file mode 100644 index 00000000000..ca7794a37ff --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BmsProtocolSelection.java @@ -0,0 +1,34 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum BmsProtocolSelection implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + ENERGY_PORT(0, "EP"), // + ALPHA(1, "Alpha-Ess"), // + PYLONTECH(2, "Pylontech"), // + BMSER(3, "Bmser"); // + + private final int value; + private final String name; + + private BmsProtocolSelection(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CountryCode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CountryCode.java new file mode 100644 index 00000000000..9c20f47ece2 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CountryCode.java @@ -0,0 +1,18 @@ +package io.openems.edge.deye.batteryinverter.enums; + +public enum CountryCode { + + GERMANY("Germany"), // + AUSTRIA("Austria"), // + SWITZERLAND("Switzerland"); + + private final String value; + + private CountryCode(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CpuType.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CpuType.java new file mode 100644 index 00000000000..38a5ae32b66 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CpuType.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum CpuType implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + SINGLE_CPU(0, "Single Cpu"), // + DOUBLE_CPU(1, "Double Cpu");// + + private final int value; + private final String name; + + private CpuType(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/DcVoltageLevel.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/DcVoltageLevel.java new file mode 100644 index 00000000000..47cc6fe8809 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/DcVoltageLevel.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum DcVoltageLevel implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + V_750(0, "750 V"), // + V_830(1, "830 V");// + + private final int value; + private final String name; + + private DcVoltageLevel(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/EnableDisable.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/EnableDisable.java new file mode 100644 index 00000000000..6687d51ff7a --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/EnableDisable.java @@ -0,0 +1,17 @@ +package io.openems.edge.deye.batteryinverter.enums; + +public enum EnableDisable { + + ENABLE("Enable"), // + DISABLE("Disable"); + + private final String value; + + private EnableDisable(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Epo.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Epo.java new file mode 100644 index 00000000000..4e041753ab6 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Epo.java @@ -0,0 +1,33 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum Epo implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + INVALID(0, "Modbus"), // + EPO(1, "Sunspec"), // + DRMO(2, "Sunspec");// + + private final int value; + private final String name; + + private Epo(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyLevel.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyLevel.java new file mode 100644 index 00000000000..c76850b1b1a --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyLevel.java @@ -0,0 +1,22 @@ +package io.openems.edge.deye.batteryinverter.enums; + +public enum FrequencyLevel { + HZ_50("50 Hz", 0), // + HZ_60("60 Hz", 1);// + + private final String name; + private final int value; + + private FrequencyLevel(String name, int value) { + this.name = name; + this.value = value; + } + + public String getName() { + return this.name; + } + + public int getValue() { + return this.value; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyVariationRate.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyVariationRate.java new file mode 100644 index 00000000000..bb86a05d727 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyVariationRate.java @@ -0,0 +1,33 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum FrequencyVariationRate implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + DISABLED(0, "Disabled"), // + RATE_0125(1, "Rate limit 0.125 Hz/s"), // + RATE_02(2, "Rate limit 0.2 Hz/s");// + + private final int value; + private final String name; + + private FrequencyVariationRate(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/GridCodeSelection.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/GridCodeSelection.java new file mode 100644 index 00000000000..429deb65b58 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/GridCodeSelection.java @@ -0,0 +1,27 @@ +package io.openems.edge.deye.batteryinverter.enums; + +public enum GridCodeSelection { + SA1741("SA1741", 0), // + VDE("VDE", 1), // + AUSTRALIAN("Australian", 2), // + G99("G99", 3), // + HAWAIIAN("Hawaiian", 4), // + EN50549("EN50549", 5), // + AUSTRIA_TYPEA("Austria Type A", 6);// + + private final String name; + private final int value; + + private GridCodeSelection(String name, int value) { + this.name = name; + this.value = value; + } + + public String getName() { + return this.name; + } + + public int getValue() { + return this.value; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InterfaceType.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InterfaceType.java new file mode 100644 index 00000000000..96d71d9ac4e --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InterfaceType.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum InterfaceType implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + RS_485(0, "RS-485"), // + ETHERNET(1, "Ethernet"); // + + private final int value; + private final String name; + + private InterfaceType(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InverterWiringTopology.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InverterWiringTopology.java new file mode 100644 index 00000000000..3d19ac3e156 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InverterWiringTopology.java @@ -0,0 +1,16 @@ +package io.openems.edge.deye.batteryinverter.enums; + +public enum InverterWiringTopology { + THREE_PHASE_FOUR_WIRE("3P4W"), // + THREE_PHASE_THREE_WIRE("3P3W or 3P3W+N"); // + + private final String value; + + private InverterWiringTopology(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ModulePowerLevel.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ModulePowerLevel.java new file mode 100644 index 00000000000..8df965bcd39 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ModulePowerLevel.java @@ -0,0 +1,34 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum ModulePowerLevel implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + TEN_KW(0, " 10 kW"), // + TWENTY_KW(1, "20 kW"), // + THIRTY_KW(2, "30 kW"), // + TWENTY_NINE_KW(3, "29 kW"); // + + private final int value; + private final String name; + + private ModulePowerLevel(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PhaseAngleAbrupt.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PhaseAngleAbrupt.java new file mode 100644 index 00000000000..b1160a7cad8 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PhaseAngleAbrupt.java @@ -0,0 +1,33 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum PhaseAngleAbrupt implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + DISABLED(0, "Disabled"), // + ANGLE_ABRUPT_LIMIT_12_DEGREE(1, "Angle abrupt limit 12 deg"), // + ANGLE_ABRUPT_LIMIT_6_DEGREE(2, "Angle abrupt limit 6 deg"); // + + private final int value; + private final String name; + + private PhaseAngleAbrupt(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PowerRisingMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PowerRisingMode.java new file mode 100644 index 00000000000..f0fba7ebd3d --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PowerRisingMode.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum PowerRisingMode implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + STEP(0, "Step Function"), // + RAMP(1, "Ramp Function");// + + private final int value; + private final String name; + + private PowerRisingMode(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ProtocolSelection.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ProtocolSelection.java new file mode 100644 index 00000000000..f527df7f2e8 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ProtocolSelection.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum ProtocolSelection implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + MODBUS(0, "Modbus"), // + SUNSPEC(1, "Sunspec"); // + + private final int value; + private final String name; + + private ProtocolSelection(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ReactivePowerControlMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ReactivePowerControlMode.java new file mode 100644 index 00000000000..e0a44553e4b --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ReactivePowerControlMode.java @@ -0,0 +1,34 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum ReactivePowerControlMode implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + CONSTANT_REACTIVE_POWER(0, "Constant Reactive Power"), // + VOLT_VAR_ENABLED(1, "Volt Var Enabled"), // + CONSTANT_PF(2, "Constanr Power Factor"), // + WATT_PF_ENABLED(3, "Watt Power Factor Enabled"); // + + private final int value; + private final String name; + + private ReactivePowerControlMode(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelGridMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelGridMode.java new file mode 100644 index 00000000000..a4a720775f2 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelGridMode.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum SinexcelGridMode implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + ON_GRID(0, "On Grid"), // + OFF_GRID(1, "Off Grid"); // + + private final int value; + private final String name; + + private SinexcelGridMode(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelState.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelState.java new file mode 100644 index 00000000000..144cc4f2c15 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelState.java @@ -0,0 +1,40 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum SinexcelState implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + OFF(1, "Off"), // + SLEEPING(2, "Sleeping"), // + STARTING(3, "Starting"), // + MPPT(4, "MPPT"), // + THROTTLED(5, "Throttled"), // + SHUTTINGDOWN(6, "Shutting Down"), // + FAULT(7, "Fault"), // + STANDBY(8, "Standby"), // + STARTED(9, "Started"); + + private final int value; + private final String option; + + private SinexcelState(int value, String option) { + this.value = value; + this.option = option; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.option; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } + +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinglePhaseMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinglePhaseMode.java new file mode 100644 index 00000000000..30396d97c81 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinglePhaseMode.java @@ -0,0 +1,33 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum SinglePhaseMode implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + DISABLE(0, "Disable"), // + SINGLE_PHASE_230V(1, "Single Phae 230V"), // + SINGLE_PHASE_480V(2, "Single Phase 480V");// + + private final int value; + private final String name; + + private SinglePhaseMode(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/StartMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/StartMode.java new file mode 100644 index 00000000000..b2d985d7cd5 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/StartMode.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum StartMode implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + MANUAL(0, "Manual Start"), // + AUTO(1, "Auto Start"); // + + private final int value; + private final String name; + + private StartMode(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Switch.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Switch.java new file mode 100644 index 00000000000..aedd0fa157c --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Switch.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.batteryinverter.enums; + +import io.openems.common.types.OptionsEnum; + +public enum Switch implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + NO_SWITCH(0, "No Switch"), // + SWITCH(1, "Switch");// + + private final int value; + private final String name; + + private Switch(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/VoltageLevel.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/VoltageLevel.java new file mode 100644 index 00000000000..3a04e4106c8 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/VoltageLevel.java @@ -0,0 +1,23 @@ +package io.openems.edge.deye.batteryinverter.enums; + +public enum VoltageLevel { + V_380("380 V", 0), // + V_400("400 V", 1), // + V_480("480 V", 2); // + + private final String name; + private final int value; + + private VoltageLevel(String name, int value) { + this.name = name; + this.value = value; + } + + public String getName() { + return this.name; + } + + public int getValue() { + return this.value; + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/Context.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/Context.java new file mode 100644 index 00000000000..1e0e20c445b --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/Context.java @@ -0,0 +1,24 @@ +package io.openems.edge.deye.batteryinverter.statemachine; + +import io.openems.edge.batteryinverter.api.OffGridBatteryInverter; +import io.openems.edge.deye.batteryinverter.BatteryInverterDeyeImpl; +import io.openems.edge.deye.batteryinverter.Config; +import io.openems.edge.common.statemachine.AbstractContext; + +public class Context extends AbstractContext { + + protected final Config config; + protected final OffGridBatteryInverter.TargetGridMode targetGridMode; + protected final int setActivePower; + protected final int setReactivePower; + + public Context(BatteryInverterDeyeImpl parent, Config config, OffGridBatteryInverter.TargetGridMode targetGridMode, int setActivePower, + int setReactivePower) { + super(parent); + this.config = config; + this.targetGridMode = targetGridMode; + this.setActivePower = setActivePower; + this.setReactivePower = setReactivePower; + } + +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/ErrorHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/ErrorHandler.java new file mode 100644 index 00000000000..af24355c131 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/ErrorHandler.java @@ -0,0 +1,46 @@ +package io.openems.edge.deye.batteryinverter.statemachine; + +import java.time.Duration; +import java.time.Instant; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.edge.deye.batteryinverter.BatteryInverterDeye; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; +import io.openems.edge.common.channel.BooleanWriteChannel; +import io.openems.edge.common.statemachine.StateHandler; + +public class ErrorHandler extends StateHandler { + + private static final int WAIT_SECONDS = 120; + + private Instant entryAt = Instant.MIN; + + @Override + protected void onEntry(Context context) throws OpenemsNamedException { + this.entryAt = Instant.now(); + + // Clear Failures + this.setClearFailureCommand(context); + + // Try to stop systems + final var inverter = context.getParent(); + inverter.setStopInverter(); + } + + @Override + public State runAndGetNextState(Context context) throws OpenemsNamedException { + if (Duration.between(this.entryAt, Instant.now()).getSeconds() > WAIT_SECONDS) { + // Try again + return State.UNDEFINED; + } + + // Wait + return State.ERROR; + } + + private void setClearFailureCommand(Context context) throws OpenemsNamedException { + BooleanWriteChannel setClearFailureCmd = context.getParent() + .channel(BatteryInverterDeye.ChannelId.CLEAR_FAILURE); + setClearFailureCmd.setNextWriteValue(true); // 1: true, other: illegal + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoRunningHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoRunningHandler.java new file mode 100644 index 00000000000..34dd6333aed --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoRunningHandler.java @@ -0,0 +1,43 @@ +package io.openems.edge.deye.batteryinverter.statemachine; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; +import io.openems.edge.common.statemachine.StateHandler; + +public class GoRunningHandler extends StateHandler { + + @Override + public State runAndGetNextState(Context context) throws OpenemsNamedException { + final var inverter = context.getParent(); + + /* + * Be sure to set the correct target grid mode + */ + var setOnGridMode = inverter.getSetOnGridMode().get(); + var setOffGridMode = inverter.getSetOffGridMode().get(); + switch (context.targetGridMode) { + case GO_ON_GRID: + if (setOnGridMode == Boolean.FALSE || setOffGridMode == Boolean.TRUE) { + inverter.setOnGridMode(true); + return State.GO_RUNNING; + } + break; + case GO_OFF_GRID: + if (setOnGridMode == Boolean.TRUE || setOffGridMode == Boolean.FALSE) { + inverter.setOffGridMode(true); + return State.GO_RUNNING; + } + break; + } + + inverter.setStartInverter(); + + if (inverter.getInverterState().get() == Boolean.TRUE) { + // Inverter is ON + return State.RUNNING; + } + // Still waiting + return State.GO_RUNNING; + } + +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoStoppedHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoStoppedHandler.java new file mode 100644 index 00000000000..f570503c526 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoStoppedHandler.java @@ -0,0 +1,23 @@ +package io.openems.edge.deye.batteryinverter.statemachine; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; +import io.openems.edge.common.statemachine.StateHandler; + +public class GoStoppedHandler extends StateHandler { + + @Override + public State runAndGetNextState(Context context) throws OpenemsNamedException { + final var inverter = context.getParent(); + + inverter.setStopInverter(); + + if (inverter.getInverterState().get() == Boolean.FALSE) { + // Inverter is OFF + return State.STOPPED; + } + // Still waiting + return State.GO_STOPPED; + } + +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/RunningHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/RunningHandler.java new file mode 100644 index 00000000000..727206eaa19 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/RunningHandler.java @@ -0,0 +1,44 @@ +package io.openems.edge.deye.batteryinverter.statemachine; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.edge.deye.batteryinverter.BatteryInverterDeye; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; +import io.openems.edge.common.channel.IntegerWriteChannel; +import io.openems.edge.common.startstop.StartStop; +import io.openems.edge.common.statemachine.StateHandler; + +public class RunningHandler extends StateHandler { + + @Override + public State runAndGetNextState(Context context) throws OpenemsNamedException { + final var inverter = context.getParent(); + + if (inverter.hasFaults() || inverter.getInverterState().get() == Boolean.FALSE) { + return State.UNDEFINED; + } + + // Mark as started + inverter._setStartStop(StartStop.START); + + // Apply Active and Reactive Power Set-Points + this.applyPower(context); + + return State.RUNNING; + } + + /** + * Applies the Active and Reactive Power Set-Points. + * + * @param context the {@link Context} + * @throws OpenemsNamedException on error + */ + private void applyPower(Context context) throws OpenemsNamedException { + final var inverter = context.getParent(); + + IntegerWriteChannel setActivePower = inverter.channel(BatteryInverterDeye.ChannelId.SET_ACTIVE_POWER); + setActivePower.setNextWriteValue(context.setActivePower); + + IntegerWriteChannel setReactivePower = inverter.channel(BatteryInverterDeye.ChannelId.SET_REACTIVE_POWER); + setReactivePower.setNextWriteValue(context.setReactivePower); + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StateMachine.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StateMachine.java new file mode 100644 index 00000000000..815f79ab5a1 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StateMachine.java @@ -0,0 +1,70 @@ +package io.openems.edge.deye.batteryinverter.statemachine; + +import io.openems.common.types.OptionsEnum; +import io.openems.edge.common.statemachine.AbstractStateMachine; +import io.openems.edge.common.statemachine.StateHandler; + +public class StateMachine extends AbstractStateMachine { + + public enum State implements io.openems.edge.common.statemachine.State, OptionsEnum { + UNDEFINED(-1), // + + GO_RUNNING(10), // + RUNNING(11), // + + GO_STOPPED(20), // + STOPPED(21), // + + ERROR(30) // + ; + + private final int value; + + private State(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name(); + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } + + @Override + public State[] getStates() { + return State.values(); + } + } + + public StateMachine(State initialState) { + super(initialState); + } + + @Override + public StateHandler getStateHandler(State state) { + switch (state) { + case UNDEFINED: + return new UndefinedHandler(); + case GO_RUNNING: + return new GoRunningHandler(); + case RUNNING: + return new RunningHandler(); + case GO_STOPPED: + return new GoStoppedHandler(); + case STOPPED: + return new StoppedHandler(); + case ERROR: + return new ErrorHandler(); + } + throw new IllegalArgumentException("Unknown State [" + state + "]"); + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StoppedHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StoppedHandler.java new file mode 100644 index 00000000000..fdda56d3728 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StoppedHandler.java @@ -0,0 +1,19 @@ +package io.openems.edge.deye.batteryinverter.statemachine; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; +import io.openems.edge.common.startstop.StartStop; +import io.openems.edge.common.statemachine.StateHandler; + +public class StoppedHandler extends StateHandler { + + @Override + public State runAndGetNextState(Context context) throws OpenemsNamedException { + final var inverter = context.getParent(); + + // Mark as stopped + inverter._setStartStop(StartStop.STOP); + return State.STOPPED; + } + +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/UndefinedHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/UndefinedHandler.java new file mode 100644 index 00000000000..c932a3d993d --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/UndefinedHandler.java @@ -0,0 +1,36 @@ +package io.openems.edge.deye.batteryinverter.statemachine; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; +import io.openems.edge.common.statemachine.StateHandler; + +public class UndefinedHandler extends StateHandler { + + @Override + public State runAndGetNextState(Context context) throws OpenemsNamedException { + final var inverter = context.getParent(); + switch (inverter.getStartStopTarget()) { + case UNDEFINED: + // Stuck in UNDEFINED State + return State.UNDEFINED; + + case START: + // force START + if (inverter.hasFaults()) { + // Has Faults -> error handling + return State.ERROR; + } else { + // No Faults -> start + return State.GO_RUNNING; + } + + case STOP: + // force STOP + return State.GO_STOPPED; + } + + assert false; + return State.UNDEFINED; // can never happen + } + +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java index 72d449f8374..a8e1812bb4e 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java @@ -18,6 +18,9 @@ @AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?") boolean enabled() default true; + @AttributeDefinition(name = "Meter-Type", description = "What is measured by this Meter?") + MeterType type() default MeterType.GRID; + @AttributeDefinition(name = "Modbus-ID", description = "ID of Modbus bridge.") String modbus_id() default "modbus0"; diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java index dd7d9117293..e743f632977 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java @@ -1,5 +1,18 @@ package io.openems.edge.deye.gridmeter; +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.ConfigurationPolicy; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; +import org.osgi.service.component.annotations.ReferencePolicyOption; +import org.osgi.service.event.propertytypes.EventTopics; +import org.osgi.service.metatype.annotations.Designate; + import io.openems.common.exceptions.OpenemsException; import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; import io.openems.edge.bridge.modbus.api.BridgeModbus; @@ -10,6 +23,7 @@ import io.openems.edge.common.component.OpenemsComponent; import io.openems.edge.common.event.EdgeEventConstants; import io.openems.edge.common.taskmanager.Priority; +import io.openems.edge.deye.batteryinverter.BatteryInverterDeye; import io.openems.edge.meter.api.ElectricityMeter; import io.openems.edge.meter.api.MeterType; import org.osgi.service.cm.ConfigurationAdmin; From a682d241346f9b4f6bf0f71235fa357e16609333 Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Thu, 15 Feb 2024 07:09:22 +0100 Subject: [PATCH 04/25] Start implement DEYE battery inverter --- .../readme.adoc | 6 - .../batteryinverter/BatteryInverterDeye.java | 949 ------------------ .../BatteryInverterDeyeImpl.java | 407 -------- .../edge/deye/batteryinverter/Config.java | 41 - .../enums/ActivePowerControlMode.java | 34 - .../deye/batteryinverter/enums/Baudrate.java | 33 - .../batteryinverter/enums/BlackStartMode.java | 32 - .../enums/BmsProtocolSelection.java | 34 - .../batteryinverter/enums/CountryCode.java | 18 - .../deye/batteryinverter/enums/CpuType.java | 32 - .../batteryinverter/enums/DcVoltageLevel.java | 32 - .../batteryinverter/enums/EnableDisable.java | 17 - .../edge/deye/batteryinverter/enums/Epo.java | 33 - .../batteryinverter/enums/FrequencyLevel.java | 22 - .../enums/FrequencyVariationRate.java | 33 - .../enums/GridCodeSelection.java | 27 - .../batteryinverter/enums/InterfaceType.java | 32 - .../enums/InverterWiringTopology.java | 16 - .../enums/ModulePowerLevel.java | 34 - .../enums/PhaseAngleAbrupt.java | 33 - .../enums/PowerRisingMode.java | 32 - .../enums/ProtocolSelection.java | 32 - .../enums/ReactivePowerControlMode.java | 34 - .../enums/SinexcelGridMode.java | 32 - .../batteryinverter/enums/SinexcelState.java | 40 - .../enums/SinglePhaseMode.java | 33 - .../deye/batteryinverter/enums/StartMode.java | 32 - .../deye/batteryinverter/enums/Switch.java | 32 - .../batteryinverter/enums/VoltageLevel.java | 23 - .../batteryinverter/statemachine/Context.java | 24 - .../statemachine/ErrorHandler.java | 46 - .../statemachine/GoRunningHandler.java | 43 - .../statemachine/GoStoppedHandler.java | 23 - .../statemachine/RunningHandler.java | 44 - .../statemachine/StateMachine.java | 70 -- .../statemachine/StoppedHandler.java | 19 - .../statemachine/UndefinedHandler.java | 36 - .../openems/edge/deye/gridmeter/Config.java | 3 - .../deye/gridmeter/DeyeGridMeterImpl.java | 14 - 39 files changed, 2477 deletions(-) delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeye.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeyeImpl.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/Config.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ActivePowerControlMode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Baudrate.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BlackStartMode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BmsProtocolSelection.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CountryCode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CpuType.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/DcVoltageLevel.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/EnableDisable.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Epo.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyLevel.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyVariationRate.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/GridCodeSelection.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InterfaceType.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InverterWiringTopology.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ModulePowerLevel.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PhaseAngleAbrupt.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PowerRisingMode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ProtocolSelection.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ReactivePowerControlMode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelGridMode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelState.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinglePhaseMode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/StartMode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Switch.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/VoltageLevel.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/Context.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/ErrorHandler.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoRunningHandler.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoStoppedHandler.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/RunningHandler.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StateMachine.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StoppedHandler.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/UndefinedHandler.java diff --git a/io.openems.edge.batteryinverter.deye/readme.adoc b/io.openems.edge.batteryinverter.deye/readme.adoc index 362b84c4748..46ceaa16a92 100644 --- a/io.openems.edge.batteryinverter.deye/readme.adoc +++ b/io.openems.edge.batteryinverter.deye/readme.adoc @@ -1,7 +1 @@ = Deye Battery Inverter - -Implemented Natures:: -- SymmetricEss -- ManagedSymmetricEss - -https://github.com/OpenEMS/openems/tree/develop/io.openems.edge.ess.sinexcel[Source Code icon:github[]] \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeye.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeye.java deleted file mode 100644 index dc188d6ab82..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeye.java +++ /dev/null @@ -1,949 +0,0 @@ -package io.openems.edge.deye.batteryinverter; - -import io.openems.common.channel.AccessMode; -import io.openems.common.channel.Debounce; -import io.openems.common.channel.Level; -import io.openems.common.channel.PersistencePriority; -import io.openems.common.channel.Unit; -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.common.types.OpenemsType; -import io.openems.edge.batteryinverter.api.ManagedSymmetricBatteryInverter; -import io.openems.edge.batteryinverter.api.OffGridBatteryInverter; -import io.openems.edge.batteryinverter.api.SymmetricBatteryInverter; -import io.openems.edge.common.channel.BooleanDoc; -import io.openems.edge.common.channel.BooleanWriteChannel; -import io.openems.edge.common.channel.Doc; -import io.openems.edge.common.channel.IntegerDoc; -import io.openems.edge.common.channel.IntegerReadChannel; -import io.openems.edge.common.channel.value.Value; -import io.openems.edge.common.component.OpenemsComponent; -import io.openems.edge.common.modbusslave.ModbusSlave; -import io.openems.edge.common.startstop.StartStoppable; -import io.openems.edge.common.sum.GridMode; -import io.openems.edge.deye.batteryinverter.enums.ActivePowerControlMode; -import io.openems.edge.deye.batteryinverter.enums.Baudrate; -import io.openems.edge.deye.batteryinverter.enums.BlackStartMode; -import io.openems.edge.deye.batteryinverter.enums.CpuType; -import io.openems.edge.deye.batteryinverter.enums.DcVoltageLevel; -import io.openems.edge.deye.batteryinverter.enums.Epo; -import io.openems.edge.deye.batteryinverter.enums.FrequencyVariationRate; -import io.openems.edge.deye.batteryinverter.enums.InterfaceType; -import io.openems.edge.deye.batteryinverter.enums.ModulePowerLevel; -import io.openems.edge.deye.batteryinverter.enums.PhaseAngleAbrupt; -import io.openems.edge.deye.batteryinverter.enums.PowerRisingMode; -import io.openems.edge.deye.batteryinverter.enums.ProtocolSelection; -import io.openems.edge.deye.batteryinverter.enums.ReactivePowerControlMode; -import io.openems.edge.deye.batteryinverter.enums.SinexcelGridMode; -import io.openems.edge.deye.batteryinverter.enums.SinglePhaseMode; -import io.openems.edge.deye.batteryinverter.enums.StartMode; -import io.openems.edge.deye.batteryinverter.enums.Switch; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; - -public interface BatteryInverterDeye extends OffGridBatteryInverter, ManagedSymmetricBatteryInverter, SymmetricBatteryInverter, OpenemsComponent, StartStoppable, ModbusSlave { - - public enum ChannelId implements io.openems.edge.common.channel.ChannelId { - STATE_MACHINE(Doc.of(State.values()) // - .text("Current State of State-Machine")), // - RUN_FAILED(Doc.of(Level.FAULT) // - .text("Running the Logic failed")), // - SET_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)// - .unit(Unit.WATT)), // - SET_REACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)// - .unit(Unit.VOLT_AMPERE_REACTIVE)), // - CHARGE_MAX_CURRENT(new IntegerDoc() // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.AMPERE)), // - DISCHARGE_MAX_CURRENT(new IntegerDoc() // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.AMPERE)), // - CHARGE_MAX_CURRENT_READ(new IntegerDoc() // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.AMPERE)), // - DISCHARGE_MAX_CURRENT_READ(new IntegerDoc() // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.AMPERE)), // - CHARGE_MAX_VOLTAGE(new IntegerDoc() // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.VOLT)), // - DISCHARGE_MIN_VOLTAGE(new IntegerDoc() // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.VOLT)), // - - ACTIVE_DISCHARGE_ENERGY_VALUE_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), - ACTIVE_DISCHARGE_ENERGY_VALUE_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), - ACTIVE_CHARGE_ENERGY_VALUE_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), - ACTIVE_CHARGE_ENERGY_VALUE_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), - - // when implementing Lithium-ion batteries, these two registers MUST be set to - // the same - TOPPING_CHARGE_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.VOLT)), - // when implementing Lithium-ion batteries, these two registers MUST be set to - // the same - FLOAT_CHARGE_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.VOLT)), // - - MANUFACTURER_AND_MODEL_NUMBER(Doc.of(OpenemsType.STRING) // - .accessMode(AccessMode.READ_ONLY)), // - SERIAL_NUMBER(Doc.of(OpenemsType.STRING) // - .persistencePriority(PersistencePriority.HIGH) // - .accessMode(AccessMode.READ_ONLY)), // - FAULT_STATUS(Doc.of(Level.FAULT) // - .accessMode(AccessMode.READ_ONLY)), // - ALERT_STATUS(Doc.of(Level.WARNING) // - .accessMode(AccessMode.READ_ONLY)), // - BATTERY_INVERTER_STATE(new BooleanDoc() // - .debounce(5, Debounce.FALSE_VALUES_IN_A_ROW_TO_SET_FALSE) // - .onChannelChange((self, value) -> self._setInverterState(value.get()))), - - INVERTER_GRID_MODE(new BooleanDoc() // - .debounce(5, Debounce.FALSE_VALUES_IN_A_ROW_TO_SET_FALSE) // - .text("On Grid") // - .onChannelChange((self, value) -> { - final GridMode gridMode; - if (!value.isDefined()) { - gridMode = GridMode.UNDEFINED; - } else if (value.get()) { - gridMode = GridMode.ON_GRID; - } else { - gridMode = GridMode.OFF_GRID; - } - self._setGridMode(gridMode); - })), - - ISLAND_MODE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DERATING_STATUS(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - ALLOW_GRID_CONNECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - STANDBY_STATUS(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - OBTAIN_FAULT_RECORD_FLAG(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - WRITE_POWER_GENERATION_INTO_EEPROM(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - INITIALIZE_DSP_PARAMETERS(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - MASTER_SLAVE_MODE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AC_OVER_VOLTAGE_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AC_UNDER_VOLTAGE_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AC_OVER_FREQUENCY_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AC_UNDER_FREQUENCY_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - GRID_VOLTAGE_UNBALANCE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - GRID_PHASE_REVERSE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - INVERTER_ISLAND(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - ON_GRID_OFF_GRID_SWITCH_OVER_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - OUTPUT_GROUND_FAULT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - GRID_PHASE_LOCK_FAILED(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - INTERNAL_AIR_OVER_TEMPERATURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - GRID_CONNECTED_CONDITION_TIME_OUT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - MODULE_RENUMBER_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - // Monitor parallel use - CANB_COMMUNICATION_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - POWER_FREQUENCY_SYNCHRONIZATION_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - CARRIER_SYNCHRONIZATION_FALURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - EPO_ERROR(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - MONITOR_PARAMETER_MISMATCH(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DSP_VERSION_ABNORMAL(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - CPLD_VERSION_ERROR(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - HARDWARE_VERSION_ERROR(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - // Monitor to DSP - CANA_COMMUNICATION_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AUXILARY_POWER_FAULT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - FAN_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_OVER_VOLTAGE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_LOW_VOLTAGE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_VOLTAGE_UNBALANCED(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AC_RELAY_SHORT_CIRCUIT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - OUTPUT_VOLTAGE_ABNORMAL(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - OUTPUT_CURRENT_UNBALANCED(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - OVER_TEMPERATURE_OF_HEAT_SINK(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - OUTPUT_OVER_LOAD_TOT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - GRID_CONTINUE_OVER_VOLTAGE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AC_SOFT_START_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - INVERTER_START_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AC_RELAY_IS_OPEN(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - U2_BOARD_COMMUNICATION_IS_ABNORMAL(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - AC_DC_COMPONENT_EXCESS(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - MASTER_SLAVE_SAMPLING_ABNORMALITY(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - PARAMETER_SETTING_ERROR(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - LOW_OFF_GRID_ENERGY(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - N_LINE_IS_NOT_CONNECTED(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - STANDBY_BUS_HEIGHT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - SINGLE_PHASE_WIRING_ERROR(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - EXCESSIVE_GRID_FREQUENCY_CHANGE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - ABRUPT_PHASE_ANGLE_FAULT_OF_POWER_GRID(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - GRID_CONNECTION_PARAMETER_CONFLICT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - EE_READING_ERROR_1(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - EE_READING_ERROR_2(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - FLASH_READING_ERROR(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - INVERTER_OVER_LOAD(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - BATTERY_PARAMETER_SETTING_ERROR(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - SLAVE_LOST_ALARM(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_CHARGING(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_DISCHARGING(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - BATTERY_FULLY_CHARGED(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - BATTERY_EMPTY(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_FAULT_STATUS(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_ALERT_STATUS(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_INPUT_OVER_VOLTAGE_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_INPUT_UNDER_VOLTAGE_PROTECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - BMS_ALERT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - BMS_COMMUNICATION_TIMEOUT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - EMS_COMMUNICATION_TIMEOUT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_SOFT_START_FAILED(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_RELAY_SHORT_CIRCUIT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_RELAY_SHORT_OPEN(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - BATTERY_POWEROVER_LOAD(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - BATTERY_POWER_OVER_LOAD(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_BUS_STARTING_FAILED(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_QUICK_CHECK_OVER_CURRENT(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - DC_OC(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_ONLY)), // - // AC L1-L2 RMS voltage - GRID_VOLTAGE_L1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIVOLT)), // - // AC L2-L3 RMS voltage - GRID_VOLTAGE_L2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIVOLT)), // - // AC L3-L1 RMS voltage - GRID_VOLTAGE_L3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIVOLT)), // - // AC L1 RMS current - GRID_CURRENT_L1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIAMPERE)), // - // AC L2 RMS current - GRID_CURRENT_L2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIAMPERE)), // - // AC L3 RMS current - GRID_CURRENT_L3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIAMPERE)), // - // AC frequency - FREQUENCY(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIHERTZ)), // - // AC L1 Active Power - ACTIVE_POWER_L1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.WATT)), // - // AC L2 Active Power - ACTIVE_POWER_L2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.WATT)), // - // AC L3 Active Power - ACTIVE_POWER_L3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.WATT)), // - // AC L1 Reactive Power - REACTIVE_POWER_L1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.VOLT_AMPERE_REACTIVE)), // - // AC L2 Reactive Power - REACTIVE_POWER_L2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.VOLT_AMPERE_REACTIVE)), // - // AC L3 Reactive Power - REACTIVE_POWER_L3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.VOLT_AMPERE_REACTIVE)), // - // AC L1 Apparent Power - APPERENT_POWER_L1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.VOLT_AMPERE)), // - // AC L2 Apparent Power - APPERENT_POWER_L2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.VOLT_AMPERE)), // - // AC L3 Apparent Power - APPERENT_POWER_L3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.VOLT_AMPERE)), // - // AC L1 Power Factor - COS_PHI_L1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_ONLY)), // - // AC L2 Power Factor - COS_PHI_L2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_ONLY)), // - // AC L3 Power Factor - COS_PHI_L3(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_ONLY)), // - // AC Apperent Power - APPARENT_POWER(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.VOLT_AMPERE)), // - // AC Power Factor - COS_PHI(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_ONLY)), // - - // Temperature of DC heat sink - TEMPERATURE_OF_AC_HEAT_SINK(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.DEGREE_CELSIUS)), // - // BUS+ side voltage - DC_VOLTAGE_POSITIVE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIVOLT)), // - // BUS- side voltage - DC_VOLTAGE_NEGATIVE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIVOLT)), // - // Target off-grid voltage bias - SET_OFF_GRID_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)// - .unit(Unit.MILLIVOLT)), // - // Target off-grid frequency bias - SET_OFF_GRID_FREQUENCY(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)// - .unit(Unit.MILLIHERTZ)), // - DC_POWER(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.WATT)), // - DC_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIVOLT)), // - DC_CURRENT(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIAMPERE)), // - DC_CHARGE_ENERGY(Doc.of(OpenemsType.LONG) // - .accessMode(AccessMode.READ_WRITE)// - .unit(Unit.CUMULATED_WATT_HOURS)), // - DC_DISCHARGE_ENERGY(Doc.of(OpenemsType.LONG) // - .accessMode(AccessMode.READ_WRITE)// - .unit(Unit.CUMULATED_WATT_HOURS)), // - TEMPERATURE_OF_DC_DC_HEAT_SINK(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.DEGREE_CELSIUS)), // - DC_RELAY_REAR_END_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.VOLT)), // - CHARGE_MAX_CURRENT_SETTING(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIAMPERE)), // - DISCHARGE_MAX_CURRENT_SETTING(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_ONLY)// - .unit(Unit.MILLIAMPERE)), // - IP_ADDRESS_BLOCK_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - IP_ADDRESS_BLOCK_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - IP_ADDRESS_BLOCK_3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - IP_ADDRESS_BLOCK_4(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - NETMASK_BLOCK_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - NETMASK_BLOCK_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - NETMASK_BLOCK_3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - NETMASK_BLOCK_4(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - GATEWAY_IP_BLOCK_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - GATEWAY_IP_BLOCK_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - GATEWAY_IP_BLOCK_3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - GATEWAY_IP_BLOCK_4(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - MAC(Doc.of(OpenemsType.STRING) // - .accessMode(AccessMode.READ_WRITE)), // - MODBUS_UNIT_ID(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - BAUDRATE(Doc.of(Baudrate.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // default 1 - INTERFACE_TYPE(Doc.of(InterfaceType.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // Takes effect after hard reset,0-modbus - COMMUNICATION_PROTOCOL_SELECTION(Doc.of(ProtocolSelection.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // Prevent unexpected results of communication failures.when EMS timeout - // enabled, watchdog will work and even reading will feed the watchdog - EMS_TIMEOUT(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // Enable ONLY when remote Emergency Stop Button is needed - EPO_ENABLE(Doc.of(Epo.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // Enable ONLY when remote BMS-inverter connection is needed - BMS_TIMEOUT(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // Takes effect after hard reset,0-modbus - BMS_PROTOCOL_SELECTION(Doc.of(ProtocolSelection.values()) // - .accessMode(AccessMode.READ_WRITE)), // - SET_GRID_MODE(Doc.of(SinexcelGridMode.values()) // - .accessMode(AccessMode.READ_WRITE)), // - BUZZER_ENABLE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - RESTORE_FACTORY_SETTING(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // To Start operation, only 1 will be accepted. Reading back value makes no - // sense - START_INVERTER(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // To Stop operation, only 1 will be accepted. Reading back value makes no sense - STOP_INVERTER(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // clear failure flag,when fault occurs, the system will stop and indicates - // fault.starting is invalid until the fault source is actually removed and this - // register is written 1. Reading back value makes no sense - CLEAR_FAILURE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.WRITE_ONLY)), // - // set the module to on grid mode. Reading back value makes no sense - SET_ON_GRID_MODE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // set the module to off grid mode. Reading back value makes no sense - SET_OFF_GRID_MODE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // set the module to standby mode,setpoint 0:IGBT switching ,setpoint 1:no IGBT - // switching,low consumption.let the inverter to halt the IGBT switching, to - // save the power consumption, but all relays are still closed. - // Reading back value makes no sense - SET_STANDBY_COMMAND(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - SET_SOFT_START(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - RESET_INSTRUCTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - GRID_STOP(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - VOLTAGE_LEVEL(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - FREQUENCY_LEVEL(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - INVERTER_WIRING_TOPOLOGY(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - SWITCHING_DEVICE_ACCESS_SETTING(Doc.of(Switch.values()) // - .accessMode(AccessMode.READ_WRITE)), // - MODULE_POWER_LEVEL(Doc.of(ModulePowerLevel.values()) // - .accessMode(AccessMode.READ_ONLY)), // - DC_VOLTAGE_LEVEL(Doc.of(DcVoltageLevel.values()) // - .accessMode(AccessMode.READ_ONLY)), // - CPU_TYPE(Doc.of(CpuType.values()) // - .accessMode(AccessMode.READ_WRITE)), // - OFF_GRID_AND_PARALLEL_ENABLE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - SET_DC_SOFT_START_EXTERNAL_CONTROL(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - GRID_OVER_VOLTAGE_PROTECTION_AMPLITUDE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_OVER_VOLTAGE_TRIP_TIME_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_OVER_VOLTAGE_TRIP_LEVEL_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_OVER_VOLTAGE_TRIP_TIME_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_VOLTAGE_TRIP_LEVEL_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_VOLTAGE_TRIP_TIME_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_VOLTAGE_TRIP_LEVEL_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_VOLTAGE_TRIP_TIME_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_VOLTAGE_TRIP_LEVEL_3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_VOLTAGE_TRIP_TIME_3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_OVER_FREQUENCY_TRIP_LEVEL_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_OVER_FREQUENCY_TRIP_TIME_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_OVER_FREQUENCY_TRIP_LEVEL_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_OVER_FREQUENCY_TRIP_TIME_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_FREQUENCY_TRIP_LEVEL_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_FREQUENCY_TRIP_TIME_1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_FREQUENCY_TRIP_LEVEL_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - AC_UNDER_FREQUENCY_TRIP_TIME_2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - RECONNECT_TIME(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // Anti-islanding is a CPUC RULE 21/HECO RULE14H/IEEE1547-requested function to - // make sure the inverter disconnect from the grid in case of blackout. - // This is to prevent the formation of an unintended island. The inverter design - // shall comply with the requirements of IEEE Std 1547 and UL 1741 standards (or - // latest versions) and be certified to have anti-islanding protection such that - // the synchronous inverter will automatically disconnect upon a utility system - // interruption - ANTI_ISLANDING(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // Frequency and Voltage Ride-Through. - // The ability to withstand voltage or frequency excursions outside defined - // limits without tripping or malfunctioning - FREQUENCY_VOLTAGE_RIDE_THROUGH(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // Grid-tied mode only, voltage and frequency setpoint the only setpoints - REACTIVE_POWER_CONTROL_MODE(Doc.of(ReactivePowerControlMode.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // To define how the power changes - POWER_RISING_MODE(Doc.of(PowerRisingMode.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // Grid-tied mode only, Volt/Watt control & Freq/Watt control means active power - // will be regulated by grid voltage/frequency following a curve/ramp rate given - // by HECO or CPUC or other local utility authority codes - ACTIVE_POWER_CONTROL_MODE(Doc.of(ActivePowerControlMode.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // Grid-tied mode only, voltage and frequency setpoint the only setpoints - GRID_VOLTAGE_ASYMMETRIC_DETECTON(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // Grid-tied mode only - CONTINUOUS_OVERVOLTAGE_DETECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // Grid-tied mode only,detect whether the grid is on-service at powered-up. - GRID_EXISTENCE_DETECTION_ON(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), - // Grid-tied mode only - NEUTRAL_FLOATING_DETECTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // if disabled, the inverter will start the AC voltage, then close the relay. In - // some off-grid cases, such as there are inductive loads or transformer, the - // in rush exciting current will trip the inverter. Enabling this register, the - // inverter will close the relay first try to limit the current and start the - // voltage slowly - OFF_GRID_BLACKSTART_MODE(Doc.of(BlackStartMode.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // Grid tied mode only. take effect after power off. - GRID_CODE_SELECTION(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - GRID_CONNECTED_ACTIVE_CAPACITY_LIMITATION_FUNCTION(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - GRID_ACTIVE_POWER_CAPACITY_SETTING(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - // Single mode enable and select - SINGLE_PHASE_MODE_SELECTION(Doc.of(SinglePhaseMode.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // Overvoltage drop active enable (only for EN50549 certification) - OVER_VOLTAGE_DROP_ACTIVE(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - // 0-Manual start,1-Auto start,default:0 - START_UP_MODE(Doc.of(StartMode.values()) // - .accessMode(AccessMode.READ_WRITE)), // - LOCAL_ID_SETTING(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // when implementing Lithium-ion batteries,this register MUST be set to 0 - CURRENT_FROM_TOPPING_CHARGING_TO_FLOAT_CHARGING(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - BATTERY_VOLTAGE_PROTECTION_LIMIT(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE) // - .unit(Unit.VOLT)), // - LEAKAGE_CURRENT_DC_COMPONENT_DETECTOR(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - RESUME_AND_LIMIT_FREQUENCY(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - RESTORE_LOWER_FREQUENCY_OF_GRID_CONNECTION(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - VOLTAGE_REACTIVE_REFERENCE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - - // ratio * rated voltage,Available only when reactive power regulation mode is - // set to Volt/Var(53626). - VOLTAGE_AND_REACTIVE_POWER_ADJUSTMENT_POINT_V1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - VOLTAGE_AND_REACTIVE_POWER_ADJUSTMENT_POINT_V2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - VOLTAGE_AND_REACTIVE_POWER_ADJUSTMENT_POINT_V3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - VOLTAGE_AND_REACTIVE_POWER_ADJUSTMENT_POINT_V4(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - - // refer to HECO RULE 14, keep default value if no aware of it - MAX_CAPACITIVE_REACTIVE_REGULATION_Q1(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - INITIAL_CAPACITIVE_REACTIVE_REGULATION_Q2(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - INITIAL_INDUCTIVE_REACTIVE_REGULATION_Q3(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - MAX_INDUCTIVE_REACTIVE_REGULATION_Q4(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - VOLTAGE_AND_REACTIVE_RESPONSE_TIME(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - REACTIVE_FIRST_ORDER_RESPONSE_TIME(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - - // ratio * rated voltage, Available only when active power regulation - // mode(53636) is set to Volt/Watt and operating in discharge mode, follow the - // FVRT table given by HECO or CPUC or other local utility authority codes. - INITIAL_VOLTAGE_V_START(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - END_VOLTAGE_V_STOP(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - INITIAL_POWER_P_START(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - END_POWER_P_STOP(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - RETURN_TO_SERVICE_DELAY(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - VOLT_WATT_RESPONSE_TIME(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - - // Available only when active power regulation mode(53636) is set to Freq/Watt - // and operating in discharge mode. When the actual frequency is above the - // point, the active power will be regulated(lowered) with the ramp rate. In - // Australia, this register shall be fixed to 0.25Hz - START_OF_FREQUENY_DROP(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // The ramp rate is defined as multiple of set active power per hertz that above - // the above the Freq/Watt regulation point. Available only when active power - // regulation mode(53636) is set to Freq/Watt and operating in discharge mode. - // Example: Rated frequency is 60Hz, the target active power is set to 10kW, - // Freq/Watt regulation point is set to 2Hz, ramp rate is set as 0.5, If the - // actual frequency reaches 63Hz, the output active power will be - // 10kW-(63Hz-62Hz) x 0.5*(10kW/Hz) = 5kW - SLOPE_OF_FREQUENCY_DROP(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // AS4777 only, bias Bias from rated frequency - FREQUENCY_WATT_F_STOP_DISCHARGE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - FREQUENCY_WATT_F_STOP_CHARGE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // %Vrated,AS4777 only, ratio - VOLT_WATT_V_START_CHARGE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // SS takes effect when the inverter starts, or when the inverter is on "grid - // reconnection" after the trip caused by FVRT timeout - SOFT_START_RAMP_RATE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // RR takes effect in Volt-Watt or Freq-Watt mode when the grid is back to - // normal state and the inverter trying to go back to normal output. - // In other words, as long as the inverter does not trip, and the inverter had - // derated the output power, RR takes effect when the inverter tries to go back - // to normal output. Available only when Power rising mode is set to ramp - // mode(53626).If the value is 2.000, which means within 0.5 seconds the system - // can runs to full power output. - POWER_RAMP_RATE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // Available only when Constant PF is enabled,Negative inductive, positive - // capacitive - POWER_FACTOR_SETTING(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - // Available only when active power regulation mode(53636) is set to Freq/Watt - // and operating in discharge mode. When the actual frequency is above the - // point, the active power will be regulated(lowered) with the ramp rate - POWER_FACTOR_P1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - POWER_FACTOR_P2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - POWER_FACTOR_P3(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - POWER_FACTOR_P4(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - - // +(lagging), -(leading), - POWER_FACTOR_CURVE_MODE_P1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - POWER_FACTOR_CURVE_MODE_P2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - POWER_FACTOR_CURVE_MODE_P3(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - POWER_FACTOR_CURVE_MODE_P4(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - - // %Vrated - CONTINUOS_OVER_VOLTAGE_TRIP_THRESHOLD(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - FREQUENCY_VARIATION_RATE_TRIP_THRESHOLD(Doc.of(FrequencyVariationRate.values()) // - .accessMode(AccessMode.READ_WRITE)), // - PHASE_ANGLE_ABRUPT_TRIP_THRESHOLD(Doc.of(PhaseAngleAbrupt.values()) // - .accessMode(AccessMode.READ_WRITE)), // - // Available only when Power rising mode is set to ramp mode . once tripped - // after FVRT timeout, the inverter can reconnect to the grid when frequency or - // voltage is back to the thresholds defined as "grid is back to service". In - // HECO14 /CPUC 21, this register is unnecessary to - GRID_RECONNECTION_VOLTAGE_UPPER_LIMIT(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - GRID_RECONNECTION_VOLTAGE_LOWER_LIMIT(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // Available only when Power rising mode is set to ramp mode once tripped after - // FVRT timeout, the inverter can reconnect to the grid when frequency or - // voltage is back to the thresholds defined as "grid is back to service" - GRID_RECONNECTION_FREQUENCY_UPPER_LIMIT(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // Bias from rated frequency - GRID_RECONNECTION_FREQUENCY_LOWER_LIMIT(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - LOW_FREQUENCY_RAMP_RATE(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE)), // - // TODO Values check Meter options !!!!!!!!!!!!!!!!!! - METER_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.READ_WRITE).unit(Unit.WATT)), // - - GRID_VOLTAGE_CALIBRATION_L1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - GRID_VOLTAGE_CALIBRATION_L2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - GRID_VOLTAGE_CALIBRATION_L3(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INVERTER_VOLTAGE_CALIBRATION_L1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INVERTER_VOLTAGE_CALIBRATION_L2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INVERTER_VOLTAGE_CALIBRATION_L3(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INDUCTOR_CURRENT_CALIBRATION_L1_PARAMETERS_1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INDUCTOR_CURRENT_CALIBRATION_L2_PARAMETERS_1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INDUCTOR_CURRENT_CALIBRATION_L3_PARAMETERS_1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INDUCTOR_CURRENT_CALIBRATION_L1_PARAMETERS_2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INDUCTOR_CURRENT_CALIBRATION_L2_PARAMETERS_2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - INDUCTOR_CURRENT_CALIBRATION_L3_PARAMETERS_2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - OUTPUT_CURRENT_CALIBRATION_L1(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - OUTPUT_CURRENT_CALIBRATION_L2(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - OUTPUT_CURRENT_CALIBRATION_L3(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - POSITIVE_BUS_VOLTAGE_CALIBRATION(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - NEGATIVE_BUS_VOLTAGE_CALIBRATION(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - DC_VOLTAGE_CALIBRATION(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - DC_CURRENT_CALIBRATION(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - DC_INDUCTOR_CURRENT_CALIBRATION(Doc.of(OpenemsType.FLOAT) // - .accessMode(AccessMode.READ_WRITE)), // - TIME_SETTING(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.WRITE_ONLY)), // - PASSWORD(Doc.of(OpenemsType.INTEGER) // - .accessMode(AccessMode.WRITE_ONLY)), // - ACTIVE_POWER_1(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_ONLY)), - ACTIVE_POWER_2(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_ONLY) // - ),; - - private final Doc doc; - - private ChannelId(Doc doc) { - this.doc = doc; - } - - @Override - public Doc doc() { - return this.doc; - } - } - - /** - * Gets the Channel for {@link ChannelId#SET_ON_GRID_MODE}. - * - * @return the Channel - */ - public default BooleanWriteChannel getSetOnGridModeChannel() { - return this.channel(ChannelId.SET_ON_GRID_MODE); - } - - /** - * Gets the Set-On-Grid-Mode. See {@link ChannelId#SET_ON_GRID_MODE}. - * - * @return the Channel {@link Value} - */ - public default Value getSetOnGridMode() { - return this.getSetOnGridModeChannel().value(); - } - - /** - * Sets a the On-Grid-Mode. See {@link ChannelId#SET_ON_GRID_MODE}. - * - * @param value the next write value - * @throws OpenemsNamedException on error - */ - public default void setOnGridMode(Boolean value) throws OpenemsNamedException { - this.getSetOnGridModeChannel().setNextWriteValue(value); - } - - /** - * Gets the Channel for {@link SymmetricBatteryInverter.ChannelId#ACTIVE_POWER}. - * - * @return the Channel - */ - public default IntegerReadChannel getActive1PowerChannel() { - return this.channel(ChannelId.ACTIVE_POWER_1); - } - - /** - * Gets the Channel for {@link SymmetricBatteryInverter.ChannelId#ACTIVE_POWER}. - * - * @return the Channel - */ - public default IntegerReadChannel getActive2PowerChannel() { - return this.channel(ChannelId.ACTIVE_POWER_2); - } - - /** - * Gets the Channel for {@link ChannelId#SET_OFF_GRID_MODE}. - * - * @return the Channel - */ - public default BooleanWriteChannel getSetOffGridModeChannel() { - return this.channel(ChannelId.SET_OFF_GRID_MODE); - } - - /** - * Gets the Set-Off-Grid-Mode. See {@link ChannelId#SET_OFF_GRID_MODE}. - * - * @return the Channel {@link Value} - */ - public default Value getSetOffGridMode() { - return this.getSetOffGridModeChannel().value(); - } - - /** - * Sets a the Off-Grid-Mode. See {@link ChannelId#SET_OFF_GRID_MODE}. - * - * @param value the next write value - * @throws OpenemsNamedException on error - */ - public default void setOffGridMode(Boolean value) throws OpenemsNamedException { - this.getSetOffGridModeChannel().setNextWriteValue(value); - } - - /** - * Gets the Channel for {@link ChannelId#START_INVERTER}. - * - * @return the Channel - */ - public default BooleanWriteChannel getStartInverterChannel() { - return this.channel(ChannelId.START_INVERTER); - } - - /** - * Sends a START command to the inverter. See {@link ChannelId#START_INVERTER}. - * - * @throws OpenemsNamedException on error - */ - public default void setStartInverter() throws OpenemsNamedException { - this.getStartInverterChannel().setNextWriteValue(true); // true = START - } - - /** - * Gets the Channel for {@link ChannelId#STOP_INVERTER}. - * - * @return the Channel - */ - public default BooleanWriteChannel getStopInverterChannel() { - return this.channel(ChannelId.STOP_INVERTER); - } - - /** - * Sends a STOP command to the inverter. See {@link ChannelId#STOP_INVERTER}. - * - * @throws OpenemsNamedException on error - */ - public default void setStopInverter() throws OpenemsNamedException { - this.getStopInverterChannel().setNextWriteValue(true); // true = STOP - } - - /** - * Gets the Channel for {@link ChannelId#CLEAR_FAILURE}. - * - * @return the Channel - */ - public default BooleanWriteChannel getClearFailureChannel() { - return this.channel(ChannelId.CLEAR_FAILURE); - } - - /** - * Clear inverter failures. See {@link ChannelId#CLEAR_FAILURE}. - * - * @throws OpenemsNamedException on error - */ - public default void setClearFailure() throws OpenemsNamedException { - this.getClearFailureChannel().setNextWriteValue(true); - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeyeImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeyeImpl.java deleted file mode 100644 index 9efd4a6f008..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/BatteryInverterDeyeImpl.java +++ /dev/null @@ -1,407 +0,0 @@ -package io.openems.edge.deye.batteryinverter; - -import java.util.Objects; -import java.util.concurrent.atomic.AtomicReference; - -import org.osgi.service.cm.ConfigurationAdmin; -import org.osgi.service.component.ComponentContext; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.ConfigurationPolicy; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.component.annotations.ReferencePolicyOption; -import org.osgi.service.event.propertytypes.EventTopics; -import org.osgi.service.metatype.annotations.Designate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.openems.common.channel.AccessMode; -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.common.exceptions.OpenemsException; -import io.openems.common.types.OptionsEnum; -import io.openems.edge.battery.api.Battery; -import io.openems.edge.batteryinverter.api.BatteryInverterConstraint; -import io.openems.edge.batteryinverter.api.ManagedSymmetricBatteryInverter; -import io.openems.edge.batteryinverter.api.OffGridBatteryInverter; -import io.openems.edge.batteryinverter.api.SymmetricBatteryInverter; -import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; -import io.openems.edge.bridge.modbus.api.BridgeModbus; -import io.openems.edge.bridge.modbus.api.ModbusComponent; -import io.openems.edge.bridge.modbus.api.ModbusProtocol; -import io.openems.edge.bridge.modbus.api.element.SignedWordElement; -import io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask; -import io.openems.edge.common.channel.BooleanWriteChannel; -import io.openems.edge.common.channel.IntegerWriteChannel; -import io.openems.edge.common.channel.WriteChannel; -import io.openems.edge.common.component.ComponentManager; -import io.openems.edge.common.component.OpenemsComponent; -import io.openems.edge.common.event.EdgeEventConstants; -import io.openems.edge.common.modbusslave.ModbusSlaveTable; -import io.openems.edge.common.startstop.StartStop; -import io.openems.edge.common.startstop.StartStoppable; -import io.openems.edge.common.taskmanager.Priority; -import io.openems.edge.common.type.TypeUtils; -import io.openems.edge.deye.batteryinverter.enums.EnableDisable; -import io.openems.edge.deye.batteryinverter.enums.FrequencyLevel; -import io.openems.edge.deye.batteryinverter.enums.GridCodeSelection; -import io.openems.edge.deye.batteryinverter.enums.PowerRisingMode; -import io.openems.edge.deye.batteryinverter.enums.VoltageLevel; -import io.openems.edge.deye.batteryinverter.statemachine.Context; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; -import io.openems.edge.ess.power.api.Phase; -import io.openems.edge.ess.power.api.Pwr; -import io.openems.edge.ess.power.api.Relationship; -import io.openems.edge.timedata.api.Timedata; -import io.openems.edge.timedata.api.TimedataProvider; -import io.openems.edge.timedata.api.utils.CalculateEnergyFromPower; - -@Designate(ocd = Config.class, factory = true) -@Component(// - name = "Battery-Inverter.Deye", // - immediate = true, // - configurationPolicy = ConfigurationPolicy.REQUIRE // -) -@EventTopics({ // - EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE, // - EdgeEventConstants.TOPIC_CYCLE_BEFORE_PROCESS_IMAGE // -}) -public class BatteryInverterDeyeImpl extends AbstractOpenemsModbusComponent - implements BatteryInverterDeye, OffGridBatteryInverter, ManagedSymmetricBatteryInverter, - SymmetricBatteryInverter, ModbusComponent, OpenemsComponent, TimedataProvider, StartStoppable { - - public static final int DEFAULT_EMS_TIMEOUT = 60; - public static final int DEFAULT_BMS_TIMEOUT = 0; - public static final EnableDisable DEFAULT_GRID_EXISTENCE_DETECTION_ON = EnableDisable.DISABLE; - public static final PowerRisingMode DEFAULT_POWER_RISING_MODE = PowerRisingMode.STEP; - - private static final int MAX_CURRENT = 90; // [A] - private static final int MAX_TOPPING_CHARGE_VOLTAGE = 750; - - private final Logger log = LoggerFactory.getLogger(BatteryInverterDeyeImpl.class); - private final StateMachine stateMachine = new StateMachine(State.UNDEFINED); - - private final CalculateEnergyFromPower calculateChargeEnergy = new CalculateEnergyFromPower(this, - SymmetricBatteryInverter.ChannelId.ACTIVE_CHARGE_ENERGY); - private final CalculateEnergyFromPower calculateDischargeEnergy = new CalculateEnergyFromPower(this, - SymmetricBatteryInverter.ChannelId.ACTIVE_DISCHARGE_ENERGY); - - @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL) - private volatile Timedata timedata = null; - - @Reference - private ComponentManager componentManager; - - @Reference - private ConfigurationAdmin cm; - - @Override - @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) - protected void setModbus(BridgeModbus modbus) { - super.setModbus(modbus); - } - - protected Config config; - - public BatteryInverterDeyeImpl() throws OpenemsNamedException { - super(// - OpenemsComponent.ChannelId.values(), // - ModbusComponent.ChannelId.values(), // - SymmetricBatteryInverter.ChannelId.values(), // - ManagedSymmetricBatteryInverter.ChannelId.values(), // - StartStoppable.ChannelId.values(), // - OffGridBatteryInverter.ChannelId.values(), // - BatteryInverterDeye.ChannelId.values() // - ); - } - - @Override - protected ModbusProtocol defineModbusProtocol() throws OpenemsException { - return new ModbusProtocol(this, - new FC3ReadRegistersTask(672, Priority.HIGH, m(BatteryInverterDeye.ChannelId.ACTIVE_POWER_1, - new SignedWordElement(672)),m(BatteryInverterDeye.ChannelId.ACTIVE_POWER_2, - new SignedWordElement(673)))); - } - - @Activate - private void activate(ComponentContext context, Config config) throws OpenemsNamedException { - this.config = config; - if (super.activate(context, config.id(), config.alias(), config.enabled(), config.modbusUnitId(), this.cm, "Modbus", - config.modbus_id())) { - return; - } - } - - @Override - @Deactivate - protected void deactivate() { - super.deactivate(); - } - - @Override - public void run(Battery battery, int setActivePower, int setReactivePower) throws OpenemsNamedException { - // Store the current State - this.channel(BatteryInverterDeye.ChannelId.STATE_MACHINE).setNextValue(this.stateMachine.getCurrentState()); - - // Initialize 'Start-Stop' Channel - this._setStartStop(StartStop.UNDEFINED); - - // Set Default Settings - this.setDefaultSettings(); - - // Set Battery Limits - this.setBatteryLimits(battery); - - // Calculate the Energy values from ActivePower. - this.calculateEnergy(); - - // Prepare Context - var context = new Context(this, this.config, this.targetGridMode.get(), setActivePower, setReactivePower); - - // Call the StateMachine - try { - this.stateMachine.run(context); - - this.channel(BatteryInverterDeye.ChannelId.RUN_FAILED).setNextValue(false); - - } catch (OpenemsNamedException e) { - this.channel(BatteryInverterDeye.ChannelId.RUN_FAILED).setNextValue(true); - this.logError(this.log, "StateMachine failed: " + e.getMessage()); - } - } - - /** - * Updates the Channel if its current value is not equal to the new value. - * - * @param channelId Sinexcel Channel-Id - * @param value {@link OptionsEnum} value. - * @throws IllegalArgumentException on error - */ - private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, OptionsEnum value) - throws IllegalArgumentException, OpenemsNamedException { - this.updateIfNotEqual(channelId, value.getValue()); - } - - /** - * Updates the Channel if its current value is not equal to the new value. - * - * @param channelId Sinexcel Channel-Id - * @param newValue Integer value. - * @throws IllegalArgumentException on error - */ - private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, Integer newValue) - throws IllegalArgumentException { - WriteChannel channel = this.channel(channelId); - var currentValue = channel.value(); - if (currentValue.isDefined() && !Objects.equals(currentValue.get(), newValue)) { - try { - channel.setNextWriteValue(newValue); - } catch (OpenemsNamedException e) { - this.logWarn(this.log, "Unable to update Channel [" + channel.address() + "] from [" + currentValue - + "] to [" + newValue + "]"); - e.printStackTrace(); - } - } - } - - private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, VoltageLevel voltageLevel) - throws IllegalArgumentException, OpenemsNamedException { - IntegerWriteChannel channel = this.channel(channelId); - channel.setNextWriteValue(voltageLevel.getValue()); - } - - private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, FrequencyLevel frequencyLevel) - throws IllegalArgumentException, OpenemsNamedException { - IntegerWriteChannel channel = this.channel(channelId); - channel.setNextWriteValue(frequencyLevel.getValue()); - } - - private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, GridCodeSelection gridCodeSelection) - throws IllegalArgumentException, OpenemsNamedException { - IntegerWriteChannel channel = this.channel(channelId); - channel.setNextWriteValue(gridCodeSelection.getValue()); - } - - private void updateIfNotEqual(BatteryInverterDeye.ChannelId channelId, EnableDisable value) - throws IllegalArgumentException, OpenemsNamedException { - BooleanWriteChannel channel = this.channel(channelId); - switch (value) { - case ENABLE: - channel.setNextWriteValue(true); - break; - case DISABLE: - channel.setNextWriteValue(false); - break; - } - } - - /** - * Sets some default settings on the inverter, like Timeout. - * - * @throws OpenemsNamedException on error - */ - private void setDefaultSettings() throws OpenemsNamedException { - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.EMS_TIMEOUT, DEFAULT_EMS_TIMEOUT); - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.BMS_TIMEOUT, DEFAULT_BMS_TIMEOUT); - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.GRID_EXISTENCE_DETECTION_ON, - DEFAULT_GRID_EXISTENCE_DETECTION_ON); - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.POWER_RISING_MODE, DEFAULT_POWER_RISING_MODE); - - switch (this.config.countryCode()) { - case AUSTRIA: - case GERMANY: - case SWITZERLAND: - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.VOLTAGE_LEVEL, VoltageLevel.V_400); - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.FREQUENCY_LEVEL, FrequencyLevel.HZ_50); - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.GRID_CODE_SELECTION, GridCodeSelection.VDE); - break; - } - - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.INVERTER_WIRING_TOPOLOGY, this.config.emergencyPower()); - } - - /** - * Sets the Battery Limits. - * - * @param battery the linked {@link Battery} - * @throws OpenemsNamedException on error - */ - private void setBatteryLimits(Battery battery) throws OpenemsNamedException { - // Upper voltage limit of battery protection >= Topping charge voltage >= Float - // charge voltage >= Lower voltage limit of battery protection (814 >= 809 >= - // 808 >= 813). - // Discharge Min Voltage - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.DISCHARGE_MIN_VOLTAGE, - battery.getDischargeMinVoltage().get()); - - // Charge Max Voltage - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.CHARGE_MAX_VOLTAGE, battery.getChargeMaxVoltage().get()); - - // Topping Charge Voltage - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.TOPPING_CHARGE_VOLTAGE, - TypeUtils.min(battery.getChargeMaxVoltage().get(), MAX_TOPPING_CHARGE_VOLTAGE)); - - // Float Charge Voltage - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.FLOAT_CHARGE_VOLTAGE, - TypeUtils.min(battery.getChargeMaxVoltage().get(), MAX_TOPPING_CHARGE_VOLTAGE)); - - // Discharge Max Current - // negative value is corrected as zero - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.DISCHARGE_MAX_CURRENT, - TypeUtils.fitWithin(0 /* enforce positive */, MAX_CURRENT, battery.getDischargeMaxCurrent().orElse(0))); - - // Charge Max Current - // negative value is corrected as zero - this.updateIfNotEqual(BatteryInverterDeye.ChannelId.CHARGE_MAX_CURRENT, - TypeUtils.fitWithin(0 /* enforce positive */, MAX_CURRENT, battery.getChargeMaxCurrent().orElse(0))); - } - - @Override - public String debugLog() { - return "MOIN - L:" + this.getActivePower().asString(); - } - - private final AtomicReference startStopTarget = new AtomicReference<>(StartStop.UNDEFINED); - - @Override - public void setStartStop(StartStop value) { - if (this.startStopTarget.getAndSet(value) != value) { - // Set only if value changed - this.stateMachine.forceNextState(State.UNDEFINED); - } - } - - /** - * Gets the inverter start-stop target. - * - * @return {@link StartStop} - */ - public StartStop getStartStopTarget() { - switch (this.config.startStop()) { - case AUTO: - // read StartStop-Channel - return this.startStopTarget.get(); - - case START: - // force START - return StartStop.START; - - case STOP: - // force STOP - return StartStop.STOP; - } - - assert false; - return StartStop.UNDEFINED; // can never happen - } - - protected final AtomicReference targetGridMode = new AtomicReference<>(TargetGridMode.GO_ON_GRID); - - @Override - public void setTargetGridMode(TargetGridMode targetGridMode) { - if (this.targetGridMode.getAndSet(targetGridMode) != targetGridMode) { - // Set only if value changed - this.stateMachine.forceNextState(State.UNDEFINED); - } - } - - @Override - public BatteryInverterConstraint[] getStaticConstraints() throws OpenemsException { - if (this.stateMachine.getCurrentState() == State.RUNNING) { - return BatteryInverterConstraint.NO_CONSTRAINTS; - - } - // Block any power as long as we are not RUNNING - return new BatteryInverterConstraint[] { // - new BatteryInverterConstraint("Sinexcel inverter not ready", Phase.ALL, Pwr.REACTIVE, // - Relationship.EQUALS, 0d), // - new BatteryInverterConstraint("Sinexcel inverter not ready", Phase.ALL, Pwr.ACTIVE, // - Relationship.EQUALS, 0d) // - }; - } - - @Override - public int getPowerPrecision() { - return 100; - } - - @Override - public ModbusSlaveTable getModbusSlaveTable(AccessMode accessMode) { - return new ModbusSlaveTable(// - OpenemsComponent.getModbusSlaveNatureTable(accessMode), // - SymmetricBatteryInverter.getModbusSlaveNatureTable(accessMode), // - ManagedSymmetricBatteryInverter.getModbusSlaveNatureTable(accessMode) // - ); - } - - /** - * Calculate the Energy values from ActivePower. - */ - private void calculateEnergy() { - // Calculate Energy - var activePower1 = this.getActive1PowerChannel().value().get(); - var activePower2 = this.getActive2PowerChannel().value().get(); - var activePower = activePower1 + activePower2; - if (activePower1 == null && activePower2 == null) { - // Not available - this.calculateChargeEnergy.update(null); - this.calculateDischargeEnergy.update(null); - } else if (activePower > 0) { - // Buy-From-Grid - this.calculateChargeEnergy.update(0); - this.calculateDischargeEnergy.update(activePower); - } else { - // Sell-To-Grid - this.calculateChargeEnergy.update(activePower * -1); - this.calculateDischargeEnergy.update(0); - } - } - - @Override - public Timedata getTimedata() { - return this.timedata; - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/Config.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/Config.java deleted file mode 100644 index 26202dff197..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/Config.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.openems.edge.deye.batteryinverter; - -import io.openems.edge.deye.batteryinverter.enums.CountryCode; -import io.openems.edge.deye.batteryinverter.enums.EnableDisable; -import org.osgi.service.metatype.annotations.AttributeDefinition; -import org.osgi.service.metatype.annotations.ObjectClassDefinition; - -import io.openems.edge.common.startstop.StartStopConfig; - -@ObjectClassDefinition(// - name = "Battery-Inverter Deye", // - description = "Implements the Deye battery inverter.") -public @interface Config { - - @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") - String id() default "batteryInverter0"; - - @AttributeDefinition(name = "Alias", description = "Human-readable name of this Component; defaults to Component-ID") - String alias() default ""; - - @AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?") - boolean enabled() default true; - - @AttributeDefinition(name = "Start/stop behaviour?", description = "Should this Component be forced to start or stop?") - StartStopConfig startStop() default StartStopConfig.AUTO; - - @AttributeDefinition(name = "Modbus-ID", description = "ID of Modbus bridge.") - String modbus_id(); - - @AttributeDefinition(name = "Modbus Unit-ID", description = "The Unit-ID of the Modbus device.") - int modbusUnitId() default 1; - - @AttributeDefinition(name = "Country Code", description = "Selection of the country code.") CountryCode countryCode() default CountryCode.GERMANY; - - @AttributeDefinition(name = "Is emergency power enabled?", description = "Emergency power enable/disable.") EnableDisable emergencyPower() default EnableDisable.DISABLE; - - @AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID'.") - String Modbus_target() default "(enabled=true)"; - - String webconsole_configurationFactory_nameHint() default "Battery-Inverter Deye [{id}]"; -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ActivePowerControlMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ActivePowerControlMode.java deleted file mode 100644 index d9691bbba40..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ActivePowerControlMode.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum ActivePowerControlMode implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - CONTANT_ACTIVE_POWER(0, "Constant Active Power"), // - VOLT_WATT_ENABLED(1, "Volt watt enabled"), // - CONSTANT_PF(2, "Constant power factor"), // - WATT_PF_ENABLED(3, "Watt power factor enabled");// - - private final int value; - private final String name; - - private ActivePowerControlMode(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Baudrate.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Baudrate.java deleted file mode 100644 index 74194f196a1..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Baudrate.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -//default 0 -public enum Baudrate implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - B_19200(0, "19200"), // - B_9600(1, "9600"); // - - private final int value; - private final String name; - - private Baudrate(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BlackStartMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BlackStartMode.java deleted file mode 100644 index 1abb25b25b2..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BlackStartMode.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum BlackStartMode implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - NORMAL_STARTUP(0, "Normal Start Up"), // - BLACK_STARTUP(1, "Black Start Up");// - - private final int value; - private final String name; - - private BlackStartMode(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BmsProtocolSelection.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BmsProtocolSelection.java deleted file mode 100644 index ca7794a37ff..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/BmsProtocolSelection.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum BmsProtocolSelection implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - ENERGY_PORT(0, "EP"), // - ALPHA(1, "Alpha-Ess"), // - PYLONTECH(2, "Pylontech"), // - BMSER(3, "Bmser"); // - - private final int value; - private final String name; - - private BmsProtocolSelection(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CountryCode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CountryCode.java deleted file mode 100644 index 9c20f47ece2..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CountryCode.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -public enum CountryCode { - - GERMANY("Germany"), // - AUSTRIA("Austria"), // - SWITZERLAND("Switzerland"); - - private final String value; - - private CountryCode(String value) { - this.value = value; - } - - public String getValue() { - return this.value; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CpuType.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CpuType.java deleted file mode 100644 index 38a5ae32b66..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/CpuType.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum CpuType implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - SINGLE_CPU(0, "Single Cpu"), // - DOUBLE_CPU(1, "Double Cpu");// - - private final int value; - private final String name; - - private CpuType(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/DcVoltageLevel.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/DcVoltageLevel.java deleted file mode 100644 index 47cc6fe8809..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/DcVoltageLevel.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum DcVoltageLevel implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - V_750(0, "750 V"), // - V_830(1, "830 V");// - - private final int value; - private final String name; - - private DcVoltageLevel(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/EnableDisable.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/EnableDisable.java deleted file mode 100644 index 6687d51ff7a..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/EnableDisable.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -public enum EnableDisable { - - ENABLE("Enable"), // - DISABLE("Disable"); - - private final String value; - - private EnableDisable(String value) { - this.value = value; - } - - public String getValue() { - return this.value; - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Epo.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Epo.java deleted file mode 100644 index 4e041753ab6..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Epo.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum Epo implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - INVALID(0, "Modbus"), // - EPO(1, "Sunspec"), // - DRMO(2, "Sunspec");// - - private final int value; - private final String name; - - private Epo(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyLevel.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyLevel.java deleted file mode 100644 index c76850b1b1a..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyLevel.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -public enum FrequencyLevel { - HZ_50("50 Hz", 0), // - HZ_60("60 Hz", 1);// - - private final String name; - private final int value; - - private FrequencyLevel(String name, int value) { - this.name = name; - this.value = value; - } - - public String getName() { - return this.name; - } - - public int getValue() { - return this.value; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyVariationRate.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyVariationRate.java deleted file mode 100644 index bb86a05d727..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/FrequencyVariationRate.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum FrequencyVariationRate implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - DISABLED(0, "Disabled"), // - RATE_0125(1, "Rate limit 0.125 Hz/s"), // - RATE_02(2, "Rate limit 0.2 Hz/s");// - - private final int value; - private final String name; - - private FrequencyVariationRate(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/GridCodeSelection.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/GridCodeSelection.java deleted file mode 100644 index 429deb65b58..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/GridCodeSelection.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -public enum GridCodeSelection { - SA1741("SA1741", 0), // - VDE("VDE", 1), // - AUSTRALIAN("Australian", 2), // - G99("G99", 3), // - HAWAIIAN("Hawaiian", 4), // - EN50549("EN50549", 5), // - AUSTRIA_TYPEA("Austria Type A", 6);// - - private final String name; - private final int value; - - private GridCodeSelection(String name, int value) { - this.name = name; - this.value = value; - } - - public String getName() { - return this.name; - } - - public int getValue() { - return this.value; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InterfaceType.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InterfaceType.java deleted file mode 100644 index 96d71d9ac4e..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InterfaceType.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum InterfaceType implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - RS_485(0, "RS-485"), // - ETHERNET(1, "Ethernet"); // - - private final int value; - private final String name; - - private InterfaceType(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InverterWiringTopology.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InverterWiringTopology.java deleted file mode 100644 index 3d19ac3e156..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/InverterWiringTopology.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -public enum InverterWiringTopology { - THREE_PHASE_FOUR_WIRE("3P4W"), // - THREE_PHASE_THREE_WIRE("3P3W or 3P3W+N"); // - - private final String value; - - private InverterWiringTopology(String value) { - this.value = value; - } - - public String getValue() { - return this.value; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ModulePowerLevel.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ModulePowerLevel.java deleted file mode 100644 index 8df965bcd39..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ModulePowerLevel.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum ModulePowerLevel implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - TEN_KW(0, " 10 kW"), // - TWENTY_KW(1, "20 kW"), // - THIRTY_KW(2, "30 kW"), // - TWENTY_NINE_KW(3, "29 kW"); // - - private final int value; - private final String name; - - private ModulePowerLevel(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PhaseAngleAbrupt.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PhaseAngleAbrupt.java deleted file mode 100644 index b1160a7cad8..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PhaseAngleAbrupt.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum PhaseAngleAbrupt implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - DISABLED(0, "Disabled"), // - ANGLE_ABRUPT_LIMIT_12_DEGREE(1, "Angle abrupt limit 12 deg"), // - ANGLE_ABRUPT_LIMIT_6_DEGREE(2, "Angle abrupt limit 6 deg"); // - - private final int value; - private final String name; - - private PhaseAngleAbrupt(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PowerRisingMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PowerRisingMode.java deleted file mode 100644 index f0fba7ebd3d..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/PowerRisingMode.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum PowerRisingMode implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - STEP(0, "Step Function"), // - RAMP(1, "Ramp Function");// - - private final int value; - private final String name; - - private PowerRisingMode(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ProtocolSelection.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ProtocolSelection.java deleted file mode 100644 index f527df7f2e8..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ProtocolSelection.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum ProtocolSelection implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - MODBUS(0, "Modbus"), // - SUNSPEC(1, "Sunspec"); // - - private final int value; - private final String name; - - private ProtocolSelection(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ReactivePowerControlMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ReactivePowerControlMode.java deleted file mode 100644 index e0a44553e4b..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/ReactivePowerControlMode.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum ReactivePowerControlMode implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - CONSTANT_REACTIVE_POWER(0, "Constant Reactive Power"), // - VOLT_VAR_ENABLED(1, "Volt Var Enabled"), // - CONSTANT_PF(2, "Constanr Power Factor"), // - WATT_PF_ENABLED(3, "Watt Power Factor Enabled"); // - - private final int value; - private final String name; - - private ReactivePowerControlMode(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelGridMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelGridMode.java deleted file mode 100644 index a4a720775f2..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelGridMode.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum SinexcelGridMode implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - ON_GRID(0, "On Grid"), // - OFF_GRID(1, "Off Grid"); // - - private final int value; - private final String name; - - private SinexcelGridMode(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelState.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelState.java deleted file mode 100644 index 144cc4f2c15..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinexcelState.java +++ /dev/null @@ -1,40 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum SinexcelState implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - OFF(1, "Off"), // - SLEEPING(2, "Sleeping"), // - STARTING(3, "Starting"), // - MPPT(4, "MPPT"), // - THROTTLED(5, "Throttled"), // - SHUTTINGDOWN(6, "Shutting Down"), // - FAULT(7, "Fault"), // - STANDBY(8, "Standby"), // - STARTED(9, "Started"); - - private final int value; - private final String option; - - private SinexcelState(int value, String option) { - this.value = value; - this.option = option; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.option; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } - -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinglePhaseMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinglePhaseMode.java deleted file mode 100644 index 30396d97c81..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/SinglePhaseMode.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum SinglePhaseMode implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - DISABLE(0, "Disable"), // - SINGLE_PHASE_230V(1, "Single Phae 230V"), // - SINGLE_PHASE_480V(2, "Single Phase 480V");// - - private final int value; - private final String name; - - private SinglePhaseMode(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/StartMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/StartMode.java deleted file mode 100644 index b2d985d7cd5..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/StartMode.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum StartMode implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - MANUAL(0, "Manual Start"), // - AUTO(1, "Auto Start"); // - - private final int value; - private final String name; - - private StartMode(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Switch.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Switch.java deleted file mode 100644 index aedd0fa157c..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/Switch.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -import io.openems.common.types.OptionsEnum; - -public enum Switch implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - NO_SWITCH(0, "No Switch"), // - SWITCH(1, "Switch");// - - private final int value; - private final String name; - - private Switch(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/VoltageLevel.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/VoltageLevel.java deleted file mode 100644 index 3a04e4106c8..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/enums/VoltageLevel.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.openems.edge.deye.batteryinverter.enums; - -public enum VoltageLevel { - V_380("380 V", 0), // - V_400("400 V", 1), // - V_480("480 V", 2); // - - private final String name; - private final int value; - - private VoltageLevel(String name, int value) { - this.name = name; - this.value = value; - } - - public String getName() { - return this.name; - } - - public int getValue() { - return this.value; - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/Context.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/Context.java deleted file mode 100644 index 1e0e20c445b..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/Context.java +++ /dev/null @@ -1,24 +0,0 @@ -package io.openems.edge.deye.batteryinverter.statemachine; - -import io.openems.edge.batteryinverter.api.OffGridBatteryInverter; -import io.openems.edge.deye.batteryinverter.BatteryInverterDeyeImpl; -import io.openems.edge.deye.batteryinverter.Config; -import io.openems.edge.common.statemachine.AbstractContext; - -public class Context extends AbstractContext { - - protected final Config config; - protected final OffGridBatteryInverter.TargetGridMode targetGridMode; - protected final int setActivePower; - protected final int setReactivePower; - - public Context(BatteryInverterDeyeImpl parent, Config config, OffGridBatteryInverter.TargetGridMode targetGridMode, int setActivePower, - int setReactivePower) { - super(parent); - this.config = config; - this.targetGridMode = targetGridMode; - this.setActivePower = setActivePower; - this.setReactivePower = setReactivePower; - } - -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/ErrorHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/ErrorHandler.java deleted file mode 100644 index af24355c131..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/ErrorHandler.java +++ /dev/null @@ -1,46 +0,0 @@ -package io.openems.edge.deye.batteryinverter.statemachine; - -import java.time.Duration; -import java.time.Instant; - -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.edge.deye.batteryinverter.BatteryInverterDeye; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; -import io.openems.edge.common.channel.BooleanWriteChannel; -import io.openems.edge.common.statemachine.StateHandler; - -public class ErrorHandler extends StateHandler { - - private static final int WAIT_SECONDS = 120; - - private Instant entryAt = Instant.MIN; - - @Override - protected void onEntry(Context context) throws OpenemsNamedException { - this.entryAt = Instant.now(); - - // Clear Failures - this.setClearFailureCommand(context); - - // Try to stop systems - final var inverter = context.getParent(); - inverter.setStopInverter(); - } - - @Override - public State runAndGetNextState(Context context) throws OpenemsNamedException { - if (Duration.between(this.entryAt, Instant.now()).getSeconds() > WAIT_SECONDS) { - // Try again - return State.UNDEFINED; - } - - // Wait - return State.ERROR; - } - - private void setClearFailureCommand(Context context) throws OpenemsNamedException { - BooleanWriteChannel setClearFailureCmd = context.getParent() - .channel(BatteryInverterDeye.ChannelId.CLEAR_FAILURE); - setClearFailureCmd.setNextWriteValue(true); // 1: true, other: illegal - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoRunningHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoRunningHandler.java deleted file mode 100644 index 34dd6333aed..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoRunningHandler.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.openems.edge.deye.batteryinverter.statemachine; - -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; -import io.openems.edge.common.statemachine.StateHandler; - -public class GoRunningHandler extends StateHandler { - - @Override - public State runAndGetNextState(Context context) throws OpenemsNamedException { - final var inverter = context.getParent(); - - /* - * Be sure to set the correct target grid mode - */ - var setOnGridMode = inverter.getSetOnGridMode().get(); - var setOffGridMode = inverter.getSetOffGridMode().get(); - switch (context.targetGridMode) { - case GO_ON_GRID: - if (setOnGridMode == Boolean.FALSE || setOffGridMode == Boolean.TRUE) { - inverter.setOnGridMode(true); - return State.GO_RUNNING; - } - break; - case GO_OFF_GRID: - if (setOnGridMode == Boolean.TRUE || setOffGridMode == Boolean.FALSE) { - inverter.setOffGridMode(true); - return State.GO_RUNNING; - } - break; - } - - inverter.setStartInverter(); - - if (inverter.getInverterState().get() == Boolean.TRUE) { - // Inverter is ON - return State.RUNNING; - } - // Still waiting - return State.GO_RUNNING; - } - -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoStoppedHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoStoppedHandler.java deleted file mode 100644 index f570503c526..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/GoStoppedHandler.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.openems.edge.deye.batteryinverter.statemachine; - -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; -import io.openems.edge.common.statemachine.StateHandler; - -public class GoStoppedHandler extends StateHandler { - - @Override - public State runAndGetNextState(Context context) throws OpenemsNamedException { - final var inverter = context.getParent(); - - inverter.setStopInverter(); - - if (inverter.getInverterState().get() == Boolean.FALSE) { - // Inverter is OFF - return State.STOPPED; - } - // Still waiting - return State.GO_STOPPED; - } - -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/RunningHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/RunningHandler.java deleted file mode 100644 index 727206eaa19..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/RunningHandler.java +++ /dev/null @@ -1,44 +0,0 @@ -package io.openems.edge.deye.batteryinverter.statemachine; - -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.edge.deye.batteryinverter.BatteryInverterDeye; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; -import io.openems.edge.common.channel.IntegerWriteChannel; -import io.openems.edge.common.startstop.StartStop; -import io.openems.edge.common.statemachine.StateHandler; - -public class RunningHandler extends StateHandler { - - @Override - public State runAndGetNextState(Context context) throws OpenemsNamedException { - final var inverter = context.getParent(); - - if (inverter.hasFaults() || inverter.getInverterState().get() == Boolean.FALSE) { - return State.UNDEFINED; - } - - // Mark as started - inverter._setStartStop(StartStop.START); - - // Apply Active and Reactive Power Set-Points - this.applyPower(context); - - return State.RUNNING; - } - - /** - * Applies the Active and Reactive Power Set-Points. - * - * @param context the {@link Context} - * @throws OpenemsNamedException on error - */ - private void applyPower(Context context) throws OpenemsNamedException { - final var inverter = context.getParent(); - - IntegerWriteChannel setActivePower = inverter.channel(BatteryInverterDeye.ChannelId.SET_ACTIVE_POWER); - setActivePower.setNextWriteValue(context.setActivePower); - - IntegerWriteChannel setReactivePower = inverter.channel(BatteryInverterDeye.ChannelId.SET_REACTIVE_POWER); - setReactivePower.setNextWriteValue(context.setReactivePower); - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StateMachine.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StateMachine.java deleted file mode 100644 index 815f79ab5a1..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StateMachine.java +++ /dev/null @@ -1,70 +0,0 @@ -package io.openems.edge.deye.batteryinverter.statemachine; - -import io.openems.common.types.OptionsEnum; -import io.openems.edge.common.statemachine.AbstractStateMachine; -import io.openems.edge.common.statemachine.StateHandler; - -public class StateMachine extends AbstractStateMachine { - - public enum State implements io.openems.edge.common.statemachine.State, OptionsEnum { - UNDEFINED(-1), // - - GO_RUNNING(10), // - RUNNING(11), // - - GO_STOPPED(20), // - STOPPED(21), // - - ERROR(30) // - ; - - private final int value; - - private State(int value) { - this.value = value; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name(); - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } - - @Override - public State[] getStates() { - return State.values(); - } - } - - public StateMachine(State initialState) { - super(initialState); - } - - @Override - public StateHandler getStateHandler(State state) { - switch (state) { - case UNDEFINED: - return new UndefinedHandler(); - case GO_RUNNING: - return new GoRunningHandler(); - case RUNNING: - return new RunningHandler(); - case GO_STOPPED: - return new GoStoppedHandler(); - case STOPPED: - return new StoppedHandler(); - case ERROR: - return new ErrorHandler(); - } - throw new IllegalArgumentException("Unknown State [" + state + "]"); - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StoppedHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StoppedHandler.java deleted file mode 100644 index fdda56d3728..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/StoppedHandler.java +++ /dev/null @@ -1,19 +0,0 @@ -package io.openems.edge.deye.batteryinverter.statemachine; - -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; -import io.openems.edge.common.startstop.StartStop; -import io.openems.edge.common.statemachine.StateHandler; - -public class StoppedHandler extends StateHandler { - - @Override - public State runAndGetNextState(Context context) throws OpenemsNamedException { - final var inverter = context.getParent(); - - // Mark as stopped - inverter._setStartStop(StartStop.STOP); - return State.STOPPED; - } - -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/UndefinedHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/UndefinedHandler.java deleted file mode 100644 index c932a3d993d..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/batteryinverter/statemachine/UndefinedHandler.java +++ /dev/null @@ -1,36 +0,0 @@ -package io.openems.edge.deye.batteryinverter.statemachine; - -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.edge.deye.batteryinverter.statemachine.StateMachine.State; -import io.openems.edge.common.statemachine.StateHandler; - -public class UndefinedHandler extends StateHandler { - - @Override - public State runAndGetNextState(Context context) throws OpenemsNamedException { - final var inverter = context.getParent(); - switch (inverter.getStartStopTarget()) { - case UNDEFINED: - // Stuck in UNDEFINED State - return State.UNDEFINED; - - case START: - // force START - if (inverter.hasFaults()) { - // Has Faults -> error handling - return State.ERROR; - } else { - // No Faults -> start - return State.GO_RUNNING; - } - - case STOP: - // force STOP - return State.GO_STOPPED; - } - - assert false; - return State.UNDEFINED; // can never happen - } - -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java index a8e1812bb4e..72d449f8374 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java @@ -18,9 +18,6 @@ @AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?") boolean enabled() default true; - @AttributeDefinition(name = "Meter-Type", description = "What is measured by this Meter?") - MeterType type() default MeterType.GRID; - @AttributeDefinition(name = "Modbus-ID", description = "ID of Modbus bridge.") String modbus_id() default "modbus0"; diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java index e743f632977..dd7d9117293 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java @@ -1,18 +1,5 @@ package io.openems.edge.deye.gridmeter; -import org.osgi.service.cm.ConfigurationAdmin; -import org.osgi.service.component.ComponentContext; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.ConfigurationPolicy; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.component.annotations.ReferencePolicyOption; -import org.osgi.service.event.propertytypes.EventTopics; -import org.osgi.service.metatype.annotations.Designate; - import io.openems.common.exceptions.OpenemsException; import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; import io.openems.edge.bridge.modbus.api.BridgeModbus; @@ -23,7 +10,6 @@ import io.openems.edge.common.component.OpenemsComponent; import io.openems.edge.common.event.EdgeEventConstants; import io.openems.edge.common.taskmanager.Priority; -import io.openems.edge.deye.batteryinverter.BatteryInverterDeye; import io.openems.edge.meter.api.ElectricityMeter; import io.openems.edge.meter.api.MeterType; import org.osgi.service.cm.ConfigurationAdmin; From f7c4086d9c7cbb66681b1a91ea1492ae524490c9 Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Thu, 4 Apr 2024 14:15:32 +0200 Subject: [PATCH 05/25] Deye implementation --- .../deye/common/BatteryMaintenanceState.java | 32 + .../deye/common/BatteryStringSwitchState.java | 35 + .../edge/deye/common/BmsDcdcWorkMode.java | 33 + .../edge/deye/common/BmsDcdcWorkState.java | 37 + .../io/openems/edge/deye/common/Config.java | 54 + .../openems/edge/deye/common/ControlMode.java | 32 + .../edge/deye/common/DeyeSunHybrid.java | 1208 +++++++++++++++++ .../edge/deye/common/DeyeSunHybridImpl.java | 491 +++++++ .../edge/deye/common/InverterState.java | 38 + .../edge/deye/common/SetWorkState.java | 33 + .../deye/common/SurplusFeedInHandler.java | 215 +++ .../common/SurplusFeedInStateMachine.java | 34 + .../edge/deye/common/SystemManufacturer.java | 31 + .../openems/edge/deye/common/SystemState.java | 36 + .../openems/edge/deye/common/SystemType.java | 31 + .../common/charger/AbstractEssDeyePv.java | 245 ++++ .../edge/deye/common/charger/ConfigPv1.java | 30 + .../edge/deye/common/charger/ConfigPv2.java | 30 + .../deye/common/charger/DeyeSun2Impl.java | 94 ++ .../edge/deye/common/charger/DeyeSunImpl.java | 92 ++ .../edge/deye/common/charger/DeyeSunPv.java | 97 ++ .../openems/edge/deye/gridmeter/Config.java | 2 - .../{meter => productionmeter}/Config.java | 5 +- .../{meter => productionmeter}/DeyeMeter.java | 2 +- .../DeyeMeterImpl.java | 88 +- .../deye/gridmeter/DeyeGridMeterImplTest.java | 7 + .../openems/edge/deye/gridmeter/MyConfig.java | 75 + .../gridmeter/SurplusFeedInStateMachine.java | 34 + 28 files changed, 3125 insertions(+), 16 deletions(-) create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BatteryMaintenanceState.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BatteryStringSwitchState.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BmsDcdcWorkMode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BmsDcdcWorkState.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/Config.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/ControlMode.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/InverterState.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SetWorkState.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInHandler.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInStateMachine.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemManufacturer.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemState.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemType.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/AbstractEssDeyePv.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv1.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv2.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSun2Impl.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunImpl.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunPv.java rename io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/{meter => productionmeter}/Config.java (88%) rename io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/{meter => productionmeter}/DeyeMeter.java (91%) rename io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/{meter => productionmeter}/DeyeMeterImpl.java (51%) create mode 100644 io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/DeyeGridMeterImplTest.java create mode 100644 io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/MyConfig.java create mode 100644 io.openems.edge.ess.fenecon.commercial40/src/io/openems/edge/deye/gridmeter/SurplusFeedInStateMachine.java diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BatteryMaintenanceState.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BatteryMaintenanceState.java new file mode 100644 index 00000000000..a346c84c6a7 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BatteryMaintenanceState.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.common; + +import io.openems.common.types.OptionsEnum; + +public enum BatteryMaintenanceState implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + OFF(0, "Off"), // + ON(1, "On"); // + + private final int value; + private final String name; + + private BatteryMaintenanceState(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BatteryStringSwitchState.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BatteryStringSwitchState.java new file mode 100644 index 00000000000..36676880d15 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BatteryStringSwitchState.java @@ -0,0 +1,35 @@ +package io.openems.edge.deye.common; + +import io.openems.common.types.OptionsEnum; + +public enum BatteryStringSwitchState implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + MAIN_CONTATCTOR(1, "Main contactor"), // + PRECHARGE_CONTACTOR(2, "Precharge contactor"), // + FAN_CONTACTOR(4, "FAN contactor"), // + BMU_POWER_SUPPLY_RELAY(8, "BMU power supply relay"), // + MIDDLE_RELAY(16, "Middle relay"); + + private final int value; + private final String name; + + private BatteryStringSwitchState(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BmsDcdcWorkMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BmsDcdcWorkMode.java new file mode 100644 index 00000000000..e953e73f042 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BmsDcdcWorkMode.java @@ -0,0 +1,33 @@ +package io.openems.edge.deye.common; + +import io.openems.common.types.OptionsEnum; + +public enum BmsDcdcWorkMode implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + CONSTANT_CURRENT(128, "Constant Current"), // + CONSTANT_VOLTAGE(256, "Constant Voltage"), // + BOOST_MPPT(512, "Boost MPPT"); // + + private final int value; + private final String name; + + private BmsDcdcWorkMode(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BmsDcdcWorkState.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BmsDcdcWorkState.java new file mode 100644 index 00000000000..6ab1dd0f2ab --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BmsDcdcWorkState.java @@ -0,0 +1,37 @@ +package io.openems.edge.deye.common; + +import io.openems.common.types.OptionsEnum; + +public enum BmsDcdcWorkState implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + INITIAL(2, "Initial"), // + STOP(4, "Stop"), // + READY(8, "Ready"), // + RUNNING(16, "Running"), // + FAULT(32, "Fault"), // + DEBUG(64, "Debug"), // + LOCKED(128, "Locked"); // + + private final int value; + private final String name; + + private BmsDcdcWorkState(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/Config.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/Config.java new file mode 100644 index 00000000000..37f5edc8a08 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/Config.java @@ -0,0 +1,54 @@ +package io.openems.edge.deye.common; + +import org.osgi.service.metatype.annotations.AttributeDefinition; +import org.osgi.service.metatype.annotations.ObjectClassDefinition; + +@ObjectClassDefinition(// + name = "Deye.Sun.Hybrid - MaMoTec", // + description = "Deye.Sun.Hybrid.") +@interface Config { + + @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") + String id() default "ess0"; + + @AttributeDefinition(name = "Alias", description = "Human-readable name of this Component; defaults to Component-ID") + String alias() default ""; + + @AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?") + boolean enabled() default true; + + @AttributeDefinition(name = "Read-Only mode", description = "Enables Read-Only mode") + boolean readOnlyMode() default false; + + @AttributeDefinition(name = "Modbus-ID", description = "ID of Modbus bridge.") + String modbus_id() default "modbus0"; + + @AttributeDefinition(name = "Modbus-Unit-ID", description = "Unit ID of Modbus bridge.") + int unit_id() default 0; + + @AttributeDefinition(name = "Power limit on PowerDecreaseCausedByOvertemperature error; '0' to disable power limit logic", description = "") + int powerLimitOnPowerDecreaseCausedByOvertemperatureChannel() default 20_000; + + @AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID'.") + String Modbus_target() default "(enabled=true)"; + + @AttributeDefinition(name = "Surplus Feed-In: State-of-Charge limit", description = "Start Surplus-feed-in if State-of-Charge is bigger than this limit") + int surplusFeedInSocLimit() default 90; + + @AttributeDefinition(name = "Surplus Feed-In: Allowed-Charge-Power limit", description = "Start Surplus-feed-in if Charge-Power is smaller than this limit. (Needs to set negative)") + int surplusFeedInAllowedChargePowerLimit() default -8_000; + + @AttributeDefinition(name = "Surplus Feed-In: Increase Power by percentage", description = "1.1 for 10 %") + double surplusFeedInIncreasePowerFactor() default 1.1; + + @AttributeDefinition(name = "Surplus Feed-In: Max increase Power", description = "") + int surplusFeedInMaxIncreasePowerFactor() default 2_000; + + @AttributeDefinition(name = "Surplus Feed-In: Off Time", description = "The time to stop grid feed in.") + String surplusFeedInOffTime() default "17:00:00"; + + @AttributeDefinition(name = "Surplus Feed-In: PV-Limit on PowerDecreaseCausedByOvertemperature", description = "") + int surplusFeedInPvLimitOnPowerDecreaseCausedByOvertemperature() default 5_000; + + String webconsole_configurationFactory_nameHint() default "Deye [{id}]"; +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/ControlMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/ControlMode.java new file mode 100644 index 00000000000..d0d94d39855 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/ControlMode.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.common; + +import io.openems.common.types.OptionsEnum; + +public enum ControlMode implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + REMOTE(1, "Remote"), // + LOCAL(2, "Local"); // + + private final int value; + private final String name; + + private ControlMode(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java new file mode 100644 index 00000000000..25f3c28a4a6 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java @@ -0,0 +1,1208 @@ +package io.openems.edge.deye.common; + +import io.openems.common.channel.AccessMode; +import io.openems.common.channel.Level; +import io.openems.common.channel.PersistencePriority; +import io.openems.common.channel.Unit; +import io.openems.common.types.OpenemsType; +import io.openems.edge.common.channel.Doc; +import io.openems.edge.common.channel.IntegerDoc; +import io.openems.edge.common.channel.IntegerReadChannel; +import io.openems.edge.common.channel.StateChannel; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.common.modbusslave.ModbusSlave; +import io.openems.edge.deye.common.charger.DeyeSunPv; +import io.openems.edge.ess.api.ManagedSymmetricEss; +import io.openems.edge.ess.api.SymmetricEss; +import io.openems.edge.timedata.api.TimedataProvider; +import org.osgi.service.event.EventHandler; + +public interface DeyeSunHybrid + extends ManagedSymmetricEss, SymmetricEss, OpenemsComponent, EventHandler, ModbusSlave, TimedataProvider { + + /** + * Gets the Modbus Unit-ID. + * + * @return the Unit-ID + */ + public Integer getUnitId(); + + /** + * Gets the Modbus-Bridge Component-ID, i.e. "modbus0". + * + * @return the Component-ID + */ + public String getModbusBridgeId(); + + /** + * Registers a Charger with this ESS. + * + * @param charger the Charger + */ + public void addCharger(DeyeSunPv charger); + + /** + * Unregisters a Charger from this ESS. + * + * @param charger the Charger + */ + public void removeCharger(DeyeSunPv charger); + + public enum ChannelId implements io.openems.edge.common.channel.ChannelId { + // EnumReadChannels + SERIAL_NUMBER(Doc.of(OpenemsType.STRING) // + .persistencePriority(PersistencePriority.HIGH) // + .accessMode(AccessMode.READ_ONLY)), + CONTROL_MODE(Doc.of(ControlMode.values())), // + BATTERY_MAINTENANCE_STATE(Doc.of(BatteryMaintenanceState.values())), // + SYSTEM_MANUFACTURER(Doc.of(SystemManufacturer.values())), // + SYSTEM_TYPE(Doc.of(SystemType.values())), // + BATTERY_STRING_SWITCH_STATE(Doc.of(BatteryStringSwitchState.values())), // + BMS_DCDC_WORK_STATE(Doc.of(BmsDcdcWorkState.values())), // + BMS_DCDC_WORK_MODE(Doc.of(BmsDcdcWorkMode.values())), // + SURPLUS_FEED_IN_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT)), // + SURPLUS_FEED_IN_STATE_MACHINE(Doc.of(SurplusFeedInStateMachine.values())), + + + // Gen Port Use Channels + // AC 1/28/2024 + SET_GRID_LOAD_OFF_POWER(Doc.of(OpenemsType.INTEGER) + .unit(Unit.PERCENT) // + .accessMode(AccessMode.WRITE_ONLY)), //), // + + // Battery Channels + // AC 1/31/2024 + BATTERY_CAPACITY(Doc.of(OpenemsType.INTEGER) + .unit(Unit.AMPERE_HOURS) + .accessMode(AccessMode.READ_WRITE)), + BATTERY_CAPACITY_SHUTDOWN(Doc.of(OpenemsType.INTEGER) + .unit(Unit.PERCENT)), + BATTERY_CAPACITY_RESTART(Doc.of(OpenemsType.INTEGER) + .unit(Unit.PERCENT)), + BATTERY_CAPACITY_LOW_BATTERY(Doc.of(OpenemsType.INTEGER) + .unit(Unit.PERCENT)), + MAX_A_BATTERY_CHARGE_CURRENT(Doc.of(OpenemsType.INTEGER) + .unit(Unit.AMPERE)), + MAX_A_BATTERY_DISCHARGE_CURRENT(Doc.of(OpenemsType.INTEGER) + .unit(Unit.AMPERE)), + PARALLEL_BAT_1_AND_BAT_2(Doc.of(OpenemsType.INTEGER)), + BAT_1_SOC(Doc.of(OpenemsType.INTEGER)), + + // Battery Time of Use settings + // AC 2/16/2024 + TIME_OF_USE_SELLING_FLAG(Doc.of(OpenemsType.BOOLEAN) + .accessMode(AccessMode.READ_WRITE)), + + TIME_OF_USE_ENABLED_FLAG(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + TIME_OF_USE_MONDAY(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + TIME_OF_USE_TUESDAY(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + TIME_OF_USE_WEDNESDAY(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + TIME_OF_USE_THURSDAY(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + TIME_OF_USE_FRIDAY(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + TIME_OF_USE_SATURDAY(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + TIME_OF_USE_SUNDAY(Doc.of(OpenemsType.BOOLEAN) // + .accessMode(AccessMode.READ_WRITE)), // + + // Generator and Grid Channels + // AC 1/31/2024 + GEN_MAX_RUN_TIME(Doc.of(OpenemsType.INTEGER) + .unit(Unit.HOUR)), + GEN_COOLING_TIME(Doc.of(OpenemsType.INTEGER) + .unit(Unit.HOUR)), + GEN_CHARGING_STARTING_CAPACITY_POINT(Doc.of(OpenemsType.INTEGER) + .unit(Unit.PERCENT)), + GEN_CHARGING_CURRENT_TO_BATTERY(Doc.of(OpenemsType.INTEGER) + .unit(Unit.AMPERE)), + GEN_CHARGE_ENABLED(Doc.of(OpenemsType.INTEGER)), + GRID_CHARGING_STARTING_CAPACITY_POINT(Doc.of(OpenemsType.INTEGER) + .unit(Unit.PERCENT)), + GRID_CHARGING_CURRENT_TO_BATTERY(Doc.of(OpenemsType.INTEGER) + .unit(Unit.AMPERE)), + GRID_CHARGE_ENABLED(Doc.of(OpenemsType.INTEGER)), + AC_COUPLE_FREQUENCY_CAP(Doc.of(OpenemsType.INTEGER)), + GEN_LOAD_OFF_POWER(Doc.of(OpenemsType.INTEGER) + .unit(Unit.PERCENT)), + GEN_LOAD_ON_POWER(Doc.of(OpenemsType.INTEGER) + .unit(Unit.PERCENT)), + GEN_GRID_SIGNAL(Doc.of(OpenemsType.INTEGER)), + GEN_CONNECTED_TO_GRID_INPUT(Doc.of(OpenemsType.INTEGER)), + GEN_PEAK_SHAVING_POWER(Doc.of(OpenemsType.INTEGER) + .unit(Unit.WATT)), + GRID_PEAK_SHAVING_POWER(Doc.of(OpenemsType.INTEGER) + .unit(Unit.WATT)), + + // Solar Channels + // AC 1/31/2024 + SOLAR_SELL(Doc.of(OpenemsType.INTEGER)), + + TIME_POINT_1_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER) + .accessMode(AccessMode.READ_WRITE)), + TIME_POINT_2_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER) + .accessMode(AccessMode.READ_WRITE)), + TIME_POINT_3_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER) + .accessMode(AccessMode.READ_WRITE)), + TIME_POINT_4_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER) + .accessMode(AccessMode.READ_WRITE)), + TIME_POINT_5_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER) + .accessMode(AccessMode.READ_WRITE)), + TIME_POINT_6_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER) + .accessMode(AccessMode.READ_WRITE)), + + SELL_MODE_TIME_POINT_1(Doc.of(OpenemsType.INTEGER) + .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_2(Doc.of(OpenemsType.INTEGER) + .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_3(Doc.of(OpenemsType.INTEGER) + .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_4(Doc.of(OpenemsType.INTEGER) + .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_5(Doc.of(OpenemsType.INTEGER) + .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_6(Doc.of(OpenemsType.INTEGER) + .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_1_POWER(Doc.of(OpenemsType.INTEGER) + .unit(Unit.WATT) + .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_2_POWER(Doc.of(OpenemsType.INTEGER) + .unit(Unit.WATT) + .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_3_POWER(Doc.of(OpenemsType.INTEGER) + .unit(Unit.WATT) + .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_4_POWER(Doc.of(OpenemsType.INTEGER) + .unit(Unit.WATT) + .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_5_POWER(Doc.of(OpenemsType.INTEGER) + .unit(Unit.WATT) + .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_6_POWER(Doc.of(OpenemsType.INTEGER) + .unit(Unit.WATT) + .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_CAPACITY_1(Doc.of(OpenemsType.INTEGER) + .unit(Unit.PERCENT) + .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_CAPACITY_2(Doc.of(OpenemsType.INTEGER) + .unit(Unit.PERCENT) + .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_CAPACITY_3(Doc.of(OpenemsType.INTEGER) + .unit(Unit.PERCENT) + .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_CAPACITY_4(Doc.of(OpenemsType.INTEGER) + .unit(Unit.PERCENT) + .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_CAPACITY_5(Doc.of(OpenemsType.INTEGER) + .unit(Unit.PERCENT) + .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_CAPACITY_6(Doc.of(OpenemsType.INTEGER) + .unit(Unit.PERCENT) + .accessMode(AccessMode.READ_WRITE)), + MICROINVERTER_EXPORT_TO_GRID_CUTOFF(Doc.of(OpenemsType.INTEGER)), + SOLAR_ARC_FAULT_ON(Doc.of(OpenemsType.INTEGER)), + MAX_SOLAR_SELL_POWER(Doc.of(OpenemsType.INTEGER) + .unit(Unit.WATT)), + + // Other Channels + // AC 1/31/2024 + ZERO_EXPORT_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT) + .accessMode(AccessMode.READ_WRITE)), + UPS_BACKUP_DELAY_TIME(Doc.of(OpenemsType.INTEGER) + .unit(Unit.SECONDS)), + + // EnumWriteChannels + SET_WORK_STATE(Doc.of(SetWorkState.values()) // + .accessMode(AccessMode.WRITE_ONLY)), // + + // IntegerWriteChannel + SET_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT) // + .accessMode(AccessMode.WRITE_ONLY)), // + SET_REACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.VOLT_AMPERE_REACTIVE) // + .accessMode(AccessMode.WRITE_ONLY)), // + + SET_GEN_PEAK_SHAVING_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT) // + .accessMode(AccessMode.WRITE_ONLY)), // + SET_GRID_PEAK_SHAVING_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT) // + .accessMode(AccessMode.WRITE_ONLY)), // + CT_RATIO(Doc.of(OpenemsType.INTEGER)), // + INVERTER_RUN_STATE(Doc.of(OpenemsType.INTEGER)), // + + // LongReadChannel + ORIGINAL_ACTIVE_CHARGE_ENERGY(Doc.of(OpenemsType.LONG)), // + ORIGINAL_ACTIVE_DISCHARGE_ENERGY(Doc.of(OpenemsType.LONG)), // + + // IntegerReadChannels + ORIGINAL_ALLOWED_CHARGE_POWER(new IntegerDoc() // + .onChannelUpdate((self, newValue) -> { + // on each Update to the channel -> set the ALLOWED_CHARGE_POWER value with a + // delta of max 500 + IntegerReadChannel currentValueChannel = self + .channel(ManagedSymmetricEss.ChannelId.ALLOWED_CHARGE_POWER); + var originalValue = newValue.asOptional(); + var currentValue = currentValueChannel.value().asOptional(); + final int value; + if (!originalValue.isPresent() && !currentValue.isPresent()) { + value = 0; + } else if (originalValue.isPresent() && !currentValue.isPresent()) { + value = originalValue.get(); + } else if (!originalValue.isPresent() && currentValue.isPresent()) { + value = currentValue.get(); + } else { + value = Math.max(originalValue.get(), currentValue.get() - 500); + } + currentValueChannel.setNextValue(value); + })), // + + ORIGINAL_ALLOWED_DISCHARGE_POWER(new IntegerDoc() // + .onChannelUpdate((self, newValue) -> { + // on each Update to the channel -> set the ALLOWED_DISCHARGE_POWER value with a + // delta of max 500 + IntegerReadChannel currentValueChannel = self + .channel(ManagedSymmetricEss.ChannelId.ALLOWED_DISCHARGE_POWER); + var originalValue = newValue.asOptional(); + var currentValue = currentValueChannel.value().asOptional(); + final int value; + if (!originalValue.isPresent() && !currentValue.isPresent()) { + value = 0; + } else if (originalValue.isPresent() && !currentValue.isPresent()) { + value = originalValue.get(); + } else if (!originalValue.isPresent() && currentValue.isPresent()) { + value = currentValue.get(); + } else { + value = Math.min(originalValue.get(), currentValue.get() + 500); + } + currentValueChannel.setNextValue(value); + })), // + + PROTOCOL_VERSION(Doc.of(OpenemsType.INTEGER)), // + BATTERY_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + BATTERY_CURRENT(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIAMPERE)), // + BATTERY_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT)), // + AC_CHARGE_ENERGY(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.CUMULATED_WATT_HOURS)), // + AC_DISCHARGE_ENERGY(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.CUMULATED_WATT_HOURS)), // + GRID_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT)), // + APPARENT_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.VOLT_AMPERE)), // + CURRENT_L1(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIAMPERE)), // + CURRENT_L2(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIAMPERE)), // + CURRENT_L3(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIAMPERE)), // + VOLTAGE_L1(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + VOLTAGE_L2(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + VOLTAGE_L3(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + FREQUENCY(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIHERTZ)), // + INVERTER_VOLTAGE_L1(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + INVERTER_VOLTAGE_L2(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + INVERTER_VOLTAGE_L3(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + INVERTER_CURRENT_L1(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIAMPERE)), // + INVERTER_CURRENT_L2(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIAMPERE)), // + INVERTER_CURRENT_L3(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIAMPERE)), // + IPM_TEMPERATURE_L1(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.DEGREE_CELSIUS)), // + IPM_TEMPERATURE_L2(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.DEGREE_CELSIUS)), // + IPM_TEMPERATURE_L3(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.DEGREE_CELSIUS)), // + TRANSFORMER_TEMPERATURE_L2(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.DEGREE_CELSIUS)), // + BATTERY_STRING_TOTAL_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + BATTERY_STRING_TOTAL_CURRENT(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIAMPERE)), // + BATTERY_STRING_SOH(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.PERCENT)), // + BATTERY_STRING_AVG_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.DEGREE_CELSIUS)), // + BATTERY_STRING_CHARGE_CURRENT_LIMIT(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIAMPERE)), // + BATTERY_STRING_DISCHARGE_CURRENT_LIMIT(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIAMPERE)), // + BATTERY_STRING_CYCLES(Doc.of(OpenemsType.INTEGER)), // + BATTERY_STRING_CHARGE_ENERGY(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.CUMULATED_WATT_HOURS)), // + BATTERY_STRING_DISCHARGE_ENERGY(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.CUMULATED_WATT_HOURS)), // + BATTERY_STRING_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT)), // + BATTERY_STRING_MAX_CELL_VOLTAGE_NO(Doc.of(OpenemsType.INTEGER)), // + BATTERY_STRING_MAX_CELL_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + BATTERY_STRING_MAX_CELL_VOLTAGE_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.DEGREE_CELSIUS)), // + BATTERY_STRING_MIN_CELL_VOLTAGE_NO(Doc.of(OpenemsType.INTEGER)), // + BATTERY_STRING_MIN_CELL_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + BATTERY_STRING_MIN_CELL_VOLTAGE_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.DEGREE_CELSIUS)), // + BATTERY_STRING_MAX_CELL_TEMPERATURE_NO(Doc.of(OpenemsType.INTEGER)), // + BATTERY_STRING_MAX_CELL_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.DEGREE_CELSIUS)), // + BATTERY_STRING_MAX_CELL_TEMPERATURE_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + BATTERY_STRING_MIN_CELL_TEMPERATURE_NO(Doc.of(OpenemsType.INTEGER)), // + BATTERY_STRING_MIN_CELL_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.DEGREE_CELSIUS)), // + BATTERY_STRING_MIN_CELL_TEMPERATURE_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_1_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_2_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_3_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_4_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_5_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_6_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_7_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_8_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_9_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_10_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_11_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_12_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_13_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_14_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_15_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_16_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_17_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_18_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_19_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_20_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_21_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_22_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_23_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_24_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_25_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_26_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_27_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_28_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_29_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_30_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_31_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_32_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_33_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_34_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_35_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_36_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_37_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_38_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_39_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_40_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_41_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_42_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_43_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_44_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_45_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_46_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_47_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_48_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_49_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_50_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_51_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_52_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_53_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_54_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_55_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_56_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_57_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_58_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_59_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_60_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_61_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_62_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_63_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_64_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_65_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_66_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_67_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_68_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_69_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_70_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_71_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_72_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_73_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_74_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_75_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_76_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_77_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_78_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_79_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_80_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_81_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_82_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_83_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_84_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_85_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_86_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_87_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_88_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_89_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_90_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_91_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_92_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_93_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_94_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_95_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_96_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_97_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_98_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_99_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_100_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_101_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_102_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_103_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_104_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_105_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_106_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_107_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_108_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_109_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_110_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_111_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_112_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_113_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_114_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_115_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_116_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_117_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_118_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_119_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_120_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_121_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_122_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_123_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_124_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_125_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_126_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_127_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_128_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_129_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_130_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_131_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_132_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_133_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_134_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_135_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_136_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_137_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_138_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_139_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_140_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_141_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_142_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_143_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_144_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_145_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_146_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_147_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_148_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_149_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_150_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_151_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_152_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_153_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_154_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_155_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_156_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_157_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_158_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_159_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_160_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_161_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_162_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_163_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_164_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_165_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_166_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_167_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_168_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_169_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_170_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_171_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_172_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_173_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_174_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_175_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_176_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_177_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_178_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_179_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_180_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_181_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_182_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_183_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_184_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_185_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_186_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_187_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_188_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_189_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_190_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_191_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_192_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_193_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_194_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_195_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_196_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_197_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_198_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_199_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_200_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_201_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_202_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_203_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_204_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_205_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_206_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_207_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_208_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_209_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_210_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_211_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_212_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_213_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_214_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_215_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_216_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_217_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_218_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_219_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_220_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_221_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_222_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_223_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + CELL_224_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + + // StateChannels + SYSTEM_ERROR(Doc.of(Level.FAULT) // + .onInit(new StateChannel.TriggerOnAny(SystemErrorChannelId.values())) + .text("System-Error. More information at: https://deyeinverter.com/")), // + INSUFFICIENT_GRID_PARAMTERS(Doc.of(Level.FAULT) // + .onInit(new StateChannel.TriggerOnAny(InsufficientGridParametersChannelId.values())) + .text("Insufficient Grid Parameters. More information at: https://deyeinverter.com/")), // + POWER_DECREASE_CAUSED_BY_OVERTEMPERATURE(Doc.of(Level.FAULT) // + .onInit(new StateChannel.TriggerOnAny(PowerDecreaseCausedByOvertemperatureChannelId.values())) + .text("Power Decrease caused by Overtemperature. More information at: https://deyeinverter.com/")), // + EMERGENCY_STOP_ACTIVATED(Doc.of(Level.WARNING) // + .text("Emergency Stop has been activated. More information at: https://deyeinverter.com/")), // + KEY_MANUAL_ACTIVATED(Doc.of(Level.WARNING) // + .text("Key Manual has been activated. More information at: https://deyeinverter.com/")), // + BECU_UNIT_DEFECTIVE(Doc.of(Level.FAULT) // + .text("BECU Unit is defective. More information at: https://deyeinverter.com/")), // + ; + + private final Doc doc; + + private ChannelId(Doc doc) { + this.doc = doc; + } + + @Override + public Doc doc() { + return this.doc; + } + + } + + /** + * Source-Channels for {@link ChannelId#SYSTEM_ERROR}. + */ + public static enum SystemErrorChannelId implements io.openems.edge.common.channel.ChannelId { + STATE_2(Doc.of(OpenemsType.BOOLEAN) // + .text("Transformer Phase B Temperature Sensor Invalidation")), + STATE_3(Doc.of(OpenemsType.BOOLEAN) // + .text("SD Memory Card Invalidation")), // + STATE_4(Doc.of(OpenemsType.BOOLEAN) // + .text("Inverter Communication Abnormity")), // + STATE_5(Doc.of(OpenemsType.BOOLEAN) // + .text("Battery Stack Communication Abnormity")), // + STATE_6(Doc.of(OpenemsType.BOOLEAN) // + .text("Multifunctional Ammeter Communication Abnormity")), // + STATE_7(Doc.of(OpenemsType.BOOLEAN) // + .text("Remote Communication Abnormity")), // + STATE_8(Doc.of(OpenemsType.BOOLEAN) // + .text("PVDC1 Communication Abnormity")), // + STATE_9(Doc.of(OpenemsType.BOOLEAN) // + .text("PVDC2 Communication Abnormity")), // + STATE_10(Doc.of(OpenemsType.BOOLEAN) // + .text("Transformer Severe Overtemperature")), // + STATE_11(Doc.of(OpenemsType.BOOLEAN) // + .text("DC Precharge Contactor Close Unsuccessfully")), // + STATE_12(Doc.of(OpenemsType.BOOLEAN) // + .text("AC Precharge Contactor Close Unsuccessfully")), // + STATE_13(Doc.of(OpenemsType.BOOLEAN) // + .text("AC Main Contactor Close Unsuccessfully")), // + STATE_14(Doc.of(OpenemsType.BOOLEAN) // + .text("DC Electrical Breaker1 Close Unsuccessfully")), // + STATE_15(Doc.of(OpenemsType.BOOLEAN) // + .text("DC Main Contactor Close Unsuccessfully")), // + STATE_16(Doc.of(OpenemsType.BOOLEAN) // + .text("AC Breaker Trip")), // + STATE_17(Doc.of(OpenemsType.BOOLEAN) // + .text("AC Main Contactor Open When Running")), // + STATE_18(Doc.of(OpenemsType.BOOLEAN) // + .text("DC Main Contactor Open When Running")), // + STATE_19(Doc.of(OpenemsType.BOOLEAN) // + .text("AC Main Contactor Open Unsuccessfully")), // + STATE_20(Doc.of(OpenemsType.BOOLEAN) // + .text("DC Electrical Breaker1 Open Unsuccessfully")), // + STATE_21(Doc.of(OpenemsType.BOOLEAN) // + .text("DC Main Contactor Open Unsuccessfully")), // + STATE_22(Doc.of(OpenemsType.BOOLEAN) // + .text("Hardware PDP Fault")), // + STATE_23(Doc.of(OpenemsType.BOOLEAN) // + .text("Master Stop Suddenly")), // + STATE_24(Doc.of(OpenemsType.BOOLEAN) // + .text("DCShortCircuitProtection")), // + STATE_25(Doc.of(OpenemsType.BOOLEAN) // + .text("DCOvervoltageProtection")), // + STATE_26(Doc.of(OpenemsType.BOOLEAN) // + .text("DCUndervoltageProtection")), // + STATE_28(Doc.of(OpenemsType.BOOLEAN) // + .text("DCDisconnectionProtection")), // + STATE_29(Doc.of(OpenemsType.BOOLEAN) // + .text("CommutingVoltageAbnormityProtection")), // + STATE_30(Doc.of(OpenemsType.BOOLEAN) // + .text("DCOvercurrentProtection")), // + STATE_31(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase1PeakCurrentOverLimitProtection")), // + STATE_32(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase2PeakCurrentOverLimitProtection")), // + STATE_33(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase3PeakCurrentOverLimitProtection")), // + STATE_34(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase1GridVoltageSamplingInvalidation")), // + STATE_35(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase2VirtualCurrentOverLimitProtection")), // + STATE_36(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase3VirtualCurrentOverLimitProtection")), // + STATE_37(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase1GridVoltageSamplingInvalidation2")), // + STATE_38(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase2ridVoltageSamplingInvalidation")), // + STATE_39(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase3GridVoltageSamplingInvalidation")), // + STATE_40(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase1InvertVoltageSamplingInvalidation")), // + STATE_41(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase2InvertVoltageSamplingInvalidation")), // + STATE_42(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase3InvertVoltageSamplingInvalidation")), // + STATE_43(Doc.of(OpenemsType.BOOLEAN) // + .text("ACCurrentSamplingInvalidation")), // + STATE_44(Doc.of(OpenemsType.BOOLEAN) // + .text("DCCurrentSamplingInvalidation")), // + STATE_45(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase1OvertemperatureProtection")), // + STATE_46(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase2OvertemperatureProtection")), // + STATE_47(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase3OvertemperatureProtection")), // + STATE_48(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase1TemperatureSamplingInvalidation")), // + STATE_49(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase2TemperatureSamplingInvalidation")), // + STATE_50(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase3TemperatureSamplingInvalidation")), // + STATE_51(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase1PrechargeUnmetProtection")), // + STATE_52(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase2PrechargeUnmetProtection")), // + STATE_53(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase3PrechargeUnmetProtection")), // + STATE_54(Doc.of(OpenemsType.BOOLEAN) // + .text("UnadaptablePhaseSequenceErrorProtection")), // + STATE_55(Doc.of(OpenemsType.BOOLEAN) // + .text("DSPProtection")), // + STATE_85(Doc.of(OpenemsType.BOOLEAN) // + .text("InverterPeakVoltageHighProtectionCauseByACDisconnect")), // + STATE_86(Doc.of(OpenemsType.BOOLEAN) // + .text("DCPrechargeContactorInspectionAbnormity")), // + STATE_87(Doc.of(OpenemsType.BOOLEAN) // + .text("DCBreaker1InspectionAbnormity")), // + STATE_88(Doc.of(OpenemsType.BOOLEAN) // + .text("DCBreaker2InspectionAbnormity")), // + STATE_89(Doc.of(OpenemsType.BOOLEAN) // + .text("ACPrechargeContactorInspectionAbnormity")), // + STATE_90(Doc.of(OpenemsType.BOOLEAN) // + .text("ACMainontactorInspectionAbnormity")), // + STATE_91(Doc.of(OpenemsType.BOOLEAN) // + .text("ACBreakerInspectionAbnormity")), // + STATE_92(Doc.of(OpenemsType.BOOLEAN) // + .text("DCBreaker1CloseUnsuccessfully")), // + STATE_93(Doc.of(OpenemsType.BOOLEAN) // + .text("DCBreaker2CloseUnsuccessfully")), // + STATE_94(Doc.of(OpenemsType.BOOLEAN) // + .text("ControlSignalCloseAbnormallyInspectedBySystem")), // + STATE_95(Doc.of(OpenemsType.BOOLEAN) // + .text("ControlSignalOpenAbnormallyInspectedBySystem")), // + STATE_96(Doc.of(OpenemsType.BOOLEAN) // + .text("NeutralWireContactorCloseUnsuccessfully")), // + STATE_97(Doc.of(OpenemsType.BOOLEAN) // + .text("NeutralWireContactorOpenUnsuccessfully")), // + STATE_98(Doc.of(OpenemsType.BOOLEAN) // + .text("WorkDoorOpen")), // + STATE_99(Doc.of(OpenemsType.BOOLEAN) // + .text("Emergency1Stop")), // + STATE_100(Doc.of(OpenemsType.BOOLEAN) // + .text("ACBreakerCloseUnsuccessfully")), // + STATE_101(Doc.of(OpenemsType.BOOLEAN) // + .text("ControlSwitchStop")), // + STATE_102(Doc.of(OpenemsType.BOOLEAN) // + .text("GeneralOverload")), // + STATE_103(Doc.of(OpenemsType.BOOLEAN) // + .text("SevereOverload")), // + STATE_104(Doc.of(OpenemsType.BOOLEAN) // + .text("BatteryCurrentOverLimit")), // + STATE_106(Doc.of(OpenemsType.BOOLEAN) // + .text("InverterGeneralOvertemperature")), // + STATE_107(Doc.of(OpenemsType.BOOLEAN) // + .text("ACThreePhaseCurrentUnbalance")), // + STATE_108(Doc.of(OpenemsType.BOOLEAN) // + .text("RestoreFactorySettingUnsuccessfully")), // + STATE_109(Doc.of(OpenemsType.BOOLEAN) // + .text("PoleBoardInvalidation")), // + STATE_110(Doc.of(OpenemsType.BOOLEAN) // + .text("SelfInspectionFailed")), // + STATE_111(Doc.of(OpenemsType.BOOLEAN) // + .text("ReceiveBMSFaultAndStop")), // + STATE_112(Doc.of(OpenemsType.BOOLEAN) // + .text("RefrigerationEquipmentinvalidation")), // + STATE_113(Doc.of(OpenemsType.BOOLEAN) // + .text("LargeTemperatureDifferenceAmongIGBTThreePhases")), // + STATE_114(Doc.of(OpenemsType.BOOLEAN) // + .text("EEPROMParametersOverRange")), // + STATE_115(Doc.of(OpenemsType.BOOLEAN) // + .text("EEPROMParametersBackupFailed")), // + STATE_116(Doc.of(OpenemsType.BOOLEAN) // + .text("DCBreakerCloseunsuccessfully")), // + STATE_117(Doc.of(OpenemsType.BOOLEAN) // + .text("CommunicationBetweenInverterAndBSMUDisconnected")), // + STATE_118(Doc.of(OpenemsType.BOOLEAN) // + .text("CommunicationBetweenInverterAndMasterDisconnected")), // + STATE_119(Doc.of(OpenemsType.BOOLEAN) // + .text("CommunicationBetweenInverterAndUCDisconnected")), // + STATE_120(Doc.of(OpenemsType.BOOLEAN) // + .text("BMSStartOvertimeControlledByPCS")), // + STATE_121(Doc.of(OpenemsType.BOOLEAN) // + .text("BMSStopOvertimeControlledByPCS")), // + STATE_122(Doc.of(OpenemsType.BOOLEAN) // + .text("SyncSignalInvalidation")), // + STATE_123(Doc.of(OpenemsType.BOOLEAN) // + .text("SyncSignalContinuousCaputureFault")), // + STATE_124(Doc.of(OpenemsType.BOOLEAN) // + .text("SyncSignalSeveralTimesCaputureFault")), // + STATE_125(Doc.of(OpenemsType.BOOLEAN) // + .text("CurrentSamplingChannelAbnormityOnHighVoltageSide")), // + STATE_126(Doc.of(OpenemsType.BOOLEAN) // + .text("CurrentSamplingChannelAbnormityOnLowVoltageSide")), // + STATE_127(Doc.of(OpenemsType.BOOLEAN) // + .text("EEPROMParametersOverRange")), // + STATE_128(Doc.of(OpenemsType.BOOLEAN) // + .text("UpdateEEPROMFailed")), // + STATE_129(Doc.of(OpenemsType.BOOLEAN) // + .text("ReadEEPROMFailed")), // + STATE_130(Doc.of(OpenemsType.BOOLEAN) // + .text("CurrentSamplingChannelAbnormityBeforeInductance")), // + STATE_147(Doc.of(OpenemsType.BOOLEAN) // + .text("HighVoltageSideOvervoltage")), // + STATE_148(Doc.of(OpenemsType.BOOLEAN) // + .text("HighVoltageSideUndervoltage")), // + STATE_149(Doc.of(OpenemsType.BOOLEAN) // + .text("HighVoltageSideVoltageChangeUnconventionally")) // + ; + + private final Doc doc; + + private SystemErrorChannelId(Doc doc) { + this.doc = doc; + } + + @Override + public Doc doc() { + return this.doc; + + } + } + + /** + * Source-Channels for {@link ChannelId#INSUFFICIENT_GRID_PARAMTERS}. + */ + public static enum InsufficientGridParametersChannelId implements io.openems.edge.common.channel.ChannelId { + STATE_56(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase1GridVoltageSevereOvervoltageProtection")), // + STATE_57(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase1GridVoltageGeneralOvervoltageProtection")), // + STATE_58(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase2GridVoltageSevereOvervoltageProtection")), // + STATE_59(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase2GridVoltageGeneralOvervoltageProtection")), // + STATE_60(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase3GridVoltageSevereOvervoltageProtection")), // + STATE_61(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase3GridVoltageGeneralOvervoltageProtection")), // + STATE_62(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase1GridVoltageSevereUndervoltageProtection")), // + STATE_63(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase1GridVoltageGeneralUndervoltageProtection")), // + STATE_64(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase2GridVoltageSevereUndervoltageProtection")), // + STATE_65(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase2GridVoltageGeneralUndervoltageProtection")), // + STATE_66(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase3GridVoltageSevereUndervoltageProtection")), // + STATE_67(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase3GridVoltageGeneralUndervoltageProtection")), // + STATE_68(Doc.of(OpenemsType.BOOLEAN) // + .text("SevereOverfrequncyProtection")), // + STATE_69(Doc.of(OpenemsType.BOOLEAN) // + .text("GeneralOverfrequncyProtection")), // + STATE_70(Doc.of(OpenemsType.BOOLEAN) // + .text("SevereUnderfrequncyProtection")), // + STATE_71(Doc.of(OpenemsType.BOOLEAN) // + .text("GeneralsUnderfrequncyProtection")), // + STATE_72(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase1Gridloss")), // + STATE_73(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase2Gridloss")), // + STATE_74(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase3Gridloss")), // + STATE_75(Doc.of(OpenemsType.BOOLEAN) // + .text("IslandingProtection")), // + STATE_76(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase1UnderVoltageRideThrough")), // + STATE_77(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase2UnderVoltageRideThrough")), // + STATE_78(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase3UnderVoltageRideThrough")), // + STATE_79(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase1InverterVoltageSevereOvervoltageProtection")), // + STATE_80(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase1InverterVoltageGeneralOvervoltageProtection")), // + STATE_81(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase2InverterVoltageSevereOvervoltageProtection")), // + STATE_82(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase2InverterVoltageGeneralOvervoltageProtection")), // + STATE_83(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase3InverterVoltageSevereOvervoltageProtection")), // + STATE_84(Doc.of(OpenemsType.BOOLEAN) // + .text("Phase3InverterVoltageGeneralOvervoltageProtection")), // + ; + + private final Doc doc; + + private InsufficientGridParametersChannelId(Doc doc) { + this.doc = doc; + } + + @Override + public Doc doc() { + return this.doc; + + } + } + + /** + * Source-Channels for + * {@link ChannelId#POWER_DECREASE_CAUSED_BY_OVERTEMPERATURE}. + */ + public static enum PowerDecreaseCausedByOvertemperatureChannelId + implements io.openems.edge.common.channel.ChannelId { + STATE_105(Doc.of(OpenemsType.BOOLEAN) // + .text("PowerDecreaseCausedByOvertemperature")), // + STATE_131(Doc.of(OpenemsType.BOOLEAN) // + .text("ReactorPowerDecreaseCausedByOvertemperature")), // + STATE_132(Doc.of(OpenemsType.BOOLEAN) // + .text("IGBTPowerDecreaseCausedByOvertemperature")), // + STATE_133(Doc.of(OpenemsType.BOOLEAN) // + .text("TemperatureChanel3PowerDecreaseCausedByOvertemperature")), // + STATE_134(Doc.of(OpenemsType.BOOLEAN) // + .text("TemperatureChanel4PowerDecreaseCausedByOvertemperature")), // + STATE_135(Doc.of(OpenemsType.BOOLEAN) // + .text("TemperatureChanel5PowerDecreaseCausedByOvertemperature")), // + STATE_136(Doc.of(OpenemsType.BOOLEAN) // + .text("TemperatureChanel6PowerDecreaseCausedByOvertemperature")), // + STATE_137(Doc.of(OpenemsType.BOOLEAN) // + .text("TemperatureChanel7PowerDecreaseCausedByOvertemperature")), // + STATE_138(Doc.of(OpenemsType.BOOLEAN) // + .text("TemperatureChanel8PowerDecreaseCausedByOvertemperature")), // + STATE_139(Doc.of(OpenemsType.BOOLEAN) // + .text("Fan1StopFailed")), // + STATE_140(Doc.of(OpenemsType.BOOLEAN) // + .text("Fan2StopFailed")), // + STATE_141(Doc.of(OpenemsType.BOOLEAN) // + .text("Fan3StopFailed")), // + STATE_142(Doc.of(OpenemsType.BOOLEAN) // + .text("Fan4StopFailed")), // + STATE_143(Doc.of(OpenemsType.BOOLEAN) // + .text("Fan1StartupFailed")), // + STATE_144(Doc.of(OpenemsType.BOOLEAN) // + .text("Fan2StartupFailed")), // + STATE_145(Doc.of(OpenemsType.BOOLEAN) // + .text("Fan3StartupFailed")), // + STATE_146(Doc.of(OpenemsType.BOOLEAN) // + .text("Fan4StartupFailed")); + + private final Doc doc; + + private PowerDecreaseCausedByOvertemperatureChannelId(Doc doc) { + this.doc = doc; + } + + @Override + public Doc doc() { + return this.doc; + + } + } + +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java new file mode 100644 index 00000000000..34c7a6376d4 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java @@ -0,0 +1,491 @@ +package io.openems.edge.deye.common; + +import io.openems.common.channel.AccessMode; +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.common.exceptions.OpenemsException; +import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; +import io.openems.edge.bridge.modbus.api.BridgeModbus; +import io.openems.edge.bridge.modbus.api.ModbusComponent; +import io.openems.edge.bridge.modbus.api.ModbusProtocol; +import io.openems.edge.bridge.modbus.api.element.BitsWordElement; +import io.openems.edge.bridge.modbus.api.element.DummyRegisterElement; +import io.openems.edge.bridge.modbus.api.element.SignedWordElement; +import io.openems.edge.bridge.modbus.api.element.StringWordElement; +import io.openems.edge.bridge.modbus.api.element.UnsignedWordElement; +import io.openems.edge.bridge.modbus.api.task.FC16WriteRegistersTask; +import io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask; +import io.openems.edge.bridge.modbus.api.task.FC6WriteRegisterTask; +import io.openems.edge.common.channel.EnumWriteChannel; +import io.openems.edge.common.channel.IntegerWriteChannel; +import io.openems.edge.common.channel.StateChannel; +import io.openems.edge.common.component.ComponentManager; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.common.event.EdgeEventConstants; +import io.openems.edge.common.modbusslave.ModbusSlave; +import io.openems.edge.common.modbusslave.ModbusSlaveTable; +import io.openems.edge.common.taskmanager.Priority; +import io.openems.edge.common.type.TypeUtils; +import io.openems.edge.deye.common.charger.DeyeSunPv; +import io.openems.edge.ess.api.HybridEss; +import io.openems.edge.ess.api.ManagedSymmetricEss; +import io.openems.edge.ess.api.SymmetricEss; +import io.openems.edge.ess.power.api.Constraint; +import io.openems.edge.ess.power.api.Phase; +import io.openems.edge.ess.power.api.Power; +import io.openems.edge.ess.power.api.Pwr; +import io.openems.edge.ess.power.api.Relationship; +import io.openems.edge.timedata.api.Timedata; +import io.openems.edge.timedata.api.TimedataProvider; +import io.openems.edge.timedata.api.utils.CalculateEnergyFromPower; +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.ConfigurationPolicy; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; +import org.osgi.service.component.annotations.ReferencePolicyOption; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventHandler; +import org.osgi.service.event.propertytypes.EventTopics; +import org.osgi.service.metatype.annotations.Designate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import static io.openems.edge.bridge.modbus.api.ElementToChannelConverter.SCALE_FACTOR_1; +import static io.openems.edge.bridge.modbus.api.ElementToChannelConverter.SCALE_FACTOR_MINUS_1; +import static io.openems.edge.bridge.modbus.api.ElementToChannelConverter.SCALE_FACTOR_MINUS_2; + +@Designate(ocd = Config.class, factory = true) +@Component(// + name = "Deye.Sun.Hybrid - MaMoTec", // + immediate = true, // + configurationPolicy = ConfigurationPolicy.REQUIRE // +) +@EventTopics({ // + EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE, // + EdgeEventConstants.TOPIC_CYCLE_BEFORE_CONTROLLERS // +}) +public class DeyeSunHybridImpl extends AbstractOpenemsModbusComponent + implements DeyeSunHybrid, ManagedSymmetricEss, SymmetricEss, HybridEss, ModbusComponent, OpenemsComponent, EventHandler, ModbusSlave, TimedataProvider { + + protected static final int MAX_APPARENT_POWER = 40000; + + protected static final int NET_CAPACITY = 40000; + + private static final int MIN_REACTIVE_POWER = -10000; + + private static final int MAX_REACTIVE_POWER = 10000; + + private final Logger log = LoggerFactory.getLogger(DeyeSunHybridImpl.class); + + private final CalculateEnergyFromPower calculateAcChargeEnergy = new CalculateEnergyFromPower(this, SymmetricEss.ChannelId.ACTIVE_CHARGE_ENERGY); + + private final CalculateEnergyFromPower calculateAcDischargeEnergy = new CalculateEnergyFromPower(this, SymmetricEss.ChannelId.ACTIVE_DISCHARGE_ENERGY); + + private final CalculateEnergyFromPower calculateDcChargeEnergy = new CalculateEnergyFromPower(this, HybridEss.ChannelId.DC_CHARGE_ENERGY); + + private final CalculateEnergyFromPower calculateDcDischargeEnergy = new CalculateEnergyFromPower(this, HybridEss.ChannelId.DC_DISCHARGE_ENERGY); + + private final List chargers = new ArrayList<>(); + + private final SurplusFeedInHandler surplusFeedInHandler = new SurplusFeedInHandler(this); + + @Reference + private ComponentManager componentManager; + + @Reference + private Power power; + + @Reference + private ConfigurationAdmin cm; + + @Override + @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) + protected void setModbus(BridgeModbus modbus) { + super.setModbus(modbus); + } + + @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL) + private volatile Timedata timedata = null; + + private Config config; + + public DeyeSunHybridImpl() { + super(// + OpenemsComponent.ChannelId.values(), // + ModbusComponent.ChannelId.values(), // + SymmetricEss.ChannelId.values(), // + ManagedSymmetricEss.ChannelId.values(), // + HybridEss.ChannelId.values(), // + DeyeSunHybrid.SystemErrorChannelId.values(), // + DeyeSunHybrid.InsufficientGridParametersChannelId.values(), // + DeyeSunHybrid.PowerDecreaseCausedByOvertemperatureChannelId.values(), // + DeyeSunHybrid.ChannelId.values() // + ); + this._setCapacity(NET_CAPACITY); + } + + @Activate + private void activate(ComponentContext context, Config config) throws OpenemsException { + if (super.activate(context, config.id(), config.alias(), config.enabled(), config.unit_id(), this.cm, "Modbus", config.modbus_id())) { + return; + } + this.config = config; + } + + @Override + @Deactivate + protected void deactivate() { + super.deactivate(); + } + + @Override + public void applyPower(int activePower, int reactivePower) throws OpenemsNamedException { + if (this.config.readOnlyMode()) { + return; + } + + IntegerWriteChannel setActivePowerChannel = this.channel(DeyeSunHybrid.ChannelId.SET_ACTIVE_POWER); + setActivePowerChannel.setNextWriteValue(activePower); + IntegerWriteChannel setReactivePowerChannel = this.channel(DeyeSunHybrid.ChannelId.SET_REACTIVE_POWER); + setReactivePowerChannel.setNextWriteValue(reactivePower); + + // AC 1/28/2024 + IntegerWriteChannel setGridLoadOffPowerChannel = this.channel(DeyeSunHybrid.ChannelId.SET_GRID_LOAD_OFF_POWER); + setGridLoadOffPowerChannel.setNextWriteValue(93); + } + + @Override + public String getModbusBridgeId() { + return this.config.modbus_id(); + } + + @Override + public void addCharger(DeyeSunPv charger) { + + } + + @Override + public void removeCharger(DeyeSunPv charger) { + + } + + @Override + protected ModbusProtocol defineModbusProtocol() throws OpenemsException { + return new ModbusProtocol(this, // + + new FC3ReadRegistersTask(1, Priority.LOW, + m(SymmetricEss.ChannelId.GRID_MODE, new UnsignedWordElement(1)), + new DummyRegisterElement(2), + m(DeyeSunHybrid.ChannelId.SERIAL_NUMBER, new StringWordElement(3, 5))), + + new FC16WriteRegistersTask(77, + m(DeyeSunHybrid.ChannelId.SET_ACTIVE_POWER, new SignedWordElement(77)), + m(DeyeSunHybrid.ChannelId.SET_REACTIVE_POWER, new SignedWordElement(78))), + + new FC16WriteRegistersTask(99,new DummyRegisterElement(99, 101), + m(DeyeSunHybrid.ChannelId.BATTERY_CAPACITY, new SignedWordElement(102)), + new DummyRegisterElement(103), + m(DeyeSunHybrid.ChannelId.ZERO_EXPORT_POWER, new SignedWordElement(104))), + + new FC16WriteRegistersTask(108, + m(DeyeSunHybrid.ChannelId.MAX_A_BATTERY_CHARGE_CURRENT, new SignedWordElement(108)), + m(DeyeSunHybrid.ChannelId.MAX_A_BATTERY_DISCHARGE_CURRENT, new SignedWordElement(109)), + m(DeyeSunHybrid.ChannelId.PARALLEL_BAT_1_AND_BAT_2, new SignedWordElement(110))), + + new FC16WriteRegistersTask(115, + m(DeyeSunHybrid.ChannelId.BATTERY_CAPACITY_SHUTDOWN, new SignedWordElement(115)), + m(DeyeSunHybrid.ChannelId.BATTERY_CAPACITY_RESTART, new SignedWordElement(116)), + m(DeyeSunHybrid.ChannelId.BATTERY_CAPACITY_LOW_BATTERY, new SignedWordElement(117))), + + new FC16WriteRegistersTask(121, + m(DeyeSunHybrid.ChannelId.GEN_MAX_RUN_TIME, new SignedWordElement(121), SCALE_FACTOR_MINUS_1), + m(DeyeSunHybrid.ChannelId.GEN_COOLING_TIME, new SignedWordElement(122), SCALE_FACTOR_MINUS_1), + new DummyRegisterElement(123), + m(DeyeSunHybrid.ChannelId.GEN_CHARGING_STARTING_CAPACITY_POINT, new SignedWordElement(124)), + m(DeyeSunHybrid.ChannelId.GEN_CHARGING_CURRENT_TO_BATTERY, new SignedWordElement(125)), + new DummyRegisterElement(126), + m(DeyeSunHybrid.ChannelId.GRID_CHARGING_STARTING_CAPACITY_POINT, new SignedWordElement(127)), + m(DeyeSunHybrid.ChannelId.GRID_CHARGING_CURRENT_TO_BATTERY, new SignedWordElement(128)), + m(DeyeSunHybrid.ChannelId.GEN_CHARGE_ENABLED, new SignedWordElement(129)), + m(DeyeSunHybrid.ChannelId.GRID_CHARGE_ENABLED, new SignedWordElement(130)), + m(DeyeSunHybrid.ChannelId.AC_COUPLE_FREQUENCY_CAP, new SignedWordElement(131), SCALE_FACTOR_MINUS_2), + new DummyRegisterElement(132, 134), + m(DeyeSunHybrid.ChannelId.GEN_LOAD_OFF_POWER, new SignedWordElement(135)), + new DummyRegisterElement(136), + m(DeyeSunHybrid.ChannelId.GEN_LOAD_ON_POWER, new SignedWordElement(137)), + new DummyRegisterElement(138, 139), + m(DeyeSunHybrid.ChannelId.GEN_GRID_SIGNAL, new SignedWordElement(140))), + + new FC16WriteRegistersTask(145, + m(DeyeSunHybrid.ChannelId.SOLAR_SELL, new SignedWordElement(145))), + + new FC6WriteRegisterTask(146, + m(new BitsWordElement(146, this) // + .bit(0, DeyeSunHybrid.ChannelId.TIME_OF_USE_ENABLED_FLAG) // + .bit(1, DeyeSunHybrid.ChannelId.TIME_OF_USE_MONDAY) // + .bit(2, DeyeSunHybrid.ChannelId.TIME_OF_USE_TUESDAY) // + .bit(3, DeyeSunHybrid.ChannelId.TIME_OF_USE_WEDNESDAY) // + .bit(4, DeyeSunHybrid.ChannelId.TIME_OF_USE_THURSDAY) // + .bit(5, DeyeSunHybrid.ChannelId.TIME_OF_USE_FRIDAY) + .bit(6, DeyeSunHybrid.ChannelId.TIME_OF_USE_SATURDAY) + .bit(7, DeyeSunHybrid.ChannelId.TIME_OF_USE_SUNDAY) + )), + + new FC16WriteRegistersTask(148, + m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_1, new UnsignedWordElement(148)), + m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_2, new UnsignedWordElement(149)), + m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_3, new UnsignedWordElement(150)), + m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_4, new UnsignedWordElement(151)), + m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_5, new UnsignedWordElement(152)), + m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_6, new UnsignedWordElement(153)), + m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_1_POWER, new UnsignedWordElement(154), SCALE_FACTOR_1), + m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_2_POWER, new UnsignedWordElement(155), SCALE_FACTOR_1), + m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_3_POWER, new UnsignedWordElement(156), SCALE_FACTOR_1), + m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_4_POWER, new UnsignedWordElement(157), SCALE_FACTOR_1), + m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_5_POWER, new UnsignedWordElement(158), SCALE_FACTOR_1), + m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_6_POWER, new UnsignedWordElement(159), SCALE_FACTOR_1), + new DummyRegisterElement(160, 165), + m(DeyeSunHybrid.ChannelId.SELL_MODE_CAPACITY_1, new UnsignedWordElement(166)), + m(DeyeSunHybrid.ChannelId.SELL_MODE_CAPACITY_2, new UnsignedWordElement(167)), + m(DeyeSunHybrid.ChannelId.SELL_MODE_CAPACITY_3, new UnsignedWordElement(168)), + m(DeyeSunHybrid.ChannelId.SELL_MODE_CAPACITY_4, new UnsignedWordElement(169)), + m(DeyeSunHybrid.ChannelId.SELL_MODE_CAPACITY_5, new UnsignedWordElement(170)), + m(DeyeSunHybrid.ChannelId.SELL_MODE_CAPACITY_6, new UnsignedWordElement(171)), + m(DeyeSunHybrid.ChannelId.TIME_POINT_1_GRID_GEN_CHARGE_ENABLE, new UnsignedWordElement(172)), + m(DeyeSunHybrid.ChannelId.TIME_POINT_2_GRID_GEN_CHARGE_ENABLE, new UnsignedWordElement(173)), + m(DeyeSunHybrid.ChannelId.TIME_POINT_3_GRID_GEN_CHARGE_ENABLE, new UnsignedWordElement(174)), + m(DeyeSunHybrid.ChannelId.TIME_POINT_4_GRID_GEN_CHARGE_ENABLE, new UnsignedWordElement(175)), + m(DeyeSunHybrid.ChannelId.TIME_POINT_5_GRID_GEN_CHARGE_ENABLE, new UnsignedWordElement(176)), + m(DeyeSunHybrid.ChannelId.TIME_POINT_6_GRID_GEN_CHARGE_ENABLE, new UnsignedWordElement(177)), + m(DeyeSunHybrid.ChannelId.MICROINVERTER_EXPORT_TO_GRID_CUTOFF, new UnsignedWordElement(178)), + new DummyRegisterElement(179, 180), + m(DeyeSunHybrid.ChannelId.SOLAR_ARC_FAULT_ON, new SignedWordElement(181)) + ), + + new FC16WriteRegistersTask(189, + m(DeyeSunHybrid.ChannelId.GEN_CONNECTED_TO_GRID_INPUT, new UnsignedWordElement(189)) + // m(DeyeSunHybrid.ChannelId.GEN_PEAK_SHAVING_POWER, new UnsignedWordElement(190)), + // m(DeyeSunHybrid.ChannelId.GRID_PEAK_SHAVING_POWER, new UnsignedWordElement(191)) + ), + + new FC16WriteRegistersTask(190, + m(DeyeSunHybrid.ChannelId.SET_GEN_PEAK_SHAVING_POWER, new SignedWordElement(190)), + m(DeyeSunHybrid.ChannelId.SET_GRID_PEAK_SHAVING_POWER, new SignedWordElement(191))), + + new FC16WriteRegistersTask(209, + m(DeyeSunHybrid.ChannelId.UPS_BACKUP_DELAY_TIME, new UnsignedWordElement(209))), + + // new FC3ReadRegistersTask(214, Priority.LOW, + // m(SymmetricEss.ChannelId.SOC, new UnsignedWordElement(214))), + + new FC16WriteRegistersTask(214, + m(SymmetricEss.ChannelId.SOC, new SignedWordElement(214))), + + new FC16WriteRegistersTask(340, + m(DeyeSunHybrid.ChannelId.MAX_SOLAR_SELL_POWER, new UnsignedWordElement(340), SCALE_FACTOR_1)), + + new FC16WriteRegistersTask(347, + m(DeyeSunHybrid.ChannelId.CT_RATIO, new UnsignedWordElement(347))), + + new FC3ReadRegistersTask(500, Priority.LOW, + m(DeyeSunHybrid.ChannelId.INVERTER_RUN_STATE, new UnsignedWordElement(500))), + + new FC3ReadRegistersTask(588, Priority.LOW, + m(DeyeSunHybrid.ChannelId.BAT_1_SOC, new UnsignedWordElement(588))), + + new FC3ReadRegistersTask(607, Priority.LOW, + m(SymmetricEss.ChannelId.ACTIVE_POWER, new SignedWordElement(607)), + m(SymmetricEss.ChannelId.REACTIVE_POWER, new SignedWordElement(608))), + + new FC3ReadRegistersTask(620, Priority.LOW, // + m(DeyeSunHybrid.ChannelId.APPARENT_POWER, new UnsignedWordElement(620))) + + ); + } + + @Override + public String debugLog() { + return "SoC:" + this.getSoc().asString() // + + "|L:" + this.getActivePower().asString() // + + "|Active Power:" + + this.channel(SymmetricEss.ChannelId.ACTIVE_POWER).value().asStringWithoutUnit() + ";" + + "|Allowed:" + + this.channel(ManagedSymmetricEss.ChannelId.ALLOWED_CHARGE_POWER).value().asStringWithoutUnit() + ";" + + this.channel(ManagedSymmetricEss.ChannelId.ALLOWED_DISCHARGE_POWER).value().asString(); + } + + @Override + public void handleEvent(Event event) { + if (!this.isEnabled()) { + return; + } + switch (event.getTopic()) { + case EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE: + this.applyPowerLimitOnPowerDecreaseCausedByOvertemperatureError(); + this.calculateEnergy(); + break; + case EdgeEventConstants.TOPIC_CYCLE_BEFORE_CONTROLLERS: + this.defineWorkState(); + break; + } + } + + private LocalDateTime lastDefineWorkState = null; + + private void defineWorkState() { + /* + * Set ESS in running mode + */ + // TODO this should be smarter: set in energy saving mode if there was no output + // power for a while and we don't need emergency power. + var now = LocalDateTime.now(); + if (this.lastDefineWorkState == null || now.minusMinutes(1).isAfter(this.lastDefineWorkState)) { + this.lastDefineWorkState = now; + EnumWriteChannel setWorkStateChannel = this.channel(DeyeSunHybrid.ChannelId.SET_WORK_STATE); + try { + setWorkStateChannel.setNextWriteValue(SetWorkState.START); + } catch (OpenemsNamedException e) { + this.logError(this.log, "Unable to start: " + e.getMessage()); + } + } + } + + @Override + public Power getPower() { + return this.power; + } + + @Override + public boolean isManaged() { + return !this.config.readOnlyMode(); + } + + @Override + public int getPowerPrecision() { + return 100; // the modbus field for SetActivePower has the unit 0.1 kW + } + + @Override + public Constraint[] getStaticConstraints() throws OpenemsNamedException { + // Read-Only-Mode + if (this.config.readOnlyMode()) { + return new Constraint[] { // + this.createPowerConstraint("Read-Only-Mode", Phase.ALL, Pwr.ACTIVE, Relationship.EQUALS, 0), // + this.createPowerConstraint("Read-Only-Mode", Phase.ALL, Pwr.REACTIVE, Relationship.EQUALS, 0) // + }; + } + + // Reactive Power constraints + return new Constraint[] { // + this.createPowerConstraint("Commercial40 Min Reactive Power", Phase.ALL, Pwr.REACTIVE, Relationship.GREATER_OR_EQUALS, MIN_REACTIVE_POWER), // + this.createPowerConstraint("Commercial40 Max Reactive Power", Phase.ALL, Pwr.REACTIVE, Relationship.LESS_OR_EQUALS, MAX_REACTIVE_POWER) }; + } + + @Override + public ModbusSlaveTable getModbusSlaveTable(AccessMode accessMode) { + return new ModbusSlaveTable(// + OpenemsComponent.getModbusSlaveNatureTable(accessMode), // + SymmetricEss.getModbusSlaveNatureTable(accessMode), // + ManagedSymmetricEss.getModbusSlaveNatureTable(accessMode) // + ); + } + + @Override + protected void logInfo(Logger log, String message) { + super.logInfo(log, message); + } + + private void applyPowerLimitOnPowerDecreaseCausedByOvertemperatureError() { + if (this.config.powerLimitOnPowerDecreaseCausedByOvertemperatureChannel() != 0) { + StateChannel powerDecreaseCausedByOvertemperatureChannel = this.channel(DeyeSunHybrid.ChannelId.POWER_DECREASE_CAUSED_BY_OVERTEMPERATURE); + if (powerDecreaseCausedByOvertemperatureChannel.value().orElse(false)) { + /* + * Apply limit on ESS charge/discharge power + */ + try { + this.power.addConstraintAndValidate( + this.createPowerConstraint("Limit On PowerDecreaseCausedByOvertemperature Error", Phase.ALL, Pwr.ACTIVE, Relationship.GREATER_OR_EQUALS, + this.config.powerLimitOnPowerDecreaseCausedByOvertemperatureChannel() * -1)); + this.power.addConstraintAndValidate( + this.createPowerConstraint("Limit On PowerDecreaseCausedByOvertemperature Error", Phase.ALL, Pwr.ACTIVE, Relationship.LESS_OR_EQUALS, + this.config.powerLimitOnPowerDecreaseCausedByOvertemperatureChannel())); + } catch (OpenemsException e) { + this.logError(this.log, e.getMessage()); + } + /* + * Apply limit on Charger + */ + if (this.chargers.size() > 0) { + IntegerWriteChannel setPvPowerLimit = this.chargers.get(0).channel(DeyeSunPv.ChannelId.SET_PV_POWER_LIMIT); + try { + setPvPowerLimit.setNextWriteValue(this.config.powerLimitOnPowerDecreaseCausedByOvertemperatureChannel()); + } catch (OpenemsNamedException e) { + this.logError(this.log, e.getMessage()); + } + } + + } + } + } + + @Override + public Integer getSurplusPower() { + return this.surplusFeedInHandler.run(this.chargers, this.config, this.componentManager); + } + + @Override + public Timedata getTimedata() { + return this.timedata; + } + + private void calculateEnergy() { + /* + * Calculate AC Energy + */ + var acActivePower = this.getActivePowerChannel().getNextValue().get(); + if (acActivePower == null) { + // Not available + this.calculateAcChargeEnergy.update(null); + this.calculateAcDischargeEnergy.update(null); + } else if (acActivePower > 0) { + // Discharge + this.calculateAcChargeEnergy.update(0); + this.calculateAcDischargeEnergy.update(acActivePower); + } else { + // Charge + this.calculateAcChargeEnergy.update(acActivePower * -1); + this.calculateAcDischargeEnergy.update(0); + } + /* + * Calculate DC Power and Energy + */ + var dcDischargePower = acActivePower; + for (DeyeSunPv charger : this.chargers) { + dcDischargePower = TypeUtils.subtract(dcDischargePower, charger.getActualPowerChannel().getNextValue().get()); + } + this._setDcDischargePower(dcDischargePower); + + if (dcDischargePower == null) { + // Not available + this.calculateDcChargeEnergy.update(null); + this.calculateDcDischargeEnergy.update(null); + } else if (dcDischargePower > 0) { + // Discharge + this.calculateDcChargeEnergy.update(0); + this.calculateDcDischargeEnergy.update(dcDischargePower); + } else { + // Charge + this.calculateDcChargeEnergy.update(dcDischargePower * -1); + this.calculateDcDischargeEnergy.update(0); + } + } + +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/InverterState.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/InverterState.java new file mode 100644 index 00000000000..45ccd4102ce --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/InverterState.java @@ -0,0 +1,38 @@ +package io.openems.edge.deye.common; + +import io.openems.common.types.OptionsEnum; + +public enum InverterState implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + INIT(0, "Init"), // + FAULT(2, "Fault"), // + STOP(4, "Stop"), // + STANDBY(8, "Standby"), // + GRID_MONITOR(16, "Grid-Monitor"), // + READY(32, "Ready"), // + START(64, "Start"), // + DEBUG(128, "Debug"); // + + private final int value; + private final String name; + + private InverterState(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SetWorkState.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SetWorkState.java new file mode 100644 index 00000000000..3e002767674 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SetWorkState.java @@ -0,0 +1,33 @@ +package io.openems.edge.deye.common; + +import io.openems.common.types.OptionsEnum; + +public enum SetWorkState implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + STOP(4, "Stop"), // + STANDBY(32, "Standby"), // + START(64, "Start"); // + + private final int value; + private final String name; + + private SetWorkState(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInHandler.java new file mode 100644 index 00000000000..f7515cb6031 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInHandler.java @@ -0,0 +1,215 @@ +package io.openems.edge.deye.common; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.common.utils.DoubleUtils; +import io.openems.edge.common.channel.IntegerReadChannel; +import io.openems.edge.common.channel.IntegerWriteChannel; +import io.openems.edge.common.channel.StateChannel; +import io.openems.edge.common.component.ComponentManager; +import io.openems.edge.deye.common.charger.DeyeSunImpl; +import io.openems.edge.deye.common.charger.DeyeSunPv; +import io.openems.edge.ess.dccharger.api.EssDcCharger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.List; + +public class SurplusFeedInHandler { + + private static final int GOING_DEACTIVATED_MINUTES = 15; + private static final float PV_LIMIT_FACTOR = 0.9f; + private static final int MIN_PV_LIMIT = 5_000; + private static final int NO_PV_LIMIT = 60_000; + // If AllowedDischarge is < 1000, surplus is not activated + private static final int SURPLUS_ALLOWED_DISCHARGE_LIMIT = 35_000; + + private final Logger log = LoggerFactory.getLogger(SurplusFeedInHandler.class); + private final DeyeSunHybridImpl parent; + + private SurplusFeedInStateMachine state = SurplusFeedInStateMachine.DEACTIVATED; + private LocalDateTime startedGoingDeactivated = null; + + public SurplusFeedInHandler(DeyeSunHybridImpl parent) { + this.parent = parent; + } + + protected Integer run(List chargers, Config config, ComponentManager componentManager) { + var offTime = LocalTime.parse(config.surplusFeedInOffTime()); + + var areSurplusConditionsMet = this.areSurplusConditionsMet(this.parent, chargers, config); + + if (chargers.isEmpty()) { + // Is no Charger set (i.e. is this not a Commercial 40-40 "DC") + this.setState(SurplusFeedInStateMachine.DEACTIVATED); + + } else if (LocalTime.now(componentManager.getClock()).isAfter(offTime)) { + // Passed surplusOffTime? + this.setState(SurplusFeedInStateMachine.PASSED_OFF_TIME); + + } else if (areSurplusConditionsMet) { + // Always immediately activate surplus-feed-in if conditions are met + this.setState(SurplusFeedInStateMachine.ACTIVATED); + + } else if (this.state == SurplusFeedInStateMachine.UNDEFINED) { + this.setState(SurplusFeedInStateMachine.DEACTIVATED); + } + + // State-Machine + switch (this.state) { + case UNDEFINED: + case DEACTIVATED: + this.applyPvPowerLimit(chargers, config, false); + return null; + + case ACTIVATED: { + if (areSurplusConditionsMet) { + this.startedGoingDeactivated = null; + } else { + this.setState(SurplusFeedInStateMachine.GOING_DEACTIVATED); + this.startedGoingDeactivated = LocalDateTime.now(); + } + var pvPower = this.getPvPower(chargers); + var power = pvPower + this.getIncreasePower(config, pvPower); + this.applyPvPowerLimit(chargers, config, true); + return power; + } + + case GOING_DEACTIVATED: { + var goingDeactivatedSinceMinutes = Duration.between(this.startedGoingDeactivated, LocalDateTime.now()) + .toMinutes(); + // slowly reduce the surplus-feed-in-power from 100 to 0 % + var pvPower = this.getPvPower(chargers); + var factor = DoubleUtils.normalize(goingDeactivatedSinceMinutes, 0, GOING_DEACTIVATED_MINUTES, 0, 1, true); + var power = Math.max((int) ((pvPower + this.getIncreasePower(config, pvPower)) * factor), + this.getIncreasePower(config, pvPower)); + if (goingDeactivatedSinceMinutes > GOING_DEACTIVATED_MINUTES) { + this.setState(SurplusFeedInStateMachine.PASSED_OFF_TIME); + } + this.applyPvPowerLimit(chargers, config, false); + return power; + } + + case PASSED_OFF_TIME: + if (LocalTime.now().isBefore(offTime)) { + this.setState(SurplusFeedInStateMachine.DEACTIVATED); + } + this.applyPvPowerLimit(chargers, config, false); + return null; + } + + // should never come here + return null; + } + + /** + * Gets the PV-Power. Zero if not available. + * + * @param chargers the DC Chargers + * @return pv power + */ + private int getPvPower(List chargers) { + var pvPower = 0; + for (EssDcCharger charger : chargers) { + pvPower += charger.getActualPower().orElse(0); + } + return pvPower; + } + + private boolean areSurplusConditionsMet(DeyeSunHybridImpl ess, List chargers, + Config config) { + if (chargers.isEmpty()) { + return false; + } + + IntegerReadChannel allowedChargeChannel = ess + .channel(DeyeSunHybrid.ChannelId.ORIGINAL_ALLOWED_CHARGE_POWER); + IntegerReadChannel allowedDischargeChannel = ess + .channel(DeyeSunHybrid.ChannelId.ORIGINAL_ALLOWED_DISCHARGE_POWER); + if ( + // Is battery Allowed Charge bigger than the limit? (and Discharge is allowed) + (allowedChargeChannel.value().orElse(0) < config.surplusFeedInAllowedChargePowerLimit() + || allowedDischargeChannel.value().orElse(Integer.MAX_VALUE) < SURPLUS_ALLOWED_DISCHARGE_LIMIT) + // Is State-of-charge lower than limit? + && ess.getSoc().orElse(100) < config.surplusFeedInSocLimit()) { + return false; + } + + var maxVoltage = 0; + for (DeyeSunPv charger : chargers) { + int thisVoltage = ((IntegerReadChannel) charger + .channel(DeyeSunPv.ChannelId.PV_DCDC_INPUT_VOLTAGE)).value().orElse(0); + if (thisVoltage > maxVoltage) { + maxVoltage = thisVoltage; + } + } + + // Is PV NOT producing? + if (maxVoltage < 100_000) { + return false; + } + + return true; + } + + private void applyPvPowerLimit(List chargers, Config config, boolean limitPv) { + /* + * Limit PV production power + */ + var pvPowerLimit = NO_PV_LIMIT; + if (limitPv) { + // Limit PV-Power to maximum apparent power of inverter + // this avoids filling the battery faster than we can empty it + StateChannel powerDecreaseCausedByOvertemperatureChannel = this.parent + .channel(DeyeSunHybrid.ChannelId.POWER_DECREASE_CAUSED_BY_OVERTEMPERATURE); + if (powerDecreaseCausedByOvertemperatureChannel.value().orElse(false)) { + // Always decrease if POWER_DECREASE_CAUSED_BY_OVERTEMPERATURE StateChannel is + // set + pvPowerLimit = config.surplusFeedInPvLimitOnPowerDecreaseCausedByOvertemperature(); + } else { + // Otherwise reduce to MAX_APPARENT_POWER multiplied with PV_LIMIT_FACTOR; + // minimally MIN_PV_LIMIT + var maxApparentPower = this.parent.getMaxApparentPower(); + if (maxApparentPower.isDefined()) { + pvPowerLimit = Math.max(Math.round(maxApparentPower.get() * PV_LIMIT_FACTOR), MIN_PV_LIMIT); + } + } + } + + for (DeyeSunPv charger : chargers) { + IntegerWriteChannel setPvPowerLimit = charger + .channel(DeyeSunPv.ChannelId.SET_PV_POWER_LIMIT); + try { + setPvPowerLimit.setNextWriteValue(pvPowerLimit); + } catch (OpenemsNamedException e) { + e.printStackTrace(); + } + // stop after one: write-channel is shared between all chargers + break; + } + } + + private void setState(SurplusFeedInStateMachine state) { + if (this.state != state) { + this.parent.logInfo(this.log, "Changing State-Machine from [" + this.state + "] to [" + state + "]"); + this.state = state; + this.parent.channel(DeyeSunHybrid.ChannelId.SURPLUS_FEED_IN_STATE_MACHINE).setNextValue(state); + } + } + + private int getIncreasePower(Config config, int pvPower) { + // if we reached here, state is ACTIVATED or GOING_DEACTIVATED; i.e. surplus + // feed in is activated + if (pvPower <= 0) { + // if PV-Power is zero, we assume the charger turned off because of full battery + // -> discharge with max increase power + return config.surplusFeedInMaxIncreasePowerFactor(); + } + // increase power is PV-Power + 10 % (INCREASE_POWER_FACTOR); limited by + // MAX_INCREASE_POWER + var increasePower = (int) (pvPower * config.surplusFeedInIncreasePowerFactor()); + return Math.min(increasePower, config.surplusFeedInMaxIncreasePowerFactor()); + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInStateMachine.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInStateMachine.java new file mode 100644 index 00000000000..ca711be6d72 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInStateMachine.java @@ -0,0 +1,34 @@ +package io.openems.edge.deye.common; + +import io.openems.common.types.OptionsEnum; + +public enum SurplusFeedInStateMachine implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + DEACTIVATED(0, "Deactivated"), // + ACTIVATED(1, "Activated"), // + GOING_DEACTIVATED(2, "Going Deactivated"), // + PASSED_OFF_TIME(3, "Passed Off-Time"); // + + private final int value; + private final String name; + + private SurplusFeedInStateMachine(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemManufacturer.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemManufacturer.java new file mode 100644 index 00000000000..e3b21567887 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemManufacturer.java @@ -0,0 +1,31 @@ +package io.openems.edge.deye.common; + +import io.openems.common.types.OptionsEnum; + +public enum SystemManufacturer implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + BYD(1, "BYD"); + + private final int value; + private final String name; + + private SystemManufacturer(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemState.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemState.java new file mode 100644 index 00000000000..9ca762181a0 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemState.java @@ -0,0 +1,36 @@ +package io.openems.edge.deye.common; + +import io.openems.common.types.OptionsEnum; + +public enum SystemState implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + STARTING(2, "Stop"), // + PV_CHARGE(4, "PV-Charge"), // + STANDBY(8, "Standby"), // + START(16, "Start"), // + FAULT(32, "Fault"), // + DEBUG(64, "Debug"); + + private final int value; + private final String name; + + private SystemState(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemType.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemType.java new file mode 100644 index 00000000000..b096bcaca9b --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemType.java @@ -0,0 +1,31 @@ +package io.openems.edge.deye.common; + +import io.openems.common.types.OptionsEnum; + +public enum SystemType implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + CESS(1, "CESS"); // + + private final int value; + private final String name; + + private SystemType(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/AbstractEssDeyePv.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/AbstractEssDeyePv.java new file mode 100644 index 00000000000..6ce46d380af --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/AbstractEssDeyePv.java @@ -0,0 +1,245 @@ +package io.openems.edge.deye.common.charger; + +import io.openems.common.channel.AccessMode; +import io.openems.common.exceptions.OpenemsException; +import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; +import io.openems.edge.bridge.modbus.api.ModbusComponent; +import io.openems.edge.bridge.modbus.api.ModbusProtocol; +import io.openems.edge.bridge.modbus.api.element.DummyRegisterElement; +import io.openems.edge.bridge.modbus.api.element.SignedWordElement; +import io.openems.edge.bridge.modbus.api.element.UnsignedDoublewordElement; +import io.openems.edge.bridge.modbus.api.element.UnsignedWordElement; +import io.openems.edge.bridge.modbus.api.element.WordOrder; +import io.openems.edge.bridge.modbus.api.task.FC16WriteRegistersTask; +import io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.common.event.EdgeEventConstants; +import io.openems.edge.common.modbusslave.ModbusSlave; +import io.openems.edge.common.modbusslave.ModbusSlaveNatureTable; +import io.openems.edge.common.modbusslave.ModbusSlaveTable; +import io.openems.edge.common.taskmanager.Priority; +import io.openems.edge.ess.dccharger.api.EssDcCharger; +import io.openems.edge.timedata.api.TimedataProvider; +import io.openems.edge.timedata.api.utils.CalculateEnergyFromPower; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventHandler; + +import static io.openems.edge.bridge.modbus.api.ElementToChannelConverter.SCALE_FACTOR_2; + +public abstract class AbstractEssDeyePv extends AbstractOpenemsModbusComponent + implements DeyeSunPv, EssDcCharger, ModbusComponent, OpenemsComponent, TimedataProvider, + EventHandler, ModbusSlave { + + private final CalculateEnergyFromPower calculateActualEnergy = new CalculateEnergyFromPower(this, + EssDcCharger.ChannelId.ACTUAL_ENERGY); + + /** + * Is this PV1 or PV2 charger?. + * + * @return true for PV1, false for PV2 + */ + protected abstract boolean isPV1(); + + public AbstractEssDeyePv() { + super(// + OpenemsComponent.ChannelId.values(), // + ModbusComponent.ChannelId.values(), // + EssDcCharger.ChannelId.values(), // + DeyeSunPv.ChannelId.values() // + ); + + } + + @Override + protected ModbusProtocol defineModbusProtocol() throws OpenemsException { + var protocol = new ModbusProtocol(this, // + new FC16WriteRegistersTask(0x0503, // + m(DeyeSunPv.ChannelId.SET_PV_POWER_LIMIT, new UnsignedWordElement(0x0503), + SCALE_FACTOR_2))); // + + if (this.isPV1()) { + protocol.addTasks(// + new FC3ReadRegistersTask(0xA130, Priority.LOW, // + m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_VOLTAGE, new SignedWordElement(0xA130), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_CURRENT, new SignedWordElement(0xA131), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_POWER, new SignedWordElement(0xA132), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_VOLTAGE, new SignedWordElement(0xA133), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_CURRENT, new SignedWordElement(0xA134), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_POWER, new SignedWordElement(0xA135), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_ENERGY, new SignedWordElement(0xA136), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_ENERGY, new SignedWordElement(0xA137), + SCALE_FACTOR_2), // + new DummyRegisterElement(0xA138, 0xA13F), // + m(DeyeSunPv.ChannelId.BMS_DCDC_REACTOR_TEMPERATURE, + new SignedWordElement(0xA140)), // + m(DeyeSunPv.ChannelId.BMS_DCDC_IGBT_TEMPERATURE, + new SignedWordElement(0xA141)), // + new DummyRegisterElement(0xA142, 0xA14F), // + m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_CHARGE_ENERGY, + new UnsignedDoublewordElement(0xA150).wordOrder(WordOrder.LSWMSW), // + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_DISCHARGE_ENERGY, + new UnsignedDoublewordElement(0xA152).wordOrder(WordOrder.LSWMSW), // + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_CHARGE_ENERGY, + new UnsignedDoublewordElement(0xA154).wordOrder(WordOrder.LSWMSW), // + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_DISCHARGE_ENERGY, + new UnsignedDoublewordElement(0xA156).wordOrder(WordOrder.LSWMSW), // + SCALE_FACTOR_2)), // + + new FC3ReadRegistersTask(0xA730, Priority.LOW, // + m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_VOLTAGE, new SignedWordElement(0xA730), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_CURRENT, new SignedWordElement(0xA731), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_POWER, new SignedWordElement(0xA732), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_VOLTAGE, new SignedWordElement(0xA733), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_CURRENT, new SignedWordElement(0xA734), + SCALE_FACTOR_2), // + m(EssDcCharger.ChannelId.ACTUAL_POWER, new SignedWordElement(0xA735), SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_ENERGY, new SignedWordElement(0xA736), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_ENERGY, new SignedWordElement(0xA737), + SCALE_FACTOR_2), // + new DummyRegisterElement(0xA738, 0xA73F), // + m(DeyeSunPv.ChannelId.PV_DCDC_REACTOR_TEMPERATURE, + new SignedWordElement(0xA740)), // + m(DeyeSunPv.ChannelId.PV_DCDC_IGBT_TEMPERATURE, + new SignedWordElement(0xA741)), // + new DummyRegisterElement(0xA742, 0xA74F), // + m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_CHARGE_ENERGY, + new UnsignedDoublewordElement(0xA750).wordOrder(WordOrder.LSWMSW), // + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_DISCHARGE_ENERGY, + new UnsignedDoublewordElement(0xA752).wordOrder(WordOrder.LSWMSW), // + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_CHARGE_ENERGY, + new UnsignedDoublewordElement(0xA754).wordOrder(WordOrder.LSWMSW), // + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_DISCHARGE_ENERGY, + new UnsignedDoublewordElement(0xA756).wordOrder(WordOrder.LSWMSW), // + SCALE_FACTOR_2))); + + } else { + protocol.addTasks(// + new FC3ReadRegistersTask(0xAA30, Priority.LOW, // + m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_VOLTAGE, new SignedWordElement(0xAA30), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_CURRENT, new SignedWordElement(0xAA31), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_POWER, new SignedWordElement(0xAA32), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_VOLTAGE, new SignedWordElement(0xAA33), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_CURRENT, new SignedWordElement(0xAA34), + SCALE_FACTOR_2), // + m(EssDcCharger.ChannelId.ACTUAL_POWER, new SignedWordElement(0xAA35), SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_ENERGY, new SignedWordElement(0xAA36), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_ENERGY, new SignedWordElement(0xAA37), + SCALE_FACTOR_2), // + new DummyRegisterElement(0xAA38, 0xAA3F), // + m(DeyeSunPv.ChannelId.PV_DCDC_REACTOR_TEMPERATURE, + new SignedWordElement(0xAA40)), // + m(DeyeSunPv.ChannelId.PV_DCDC_IGBT_TEMPERATURE, + new SignedWordElement(0xAA41)), // + new DummyRegisterElement(0xAA42, 0xAA4F), // + m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_CHARGE_ENERGY, + new UnsignedDoublewordElement(0xAA50).wordOrder(WordOrder.LSWMSW), // + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_DISCHARGE_ENERGY, + new UnsignedDoublewordElement(0xAA52).wordOrder(WordOrder.LSWMSW), // + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_CHARGE_ENERGY, + new UnsignedDoublewordElement(0xAA54).wordOrder(WordOrder.LSWMSW), // + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_DISCHARGE_ENERGY, + new UnsignedDoublewordElement(0xAA56).wordOrder(WordOrder.LSWMSW), // + SCALE_FACTOR_2)), + new FC3ReadRegistersTask(0xA430, Priority.LOW, // + m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_VOLTAGE, new SignedWordElement(0xA430), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_CURRENT, new SignedWordElement(0xA431), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_POWER, new SignedWordElement(0xA432), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_VOLTAGE, new SignedWordElement(0xA433), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_CURRENT, new SignedWordElement(0xA434), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_POWER, new SignedWordElement(0xA435), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_ENERGY, new SignedWordElement(0xA436), + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_ENERGY, new SignedWordElement(0xA437), + SCALE_FACTOR_2), // + new DummyRegisterElement(0xA438, 0xA43F), // + m(DeyeSunPv.ChannelId.BMS_DCDC_REACTOR_TEMPERATURE, + new SignedWordElement(0xA440)), // + m(DeyeSunPv.ChannelId.BMS_DCDC_IGBT_TEMPERATURE, + new SignedWordElement(0xA441)), // + new DummyRegisterElement(0xA442, 0xA44F), // + m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_CHARGE_ENERGY, + new UnsignedDoublewordElement(0xA450).wordOrder(WordOrder.LSWMSW), // + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_DISCHARGE_ENERGY, + new UnsignedDoublewordElement(0xA452).wordOrder(WordOrder.LSWMSW), // + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_CHARGE_ENERGY, + new UnsignedDoublewordElement(0xA454).wordOrder(WordOrder.LSWMSW), // + SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_DISCHARGE_ENERGY, + new UnsignedDoublewordElement(0xA456).wordOrder(WordOrder.LSWMSW), // + SCALE_FACTOR_2))); // + } + return protocol; + } + + @Override + public String debugLog() { + return "P:" + this.getActualPower().asString(); + } + + @Override + public void handleEvent(Event event) { + switch (event.getTopic()) { + case EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE: + this.calculateEnergy(); + break; + } + } + + /** + * Calculate the Energy values from ActivePower. + */ + private void calculateEnergy() { + var actualPower = this.getActualPower().get(); + if (actualPower == null) { + // Not available + this.calculateActualEnergy.update(null); + } else if (actualPower > 0) { + this.calculateActualEnergy.update(actualPower); + } else { + this.calculateActualEnergy.update(0); + } + } + + @Override + public ModbusSlaveTable getModbusSlaveTable(AccessMode accessMode) { + return new ModbusSlaveTable(// + OpenemsComponent.getModbusSlaveNatureTable(accessMode), // + EssDcCharger.getModbusSlaveNatureTable(accessMode), // + ModbusSlaveNatureTable.of(DeyeSunPv.class, accessMode, 100) // + .build()); + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv1.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv1.java new file mode 100644 index 00000000000..ea06e5435fb --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv1.java @@ -0,0 +1,30 @@ +package io.openems.edge.deye.common.charger; + +import org.osgi.service.metatype.annotations.AttributeDefinition; +import org.osgi.service.metatype.annotations.ObjectClassDefinition; + +@ObjectClassDefinition(// + name = "ESS FENECON Commercial 40 DC Charger PV1", // + description = "Implements the FENECON Commercial 40 DC Charger.") +@interface ConfigPv1 { + + @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") + String id() default "charger0"; + + @AttributeDefinition(name = "Alias", description = "Human-readable name of this Component; defaults to Component-ID") + String alias() default "PV1"; + + @AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?") + boolean enabled() default true; + + @AttributeDefinition(name = "FENECON Commercial40-ID", description = "ID of FENECON Commercial 40 device.") + String ess_id() default "ess0"; + + @AttributeDefinition(name = "FENECON Commercial40 target filter", description = "This is auto-generated by 'FENECON Commercial40-ID'.") + String Ess_target() default "(enabled=true)"; + + @AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID' from FENECON Commercial40.") + String Modbus_target() default "(enabled=true)"; + + String webconsole_configurationFactory_nameHint() default "ESS FENECON Commercial 40 DC Charger PV1 [{id}]"; +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv2.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv2.java new file mode 100644 index 00000000000..756f3b59344 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv2.java @@ -0,0 +1,30 @@ +package io.openems.edge.deye.common.charger; + +import org.osgi.service.metatype.annotations.AttributeDefinition; +import org.osgi.service.metatype.annotations.ObjectClassDefinition; + +@ObjectClassDefinition(// + name = "ESS FENECON Commercial 40 DC Charger PV2", // + description = "Implements the FENECON Commercial 40 DC Charger.") +@interface ConfigPv2 { + + @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") + String id() default "charger1"; + + @AttributeDefinition(name = "Alias", description = "Human-readable name of this Component; defaults to Component-ID") + String alias() default "PV2"; + + @AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?") + boolean enabled() default true; + + @AttributeDefinition(name = "FENECON Commercial40-ID", description = "ID of FENECON Commercial 40 device.") + String ess_id() default "ess0"; + + @AttributeDefinition(name = "FENECON Commercial40 target filter", description = "This is auto-generated by 'FENECON Commercial40-ID'.") + String Ess_target() default "(enabled=true)"; + + @AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID' from FENECON Commercial40.") + String Modbus_target() default "(enabled=true)"; + + String webconsole_configurationFactory_nameHint() default "ESS FENECON Commercial 40 DC Charger PV2 [{id}]"; +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSun2Impl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSun2Impl.java new file mode 100644 index 00000000000..ca4905d0e72 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSun2Impl.java @@ -0,0 +1,94 @@ +package io.openems.edge.deye.common.charger; + +import io.openems.common.exceptions.OpenemsException; +import io.openems.edge.bridge.modbus.api.BridgeModbus; +import io.openems.edge.bridge.modbus.api.ModbusComponent; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.common.event.EdgeEventConstants; +import io.openems.edge.deye.common.DeyeSunHybrid; +import io.openems.edge.ess.dccharger.api.EssDcCharger; +import io.openems.edge.timedata.api.Timedata; +import io.openems.edge.timedata.api.TimedataProvider; +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.ConfigurationPolicy; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; +import org.osgi.service.component.annotations.ReferencePolicyOption; +import org.osgi.service.event.EventHandler; +import org.osgi.service.event.propertytypes.EventTopics; +import org.osgi.service.metatype.annotations.Designate; + +@Designate(ocd = ConfigPv2.class, factory = true) +@Component(// + name = "Ess.Fenecon.Commercial40.PV2", // + immediate = true, // + configurationPolicy = ConfigurationPolicy.REQUIRE // +) +@EventTopics({ // + EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE // +}) +public class DeyeSun2Impl extends AbstractEssDeyePv implements DeyeSunPv, + EssDcCharger, ModbusComponent, OpenemsComponent, EventHandler, TimedataProvider { + + @Reference + private ConfigurationAdmin cm; + + @Override + @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) + protected void setModbus(BridgeModbus modbus) { + super.setModbus(modbus); + } + + @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) + private DeyeSunHybrid ess; + + @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL) + private volatile Timedata timedata = null; + + public DeyeSun2Impl() { + } + + @Activate + private void activate(ComponentContext context, ConfigPv2 config) throws OpenemsException { + if (super.activate(context, config.id(), config.alias(), config.enabled(), this.ess.getUnitId(), this.cm, + "Modbus", this.ess.getModbusBridgeId())) { + return; + } + + // update filter for 'Ess' + if (OpenemsComponent.updateReferenceFilter(this.cm, this.servicePid(), "Ess", config.ess_id())) { + return; + } + + this.ess.addCharger(this); + } + + @Override + @Deactivate + protected void deactivate() { + if (this.ess != null) { + this.ess.removeCharger(this); + } + super.deactivate(); + } + + @Override + public String debugLog() { + return "P:" + this.getActualPower().asString(); + } + + @Override + public Timedata getTimedata() { + return this.timedata; + } + + @Override + protected boolean isPV1() { + return false; + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunImpl.java new file mode 100644 index 00000000000..e76f7533a0e --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunImpl.java @@ -0,0 +1,92 @@ +package io.openems.edge.deye.common.charger; + +import io.openems.common.exceptions.OpenemsException; +import io.openems.edge.bridge.modbus.api.BridgeModbus; +import io.openems.edge.bridge.modbus.api.ModbusComponent; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.common.event.EdgeEventConstants; +import io.openems.edge.deye.common.DeyeSunHybrid; +import io.openems.edge.ess.dccharger.api.EssDcCharger; +import io.openems.edge.timedata.api.Timedata; +import io.openems.edge.timedata.api.TimedataProvider; +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.ConfigurationPolicy; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; +import org.osgi.service.component.annotations.ReferencePolicyOption; +import org.osgi.service.event.EventHandler; +import org.osgi.service.event.propertytypes.EventTopics; +import org.osgi.service.metatype.annotations.Designate; + +@Designate(ocd = ConfigPv1.class, factory = true) +@Component(// + name = "Ess.Fenecon.Commercial40.PV1", // + immediate = true, // + configurationPolicy = ConfigurationPolicy.REQUIRE // +) +@EventTopics({ // + EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE // +}) +public class DeyeSunImpl extends AbstractEssDeyePv implements DeyeSunPv, + EssDcCharger, ModbusComponent, OpenemsComponent, EventHandler, TimedataProvider { + + @Reference + private ConfigurationAdmin cm; + + @Override + @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) + protected void setModbus(BridgeModbus modbus) { + super.setModbus(modbus); + } + + @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) + private DeyeSunHybrid ess; + + @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL) + private volatile Timedata timedata = null; + + public DeyeSunImpl() { + } + + @Activate + private void activate(ComponentContext context, ConfigPv1 config) throws OpenemsException { + if (super.activate(context, config.id(), config.alias(), config.enabled(), this.ess.getUnitId(), this.cm, + "Modbus", this.ess.getModbusBridgeId())) { + return; + } + + // update filter for 'Ess' + if (OpenemsComponent.updateReferenceFilter(this.cm, this.servicePid(), "Ess", config.ess_id())) { + return; + } + + this.ess.addCharger(this); + } + + @Override + @Deactivate + protected void deactivate() { + this.ess.removeCharger(this); + super.deactivate(); + } + + @Override + public String debugLog() { + return "P:" + this.getActualPower().asString(); + } + + @Override + public Timedata getTimedata() { + return this.timedata; + } + + @Override + protected boolean isPV1() { + return true; + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunPv.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunPv.java new file mode 100644 index 00000000000..bf60c820321 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunPv.java @@ -0,0 +1,97 @@ +package io.openems.edge.deye.common.charger; + +import io.openems.common.channel.AccessMode; +import io.openems.common.channel.Unit; +import io.openems.common.types.OpenemsType; +import io.openems.edge.common.channel.Doc; +import io.openems.edge.common.channel.IntegerDoc; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.ess.dccharger.api.EssDcCharger; +import io.openems.edge.timedata.api.TimedataProvider; + +public interface DeyeSunPv extends EssDcCharger, OpenemsComponent, TimedataProvider { + + public enum ChannelId implements io.openems.edge.common.channel.ChannelId { + DEBUG_SET_PV_POWER_LIMIT(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT)), + + /** + * Curtail PV. Careful: this channel is shared between both Chargers. + */ + SET_PV_POWER_LIMIT(new IntegerDoc() // + .unit(Unit.WATT) // + .accessMode(AccessMode.WRITE_ONLY) // + .onChannelSetNextWriteMirrorToDebugChannel(ChannelId.DEBUG_SET_PV_POWER_LIMIT)), + + // LongReadChannel + BMS_DCDC_OUTPUT_ENERGY(Doc.of(OpenemsType.LONG) // + .unit(Unit.CUMULATED_WATT_HOURS)), // + BMS_DCDC_INPUT_ENERGY(Doc.of(OpenemsType.LONG) // + .unit(Unit.CUMULATED_WATT_HOURS)), // + BMS_DCDC_INPUT_CHARGE_ENERGY(Doc.of(OpenemsType.LONG) // + .unit(Unit.CUMULATED_WATT_HOURS)), // + BMS_DCDC_INPUT_DISCHARGE_ENERGY(Doc.of(OpenemsType.LONG) // + .unit(Unit.CUMULATED_WATT_HOURS)), // + BMS_DCDC_OUTPUT_CHARGE_ENERGY(Doc.of(OpenemsType.LONG) // + .unit(Unit.CUMULATED_WATT_HOURS)), // + BMS_DCDC_OUTPUT_DISCHARGE_ENERGY(Doc.of(OpenemsType.LONG) // + .unit(Unit.CUMULATED_WATT_HOURS)), // + PV_DCDC_INPUT_ENERGY(Doc.of(OpenemsType.LONG) // + .unit(Unit.CUMULATED_WATT_HOURS)), // + PV_DCDC_OUTPUT_ENERGY(Doc.of(OpenemsType.LONG) // + .unit(Unit.CUMULATED_WATT_HOURS)), // + PV_DCDC_INPUT_CHARGE_ENERGY(Doc.of(OpenemsType.LONG) // + .unit(Unit.CUMULATED_WATT_HOURS)), // + PV_DCDC_INPUT_DISCHARGE_ENERGY(Doc.of(OpenemsType.LONG) // + .unit(Unit.WATT_HOURS)), // + PV_DCDC_OUTPUT_CHARGE_ENERGY(Doc.of(OpenemsType.LONG) // + .unit(Unit.WATT_HOURS)), // + PV_DCDC_OUTPUT_DISCHARGE_ENERGY(Doc.of(OpenemsType.LONG) // + .unit(Unit.WATT_HOURS)), // + + // IntegerReadChannel + BMS_DCDC_OUTPUT_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + BMS_DCDC_OUTPUT_CURRENT(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIAMPERE)), // + BMS_DCDC_OUTPUT_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT)), // + BMS_DCDC_INPUT_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIWATT)), // + BMS_DCDC_INPUT_CURRENT(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIWATT)), // + BMS_DCDC_INPUT_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT)), // + BMS_DCDC_REACTOR_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.DEGREE_CELSIUS)), // + BMS_DCDC_IGBT_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.DEGREE_CELSIUS)), // + PV_DCDC_OUTPUT_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIVOLT)), // + PV_DCDC_OUTPUT_CURRENT(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIAMPERE)), // + PV_DCDC_OUTPUT_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT)), // + PV_DCDC_INPUT_VOLTAGE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIWATT)), // + PV_DCDC_INPUT_CURRENT(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.MILLIWATT)), // + PV_DCDC_INPUT_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT)), // + PV_DCDC_REACTOR_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.DEGREE_CELSIUS)), // + PV_DCDC_IGBT_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.DEGREE_CELSIUS)); // + + private final Doc doc; + + private ChannelId(Doc doc) { + this.doc = doc; + } + + @Override + public Doc doc() { + return this.doc; + } + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java index 72d449f8374..89ce7767bbc 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/Config.java @@ -3,8 +3,6 @@ import org.osgi.service.metatype.annotations.AttributeDefinition; import org.osgi.service.metatype.annotations.ObjectClassDefinition; -import io.openems.edge.meter.api.MeterType; - @ObjectClassDefinition(name = "Grid Meter Deye", // description = "Implements the Deye Meter - Grid") @interface Config { diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/Config.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Config.java similarity index 88% rename from io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/Config.java rename to io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Config.java index 4679f641cd0..fcf3c64957b 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/Config.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Config.java @@ -1,10 +1,9 @@ -package io.openems.edge.deye.meter; +package io.openems.edge.deye.productionmeter; -import io.openems.edge.meter.api.MeterType; import org.osgi.service.metatype.annotations.AttributeDefinition; import org.osgi.service.metatype.annotations.ObjectClassDefinition; -@ObjectClassDefinition(name = "Production Meter Deye", // +@ObjectClassDefinition(name = "Production Meter Deye Ouida", // description = "Implements the Deye Meter - Production") @interface Config { diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/DeyeMeter.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/DeyeMeter.java similarity index 91% rename from io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/DeyeMeter.java rename to io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/DeyeMeter.java index 83ecee1b363..e3675dfc7d3 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/DeyeMeter.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/DeyeMeter.java @@ -1,4 +1,4 @@ -package io.openems.edge.deye.meter; +package io.openems.edge.deye.productionmeter; import io.openems.edge.bridge.modbus.api.ModbusComponent; import io.openems.edge.common.channel.Doc; diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/DeyeMeterImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/DeyeMeterImpl.java similarity index 51% rename from io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/DeyeMeterImpl.java rename to io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/DeyeMeterImpl.java index 1ff4ae67282..7ce66043485 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/meter/DeyeMeterImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/DeyeMeterImpl.java @@ -1,18 +1,26 @@ -package io.openems.edge.deye.meter; +package io.openems.edge.deye.productionmeter; +import io.openems.common.exceptions.OpenemsError; import io.openems.common.exceptions.OpenemsException; +import io.openems.common.types.ChannelAddress; +import io.openems.common.types.OpenemsType; +import io.openems.edge.battery.api.Battery; +import io.openems.edge.batteryinverter.api.ManagedSymmetricBatteryInverter; import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; import io.openems.edge.bridge.modbus.api.BridgeModbus; -import io.openems.edge.bridge.modbus.api.ElementToChannelConverter; import io.openems.edge.bridge.modbus.api.ModbusComponent; import io.openems.edge.bridge.modbus.api.ModbusProtocol; -import io.openems.edge.bridge.modbus.api.element.UnsignedDoublewordElement; +import io.openems.edge.bridge.modbus.api.element.UnsignedWordElement; import io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask; import io.openems.edge.common.component.OpenemsComponent; import io.openems.edge.common.event.EdgeEventConstants; +import io.openems.edge.common.startstop.StartStop; import io.openems.edge.common.taskmanager.Priority; import io.openems.edge.meter.api.ElectricityMeter; import io.openems.edge.meter.api.MeterType; +import io.openems.edge.timedata.api.Timedata; +import io.openems.edge.timedata.api.TimedataProvider; +import io.openems.edge.timedata.api.utils.CalculateEnergyFromPower; import org.osgi.service.cm.ConfigurationAdmin; import org.osgi.service.component.ComponentContext; import org.osgi.service.component.annotations.Activate; @@ -23,6 +31,8 @@ import org.osgi.service.component.annotations.ReferenceCardinality; import org.osgi.service.component.annotations.ReferencePolicy; import org.osgi.service.component.annotations.ReferencePolicyOption; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventHandler; import org.osgi.service.event.propertytypes.EventTopics; import org.osgi.service.metatype.annotations.Designate; @@ -35,13 +45,21 @@ "type=PRODUCTION" // }) @EventTopics({ // - EdgeEventConstants.TOPIC_CYCLE_EXECUTE_WRITE // + EdgeEventConstants.TOPIC_CYCLE_BEFORE_PROCESS_IMAGE, // + EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE // }) -public class DeyeMeterImpl extends AbstractOpenemsModbusComponent implements DeyeMeter, ElectricityMeter, ModbusComponent, OpenemsComponent { +public class DeyeMeterImpl extends AbstractOpenemsModbusComponent implements DeyeMeter, ElectricityMeter, ModbusComponent, OpenemsComponent, EventHandler, TimedataProvider { + + private final CalculateEnergyFromPower calculateProductionEnergy = new CalculateEnergyFromPower(this, ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY); + + private final CalculateEnergyFromPower calculateConsumptionEnergy = new CalculateEnergyFromPower(this, ElectricityMeter.ChannelId.ACTIVE_CONSUMPTION_ENERGY); @Reference private ConfigurationAdmin cm; + @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL) + private volatile Timedata timedata = null; + @Override @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) protected void setModbus(BridgeModbus modbus) { @@ -52,14 +70,12 @@ protected void setModbus(BridgeModbus modbus) { public DeyeMeterImpl() throws OpenemsException { super(// + OpenemsComponent.ChannelId.values(), // ModbusComponent.ChannelId.values(), // ElectricityMeter.ChannelId.values(), // DeyeMeter.ChannelId.values() // ); - - // Automatically calculate sum values from L1/L2/L3 - ElectricityMeter.calculateSumActivePowerFromPhases(this); } @Activate @@ -88,8 +104,10 @@ public void retryModbusCommunication() { @Override protected ModbusProtocol defineModbusProtocol() throws OpenemsException { - return new ModbusProtocol(this, new FC3ReadRegistersTask(672, Priority.HIGH, - m(ElectricityMeter.ChannelId.ACTIVE_POWER, new UnsignedDoublewordElement(672), ElementToChannelConverter.DIRECT_1_TO_1))); + return new ModbusProtocol(this, // + new FC3ReadRegistersTask(607, Priority.LOW, // + m(ElectricityMeter.ChannelId.ACTIVE_POWER, new UnsignedWordElement(607)))// + ); } @Override @@ -97,4 +115,54 @@ public String debugLog() { return "PRODUCTION:" + this.getActivePower().asString(); } + @Override + public void handleEvent(Event event) { + if (!this.isEnabled()) { + return; + } + switch (event.getTopic()) { + case EdgeEventConstants.TOPIC_CYCLE_BEFORE_PROCESS_IMAGE: + this.updateChannels(); + break; + case EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE: + this.calculateEnergy(); + break; + } + } + + private void updateChannels() { + + Integer simulatedActivePower = Integer.valueOf(1000); + + // Apply Active Power Limit + + this._setActivePower(simulatedActivePower); + } + + /** + * Calculate the Energy values from ActivePower. + */ + private void calculateEnergy() { + // Calculate Energy + var activePower = Integer.valueOf(1000); + if (activePower == null) { + // Not available + this.calculateProductionEnergy.update(null); + this.calculateConsumptionEnergy.update(null); + } else if (activePower > 0) { + // Production + this.calculateProductionEnergy.update(activePower); + this.calculateConsumptionEnergy.update(0); + } else { + // Consumption (or in this context: "Negative Production") + this.calculateProductionEnergy.update(0); + this.calculateConsumptionEnergy.update(activePower * -1); + } + } + + @Override + public Timedata getTimedata() { + return this.timedata; + } + } diff --git a/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/DeyeGridMeterImplTest.java b/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/DeyeGridMeterImplTest.java new file mode 100644 index 00000000000..273fab0b55f --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/DeyeGridMeterImplTest.java @@ -0,0 +1,7 @@ +package io.openems.edge.deye.gridmeter; + +import junit.framework.TestCase; + +public class DeyeGridMeterImplTest extends TestCase { + +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/MyConfig.java b/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/MyConfig.java new file mode 100644 index 00000000000..0160fe0c25f --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/MyConfig.java @@ -0,0 +1,75 @@ +package io.openems.edge.deye.gridmeter; + +import io.openems.common.test.AbstractComponentConfig; +import io.openems.common.utils.ConfigUtils; +import io.openems.edge.common.startstop.StartStopConfig; + +@SuppressWarnings("all") +public class MyConfig extends AbstractComponentConfig implements Config { + + protected static class Builder { + private String id = null; + private StartStopConfig startStopConfig = null; + private String modbusId = null; + private boolean activateWatchdog; + + private Builder() { + } + + public Builder setId(String id) { + this.id = id; + return this; + } + + public Builder setStartStopConfig(StartStopConfig startStopConfig) { + this.startStopConfig = startStopConfig; + return this; + } + + public Builder setModbusId(String modbusId) { + this.modbusId = modbusId; + return this; + } + + public Builder setActivateWatchdog(boolean activateWatchdog) { + this.activateWatchdog = activateWatchdog; + return this; + } + + public MyConfig build() { + return new MyConfig(this); + } + } + + /** + * Create a Config builder. + * + * @return a {@link Builder} + */ + public static Builder create() { + return new Builder(); + } + + private final Builder builder; + + private MyConfig(Builder builder) { + super(Config.class, builder.id); + this.builder = builder; + } + + @Override + public String modbus_id() { + return this.builder.modbusId; + } + + @Override + public int modbusUnitId() { + return 0; + } + + @Override + public String Modbus_target() { + return ConfigUtils.generateReferenceTargetFilter(this.id(), this.modbus_id()); + } + +} \ No newline at end of file diff --git a/io.openems.edge.ess.fenecon.commercial40/src/io/openems/edge/deye/gridmeter/SurplusFeedInStateMachine.java b/io.openems.edge.ess.fenecon.commercial40/src/io/openems/edge/deye/gridmeter/SurplusFeedInStateMachine.java new file mode 100644 index 00000000000..9c591d0f47a --- /dev/null +++ b/io.openems.edge.ess.fenecon.commercial40/src/io/openems/edge/deye/gridmeter/SurplusFeedInStateMachine.java @@ -0,0 +1,34 @@ +package io.openems.edge.deye.gridmeter; + +import io.openems.common.types.OptionsEnum; + +public enum SurplusFeedInStateMachine implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + DEACTIVATED(0, "Deactivated"), // + ACTIVATED(1, "Activated"), // + GOING_DEACTIVATED(2, "Going Deactivated"), // + PASSED_OFF_TIME(3, "Passed Off-Time"); // + + private final int value; + private final String name; + + private SurplusFeedInStateMachine(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file From 08f75aff961019caa9af847d9715c38d415ddba8 Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Thu, 4 Apr 2024 14:45:13 +0200 Subject: [PATCH 06/25] Update implementation for PV Inverter - DEYE --- .../edge/deye/productionmeter/Config.java | 6 +- .../edge/deye/productionmeter/DeyeMeter.java | 23 ---- .../edge/deye/productionmeter/PLimitType.java | 34 ++++++ .../deye/productionmeter/PvInverterDeye.java | 68 ++++++++++++ ...MeterImpl.java => PvInverterDeyeImpl.java} | 101 ++++++++---------- .../productionmeter/SetPvLimitHandler.java | 70 ++++++++++++ .../edge/deye/productionmeter/Status.java | 32 ++++++ 7 files changed, 256 insertions(+), 78 deletions(-) delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/DeyeMeter.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PLimitType.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java rename io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/{DeyeMeterImpl.java => PvInverterDeyeImpl.java} (68%) create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/SetPvLimitHandler.java create mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Status.java diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Config.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Config.java index fcf3c64957b..f68eb6311b4 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Config.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Config.java @@ -3,7 +3,7 @@ import org.osgi.service.metatype.annotations.AttributeDefinition; import org.osgi.service.metatype.annotations.ObjectClassDefinition; -@ObjectClassDefinition(name = "Production Meter Deye Ouida", // +@ObjectClassDefinition(name = "Production Meter Deye", // description = "Implements the Deye Meter - Production") @interface Config { @@ -22,6 +22,10 @@ @AttributeDefinition(name = "Modbus Unit-ID", description = "The Unit-ID of the Modbus device. ") int modbusUnitId() default 1; + @AttributeDefinition(name = "Maximum Active Power", description = "This is the rated output of the PV installation.") + int maxActivePower(); + + @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.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/DeyeMeter.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/DeyeMeter.java deleted file mode 100644 index e3675dfc7d3..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/DeyeMeter.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.openems.edge.deye.productionmeter; - -import io.openems.edge.bridge.modbus.api.ModbusComponent; -import io.openems.edge.common.channel.Doc; -import io.openems.edge.common.component.OpenemsComponent; -import io.openems.edge.meter.api.ElectricityMeter; - -public interface DeyeMeter extends ElectricityMeter, ModbusComponent, OpenemsComponent { - - public enum ChannelId implements io.openems.edge.common.channel.ChannelId { - ; - private final Doc doc; - - private ChannelId(Doc doc) { - this.doc = doc; - } - - @Override - public Doc doc() { - return this.doc; - } - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PLimitType.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PLimitType.java new file mode 100644 index 00000000000..9fb1a10ba78 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PLimitType.java @@ -0,0 +1,34 @@ +package io.openems.edge.deye.productionmeter; + +import io.openems.common.types.OptionsEnum; + +public enum PLimitType implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + NOT_ACTIVE(0, "Interface not active"), // + NO_LIMIT(1, "No limitation active (100 %)"), // + FIXED_LIMIT(2, "Fixed limitation active in %"), // + LIMIT_SELF_SUFFICIENCY(3, "Limitation in %, considering self-sufficiency"); // + + private final int value; + private final String name; + + private PLimitType(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java new file mode 100644 index 00000000000..89abdfe3fdc --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java @@ -0,0 +1,68 @@ +package io.openems.edge.deye.productionmeter; + +import io.openems.common.channel.AccessMode; +import io.openems.common.channel.Level; +import io.openems.common.channel.Unit; +import io.openems.common.types.OpenemsType; +import io.openems.edge.bridge.modbus.api.ModbusComponent; +import io.openems.edge.common.channel.Doc; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.meter.api.ElectricityMeter; + +public interface PvInverterDeye extends ElectricityMeter, ModbusComponent, OpenemsComponent { + + public enum ChannelId implements io.openems.edge.common.channel.ChannelId { + + LAST_UPDATE_TIME(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.SECONDS)), // + PDC(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT)), // + UDC(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.VOLT)), + YESTERDAY_YIELD(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT_HOURS)), + MONTHLY_YIELD(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT_HOURS)), + YEARLY_YIELD(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT_HOURS)), + TOTAL_YIELD(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.CUMULATED_WATT_HOURS)), + PAC_CONSUMPTION(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT)), + YESTERDAY_YIELD_CONS(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT_HOURS)), + MONTHLY_YIELD_CONS(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT_HOURS)), + YEARLY_YIELD_CONS(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT_HOURS)), + TOTAL_YIELD_CONS(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.CUMULATED_WATT_HOURS)), + TOTAL_POWER(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.WATT_HOURS_BY_WATT_PEAK)), + + // PV + P_LIMIT_TYPE(Doc.of(PLimitType.values()) // + .accessMode(AccessMode.WRITE_ONLY)), // + P_LIMIT_PERC(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE) // + .unit(Unit.PERCENT)), + P_LIMIT(Doc.of(OpenemsType.INTEGER) // + .unit(Unit.KILOWATT)), + WATCH_DOG_TAG(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE)), // + STATUS(Doc.of(Status.values())), + + PV_LIMIT_FAILED(Doc.of(Level.FAULT) // + .text("PV-Limit failed")); + private final Doc doc; + + private ChannelId(Doc doc) { + this.doc = doc; + } + + @Override + public Doc doc() { + return this.doc; + } + } +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/DeyeMeterImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java similarity index 68% rename from io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/DeyeMeterImpl.java rename to io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java index 7ce66043485..2b29d597176 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/DeyeMeterImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java @@ -1,11 +1,8 @@ package io.openems.edge.deye.productionmeter; +import io.openems.common.channel.AccessMode; import io.openems.common.exceptions.OpenemsError; import io.openems.common.exceptions.OpenemsException; -import io.openems.common.types.ChannelAddress; -import io.openems.common.types.OpenemsType; -import io.openems.edge.battery.api.Battery; -import io.openems.edge.batteryinverter.api.ManagedSymmetricBatteryInverter; import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; import io.openems.edge.bridge.modbus.api.BridgeModbus; import io.openems.edge.bridge.modbus.api.ModbusComponent; @@ -14,10 +11,12 @@ import io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask; import io.openems.edge.common.component.OpenemsComponent; import io.openems.edge.common.event.EdgeEventConstants; -import io.openems.edge.common.startstop.StartStop; +import io.openems.edge.common.modbusslave.ModbusSlave; +import io.openems.edge.common.modbusslave.ModbusSlaveTable; import io.openems.edge.common.taskmanager.Priority; import io.openems.edge.meter.api.ElectricityMeter; import io.openems.edge.meter.api.MeterType; +import io.openems.edge.pvinverter.api.ManagedSymmetricPvInverter; import io.openems.edge.timedata.api.Timedata; import io.openems.edge.timedata.api.TimedataProvider; import io.openems.edge.timedata.api.utils.CalculateEnergyFromPower; @@ -35,10 +34,11 @@ import org.osgi.service.event.EventHandler; import org.osgi.service.event.propertytypes.EventTopics; import org.osgi.service.metatype.annotations.Designate; +import org.slf4j.Logger; @Designate(ocd = Config.class, factory = true) @Component(// - name = "Deye.Meter", // + name = "PV-Inverter.Deye", // immediate = true, // configurationPolicy = ConfigurationPolicy.REQUIRE, // property = { // @@ -48,11 +48,12 @@ EdgeEventConstants.TOPIC_CYCLE_BEFORE_PROCESS_IMAGE, // EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE // }) -public class DeyeMeterImpl extends AbstractOpenemsModbusComponent implements DeyeMeter, ElectricityMeter, ModbusComponent, OpenemsComponent, EventHandler, TimedataProvider { +public class PvInverterDeyeImpl extends AbstractOpenemsModbusComponent + implements PvInverterDeye, ManagedSymmetricPvInverter, ElectricityMeter, ModbusComponent, OpenemsComponent, EventHandler, ModbusSlave, TimedataProvider { - private final CalculateEnergyFromPower calculateProductionEnergy = new CalculateEnergyFromPower(this, ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY); + private final SetPvLimitHandler setPvLimitHandler = new SetPvLimitHandler(this, ManagedSymmetricPvInverter.ChannelId.ACTIVE_POWER_LIMIT); - private final CalculateEnergyFromPower calculateConsumptionEnergy = new CalculateEnergyFromPower(this, ElectricityMeter.ChannelId.ACTIVE_CONSUMPTION_ENERGY); + private final CalculateEnergyFromPower calculateProductionEnergy = new CalculateEnergyFromPower(this, ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY); @Reference private ConfigurationAdmin cm; @@ -66,15 +67,16 @@ protected void setModbus(BridgeModbus modbus) { super.setModbus(modbus); } - private Config config; + protected Config config; - public DeyeMeterImpl() throws OpenemsException { + public PvInverterDeyeImpl() throws OpenemsException { super(// OpenemsComponent.ChannelId.values(), // ModbusComponent.ChannelId.values(), // ElectricityMeter.ChannelId.values(), // - DeyeMeter.ChannelId.values() // + ManagedSymmetricPvInverter.ChannelId.values(), // + PvInverterDeye.ChannelId.values() // ); } @@ -84,6 +86,13 @@ private void activate(ComponentContext context, Config config) throws OpenemsExc return; } this.config = config; + this._setMaxApparentPower(config.maxActivePower()); + + // Stop if component is disabled + if (!config.enabled()) { + return; + } + } @Override @@ -92,16 +101,6 @@ protected void deactivate() { super.deactivate(); } - @Override - public MeterType getMeterType() { - return MeterType.PRODUCTION; - } - - @Override - public void retryModbusCommunication() { - - } - @Override protected ModbusProtocol defineModbusProtocol() throws OpenemsException { return new ModbusProtocol(this, // @@ -110,54 +109,48 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException { ); } - @Override - public String debugLog() { - return "PRODUCTION:" + this.getActivePower().asString(); - } - @Override public void handleEvent(Event event) { if (!this.isEnabled()) { return; } switch (event.getTopic()) { - case EdgeEventConstants.TOPIC_CYCLE_BEFORE_PROCESS_IMAGE: - this.updateChannels(); + case EdgeEventConstants.TOPIC_CYCLE_EXECUTE_WRITE: + try { + this.setPvLimitHandler.run(); + + this.channel(PvInverterDeye.ChannelId.PV_LIMIT_FAILED).setNextValue(false); + } catch (OpenemsError.OpenemsNamedException e) { + this.channel(PvInverterDeye.ChannelId.PV_LIMIT_FAILED).setNextValue(true); + } break; case EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE: - this.calculateEnergy(); + this.calculateProductionEnergy.update(this.getActivePower().get()); break; } } - private void updateChannels() { - - Integer simulatedActivePower = Integer.valueOf(1000); + @Override + public MeterType getMeterType() { + return MeterType.PRODUCTION; + } - // Apply Active Power Limit + @Override + public String debugLog() { + return "L:" + this.getActivePower().asString(); + } - this._setActivePower(simulatedActivePower); + @Override + protected void logInfo(Logger log, String message) { + super.logInfo(log, message); } - /** - * Calculate the Energy values from ActivePower. - */ - private void calculateEnergy() { - // Calculate Energy - var activePower = Integer.valueOf(1000); - if (activePower == null) { - // Not available - this.calculateProductionEnergy.update(null); - this.calculateConsumptionEnergy.update(null); - } else if (activePower > 0) { - // Production - this.calculateProductionEnergy.update(activePower); - this.calculateConsumptionEnergy.update(0); - } else { - // Consumption (or in this context: "Negative Production") - this.calculateProductionEnergy.update(0); - this.calculateConsumptionEnergy.update(activePower * -1); - } + @Override + public ModbusSlaveTable getModbusSlaveTable(AccessMode accessMode) { + return new ModbusSlaveTable(// + OpenemsComponent.getModbusSlaveNatureTable(accessMode), // + ElectricityMeter.getModbusSlaveNatureTable(accessMode), // + ManagedSymmetricPvInverter.getModbusSlaveNatureTable(accessMode)); } @Override diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/SetPvLimitHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/SetPvLimitHandler.java new file mode 100644 index 00000000000..81bbbeb2c45 --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/SetPvLimitHandler.java @@ -0,0 +1,70 @@ +package io.openems.edge.deye.productionmeter; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.common.function.ThrowingRunnable; +import io.openems.edge.common.channel.EnumWriteChannel; +import io.openems.edge.common.channel.IntegerWriteChannel; +import io.openems.edge.pvinverter.api.ManagedSymmetricPvInverter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.LocalDateTime; +import java.util.Objects; + +public class SetPvLimitHandler implements ThrowingRunnable { + + private final Logger log = LoggerFactory.getLogger(SetPvLimitHandler.class); + private final PvInverterDeyeImpl parent; + private final ManagedSymmetricPvInverter.ChannelId channelId; + + private Integer lastPLimitPerc = null; + private LocalDateTime lastPLimitPercTime = LocalDateTime.MIN; + + public SetPvLimitHandler(PvInverterDeyeImpl parent, ManagedSymmetricPvInverter.ChannelId activePowerLimit) { + this.parent = parent; + this.channelId = activePowerLimit; + } + + @Override + public void run() throws OpenemsNamedException { + IntegerWriteChannel channel = this.parent.channel(this.channelId); + var powerOpt = channel.getNextWriteValueAndReset(); + + int pLimitPerc; + int power; + if (powerOpt.isPresent()) { + power = powerOpt.get(); + pLimitPerc = (int) ((double) power / (double) this.parent.config.maxActivePower() * 100.0); + + // keep percentage in range [0, 100] + if (pLimitPerc > 100) { + pLimitPerc = 100; + } + if (pLimitPerc < 0) { + pLimitPerc = 0; + } + } else { + // Reset limit + power = this.parent.config.maxActivePower(); + pLimitPerc = 100; + } + + if (!Objects.equals(this.lastPLimitPerc, pLimitPerc) || this.lastPLimitPercTime + .isBefore(LocalDateTime.now().minusSeconds(150 /* watchdog timeout is 300 */))) { + // Value needs to be set + this.parent.logInfo(this.log, "Apply new limit: " + power + " W (" + pLimitPerc + " %)"); + IntegerWriteChannel pLimitPercCh = this.parent.channel(PvInverterDeye.ChannelId.P_LIMIT_PERC); + pLimitPercCh.setNextWriteValue(pLimitPerc); + + EnumWriteChannel pLimitTypeCh = this.parent.channel(PvInverterDeye.ChannelId.P_LIMIT_TYPE); + pLimitTypeCh.setNextWriteValue(PLimitType.FIXED_LIMIT); + + IntegerWriteChannel watchDogTagCh = this.parent.channel(PvInverterDeye.ChannelId.WATCH_DOG_TAG); + watchDogTagCh.setNextWriteValue((int) System.currentTimeMillis()); + + this.lastPLimitPerc = pLimitPerc; + this.lastPLimitPercTime = LocalDateTime.now(); + } + } + +} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Status.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Status.java new file mode 100644 index 00000000000..fcd956bb53f --- /dev/null +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Status.java @@ -0,0 +1,32 @@ +package io.openems.edge.deye.productionmeter; + +import io.openems.common.types.OptionsEnum; + +public enum Status implements OptionsEnum { + UNDEFINED(-1, "Undefined"), // + OK(0, "Ok"), // + LICENSE_NOT_SUFFICIENT(1, "License not sufficient for size of installation"); // + + private final int value; + private final String name; + + private Status(int value, String name) { + this.value = value; + this.name = name; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public OptionsEnum getUndefined() { + return UNDEFINED; + } +} \ No newline at end of file From 94073126a2db1b2e7f8e245c4a44e8b0bd1c0f56 Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Thu, 4 Apr 2024 16:09:28 +0200 Subject: [PATCH 07/25] Update implementation for PV Inverter - DEYE Calculate energy the right way --- .../deye/productionmeter/PvInverterDeye.java | 50 +++++++++++++++++++ .../productionmeter/PvInverterDeyeImpl.java | 11 ++-- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java index 89abdfe3fdc..ae5697fdbe7 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java @@ -6,13 +6,23 @@ import io.openems.common.types.OpenemsType; import io.openems.edge.bridge.modbus.api.ModbusComponent; import io.openems.edge.common.channel.Doc; +import io.openems.edge.common.channel.IntegerReadChannel; +import io.openems.edge.common.channel.value.Value; import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.common.type.TypeUtils; import io.openems.edge.meter.api.ElectricityMeter; +import java.util.function.Consumer; + public interface PvInverterDeye extends ElectricityMeter, ModbusComponent, OpenemsComponent { public enum ChannelId implements io.openems.edge.common.channel.ChannelId { + ACTIVE_POWER_STRING_1(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), + ACTIVE_POWER_STRING_2(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), + ACTIVE_POWER_STRING_3(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), + ACTIVE_POWER_STRING_4(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), + LAST_UPDATE_TIME(Doc.of(OpenemsType.INTEGER) // .unit(Unit.SECONDS)), // PDC(Doc.of(OpenemsType.INTEGER) // @@ -64,5 +74,45 @@ private ChannelId(Doc doc) { public Doc doc() { return this.doc; } + + + } + + /** + * Initializes Channel listeners to calculate the + * {@link ElectricityMeter.ChannelId#ACTIVE_POWER}-Channel value as the sum of + * {@link ElectricityMeter.ChannelId#ACTIVE_POWER_L1}, {@link ElectricityMeter.ChannelId#ACTIVE_POWER_L2} and + * {@link ElectricityMeter.ChannelId#ACTIVE_POWER_L3}. + * + * @param meter the {@link ElectricityMeter} + */ + public static void calculateSumActivePowerFromPhases(PvInverterDeye meter) { + final Consumer> calculate = ignore -> { + meter._setActivePower(TypeUtils.sum(// + meter.getActivePowerS1Channel().getNextValue().get(), // + meter.getActivePowerS2Channel().getNextValue().get(), // + meter.getActivePowerS3Channel().getNextValue().get(), // + meter.getActivePowerS4Channel().getNextValue().get())); // + }; + meter.getActivePowerS1Channel().onSetNextValue(calculate); + meter.getActivePowerS2Channel().onSetNextValue(calculate); + meter.getActivePowerS3Channel().onSetNextValue(calculate); + meter.getActivePowerS4Channel().onSetNextValue(calculate); + } + + public default IntegerReadChannel getActivePowerS1Channel() { + return this.channel(ChannelId.ACTIVE_POWER_STRING_1); + } + + public default IntegerReadChannel getActivePowerS2Channel() { + return this.channel(ChannelId.ACTIVE_POWER_STRING_2); + } + + public default IntegerReadChannel getActivePowerS3Channel() { + return this.channel(ChannelId.ACTIVE_POWER_STRING_3); + } + + public default IntegerReadChannel getActivePowerS4Channel() { + return this.channel(ChannelId.ACTIVE_POWER_STRING_4); } } diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java index 2b29d597176..2c1bed0c660 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java @@ -77,7 +77,9 @@ public PvInverterDeyeImpl() throws OpenemsException { ElectricityMeter.ChannelId.values(), // ManagedSymmetricPvInverter.ChannelId.values(), // PvInverterDeye.ChannelId.values() // + ); + PvInverterDeye.calculateSumActivePowerFromPhases(this); } @Activate @@ -104,9 +106,12 @@ protected void deactivate() { @Override protected ModbusProtocol defineModbusProtocol() throws OpenemsException { return new ModbusProtocol(this, // - new FC3ReadRegistersTask(607, Priority.LOW, // - m(ElectricityMeter.ChannelId.ACTIVE_POWER, new UnsignedWordElement(607)))// - ); + new FC3ReadRegistersTask(672, Priority.LOW, // + m(PvInverterDeye.ChannelId.ACTIVE_POWER_STRING_1, new UnsignedWordElement(672)), + m(PvInverterDeye.ChannelId.ACTIVE_POWER_STRING_2, new UnsignedWordElement(673)), + m(PvInverterDeye.ChannelId.ACTIVE_POWER_STRING_3, new UnsignedWordElement(674)), + m(PvInverterDeye.ChannelId.ACTIVE_POWER_STRING_4, new UnsignedWordElement(675)// + ))); } @Override From 087902b8f2ce84b83d6df6307657b1dc6b3e2f52 Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Fri, 5 Apr 2024 08:37:35 +0200 Subject: [PATCH 08/25] Update implementation of DEYE Grid meter --- .../deye/gridmeter/DeyeGridMeterImpl.java | 74 +++++++++++++++++-- 1 file changed, 66 insertions(+), 8 deletions(-) diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java index dd7d9117293..0bb4ee95ce6 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java @@ -1,5 +1,6 @@ package io.openems.edge.deye.gridmeter; +import io.openems.common.channel.AccessMode; import io.openems.common.exceptions.OpenemsException; import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; import io.openems.edge.bridge.modbus.api.BridgeModbus; @@ -9,9 +10,15 @@ import io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask; import io.openems.edge.common.component.OpenemsComponent; import io.openems.edge.common.event.EdgeEventConstants; +import io.openems.edge.common.modbusslave.ModbusSlave; +import io.openems.edge.common.modbusslave.ModbusSlaveNatureTable; +import io.openems.edge.common.modbusslave.ModbusSlaveTable; import io.openems.edge.common.taskmanager.Priority; import io.openems.edge.meter.api.ElectricityMeter; import io.openems.edge.meter.api.MeterType; +import io.openems.edge.timedata.api.Timedata; +import io.openems.edge.timedata.api.TimedataProvider; +import io.openems.edge.timedata.api.utils.CalculateEnergyFromPower; import org.osgi.service.cm.ConfigurationAdmin; import org.osgi.service.component.ComponentContext; import org.osgi.service.component.annotations.Activate; @@ -22,8 +29,12 @@ import org.osgi.service.component.annotations.ReferenceCardinality; import org.osgi.service.component.annotations.ReferencePolicy; import org.osgi.service.component.annotations.ReferencePolicyOption; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventHandler; import org.osgi.service.event.propertytypes.EventTopics; import org.osgi.service.metatype.annotations.Designate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @Designate(ocd = Config.class, factory = true) @Component(// @@ -34,10 +45,16 @@ "type=GRID" // }) @EventTopics({ // - EdgeEventConstants.TOPIC_CYCLE_EXECUTE_WRITE // + EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE // }) public class DeyeGridMeterImpl extends AbstractOpenemsModbusComponent - implements DeyeGridMeter, ElectricityMeter, ModbusComponent, OpenemsComponent { + implements DeyeGridMeter, ElectricityMeter, ModbusComponent, OpenemsComponent, TimedataProvider, EventHandler, ModbusSlave { + + private final Logger log = LoggerFactory.getLogger(DeyeGridMeterImpl.class); + private final CalculateEnergyFromPower calculateProductionEnergy = new CalculateEnergyFromPower(this, + ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY); + private final CalculateEnergyFromPower calculateConsumptionEnergy = new CalculateEnergyFromPower(this, + ElectricityMeter.ChannelId.ACTIVE_CONSUMPTION_ENERGY); @Reference private ConfigurationAdmin cm; @@ -47,6 +64,8 @@ public class DeyeGridMeterImpl extends AbstractOpenemsModbusComponent protected void setModbus(BridgeModbus modbus) { super.setModbus(modbus); } + @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL) + private volatile Timedata timedata = null; private Config config; @@ -82,11 +101,6 @@ public MeterType getMeterType() { return MeterType.GRID; } - @Override - public void retryModbusCommunication() { - - } - @Override protected ModbusProtocol defineModbusProtocol() throws OpenemsException { return new ModbusProtocol(this, @@ -96,9 +110,53 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException { m(ElectricityMeter.ChannelId.ACTIVE_POWER_L3, new SignedWordElement(635)))); } + @Override + public void handleEvent(Event event) { + switch (event.getTopic()) { + case EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE: + this.calculateEnergy(); + break; + } + } + + /** + * Calculate the Energy values from ActivePower. + */ + private void calculateEnergy() { + // Calculate Energy + var activePower = this.getActivePower().get(); + if (activePower == null) { + // Not available + this.calculateProductionEnergy.update(null); + this.calculateConsumptionEnergy.update(null); + } else if (activePower > 0) { + // Buy-From-Grid + this.calculateProductionEnergy.update(activePower); + this.calculateConsumptionEnergy.update(0); + } else { + // Sell-To-Grid + this.calculateProductionEnergy.update(0); + this.calculateConsumptionEnergy.update(activePower * -1); + } + } + @Override public String debugLog() { - return "GRID:" + this.getActivePower().asString(); + return "L:" + this.getActivePower().asString(); + } + + @Override + public Timedata getTimedata() { + return this.timedata; + } + + @Override + public ModbusSlaveTable getModbusSlaveTable(AccessMode accessMode) { + return new ModbusSlaveTable(// + OpenemsComponent.getModbusSlaveNatureTable(accessMode), // + ElectricityMeter.getModbusSlaveNatureTable(accessMode), // + ModbusSlaveNatureTable.of(DeyeGridMeter.class, accessMode, 100).build() // + ); } } From 54e65b63bdff95c8b4c42798fad38ac0211ac127 Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Mon, 8 Apr 2024 22:04:04 +0200 Subject: [PATCH 09/25] Implementing DEYE inverter --- io.openems.edge.batteryinverter.deye/bnd.bnd | 2 +- .../edge/deye/productionmeter/PvInverterDeye.java | 10 +++++++++- .../edge/deye/productionmeter/PvInverterDeyeImpl.java | 5 +++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/io.openems.edge.batteryinverter.deye/bnd.bnd b/io.openems.edge.batteryinverter.deye/bnd.bnd index 8ff040a6be6..4a48b5afce1 100644 --- a/io.openems.edge.batteryinverter.deye/bnd.bnd +++ b/io.openems.edge.batteryinverter.deye/bnd.bnd @@ -14,6 +14,6 @@ Bundle-Version: 1.0.0.${tstamp} io.openems.edge.common,\ io.openems.edge.ess.api,\ io.openems.edge.timedata.api,\ - + io.openems.edge.pvinverter.api -testpath: \ ${testpath} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java index ae5697fdbe7..c1479621804 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java @@ -22,6 +22,8 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { ACTIVE_POWER_STRING_2(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), ACTIVE_POWER_STRING_3(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), ACTIVE_POWER_STRING_4(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), + + ACTIVE_POWER_GENERATOR(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), LAST_UPDATE_TIME(Doc.of(OpenemsType.INTEGER) // .unit(Unit.SECONDS)), // @@ -92,12 +94,14 @@ public static void calculateSumActivePowerFromPhases(PvInverterDeye meter) { meter.getActivePowerS1Channel().getNextValue().get(), // meter.getActivePowerS2Channel().getNextValue().get(), // meter.getActivePowerS3Channel().getNextValue().get(), // - meter.getActivePowerS4Channel().getNextValue().get())); // + meter.getActivePowerS4Channel().getNextValue().get(), + meter.getActivePowerGen().getNextValue().get())); // }; meter.getActivePowerS1Channel().onSetNextValue(calculate); meter.getActivePowerS2Channel().onSetNextValue(calculate); meter.getActivePowerS3Channel().onSetNextValue(calculate); meter.getActivePowerS4Channel().onSetNextValue(calculate); + meter.getActivePowerGen().onSetNextValue(calculate); } public default IntegerReadChannel getActivePowerS1Channel() { @@ -115,4 +119,8 @@ public default IntegerReadChannel getActivePowerS3Channel() { public default IntegerReadChannel getActivePowerS4Channel() { return this.channel(ChannelId.ACTIVE_POWER_STRING_4); } + + public default IntegerReadChannel getActivePowerGen() { + return this.channel(ChannelId.ACTIVE_POWER_GENERATOR); + } } diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java index 2c1bed0c660..62d584115a2 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java @@ -110,8 +110,9 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException { m(PvInverterDeye.ChannelId.ACTIVE_POWER_STRING_1, new UnsignedWordElement(672)), m(PvInverterDeye.ChannelId.ACTIVE_POWER_STRING_2, new UnsignedWordElement(673)), m(PvInverterDeye.ChannelId.ACTIVE_POWER_STRING_3, new UnsignedWordElement(674)), - m(PvInverterDeye.ChannelId.ACTIVE_POWER_STRING_4, new UnsignedWordElement(675)// - ))); + m(PvInverterDeye.ChannelId.ACTIVE_POWER_STRING_4, new UnsignedWordElement(675))), + new FC3ReadRegistersTask(667, Priority.LOW, // + m(PvInverterDeye.ChannelId.ACTIVE_POWER_GENERATOR, new UnsignedWordElement(667)))); } @Override From 87aa6879ad46f543647d7bc4fc78a211e66b69db Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Wed, 10 Apr 2024 08:40:12 +0200 Subject: [PATCH 10/25] Implement ESS for DEYE Inverter --- .../io/openems/edge/deye/common/Config.java | 4 +- .../edge/deye/common/DeyeSunHybridImpl.java | 120 +- .../deye/gridmeter/DeyeGridMeterImpl.java | 8 +- .../productionmeter/PvInverterDeyeImpl.java | 2 +- .../generated/buildfiles | 1 + io.openems.edge.io.gpio/generated/buildfiles | 1 + ui/src/app/shared/edge/edgeconfig.ts | 1267 +++++++++-------- 7 files changed, 650 insertions(+), 753 deletions(-) create mode 100644 io.openems.edge.evcs.spelsberg/generated/buildfiles create mode 100644 io.openems.edge.io.gpio/generated/buildfiles diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/Config.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/Config.java index 37f5edc8a08..8d1793036e2 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/Config.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/Config.java @@ -4,8 +4,8 @@ import org.osgi.service.metatype.annotations.ObjectClassDefinition; @ObjectClassDefinition(// - name = "Deye.Sun.Hybrid - MaMoTec", // - description = "Deye.Sun.Hybrid.") + name = "Deye.BatteryInverter", // + description = "Deye.BatteryInverter") @interface Config { @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java index 34c7a6376d4..e1dd2b9166d 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java @@ -64,7 +64,7 @@ @Designate(ocd = Config.class, factory = true) @Component(// - name = "Deye.Sun.Hybrid - MaMoTec", // + name = "Deye.BatteryInverter1", // immediate = true, // configurationPolicy = ConfigurationPolicy.REQUIRE // ) @@ -190,120 +190,15 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException { m(DeyeSunHybrid.ChannelId.SET_ACTIVE_POWER, new SignedWordElement(77)), m(DeyeSunHybrid.ChannelId.SET_REACTIVE_POWER, new SignedWordElement(78))), - new FC16WriteRegistersTask(99,new DummyRegisterElement(99, 101), - m(DeyeSunHybrid.ChannelId.BATTERY_CAPACITY, new SignedWordElement(102)), - new DummyRegisterElement(103), - m(DeyeSunHybrid.ChannelId.ZERO_EXPORT_POWER, new SignedWordElement(104))), - - new FC16WriteRegistersTask(108, - m(DeyeSunHybrid.ChannelId.MAX_A_BATTERY_CHARGE_CURRENT, new SignedWordElement(108)), - m(DeyeSunHybrid.ChannelId.MAX_A_BATTERY_DISCHARGE_CURRENT, new SignedWordElement(109)), - m(DeyeSunHybrid.ChannelId.PARALLEL_BAT_1_AND_BAT_2, new SignedWordElement(110))), - - new FC16WriteRegistersTask(115, - m(DeyeSunHybrid.ChannelId.BATTERY_CAPACITY_SHUTDOWN, new SignedWordElement(115)), - m(DeyeSunHybrid.ChannelId.BATTERY_CAPACITY_RESTART, new SignedWordElement(116)), - m(DeyeSunHybrid.ChannelId.BATTERY_CAPACITY_LOW_BATTERY, new SignedWordElement(117))), - - new FC16WriteRegistersTask(121, - m(DeyeSunHybrid.ChannelId.GEN_MAX_RUN_TIME, new SignedWordElement(121), SCALE_FACTOR_MINUS_1), - m(DeyeSunHybrid.ChannelId.GEN_COOLING_TIME, new SignedWordElement(122), SCALE_FACTOR_MINUS_1), - new DummyRegisterElement(123), - m(DeyeSunHybrid.ChannelId.GEN_CHARGING_STARTING_CAPACITY_POINT, new SignedWordElement(124)), - m(DeyeSunHybrid.ChannelId.GEN_CHARGING_CURRENT_TO_BATTERY, new SignedWordElement(125)), - new DummyRegisterElement(126), - m(DeyeSunHybrid.ChannelId.GRID_CHARGING_STARTING_CAPACITY_POINT, new SignedWordElement(127)), - m(DeyeSunHybrid.ChannelId.GRID_CHARGING_CURRENT_TO_BATTERY, new SignedWordElement(128)), - m(DeyeSunHybrid.ChannelId.GEN_CHARGE_ENABLED, new SignedWordElement(129)), - m(DeyeSunHybrid.ChannelId.GRID_CHARGE_ENABLED, new SignedWordElement(130)), - m(DeyeSunHybrid.ChannelId.AC_COUPLE_FREQUENCY_CAP, new SignedWordElement(131), SCALE_FACTOR_MINUS_2), - new DummyRegisterElement(132, 134), - m(DeyeSunHybrid.ChannelId.GEN_LOAD_OFF_POWER, new SignedWordElement(135)), - new DummyRegisterElement(136), - m(DeyeSunHybrid.ChannelId.GEN_LOAD_ON_POWER, new SignedWordElement(137)), - new DummyRegisterElement(138, 139), - m(DeyeSunHybrid.ChannelId.GEN_GRID_SIGNAL, new SignedWordElement(140))), - - new FC16WriteRegistersTask(145, - m(DeyeSunHybrid.ChannelId.SOLAR_SELL, new SignedWordElement(145))), - - new FC6WriteRegisterTask(146, - m(new BitsWordElement(146, this) // - .bit(0, DeyeSunHybrid.ChannelId.TIME_OF_USE_ENABLED_FLAG) // - .bit(1, DeyeSunHybrid.ChannelId.TIME_OF_USE_MONDAY) // - .bit(2, DeyeSunHybrid.ChannelId.TIME_OF_USE_TUESDAY) // - .bit(3, DeyeSunHybrid.ChannelId.TIME_OF_USE_WEDNESDAY) // - .bit(4, DeyeSunHybrid.ChannelId.TIME_OF_USE_THURSDAY) // - .bit(5, DeyeSunHybrid.ChannelId.TIME_OF_USE_FRIDAY) - .bit(6, DeyeSunHybrid.ChannelId.TIME_OF_USE_SATURDAY) - .bit(7, DeyeSunHybrid.ChannelId.TIME_OF_USE_SUNDAY) - )), - - new FC16WriteRegistersTask(148, - m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_1, new UnsignedWordElement(148)), - m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_2, new UnsignedWordElement(149)), - m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_3, new UnsignedWordElement(150)), - m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_4, new UnsignedWordElement(151)), - m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_5, new UnsignedWordElement(152)), - m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_6, new UnsignedWordElement(153)), - m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_1_POWER, new UnsignedWordElement(154), SCALE_FACTOR_1), - m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_2_POWER, new UnsignedWordElement(155), SCALE_FACTOR_1), - m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_3_POWER, new UnsignedWordElement(156), SCALE_FACTOR_1), - m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_4_POWER, new UnsignedWordElement(157), SCALE_FACTOR_1), - m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_5_POWER, new UnsignedWordElement(158), SCALE_FACTOR_1), - m(DeyeSunHybrid.ChannelId.SELL_MODE_TIME_POINT_6_POWER, new UnsignedWordElement(159), SCALE_FACTOR_1), - new DummyRegisterElement(160, 165), - m(DeyeSunHybrid.ChannelId.SELL_MODE_CAPACITY_1, new UnsignedWordElement(166)), - m(DeyeSunHybrid.ChannelId.SELL_MODE_CAPACITY_2, new UnsignedWordElement(167)), - m(DeyeSunHybrid.ChannelId.SELL_MODE_CAPACITY_3, new UnsignedWordElement(168)), - m(DeyeSunHybrid.ChannelId.SELL_MODE_CAPACITY_4, new UnsignedWordElement(169)), - m(DeyeSunHybrid.ChannelId.SELL_MODE_CAPACITY_5, new UnsignedWordElement(170)), - m(DeyeSunHybrid.ChannelId.SELL_MODE_CAPACITY_6, new UnsignedWordElement(171)), - m(DeyeSunHybrid.ChannelId.TIME_POINT_1_GRID_GEN_CHARGE_ENABLE, new UnsignedWordElement(172)), - m(DeyeSunHybrid.ChannelId.TIME_POINT_2_GRID_GEN_CHARGE_ENABLE, new UnsignedWordElement(173)), - m(DeyeSunHybrid.ChannelId.TIME_POINT_3_GRID_GEN_CHARGE_ENABLE, new UnsignedWordElement(174)), - m(DeyeSunHybrid.ChannelId.TIME_POINT_4_GRID_GEN_CHARGE_ENABLE, new UnsignedWordElement(175)), - m(DeyeSunHybrid.ChannelId.TIME_POINT_5_GRID_GEN_CHARGE_ENABLE, new UnsignedWordElement(176)), - m(DeyeSunHybrid.ChannelId.TIME_POINT_6_GRID_GEN_CHARGE_ENABLE, new UnsignedWordElement(177)), - m(DeyeSunHybrid.ChannelId.MICROINVERTER_EXPORT_TO_GRID_CUTOFF, new UnsignedWordElement(178)), - new DummyRegisterElement(179, 180), - m(DeyeSunHybrid.ChannelId.SOLAR_ARC_FAULT_ON, new SignedWordElement(181)) - ), - - new FC16WriteRegistersTask(189, - m(DeyeSunHybrid.ChannelId.GEN_CONNECTED_TO_GRID_INPUT, new UnsignedWordElement(189)) - // m(DeyeSunHybrid.ChannelId.GEN_PEAK_SHAVING_POWER, new UnsignedWordElement(190)), - // m(DeyeSunHybrid.ChannelId.GRID_PEAK_SHAVING_POWER, new UnsignedWordElement(191)) - ), - - new FC16WriteRegistersTask(190, - m(DeyeSunHybrid.ChannelId.SET_GEN_PEAK_SHAVING_POWER, new SignedWordElement(190)), - m(DeyeSunHybrid.ChannelId.SET_GRID_PEAK_SHAVING_POWER, new SignedWordElement(191))), - - new FC16WriteRegistersTask(209, - m(DeyeSunHybrid.ChannelId.UPS_BACKUP_DELAY_TIME, new UnsignedWordElement(209))), - - // new FC3ReadRegistersTask(214, Priority.LOW, - // m(SymmetricEss.ChannelId.SOC, new UnsignedWordElement(214))), - - new FC16WriteRegistersTask(214, - m(SymmetricEss.ChannelId.SOC, new SignedWordElement(214))), - - new FC16WriteRegistersTask(340, - m(DeyeSunHybrid.ChannelId.MAX_SOLAR_SELL_POWER, new UnsignedWordElement(340), SCALE_FACTOR_1)), - - new FC16WriteRegistersTask(347, - m(DeyeSunHybrid.ChannelId.CT_RATIO, new UnsignedWordElement(347))), + new FC3ReadRegistersTask(588, Priority.HIGH, + m(SymmetricEss.ChannelId.SOC, new UnsignedWordElement(588))), new FC3ReadRegistersTask(500, Priority.LOW, m(DeyeSunHybrid.ChannelId.INVERTER_RUN_STATE, new UnsignedWordElement(500))), - new FC3ReadRegistersTask(588, Priority.LOW, - m(DeyeSunHybrid.ChannelId.BAT_1_SOC, new UnsignedWordElement(588))), - new FC3ReadRegistersTask(607, Priority.LOW, - m(SymmetricEss.ChannelId.ACTIVE_POWER, new SignedWordElement(607)), - m(SymmetricEss.ChannelId.REACTIVE_POWER, new SignedWordElement(608))), + new FC3ReadRegistersTask(590, Priority.HIGH, + m(SymmetricEss.ChannelId.ACTIVE_POWER, new SignedWordElement(590))), new FC3ReadRegistersTask(620, Priority.LOW, // m(DeyeSunHybrid.ChannelId.APPARENT_POWER, new UnsignedWordElement(620))) @@ -385,8 +280,8 @@ public Constraint[] getStaticConstraints() throws OpenemsNamedException { // Reactive Power constraints return new Constraint[] { // - this.createPowerConstraint("Commercial40 Min Reactive Power", Phase.ALL, Pwr.REACTIVE, Relationship.GREATER_OR_EQUALS, MIN_REACTIVE_POWER), // - this.createPowerConstraint("Commercial40 Max Reactive Power", Phase.ALL, Pwr.REACTIVE, Relationship.LESS_OR_EQUALS, MAX_REACTIVE_POWER) }; + this.createPowerConstraint("Deye Min Reactive Power", Phase.ALL, Pwr.REACTIVE, Relationship.GREATER_OR_EQUALS, MIN_REACTIVE_POWER), // + this.createPowerConstraint("Deye Max Reactive Power", Phase.ALL, Pwr.REACTIVE, Relationship.LESS_OR_EQUALS, MAX_REACTIVE_POWER) }; } @Override @@ -464,6 +359,7 @@ private void calculateEnergy() { this.calculateAcChargeEnergy.update(acActivePower * -1); this.calculateAcDischargeEnergy.update(0); } + /* * Calculate DC Power and Energy */ diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java index 0bb4ee95ce6..eb833f780c5 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java @@ -77,8 +77,6 @@ public DeyeGridMeterImpl() throws OpenemsException { DeyeGridMeter.ChannelId.values() // ); - // Automatically calculate sum values from L1/L2/L3 - ElectricityMeter.calculateSumActivePowerFromPhases(this); } @Activate @@ -104,10 +102,8 @@ public MeterType getMeterType() { @Override protected ModbusProtocol defineModbusProtocol() throws OpenemsException { return new ModbusProtocol(this, - new FC3ReadRegistersTask(633, Priority.HIGH, - m(ElectricityMeter.ChannelId.ACTIVE_POWER_L1, new SignedWordElement(633)), - m(ElectricityMeter.ChannelId.ACTIVE_POWER_L2, new SignedWordElement(634)), - m(ElectricityMeter.ChannelId.ACTIVE_POWER_L3, new SignedWordElement(635)))); + new FC3ReadRegistersTask(625, Priority.HIGH, + m(ElectricityMeter.ChannelId.ACTIVE_POWER, new SignedWordElement(625)))); } @Override diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java index 62d584115a2..db079119552 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java @@ -38,7 +38,7 @@ @Designate(ocd = Config.class, factory = true) @Component(// - name = "PV-Inverter.Deye", // + name = "Deye.Production-Meter", // immediate = true, // configurationPolicy = ConfigurationPolicy.REQUIRE, // property = { // diff --git a/io.openems.edge.evcs.spelsberg/generated/buildfiles b/io.openems.edge.evcs.spelsberg/generated/buildfiles new file mode 100644 index 00000000000..ef95c181a81 --- /dev/null +++ b/io.openems.edge.evcs.spelsberg/generated/buildfiles @@ -0,0 +1 @@ +/Users/mvogt/IdeaProjects/openems/io.openems.edge.evcs.spelsberg/generated/io.openems.edge.evcs.spelsberg.jar diff --git a/io.openems.edge.io.gpio/generated/buildfiles b/io.openems.edge.io.gpio/generated/buildfiles new file mode 100644 index 00000000000..d19112c47b3 --- /dev/null +++ b/io.openems.edge.io.gpio/generated/buildfiles @@ -0,0 +1 @@ +/Users/mvogt/IdeaProjects/openems/io.openems.edge.io.gpio/generated/io.openems.edge.io.gpio.jar diff --git a/ui/src/app/shared/edge/edgeconfig.ts b/ui/src/app/shared/edge/edgeconfig.ts index 67084f8d382..7aac0b2e08e 100644 --- a/ui/src/app/shared/edge/edgeconfig.ts +++ b/ui/src/app/shared/edge/edgeconfig.ts @@ -1,625 +1,626 @@ -import { ChannelAddress } from '../type/channeladdress'; -import { Widgets } from '../type/widget'; -import { Edge } from './edge'; +import {ChannelAddress} from '../type/channeladdress'; +import {Widgets} from '../type/widget'; +import {Edge} from './edge'; export interface CategorizedComponents { - category: { - title: string, - icon: string - }, - components: EdgeConfig.Component[] + category: { + title: string, + icon: string + }, + components: EdgeConfig.Component[] } export interface CategorizedFactories { - category: { - title: string, - icon: string - }, - factories: EdgeConfig.Factory[] + category: { + title: string, + icon: string + }, + factories: EdgeConfig.Factory[] } export class EdgeConfig { - constructor(edge: Edge, source?: EdgeConfig) { - if (source) { - this.components = source.components; - this.factories = source.factories; - } + constructor(edge: Edge, source?: EdgeConfig) { + if (source) { + this.components = source.components; + this.factories = source.factories; + } - // initialize Components - for (const componentId in this.components) { - const component = this.components[componentId]; - component.id = componentId; - if ('enabled' in component.properties) { - component.isEnabled = component.properties['enabled']; - } else { - component.isEnabled = true; - } - } + // initialize Components + for (const componentId in this.components) { + const component = this.components[componentId]; + component.id = componentId; + if ('enabled' in component.properties) { + component.isEnabled = component.properties['enabled']; + } else { + component.isEnabled = true; + } + } - // initialize Factorys - for (const factoryId in this.factories) { - const factory = this.factories[factoryId]; - factory.id = factoryId; - factory.componentIds = []; - - // Fill 'natures' map - for (const natureId of factory.natureIds) { - if (!(natureId in this.natures)) { - const parts = natureId.split("."); - const name = parts[parts.length - 1]; - this.natures[natureId] = { - id: natureId, - name: name, - factoryIds: [], - }; - } - this.natures[natureId].factoryIds.push(factoryId); - } + // initialize Factorys + for (const factoryId in this.factories) { + const factory = this.factories[factoryId]; + factory.id = factoryId; + factory.componentIds = []; + + // Fill 'natures' map + for (const natureId of factory.natureIds) { + if (!(natureId in this.natures)) { + const parts = natureId.split("."); + const name = parts[parts.length - 1]; + this.natures[natureId] = { + id: natureId, + name: name, + factoryIds: [], + }; } + this.natures[natureId].factoryIds.push(factoryId); + } + } - if (Object.keys(this.components).length != 0 && Object.keys(this.factories).length == 0) { - console.warn("Factory definitions are missing."); - } else { - for (const componentId in this.components) { - const component = this.components[componentId]; - if (component.factoryId === "") { - continue; // Singleton components have no factory-PID - } - const factory = this.factories[component.factoryId]; - if (!factory) { - console.warn("Factory definition [" + component.factoryId + "] for [" + componentId + "] is missing."); - continue; - } - - // Complete 'factories' map - factory.componentIds.push(componentId); - } + if (Object.keys(this.components).length != 0 && Object.keys(this.factories).length == 0) { + console.warn("Factory definitions are missing."); + } else { + for (const componentId in this.components) { + const component = this.components[componentId]; + if (component.factoryId === "") { + continue; // Singleton components have no factory-PID + } + const factory = this.factories[component.factoryId]; + if (!factory) { + console.warn("Factory definition [" + component.factoryId + "] for [" + componentId + "] is missing."); + continue; } - // Initialize Widgets - this.widgets = Widgets.parseWidgets(edge, this); + // Complete 'factories' map + factory.componentIds.push(componentId); + } } - /** - * Component-ID -> Component. - */ - public readonly components: { [id: string]: EdgeConfig.Component } = {}; - - /** - * Factory-PID -> OSGi Factory. - */ - public readonly factories: { [id: string]: EdgeConfig.Factory } = {}; - - /** - * Nature-PID -> Component-IDs. - */ - public readonly natures: { [id: string]: EdgeConfig.Nature } = {}; - - /** - * UI-Widgets. - */ - public readonly widgets: Widgets; - - public isValid(): boolean { - return Object.keys(this.components).length > 0 && Object.keys(this.factories).length > 0; + // Initialize Widgets + this.widgets = Widgets.parseWidgets(edge, this); + } + + /** + * Component-ID -> Component. + */ + public readonly components: { [id: string]: EdgeConfig.Component } = {}; + + /** + * Factory-PID -> OSGi Factory. + */ + public readonly factories: { [id: string]: EdgeConfig.Factory } = {}; + + /** + * Nature-PID -> Component-IDs. + */ + public readonly natures: { [id: string]: EdgeConfig.Nature } = {}; + + /** + * UI-Widgets. + */ + public readonly widgets: Widgets; + + public isValid(): boolean { + return Object.keys(this.components).length > 0 && Object.keys(this.factories).length > 0; + } + + /** + * Get Component-IDs of Component instances by the given Factory. + * + * @param factoryId the Factory PID. + */ + public getComponentIdsByFactory(factoryId: string): string[] { + const factory = this.factories[factoryId]; + if (factory) { + return factory.componentIds; + } else { + return []; } - - /** - * Get Component-IDs of Component instances by the given Factory. - * - * @param factoryId the Factory PID. - */ - public getComponentIdsByFactory(factoryId: string): string[] { - const factory = this.factories[factoryId]; - if (factory) { - return factory.componentIds; - } else { - return []; + } + + /** + * Get Factories of Nature. + * + * @param natureId the given Nature. + */ + public getFactoriesByNature(natureId: string): EdgeConfig.Factory[] { + const result = []; + const nature = this.natures[natureId]; + if (nature) { + for (const factoryId of nature.factoryIds) { + if (factoryId in this.factories) { + result.push(this.factories[factoryId]); } + } } - - /** - * Get Factories of Nature. - * - * @param natureId the given Nature. - */ - public getFactoriesByNature(natureId: string): EdgeConfig.Factory[] { - const result = []; - const nature = this.natures[natureId]; - if (nature) { - for (const factoryId of nature.factoryIds) { - if (factoryId in this.factories) { - result.push(this.factories[factoryId]); - } - } - } - return result; + return result; + } + + /** + * Get Factories by Factory-IDs. + * + * @param ids the given Factory-IDs. + */ + public getFactoriesByIds(factoryIds: string[]): EdgeConfig.Factory[] { + const result = []; + for (const factoryId of factoryIds) { + if (factoryId in this.factories) { + result.push(this.factories[factoryId]); + } } - - /** - * Get Factories by Factory-IDs. - * - * @param ids the given Factory-IDs. - */ - public getFactoriesByIds(factoryIds: string[]): EdgeConfig.Factory[] { - const result = []; - for (const factoryId of factoryIds) { - if (factoryId in this.factories) { - result.push(this.factories[factoryId]); - } + return result; + } + + /** + * Get Factories by Factory-IDs pattern. + * + * @param ids the given Factory-IDs pattern. + */ + public getFactoriesByIdsPattern(patterns: RegExp[]): EdgeConfig.Factory[] { + const result = []; + for (const pattern of patterns) { + for (const factoryId in this.factories) { + if (pattern.test(factoryId)) { + result.push(this.factories[factoryId]); } - return result; + } } - - /** - * Get Factories by Factory-IDs pattern. - * - * @param ids the given Factory-IDs pattern. - */ - public getFactoriesByIdsPattern(patterns: RegExp[]): EdgeConfig.Factory[] { - const result = []; - for (const pattern of patterns) { - for (const factoryId in this.factories) { - if (pattern.test(factoryId)) { - result.push(this.factories[factoryId]); - } - } - } - return result; + return result; + } + + /** + * Get Component instances by the given Factory. + * + * @param factoryId the Factory PID. + */ + public getComponentsByFactory(factoryId: string): EdgeConfig.Component[] { + const componentIds = this.getComponentIdsByFactory(factoryId); + const result: EdgeConfig.Component[] = []; + for (const componentId of componentIds) { + result.push(this.components[componentId]); } - - /** - * Get Component instances by the given Factory. - * - * @param factoryId the Factory PID. - */ - public getComponentsByFactory(factoryId: string): EdgeConfig.Component[] { - const componentIds = this.getComponentIdsByFactory(factoryId); - const result: EdgeConfig.Component[] = []; - for (const componentId of componentIds) { - result.push(this.components[componentId]); - } - return result; + return result; + } + + /** + * Get Component-IDs of Components that implement the given Nature. + * + * @param nature the given Nature. + */ + public getComponentIdsImplementingNature(natureId: string): string[] { + const result: string[] = []; + const nature = this.natures[natureId]; + if (nature) { + for (const factoryId of nature.factoryIds) { + result.push(... this.getComponentIdsByFactory(factoryId)); + } } - /** - * Get Component-IDs of Components that implement the given Nature. - * - * @param nature the given Nature. - */ - public getComponentIdsImplementingNature(natureId: string): string[] { - const result: string[] = []; - const nature = this.natures[natureId]; - if (nature) { - for (const factoryId of nature.factoryIds) { - result.push(...this.getComponentIdsByFactory(factoryId)); - } - } - - // Backwards compatibilty - // TODO drop after full migration to ElectricityMeter - switch (natureId) { - // ElectricityMeter replaces SymmetricMeter (and AsymmetricMeter implicitely) - case "io.openems.edge.meter.api.ElectricityMeter": - result.push(...this.getComponentIdsImplementingNature("io.openems.edge.meter.api.SymmetricMeter")); - } - - return result; + // Backwards compatibilty + // TODO drop after full migration to ElectricityMeter + switch (natureId) { + // ElectricityMeter replaces SymmetricMeter (and AsymmetricMeter implicitely) + case "io.openems.edge.meter.api.ElectricityMeter": + result.push(...this.getComponentIdsImplementingNature("io.openems.edge.meter.api.SymmetricMeter")); } - /** - * Get Components that implement the given Nature. - * - * @param nature the given Nature. - */ - public getComponentsImplementingNature(natureId: string): EdgeConfig.Component[] { - const result: EdgeConfig.Component[] = []; - const nature = this.natures[natureId]; - if (nature) { - for (const factoryId of nature.factoryIds) { - result.push(...this.getComponentsByFactory(factoryId)); - } - } - - // Backwards compatibilty - // TODO drop after full migration to ElectricityMeter - switch (natureId) { - // ElectricityMeter replaces SymmetricMeter (and AsymmetricMeter implicitely) - case "io.openems.edge.meter.api.ElectricityMeter": - result.push(...this.getComponentsImplementingNature("io.openems.edge.meter.api.SymmetricMeter")); - } - - return result; + return result; + } + + /** + * Get Components that implement the given Nature. + * + * @param nature the given Nature. + */ + public getComponentsImplementingNature(natureId: string): EdgeConfig.Component[] { + const result: EdgeConfig.Component[] = []; + const nature = this.natures[natureId]; + if (nature) { + for (const factoryId of nature.factoryIds) { + result.push(... this.getComponentsByFactory(factoryId)); + } } - /** - * Get the implemented NatureIds by Factory-ID. - * - * @param factoryId the Factory-ID - */ - public getNatureIdsByFactoryId(factoryId: string): string[] { - const factory = this.factories[factoryId]; - if (factory) { - return factory.natureIds; - } else { - return []; - } + // Backwards compatibilty + // TODO drop after full migration to ElectricityMeter + switch (natureId) { + // ElectricityMeter replaces SymmetricMeter (and AsymmetricMeter implicitely) + case "io.openems.edge.meter.api.ElectricityMeter": + result.push(...this.getComponentsImplementingNature("io.openems.edge.meter.api.SymmetricMeter")); } - /** - * Determines if Edge has a Storage device - */ - public hasStorage(): boolean { - if (this.getComponentIdsImplementingNature('io.openems.edge.ess.api.SymmetricEss').length > 0) { - return true; - } else { - return false; - } + return result; + } + + /** + * Get the implemented NatureIds by Factory-ID. + * + * @param factoryId the Factory-ID + */ + public getNatureIdsByFactoryId(factoryId: string): string[] { + const factory = this.factories[factoryId]; + if (factory) { + return factory.natureIds; + } else { + return []; } - - /** - * Determines if Edge has a Meter device - */ - public hasMeter(): boolean { - if (this.getComponentIdsImplementingNature('io.openems.edge.meter.api.ElectricityMeter').length > 0) { - return true; - } else { - return false; - } + } + + /** + * Determines if Edge has a Storage device + */ + public hasStorage(): boolean { + if (this.getComponentIdsImplementingNature('io.openems.edge.ess.api.SymmetricEss').length > 0) { + return true; + } else { + return false; } - - /** - * Determines if Edge has a producing device - */ - public hasProducer(): boolean { - // Do we have a Ess DC Charger? - if (this.getComponentsImplementingNature('io.openems.edge.ess.dccharger.api.EssDcCharger').length > 0) { - return true; - } - // Do we have a Meter with type PRODUCTION? - for (const component of this.getComponentsImplementingNature("io.openems.edge.meter.api.ElectricityMeter")) { - if (component.isEnabled && this.isProducer(component)) { - return true; - } - } - return false; + } + + /** + * Determines if Edge has a Meter device + */ + public hasMeter(): boolean { + if (this.getComponentIdsImplementingNature('io.openems.edge.meter.api.ElectricityMeter').length > 0) { + return true; + } else { + return false; } - - /** - * Is the given Meter of type 'PRODUCTION'? - * - * @param component the Meter Component - * @returns true for PRODUCTION - */ - public isProducer(component: EdgeConfig.Component) { - if (component.properties['type'] == "PRODUCTION") { - return true; - } - // TODO properties in OSGi Component annotations are not transmitted correctly with Apache Felix SCR - switch (component.factoryId) { - case 'Fenecon.Dess.PvMeter': - case 'Fenecon.Mini.PvMeter': - case 'Fenecon.Pro.PvMeter': - case 'Kaco.BlueplanetHybrid10.PvInverter': - case 'Kostal.Piko.Charger': - case 'PV-Inverter.Fronius': - case 'PV-Inverter.KACO.blueplanet': - case 'PV-Inverter.Kostal': - case 'PV-Inverter.SMA.SunnyTripower': - case 'PV-Inverter.Solarlog': - case 'PV-Inverter.SunSpec': - case 'Simulator.ProductionMeter.Acting': - case 'Simulator.PvInverter': - case 'SolarEdge.PV-Inverter': - return true; - } - - return false; + } + + /** + * Determines if Edge has a producing device + */ + public hasProducer(): boolean { + // Do we have a Ess DC Charger? + if (this.getComponentsImplementingNature('io.openems.edge.ess.dccharger.api.EssDcCharger').length > 0) { + return true; } - - /** - * Is the given Meter of type 'CONSUMPTION_METERED'? - * - * @param component the Meter Component - * @returns true for CONSUMPTION_METERED - */ - public isTypeConsumptionMetered(component: EdgeConfig.Component) { - if (component.properties['type'] == "CONSUMPTION_METERED") { - return true; - } else { - switch (component.factoryId) { - case 'GoodWe.EmergencyPowerMeter': - return true; - } - } - return false; + // Do we have a Meter with type PRODUCTION? + for (const component of this.getComponentsImplementingNature("io.openems.edge.meter.api.ElectricityMeter")) { + if (component.isEnabled && this.isProducer(component)) { + return true; + } } - - /** - * Is the given Meter of type 'GRID'? - * - * @param component the Meter Component - * @returns true for GRID - */ - public isTypeGrid(component: EdgeConfig.Component) { - if (component.properties["type"] == "GRID") { - return true; - } - - switch (component.factoryId) { - case 'GoodWe.Grid-Meter': - case 'Kaco.BlueplanetHybrid10.GridMeter': - case 'Fenecon.Dess.GridMeter': - case 'Fenecon.Mini.GridMeter': - case 'Kostal.Piko.GridMeter': - case 'SolarEdge.Grid-Meter': - case 'Simulator.GridMeter.Acting': - case 'Simulator.GridMeter.Reacting': - return true; - } - return false; + return false; + } + + /** + * Is the given Meter of type 'PRODUCTION'? + * + * @param component the Meter Component + * @returns true for PRODUCTION + */ + public isProducer(component: EdgeConfig.Component) { + if (component.properties['type'] == "PRODUCTION") { + return true; } - - /** - * Lists all available Factories, grouped by category. - */ - public listAvailableFactories(): CategorizedFactories[] { - const allFactories = [ - { - category: { title: 'Simulatoren', icon: 'flask-outline' }, - factories: Object.values(this.factories).filter(factory => factory.id.startsWith('Simulator.')), - }, - { - category: { title: 'Zähler', icon: 'speedometer-outline' }, - factories: [ - this.getFactoriesByNature("io.openems.edge.meter.api.SymmetricMeter"), // TODO replaced by ElectricityMeter - this.getFactoriesByNature("io.openems.edge.meter.api.ElectricityMeter"), - this.getFactoriesByNature("io.openems.edge.ess.dccharger.api.EssDcCharger"), - ], - }, - { - category: { title: 'Speichersysteme', icon: 'battery-charging-outline' }, - factories: [ - this.getFactoriesByNature("io.openems.edge.ess.api.SymmetricEss"), - this.getFactoriesByNature("io.openems.edge.battery.api.Battery"), - this.getFactoriesByNature("io.openems.edge.batteryinverter.api.ManagedSymmetricBatteryInverter"), - ], - }, - { - category: { title: 'Speichersystem-Steuerung', icon: 'options-outline' }, - factories: [ - this.getFactoriesByIdsPattern([ - /Controller\.Asymmetric.*/, - /Controller\.Ess.*/, - /Controller\.Symmetric.*/, - ]), - ], - }, - { - category: { title: 'E-Auto-Ladestation', icon: 'car-outline' }, - factories: [ - this.getFactoriesByNature("io.openems.edge.evcs.api.Evcs"), - ], - }, - { - category: { title: 'E-Auto-Ladestation-Steuerung', icon: 'options-outline' }, - factories: [ - this.getFactoriesByIds([ - 'Controller.Evcs', - ]), - ], - }, - { - category: { title: 'I/Os', icon: 'log-in-outline' }, - factories: [ - this.getFactoriesByNature("io.openems.edge.io.api.DigitalOutput"), - this.getFactoriesByNature("io.openems.edge.io.api.DigitalInput"), - ], - }, - { - category: { title: 'I/O-Steuerung', icon: 'options-outline' }, - factories: [ - this.getFactoriesByIds([ - 'Controller.IO.ChannelSingleThreshold', - 'Controller.Io.FixDigitalOutput', - 'Controller.IO.HeatingElement', - 'Controller.Io.HeatPump.SgReady', - ]), - ], - }, - { - category: { title: 'Temperatursensoren', icon: 'thermometer-outline' }, - factories: [ - this.getFactoriesByNature("io.openems.edge.thermometer.api.Thermometer"), - ], - }, - { - category: { title: 'Externe Schnittstellen', icon: 'megaphone-outline' }, - factories: [ - this.getFactoriesByIds([ - 'Controller.Api.Websocket', - 'Controller.Api.ModbusTcp', - 'Controller.Api.ModbusTcp.ReadOnly', - 'Controller.Api.ModbusTcp.ReadWrite', - 'Controller.Api.MQTT', - 'Controller.Api.Rest.ReadOnly', - 'Controller.Api.Rest.ReadWrite', - ]), - ], - }, - { - category: { title: 'Cloud-Schnittstellen', icon: 'cloud-outline' }, - factories: [ - this.getFactoriesByIdsPattern([ - /TimeOfUseTariff\.*/, - ]), - this.getFactoriesByIds([ - 'Controller.Api.Backend', - ]), - ], - }, - { - category: { title: 'Geräte-Schnittstellen', icon: 'swap-horizontal-outline' }, - factories: [ - this.getFactoriesByIds([ - 'Bridge.Mbus', - 'Bridge.Onewire', - 'Bridge.Modbus.Serial', - 'Bridge.Modbus.Tcp', - 'Kaco.BlueplanetHybrid10.Core', - ]), - ], - }, - { - category: { title: 'Standard-Komponenten', icon: 'resize-outline' }, - factories: [ - this.getFactoriesByIds([ - 'Controller.Debug.Log', - 'Controller.Debug.DetailedLog', - ]), - this.getFactoriesByNature("io.openems.edge.timedata.api.Timedata"), - this.getFactoriesByNature("io.openems.edge.predictor.api.oneday.Predictor24Hours"), - this.getFactoriesByNature("io.openems.edge.scheduler.api.Scheduler"), - ], - }, - { - category: { title: 'Spezial-Controller', icon: 'repeat-outline' }, - factories: [ - this.getFactoriesByNature("io.openems.edge.controller.api.Controller"), - ], - }, - { - category: { title: 'Weitere', icon: 'radio-button-off-outline' }, - factories: Object.values(this.factories), - }, - ]; - - const ignoreFactoryIds: string[] = []; - const result: CategorizedFactories[] = []; - allFactories.forEach(item => { - const factories = - // create one flat array - [].concat(...item.factories) - // remove Factories from list that have already been listed before - .filter(factory => !ignoreFactoryIds.includes(factory.id)) - // remove duplicates - .filter((e, i, arr) => arr.indexOf(e) === i); - if (factories.length > 0) { - factories.forEach(factory => { - ignoreFactoryIds.push(factory.id); - }); - result.push({ category: item.category, factories: factories.sort((a, b) => a.id.localeCompare(b.id)) }); - } - }); - return result; + // TODO properties in OSGi Component annotations are not transmitted correctly with Apache Felix SCR + switch (component.factoryId) { + case 'Fenecon.Dess.PvMeter': + case 'Fenecon.Mini.PvMeter': + case 'Fenecon.Pro.PvMeter': + case 'Kaco.BlueplanetHybrid10.PvInverter': + case 'Kostal.Piko.Charger': + case 'PV-Inverter.Fronius': + case 'PV-Inverter.KACO.blueplanet': + case 'PV-Inverter.Kostal': + case 'PV-Inverter.SMA.SunnyTripower': + case 'PV-Inverter.Solarlog': + case 'PV-Inverter.SunSpec': + case 'Simulator.ProductionMeter.Acting': + case 'Simulator.PvInverter': + case 'SolarEdge.PV-Inverter': + case 'Deye.Production-Meter': + return true; } - /** - * Returns the corresponding icon for a given factory - */ - public getFactoryIcon(factory: EdgeConfig.Factory): string { - // default icon, if no icons are found - let result = "stats-chart-outline"; - this.listAvailableFactories().forEach(availableFactories => { - availableFactories.factories.forEach(availableFactory => { - if (factory == availableFactory) { - result = availableFactories.category.icon; - } - }); - }); - return result; + return false; + } + + /** + * Is the given Meter of type 'CONSUMPTION_METERED'? + * + * @param component the Meter Component + * @returns true for CONSUMPTION_METERED + */ + public isTypeConsumptionMetered(component: EdgeConfig.Component) { + if (component.properties['type'] == "CONSUMPTION_METERED") { + return true; + } else { + switch (component.factoryId) { + case 'GoodWe.EmergencyPowerMeter': + return true; + } } - - /** - * Lists all active Components, grouped by category. - */ - public listActiveComponents(ignoreComponentIds: string[]): CategorizedComponents[] { - const allComponents = []; - const factories = this.listAvailableFactories(); - for (const entry of factories) { - const components = []; - for (const factory of entry.factories) { - components.push(this.getComponentsByFactory(factory.id)); - // components.concat(...this.getComponentsByFactory(factory.id)); - } - allComponents.push({ - category: entry.category, - components: components, - }); - } - const result: CategorizedComponents[] = []; - allComponents.forEach(item => { - const components = - // create one flat array - [].concat(...item.components) - // remove Components from list that have already been listed before - .filter(component => !ignoreComponentIds.includes(component.id)) - // remove duplicates - .filter((e, i, arr) => arr.indexOf(e) === i) - // sort by ID - .sort((c1, c2) => c1.id.localeCompare(c2.id)); - if (components.length > 0) { - components.forEach(component => { - ignoreComponentIds.push(component.id); - }); - result.push({ category: item.category, components: components }); - } - }); - return result; + return false; + } + + /** + * Is the given Meter of type 'GRID'? + * + * @param component the Meter Component + * @returns true for GRID + */ + public isTypeGrid(component: EdgeConfig.Component) { + if (component.properties["type"] == "GRID") { + return true; } - - /** - * Get the implemented Natures by Component-ID. - * - * @param componentId the Component-ID - */ - public getNatureIdsByComponentId(componentId: string): string[] { - const component = this.components[componentId]; - if (!component) { - return []; + switch (component.factoryId) { + case 'GoodWe.Grid-Meter': + case 'Kaco.BlueplanetHybrid10.GridMeter': + case 'Fenecon.Dess.GridMeter': + case 'Fenecon.Mini.GridMeter': + case 'Kostal.Piko.GridMeter': + case 'SolarEdge.Grid-Meter': + case 'Simulator.GridMeter.Acting': + case 'Simulator.GridMeter.Reacting': + return true; + } + return false; + } + + /** + * Lists all available Factories, grouped by category. + */ + public listAvailableFactories(): CategorizedFactories[] { + const allFactories = [ + { + category: {title: 'Simulatoren', icon: 'flask-outline'}, + factories: Object.values(this.factories).filter(factory => factory.id.startsWith('Simulator.')), + }, + { + category: {title: 'Zähler', icon: 'speedometer-outline'}, + factories: [ + this.getFactoriesByNature("io.openems.edge.meter.api.SymmetricMeter"), // TODO replaced by ElectricityMeter + this.getFactoriesByNature("io.openems.edge.meter.api.ElectricityMeter"), + this.getFactoriesByNature("io.openems.edge.ess.dccharger.api.EssDcCharger"), + ], + }, + { + category: {title: 'Speichersysteme', icon: 'battery-charging-outline'}, + factories: [ + this.getFactoriesByNature("io.openems.edge.ess.api.SymmetricEss"), + this.getFactoriesByNature("io.openems.edge.battery.api.Battery"), + this.getFactoriesByNature("io.openems.edge.batteryinverter.api.ManagedSymmetricBatteryInverter"), + ], + }, + { + category: {title: 'Speichersystem-Steuerung', icon: 'options-outline'}, + factories: [ + this.getFactoriesByIdsPattern([ + /Controller\.Asymmetric.*/, + /Controller\.Ess.*/, + /Controller\.Symmetric.*/, + ]), + ], + }, + { + category: {title: 'E-Auto-Ladestation', icon: 'car-outline'}, + factories: [ + this.getFactoriesByNature("io.openems.edge.evcs.api.Evcs"), + ], + }, + { + category: {title: 'E-Auto-Ladestation-Steuerung', icon: 'options-outline'}, + factories: [ + this.getFactoriesByIds([ + 'Controller.Evcs', + ]), + ], + }, + { + category: {title: 'I/Os', icon: 'log-in-outline'}, + factories: [ + this.getFactoriesByNature("io.openems.edge.io.api.DigitalOutput"), + this.getFactoriesByNature("io.openems.edge.io.api.DigitalInput"), + ], + }, + { + category: {title: 'I/O-Steuerung', icon: 'options-outline'}, + factories: [ + this.getFactoriesByIds([ + 'Controller.IO.ChannelSingleThreshold', + 'Controller.Io.FixDigitalOutput', + 'Controller.IO.HeatingElement', + 'Controller.Io.HeatPump.SgReady', + ]), + ], + }, + { + category: {title: 'Temperatursensoren', icon: 'thermometer-outline'}, + factories: [ + this.getFactoriesByNature("io.openems.edge.thermometer.api.Thermometer"), + ], + }, + { + category: {title: 'Externe Schnittstellen', icon: 'megaphone-outline'}, + factories: [ + this.getFactoriesByIds([ + 'Controller.Api.Websocket', + 'Controller.Api.ModbusTcp', + 'Controller.Api.ModbusTcp.ReadOnly', + 'Controller.Api.ModbusTcp.ReadWrite', + 'Controller.Api.MQTT', + 'Controller.Api.Rest.ReadOnly', + 'Controller.Api.Rest.ReadWrite', + ]), + ], + }, + { + category: {title: 'Cloud-Schnittstellen', icon: 'cloud-outline'}, + factories: [ + this.getFactoriesByIdsPattern([ + /TimeOfUseTariff\.*/, + ]), + this.getFactoriesByIds([ + 'Controller.Api.Backend', + ]), + ], + }, + { + category: {title: 'Geräte-Schnittstellen', icon: 'swap-horizontal-outline'}, + factories: [ + this.getFactoriesByIds([ + 'Bridge.Mbus', + 'Bridge.Onewire', + 'Bridge.Modbus.Serial', + 'Bridge.Modbus.Tcp', + 'Kaco.BlueplanetHybrid10.Core', + ]), + ], + }, + { + category: {title: 'Standard-Komponenten', icon: 'resize-outline'}, + factories: [ + this.getFactoriesByIds([ + 'Controller.Debug.Log', + 'Controller.Debug.DetailedLog', + ]), + this.getFactoriesByNature("io.openems.edge.timedata.api.Timedata"), + this.getFactoriesByNature("io.openems.edge.predictor.api.oneday.Predictor24Hours"), + this.getFactoriesByNature("io.openems.edge.scheduler.api.Scheduler"), + ], + }, + { + category: {title: 'Spezial-Controller', icon: 'repeat-outline'}, + factories: [ + this.getFactoriesByNature("io.openems.edge.controller.api.Controller"), + ], + }, + { + category: {title: 'Weitere', icon: 'radio-button-off-outline'}, + factories: Object.values(this.factories), + }, + ]; + + const ignoreFactoryIds: string[] = []; + const result: CategorizedFactories[] = []; + allFactories.forEach(item => { + const factories = + // create one flat array + [].concat(...item.factories) + // remove Factories from list that have already been listed before + .filter(factory => !ignoreFactoryIds.includes(factory.id)) + // remove duplicates + .filter((e, i, arr) => arr.indexOf(e) === i); + if (factories.length > 0) { + factories.forEach(factory => { + ignoreFactoryIds.push(factory.id); + }); + result.push({category: item.category, factories: factories.sort((a, b) => a.id.localeCompare(b.id))}); + } + }); + return result; + } + + /** + * Returns the corresponding icon for a given factory + */ + public getFactoryIcon(factory: EdgeConfig.Factory): string { + // default icon, if no icons are found + let result = "stats-chart-outline"; + this.listAvailableFactories().forEach(availableFactories => { + availableFactories.factories.forEach(availableFactory => { + if (factory == availableFactory) { + result = availableFactories.category.icon; } - const factoryId = component.factoryId; - return this.getNatureIdsByFactoryId(factoryId); + }); + }); + return result; + } + + /** + * Lists all active Components, grouped by category. + */ + public listActiveComponents(ignoreComponentIds: string[]): CategorizedComponents[] { + const allComponents = []; + const factories = this.listAvailableFactories(); + for (const entry of factories) { + const components = []; + for (const factory of entry.factories) { + components.push(this.getComponentsByFactory(factory.id)); + // components.concat(...this.getComponentsByFactory(factory.id)); + } + allComponents.push({ + category: entry.category, + components: components, + }); } - - /** - * Get the Component. - * - * @param componentId the Component-ID - */ - public getComponent(componentId: string): EdgeConfig.Component { - return this.components[componentId]; + const result: CategorizedComponents[] = []; + allComponents.forEach(item => { + const components = + // create one flat array + [].concat(...item.components) + // remove Components from list that have already been listed before + .filter(component => !ignoreComponentIds.includes(component.id)) + // remove duplicates + .filter((e, i, arr) => arr.indexOf(e) === i) + // sort by ID + .sort((c1, c2) => c1.id.localeCompare(c2.id)); + if (components.length > 0) { + components.forEach(component => { + ignoreComponentIds.push(component.id); + }); + result.push({category: item.category, components: components}); + } + }); + return result; + } + + + /** + * Get the implemented Natures by Component-ID. + * + * @param componentId the Component-ID + */ + public getNatureIdsByComponentId(componentId: string): string[] { + const component = this.components[componentId]; + if (!component) { + return []; } - - /** - * Get the Component properties. - * - * @param componentId the Component-ID - */ - public getComponentProperties(componentId: string): { [key: string]: any } { - const component = this.components[componentId]; - if (component) { - return component.properties; - } else { - return {}; - } + const factoryId = component.factoryId; + return this.getNatureIdsByFactoryId(factoryId); + } + + /** + * Get the Component. + * + * @param componentId the Component-ID + */ + public getComponent(componentId: string): EdgeConfig.Component { + return this.components[componentId]; + } + + /** + * Get the Component properties. + * + * @param componentId the Component-ID + */ + public getComponentProperties(componentId: string): { [key: string]: any } { + const component = this.components[componentId]; + if (component) { + return component.properties; + } else { + return {}; } - - /** - * Get Channel. - * - * @param address the ChannelAddress - */ - public getChannel(address: ChannelAddress): EdgeConfig.ComponentChannel { - const component = this.components[address.componentId]; - if (component) { - return component.channels[address.channelId]; - } else { - return null; - } + } + + /** + * Get Channel. + * + * @param address the ChannelAddress + */ + public getChannel(address: ChannelAddress): EdgeConfig.ComponentChannel { + const component = this.components[address.componentId]; + if (component) { + return component.channels[address.channelId]; + } else { + return null; } + } } export enum PersistencePriority { @@ -644,65 +645,67 @@ export namespace PersistencePriority { } export module EdgeConfig { - export class ComponentChannel { - public readonly type: "BOOLEAN" | "SHORT" | "INTEGER" | "LONG" | "FLOAT" | "DOUBLE" | "STRING"; - public readonly accessMode: "RO" | "RW" | "WO"; - public readonly unit: string; - public readonly category: "OPENEMS_TYPE" | "ENUM" | "STATE"; - public readonly level: "INFO" | "OK" | "WARNING" | "FAULT"; - public readonly persistencePriority: PersistencePriority; - } - - export class Component { - public id: string = ""; - public alias: string = ""; - public isEnabled: boolean = false; - - constructor( - public readonly factoryId: string = "", - public readonly properties: { [key: string]: any } = {}, - public readonly channels: { [channelId: string]: ComponentChannel } = {}, - ) { } - } - - export class FactoryProperty { - public readonly id: string; - public readonly name: string; - public readonly description: string; - public readonly isRequired: boolean; - public readonly defaultValue: any; - public readonly schema: {}; - } - - export class Factory { - public id: string = ""; - public componentIds: string[] = []; - - constructor( - public readonly name: string, - public readonly description: string, - public readonly natureIds: string[] = [], - public readonly properties: FactoryProperty[] = [], - ) { } - - /** - * Gets the FactoryProperty definition for a Property-ID. - * - * @param propertyId the Property-ID - */ - static getPropertyForId(factory: Factory, propertyId: string): FactoryProperty { - for (const property of factory.properties) { - if (property.id === propertyId) { - return property; - } - } - return null; - } + export class ComponentChannel { + public readonly type: "BOOLEAN" | "SHORT" | "INTEGER" | "LONG" | "FLOAT" | "DOUBLE" | "STRING"; + public readonly accessMode: "RO" | "RW" | "WO"; + public readonly unit: string; + public readonly category: "OPENEMS_TYPE" | "ENUM" | "STATE"; + public readonly level: "INFO" | "OK" | "WARNING" | "FAULT"; + public readonly persistencePriority: PersistencePriority; } - export class Nature { - public id: string = ""; - public name: string = ""; - public factoryIds: string[] = []; + export class Component { + public id: string = ""; + public alias: string = ""; + public isEnabled: boolean = false; + + constructor( + public readonly factoryId: string = "", + public readonly properties: { [key: string]: any } = {}, + public readonly channels: { [channelId: string]: ComponentChannel } = {}, + ) { } + } + + export class FactoryProperty { + public readonly id: string; + public readonly name: string; + public readonly description: string; + public readonly isRequired: boolean; + public readonly defaultValue: any; + public readonly schema: {}; + } + + export class Factory { + public id: string = ""; + public componentIds: string[] = []; + + constructor( + public readonly name: string, + public readonly description: string, + public readonly natureIds: string[] = [], + public readonly properties: FactoryProperty[] = [], + ) { + } + + /** + * Gets the FactoryProperty definition for a Property-ID. + * + * @param propertyId the Property-ID + */ + static getPropertyForId(factory: Factory, propertyId: string): FactoryProperty { + for (const property of factory.properties) { + if (property.id === propertyId) { + return property; + } + } + return null; + } + } + + export class Nature { + public id: string = ""; + public name: string = ""; + public factoryIds: string[] = []; + } } From 9a029e25950ed83c5181badc11b4674e6d6e956b Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Wed, 10 Apr 2024 09:00:17 +0200 Subject: [PATCH 11/25] Ignore negavtive values on generator Port --- .../edge/deye/productionmeter/PvInverterDeye.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java index c1479621804..d3a888eb080 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java @@ -90,12 +90,21 @@ public Doc doc() { */ public static void calculateSumActivePowerFromPhases(PvInverterDeye meter) { final Consumer> calculate = ignore -> { + final Integer generatorPower = meter.getActivePowerGen().getNextValue().get(); + Integer generatorPowerToSet = 0; + + if(generatorPower > 65536) { + generatorPowerToSet = 0; + } else { + generatorPowerToSet = generatorPower; + } + meter._setActivePower(TypeUtils.sum(// meter.getActivePowerS1Channel().getNextValue().get(), // meter.getActivePowerS2Channel().getNextValue().get(), // meter.getActivePowerS3Channel().getNextValue().get(), // meter.getActivePowerS4Channel().getNextValue().get(), - meter.getActivePowerGen().getNextValue().get())); // + generatorPower)); // }; meter.getActivePowerS1Channel().onSetNextValue(calculate); meter.getActivePowerS2Channel().onSetNextValue(calculate); From 1e5adc5aafb11a2f9e43dce4b6d5e5da2a8be4a4 Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Wed, 10 Apr 2024 09:01:57 +0200 Subject: [PATCH 12/25] Use right variable --- .../io/openems/edge/deye/productionmeter/PvInverterDeye.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java index d3a888eb080..787a495efe6 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java @@ -104,7 +104,7 @@ public static void calculateSumActivePowerFromPhases(PvInverterDeye meter) { meter.getActivePowerS2Channel().getNextValue().get(), // meter.getActivePowerS3Channel().getNextValue().get(), // meter.getActivePowerS4Channel().getNextValue().get(), - generatorPower)); // + generatorPowerToSet)); // }; meter.getActivePowerS1Channel().onSetNextValue(calculate); meter.getActivePowerS2Channel().onSetNextValue(calculate); From 852a163fd4d6e017817bf1ee76ca8b137cf61c82 Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Tue, 16 Apr 2024 07:51:26 +0200 Subject: [PATCH 13/25] Re Implement Generator Port --- .../deye/productionmeter/PvInverterDeye.java | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java index 787a495efe6..bbd6c5a79df 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java @@ -81,31 +81,29 @@ public Doc doc() { } /** - * Initializes Channel listeners to calculate the - * {@link ElectricityMeter.ChannelId#ACTIVE_POWER}-Channel value as the sum of - * {@link ElectricityMeter.ChannelId#ACTIVE_POWER_L1}, {@link ElectricityMeter.ChannelId#ACTIVE_POWER_L2} and - * {@link ElectricityMeter.ChannelId#ACTIVE_POWER_L3}. + * Updates the total active power of the meter by summing the individual phase + * powers and adjusting for generator power. This method assumes all necessary + * values are always present and uses a simple fallback for any missing data. * * @param meter the {@link ElectricityMeter} + * @param meter the {@link PvInverterDeye} instance being updated */ public static void calculateSumActivePowerFromPhases(PvInverterDeye meter) { final Consumer> calculate = ignore -> { - final Integer generatorPower = meter.getActivePowerGen().getNextValue().get(); - Integer generatorPowerToSet = 0; - - if(generatorPower > 65536) { - generatorPowerToSet = 0; - } else { - generatorPowerToSet = generatorPower; - } - - meter._setActivePower(TypeUtils.sum(// - meter.getActivePowerS1Channel().getNextValue().get(), // - meter.getActivePowerS2Channel().getNextValue().get(), // - meter.getActivePowerS3Channel().getNextValue().get(), // - meter.getActivePowerS4Channel().getNextValue().get(), - generatorPowerToSet)); // + // Adjust generator power if it overflows + Integer generatorPower = meter.getActivePowerGen().getNextValue().orElse(0); + Integer adjustedGeneratorPower = (generatorPower > 32768) ? generatorPower - 65536 : generatorPower; + + // Sum phase powers and include adjusted generator power + Integer totalPower = TypeUtils.sum(meter.getActivePowerS1Channel().getNextValue().orElse(0), + meter.getActivePowerS2Channel().getNextValue().orElse(0), + meter.getActivePowerS3Channel().getNextValue().orElse(0), + meter.getActivePowerS4Channel().getNextValue().orElse(0), adjustedGeneratorPower); + + meter._setActivePower(totalPower); }; + + // Attach the calculation method to each relevant channel meter.getActivePowerS1Channel().onSetNextValue(calculate); meter.getActivePowerS2Channel().onSetNextValue(calculate); meter.getActivePowerS3Channel().onSetNextValue(calculate); From 69a6e9fa3c585db2bd3366efbc2cca90770f6395 Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Tue, 16 Apr 2024 08:08:53 +0200 Subject: [PATCH 14/25] Formatting and Refactoring - 00eb6e11db46fdfbc79b206409bcbf43aa38b816 --- .../deye/common/BatteryMaintenanceState.java | 32 ---- .../deye/common/BatteryStringSwitchState.java | 35 ---- .../edge/deye/common/BmsDcdcWorkMode.java | 33 ---- .../edge/deye/common/BmsDcdcWorkState.java | 37 ---- .../openems/edge/deye/common/ControlMode.java | 32 ---- .../edge/deye/common/DeyeSunHybrid.java | 165 +++++------------- .../edge/deye/common/DeyeSunHybridImpl.java | 57 +++--- .../edge/deye/common/InverterState.java | 38 ---- .../deye/common/SurplusFeedInHandler.java | 14 +- .../edge/deye/common/SystemManufacturer.java | 31 ---- .../openems/edge/deye/common/SystemType.java | 31 ---- .../deye/common/charger/DeyeSun2Impl.java | 4 +- .../edge/deye/common/charger/DeyeSunImpl.java | 4 +- .../edge/deye/productionmeter/Config.java | 2 +- .../deye/productionmeter/PvInverterDeye.java | 7 +- .../edge/deye/productionmeter/Status.java | 32 ---- 16 files changed, 94 insertions(+), 460 deletions(-) delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BatteryMaintenanceState.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BatteryStringSwitchState.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BmsDcdcWorkMode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BmsDcdcWorkState.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/ControlMode.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/InverterState.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemManufacturer.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemType.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Status.java diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BatteryMaintenanceState.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BatteryMaintenanceState.java deleted file mode 100644 index a346c84c6a7..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BatteryMaintenanceState.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.common; - -import io.openems.common.types.OptionsEnum; - -public enum BatteryMaintenanceState implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - OFF(0, "Off"), // - ON(1, "On"); // - - private final int value; - private final String name; - - private BatteryMaintenanceState(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BatteryStringSwitchState.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BatteryStringSwitchState.java deleted file mode 100644 index 36676880d15..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BatteryStringSwitchState.java +++ /dev/null @@ -1,35 +0,0 @@ -package io.openems.edge.deye.common; - -import io.openems.common.types.OptionsEnum; - -public enum BatteryStringSwitchState implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - MAIN_CONTATCTOR(1, "Main contactor"), // - PRECHARGE_CONTACTOR(2, "Precharge contactor"), // - FAN_CONTACTOR(4, "FAN contactor"), // - BMU_POWER_SUPPLY_RELAY(8, "BMU power supply relay"), // - MIDDLE_RELAY(16, "Middle relay"); - - private final int value; - private final String name; - - private BatteryStringSwitchState(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BmsDcdcWorkMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BmsDcdcWorkMode.java deleted file mode 100644 index e953e73f042..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BmsDcdcWorkMode.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.openems.edge.deye.common; - -import io.openems.common.types.OptionsEnum; - -public enum BmsDcdcWorkMode implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - CONSTANT_CURRENT(128, "Constant Current"), // - CONSTANT_VOLTAGE(256, "Constant Voltage"), // - BOOST_MPPT(512, "Boost MPPT"); // - - private final int value; - private final String name; - - private BmsDcdcWorkMode(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BmsDcdcWorkState.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BmsDcdcWorkState.java deleted file mode 100644 index 6ab1dd0f2ab..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/BmsDcdcWorkState.java +++ /dev/null @@ -1,37 +0,0 @@ -package io.openems.edge.deye.common; - -import io.openems.common.types.OptionsEnum; - -public enum BmsDcdcWorkState implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - INITIAL(2, "Initial"), // - STOP(4, "Stop"), // - READY(8, "Ready"), // - RUNNING(16, "Running"), // - FAULT(32, "Fault"), // - DEBUG(64, "Debug"), // - LOCKED(128, "Locked"); // - - private final int value; - private final String name; - - private BmsDcdcWorkState(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/ControlMode.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/ControlMode.java deleted file mode 100644 index d0d94d39855..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/ControlMode.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.common; - -import io.openems.common.types.OptionsEnum; - -public enum ControlMode implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - REMOTE(1, "Remote"), // - LOCAL(2, "Local"); // - - private final int value; - private final String name; - - private ControlMode(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java index 25f3c28a4a6..466bf5b65c3 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java @@ -53,46 +53,28 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { SERIAL_NUMBER(Doc.of(OpenemsType.STRING) // .persistencePriority(PersistencePriority.HIGH) // .accessMode(AccessMode.READ_ONLY)), - CONTROL_MODE(Doc.of(ControlMode.values())), // - BATTERY_MAINTENANCE_STATE(Doc.of(BatteryMaintenanceState.values())), // - SYSTEM_MANUFACTURER(Doc.of(SystemManufacturer.values())), // - SYSTEM_TYPE(Doc.of(SystemType.values())), // - BATTERY_STRING_SWITCH_STATE(Doc.of(BatteryStringSwitchState.values())), // - BMS_DCDC_WORK_STATE(Doc.of(BmsDcdcWorkState.values())), // - BMS_DCDC_WORK_MODE(Doc.of(BmsDcdcWorkMode.values())), // SURPLUS_FEED_IN_POWER(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT)), // SURPLUS_FEED_IN_STATE_MACHINE(Doc.of(SurplusFeedInStateMachine.values())), - // Gen Port Use Channels // AC 1/28/2024 - SET_GRID_LOAD_OFF_POWER(Doc.of(OpenemsType.INTEGER) - .unit(Unit.PERCENT) // - .accessMode(AccessMode.WRITE_ONLY)), //), // + SET_GRID_LOAD_OFF_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT) // + .accessMode(AccessMode.WRITE_ONLY)), // ), // // Battery Channels // AC 1/31/2024 - BATTERY_CAPACITY(Doc.of(OpenemsType.INTEGER) - .unit(Unit.AMPERE_HOURS) - .accessMode(AccessMode.READ_WRITE)), - BATTERY_CAPACITY_SHUTDOWN(Doc.of(OpenemsType.INTEGER) - .unit(Unit.PERCENT)), - BATTERY_CAPACITY_RESTART(Doc.of(OpenemsType.INTEGER) - .unit(Unit.PERCENT)), - BATTERY_CAPACITY_LOW_BATTERY(Doc.of(OpenemsType.INTEGER) - .unit(Unit.PERCENT)), - MAX_A_BATTERY_CHARGE_CURRENT(Doc.of(OpenemsType.INTEGER) - .unit(Unit.AMPERE)), - MAX_A_BATTERY_DISCHARGE_CURRENT(Doc.of(OpenemsType.INTEGER) - .unit(Unit.AMPERE)), - PARALLEL_BAT_1_AND_BAT_2(Doc.of(OpenemsType.INTEGER)), - BAT_1_SOC(Doc.of(OpenemsType.INTEGER)), + BATTERY_CAPACITY(Doc.of(OpenemsType.INTEGER).unit(Unit.AMPERE_HOURS).accessMode(AccessMode.READ_WRITE)), + BATTERY_CAPACITY_SHUTDOWN(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT)), + BATTERY_CAPACITY_RESTART(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT)), + BATTERY_CAPACITY_LOW_BATTERY(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT)), + MAX_A_BATTERY_CHARGE_CURRENT(Doc.of(OpenemsType.INTEGER).unit(Unit.AMPERE)), + MAX_A_BATTERY_DISCHARGE_CURRENT(Doc.of(OpenemsType.INTEGER).unit(Unit.AMPERE)), + PARALLEL_BAT_1_AND_BAT_2(Doc.of(OpenemsType.INTEGER)), BAT_1_SOC(Doc.of(OpenemsType.INTEGER)), // Battery Time of Use settings // AC 2/16/2024 - TIME_OF_USE_SELLING_FLAG(Doc.of(OpenemsType.BOOLEAN) - .accessMode(AccessMode.READ_WRITE)), + TIME_OF_USE_SELLING_FLAG(Doc.of(OpenemsType.BOOLEAN).accessMode(AccessMode.READ_WRITE)), TIME_OF_USE_ENABLED_FLAG(Doc.of(OpenemsType.BOOLEAN) // .accessMode(AccessMode.READ_WRITE)), // @@ -113,109 +95,58 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { // Generator and Grid Channels // AC 1/31/2024 - GEN_MAX_RUN_TIME(Doc.of(OpenemsType.INTEGER) - .unit(Unit.HOUR)), - GEN_COOLING_TIME(Doc.of(OpenemsType.INTEGER) - .unit(Unit.HOUR)), - GEN_CHARGING_STARTING_CAPACITY_POINT(Doc.of(OpenemsType.INTEGER) - .unit(Unit.PERCENT)), - GEN_CHARGING_CURRENT_TO_BATTERY(Doc.of(OpenemsType.INTEGER) - .unit(Unit.AMPERE)), + GEN_MAX_RUN_TIME(Doc.of(OpenemsType.INTEGER).unit(Unit.HOUR)), + GEN_COOLING_TIME(Doc.of(OpenemsType.INTEGER).unit(Unit.HOUR)), + GEN_CHARGING_STARTING_CAPACITY_POINT(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT)), + GEN_CHARGING_CURRENT_TO_BATTERY(Doc.of(OpenemsType.INTEGER).unit(Unit.AMPERE)), GEN_CHARGE_ENABLED(Doc.of(OpenemsType.INTEGER)), - GRID_CHARGING_STARTING_CAPACITY_POINT(Doc.of(OpenemsType.INTEGER) - .unit(Unit.PERCENT)), - GRID_CHARGING_CURRENT_TO_BATTERY(Doc.of(OpenemsType.INTEGER) - .unit(Unit.AMPERE)), - GRID_CHARGE_ENABLED(Doc.of(OpenemsType.INTEGER)), - AC_COUPLE_FREQUENCY_CAP(Doc.of(OpenemsType.INTEGER)), - GEN_LOAD_OFF_POWER(Doc.of(OpenemsType.INTEGER) - .unit(Unit.PERCENT)), - GEN_LOAD_ON_POWER(Doc.of(OpenemsType.INTEGER) - .unit(Unit.PERCENT)), - GEN_GRID_SIGNAL(Doc.of(OpenemsType.INTEGER)), + GRID_CHARGING_STARTING_CAPACITY_POINT(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT)), + GRID_CHARGING_CURRENT_TO_BATTERY(Doc.of(OpenemsType.INTEGER).unit(Unit.AMPERE)), + GRID_CHARGE_ENABLED(Doc.of(OpenemsType.INTEGER)), AC_COUPLE_FREQUENCY_CAP(Doc.of(OpenemsType.INTEGER)), + GEN_LOAD_OFF_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT)), + GEN_LOAD_ON_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT)), GEN_GRID_SIGNAL(Doc.of(OpenemsType.INTEGER)), GEN_CONNECTED_TO_GRID_INPUT(Doc.of(OpenemsType.INTEGER)), - GEN_PEAK_SHAVING_POWER(Doc.of(OpenemsType.INTEGER) - .unit(Unit.WATT)), - GRID_PEAK_SHAVING_POWER(Doc.of(OpenemsType.INTEGER) - .unit(Unit.WATT)), + GEN_PEAK_SHAVING_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), + GRID_PEAK_SHAVING_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), // Solar Channels // AC 1/31/2024 SOLAR_SELL(Doc.of(OpenemsType.INTEGER)), - TIME_POINT_1_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER) - .accessMode(AccessMode.READ_WRITE)), - TIME_POINT_2_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER) - .accessMode(AccessMode.READ_WRITE)), - TIME_POINT_3_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER) - .accessMode(AccessMode.READ_WRITE)), - TIME_POINT_4_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER) - .accessMode(AccessMode.READ_WRITE)), - TIME_POINT_5_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER) - .accessMode(AccessMode.READ_WRITE)), - TIME_POINT_6_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER) - .accessMode(AccessMode.READ_WRITE)), + TIME_POINT_1_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), + TIME_POINT_2_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), + TIME_POINT_3_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), + TIME_POINT_4_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), + TIME_POINT_5_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), + TIME_POINT_6_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_1(Doc.of(OpenemsType.INTEGER) - .accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_2(Doc.of(OpenemsType.INTEGER) - .accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_3(Doc.of(OpenemsType.INTEGER) - .accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_4(Doc.of(OpenemsType.INTEGER) - .accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_5(Doc.of(OpenemsType.INTEGER) - .accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_6(Doc.of(OpenemsType.INTEGER) - .accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_1_POWER(Doc.of(OpenemsType.INTEGER) - .unit(Unit.WATT) - .accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_2_POWER(Doc.of(OpenemsType.INTEGER) - .unit(Unit.WATT) - .accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_3_POWER(Doc.of(OpenemsType.INTEGER) - .unit(Unit.WATT) - .accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_4_POWER(Doc.of(OpenemsType.INTEGER) - .unit(Unit.WATT) - .accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_5_POWER(Doc.of(OpenemsType.INTEGER) - .unit(Unit.WATT) - .accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_6_POWER(Doc.of(OpenemsType.INTEGER) - .unit(Unit.WATT) - .accessMode(AccessMode.READ_WRITE)), - SELL_MODE_CAPACITY_1(Doc.of(OpenemsType.INTEGER) - .unit(Unit.PERCENT) - .accessMode(AccessMode.READ_WRITE)), - SELL_MODE_CAPACITY_2(Doc.of(OpenemsType.INTEGER) - .unit(Unit.PERCENT) - .accessMode(AccessMode.READ_WRITE)), - SELL_MODE_CAPACITY_3(Doc.of(OpenemsType.INTEGER) - .unit(Unit.PERCENT) - .accessMode(AccessMode.READ_WRITE)), - SELL_MODE_CAPACITY_4(Doc.of(OpenemsType.INTEGER) - .unit(Unit.PERCENT) - .accessMode(AccessMode.READ_WRITE)), - SELL_MODE_CAPACITY_5(Doc.of(OpenemsType.INTEGER) - .unit(Unit.PERCENT) - .accessMode(AccessMode.READ_WRITE)), - SELL_MODE_CAPACITY_6(Doc.of(OpenemsType.INTEGER) - .unit(Unit.PERCENT) - .accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_1(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_2(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_3(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_4(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_5(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_6(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_1_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT).accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_2_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT).accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_3_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT).accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_4_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT).accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_5_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT).accessMode(AccessMode.READ_WRITE)), + SELL_MODE_TIME_POINT_6_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT).accessMode(AccessMode.READ_WRITE)), + SELL_MODE_CAPACITY_1(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT).accessMode(AccessMode.READ_WRITE)), + SELL_MODE_CAPACITY_2(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT).accessMode(AccessMode.READ_WRITE)), + SELL_MODE_CAPACITY_3(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT).accessMode(AccessMode.READ_WRITE)), + SELL_MODE_CAPACITY_4(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT).accessMode(AccessMode.READ_WRITE)), + SELL_MODE_CAPACITY_5(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT).accessMode(AccessMode.READ_WRITE)), + SELL_MODE_CAPACITY_6(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT).accessMode(AccessMode.READ_WRITE)), MICROINVERTER_EXPORT_TO_GRID_CUTOFF(Doc.of(OpenemsType.INTEGER)), SOLAR_ARC_FAULT_ON(Doc.of(OpenemsType.INTEGER)), - MAX_SOLAR_SELL_POWER(Doc.of(OpenemsType.INTEGER) - .unit(Unit.WATT)), + MAX_SOLAR_SELL_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), // Other Channels // AC 1/31/2024 ZERO_EXPORT_POWER(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.WATT) - .accessMode(AccessMode.READ_WRITE)), - UPS_BACKUP_DELAY_TIME(Doc.of(OpenemsType.INTEGER) - .unit(Unit.SECONDS)), + .unit(Unit.WATT).accessMode(AccessMode.READ_WRITE)), + UPS_BACKUP_DELAY_TIME(Doc.of(OpenemsType.INTEGER).unit(Unit.SECONDS)), // EnumWriteChannels SET_WORK_STATE(Doc.of(SetWorkState.values()) // diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java index e1dd2b9166d..045d0cebe0c 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java @@ -72,8 +72,8 @@ EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE, // EdgeEventConstants.TOPIC_CYCLE_BEFORE_CONTROLLERS // }) -public class DeyeSunHybridImpl extends AbstractOpenemsModbusComponent - implements DeyeSunHybrid, ManagedSymmetricEss, SymmetricEss, HybridEss, ModbusComponent, OpenemsComponent, EventHandler, ModbusSlave, TimedataProvider { +public class DeyeSunHybridImpl extends AbstractOpenemsModbusComponent implements DeyeSunHybrid, ManagedSymmetricEss, + SymmetricEss, HybridEss, ModbusComponent, OpenemsComponent, EventHandler, ModbusSlave, TimedataProvider { protected static final int MAX_APPARENT_POWER = 40000; @@ -85,13 +85,17 @@ public class DeyeSunHybridImpl extends AbstractOpenemsModbusComponent private final Logger log = LoggerFactory.getLogger(DeyeSunHybridImpl.class); - private final CalculateEnergyFromPower calculateAcChargeEnergy = new CalculateEnergyFromPower(this, SymmetricEss.ChannelId.ACTIVE_CHARGE_ENERGY); + private final CalculateEnergyFromPower calculateAcChargeEnergy = new CalculateEnergyFromPower(this, + SymmetricEss.ChannelId.ACTIVE_CHARGE_ENERGY); - private final CalculateEnergyFromPower calculateAcDischargeEnergy = new CalculateEnergyFromPower(this, SymmetricEss.ChannelId.ACTIVE_DISCHARGE_ENERGY); + private final CalculateEnergyFromPower calculateAcDischargeEnergy = new CalculateEnergyFromPower(this, + SymmetricEss.ChannelId.ACTIVE_DISCHARGE_ENERGY); - private final CalculateEnergyFromPower calculateDcChargeEnergy = new CalculateEnergyFromPower(this, HybridEss.ChannelId.DC_CHARGE_ENERGY); + private final CalculateEnergyFromPower calculateDcChargeEnergy = new CalculateEnergyFromPower(this, + HybridEss.ChannelId.DC_CHARGE_ENERGY); - private final CalculateEnergyFromPower calculateDcDischargeEnergy = new CalculateEnergyFromPower(this, HybridEss.ChannelId.DC_DISCHARGE_ENERGY); + private final CalculateEnergyFromPower calculateDcDischargeEnergy = new CalculateEnergyFromPower(this, + HybridEss.ChannelId.DC_DISCHARGE_ENERGY); private final List chargers = new ArrayList<>(); @@ -134,7 +138,8 @@ public DeyeSunHybridImpl() { @Activate private void activate(ComponentContext context, Config config) throws OpenemsException { - if (super.activate(context, config.id(), config.alias(), config.enabled(), config.unit_id(), this.cm, "Modbus", config.modbus_id())) { + if (super.activate(context, config.id(), config.alias(), config.enabled(), config.unit_id(), this.cm, "Modbus", + config.modbus_id())) { return; } this.config = config; @@ -182,12 +187,10 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException { return new ModbusProtocol(this, // new FC3ReadRegistersTask(1, Priority.LOW, - m(SymmetricEss.ChannelId.GRID_MODE, new UnsignedWordElement(1)), - new DummyRegisterElement(2), + m(SymmetricEss.ChannelId.GRID_MODE, new UnsignedWordElement(1)), new DummyRegisterElement(2), m(DeyeSunHybrid.ChannelId.SERIAL_NUMBER, new StringWordElement(3, 5))), - new FC16WriteRegistersTask(77, - m(DeyeSunHybrid.ChannelId.SET_ACTIVE_POWER, new SignedWordElement(77)), + new FC16WriteRegistersTask(77, m(DeyeSunHybrid.ChannelId.SET_ACTIVE_POWER, new SignedWordElement(77)), m(DeyeSunHybrid.ChannelId.SET_REACTIVE_POWER, new SignedWordElement(78))), new FC3ReadRegistersTask(588, Priority.HIGH, @@ -196,7 +199,6 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException { new FC3ReadRegistersTask(500, Priority.LOW, m(DeyeSunHybrid.ChannelId.INVERTER_RUN_STATE, new UnsignedWordElement(500))), - new FC3ReadRegistersTask(590, Priority.HIGH, m(SymmetricEss.ChannelId.ACTIVE_POWER, new SignedWordElement(590))), @@ -210,9 +212,8 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException { public String debugLog() { return "SoC:" + this.getSoc().asString() // + "|L:" + this.getActivePower().asString() // - + "|Active Power:" - + this.channel(SymmetricEss.ChannelId.ACTIVE_POWER).value().asStringWithoutUnit() + ";" - + "|Allowed:" + + "|Active Power:" + this.channel(SymmetricEss.ChannelId.ACTIVE_POWER).value().asStringWithoutUnit() + + ";" + "|Allowed:" + this.channel(ManagedSymmetricEss.ChannelId.ALLOWED_CHARGE_POWER).value().asStringWithoutUnit() + ";" + this.channel(ManagedSymmetricEss.ChannelId.ALLOWED_DISCHARGE_POWER).value().asString(); } @@ -280,8 +281,10 @@ public Constraint[] getStaticConstraints() throws OpenemsNamedException { // Reactive Power constraints return new Constraint[] { // - this.createPowerConstraint("Deye Min Reactive Power", Phase.ALL, Pwr.REACTIVE, Relationship.GREATER_OR_EQUALS, MIN_REACTIVE_POWER), // - this.createPowerConstraint("Deye Max Reactive Power", Phase.ALL, Pwr.REACTIVE, Relationship.LESS_OR_EQUALS, MAX_REACTIVE_POWER) }; + this.createPowerConstraint("Deye Min Reactive Power", Phase.ALL, Pwr.REACTIVE, + Relationship.GREATER_OR_EQUALS, MIN_REACTIVE_POWER), // + this.createPowerConstraint("Deye Max Reactive Power", Phase.ALL, Pwr.REACTIVE, + Relationship.LESS_OR_EQUALS, MAX_REACTIVE_POWER) }; } @Override @@ -300,17 +303,20 @@ protected void logInfo(Logger log, String message) { private void applyPowerLimitOnPowerDecreaseCausedByOvertemperatureError() { if (this.config.powerLimitOnPowerDecreaseCausedByOvertemperatureChannel() != 0) { - StateChannel powerDecreaseCausedByOvertemperatureChannel = this.channel(DeyeSunHybrid.ChannelId.POWER_DECREASE_CAUSED_BY_OVERTEMPERATURE); + StateChannel powerDecreaseCausedByOvertemperatureChannel = this + .channel(DeyeSunHybrid.ChannelId.POWER_DECREASE_CAUSED_BY_OVERTEMPERATURE); if (powerDecreaseCausedByOvertemperatureChannel.value().orElse(false)) { /* * Apply limit on ESS charge/discharge power */ try { this.power.addConstraintAndValidate( - this.createPowerConstraint("Limit On PowerDecreaseCausedByOvertemperature Error", Phase.ALL, Pwr.ACTIVE, Relationship.GREATER_OR_EQUALS, + this.createPowerConstraint("Limit On PowerDecreaseCausedByOvertemperature Error", Phase.ALL, + Pwr.ACTIVE, Relationship.GREATER_OR_EQUALS, this.config.powerLimitOnPowerDecreaseCausedByOvertemperatureChannel() * -1)); this.power.addConstraintAndValidate( - this.createPowerConstraint("Limit On PowerDecreaseCausedByOvertemperature Error", Phase.ALL, Pwr.ACTIVE, Relationship.LESS_OR_EQUALS, + this.createPowerConstraint("Limit On PowerDecreaseCausedByOvertemperature Error", Phase.ALL, + Pwr.ACTIVE, Relationship.LESS_OR_EQUALS, this.config.powerLimitOnPowerDecreaseCausedByOvertemperatureChannel())); } catch (OpenemsException e) { this.logError(this.log, e.getMessage()); @@ -319,9 +325,11 @@ private void applyPowerLimitOnPowerDecreaseCausedByOvertemperatureError() { * Apply limit on Charger */ if (this.chargers.size() > 0) { - IntegerWriteChannel setPvPowerLimit = this.chargers.get(0).channel(DeyeSunPv.ChannelId.SET_PV_POWER_LIMIT); + IntegerWriteChannel setPvPowerLimit = this.chargers.get(0) + .channel(DeyeSunPv.ChannelId.SET_PV_POWER_LIMIT); try { - setPvPowerLimit.setNextWriteValue(this.config.powerLimitOnPowerDecreaseCausedByOvertemperatureChannel()); + setPvPowerLimit.setNextWriteValue( + this.config.powerLimitOnPowerDecreaseCausedByOvertemperatureChannel()); } catch (OpenemsNamedException e) { this.logError(this.log, e.getMessage()); } @@ -359,13 +367,14 @@ private void calculateEnergy() { this.calculateAcChargeEnergy.update(acActivePower * -1); this.calculateAcDischargeEnergy.update(0); } - + /* * Calculate DC Power and Energy */ var dcDischargePower = acActivePower; for (DeyeSunPv charger : this.chargers) { - dcDischargePower = TypeUtils.subtract(dcDischargePower, charger.getActualPowerChannel().getNextValue().get()); + dcDischargePower = TypeUtils.subtract(dcDischargePower, + charger.getActualPowerChannel().getNextValue().get()); } this._setDcDischargePower(dcDischargePower); diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/InverterState.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/InverterState.java deleted file mode 100644 index 45ccd4102ce..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/InverterState.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.openems.edge.deye.common; - -import io.openems.common.types.OptionsEnum; - -public enum InverterState implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - INIT(0, "Init"), // - FAULT(2, "Fault"), // - STOP(4, "Stop"), // - STANDBY(8, "Standby"), // - GRID_MONITOR(16, "Grid-Monitor"), // - READY(32, "Ready"), // - START(64, "Start"), // - DEBUG(128, "Debug"); // - - private final int value; - private final String name; - - private InverterState(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInHandler.java index f7515cb6031..b202b9d626f 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInHandler.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInHandler.java @@ -6,7 +6,6 @@ import io.openems.edge.common.channel.IntegerWriteChannel; import io.openems.edge.common.channel.StateChannel; import io.openems.edge.common.component.ComponentManager; -import io.openems.edge.deye.common.charger.DeyeSunImpl; import io.openems.edge.deye.common.charger.DeyeSunPv; import io.openems.edge.ess.dccharger.api.EssDcCharger; import org.slf4j.Logger; @@ -118,14 +117,12 @@ private int getPvPower(List chargers) { return pvPower; } - private boolean areSurplusConditionsMet(DeyeSunHybridImpl ess, List chargers, - Config config) { + private boolean areSurplusConditionsMet(DeyeSunHybridImpl ess, List chargers, Config config) { if (chargers.isEmpty()) { return false; } - IntegerReadChannel allowedChargeChannel = ess - .channel(DeyeSunHybrid.ChannelId.ORIGINAL_ALLOWED_CHARGE_POWER); + IntegerReadChannel allowedChargeChannel = ess.channel(DeyeSunHybrid.ChannelId.ORIGINAL_ALLOWED_CHARGE_POWER); IntegerReadChannel allowedDischargeChannel = ess .channel(DeyeSunHybrid.ChannelId.ORIGINAL_ALLOWED_DISCHARGE_POWER); if ( @@ -139,8 +136,8 @@ private boolean areSurplusConditionsMet(DeyeSunHybridImpl ess, List c var maxVoltage = 0; for (DeyeSunPv charger : chargers) { - int thisVoltage = ((IntegerReadChannel) charger - .channel(DeyeSunPv.ChannelId.PV_DCDC_INPUT_VOLTAGE)).value().orElse(0); + int thisVoltage = ((IntegerReadChannel) charger.channel(DeyeSunPv.ChannelId.PV_DCDC_INPUT_VOLTAGE)).value() + .orElse(0); if (thisVoltage > maxVoltage) { maxVoltage = thisVoltage; } @@ -179,8 +176,7 @@ private void applyPvPowerLimit(List chargers, Config config, boolean } for (DeyeSunPv charger : chargers) { - IntegerWriteChannel setPvPowerLimit = charger - .channel(DeyeSunPv.ChannelId.SET_PV_POWER_LIMIT); + IntegerWriteChannel setPvPowerLimit = charger.channel(DeyeSunPv.ChannelId.SET_PV_POWER_LIMIT); try { setPvPowerLimit.setNextWriteValue(pvPowerLimit); } catch (OpenemsNamedException e) { diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemManufacturer.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemManufacturer.java deleted file mode 100644 index e3b21567887..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemManufacturer.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.openems.edge.deye.common; - -import io.openems.common.types.OptionsEnum; - -public enum SystemManufacturer implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - BYD(1, "BYD"); - - private final int value; - private final String name; - - private SystemManufacturer(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemType.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemType.java deleted file mode 100644 index b096bcaca9b..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemType.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.openems.edge.deye.common; - -import io.openems.common.types.OptionsEnum; - -public enum SystemType implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - CESS(1, "CESS"); // - - private final int value; - private final String name; - - private SystemType(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSun2Impl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSun2Impl.java index ca4905d0e72..d8916d7bfde 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSun2Impl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSun2Impl.java @@ -32,8 +32,8 @@ @EventTopics({ // EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE // }) -public class DeyeSun2Impl extends AbstractEssDeyePv implements DeyeSunPv, - EssDcCharger, ModbusComponent, OpenemsComponent, EventHandler, TimedataProvider { +public class DeyeSun2Impl extends AbstractEssDeyePv + implements DeyeSunPv, EssDcCharger, ModbusComponent, OpenemsComponent, EventHandler, TimedataProvider { @Reference private ConfigurationAdmin cm; diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunImpl.java index e76f7533a0e..84b6840d936 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunImpl.java @@ -32,8 +32,8 @@ @EventTopics({ // EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE // }) -public class DeyeSunImpl extends AbstractEssDeyePv implements DeyeSunPv, - EssDcCharger, ModbusComponent, OpenemsComponent, EventHandler, TimedataProvider { +public class DeyeSunImpl extends AbstractEssDeyePv + implements DeyeSunPv, EssDcCharger, ModbusComponent, OpenemsComponent, EventHandler, TimedataProvider { @Reference private ConfigurationAdmin cm; diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Config.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Config.java index f68eb6311b4..a065ff77139 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Config.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Config.java @@ -4,7 +4,7 @@ import org.osgi.service.metatype.annotations.ObjectClassDefinition; @ObjectClassDefinition(name = "Production Meter Deye", // - description = "Implements the Deye Meter - Production") + description = "Implements the Deye Meter - Production 1") @interface Config { @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java index bbd6c5a79df..35d7508e90a 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java @@ -22,7 +22,7 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { ACTIVE_POWER_STRING_2(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), ACTIVE_POWER_STRING_3(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), ACTIVE_POWER_STRING_4(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), - + ACTIVE_POWER_GENERATOR(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), LAST_UPDATE_TIME(Doc.of(OpenemsType.INTEGER) // @@ -62,10 +62,10 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { .unit(Unit.KILOWATT)), WATCH_DOG_TAG(Doc.of(OpenemsType.INTEGER) // .accessMode(AccessMode.READ_WRITE)), // - STATUS(Doc.of(Status.values())), PV_LIMIT_FAILED(Doc.of(Level.FAULT) // .text("PV-Limit failed")); + private final Doc doc; private ChannelId(Doc doc) { @@ -77,7 +77,6 @@ public Doc doc() { return this.doc; } - } /** @@ -126,7 +125,7 @@ public default IntegerReadChannel getActivePowerS3Channel() { public default IntegerReadChannel getActivePowerS4Channel() { return this.channel(ChannelId.ACTIVE_POWER_STRING_4); } - + public default IntegerReadChannel getActivePowerGen() { return this.channel(ChannelId.ACTIVE_POWER_GENERATOR); } diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Status.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Status.java deleted file mode 100644 index fcd956bb53f..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/Status.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.openems.edge.deye.productionmeter; - -import io.openems.common.types.OptionsEnum; - -public enum Status implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - OK(0, "Ok"), // - LICENSE_NOT_SUFFICIENT(1, "License not sufficient for size of installation"); // - - private final int value; - private final String name; - - private Status(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file From e9452d4712c015ee15ba062bb73573ba423c58e7 Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Tue, 16 Apr 2024 08:24:32 +0200 Subject: [PATCH 15/25] Remove unused imports - f728fa91442eb8050b77a9a437309235a9e77763 --- .../edge/deye/gridmeter/DeyeGridMeterImpl.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java index eb833f780c5..62ca4e137f2 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java @@ -33,8 +33,6 @@ import org.osgi.service.event.EventHandler; import org.osgi.service.event.propertytypes.EventTopics; import org.osgi.service.metatype.annotations.Designate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; @Designate(ocd = Config.class, factory = true) @Component(// @@ -47,10 +45,9 @@ @EventTopics({ // EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE // }) -public class DeyeGridMeterImpl extends AbstractOpenemsModbusComponent - implements DeyeGridMeter, ElectricityMeter, ModbusComponent, OpenemsComponent, TimedataProvider, EventHandler, ModbusSlave { +public class DeyeGridMeterImpl extends AbstractOpenemsModbusComponent implements DeyeGridMeter, ElectricityMeter, + ModbusComponent, OpenemsComponent, TimedataProvider, EventHandler, ModbusSlave { - private final Logger log = LoggerFactory.getLogger(DeyeGridMeterImpl.class); private final CalculateEnergyFromPower calculateProductionEnergy = new CalculateEnergyFromPower(this, ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY); private final CalculateEnergyFromPower calculateConsumptionEnergy = new CalculateEnergyFromPower(this, @@ -64,6 +61,7 @@ public class DeyeGridMeterImpl extends AbstractOpenemsModbusComponent protected void setModbus(BridgeModbus modbus) { super.setModbus(modbus); } + @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL) private volatile Timedata timedata = null; @@ -101,9 +99,8 @@ public MeterType getMeterType() { @Override protected ModbusProtocol defineModbusProtocol() throws OpenemsException { - return new ModbusProtocol(this, - new FC3ReadRegistersTask(625, Priority.HIGH, - m(ElectricityMeter.ChannelId.ACTIVE_POWER, new SignedWordElement(625)))); + return new ModbusProtocol(this, new FC3ReadRegistersTask(625, Priority.HIGH, + m(ElectricityMeter.ChannelId.ACTIVE_POWER, new SignedWordElement(625)))); } @Override From 16e1dd69a1bac8a1f500c7c11d177a5d8cdfc21c Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Tue, 16 Apr 2024 08:28:06 +0200 Subject: [PATCH 16/25] Delete io.openems.edge.evcs.spelsberg/generated/buildfiles - 48ce7291814e8a40e2f7f53e8c76f8f5a1c20579 --- io.openems.edge.evcs.spelsberg/generated/buildfiles | 1 - 1 file changed, 1 deletion(-) diff --git a/io.openems.edge.evcs.spelsberg/generated/buildfiles b/io.openems.edge.evcs.spelsberg/generated/buildfiles index ef95c181a81..e69de29bb2d 100644 --- a/io.openems.edge.evcs.spelsberg/generated/buildfiles +++ b/io.openems.edge.evcs.spelsberg/generated/buildfiles @@ -1 +0,0 @@ -/Users/mvogt/IdeaProjects/openems/io.openems.edge.evcs.spelsberg/generated/io.openems.edge.evcs.spelsberg.jar From 0ab5a1b693886ece9a025a4566006aef492d1e3b Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Tue, 16 Apr 2024 08:29:05 +0200 Subject: [PATCH 17/25] Delete io.openems.edge.io.gpio/generated/buildfiles - b10da123dec2189908fd1fc5c7753c4e54f3bf47 --- io.openems.edge.io.gpio/generated/buildfiles | 1 - 1 file changed, 1 deletion(-) diff --git a/io.openems.edge.io.gpio/generated/buildfiles b/io.openems.edge.io.gpio/generated/buildfiles index d19112c47b3..e69de29bb2d 100644 --- a/io.openems.edge.io.gpio/generated/buildfiles +++ b/io.openems.edge.io.gpio/generated/buildfiles @@ -1 +0,0 @@ -/Users/mvogt/IdeaProjects/openems/io.openems.edge.io.gpio/generated/io.openems.edge.io.gpio.jar From 232bbb4362e6a95592771a4445cbd60af4f22ccd Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Tue, 16 Apr 2024 08:31:12 +0200 Subject: [PATCH 18/25] Removed wrong Component Names - a041a91664d65f063d95a3c938cb03609f724075 --- .../src/io/openems/edge/deye/common/charger/ConfigPv1.java | 4 ++-- .../src/io/openems/edge/deye/common/charger/ConfigPv2.java | 4 ++-- .../src/io/openems/edge/deye/common/charger/DeyeSun2Impl.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv1.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv1.java index ea06e5435fb..1244aaf878e 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv1.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv1.java @@ -4,8 +4,8 @@ import org.osgi.service.metatype.annotations.ObjectClassDefinition; @ObjectClassDefinition(// - name = "ESS FENECON Commercial 40 DC Charger PV1", // - description = "Implements the FENECON Commercial 40 DC Charger.") + name = "Deye Sun DC Charger PV1", // + description = "Implements the Deye Sun DC Charger.") @interface ConfigPv1 { @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv2.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv2.java index 756f3b59344..83815eb28e0 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv2.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv2.java @@ -4,8 +4,8 @@ import org.osgi.service.metatype.annotations.ObjectClassDefinition; @ObjectClassDefinition(// - name = "ESS FENECON Commercial 40 DC Charger PV2", // - description = "Implements the FENECON Commercial 40 DC Charger.") + name = "Deye Sun DC Charger PV1", // + description = "Implements the Deye Sun DC Charger.") @interface ConfigPv2 { @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSun2Impl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSun2Impl.java index d8916d7bfde..533385e9040 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSun2Impl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSun2Impl.java @@ -25,7 +25,7 @@ @Designate(ocd = ConfigPv2.class, factory = true) @Component(// - name = "Ess.Fenecon.Commercial40.PV2", // + name = "Deye.Sun.PV2", // immediate = true, // configurationPolicy = ConfigurationPolicy.REQUIRE // ) From a72c692129079372d2633b60371f46412912267f Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Tue, 16 Apr 2024 08:33:17 +0200 Subject: [PATCH 19/25] Implement a Grid_Meter Test - 73092e33f80fd0c1fea9aa135edc1a07e7650f8e --- .../edge/deye/common/charger/DeyeSunImpl.java | 2 +- .../deye/gridmeter/DeyeGridMeterImplTest.java | 22 ++++++++++++++-- .../openems/edge/deye/gridmeter/MyConfig.java | 26 +++++-------------- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunImpl.java index 84b6840d936..67679e00698 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunImpl.java @@ -25,7 +25,7 @@ @Designate(ocd = ConfigPv1.class, factory = true) @Component(// - name = "Ess.Fenecon.Commercial40.PV1", // + name = "Deye.Sun.PV1", // immediate = true, // configurationPolicy = ConfigurationPolicy.REQUIRE // ) diff --git a/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/DeyeGridMeterImplTest.java b/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/DeyeGridMeterImplTest.java index 273fab0b55f..4271547d9b4 100644 --- a/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/DeyeGridMeterImplTest.java +++ b/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/DeyeGridMeterImplTest.java @@ -1,7 +1,25 @@ package io.openems.edge.deye.gridmeter; -import junit.framework.TestCase; +import org.junit.Test; -public class DeyeGridMeterImplTest extends TestCase { +import io.openems.edge.bridge.modbus.test.DummyModbusBridge; +import io.openems.edge.common.test.ComponentTest; +import io.openems.edge.common.test.DummyConfigurationAdmin; +public class DeyeGridMeterImplTest { + + private static final String METER_ID = "meter0"; + private static final String MODBUS_ID = "modbus0"; + + @Test + public void test() throws Exception { + new ComponentTest(new DeyeGridMeterImpl()) // + .addReference("cm", new DummyConfigurationAdmin()) // + .addReference("setModbus", new DummyModbusBridge(MODBUS_ID)) // + .activate(MyConfig.create() // + .setId(METER_ID) // + .setModbusId(MODBUS_ID) // + .build()) // + ; + } } \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/MyConfig.java b/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/MyConfig.java index 0160fe0c25f..e637d42db71 100644 --- a/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/MyConfig.java +++ b/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/MyConfig.java @@ -8,10 +8,9 @@ public class MyConfig extends AbstractComponentConfig implements Config { protected static class Builder { - private String id = null; - private StartStopConfig startStopConfig = null; - private String modbusId = null; - private boolean activateWatchdog; + private String id; + private String modbusId; + private int modbusUnitId; private Builder() { } @@ -21,21 +20,12 @@ public Builder setId(String id) { return this; } - public Builder setStartStopConfig(StartStopConfig startStopConfig) { - this.startStopConfig = startStopConfig; - return this; - } public Builder setModbusId(String modbusId) { this.modbusId = modbusId; return this; } - public Builder setActivateWatchdog(boolean activateWatchdog) { - this.activateWatchdog = activateWatchdog; - return this; - } - public MyConfig build() { return new MyConfig(this); } @@ -62,14 +52,12 @@ public String modbus_id() { return this.builder.modbusId; } - @Override - public int modbusUnitId() { - return 0; - } - @Override public String Modbus_target() { return ConfigUtils.generateReferenceTargetFilter(this.id(), this.modbus_id()); } - + @Override + public int modbusUnitId() { + return this.builder.modbusUnitId; + } } \ No newline at end of file From 654fdca9bdcf3a236b111c608846d4aea4a198cf Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Tue, 16 Apr 2024 08:45:33 +0200 Subject: [PATCH 20/25] Removed not needed Channels - commit 09fdc3ed8f20ce8577683fa21a1ba6c38d21b69a --- .../io/openems/edge/deye/common/Config.java | 4 +- .../edge/deye/common/DeyeSunHybrid.java | 910 +----------------- .../edge/deye/common/DeyeSunHybridImpl.java | 2 +- .../common/charger/AbstractEssDeyePv.java | 80 +- 4 files changed, 33 insertions(+), 963 deletions(-) diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/Config.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/Config.java index 8d1793036e2..be01901fefd 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/Config.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/Config.java @@ -5,7 +5,7 @@ @ObjectClassDefinition(// name = "Deye.BatteryInverter", // - description = "Deye.BatteryInverter") + description = "Implements the Deye Battery Inverter") @interface Config { @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") @@ -50,5 +50,5 @@ @AttributeDefinition(name = "Surplus Feed-In: PV-Limit on PowerDecreaseCausedByOvertemperature", description = "") int surplusFeedInPvLimitOnPowerDecreaseCausedByOvertemperature() default 5_000; - String webconsole_configurationFactory_nameHint() default "Deye [{id}]"; + String webconsole_configurationFactory_nameHint() default "Deye Battery Inverter [{id}]"; } diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java index 466bf5b65c3..e5d0dd77d95 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java @@ -62,91 +62,7 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { SET_GRID_LOAD_OFF_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT) // .accessMode(AccessMode.WRITE_ONLY)), // ), // - // Battery Channels - // AC 1/31/2024 - BATTERY_CAPACITY(Doc.of(OpenemsType.INTEGER).unit(Unit.AMPERE_HOURS).accessMode(AccessMode.READ_WRITE)), - BATTERY_CAPACITY_SHUTDOWN(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT)), - BATTERY_CAPACITY_RESTART(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT)), - BATTERY_CAPACITY_LOW_BATTERY(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT)), - MAX_A_BATTERY_CHARGE_CURRENT(Doc.of(OpenemsType.INTEGER).unit(Unit.AMPERE)), - MAX_A_BATTERY_DISCHARGE_CURRENT(Doc.of(OpenemsType.INTEGER).unit(Unit.AMPERE)), - PARALLEL_BAT_1_AND_BAT_2(Doc.of(OpenemsType.INTEGER)), BAT_1_SOC(Doc.of(OpenemsType.INTEGER)), - - // Battery Time of Use settings - // AC 2/16/2024 - TIME_OF_USE_SELLING_FLAG(Doc.of(OpenemsType.BOOLEAN).accessMode(AccessMode.READ_WRITE)), - - TIME_OF_USE_ENABLED_FLAG(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - TIME_OF_USE_MONDAY(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - TIME_OF_USE_TUESDAY(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - TIME_OF_USE_WEDNESDAY(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - TIME_OF_USE_THURSDAY(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - TIME_OF_USE_FRIDAY(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - TIME_OF_USE_SATURDAY(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - TIME_OF_USE_SUNDAY(Doc.of(OpenemsType.BOOLEAN) // - .accessMode(AccessMode.READ_WRITE)), // - - // Generator and Grid Channels - // AC 1/31/2024 - GEN_MAX_RUN_TIME(Doc.of(OpenemsType.INTEGER).unit(Unit.HOUR)), - GEN_COOLING_TIME(Doc.of(OpenemsType.INTEGER).unit(Unit.HOUR)), - GEN_CHARGING_STARTING_CAPACITY_POINT(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT)), - GEN_CHARGING_CURRENT_TO_BATTERY(Doc.of(OpenemsType.INTEGER).unit(Unit.AMPERE)), - GEN_CHARGE_ENABLED(Doc.of(OpenemsType.INTEGER)), - GRID_CHARGING_STARTING_CAPACITY_POINT(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT)), - GRID_CHARGING_CURRENT_TO_BATTERY(Doc.of(OpenemsType.INTEGER).unit(Unit.AMPERE)), - GRID_CHARGE_ENABLED(Doc.of(OpenemsType.INTEGER)), AC_COUPLE_FREQUENCY_CAP(Doc.of(OpenemsType.INTEGER)), - GEN_LOAD_OFF_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT)), - GEN_LOAD_ON_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT)), GEN_GRID_SIGNAL(Doc.of(OpenemsType.INTEGER)), - GEN_CONNECTED_TO_GRID_INPUT(Doc.of(OpenemsType.INTEGER)), - GEN_PEAK_SHAVING_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), - GRID_PEAK_SHAVING_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), - - // Solar Channels - // AC 1/31/2024 - SOLAR_SELL(Doc.of(OpenemsType.INTEGER)), - - TIME_POINT_1_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), - TIME_POINT_2_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), - TIME_POINT_3_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), - TIME_POINT_4_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), - TIME_POINT_5_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), - TIME_POINT_6_GRID_GEN_CHARGE_ENABLE(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), - - SELL_MODE_TIME_POINT_1(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_2(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_3(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_4(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_5(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_6(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_1_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_2_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_3_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_4_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_5_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_TIME_POINT_6_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_CAPACITY_1(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_CAPACITY_2(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_CAPACITY_3(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_CAPACITY_4(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_CAPACITY_5(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT).accessMode(AccessMode.READ_WRITE)), - SELL_MODE_CAPACITY_6(Doc.of(OpenemsType.INTEGER).unit(Unit.PERCENT).accessMode(AccessMode.READ_WRITE)), - MICROINVERTER_EXPORT_TO_GRID_CUTOFF(Doc.of(OpenemsType.INTEGER)), - SOLAR_ARC_FAULT_ON(Doc.of(OpenemsType.INTEGER)), - MAX_SOLAR_SELL_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.WATT)), - - // Other Channels - // AC 1/31/2024 - ZERO_EXPORT_POWER(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.WATT).accessMode(AccessMode.READ_WRITE)), - UPS_BACKUP_DELAY_TIME(Doc.of(OpenemsType.INTEGER).unit(Unit.SECONDS)), + // EnumWriteChannels SET_WORK_STATE(Doc.of(SetWorkState.values()) // @@ -216,542 +132,10 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { currentValueChannel.setNextValue(value); })), // - PROTOCOL_VERSION(Doc.of(OpenemsType.INTEGER)), // - BATTERY_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - BATTERY_CURRENT(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIAMPERE)), // - BATTERY_POWER(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.WATT)), // - AC_CHARGE_ENERGY(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.CUMULATED_WATT_HOURS)), // - AC_DISCHARGE_ENERGY(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.CUMULATED_WATT_HOURS)), // - GRID_ACTIVE_POWER(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.WATT)), // + APPARENT_POWER(Doc.of(OpenemsType.INTEGER) // .unit(Unit.VOLT_AMPERE)), // - CURRENT_L1(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIAMPERE)), // - CURRENT_L2(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIAMPERE)), // - CURRENT_L3(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIAMPERE)), // - VOLTAGE_L1(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - VOLTAGE_L2(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - VOLTAGE_L3(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - FREQUENCY(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIHERTZ)), // - INVERTER_VOLTAGE_L1(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - INVERTER_VOLTAGE_L2(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - INVERTER_VOLTAGE_L3(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - INVERTER_CURRENT_L1(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIAMPERE)), // - INVERTER_CURRENT_L2(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIAMPERE)), // - INVERTER_CURRENT_L3(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIAMPERE)), // - IPM_TEMPERATURE_L1(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.DEGREE_CELSIUS)), // - IPM_TEMPERATURE_L2(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.DEGREE_CELSIUS)), // - IPM_TEMPERATURE_L3(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.DEGREE_CELSIUS)), // - TRANSFORMER_TEMPERATURE_L2(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.DEGREE_CELSIUS)), // - BATTERY_STRING_TOTAL_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - BATTERY_STRING_TOTAL_CURRENT(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIAMPERE)), // - BATTERY_STRING_SOH(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.PERCENT)), // - BATTERY_STRING_AVG_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.DEGREE_CELSIUS)), // - BATTERY_STRING_CHARGE_CURRENT_LIMIT(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIAMPERE)), // - BATTERY_STRING_DISCHARGE_CURRENT_LIMIT(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIAMPERE)), // - BATTERY_STRING_CYCLES(Doc.of(OpenemsType.INTEGER)), // - BATTERY_STRING_CHARGE_ENERGY(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.CUMULATED_WATT_HOURS)), // - BATTERY_STRING_DISCHARGE_ENERGY(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.CUMULATED_WATT_HOURS)), // - BATTERY_STRING_POWER(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.WATT)), // - BATTERY_STRING_MAX_CELL_VOLTAGE_NO(Doc.of(OpenemsType.INTEGER)), // - BATTERY_STRING_MAX_CELL_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - BATTERY_STRING_MAX_CELL_VOLTAGE_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.DEGREE_CELSIUS)), // - BATTERY_STRING_MIN_CELL_VOLTAGE_NO(Doc.of(OpenemsType.INTEGER)), // - BATTERY_STRING_MIN_CELL_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - BATTERY_STRING_MIN_CELL_VOLTAGE_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.DEGREE_CELSIUS)), // - BATTERY_STRING_MAX_CELL_TEMPERATURE_NO(Doc.of(OpenemsType.INTEGER)), // - BATTERY_STRING_MAX_CELL_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.DEGREE_CELSIUS)), // - BATTERY_STRING_MAX_CELL_TEMPERATURE_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - BATTERY_STRING_MIN_CELL_TEMPERATURE_NO(Doc.of(OpenemsType.INTEGER)), // - BATTERY_STRING_MIN_CELL_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.DEGREE_CELSIUS)), // - BATTERY_STRING_MIN_CELL_TEMPERATURE_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_1_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_2_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_3_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_4_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_5_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_6_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_7_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_8_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_9_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_10_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_11_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_12_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_13_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_14_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_15_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_16_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_17_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_18_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_19_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_20_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_21_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_22_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_23_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_24_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_25_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_26_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_27_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_28_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_29_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_30_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_31_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_32_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_33_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_34_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_35_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_36_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_37_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_38_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_39_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_40_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_41_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_42_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_43_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_44_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_45_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_46_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_47_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_48_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_49_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_50_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_51_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_52_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_53_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_54_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_55_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_56_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_57_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_58_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_59_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_60_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_61_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_62_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_63_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_64_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_65_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_66_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_67_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_68_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_69_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_70_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_71_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_72_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_73_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_74_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_75_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_76_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_77_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_78_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_79_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_80_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_81_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_82_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_83_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_84_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_85_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_86_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_87_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_88_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_89_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_90_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_91_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_92_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_93_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_94_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_95_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_96_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_97_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_98_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_99_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_100_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_101_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_102_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_103_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_104_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_105_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_106_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_107_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_108_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_109_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_110_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_111_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_112_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_113_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_114_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_115_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_116_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_117_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_118_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_119_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_120_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_121_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_122_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_123_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_124_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_125_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_126_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_127_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_128_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_129_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_130_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_131_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_132_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_133_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_134_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_135_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_136_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_137_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_138_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_139_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_140_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_141_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_142_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_143_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_144_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_145_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_146_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_147_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_148_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_149_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_150_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_151_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_152_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_153_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_154_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_155_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_156_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_157_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_158_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_159_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_160_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_161_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_162_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_163_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_164_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_165_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_166_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_167_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_168_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_169_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_170_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_171_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_172_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_173_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_174_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_175_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_176_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_177_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_178_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_179_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_180_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_181_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_182_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_183_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_184_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_185_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_186_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_187_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_188_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_189_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_190_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_191_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_192_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_193_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_194_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_195_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_196_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_197_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_198_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_199_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_200_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_201_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_202_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_203_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_204_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_205_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_206_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_207_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_208_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_209_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_210_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_211_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_212_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_213_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_214_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_215_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_216_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_217_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_218_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_219_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_220_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_221_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_222_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_223_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - CELL_224_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // + // StateChannels SYSTEM_ERROR(Doc.of(Level.FAULT) // @@ -788,206 +172,6 @@ public Doc doc() { * Source-Channels for {@link ChannelId#SYSTEM_ERROR}. */ public static enum SystemErrorChannelId implements io.openems.edge.common.channel.ChannelId { - STATE_2(Doc.of(OpenemsType.BOOLEAN) // - .text("Transformer Phase B Temperature Sensor Invalidation")), - STATE_3(Doc.of(OpenemsType.BOOLEAN) // - .text("SD Memory Card Invalidation")), // - STATE_4(Doc.of(OpenemsType.BOOLEAN) // - .text("Inverter Communication Abnormity")), // - STATE_5(Doc.of(OpenemsType.BOOLEAN) // - .text("Battery Stack Communication Abnormity")), // - STATE_6(Doc.of(OpenemsType.BOOLEAN) // - .text("Multifunctional Ammeter Communication Abnormity")), // - STATE_7(Doc.of(OpenemsType.BOOLEAN) // - .text("Remote Communication Abnormity")), // - STATE_8(Doc.of(OpenemsType.BOOLEAN) // - .text("PVDC1 Communication Abnormity")), // - STATE_9(Doc.of(OpenemsType.BOOLEAN) // - .text("PVDC2 Communication Abnormity")), // - STATE_10(Doc.of(OpenemsType.BOOLEAN) // - .text("Transformer Severe Overtemperature")), // - STATE_11(Doc.of(OpenemsType.BOOLEAN) // - .text("DC Precharge Contactor Close Unsuccessfully")), // - STATE_12(Doc.of(OpenemsType.BOOLEAN) // - .text("AC Precharge Contactor Close Unsuccessfully")), // - STATE_13(Doc.of(OpenemsType.BOOLEAN) // - .text("AC Main Contactor Close Unsuccessfully")), // - STATE_14(Doc.of(OpenemsType.BOOLEAN) // - .text("DC Electrical Breaker1 Close Unsuccessfully")), // - STATE_15(Doc.of(OpenemsType.BOOLEAN) // - .text("DC Main Contactor Close Unsuccessfully")), // - STATE_16(Doc.of(OpenemsType.BOOLEAN) // - .text("AC Breaker Trip")), // - STATE_17(Doc.of(OpenemsType.BOOLEAN) // - .text("AC Main Contactor Open When Running")), // - STATE_18(Doc.of(OpenemsType.BOOLEAN) // - .text("DC Main Contactor Open When Running")), // - STATE_19(Doc.of(OpenemsType.BOOLEAN) // - .text("AC Main Contactor Open Unsuccessfully")), // - STATE_20(Doc.of(OpenemsType.BOOLEAN) // - .text("DC Electrical Breaker1 Open Unsuccessfully")), // - STATE_21(Doc.of(OpenemsType.BOOLEAN) // - .text("DC Main Contactor Open Unsuccessfully")), // - STATE_22(Doc.of(OpenemsType.BOOLEAN) // - .text("Hardware PDP Fault")), // - STATE_23(Doc.of(OpenemsType.BOOLEAN) // - .text("Master Stop Suddenly")), // - STATE_24(Doc.of(OpenemsType.BOOLEAN) // - .text("DCShortCircuitProtection")), // - STATE_25(Doc.of(OpenemsType.BOOLEAN) // - .text("DCOvervoltageProtection")), // - STATE_26(Doc.of(OpenemsType.BOOLEAN) // - .text("DCUndervoltageProtection")), // - STATE_28(Doc.of(OpenemsType.BOOLEAN) // - .text("DCDisconnectionProtection")), // - STATE_29(Doc.of(OpenemsType.BOOLEAN) // - .text("CommutingVoltageAbnormityProtection")), // - STATE_30(Doc.of(OpenemsType.BOOLEAN) // - .text("DCOvercurrentProtection")), // - STATE_31(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase1PeakCurrentOverLimitProtection")), // - STATE_32(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase2PeakCurrentOverLimitProtection")), // - STATE_33(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase3PeakCurrentOverLimitProtection")), // - STATE_34(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase1GridVoltageSamplingInvalidation")), // - STATE_35(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase2VirtualCurrentOverLimitProtection")), // - STATE_36(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase3VirtualCurrentOverLimitProtection")), // - STATE_37(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase1GridVoltageSamplingInvalidation2")), // - STATE_38(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase2ridVoltageSamplingInvalidation")), // - STATE_39(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase3GridVoltageSamplingInvalidation")), // - STATE_40(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase1InvertVoltageSamplingInvalidation")), // - STATE_41(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase2InvertVoltageSamplingInvalidation")), // - STATE_42(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase3InvertVoltageSamplingInvalidation")), // - STATE_43(Doc.of(OpenemsType.BOOLEAN) // - .text("ACCurrentSamplingInvalidation")), // - STATE_44(Doc.of(OpenemsType.BOOLEAN) // - .text("DCCurrentSamplingInvalidation")), // - STATE_45(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase1OvertemperatureProtection")), // - STATE_46(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase2OvertemperatureProtection")), // - STATE_47(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase3OvertemperatureProtection")), // - STATE_48(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase1TemperatureSamplingInvalidation")), // - STATE_49(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase2TemperatureSamplingInvalidation")), // - STATE_50(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase3TemperatureSamplingInvalidation")), // - STATE_51(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase1PrechargeUnmetProtection")), // - STATE_52(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase2PrechargeUnmetProtection")), // - STATE_53(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase3PrechargeUnmetProtection")), // - STATE_54(Doc.of(OpenemsType.BOOLEAN) // - .text("UnadaptablePhaseSequenceErrorProtection")), // - STATE_55(Doc.of(OpenemsType.BOOLEAN) // - .text("DSPProtection")), // - STATE_85(Doc.of(OpenemsType.BOOLEAN) // - .text("InverterPeakVoltageHighProtectionCauseByACDisconnect")), // - STATE_86(Doc.of(OpenemsType.BOOLEAN) // - .text("DCPrechargeContactorInspectionAbnormity")), // - STATE_87(Doc.of(OpenemsType.BOOLEAN) // - .text("DCBreaker1InspectionAbnormity")), // - STATE_88(Doc.of(OpenemsType.BOOLEAN) // - .text("DCBreaker2InspectionAbnormity")), // - STATE_89(Doc.of(OpenemsType.BOOLEAN) // - .text("ACPrechargeContactorInspectionAbnormity")), // - STATE_90(Doc.of(OpenemsType.BOOLEAN) // - .text("ACMainontactorInspectionAbnormity")), // - STATE_91(Doc.of(OpenemsType.BOOLEAN) // - .text("ACBreakerInspectionAbnormity")), // - STATE_92(Doc.of(OpenemsType.BOOLEAN) // - .text("DCBreaker1CloseUnsuccessfully")), // - STATE_93(Doc.of(OpenemsType.BOOLEAN) // - .text("DCBreaker2CloseUnsuccessfully")), // - STATE_94(Doc.of(OpenemsType.BOOLEAN) // - .text("ControlSignalCloseAbnormallyInspectedBySystem")), // - STATE_95(Doc.of(OpenemsType.BOOLEAN) // - .text("ControlSignalOpenAbnormallyInspectedBySystem")), // - STATE_96(Doc.of(OpenemsType.BOOLEAN) // - .text("NeutralWireContactorCloseUnsuccessfully")), // - STATE_97(Doc.of(OpenemsType.BOOLEAN) // - .text("NeutralWireContactorOpenUnsuccessfully")), // - STATE_98(Doc.of(OpenemsType.BOOLEAN) // - .text("WorkDoorOpen")), // - STATE_99(Doc.of(OpenemsType.BOOLEAN) // - .text("Emergency1Stop")), // - STATE_100(Doc.of(OpenemsType.BOOLEAN) // - .text("ACBreakerCloseUnsuccessfully")), // - STATE_101(Doc.of(OpenemsType.BOOLEAN) // - .text("ControlSwitchStop")), // - STATE_102(Doc.of(OpenemsType.BOOLEAN) // - .text("GeneralOverload")), // - STATE_103(Doc.of(OpenemsType.BOOLEAN) // - .text("SevereOverload")), // - STATE_104(Doc.of(OpenemsType.BOOLEAN) // - .text("BatteryCurrentOverLimit")), // - STATE_106(Doc.of(OpenemsType.BOOLEAN) // - .text("InverterGeneralOvertemperature")), // - STATE_107(Doc.of(OpenemsType.BOOLEAN) // - .text("ACThreePhaseCurrentUnbalance")), // - STATE_108(Doc.of(OpenemsType.BOOLEAN) // - .text("RestoreFactorySettingUnsuccessfully")), // - STATE_109(Doc.of(OpenemsType.BOOLEAN) // - .text("PoleBoardInvalidation")), // - STATE_110(Doc.of(OpenemsType.BOOLEAN) // - .text("SelfInspectionFailed")), // - STATE_111(Doc.of(OpenemsType.BOOLEAN) // - .text("ReceiveBMSFaultAndStop")), // - STATE_112(Doc.of(OpenemsType.BOOLEAN) // - .text("RefrigerationEquipmentinvalidation")), // - STATE_113(Doc.of(OpenemsType.BOOLEAN) // - .text("LargeTemperatureDifferenceAmongIGBTThreePhases")), // - STATE_114(Doc.of(OpenemsType.BOOLEAN) // - .text("EEPROMParametersOverRange")), // - STATE_115(Doc.of(OpenemsType.BOOLEAN) // - .text("EEPROMParametersBackupFailed")), // - STATE_116(Doc.of(OpenemsType.BOOLEAN) // - .text("DCBreakerCloseunsuccessfully")), // - STATE_117(Doc.of(OpenemsType.BOOLEAN) // - .text("CommunicationBetweenInverterAndBSMUDisconnected")), // - STATE_118(Doc.of(OpenemsType.BOOLEAN) // - .text("CommunicationBetweenInverterAndMasterDisconnected")), // - STATE_119(Doc.of(OpenemsType.BOOLEAN) // - .text("CommunicationBetweenInverterAndUCDisconnected")), // - STATE_120(Doc.of(OpenemsType.BOOLEAN) // - .text("BMSStartOvertimeControlledByPCS")), // - STATE_121(Doc.of(OpenemsType.BOOLEAN) // - .text("BMSStopOvertimeControlledByPCS")), // - STATE_122(Doc.of(OpenemsType.BOOLEAN) // - .text("SyncSignalInvalidation")), // - STATE_123(Doc.of(OpenemsType.BOOLEAN) // - .text("SyncSignalContinuousCaputureFault")), // - STATE_124(Doc.of(OpenemsType.BOOLEAN) // - .text("SyncSignalSeveralTimesCaputureFault")), // - STATE_125(Doc.of(OpenemsType.BOOLEAN) // - .text("CurrentSamplingChannelAbnormityOnHighVoltageSide")), // - STATE_126(Doc.of(OpenemsType.BOOLEAN) // - .text("CurrentSamplingChannelAbnormityOnLowVoltageSide")), // - STATE_127(Doc.of(OpenemsType.BOOLEAN) // - .text("EEPROMParametersOverRange")), // - STATE_128(Doc.of(OpenemsType.BOOLEAN) // - .text("UpdateEEPROMFailed")), // - STATE_129(Doc.of(OpenemsType.BOOLEAN) // - .text("ReadEEPROMFailed")), // - STATE_130(Doc.of(OpenemsType.BOOLEAN) // - .text("CurrentSamplingChannelAbnormityBeforeInductance")), // - STATE_147(Doc.of(OpenemsType.BOOLEAN) // - .text("HighVoltageSideOvervoltage")), // - STATE_148(Doc.of(OpenemsType.BOOLEAN) // - .text("HighVoltageSideUndervoltage")), // STATE_149(Doc.of(OpenemsType.BOOLEAN) // .text("HighVoltageSideVoltageChangeUnconventionally")) // ; @@ -1009,62 +193,6 @@ public Doc doc() { * Source-Channels for {@link ChannelId#INSUFFICIENT_GRID_PARAMTERS}. */ public static enum InsufficientGridParametersChannelId implements io.openems.edge.common.channel.ChannelId { - STATE_56(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase1GridVoltageSevereOvervoltageProtection")), // - STATE_57(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase1GridVoltageGeneralOvervoltageProtection")), // - STATE_58(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase2GridVoltageSevereOvervoltageProtection")), // - STATE_59(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase2GridVoltageGeneralOvervoltageProtection")), // - STATE_60(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase3GridVoltageSevereOvervoltageProtection")), // - STATE_61(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase3GridVoltageGeneralOvervoltageProtection")), // - STATE_62(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase1GridVoltageSevereUndervoltageProtection")), // - STATE_63(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase1GridVoltageGeneralUndervoltageProtection")), // - STATE_64(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase2GridVoltageSevereUndervoltageProtection")), // - STATE_65(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase2GridVoltageGeneralUndervoltageProtection")), // - STATE_66(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase3GridVoltageSevereUndervoltageProtection")), // - STATE_67(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase3GridVoltageGeneralUndervoltageProtection")), // - STATE_68(Doc.of(OpenemsType.BOOLEAN) // - .text("SevereOverfrequncyProtection")), // - STATE_69(Doc.of(OpenemsType.BOOLEAN) // - .text("GeneralOverfrequncyProtection")), // - STATE_70(Doc.of(OpenemsType.BOOLEAN) // - .text("SevereUnderfrequncyProtection")), // - STATE_71(Doc.of(OpenemsType.BOOLEAN) // - .text("GeneralsUnderfrequncyProtection")), // - STATE_72(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase1Gridloss")), // - STATE_73(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase2Gridloss")), // - STATE_74(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase3Gridloss")), // - STATE_75(Doc.of(OpenemsType.BOOLEAN) // - .text("IslandingProtection")), // - STATE_76(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase1UnderVoltageRideThrough")), // - STATE_77(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase2UnderVoltageRideThrough")), // - STATE_78(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase3UnderVoltageRideThrough")), // - STATE_79(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase1InverterVoltageSevereOvervoltageProtection")), // - STATE_80(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase1InverterVoltageGeneralOvervoltageProtection")), // - STATE_81(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase2InverterVoltageSevereOvervoltageProtection")), // - STATE_82(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase2InverterVoltageGeneralOvervoltageProtection")), // - STATE_83(Doc.of(OpenemsType.BOOLEAN) // - .text("Phase3InverterVoltageSevereOvervoltageProtection")), // STATE_84(Doc.of(OpenemsType.BOOLEAN) // .text("Phase3InverterVoltageGeneralOvervoltageProtection")), // ; @@ -1088,38 +216,6 @@ public Doc doc() { */ public static enum PowerDecreaseCausedByOvertemperatureChannelId implements io.openems.edge.common.channel.ChannelId { - STATE_105(Doc.of(OpenemsType.BOOLEAN) // - .text("PowerDecreaseCausedByOvertemperature")), // - STATE_131(Doc.of(OpenemsType.BOOLEAN) // - .text("ReactorPowerDecreaseCausedByOvertemperature")), // - STATE_132(Doc.of(OpenemsType.BOOLEAN) // - .text("IGBTPowerDecreaseCausedByOvertemperature")), // - STATE_133(Doc.of(OpenemsType.BOOLEAN) // - .text("TemperatureChanel3PowerDecreaseCausedByOvertemperature")), // - STATE_134(Doc.of(OpenemsType.BOOLEAN) // - .text("TemperatureChanel4PowerDecreaseCausedByOvertemperature")), // - STATE_135(Doc.of(OpenemsType.BOOLEAN) // - .text("TemperatureChanel5PowerDecreaseCausedByOvertemperature")), // - STATE_136(Doc.of(OpenemsType.BOOLEAN) // - .text("TemperatureChanel6PowerDecreaseCausedByOvertemperature")), // - STATE_137(Doc.of(OpenemsType.BOOLEAN) // - .text("TemperatureChanel7PowerDecreaseCausedByOvertemperature")), // - STATE_138(Doc.of(OpenemsType.BOOLEAN) // - .text("TemperatureChanel8PowerDecreaseCausedByOvertemperature")), // - STATE_139(Doc.of(OpenemsType.BOOLEAN) // - .text("Fan1StopFailed")), // - STATE_140(Doc.of(OpenemsType.BOOLEAN) // - .text("Fan2StopFailed")), // - STATE_141(Doc.of(OpenemsType.BOOLEAN) // - .text("Fan3StopFailed")), // - STATE_142(Doc.of(OpenemsType.BOOLEAN) // - .text("Fan4StopFailed")), // - STATE_143(Doc.of(OpenemsType.BOOLEAN) // - .text("Fan1StartupFailed")), // - STATE_144(Doc.of(OpenemsType.BOOLEAN) // - .text("Fan2StartupFailed")), // - STATE_145(Doc.of(OpenemsType.BOOLEAN) // - .text("Fan3StartupFailed")), // STATE_146(Doc.of(OpenemsType.BOOLEAN) // .text("Fan4StartupFailed")); diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java index 045d0cebe0c..c56e8ca1926 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java @@ -64,7 +64,7 @@ @Designate(ocd = Config.class, factory = true) @Component(// - name = "Deye.BatteryInverter1", // + name = "Deye.BatteryInverter", // immediate = true, // configurationPolicy = ConfigurationPolicy.REQUIRE // ) diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/AbstractEssDeyePv.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/AbstractEssDeyePv.java index 6ce46d380af..a90ee26990d 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/AbstractEssDeyePv.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/AbstractEssDeyePv.java @@ -26,9 +26,8 @@ import static io.openems.edge.bridge.modbus.api.ElementToChannelConverter.SCALE_FACTOR_2; -public abstract class AbstractEssDeyePv extends AbstractOpenemsModbusComponent - implements DeyeSunPv, EssDcCharger, ModbusComponent, OpenemsComponent, TimedataProvider, - EventHandler, ModbusSlave { +public abstract class AbstractEssDeyePv extends AbstractOpenemsModbusComponent implements DeyeSunPv, EssDcCharger, + ModbusComponent, OpenemsComponent, TimedataProvider, EventHandler, ModbusSlave { private final CalculateEnergyFromPower calculateActualEnergy = new CalculateEnergyFromPower(this, EssDcCharger.ChannelId.ACTUAL_ENERGY); @@ -54,8 +53,7 @@ public AbstractEssDeyePv() { protected ModbusProtocol defineModbusProtocol() throws OpenemsException { var protocol = new ModbusProtocol(this, // new FC16WriteRegistersTask(0x0503, // - m(DeyeSunPv.ChannelId.SET_PV_POWER_LIMIT, new UnsignedWordElement(0x0503), - SCALE_FACTOR_2))); // + m(DeyeSunPv.ChannelId.SET_PV_POWER_LIMIT, new UnsignedWordElement(0x0503), SCALE_FACTOR_2))); // if (this.isPV1()) { protocol.addTasks(// @@ -64,23 +62,18 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException { SCALE_FACTOR_2), // m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_CURRENT, new SignedWordElement(0xA131), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_POWER, new SignedWordElement(0xA132), - SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_POWER, new SignedWordElement(0xA132), SCALE_FACTOR_2), // m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_VOLTAGE, new SignedWordElement(0xA133), SCALE_FACTOR_2), // m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_CURRENT, new SignedWordElement(0xA134), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_POWER, new SignedWordElement(0xA135), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_ENERGY, new SignedWordElement(0xA136), - SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_POWER, new SignedWordElement(0xA135), SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_ENERGY, new SignedWordElement(0xA136), SCALE_FACTOR_2), // m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_ENERGY, new SignedWordElement(0xA137), SCALE_FACTOR_2), // new DummyRegisterElement(0xA138, 0xA13F), // - m(DeyeSunPv.ChannelId.BMS_DCDC_REACTOR_TEMPERATURE, - new SignedWordElement(0xA140)), // - m(DeyeSunPv.ChannelId.BMS_DCDC_IGBT_TEMPERATURE, - new SignedWordElement(0xA141)), // + m(DeyeSunPv.ChannelId.BMS_DCDC_REACTOR_TEMPERATURE, new SignedWordElement(0xA140)), // + m(DeyeSunPv.ChannelId.BMS_DCDC_IGBT_TEMPERATURE, new SignedWordElement(0xA141)), // new DummyRegisterElement(0xA142, 0xA14F), // m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_CHARGE_ENERGY, new UnsignedDoublewordElement(0xA150).wordOrder(WordOrder.LSWMSW), // @@ -100,22 +93,15 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException { SCALE_FACTOR_2), // m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_CURRENT, new SignedWordElement(0xA731), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_POWER, new SignedWordElement(0xA732), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_VOLTAGE, new SignedWordElement(0xA733), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_CURRENT, new SignedWordElement(0xA734), - SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_POWER, new SignedWordElement(0xA732), SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_VOLTAGE, new SignedWordElement(0xA733), SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_CURRENT, new SignedWordElement(0xA734), SCALE_FACTOR_2), // m(EssDcCharger.ChannelId.ACTUAL_POWER, new SignedWordElement(0xA735), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_ENERGY, new SignedWordElement(0xA736), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_ENERGY, new SignedWordElement(0xA737), - SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_ENERGY, new SignedWordElement(0xA736), SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_ENERGY, new SignedWordElement(0xA737), SCALE_FACTOR_2), // new DummyRegisterElement(0xA738, 0xA73F), // - m(DeyeSunPv.ChannelId.PV_DCDC_REACTOR_TEMPERATURE, - new SignedWordElement(0xA740)), // - m(DeyeSunPv.ChannelId.PV_DCDC_IGBT_TEMPERATURE, - new SignedWordElement(0xA741)), // + m(DeyeSunPv.ChannelId.PV_DCDC_REACTOR_TEMPERATURE, new SignedWordElement(0xA740)), // + m(DeyeSunPv.ChannelId.PV_DCDC_IGBT_TEMPERATURE, new SignedWordElement(0xA741)), // new DummyRegisterElement(0xA742, 0xA74F), // m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_CHARGE_ENERGY, new UnsignedDoublewordElement(0xA750).wordOrder(WordOrder.LSWMSW), // @@ -137,22 +123,15 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException { SCALE_FACTOR_2), // m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_CURRENT, new SignedWordElement(0xAA31), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_POWER, new SignedWordElement(0xAA32), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_VOLTAGE, new SignedWordElement(0xAA33), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_CURRENT, new SignedWordElement(0xAA34), - SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_POWER, new SignedWordElement(0xAA32), SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_VOLTAGE, new SignedWordElement(0xAA33), SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_CURRENT, new SignedWordElement(0xAA34), SCALE_FACTOR_2), // m(EssDcCharger.ChannelId.ACTUAL_POWER, new SignedWordElement(0xAA35), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_ENERGY, new SignedWordElement(0xAA36), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_ENERGY, new SignedWordElement(0xAA37), - SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_ENERGY, new SignedWordElement(0xAA36), SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_ENERGY, new SignedWordElement(0xAA37), SCALE_FACTOR_2), // new DummyRegisterElement(0xAA38, 0xAA3F), // - m(DeyeSunPv.ChannelId.PV_DCDC_REACTOR_TEMPERATURE, - new SignedWordElement(0xAA40)), // - m(DeyeSunPv.ChannelId.PV_DCDC_IGBT_TEMPERATURE, - new SignedWordElement(0xAA41)), // + m(DeyeSunPv.ChannelId.PV_DCDC_REACTOR_TEMPERATURE, new SignedWordElement(0xAA40)), // + m(DeyeSunPv.ChannelId.PV_DCDC_IGBT_TEMPERATURE, new SignedWordElement(0xAA41)), // new DummyRegisterElement(0xAA42, 0xAA4F), // m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_CHARGE_ENERGY, new UnsignedDoublewordElement(0xAA50).wordOrder(WordOrder.LSWMSW), // @@ -171,23 +150,18 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException { SCALE_FACTOR_2), // m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_CURRENT, new SignedWordElement(0xA431), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_POWER, new SignedWordElement(0xA432), - SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_POWER, new SignedWordElement(0xA432), SCALE_FACTOR_2), // m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_VOLTAGE, new SignedWordElement(0xA433), SCALE_FACTOR_2), // m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_CURRENT, new SignedWordElement(0xA434), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_POWER, new SignedWordElement(0xA435), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_ENERGY, new SignedWordElement(0xA436), - SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_POWER, new SignedWordElement(0xA435), SCALE_FACTOR_2), // + m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_ENERGY, new SignedWordElement(0xA436), SCALE_FACTOR_2), // m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_ENERGY, new SignedWordElement(0xA437), SCALE_FACTOR_2), // new DummyRegisterElement(0xA438, 0xA43F), // - m(DeyeSunPv.ChannelId.BMS_DCDC_REACTOR_TEMPERATURE, - new SignedWordElement(0xA440)), // - m(DeyeSunPv.ChannelId.BMS_DCDC_IGBT_TEMPERATURE, - new SignedWordElement(0xA441)), // + m(DeyeSunPv.ChannelId.BMS_DCDC_REACTOR_TEMPERATURE, new SignedWordElement(0xA440)), // + m(DeyeSunPv.ChannelId.BMS_DCDC_IGBT_TEMPERATURE, new SignedWordElement(0xA441)), // new DummyRegisterElement(0xA442, 0xA44F), // m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_CHARGE_ENERGY, new UnsignedDoublewordElement(0xA450).wordOrder(WordOrder.LSWMSW), // From 94cd89b90bb85b951631af06a78defd6b7dba7f9 Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Tue, 16 Apr 2024 08:52:37 +0200 Subject: [PATCH 21/25] Remove not necessary code --- .../edge/deye/common/DeyeSunHybrid.java | 16 -- .../edge/deye/common/DeyeSunHybridImpl.java | 50 +--- .../deye/common/SurplusFeedInHandler.java | 211 ----------------- .../common/charger/AbstractEssDeyePv.java | 219 ------------------ .../edge/deye/common/charger/ConfigPv1.java | 30 --- .../edge/deye/common/charger/ConfigPv2.java | 30 --- .../deye/common/charger/DeyeSun2Impl.java | 94 -------- .../edge/deye/common/charger/DeyeSunImpl.java | 92 -------- .../edge/deye/common/charger/DeyeSunPv.java | 97 -------- 9 files changed, 2 insertions(+), 837 deletions(-) delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInHandler.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/AbstractEssDeyePv.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv1.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv2.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSun2Impl.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunImpl.java delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunPv.java diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java index e5d0dd77d95..4a1f88d36ec 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java @@ -11,7 +11,6 @@ import io.openems.edge.common.channel.StateChannel; import io.openems.edge.common.component.OpenemsComponent; import io.openems.edge.common.modbusslave.ModbusSlave; -import io.openems.edge.deye.common.charger.DeyeSunPv; import io.openems.edge.ess.api.ManagedSymmetricEss; import io.openems.edge.ess.api.SymmetricEss; import io.openems.edge.timedata.api.TimedataProvider; @@ -34,20 +33,6 @@ public interface DeyeSunHybrid */ public String getModbusBridgeId(); - /** - * Registers a Charger with this ESS. - * - * @param charger the Charger - */ - public void addCharger(DeyeSunPv charger); - - /** - * Unregisters a Charger from this ESS. - * - * @param charger the Charger - */ - public void removeCharger(DeyeSunPv charger); - public enum ChannelId implements io.openems.edge.common.channel.ChannelId { // EnumReadChannels SERIAL_NUMBER(Doc.of(OpenemsType.STRING) // @@ -55,7 +40,6 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId { .accessMode(AccessMode.READ_ONLY)), SURPLUS_FEED_IN_POWER(Doc.of(OpenemsType.INTEGER) // .unit(Unit.WATT)), // - SURPLUS_FEED_IN_STATE_MACHINE(Doc.of(SurplusFeedInStateMachine.values())), // Gen Port Use Channels // AC 1/28/2024 diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java index c56e8ca1926..ded1ce32c72 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java @@ -7,14 +7,12 @@ import io.openems.edge.bridge.modbus.api.BridgeModbus; import io.openems.edge.bridge.modbus.api.ModbusComponent; import io.openems.edge.bridge.modbus.api.ModbusProtocol; -import io.openems.edge.bridge.modbus.api.element.BitsWordElement; import io.openems.edge.bridge.modbus.api.element.DummyRegisterElement; import io.openems.edge.bridge.modbus.api.element.SignedWordElement; import io.openems.edge.bridge.modbus.api.element.StringWordElement; import io.openems.edge.bridge.modbus.api.element.UnsignedWordElement; import io.openems.edge.bridge.modbus.api.task.FC16WriteRegistersTask; import io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask; -import io.openems.edge.bridge.modbus.api.task.FC6WriteRegisterTask; import io.openems.edge.common.channel.EnumWriteChannel; import io.openems.edge.common.channel.IntegerWriteChannel; import io.openems.edge.common.channel.StateChannel; @@ -24,8 +22,6 @@ import io.openems.edge.common.modbusslave.ModbusSlave; import io.openems.edge.common.modbusslave.ModbusSlaveTable; import io.openems.edge.common.taskmanager.Priority; -import io.openems.edge.common.type.TypeUtils; -import io.openems.edge.deye.common.charger.DeyeSunPv; import io.openems.edge.ess.api.HybridEss; import io.openems.edge.ess.api.ManagedSymmetricEss; import io.openems.edge.ess.api.SymmetricEss; @@ -55,12 +51,6 @@ import org.slf4j.LoggerFactory; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - -import static io.openems.edge.bridge.modbus.api.ElementToChannelConverter.SCALE_FACTOR_1; -import static io.openems.edge.bridge.modbus.api.ElementToChannelConverter.SCALE_FACTOR_MINUS_1; -import static io.openems.edge.bridge.modbus.api.ElementToChannelConverter.SCALE_FACTOR_MINUS_2; @Designate(ocd = Config.class, factory = true) @Component(// @@ -73,7 +63,7 @@ EdgeEventConstants.TOPIC_CYCLE_BEFORE_CONTROLLERS // }) public class DeyeSunHybridImpl extends AbstractOpenemsModbusComponent implements DeyeSunHybrid, ManagedSymmetricEss, - SymmetricEss, HybridEss, ModbusComponent, OpenemsComponent, EventHandler, ModbusSlave, TimedataProvider { + SymmetricEss, ModbusComponent, OpenemsComponent, EventHandler, ModbusSlave, TimedataProvider { protected static final int MAX_APPARENT_POWER = 40000; @@ -97,10 +87,7 @@ public class DeyeSunHybridImpl extends AbstractOpenemsModbusComponent implements private final CalculateEnergyFromPower calculateDcDischargeEnergy = new CalculateEnergyFromPower(this, HybridEss.ChannelId.DC_DISCHARGE_ENERGY); - private final List chargers = new ArrayList<>(); - - private final SurplusFeedInHandler surplusFeedInHandler = new SurplusFeedInHandler(this); - + @Reference private ComponentManager componentManager; @@ -172,16 +159,6 @@ public String getModbusBridgeId() { return this.config.modbus_id(); } - @Override - public void addCharger(DeyeSunPv charger) { - - } - - @Override - public void removeCharger(DeyeSunPv charger) { - - } - @Override protected ModbusProtocol defineModbusProtocol() throws OpenemsException { return new ModbusProtocol(this, // @@ -321,29 +298,11 @@ private void applyPowerLimitOnPowerDecreaseCausedByOvertemperatureError() { } catch (OpenemsException e) { this.logError(this.log, e.getMessage()); } - /* - * Apply limit on Charger - */ - if (this.chargers.size() > 0) { - IntegerWriteChannel setPvPowerLimit = this.chargers.get(0) - .channel(DeyeSunPv.ChannelId.SET_PV_POWER_LIMIT); - try { - setPvPowerLimit.setNextWriteValue( - this.config.powerLimitOnPowerDecreaseCausedByOvertemperatureChannel()); - } catch (OpenemsNamedException e) { - this.logError(this.log, e.getMessage()); - } - } } } } - @Override - public Integer getSurplusPower() { - return this.surplusFeedInHandler.run(this.chargers, this.config, this.componentManager); - } - @Override public Timedata getTimedata() { return this.timedata; @@ -372,11 +331,6 @@ private void calculateEnergy() { * Calculate DC Power and Energy */ var dcDischargePower = acActivePower; - for (DeyeSunPv charger : this.chargers) { - dcDischargePower = TypeUtils.subtract(dcDischargePower, - charger.getActualPowerChannel().getNextValue().get()); - } - this._setDcDischargePower(dcDischargePower); if (dcDischargePower == null) { // Not available diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInHandler.java deleted file mode 100644 index b202b9d626f..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInHandler.java +++ /dev/null @@ -1,211 +0,0 @@ -package io.openems.edge.deye.common; - -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.common.utils.DoubleUtils; -import io.openems.edge.common.channel.IntegerReadChannel; -import io.openems.edge.common.channel.IntegerWriteChannel; -import io.openems.edge.common.channel.StateChannel; -import io.openems.edge.common.component.ComponentManager; -import io.openems.edge.deye.common.charger.DeyeSunPv; -import io.openems.edge.ess.dccharger.api.EssDcCharger; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.time.Duration; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.util.List; - -public class SurplusFeedInHandler { - - private static final int GOING_DEACTIVATED_MINUTES = 15; - private static final float PV_LIMIT_FACTOR = 0.9f; - private static final int MIN_PV_LIMIT = 5_000; - private static final int NO_PV_LIMIT = 60_000; - // If AllowedDischarge is < 1000, surplus is not activated - private static final int SURPLUS_ALLOWED_DISCHARGE_LIMIT = 35_000; - - private final Logger log = LoggerFactory.getLogger(SurplusFeedInHandler.class); - private final DeyeSunHybridImpl parent; - - private SurplusFeedInStateMachine state = SurplusFeedInStateMachine.DEACTIVATED; - private LocalDateTime startedGoingDeactivated = null; - - public SurplusFeedInHandler(DeyeSunHybridImpl parent) { - this.parent = parent; - } - - protected Integer run(List chargers, Config config, ComponentManager componentManager) { - var offTime = LocalTime.parse(config.surplusFeedInOffTime()); - - var areSurplusConditionsMet = this.areSurplusConditionsMet(this.parent, chargers, config); - - if (chargers.isEmpty()) { - // Is no Charger set (i.e. is this not a Commercial 40-40 "DC") - this.setState(SurplusFeedInStateMachine.DEACTIVATED); - - } else if (LocalTime.now(componentManager.getClock()).isAfter(offTime)) { - // Passed surplusOffTime? - this.setState(SurplusFeedInStateMachine.PASSED_OFF_TIME); - - } else if (areSurplusConditionsMet) { - // Always immediately activate surplus-feed-in if conditions are met - this.setState(SurplusFeedInStateMachine.ACTIVATED); - - } else if (this.state == SurplusFeedInStateMachine.UNDEFINED) { - this.setState(SurplusFeedInStateMachine.DEACTIVATED); - } - - // State-Machine - switch (this.state) { - case UNDEFINED: - case DEACTIVATED: - this.applyPvPowerLimit(chargers, config, false); - return null; - - case ACTIVATED: { - if (areSurplusConditionsMet) { - this.startedGoingDeactivated = null; - } else { - this.setState(SurplusFeedInStateMachine.GOING_DEACTIVATED); - this.startedGoingDeactivated = LocalDateTime.now(); - } - var pvPower = this.getPvPower(chargers); - var power = pvPower + this.getIncreasePower(config, pvPower); - this.applyPvPowerLimit(chargers, config, true); - return power; - } - - case GOING_DEACTIVATED: { - var goingDeactivatedSinceMinutes = Duration.between(this.startedGoingDeactivated, LocalDateTime.now()) - .toMinutes(); - // slowly reduce the surplus-feed-in-power from 100 to 0 % - var pvPower = this.getPvPower(chargers); - var factor = DoubleUtils.normalize(goingDeactivatedSinceMinutes, 0, GOING_DEACTIVATED_MINUTES, 0, 1, true); - var power = Math.max((int) ((pvPower + this.getIncreasePower(config, pvPower)) * factor), - this.getIncreasePower(config, pvPower)); - if (goingDeactivatedSinceMinutes > GOING_DEACTIVATED_MINUTES) { - this.setState(SurplusFeedInStateMachine.PASSED_OFF_TIME); - } - this.applyPvPowerLimit(chargers, config, false); - return power; - } - - case PASSED_OFF_TIME: - if (LocalTime.now().isBefore(offTime)) { - this.setState(SurplusFeedInStateMachine.DEACTIVATED); - } - this.applyPvPowerLimit(chargers, config, false); - return null; - } - - // should never come here - return null; - } - - /** - * Gets the PV-Power. Zero if not available. - * - * @param chargers the DC Chargers - * @return pv power - */ - private int getPvPower(List chargers) { - var pvPower = 0; - for (EssDcCharger charger : chargers) { - pvPower += charger.getActualPower().orElse(0); - } - return pvPower; - } - - private boolean areSurplusConditionsMet(DeyeSunHybridImpl ess, List chargers, Config config) { - if (chargers.isEmpty()) { - return false; - } - - IntegerReadChannel allowedChargeChannel = ess.channel(DeyeSunHybrid.ChannelId.ORIGINAL_ALLOWED_CHARGE_POWER); - IntegerReadChannel allowedDischargeChannel = ess - .channel(DeyeSunHybrid.ChannelId.ORIGINAL_ALLOWED_DISCHARGE_POWER); - if ( - // Is battery Allowed Charge bigger than the limit? (and Discharge is allowed) - (allowedChargeChannel.value().orElse(0) < config.surplusFeedInAllowedChargePowerLimit() - || allowedDischargeChannel.value().orElse(Integer.MAX_VALUE) < SURPLUS_ALLOWED_DISCHARGE_LIMIT) - // Is State-of-charge lower than limit? - && ess.getSoc().orElse(100) < config.surplusFeedInSocLimit()) { - return false; - } - - var maxVoltage = 0; - for (DeyeSunPv charger : chargers) { - int thisVoltage = ((IntegerReadChannel) charger.channel(DeyeSunPv.ChannelId.PV_DCDC_INPUT_VOLTAGE)).value() - .orElse(0); - if (thisVoltage > maxVoltage) { - maxVoltage = thisVoltage; - } - } - - // Is PV NOT producing? - if (maxVoltage < 100_000) { - return false; - } - - return true; - } - - private void applyPvPowerLimit(List chargers, Config config, boolean limitPv) { - /* - * Limit PV production power - */ - var pvPowerLimit = NO_PV_LIMIT; - if (limitPv) { - // Limit PV-Power to maximum apparent power of inverter - // this avoids filling the battery faster than we can empty it - StateChannel powerDecreaseCausedByOvertemperatureChannel = this.parent - .channel(DeyeSunHybrid.ChannelId.POWER_DECREASE_CAUSED_BY_OVERTEMPERATURE); - if (powerDecreaseCausedByOvertemperatureChannel.value().orElse(false)) { - // Always decrease if POWER_DECREASE_CAUSED_BY_OVERTEMPERATURE StateChannel is - // set - pvPowerLimit = config.surplusFeedInPvLimitOnPowerDecreaseCausedByOvertemperature(); - } else { - // Otherwise reduce to MAX_APPARENT_POWER multiplied with PV_LIMIT_FACTOR; - // minimally MIN_PV_LIMIT - var maxApparentPower = this.parent.getMaxApparentPower(); - if (maxApparentPower.isDefined()) { - pvPowerLimit = Math.max(Math.round(maxApparentPower.get() * PV_LIMIT_FACTOR), MIN_PV_LIMIT); - } - } - } - - for (DeyeSunPv charger : chargers) { - IntegerWriteChannel setPvPowerLimit = charger.channel(DeyeSunPv.ChannelId.SET_PV_POWER_LIMIT); - try { - setPvPowerLimit.setNextWriteValue(pvPowerLimit); - } catch (OpenemsNamedException e) { - e.printStackTrace(); - } - // stop after one: write-channel is shared between all chargers - break; - } - } - - private void setState(SurplusFeedInStateMachine state) { - if (this.state != state) { - this.parent.logInfo(this.log, "Changing State-Machine from [" + this.state + "] to [" + state + "]"); - this.state = state; - this.parent.channel(DeyeSunHybrid.ChannelId.SURPLUS_FEED_IN_STATE_MACHINE).setNextValue(state); - } - } - - private int getIncreasePower(Config config, int pvPower) { - // if we reached here, state is ACTIVATED or GOING_DEACTIVATED; i.e. surplus - // feed in is activated - if (pvPower <= 0) { - // if PV-Power is zero, we assume the charger turned off because of full battery - // -> discharge with max increase power - return config.surplusFeedInMaxIncreasePowerFactor(); - } - // increase power is PV-Power + 10 % (INCREASE_POWER_FACTOR); limited by - // MAX_INCREASE_POWER - var increasePower = (int) (pvPower * config.surplusFeedInIncreasePowerFactor()); - return Math.min(increasePower, config.surplusFeedInMaxIncreasePowerFactor()); - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/AbstractEssDeyePv.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/AbstractEssDeyePv.java deleted file mode 100644 index a90ee26990d..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/AbstractEssDeyePv.java +++ /dev/null @@ -1,219 +0,0 @@ -package io.openems.edge.deye.common.charger; - -import io.openems.common.channel.AccessMode; -import io.openems.common.exceptions.OpenemsException; -import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; -import io.openems.edge.bridge.modbus.api.ModbusComponent; -import io.openems.edge.bridge.modbus.api.ModbusProtocol; -import io.openems.edge.bridge.modbus.api.element.DummyRegisterElement; -import io.openems.edge.bridge.modbus.api.element.SignedWordElement; -import io.openems.edge.bridge.modbus.api.element.UnsignedDoublewordElement; -import io.openems.edge.bridge.modbus.api.element.UnsignedWordElement; -import io.openems.edge.bridge.modbus.api.element.WordOrder; -import io.openems.edge.bridge.modbus.api.task.FC16WriteRegistersTask; -import io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask; -import io.openems.edge.common.component.OpenemsComponent; -import io.openems.edge.common.event.EdgeEventConstants; -import io.openems.edge.common.modbusslave.ModbusSlave; -import io.openems.edge.common.modbusslave.ModbusSlaveNatureTable; -import io.openems.edge.common.modbusslave.ModbusSlaveTable; -import io.openems.edge.common.taskmanager.Priority; -import io.openems.edge.ess.dccharger.api.EssDcCharger; -import io.openems.edge.timedata.api.TimedataProvider; -import io.openems.edge.timedata.api.utils.CalculateEnergyFromPower; -import org.osgi.service.event.Event; -import org.osgi.service.event.EventHandler; - -import static io.openems.edge.bridge.modbus.api.ElementToChannelConverter.SCALE_FACTOR_2; - -public abstract class AbstractEssDeyePv extends AbstractOpenemsModbusComponent implements DeyeSunPv, EssDcCharger, - ModbusComponent, OpenemsComponent, TimedataProvider, EventHandler, ModbusSlave { - - private final CalculateEnergyFromPower calculateActualEnergy = new CalculateEnergyFromPower(this, - EssDcCharger.ChannelId.ACTUAL_ENERGY); - - /** - * Is this PV1 or PV2 charger?. - * - * @return true for PV1, false for PV2 - */ - protected abstract boolean isPV1(); - - public AbstractEssDeyePv() { - super(// - OpenemsComponent.ChannelId.values(), // - ModbusComponent.ChannelId.values(), // - EssDcCharger.ChannelId.values(), // - DeyeSunPv.ChannelId.values() // - ); - - } - - @Override - protected ModbusProtocol defineModbusProtocol() throws OpenemsException { - var protocol = new ModbusProtocol(this, // - new FC16WriteRegistersTask(0x0503, // - m(DeyeSunPv.ChannelId.SET_PV_POWER_LIMIT, new UnsignedWordElement(0x0503), SCALE_FACTOR_2))); // - - if (this.isPV1()) { - protocol.addTasks(// - new FC3ReadRegistersTask(0xA130, Priority.LOW, // - m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_VOLTAGE, new SignedWordElement(0xA130), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_CURRENT, new SignedWordElement(0xA131), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_POWER, new SignedWordElement(0xA132), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_VOLTAGE, new SignedWordElement(0xA133), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_CURRENT, new SignedWordElement(0xA134), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_POWER, new SignedWordElement(0xA135), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_ENERGY, new SignedWordElement(0xA136), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_ENERGY, new SignedWordElement(0xA137), - SCALE_FACTOR_2), // - new DummyRegisterElement(0xA138, 0xA13F), // - m(DeyeSunPv.ChannelId.BMS_DCDC_REACTOR_TEMPERATURE, new SignedWordElement(0xA140)), // - m(DeyeSunPv.ChannelId.BMS_DCDC_IGBT_TEMPERATURE, new SignedWordElement(0xA141)), // - new DummyRegisterElement(0xA142, 0xA14F), // - m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_CHARGE_ENERGY, - new UnsignedDoublewordElement(0xA150).wordOrder(WordOrder.LSWMSW), // - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_DISCHARGE_ENERGY, - new UnsignedDoublewordElement(0xA152).wordOrder(WordOrder.LSWMSW), // - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_CHARGE_ENERGY, - new UnsignedDoublewordElement(0xA154).wordOrder(WordOrder.LSWMSW), // - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_DISCHARGE_ENERGY, - new UnsignedDoublewordElement(0xA156).wordOrder(WordOrder.LSWMSW), // - SCALE_FACTOR_2)), // - - new FC3ReadRegistersTask(0xA730, Priority.LOW, // - m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_VOLTAGE, new SignedWordElement(0xA730), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_CURRENT, new SignedWordElement(0xA731), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_POWER, new SignedWordElement(0xA732), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_VOLTAGE, new SignedWordElement(0xA733), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_CURRENT, new SignedWordElement(0xA734), SCALE_FACTOR_2), // - m(EssDcCharger.ChannelId.ACTUAL_POWER, new SignedWordElement(0xA735), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_ENERGY, new SignedWordElement(0xA736), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_ENERGY, new SignedWordElement(0xA737), SCALE_FACTOR_2), // - new DummyRegisterElement(0xA738, 0xA73F), // - m(DeyeSunPv.ChannelId.PV_DCDC_REACTOR_TEMPERATURE, new SignedWordElement(0xA740)), // - m(DeyeSunPv.ChannelId.PV_DCDC_IGBT_TEMPERATURE, new SignedWordElement(0xA741)), // - new DummyRegisterElement(0xA742, 0xA74F), // - m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_CHARGE_ENERGY, - new UnsignedDoublewordElement(0xA750).wordOrder(WordOrder.LSWMSW), // - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_DISCHARGE_ENERGY, - new UnsignedDoublewordElement(0xA752).wordOrder(WordOrder.LSWMSW), // - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_CHARGE_ENERGY, - new UnsignedDoublewordElement(0xA754).wordOrder(WordOrder.LSWMSW), // - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_DISCHARGE_ENERGY, - new UnsignedDoublewordElement(0xA756).wordOrder(WordOrder.LSWMSW), // - SCALE_FACTOR_2))); - - } else { - protocol.addTasks(// - new FC3ReadRegistersTask(0xAA30, Priority.LOW, // - m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_VOLTAGE, new SignedWordElement(0xAA30), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_CURRENT, new SignedWordElement(0xAA31), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_POWER, new SignedWordElement(0xAA32), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_VOLTAGE, new SignedWordElement(0xAA33), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_CURRENT, new SignedWordElement(0xAA34), SCALE_FACTOR_2), // - m(EssDcCharger.ChannelId.ACTUAL_POWER, new SignedWordElement(0xAA35), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_ENERGY, new SignedWordElement(0xAA36), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_ENERGY, new SignedWordElement(0xAA37), SCALE_FACTOR_2), // - new DummyRegisterElement(0xAA38, 0xAA3F), // - m(DeyeSunPv.ChannelId.PV_DCDC_REACTOR_TEMPERATURE, new SignedWordElement(0xAA40)), // - m(DeyeSunPv.ChannelId.PV_DCDC_IGBT_TEMPERATURE, new SignedWordElement(0xAA41)), // - new DummyRegisterElement(0xAA42, 0xAA4F), // - m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_CHARGE_ENERGY, - new UnsignedDoublewordElement(0xAA50).wordOrder(WordOrder.LSWMSW), // - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_INPUT_DISCHARGE_ENERGY, - new UnsignedDoublewordElement(0xAA52).wordOrder(WordOrder.LSWMSW), // - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_CHARGE_ENERGY, - new UnsignedDoublewordElement(0xAA54).wordOrder(WordOrder.LSWMSW), // - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.PV_DCDC_OUTPUT_DISCHARGE_ENERGY, - new UnsignedDoublewordElement(0xAA56).wordOrder(WordOrder.LSWMSW), // - SCALE_FACTOR_2)), - new FC3ReadRegistersTask(0xA430, Priority.LOW, // - m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_VOLTAGE, new SignedWordElement(0xA430), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_CURRENT, new SignedWordElement(0xA431), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_POWER, new SignedWordElement(0xA432), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_VOLTAGE, new SignedWordElement(0xA433), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_CURRENT, new SignedWordElement(0xA434), - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_POWER, new SignedWordElement(0xA435), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_ENERGY, new SignedWordElement(0xA436), SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_ENERGY, new SignedWordElement(0xA437), - SCALE_FACTOR_2), // - new DummyRegisterElement(0xA438, 0xA43F), // - m(DeyeSunPv.ChannelId.BMS_DCDC_REACTOR_TEMPERATURE, new SignedWordElement(0xA440)), // - m(DeyeSunPv.ChannelId.BMS_DCDC_IGBT_TEMPERATURE, new SignedWordElement(0xA441)), // - new DummyRegisterElement(0xA442, 0xA44F), // - m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_CHARGE_ENERGY, - new UnsignedDoublewordElement(0xA450).wordOrder(WordOrder.LSWMSW), // - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_INPUT_DISCHARGE_ENERGY, - new UnsignedDoublewordElement(0xA452).wordOrder(WordOrder.LSWMSW), // - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_CHARGE_ENERGY, - new UnsignedDoublewordElement(0xA454).wordOrder(WordOrder.LSWMSW), // - SCALE_FACTOR_2), // - m(DeyeSunPv.ChannelId.BMS_DCDC_OUTPUT_DISCHARGE_ENERGY, - new UnsignedDoublewordElement(0xA456).wordOrder(WordOrder.LSWMSW), // - SCALE_FACTOR_2))); // - } - return protocol; - } - - @Override - public String debugLog() { - return "P:" + this.getActualPower().asString(); - } - - @Override - public void handleEvent(Event event) { - switch (event.getTopic()) { - case EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE: - this.calculateEnergy(); - break; - } - } - - /** - * Calculate the Energy values from ActivePower. - */ - private void calculateEnergy() { - var actualPower = this.getActualPower().get(); - if (actualPower == null) { - // Not available - this.calculateActualEnergy.update(null); - } else if (actualPower > 0) { - this.calculateActualEnergy.update(actualPower); - } else { - this.calculateActualEnergy.update(0); - } - } - - @Override - public ModbusSlaveTable getModbusSlaveTable(AccessMode accessMode) { - return new ModbusSlaveTable(// - OpenemsComponent.getModbusSlaveNatureTable(accessMode), // - EssDcCharger.getModbusSlaveNatureTable(accessMode), // - ModbusSlaveNatureTable.of(DeyeSunPv.class, accessMode, 100) // - .build()); - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv1.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv1.java deleted file mode 100644 index 1244aaf878e..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv1.java +++ /dev/null @@ -1,30 +0,0 @@ -package io.openems.edge.deye.common.charger; - -import org.osgi.service.metatype.annotations.AttributeDefinition; -import org.osgi.service.metatype.annotations.ObjectClassDefinition; - -@ObjectClassDefinition(// - name = "Deye Sun DC Charger PV1", // - description = "Implements the Deye Sun DC Charger.") -@interface ConfigPv1 { - - @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") - String id() default "charger0"; - - @AttributeDefinition(name = "Alias", description = "Human-readable name of this Component; defaults to Component-ID") - String alias() default "PV1"; - - @AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?") - boolean enabled() default true; - - @AttributeDefinition(name = "FENECON Commercial40-ID", description = "ID of FENECON Commercial 40 device.") - String ess_id() default "ess0"; - - @AttributeDefinition(name = "FENECON Commercial40 target filter", description = "This is auto-generated by 'FENECON Commercial40-ID'.") - String Ess_target() default "(enabled=true)"; - - @AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID' from FENECON Commercial40.") - String Modbus_target() default "(enabled=true)"; - - String webconsole_configurationFactory_nameHint() default "ESS FENECON Commercial 40 DC Charger PV1 [{id}]"; -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv2.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv2.java deleted file mode 100644 index 83815eb28e0..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/ConfigPv2.java +++ /dev/null @@ -1,30 +0,0 @@ -package io.openems.edge.deye.common.charger; - -import org.osgi.service.metatype.annotations.AttributeDefinition; -import org.osgi.service.metatype.annotations.ObjectClassDefinition; - -@ObjectClassDefinition(// - name = "Deye Sun DC Charger PV1", // - description = "Implements the Deye Sun DC Charger.") -@interface ConfigPv2 { - - @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") - String id() default "charger1"; - - @AttributeDefinition(name = "Alias", description = "Human-readable name of this Component; defaults to Component-ID") - String alias() default "PV2"; - - @AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?") - boolean enabled() default true; - - @AttributeDefinition(name = "FENECON Commercial40-ID", description = "ID of FENECON Commercial 40 device.") - String ess_id() default "ess0"; - - @AttributeDefinition(name = "FENECON Commercial40 target filter", description = "This is auto-generated by 'FENECON Commercial40-ID'.") - String Ess_target() default "(enabled=true)"; - - @AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID' from FENECON Commercial40.") - String Modbus_target() default "(enabled=true)"; - - String webconsole_configurationFactory_nameHint() default "ESS FENECON Commercial 40 DC Charger PV2 [{id}]"; -} \ No newline at end of file diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSun2Impl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSun2Impl.java deleted file mode 100644 index 533385e9040..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSun2Impl.java +++ /dev/null @@ -1,94 +0,0 @@ -package io.openems.edge.deye.common.charger; - -import io.openems.common.exceptions.OpenemsException; -import io.openems.edge.bridge.modbus.api.BridgeModbus; -import io.openems.edge.bridge.modbus.api.ModbusComponent; -import io.openems.edge.common.component.OpenemsComponent; -import io.openems.edge.common.event.EdgeEventConstants; -import io.openems.edge.deye.common.DeyeSunHybrid; -import io.openems.edge.ess.dccharger.api.EssDcCharger; -import io.openems.edge.timedata.api.Timedata; -import io.openems.edge.timedata.api.TimedataProvider; -import org.osgi.service.cm.ConfigurationAdmin; -import org.osgi.service.component.ComponentContext; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.ConfigurationPolicy; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.component.annotations.ReferencePolicyOption; -import org.osgi.service.event.EventHandler; -import org.osgi.service.event.propertytypes.EventTopics; -import org.osgi.service.metatype.annotations.Designate; - -@Designate(ocd = ConfigPv2.class, factory = true) -@Component(// - name = "Deye.Sun.PV2", // - immediate = true, // - configurationPolicy = ConfigurationPolicy.REQUIRE // -) -@EventTopics({ // - EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE // -}) -public class DeyeSun2Impl extends AbstractEssDeyePv - implements DeyeSunPv, EssDcCharger, ModbusComponent, OpenemsComponent, EventHandler, TimedataProvider { - - @Reference - private ConfigurationAdmin cm; - - @Override - @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) - protected void setModbus(BridgeModbus modbus) { - super.setModbus(modbus); - } - - @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) - private DeyeSunHybrid ess; - - @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL) - private volatile Timedata timedata = null; - - public DeyeSun2Impl() { - } - - @Activate - private void activate(ComponentContext context, ConfigPv2 config) throws OpenemsException { - if (super.activate(context, config.id(), config.alias(), config.enabled(), this.ess.getUnitId(), this.cm, - "Modbus", this.ess.getModbusBridgeId())) { - return; - } - - // update filter for 'Ess' - if (OpenemsComponent.updateReferenceFilter(this.cm, this.servicePid(), "Ess", config.ess_id())) { - return; - } - - this.ess.addCharger(this); - } - - @Override - @Deactivate - protected void deactivate() { - if (this.ess != null) { - this.ess.removeCharger(this); - } - super.deactivate(); - } - - @Override - public String debugLog() { - return "P:" + this.getActualPower().asString(); - } - - @Override - public Timedata getTimedata() { - return this.timedata; - } - - @Override - protected boolean isPV1() { - return false; - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunImpl.java deleted file mode 100644 index 67679e00698..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunImpl.java +++ /dev/null @@ -1,92 +0,0 @@ -package io.openems.edge.deye.common.charger; - -import io.openems.common.exceptions.OpenemsException; -import io.openems.edge.bridge.modbus.api.BridgeModbus; -import io.openems.edge.bridge.modbus.api.ModbusComponent; -import io.openems.edge.common.component.OpenemsComponent; -import io.openems.edge.common.event.EdgeEventConstants; -import io.openems.edge.deye.common.DeyeSunHybrid; -import io.openems.edge.ess.dccharger.api.EssDcCharger; -import io.openems.edge.timedata.api.Timedata; -import io.openems.edge.timedata.api.TimedataProvider; -import org.osgi.service.cm.ConfigurationAdmin; -import org.osgi.service.component.ComponentContext; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.ConfigurationPolicy; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.component.annotations.ReferencePolicyOption; -import org.osgi.service.event.EventHandler; -import org.osgi.service.event.propertytypes.EventTopics; -import org.osgi.service.metatype.annotations.Designate; - -@Designate(ocd = ConfigPv1.class, factory = true) -@Component(// - name = "Deye.Sun.PV1", // - immediate = true, // - configurationPolicy = ConfigurationPolicy.REQUIRE // -) -@EventTopics({ // - EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE // -}) -public class DeyeSunImpl extends AbstractEssDeyePv - implements DeyeSunPv, EssDcCharger, ModbusComponent, OpenemsComponent, EventHandler, TimedataProvider { - - @Reference - private ConfigurationAdmin cm; - - @Override - @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) - protected void setModbus(BridgeModbus modbus) { - super.setModbus(modbus); - } - - @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) - private DeyeSunHybrid ess; - - @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL) - private volatile Timedata timedata = null; - - public DeyeSunImpl() { - } - - @Activate - private void activate(ComponentContext context, ConfigPv1 config) throws OpenemsException { - if (super.activate(context, config.id(), config.alias(), config.enabled(), this.ess.getUnitId(), this.cm, - "Modbus", this.ess.getModbusBridgeId())) { - return; - } - - // update filter for 'Ess' - if (OpenemsComponent.updateReferenceFilter(this.cm, this.servicePid(), "Ess", config.ess_id())) { - return; - } - - this.ess.addCharger(this); - } - - @Override - @Deactivate - protected void deactivate() { - this.ess.removeCharger(this); - super.deactivate(); - } - - @Override - public String debugLog() { - return "P:" + this.getActualPower().asString(); - } - - @Override - public Timedata getTimedata() { - return this.timedata; - } - - @Override - protected boolean isPV1() { - return true; - } -} diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunPv.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunPv.java deleted file mode 100644 index bf60c820321..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/charger/DeyeSunPv.java +++ /dev/null @@ -1,97 +0,0 @@ -package io.openems.edge.deye.common.charger; - -import io.openems.common.channel.AccessMode; -import io.openems.common.channel.Unit; -import io.openems.common.types.OpenemsType; -import io.openems.edge.common.channel.Doc; -import io.openems.edge.common.channel.IntegerDoc; -import io.openems.edge.common.component.OpenemsComponent; -import io.openems.edge.ess.dccharger.api.EssDcCharger; -import io.openems.edge.timedata.api.TimedataProvider; - -public interface DeyeSunPv extends EssDcCharger, OpenemsComponent, TimedataProvider { - - public enum ChannelId implements io.openems.edge.common.channel.ChannelId { - DEBUG_SET_PV_POWER_LIMIT(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.WATT)), - - /** - * Curtail PV. Careful: this channel is shared between both Chargers. - */ - SET_PV_POWER_LIMIT(new IntegerDoc() // - .unit(Unit.WATT) // - .accessMode(AccessMode.WRITE_ONLY) // - .onChannelSetNextWriteMirrorToDebugChannel(ChannelId.DEBUG_SET_PV_POWER_LIMIT)), - - // LongReadChannel - BMS_DCDC_OUTPUT_ENERGY(Doc.of(OpenemsType.LONG) // - .unit(Unit.CUMULATED_WATT_HOURS)), // - BMS_DCDC_INPUT_ENERGY(Doc.of(OpenemsType.LONG) // - .unit(Unit.CUMULATED_WATT_HOURS)), // - BMS_DCDC_INPUT_CHARGE_ENERGY(Doc.of(OpenemsType.LONG) // - .unit(Unit.CUMULATED_WATT_HOURS)), // - BMS_DCDC_INPUT_DISCHARGE_ENERGY(Doc.of(OpenemsType.LONG) // - .unit(Unit.CUMULATED_WATT_HOURS)), // - BMS_DCDC_OUTPUT_CHARGE_ENERGY(Doc.of(OpenemsType.LONG) // - .unit(Unit.CUMULATED_WATT_HOURS)), // - BMS_DCDC_OUTPUT_DISCHARGE_ENERGY(Doc.of(OpenemsType.LONG) // - .unit(Unit.CUMULATED_WATT_HOURS)), // - PV_DCDC_INPUT_ENERGY(Doc.of(OpenemsType.LONG) // - .unit(Unit.CUMULATED_WATT_HOURS)), // - PV_DCDC_OUTPUT_ENERGY(Doc.of(OpenemsType.LONG) // - .unit(Unit.CUMULATED_WATT_HOURS)), // - PV_DCDC_INPUT_CHARGE_ENERGY(Doc.of(OpenemsType.LONG) // - .unit(Unit.CUMULATED_WATT_HOURS)), // - PV_DCDC_INPUT_DISCHARGE_ENERGY(Doc.of(OpenemsType.LONG) // - .unit(Unit.WATT_HOURS)), // - PV_DCDC_OUTPUT_CHARGE_ENERGY(Doc.of(OpenemsType.LONG) // - .unit(Unit.WATT_HOURS)), // - PV_DCDC_OUTPUT_DISCHARGE_ENERGY(Doc.of(OpenemsType.LONG) // - .unit(Unit.WATT_HOURS)), // - - // IntegerReadChannel - BMS_DCDC_OUTPUT_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - BMS_DCDC_OUTPUT_CURRENT(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIAMPERE)), // - BMS_DCDC_OUTPUT_POWER(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.WATT)), // - BMS_DCDC_INPUT_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIWATT)), // - BMS_DCDC_INPUT_CURRENT(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIWATT)), // - BMS_DCDC_INPUT_POWER(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.WATT)), // - BMS_DCDC_REACTOR_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.DEGREE_CELSIUS)), // - BMS_DCDC_IGBT_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.DEGREE_CELSIUS)), // - PV_DCDC_OUTPUT_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIVOLT)), // - PV_DCDC_OUTPUT_CURRENT(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIAMPERE)), // - PV_DCDC_OUTPUT_POWER(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.WATT)), // - PV_DCDC_INPUT_VOLTAGE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIWATT)), // - PV_DCDC_INPUT_CURRENT(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.MILLIWATT)), // - PV_DCDC_INPUT_POWER(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.WATT)), // - PV_DCDC_REACTOR_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.DEGREE_CELSIUS)), // - PV_DCDC_IGBT_TEMPERATURE(Doc.of(OpenemsType.INTEGER) // - .unit(Unit.DEGREE_CELSIUS)); // - - private final Doc doc; - - private ChannelId(Doc doc) { - this.doc = doc; - } - - @Override - public Doc doc() { - return this.doc; - } - } -} From 240240f8c6b3e6f1243c13bf1d00501b380b54fa Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Tue, 16 Apr 2024 08:53:46 +0200 Subject: [PATCH 22/25] Remove not necessary code --- .../common/SurplusFeedInStateMachine.java | 34 ------------------- 1 file changed, 34 deletions(-) delete mode 100644 io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInStateMachine.java diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInStateMachine.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInStateMachine.java deleted file mode 100644 index ca711be6d72..00000000000 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SurplusFeedInStateMachine.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.openems.edge.deye.common; - -import io.openems.common.types.OptionsEnum; - -public enum SurplusFeedInStateMachine implements OptionsEnum { - UNDEFINED(-1, "Undefined"), // - DEACTIVATED(0, "Deactivated"), // - ACTIVATED(1, "Activated"), // - GOING_DEACTIVATED(2, "Going Deactivated"), // - PASSED_OFF_TIME(3, "Passed Off-Time"); // - - private final int value; - private final String name; - - private SurplusFeedInStateMachine(int value, String name) { - this.value = value; - this.name = name; - } - - @Override - public int getValue() { - return this.value; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public OptionsEnum getUndefined() { - return UNDEFINED; - } -} \ No newline at end of file From 1556956f991ca07e7fc93552eaf7f192120d5cd9 Mon Sep 17 00:00:00 2001 From: Moritz Vogt Date: Tue, 16 Apr 2024 16:08:09 +0200 Subject: [PATCH 23/25] Rename package for ess --- .../src/io/openems/edge/deye/{common => ess}/Config.java | 4 ++-- .../io/openems/edge/deye/{common => ess}/DeyeSunHybrid.java | 2 +- .../openems/edge/deye/{common => ess}/DeyeSunHybridImpl.java | 2 +- .../io/openems/edge/deye/{common => ess}/SetWorkState.java | 2 +- .../src/io/openems/edge/deye/{common => ess}/SystemState.java | 2 +- io.openems.edge.evcs.spelsberg/generated/buildfiles | 1 + io.openems.edge.io.gpio/generated/buildfiles | 1 + 7 files changed, 8 insertions(+), 6 deletions(-) rename io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/{common => ess}/Config.java (97%) rename io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/{common => ess}/DeyeSunHybrid.java (99%) rename io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/{common => ess}/DeyeSunHybridImpl.java (99%) rename io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/{common => ess}/SetWorkState.java (93%) rename io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/{common => ess}/SystemState.java (94%) diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/Config.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/Config.java similarity index 97% rename from io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/Config.java rename to io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/Config.java index be01901fefd..eec95643f5c 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/Config.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/Config.java @@ -1,4 +1,4 @@ -package io.openems.edge.deye.common; +package io.openems.edge.deye.ess; import org.osgi.service.metatype.annotations.AttributeDefinition; import org.osgi.service.metatype.annotations.ObjectClassDefinition; @@ -24,7 +24,7 @@ String modbus_id() default "modbus0"; @AttributeDefinition(name = "Modbus-Unit-ID", description = "Unit ID of Modbus bridge.") - int unit_id() default 0; + int unit_id() default 1; @AttributeDefinition(name = "Power limit on PowerDecreaseCausedByOvertemperature error; '0' to disable power limit logic", description = "") int powerLimitOnPowerDecreaseCausedByOvertemperatureChannel() default 20_000; diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/DeyeSunHybrid.java similarity index 99% rename from io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java rename to io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/DeyeSunHybrid.java index 4a1f88d36ec..bad1669a91c 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybrid.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/DeyeSunHybrid.java @@ -1,4 +1,4 @@ -package io.openems.edge.deye.common; +package io.openems.edge.deye.ess; import io.openems.common.channel.AccessMode; import io.openems.common.channel.Level; diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/DeyeSunHybridImpl.java similarity index 99% rename from io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java rename to io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/DeyeSunHybridImpl.java index ded1ce32c72..2cde7b5c81a 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/DeyeSunHybridImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/DeyeSunHybridImpl.java @@ -1,4 +1,4 @@ -package io.openems.edge.deye.common; +package io.openems.edge.deye.ess; import io.openems.common.channel.AccessMode; import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SetWorkState.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/SetWorkState.java similarity index 93% rename from io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SetWorkState.java rename to io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/SetWorkState.java index 3e002767674..848a9976ad8 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SetWorkState.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/SetWorkState.java @@ -1,4 +1,4 @@ -package io.openems.edge.deye.common; +package io.openems.edge.deye.ess; import io.openems.common.types.OptionsEnum; diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemState.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/SystemState.java similarity index 94% rename from io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemState.java rename to io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/SystemState.java index 9ca762181a0..411056fa363 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/common/SystemState.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/SystemState.java @@ -1,4 +1,4 @@ -package io.openems.edge.deye.common; +package io.openems.edge.deye.ess; import io.openems.common.types.OptionsEnum; diff --git a/io.openems.edge.evcs.spelsberg/generated/buildfiles b/io.openems.edge.evcs.spelsberg/generated/buildfiles index e69de29bb2d..ef95c181a81 100644 --- a/io.openems.edge.evcs.spelsberg/generated/buildfiles +++ b/io.openems.edge.evcs.spelsberg/generated/buildfiles @@ -0,0 +1 @@ +/Users/mvogt/IdeaProjects/openems/io.openems.edge.evcs.spelsberg/generated/io.openems.edge.evcs.spelsberg.jar diff --git a/io.openems.edge.io.gpio/generated/buildfiles b/io.openems.edge.io.gpio/generated/buildfiles index e69de29bb2d..d19112c47b3 100644 --- a/io.openems.edge.io.gpio/generated/buildfiles +++ b/io.openems.edge.io.gpio/generated/buildfiles @@ -0,0 +1 @@ +/Users/mvogt/IdeaProjects/openems/io.openems.edge.io.gpio/generated/io.openems.edge.io.gpio.jar From 7e6a83ed28677b1ed862738452195c33681306fb Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Tue, 4 Mar 2025 16:22:29 +0100 Subject: [PATCH 24/25] prepare-commit --- io.openems.edge.batteryinverter.deye/.classpath | 2 +- io.openems.edge.batteryinverter.deye/.project | 2 +- io.openems.edge.batteryinverter.deye/bnd.bnd | 2 +- io.openems.edge.batteryinverter.deye/test/.gitignore | 0 4 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 io.openems.edge.batteryinverter.deye/test/.gitignore diff --git a/io.openems.edge.batteryinverter.deye/.classpath b/io.openems.edge.batteryinverter.deye/.classpath index bbfbdbe40e7..b4cffd0fe60 100644 --- a/io.openems.edge.batteryinverter.deye/.classpath +++ b/io.openems.edge.batteryinverter.deye/.classpath @@ -1,7 +1,7 @@ - + diff --git a/io.openems.edge.batteryinverter.deye/.project b/io.openems.edge.batteryinverter.deye/.project index 522ed9ee544..45320285774 100644 --- a/io.openems.edge.batteryinverter.deye/.project +++ b/io.openems.edge.batteryinverter.deye/.project @@ -1,6 +1,6 @@ - io.openems.edge.batteryinverter.sinexcel + io.openems.edge.batteryinverter.deye diff --git a/io.openems.edge.batteryinverter.deye/bnd.bnd b/io.openems.edge.batteryinverter.deye/bnd.bnd index 4a48b5afce1..55ef7585bfd 100644 --- a/io.openems.edge.batteryinverter.deye/bnd.bnd +++ b/io.openems.edge.batteryinverter.deye/bnd.bnd @@ -8,11 +8,11 @@ Bundle-Version: 1.0.0.${tstamp} com.ghgande.j2mod,\ io.openems.common,\ io.openems.edge.battery.api,\ - io.openems.edge.meter.api,\ io.openems.edge.batteryinverter.api,\ io.openems.edge.bridge.modbus,\ io.openems.edge.common,\ io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ io.openems.edge.timedata.api,\ io.openems.edge.pvinverter.api -testpath: \ diff --git a/io.openems.edge.batteryinverter.deye/test/.gitignore b/io.openems.edge.batteryinverter.deye/test/.gitignore new file mode 100644 index 00000000000..e69de29bb2d From 5424d3bc0d34abe8060462e96f6666a7edb49293 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Tue, 4 Mar 2025 17:10:21 +0100 Subject: [PATCH 25/25] Organize imports + formatting --- .../openems/edge/deye/ess/DeyeSunHybrid.java | 3 +- .../edge/deye/ess/DeyeSunHybridImpl.java | 40 +++++++-------- .../deye/gridmeter/DeyeGridMeterImpl.java | 36 +++++++------- .../deye/productionmeter/PvInverterDeye.java | 5 +- .../productionmeter/PvInverterDeyeImpl.java | 49 ++++++++++--------- .../productionmeter/SetPvLimitHandler.java | 11 +++-- .../openems/edge/deye/gridmeter/MyConfig.java | 2 +- .../generated/buildfiles | 1 - io.openems.edge.io.gpio/generated/buildfiles | 1 - 9 files changed, 75 insertions(+), 73 deletions(-) delete mode 100644 io.openems.edge.evcs.spelsberg/generated/buildfiles delete mode 100644 io.openems.edge.io.gpio/generated/buildfiles diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/DeyeSunHybrid.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/DeyeSunHybrid.java index bad1669a91c..f181cf533bc 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/DeyeSunHybrid.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/DeyeSunHybrid.java @@ -1,5 +1,7 @@ package io.openems.edge.deye.ess; +import org.osgi.service.event.EventHandler; + import io.openems.common.channel.AccessMode; import io.openems.common.channel.Level; import io.openems.common.channel.PersistencePriority; @@ -14,7 +16,6 @@ import io.openems.edge.ess.api.ManagedSymmetricEss; import io.openems.edge.ess.api.SymmetricEss; import io.openems.edge.timedata.api.TimedataProvider; -import org.osgi.service.event.EventHandler; public interface DeyeSunHybrid extends ManagedSymmetricEss, SymmetricEss, OpenemsComponent, EventHandler, ModbusSlave, TimedataProvider { diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/DeyeSunHybridImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/DeyeSunHybridImpl.java index 2cde7b5c81a..7534a73ef18 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/DeyeSunHybridImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/ess/DeyeSunHybridImpl.java @@ -1,5 +1,24 @@ package io.openems.edge.deye.ess; +import java.time.LocalDateTime; + +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.ConfigurationPolicy; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; +import org.osgi.service.component.annotations.ReferencePolicyOption; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventHandler; +import org.osgi.service.event.propertytypes.EventTopics; +import org.osgi.service.metatype.annotations.Designate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import io.openems.common.channel.AccessMode; import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; import io.openems.common.exceptions.OpenemsException; @@ -33,24 +52,6 @@ import io.openems.edge.timedata.api.Timedata; import io.openems.edge.timedata.api.TimedataProvider; import io.openems.edge.timedata.api.utils.CalculateEnergyFromPower; -import org.osgi.service.cm.ConfigurationAdmin; -import org.osgi.service.component.ComponentContext; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.ConfigurationPolicy; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.component.annotations.ReferencePolicyOption; -import org.osgi.service.event.Event; -import org.osgi.service.event.EventHandler; -import org.osgi.service.event.propertytypes.EventTopics; -import org.osgi.service.metatype.annotations.Designate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.time.LocalDateTime; @Designate(ocd = Config.class, factory = true) @Component(// @@ -87,7 +88,6 @@ public class DeyeSunHybridImpl extends AbstractOpenemsModbusComponent implements private final CalculateEnergyFromPower calculateDcDischargeEnergy = new CalculateEnergyFromPower(this, HybridEss.ChannelId.DC_DISCHARGE_ENERGY); - @Reference private ComponentManager componentManager; @@ -160,7 +160,7 @@ public String getModbusBridgeId() { } @Override - protected ModbusProtocol defineModbusProtocol() throws OpenemsException { + protected ModbusProtocol defineModbusProtocol() { return new ModbusProtocol(this, // new FC3ReadRegistersTask(1, Priority.LOW, diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java index 62ca4e137f2..fe69a9d9803 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/gridmeter/DeyeGridMeterImpl.java @@ -1,7 +1,23 @@ package io.openems.edge.deye.gridmeter; +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.ConfigurationPolicy; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; +import org.osgi.service.component.annotations.ReferencePolicyOption; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventHandler; +import org.osgi.service.event.propertytypes.EventTopics; +import org.osgi.service.metatype.annotations.Designate; + import io.openems.common.channel.AccessMode; import io.openems.common.exceptions.OpenemsException; +import io.openems.common.types.MeterType; import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; import io.openems.edge.bridge.modbus.api.BridgeModbus; import io.openems.edge.bridge.modbus.api.ModbusComponent; @@ -15,24 +31,9 @@ import io.openems.edge.common.modbusslave.ModbusSlaveTable; import io.openems.edge.common.taskmanager.Priority; import io.openems.edge.meter.api.ElectricityMeter; -import io.openems.edge.meter.api.MeterType; import io.openems.edge.timedata.api.Timedata; import io.openems.edge.timedata.api.TimedataProvider; import io.openems.edge.timedata.api.utils.CalculateEnergyFromPower; -import org.osgi.service.cm.ConfigurationAdmin; -import org.osgi.service.component.ComponentContext; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.ConfigurationPolicy; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.component.annotations.ReferencePolicyOption; -import org.osgi.service.event.Event; -import org.osgi.service.event.EventHandler; -import org.osgi.service.event.propertytypes.EventTopics; -import org.osgi.service.metatype.annotations.Designate; @Designate(ocd = Config.class, factory = true) @Component(// @@ -65,8 +66,6 @@ protected void setModbus(BridgeModbus modbus) { @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL) private volatile Timedata timedata = null; - private Config config; - public DeyeGridMeterImpl() throws OpenemsException { super(// OpenemsComponent.ChannelId.values(), // @@ -83,7 +82,6 @@ private void activate(ComponentContext context, Config config) throws OpenemsExc "Modbus", config.modbus_id())) { return; } - this.config = config; } @Override @@ -98,7 +96,7 @@ public MeterType getMeterType() { } @Override - protected ModbusProtocol defineModbusProtocol() throws OpenemsException { + protected ModbusProtocol defineModbusProtocol() { return new ModbusProtocol(this, new FC3ReadRegistersTask(625, Priority.HIGH, m(ElectricityMeter.ChannelId.ACTIVE_POWER, new SignedWordElement(625)))); } diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java index 35d7508e90a..783a3a924d6 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeye.java @@ -1,5 +1,7 @@ package io.openems.edge.deye.productionmeter; +import java.util.function.Consumer; + import io.openems.common.channel.AccessMode; import io.openems.common.channel.Level; import io.openems.common.channel.Unit; @@ -12,8 +14,6 @@ import io.openems.edge.common.type.TypeUtils; import io.openems.edge.meter.api.ElectricityMeter; -import java.util.function.Consumer; - public interface PvInverterDeye extends ElectricityMeter, ModbusComponent, OpenemsComponent { public enum ChannelId implements io.openems.edge.common.channel.ChannelId { @@ -84,7 +84,6 @@ public Doc doc() { * powers and adjusting for generator power. This method assumes all necessary * values are always present and uses a simple fallback for any missing data. * - * @param meter the {@link ElectricityMeter} * @param meter the {@link PvInverterDeye} instance being updated */ public static void calculateSumActivePowerFromPhases(PvInverterDeye meter) { diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java index db079119552..88d948906b0 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/PvInverterDeyeImpl.java @@ -1,8 +1,25 @@ package io.openems.edge.deye.productionmeter; +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.ConfigurationPolicy; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; +import org.osgi.service.component.annotations.ReferencePolicyOption; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventHandler; +import org.osgi.service.event.propertytypes.EventTopics; +import org.osgi.service.metatype.annotations.Designate; +import org.slf4j.Logger; + import io.openems.common.channel.AccessMode; import io.openems.common.exceptions.OpenemsError; import io.openems.common.exceptions.OpenemsException; +import io.openems.common.types.MeterType; import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; import io.openems.edge.bridge.modbus.api.BridgeModbus; import io.openems.edge.bridge.modbus.api.ModbusComponent; @@ -15,26 +32,10 @@ import io.openems.edge.common.modbusslave.ModbusSlaveTable; import io.openems.edge.common.taskmanager.Priority; import io.openems.edge.meter.api.ElectricityMeter; -import io.openems.edge.meter.api.MeterType; import io.openems.edge.pvinverter.api.ManagedSymmetricPvInverter; import io.openems.edge.timedata.api.Timedata; import io.openems.edge.timedata.api.TimedataProvider; import io.openems.edge.timedata.api.utils.CalculateEnergyFromPower; -import org.osgi.service.cm.ConfigurationAdmin; -import org.osgi.service.component.ComponentContext; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.ConfigurationPolicy; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.component.annotations.ReferencePolicyOption; -import org.osgi.service.event.Event; -import org.osgi.service.event.EventHandler; -import org.osgi.service.event.propertytypes.EventTopics; -import org.osgi.service.metatype.annotations.Designate; -import org.slf4j.Logger; @Designate(ocd = Config.class, factory = true) @Component(// @@ -49,11 +50,14 @@ EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE // }) public class PvInverterDeyeImpl extends AbstractOpenemsModbusComponent - implements PvInverterDeye, ManagedSymmetricPvInverter, ElectricityMeter, ModbusComponent, OpenemsComponent, EventHandler, ModbusSlave, TimedataProvider { + implements PvInverterDeye, ManagedSymmetricPvInverter, ElectricityMeter, ModbusComponent, OpenemsComponent, + EventHandler, ModbusSlave, TimedataProvider { - private final SetPvLimitHandler setPvLimitHandler = new SetPvLimitHandler(this, ManagedSymmetricPvInverter.ChannelId.ACTIVE_POWER_LIMIT); + private final SetPvLimitHandler setPvLimitHandler = new SetPvLimitHandler(this, + ManagedSymmetricPvInverter.ChannelId.ACTIVE_POWER_LIMIT); - private final CalculateEnergyFromPower calculateProductionEnergy = new CalculateEnergyFromPower(this, ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY); + private final CalculateEnergyFromPower calculateProductionEnergy = new CalculateEnergyFromPower(this, + ElectricityMeter.ChannelId.ACTIVE_PRODUCTION_ENERGY); @Reference private ConfigurationAdmin cm; @@ -84,7 +88,8 @@ public PvInverterDeyeImpl() throws OpenemsException { @Activate private void activate(ComponentContext context, Config config) throws OpenemsException { - if (super.activate(context, config.id(), config.alias(), config.enabled(), config.modbusUnitId(), this.cm, "Modbus", config.modbus_id())) { + if (super.activate(context, config.id(), config.alias(), config.enabled(), config.modbusUnitId(), this.cm, + "Modbus", config.modbus_id())) { return; } this.config = config; @@ -104,7 +109,7 @@ protected void deactivate() { } @Override - protected ModbusProtocol defineModbusProtocol() throws OpenemsException { + protected ModbusProtocol defineModbusProtocol() { return new ModbusProtocol(this, // new FC3ReadRegistersTask(672, Priority.LOW, // m(PvInverterDeye.ChannelId.ACTIVE_POWER_STRING_1, new UnsignedWordElement(672)), @@ -112,7 +117,7 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException { m(PvInverterDeye.ChannelId.ACTIVE_POWER_STRING_3, new UnsignedWordElement(674)), m(PvInverterDeye.ChannelId.ACTIVE_POWER_STRING_4, new UnsignedWordElement(675))), new FC3ReadRegistersTask(667, Priority.LOW, // - m(PvInverterDeye.ChannelId.ACTIVE_POWER_GENERATOR, new UnsignedWordElement(667)))); + m(PvInverterDeye.ChannelId.ACTIVE_POWER_GENERATOR, new UnsignedWordElement(667)))); } @Override diff --git a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/SetPvLimitHandler.java b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/SetPvLimitHandler.java index 81bbbeb2c45..0d3af6c4cd5 100644 --- a/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/SetPvLimitHandler.java +++ b/io.openems.edge.batteryinverter.deye/src/io/openems/edge/deye/productionmeter/SetPvLimitHandler.java @@ -1,15 +1,16 @@ package io.openems.edge.deye.productionmeter; +import java.time.LocalDateTime; +import java.util.Objects; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; import io.openems.common.function.ThrowingRunnable; import io.openems.edge.common.channel.EnumWriteChannel; import io.openems.edge.common.channel.IntegerWriteChannel; import io.openems.edge.pvinverter.api.ManagedSymmetricPvInverter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.time.LocalDateTime; -import java.util.Objects; public class SetPvLimitHandler implements ThrowingRunnable { diff --git a/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/MyConfig.java b/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/MyConfig.java index e637d42db71..7b15217fd95 100644 --- a/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/MyConfig.java +++ b/io.openems.edge.batteryinverter.deye/test/io/openems/edge/deye/gridmeter/MyConfig.java @@ -2,7 +2,6 @@ import io.openems.common.test.AbstractComponentConfig; import io.openems.common.utils.ConfigUtils; -import io.openems.edge.common.startstop.StartStopConfig; @SuppressWarnings("all") public class MyConfig extends AbstractComponentConfig implements Config { @@ -56,6 +55,7 @@ public String modbus_id() { public String Modbus_target() { return ConfigUtils.generateReferenceTargetFilter(this.id(), this.modbus_id()); } + @Override public int modbusUnitId() { return this.builder.modbusUnitId; diff --git a/io.openems.edge.evcs.spelsberg/generated/buildfiles b/io.openems.edge.evcs.spelsberg/generated/buildfiles deleted file mode 100644 index ef95c181a81..00000000000 --- a/io.openems.edge.evcs.spelsberg/generated/buildfiles +++ /dev/null @@ -1 +0,0 @@ -/Users/mvogt/IdeaProjects/openems/io.openems.edge.evcs.spelsberg/generated/io.openems.edge.evcs.spelsberg.jar diff --git a/io.openems.edge.io.gpio/generated/buildfiles b/io.openems.edge.io.gpio/generated/buildfiles deleted file mode 100644 index d19112c47b3..00000000000 --- a/io.openems.edge.io.gpio/generated/buildfiles +++ /dev/null @@ -1 +0,0 @@ -/Users/mvogt/IdeaProjects/openems/io.openems.edge.io.gpio/generated/io.openems.edge.io.gpio.jar