Get all values through REST API

Posted on
Sat Jan 25, 2020 8:29 am
davinci offline

Get all values through REST API

I want to use some variables and device states inside an html.

Of course I could just get all the individual values separately, but I think it makes sense to get them all at once - but only the ones I care (e.g. no type, but only value).

How can I do this?


What I imagine is something like this:
Response from calling REST API
Code: Select all
LightKitchen:0
LightBasement:50
Door:false
ValueVariable:"test"


Like this I can set these variables in JavaScript and update them if needed. This will save me lots of traffic and time to get all values.

Alternatively how can I get only the value in the response?
/variables/isDaylight/value

Response:
true

Posted on
Sat Jan 25, 2020 12:42 pm
matt (support) offline
Site Admin
User avatar
Posts: 21411
Joined: Jan 27, 2003
Location: Texas

Re: Get all values through REST API

That isn't current possible through Indigo's existing RESTful API. The wiki page has pretty much all of the current examples/capabilities documented. We have plans on a big overhaul of Indigo's Web Server which will include an improved RESTful API.

For cases where you have specific needs you might want to consider creating either a plugin, or executing an Indigo script periodically that writes out (to XML, etc.) the data you need. Both of those (plugin and script) would have complete access to Indigo's Python API which can quickly fetch the information you need.

Image

Posted on
Sat Jan 25, 2020 3:46 pm
davinci offline

Re: Get all values through REST API

Thanks, I will try the Python Script in that case. However , I use the reflector to access the data. I might be able to store all the values into one variable. Is there a limit to variable size?

Posted on
Sat Jan 25, 2020 4:08 pm
matt (support) offline
Site Admin
User avatar
Posts: 21411
Joined: Jan 27, 2003
Location: Texas

Re: Get all values through REST API

I don't believe so but I'm not sure that large values have been stress tested. :roll: Let us know if you run into problems.

Image

Posted on
Sun Jan 26, 2020 2:44 am
davinci offline

Re: Get all values through REST API

Cool, no issues so far with over 9000 characters. :D

For reference, this would be the JS side - not sure if it already works with authentication: https://github.com/inorganik/digest-auth-request

Untested code
Code: Select all
function updateIndigo() {

    var url = 'URL/variables/test.json';
    var getRequest = new digestAuthRequest('GET', url, USER, PWD);
    getRequest.request(function(data) {
      // success callback
                       var obj=data;
    },function(errorCode) {
      // error callback
    });
        //var obj = JSON.parse( '{ "value": "John:1;Mike:2" }' );
        valueArray=obj.value;
        valueArray = valueArray.split(";");
        lengthArray = valueArray.length;

        var jsonText = {};

        for (var i = 0; i < lengthArray; i++) {
            variableArray = valueArray[i].split(":");
            setName = variableArray[0];
            setValue = variableArray[1];
            jsonText[setName] = setValue;

            }

        alert(jsonText["John"]);

}


Now I need to tackle the Python side. Is it ok to write status every second in the variable or do you suggest to do it on demand? Would you use Schedule or just have one python script running forever?
I think it is more efficient to do it every second, since the variables might change more often than this. Hence a group trigger would trigger this too often.

The goal is to get this string:
LightKitchen:true;TemperatureKitchen:22.1;LightBasement:50

Something like this might be a start for variables:
Code: Select all

bigVariable = ""

#Variables
id = [794830341, 794830341]
lengthArray = len(id)
for x in range(0, lengthArray):
    value = indigo.variables[id[x]].value
    name = indigo.variables[id[x]].name
    bigVariable = bigVariable + name + ':' + value +';'

#Switches
id = [794830341, 794830341]
lengthArray = len(id)
for x in range(0, lengthArray):
    value = indigo.variables[id[x]].value
    name = indigo.variables[id[x]].name
    bigVariable = bigVariable + name + ':' + value +';'

#Brightness devices
id = [794830341, 794830341]
lengthArray = len(id)
for x in range(0, lengthArray):
    value = indigo.variables[id[x]].value
    name = indigo.variables[id[x]].name
    bigVariable = bigVariable + name + ':' + value +';'

indigo.variable.updateValue(1603257068, bigVariable)
indigo.server.log(bigVariable)




The name ist the name of variable or the device. The value is either value or brightness, ...

How can I get all the ids for a specific device or variable?

Posted on
Sun Jan 26, 2020 4:26 am
howartp offline
Posts: 4559
Joined: Jan 09, 2014
Location: West Yorkshire, UK

Re: Get all values through REST API

Trigger on a separate dedicated variable called ‘doRefresh’

When you visit your http page, use API to increment that variable so that the trigger fires and runs python script.


Sent from my iPhone using Tapatalk Pro

Posted on
Sun Jan 26, 2020 9:36 am
davinci offline

Re: Get all values through REST API

Good idea to trigger like that. I have to test if this is fast enough though or if it triggers the old results.

