Is it possible to use global/persistent variable in a JavaScript Transform function

The title says it all.
But to be clear, if I have for example a HTTP Thing with channel definition like this:

Type string : gldState "Garage Door State" [ stateExtension="input.cgi", stateTransformation="JS:gldTransform.js" ]

Is there any way to implement a global/persistent variable in gldTransform.js, i.e. to keep its value between calls.

Thanks

You could use an item and call that each time

How do you do that from a Transform function? Example please?

This is an example in the docs

const thingStatusInfo = actions.Things.getThingStatusInfo("zwave:serial_zstick:512");
console.log("Thing status",thingStatusInfo.getStatus());

That won’t work from a transformation function. I am pretty sure that the transform only uses Nashorn, not JS Scripting.

I think it might be possible to get at the item registry from a transformation. But it’s going to take some doing. In the end you might be better off processing this from a rule instead of a transformation. Link a String Item to the Channel without any transformation. Create a rule triggered when that Item receives an update and do the parsing in that rule. Items are easy to get at in a rule.

Anyway, from a transformation I think something like the following might work to get access to the Item Registry.

  // Get the reference to the Item Registry
  var FrameworkUtil = Java.type("org.osgi.framework.FrameworkUtil");
  var _bundle = FrameworkUtil.getBundle(scriptExtension.class);
  var bundle_context = _bundle.getBundleContext()
  var ItemRegistry_Ref = bundle_context.getServiceReference("org.openhab.core.items.ItemRegistry");
  var ItemRegistry = bundle_context.getService(ItemRegistry_Ref);

  // Use the Item Registry
  var myItem = ItemRegistry.getItem('name');
2 Likes

Transformations were always intended to be isolated, that’s why its called “transformation” and not “general purpose scripting” i.e.
single value in -> transformation -> single value out

1 Like

Thanks guys. Doesn’t help much, but thanks :slightly_smiling_face:

My question was is there any way to use persistent variable in transformation JS, not how to access Items and Things (which obviously needs a “hack” - thanks Rich, good tip :slightly_smiling_face:).

Persistent var won’t violate “transformation isolation” rule… It still runs in isolation, but keeps its value in between calls. That’s what I need. And there a million reasons why would you need that.

As for single value in or single value out - this of course is not entirely true. You can pass multiple arguments to a transformation JS function like this:

stateTransformation="JS:gldTransform.js?op1=PARM1&op2=PARM2"

and then your JS would be:

(function(i, op1, op2) {
   .....
})(input, op1, op2)

This gives you freedom to use one transformation function in multiple channels.

But you gonna need persistence…

Which doesn’t exist. That’s why we’ve gone through the effort to show how to access an Item’s state. Every time you run the transformation it’s a clean slate so the only thing you can do is use an Item.

Transformations were never designed to be stateful. That’s what rules are for (and even there there is some debate on how stateful rules should be from one run to the next among some of the developers).

Ultimately this is an XY Problem. You’ve decided that there is only one acceptable approach and any solution that gets you to the same end goal that deviates isn’t right. So despite the fact that you think it doesn’t “help much”, it’s the best we can offer.

Of course there are other solutions Rich. If anything, I am not ungrateful for your help guys. You are the authorities here. It’s much appreciated (learning something new every day :slightly_smiling_face: ).

The JS trasnform approach was working best for me, but apparently I’d have to think of something else. Probably will go with rules…

My innocent question was really, is there any way to define state persistent variables in transformation JavaScript, which I didn’t know of (docos say nothing). Apparently there isn’t. It’s stateless. I got it. So moving onto something else.

Thanks again.

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.