Cannot get namespace data anymore

Dear all,

After a restart (no driven by any update or similar) of my openhab server (OH3.4.1, Rpi4, 2GB), the following unchanged rule does not work any more (apologize if the rule is not such elegant)

from core.rules import rule
from core.triggers import when
from core.items import itemRegistry
from core.metadata import get_metadata, get_all_namespaces, get_key_value
from core.actions import Transformation



@rule("Contact triggers heating", description="This rule set heating to off (if contact open) or back to group defaults (if contact closed)", tags=["contact", "heating"])
@when("Member of gContacts received update")
def setHeatingFromContact(event):

    itName = event.itemName
    triggeringItem = itemRegistry.getItem(itName)

    opState = event.itemState

    nspList = get_all_namespaces(itName)
    setHeatingFromContact.log.info("Item {} with state {} triggered the event with namespaces {}".format(triggeringItem, opState, nspList))
    setHeatingFromContact.log.info("Metadata available: {}".format(get_metadata(itName, "semantics")))

    equipmentName = get_key_value(itName, "semantics", "isPointOf")
    setHeatingFromContact.log.info("Equipment name: {}".format(equipmentName))

    setHeatingFromContact.log.info("Metadata available: {}".format(get_metadata(equipmentName, "semantics")))

    locationName = get_key_value(equipmentName, "semantics", "hasLocation")
    setHeatingFromContact.log.info("Location affected by the rule: {}".format(locationName))

    thermostaticValvesList = [item.name for item in itemRegistry.getItem(locationName).allMembers if "gThermoStatMode" in item.groupNames]
    setHeatingFromContact.log.info("List of affected thermostatic valves: {}".format(thermostaticValvesList))

    if opState == OPEN :
        heatModeVal = 0
    else:
        heatModeVal = itemRegistry.getItem("allThermostatModes").state

    setHeatingFromContact.log.info("Setting affected thermostatic valves to {}".format(heatModeVal))
    setHeatingFromContact.log.info("Setpoint for all thermostatic valves to {}".format(itemRegistry.getItem("allThermostatModes").state))

    for iName in thermostaticValvesList:

        item2cmd = itemRegistry.getItem(iName)

        if(itemRegistry.getItem(iName).getTags().contains("radiatorStringMode")):
            events.sendCommand(item2cmd, Transformation.transform("MAP", "thermostat2cometRadiatorMode.map", str(heatModeVal)))
        else:
            events.sendCommand(item2cmd, heatModeVal)

This is the log output


2023-01-09 10:55:07.476 [INFO ] [.automation.Contact triggers heating] - Item espgateway_GuestRoomWindowSensor_Status (Type=ContactItem, State=OPEN, Label=Guest Room Win
dow Contact Status, Category=contact, Tags=[OpenState, Opening], Groups=[espgatewayGuestRoomWindowContact, gContacts]) with state OPEN triggered the event with namespace
s [u'semantics']
2023-01-09 10:55:07.483 [INFO ] [.automation.Contact triggers heating] - Metadata available: None
2023-01-09 10:55:07.491 [INFO ] [.automation.Contact triggers heating] - Equipment name: {}
2023-01-09 10:55:07.527 [WARN ] [org.openhab.core.automation         ] - Traceback (most recent call last):
  File "/etc/openhab/automation/lib/python/core/log.py", line 65, in wrapper
    return function(*args, **kwargs)
  File "/etc/openhab/automation/lib/python/core/rules.py", line 109, in execute
    self.callback(inputs.get('event'))
  File "/etc/openhab/automation/jsr223/python/personal/contact_heating.py", line 25, in setHeatingFromContact
    setHeatingFromContact.log.info("Metadata available: {}".format(get_metadata(equipmentName, "semantics")))
  File "/etc/openhab/automation/lib/python/core/metadata.py", line 112, in get_metadata
    return METADATA_REGISTRY.get(MetadataKey(namespace, item_name))
TypeError: org.openhab.core.items.MetadataKey(): 2nd arg can't be coerced to String

Following the same event, I previously had this log message


