Dimmer stepping issue

Hello,
I’m trying to control a water boiler electrical heating from OpenHAB (3.4.2 openhabian) according to my actual photovoltaic output.
Since I did not find a smart power dimmer, I use a Sonoff D1 (equipped with a more powerful triac) running Tasmota. The controlling uses a mosquitto broker on my raspi.
Probably, my problem is not in the Tasmota device but within OpenHAB, because it also happens, when the thing is offline.
When I step the dimmer up, everything works fine, as long as I don’t reach values with a 5 as last digit. Then the actor suddenly jumps up to the next decade.
So I start with 1,2,3,4 and the dimmer steps up normally. Entering the “5” causes him to jump immediately to 10. In the Tasmota console, I see the 5, immediately followed by the 10. At 15, the jump goes to 20. The similar problem happens at 25, 35, 45 etc.
Stepping down, the jumping occurs at 4 as last digit (from 25 to 20 instead of 24).
Resending the desired value (with delay) helps to overcome the problem, but I believe that a good bugfix is the better solution.
Here is the Dimmer channel code:
UID: mqtt:topic:mosquitto_on_pi:Dimmer1
label: Dimmer1
thingTypeUID: mqtt:topic
configuration: {}
bridgeUID: mqtt:broker:mosquitto_on_pi
channels:

  • id: Dimmer1
    channelTypeUID: mqtt:dimmer
    label: Dimmer1
    description: “”
    configuration:
    commandTopic: cmnd/D1/DIMMER
    min: 0
    stateTopic: stat/D1/RESULT
    transformationPattern: JSONPATH:$.Dimmer
    max: 100
  • id: DimmerSw1
    channelTypeUID: mqtt:switch
    label: DimmerSw1
    description: “”
    configuration:
    commandTopic: cmnd/D1/POWER
    stateTopic: stat/D1/RESULT
    transformationPattern: JSONPATH:$.POWER

What’s the rule to step up and down? Better don’t use UP and DOWN commands, but send the correct level. So, instead of something like this:

rule "power heating rod"
when
    Item PowerFeed changed or
    Item PowerConsume changed
