-
Notifications
You must be signed in to change notification settings - Fork 432
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
286 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
io.openems.edge.edge2edge/src/io/openems/edge/edge2edge/meter/Config.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package io.openems.edge.edge2edge.meter; | ||
|
||
import org.osgi.service.metatype.annotations.AttributeDefinition; | ||
import org.osgi.service.metatype.annotations.ObjectClassDefinition; | ||
|
||
import io.openems.edge.meter.api.MeterType; | ||
|
||
@ObjectClassDefinition(// | ||
name = "Edge-2-Edge Meter", // | ||
description = "Connects an energy storage system from a slave OpenEMS Edge via Modbus") | ||
@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 = "Remote Component-ID", description = "Component-ID of ESS at the slave OpenEMS Edge.") | ||
String remoteComponentId() default "meter0"; | ||
|
||
@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 = "Meter-Type", description = "What is measured by this Meter?") | ||
MeterType type() default MeterType.PRODUCTION; | ||
|
||
@AttributeDefinition(name = "Modbus target filter", description = "This is auto-generated by 'Modbus-ID'.") | ||
String Modbus_target() default "(enabled=true)"; | ||
|
||
String webconsole_configurationFactory_nameHint() default "Edge-2-Edge Meter [{id}]"; | ||
|
||
} |
22 changes: 22 additions & 0 deletions
22
io.openems.edge.edge2edge/src/io/openems/edge/edge2edge/meter/Edge2EdgeMeter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package io.openems.edge.edge2edge.meter; | ||
|
||
import io.openems.edge.common.channel.Doc; | ||
import io.openems.edge.common.component.OpenemsComponent; | ||
|
||
public interface Edge2EdgeMeter extends 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; | ||
} | ||
} | ||
} |
98 changes: 98 additions & 0 deletions
98
io.openems.edge.edge2edge/src/io/openems/edge/edge2edge/meter/Edge2EdgeMeterImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package io.openems.edge.edge2edge.meter; | ||
|
||
import java.util.List; | ||
import java.util.function.Consumer; | ||
|
||
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.metatype.annotations.Designate; | ||
|
||
import io.openems.common.channel.AccessMode; | ||
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.modbusslave.ModbusRecord; | ||
import io.openems.edge.common.modbusslave.ModbusSlaveNatureTable; | ||
import io.openems.edge.edge2edge.common.AbstractEdge2Edge; | ||
import io.openems.edge.edge2edge.common.Edge2Edge; | ||
import io.openems.edge.meter.api.ElectricityMeter; | ||
import io.openems.edge.meter.api.MeterType; | ||
|
||
@Designate(ocd = Config.class, factory = true) | ||
@Component(// | ||
name = "Edge2Edge.Meter", // | ||
immediate = true, // | ||
configurationPolicy = ConfigurationPolicy.REQUIRE // | ||
) | ||
public class Edge2EdgeMeterImpl extends AbstractEdge2Edge | ||
implements Edge2EdgeMeter, ElectricityMeter, Edge2Edge, ModbusComponent, OpenemsComponent { | ||
|
||
@Reference | ||
protected ConfigurationAdmin cm; | ||
|
||
@Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) | ||
protected void setModbus(BridgeModbus modbus) { | ||
super.setModbus(modbus); | ||
} | ||
|
||
private Config config; | ||
|
||
public Edge2EdgeMeterImpl() throws OpenemsException { | ||
super(// | ||
List.of(// | ||
OpenemsComponent::getModbusSlaveNatureTable, // | ||
ElectricityMeter::getModbusSlaveNatureTable // | ||
), // | ||
OpenemsComponent.ChannelId.values(), // | ||
ModbusComponent.ChannelId.values(), // | ||
Edge2Edge.ChannelId.values(), // | ||
ElectricityMeter.ChannelId.values() // | ||
); | ||
} | ||
|
||
@Activate | ||
private void activate(ComponentContext context, Config config) throws OpenemsException { | ||
this.config = config; | ||
if (super.activate(context, config.id(), config.alias(), config.enabled(), config.modbusUnitId(), this.cm, | ||
"Modbus", config.modbus_id(), config.remoteComponentId(), AccessMode.READ_ONLY)) { | ||
return; | ||
} | ||
} | ||
|
||
@Deactivate | ||
protected void deactivate() { | ||
super.deactivate(); | ||
} | ||
|
||
@Override | ||
protected Consumer<Object> getOnUpdateCallback(ModbusSlaveNatureTable modbusSlaveNatureTable, ModbusRecord record) { | ||
return null; | ||
} | ||
|
||
@Override | ||
protected io.openems.edge.common.channel.ChannelId getWriteChannelId(ModbusSlaveNatureTable modbusSlaveNatureTable, | ||
ModbusRecord record) { | ||
// No writable Channels | ||
return null; | ||
} | ||
|
||
@Override | ||
public String debugLog() { | ||
return "L:" + this.getActivePower().asString(); | ||
} | ||
|
||
@Override | ||
public MeterType getMeterType() { | ||
return this.config.type(); | ||
} | ||
|
||
} |
30 changes: 30 additions & 0 deletions
30
...penems.edge.edge2edge/test/io/openems/edge/edge2edge/meter/Edge2EdgeEssMeterImplTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package io.openems.edge.edge2edge.meter; | ||
|
||
import org.junit.Test; | ||
|
||
import io.openems.edge.bridge.modbus.test.DummyModbusBridge; | ||
import io.openems.edge.common.test.AbstractComponentTest.TestCase; | ||
import io.openems.edge.common.test.ComponentTest; | ||
import io.openems.edge.common.test.DummyConfigurationAdmin; | ||
import io.openems.edge.meter.api.MeterType; | ||
|
||
public class Edge2EdgeEssMeterImplTest { | ||
|
||
private static final String COMPONENT_ID = "meter0"; | ||
private static final String MODBUS_ID = "modbus0"; | ||
|
||
@Test | ||
public void test() throws Exception { | ||
new ComponentTest(new Edge2EdgeMeterImpl()) // | ||
.addReference("cm", new DummyConfigurationAdmin()) // | ||
.addReference("setModbus", new DummyModbusBridge(MODBUS_ID)) // | ||
.activate(MyConfig.create() // | ||
.setId(COMPONENT_ID) // | ||
.setModbusId(MODBUS_ID) // | ||
.setRemoteComponentId(COMPONENT_ID) // | ||
.setMeterType(MeterType.PRODUCTION) // | ||
.build()) | ||
.next(new TestCase()); | ||
} | ||
|
||
} |
91 changes: 91 additions & 0 deletions
91
io.openems.edge.edge2edge/test/io/openems/edge/edge2edge/meter/MyConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package io.openems.edge.edge2edge.meter; | ||
|
||
import io.openems.common.test.AbstractComponentConfig; | ||
import io.openems.common.utils.ConfigUtils; | ||
import io.openems.edge.meter.api.MeterType; | ||
|
||
@SuppressWarnings("all") | ||
public class MyConfig extends AbstractComponentConfig implements Config { | ||
|
||
protected static class Builder { | ||
private String id; | ||
private String modbusId = null; | ||
private int modbusUnitId; | ||
private String remoteComponentId; | ||
private MeterType type; | ||
|
||
private Builder() { | ||
} | ||
|
||
public Builder setId(String id) { | ||
this.id = id; | ||
return this; | ||
} | ||
|
||
public Builder setModbusId(String modbusId) { | ||
this.modbusId = modbusId; | ||
return this; | ||
} | ||
|
||
public Builder setModbusUnitId(int modbusUnitId) { | ||
this.modbusUnitId = modbusUnitId; | ||
return this; | ||
} | ||
|
||
public Builder setRemoteComponentId(String remoteComponentId) { | ||
this.remoteComponentId = remoteComponentId; | ||
return this; | ||
} | ||
|
||
public Builder setMeterType(MeterType type) { | ||
this.type = type; | ||
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 String Modbus_target() { | ||
return ConfigUtils.generateReferenceTargetFilter(this.id(), this.modbus_id()); | ||
} | ||
|
||
@Override | ||
public int modbusUnitId() { | ||
return this.builder.modbusUnitId; | ||
} | ||
|
||
@Override | ||
public String remoteComponentId() { | ||
return this.builder.remoteComponentId; | ||
} | ||
|
||
@Override | ||
public MeterType type() { | ||
return this.builder.type; | ||
} | ||
|
||
} |