[SOLVED] Jython rule to convert string item to number item

I am trying to persist the current java heap size so I can try and track down the cause of java running out of memory on my OH 2.4 system. @rlkoshak helped tremendously by showing me how to set up passwordless logins to the karaf shell and extract the relevant value and I now have a script called from an exec command that stores the current heap size in a string item.

I’ve nearly cracked it but have been banging my head on the desk at the very last step which is converting the output of the ssh command from a string to a number item.

I have the following items:

String		ShellCurrentHeapString		"Current Heap Size (String)"			{channel="exec:command:exec_shell_current_heap5:output"}
Number		ShellCurrentHeapNumber		"Current Heap Size"		(gGraphing)

The number item is intended to store the value of the string item cast to a number by the following rule:

from core.triggers import when
from core.rules import rule

@rule("Karaf current heap size", description="This rule converts the string value of the current heap size to a number value", tags=["Example"])
@when("Item ShellCurrentHeapString received update")
def karaf_current_heap_size(event):
    testvar     = None

    testvar = float(str(ir.getItem(event.itemName).getState))

(I need to store the current heap size as a number so I can persist it in InfluxDB and then graph it with Grafana.)

However, I can’t seem to get the syntax right to cast from string to int (or float), I thought that part would be the easy bit. Errors in the log are:

2019-09-06 20:44:35.769 [ERROR] [omation.core.internal.RuleEngineImpl] - Failed to execute rule '7595688b-2d1c-4777-ba36-31af43d15fcb': Fail to execute action: 1
2019-09-06 20:44:37.913 [ERROR] [sr223.jython.Karaf current heap size] - Traceback (most recent call last):
  File "/etc/openhab2/automation/lib/python/core/log.py", line 43, in wrapper
    return fn(*args, **kwargs)
  File "<script>", line 9, in karaf_current_heap_size
ValueError: invalid literal for float: <bound method org.eclipse.smarthome.core.library.items.StringItem.getState of ShellCurrentHeapString (Type=StringItem, State=2019178, Label=Current Heap Size (String), Category=null)>

2019-09-06 20:44:37.913 [ERROR] [omation.core.internal.RuleEngineImpl] - Failed to execute rule '7595688b-2d1c-4777-ba36-31af43d15fcb': Fail to execute action: 1

Or if I try to convert to an integer:

2019-09-06 20:45:32.378 [ERROR] [sr223.jython.Karaf current heap size] - Traceback (most recent call last):
  File "/etc/openhab2/automation/lib/python/core/log.py", line 43, in wrapper
    return fn(*args, **kwargs)
  File "<script>", line 9, in karaf_current_heap_size
ValueError: invalid literal for int() with base 10: '<bound method org.eclipse.smarthome.core.library.items.StringItem.getState of ShellCurrentHeapString (Type=StringItem, State=2020605, Label=Current Heap Size (String), Catego
ry=null)>'

2019-09-06 20:45:32.378 [ERROR] [omation.core.internal.RuleEngineImpl] - Failed to execute rule '030dc9c7-769b-4ea4-88fb-e7dd2377350c': Fail to execute action: 1

I thought converting from a string to an integer would be the easy part! :slight_smile:

getState() is a method and you have forgotten the parenthesis. You could also use the state attribute, but there’s no need to go to the ItemRegistry for this. Just do…

testvar = float(str(items[event.itemName]))

https://openhab-scripters.github.io/openhab-helper-libraries/Guides/But%20How%20Do%20I.html#convert-decimaltype-to-an-integer-or-float-for-arithmetic

I must be missing something fundamental here. In the extracts from the logs that I included in the OP it seems clear to me that the state is a valid representation of both an integer and a float since the state is always a sequence of numerical characters. Yet, when trying to convert to a float the error was

invalid literal for float

and when trying to convert to an integer the error was

invalid literal for int() with base 10

Now, I’ve updated the rule to be:

from core.triggers import when
from core.rules import rule

