[SOLVED] Jython - Persistence return value


I just noticed while converting my rules from DSL to JSR that the return value from a persistence action is not directy usable for comparison (ie. higher/less than) without converting it to string and then float.

myVal = pe.averageSince(ir.getItem("myItem"), DateTime.now().minusMinutes(10), "jdbc")
if (myVal > 50): <- This doesn't work correctly, the comparison is not "numerical"
        #do something

This however works:
if (float(str(myVal) > 50):

I don’t know if this is as designed or if I’m doing something wrong, could it be worth adding to the Wiki in the persistence action section as a note? Could save some users some time

Edit: “MyItem” is a Number item.

I clearly have a problem with type conversion in jython :confounded: I’m having the same challenges with plain Number items. What am I doing wrong? :crazy_face:

if (ir.getItem("myNumericItem").state == 1):
TypeError: cannot concatenate ‘str’ and ‘org.eclipse.smarthome.core.library.types.DecimalType’ objects

if (int(ir.getItem("HouseMode").state) == 1):
TypeError: int() argument must be a string or a number, not ‘2’

if (DecimalType(ir.getItem("HouseMode").state) == 1):
TypeError: org.eclipse.smarthome.core.library.types.DecimalType(): 1st arg can’t be coerced to java.math.BigDecimal, double, long, String

It works a little differently in Jython, and a little less intuitively. See https://openhab-scripters.github.io/openhab-helper-libraries/Guides/But%20How%20Do%20I.html#convert-a-value-to-a-state-for-comparison

What you should notice is you need to convert the 50 to a DecimalType for the comparison.

myVal = pe.averageSince(ir.getItem("myItem"), DateTime.now().minusMinutes(10), "jdbc")
if myVal > DecimalType(50):
    # do someting

If you really do need to convert these values to a Python primitive, then you are doing it right, you need to convert it to a String (str()) and parse the String (float()) like you are doing.

if items["myNumericItem"] == DecimalType(1):

If you are using the helper libraries remember that there is a dict with Item names as keys and states as the value. The parens are also not necessary in Python in the if statement.

if int(str(items["HouseMode"])) == 1:

See above, you need to convert the 1 to decimal type or convert the state to a Python int.

This is definitely one of the frustrating things with using Jython.

1 Like

items is included in the default scope for scripted automation and is not part of the helper libraries. But, the Jython HLs allow you to save a couple key strokes (I still don’t use this myself) and get an Item’s state from items as an attribute rather than treating it as a dict…

if items.myNumericItem == DecimalType(1):

I’ll see if I can get the core.init.py into the documentation, but this is covered in the But How Do I.

I really hope you don’t get offended by me swooping in with comments/corrections. I really only intend tham as helpful info as you get trained up! :slight_smile:

Not at all. It’s a learning activity. It also shows that even if something is in the docs doesn’t mean we know to look there. I’ve seen items[“MyItem”] in lots of examples. It never occurred to me to look at the docs to see if there is another way.

This kind of stuff can help us with the docs. We should settle on one way and stick to it where possible.

1 Like