From a05dc92c4a5ab89147880219f366bc2a6617ff08 Mon Sep 17 00:00:00 2001 From: Joshua Rich Date: Mon, 27 Nov 2023 10:17:22 +1000 Subject: [PATCH] docs(scripts,sensors): add script documentation --- docs/development/sensors.md | 10 ++- docs/scripts.md | 150 ++++++++++++++++++++++++++++++++++++ docs/sensors.md | 3 + 3 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 docs/scripts.md diff --git a/docs/development/sensors.md b/docs/development/sensors.md index 3a44f4006..86e62aaa4 100644 --- a/docs/development/sensors.md +++ b/docs/development/sensors.md @@ -61,14 +61,16 @@ The `sensor.SensorType` for this sensor. Either `TypeSensor` or `TypeBinary`. ### DeviceClass() hass.SensorDeviceClass The `sensor.SensorDeviceClass` for this sensor. There are many, pick an -appropriate one (see `internal/hass/sensor/deviceClass.go`) for the sensor or -return a value of 0 to indicate it has none. +appropriate one (see +[`internal/hass/sensor/deviceClass.go`](../../internal/hass/sensor/deviceClass.go)) +for the sensor or return a value of 0 to indicate it has none. ### StateClass() hass.SensorStateClass The `sensor.SensorStateClass` for this sensor. There are a few, pick an -appropriate one for the sensor (see `internal/hass/sensor/stateClass.go`) sensor -return a value of 0 to indicate it has none. +appropriate one for the sensor (see +[`internal/hass/sensor/stateClass.go`](../../internal/hass/sensor/stateClass.go)) +sensor return a value of 0 to indicate it has none. ### State() interface{} diff --git a/docs/scripts.md b/docs/scripts.md new file mode 100644 index 000000000..ee1a3b4b3 --- /dev/null +++ b/docs/scripts.md @@ -0,0 +1,150 @@ + + +# Script Sensors + +Go Hass Agent supports utilising scripts to create sensors. In this way, you can +extend the sensors presented to Home Assistant by the agent. Note that as the +agent is a "mobile app" in Home Assistant, any script sensors will be associated +with the Go Hass Agent device in Home Asssistant. + +Each script run by the agent can create one or more sensors and each script can +run on its own schedule, specified using a Cron-like syntax. + + +## Requirements + +- Scripts need to be put in `$HOME/.config/com.github.joshuar.go-hass-agent-debug/scripts/`. You can use symlinks. +- Script files need to be executable by the user running Go Hass Agent. +- Scripts need to run without any user interaction. +- Scripts need to output either valid JSON, YAML or TOML. See [Output Format](#output-format) for details. + + +## Output Format + +All scripts should produce output that is either valid JSON, YAML or TOML. +Scripts do not need to use the same format; you can have one script that +produces JSON and another that produces TOML. All scripts will need to output the following fields: + +- A `schedule` field containing a [cron-formatted schedule](#schedule). +- A `sensors` field containing a list of sensors. + +Sensors themselves need to be represented by the following fields: + +- `sensor_name`: the *friendly* name of the sensor in Home Assistant (e.g., *My Script Sensor*). +- `sensor_icon`: a [Material Design +Icon](https://pictogrammers.github.io/@mdi/font/2.0.46/) representing the +current state. It can be changed dynamically based on the current state or +remain constant. Format is `mdi:icon_name`. +- `sensor_state`: the current value of the sensor. For numerical states, without + the units. Otherwise a string or bool (for binary sensors). + +The following optional fields can also be specified, which help control the display in Home Assistant. + +- `sensor_units`: the units for the state value. +- `sensor_type`: the *type* of sensor. If this is a binary sensor with a boolean + value, set this to *"binary"*. Else, do not set this field. +- `sensor_device_class`: a Home Assistant [Device Class](https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes) +for the sensor, which will dictate how it will be displayed in Home Assistant. +There are many, pick an appropriate one (see +[`internal/hass/sensor/deviceClass.go`](../../internal/hass/sensor/deviceClass.go)). +If setting `sensor_device_class`, it is likely required to set an appropriate +unit in `sensor_units` as well. +- `sensor_state_class`: the Home Assistant [State Class](https://developers.home-assistant.io/docs/core/entity/sensor/#available-state-classes). Either *measurement*, *total* or *total_increasing*. +- `sensor_attributes`: any additional attributes to be displayed with the sensor. **Note that the value is required to be valid JSON, regardless of the script output format.** + +### Examples + +The following examples show a script that produces two sensors, in different output formats. + +#### JSON + +JSON output can be either compressed: + +```json +{"schedule":"@every 5s","sensors":[{"sensor_name": "random 1","sensor_icon": "mdi:dice-1","sensor_state":1},{"sensor_name": "random 2","sensor_icon": "mdi:dice-2","sensor_state_class":"measurement","sensor_state":6}]} +``` + +Or pretty-printed: + +```json +{ + "schedule": "@every 5s", + "sensors": [ + { + "sensor_name": "random 1", + "sensor_icon": "mdi:dice-1", + "sensor_state": 2 + }, + { + "sensor_name": "random 2", + "sensor_icon": "mdi:dice-2", + "sensor_state_class": "measurement", + "sensor_state": 6 + } + ] +} +``` + +#### YAML + +```yaml +schedule: '@every 5s' +sensors: + - sensor_name: random 1 + sensor_icon: mdi:dice-1 + sensor_state: 8 + - sensor_name: random 2 + sensor_icon: mdi:dice-2 + sensor_state_class: measurement + sensor_state: 9 +``` + +#### TOML + +```toml +schedule = '@every 5s' + +[[sensors]] +sensor_icon = 'mdi:dice-1' +sensor_name = 'random 1' +sensor_state = 3 + +[[sensors]] +sensor_icon = 'mdi:dice-2' +sensor_name = 'random 2' +sensor_state = 3 +sensor_state_class = 'measurement' +``` + + +## Schedule + +The `schedule` field is used to specify the schedule or interval on which the script will be run by the agent. Each script is run on its own schedule. All sensors and their values should be returned each time the script is run. The format is documented by the [cron Golang package](https://pkg.go.dev/github.com/robfig/cron/v3#hdr-CRON_Expression_Format). In most cases, it is presumed that the script needs to be run on some interval of time. In that case, the easiest way to specify that is with the `@every ` as per the [example output](#examples) such as: + +- `@every 5s`: every 5 seconds +- `@every 1h30m`: every 1 and a half hours. + +Or a pre-defined schedule: + +- `@hourly`. +- `@daily`. +- `@weekly`. +- `@monthly`. +- `@yearly`. + +However, more cron-like formats are supported: + +- `"30 * * * *"`: every hour on the half hour. +- `"30 3-6,20-23 * * *"`: in the range 3-6am, 8-11pm. +- `"CRON_TZ=Asia/Tokyo 30 04 * * *"`: at 04:30 Tokyo time every day. + +*Some schedules, while supported, might not make much sense.* + +## Security + +Running scripts can be dangerous, especially if the script does not have robust error-handling or whose origin is untrusted or unknown. Go Hass Agent makes no attempt to do any analysis or sanitisation of script output, other than ensuring the output is a [valid supported format](#output-format). As such, ensure you trust and understand what the script does and all possible outputs that the script can produce. Scripts are run by the agent and have the permissions of the user running the agent. Script output is sent to your Home Assistant instance. \ No newline at end of file diff --git a/docs/sensors.md b/docs/sensors.md index 2a61ff59f..3d12da6cb 100644 --- a/docs/sensors.md +++ b/docs/sensors.md @@ -56,3 +56,6 @@ [^1]: Only updated when currently connected to a Wi-Fi network. +## Scripts (All Platforms) + +All platforms can also utilise scripts to create custom sensors. See [scripts](scripts.md).