Jython: Properly read values for uninitialized items

Hi there!

For several reasons, an item may not always have a value. (E.g. a new value or not persisted)

In my first attempts I tried to get the value like this (defaulting to 3):

myValue = 3 if ir.getItem("itemName").getState().intValue() is None else ir.getItem("itemName").getState().intValue()

But it’s not as simple as that. First, intValue() is not a valid function name if the item has not been initialized. I ended up with doing a function:

def getItemValue(ir, itemName, defVal):
    '''
    Returns the items value if the item is initialized otherwise return the default value.
    ir.getItem will return an object also for uninitialized items but it has less methods.
    '''
    itemValue = defVal
    try:
        if type(defVal) is int:
            if 'intValue' in dir(ir.getItem(itemName).getState()):
                itemValue = ir.getItem(itemName).getState().intValue()
        elif type(defVal) is float:
            if 'floatValue' in dir(ir.getItem(itemName).getState()):
                itemValue = ir.getItem(itemName).getState().floatValue()
        elif type(defVal) is str:
            if 'toString' in dir(ir.getItem(itemName).getState()):
                itemValue = ir.getItem(itemName).getState().toString()
        else:
            log.error('The type of the passed default value is not handled')
    except:
        log.error('Can not get item with name: ' + itemName)
        raise
    return itemValue

Usage example: cur_mood = getItem(ir, 'Sys_LightLevel', LIGHTING_MOOD['OFF'])

Is this overkill? I guess there must be an easier way… How do you do these things?

Cheers!

I’m using this for testing on an uninitialized item:

    _item = ir.getItem("Temperature_GF_Wigarden")
    _maxitem = ir.getItem('Temperature_Wigarden_Max')
    if str(_maxitem.state) == 'NULL':
1 Like

Thanks @Jue_Wis

Using your example, here is my one-liner variable assignment line (using 8 as default value if the item isn’t initialized):

myVar = 8 if str(ir.getItem("SomeItem").state) == 'NULL' else ir.getItem("SomeItem").state.intValue()

Thanks a lot!

Another way to check for NULL states is to import the related openHAB type and check for that (instead of doing the string conversion). Note there is also an UNDEF state value.

from org.openhab.core.types import UnDefType
	
NULL = UnDefType.NULL
UNDEF = UnDefType.UNDEF

....
item = ir.getItem("SomeItem")

if item.state != NULL:
  do something
else:
  do something else

....

value = item.state.intValue() if item.state not in [NULL, UNDEF] else my_default_value
1 Like

Beautiful @steve1 THANKS!

Code adopted :rofl:

EDIT: On my system (OH2.2) I need to do this import instead of the one suggested

from org.eclipse.smarthome.core.types import UnDefType

@steve1 Thank you for the hint.
Didn’t know yet about the types module.