This custom integration allows you to control and monitor devices in Home Assistant by executing terminal commands via SSH. It uses the paramiko library and works in a similar way as the official Command Line integration.
- SSH authentication with username/password or key file.
- Connect to multiple devices at the same time.
- Generate sensor, binary sensor, text, select, number, switch and update entities.
- Default commands for Linux and Windows included and available without configuration.
- Edit all commands and settings from the UI.
- Get the value of multiple sensors from the output of a single command.
- Use dynamic sensors to automatically add/remove entities.
- Render commands and sensor values with templates.
- Poll sensors manually by calling a service.
- Include sensor values in commands and update them automatically when executing.
- Turn on devices by Wake on LAN.
Install HACS and open it in Home Assistant. Select Integrations and add a custom repository by clicking on the three dots on the top right corner. Enter https://github.com/zhbjsh/homeassistant-ssh
as Repository and select Integration as Category. You can now search for the SSH integration and download it.
Download the latest release and copy the custom_components/ssh
folder from the zip file to config/custom_components/
on your Home Assistant installation. Don't forget to restart Home Assistant after you're done.
Click on the Add Integration button in Settings -> Devices & Services and select the SSH integration.
Authentication can be done with username and password or you can use key-based authentication.
Simply enter them in the configuration dialog.
Key files in the Home Assistant users ~/.ssh/
folder are used automatically. To use another location, enter the path to your file (for example /config/id_rsa
) and make sure the Home Assistant user has access to it.
When connecting to the device, the integration looks for its host key in the Host keys file. If the key is missing, you can choose to automatically save it to the file by enabling the option Automatically add key to host keys file. Use the option Load system host keys if you want to also load the host keys from the known_hosts
file generated by the ssh
terminal command.
Choose the option that matches your device to have a set of default commands available after setup. This will create some sensors (CPU load, free memory, temperature, etc.) and makes it possible to shutdown and restart the device. The default commands can be modified or deleted later.
Enable this option only if the integration can't execute commands on your device, even though it works when you run the same commands manually from a terminal. It will open an interactive shell session in the background every time a command is executed. This is an experimental feature, it is possible that some commands won't work in this mode or the returned output is not correct!
After connecting to the device, setup asks you to enter the MAC address of the device. Make sure the MAC address is correct, as it is used as unique ID and to turn the device on by Wake on LAN.
Enter a name for the device to complete the setup. The name is used to generate entity IDs and can not be changed later.
Devices can be configured by clicking on the Configure button in Settings -> Devices & Services.
To avoid unintentional shutdowns, this function is disabled by default. After enabling it, power button and ssh.turn_off
service can be used to turn the device off.
Select this option to reset all actions/sensors whose keys are included in the default commands and update them to their newest version. In the following dialog you can also choose to remove all user defined commands.
By default, the integration keeps the SSH connection to the device constantly alive. If you want to change this behaviour, you can let the integration disconnect automatically after every command. This is only recommended if you just have a few sensor commands with a long scan_interval
, as constant connecting/disconnecting will slow down the execution of the commands. This is an experimental feature which has not been tested thoroughly yet!
The update interval is the time in seconds between updates of the device state. If the device disconnects (shown by the SSH Status sensor), the integration will try to reconnect to it as long as it replies to ping requests (shown by the Network Status sensor). This doesn't apply when the Disconnect between commands option is enabled
The command timeout is the time in seconds that the integration waits for a command to complete. Generally commands should be short (maximum a couple seconds), as they are executed one after another and block the next command while they are running.
Action commands and sensor commands of the device can be edited in the configuration window. This is where the default commands from the setup will show up. You can modify them, delete them or add new commands. Be careful when deleting commands, as all entities created by them will become unavailable.
You can test new commands with the ssh.execute_command
service in the developer tools, where the service response will show you the output.
Templates can be used in commands, same as with the Command Line integration (example).
Sensors of the same device can be accessed in commands with &{my_sensor_key}
. The integration will poll the required sensors once before every execution and include their values in the command (example).
Variables can be passed to action commands (but not sensor commands) and accessed with @{my_variable_name}
. Action commands that require variables can only be executed by calling the ssh.run_action
service (example).
Name | Description | Type | Required | Default |
---|---|---|---|---|
command |
The command to execute. | string | yes | |
timeout |
The timeout of the command in seconds. | integer | no | Command timeout of the device |
Action commands are executed manually by pressing a button or calling the ssh.run_action
service. A button entity is created for each action command that doesn’t require variables. (example).
Name | Description | Type | Required | Default |
---|---|---|---|---|
name |
The name of the entity. | string | If no key specified |
|
key |
The action key (can be used with ssh.run_action ). |
string | If no name specified |
Slugified name |
device_class |
The device class of the entity. | string | no | |
icon |
The icon of the entity. | string | no | |
entity_registry_enabled_default |
Set false to disable the entity by default. |
boolean | no | true |
Sensor commands are executed automatically when the device connects or when their scan_interval
has passed. Each sensor command contains a list of one or more sensors that receive their value from its output (example).
Name | Description | Type | Required | Default |
---|---|---|---|---|
scan_interval |
The scan interval. Without it, the command will only execute every time the device connects. | integer | no | |
separator |
Separator in the command output between ID and value for dynamic sensors. | string | no | |
sensors |
A list of sensors. | list | yes |
Sensors are updated every time their command executes. Depending on type and configuration, they can appear as sensor, binary sensor, switch, number, text or select entities in Home Assistant.
Static sensors are created by default. Each static sensor gets its value from one line of the command output. Static sensors must therefore be defined in the right order (example).
Static sensors can only be placed before, but not after dynamic sensors.
Dynamic sensors are created with dynamic: true
. They can get a variable number of values from the command output and create a "child sensor" for each one of them. To be able to use a dynamic sensor, each line of the command output must contain ID and value of a child sensor with either one or more spaces between them, or a separator
defined with the command (example).
Since version 1.2.1 it is possible to have multiple dynamic sensors in one command. The command must then provide a value for each dynamic sensor on the same output line (example).
In case the child sensor ID is not useful to display in Home Assistant, the last output column can contain names to overwrite the IDs as entity names (example).
Both static and dynamic sensors can be made controllable by adding a command_set
command to their configuration. This command is executed when the user changes the value of the entity. The new value will be passed to the command as variable and can be accessed with @{value}
. For dynamic sensors, the ID of the current child sensor can be accessed with @{id}
. Binary sensors can also have the two separate commands command_on
and command_off
instead of command_set
(example).
Name | Description | Type | Required | Default |
---|---|---|---|---|
type |
The sensor type (text , number , binary or version ). |
string | yes | |
name |
The name of the entity. | string | If no key specified |
|
key |
The sensor key (can be used in commands). | string | If no name specified |
Slugified name |
dynamic |
Set true to create a dynamic sensor. |
boolean | no | false |
unit_of_measurement |
The unit of the sensor value. | string | no | |
value_template |
Template to render the sensor value (example). | string | no | |
command_set |
Command to set the sensor value (creates a controllable sensor). | string | no | |
timeout_set |
The timeout of command_set in seconds. |
integer | no | Command timeout of the device |
device_class |
The device class of the entity. | string | no | |
icon |
The icon of the entity. | string | no | |
entity_registry_enabled_default |
Set false to disable the entity by default. |
boolean | no | true |
suggested_unit_of_measurement |
The suggested unit of the entity. | string | no | |
suggested_display_precision |
The suggested display precision of the entity. | integer | no |
Sensors with type: text
appear as sensor (not controllable), text (without options
) or select entities in Home Assistant.
Name | Description | Type | Required | Default |
---|---|---|---|---|
minimum |
The minimum length of the sensor value. | integer | no | 0 |
maximum |
The maximum length of the sensor value. | integer | no | 100 |
pattern |
A regex pattern that the sensor value has to match. | string | no | |
options |
A list of all possible sensor values (use with command_set to create a select entity). |
list | no | |
mode |
Display mode (only for text entities, can be text or password ). |
string | no | text |
Sensors with type: number
appear as sensor (not controllable) or number entities in Home Assistant.
Name | Description | Type | Required | Default |
---|---|---|---|---|
float |
Set true to enable decimal places for the sensor value. |
boolean | no | false |
minimum |
The minimum sensor value. | integer, float | no | 0.0 |
maximum |
The maximum sensor value. | integer, float | no | 100.0 |
mode |
Display mode (only for number entities, can be auto , box or slider ). |
string | no | auto |
Sensors with type: binary
appear as binary sensor (not controllable) or switch entities in Home Assistant.
Name | Description | Type | Required | Default |
---|---|---|---|---|
command_on |
Command to set the sensor value to true (will be used instead of command_set ). |
string | no | |
command_off |
Command to set the sensor value to false (will be used instead of command_set ). |
string | no | |
timeout_on |
The timeout of command_on in seconds. |
integer | no | Command timeout of the device |
timeout_off |
The timeout of command_off in seconds. |
integer | no | Command timeout of the device |
payload_on |
String to detect a true sensor value. |
string | no | |
payload_off |
String to detect a false sensor value. |
string | no |
Sensors with type: version
appear as sensor (without latest
attribute) or update entities in Home Assistant.
Name | Description | Type | Required | Default |
---|---|---|---|---|
latest |
Key of another version sensor to get the latest version (creates an update entity). | string | no |
A simple action command that doesn't require variables.
# Action command
- command: ~/script.sh
name: Execute my script
icon: mdi:script-text-play
An example of a command that uses a template.
# Action command with template
- command: echo 'Today will be {{ states("weather.forecast_home") }}' | mail -s "Weather" me@example.com
name: Send weather forecast
icon: mdi:weather-partly-cloudy
This command includes a variable. To execute it, ssh.run_action
has to be called with the key add_note
and a value for note
.
# Action command with variable
- command: echo '@{note}' >> ~/notes.txt
key: add_note
A simple sensor command with one static sensor. The command returns a number on the first line, which will be the value of the sensor.
# Sensor command with static sensor
- command: who --count | awk -F "=" 'NR>1 {print $2}'
scan_interval: 60
sensors:
- type: number
name: Logged in users
icon: mdi:account-multiple
# Example output
2
In this command, the sensor uses a value_template
to transform the command output from seconds to days.
# Sensor command with static sensor and value template
- command: cat /proc/uptime | awk '{print $1}'
scan_interval: 300
sensors:
- type: number
name: Uptime
unit_of_measurement: d
value_template: "{{ value | float // 86400 }}"
# Example output
248938.30
This sensor command includes the value of another sensor with the key network_interface
.
# Sensor command with static sensor and value of another sensor
- command: ip addr show &{network_interface} | awk '/inet/ {print $2}' | cut -f1 -d'/'
sensors:
- type: text
name: IP address
# Example output
192.168.0.123
This command returns the values of four sensors, each on a new line. The sensors must be listed in the same order.
# Sensor command with multiple static sensors
- command: 'lscpu | awk -F '': +'' ''/^CPU\(s\)|^Vendor|^Model name|^CPU max/ {print $2}'''
sensors:
- type: number
name: CPU count
- type: text
name: CPU vendor
- type: text
name: CPU model
- type: number
name: CPU MHz max.
# Example output
4
ARM
Cortex-A53
1512.0000
This command returns the current value of the log_level
setting in a config file. The sensors command_set
is used to change the value, which makes the sensor controllable and creates a select entity. Without the options
list, a text entity would be generated.
# Sensor command with controllable static sensor
- command: cat /etc/app.conf | awk -F "=" '/^log_level/ {print $2}'
scan_interval: 300
sensors:
- type: text
name: Log level
command_set: sed -i "s|^log_level=.*|log_level=@{value}|" /etc/app.conf
options:
- warning
- info
- debug
# Example output
debug
Version sensors can be used to create update entities. Two separate sensors are needed: One for the currently installed version and one for the latest available version. They are linked by setting the key of the latest version sensor as latest
attribute of the installed version sensor. To be able to install updates from Home Assistant, command_set
must be defined in the installed version sensor.
# Sensor command with two version sensors to generate an update entity
- command: apt-get update >/dev/null 2>&1 && apt-cache policy apache2 | awk 'NR>1 && NR<4 {print $2}'
scan_interval: 86400
sensors:
- type: version
name: Apache
command_set: apt-get install apache2=@{value} -y
timeout_set: 60
latest: apache_latest
- type: version
name: Apache latest
key: apache_latest
# Example output
2.4.62-1~deb11u2
2.4.62-1~deb11u2
Example of a sensor command with dynamic sensor. Each line of the output contains name and size of a file, separated by a comma. When files are added to the folder, new sensor entities are automatically generated in Home Assistant.
# Sensor command with dynamic sensor
- command: ls -lp /path/to/folder/ | awk 'NR>1 && !/\// {print $NF "," $5}'
scan_interval: 600
separator: ","
sensors:
- type: number
name: File
dynamic: true
unit_of_measurement: B
suggested_unit_of_measurement: MB
suggested_display_precision: 3
device_class: data_size
icon: mdi:file
# Example output
notes.txt,108
script.sh,74
app.conf,384
Dynamic sensors can be controllable as well. This command returns name and status of two services and creates a switch entity. To start or stop one of the services, command_on
and command_off
are used. The service names are used as ID's and can be accessed in both commands with @{id}
.
# Sensor command with controllable dynamic sensor
- command: systemctl -a | awk '/bluetooth.service|smbd.service/ {print $1 "," $4}'
scan_interval: 300
separator: ","
sensors:
- type: binary
key: service
dynamic: true
command_on: systemctl start @{id}
command_off: systemctl stop @{id}
payload_on: running
# Example output
bluetooth.service,running
smbd.service,dead
This example uses two dynamic sensors in the same command to create a switch entity plus one status sensor for each docker container. The command output must provide the following data on each line: ID, value sensor 1, value sensor 2. In addition to that, the last output column is used to display container names instead of IDs in Home Assistant.
The outer {{'...'}}
in the command is a workarround to avoid the interpretation of the double curly braces as templates.
# Sensor command with multiple dynamic sensors and name field
- command: docker ps -a --format 'table {{'{{.ID}},{{.State}},{{.Status}},{{.Names}}'}}' | tail -n +2
scan_interval: 60
separator: ","
sensors:
- type: binary
name: Container
dynamic: true
command_on: docker container start @{id}
command_off: docker container stop @{id}
payload_on: running
- type: text
name: Container status
dynamic: true
# Example output
5d9ba26d9440,running,Up 24 hours,happy_kilby
4b73340d977f,exited,Exited (0) 11 minutes ago,serene_joliot
The following services are available.
Execute a command on the selected devices.
Name | Description | Type | Required | Default |
---|---|---|---|---|
command |
The command to execute. | string | yes | |
timeout |
Timeout of the command in seconds. | integer | no | Command timeout of the device |
variables |
Variables to pass to the command. | map | no |
Run an action on the selected devices.
Name | Description | Type | Required | Default |
---|---|---|---|---|
key |
The action key. | string | yes | |
variables |
Variables to pass to the command. | map | no |
Poll one or more sensors.
Turn the selected devices on.
Turn the selected devices off.
Restart the selected devices.