[SOLVED] Simplifying Javascript from http return through Json

  • Platform information:
    • Hardware: Intel NUC clone
    • OS: Debian Stretch on Virtualbox
    • Java Runtime Environment: Zulu 8 (build 25.192-b01)
    • openHAB version: Snapshot #1549

I’m getting several Strings through Json from my heating boiler and process them through Javascript code thanks to @opus post here:

Is it possible to make the Javascript more generic as now I need 14 scripts to process my 14 items:

Json return for first item, all are similar (unit is the string of interest):

{
  "500": {
    "name": "Mo",
    "value": "1.",
    "unit": "05:20 - 22:30 2. --:-- - --:-- 3. --:-- - --:--",
    "desc": "",
    "dataType": 5
  }
}

items:

String BSBLAN_Mo_Start (gHeatingTimes) { http="<[http://192.168.2.150/JQ=500:3600000:JS(500_start.js)]" }
String BSBLAN_Mo_End (gHeatingTimes)  { http="<[http://192.168.2.150/JQ=500:3600000:JS(500_end.js)]" }
String BSBLAN_Di_Start (gHeatingTimes)  { http="<[http://192.168.2.150/JQ=501:3600000:JS(501_start.js)]" }
String BSBLAN_Di_End  (gHeatingTimes) { http="<[http://192.168.2.150/JQ=501:3600000:JS(501_end.js)]" }
...
String BSBLAN_So_Start (gHeatingTimes)  { http="<[http://192.168.2.150/JQ=506:3600000:JS(506_start.js)]" }
String BSBLAN_So_End (gHeatingTimes)  { http="<[http://192.168.2.150/JQ=506:3600000:JS(506_end.js)]" }

Javascript for first and second string item (all are similar):
/transform/500_start.js

(function(i) {
    var version =JSON.parse(i)[500].unit;
    return version.substring(0,5);
})(input)

/transform/500_end.js

 (function(i) {
    var version =JSON.parse(i)[500].unit;
    return version.substring(8,13);
})(input)

Javascript for third and fourth string item:
/transform/501_start.js

(function(i) {
    var version =JSON.parse(i)[501].unit;
    return version.substring(0,5);
})(input)

/transform/501_end.js

 (function(i) {
    var version =JSON.parse(i)[501].unit;
    return version.substring(8,13);
})(input)

It would be great to reduce the number of scripts from 14 to just 2 :grinning:

Can’t test ATM, but wouldn’t something like this work?

(function(i,j,k,l) {
    var version =JSON.parse(i)[j].unit;
    return version.substring(k,l);
})(input)

Thank you very much for looking at this. Unfortunately it throws an error:

2019-04-15 08:29:23.941 [WARN ] [ab.binding.http.internal.HttpBinding] - Transformation 'JS(500_start.js)' threw an exception. [response={
  "500": {
    "name": "Mo",
    "value": "1.",
    "unit": "05:20 - 22:30 2. --:-- - --:-- 3. --:-- - --:--",
    "desc": "",
    "dataType": 5
  }
}
]
org.openhab.core.transform.TransformationException: An error occurred while executing script. TypeError: Cannot read property "unit" from undefined in <eval> at line number 2
	at org.openhab.core.transform.TransformationHelper$TransformationServiceDelegate.transform(TransformationHelper.java:71) ~[206:org.openhab.core.compat1x:2.5.0.201903021540]
	at org.openhab.binding.http.internal.HttpBinding.execute(HttpBinding.java:194) [241:org.openhab.binding.http:1.14.0.201904020715]
	at org.openhab.core.binding.AbstractActiveBinding$BindingActiveService.execute(AbstractActiveBinding.java:148) [206:org.openhab.core.compat1x:2.5.0.201903021540]
	at org.openhab.core.service.AbstractActiveService$RefreshThread.run(AbstractActiveService.java:170) [206:org.openhab.core.compat1x:2.5.0.201903021540]

As everything works with the 14 scripts nothing is time critical here :grinning:

How would you intend to send the additional parameters in this case? The JS transform doesn’t allow for that, does it?

My take on this, assuming you get only one entry upon your request (so if you request 500 in the url, you only get 500 as result, and if you request 501, you only get 501 returned), would be to have one “start” script and one “end script”:

start.js

(function(i) {
    var obj=JSON.parse(i);
    return obj[Object.keys(obj)[0]].unit.substring(0,5);
})(input)

end.js

(function(i) {
    var obj=JSON.parse(i);
    return obj[Object.keys(obj)[0]].unit.substring(8,13);
})(input)
1 Like

Yes, correct.

Brilliant, from a quick test it did work for today’s weekday Monday, will report back tomorrow for Tuesday.
Thanks a lot (I promise to improve my script skills).

Again, thanks a lot, it’s also working for Tuesday so I guess it will also work for all the other days :grinning:
Also big thanks to @opus for the initial script which made this possible at all.