Problems configuring a Command Line Binary Sensor

Hi,

I’m trying to configure a binary sensor which checks if home assistant is still connected to a specific wifi network (mywifi).
I tested the command on home assistant using the terminal and it returns ON or OFF if it is connected to the WIFI. So the command is working.
My question now is what am I doing wrong in this configuration?

binary_sensor:
  - platform: command_line
    unique_id: unique_id_wifi_status 
    name: WIFI Status
    command: "response=$(nmcli -t -f active,ssid dev wifi | egrep \"^yes\" | cut -d\\' -f2 ); test \"$response\" = \"yes:mywifi\" && echo \"ON\" || echo \"OFF\""
    device_class: connectivity
    scan_interval: 60
    payload_on: 'ON'
    payload_off: 'OFF'

If you are running home assistant supervised or in a container, the shell command is executed inside the home assistant docker container. The container has its own virtual environment and cannot see outside of the container. You would need to ssh into the machine running home assistant which is complicated. It’s possible with sshpass sshpass: An Excellent Tool for Non-Interactive SSH Login - Never Use on Production Server but you would need to install it in the container everytime you upgrade to a new version of HA. nmcli is also not available inside the container, so you would need to install that also inside the container.
It’s probably easier to run a script on the machine that updates a sensor through the REST API.

1 Like

It’s probably easier to run a script on the machine that updates a sensor through the REST API.

Do you know of an example somewhere which explains how to do this?

Sure. Here is a simple bash script that creates a sensor in HA and sets the state to the current wifi network name. You need to get a long-lived access token from the HA frontend.

wifi=$( nmcli -t -f active,ssid dev wifi | grep yes | cut -d ":" -f2)
token="A_LONG_LIVED_ACCESS_TOKEN_FROM_HA"
payload='{"state": "'"$wifi"'"}'

curl -X POST http://192.168.xx.xx:8123/api/states/sensor.wifi_network \
  -H "Authorization: Bearer $token" \
  -H "Content-Type: application/json" \
  -d "$payload"

All you’re looking to find out is if you’re connect to a wifi device?

This is why your command is failing. Remember, the commands run within the homeassistant container and where you tested it is NOT in that container. You should test commands by connecting to the container. See:

# 
# docker exec -it homeassistant  nmcli
OCI runtime exec failed: exec failed: unable to start container process: exec: "nmcli": executable file not found in $PATH: unknown
# docker exec -it homeassistant  bash
bash-5.1# which nmcli
bash-5.1# nmcli
bash: nmcli: command not found
bash-5.1# exit

There is no nmcli within the home assistant container. Let’s step back and see what you’re trying to do. Perhaps you can grab what you need from the supervisor itself?

For Example: I am not using wifi but you get the idea…

bash-5.1# curl -sSL -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" http://supervisor/network/interface/wlan0/info | jq
{
  "result": "ok",
  "data": {
    "interface": "wlan0",
    "type": "wireless",
    "enabled": false,
    "connected": false,
    "primary": false,
    "ipv4": {
      "method": "disabled",
      "address": [],
      "nameservers": [],
      "gateway": null
    },
    "ipv6": {
      "method": "disabled",
      "address": [],
      "nameservers": [],
      "gateway": null
    },
    "wifi": null,
    "vlan": null
  }
}

There is a ‘connected’ attribute above. You could create a rest command…

Ok, I gave this a try. But how often does the supervisor update this? Because I disconnected it from the wifi, but the connected value stayed true.

Frankly, I am not sure. I use this to scan for ap’s:

aps=curl -sSL -H “Authorization: Bearer $(printenv SUPERVISOR_TOKEN)” http://supervisor/network/interface/wlan0/accesspoints`

and it is update to date immediately. I am not sure about those specific fields though. Maybe someone with internal knowledge will update here…

I’ve found the reload endpoint :grinning:
Now I should only have to combine these two calls. Which shouldn’t be a problem.

Ok, This works. So now I have the status of my wifi connection. But I think I’m running into the same problems trying to connect to the wifi because this is also a nmcli command.

The best way to test is to get ssh access and connect to the homeassistant docker to test. Otherwise you’re guessing… nmcli definitely isn’t available.

I’ve created a shell command and had it executed by an automation. But I get the following error:

2022-08-22 07:53:45.912 DEBUG (MainThread) [homeassistant.components.shell_command] Stdout of command: 'curl -L -sSL -X POST 'http://supervisor/network/interface/wlan0/update' -H 'Content-Type: application/json' -H 'Authorization: Bearer $(printenv SUPERVISOR_TOKEN)' --data-raw '{ "wifi": { "mode": "infrastructure", "auth": "wpa-psk", "ssid": "MyWifi", "psk": "MyPassword" } }', return code: 0:
b'403: Forbidden'

If I execute this command in the terminal (add-on) it works. So I guess the SUPERVISOR_TOKEN is not available to the shell_command or should I add it in a different way?

I figured it out… stupid double quotes and escaping. But now it works.
I can use the update endpoint to reconnect to the wifi.