Get metadata from item (File), JSSCRIPTING

unfortunately i have not found a solution for the following problem, i have tried several things, but unfortunately i can’t get a result. i want to read the value for

alarmIntervallMin

(=60) from the metadata of an item, but unfortunately i fail …
(OH 3.4.2, JSScripting Helper Library 4.1.0)

item:

DateTime  LaCrosseSensor1_Temperatur_LastUpdate   "Temperatur Kellerraum groß LastUpdate [%1$td.%1$tm.%1$tY %1$tR]"  <clock>  (gSensorExpired) {channel="jeelink:lacrosse:84e3ec08:4:temperature" [profile="timestamp-update"], Static="SensorExpire"[alarmIntervallMin=60]}
var alarmIntervallMin6 = items.metadata.getMetadata(items.LaCrosseSensor1_Temperatur_LastUpdate);
var namespaces1 = Object.keys(alarmIntervallMin6); // Get metadata namespaces
logger.info("METADATA6: " + namespaces1);  // --> METADATA6: Static

var alarmIntervallMin7 = items.metadata.getMetadata(items.LaCrosseSensor1_Temperatur_LastUpdate, "Static").value;
logger.info("METADATA7: " + alarmIntervallMin7); // -->  METADATA7: SensorExpire

var alarmIntervallMin8 = items.metadata.getMetadata(items.LaCrosseSensor1_Temperatur_LastUpdate, "Static").configuration;
logger.info("METADATA8: " + alarmIntervallMin8); // --> METADATA8: [object Object]

Where did you get that syntax? Always check the docs when it doesn’t work. JavaScript Scripting - Automation | openHAB

items.LaCrosseSensor1_Temperature.getMetadata()[‘Static’].value;
items.LaCrosseSensor1_Temperature.getMetadata()[‘Static’].configuration[‘alarmIntervalMin’];

from here: metadata - Documentation
and here: openHAB JavaScript library releases

your code gives the following error for both lines:

2023-03-08 19:45:02.292 [ERROR] [b.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: TypeError: null has no such function "getMetadata"
        at <js>.:program(test.js:358) ~[?:?]
        at org.graalvm.polyglot.Context.eval(Context.java:399) ~[?:?]
        at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:458) ~[?:?]
        at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:400) ~[?:?]
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:249) ~[java.scripting:?]
        at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocableAndAutocloseable.eval(DelegatingScriptEngineWithInvocableAndAutocloseable.java:58) ~[?:?]
        at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.eval(InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.java:84) ~[?:?]
        at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocableAndAutocloseable.eval(DelegatingScriptEngineWithInvocableAndAutocloseable.java:58) ~[?:?]
        at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.eval(InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.java:84) ~[?:?]
        at org.openhab.core.automation.module.script.internal.ScriptEngineManagerImpl.loadScript(ScriptEngineManagerImpl.java:185) ~[?:?]
        at org.openhab.core.automation.module.script.rulesupport.loader.AbstractScriptFileWatcher.createAndLoad(AbstractScriptFileWatcher.java:276) ~[?:?]
        at org.openhab.automation.jsscripting.internal.fs.watch.JSScriptFileWatcher.createAndLoad(JSScriptFileWatcher.java:63) ~[?:?]
        at org.openhab.core.automation.module.script.rulesupport.loader.AbstractScriptFileWatcher.importFile(AbstractScriptFileWatcher.java:256) ~[?:?]
        at org.openhab.core.automation.module.script.rulesupport.loader.AbstractScriptFileWatcher.lambda$5(AbstractScriptFileWatcher.java:248) ~[?:?]
        at java.util.Optional.ifPresent(Optional.java:183) ~[?:?]
        at org.openhab.core.automation.module.script.rulesupport.loader.AbstractScriptFileWatcher.importFileWhenReady(AbstractScriptFileWatcher.java:246) ~[?:?]
        at java.lang.Iterable.forEach(Iterable.java:75) ~[?:?]
        at org.openhab.core.automation.module.script.rulesupport.loader.AbstractScriptFileWatcher.processWatchEvent(AbstractScriptFileWatcher.java:223) ~[?:?]
        at org.openhab.automation.jsscripting.internal.fs.watch.JSScriptFileWatcher.processWatchEvent(JSScriptFileWatcher.java:56) ~[?:?]
        at org.openhab.core.service.WatchQueueReader.lambda$5(WatchQueueReader.java:357) ~[?:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        at java.lang.Thread.run(Thread.java:829) [?:?]
2023-03-08 19:45:02.298 [ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error during evaluation of script 'file:/etc/openhab/automation/js/test.js': org.graalvm.polyglot.PolyglotException: TypeError: null has no such function "getMetadata"

Your code looks correct to me. I think your problem is that you are taking this

to mean that it is not working, In fact. that log statement is entirely correct. The configuration of item metadata is an object and when you log out an object it gets converted to a string and the default string conversion for objects results in [object Object]. If you want to the contents of the object in string form then you need

JSON.stringify(alarmIntervallMin8)

Or, just trust that your object is there and go the final step: alarmIntervallMin8.alarmIntervalMin and you should see your value.

Rich’s code should work too, and be more readable. It looks like the item name didn’t fully translate over from your original to his example, if you didn’t correct the item name then is it not a surprise you got an error.

Are you sure that LaCrossSensor1_Temperature is an Item? The error indicates that items.LaCrosseSensor1_Temperature returned null.

Are you certain you are on version 4.1 of openhab-js? You have to install it separately. It doesn’t come with the addon except in the OH 4.0 snapshots. The ability to use items.ItemName or item['ItemName'] wasn’t added until openhab-js 4.0, nor was the reimplementation of the metadata interface.

I’m working on a rule right as I type this that uses this syntax. Some examples:

  console.debug('Populating record from Item metadata or rule defauls');
  const md = (items[name].getMetadata()[namespace] !== undefined) ? items[name].getMetadata()[namespace].configuration : {};
  record.threshold = stateToValue(thresholdStr);
  if(md['threshold'] !== undefined) record.threshold = stateToValue(md['threshold']);
  if(md['thresholdItem'] !== undefined) record.threshold = stateToValue(items[md['thresholdItem']].rawState);
  record.operator   = (md['operator'] !== undefined) ? md['operator'] : operator;
  const md = items[itemName].getMetadata()[NAMESPACE];

  if(!md) {
    throw itemName + ' does not have ' + NAMESPACE + ' metadata!';
  }

  if(!md.value) {
    throw itemName + ' has malformed ' + NAMESPACE + ' metadata, no value found!';
  }

  const dayType = md.configuration['type'];
  if(!dayType) {
    throw itemName + ' has malformed ' + NAMESPACE + ' metadata, required "type" property is not found!';
  }
  const md = items[itemName].getMetadata()['debounce'];
  
  if(!md) {
    throw itemName + ' does not have debounce metadata!\n' + USAGE;
  }

  if(!md.value) {
    throw itemName + ' has malformed debounce metadata, no value found!\n' + USAGE;
  }

  if(!items.getItem(md.value)) {
    throw itemName + ' has invalid debounce metadata, proxy Item ' + md.value + ' does not exist!\n' + USAGE;
  }

  if(!md.configuration['timeout']) {
    throw itemName + 'has malformed debounce metadata, timeout configuration parameter does not exist!\n' + USAGE;
  }

No the original item is LaCrosseSensor1_Temperatur_LastUpdate

You truncated the _LastUpdate part in your example. So if this issue was not caught when OP tested your example code that is, in deed, the source of the error.

1 Like

sorry, that was a copy error.

OH Version: 3.4.2, i have manually installed version 4.1.0

logger.info("openhab-js library Version: " + utils.OPENHAB_JS_VERSION);
2023-03-08 21:50:25.825 [INFO ] [hab.automation.openhab-js.testscript] - openhab-js library Version: 4.1.0

it makes a difference if the value 60 is with quotes or without in the metadata, why?

// item: .... Static="SensorExpire"[alarmIntervallMin=60]}

var alarmIntervallMin10 = items.LaCrosseSensor1_Temperatur_LastUpdate.getMetadata()["Static"].configuration;

logger.info("METADATA10: " + JSON.stringify(alarmIntervallMin10)); // --> METADATA10: {"alarmIntervallMin":{}}

// item: .... Static="SensorExpire"[alarmIntervallMin="60"]}

var alarmIntervallMin11 = items.LaCrosseSensor1_Temperatur_LastUpdate.getMetadata()["Static"].configuration;

logger.info("METADATA11: " + JSON.stringify(alarmIntervallMin11)); // --> METADATA11: {"alarmIntervallMin":"60"}

i’m sorry, but can you please explain this to me in more detail?

With the quotes it’s treated as a String. Without it’s treated as a number. Metadata can store more than just string values.

1 Like

When you store the result of .getMetadata()["Static"].configuration in a variable, that variable is now a javascript object.

thank you for the support, i was finally able to get it to run …

// item: .... Static="SensorExpire"[alarmIntervallMin="60"]}

var alarmIntervallMin13 = items.LaCrosseSensor1_Temperatur_LastUpdate.getMetadata()["Static"].configuration;

logger.info("METADATA13: " + alarmIntervallMin13.alarmIntervallMin); // --> METADATA13: 60