How to get REST switch state

Hi,
I am currently trying to integrate program that controls my PC/Desk led lighting via REST. I am trying to achieve this using a command line switch. Here is the config:

switch:
  - platform: command_line
    switches:
      ambilight:
        friendly_name: "Ambilight"
        command_on: curl -X POST http://192.168.1.100:6969/profiles/suspend/de7e6390-c10e-4e4f-9a7b-d69c3982f61f -d "suspend=false" 
        command_off: curl -X POST http://192.168.1.100:6969/profiles/suspend/de7e6390-c10e-4e4f-9a7b-d69c3982f61f -d "suspend=true"

I would like to add a command_state: and value_template: section but I don’t know how to filter the response to make it useable.
Here is the code I’m trying to use:

#This is the command to get the states
curl -X GET http://192.168.1.100:6969/profiles -H 'Content-Type: application/json; charset=utf-8'
#this is the response
[
  {
    "IsBeingEdited" : false,
    "Category" : {
      "Id" : "92f465aa-8708-47bf-9262-691cc120978e",
      "Name" : "General",
      "IsSuspended" : false,
      "Order" : 0,
      "$id" : "2"
    },
    "Id" : "de7e6390-c10e-4e4f-9a7b-d69c3982f61f",
    "$id" : "1",
    "IsActive" : false,
    "Order" : 0,
    "IsSuspended" : true,
    "Name" : "Ambilight",
    "IsMissingModule" : false,
    "HasActivationCondition" : true,
    "ActivationConditionMet" : true
  },
  {
    "IsBeingEdited" : false,
    "Category" : {
      "Id" : "92f465aa-8708-47bf-9262-691cc120978e",
      "Name" : "General",
      "IsSuspended" : false,
      "Order" : 0,
      "$id" : "4"
    },
    "Id" : "9d841a42-255f-46fa-9494-fada1ec685d1",
    "$id" : "3",
    "IsActive" : false,
    "Order" : 1,
    "IsSuspended" : true,
    "Name" : "Rainbow - copy",
    "IsMissingModule" : false,
    "HasActivationCondition" : true,
    "ActivationConditionMet" : false
  },
  {
    "IsBeingEdited" : false,
    "Category" : {
      "Id" : "92f465aa-8708-47bf-9262-691cc120978e",
      "Name" : "General",
      "IsSuspended" : false,
      "Order" : 0,
      "$id" : "6"
    },
    "Id" : "41b207dd-3b5a-4c80-ad59-d0a44a1f40e7",
    "$id" : "5",
    "IsActive" : false,
    "Order" : 2,
    "IsSuspended" : true,
    "Name" : "Noise",
    "IsMissingModule" : false,
    "HasActivationCondition" : true,
    "ActivationConditionMet" : false
  },
  {
    "IsBeingEdited" : false,
    "Category" : {
      "Id" : "92f465aa-8708-47bf-9262-691cc120978e",
      "Name" : "General",
      "IsSuspended" : false,
      "Order" : 0,
      "$id" : "8"
    },
    "Id" : "4f5ecfdf-2cd9-4d68-8a2a-648137715779",
    "$id" : "7",
    "IsActive" : false,
    "Order" : 3,
    "IsSuspended" : true,
    "Name" : "Rainbow",
    "IsMissingModule" : false,
    "HasActivationCondition" : true,
    "ActivationConditionMet" : false
  }
]

I am having trouble figuring out to how to filter the response down to the IsActive or IsSuspended value of the first profile.

Edit:
I have figured out how to get the value I want using a value template. It works in the template editor but when I try and use it in a switch or sensor it returns unknown. Here is the code I am working with currently

sensor:
  - platform: rest
    name: Ambilight
    resource: http://192.168.1.100:6969/profiles
    scan_interval: 5
    value_template: "{{ value_json[0].IsActive }}"

#or

switch:
  - platform: command_line
    switches:
      ambilight:
        friendly_name: "Ambilight"
        command_on: curl -X POST http://192.168.1.100:6969/profiles/suspend/de7e6390-c10e-4e4f-9a7b-d69c3982f61f -d "suspend=false" 
        command_off: curl -X POST http://192.168.1.100:6969/profiles/suspend/de7e6390-c10e-4e4f-9a7b-d69c3982f61f -d "suspend=true"
        command_state: curl -X GET http://192.168.1.100:6969/profiles
        value_template: "{{ value_json[0].IsActive }}"

When I try this ↓ in the template editor I get the correct boolean value. Why doesn’t work in a switch?