2023-01-02 20:32:32.406 [INFO ] [.automation.Contact triggers heating] - Item espgateway_GuestRoomWindowSensor_Status (Type=ContactItem, State=OPEN, Label=Guest Room Window Contact Status, Category=contact, Tags=[OpenState, Opening], Groups=[espgatewayGuestRoomWindowContact, gContacts]) with state OPEN triggered the event with namespaces [u'semantics']
2023-01-02 20:32:32.415 [INFO ] [.automation.Contact triggers heating] - Metadata available: Metadata [key=semantics:espgateway_GuestRoomWindowSensor_Status, value=Point_Status_OpenState, configuration=[relatesTo=Property_Opening, isPointOf=espgatewayGuestRoomWindowContact]]
2023-01-02 20:32:32.427 [INFO ] [.automation.Contact triggers heating] - Equipment name: espgatewayGuestRoomWindowContact
2023-01-02 20:32:32.435 [INFO ] [.automation.Contact triggers heating] - Metadata available: Metadata [key=semantics:espgatewayGuestRoomWindowContact, value=Equipment_Window, configuration=[hasPoint=espgateway_GuestRoomWindowSensor_Status, hasLocation=gGuestRoom]]
2023-01-02 20:32:32.447 [INFO ] [.automation.Contact triggers heating] - Location affected by the rule: gGuestRoom
2023-01-02 20:32:32.456 [INFO ] [.automation.Contact triggers heating] - List of affected thermostatic valves: [u'ThermostaticValveGuestRoom_Thermostatmode']

How could I trace back the issue? Please note that log:set DEBUG does not seem to work for me at the moment (more in an another thread).

Thanks!
Max

There’s the root of the problem. There is no “semantics” metadata on this Item. Double check that the Item does have that metadata and that something hasn’t happened to it.

@rlkoshak

Thanks for your swift replay! Actually I was thinking the same, but when I looked to the Item page

The semantic is there, so I would expect the function

get_metadata()

to return all the values, as in the attached example. Apologize to have missed the attachment before.

Could I run somehow the rule interactively from an (OH) console? I could then debug it and find out if any library is playing wild (a fs corruption is my next guess).

Thanks
Max

Those are tags, not metadata.

@rlkoshak

correct me if I am wrong, but I think that

are metadata of the

 espgateway_GuestRoomWindowSensor_Status

I then expect the function

equipmentName = get_key_value(itName, "semantics", "isPointOf")

to return (as in the working example)

[key=semantics:espgateway_GuestRoomWindowSensor_Status, value=Point_Status_OpenState, configuration=[relatesTo=Property_Opening, isPointOf=espgatewayGuestRoomWindowContact]]

So that in

    locationName = get_key_value(equipmentName, "semantics", "hasLocation")

I can get the room where the window contact is located and turn on/off all radiators in the same room. It is quite a complicated rule, I did not know how to do better 12 months ago :sweat_smile:

Does it make sense? Do you agree the rule could work? At least it did till the last reboot :wink:

Max

That does appear to be added to the Item metadata on the fly. If you search org.openhab.core.items.Metadata.json though you will not find a semantics metadata anywhere. But the REST API does appear to return that metadata.

But, are you aware of the semantic actions? Actions | openHAB. You don’t need to mess with Item metadata to see what equipment and location an Item belongs to in the model. Just use the actions.

I don’t know the nature of this metadata that is created on the fly. I suspect it may not exist until the Item is loaded in MainUI or something like that. It’s not permanent or else it would be in the Metadata.json file. But the Actions will always work.

No I was not :sob:

They look much easier than my implementation. You pointed out to the DSL syntax - would you have a link to the python version for me? :pray:

Max

These were created long after the last update to the Python helper library. However, IIRC the Python helper library will discover and import the core Actions automatically so you might be able to use something like actions.Semantics.isLocation(i) and such.

If not, you’ll have to import org.openhab.core.model.script.actions.Semantics directly and call the functions on that. Unfortunately the Jython add-on and Helper Library isn’t being maintained by anyone anymore so over time you’ll be increasingly on your own when using it for new features in OH.

Thanks, I will have a look to both options - at the end I am still quite flexible in terms of programming language for the rules (70% DSL, 30% python right now).

Any guideline in terms of which is the rule language to use that is well maintained now and in the near future? (no flame war here, please :wink: )

Max

JS Scripting and jRuby are the two front contenders, though Groovy still has a fan base. JS Scripting is particularly nice for UI rules and it’s what Blockly will compile into in OH 4.

1 Like