then
    val nPowerFeed    = (PowerFeed.state as Number).intValue    // get feed from Item (in W)
    val nPowerConsume = (PowerConsume.state as Number).intValue // get consume from Item (in W)
    val nHeat         = heatingRod.state as Number              // get current state
    if(((nPowerFeed > 0 && nHeat < 100)                         // more power than consumed
        heatingRod.sendCommand(UP)
    else if((nPowerConsume > 0 && val nHeat > 0)                // less power than consumed
        heatingRod.sendCommand(DOWN)
end

better like that:

rule "power heating rod"
when
    Item PowerFeed changed or
    Item PowerConsume changed
then
    val iRodMax = 2000                                            // max power consumption of heating rod; Integer
    val iPowerFeed    = (PowerFeed.state as Number).intValue      // get feed from Item (in W)
    val iPowerConsume = (PowerConsume.state as Number).intValue   // get consume from Item (in W)
    val iHeat         = heatingRod.state as Number                // get current state; Integer
    var iPowAvail = 0
    if(iPowerConsume == 0 && iPowerFeed > 0)                      // more power than consumed
        iPowAvail = (iPowerFeed + iHeat / 100 * iRodMax).intValue 
    if(iPowAvail > iRodMax) iPowAvail = iRodMax
    val iSetHeat = (iPowAvail / iRodMax * 100).intValue           // calculate correct level
    heatingRod.sendCommand(iSetHeat)
end

It’s very likely that dimmer percentage to power consumption is not linear, so this should be taken in account.
My point is, better to calculate the absolute dim level rather than swerve towards the correct level.

Please be aware that the code above is not tested at all :wink:

Hello Udo,

TNX for Your reply.
W/O success, I tried to send Up and down commands. Perhaps, my syntax was buggy. I think, that there is a lack of documentation from Openhab and also from Tasmota. In the next days, I will play again.
At this moment, I send the absolute value twice with a small delay. This helps to overcome the gap.
But it would be better to find the real cause.
In the Tasmota log, I see the value of 54 when dimming from 55 to 54 for a short while, but at once it is overwritten by a command to set the value to 50. Now, the resending of 54 works and the dimmer remains at 54%.

I saw the non-linearity of the Dimmer. In my case, it swings between 4 and 35W/% with a nominal boiler power of 1850W. But using a correction table is far away from my programming possibilities and I don’t think, that it is essential for my applcation. So I step up, when the smartmeter gives me more than 35W deliverage and step down on consumption.

Here is my actual script:
var unteregrenze = -36;
var oberegrenze = 6;

console.info(“DEBUG: Test output”);
var curvaldim = items.getItem(‘Dimmer1_Dimmer1’).state;
console.info("DEBUG:Dimmer: " + curvaldim);

var curvalstrom = items.getItem(‘StromZaehler_AktuellerVerbrauch’).state;
// Einheit “W” abtrennen
curvalstrom = curvalstrom.split(" ")[0];
console.info("DEBUG:Stromzähler: " + curvalstrom);

// Speisen mehr als Untergrenze ein, dann Hochregeln
while (curvalstrom < unteregrenze) {

if (curvaldim > 99) {
break;
}
console.info("DEBUG:Dimmer: " + curvaldim);
console.info("DEBUG:Stromzähler: " + curvalstrom);
var nextval = parseInt(curvaldim) + 1;
console.info("DEBUG:Dimmer next: " + nextval.toString());
items.getItem(‘Dimmer1_Dimmer1’).sendCommand(nextval.toString());
java.lang.Thread.sleep(50);
items.getItem(‘Dimmer1_Dimmer1’).sendCommand(nextval.toString());

java.lang.Thread.sleep(300);
curvaldim = items.getItem(‘Dimmer1_Dimmer1’).state;
curvalstrom = items.getItem(‘StromZaehler_AktuellerVerbrauch’).state;
curvalstrom = curvalstrom.split(" ")[0];
}

// Speisen weniger als Obergrenze ein, dann Runterregeln
while (curvalstrom > oberegrenze) {

if (curvaldim < 1) {
break;
}
console.info("DEBUG:Dimmer: " + curvaldim);
console.info("DEBUG:Stromzähler: " + curvalstrom);
var nextval = parseInt(curvaldim) - 1;
console.info("DEBUG:Dimmer next: " + nextval.toString());
items.getItem(‘Dimmer1_Dimmer1’).sendCommand(nextval.toString());
java.lang.Thread.sleep(50);
items.getItem(‘Dimmer1_Dimmer1’).sendCommand(nextval.toString());

java.lang.Thread.sleep(300);
curvaldim = items.getItem(‘Dimmer1_Dimmer1’).state;
curvalstrom = items.getItem(‘StromZaehler_AktuellerVerbrauch’).state;
curvalstrom = curvalstrom.split(" ")[0];
}

If sending UP or DOWN to a Dimmer Item, the command is passed directly to the linked Channel, so it’s up to the Dimmer itself to react to the command. For a default Tasmota Dimmer, the correct commands would be + instead of UP and - instead of DOWN, but the mqtt Binding doesn’t send any UP/DOWN commands to a dimmer channel. Instead, it will set the absolute level by itself.

Please check correct configuration in the dimmer channel (i.e. set step to 1, min to 0 and max to 100, then an UP command should result in an instant current_level + 1 command and a DOWN command should result in an instant current_level - 1 command in range from 0 to 100.

So the rule could be much simpler (even simpler as my own…).

Another option would be to send + or - through another channel type (string) (but to the dimmer command topic). You’ll have to set the step in Tasmota to 1 then:

DimmerRange 0,255
DimmerStep 1

Please be aware that DimmerRange is the internal Range, which does not change the external Dimmer Range (0 - 100). DimmerStep is the Step for external Range, so 1 % for each + or - command.