{% set value_json = [{"$id":"1","Id":"de7e6390-c10e-4e4f-9a7b-d69c3982f61f","Name":"Ambilight","Order":0,"IsActive":false,"IsSuspended":true,"IsBeingEdited":false,"IsMissingModule":false,"HasActivationCondition":true,"ActivationConditionMet":true,"Category":{"$id":"2","Id":"92f465aa-8708-47bf-9262-691cc120978e","Name":"General","Order":0,"IsSuspended":false}},{"$id":"3","Id":"9d841a42-255f-46fa-9494-fada1ec685d1","Name":"Rainbow - copy","Order":1,"IsActive":false,"IsSuspended":true,"IsBeingEdited":false,"IsMissingModule":false,"HasActivationCondition":true,"ActivationConditionMet":true,"Category":{"$id":"4","Id":"92f465aa-8708-47bf-9262-691cc120978e","Name":"General","Order":0,"IsSuspended":false}},{"$id":"5","Id":"41b207dd-3b5a-4c80-ad59-d0a44a1f40e7","Name":"Noise","Order":2,"IsActive":false,"IsSuspended":true,"IsBeingEdited":false,"IsMissingModule":false,"HasActivationCondition":true,"ActivationConditionMet":false,"Category":{"$id":"6","Id":"92f465aa-8708-47bf-9262-691cc120978e","Name":"General","Order":0,"IsSuspended":false}},{"$id":"7","Id":"4f5ecfdf-2cd9-4d68-8a2a-648137715779","Name":"Rainbow","Order":3,"IsActive":false,"IsSuspended":true,"IsBeingEdited":false,"IsMissingModule":false,"HasActivationCondition":true,"ActivationConditionMet":false,"Category":{"$id":"8","Id":"92f465aa-8708-47bf-9262-691cc120978e","Name":"General","Order":0,"IsSuspended":false}}] %}

{{ value_json[0].IsActive }}

Edit 2:
Checked the logs. Parsing error. Trying to fix.

Error parsing value: 'value_json' is undefined (value: [{"$id":"1","Id":"de7e6390-c10e-4e4f-9a7b-d69c3982f61f","Name":"Ambilight","Order":0,"IsActive":true,"IsSuspended":false,"IsBeingEdited":false,"IsMissingModule":false,"HasActivationCondition":true,"ActivationConditionMet":true,"Category":{"$id":"2","Id":"92f465aa-8708-47bf-9262-691cc120978e","Name":"General","Order":0,"IsSuspended":false}},{"$id":"3","Id":"9d841a42-255f-46fa-9494-fada1ec685d1","Name":"Rainbow - copy","Order":1,"IsActive":false,"IsSuspended":true,"IsBeingEdited":false,"IsMissingModule":false,"HasActivationCondition":true,"ActivationConditionMet":true,"Category":{"$id":"4","Id":"92f465aa-8708-47bf-9262-691cc120978e","Name":"General","Order":0,"IsSuspended":false}},{"$id":"5","Id":"41b207dd-3b5a-4c80-ad59-d0a44a1f40e7","Name":"Noise","Order":2,"IsActive":false,"IsSuspended":true,"IsBeingEdited":false,"IsMissingModule":false,"HasActivationCondition":true,"ActivationConditionMet":false,"Category":{"$id":"6","Id":"92f465aa-8708-47bf-9262-691cc120978e","Name":"General","Order":0,"IsSuspended":false}},{"$id":"7","Id":"4f5ecfdf-2cd9-4d68-8a2a-648137715779","Name":"Rainbow","Order":3,"IsActive":false,"IsSuspended":true,"IsBeingEdited":false,"IsMissingModule":false,"HasActivationCondition":true,"ActivationConditionMet":false,"Category":{"$id":"8","Id":"92f465aa-8708-47bf-9262-691cc120978e","Name":"General","Order":0,"IsSuspended":false}}], template: {{ value_json[0].IsActive }})

Edit 3:
Error is
TemplateSyntaxError: unexpected char '\ufeff' at 20
I suspect this has something to do with utf-8 encoding, I’ve added ↓ to the sensor entry but the error still persists.

      Content-Type: application/json;charset=utf-8
      Accept-encoding: gzip

change that to

Content-Type: application/json;charset=utf-16

The error is still there, here is exactly how I have my YAML set up

sensor:
  - platform: rest
    name: Ambilight
    resource: http://192.168.1.100:6969/profiles
    scan_interval: 5
    headers:
      Content-Type: application/json;charset=utf-16
      Accept-encoding: gzip
    value_template: "{{ value_json[0].IsActive }}"
