4
0

enabledExpression.adoc 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. [#enabled-expression]
  2. = Enabled Expression
  3. 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.
  4. == Basic Usage
  5. 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).
  6. [source,yaml]
  7. ----
  8. actions:
  9. - title: Turn On Light
  10. shell: echo "Turning on {{ .CurrentEntity.name }}"
  11. icon: 💡
  12. entity: light
  13. enabledExpression: "{{ eq .CurrentEntity.powered_on false }}"
  14. - title: Turn Off Light
  15. shell: echo "Turning off {{ .CurrentEntity.name }}"
  16. icon: 💡
  17. entity: light
  18. enabledExpression: "{{ eq .CurrentEntity.powered_on true }}"
  19. ----
  20. In this example:
  21. * The "Turn On Light" button is only enabled when `powered_on` is `false`
  22. * The "Turn Off Light" button is only enabled when `powered_on` is `true`
  23. == How It Works
  24. 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.
  25. === Result Evaluation
  26. The template result is evaluated as follows:
  27. [cols="1,1", options="header"]
  28. |===
  29. | Result | Enabled?
  30. | `true` (case insensitive) | ✓ Yes
  31. | Non-zero integer (e.g., `1`, `42`) | ✓ Yes
  32. | `false` (case insensitive) | ✗ No
  33. | `0` | ✗ No
  34. | Empty string | ✗ No
  35. | Template error | ✗ No
  36. |===
  37. === Default Behavior
  38. If `enabledExpression` is not specified, the action is always enabled (assuming the user has permission to execute it via ACLs).
  39. == Examples
  40. === Simple Boolean Check
  41. [source,yaml]
  42. ----
  43. actions:
  44. - title: Start Service
  45. shell: systemctl start {{ .CurrentEntity.service_name }}
  46. entity: service
  47. enabledExpression: "{{ eq .CurrentEntity.running false }}"
  48. - title: Stop Service
  49. shell: systemctl stop {{ .CurrentEntity.service_name }}
  50. entity: service
  51. enabledExpression: "{{ eq .CurrentEntity.running true }}"
  52. ----
  53. === Checking Status Values
  54. [source,yaml]
  55. ----
  56. actions:
  57. - title: Resume Download
  58. shell: resume-download {{ .CurrentEntity.id }}
  59. entity: download
  60. enabledExpression: "{{ eq .CurrentEntity.status \"paused\" }}"
  61. ----
  62. === Using Integer Status Codes
  63. If your entity has integer status values, you can use them directly:
  64. [source,yaml]
  65. ----
  66. actions:
  67. - title: Process Item
  68. shell: process {{ .CurrentEntity.id }}
  69. entity: item
  70. # Status 1 means "ready" - action is enabled when status is 1
  71. enabledExpression: "{{ .CurrentEntity.status }}"
  72. ----
  73. === Combining with Other Template Functions
  74. You can use Go template functions for more complex logic:
  75. [source,yaml]
  76. ----
  77. actions:
  78. - title: Deploy to Production
  79. shell: deploy {{ .CurrentEntity.name }}
  80. entity: service
  81. # Only enable if status is "ready" AND environment is "staging"
  82. enabledExpression: "{{ and (eq .CurrentEntity.status \"ready\") (eq .CurrentEntity.environment \"staging\") }}"
  83. ----
  84. == Complete Example
  85. Here's a complete configuration showing `enabledExpression` with entities and dashboards:
  86. [source,yaml]
  87. ----
  88. entities:
  89. - file: /etc/OliveTin/lights.yaml
  90. name: light
  91. actions:
  92. - title: Turn On Light
  93. shell: /opt/smart-home/light-control.sh on {{ .CurrentEntity.id }}
  94. icon: 💡
  95. entity: light
  96. enabledExpression: "{{ eq .CurrentEntity.powered_on false }}"
  97. - title: Turn Off Light
  98. shell: /opt/smart-home/light-control.sh off {{ .CurrentEntity.id }}
  99. icon: 🔌
  100. entity: light
  101. enabledExpression: "{{ eq .CurrentEntity.powered_on true }}"
  102. dashboards:
  103. - title: Light Controls
  104. contents:
  105. - title: Lights
  106. type: fieldset
  107. entity: light
  108. contents:
  109. - type: display
  110. title: |
  111. <strong>{{ .CurrentEntity.name }}</strong>
  112. - title: Turn On Light
  113. - title: Turn Off Light
  114. ----
  115. With an entity file like:
  116. [source,yaml]
  117. ./etc/OliveTin/lights.yaml
  118. ----
  119. - id: kitchen
  120. name: Kitchen Light
  121. powered_on: false
  122. - id: living_room
  123. name: Living Room Light
  124. powered_on: true
  125. ----
  126. In this setup:
  127. * The Kitchen Light will have "Turn On" enabled and "Turn Off" disabled
  128. * The Living Room Light will have "Turn Off" enabled and "Turn On" disabled
  129. == Error Handling
  130. If the `enabledExpression` template fails to parse or execute (e.g., due to syntax errors or missing entity properties), OliveTin will:
  131. 1. Log a warning message with details about the failure
  132. 2. Treat the action as **disabled** for safety
  133. This ensures that misconfigured expressions don't accidentally allow unintended actions.
  134. == Relationship with ACLs
  135. 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:
  136. 1. The user has `exec` permission via ACLs
  137. 2. The `enabledExpression` evaluates to `true`
  138. If either condition is not met, the action button will be disabled.
  139. == See Also
  140. * xref:entities/intro.adoc[Entities] - Learn about defining entities
  141. * xref:dashboards/intro.adoc[Dashboards] - Display entity-bound actions
  142. * xref:security/acl.adoc[Access Control Lists] - Control who can execute actions