Hi,
I wanna implement a custom battery which communicate with modbus, but I got an error:
2025-01-22T10:37:37,524 [_cycle ] INFO [onent.AbstractOpenemsComponent] [uzenergyBattery0] Activate io.openems.edge.uz.battery1
2025-01-22T10:37:37,529 [_cycle ] ERROR [.battery1.UzenergyBattery1Impl] bundle io.openems.edge.uzenergy:1.0.0.202501221028 (245)[io.openems.edge.uzenergy.battery1.UzenergyBattery1Impl(139)] : The activate method has thrown an exception
java.lang.IllegalArgumentException: StartAddress for Modbus Element wrong. Got [8451/0x2103] Expected [8450/0x2102]
at io.openems.edge.bridge.modbus.api.task.AbstractTask.<init>(AbstractTask.java:55) ~[?:?]
at io.openems.edge.bridge.modbus.api.task.AbstractReadTask.<init>(AbstractReadTask.java:39) ~[?:?]
at io.openems.edge.bridge.modbus.api.task.AbstractReadRegistersTask.<init>(AbstractReadRegistersTask.java:23) ~[?:?]
at io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask.<init>(FC3ReadRegistersTask.java:29) ~[?:?]
at io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask.<init>(FC3ReadRegistersTask.java:23) ~[?:?]
at io.openems.edge.uzenergy.battery1.UzenergyBattery1Impl.defineModbusProtocol(UzenergyBattery1Impl.java:217) ~[?:?]
at io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent.getModbusProtocol(AbstractOpenemsModbusComponent.java:238) ~[?:?]
at io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent.activate(AbstractOpenemsModbusComponent.java:120) ~[?:?]
at io.openems.edge.uzenergy.battery1.UzenergyBattery1Impl.activate(UzenergyBattery1Impl.java:91) ~[?:?]
at jdk.internal.reflect.GeneratedMethodAccessor11.invoke(Unknown Source) ~[?:?]
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:569) ~[?:?]
at org.apache.felix.scr.impl.inject.methods.BaseMethod.invokeMethod(BaseMethod.java:257) ~[?:?]
at org.apache.felix.scr.impl.inject.methods.BaseMethod.access$500(BaseMethod.java:41) ~[?:?]
at org.apache.felix.scr.impl.inject.methods.BaseMethod$Resolved.invoke(BaseMethod.java:701) ~[?:?]
at org.apache.felix.scr.impl.inject.methods.BaseMethod.invoke(BaseMethod.java:544) ~[?:?]
at org.apache.felix.scr.impl.inject.methods.ActivateMethod.invoke(ActivateMethod.java:317) ~[?:?]
at org.apache.felix.scr.impl.inject.methods.ActivateMethod.invoke(ActivateMethod.java:307) ~[?:?]
at org.apache.felix.scr.impl.manager.SingleComponentManager.createImplementationObject(SingleComponentManager.java:354) ~[?:?]
at org.apache.felix.scr.impl.manager.SingleComponentManager.createComponent(SingleComponentManager.java:115) ~[?:?]
at org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:1002) ~[?:?]
at org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:975) ~[?:?]
at org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:920) ~[?:?]
at org.apache.felix.framework.ServiceRegistrationImpl.getFactoryUnchecked(ServiceRegistrationImpl.java:349) ~[?:?]
at org.apache.felix.framework.ServiceRegistrationImpl.getService(ServiceRegistrationImpl.java:249) ~[?:?]
at org.apache.felix.framework.ServiceRegistry.getService(ServiceRegistry.java:362) ~[?:?]
at org.apache.felix.framework.Felix.getService(Felix.java:3984) ~[?:?]
at org.apache.felix.framework.BundleContextImpl.getService(BundleContextImpl.java:450) ~[?:?]
at org.apache.felix.eventadmin.impl.handler.EventHandlerProxy.obtain(EventHandlerProxy.java:296) ~[?:?]
at org.apache.felix.eventadmin.impl.handler.EventHandlerProxy.sendEvent(EventHandlerProxy.java:424) ~[?:?]
at org.apache.felix.eventadmin.impl.tasks.HandlerTask.runWithoutDenylistTiming(HandlerTask.java:82) ~[?:?]
at org.apache.felix.eventadmin.impl.tasks.SyncDeliverTasks.execute(SyncDeliverTasks.java:107) ~[?:?]
at org.apache.felix.eventadmin.impl.handler.EventAdminImpl.sendEvent(EventAdminImpl.java:155) ~[?:?]
at org.apache.felix.eventadmin.impl.security.EventAdminSecurityDecorator.sendEvent(EventAdminSecurityDecorator.java:96) ~[?:?]
at io.openems.common.event.EventBuilder.send(EventBuilder.java:68) ~[?:?]
at io.openems.edge.core.cycle.CycleWorker.forever(CycleWorker.java:50) ~[?:?]
at io.openems.common.worker.AbstractWorker$1.run(AbstractWorker.java:156) ~[?:?]
2025-01-22T10:37:37,550 [tchQueue] ERROR [Events.Framework ] FrameworkEvent ERROR
org.osgi.framework.ServiceException: Service factory returned null. (Component: io.openems.edge.uzenergy.battery1 (139))
at org.apache.felix.framework.ServiceRegistrationImpl.getFactoryUnchecked(ServiceRegistrationImpl.java:385) ~[?:?]
at org.apache.felix.framework.ServiceRegistrationImpl.getService(ServiceRegistrationImpl.java:249) ~[?:?]
at org.apache.felix.framework.ServiceRegistry.getService(ServiceRegistry.java:362) ~[?:?]
at org.apache.felix.framework.Felix.getService(Felix.java:3984) ~[?:?]
at org.apache.felix.framework.BundleContextImpl.getService(BundleContextImpl.java:450) ~[?:?]
at org.apache.felix.eventadmin.impl.handler.EventHandlerProxy.obtain(EventHandlerProxy.java:296) ~[?:?]
at org.apache.felix.eventadmin.impl.handler.EventHandlerProxy.sendEvent(EventHandlerProxy.java:424) ~[?:?]
at org.apache.felix.eventadmin.impl.tasks.HandlerTask.runWithoutDenylistTiming(HandlerTask.java:82) ~[?:?]
at org.apache.felix.eventadmin.impl.tasks.SyncDeliverTasks.execute(SyncDeliverTasks.java:107) ~[?:?]
at org.apache.felix.eventadmin.impl.handler.EventAdminImpl.sendEvent(EventAdminImpl.java:155) ~[?:?]
at org.apache.felix.eventadmin.impl.security.EventAdminSecurityDecorator.sendEvent(EventAdminSecurityDecorator.java:96) ~[?:?]
at io.openems.common.event.EventBuilder.send(EventBuilder.java:68) ~[?:?]
at io.openems.edge.core.cycle.CycleWorker.forever(CycleWorker.java:50) ~[?:?]
at io.openems.common.worker.AbstractWorker$1.run(AbstractWorker.java:156) ~[?:?]
It’s a simple implementation of SymmetricEss, only to get data from battery and display in dashboard.
my code is as follow:
public class UzenergySymmetricEssImpl extends AbstractOpenemsModbusComponent implements SymmetricEss, ModbusComponent,
ModbusSlave, UzenergySymmetricEss, EventHandler {
protected ModbusProtocol defineModbusProtocol() {
return new ModbusProtocol(this, //
new FC3ReadRegistersTask(0x0101, Priority.LOW,
m(SymmetricEss.ChannelId.GRID_MODE, new UnsignedWordElement(0x106),
new ElementToChannelConverter(value -> {
var intValue = TypeUtils.<Integer>getAsType(OpenemsType.INTEGER, value);
if (intValue != null) {
switch (intValue) {
case 1:
return GridMode.OFF_GRID;
case 2:
return GridMode.ON_GRID;
}
}
return GridMode.UNDEFINED;
})
)),
new FC3ReadRegistersTask(0x0200, Priority.LOW, //
m(SymmetricEss.ChannelId.ACTIVE_POWER, new SignedWordElement(0x0228), SCALE_FACTOR_2), //
m(SymmetricEss.ChannelId.REACTIVE_POWER, new SignedWordElement(0x0211), SCALE_FACTOR_2), //
m(SymmetricEss.ChannelId.MAX_APPARENT_POWER, new UnsignedWordElement(0x0232), SCALE_FACTOR_2) //
),
new FC3ReadRegistersTask(0x1400, Priority.LOW, //
m(SymmetricEss.ChannelId.SOC, new UnsignedWordElement(0x1402))
)
);
}
@Designate(ocd = Config.class, factory = true)
@Component(//
name = "io.openems.edge.uzenergy.battery1", //
immediate = true, //
configurationPolicy = ConfigurationPolicy.REQUIRE //
)
@EventTopics({ //
EdgeEventConstants.TOPIC_CYCLE_BEFORE_PROCESS_IMAGE //
})
public class UzenergyBattery1Impl extends AbstractOpenemsModbusComponent implements UzenergyBattery1, Battery,
ModbusComponent, ModbusSlave, EventHandler{
....
@Override
protected ModbusProtocol defineModbusProtocol() {
return new ModbusProtocol(this, new FC3ReadRegistersTask(0x2100, Priority.HIGH, //
m(new UnsignedWordElement(0x2100).onUpdateCallback(this.onRegister0x2100Update)) //
.m(Battery.ChannelId.VOLTAGE, SCALE_FACTOR_MINUS_1) // [V]
.build(), //
m(new SignedWordElement(0x2101)) //
.m(Battery.ChannelId.CURRENT, SCALE_FACTOR_MINUS_1) // [A]
.build(), //
m(Battery.ChannelId.SOC, new UnsignedWordElement(0x2103)), //
m(new UnsignedWordElement(0x2104)) //
.m(Battery.ChannelId.SOH, DIRECT_1_TO_1) // [%]
.build(), //
m(new UnsignedWordElement(0x2106)) //
.m(Battery.ChannelId.MAX_CELL_VOLTAGE, DIRECT_1_TO_1) //
.build(), //
m(new UnsignedWordElement(0x2108)) //
.m(Battery.ChannelId.MIN_CELL_VOLTAGE, DIRECT_1_TO_1) //
.build(), //
m(new SignedWordElement(0x210A)) //
.m(Battery.ChannelId.MAX_CELL_TEMPERATURE, SCALE_FACTOR_MINUS_1) //
.build(), //
m(new SignedWordElement(0x210C)) //
.m(Battery.ChannelId.MIN_CELL_TEMPERATURE, SCALE_FACTOR_MINUS_1) //
.build()) //
);
}
cofig of battery:
@ObjectClassDefinition(//
name = "io.openems.edge.uzenergy.ess", //
description = "Implements the io.openems.edge.uzenergy.ess system")
@interface Config {
@AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component")
String id() default "ess0";
@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";
String battery_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 "io.openems.edge.uzenergy [{id}]";
}