Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class OpenemsConstants {
/**
* The additional version string.
*/
public static final String VERSION_STRING = "SNAPSHOT";
public static final String VERSION_STRING = "";

/**
* The complete version as a SemanticVersion.
Expand Down
27 changes: 24 additions & 3 deletions io.openems.common/src/io/openems/common/worker/AbstractWorker.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,17 @@ public void deactivate() {
*/
protected abstract int getCycleTime();

/**
* Returns the minimum sleep time between two cycles. This avoids tasks
* to run immediately after each other, eg. forces a break between two
* modbus reads.
*
* @return sleep time in ms
*/
protected int getMinSleepTime() {
return 0;
}

/**
* Allows the next execution of the forever() method.
*/
Expand All @@ -133,15 +144,25 @@ public void run() {
* Wait for next cycle
*/
var cycleTime = AbstractWorker.this.getCycleTime();
var minSleepTime = AbstractWorker.this.getMinSleepTime();

if (cycleTime == AbstractWorker.DO_NOT_WAIT) {
// no wait

// no wait, only minSleepTime
if (minSleepTime > 0) {
AbstractWorker.this.cycleMutex.awaitOrTimeout(minSleepTime, TimeUnit.MILLISECONDS);
}

} else if (cycleTime > 0) {
// wait remaining cycleTime
var sleep = cycleTime - (System.currentTimeMillis() - cycleStart);

// wait remaining cycleTime, at least minSleepTime
var sleep = Math.max(minSleepTime, cycleTime - (System.currentTimeMillis() - cycleStart));

if (sleep > 0) {
AbstractWorker.this.cycleMutex.awaitOrTimeout(sleep, TimeUnit.MILLISECONDS);
}
} else { // < 0 (ALWAYS_WAIT_FOR_TRIGGER_NEXT_RUN)

// wait till next run is triggered
AbstractWorker.this.cycleMutex.await();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ public BridgeModbusTcpImpl() {
@Activate
private void activate(ComponentContext context, ConfigTcp config) throws UnknownHostException {
super.activate(context, new Config(config.id(), config.alias(), config.enabled(), config.logVerbosity(),
config.invalidateElementsAfterReadErrors()));
config.invalidateElementsAfterReadErrors(), config.cycleTime(), config.minSleepTime()));
this.applyConfig(config);
}

@Modified
private void modified(ComponentContext context, ConfigTcp config) throws UnknownHostException {
super.modified(context, new Config(config.id(), config.alias(), config.enabled(), config.logVerbosity(),
config.invalidateElementsAfterReadErrors()));
config.invalidateElementsAfterReadErrors(), config.cycleTime(), config.minSleepTime()));
this.applyConfig(config);
this.closeModbusConnection();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,11 @@
@AttributeDefinition(name = "Invalidate elements after how many read Errors?", description = "Increase this value if modbus read errors happen frequently.")
int invalidateElementsAfterReadErrors() default 1;

@AttributeDefinition(name = "Duration of a cycle on the modbus", description = "Defines how long a cylce on the modbus thread should take in ms. 0 means next task executes immediately. A value below 0 requires external triggering to run the next task.")
int cycleTime() default 0;

@AttributeDefinition(name = "Minimum wait time between modbus actions.", description = "Throttles modbus read- and writes in ms.")
int minSleepTime() default 0;

String webconsole_configurationFactory_nameHint() default "Bridge Modbus/TCP [{id}]";
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ protected void modified(ComponentContext context, Config config) {
}

private void applyConfig(Config config) {
this.worker.setCycleTime(config.cycleTime);
this.worker.setMinSleepTime(config.minSleepTime);
this.config = config;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,22 @@ public class Config {
public final String alias;
public final boolean enabled;
public final int invalidateElementsAfterReadErrors;
public final int cycleTime;
public final int minSleepTime;
public final LogHandler log;

public Config(String id, String alias, boolean enabled, LogVerbosity logVerbosity, int invalidateElementsAfterReadErrors) {
this(id, alias, enabled, logVerbosity, invalidateElementsAfterReadErrors, 0, 0);
}

public Config(String id, String alias, boolean enabled, LogVerbosity logVerbosity,
int invalidateElementsAfterReadErrors) {
int invalidateElementsAfterReadErrors, int cycleTime, int minSleepTime) {
this.id = id;
this.alias = alias;
this.enabled = enabled;
this.invalidateElementsAfterReadErrors = invalidateElementsAfterReadErrors;
this.cycleTime = cycleTime;
this.minSleepTime = minSleepTime;
this.log = new LogHandler(this, logVerbosity);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public FC2ReadInputsTask(int startAddress, Priority priority, CoilElement... ele

public FC2ReadInputsTask(Consumer<ExecuteState> onExecute, int startAddress, Priority priority,
CoilElement... elements) {
super("FC2ReadCoils", onExecute, ReadInputDiscretesResponse.class, startAddress, priority, elements);
super("FC2ReadInputsTask", onExecute, ReadInputDiscretesResponse.class, startAddress, priority, elements);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import java.util.function.Function;
import java.util.function.Supplier;

import io.openems.common.worker.AbstractImmediateWorker;
import io.openems.common.worker.AbstractWorker;
import io.openems.edge.bridge.modbus.api.BridgeModbus;
import io.openems.edge.bridge.modbus.api.Config.LogHandler;
import io.openems.edge.bridge.modbus.api.ModbusComponent;
Expand All @@ -31,7 +31,7 @@
* {@link CycleTasksManager} that internally uses a {@link TasksSupplierImpl}
* that supplies the tasks for one Cycle ({@link CycleTasks}).
*/
public class ModbusWorker extends AbstractImmediateWorker {
public class ModbusWorker extends AbstractWorker {

// Callbacks
private final Function<Task, ExecuteState> execute;
Expand All @@ -41,6 +41,9 @@ public class ModbusWorker extends AbstractImmediateWorker {
private final TasksSupplierImpl tasksSupplier;
private final CycleTasksManager cycleTasksManager;

private int cycleTime = 0;
private int minSleepTime = 0;

/**
* Constructor for {@link ModbusWorker}.
*
Expand Down Expand Up @@ -163,4 +166,23 @@ public void onExecuteWrite() {
public void onBeforeProcessImage() {
this.cycleTasksManager.onBeforeProcessImage();
}

@Override
protected final int getCycleTime() {
return this.cycleTime;
}

public void setCycleTime(int cycleTime) {
this.cycleTime = cycleTime;
}

@Override
protected final int getMinSleepTime() {
return this.minSleepTime;
}

public void setMinSleepTime(int minSleepTime) {
this.minSleepTime = minSleepTime;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public static class Builder {
private int port;
private LogVerbosity logVerbosity;
private int invalidateElementsAfterReadErrors;
private int cycleTime = 0;
private int minSleepTime = 0;

private Builder() {
}
Expand Down Expand Up @@ -41,6 +43,16 @@ public Builder setInvalidateElementsAfterReadErrors(int invalidateElementsAfterR
return this;
}

public Builder setCycleTime(int cycleTime) {
this.cycleTime = cycleTime;
return this;
}

public Builder setMinSleepTime(int minSleepTime) {
this.minSleepTime = minSleepTime;
return this;
}

public MyConfigTcp build() {
return new MyConfigTcp(this);
}
Expand Down Expand Up @@ -82,4 +94,14 @@ public int invalidateElementsAfterReadErrors() {
return this.builder.invalidateElementsAfterReadErrors;
}

@Override
public int cycleTime() {
return this.builder.cycleTime;
}

@Override
public int minSleepTime() {
return this.builder.minSleepTime;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public void test() throws OpenemsException {
response.setDiscreteStatus(0, true);
response.setDiscreteStatus(1, false);

assertEquals("FC2ReadCoils [device0;unitid=1;priority=HIGH;ref=10/0xa;length=2;response=10]",
assertEquals("FC2ReadInputsTask [device0;unitid=1;priority=HIGH;ref=10/0xa;length=2;response=10]",
task.toLogMessage(LogVerbosity.READS_AND_WRITES_VERBOSE, request, response));

var discretes = response.getDiscretes();
Expand Down
74 changes: 52 additions & 22 deletions ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "openems-ui",
"version": "2025.9.0-SNAPSHOT",
"version": "2025.9.0",
"license": "AGPL-3.0",
"private": true,
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/changelog/view/component/changelog.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Role } from "src/app/shared/type/role";

export class Changelog {

public static readonly UI_VERSION = "2025.9.0-SNAPSHOT";
public static readonly UI_VERSION = "2025.9.0";

public static product(...products: Product[]) {
return products.map(product => Changelog.link(product.name, product.url)).join(", ") + ". ";
Expand Down
Loading