HA Switch to turn ON/OFF motion detection on my IP Cameras

Hi guys,
I’m trying to accomplish a simple task: I want to create some On/Off Switches that are sending .xml files to my IPCams.
The commands I need to send to the camera are as follows:

  • action:Turn ON PIR Sensor; run command: curl -T /config/PIR_Sensor_ON.xml http://:@<IPCam_IP_Address>/ISAPI/WLAlarm/PIR
  • action:Turn OFF PIR Sensor; run command: curl -T /config/PIR_Sensor_ON.xml http://:@<IPCam_IP_Address>/ISAPI/WLAlarm/PIR
    To get the current status of the PIR Sensor: curl -X GET http://:@<IPCam_IP_Address>/ISAPI/WLAlarm/PIR
    where I need to filter the output that looks like this:
    _<?xml version="1.0" encoding="UTF-8"?>_
    _<PIRAlarm version="1.0" xmlns="http://www.hikvision.com/ver10/XMLSchema">_
    _<enabled>**true**</enabled>_
    _<name>PIR Alarm</name>_
    _</PIRAlarm>_

Thanks a lot for your help

You need a command line switch

Thanks GP,
I’ve tried the following command switch:

Invalid config for [switch.command_line]: expected a dictionary for dictionary value @ data[‘switches’][‘command_off’]. Got ‘curl -T /config/PIR_Sensor_OFF.xml http://user:pass@IP/ISAPI/WLAlarm/PIR

Please format your configuration snippet according to the instructions in the big blue box at the top of the post.

Your syntax error may well be an indentation problem that nobody can diagnose without you doing this.

@GP: thanks, you are right - I’ve been missing some spaces in the config. Now, when I check the config, everything looks ok from the syntax point of view.
The problem is that the switch is always on, no matter how the PIR Sensor is set on the camera.
Any idea how can I filter the output of the command “curl -X GET http://user:pass@IP/ISAPI/WLAlarm/PIR” ?
The output looks like this:

core-ssh:/usr/bin# curl -X GET http://user:pass@IP/ISAPI/WLAlarm/PIR
?xml version="1.0" encoding="UTF-8"?>
<PIRAlarm version="1.0" xmlns="http://www.hikvision.com/ver10/XMLSchema">
<enabled>false</enabled>
<name>PIR Alarm</name>
</PIRAlarm>

which means PIR is OFF in this case (that “false” line)

You need to write a template to extract the field between the tags. Unfortunately, HA doesn’t handle xml tags very easily (it would be much simpler if your switch returned json formatted information). The templating info is here

This is not may area of expertise - it may be easier to search through the forums to see if someone else has handled a similar problem, A quick search of xml and template shows a few failed attempts, but I’m sure its possible.

The best way of testing out templates is using the templates tool under the Developer Tools section on the HA left side menu.

I think you just need the value template to return true if that is in the xml, so a value template of

value_template: '{% if "true" in value %} true {% else %} false {% endif %}'

would be a very crude way of doing it. Just make sure ‘true’ doesn’t appear elsewhere in the returned xml.

Thanks a lot GP for your time. Unfortunately I’m a super beginner when it comes to scripting.
My switch config looks now like this:

- platform: command_line
    switches:
       pir_sensor:
          command_on: "curl -T /config/PIR_Sensor_ON.xml http://user:pass@IP/ISAPI/WLAlarm/PIR"
          command_off: "curl -T /config/PIR_Sensor_OFF.xml http://user:pass@IP/ISAPI/WLAlarm/PIR"*
          command_state: "curl -X GET http://user:pass@IP/ISAPI/WLAlarm/PIR"
          value_template: '{% if "true" in value %} true {% else %} false {% endif %}'
          friendly_name: "Turn ON/OFF PIR Sensor"

Unfortunately is not working, exactly as before - the status is always on and when I click the switch nothing happens on the camera settings.

as gpbenton said above, you need to format your code snippets correctly.

highlight the code in the post editor and click the </> symbol at the top of that window.

that said, try moving your quotes to just around the command part.

like:

command_on: curl -T "/config/PIR_Sensor_ON.xml http://user:pass@IP/ISAPI/WLAlarm/PIR”

Thanks @finity - done the text format part.
As about moving the quotes back and forth I don’t think it is a solution - first I need to make sure the state of the switch reflects the reality (as I said the status of the swith is always On - if this happens to be also the status of the PIR sensor in IPcam then the turn to Off click works just fine, so the syntax of command_on or command_off is just fine).
I’ve tried also to replace the value_template results with on/off and not true/false in @gpbenton line - same thing

