We would like to switch a consumer on/off depending on the electricity cost. We are using a Shelly Pro 3 as contractor for the three phases, the ctrlIoChannelSingleThreshold as controller and the timeOfUseTariff component for the price.
The controller is configured as depicted in the screenshot:
But the controller seems not to work, the debug log shows:
8.1.2026, 18:34:55
WARN
io.openems.edge.core.cycle.CycleWorker
[_cycle] Error in Controller [ctrlIoChannelSingleThreshold0]. ClassCastException: class io.openems.edge.common.channel.DoubleReadChannel cannot be cast to class io.openems.edge.common.channel.IntegerReadChannel (io.openems.edge.common.channel.DoubleReadChannel and io.openems.edge.common.channel.IntegerReadChannel are in unnamed module of loader org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @3316dc5f)
We also tried to specify the Threshold as 300 instead of 300.0, leading to the same result.
We additionally noted, that the channel _sum/GridBuyPrice uses ā¬/MWh and the log uses ā¬/kWh ā we assumed, that the channel value is more relevant, thus using the threshold value of 300 (as ā¬/MWh).
Can someone please give a hint whatās going wrong? Thx for any help!
Simon
PS: The meaning of the Mode (default: automatic) within the controller isnāt clear to us. Can someone explain it to us?
Maybe the variable inputChannel should be changed to DoubleReadChannel and there should be a handler that determines the input channel type and converts the value to Double.
public void run() throws OpenemsNamedException {
var outputChannels = this.getOutputChannels();
switch (this.config.mode()) {
case ON:
this.setOutputs(outputChannels, true);
break;
case OFF:
this.setOutputs(outputChannels, false);
break;
case AUTOMATIC:
this.automaticMode(outputChannels);
break;
}
}
This was the piece of information I was missing.
What would be the use case to specify something different than automatic during setting up the component? There I did find the drop-down (without any further documentation) and was a little confused.
The comparison already included the (int) Math.round(inputValueOpt.getAsDouble()), in my understanding already accepting a Double and intentionally casting it to an int. Thus I thought it would be fine to keep it. Do you believe it would be better to not round() the value and compare as Double? Iām not understanding the domain/business logic enough to make an informed decision, thus needing some feedback. Iām happy to alter my PR.
In my eyes comparing Doubles as Ints doesnāt make sense, even if the loss of precision seems not much. If someone wants a very precise threshold, the system should not tell him āof course you can enter this value, but unfortunately the comparison doesnāt consider it completelyā.
If comparing power, energy or prices it may be neglect-able, but maybe there are some other cases where this would be an unwanted limitation.
The component seems originally to be built for power, so there should be done more to adapt it to any unit, at least in the front end, where āWā seems to be hard coded at some places.
Oh no, this was a misunderstanding. Iāve made these changes in my local version, just to see if the compiler has any complaints. There is no pull request ore something else.