Set default item state / retrieve Thing configuration parameters

I’d wish there was an easy way to set a default state of an (helper) item = without a rule or without some kind of startup logic. Even if the state (once set) would be persisted, the state needs to be set to its initial state (like for setpoint).

In my use case, the item state will never change, neither by command nor by update (e.g. IP address, MAC address information of network devices).

Displying on Main UI is easy, but I’d like to use this data in oh-repeater functions, that’s why I prefer to use the item’s state - in my case a string item…

- component: oh-repeater
  config:
    for: item
    fragment: true
    groupItem: =loop.groups.group
    sourceType: itemsInGroup

I was giving it a try with Metadata / Expiration Timer, but this didn’t work - the timer never got triggered by a state change.

Any suggestions?
(I’m running OH 3.4 stable)

When you have a repeater that returns an item or list of items, then you have access to the state of the item when the repeater made the call to the API. Because your item state doesn’t change that is the value you want. In the example you put above it would simply be:

loop.item.state

Thanks for your quick reply.

The repeater function is not causing me the headache - what is causing me the headache is how to set the inital state of the item. Once set, I can use it as you pointed out.

I see.

In the case of string items the default widget does not allow for interacting with the item. However, you can set the default standalone widget to something else. If I recall, there’s a string input widget available in the marketplace. If not, there are certainly examples of input widgets for other types that you might be able to adapt for your use.

To be honest, however, creating the item, setting the default widget, and then using the widget to set the state sounds to me like more work than just using a rule. I have a blockly script that I use for something very similar to this. The advantage to doing this with blockly is that a click on the item name block brings up a list of items and then you can just hit the run the rule button.

Certainly, however, for UI created items it shouldn’t be too hard to add an initial state field to the item creation wizard. You could certainly file this as an enhancement request on the webui github repository.

The most expedient thing to do is to use the ~Scratchpad~ Script (hit alt-shift-D to bring up the developer sidebar and select “Scratchpad” from the third tab to create it if it doesn’t exist).

Blockly is a good choice to choose for this but you can choose any language.

This Rule’s purpose is to have a place to quickly do stuff like that one time you need to populate an Item’s state that first time and the like. Just issue your update(s) and click the play button and you are do

We can handle this too. Configure the Item to be restoreOnStartup but not to save on change or update or periodically in the mapdb.persist file. In the ~Scratchpad~ update the Item and then call persist("mapdb") on the Item to save its initial value. Since the value doesn’t get overwritten by changes or updates, when OH restarts it will restore this initial value.

1 Like

Thank you for your suggestions.

Well, it seems as if there is no direct way to set the item’s state…

Worth noting that the IP address is already part of the thing configuration of a Network binding thing (configuration/hostname). Maybe some way to retrieve it?

It would be elegant to:

  • fetch this data somehow from the thing configuration and
  • transfer it somehow directly to the item’s state

… thereby making sure the shown IP address is always up to date in the UI.

My findings so far…

REST API request URL:

http://192.168.0.13:8080/rest/things/network%3Apingdevice%3Abcbd2958ed

provides:

