Skip to content

Commit 25a681b

Browse files
authored
Modbus Bridge: refactor & cleanup Elements (OpenEMS#2273)
This is a follow-up PR to OpenEMS#1976. The initial intention for this PR was a bug that existed previously: When the Modbus Bridge detects a 'defective device', i.e. it is not possible to read from an external device connected via modbus, e.g. because it is turned off, somebody unplugged the cable, etc., all Channels are 'invalidated'. This invalidation did not work properly for individual Bits in `BitsWordElements`. When looking at the previous code it becomes obvious how such a bug could happen. The structure and inheritance was complicated and @OVERRIDES were often unclear. Also there were hardly any JUnit tests to validate the function. Because of this I had added JUnit tests in OpenEMS#2283, then refactored all Modbus Element classes and revalidated that they behave exactly the same way as before with the JUnit tests. This implementation is tested on a couple of production systems, including my own private system.
1 parent b0dff31 commit 25a681b

File tree

76 files changed

+876
-1307
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+876
-1307
lines changed

io.openems.edge.battery.fenecon.home/src/io/openems/edge/battery/fenecon/home/BatteryFeneconHomeImpl.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -738,8 +738,8 @@ private synchronized void initializeTowerModulesChannels(int numberOfTowers, int
738738
* for Cell-Voltages.Channel-IDs are like "TOWER_0_OFFSET_2_TEMPERATURE_003".
739739
* Channel-IDs are like "TOWER_0_OFFSET_2_VOLTAGE_003".
740740
*/
741-
var ameVolt = new ModbusElement<?>[SENSORS_PER_MODULE];
742-
var ameTemp = new ModbusElement<?>[SENSORS_PER_MODULE];
741+
var ameVolt = new ModbusElement[SENSORS_PER_MODULE];
742+
var ameTemp = new ModbusElement[SENSORS_PER_MODULE];
743743
for (var j = 0; j < SENSORS_PER_MODULE; j++) {
744744
{
745745
// Create Voltage Channel

io.openems.edge.battery.soltaro/src/io/openems/edge/battery/soltaro/cluster/versionb/BatterySoltaroClusterVersionBImpl.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@
4343
import io.openems.edge.bridge.modbus.api.ElementToChannelConverter;
4444
import io.openems.edge.bridge.modbus.api.ModbusComponent;
4545
import io.openems.edge.bridge.modbus.api.ModbusProtocol;
46-
import io.openems.edge.bridge.modbus.api.element.AbstractModbusElement;
4746
import io.openems.edge.bridge.modbus.api.element.BitsWordElement;
4847
import io.openems.edge.bridge.modbus.api.element.DummyRegisterElement;
48+
import io.openems.edge.bridge.modbus.api.element.ModbusElement;
4949
import io.openems.edge.bridge.modbus.api.element.UnsignedWordElement;
5050
import io.openems.edge.bridge.modbus.api.task.FC16WriteRegistersTask;
5151
import io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask;
@@ -682,13 +682,12 @@ private int getAddressContactorControl(int addressOffsetRack) {
682682
return addressOffsetRack + OFFSET_CONTACTOR_CONTROL;
683683
}
684684

685-
protected final <T extends AbstractModbusElement<?, ?>> T map(io.openems.edge.common.channel.ChannelId channelId,
686-
T element) {
685+
protected final <T extends ModbusElement> T map(io.openems.edge.common.channel.ChannelId channelId, T element) {
687686
return this.m(channelId, element);
688687
}
689688

690-
protected final <T extends AbstractModbusElement<?, ?>> T map(io.openems.edge.common.channel.ChannelId channelId,
691-
T element, ElementToChannelConverter converter) {
689+
protected final <T extends ModbusElement> T map(io.openems.edge.common.channel.ChannelId channelId, T element,
690+
ElementToChannelConverter converter) {
692691
return this.m(channelId, element, converter);
693692
}
694693

io.openems.edge.battery.soltaro/src/io/openems/edge/battery/soltaro/cluster/versionb/SingleRack.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ protected Collection<Task> getTasks() {
252252

253253
// Cell voltages
254254
for (var i = 0; i < this.numberOfSlaves; i++) {
255-
var elements = new ArrayList<ModbusElement<?>>();
255+
var elements = new ArrayList<ModbusElement>();
256256
for (var j = i * VOLTAGE_SENSORS_PER_MODULE; j < (i + 1) * VOLTAGE_SENSORS_PER_MODULE; j++) {
257257
var key = this.getSingleCellPrefix(j) + "_" + VOLTAGE;
258258
var uwe = this.getUnsignedWordElement(VOLTAGE_ADDRESS_OFFSET + j);
@@ -268,14 +268,14 @@ protected Collection<Task> getTasks() {
268268
.subList(x * maxElementsPerTask, Math.min((x + 1) * maxElementsPerTask, elements.size())) //
269269
.stream() //
270270
.toArray(ModbusElement[]::new);
271-
tasks.add(new FC3ReadRegistersTask(taskElements[0].getStartAddress(), Priority.LOW, taskElements));
271+
tasks.add(new FC3ReadRegistersTask(taskElements[0].startAddress, Priority.LOW, taskElements));
272272
}
273273

274274
}
275275

276276
// Cell temperatures
277277
for (var i = 0; i < this.numberOfSlaves; i++) {
278-
var elements = new ArrayList<ModbusElement<?>>();
278+
var elements = new ArrayList<ModbusElement>();
279279
for (var j = i * TEMPERATURE_SENSORS_PER_MODULE; j < (i + 1) * TEMPERATURE_SENSORS_PER_MODULE; j++) {
280280
var key = this.getSingleCellPrefix(j) + "_" + TEMPERATURE;
281281

@@ -292,7 +292,7 @@ protected Collection<Task> getTasks() {
292292
.subList(x * maxElementsPerTask, Math.min((x + 1) * maxElementsPerTask, elements.size())) //
293293
.stream() //
294294
.toArray(ModbusElement[]::new);
295-
tasks.add(new FC3ReadRegistersTask(taskElements[0].getStartAddress(), Priority.LOW, taskElements));
295+
tasks.add(new FC3ReadRegistersTask(taskElements[0].startAddress, Priority.LOW, taskElements));
296296
}
297297
}
298298

io.openems.edge.battery.soltaro/src/io/openems/edge/battery/soltaro/cluster/versionc/BatterySoltaroClusterVersionCImpl.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ private void updateRackChannels(Integer numberOfModules, TreeSet<Rack> racks) th
386386
} //
387387
Consumer<CellChannelFactory.Type> addCellChannels = type -> {
388388
for (var i = 0; i < numberOfModules; i++) {
389-
var elements = new ModbusElement<?>[type.getSensorsPerModule()];
389+
var elements = new ModbusElement[type.getSensorsPerModule()];
390390
for (var j = 0; j < type.getSensorsPerModule(); j++) {
391391
var sensorIndex = i * type.getSensorsPerModule() + j;
392392
var channelId = CellChannelFactory.create(r, type, sensorIndex);
@@ -411,7 +411,7 @@ private void updateRackChannels(Integer numberOfModules, TreeSet<Rack> racks) th
411411

412412
// WARN_LEVEL_Pre Alarm (Pre Alarm configuration registers RW)
413413
{
414-
ModbusElement<?>[] elements = {
414+
ModbusElement[] elements = {
415415
m(this.createChannelId(r, RackChannel.PRE_ALARM_CELL_OVER_VOLTAGE_ALARM),
416416
new UnsignedWordElement(r.offset + 0x080)), //
417417
m(this.createChannelId(r, RackChannel.PRE_ALARM_CELL_OVER_VOLTAGE_RECOVER),
@@ -486,7 +486,7 @@ private void updateRackChannels(Integer numberOfModules, TreeSet<Rack> racks) th
486486

487487
// WARN_LEVEL1 (Level1 warning registers RW)
488488
{
489-
ModbusElement<?>[] elements = {
489+
ModbusElement[] elements = {
490490
m(this.createChannelId(r, RackChannel.LEVEL1_CELL_OVER_VOLTAGE_PROTECTION),
491491
new UnsignedWordElement(r.offset + 0x040)), //
492492
m(this.createChannelId(r, RackChannel.LEVEL1_CELL_OVER_VOLTAGE_RECOVER),
@@ -561,7 +561,7 @@ private void updateRackChannels(Integer numberOfModules, TreeSet<Rack> racks) th
561561

562562
// WARN_LEVEL2 (Level2 Protection registers RW)
563563
{
564-
ModbusElement<?>[] elements = {
564+
ModbusElement[] elements = {
565565
m(this.createChannelId(r, RackChannel.LEVEL2_CELL_OVER_VOLTAGE_PROTECTION),
566566
new UnsignedWordElement(r.offset + 0x400)), //
567567
m(this.createChannelId(r, RackChannel.LEVEL2_CELL_OVER_VOLTAGE_RECOVER),

io.openems.edge.battery.soltaro/src/io/openems/edge/battery/soltaro/single/versionb/BatterySoltaroSingleRackVersionBImpl.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -966,8 +966,8 @@ private void calculateCapacity(Integer numberOfModules) {
966966
private void createDynamicChannels(int numberOfModules) {
967967
try {
968968
for (var i = 0; i < numberOfModules; i++) {
969-
var ameVolt = new ModbusElement<?>[SENSORS_PER_MODULE];
970-
var ameTemp = new ModbusElement<?>[SENSORS_PER_MODULE];
969+
var ameVolt = new ModbusElement[SENSORS_PER_MODULE];
970+
var ameTemp = new ModbusElement[SENSORS_PER_MODULE];
971971
for (var j = 0; j < SENSORS_PER_MODULE; j++) {
972972
var sensor = i * SENSORS_PER_MODULE + j;
973973
{

io.openems.edge.battery.soltaro/src/io/openems/edge/battery/soltaro/single/versionc/BatterySoltaroSingleRackVersionCImpl.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException {
492492
.bit(12, BatterySoltaroSingleRackVersionC.ChannelId.SLAVE_BMS_INIT)//
493493
))); //
494494
{
495-
ModbusElement<?>[] elements = {
495+
ModbusElement[] elements = {
496496
m(BatterySoltaroSingleRackVersionC.ChannelId.PRE_ALARM_CELL_OVER_VOLTAGE_ALARM,
497497
new UnsignedWordElement(0x2080)), //
498498
m(BatterySoltaroSingleRackVersionC.ChannelId.PRE_ALARM_CELL_OVER_VOLTAGE_RECOVER,
@@ -565,7 +565,7 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException {
565565

566566
// WARN_LEVEL1 (Level1 warning registers RW)
567567
{
568-
ModbusElement<?>[] elements = {
568+
ModbusElement[] elements = {
569569
m(BatterySoltaroSingleRackVersionC.ChannelId.LEVEL1_CELL_OVER_VOLTAGE_PROTECTION,
570570
new UnsignedWordElement(0x2040)), //
571571
m(BatterySoltaroSingleRackVersionC.ChannelId.LEVEL1_CELL_OVER_VOLTAGE_RECOVER,
@@ -638,7 +638,7 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException {
638638

639639
// WARN_LEVEL2 (Level2 Protection registers RW)
640640
{
641-
ModbusElement<?>[] elements = {
641+
ModbusElement[] elements = {
642642
m(BatterySoltaroSingleRackVersionC.ChannelId.LEVEL2_CELL_OVER_VOLTAGE_PROTECTION,
643643
new UnsignedWordElement(0x2400)), //
644644
m(BatterySoltaroSingleRackVersionC.ChannelId.LEVEL2_CELL_OVER_VOLTAGE_RECOVER,
@@ -725,7 +725,7 @@ void createCellVoltageAndTemperatureChannels(int numberOfModules) {
725725
*/
726726
Consumer<CellChannelFactory.Type> addCellChannels = type -> {
727727
for (var i = 0; i < numberOfModules; i++) {
728-
var elements = new ModbusElement<?>[type.getSensorsPerModule()];
728+
var elements = new ModbusElement[type.getSensorsPerModule()];
729729
for (var j = 0; j < type.getSensorsPerModule(); j++) {
730730
var sensorIndex = i * type.getSensorsPerModule() + j;
731731
var channelId = CellChannelFactory.create(type, sensorIndex);

io.openems.edge.bridge.modbus/src/io/openems/edge/bridge/modbus/api/AbstractOpenemsModbusComponent.java

+30-29
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import java.util.HashMap;
66
import java.util.Map;
7-
import java.util.Optional;
87
import java.util.concurrent.atomic.AtomicReference;
98
import java.util.function.Function;
109

@@ -17,7 +16,8 @@
1716
import io.openems.common.types.OpenemsType;
1817
import io.openems.edge.bridge.modbus.api.element.AbstractModbusElement;
1918
import io.openems.edge.bridge.modbus.api.element.BitsWordElement;
20-
import io.openems.edge.bridge.modbus.api.element.ModbusCoilElement;
19+
import io.openems.edge.bridge.modbus.api.element.CoilElement;
20+
import io.openems.edge.bridge.modbus.api.element.ModbusElement;
2121
import io.openems.edge.bridge.modbus.api.element.ModbusRegisterElement;
2222
import io.openems.edge.bridge.modbus.api.task.ReadTask;
2323
import io.openems.edge.bridge.modbus.api.task.WriteTask;
@@ -260,7 +260,7 @@ public void retryModbusCommunication() {
260260
* Maps an Element to one or more ModbusChannels using converters, that convert
261261
* the value forward and backwards.
262262
*/
263-
public class ChannelMapper<ELEMENT extends AbstractModbusElement<?, ?>> {
263+
public class ChannelMapper<ELEMENT extends ModbusElement> {
264264

265265
private final ELEMENT element;
266266
private final Map<Channel<?>, ElementToChannelConverter> channelMaps = new HashMap<>();
@@ -278,7 +278,7 @@ public ChannelMapper(ELEMENT element) {
278278
*/
279279
public ChannelMapper<ELEMENT> m(io.openems.edge.common.channel.ChannelId channelId,
280280
ElementToChannelConverter converter) {
281-
return this.m(channelId, converter, new ChannelMetaInfo(this.element.getStartAddress()));
281+
return this.m(channelId, converter, new ChannelMetaInfo(this.element.startAddress));
282282
}
283283

284284
/**
@@ -324,7 +324,8 @@ public ELEMENT build() {
324324
/*
325325
* Forward Element Read-Value to Channel
326326
*/
327-
this.element.onUpdateCallback(value -> { //
327+
// This is guaranteed to work because of sealed abstract classes
328+
((AbstractModbusElement<?, ?, ?>) this.element).onUpdateCallback(value -> { //
328329
/*
329330
* Applies the updated value on every Channel in ChannelMaps using the given
330331
* Converter. If the converter returns an Optional.empty, the value is ignored.
@@ -349,13 +350,13 @@ public ELEMENT build() {
349350
// dynamically get the Converter; this allows the converter to be changed
350351
var converter = this.channelMaps.get(channel);
351352
var convertedValue = converter.channelToElement(value);
352-
if (this.element instanceof ModbusRegisterElement<?> registerElement) {
353+
if (this.element instanceof ModbusRegisterElement<?, ?> registerElement) {
353354
try {
354-
registerElement.setNextWriteValue(Optional.ofNullable(convertedValue));
355-
} catch (OpenemsException | IllegalArgumentException e) {
355+
registerElement.setNextWriteValueFromObject(convertedValue);
356+
} catch (IllegalArgumentException e) {
356357
AbstractOpenemsModbusComponent.this.logWarn(AbstractOpenemsModbusComponent.this.log,
357358
"Unable to write to ModbusRegisterElement. " //
358-
+ "Address [" + this.element.getStartAddress() + "] " //
359+
+ "Address [" + this.element.startAddress + "] " //
359360
+ "Channel [" + channel.address() + "]. " //
360361
+ "Exception [" + e.getClass().getSimpleName() + "] " //
361362
+ ": " + e.getMessage());
@@ -364,19 +365,20 @@ public ELEMENT build() {
364365
e.printStackTrace();
365366
}
366367
}
367-
} else if (this.element instanceof ModbusCoilElement coilElement) {
368+
369+
} else if (this.element instanceof CoilElement coilElement) {
368370
try {
369-
coilElement.setNextWriteValue(
370-
Optional.ofNullable(TypeUtils.getAsType(OpenemsType.BOOLEAN, convertedValue)));
371-
} catch (OpenemsException e) {
371+
coilElement.setNextWriteValue(TypeUtils.getAsType(OpenemsType.BOOLEAN, convertedValue));
372+
} catch (IllegalArgumentException e) {
372373
AbstractOpenemsModbusComponent.this.logWarn(AbstractOpenemsModbusComponent.this.log,
373374
"Unable to write to ModbusCoilElement " //
374-
+ "[" + this.element.getStartAddress() + "]: " + e.getMessage());
375+
+ "[" + this.element.startAddress + "]: " + e.getMessage());
375376
}
377+
376378
} else {
377379
AbstractOpenemsModbusComponent.this.logWarn(AbstractOpenemsModbusComponent.this.log,
378380
"Unable to write to Element " //
379-
+ "[" + this.element.getStartAddress() + "]: it is not a ModbusElement");
381+
+ "[" + this.element.startAddress + "]: it is not a ModbusElement");
380382
}
381383
});
382384
}
@@ -390,11 +392,11 @@ public ELEMENT build() {
390392
* Creates a ChannelMapper that can be used with builder pattern inside the
391393
* protocol definition.
392394
*
393-
* @param <T> the type of the {@link AbstractModbusElement}d
395+
* @param <T> the type of the {@link ModbusElement}
394396
* @param element the ModbusElement
395397
* @return a {@link ChannelMapper}
396398
*/
397-
protected final <T extends AbstractModbusElement<?, ?>> ChannelMapper<T> m(T element) {
399+
protected final <T extends ModbusElement> ChannelMapper<T> m(T element) {
398400
return new ChannelMapper<>(element);
399401
}
400402

@@ -411,43 +413,42 @@ protected final BitsWordElement m(BitsWordElement bitsWordElement) {
411413
/**
412414
* Maps the given element 1-to-1 to the Channel identified by channelId.
413415
*
414-
* @param <T> the type of the {@link AbstractModbusElement}d
416+
* @param <T> the type of the {@link ModbusElement}
415417
* @param channelId the Channel-ID
416418
* @param element the ModbusElement
417419
* @return the element parameter
418420
*/
419-
protected final <T extends AbstractModbusElement<?, ?>> T m(io.openems.edge.common.channel.ChannelId channelId,
420-
T element) {
421+
protected final <T extends ModbusElement> T m(io.openems.edge.common.channel.ChannelId channelId, T element) {
421422
return this.m(channelId, element, DIRECT_1_TO_1);
422423
}
423424

424425
/**
425426
* Maps the given element 1-to-1 to the Channel identified by channelId.
426427
*
427-
* @param <T> the type of the {@link AbstractModbusElement}d
428+
* @param <T> the type of the {@link ModbusElement}
428429
* @param channelId the Channel-ID
429430
* @param element the ModbusElement
430431
* @param channelMetaInfo an object that holds meta information about the
431432
* Channel
432433
* @return the element parameter
433434
*/
434-
protected final <T extends AbstractModbusElement<?, ?>> T m(io.openems.edge.common.channel.ChannelId channelId,
435-
T element, ChannelMetaInfo channelMetaInfo) {
435+
protected final <T extends ModbusElement> T m(io.openems.edge.common.channel.ChannelId channelId, T element,
436+
ChannelMetaInfo channelMetaInfo) {
436437
return this.m(channelId, element, DIRECT_1_TO_1, channelMetaInfo);
437438
}
438439

439440
/**
440441
* Maps the given element to the Channel identified by channelId, applying the
441442
* given @link{ElementToChannelConverter}.
442443
*
443-
* @param <T> the type of the {@link AbstractModbusElement}d
444+
* @param <T> the type of the {@link ModbusElement}
444445
* @param channelId the Channel-ID
445446
* @param element the ModbusElement
446447
* @param converter the ElementToChannelConverter
447448
* @return the element parameter
448449
*/
449-
protected final <T extends AbstractModbusElement<?, ?>> T m(io.openems.edge.common.channel.ChannelId channelId,
450-
T element, ElementToChannelConverter converter) {
450+
protected final <T extends ModbusElement> T m(io.openems.edge.common.channel.ChannelId channelId, T element,
451+
ElementToChannelConverter converter) {
451452
return new ChannelMapper<>(element) //
452453
.m(channelId, converter) //
453454
.build();
@@ -457,16 +458,16 @@ protected final BitsWordElement m(BitsWordElement bitsWordElement) {
457458
* Maps the given element to the Channel identified by channelId, applying the
458459
* given @link{ElementToChannelConverter}.
459460
*
460-
* @param <T> the type of the {@link AbstractModbusElement}d
461+
* @param <T> the type of the {@link ModbusElement}
461462
* @param channelId the Channel-ID
462463
* @param element the ModbusElement
463464
* @param converter the ElementToChannelConverter
464465
* @param channelMetaInfo an object that holds meta information about the
465466
* Channel
466467
* @return the element parameter
467468
*/
468-
protected final <T extends AbstractModbusElement<?, ?>> T m(io.openems.edge.common.channel.ChannelId channelId,
469-
T element, ElementToChannelConverter converter, ChannelMetaInfo channelMetaInfo) {
469+
protected final <T extends ModbusElement> T m(io.openems.edge.common.channel.ChannelId channelId, T element,
470+
ElementToChannelConverter converter, ChannelMetaInfo channelMetaInfo) {
470471
return new ChannelMapper<>(element) //
471472
.m(channelId, converter, channelMetaInfo) //
472473
.build();

io.openems.edge.bridge.modbus/src/io/openems/edge/bridge/modbus/api/ModbusUtils.java

+7-8
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@
1515
import com.ghgande.j2mod.modbus.procimg.Register;
1616

1717
import io.openems.common.exceptions.OpenemsException;
18-
import io.openems.edge.bridge.modbus.api.element.AbstractModbusElement;
19-
import io.openems.edge.bridge.modbus.api.element.AbstractModbusRegisterElement;
18+
import io.openems.edge.bridge.modbus.api.element.ModbusRegisterElement;
2019
import io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask;
2120
import io.openems.edge.bridge.modbus.api.task.Task;
2221
import io.openems.edge.common.taskmanager.Priority;
@@ -29,19 +28,19 @@ public class ModbusUtils {
2928
* @param <T> the Type of the element
3029
* @param modbusProtocol the {@link ModbusProtocol}, that is linked with a
3130
* {@link BridgeModbus}
32-
* @param element the {@link AbstractModbusElement}
31+
* @param element the {@link ModbusRegisterElement}
3332
* @param tryAgainOnError if true, tries to read till it receives a value; if
3433
* false, stops after first try and possibly return null
3534
* @return a future value, e.g. a Integer or null (if tryAgainOnError is false)
3635
* @throws OpenemsException on error with the {@link ModbusProtocol} object
3736
*/
3837
public static <T> CompletableFuture<T> readELementOnce(ModbusProtocol modbusProtocol,
39-
AbstractModbusRegisterElement<?, T> element, boolean tryAgainOnError) throws OpenemsException {
38+
ModbusRegisterElement<?, T> element, boolean tryAgainOnError) throws OpenemsException {
4039
// Prepare result
4140
final var result = new CompletableFuture<T>();
4241

4342
// Activate task
44-
final Task task = new FC3ReadRegistersTask(element.getStartAddress(), Priority.HIGH, element);
43+
final Task task = new FC3ReadRegistersTask(element.startAddress, Priority.HIGH, element);
4544
modbusProtocol.addTask(task);
4645

4746
// Register listener for element
@@ -66,7 +65,7 @@ public static <T> CompletableFuture<T> readELementOnce(ModbusProtocol modbusProt
6665
* @param <T> the Type of the elements
6766
* @param modbusProtocol the {@link ModbusProtocol}, that is linked with a
6867
* {@link BridgeModbus}
69-
* @param elements the {@link AbstractModbusElement}s
68+
* @param elements the {@link ModbusRegisterElement}s
7069
* @param tryAgainOnError if true, tries to read till it receives a value on
7170
* first register; if false, stops after first try and
7271
* possibly return null
@@ -76,7 +75,7 @@ public static <T> CompletableFuture<T> readELementOnce(ModbusProtocol modbusProt
7675
* @throws OpenemsException on error with the {@link ModbusProtocol} object
7776
*/
7877
public static <T> CompletableFuture<List<T>> readELementsOnce(ModbusProtocol modbusProtocol,
79-
AbstractModbusRegisterElement<?, T>[] elements, boolean tryAgainOnError) throws OpenemsException {
78+
ModbusRegisterElement<?, T>[] elements, boolean tryAgainOnError) throws OpenemsException {
8079
if (elements.length == 0) {
8180
return CompletableFuture.completedFuture(Collections.emptyList());
8281
}
@@ -85,7 +84,7 @@ public static <T> CompletableFuture<List<T>> readELementsOnce(ModbusProtocol mod
8584
final var result = new CompletableFuture<List<T>>();
8685

8786
// Activate task
88-
final Task task = new FC3ReadRegistersTask(elements[0].getStartAddress(), Priority.HIGH, elements);
87+
final Task task = new FC3ReadRegistersTask(elements[0].startAddress, Priority.HIGH, elements);
8988
modbusProtocol.addTask(task);
9089

9190
// Register listener for each element

0 commit comments

Comments
 (0)