JS API response difference between z-Way 1.x and 2.x

Discussions about Z-Way software and Z-Wave technology in general
Post Reply
droll
Posts: 48
Joined: 20 Dec 2013 01:37

JS API response difference between z-Way 1.x and 2.x

Post by droll »

Hello,
Javascript functions accessed via the JS API may return different responses with z-Way 1.x and 2.x. While the z-Way 1.x JS API recognizes correctly that a function result is an array, the z-Way 2.x JS API has sometimes some troubles, as the following examples are showing. Custom functions accessed via the JS API are used in the following sections.

Let's start with the example that that has different results for the two major z-Way versions:

Code: Select all

Get_TestArray1 = function() {
	var ThreeVal = [65,66,67];
	return ThreeVal;
}
The results are:
* z-Way 2.x: ABC <- This seems be an bug in the JS API!
* z-Way 1.x: [65,66,67]
z-Way 2.x seems to consider the values as ASCII characters that concatenated together to a string (ASCII(65)='A').

From the moment that a single array element cannot be considered anymore as ASCII characters (e.g. element is an integer between 0 and 255) a proper array is returned. For example, all elements are strings:

Code: Select all

Get_TestArray2 = function() {
	var ThreeVal = ["65","66","67"];
	return ThreeVal;
}
The results are:
* z-Way 2.x: ["65","66","67"]
* z-Way 1.x: ["65","66","67"]

Z-Way 2.x returns also an array if one of the element is a double:

Code: Select all

Get_TestArray3 = function() {
	var ThreeVal = [65.1,66,67];
	return ThreeVal;
}
The results are:
* z-Way 2.x: [65.1,66,67]
* z-Way 1.x: [65.1,66,67]

The following example show that also a value above 255 "forces" the JS API to return an array:

Code: Select all

Get_TestArray4 = function() {
	var ThreeVal = [265,66,67];
	return ThreeVal;
}
The results are:
* z-Way 2.x: [265,66,67]
* z-Way 1.x: [265,66,67]

And here is a final array example that uses as final array element an empty string:

Code: Select all

Get_TestArray5 = function() {
	var ThreeVal = new Array(65,66,67,"");
	return ThreeVal;
}
The results are:
* z-Way 2.x: [65,66,67,""]
* z-Way 1.x: [65,66,67,""]

Scalar results are not translated into an ASCII char, as the following example shows:

Code: Select all

Get_TestScalar = function() {
	return 65;
}
The results are:
* z-Way 2.x: 65
* z-Way 1.x: 65

The following z-Way version have been used for the above examples:
* 1.x: 1.4, 1.5, 1.7
* 2.x: 2.01-RC6

Let's hope that this obvious bug of the JS API is fixed soon!
pofs
Posts: 688
Joined: 25 Mar 2011 19:03

Re: JS API response difference between z-Way 1.x and 2.x

Post by pofs »

Cannot reproduce your issue.

I've added the following UserCode block:

Code: Select all

Get_TestArray1 = function() {
   var ThreeVal = [65,66,67];
   return ThreeVal;
}
ws.allowExternalAccess("Get_TestArray1");
And it works as expected:

Code: Select all

user# curl -v http://127.0.0.1:8083/Get_TestArray1
* About to connect() to 127.0.0.1 port 8083 (#0)
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8083 (#0)
> GET /Get_TestArray1 HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 127.0.0.1:8083
> Accept: */*
> 
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true
< Connection: keep-alive
< Content-Length: 10
< Content-Type: application/json
< Transfer-Encoding: chunked
< 
* Connection #0 to host 127.0.0.1 left intact
[65,66,67]
Though I'm on a Mac, it shouldn't make much difference compared to RPi. When the function returns not a http-like response, it is just blindly JSON.stringify()-ed with a built-in v8 function. There's no ascii/non-ascii checks there.
pofs
Posts: 688
Joined: 25 Mar 2011 19:03

Re: JS API response difference between z-Way 1.x and 2.x

Post by pofs »

Oh, I think I get it. You're running it with /JS/Run, aren't you?

JS Run internally returns a http-like object with eval() result, so it does perform some checks.
For example, it prefers binary encoding to JSON in case the result is an array with integers in range from 0 to 255 (so you can return binary data). You can either manually wrap your response in JSON.stringify(), or stop using /JS/Run and use direct calls instead.

It is an expected behavior in 2.0 and likely not gonna be changed. We may remove this feature from /JS/Run handler, but the rest of code should respect new rules.
droll
Posts: 48
Joined: 20 Dec 2013 01:37

Re: JS API response difference between z-Way 1.x and 2.x

Post by droll »

Sorry for not being sufficiently precise in my description; But yes, I am using /JS/Run as this is described in the Z-Way Developer Documentation (version 2, sections 1.3.3 and 3). The URL to call the function is therefore:

Code: Select all

http://192.168.1.21:8083/JS/Run/Get_TestArray1()
Please reconsider the way the JS API prefers binary encoding of arrays! It's in my point of view not practical at all that the result type depends on the array element values! (e.g. [165,166,167] returns a string, [265,266,267] returns an array)

I am looking for a way to call JS functions that works and behaves identically between z-Way 1.x and 2.x. Calling JS/Run and JSON.stringify in the function leads on z-Way 2.x indeed to the expected result, but unfortunately z-Way 1.x behaves again slightly differently:

Code: Select all

Get_TestArray6 = function() {
	var ThreeVal = [65,66,67];
	return JSON.stringify(ThreeVal);
}
Results:
* z-Way 1.x: "[65,66,67]"
* z-Way 2.x: [65,66,67]

Using a direct call works on z-Way 2.x, but is unfortunately not supported on z-Way 1.x. Another problem I see with direct calls is the handling of the function arguments. It is very convenient to call functions via the JS API (JS/Run), the function arguments can be provided in a JS-like syntax. With direct calls I was not able to figure out the way arguments need to be provided to the functions (e.g. array arguments). It would be great to have some URL examples in the documentation that shows how function are called directly (including the way arguments have to be provided).

PS: The 'ws.' prefix for the allowExternalAccess command is missing in the documentation.
pz1
Posts: 2053
Joined: 08 Apr 2012 13:44

Re: JS API response difference between z-Way 1.x and 2.x

Post by pz1 »

droll wrote:I am looking for a way to call JS functions that works and behaves identically between z-Way 1.x and 2.x.
Just out of curiosity: Why do you need to continue using both releases 1.x and 2.x?
Since 29-12-2016 I am no longer a moderator for this forum
droll
Posts: 48
Joined: 20 Dec 2013 01:37

Re: JS API response difference between z-Way 1.x and 2.x

Post by droll »

Good question! Once it is fully validated that my system works with z-Way 2.x there should be nothing that blocks my from switching definitively to the new version. But for the moment I have still some issues with the alarm command that behaves differently between 1.x and 2.x. I encountered also HTTP communication issues with 1.7 (viewtopic.php?f=3422&t=20397), so I want to validate first that really everything works with 2.x before I switch definitively. Until this validation happened I have to switch between the versions.
pz1
Posts: 2053
Joined: 08 Apr 2012 13:44

Re: JS API response difference between z-Way 1.x and 2.x

Post by pz1 »

Thanks, now I understand. You do make calls to the raspberry from a client applications that you have to change with every change on the RaZberry side. Since version 1.3, I tried to avoid such problems with what is now called OpenRemoteHelpers (formerly RaZ-OR). It is a simplified restricted API, which use is not restricted to OpenRemote only. Over time I had my hardships with that as well :)
Good luck with your app
Since 29-12-2016 I am no longer a moderator for this forum
Post Reply