Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
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.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;
Expand Down Expand Up @@ -52,19 +51,38 @@ protected ModbusProtocol defineModbusProtocol() {
new FC3ReadRegistersTask(startAddress, Priority.HIGH, //
m(EssDcCharger.ChannelId.VOLTAGE, new UnsignedWordElement(startAddress), //
SCALE_FACTOR_2), //
m(EssDcCharger.ChannelId.CURRENT, new UnsignedWordElement(startAddress + 1), SCALE_FACTOR_2),
m(EssDcCharger.ChannelId.ACTUAL_POWER, new UnsignedDoublewordElement(startAddress + 2))));
m(EssDcCharger.ChannelId.CURRENT, new UnsignedWordElement(startAddress + 1), SCALE_FACTOR_2)));
}

@Override
public void handleEvent(Event event) {
switch (event.getTopic()) {
case EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE:
this.calculatePower();
this.calculateEnergy();
this.updateState();
break;
}
}

/**
* Calculate the ActivePower from Current and Voltage.
*/
private void calculatePower() {
var voltage = this.getVoltage().get();
var current = this.getCurrent().get();
if (voltage == null || current == null) {
return;
}
int milliAmpere = current;
int milliVolt = voltage;
long powerMicrowatt = (long) milliAmpere * (long) milliVolt; // mA * mV = µW
int powerWatt = (int) (powerMicrowatt / 1_000_000L); // µW -> W
var actualPower = this.getActualPower().get();
if (actualPower == null || actualPower != powerWatt) {
this._setActualPower(powerWatt);
}
}

