Type Error with JavaScript Scripting ECMAScript 2022+

Hello,

I am new to JavaScript Scripting in OH. I thought I give it a try, however I did not figure it out yet.

I am trying to map the dynamic prices from every hour of tibber to own items using JavaScript Scripting. This is my simple code:

var runtime = require('@runtime');
var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' +ctx.ruleUID);
var cost = (runtime.itemRegistry.getItem("Tibber_API_Prices_for_today_as_a_JSON_array").getState()).toString();

var i=0;
while(i<24)
{
  var name="hourly_cost_"+i.toString();
  var key=runtime.itemRegistry.getItem(name);
  
  logger.info("Item Name: "+key.getName());
  logger.info("Item State: "+key.getState());
  logger.info("i: "+i.toString());
  var expr="$.["+i.toString()+"].total";
  logger.info("Expr: "+expr.toString());
  
  var hourlyCost=actions.Transformation.transform("JSONPATH",expr.toString(),cost);
  logger.info("Hourly cost: "+hourlyCost);
  key.sendCommand(hourlyCost); 
  i=i+1;
}

When I am trying to update the item I get the following error

TypeError: invokeMember (sendCommand) on org.openhab.core.library.items.NumberItem@1e70dd5 failed due to: Unknown identifier: sendCommand

What do I do wrong here?

You have a several lines of this code that are from older versions of javascript rules, and as result you are working with a mixture of javascript and actual java objects.

What version of OH are you running and which Javascript add-on have you installed?

Thx.

I am running OH4.3 and I have installed:

The script itself is defined asECMAScript (ECMAScript 262 Edition1 11)

What do I have to change?

That’s all good. In that case it’s the code you have to change.

You don’t need this. This is from very early versions before the current javascript helper library was fully mature. With your up-to-date versions of the add-on and OH you will almost never need this line.

When you do this, you are getting access to the underlying java object item, not a javasacript version of it. This is where the real issue arises.

All you need to do to get access to a javascript version of an item is:

items.getItem("Tibber_API_Prices_for_today_as_a_JSON_array")

or even just

items.Tibber_API_Prices_for_today_as_a_JSON_array

getState will still work exactly the same way (but it will return javascript types) and the item will have the sendCommand method so you won’t get the error you are seeing at the end of the script.

Here’s a link to the javascript helper library docs. This is extremely helpful when you are just starting out with the jsscripting rules:

https://openhab.github.io/openhab-js/index.html

Another little note: You don’t need toString() on all your calls of your expr variable. It is already a string by its definition.

1 Like

Thanks a lot. This was pushing me into the right direction. Have a nice Christmas :slight_smile:

It works partly. However, I am loosing the transformation of JSONPath now.

This is my code now:

console.loggerName = 'org.openhab.custom';
var cost =items.getItem("Tibber_API_Prices_for_today_as_a_JSON_array").toString();

var i=0;
while(i<24)
{
  var name="hourly_cost_"+i.toString();
  var key=items.getItem(name);
  
  console.log("Item Name: "+key.name);
  console.log("Item State: "+key.state);
  console.log("i: "+i.toString());
  var expr="$.["+i.toString()+"].total";
  console.log("Expr: "+expr);
  
  var hourlyCost=actions.Transformation.transform("JSONPATH",expr,cost);
  console.log("Hourly cost: "+hourlyCost);
  key.sendCommand(hourlyCost); 
  i=i+1;
}

The code itself runs, however the JSONPath transformation is not happening. Do I need to include something to get it running?

You are not transforming the correct thing. If you log your cost variable as currently written, I suspect you willl find that it is '[object object]' which is not what you expect. When you define cost

you are getting the whole javascript item object, not the state of the item (which I’m guessing is what you want) and then calling toString on the item object.

Instead, you just want:

var cost =items.getItem("Tibber_API_Prices_for_today_as_a_JSON_array").state;

which will automatically give you the string version of the item’s state.

Just for good measure, of course, you also have to make sure that you have installed the JSONPath add-on.

1 Like

That was correct. The

.state

made the difference.

Thanks a lot