switch:
  - platform: command_line
    switches:
      ambilight:
        friendly_name: "Ambilight"
        command_on: curl -X POST http://192.168.1.100:6969/profiles/suspend/de7e6390-c10e-4e4f-9a7b-d69c3982f61f -d "suspend=false" 
        command_off: curl -X POST http://192.168.1.100:6969/profiles/suspend/de7e6390-c10e-4e4f-9a7b-d69c3982f61f -d "suspend=true"
        command_state: curl -X GET http://192.168.1.100:6969/profiles -H Content-Type:application/json;charset=utf-16
        value_template: "{{ value_json[0].IsActive }}"

Neither work

Could there be something wrong with the way the application sends the json or is there something wrong with my code?

No, your error is specifically outside the utf-8 character set. It doesn’t recognize a character thats provided in the utf-16 lib. You could also just stop using characters that aren’t ascii. Nothing in that response requires utf-8 let alone utf-16.

When I post the json that I receive by making a get request on my linux PC into a online json parser there are no errors but when I post the json from the home assistant error there is something wrong with the start of the json in the [{"$id":" section.

Yes, but that’s probably because it accepts utf-16

I’m a bit new to this so sorry for the basic questions. Does that mean I should try something like:
Content-Type: application/json;charset=ascii
or just
Content-Type: application/json

edit: both return with a a ZERO WIDTH NO-BREAK SPACE at the start of the json, same as utf-8 and 16

No, the response coming from your endpoint has the encoding. Your rest sensor needs to know the correct encoding in order to use it.

If you force your endpoint to return ascii or you remove the characters that are not utf-8 or utf-16, then everything should work. According to google, the zero’s you’re using are utf-16, so it must be coming from your keyboard or something.

Ok, so from what I am reading online it looks like there is a BOM character at the start of the API call that shouldn’t be there. Is there any way to filter it using my HomeAssistant config so that It can parse the response?

you can try

"{{ (value[0:] | from_json).IsActive }}"

Nope still doesn’t work. Thanks for the help, you’ve helped me pinpoint the issue. I’m going to try and contact the developer of the app and see if he can remove the BOM character at the start of the response.

It might be a few characters long, you could replace the 0 with a 1

Instead of an error or unknown state it now gives a blank state, which is an improvement.
Here is the warning code from the logs:

Template variable warning: 'list object' has no attribute 'IsActive' when rendering '{{ (value[1:] | from_json).IsActive }}'

Edit:
THIS WORKS!

"{{ (value[1:] | from_json)[0].IsActive }}" 

Can you explain what is going on with this value template? How does it ignore the BOM?

Nice, that means it worked.

"{{ (value[1:] | from_json)[0].IsActive }}"

But if you want to select by id…

    value_template: 
      {% set items = value[1:] | from_json %}
      {% set target = items | selectattr('Id','eq', 'de7e6390-c10e-4e4f-9a7b-d69c3982f61f') | first | default({'IsActive': False}) }}
      {{ target.IsActive }}
1 Like

Now if I want to use that sensor as the state value of a command line switch would this command_state config work?

  - platform: command_line
    switches:
      ambilight:
        friendly_name: "Ambilight"
        command_on: curl -X POST http://192.168.1.100:6969/profiles/suspend/de7e6390-c10e-4e4f-9a7b-d69c3982f61f -d "suspend=false" 
        command_off: curl -X POST http://192.168.1.100:6969/profiles/suspend/de7e6390-c10e-4e4f-9a7b-d69c3982f61f -d "suspend=true"
        command_state: sensor.ambilight

No, you’d need to make a template switch

Alright, will do. Thanks for all the help!

Here is the config for anyone trying to make a similar switch in the future.

sensor:
  - platform: rest
    name: Ambilight
    resource: http://192.168.1.100:6969/profiles
    headers:
      Content-Type: application/json; charset=utf-8
      Content-Encoding: gzip
      Vary: Accept-Encoding
    value_template: "{{ (value[1:] | from_json)[0].IsActive }}"

switch:
  - platform: template
    switches:
      ambilight:
        friendly_name: "Ambilight"
        value_template: "{{ states('sensor.ambilight') }}"
        availability_template: "{{ states('sensor.ambilight') != 'unavailable' }}"
        turn_on:
          service: shell_command.ambilight_on
        turn_off:
          service: shell_command.ambilight_off

shell_command:
  ambilight_on: 'curl -X POST http://192.168.1.100:6969/profiles/suspend/de7e6390-c10e-4e4f-9a7b-d69c3982f61f -d "suspend=false"'
  ambilight_off: 'curl -X POST http://192.168.1.100:6969/profiles/suspend/de7e6390-c10e-4e4f-9a7b-d69c3982f61f -d "suspend=true"'
2 Likes

How fast is it? I solved it to transfer rgb values and fire it via event API of HA: