Jython: 'str()' returning: 'org.eclipse.smarthome.core.library.types.StringType': object has no attribute 'split'

I’m running the latest openHAB 2.5.5 release and see that there’s a problem in one of my rules where I convert a state to String. I understood that when using str() I would be using a plain Python string in that case, but this seems to be an incorrect assumption as instead I get a org.eclipse.smarthome.core.library.types.StringType

Code snippet:

@rule(
    rulePrefix + "Sun Time of Day changed",
    description=u"Sun Time of Day changed" + ruleTimeStamp,
    tags=["TimeOfDay", "Astro", ruleTimeStamp],
)
@when("System started")
@when("Item {} changed".format(my_rule_items.SUN_TIME_OF_DAY))
def Rule_SunTimeOfDayChanged(event):
    global logTitle
    logPrefix = "Rule_SunTimeOfDayChanged(): "

    if event:
        oldState = (
            "(Not defined)"
            if event.oldItemState is None
            else str(event.oldItemState) # seems to return org.eclipse.smarthome.core.library.types.StringType (not java.lang.String)
        )
        newState = event.itemState
    else:
        item = ir.getItem(my_rule_items.SUN_TIME_OF_DAY)
        if item:
            oldState = "(unknown)"
            newState = str(item.state) # seems to return org.eclipse.smarthome.core.library.types.StringType (not java.lang.String)
        else:
            oldState = "(Item not in item registry)"
            newState = oldState
    Telegram.sendTelegram(
        defaults.TELEGRAM_BOT_NAME,
        "<b>Sun: Time Of Day</b> {item} changed from <pre>{oldState}</pre> to <pre>{newState}</pre>: <b>{tod}</b>).".format(
            item=my_rule_items.SUN_TIME_OF_DAY,
            oldState=oldState,
            newState=newState,
            tod=capitalizeWords(" ".join(newState.split("_"))), # ERROR OCCURS HERE AT `split()`
        ),
    )

Error log:

2020-05-26 13:42:12.955 [ERROR] [ime Of Day | Sun Time of Day changed] - Traceback (most recent call last):
  File "/etc/openhab2/automation/lib/python/core/log.py", line 52, in wrapper
    return fn(*args, **kwargs)
  File "<script>", line 150, in Rule_SunTimeOfDayChanged
AttributeError: 'org.eclipse.smarthome.core.library.types.StringTyp' object has no attribute 'split'

Is this intentional? How can I fix this so that split() works (again) as expected?

The state of a String Item is of type StringType, not String. And as the error indicates, StringType, not being a String, doesn’t have a split method. You need to convert the StringType to a String. This part you already understand.

When you call the Python str() method with a Java Object, it appears to not call the toString() method on that Java Object. Instead it generates a String based on the class information of the Object.

Therefore, instead of calling str(item.state) call item.state.toString(). That will return a java.lang.String which might be converted to or is the same thing as a Jython String (I’m not sure) but in either case that will have the split() method.

As a rule of thumb, use str() when you are working with Python primitives and devices and use .toString() when working with Java Objects. Items, States, Timers, Commands are all going to be Java Objects.

1 Like