/**
* Calculate the Energy values from ActivePower.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.openems.edge.goodwe.charger.singlestring;

import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

import io.openems.edge.goodwe.GoodWeConstants;

@ObjectClassDefinition(//
name = "GoodWe Charger PV4", //
description = "Implements the GoodWe-ET Charger 4.")

@interface ConfigPV4 {
@AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component")
String id() default "charger3";

@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 = "GoodWe ESS or Battery-Inverter", description = "ID of GoodWe Energy Storage System or Battery-Inverter.")
String essOrBatteryInverter_id() default "batteryInverter0";

@AttributeDefinition(name = "GoodWe ESS or Battery-Inverter target filter", description = "This is auto-generated by 'GoodWe ESS or Battery-Inverter'.")
String essOrBatteryInverter_target() default "(enabled=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 GoodWeConstants.DEFAULT_UNIT_ID;

@AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID'.")
String Modbus_target() default "(enabled=true)";

String webconsole_configurationFactory_nameHint() default "GoodWe Charger PV4 [{id}]";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.openems.edge.goodwe.charger.singlestring;

import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

import io.openems.edge.goodwe.GoodWeConstants;

@ObjectClassDefinition(//
name = "GoodWe Charger PV5", //
description = "Implements the GoodWe-ET Charger 5.")

@interface ConfigPV5 {
@AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component")
String id() default "charger4";

@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 = "GoodWe ESS or Battery-Inverter", description = "ID of GoodWe Energy Storage System or Battery-Inverter.")
String essOrBatteryInverter_id() default "batteryInverter0";

@AttributeDefinition(name = "GoodWe ESS or Battery-Inverter target filter", description = "This is auto-generated by 'GoodWe ESS or Battery-Inverter'.")
String essOrBatteryInverter_target() default "(enabled=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 GoodWeConstants.DEFAULT_UNIT_ID;

@AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID'.")
String Modbus_target() default "(enabled=true)";

String webconsole_configurationFactory_nameHint() default "GoodWe Charger PV5 [{id}]";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.openems.edge.goodwe.charger.singlestring;

import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

import io.openems.edge.goodwe.GoodWeConstants;

@ObjectClassDefinition(//
name = "GoodWe Charger PV6", //
description = "Implements the GoodWe-ET Charger 6.")

@interface ConfigPV6 {
@AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component")
String id() default "charger5";

@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 = "GoodWe ESS or Battery-Inverter", description = "ID of GoodWe Energy Storage System or Battery-Inverter.")
String essOrBatteryInverter_id() default "batteryInverter0";

@AttributeDefinition(name = "GoodWe ESS or Battery-Inverter target filter", description = "This is auto-generated by 'GoodWe ESS or Battery-Inverter'.")
String essOrBatteryInverter_target() default "(enabled=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 GoodWeConstants.DEFAULT_UNIT_ID;

@AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID'.")
String Modbus_target() default "(enabled=true)";

String webconsole_configurationFactory_nameHint() default "GoodWe Charger PV6 [{id}]";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.openems.edge.goodwe.charger.singlestring;

import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

import io.openems.edge.goodwe.GoodWeConstants;

@ObjectClassDefinition(//
name = "GoodWe Charger PV7", //
description = "Implements the GoodWe-ET Charger 7.")

@interface ConfigPV7 {
@AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component")
String id() default "charger6";

@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 = "GoodWe ESS or Battery-Inverter", description = "ID of GoodWe Energy Storage System or Battery-Inverter.")
String essOrBatteryInverter_id() default "batteryInverter0";

@AttributeDefinition(name = "GoodWe ESS or Battery-Inverter target filter", description = "This is auto-generated by 'GoodWe ESS or Battery-Inverter'.")
String essOrBatteryInverter_target() default "(enabled=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 GoodWeConstants.DEFAULT_UNIT_ID;

@AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID'.")
String Modbus_target() default "(enabled=true)";

String webconsole_configurationFactory_nameHint() default "GoodWe Charger PV7 [{id}]";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.openems.edge.goodwe.charger.singlestring;

import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

import io.openems.edge.goodwe.GoodWeConstants;

@ObjectClassDefinition(//
name = "GoodWe Charger PV8", //
description = "Implements the GoodWe-ET Charger 8.")

@interface ConfigPV8 {
@AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component")
String id() default "charger7";

@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 = "GoodWe ESS or Battery-Inverter", description = "ID of GoodWe Energy Storage System or Battery-Inverter.")
String essOrBatteryInverter_id() default "batteryInverter0";

@AttributeDefinition(name = "GoodWe ESS or Battery-Inverter target filter", description = "This is auto-generated by 'GoodWe ESS or Battery-Inverter'.")
String essOrBatteryInverter_target() default "(enabled=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 GoodWeConstants.DEFAULT_UNIT_ID;

@AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID'.")
String Modbus_target() default "(enabled=true)";

String webconsole_configurationFactory_nameHint() default "GoodWe Charger PV8 [{id}]";
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ protected void setModbus(BridgeModbus modbus) {
super.setModbus(modbus);
}

public GoodWeChargerPv1() {
}

@Activate
private void activate(ComponentContext context, ConfigPV1 config) throws OpenemsException {
if (super.activate(context, config.id(), config.alias(), config.enabled(), config.modbusUnitId(), this.cm,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ protected void setModbus(BridgeModbus modbus) {
super.setModbus(modbus);
}

public GoodWeChargerPv2() {
}

@Activate
private void activate(ComponentContext context, ConfigPV2 config) throws OpenemsException {
if (super.activate(context, config.id(), config.alias(), config.enabled(), config.modbusUnitId(), this.cm,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class GoodWeChargerPv3 extends AbstractGoodWeEtCharger
@Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY)
private GoodWe essOrBatteryInverter;

@Reference(policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL)
@Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL)
private volatile Timedata timedata = null;

@Override
Expand Down Expand Up @@ -73,7 +73,9 @@ private void activate(ComponentContext context, ConfigPV3 config) throws Openems
@Override
@Deactivate
protected void deactivate() {
this.essOrBatteryInverter.removeCharger(this);
if (this.essOrBatteryInverter != null) {
this.essOrBatteryInverter.removeCharger(this);
}
super.deactivate();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package io.openems.edge.goodwe.charger.singlestring;

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;

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.ess.dccharger.api.EssDcCharger;
import io.openems.edge.goodwe.charger.AbstractGoodWeEtCharger;
import io.openems.edge.goodwe.charger.GoodWeCharger;
import io.openems.edge.goodwe.common.GoodWe;
import io.openems.edge.timedata.api.Timedata;
import io.openems.edge.timedata.api.TimedataProvider;

@Designate(ocd = ConfigPV4.class, factory = true)
@Component(//
name = "GoodWe.Charger-PV4", //
immediate = true, //
configurationPolicy = ConfigurationPolicy.REQUIRE //
)
@EventTopics({ //
EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE //
})
public class GoodWeChargerPv4 extends AbstractGoodWeEtCharger
implements GoodWeCharger, EssDcCharger, ModbusComponent, OpenemsComponent, EventHandler, TimedataProvider {

@Reference
private ConfigurationAdmin cm;

@Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY)
private GoodWe essOrBatteryInverter;

@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) {
super.setModbus(modbus);
}

@Activate
private void activate(ComponentContext context, ConfigPV4 config) throws OpenemsException {
if (super.activate(context, config.id(), config.alias(), config.enabled(), config.modbusUnitId(), this.cm,
"Modbus", config.modbus_id())) {
return;
}

if (OpenemsComponent.updateReferenceFilter(this.cm, this.servicePid(), "essOrBatteryInverter",
config.essOrBatteryInverter_id())) {
return;
}

if (this.essOrBatteryInverter != null) {
this.essOrBatteryInverter.addCharger(this);
}
}

@Override
@Deactivate
protected void deactivate() {
if (this.essOrBatteryInverter != null) {
this.essOrBatteryInverter.removeCharger(this);
}
super.deactivate();
}

@Override
protected int getStartAddress() {
return 35115;
}

@Override
public Timedata getTimedata() {
return this.timedata;
}

@Override
protected GoodWe getEssOrBatteryInverter() {
return this.essOrBatteryInverter;
}
}
Loading