@rule("Karaf current heap size", description="This rule converts the string value of the current heap size to a number value", tags=["Example"])
@when("Item ShellCurrentHeapString received update")
def karaf_current_heap_size(event):
    testvar     = None

    events.postUpdate("ShellCurrentHeapNumber", float(str(items[event.itemName])) )

I see the following errors in the log:

2019-09-06 21:37:25.185 [ERROR] [omation.core.internal.RuleEngineImpl] - Failed to execute rule '5ffdf780-70a2-4063-8c1d-f88d87436b50': Fail to execute action: 1
2019-09-06 21:37:27.253 [ERROR] [sr223.jython.Karaf current heap size] - Traceback (most recent call last):
  File "/etc/openhab2/automation/lib/python/core/log.py", line 43, in wrapper
    return fn(*args, **kwargs)
  File "<script>", line 11, in karaf_current_heap_size
TypeError: postUpdate(): 1st arg can't be coerced to org.eclipse.smarthome.core.items.Item, String

2019-09-06 21:37:27.253 [ERROR] [omation.core.internal.RuleEngineImpl] - Failed to execute rule '5ffdf780-70a2-4063-8c1d-f88d87436b50': Fail to execute action: 1

But if I hardcode the value to be “1”:

from core.triggers import when
from core.rules import rule

@rule("Karaf current heap size", description="This rule converts the string value of the current heap size to a number value", tags=["Example"])
@when("Item ShellCurrentHeapString received update")
def karaf_current_heap_size(event):
    testvar     = None

    events.postUpdate("ShellCurrentHeapNumber", "1" )

I get no errors in the log.

The item ShellCurrentHeapNumber is definitely a Number item:

openhab> smarthome:items list  ShellCurrentHeapNumber
ShellCurrentHeapNumber (Type=NumberItem, State=1, Label=Current Heap Size, Category=null, Groups=[gGraphing])

The conversion to float worked, but now you’re trying to convert it back to a string. Try this…

from core.triggers import when
from core.rules import rule

@rule("Karaf current heap size", description="This rule converts the string value of the current heap size to a number value", tags=["Example"])
@when("Item ShellCurrentHeapString received update")
def karaf_current_heap_size(event):
    testvar     = None
    events.postUpdate("ShellCurrentHeapNumber", event.itemState.toString())

Good grief. Was I trying to be too helpful to the postUpdate method?

Do I understand from that that you only ever need to pass strings to the postUpdate method? The conversion to whatever type the item is is taken care of within postUpdate?

Correct… for both postUpate and sendCommand. Here are all of the options… https://www.openhab.org/docs/configuration/jsr223.html#events-operations.

The second option on that page is:

events.postUpdate(Item, Number)

so why didn’t

events.postUpdate("ShellCurrentHeapNumber", float(str(items[event.itemName])) )

work?

Or

events.postUpdate("ShellCurrentHeapNumber", int(str(items[event.itemName])) )

which didn’t work either.

Because "ShellCurrentHeapNumber" is not an Item but a string. This would work too…

events.postUpdate(ir.getItem("ShellCurrentHeapNumber"), float(str(items[event.itemName])))

or

events.postUpdate(ir.getItem("ShellCurrentHeapNumber"), event.itemState)

or

events.postUpdate(ir.getItem("ShellCurrentHeapNumber"), event.itemState.toString())

or

events.postUpdate("ShellCurrentHeapNumber", event.itemState.toString())

I think this is something like what I was trying to achieve:

events.postUpdate(ir.getItem(event.itemName), event.itemState)

I.e., no item name being hardcoded. I’ve just tried this and while it results in no errors in the log it doesn’t seem to cause the item to be updated either.

But event.itemName would be ShellCurrentHeapString and you want to update ShellCurrentHeapNumber.

But event.itemName would be ShellCurrentHeapString and you want to update ShellCurrentHeapNumber.

OMFG

1 Like