I recently got the problem that the modbus API is setting the channel values to null directly after setting a new value. Since that error wasn’t there at the beginning, I don’t know what can cause it. Do you have any idea?
2025-05-14T10:12:37,841 [modbusPI] INFO [.element.AbstractModbusElement] Element [UnsignedWordElementtype=INTEGER;ref=5108/0x13f4;DEBUG]] set value to [7747].
2025-05-14T10:12:37,841 [modbusPI] INFO [.element.AbstractModbusElement] Element [UnsignedWordElementtype=INTEGER;ref=5108/0x13f4;DEBUG]] set value to [null].
2025-05-14T10:12:37,841 [modbusPI] INFO [.element.AbstractModbusElement] Element [UnsignedWordElementtype=INTEGER;ref=5108/0x13f4;DEBUG]] set value to [null].
I digged a little bit deeper and found that this function is throwing an exception:
package io.openems.edge.bridge.modbus.api.task
class: AbstractReadTask
@Override
public ExecuteState execute(AbstractModbusBridge bridge) {
try {
var response = this.executeRequest(bridge, this.createModbusRequest());
// On error a log message has already been logged
try {
var result = this.parseResponse(response);
validateResponse(result, this.length);
// NOTE: onExecute has to be called before filling elements; but OK could be
// wrong if fillElements throws an exception.
this.onExecute.accept(ExecuteState.OK);
this.fillElements(result);
return ExecuteState.OK;
} catch (OpenemsException e1) {
logError(this.log, e1, "Parsing Response failed.");
throw e1;
}
} catch (Exception e) {
var executeState = new ExecuteState.Error(e);
this.onExecute.accept(executeState);
// Invalidate Elements
Stream.of(this.elements).forEach(el -> el.invalidate(bridge));
return executeState;
}
}
The exception:
Exception in AbstractReadTask: java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.Double (java.lang.Integer and java.lang.Double are in module java.base of loader ‘bootstrap’)
Current Workaround:
When commenting out that channels are set to “null” when an invalidValueCounter > 0 helps. But I don’t think its a good solution
Can you please share your code. It seems there is some incompatibility between your Channel definitions and Modbus mapping, that causes a conversion from Integer to Double.
Thats the code where the Modbus-Protocoll is defined. Did you mean that or additional code?
protected ModbusProtocol defineModbusProtocol() {ModbusProtocol modbusProtocol = new ModbusProtocol(this,
new FC3ReadRegistersTask(5095, Priority.HIGH,
m(SkaleEss.ChannelId.SKALE_ESS_STATE, new UnsignedWordElement(5095)),
...
m(SymmetricEss.ChannelId.CAPACITY, new UnsignedWordElement(5104),ElementToChannelConverter.SCALE_FACTOR_3),
m(EssTesvoltSkale.ChannelId.CAPACITY_AH, new UnsignedWordElement(5105)),
m(EssTesvoltSkale.ChannelId.SOH, new UnsignedWordElement(5106),ElementToChannelConverter.SCALE_FACTOR_MINUS_2),
m(SymmetricEss.ChannelId.SOC, new UnsignedWordElement(5107),ElementToChannelConverter.SCALE_FACTOR_MINUS_2),
m(EssDcCharger.ChannelId.VOLTAGE, new UnsignedWordElement(5108),ElementToChannelConverter.SCALE_FACTOR_2),
new DummyRegisterElement(5109, 5110),
m(EssTesvoltSkale.ChannelId.MAX_OPERATIONAL_VOLTAGE, new UnsignedWordElement(5111),ElementToChannelConverter.SCALE_FACTOR_2),
m(EssTesvoltSkale.ChannelId.MIN_OPERATIONAL_VOLTAGE, new UnsignedWordElement(5112), ElementToChannelConverter.SCALE_FACTOR_2),
...