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
2 changes: 1 addition & 1 deletion io.openems.edge.bridge.modbus/bnd.bnd
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ Bundle-Version: 1.0.0.${tstamp}
io.openems.edge.meter.api,\
io.openems.edge.pvinverter.api,\
io.openems.j2mod,\

io.openems.edge.ess.api
-testpath: \
${testpath}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package io.openems.edge.bridge.modbus.sunspec;

import java.util.Arrays;

/**
* Represents a Filtered SunSpec Model.
*/
public class FilteredSunSpecModel implements SunSpecModel {

private final SunSpecModel delegate;
private final SunSpecPoint[] points;

public FilteredSunSpecModel(SunSpecModel delegate, SunSpecPoint[] points) {
this.delegate = delegate;
this.points = points;
}

@Override
public String name() {
return this.delegate.name();
}

@Override
public String label() {
return this.delegate.label();
}

@Override
public SunSpecPoint[] points() {
return this.points;
}

/**
* Creates a {@link FilteredSunSpecModel} that delegates to the given
* {@link SunSpecModel} but excludes the specified {@link SunSpecPoint}s
* from the returned {@link SunSpecModel#points()}.
*
* <p>
* This can be used if a device implements a standard SunSpec model but
* does not support some points (e.g. vendor-specific event registers).
* The returned model behaves like the original model except that the
* excluded points are not exposed and therefore not mapped to Modbus
* registers.
*
* @param delegate the original {@link SunSpecModel}
* @param excluded the {@link SunSpecPoint}s that should be removed
* @return a {@link FilteredSunSpecModel} without the specified points
*/
public static FilteredSunSpecModel withoutPoints(SunSpecModel delegate, SunSpecPoint... excluded) {
var excludedSet = Arrays.asList(excluded);
var filtered = Arrays.stream(delegate.points())
.filter(p -> !excludedSet.contains(p))
.toArray(SunSpecPoint[]::new);
return new FilteredSunSpecModel(delegate, filtered);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package io.openems.edge.bridge.modbus.sunspec.ess;

import java.util.Map;
import java.util.Optional;

import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Deactivate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.openems.common.exceptions.OpenemsException;
import io.openems.edge.bridge.modbus.sunspec.AbstractOpenemsSunSpecComponent;
import io.openems.edge.bridge.modbus.sunspec.SunSpecModel;
import io.openems.edge.bridge.modbus.sunspec.SunSpecPoint;
import io.openems.edge.common.channel.Channel;
import io.openems.edge.common.component.OpenemsComponent;
import io.openems.edge.common.sum.GridMode;
import io.openems.edge.common.taskmanager.Priority;
import io.openems.edge.ess.api.ManagedSymmetricEss;
import io.openems.edge.ess.api.SymmetricEss;

public abstract class AbstractSunSpecEss extends AbstractOpenemsSunSpecComponent
implements ManagedSymmetricEss, SymmetricEss, OpenemsComponent {

private final Logger log = LoggerFactory.getLogger(AbstractSunSpecEss.class);

public AbstractSunSpecEss(Map<SunSpecModel, Priority> activeModels,
io.openems.edge.common.channel.ChannelId[] firstInitialChannelIds,
io.openems.edge.common.channel.ChannelId[]... furtherInitialChannelIds) throws OpenemsException {
super(activeModels, firstInitialChannelIds, furtherInitialChannelIds);
this._setGridMode(GridMode.ON_GRID);
}

/**
* Make sure to call this method from the inheriting OSGi Component.
*
* @param context ComponentContext of this component. Receive it
* from parameter for @Activate
* @param id ID of this component. Typically 'config.id()'
* @param alias Human-readable name of this Component. Typically
* 'config.alias()'. Defaults to 'id' if empty
* @param enabled Whether the component should be enabled.
* Typically 'config.enabled()'
* @param unitId Unit-ID of the Modbus target
* @param cm An instance of ConfigurationAdmin. Receive it
* using @Reference
* @param modbusReference The name of the @Reference setter method for the
* Modbus bridge - e.g. 'Modbus' if you have a
* setModbus()-method
* @param modbusId The ID of the Modbus bridge. Typically
* 'config.modbus_id()'
* @param readFromCommonBlockNo the starting block number
* @return true if the target filter was updated. You may use it to abort the
* activate() method.
* @throws OpenemsException on error
*/
@Override
protected boolean activate(ComponentContext context, String id, String alias, boolean enabled, int unitId,
ConfigurationAdmin cm, String modbusReference, String modbusId, int readFromCommonBlockNo)
throws OpenemsException {
return super.activate(context, id, alias, enabled, unitId, cm, modbusReference, modbusId,
readFromCommonBlockNo);
}

/**
* Make sure to call this method from the inheriting OSGi Component.
*/
@Override
@Deactivate
protected void deactivate() {
super.deactivate();
}

@Override
public String debugLog() {
return new StringBuilder() //
.append("SoC:").append(this.getSoc().asString()) //
.append("|ESS ActivePower:").append(this.getActivePower().asString()) //
.toString();
}

@Override
protected void onSunSpecInitializationCompleted() {
this.logInfo(this.log, "SunSpec initialization finished. " + this.channels().size() + " Channels available.");
}

@Override
protected <T extends Channel<?>> Optional<T> getSunSpecChannel(SunSpecPoint point) {
return super.getSunSpecChannel(point);
}

@Override
protected <T extends Channel<?>> T getSunSpecChannelOrError(SunSpecPoint point) throws OpenemsException {
return super.getSunSpecChannelOrError(point);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@org.osgi.annotation.versioning.Version("1.0.0")
@org.osgi.annotation.bundle.Export
package io.openems.edge.bridge.modbus.sunspec.ess;
7 changes: 6 additions & 1 deletion io.openems.edge.solaredge/bnd.bnd
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ Bundle-Version: 1.0.0.${tstamp}
-buildpath: \
${buildpath},\
io.openems.common,\
io.openems.edge.battery.api,\
io.openems.edge.batteryinverter.api,\
io.openems.edge.bridge.modbus,\
io.openems.edge.common,\
io.openems.edge.ess.api,\
io.openems.edge.ess.generic,\
io.openems.edge.meter.api,\
io.openems.edge.pvinverter.api,\

io.openems.edge.timedata.api,\
io.openems.j2mod
-testpath: \
${testpath},\
io.openems.j2mod,\
19 changes: 15 additions & 4 deletions io.openems.edge.solaredge/readme.adoc
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
= SolarEdge PV Inverter + Grid-Meter
= SolarEdge PV Inverter + Grid-Meter + Hybrid Inverters

Implementation of the SolarEdge PV inverters.

Implemented Natures:
PV-Inverter::
- ElectricityMeter

ESS::
- HybridEss
- SymmetricEss
- ManagedSymmetricEss
- AsymmetricEss
- ManagedAsymmetricEss
- SinglePhaseEss
- ManagedSinglePhaseEss

Charger::
- EssDcCharger


https://github.com/OpenEMS/openems/tree/develop/io.openems.edge.solaredge[Source Code icon:github[]]
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.openems.edge.solaredge.charger;

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


@ObjectClassDefinition(name = "SolarEdge Charger", //
description = "Implements the SolarEdge Charger.")
@interface Config {

@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 "";

@AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?")
boolean enabled() default true;

@AttributeDefinition(name = "SolarEdge ESS-Inverter", description = "ID of SolarEdge Energy Storage System.")
String essInverter_id() default "ess0";

@AttributeDefinition(name = "SolarEdge ESS-Inverter target filter", description = "This is auto-generated by 'SolarEdge ESS-Inverter'.")
String essInverter_target() default "(enabled=true)";

String webconsole_configurationFactory_nameHint() default "Charger SolarEdge [{id}]";

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.openems.edge.solaredge.charger;

import io.openems.edge.common.channel.Doc;

import io.openems.edge.common.component.OpenemsComponent;
import io.openems.edge.ess.dccharger.api.EssDcCharger;

public interface SolarEdgeCharger extends EssDcCharger, 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;
}
}

}
Loading