Later edit: also tried different variation with this:

command_state: ‘curl -X GET http://user:pass@IP/ISAPI/WLAlarm/PIR | grep -oP “*”’
value_template: ‘{{ value == “1” }}’
now the status if “off” no matter what

I didn’t realize this. The first thing to do is to get the commands working before worrying about templates.

Try running the curl command as homeassistant user in the HA virtual environment to see if it works there.

@gpbenton both command_on and command_off commands are working fine - when the switch is stuck in “on” state, if the camera’s PIR is also “on” then clicking on the HA switch works fine and disables the PIR.
In my opinion the only problem is that I’m unable to sense the correct state of the switch so I need to find a way to solve the command_state line and after that i’m 99% it will work just fine.

Later edit: a new try for command_state line looks like this:

  command_state: 'curl -X GET http://user:pass@IP/ISAPI/WLAlarm/PIR | grep -oP "(?<=enabled>).*?(?=</enabled>)"' 

but now the switch is always in “off” state

Another failure (I wanted to count the number of appearences of word “true” - if in the response it finds word “true” then the grep result is “1”, else “0” and after that I’m trying to map “1” value to “on” state and “0” to value “off”)

[code]
command_state: ‘curl -X GET http://user:pass@IP/ISAPI/WLAlarm/PIR | grep -c true’
value_template: >-
{%- if value == “1” -%}
on
{%- else -%}
off
{%- endif -%}

This is an interesting approach I hadn’t considered, and I think its the right lines. But looking at the component documentation, the command has to return 0 for it to be on and something else for off. grep returns 0 on a match and 1 on not matching and your command will always match.

Instead try this grep command

grep -qP "(?<=enabled>)true(?=</enabled>)"

which only only match if there is true in the correct tag. It also uses the q flag to stop any output, in case that is confusing something.

Also remember to remove the value_template field as this wouldn’t be necessary.

Also try the whole command on the command line before entering into HA, to make sure it does return 0 or 1. You can test this by doing

echo $?

after running the command.

@gpbenton: unfortunately it $? value is always “2” no matter if the PIR sensor is active or disabled.
What I can say is that if i’m using the count option of the grep I get “0” for PIR off and “1” for PIR active.
What values does command_state to get for on and off state?
I’m thinking to use the count option and use value templete to remark the state to the needed values, something like:

value_template: >-
            {%- if value == "1" -%}
               on
            {%- else -%}
               off
            {%- endif -%}

If you read the component documentation this is the opposite of what you want. Just change the item of what you are searching for and enter that command as the command_state value. Then there is no need for a value_template.

@gpbenton it looks like I was thinking too complicated (overthinking) - now, with only this line, the switch works like a charm - no value_template, no nothing.

 command_state: 'curl -X GET http://user:pass@IP/ISAPI/WLAlarm/PIR | grep -c true' 

So, in the end, the working solution, at least for me is:

  - platform: command_line
    scan_interval: 10
    switches:
       pir_sensor:
          command_on: "curl -T /config/PIR_Sensor_ON.xml http://<user>:<pass>@<IP>/ISAPI/WLAlarm/PIR"
          command_off: "curl -T /config/PIR_Sensor_OFF.xml http://<user>:<pass>@<IP>/ISAPI/WLAlarm/PIR"
          command_state: 'curl -X GET http://<user>:<pass>@<IP>/ISAPI/WLAlarm/PIR | grep -c true'
          friendly_name: "Turn ON/OFF PIR Sensor"

Where the content of those two *.xml files is:
PIR_Sensor_OFF.xml

<?xml version="1.0" encoding="UTF-8"?>
<PIRAlarm version="1.0" xmlns="http://www.hikvision.com/ver10/XMLSchema">
<enabled>false</enabled>
<name>PIR Alarm</name>
</PIRAlarm> 

PIR_Sensor_ON.xml

<?xml version="1.0" encoding="UTF-8"?>
<PIRAlarm version="1.0" xmlns="http://www.hikvision.com/ver10/XMLSchema">
<enabled>true</enabled>
<name>PIR Alarm</name>
</PIRAlarm> 

Thank you all for your time, with a special thanks for @gpbenton

1 Like

Hi ValiE.
Have you found any other solution to this issue? I imagine that there have been changes, even in the Hikvision API, since 5 years ago.