Unknown variable or command ‘-’ In Rule

Hi,
i have a problem with a rule that worked few days back but now does not trigger and throws the " [Unknown variable or command ‘-’ In Rule]" error.

I found this similar case, but to me its different as its not an object before the “minus”.

Furthermore, i did not change anything, except that i did an update. but only a minor move forward from openHAB 4.2.0.M2 to M3. So not sure if there has been such change, dont think so…

I don’t see the problem, its in line 9 /char 33. Any idea what i should do to make it work again. Thanks! Norbert

rule "EV goes PV Excess Charging"
when
    Item miFro_ACpower received update
then

    miFro_AvgPower.postUpdate(miFro_ACpower.averageSince(now.minusMinutes(2)))

    if ((GoEChargerExcess_1P.state == ON) && (GoEChargerExcess_3P.state == OFF) && (GoEChargerForceState.state == 2)) {
        var AvailChargePower = (miFro_ACpower.averageSince(now.minusMinutes(2)) - 400)
        var maxAmp1Phases = AvailChargePower / 230
        var actMaxChargCurrent = (GoEChargerMaxCurrent.state as Number).intValue

        if (maxAmp1Phases > 16.0) {
            maxAmp1Phases = 16.0
        }

        if ((maxAmp1Phases.intValue < 6) && (GoEChargerKeepGo.state == ON)) { maxAmp1Phases = 6 }

        if (maxAmp1Phases.intValue >= 6 ) {
            if (GoEChargerPhases.state != 1) {
                GoEChargerPhases.sendCommand(1)
            }

            if (actMaxChargCurrent != maxAmp1Phases.intValue) {
                GoEChargerMaxCurrent.sendCommand(maxAmp1Phases.intValue)
                logInfo("GoECharger", "miFro Power avg(2min): " + AvailChargePower.intValue + " W")
                logInfo("GoECharger", "Set charging limit 1 Phase: " + maxAmp1Phases.intValue + " A")
            }
        } else {
                 GoEChargerForceState.sendCommand(1)
                 GoEChargerExcess_1P.sendCommand(OFF)
                 logInfo("GoECharger", "Switch charging off...")
                 val actions = getActions("pushover", "pushover:pushover-account:account")
                 actions.sendMessage("miFro.avg: " + (miFro_AvgPower.state as DecimalType).intValue + "W", "GoECharger | 1~ charger OFF")
            }
        }

The differences between milestone releases can be huge. Don’t discount the possibility there is a breaking change or a bug.

And in fact one of the big changes between 4.2 M2 and 4.2 M3 is an almost complete overhaul of the persistence actions. They now return the units and there are some additional changes in what they return. Read the release notes closely as well as the discussion threads for the relevant PRs.

@rlkoshak thanks for the hint. i was not expecting milestone releases to be that much changing. but it makes sense as my rule worked before.
I found the page describing what you were marking out.

I’m pretty sure it has to do with this line, especially the averageSince.
will ask in that threat.

var AvailChargePower = (miFro_ACpower.averageSince(now.minusMinutes(2)) - 400)

If miFro_ACpower is a dimensioned item with a unit, the averageSince will return a QuantityType. You have two options:

  • Convert it to a known unit (if necessary), then convert it to fload or double, then subtract with 400, or
  • Subtract it with new QuantityType("400 W") or whatever the unit is supposed to be. Just be aware that the result will also be in QuantityType, and you probably are expecting it as a plain Number. To do the subtraction do this:
    var AvailChargePower = 
    (miFro_ACpower.averageSince(now.minusMinutes(2)) as QuantityType).subtract(400 | W)
    

FYI, in JRuby scripting, that would look like this:

avail_charge_power = miFro_ACpower.average_since(2.minutes.ago) - 400 | "W"

Generally things are much simpler, easier and shorter to read / write in jruby compared to any other scripting language.

@jimtng Thanks a lot for the examples and explainations!

First, is this already to be read in the documentations?

I’m little confused as I undeerstand that the problem is an item with the unit W and a number without any unit to be subtracted. However my AC_power items are all without units. Have a look. i would expect a unitless item to be able to be subtracted from a unitless value of 400. but i guess i’m wrong, otherwise it would work…

If the item is not dimensioned, then try this:

var AvailChargePower = 
(miFro_ACpower.averageSince(now.minusMinutes(2)) as DecimalType) - 400

The averageSince now returns a State instead of DecimalType.

The difference is that DecimalType is a direct descendant of Number, so you can treat it like a Number and apply subtraction - directly, whereas a State is just an interface that DecimalState and QuantityType implements. So a type cast is required.

This change doesn’t affect jruby but it does affect DSL. Not sure whether it also affects jsscripting (@florian-h05 ?).

@Mherwege

1 Like

Indeed, and the same issue seems to be here: openHAB 4.2 Milestone discussion - #140 by TomV

This is unfortunate, but caused by DSL trying to be too intelligent in its type casting. I don’t see an easy way to avoid this.

It also affects JS Scripting, there is a breaking change warning shown on upgrade and this warning will also be part of the release notes later.

Thanks,
did finally use this proposal. Works fine

ar AvailChargePower = 
(miFro_ACpower.averageSince(now.minusMinutes(2)) as DecimalType) - 400

Hi after update openHAB to V4.3 (skipped V4.2) I got the issue with the dimension of var. Unfortunately the proposed solution don’t work for me

            var tmp_Input_pwr_AVG = (PV_Input_pwr.averageSince(now.minusMinutes(5)) as DecimalType) - 400   // Erzeugerleistung ohne Einheit

It throws following error:

[ERROR] [.handler.AbstractScriptModuleHandler] - Script execution of rule with UID ‘70_wallbox-4’ failed: Could not cast 0.03994404488888889 kW to org.openhab.core.library.types.DecimalType; line 111, column 38, length 61 in 70_wallbox

Any other suggestions to get rid of the dimension?
PS: I’m using text based rules

This is because your PV_Input_pwr is a dimensioned item.

You need:

var tmp_Input_pwr_AVG = PV_Input_pwr.averageSince(now.minusMinutes(5)).floatValue - 400   // Erzeugerleistung ohne Einheit

Assuming you are ok with the default unit. Ideally you should be working in QuantityType not converting it into plain number.

now I got:

Script execution of rule with UID ‘70_wallbox-4’ failed: ‘floatValue’ is not a member of ‘org.openhab.core.types.State’;

… and yes, working with the QuantityType is a better, but a long time ago :wink: a decide the use proxy var’s without a dimension for some math calculations. In my opinion that’s faster if you need it more the one time.

Now I got one solution

var tmp_Input_pwr_AVG = (PV_Input_pwr.averageSince(now.minusMinutes(5)) as Number).floatValue 

but I am still curious, why the first solution with “as DecimalType” is not working with V4.3

Because a QuantityType isn’t a DecmalType. In prior versions of OH, the persistence functions returned a DecimalType for all Number Items. Now it returns a QuantityType for any Number that carries a unit

I’m not sure what you mean by “faster”. The differences in speeds of the calculations should be all But unmeasurable.

But if you don’t want to use units, define your Items just a Number and you won’t need to deal with units anywhere. Any state sent to the Item will have the units stripped off. Persistence won’t give you QuantityTypes. Etc.

Ah yes, I forgot, you need to cast it to QuantityType explicitly.