Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 3 additions & 1 deletion io.openems.edge.application/EdgeApp.bndrun
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@
bnd.identity;id='io.openems.edge.meter.virtual',\
bnd.identity;id='io.openems.edge.meter.weidmueller',\
bnd.identity;id='io.openems.edge.meter.ziehl',\
bnd.identity;id='io.openems.edge.meter.inepro',\
bnd.identity;id='io.openems.edge.onewire.thermometer',\
bnd.identity;id='io.openems.edge.predictor.lstm',\
bnd.identity;id='io.openems.edge.predictor.persistencemodel',\
Expand Down Expand Up @@ -496,4 +497,5 @@
org.owasp.encoder;version='[1.4.0,1.4.1)',\
reactive-streams;version='[1.0.4,1.0.5)',\
rrd4j;version='[3.10.0,3.10.1)',\
stax2-api;version='[4.2.2,4.2.3)'
stax2-api;version='[4.2.2,4.2.3)',\
io.openems.edge.meter.inepro;version=snapshot
23 changes: 23 additions & 0 deletions io.openems.edge.meter.inepro/.project
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.pro380modct</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>
16 changes: 16 additions & 0 deletions io.openems.edge.meter.inepro/bnd.bnd
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Bundle-Name: OpenEMS Edge io.openems.edge.meter.inepro
Bundle-Vendor: VEV Platform Services France
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

-testpath: \
${testpath},\
io.openems.common
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.openems.edge.meter.inepro.pro380modct;

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

import io.openems.common.types.MeterType;

@ObjectClassDefinition(//
name = "Meter inepro Pro380ModCT", //
description = "Implements the inepro Pro380ModCT meter.")
public @interface Config {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Config should be package-private - it's an internal implementation detail, not part of the public api


@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 "io.openems.edge.meter.pro380modct [{id}]";

@AttributeDefinition(name = "Meter-Type", description = "What is measured by this Meter?")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

package io.openems.edge.meter.inepro.pro380modct;

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

import io.openems.common.types.MeterType;

@ObjectClassDefinition(//
		name = "Meter inepro Pro380ModCT", //
		description = "Implements the inepro Pro380ModCT meter.")
public @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 = "Meter-Type", description = "What is measured by this Meter?")
	MeterType type() default MeterType.CONSUMPTION_METERED;

	@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.pro380modct [{id}]";
}

MeterType type() default MeterType.CONSUMPTION_METERED;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.openems.edge.meter.inepro.pro380modct;

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;
import io.openems.edge.meter.api.ElectricityMeter;