Here is what I have so far. Unfortunately I get an error on virtual devices and real devices when accessing the value: KeyError: 'key id 170781720 not found in database'
Any ideas why this happens?

Second problem ü is not saved correctly...

Code: Select all
bigVariable = ""

#Variables

id = []
for var in indigo.variables:
    if var.id != 1603257068: #this variable
        id.append(var.id)
lengthArray = len(id)
for x in range(0, lengthArray):
    value = indigo.variables[id[x]].value
    name = indigo.variables[id[x]].name
    bigVariable = bigVariable + name + ':' + value +';'



#Switches
id = []
for var in indigo.devices:
    if var.enabled and u"onOffState" in var.states:
        id.append(var.id)

lengthArray = len(id)
for x in range(0, lengthArray):
    value = indigo.variables[id[x]].value
    name = indigo.variables[id[x]].name
    bigVariable = bigVariable + name + ':' + value +';'





#Brightness devices
id = []
for var in indigo.devices:
    if var.enabled and u"brightnessLevel" in var.states:
        id.append(var.id)

lengthArray = len(id)
for x in range(0, lengthArray):
    value = indigo.variables[id[x]].value
    name = indigo.variables[id[x]].name
    bigVariable = bigVariable + name + ':' + value +';'



indigo.variable.updateValue(1603257068, bigVariable)
indigo.server.log(bigVariable)

Posted on
Sun Jan 26, 2020 12:06 pm
howartp offline
Posts: 4559
Joined: Jan 09, 2014
Location: West Yorkshire, UK

Re: Get all values through REST API

For your switches and brightness devices, you’re still accessing indigo.variables[].value - you’ve not changed it to indigo.devices[].value or the appropriate code thereof.


Sent from my iPhone using Tapatalk Pro

Posted on
Sun Jan 26, 2020 12:48 pm
davinci offline

Re: Get all values through REST API

Good catch, thanks. It works now.

When accessing REST API over json "Umlaute" like äöü are not shown correctly. They are ok when not using .json.
I guess I will have to translate this in JS.

Posted on
Sun Jan 26, 2020 5:50 pm
jay (support) offline
Site Admin
User avatar
Posts: 18200
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Get all values through REST API

We'll look into that - it's likely a bug.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Mon Jan 27, 2020 11:45 am
jay (support) offline
Site Admin
User avatar
Posts: 18200
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Get all values through REST API

davinci wrote:
Good catch, thanks. It works now.

When accessing REST API over json "Umlaute" like äöü are not shown correctly. They are ok when not using .json.
I guess I will have to translate this in JS.


Can you be more specific about this?

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Mon Jan 27, 2020 11:54 am
davinci offline

Re: Get all values through REST API

I have a workaround for this:
Code: Select all
        valueArray = valueArray.replace(/[\u00e4]/g, 'ä').replace(/[\u00F6]/g, 'ö').replace(/[\u00fc]/g, 'ü');


However, the authentication doesn't work...

https://github.com/inorganik/digest-auth-request

Is this Indigo-related?

Code: Select all
    var getRequest = new digestAuthRequest('GET', urlIndigo + "variables/UpdateIndigo.json", user, password);
    getRequest.request(function(data) {
                       var obj=data;
    },function(errorCode) {
      // error callback
    });

Posted on
Mon Jan 27, 2020 11:57 am
davinci offline

Re: Get all values through REST API

When opening the json url in a browser I get B\u00fcro instead of Büro.

What I read about this ist, that this is a normal behavior for json, but there is a setting to change that..

Posted on
Mon Jan 27, 2020 2:41 pm
jay (support) offline
Site Admin
User avatar
Posts: 18200
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Get all values through REST API

davinci wrote:
However, the authentication doesn't work...

https://github.com/inorganik/digest-auth-request

Is this Indigo-related?

Code: Select all
    var getRequest = new digestAuthRequest('GET', urlIndigo + "variables/UpdateIndigo.json", user, password);
    getRequest.request(function(data) {
                       var obj=data;
    },function(errorCode) {
      // error callback
    });


I have no idea what that JavaScript does as I'm not a JavaScript expert. The Python requests library, which supports Digest Authentication, works fine (as do all browsers and the curl command), so I'm guessing there's something going on in the JavaScript.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Mon Jan 27, 2020 2:42 pm
jay (support) offline
Site Admin
User avatar
Posts: 18200
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Get all values through REST API

davinci wrote:
When opening the json url in a browser I get B\u00fcro instead of Büro.

What I read about this ist, that this is a normal behavior for json, but there is a setting to change that..


Yes - that's standard ASCII encoding for unicode characters. JavaScript should correctly convert those when converting JSON to JavaScript objects, though again since I'm not a JavaScript expert I don't know where to kick it to make it work.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Who is online

Users browsing this forum: No registered users and 26 guests