{
  "channels": [
    {
      "linkedItems": [
        "KostalWechselrichterPing_Online"
      ],
      "uid": "network:pingdevice:bcbd2958ed:online",
      "id": "online",
      "channelTypeUID": "network:online",
      "itemType": "Switch",
      "kind": "STATE",
      "label": "Online",
      "description": "Gibt an ob das Gerät aktuell online oder offline ist.",
      "defaultTags": [],
      "properties": {},
      "configuration": {}
    },
    {
      "linkedItems": [
        "KostalWechselrichterPing_Pingzeit"
      ],
      "uid": "network:pingdevice:bcbd2958ed:latency",
      "id": "latency",
      "channelTypeUID": "network:latency",
      "itemType": "Number:Time",
      "kind": "STATE",
      "label": "Pingzeit",
      "description": "Gibt an wie lange ein Ping in Millisekunden an das Gerät dauert.",
      "defaultTags": [],
      "properties": {},
      "configuration": {}
    },
    {
      "linkedItems": [
        "KostalWechselrichterPing_Zuletztgesehen"
      ],
      "uid": "network:pingdevice:bcbd2958ed:lastseen",
      "id": "lastseen",
      "channelTypeUID": "network:lastseen",
      "itemType": "DateTime",
      "kind": "STATE",
      "label": "Zuletzt gesehen",
      "description": "Gibt Zeit/Datum an wann das Gerät zuletzt gesehen wurde.",
      "defaultTags": [],
      "properties": {},
      "configuration": {}
    }
  ],
  "statusInfo": {
    "status": "ONLINE",
    "statusDetail": "NONE"
  },
  "editable": true,
  "label": "Kostal Wechselrichter (Ping)",
  "configuration": {
    "hostname": "192.168.0.10",
    "refreshInterval": 60000,
    "retry": 2,
    "timeout": 5000
  },
  "properties": {
    "icmp_state": "IPUTILS_LINUX_PING",
    "dhcp_state": "Bound to port 6767 - Port forwarding necessary !",
    "presence_detection_type": "",
    "arp_state": "Unknown arping tool",
    "uses_ios_wakeup": "Yes"
  },
  "UID": "network:pingdevice:bcbd2958ed",
  "thingTypeUID": "network:pingdevice"
}

Alternatively the IP address is also shown in Main UI (Thing → Code):

UID: network:pingdevice:bcbd2958ed
label: Kostal Wechselrichter (Ping)
thingTypeUID: network:pingdevice
configuration:
  hostname: 192.168.0.10
  refreshInterval: 60000
  retry: 2
  timeout: 5000

There seem to be another way to somehow get the IP address via the Thingshandler…
+++
Things can be configured with parameters. To retrieve the configuration of a Thing one can call getThing().getConfiguration() inside the ThingHandler . The configuration class has the equivalent methods as the Map interface, thus the method get(String key) can be used to retrieve a value for a given key.
+++

Item’s stateDescription can hold a transformation:
+++
Pattern or transformation applied to the state for display purposes
+++

What would such a transformation be?
Any other way to get this done with no rule?

If the state of the Item isn’t what you want to see on your UI, you can transform it. See Transformations | openHAB.

No, beyond the fact that all the Thing information already is shown in MainUI under the Things page. You’d only need to go through all of this if for some reason you insist on seeing it in an Item.

Happy New Year!

Well, while accepting the fact that it doesn’t work without some kind of rule approach, I’m following up on:

The IP Address is part of the thing’s configuration…

While successfully testing with “getThingStatusInfo”…

Test3.postUpdate(getThingStatusInfo("kostalinverter:kostalinverter:cc02a0692f").getStatus().toString())

(the item “Test3” gets properly updated with “ONLINE” / “OFFLINE” / “UNINITIALIZED”)

… the following code …

Test3.postUpdate(getThing("network:pingdevice:bcbd2958ed").getConfiguration().get("hostname").toString())

… results in the following error …

2023-01-01 10:53:01.280 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'network_device_status-5' failed: The name 'getThing' cannot be resolved to an item or type; line 85, column 22, length 41 in network_device_status

Do you have any idea, whether there is something wrong with the code or whether this approach simply can’t be used in DSL rules (but why)?

getThingStatusActions is a documented and supported action. Actions | openHAB

getThing is not. You can’t just call any random function as an Action in a rule.

1 Like

… left with my last option (REST API), I came up with the following solution.

The following command can be used in DSL rules to get e.g. “hostname” from a Network binding Thing:

Test3.postUpdate(transform("JSONPATH","$.configuration.hostname",sendHttpGetRequest('http://"user":"password"@192.168.0.13:8080/rest/things/network%3Apingdevice%3Abcbd2958ed')))