Add a Scene settings menu entry and editor (#1662)
Closes #1528. The scene editor allows defining Item — command pairs that are applied when the scene is activated. While designing a scene, it is possible to sync the target state to the current Item state and test the target state command. Technologically scenes are just rules without triggers, so they can be activated using the „Run Rule, Script, Scene …“ action. Signed-off-by: Jan N. Klug <github@klug.nrw> Signed-off-by: Yannick Schaus <github@schaus.net>pull/1719/head
parent
b2bd16b43f
commit
5bf98457f4
|
@ -150,7 +150,7 @@ prev: /docs/ui/components/
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -191,14 +191,14 @@ prev: /docs/ui/components/
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -130,7 +130,7 @@ Button performing an action
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -171,14 +171,14 @@ Button performing an action
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
@ -289,7 +289,7 @@ Button performing an action
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -330,14 +330,14 @@ Button performing an action
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="taphold_actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="taphold_actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="taphold_actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="taphold_actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="taphold_actionPage" label="Page" context="page">
|
||||
|
|
|
@ -67,7 +67,7 @@ prev: /docs/ui/components/
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -108,14 +108,14 @@ prev: /docs/ui/components/
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -112,7 +112,7 @@ prev: /docs/ui/components/
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -153,14 +153,14 @@ prev: /docs/ui/components/
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -80,7 +80,7 @@ A regular or expandable cell
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -121,14 +121,14 @@ A regular or expandable cell
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -135,7 +135,7 @@ Display a digital clock in a card
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -176,14 +176,14 @@ Display a digital clock in a card
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -109,7 +109,7 @@ A cell expanding to a color picker
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -150,14 +150,14 @@ A cell expanding to a color picker
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -53,7 +53,7 @@ prev: /docs/ui/components/
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -94,14 +94,14 @@ prev: /docs/ui/components/
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -171,7 +171,7 @@ Display a read-only gauge in a card to visualize a quantifiable item
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -212,14 +212,14 @@ Display a read-only gauge in a card to visualize a quantifiable item
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -89,7 +89,7 @@ Display an openHAB icon
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -130,14 +130,14 @@ Display an openHAB icon
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -101,7 +101,7 @@ Display an image (URL or Image item ) in a card
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -142,14 +142,14 @@ Display an image (URL or Image item ) in a card
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -69,7 +69,7 @@ Displays an image from a URL or an item
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -110,14 +110,14 @@ Displays an image from a URL or an item
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -194,7 +194,7 @@ A cell expanding to a knob control
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -235,14 +235,14 @@ A cell expanding to a knob control
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -70,7 +70,7 @@ Display the state of an item in a card
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -111,14 +111,14 @@ Display the state of an item in a card
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
@ -229,7 +229,7 @@ Display the state of an item in a card
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -270,14 +270,14 @@ Display the state of an item in a card
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="taphold_actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="taphold_actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="taphold_actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="taphold_actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="taphold_actionPage" label="Page" context="page">
|
||||
|
|
|
@ -96,7 +96,7 @@ A cell with a big label to show a short item state value
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -137,14 +137,14 @@ A cell with a big label to show a short item state value
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -86,7 +86,7 @@ Display the state of an item in a list
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -127,14 +127,14 @@ Display the state of an item in a list
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -104,7 +104,7 @@ Link performing an action
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -145,14 +145,14 @@ Link performing an action
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -75,7 +75,7 @@ A list item
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -116,14 +116,14 @@ A list item
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -88,7 +88,7 @@ A circle on a map, to represent a radius
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -129,14 +129,14 @@ A circle on a map, to represent a radius
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -72,7 +72,7 @@ An icon on a map
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -113,14 +113,14 @@ An icon on a map
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -175,7 +175,7 @@ A marker on a floor plan
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -216,14 +216,14 @@ A marker on a floor plan
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -141,7 +141,7 @@ A cell expanding to rollershutter controls
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -182,14 +182,14 @@ A cell expanding to rollershutter controls
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -151,7 +151,7 @@ A cell expanding to a big vertical slider
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -192,14 +192,14 @@ A cell expanding to a big vertical slider
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -104,7 +104,7 @@ prev: /docs/ui/components/
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -145,14 +145,14 @@ prev: /docs/ui/components/
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -93,7 +93,7 @@ Displays a video player from a URL or an item
|
|||
<PropOption value="command" label="Send command" />
|
||||
<PropOption value="toggle" label="Toggle Item" />
|
||||
<PropOption value="options" label="Command options" />
|
||||
<PropOption value="rule" label="Run rule" />
|
||||
<PropOption value="rule" label="Run scene, script or rule" />
|
||||
<PropOption value="popup" label="Open popup" />
|
||||
<PropOption value="popover" label="Open popover" />
|
||||
<PropOption value="sheet" label="Open sheet" />
|
||||
|
@ -134,14 +134,14 @@ Displays a video player from a URL or an item
|
|||
Comma-separated list of options; if omitted, retrieve the command options from the Item dynamically. Use <code>value=label</code> format to provide a label different than the option.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRule" label="Rule" context="rule">
|
||||
<PropBlock type="TEXT" name="actionRule" label="Scene, Script or Rule" context="rule">
|
||||
<PropDescription>
|
||||
Rule to run
|
||||
Scene, Script or Rule to run
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Rule Context" context="script">
|
||||
<PropBlock type="TEXT" name="actionRuleContext" label="Context" context="script">
|
||||
<PropDescription>
|
||||
Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="actionPage" label="Page" context="page">
|
||||
|
|
|
@ -19,7 +19,7 @@ export const actionParams = (groupName, paramPrefix) => {
|
|||
{ value: 'command', label: 'Send command' },
|
||||
{ value: 'toggle', label: 'Toggle Item' },
|
||||
{ value: 'options', label: 'Command options' },
|
||||
{ value: 'rule', label: 'Run rule' },
|
||||
{ value: 'rule', label: 'Run scene, script or rule' },
|
||||
{ value: 'popup', label: 'Open popup' },
|
||||
{ value: 'popover', label: 'Open popover' },
|
||||
{ value: 'sheet', label: 'Open sheet' },
|
||||
|
@ -53,11 +53,11 @@ export const actionParams = (groupName, paramPrefix) => {
|
|||
.v((value, configuration, configDescription, parameters) => {
|
||||
return ['options'].indexOf(configuration[paramPrefix + 'action']) >= 0
|
||||
}),
|
||||
pt(paramPrefix + 'actionRule', 'Rule', 'Rule to run').c('rule')
|
||||
pt(paramPrefix + 'actionRule', 'Scene, Script or Rule', 'Scene, Script or Rule to run').c('rule')
|
||||
.v((value, configuration, configDescription, parameters) => {
|
||||
return ['rule'].indexOf(configuration[paramPrefix + 'action']) >= 0
|
||||
}),
|
||||
pt(paramPrefix + 'actionRuleContext', 'Rule Context', 'Object representing the optional context to pass to the rule. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.').c('script')
|
||||
pt(paramPrefix + 'actionRuleContext', 'Context', 'Object representing the optional context to pass. Edit in YAML or provide a JSON object, e.g. <code>{ "param1": "value1", "param2": { "subkey1": "testing", "subkey2": 123 } }</code>.').c('script')
|
||||
.v((value, configuration, configDescription, parameters) => {
|
||||
return ['rule'].indexOf(configuration[paramPrefix + 'action']) >= 0
|
||||
}),
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
"rules.title": "No rules yet",
|
||||
"rules.text": "Rules are the basic building blocks to automate your home - they define which actions to perform when certain events occur.<br><br>Create your first rule with the button below; for more advanced scenarios, you can also write script files in your configuration folder.",
|
||||
|
||||
"scenes.title": "No scenes yet",
|
||||
"scenes.text": "Scenes are rules sending commands to restore a set of items to a desired state.<br />You can run them on-demand or call them from other rules.<br><br>Create your first scene with the button below.",
|
||||
|
||||
"scripts.title": "No scripts yet",
|
||||
"scripts.text": "Scripts are a special kind of rules, with no triggers and a single action module to execute code.<br />You can run them on-demand or call them from other rules.<br><br>Create your first script with the button below.",
|
||||
|
||||
|
|
|
@ -58,6 +58,10 @@
|
|||
:class="{ currentsection: currentUrl.indexOf('/settings/rules') >= 0 }">
|
||||
<f7-icon slot="media" f7="wand_stars" color="gray" />
|
||||
</f7-list-item>
|
||||
<f7-list-item v-if="$store.getters.apiEndpoint('rules')" link="/settings/scenes/" title="Scenes" view=".view-main" panel-close :animate="false" no-chevron
|
||||
:class="{ currentsection: currentUrl.indexOf('/settings/scenes') >= 0 }">
|
||||
<f7-icon slot="media" f7="film" color="gray" />
|
||||
</f7-list-item>
|
||||
<f7-list-item v-if="$store.getters.apiEndpoint('rules')" link="/settings/scripts/" title="Scripts" view=".view-main" panel-close :animate="false" no-chevron
|
||||
:class="{ currentsection: currentUrl.indexOf('/settings/scripts') >= 0 }">
|
||||
<f7-icon slot="media" f7="doc_plaintext" color="gray" />
|
||||
|
|
|
@ -3,9 +3,21 @@
|
|||
<f7-list-item :title="title || 'Rule'" smart-select :smart-select-params="smartSelectParams" v-if="ready" ref="smartSelect">
|
||||
<select :name="name" :multiple="multiple" @change="select" :required="required">
|
||||
<option v-if="!multiple" value="" />
|
||||
<option v-for="rule in rules" :value="rule.uid" :key="rule.uid" :selected="(multiple) ? value && value.indexOf(rule.uid) >= 0 : value === rule.uid">
|
||||
{{ rule.name }}
|
||||
</option>
|
||||
<optgroup v-if="scenes.length > 0" label="Scenes">
|
||||
<option v-for="rule in scenes" :value="rule.uid" :key="rule.uid" :selected="(multiple) ? value && value.indexOf(rule.uid) >= 0 : value === rule.uid">
|
||||
{{ rule.name }}
|
||||
</option>
|
||||
</optgroup>
|
||||
<optgroup v-if="scripts.length > 0" label="Scripts">
|
||||
<option v-for="rule in scripts" :value="rule.uid" :key="rule.uid" :selected="(multiple) ? value && value.indexOf(rule.uid) >= 0 : value === rule.uid">
|
||||
{{ rule.name }}
|
||||
</option>
|
||||
</optgroup>
|
||||
<optgroup v-if="rules.length > 0" label="Rules">
|
||||
<option v-for="rule in rules" :value="rule.uid" :key="rule.uid" :selected="(multiple) ? value && value.indexOf(rule.uid) >= 0 : value === rule.uid">
|
||||
{{ rule.name }}
|
||||
</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</f7-list-item>
|
||||
<!-- for placeholder purposes before items are loaded -->
|
||||
|
@ -19,6 +31,8 @@ export default {
|
|||
data () {
|
||||
return {
|
||||
ready: false,
|
||||
scenes: [],
|
||||
scripts: [],
|
||||
rules: [],
|
||||
icons: {},
|
||||
smartSelectParams: {
|
||||
|
@ -33,8 +47,18 @@ export default {
|
|||
created () {
|
||||
this.smartSelectParams.closeOnSelect = !(this.multiple)
|
||||
// TODO use a Vuex store
|
||||
this.$oh.api.get('/rest/rules').then((data) => {
|
||||
this.rules = data.sort((a, b) => {
|
||||
this.$oh.api.get('/rest/rules?summary=true').then((data) => {
|
||||
this.scenes = data.filter((r) => r.tags.indexOf('Scene') >= 0).sort((a, b) => {
|
||||
const labelA = a.name
|
||||
const labelB = b.name
|
||||
return labelA.localeCompare(labelB)
|
||||
})
|
||||
this.scripts = data.filter((r) => r.tags.indexOf('Script') >= 0).sort((a, b) => {
|
||||
const labelA = a.name
|
||||
const labelB = b.name
|
||||
return labelA.localeCompare(labelB)
|
||||
})
|
||||
this.rules = data.filter((r) => r.tags.indexOf('Scene') < 0 && r.tags.indexOf('Script') < 0).sort((a, b) => {
|
||||
const labelA = a.name
|
||||
const labelB = b.name
|
||||
return labelA.localeCompare(labelB)
|
||||
|
|
|
@ -34,7 +34,7 @@ export default {
|
|||
created () {
|
||||
this.smartSelectParams.closeOnSelect = !(this.multiple)
|
||||
// TODO use a Vuex store
|
||||
this.$oh.api.get('/rest/things').then((data) => {
|
||||
this.$oh.api.get('/rest/things?summary=true').then((data) => {
|
||||
this.things = data.sort((a, b) => {
|
||||
const labelA = a.label
|
||||
const labelB = b.label
|
||||
|
|
|
@ -11,7 +11,7 @@ function getModuleTypes (cm, section) {
|
|||
})
|
||||
}
|
||||
|
||||
function hintItems (cm, line, replaceAfterColon, addStatePropertySuffix) {
|
||||
function hintItems (cm, line, replaceAfterColon, replaceAfterLastSpace, addColonSuffix) {
|
||||
const cursor = cm.getCursor()
|
||||
if (!cm.state.$oh) return
|
||||
const promise = (itemsCache) ? Promise.resolve(itemsCache) : cm.state.$oh.api.get('/rest/items')
|
||||
|
@ -20,7 +20,7 @@ function hintItems (cm, line, replaceAfterColon, addStatePropertySuffix) {
|
|||
let ret = {
|
||||
list: data.map((item) => {
|
||||
return {
|
||||
text: item.name + ((addStatePropertySuffix ? '.state' : '')),
|
||||
text: item.name + ((addColonSuffix ? ': ' : '')),
|
||||
displayText: item.name,
|
||||
description: `${(item.label) ? item.label + ' ' : ''}(${item.type})<br />${item.state}`
|
||||
}
|
||||
|
@ -32,6 +32,11 @@ function hintItems (cm, line, replaceAfterColon, addStatePropertySuffix) {
|
|||
ret.from = { line: cursor.line, ch: colonPos + 2 }
|
||||
ret.to = { line: cursor.line, ch: line.length }
|
||||
}
|
||||
if (replaceAfterLastSpace) {
|
||||
const lastSpacePos = line.lastIndexOf(' ')
|
||||
ret.from = { line: cursor.line, ch: lastSpacePos + 1 }
|
||||
ret.to = { line: cursor.line, ch: line.length }
|
||||
}
|
||||
addTooltipHandlers(cm, ret)
|
||||
return ret
|
||||
})
|
||||
|
@ -144,9 +149,18 @@ function buildModuleStructure (cm, moduleType) {
|
|||
return ret
|
||||
}
|
||||
|
||||
function hintSceneItems (cm, line, parentNr) {
|
||||
console.info('hinting in the items section (scenes)')
|
||||
return hintItems(cm, line, false, true, true)
|
||||
}
|
||||
|
||||
function hintModuleStructure (cm, line, parentLineNr) {
|
||||
const cursor = cm.getCursor()
|
||||
const section = cm.getLine(parentLineNr).replace('s:', '').trim()
|
||||
if (section === 'item') {
|
||||
if (line.indexOf(':') < 0) return hintSceneItems(cm, line, parentLineNr)
|
||||
return // todo: hint commands?
|
||||
}
|
||||
return getModuleTypes(cm, section).then((moduleTypes) => {
|
||||
let completions = moduleTypes.map((m) => {
|
||||
return {
|
||||
|
|
|
@ -47,7 +47,7 @@ export function isComponent (line) {
|
|||
|
||||
export function isRuleSection (line) {
|
||||
if (!line) return false
|
||||
return line.match(/^(triggers|conditions|actions):/)
|
||||
return line.match(/^(triggers|conditions|actions|items):/)
|
||||
}
|
||||
|
||||
export function isChannelsSection (line) {
|
||||
|
|
|
@ -43,6 +43,7 @@ const PageEditors = {
|
|||
|
||||
const RulesListPage = () => import(/* webpackChunkName: "admin-rules" */ '../pages/settings/rules/rules-list.vue')
|
||||
const RuleEditPage = () => import(/* webpackChunkName: "admin-rules" */ '../pages/settings/rules/rule-edit.vue')
|
||||
const SceneEditPage = () => import(/* webpackChunkName: "admin-rules" */ '../pages/settings/rules/scene/scene-edit.vue')
|
||||
const ScriptEditPage = () => import(/* webpackChunkName: "admin-rules" */ '../pages/settings/rules/script/script-edit.vue')
|
||||
const SchedulePage = () => import(/* webpackChunkName: "admin-schedule" */ '../pages/settings/schedule/schedule.vue')
|
||||
|
||||
|
@ -212,6 +213,17 @@ export default [
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'scenes/',
|
||||
async: loadAsync(RulesListPage, { showScenes: true }),
|
||||
routes: [
|
||||
{
|
||||
path: ':ruleId',
|
||||
beforeLeave: checkDirtyBeforeLeave,
|
||||
async: loadAsync(SceneEditPage, (routeTo) => (routeTo.params.ruleId === 'add') ? { createMode: true } : {})
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'scripts/',
|
||||
async: loadAsync(RulesListPage, { showScripts: true }),
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
</f7-nav-right>
|
||||
</f7-navbar>
|
||||
<f7-block v-if="ruleModule" class="no-margin no-padding">
|
||||
<f7-col class="margin-top">
|
||||
<f7-col v-if="!isSceneModule" class="margin-top">
|
||||
<f7-list inline-labels no-hairlines-md class="no-margin">
|
||||
<f7-list-input type="text" :placeholder="moduleTitleSuggestion" :value="ruleModule.label" required
|
||||
@input="ruleModule.label = $event.target.value" clear-button />
|
||||
|
@ -46,7 +46,7 @@
|
|||
<condition-module-wizard v-else-if="!advancedTypePicker && currentSection === 'conditions'" :current-module="ruleModule" :current-module-type="currentRuleModuleType" @typeSelect="setModuleType" @showAdvanced="advancedTypePicker = true" @startScript="startScripting" />
|
||||
<action-module-wizard v-else-if="!advancedTypePicker && currentSection === 'actions'" :current-module="ruleModule" :current-module-type="currentRuleModuleType" @typeSelect="setModuleType" @showAdvanced="advancedTypePicker = true" @startScript="startScripting" />
|
||||
</div>
|
||||
<f7-list v-if="ruleModule.type && (!ruleModule.new || advancedTypePicker)">
|
||||
<f7-list v-if="!isSceneModule && ruleModule.type && (!ruleModule.new || advancedTypePicker)">
|
||||
<f7-list-item :title="sectionLabels[currentSection][0]" ref="ruleModuleTypeSmartSelect" smart-select :smart-select-params="{ view: $f7.views.main, openIn: 'popup', closeOnSelect: true }">
|
||||
<select name="ruleModuleType"
|
||||
@change="setModuleType(moduleTypes[currentSection].find((t) => t.uid === $refs.ruleModuleTypeSmartSelect.f7SmartSelect.getValue()), true)">
|
||||
|
@ -59,7 +59,7 @@
|
|||
</select>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
<f7-block-title v-if="ruleModule && currentRuleModuleType && (!ruleModule.new || advancedTypePicker)" style="margin-bottom: calc(var(--f7-block-title-margin-bottom) - var(--f7-list-margin-vertical))">
|
||||
<f7-block-title v-if="!isSceneModule && ruleModule && currentRuleModuleType && (!ruleModule.new || advancedTypePicker)" style="margin-bottom: calc(var(--f7-block-title-margin-bottom) - var(--f7-list-margin-vertical))">
|
||||
Configuration
|
||||
</f7-block-title>
|
||||
<f7-col v-if="ruleModule && currentRuleModuleType && (!ruleModule.new || advancedTypePicker)">
|
||||
|
@ -90,7 +90,7 @@ export default {
|
|||
ActionModuleWizard,
|
||||
ConfigSheet
|
||||
},
|
||||
props: ['rule', 'ruleModule', 'ruleModuleType', 'moduleTypes', 'currentSection'],
|
||||
props: ['rule', 'ruleModule', 'ruleModuleType', 'moduleTypes', 'currentSection', 'isSceneModule'],
|
||||
data () {
|
||||
return {
|
||||
currentRuleModuleType: this.ruleModuleType,
|
||||
|
|
|
@ -74,9 +74,13 @@
|
|||
<f7-block-title v-if="showScripts" class="searchbar-hide-on-search">
|
||||
{{ rules.length }} scripts
|
||||
</f7-block-title>
|
||||
<f7-block-title v-else-if="showScenes" class="searchbar-hide-on-search">
|
||||
{{ rules.length }} scenes
|
||||
</f7-block-title>
|
||||
<f7-block-title v-else class="searchbar-hide-on-search">
|
||||
{{ rules.length }} rules
|
||||
</f7-block-title>
|
||||
|
||||
<f7-list
|
||||
v-show="rules.length > 0"
|
||||
class="searchbar-found col rules-list"
|
||||
|
@ -98,10 +102,10 @@
|
|||
:title="rule.name"
|
||||
:text="rule.uid"
|
||||
:footer="rule.description"
|
||||
:badge="ruleStatusBadgeText(rule.status)"
|
||||
:badge="showScenes ? '' : ruleStatusBadgeText(rule.status)"
|
||||
:badge-color="ruleStatusBadgeColor(rule.status)">
|
||||
<div slot="footer">
|
||||
<f7-chip v-for="tag in rule.tags.filter((t) => t !== 'Script')" :key="tag" :text="tag" media-bg-color="blue" style="margin-right: 6px">
|
||||
<f7-chip v-for="tag in rule.tags.filter((t) => t !== 'Script' && t !== 'Scene')" :key="tag" :text="tag" media-bg-color="blue" style="margin-right: 6px">
|
||||
<f7-icon slot="media" ios="f7:tag_fill" md="material:label" aurora="f7:tag_fill" />
|
||||
</f7-chip>
|
||||
</div>
|
||||
|
@ -114,6 +118,7 @@
|
|||
</f7-block>
|
||||
<f7-block v-if="ready && !noRuleEngine && !rules.length" class="service-config block-narrow">
|
||||
<empty-state-placeholder v-if="showScripts" icon="doc_plaintext" title="scripts.title" text="scripts.text" />
|
||||
<empty-state-placeholder v-else-if="showScenes" icon="film" title="scenes.title" text="scenes.text" />
|
||||
<empty-state-placeholder v-else icon="wand_stars" title="rules.title" text="rules.text" />
|
||||
</f7-block>
|
||||
<f7-fab v-show="ready && !showCheckboxes" position="right-bottom" slot="fixed" color="blue" href="add">
|
||||
|
@ -128,7 +133,7 @@ import RuleStatus from '@/components/rule/rule-status-mixin'
|
|||
|
||||
export default {
|
||||
mixins: [RuleStatus],
|
||||
props: ['showScripts'],
|
||||
props: ['showScripts', 'showScenes'],
|
||||
components: {
|
||||
'empty-state-placeholder': () => import('@/components/empty-state-placeholder.vue')
|
||||
},
|
||||
|
@ -166,7 +171,14 @@ export default {
|
|||
this.loading = true
|
||||
this.$set(this, 'selectedItems', [])
|
||||
this.showCheckboxes = false
|
||||
this.$oh.api.get('/rest/rules?summary=true' + (this.showScripts ? '&tags=Script' : '')).then(data => {
|
||||
let filter = ''
|
||||
if (this.showScripts) {
|
||||
filter = '&tags=Script'
|
||||
}
|
||||
if (this.showScenes) {
|
||||
filter = '&tags=Scene'
|
||||
}
|
||||
this.$oh.api.get('/rest/rules?summary=true' + filter).then(data => {
|
||||
this.rules = data.sort((a, b) => {
|
||||
return a.name.localeCompare(b.name)
|
||||
})
|
||||
|
@ -175,6 +187,10 @@ export default {
|
|||
this.rules = this.rules.filter((r) => !r.tags || r.tags.indexOf('Script') < 0)
|
||||
}
|
||||
|
||||
if (!this.showScenes) {
|
||||
this.rules = this.rules.filter((r) => !r.tags || r.tags.indexOf('Scene') < 0)
|
||||
}
|
||||
|
||||
this.loading = false
|
||||
this.ready = true
|
||||
setTimeout(() => {
|
||||
|
|
|
@ -0,0 +1,242 @@
|
|||
<template>
|
||||
<f7-popup ref="sceneItemPopup" class="sceneitemconfig-popup" close-on-escape @popup:open="itemConfigOpened" @popup:closed="itemConfigClosed">
|
||||
<f7-page>
|
||||
<f7-navbar>
|
||||
<f7-nav-left>
|
||||
<f7-link icon-ios="f7:arrow_left" icon-md="material:arrow_back" icon-aurora="f7:arrow_left" popup-close />
|
||||
</f7-nav-left>
|
||||
<f7-nav-title>
|
||||
Configure Item:
|
||||
{{ itemName }}
|
||||
</f7-nav-title>
|
||||
<f7-nav-right>
|
||||
<f7-link @click="updateItemConfig" popup-close>
|
||||
Done
|
||||
</f7-link>
|
||||
</f7-nav-right>
|
||||
</f7-navbar>
|
||||
<f7-toolbar bottom>
|
||||
<f7-link class="left" icon-f7="arrow_uturn_left_circle" @click="updateCommandFromCurrentState">
|
||||
Set to current state
|
||||
</f7-link>
|
||||
<f7-link class="right" icon-f7="arrowtriangle_right_circle" @click="testCommand">
|
||||
Test command
|
||||
</f7-link>
|
||||
</f7-toolbar>
|
||||
<f7-block class="no-padding">
|
||||
<f7-col v-if="ready">
|
||||
<f7-list no-hairlines-md>
|
||||
<f7-list-input
|
||||
label="Command"
|
||||
floating-label
|
||||
:value="command"
|
||||
@input="command = $event.target.value"
|
||||
type="text" />
|
||||
<ul v-if="commandSuggestions.length">
|
||||
<f7-list-item radio :checked="command === suggestion.command" v-for="suggestion in commandSuggestions" :key="suggestion.command"
|
||||
:title="suggestion.label" @click="command = suggestion.command" />
|
||||
</ul>
|
||||
</f7-list>
|
||||
</f7-col>
|
||||
</f7-block>
|
||||
<f7-block v-show="control" class="scene-item-control" strong>
|
||||
<f7-col>
|
||||
<div v-show="control === 'colorpicker'" class="scene-item-control-colorpicker" ref="colorpicker" />
|
||||
<div v-if="control === 'toggle'" class="scene-item-control-toggle">
|
||||
<f7-toggle :checked="command === 'ON'" @toggle:change="(value) => command = (value) ? 'ON' : 'OFF'" />
|
||||
</div>
|
||||
<div v-else-if="control === 'slider'" class="scene-item-control-slider">
|
||||
<f7-range v-bind="sliderConfig" :value="command" @range:change="command = $event.toString()" />
|
||||
</div>
|
||||
<div v-else-if="control === 'rollershutter'" class="scene-item-control-rollershutter">
|
||||
<f7-segmented round outline strong class="rollershutter-controls">
|
||||
<f7-button @click="command = 'UP'" large icon-f7="arrowtriangle_left" icon-size="24" icon-color="gray" />
|
||||
<f7-button @click="command = 'STOP'" large icon-f7="stop" icon-size="24" icon-color="red" />
|
||||
<f7-button @click="command = 'DOWN'" large icon-f7="arrowtriangle_right" icon-size="24" icon-color="gray" />
|
||||
</f7-segmented>
|
||||
</div>
|
||||
</f7-col>
|
||||
</f7-block>
|
||||
</f7-page>
|
||||
</f7-popup>
|
||||
</template>
|
||||
|
||||
<style lang="stylus">
|
||||
.scene-item-control
|
||||
.scene-item-control-toggle
|
||||
text-align center
|
||||
padding-top calc(var(--f7-toggle-width))
|
||||
padding-bottom calc(var(--f7-toggle-width))
|
||||
.toggle
|
||||
transform scale(2) rotate(-90deg)
|
||||
transform-origin center
|
||||
|
||||
.scene-item-control-slider
|
||||
width 100%
|
||||
height: 300px
|
||||
display flex
|
||||
flex-direction column
|
||||
justify-content center
|
||||
--f7-range-bar-size 150px
|
||||
--f7-range-knob-size 0px
|
||||
--f7-range-label-size 60px
|
||||
--f7-range-label-font-size 40px
|
||||
|
||||
.scene-item-control-rollershutter
|
||||
width 100%
|
||||
height 200px
|
||||
display flex
|
||||
flex-direction column
|
||||
justify-content center
|
||||
.rollershutter-controls
|
||||
width 150px
|
||||
transform rotate(90deg)
|
||||
transform-origin center
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
components: {
|
||||
},
|
||||
props: ['rule', 'module'],
|
||||
data () {
|
||||
return {
|
||||
ready: false,
|
||||
itemName: null,
|
||||
item: null,
|
||||
command: null,
|
||||
colorpicker: null,
|
||||
control: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
itemConfigOpened () {
|
||||
this.itemName = this.module.configuration.itemName
|
||||
this.command = this.module.configuration.command
|
||||
this.$oh.api.get('/rest/items/' + this.itemName).then((item) => {
|
||||
this.item = item
|
||||
this.initializeControl()
|
||||
this.ready = true
|
||||
})
|
||||
},
|
||||
itemConfigClosed () {
|
||||
if (this.colorpicker) this.colorpicker.destroy()
|
||||
this.$f7.emit('sceneItemConfigClosed')
|
||||
this.$emit('closed')
|
||||
},
|
||||
updateItemConfig () {
|
||||
if (this.colorpicker) this.colorpicker.destroy()
|
||||
this.$f7.emit('sceneItemConfigUpdate', [this.itemName, this.command])
|
||||
this.$emit('update', [this.itemName, this.command])
|
||||
this.itemConfigClosed()
|
||||
},
|
||||
updateCommandFromCurrentState () {
|
||||
this.$oh.api.getPlain('/rest/items/' + this.itemName + '/state?metadata=semantics,widget').then((state) => {
|
||||
this.$set(this, 'command', state)
|
||||
this.$f7.toast.create({
|
||||
text: `Updated desired state of ${this.itemName} to ${state}`,
|
||||
destroyOnClose: true,
|
||||
closeTimeout: 2000
|
||||
}).open()
|
||||
})
|
||||
},
|
||||
testCommand () {
|
||||
this.$oh.api.postPlain('/rest/items/' + this.itemName, this.command, 'text/plain', 'text/plain').then((state) => {
|
||||
this.$f7.toast.create({
|
||||
text: `Sent comment ${this.command} to ${this.itemName}`,
|
||||
destroyOnClose: true,
|
||||
closeTimeout: 2000
|
||||
}).open()
|
||||
})
|
||||
},
|
||||
initializeControl () {
|
||||
if (this.item.commandDescription && this.item.commandDescription.commandOptions) return // no control if command options
|
||||
if (this.item.type === 'Color' || this.item.groupType === 'Color') {
|
||||
this.control = 'colorpicker'
|
||||
const vm = this
|
||||
this.$nextTick(() => {
|
||||
this.colorpicker = this.$f7.colorPicker.create(Object.assign({}, this.config, {
|
||||
containerEl: this.$refs.colorpicker,
|
||||
modules: ['wheel'],
|
||||
value: (this.command.split(',').length === 3) ? { hsb: this.color } : null,
|
||||
on: {
|
||||
change (colorpicker, value) {
|
||||
let command = [...value.hsb]
|
||||
command[0] = Math.round(command[0]) % 360
|
||||
command[1] = Math.round(command[1] * 100)
|
||||
command[2] = Math.round(command[2] * 100)
|
||||
command = command.join(',')
|
||||
vm.command = command
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
} else if (this.item.type === 'Switch' || this.item.groupType === 'Switch') {
|
||||
this.control = 'toggle'
|
||||
} else if (this.item.type === 'Dimmer' || this.item.groupType === 'Dimmer') {
|
||||
this.control = 'slider'
|
||||
} else if (this.item.type === 'Rollershutter' || this.item.groupType === 'Rollershutter') {
|
||||
this.control = 'rollershutter'
|
||||
} else if (this.item.type === 'Number' || this.item.groupType === 'Number') {
|
||||
if (this.item.tags.find((t) => [
|
||||
'ColorTemperature',
|
||||
'Temperature',
|
||||
'Brightness',
|
||||
'Level',
|
||||
'SoundVolume',
|
||||
'Setpoint'
|
||||
].includes(t))) {
|
||||
this.control = 'slider'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
commandSuggestions () {
|
||||
if (!this.item) return []
|
||||
let type = (this.item.type === 'Group' && this.item.groupType) ? this.item.groupType : this.item.type
|
||||
|
||||
if (this.item.commandDescription && this.item.commandDescription.commandOptions) {
|
||||
return this.item.commandDescription.commandOptions
|
||||
}
|
||||
if (type === 'Switch') {
|
||||
return ['ON', 'OFF'].map((c) => { return { command: c, label: c } })
|
||||
}
|
||||
if (type === 'Rollershutter') {
|
||||
return ['UP', 'DOWN', 'STOP'].map((c) => { return { command: c, label: c } })
|
||||
}
|
||||
if (type === 'Contact') {
|
||||
return ['UP', 'DOWN', 'STOP'].map((c) => { return { command: c, label: c } })
|
||||
}
|
||||
if (type === 'Color') {
|
||||
return ['ON', 'OFF'].map((c) => { return { command: c, label: c } })
|
||||
}
|
||||
|
||||
return []
|
||||
},
|
||||
color () {
|
||||
if (this.item.type === 'Color' && this.command && this.command.split(',').length === 3) {
|
||||
let color = this.command.split(',')
|
||||
color[0] = parseInt(color[0])
|
||||
color[1] = color[1] / 100
|
||||
color[2] = color[2] / 100
|
||||
return color
|
||||
}
|
||||
return null
|
||||
},
|
||||
sliderConfig () {
|
||||
if (!this.item) return {}
|
||||
const sd = this.item.stateDescription || { minimum: 0, maximum: 100, step: 1 }
|
||||
return {
|
||||
vertical: true,
|
||||
label: true,
|
||||
scale: true,
|
||||
min: sd.minimum,
|
||||
max: sd.maximum,
|
||||
step: sd.step
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,608 @@
|
|||
<template>
|
||||
<f7-page @page:afterin="onPageAfterIn" @page:afterout="onPageAfterOut">
|
||||
<f7-navbar :title="(createMode) ? 'Create scene' : rule.name" back-link="Back" no-hairline>
|
||||
<f7-nav-right v-if="isEditable">
|
||||
<f7-link @click="save()" v-if="$theme.md" icon-md="material:save" icon-only />
|
||||
<f7-link @click="save()" v-if="!$theme.md">
|
||||
Save<span v-if="$device.desktop"> (Ctrl-S)</span>
|
||||
</f7-link>
|
||||
</f7-nav-right>
|
||||
</f7-navbar>
|
||||
<f7-toolbar tabbar position="top">
|
||||
<f7-link @click="switchTab('design', fromYaml)" :tab-link-active="currentTab === 'design'" class="tab-link">
|
||||
Design
|
||||
</f7-link>
|
||||
<f7-link @click="switchTab('code', toYaml)" :tab-link-active="currentTab === 'code'" class="tab-link">
|
||||
Code
|
||||
</f7-link>
|
||||
</f7-toolbar>
|
||||
<f7-tabs class="scene-editor-tabs">
|
||||
<f7-tab id="design" @tab:show="() => this.currentTab = 'design'" :tab-active="currentTab === 'design'">
|
||||
<f7-block v-if="ready && rule.status && !createMode" class="block-narrow padding-left padding-right" strong>
|
||||
<f7-col v-if="!createMode">
|
||||
<div class="float-right align-items-flex-start align-items-center">
|
||||
<!-- <f7-toggle class="enable-toggle"></f7-toggle> -->
|
||||
<f7-link :icon-color="(rule.status.statusDetail === 'DISABLED') ? 'orange' : 'gray'" :tooltip="((rule.status.statusDetail === 'DISABLED') ? 'Enable' : 'Disable') + (($device.desktop) ? ' (Ctrl-D)' : '')" icon-ios="f7:pause_circle" icon-md="f7:pause_circle" icon-aurora="f7:pause_circle" icon-size="32" color="orange" @click="toggleDisabled" />
|
||||
<f7-link :tooltip="'Run Now' + (($device.desktop) ? ' (Ctrl-R)' : '')" icon-ios="f7:play_round" icon-md="f7:play_round" icon-aurora="f7:play_round" icon-size="32" color="blue" @click="runNow" />
|
||||
</div>
|
||||
Status:
|
||||
<f7-chip class="margin-left"
|
||||
:text="rule.status.status"
|
||||
:color="ruleStatusBadgeColor(rule.status)" />
|
||||
<div>
|
||||
<strong>{{ (rule.status.statusDetail !== 'NONE') ? rule.status.statusDetail : ' ' }}</strong>
|
||||
<br>
|
||||
<div v-if="rule.status.description">
|
||||
{{ rule.status.description }}
|
||||
</div>
|
||||
</div>
|
||||
</f7-col>
|
||||
</f7-block>
|
||||
<!-- skeletons for not ready -->
|
||||
<f7-block v-else-if="!createMode" class="block-narrow padding-left padding-right skeleton-text skeleton-effect-blink" strong>
|
||||
<f7-col>
|
||||
______:
|
||||
<f7-chip class="margin-left" text="________" />
|
||||
<div>
|
||||
<strong>____ _______</strong>
|
||||
<br>
|
||||
</div>
|
||||
</f7-col>
|
||||
</f7-block>
|
||||
|
||||
<!-- skeletons -->
|
||||
<f7-block v-if="!ready" class="block-narrow">
|
||||
<f7-col class="skeleton-text skeleton-effect-blink">
|
||||
<f7-list inline-labels no-hairlines-md>
|
||||
<f7-list-input label="Unique ID" type="text" placeholder="Required" value="_______" required validate
|
||||
:disabled="true" :info="(createMode) ? 'Note: cannot be changed after the creation' : ''"
|
||||
@input="rule.uid = $event.target.value" :clear-button="createMode" />
|
||||
<f7-list-input label="Name" type="text" placeholder="Required" required validate
|
||||
:disabled="true" @input="rule.name = $event.target.value" :clear-button="isEditable" />
|
||||
<f7-list-input label="Description" type="text" value="__ _____ ___ __ ___"
|
||||
:disabled="true" @input="rule.description = $event.target.value" :clear-button="isEditable" />
|
||||
</f7-list>
|
||||
</f7-col>
|
||||
</f7-block>
|
||||
|
||||
<f7-block v-else class="block-narrow">
|
||||
<f7-col>
|
||||
<f7-list inline-labels no-hairlines-md>
|
||||
<f7-list-input label="Unique ID" type="text" placeholder="Required" :value="rule.uid" required validate
|
||||
:disabled="!createMode"
|
||||
:info="(createMode) ? 'Note: cannot be changed after the creation' : ''"
|
||||
pattern="[A-Za-z0-9_\-]+" error-message="Required. A-Z,a-z,0-9,_,- only"
|
||||
@input="rule.uid = $event.target.value" :clear-button="createMode" />
|
||||
<f7-list-input label="Name" type="text" placeholder="Required" :value="rule.name" required validate
|
||||
:disabled="!isEditable" @input="rule.name = $event.target.value" :clear-button="isEditable" />
|
||||
<f7-list-input label="Description" type="text" :value="rule.description"
|
||||
:disabled="!isEditable" @input="rule.description = $event.target.value"
|
||||
:clear-button="isEditable" />
|
||||
</f7-list>
|
||||
</f7-col>
|
||||
|
||||
<f7-block-footer v-if="!isEditable" class="no-margin padding-left">
|
||||
<f7-icon f7="lock_fill" size="12" color="gray" /> Note: this rule is not editable because it has been
|
||||
provisioned from a file.
|
||||
</f7-block-footer>
|
||||
<!-- <f7-col v-if="isEditable" class="text-align-right justify-content-flex-end">
|
||||
</f7-col> -->
|
||||
<f7-col class="rule-modules">
|
||||
<div class="no-padding float-right" v-if="rule['actions'].length > 0">
|
||||
<f7-button @click="toggleModuleControls" small outline :fill="showModuleControls" sortable-toggle=".sortable"
|
||||
style="margin-top: -3px; margin-right: 5px"
|
||||
color="gray" icon-size="12" icon-ios="material:wrap_text" icon-md="material:wrap_text"
|
||||
icon-aurora="material:wrap_text">
|
||||
Reorder
|
||||
</f7-button>
|
||||
</div>
|
||||
<div>
|
||||
<f7-block-title medium style="margin-bottom: var(--f7-list-margin-vertical)">
|
||||
Configuration
|
||||
</f7-block-title>
|
||||
<f7-list class="scene-items" sortable swipeout media-list @sortable:sort="(ev) => reorderModule(ev, 'actions')">
|
||||
<f7-list-item :title="mod.configuration.itemName" media
|
||||
v-for="mod in rule['actions']" :key="mod.id"
|
||||
:link="!showModuleControls"
|
||||
@click.native="(ev) => editModule(ev, mod)" swipeout no-chevron>
|
||||
<f7-link slot="media" icon-color="red" icon-aurora="f7:minus_circle_filled"
|
||||
icon-ios="f7:minus_circle_filled" icon-md="material:remove_circle_outline"
|
||||
@click="showSwipeout" />
|
||||
<span slot="inner" class="inline-command-input">
|
||||
<f7-input type="text" outline
|
||||
:value="mod.configuration.command"
|
||||
@input="updateActionModule([mod.configuration.itemName, $event.target.value])"
|
||||
:disabled="showModuleControls" />
|
||||
</span>
|
||||
<span slot="after">
|
||||
<f7-link icon-f7="arrow_uturn_left_circle"
|
||||
class="margin-left-half" color="blue" tooltip="Set to current state"
|
||||
@click.native="(ev) => updateCommandFromCurrentState(ev, mod)" />
|
||||
<f7-link icon-f7="arrowtriangle_right_circle"
|
||||
class="margin-left-half" color="blue" tooltip="Test command"
|
||||
@click.native="(ev) => testCommand(ev, mod)" />
|
||||
</span>
|
||||
<f7-swipeout-actions right>
|
||||
<f7-swipeout-button @click="(ev) => deleteModule(ev, 'actions', mod)"
|
||||
style="background-color: var(--f7-swipeout-delete-button-bg-color)">
|
||||
Delete
|
||||
</f7-swipeout-button>
|
||||
</f7-swipeout-actions>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
<f7-list v-if="isEditable">
|
||||
<!-- <f7-list-item link no-chevron media-item :color="($theme.dark) ? 'black' : 'white'" subtitle="Add Item"
|
||||
@click="addModule()">
|
||||
<f7-icon slot="media" color="green" aurora="f7:plus_circle_fill" ios="f7:plus_circle_fill"
|
||||
md="material:control_point" />
|
||||
</f7-list-item> -->
|
||||
<item-picker title="Select Items" name="newItem" :multiple="true" :value="selectedItems" @input="selectItems" :no-after="true" class="scene-items-picker" />
|
||||
<!-- <f7-list-button :color="(showModuleControls) ? 'gray' : 'blue'" :title="sectionLabels[section][1]"></f7-list-button> -->
|
||||
</f7-list>
|
||||
</div>
|
||||
</f7-col>
|
||||
<f7-col v-if="(isEditable || rule.tags.length > 0)">
|
||||
<f7-block-title>Tags</f7-block-title>
|
||||
<semantics-picker v-if="isEditable" :item="rule" />
|
||||
<tag-input :item="rule" :disabled="!isEditable" />
|
||||
</f7-col>
|
||||
<f7-col v-if="isEditable && !createMode">
|
||||
<f7-list>
|
||||
<f7-list-button color="red" @click="deleteRule">
|
||||
Remove Scene
|
||||
</f7-list-button>
|
||||
</f7-list>
|
||||
</f7-col>
|
||||
</f7-block>
|
||||
</f7-tab>
|
||||
<f7-tab id="code" @tab:show="() => { this.currentTab = 'code'; toYaml() }" :tab-active="currentTab === 'code'">
|
||||
<editor v-if="currentTab === 'code'" class="rule-code-editor" mode="application/vnd.openhab.rule+yaml" :value="ruleYaml" @input="onEditorInput" />
|
||||
<!-- <pre class="yaml-message padding-horizontal" :class="[yamlError === 'OK' ? 'text-color-green' : 'text-color-red']">{{yamlError}}</pre> -->
|
||||
</f7-tab>
|
||||
</f7-tabs>
|
||||
</f7-page>
|
||||
</template>
|
||||
|
||||
<style lang="stylus">
|
||||
.enable-toggle
|
||||
vertical-align inherit
|
||||
|
||||
.moduleconfig-popup
|
||||
.page-content
|
||||
overflow-x hidden !important
|
||||
|
||||
.config-sheet, .parameter-group
|
||||
margin-top 0 !important
|
||||
|
||||
.rule-modules
|
||||
.swipeout-opened
|
||||
.sortable-handler
|
||||
display none
|
||||
|
||||
.item-media .icon
|
||||
color var(--f7-theme-color)
|
||||
|
||||
.media-list
|
||||
margin-bottom 0
|
||||
|
||||
.list
|
||||
margin-top 0
|
||||
|
||||
.scene-items
|
||||
.inline-command-input
|
||||
position: relative
|
||||
display: flex
|
||||
flex-direction: row-reverse
|
||||
.input
|
||||
max-width: 30%
|
||||
padding-left: 5px
|
||||
background: var(--f7-list-bg-color)
|
||||
|
||||
.ios .scene-items
|
||||
--f7-input-height: 24px
|
||||
|
||||
.scene-items-picker
|
||||
.item-after
|
||||
display none
|
||||
|
||||
.rule-code-editor.vue-codemirror
|
||||
display block
|
||||
top calc(var(--f7-navbar-height) + var(--f7-tabbar-height))
|
||||
height calc(100% - 2*var(--f7-navbar-height))
|
||||
width 100%
|
||||
.yaml-message
|
||||
display block
|
||||
position absolute
|
||||
top 80%
|
||||
white-space pre-wrap
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import YAML from 'yaml'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
|
||||
import SemanticsPicker from '@/components/tags/semantics-picker.vue'
|
||||
import ItemPicker from '@/components/config/controls/item-picker.vue'
|
||||
import TagInput from '@/components/tags/tag-input.vue'
|
||||
|
||||
import SceneConfigureItemPopup from './scene-configure-item-popup.vue'
|
||||
|
||||
import RuleStatus from '@/components/rule/rule-status-mixin'
|
||||
import DirtyMixin from '../../dirty-mixin'
|
||||
|
||||
export default {
|
||||
mixins: [RuleStatus, DirtyMixin],
|
||||
components: {
|
||||
SemanticsPicker,
|
||||
TagInput,
|
||||
ItemPicker,
|
||||
'editor': () => import(/* webpackChunkName: "script-editor" */ '@/components/config/controls/script-editor.vue')
|
||||
},
|
||||
props: ['ruleId', 'createMode'],
|
||||
data () {
|
||||
return {
|
||||
ready: false,
|
||||
loading: false,
|
||||
rule: {},
|
||||
ruleYaml: '',
|
||||
moduleTypes: {
|
||||
actions: [],
|
||||
conditions: [],
|
||||
triggers: []
|
||||
},
|
||||
showModuleControls: false,
|
||||
currentTab: 'design',
|
||||
currentModuleType: null,
|
||||
currentModule: null,
|
||||
currentModuleConfig: {},
|
||||
keyHandler: null,
|
||||
selectedItems: [],
|
||||
|
||||
codeEditorOpened: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onPageAfterIn () {
|
||||
if (window) {
|
||||
window.addEventListener('keydown', this.keyDown)
|
||||
}
|
||||
this.load()
|
||||
},
|
||||
onPageAfterOut () {
|
||||
if (window) {
|
||||
window.removeEventListener('keydown', this.keyDown)
|
||||
}
|
||||
},
|
||||
onEditorInput (value) {
|
||||
this.ruleYaml = value
|
||||
this.dirty = true
|
||||
},
|
||||
load () {
|
||||
if (this.loading) return
|
||||
this.loading = true
|
||||
|
||||
const loadModules1 = this.$oh.api.get('/rest/module-types?type=action')
|
||||
|
||||
const loadingFinished = () => {
|
||||
this.$nextTick(() => {
|
||||
this.savedRule = cloneDeep(this.rule)
|
||||
this.ready = true
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
Promise.all([loadModules1]).then((data) => {
|
||||
this.moduleTypes.actions = data[0]
|
||||
if (this.createMode) {
|
||||
this.$set(this, 'rule', {
|
||||
uid: this.$f7.utils.id(),
|
||||
name: '',
|
||||
triggers: [],
|
||||
actions: [],
|
||||
conditions: [],
|
||||
tags: [],
|
||||
configuration: {},
|
||||
templateUID: null,
|
||||
visibility: 'VISIBLE',
|
||||
status: {
|
||||
status: 'NEW'
|
||||
}
|
||||
})
|
||||
loadingFinished()
|
||||
} else {
|
||||
this.$oh.api.get('/rest/rules/' + this.ruleId).then((data2) => {
|
||||
this.$set(this, 'rule', data2)
|
||||
this.rule.tags = this.rule.tags.filter(e => e !== 'Scene')
|
||||
this.$set(this, 'selectedItems', [])
|
||||
this.rule.actions.forEach((a) => {
|
||||
if (a.type === 'core.ItemCommandAction') {
|
||||
this.selectedItems.push(a.configuration.itemName)
|
||||
}
|
||||
})
|
||||
loadingFinished()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
save (stay) {
|
||||
if (!this.isEditable) return Promise.reject()
|
||||
if (!this.rule.uid) {
|
||||
this.$f7.dialog.alert('Please give an ID to the scene')
|
||||
return Promise.reject()
|
||||
}
|
||||
if (!this.rule.name) {
|
||||
this.$f7.dialog.alert('Please give a name to the scene')
|
||||
return Promise.reject()
|
||||
}
|
||||
let saveRule = cloneDeep(this.rule)
|
||||
saveRule.tags.push('Scene')
|
||||
const promise = (this.createMode)
|
||||
? this.$oh.api.postPlain('/rest/rules', JSON.stringify(saveRule), 'text/plain', 'application/json')
|
||||
: this.$oh.api.put('/rest/rules/' + saveRule.uid, saveRule)
|
||||
return promise.then((data) => {
|
||||
this.dirty = false
|
||||
if (this.createMode) {
|
||||
this.$f7.toast.create({
|
||||
text: 'Scene created',
|
||||
destroyOnClose: true,
|
||||
closeTimeout: 2000
|
||||
}).open()
|
||||
this.$f7router.navigate(this.$f7route.url.replace('/add', '/' + this.rule.uid), { reloadCurrent: true })
|
||||
this.load()
|
||||
} else {
|
||||
this.$f7.toast.create({
|
||||
text: 'Scene updated',
|
||||
destroyOnClose: true,
|
||||
closeTimeout: 2000
|
||||
}).open()
|
||||
this.savedRule = cloneDeep(this.rule)
|
||||
}
|
||||
}).catch((err) => {
|
||||
this.$f7.toast.create({
|
||||
text: 'Error while saving scene: ' + err,
|
||||
destroyOnClose: true,
|
||||
closeTimeout: 2000
|
||||
}).open()
|
||||
})
|
||||
},
|
||||
toggleDisabled () {
|
||||
if (this.createMode) return
|
||||
const enable = (this.rule.status.statusDetail === 'DISABLED')
|
||||
this.$oh.api.postPlain('/rest/rules/' + this.rule.uid + '/enable', enable.toString()).then((data) => {
|
||||
this.$f7.toast.create({
|
||||
text: (enable) ? 'Rule enabled' : 'Rule disabled',
|
||||
destroyOnClose: true,
|
||||
closeTimeout: 2000
|
||||
}).open()
|
||||
}).catch((err) => {
|
||||
this.$f7.toast.create({
|
||||
text: 'Error while disabling or enabling: ' + err,
|
||||
destroyOnClose: true,
|
||||
closeTimeout: 2000
|
||||
}).open()
|
||||
})
|
||||
},
|
||||
runNow () {
|
||||
if (this.createMode) return
|
||||
if (this.rule.status === 'RUNNING') return
|
||||
this.$f7.toast.create({
|
||||
text: 'Running rule',
|
||||
destroyOnClose: true,
|
||||
closeTimeout: 2000
|
||||
}).open()
|
||||
this.$oh.api.postPlain('/rest/rules/' + this.rule.uid + '/runnow', '').catch((err) => {
|
||||
this.$f7.toast.create({
|
||||
text: 'Error while running rule: ' + err,
|
||||
destroyOnClose: true,
|
||||
closeTimeout: 2000
|
||||
}).open()
|
||||
})
|
||||
},
|
||||
deleteRule () {
|
||||
this.$f7.dialog.confirm(
|
||||
`Are you sure you want to delete ${this.rule.name}?`,
|
||||
'Delete Scene',
|
||||
() => {
|
||||
this.$oh.api.delete('/rest/rules/' + this.rule.uid).then(() => {
|
||||
this.$f7router.back('/settings/rules/', { force: true })
|
||||
})
|
||||
}
|
||||
)
|
||||
},
|
||||
keyDown (ev) {
|
||||
if ((ev.ctrlKey || ev.metaKey) && !(ev.altKey || ev.shiftKey)) {
|
||||
if (this.currentModule) return
|
||||
switch (ev.keyCode) {
|
||||
case 83:
|
||||
this.save(!this.createMode)
|
||||
ev.stopPropagation()
|
||||
ev.preventDefault()
|
||||
break
|
||||
}
|
||||
}
|
||||
},
|
||||
toggleModuleControls () {
|
||||
this.showModuleControls = !this.showModuleControls
|
||||
},
|
||||
showSwipeout (ev) {
|
||||
let swipeoutElement = ev.target
|
||||
ev.cancelBubble = true
|
||||
while (!swipeoutElement.classList.contains('swipeout')) {
|
||||
swipeoutElement = swipeoutElement.parentElement
|
||||
}
|
||||
|
||||
if (swipeoutElement) {
|
||||
this.$f7.swipeout.open(swipeoutElement)
|
||||
}
|
||||
},
|
||||
editModule (ev, mod) {
|
||||
if (ev.target.tagName.toLowerCase() === 'input') {
|
||||
ev.cancelBubble = true
|
||||
return
|
||||
}
|
||||
if (this.showModuleControls) return
|
||||
|
||||
let swipeoutElement = ev.target
|
||||
ev.cancelBubble = true
|
||||
while (!swipeoutElement.classList.contains('swipeout')) {
|
||||
swipeoutElement = swipeoutElement.parentElement
|
||||
}
|
||||
if (swipeoutElement && swipeoutElement.classList.contains('swipeout-opened')) return
|
||||
|
||||
const popup = {
|
||||
component: SceneConfigureItemPopup
|
||||
}
|
||||
|
||||
this.$f7router.navigate({
|
||||
url: 'item-config',
|
||||
route: {
|
||||
path: 'item-config',
|
||||
popup
|
||||
}
|
||||
}, {
|
||||
props: {
|
||||
rule: this.rule,
|
||||
module: mod
|
||||
}
|
||||
})
|
||||
|
||||
this.$f7.once('sceneItemConfigUpdate', this.updateActionModule)
|
||||
this.$f7.once('sceneItemConfigClosed', () => {
|
||||
this.$f7.off('sceneItemConfigUpdate', this.updateActionModule)
|
||||
})
|
||||
},
|
||||
deleteModule (ev, section, mod) {
|
||||
let swipeoutElement = ev.target
|
||||
if (!this.isEditable) return
|
||||
ev.cancelBubble = true
|
||||
while (!swipeoutElement.classList.contains('swipeout')) {
|
||||
swipeoutElement = swipeoutElement.parentElement
|
||||
}
|
||||
this.$f7.swipeout.delete(swipeoutElement, () => {
|
||||
const idx = this.rule[section].findIndex((m) => m.id === mod.id)
|
||||
const itemName = this.rule.actions[idx].configuration.itemName
|
||||
this.rule[section].splice(idx, 1)
|
||||
console.debug('Removing: ' + itemName)
|
||||
this.$set(this, 'selectedItems', this.selectedItems.filter((i) => i !== itemName))
|
||||
this.buildActionModules()
|
||||
})
|
||||
},
|
||||
selectItems (items) {
|
||||
console.log(items)
|
||||
this.$set(this, 'selectedItems', items)
|
||||
this.buildActionModules()
|
||||
},
|
||||
reorderModule (ev, section) {
|
||||
const newSection = [...this.rule[section]]
|
||||
newSection.splice(ev.to, 0, newSection.splice(ev.from, 1)[0])
|
||||
this.$set(this.rule, section, newSection)
|
||||
},
|
||||
buildActionModules () {
|
||||
const currentItemNames = this.rule.actions.map((a) => a.configuration.itemName)
|
||||
const modulesToRemove = this.rule.actions.filter((a) => this.selectedItems.indexOf(a.configuration.itemName) < 0)
|
||||
if (modulesToRemove.length > 0) console.debug('Removing: ' + modulesToRemove.map((m) => m.configuration.itemName).join(', '))
|
||||
this.$set(this.rule, 'actions', this.rule.actions.filter((a) => this.selectedItems.indexOf(a.configuration.itemName) >= 0))
|
||||
const itemsToAdd = this.selectedItems.filter((i) => !this.rule.actions.some((a) => a.configuration.itemName === i))
|
||||
if (itemsToAdd.length > 0) console.debug('Adding: ' + itemsToAdd.join(', '))
|
||||
|
||||
let moduleId = 1
|
||||
itemsToAdd.forEach((itemName) => {
|
||||
for (; ['triggers', 'actions', 'conditions'].some((s) => this.rule[s].some((m) => m.id === moduleId.toString())); moduleId++);
|
||||
console.debug('new moduleId=' + moduleId)
|
||||
const newModule = {
|
||||
id: moduleId.toString(),
|
||||
configuration: {
|
||||
itemName,
|
||||
command: null
|
||||
},
|
||||
type: 'core.ItemCommandAction'
|
||||
}
|
||||
this.rule.actions.push(newModule)
|
||||
})
|
||||
const statePromises = itemsToAdd.map((itemName) => this.$oh.api.getPlain('/rest/items/' + itemName + '/state'))
|
||||
Promise.all(statePromises).then((states) => {
|
||||
states.forEach((state, idx) => {
|
||||
const module = this.rule.actions.find((a) => a.configuration.itemName === itemsToAdd[idx])
|
||||
this.$set(module.configuration, 'command', state)
|
||||
})
|
||||
})
|
||||
},
|
||||
updateCommandFromCurrentState (ev, module) {
|
||||
if (ev) ev.cancelBubble = true
|
||||
const itemName = module.configuration.itemName
|
||||
this.$oh.api.getPlain('/rest/items/' + itemName + '/state').then((state) => {
|
||||
this.$set(module.configuration, 'command', state)
|
||||
})
|
||||
},
|
||||
testCommand (ev, module) {
|
||||
if (ev) ev.cancelBubble = true
|
||||
const itemName = module.configuration.itemName
|
||||
const command = module.configuration.command
|
||||
this.$oh.api.postPlain('/rest/items/' + itemName, command, 'text/plain', 'text/plain').then((state) => {
|
||||
this.$f7.toast.create({
|
||||
text: `Updated desired state of ${itemName} to ${state}`,
|
||||
destroyOnClose: true,
|
||||
closeTimeout: 2000
|
||||
}).open()
|
||||
})
|
||||
},
|
||||
updateActionModule (params) {
|
||||
const [itemName, command] = params
|
||||
const module = this.rule.actions.find((a) => a.configuration.itemName === itemName)
|
||||
if (module) module.configuration.command = command
|
||||
},
|
||||
toYaml () {
|
||||
const itemsConfig = {}
|
||||
this.rule.actions.forEach((a) => {
|
||||
itemsConfig[a.configuration.itemName] = a.configuration.command
|
||||
})
|
||||
|
||||
this.ruleYaml = YAML.stringify({
|
||||
items: itemsConfig,
|
||||
triggers: this.rule.triggers,
|
||||
conditions: this.rule.conditions
|
||||
})
|
||||
},
|
||||
fromYaml () {
|
||||
if (!this.isEditable) return
|
||||
try {
|
||||
const updatedRule = YAML.parse(this.ruleYaml)
|
||||
const actions = []
|
||||
let idx = 0
|
||||
for (let item in updatedRule.items) {
|
||||
actions.push({
|
||||
id: (idx++).toString(),
|
||||
configuration: {
|
||||
itemName: item,
|
||||
command: updatedRule.items[item]
|
||||
},
|
||||
type: 'core.ItemCommandAction'
|
||||
})
|
||||
}
|
||||
this.$set(this.rule, 'triggers', updatedRule.triggers)
|
||||
this.$set(this.rule, 'conditions', updatedRule.conditions)
|
||||
this.$set(this.rule, 'actions', actions)
|
||||
return true
|
||||
} catch (e) {
|
||||
this.$f7.dialog.alert(e).open()
|
||||
return false
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isEditable () {
|
||||
return this.rule && this.rule.editable !== false
|
||||
},
|
||||
yamlError () {
|
||||
if (this.currentTab !== 'code') return null
|
||||
try {
|
||||
YAML.parse(this.ruleYaml, { prettyErrors: true })
|
||||
return 'OK'
|
||||
} catch (e) {
|
||||
return e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -73,6 +73,14 @@
|
|||
:footer="objectsSubtitles.rules">
|
||||
<f7-icon slot="media" f7="wand_stars" color="gray" />
|
||||
</f7-list-item>
|
||||
<f7-list-item
|
||||
media-item
|
||||
link="scenes/"
|
||||
title="Scenes"
|
||||
badge-color="blue"
|
||||
:footer="objectsSubtitles.scenes">
|
||||
<f7-icon slot="media" f7="film" color="gray" />
|
||||
</f7-list-item>
|
||||
<f7-list-item
|
||||
media-item
|
||||
link="scripts/"
|
||||
|
@ -150,6 +158,7 @@ export default {
|
|||
items: 'Manage the functional layer',
|
||||
pages: 'Design displays for user control & monitoring',
|
||||
rules: 'Automate with triggers and actions',
|
||||
scenes: 'Store a set of desired states as a scene',
|
||||
scripts: 'Rules dedicated to running code',
|
||||
schedule: 'View upcoming time-based rules'
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue