How to get Item Metadata in Groovy scripting OH4.3

Hi,

I need some help for this topic. I’ve already tried a lot and I’m sure there is an easy way to get the Metadata that is assigned to an Item from an jsr223 script using Groovy.
Id like to use some “shading” related metadata that I add to my blinds rather than hard-code them into the script.
Can you help me?

Kind regards,
Andreas.

Hi,
A bit short on information, but I’ll give it a try.
If the values ​​are stored under config, you can access them with getItemMetaConfigValue.
Beispiel: Item have metadata “automation”

config:
  "0": 0
  "1": 5
  "2": 15
  "3": 35
  "4": 65
  "5": 100
function getItemMetaConfigValue(itemName, namespace, prop) {
  if (items.metadata.getMetadata(itemName, namespace) === null) {
     return 'undefined';
  };
  let props = prop.split('.');
  let value = items.metadata.getMetadata(itemName, namespace).configuration;
  props.forEach(property => {
    value = value[property];
  });
  return value;
}

var Soll = getItemMetaConfigValue('itemID', 'automation', '4');
if (Soll == undefined) {
  console.warn('Warn');
  Soll = 50;
} else {
  console.info(('Soll = ' + String(Soll)));
}

I’m using the wrong language—those who can read have a clear advantage. I’m so sorry.

Hi,

sorry for the little amount of detail. Seems I underestimate the complexity. Thanks for trying to answer any way!

A method like getItemMetaConfigValue('itemID', 'automation', '4'); sounds exactly like what I need. But I can not get hold of one. Might be I miss something I need to call or statically import before to get the method injected?

All I get is:

No signature of method: org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.getItemMetaConfigValue() is applicable for argument types: (String, String, String)

So unfortunately this does not work (for me).

Here a simple sample groovy file that I now use to test this and should give the details about what I want to do:

import org.openhab.core.model.script.ScriptServiceUtil
import org.slf4j.LoggerFactory

def log = LoggerFactory.getLogger('Metadata')
def item = ScriptServiceUtil.getItemRegistry().getItem(
        'Raffstore_Essen_Schiebeture')
def travelTimeOpenSeconds = getItemMetaConfigValue(
        'Raffstore_Essen_Schiebeture', 'shading', 'travelTimeOpenSeconds')
log.info("Found metadata for ${item.name} - travelTimeOpenSeconds is ${travelTimeOpenSeconds}!")

And I get:

Error during evaluation of script '/openhab/conf/automation/jsr223/groovy/.../MetadataAccess.groovy': 
    javax.script.ScriptException: groovy.lang.MissingMethodException: 
        No signature of method: org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.getItemMetaConfigValue() 
        is applicable for argument types: (String, String, String) values: [Raffstore_Essen_Schiebeture, shading, travelTimeOpenSeconds]

:sleeping_face: Sorry, my mistake. Created with Blockly and overlooked a feature. It’s been added above.
I’m using the wrong language—those who can read have a clear advantage. I’m too small for this world. I’m so sorry.

Null Ahnung → import org.openhab.core.items.Metadata ?

Lets see, might be someone can help now.

As documented at JSR223 Scripting | openHAB I see ‘items’ but it is a Instance of java.util.Map<String, State>. It has no property ‘metadata’. So items.metadata is null in my case.

My very basic understanding is Groovy works with the raw Java apis. If that’s the case something like the following should work.

In Nashorn JS it looks like this to get to all the Java classes:

//   Get Metadata query stuff 

        this.FrameworkUtil = (this.FrameworkUtil === undefined) ? Java.type("org.osgi.framework.FrameworkUtil") : this.FrameworkUtil; 

        this.ScriptHandler = Java.type("org.openhab.core.automation.module.script.rulesupport.shared.ScriptedHandler");

        this._bundle = (this._bundle === undefined) ? FrameworkUtil.getBundle(ScriptHandler.class) : this._bundle;

        this.bundle_context = (this.bundle_context === undefined) ? this._bundle.getBundleContext() : this.bundle_context; 

        this.MetadataRegistry_Ref = (this.MetadataRegistry_Ref === undefined) ? bundle_context.getServiceReference("org.openhab.core.items.MetadataRegistry") : this.MetadataRegistry_Ref; 

        this.MetadataRegistry = (this.MetadataRegistry === undefined) ? bundle_context.getService(MetadataRegistry_Ref) : this.MetadataRegistry; 

        this.Metadata = (this.Metadata === undefined) ? Java.type("org.openhab.core.items.Metadata") : this.Metadata; 

        this.MetadataKey = (this.MetadataKey === undefined) ? Java.type("org.openhab.core.items.MetadataKey") : this.MetadataKey; 

...

var md = MetadataRegistry.get(new MetadataKey(namespace, item));
          if(md === null || md === undefined) {
            return null;
          }
          else if(key === undefined) {
            return md.value;
          }
          else {
            return md.configuration[key];
          }
1 Like

Thanks - translated to Groovy this works:

import org.slf4j.LoggerFactory
import org.openhab.core.items.MetadataKey
import org.osgi.framework.FrameworkUtil
import org.openhab.core.automation.module.script.rulesupport.shared.ScriptedHandler

def getMetadata(namespace, itemName) {
    def _bundle = FrameworkUtil.getBundle(ScriptedHandler.class);
    def bundle_context = _bundle.getBundleContext()
    def metadataRegistry_Ref = bundle_context.getServiceReference("org.openhab.core.items.MetadataRegistry")
    def metadataRegistry = bundle_context.getService(metadataRegistry_Ref)
    return metadataRegistry?.get(new MetadataKey(namespace, itemName))?.configuration
}

def log = LoggerFactory.getLogger('Metadata')
def md = getMetadata('shading', 'Raffstore_Essen_Schiebeture')
log.info("Found metadata travelTimeOpenSeconds is ${md.travelTimeOpenSeconds}")

Wow!

1 Like