0

Im trying to parse JSON response from my home automation system in javscript. The response is available here

That is only a small part of the response, also, the order of keys changes on every reboot for reasons i do not know, su using the the number index wont really work i need to be able to store the state value of sensor.out, sensor.in, sensor.door into variables for tasker on andorid i tried to select using the entity.id, but for some reason the code never finished ( i believe i just didnt know what i was doing)

3 Answers3

1

With ES6 you can use the Array#find method:

response.find(o => o.entity_id == 'sensor.out').state

See snippet:

var response = [ { "attributes":{ "friendly_name":"door" }, "entity_id":"sensor.door", "last_changed":"2016-12-31T11:15:59.395808+00:00", "last_updated":"2016-12-31T11:15:59.395808+00:00", "state":"closed" }, { "attributes":{ "friendly_name":"In", "unit_of_measurement":"\u00b0C" }, "entity_id":"sensor.in", "last_changed":"2016-12-31T11:20:02.179821+00:00", "last_updated":"2016-12-31T11:20:02.179821+00:00", "state":"20.7" }, { "attributes":{ "changed_by":null, "code_format":".+", "friendly_name":"panel" }, "entity_id":"alarm_control_panel.panel", "last_changed":"2016-12-31T11:14:56.471966+00:00", "last_updated":"2016-12-31T11:14:56.471966+00:00", "state":"disarmed" }, { "attributes":{ "friendly_name":"Out", "unit_of_measurement":"\u00b0C" }, "entity_id":"sensor.out", "last_changed":"2016-12-31T11:14:58.452345+00:00", "last_updated":"2016-12-31T11:14:58.452345+00:00", "state":"7.1" }];
var state = response.find(o => o.entity_id == 'sensor.out').state;
console.log('sensor.out state is', state);

Alternatively, you could convert the response to an object with the entity id values as keys, so you can access it like response['session.out'].state:

response = Object.assign({}, ...response.map( o => ({[o.entity_id]: o}) ));

See snippet:

var response = [ { "attributes":{ "friendly_name":"door" }, "entity_id":"sensor.door", "last_changed":"2016-12-31T11:15:59.395808+00:00", "last_updated":"2016-12-31T11:15:59.395808+00:00", "state":"closed" }, { "attributes":{ "friendly_name":"In", "unit_of_measurement":"\u00b0C" }, "entity_id":"sensor.in", "last_changed":"2016-12-31T11:20:02.179821+00:00", "last_updated":"2016-12-31T11:20:02.179821+00:00", "state":"20.7" }, { "attributes":{ "changed_by":null, "code_format":".+", "friendly_name":"panel" }, "entity_id":"alarm_control_panel.panel", "last_changed":"2016-12-31T11:14:56.471966+00:00", "last_updated":"2016-12-31T11:14:56.471966+00:00", "state":"disarmed" }, { "attributes":{ "friendly_name":"Out", "unit_of_measurement":"\u00b0C" }, "entity_id":"sensor.out", "last_changed":"2016-12-31T11:14:58.452345+00:00", "last_updated":"2016-12-31T11:14:58.452345+00:00", "state":"7.1" }];
response = Object.assign({}, ...response.map( o => ({[o.entity_id]: o}) ));
console.log('sensor.out state is', response['sensor.out'].state);
trincot
  • 317,000
  • 35
  • 244
  • 286
0

If you're trying to uses indexes to select properties from objects, you shouldn't be, unless there is a very specific reason to do so.

Fortunately that's fine, you don't need to know the order. I took two of the objects from your JSON array, scrambled up the properties, and wrote a function that returns any object that contains the key/val you specify.

Your question is a little hard to follow, but I think this will give you the idea.

<script type="text/javascript">
let arr = [
  {
    "attributes":{
      "friendly_name":"door"
    },
    "entity_id":"sensor.frontdoor",
    "last_changed":"2016-12-31T11:15:59.395808+00:00",
    "last_updated":"2016-12-31T11:15:59.395808+00:00",
    "state":"closed"
  },
  {
    "last_changed":"2016-12-31T11:15:59.395808+00:00",
    "state":"closed",
    "attributes":{
      "friendly_name":"door"
    },
    "entity_id":"sensor.backdoor",
    "last_updated":"2016-12-31T11:15:59.395808+00:00"
  }
];

function findKey ( theKey, theVal ) {
  let reduced = arr.filter ( d => {
    return d [ theKey ] === theVal;
  });

  return reduced;
}

let targets = findKey ( 'entity_id', 'sensor.backdoor' );
targets.forEach ( d => {
   // This check is a little naive, but should give you the idea
   if ( 'state' in d ) {
      console.log ( d.state );
   }
} );
</script>
Tim Consolazio
  • 4,802
  • 2
  • 19
  • 28
  • how should i use that to get the state value of specific entity_id? – Arttu Mahlakaarto Dec 31 '16 at 12:07
  • Hmm, you mean like, if you wanted the "state" value from whatever obj contained entity_id : sensor.backdoor? – Tim Consolazio Dec 31 '16 at 12:13
  • I edited the function such that it will now return any object that contains the key/val you specify. You can just loop through the returned array for the state vals. Note that you should ensure the returned object actually has a state value (even if you believe it always will) before you try to access it. – Tim Consolazio Dec 31 '16 at 12:19
  • 1 more problem i noticed, i cant use console log, as i need to save it to a variable , i have to save sensor.in to var tempin and out to tempout etc – Arttu Mahlakaarto Dec 31 '16 at 12:35
  • console.log just shows you how to access the value. I wouldn't expect you to use that in your code. You can set whatever variables you need to, for example, "myVar = d.state". – Tim Consolazio Dec 31 '16 at 14:14
0

What everyone says is correct: The order of keys in the response doesn't matter. Use the (string) key, not a numerical index.

var arr = [
  {
    "entity_id":"sensor.door",
    "state":"closed"
  }];   // other attributes chopped out for brevity

var entity_id_interested_in = 'sensor.door';
var state = '[entity_id not found in response]';
for (var i = 0; i < arr.length; i++) {

    console.log(arr[i].entity_id + ' state:' + arr[i].state);
    if (arr[i].entity_id == entity_id_interested_in)
    {
       state = arr[i].state;
       break;
    }
}
console.log (state);
Edward D
  • 521
  • 3
  • 9