| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- [#enabled-expression]
- = Enabled Expression
- The `enabledExpression` property allows you to dynamically enable or disable action buttons based on entity properties. This is useful when you want to show context-appropriate actions - for example, only showing a "Turn Off" button when a device is already on, or only allowing a "Start" action when a service is stopped.
- == Basic Usage
- The `enabledExpression` is a Go template that must evaluate to a boolean value. When the expression evaluates to `true`, the action button will be enabled (clickable). When it evaluates to `false`, the button will be disabled (greyed out and not clickable).
- [source,yaml]
- ----
- actions:
- - title: Turn On Light
- shell: echo "Turning on {{ .CurrentEntity.name }}"
- icon: 💡
- entity: light
- enabledExpression: "{{ eq .CurrentEntity.powered_on false }}"
- - title: Turn Off Light
- shell: echo "Turning off {{ .CurrentEntity.name }}"
- icon: 💡
- entity: light
- enabledExpression: "{{ eq .CurrentEntity.powered_on true }}"
- ----
- In this example:
- * The "Turn On Light" button is only enabled when `powered_on` is `false`
- * The "Turn Off Light" button is only enabled when `powered_on` is `true`
- == How It Works
- The `enabledExpression` uses the same Go template syntax used elsewhere in OliveTin. It has access to the `.CurrentEntity` variable which contains all properties of the entity the action is bound to.
- === Result Evaluation
- The template result is evaluated as follows:
- [cols="1,1", options="header"]
- |===
- | Result | Enabled?
- | `true` (case insensitive) | ✓ Yes
- | Non-zero integer (e.g., `1`, `42`) | ✓ Yes
- | `false` (case insensitive) | ✗ No
- | `0` | ✗ No
- | Empty string | ✗ No
- | Template error | ✗ No
- |===
- === Default Behavior
- If `enabledExpression` is not specified, the action is always enabled (assuming the user has permission to execute it via ACLs).
- == Examples
- === Simple Boolean Check
- [source,yaml]
- ----
- actions:
- - title: Start Service
- shell: systemctl start {{ .CurrentEntity.service_name }}
- entity: service
- enabledExpression: "{{ eq .CurrentEntity.running false }}"
- - title: Stop Service
- shell: systemctl stop {{ .CurrentEntity.service_name }}
- entity: service
- enabledExpression: "{{ eq .CurrentEntity.running true }}"
- ----
- === Checking Status Values
- [source,yaml]
- ----
- actions:
- - title: Resume Download
- shell: resume-download {{ .CurrentEntity.id }}
- entity: download
- enabledExpression: "{{ eq .CurrentEntity.status \"paused\" }}"
- ----
- === Using Integer Status Codes
- If your entity has integer status values, you can use them directly:
- [source,yaml]
- ----
- actions:
- - title: Process Item
- shell: process {{ .CurrentEntity.id }}
- entity: item
- # Status 1 means "ready" - action is enabled when status is 1
- enabledExpression: "{{ .CurrentEntity.status }}"
- ----
- === Combining with Other Template Functions
- You can use Go template functions for more complex logic:
- [source,yaml]
- ----
- actions:
- - title: Deploy to Production
- shell: deploy {{ .CurrentEntity.name }}
- entity: service
- # Only enable if status is "ready" AND environment is "staging"
- enabledExpression: "{{ and (eq .CurrentEntity.status \"ready\") (eq .CurrentEntity.environment \"staging\") }}"
- ----
- == Complete Example
- Here's a complete configuration showing `enabledExpression` with entities and dashboards:
- [source,yaml]
- ----
- entities:
- - file: /etc/OliveTin/lights.yaml
- name: light
- actions:
- - title: Turn On Light
- shell: /opt/smart-home/light-control.sh on {{ .CurrentEntity.id }}
- icon: 💡
- entity: light
- enabledExpression: "{{ eq .CurrentEntity.powered_on false }}"
- - title: Turn Off Light
- shell: /opt/smart-home/light-control.sh off {{ .CurrentEntity.id }}
- icon: 🔌
- entity: light
- enabledExpression: "{{ eq .CurrentEntity.powered_on true }}"
- dashboards:
- - title: Light Controls
- contents:
- - title: Lights
- type: fieldset
- entity: light
- contents:
- - type: display
- title: |
- <strong>{{ .CurrentEntity.name }}</strong>
- - title: Turn On Light
- - title: Turn Off Light
- ----
- With an entity file like:
- [source,yaml]
- ./etc/OliveTin/lights.yaml
- ----
- - id: kitchen
- name: Kitchen Light
- powered_on: false
- - id: living_room
- name: Living Room Light
- powered_on: true
- ----
- In this setup:
- * The Kitchen Light will have "Turn On" enabled and "Turn Off" disabled
- * The Living Room Light will have "Turn Off" enabled and "Turn On" disabled
- == Error Handling
- If the `enabledExpression` template fails to parse or execute (e.g., due to syntax errors or missing entity properties), OliveTin will:
- 1. Log a warning message with details about the failure
- 2. Treat the action as **disabled** for safety
- This ensures that misconfigured expressions don't accidentally allow unintended actions.
- == Relationship with ACLs
- The `enabledExpression` works in combination with xref:security/acl.adoc[Access Control Lists (ACLs)]. An action button is only enabled when **both** conditions are met:
- 1. The user has `exec` permission via ACLs
- 2. The `enabledExpression` evaluates to `true`
- If either condition is not met, the action button will be disabled.
- == See Also
- * xref:entities/intro.adoc[Entities] - Learn about defining entities
- * xref:dashboards/intro.adoc[Dashboards] - Display entity-bound actions
- * xref:security/acl.adoc[Access Control Lists] - Control who can execute actions
|