public interface Pro380modct extends ElectricityMeter, OpenemsComponent {

public enum ChannelId implements io.openems.edge.common.channel.ChannelId {
APPARENT_POWER_L1(Doc.of(OpenemsType.INTEGER).unit(Unit.VOLT_AMPERE)),
APPARENT_POWER_L2(Doc.of(OpenemsType.INTEGER).unit(Unit.VOLT_AMPERE)),
APPARENT_POWER_L3(Doc.of(OpenemsType.INTEGER).unit(Unit.VOLT_AMPERE)),
APPARENT_POWER(Doc.of(OpenemsType.INTEGER).unit(Unit.VOLT_AMPERE)),
POWER_FACTOR_L1(Doc.of(OpenemsType.INTEGER).unit(Unit.NONE)),
POWER_FACTOR_L2(Doc.of(OpenemsType.INTEGER).unit(Unit.NONE)),
POWER_FACTOR_L3(Doc.of(OpenemsType.INTEGER).unit(Unit.NONE)),
POWER_FACTOR(Doc.of(OpenemsType.INTEGER).unit(Unit.NONE));

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,138 @@
package io.openems.edge.meter.inepro.pro380modct;

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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also please apply Ctrl+Shift+O after all for Sorting the imports

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.FloatDoublewordElement;
import io.openems.edge.bridge.modbus.api.element.WordOrder;
import io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask;
import io.openems.edge.common.component.OpenemsComponent;
import io.openems.edge.common.taskmanager.Priority;
import io.openems.edge.meter.api.ElectricityMeter;
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.Deactivate;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicyOption;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.metatype.annotations.Designate;

@Designate(ocd = Config.class, factory = true)
@Component(//
name = "Meter.inepro.Pro380ModCT", //
immediate = true, //
configurationPolicy = ConfigurationPolicy.REQUIRE //
)
public class Pro380modctImpl extends AbstractOpenemsModbusComponent implements Pro380modct, ElectricityMeter, ModbusComponent, OpenemsComponent {

@Reference
private ConfigurationAdmin cm;

@Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY)
protected void setModbus(BridgeModbus modbus) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method overrides AbstractOpenemsModbusComponent.setModbus(). The @OverRide annotation provides compile-time safety and documents intent.

super.setModbus(modbus);
}

private Config config = null;

public Pro380modctImpl() {
super(//
OpenemsComponent.ChannelId.values(), //
ModbusComponent.ChannelId.values(), //
ElectricityMeter.ChannelId.values(), //
Pro380modct.ChannelId.values() //
);
}

@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() {
return new ModbusProtocol(
this,

// VOLTAGE + FREQUENCY
new FC3ReadRegistersTask(
0x5002, Priority.HIGH,
//m(Pro380modct.ChannelId.VOLTAGE, new FloatDoublewordElement(0x5000).wordOrder(WordOrder.MSWLSW)),
m(ElectricityMeter.ChannelId.VOLTAGE_L1, new FloatDoublewordElement(0x5002).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3),
m(ElectricityMeter.ChannelId.VOLTAGE_L2, new FloatDoublewordElement(0x5004).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3),
m(ElectricityMeter.ChannelId.VOLTAGE_L3, new FloatDoublewordElement(0x5006).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3),
m(ElectricityMeter.ChannelId.FREQUENCY, new FloatDoublewordElement(0x5008).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3)
),

// CURRENT (total + L1/L2/L3)
new FC3ReadRegistersTask(
0x500A, Priority.HIGH,
m(ElectricityMeter.ChannelId.CURRENT, new FloatDoublewordElement(0x500A).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3),
m(ElectricityMeter.ChannelId.CURRENT_L1, new FloatDoublewordElement(0x500C).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3),
m(ElectricityMeter.ChannelId.CURRENT_L2, new FloatDoublewordElement(0x500E).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3),
m(ElectricityMeter.ChannelId.CURRENT_L3, new FloatDoublewordElement(0x5010).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3)
),

// ACTIVE POWER (kW) total + L1/L2/L3
new FC3ReadRegistersTask(
0x5012, Priority.HIGH,
m(ElectricityMeter.ChannelId.ACTIVE_POWER, new FloatDoublewordElement(0x5012).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3),
m(ElectricityMeter.ChannelId.ACTIVE_POWER_L1, new FloatDoublewordElement(0x5014).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3),
m(ElectricityMeter.ChannelId.ACTIVE_POWER_L2, new FloatDoublewordElement(0x5016).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3),
m(ElectricityMeter.ChannelId.ACTIVE_POWER_L3, new FloatDoublewordElement(0x5018).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3)
),

// REACTIVE POWER (kvar) total + L1/L2/L3
new FC3ReadRegistersTask(
0x501A, Priority.HIGH,
m(ElectricityMeter.ChannelId.REACTIVE_POWER, new FloatDoublewordElement(0x501A).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3),
m(ElectricityMeter.ChannelId.REACTIVE_POWER_L1, new FloatDoublewordElement(0x501C).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3),
m(ElectricityMeter.ChannelId.REACTIVE_POWER_L2, new FloatDoublewordElement(0x501E).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3),
m(ElectricityMeter.ChannelId.REACTIVE_POWER_L3, new FloatDoublewordElement(0x5020).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3)
),

// APPARENT POWER (kVA) total + L1/L2/L3
new FC3ReadRegistersTask(
0x5022, Priority.HIGH,
m(Pro380modct.ChannelId.APPARENT_POWER, new FloatDoublewordElement(0x5022).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3),
m(Pro380modct.ChannelId.APPARENT_POWER_L1, new FloatDoublewordElement(0x5024).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3),
m(Pro380modct.ChannelId.APPARENT_POWER_L2, new FloatDoublewordElement(0x5026).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3),
m(Pro380modct.ChannelId.APPARENT_POWER_L3, new FloatDoublewordElement(0x5028).wordOrder(WordOrder.MSWLSW), ElementToChannelConverter.SCALE_FACTOR_3)
)
);

}


@Override
public String debugLog() {
return this.channel(ElectricityMeter.ChannelId.VOLTAGE_L1).value().toString()
+ " / " + this.channel(ElectricityMeter.ChannelId.CURRENT).value().toString()
+ " / " + this.channel(ElectricityMeter.ChannelId.ACTIVE_POWER).value().toString()
+ " / " + this.channel(ElectricityMeter.ChannelId.REACTIVE_POWER).value().toString()
+ " / " + this.channel(Pro380modct.ChannelId.APPARENT_POWER).value().toString();
}

@Override
public MeterType getMeterType() {
return this.config.type();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package io.openems.edge.meter.inepro.pro380modct;

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 {

public 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 setType(MeterType type) {
this.type = type;
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;
}

}
Loading