- 
                Notifications
    You must be signed in to change notification settings 
- Fork 513
My Meter DDSU666 (Implementing a device) #3307
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <classpath> | ||
| <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21"> | ||
| <attributes> | ||
| <attribute name="module" value="true"/> | ||
| </attributes> | ||
| </classpathentry> | ||
| <classpathentry kind="con" path="aQute.bnd.classpath.container"/> | ||
| <classpathentry kind="src" output="bin" path="src"/> | ||
| <classpathentry kind="src" output="bin_test" path="test"> | ||
| <attributes> | ||
| <attribute name="test" value="true"/> | ||
| </attributes> | ||
| </classpathentry> | ||
| <classpathentry kind="output" path="bin"/> | ||
| </classpath> | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1 @@ | ||
| /bin_test/ | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <projectDescription> | ||
| <name>io.openems.edge.meter.ddsu666</name> | ||
| <comment></comment> | ||
| <projects> | ||
| </projects> | ||
| <buildSpec> | ||
| <buildCommand> | ||
| <name>org.eclipse.jdt.core.javabuilder</name> | ||
| <arguments> | ||
| </arguments> | ||
| </buildCommand> | ||
| <buildCommand> | ||
| <name>bndtools.core.bndbuilder</name> | ||
| <arguments> | ||
| </arguments> | ||
| </buildCommand> | ||
| </buildSpec> | ||
| <natures> | ||
| <nature>org.eclipse.jdt.core.javanature</nature> | ||
| <nature>bndtools.core.bndnature</nature> | ||
| </natures> | ||
| </projectDescription> | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| eclipse.preferences.version=1 | ||
| encoding//src/io/openems/edge/meter/ddsu666/Config.java=UTF-8 | ||
| encoding//src/io/openems/edge/meter/ddsu666/MeterDDSU666.java=UTF-8 | ||
| encoding//src/io/openems/edge/meter/ddsu666/MeterDDSU666Impl.java=UTF-8 | ||
| encoding//test/io/openems/edge/meter/ddsu666/MyConfig.java=UTF-8 | ||
| encoding//test/io/openems/edge/meter/ddsu666/MyModbusDeviceTest.java=UTF-8 | ||
| encoding/<project>=UTF-8 | ||
| encoding/bnd.bnd=UTF-8 | ||
| encoding/readme.adoc=UTF-8 | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| eclipse.preferences.version=1 | ||
| org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 | ||
| org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve | ||
| org.eclipse.jdt.core.compiler.compliance=21 | ||
| org.eclipse.jdt.core.compiler.debug.lineNumber=generate | ||
| org.eclipse.jdt.core.compiler.debug.localVariable=generate | ||
| org.eclipse.jdt.core.compiler.debug.sourceFile=generate | ||
| org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled | ||
| org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning | ||
| org.eclipse.jdt.core.compiler.release=enabled | ||
| org.eclipse.jdt.core.compiler.source=21 | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| Bundle-Name: OpenEMS Edge io.openems.edge.meter.ddsu666 | ||
| Bundle-Vendor: OpenEMS Association e.V. | ||
| Bundle-License: https://opensource.org/licenses/EPL-2.0 | ||
| Bundle-Version: 1.0.0.${tstamp} | ||
|  | ||
| -buildpath: \ | ||
| ${buildpath},\ | ||
| io.openems.j2mod,\ | ||
| io.openems.common,\ | ||
| io.openems.edge.bridge.modbus,\ | ||
| io.openems.edge.common,\ | ||
| io.openems.edge.meter.api;version=snapshot | ||
|  | ||
| -testpath: \ | ||
| ${testpath} | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1 @@ | ||
| /home/phat/openems/io.openems.edge.meter.ddsu666/generated/io.openems.edge.meter.ddsu666.jar | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| = io.openems.edge.meter.ddsu666 | ||
|  | ||
| https://github.com/OpenEMS/openems/tree/develop/io.openems.edge.meter.ddsu666[Source Code icon:github[]] | 
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Personally I would name the Package meter.chint and under this Package implement the ddsu666 as there are many more (I am working on the DTSU-666 which is the 3-Phase Version of the DDSU | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| package io.openems.edge.meter.ddsu666; | ||
|  | ||
| import org.osgi.service.metatype.annotations.AttributeDefinition; | ||
| import org.osgi.service.metatype.annotations.ObjectClassDefinition; | ||
|  | ||
|  | ||
| import io.openems.common.types.MeterType; | ||
| @ObjectClassDefinition(// | ||
| name = "MeterDDSU666", // | ||
| description = "") | ||
| @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 = "Grid, Production (=default), Consumption") | ||
| MeterType type() default MeterType.PRODUCTION; | ||
|  | ||
| @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 "io.openems.edge.meter.ddsu666 [{id}]"; | ||
|  | ||
| } | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package io.openems.edge.meter.ddsu666; | ||
|  | ||
| import org.osgi.service.event.EventHandler; | ||
|  | ||
| import io.openems.common.channel.Unit; | ||
| import io.openems.common.types.OpenemsType; | ||
| import io.openems.edge.common.channel.Doc; | ||
| import io.openems.edge.common.component.OpenemsComponent; | ||
|  | ||
|  | ||
| public interface MeterDDSU666 extends OpenemsComponent { | ||
|  | ||
| public enum ChannelId implements io.openems.edge.common.channel.ChannelId { | ||
|  | ||
| POWER_FACTOR(Doc.of(OpenemsType.FLOAT) // | ||
| .unit(Unit.NONE) // | ||
| .text("Power Factor")); | ||
|  | ||
| private final Doc doc; | ||
|  | ||
| private ChannelId(Doc doc) { | ||
| this.doc = doc; | ||
| } | ||
|  | ||
| @Override | ||
| public Doc doc() { | ||
| return this.doc; | ||
| } | ||
| } | ||
|  | ||
| } | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| package io.openems.edge.meter.ddsu666; | ||
|  | ||
| 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.edge.common.channel.Doc; | ||
| import io.openems.edge.bridge.modbus.api.element.FloatDoublewordElement; | ||
| import io.openems.edge.bridge.modbus.api.element.WordOrder; | ||
| import io.openems.edge.common.channel.FloatReadChannel; | ||
| 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.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.DummyRegisterElement; | ||
| import io.openems.edge.bridge.modbus.api.element.SignedDoublewordElement; | ||
| 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.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.common.modbusslave.ModbusType; | ||
|  | ||
| @Designate(ocd = Config.class, factory = true) | ||
| @Component(// | ||
| name = "MeterDDSU666", // | ||
| immediate = true, // | ||
| configurationPolicy = ConfigurationPolicy.REQUIRE // | ||
| ) | ||
| public class MeterDDSU666Impl extends AbstractOpenemsModbusComponent implements MeterDDSU666, ElectricityMeter, ModbusSlave, ModbusComponent, OpenemsComponent { | ||
|  | ||
| @Reference | ||
| private ConfigurationAdmin cm; | ||
|  | ||
| @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) | ||
| protected void setModbus(BridgeModbus modbus) { | ||
| super.setModbus(modbus); | ||
| } | ||
|  | ||
| private Config config = null; | ||
|  | ||
| public MeterDDSU666Impl() { | ||
| super(// | ||
| OpenemsComponent.ChannelId.values(), // | ||
| ModbusComponent.ChannelId.values(), // | ||
| MeterDDSU666.ChannelId.values(), // | ||
| ElectricityMeter.ChannelId.values()// | ||
| ); | ||
| // Automatically calculate sum values from L1/L2/L3 | ||
| ElectricityMeter.calculateSumCurrentFromPhases(this); | ||
| ElectricityMeter.calculateAverageVoltageFromPhases(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 | ||
| protected ModbusProtocol defineModbusProtocol() { | ||
| // TODO implement ModbusProtocol | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove unnecessary Comment | ||
| return new ModbusProtocol(this, | ||
| new FC3ReadRegistersTask(8192, Priority.HIGH, | ||
| m(ElectricityMeter.ChannelId.VOLTAGE, new FloatDoublewordElement(8192)) | ||
| .wordOrder(WordOrder.MSWLSW), | ||
| m(ElectricityMeter.ChannelId.CURRENT, new FloatDoublewordElement(8194)) | ||
| .wordOrder(WordOrder.MSWLSW), | ||
| m(ElectricityMeter.ChannelId.ACTIVE_POWER, new FloatDoublewordElement(8196)) | ||
| .wordOrder(WordOrder.MSWLSW) | ||
| ), | ||
| new FC3ReadRegistersTask(8202, Priority.HIGH, | ||
| m(MeterDDSU666.ChannelId.POWER_FACTOR, new FloatDoublewordElement(8202)) | ||
| .wordOrder(WordOrder.MSWLSW), | ||
| m(ElectricityMeter.ChannelId.FREQUENCY, new FloatDoublewordElement(8206)) | ||
| .wordOrder(WordOrder.MSWLSW) | ||
| ), | ||
| new FC3ReadRegistersTask(16384, Priority.LOW, | ||
| m(ElectricityMeter.ChannelId.ACTIVE_CONSUMPTION_ENERGY, new FloatDoublewordElement(16384)) | ||
| .wordOrder(WordOrder.MSWLSW) | ||
|  | ||
| ) | ||
| ); | ||
| } | ||
|  | ||
| private MeterType meterType = MeterType.PRODUCTION; | ||
| @Override | ||
| public MeterType getMeterType() { | ||
| return this.config.type(); | ||
| } | ||
|  | ||
| @Override | ||
| public String debugLog() { | ||
| return "L:" + this.getActivePower().asString(); | ||
| } | ||
| @Override | ||
| public ModbusSlaveTable getModbusSlaveTable(AccessMode accessMode) { | ||
| return new ModbusSlaveTable( | ||
| // Các nature tables cơ bản | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. english please | ||
| OpenemsComponent.getModbusSlaveNatureTable(accessMode), | ||
| ElectricityMeter.getModbusSlaveNatureTable(accessMode), | ||
|  | ||
| // Custom channels của DDSu666 | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. english please | ||
| ModbusSlaveNatureTable.of(MeterDDSU666.class, accessMode, 100) | ||
| .channel(0, MeterDDSU666.ChannelId.POWER_FACTOR, ModbusType.FLOAT32) | ||
| .build() | ||
| ); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| package io.openems.edge.meter.ddsu666; | ||
|  | ||
| import io.openems.common.utils.ConfigUtils; | ||
| import io.openems.common.test.AbstractComponentConfig; | ||
| import io.openems.common.types.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 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 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 MeterType type() { | ||
| return this.builder.type; | ||
| } | ||
|  | ||
| } | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package io.openems.edge.meter.ddsu666; | ||
|  | ||
| import org.junit.Test; | ||
|  | ||
| import io.openems.edge.common.test.AbstractComponentTest.TestCase; | ||
| import io.openems.edge.bridge.modbus.test.DummyModbusBridge; | ||
| import io.openems.edge.common.test.ComponentTest; | ||
| import io.openems.edge.common.test.DummyConfigurationAdmin; | ||
| import io.openems.common.types.MeterType; | ||
|  | ||
| public class MyModbusDeviceTest { | ||
|  | ||
| @Test | ||
| public void test() throws Exception { | ||
| new ComponentTest(new MeterDDSU666Impl()) // | ||
| .addReference("cm", new DummyConfigurationAdmin()) // | ||
| .addReference("setModbus", new DummyModbusBridge("modbus0")) // | ||
| .activate(MyConfig.create() // | ||
| .setId("component0") // | ||
| .setModbusId("modbus0") // | ||
| .build()) // | ||
| .next(new TestCase()) // | ||
| .deactivate(); | ||
| } | ||
|  | ||
| } | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please apply the prepare-commit.sh script again