Item value calc error

  • Platform information:
    • RasPi4
    • Java Runtime Environment: Default OpenJDK11.0.11
    • openHAB version: 3.1.0M5

Im not an programming expert but usually I get some simple code together. In this case I dont understand why addition or sum of two Item values throws errors. Any advises from the community?

Triggers a rule on updated Item value.

triggers:
  - id: "1"
    configuration:
      itemName: KOSTALPLENTICOREPlus70withBattery_PVStr1Power
    type: core.ItemStateUpdateTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/python
      script: >
        import time

        from org.slf4j import LoggerFactory


        PV1 = itemRegistry.getItem('KOSTALPLENTICOREPlus70withBattery_PVStr1Power').getState()

        PV2 = itemRegistry.getItem('KOSTALPLENTICOREPlus70withBattery_PVStr2Power').getState()

        PVPowerTotal = sum(PV1, PV2)

        #PVPowerTotal = Math.round(PVPowerTotal)

        #events.postUpdate('PVPower', PVPowerTotal)

        LoggerFactory.getLogger("org.openhab.core.automation.examples").info("calculated PVPowerTotal " + str(PVPowerTotal) + "  PV1: " + str(PV1) + "   PV2: " + str(PV2) + "\n")
    type: script.ScriptAction```

LOG output
Script execution of rule with UID ‘5642357aaa’ failed: TypeError:
‘org.openhab.core.library.types.DecimalType’ object is not iterable in at line number 6

Whats wrong with
 PVPowerTotal = sum(PV1, PV2)

PV1 and PV2 are not numbers in any sense that Python can understand. They are Java Item Objects. No matter the language, to do math with the State of an Item, you have to pull that state, e.g. PV1.state. So far so good.

But that state is a Java Object too of either DecimalType or QuantityType. The Python sum() function only knows how to deal with Python numbers, not Java Objects. And even in Rules DSL or Java code one needs to do extra to do math with Number Item’s states, particularly if they carry a unit of measurement.

So how are these Items defined? Do they have units? Are the units compatible if so? Whether or not they carry units changes how to do math with them.

Hi Rich,
that is good info. Item Types for both PV String 1 & 2 are defined as Number. Is there an elegant way to convert into int or float?

OK, that’s a start. But just because it’s a Number doesn’t mean it’s not carrying units. Do these Items log with just a number or a number with units in events.log.

Assuming that there are no units you can call .intValue() or .floatValue() to get the state as a primitive.

Note, it’s shorter and a lot easier to read usually to use the items dict which is a dictionary of all Items and their current states. So

itemRegistry.getItem('KOSTALPLENTICOREPlus70withBattery_PVStr1Power').getState().intValue()

can be replaced with

items["KOSTALPLENTICOREPlus70withBattery_PVStr1Power"].intValue()

Yeah, I thought I already tried .intvalue() recently. Indeed I remember getting that error…

2021-06-10 21:30:02.655 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘5642357aaa’ failed: TypeError: ‘int’ object is not iterable in at line number 6

After removing sum statement (just to see whats written into log, I see that PV values are unit-less.

2021-06-10 21:36:05.172 [INFO ] [org.openhab.core.automation.examples] - calculated PVPowerTotal PV1: 7 PV2: 9

.intValue()

Typo in my post - I meant intValue()

import time
from org.slf4j import LoggerFactory

PV1 = items[“KOSTALPLENTICOREPlus70withBattery_PVStr1Power”].intValue()
PV2 = items[“KOSTALPLENTICOREPlus70withBattery_PVStr2Power”].intValue()
PVPowerTotal = sum(PV1, PV2)
#PVPowerTotal = Math.round(PVPowerTotal)
#events.postUpdate(‘PVPower’, PVPowerTotal)
LoggerFactory.getLogger(“org.openhab.core.automation.examples”).info("calculated PVPowerTotal " + str(PVPowerTotal) + " PV1: " + str(PV1) + " PV2: " + str(PV2) + “\n”)

Also tried .intFloat() which results in similar error message - as expected. I think I just need a general method to manage such kind of Java Objects in python scripts.
Can someone help me out getting it solved?

Well, yes. it would be .floatValue

Isn’t the message telling you that sum() expects an iterable, like a list, and you’e giving it just a simple number? Doesn’t a simple + work here?

.floatValue() yes. (I better take care on my postings…- or even cut/past code only to avoid confusion.)

You’re the man!!!
I didn’t know about that behavior of sum.

Perhaps you can post your solution, for the benefit of later readers.

Yes, I marked your post as solution (thx):
Here is the full script:

# import time
from org.slf4j import LoggerFactory

PV1 = items["KOSTALPLENTICOREPlus70withBattery_PVStr1Power"].floatValue()
PV2 = items["KOSTALPLENTICOREPlus70withBattery_PVStr2Power"].floatValue()
PVPowerTotal = str(round(PV1+PV2, 2))+'W'
events.postUpdate("PVPower", PVPowerTotal)
LoggerFactory.getLogger("org.openhab.core.automation.examples").info('Rule:CalcPVPower - PVPower:' + PVPowerTotal)