update esppilight lib
content of the library is not filtered on 433mhz only
This commit is contained in:
1 parent
a275e48ee1
commit
67dd7ac078
1030 files changed
+203335
-116
No files matched your search
@@ -0,0 +1,76 @@
|
||||
.. |yes| image:: ../../images/yes.png
|
||||
.. |no| image:: ../../images/no.png
|
||||
|
||||
.. role:: underline
|
||||
:class: underline
|
||||
|
||||
Dim
|
||||
===
|
||||
|
||||
.. rubric:: Description
|
||||
|
||||
Dims a device to a dimlevel or starts a sequence from one dimlevel to another.
|
||||
|
||||
.. rubric:: Options
|
||||
|
||||
+----------+------------------+---------------------+-------------------------------------------------------+
|
||||
| **Name** | **Required** | **Multiple Values** | **Description** |
|
||||
+----------+------------------+---------------------+-------------------------------------------------------+
|
||||
| DEVICE | |yes| | |yes| | Device(s) to change |
|
||||
+----------+------------------+---------------------+-------------------------------------------------------+
|
||||
| TO | |yes| | |no| | New dimlevel |
|
||||
+----------+------------------+---------------------+-------------------------------------------------------+
|
||||
|
||||
.. versionadded:: 7.0
|
||||
|
||||
+----------+------------------+---------------------+-------------------------------------------------------+
|
||||
| **Name** | **Required** | **Multiple Values** | **Description** |
|
||||
+----------+------------------+---------------------+-------------------------------------------------------+
|
||||
| FOR | |no| | |no| | | Determine how long this new state lasts before |
|
||||
| | | | | we change back to the previous dimlevel and state |
|
||||
+----------+------------------+---------------------+-------------------------------------------------------+
|
||||
| AFTER | |no| | |no| | After how long do we want the new state to be set |
|
||||
+----------+------------------+---------------------+-------------------------------------------------------+
|
||||
| IN | |no| | |no| | | To be combined with FROM. In what time do we want |
|
||||
| | | | | to change the dimlevel FROM x TO y |
|
||||
+----------+------------------+---------------------+-------------------------------------------------------+
|
||||
| FROM | |no| | |no| | | To be combined with IN. From what dimlevel do we |
|
||||
| | | | | want to start a sequence to the target dimlevel |
|
||||
+----------+------------------+---------------------+-------------------------------------------------------+
|
||||
|
||||
.. note:: Units for ``FOR``, ``AFTER``, and ``IN``
|
||||
|
||||
- MILLISECOND
|
||||
- SECOND
|
||||
- MINUTE
|
||||
- HOUR
|
||||
- DAY
|
||||
|
||||
.. rubric:: Examples
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF 1 == 1 THEN dim DEVICE mainlight TO 15
|
||||
IF 1 == 1 THEN dim DEVICE mainlight AND bookshelve AND hall TO 10
|
||||
|
||||
.. versionadded:: 7.0
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF 1 == 1 THEN dim DEVICE mainlight TO 15 FOR 10 MINUTE
|
||||
IF 1 == 1 THEN dim DEVICE mainlight TO 15 AFTER 30 SECOND
|
||||
IF 1 == 1 THEN dim DEVICE mainlight TO 15 AFTER 30 SECOND FOR 10 MINUTE
|
||||
IF 1 == 1 THEN dim DEVICE mainlight TO 15 FROM 0 IN 45 MINUTE
|
||||
IF 1 == 1 THEN dim DEVICE mainlight TO 15 FROM 0 IN 45 MINUTE FOR 15 MINUTE AFTER 5 MINUTE
|
||||
IF 1 == 1 THEN switch DEVICE light TO off FOR 10 SECOND AFTER 30 MINUTE
|
||||
|
||||
.. versionchanged:: 8.1.0
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF 1 == 1 THEN dim DEVICE mainlight TO 15 FOR '10 MINUTE'
|
||||
IF 1 == 1 THEN dim DEVICE mainlight TO 15 AFTER '30 SECOND'
|
||||
IF 1 == 1 THEN dim DEVICE mainlight TO 15 AFTER '30 SECOND' FOR '10 MINUTE'
|
||||
IF 1 == 1 THEN dim DEVICE mainlight TO 15 FROM 0 IN '45 MINUTE'
|
||||
IF 1 == 1 THEN dim DEVICE mainlight TO 15 FROM 0 IN '45 MINUTE' FOR '15 MINUTE' AFTER '5 MINUTE'
|
||||
IF 1 == 1 THEN switch DEVICE light TO off FOR '10 SECOND' AFTER '30 MINUTE'
|
||||
@@ -0,0 +1,21 @@
|
||||
Actions
|
||||
=======
|
||||
|
||||
.. versionadded:: 6.0
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
dim
|
||||
pushover
|
||||
switch
|
||||
toggle
|
||||
|
||||
.. versionadded:: 7.0
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
label
|
||||
pushbullet
|
||||
sendmail
|
||||
@@ -0,0 +1,59 @@
|
||||
.. |yes| image:: ../../images/yes.png
|
||||
.. |no| image:: ../../images/no.png
|
||||
|
||||
.. role:: underline
|
||||
:class: underline
|
||||
|
||||
Label
|
||||
=====
|
||||
|
||||
.. rubric:: Description
|
||||
|
||||
Changes the text and color of a generic label device.
|
||||
|
||||
.. rubric:: Options
|
||||
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| **Name** | **Required** | **Multiple Values** | **Description** |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| DEVICE | |yes| | |yes| | Device(s) to change |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| TO | |yes| | |no| | New text |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| COLOR | |no| | |no| | New color. If omitted, color is set to black |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| **Name** | **Required** | **Multiple Values** | **Description** |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| FOR | |no| | |no| | | Determine how long this new label lasts |
|
||||
| | | | | before we change back to the previous label |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| AFTER | |no| | |no| | After how long do we want the new label to be set |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
|
||||
.. note:: Units for ``FOR`` and ``AFTER``
|
||||
|
||||
- MILLISECOND
|
||||
- SECOND
|
||||
- MINUTE
|
||||
- HOUR
|
||||
- DAY
|
||||
|
||||
.. rubric:: Examples
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF 1 == 1 THEN label DEVICE tempLabel TO on
|
||||
IF 1 == 1 THEN label DEVICE tempLabel AND humiLabel TO No information
|
||||
IF 1 == 1 THEN label DEVICE tempLabel TO 23.5 FOR 10 SECOND
|
||||
IF 1 == 1 THEN label DEVICE tempLabel TO Bell rang AFTER 30 SECOND
|
||||
IF 1 == 1 THEN label DEVICE tempLabel TO None FOR 10 MINUTE AFTER 30 SECOND
|
||||
|
||||
.. versionchanged:: 8.1.0.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF 1 == 1 THEN label DEVICE tempLabel TO on
|
||||
IF 1 == 1 THEN label DEVICE tempLabel AND humiLabel TO 'No information'
|
||||
IF 1 == 1 THEN label DEVICE tempLabel TO 23.5 FOR '10 SECOND'
|
||||
IF 1 == 1 THEN label DEVICE tempLabel TO 'Bell rang' AFTER '30 SECOND'
|
||||
IF 1 == 1 THEN label DEVICE tempLabel TO None FOR '10 MINUTE' AFTER '30 SECOND'
|
||||
@@ -0,0 +1,38 @@
|
||||
.. |yes| image:: ../../images/yes.png
|
||||
.. |no| image:: ../../images/no.png
|
||||
|
||||
.. role:: underline
|
||||
:class: underline
|
||||
|
||||
Pushbullet
|
||||
==========
|
||||
|
||||
.. rubric:: Description
|
||||
|
||||
Send a message to your mobile phone with the pushbullet API
|
||||
|
||||
.. rubric:: Options
|
||||
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| **Name** | **Required** | **Multiple Values** | **Description** |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| TITLE | |yes| | |no| | |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| BODY | |yes| | |no| | |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| TOKEN | |yes| | |no| | Unique pushbullet user account token |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| TYPE | |yes| | |no| | Message type |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF 1 == 1 THEN pushbullet TITLE Doorbell rang BODY Doorbell rang TOKEN abcd123abc TYPE note
|
||||
|
||||
.. versionchanged:: 8.1.0
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF 1 == 1 THEN pushbullet TITLE 'Doorbell rang' BODY 'Doorbell rang' TOKEN abcd123abc TYPE note
|
||||
@@ -0,0 +1,38 @@
|
||||
.. |yes| image:: ../../images/yes.png
|
||||
.. |no| image:: ../../images/no.png
|
||||
|
||||
.. role:: underline
|
||||
:class: underline
|
||||
|
||||
Pushover
|
||||
========
|
||||
|
||||
.. rubric:: Description
|
||||
|
||||
Send a message to your mobile phone with the pushover API
|
||||
|
||||
.. rubric:: Options
|
||||
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| **Name** | **Required** | **Multiple Values** | **Description** |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| TITLE | |yes| | |no| | |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| MESSAGE | |yes| | |no| | |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| TOKEN | |yes| | |no| | Unique pushover user account token |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| USER | |yes| | |no| | Unique pushover username |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF 1 == 1 THEN pushover TITLE Doorbell rang MESSAGE Doorbell rang TOKEN abcd123abc USER pilight
|
||||
|
||||
.. versionchanged:: 8.1.0
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF 1 == 1 THEN pushover TITLE 'Doorbell rang' MESSAGE 'Doorbell rang' TOKEN abcd123abc USER pilight
|
||||
@@ -0,0 +1,52 @@
|
||||
.. |yes| image:: ../../images/yes.png
|
||||
.. |no| image:: ../../images/no.png
|
||||
|
||||
.. role:: underline
|
||||
:class: underline
|
||||
|
||||
Sendmail
|
||||
========
|
||||
|
||||
.. rubric:: Description
|
||||
|
||||
Send a message to any e-mail address
|
||||
|
||||
.. rubric:: Options
|
||||
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| **Name** | **Required** | **Multiple Values** | **Description** |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| TO | |yes| | |no| | |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| SUBJECT | |yes| | |no| | |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| MESSAGE | |yes| | |no| | |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
|
||||
.. note::
|
||||
|
||||
The ``sendmail`` action requires some additional settings in the pilight configuration:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"settings": {
|
||||
"smtp-sender": "sender@domain.com",
|
||||
"smtp-host": "smtp.smtphost.com",
|
||||
"smtp-port": 465,
|
||||
"smtp-user": "smtpuser@domain.com",
|
||||
"smtp-password": "password"
|
||||
}
|
||||
}
|
||||
|
||||
.. rubric:: Examples
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF 1 == 1 THEN sendmail SUBJECT Doorbell rang MESSAGE Doorbell rang TO someone@somewhere.com
|
||||
|
||||
.. versionchanged:: 8.1.0
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF 1 == 1 THEN sendmail SUBJECT 'Doorbell rang' MESSAGE 'Doorbell rang' TO someone@somewhere.com
|
||||
@@ -0,0 +1,64 @@
|
||||
.. |yes| image:: ../../images/yes.png
|
||||
.. |no| image:: ../../images/no.png
|
||||
|
||||
.. role:: underline
|
||||
:class: underline
|
||||
|
||||
Switch
|
||||
======
|
||||
|
||||
.. rubric:: Description
|
||||
|
||||
Changes the state of a switch, relay or dimmer.
|
||||
|
||||
.. rubric:: Options
|
||||
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| **Name** | **Required** | **Multiple Values** | **Description** |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| DEVICE | |yes| | |yes| | Device(s) to change |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| TO | |yes| | |no| | New state |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
|
||||
.. versionadded:: 7.0
|
||||
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| **Name** | **Required** | **Multiple Values** | **Description** |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| FOR | |no| | |no| | | Determine how long this new state lasts |
|
||||
| | | | | before we change back to the previous state |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| AFTER | |no| | |no| | After how long do we want the new state to be set |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
|
||||
.. note:: Units for ``FOR`` and ``AFTER``
|
||||
|
||||
- MILLISECOND
|
||||
- SECOND
|
||||
- MINUTE
|
||||
- HOUR
|
||||
- DAY
|
||||
|
||||
.. rubric:: Examples
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF 1 == 1 THEN switch DEVICE light TO on
|
||||
IF 1 == 1 THEN switch DEVICE mainlight AND bookshelve AND hall TO on
|
||||
|
||||
.. versionadded:: 7.0
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF 1 == 1 THEN switch DEVICE light TO on FOR 10 MINUTE
|
||||
IF 1 == 1 THEN switch DEVICE light TO on AFTER 30 MILLISECOND
|
||||
IF 1 == 1 THEN switch DEVICE light TO off FOR 10 SECOND AFTER 30 MINUTE
|
||||
|
||||
.. versionchanged:: 8.1.0
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF 1 == 1 THEN switch DEVICE light TO on FOR '10 MINUTE'
|
||||
IF 1 == 1 THEN switch DEVICE light TO on AFTER '30 MILLISECOND'
|
||||
IF 1 == 1 THEN switch DEVICE light TO off FOR '10 SECOND' AFTER '30 MINUTE'
|
||||
@@ -0,0 +1,30 @@
|
||||
.. |yes| image:: ../../images/yes.png
|
||||
.. |no| image:: ../../images/no.png
|
||||
|
||||
.. role:: underline
|
||||
:class: underline
|
||||
|
||||
Toggle
|
||||
======
|
||||
|
||||
.. rubric:: Description
|
||||
|
||||
Toggles a device between state X and state Y. This action is especially made for ``one-shot`` devices such as a remote control button where a normal separate 'switch-on' and separate 'switch-off' rule doesn't apply. This action will check what the current state of a device is, and will change it to the non-current state.
|
||||
|
||||
.. rubric:: Options
|
||||
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| **Name** | **Required** | **Multiple Values** | **Description** |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| DEVICE | |yes| | |yes| | Device(s) to change |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| BETWEEN | |yes| | |no| | State 1 |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
| AND | |no| | |no| | State 2 |
|
||||
+----------+------------------+---------------------+---------------------------------------------------+
|
||||
|
||||
.. rubric:: Example
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF 1 == 1 THEN toggle DEVICE television BETWEEN on AND off
|
||||
@@ -0,0 +1,12 @@
|
||||
Examples
|
||||
========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
ir
|
||||
kodi
|
||||
mail
|
||||
mail1
|
||||
sunriseset
|
||||
time
|
||||
@@ -0,0 +1,62 @@
|
||||
.. |yes| image:: ../../images/yes.png
|
||||
.. |no| image:: ../../images/no.png
|
||||
|
||||
.. role:: underline
|
||||
:class: underline
|
||||
|
||||
IR Remote
|
||||
=========
|
||||
|
||||
.. rubric:: Description
|
||||
|
||||
Switch devices based on your IR remote buttons
|
||||
|
||||
.. rubric:: Devices
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"devices": {
|
||||
"television": {
|
||||
"protocol": [ "kaku_switch" ],
|
||||
"id": [{
|
||||
"id": 123456,
|
||||
"unit": 0
|
||||
}],
|
||||
"state": "off"
|
||||
},
|
||||
"remote": {
|
||||
"protocol": [ "lirc" ],
|
||||
"id": [{
|
||||
"remote": "logitech"
|
||||
}],
|
||||
"code": "000000000000e290",
|
||||
"repeat": 2,
|
||||
"button": "KEY_P"
|
||||
}
|
||||
}
|
||||
|
||||
.. rubric:: Rule
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"remote-television-switch": {
|
||||
"rule": "IF remote.button IS KEY_P AND remote.repeat == 0 THEN toggle DEVICE television BETWEEN on AND off",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
|
||||
.. versionchanged:: 8.1.0
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"remote-television-switch": {
|
||||
"rule": "IF remote.button == KEY_P AND remote.repeat == 0 THEN toggle DEVICE television BETWEEN on AND off",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
.. |yes| image:: ../../images/yes.png
|
||||
.. |no| image:: ../../images/no.png
|
||||
|
||||
.. role:: underline
|
||||
:class: underline
|
||||
|
||||
XBMC / Kodi
|
||||
===========
|
||||
|
||||
.. rubric:: Description
|
||||
|
||||
Execute rules based on XBMC / KODI based events
|
||||
|
||||
.. rubric:: Devices
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"xbmcControls": {
|
||||
"protocol": [ "xbmc" ],
|
||||
"id": [{
|
||||
"server": "127.0.0.1",
|
||||
"port": 9090
|
||||
}],
|
||||
"action": "home",
|
||||
"media": "none"
|
||||
},
|
||||
"speakers": {
|
||||
"protocol": [ "kaku_switch" ],
|
||||
"id": [{
|
||||
"id": 123456,
|
||||
"unit": 4
|
||||
}],
|
||||
"state": "off"
|
||||
}
|
||||
}
|
||||
|
||||
.. rubric:: Rule
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"speakers-on": {
|
||||
"rule": "IF xbmcControls.action IS play THEN switch DEVICE speakers TO on",
|
||||
"active": 1
|
||||
},
|
||||
"speakers-off": {
|
||||
"rule": "IF xbmcControls.action IS pause OR xbmcControls.action IS home THEN switch DEVICE speakers TO off AFTER 3 MINUTES",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
|
||||
.. versionchanged:: 8.1.0
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"speakers-on": {
|
||||
"rule": "IF xbmcControls.action == play THEN switch DEVICE speakers TO on",
|
||||
"active": 1
|
||||
},
|
||||
"speakers-off": {
|
||||
"rule": "IF xbmcControls.action == pause OR xbmcControls.action == home THEN switch DEVICE speakers TO off AFTER '3 MINUTES'",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
.. |yes| image:: ../../images/yes.png
|
||||
.. |no| image:: ../../images/no.png
|
||||
|
||||
.. role:: underline
|
||||
:class: underline
|
||||
|
||||
Mail on contact trigger
|
||||
=======================
|
||||
|
||||
.. rubric:: Description
|
||||
|
||||
Sending a mail based on a contact device trigger including the time when it happened.
|
||||
|
||||
.. rubric:: Devices
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"currentdatetime": {
|
||||
"protocol": [ "datetime" ],
|
||||
"id": [{
|
||||
"longitude": 1.2345,
|
||||
"latitude": 12.3456
|
||||
}],
|
||||
"year": 2015,
|
||||
"month": 1,
|
||||
"day": 27,
|
||||
"hour": 14,
|
||||
"minute": 37,
|
||||
"second": 8,
|
||||
"weekday": 3,
|
||||
"dst": 1
|
||||
},
|
||||
"frontdoor-contact": {
|
||||
"protocol": [ "kaku_contact" ],
|
||||
"id": [{
|
||||
"id": 123456,
|
||||
"unit": 0
|
||||
}],
|
||||
"state": "opened"
|
||||
}
|
||||
}
|
||||
|
||||
.. rubric:: Rule
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"frontdoor-contact-mail": {
|
||||
"rule": "IF frontdoor-contact.state IS opened THEN sendmail TO foo@bar.com SUBJECT Frontdoor was opened at DATE_FORMAT(currentdatetime, %c) MESSAGE .",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
|
||||
.. versionchanged:: 8.1.0
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"frontdoor-contact-mail": {
|
||||
"rule": "IF frontdoor-contact.state == opened THEN sendmail TO foo@bar.com SUBJECT 'Frontdoor was opened at ' . DATE_FORMAT(currentdatetime, %c) MESSAGE ..",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
.. |yes| image:: ../../images/yes.png
|
||||
.. |no| image:: ../../images/no.png
|
||||
|
||||
.. role:: underline
|
||||
:class: underline
|
||||
|
||||
Mail on computer disconnection
|
||||
==============================
|
||||
|
||||
.. rubric:: Description
|
||||
|
||||
Send a mail when one of the computer goes offline.
|
||||
|
||||
.. rubric:: Devices
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"currentdatetime": {
|
||||
"protocol": [ "datetime" ],
|
||||
"id": [{
|
||||
"longitude": 1.2345,
|
||||
"latitude": 12.3456
|
||||
}],
|
||||
"year": 2015,
|
||||
"month": 1,
|
||||
"day": 27,
|
||||
"hour": 14,
|
||||
"minute": 37,
|
||||
"second": 8,
|
||||
"weekday": 3,
|
||||
"dst": 1
|
||||
},
|
||||
"nasPing": {
|
||||
"protocol": [ "arping" ],
|
||||
"id": [{
|
||||
"mac": "aa:bb:cc:dd:00:11"
|
||||
}],
|
||||
"ip": "192.168.1.1",
|
||||
"state": "connected"
|
||||
}
|
||||
}
|
||||
|
||||
.. rubric:: Rule
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"nas-mail": {
|
||||
"rule": "IF nasPing.state IS disconnected THEN sendmail TO foo@bar.com SUBJECT NAS is offline since DATE_FORMAT(currentdatetime, %c) MESSAGE .",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
|
||||
.. versionchanged:: 8.1.0
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"nas-mail": {
|
||||
"rule": "IF nasPing.state IS disconnected THEN sendmail TO foo@bar.com SUBJECT 'NAS is offline since ' . DATE_FORMAT(currentdatetime, %c) MESSAGE ..",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
.. |yes| image:: ../../images/yes.png
|
||||
.. |no| image:: ../../images/no.png
|
||||
|
||||
.. role:: underline
|
||||
:class: underline
|
||||
|
||||
Sunrise / Sunset Event
|
||||
======================
|
||||
|
||||
.. rubric:: Description
|
||||
|
||||
This rule executes when the sun sets or rises.
|
||||
|
||||
.. rubric:: Devices
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"devices": {
|
||||
"currentdatetime": {
|
||||
"protocol": [ "datetime" ],
|
||||
"id": [{
|
||||
"longitude": 1.2345,
|
||||
"latitude": 12.3456
|
||||
}],
|
||||
"year": 2015,
|
||||
"month": 1,
|
||||
"day": 27,
|
||||
"hour": 14,
|
||||
"minute": 37,
|
||||
"second": 8,
|
||||
"weekday": 3,
|
||||
"dst": 1
|
||||
},
|
||||
"sunrisesetdevice": {
|
||||
"protocol": [ "sunriseset" ],
|
||||
"id": [{
|
||||
"longitude": 1.234567,
|
||||
"latitude": 12.123456
|
||||
}],
|
||||
"sunrise": 6.40,
|
||||
"sunset": 18.50,
|
||||
"sun": "rise"
|
||||
},
|
||||
"light": {
|
||||
"protocol": [ "kaku_switch" ],
|
||||
"id": [{
|
||||
"id": 123456,
|
||||
"unit": 0
|
||||
}],
|
||||
"state": "off"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.. rubric:: Rule
|
||||
|
||||
By using math
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"sunset": {
|
||||
"rule": "IF ((sunrisesetdevice.sunset == (currentdatetime.hour + (currentdatetime.minute / 100)) AND light.state IS off) AND currentdatetime.second == 0) THEN switch DEVICE light TO on",
|
||||
"active": 1
|
||||
},
|
||||
"sunrise": {
|
||||
"rule": "IF ((sunrisesetdevice.sunrise == (currentdatetime.hour + (currentdatetime.minute / 100)) AND light.state IS off) AND currentdatetime.second == 0) THEN switch DEVICE light TO on",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
|
||||
By using the DATE_FORMAT function
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"sunset": {
|
||||
"rule": "IF (sunrisesetdevice.sunset == DATE_FORMAT(currentdatetime, %H.%M)) AND light.state IS off AND currentdatetime.second == 0 THEN switch DEVICE light TO on",
|
||||
"active": 1
|
||||
},
|
||||
"sunrise": {
|
||||
"rule": "IF (sunrisesetdevice.sunrise == DATE_FORMAT(currentdatetime, %H.%M)) AND light.state IS off AND currentdatetime.second == 0 THEN switch DEVICE light TO on",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
|
||||
Or an hour before the sun sets:
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"sunset": {
|
||||
"rule": "IF (sunrisesetdevice.sunset == DATE_FORMAT(DATE_ADD(currentdatetime, +1 HOUR), \"%Y-%m-%d %H:%M:%S\", %H.%M)) AND light.state IS off AND currentdatetime.second == 0 THEN switch DEVICE light TO on",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
|
||||
.. versionchanged:: 8.1.0
|
||||
|
||||
By using math
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"sunset": {
|
||||
"rule": "IF ((sunrisesetdevice.sunset == (currentdatetime.hour + (currentdatetime.minute / 100)) AND light.state == off) AND currentdatetime.second == 0) THEN switch DEVICE light TO on",
|
||||
"active": 1
|
||||
},
|
||||
"sunrise": {
|
||||
"rule": "IF ((sunrisesetdevice.sunrise == (currentdatetime.hour + (currentdatetime.minute / 100)) AND light.state == off) AND currentdatetime.second == 0) THEN switch DEVICE light TO on",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
|
||||
By using the DATE_FORMAT function
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"sunset": {
|
||||
"rule": "IF (sunrisesetdevice.sunset == DATE_FORMAT(currentdatetime, %H.%M)) AND light.state == off AND currentdatetime.second == 0 THEN switch DEVICE light TO on",
|
||||
"active": 1
|
||||
},
|
||||
"sunrise": {
|
||||
"rule": "IF (sunrisesetdevice.sunrise == DATE_FORMAT(currentdatetime, %H.%M)) AND light.state == off AND currentdatetime.second == 0 THEN switch DEVICE light TO on",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
|
||||
Or an hour before the sun sets:
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"sunset": {
|
||||
"rule": "IF (sunrisesetdevice.sunset == DATE_FORMAT(DATE_ADD(currentdatetime, '+1 HOUR'), '%Y-%m-%d %H:%M:%S', %H.%M)) AND light.state == off AND currentdatetime.second == 0 THEN switch DEVICE light TO on",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
.. |yes| image:: ../../images/yes.png
|
||||
.. |no| image:: ../../images/no.png
|
||||
|
||||
.. role:: underline
|
||||
:class: underline
|
||||
|
||||
Time based
|
||||
==========
|
||||
|
||||
.. rubric:: Description
|
||||
|
||||
Trigger events based on time
|
||||
|
||||
.. rubric:: Devices
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"currentdatetime": {
|
||||
"protocol": [ "datetime" ],
|
||||
"id": [{
|
||||
"longitude": 1.2345,
|
||||
"latitude": 12.3456
|
||||
}],
|
||||
"year": 2015,
|
||||
"month": 1,
|
||||
"day": 27,
|
||||
"hour": 14,
|
||||
"minute": 37,
|
||||
"second": 8,
|
||||
"weekday": 3,
|
||||
"dst": 1
|
||||
},
|
||||
"outsidelight": {
|
||||
"protocol": [ "kaku_switch" ],
|
||||
"id": [{
|
||||
"id": 123456,
|
||||
"unit": 0
|
||||
}],
|
||||
"state": "off"
|
||||
}
|
||||
}
|
||||
|
||||
.. rubric:: Rule
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"christmass-tree-off": {
|
||||
"rule": "IF DATE_FORMAT(currentdatetime, %H.%M%S) == 23.0000 THEN switch DEVICE outsidelight TO on AFTER RANDOM(0, 90) MINUTE FOR RANDOM(5, 15) MINUTE",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
|
||||
.. versionchanged:: 8.1.0
|
||||
|
||||
.. code-block:: json
|
||||
:linenos:
|
||||
|
||||
{
|
||||
"christmass-tree-off": {
|
||||
"rule": "IF DATE_FORMAT(currentdatetime, %H.%M%S) == 23.0000 THEN switch DEVICE outsidelight TO on AFTER RANDOM(0, 90) . ' MINUTE' FOR RANDOM(5, 15) . ' MINUTE'",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
.. |yes| image:: ../../images/yes.png
|
||||
.. |no| image:: ../../images/no.png
|
||||
|
||||
.. role:: underline
|
||||
:class: underline
|
||||
|
||||
date_add
|
||||
========
|
||||
|
||||
.. rubric:: Description
|
||||
|
||||
Calculations with date and time values.
|
||||
|
||||
.. rubric:: Arguments
|
||||
|
||||
+----------+------------------+------------------------------------------+
|
||||
| **#** | **Required** | **Description** |
|
||||
+----------+------------------+------------------------------------------+
|
||||
| 1 | |yes| | | A datetime device or a datetime string |
|
||||
| | | | The datetime string must be in the |
|
||||
| | | | format YYYY-MM-DD HH:MM:SS. |
|
||||
+----------+------------------+------------------------------------------+
|
||||
| 2 | |yes| | | A number and unit. The number can be |
|
||||
| | | | either positive or negative. |
|
||||
| | | | The unit can be |
|
||||
| | | | - SECOND |
|
||||
| | | | - MINUTE |
|
||||
| | | | - HOUR |
|
||||
| | | | - DAY |
|
||||
| | | | - MONTH |
|
||||
| | | | - YEAR |
|
||||
+----------+------------------+------------------------------------------+
|
||||
|
||||
.. rubric:: Return value
|
||||
|
||||
The returned datetime string is always in the format ``%Y-%m-%d %H:%M:%S``. So in case of the third example, the output will be ``"2016-01-01 00:00:00"``.
|
||||
|
||||
.. rubric:: Examples
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF DATE_ADD(datetime, +1 HOUR) == ...
|
||||
IF DATE_ADD(datetime, -1 DAY) == ...
|
||||
IF DATE_ADD(2015-12-31, 23:59:59, +1 SECOND) == ...
|
||||
IF DATE_ADD(datetime, RANDOM(-3, +3) DAY) == ...
|
||||
IF DATE_FORMAT(DATE_ADD(2015-01-01 21:00:00, RANDOM(0, 120) MINUTE), \"%Y-%m-%d %H:%M:%S\", %H.%M) == ...
|
||||
|
||||
.. versionchanged:: 8.1.0
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF DATE_ADD(datetime, '+1 HOUR') == ...
|
||||
IF DATE_ADD(datetime, '-1 DAY') == ...
|
||||
IF DATE_ADD('2015-12-31, 23:59:59', '+1 SECOND') == ...
|
||||
IF DATE_ADD(datetime, RANDOM(-3, +3) . ' DAY') == ...
|
||||
IF DATE_FORMAT(DATE_ADD('2015-01-01 21:00:00', RANDOM(0, 120) . ' MINUTE'), '%Y-%m-%d %H:%M:%S', %H.%M) == ...
|
||||
@@ -0,0 +1,152 @@
|
||||
.. |yes| image:: ../../images/yes.png
|
||||
.. |no| image:: ../../images/no.png
|
||||
|
||||
.. role:: underline
|
||||
:class: underline
|
||||
|
||||
date_format
|
||||
===========
|
||||
|
||||
.. rubric:: Description
|
||||
|
||||
Reformat date and time values
|
||||
|
||||
.. rubric:: Arguments
|
||||
|
||||
+----------+------------------+------------------------------------------+
|
||||
| **#** | **Required** | **Description** |
|
||||
+----------+------------------+------------------------------------------+
|
||||
| **Using two parameters** |
|
||||
+----------+------------------+------------------------------------------+
|
||||
| 1 | |yes| | A datetime device |
|
||||
+----------+------------------+------------------------------------------+
|
||||
| 2 | |yes| | Output format (see below) |
|
||||
+----------+------------------+------------------------------------------+
|
||||
| **Using three parameters** |
|
||||
+----------+------------------+------------------------------------------+
|
||||
| 1 | |yes| | A datetime string |
|
||||
+----------+------------------+------------------------------------------+
|
||||
| 2 | |yes| | Input format (see below) |
|
||||
+----------+------------------+------------------------------------------+
|
||||
| 3 | |yes| | Output format (see below) |
|
||||
+----------+------------------+------------------------------------------+
|
||||
|
||||
.. note:: **Input / output**
|
||||
|
||||
Consider that the flexibility of the function depends on the input. If you input just ``%H:%M:%S``, the DATE_FORMAT can't output a format like this ``%Y-%m-%d``, because the function didn't receive any date information. It only received time information. So, DATE_FORMAT can't be used to exterpolate information that's not present.
|
||||
|
||||
.. rubric:: Return value
|
||||
|
||||
The function will output the exact format as requested in the last (second or third argument). There are a few things you must consider when working with the DATE_FORMAT function. The types of operators you can use with DATE_FORMAT depends on the output format requested. If you want to compare the output format ``%c`` you can only use the ``IS`` operator, because the final output will be interpreted as a string value. If you want to compare ``%H.%M``, you will need numeric operators like ``==``, ``>``, or ``<``, because the output will be evaluated as a number.
|
||||
|
||||
Also consider the usage of quotes. The flexibility in which DATE_FORMAT can format date and time values isn't always accepted by pilight. For example: ``DATE_FORMAT(datetime, %c)`` outputs ``Fri Apr 24 11:35:36 2015`` which pilight subsequently can't handle. If you want to output string like this, use quotes ``DATE_FORMAT(datetime, "%c")``, which will output as ``"Fri Apr 24 11:35:36 2015"``.
|
||||
|
||||
.. rubric:: Examples
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF DATE_ADD(datetime, +1 HOUR) == ...
|
||||
IF DATE_ADD(datetime, -1 DAY) == ...
|
||||
IF DATE_ADD(2015-12-31, 23:59:59, +1 SECOND) == ...
|
||||
IF DATE_ADD(datetime, RANDOM(-3, +3) DAY) == ...
|
||||
IF DATE_FORMAT(DATE_ADD(2015-01-01 21:00:00, RANDOM(0, 120) MINUTE), \"%Y-%m-%d %H:%M:%S\", %H.%M) == ...
|
||||
|
||||
.. versionchanged:: 8.1.0
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF DATE_ADD(datetime, '+1 HOUR') == ...
|
||||
IF DATE_ADD(datetime, '-1 DAY') == ...
|
||||
IF DATE_ADD(2015-12-31, 23:59:59, '+1 SECOND') == ...
|
||||
IF DATE_ADD(datetime, RANDOM(-3, +3) . ' DAY') == ...
|
||||
IF DATE_FORMAT(DATE_ADD('2015-01-01 21:00:00', RANDOM(0, 120) . ' MINUTE'), '%Y-%m-%d %H:%M:%S', %H.%M) == ...
|
||||
|
||||
.. note:: **DATE_ADD as an argument**
|
||||
|
||||
When you use DATE_ADD as the first argument, you should consider the return value of DATE_ADD, because that's what DATE_FORMAT will eventually receive. The output format of DATE_ADD is ``"%Y-%m-%d %H:%M:%S"``, so the input format for DATE_FORMAT should be the same.
|
||||
|
||||
.. rubric:: Formatting characters
|
||||
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| **Specifier** | **Replaced by** | **Example** |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %a | Abbreviated weekday name [#f1]_ | Thu |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %A | Full weekday name [#f1]_ | Thursday |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %b %h | Abbreviated month name [#f1]_ | Aug |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %B | Full month name [#f1]_ | August |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %c | Date and time representation [#f1]_ | Thu Aug 23 14:55:02 2001 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %C | Year divided by 100 and truncated to integer (00-99) | 20 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %d | Day of the month, zero-padded (01-31) | 23 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %D | Short MM/DD/YY date, equivalent to %m/%d/%y | 08/23/01 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %e | Day of the month, space-padded (1-31) | 23 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %F | Short YYYY-MM-DD date, equivalent to %Y-%m-%d | 2001-08-23 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %g | Week-based year, last two digits (00-99) | 01 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %G | Week-based year | 2001 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %g | Week-based year | 2001 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %H | Hour in 24h format (00-23) | 14 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %I | Hour in 12h format (01-12) | 02 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %j | Day of the year (001-366) | 235 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %m | Month as a decimal number (01-12) | 08 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %M | Minute (00-59) | 55 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %n | New-line character ('\n') | |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %p | AM or PM designation | PM |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %r | 12-hour clock time [#f1]_ | 02:55:02 pm |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %R | 24-hour HH:MM time, equivalent to %H:%M | 14:55 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %S | Second (00-61) | 02 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %t | Horizontal-tab character ('\t') | |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %T | ISO 8601 time format (HH:MM:SS), equivalent to %H:%M:%S | 14:55:02 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %u | ISO 8601 weekday as number with Monday as 1 (1-7) | 4 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %U | Week number with the first Sunday as the first day of week one (00-53) | 33 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %V | ISO 8601 week number (01-53) | 34 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %w | Weekday as a decimal number with Sunday as 0 (0-6) | 4 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %W | Week number with the first Monday as the first day of week one (00-53) | 34 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %x | Date representation [#f1]_ | 08/23/01 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %X | Time representation [#f1]_ | 14:55:02 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %y | Year, last two digits (00-99) | 01 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %Y | Year | 2001 |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %z | | ISO 8601 offset from UTC in timezone (1 minute=1, 1 hour=100) | +100 |
|
||||
| | | If timezone cannot be determined, no characters | |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %Z | | Timezone name or abbreviation [#f1]_ | CDT |
|
||||
| | | If timezone cannot be determined, no characters | |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
| %% | A ``%`` sign | % |
|
||||
+---------------+------------------------------------------------------------------------+--------------------------+
|
||||
|
||||
Copied from http://www.cplusplus.com/reference/ctime/strftime/
|
||||
|
||||
.. [#f1] These specifiers are locale-dependent.
|
||||
@@ -0,0 +1,11 @@
|
||||
Functions
|
||||
=========
|
||||
|
||||
.. versionadded:: 7.0
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
random
|
||||
date_add
|
||||
date_format
|
||||
@@ -0,0 +1,34 @@
|
||||
.. |yes| image:: ../../images/yes.png
|
||||
.. |no| image:: ../../images/no.png
|
||||
|
||||
.. role:: underline
|
||||
:class: underline
|
||||
|
||||
random
|
||||
======
|
||||
|
||||
.. rubric:: Description
|
||||
|
||||
Generate a random number.
|
||||
|
||||
.. rubric:: Parameters
|
||||
|
||||
+----------+------------------+---------------------+
|
||||
| **#** | **Required** | **Description** |
|
||||
+----------+------------------+---------------------+
|
||||
| 1 | |yes| | Lower boundary |
|
||||
+----------+------------------+---------------------+
|
||||
| 2 | |yes| | Higher boundary |
|
||||
+----------+------------------+---------------------+
|
||||
|
||||
.. rubric:: Return value
|
||||
|
||||
A random number
|
||||
|
||||
.. rubric:: Examples
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
IF RANDOM(0, 10) == 5 THEN ...
|
||||
IF RANDOM(1, 100) == 10 THEN ...
|
||||
IF RANDOM(randomLow.dimlevel, randomHigh.dimlevel) == 10 THEN ...
|
||||
@@ -0,0 +1,11 @@
|
||||
Eventing
|
||||
========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
syntax
|
||||
operators
|
||||
actions/index
|
||||
functions/index
|
||||
examples/index
|
||||
@@ -0,0 +1,106 @@
|
||||
Operators
|
||||
=========
|
||||
|
||||
.. rubric:: Arithmetic
|
||||
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| **Operator** | **Description** | **Example** |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| \+ | Adds two operands. | 10 + 20 = 30 |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| − | Subtracts second operand from the first. | 10 − 20 = -10 |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| \* | Multiplies both operands. | 10 * 20 = 200 |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| / | Divides numerator by de-numerator. | | 10 / 20 = 2 |
|
||||
| | | | 10 / 3 = 3.333... |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| \\ [#f1]_ | Integer divides numerator by de-numerator. | 10 \\ 3 = 3 |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| % | Remainder after an integer division. | | 20 % 10 = 0 |
|
||||
| | | | 11 % 3 = 2 |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
|
||||
.. [#f1] The backslash is also used as an ``escape`` character. So if you want to use the intdivide operator inside a rule you must write your rulses like this:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"rules": {
|
||||
"rule": "IF 3 \\ 2 = 1 THEN switch DEVICE light TO on",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
|
||||
.. rubric:: Relational
|
||||
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| **Operator** | **Description** | **Example** |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| == | | Checks if the first and second (nummeric) | | 20 == 10 = false |
|
||||
| | | operand are equal. | | 10 == 10 = true |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| != | | Checks if the first and second (nummeric) | | 20 != 10 = true |
|
||||
| | | operand are unequal. | | 10 != 10 = false |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| IS | | Checks if the first and second (character) | | a IS b = false |
|
||||
| | | operand are equal. | | a IS a = true |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| >= | | Checks if the first operand is greater or | | 20 >= 10 = true |
|
||||
| | | equal to the second operand. | | 10 >= 20 = false |
|
||||
| | | | 10 >= 10 = true |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| > | | Checks if the first operand is greater than | | 20 > 10 = true |
|
||||
| | | the second operand. | | 10 > 20 = false |
|
||||
| | | | 10 > 10 = false |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| <= | | Checks if the first operand is smaller or | | 20 <= 10 = false |
|
||||
| | | equal to the second operand. | | 10 <= 20 = true |
|
||||
| | | | 10 <= 10 = true |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| < | | Checks if the first operand is smaller than | | 20 < 10 = false |
|
||||
| | | the second operand. | | 10 < 20 = true |
|
||||
| | | | 10 < 10 = false |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
|
||||
.. versionadded:: 8.0 ISNOT operator added
|
||||
|
||||
.. deprecated:: 8.1.0
|
||||
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| **Operator** | **Description** | **Example** |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| ISNOT | | Checks if the first and second (character) | | a ISNOT b = true |
|
||||
| | | operand are equal. | | a ISNOT a = false |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
|
||||
.. rubric:: Logical
|
||||
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| **Operator** | **Description** | **Example** |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| AND | | Checks if the first and second operands are | | 1 AND 1 = true |
|
||||
| | | true. | | 1 AND 0 = false |
|
||||
| | | - values greater of smaller then 0 are true | | foo AND false = true |
|
||||
| | | - strings equals to ``0`` are false | | true AND true = true |
|
||||
| | | - strings other than ``0`` are true | | false AND false = true |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
| OR | | Checks if the first or second operands are | | 0 OR 0 = false |
|
||||
| | | true. | | 1 OR 0 = true |
|
||||
| | | - values greater of smaller then 0 are true | | foo OR false = true |
|
||||
| | | - strings equals to ``0`` are false | | true OR true = true |
|
||||
| | | - strings other than ``0`` are true | | false OR false = true |
|
||||
+--------------+-------------------------------------------------+--------------------------+
|
||||
|
||||
.. rubric:: Other
|
||||
|
||||
.. versionadded:: 8.1.0
|
||||
|
||||
+----------------+-------------------------------------------------+--------------------------+
|
||||
| **Operator** | **Description** | **Example** |
|
||||
+----------------+-------------------------------------------------+--------------------------+
|
||||
| | . | Concatenates two strings | | a . b == 'ab' |
|
||||
| | (single dot) | | | a . ' ' . b == 'a b' |
|
||||
| | | | RANDOM(1, 2) . '34' |
|
||||
+----------------+-------------------------------------------------+--------------------------+
|
||||
|
||||
@@ -0,0 +1,366 @@
|
||||
.. role:: event-success
|
||||
.. role:: event-fail
|
||||
|
||||
Syntax
|
||||
======
|
||||
|
||||
- `Introduction`_
|
||||
- `Rule Parsing`_
|
||||
- `Basic Structure`_
|
||||
- `True or False`_
|
||||
- `AND and OR`_
|
||||
- `Hooks`_
|
||||
- `Operator`_
|
||||
- `String and Concatenation`_
|
||||
- `Devices`_
|
||||
- `Functions`_
|
||||
- `Actions`_
|
||||
- `Using Device Parameters`_
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The pilight eventing library allows you to automate your house by writing event rules. These rules tell pilight what should happen at a given time or at a given event. pilight event rules follow the regular mathematical conventions and because you can work with an infinite number of hooks, they can become highly complex but are also highly flexible.
|
||||
|
||||
As with everything inside pilight, the eventing library is also highly modular. This means that the operators, actions, and functions are external modules that can be easily extended. Developers and users do not have to touch the core of the eventing library to add additional features.
|
||||
|
||||
Rule Parsing
|
||||
------------
|
||||
|
||||
There are few things that are useful to know before working with pilight event rules. When you better understand how pilight parses the rules, you can write really efficient and advanced rules.
|
||||
|
||||
.. _Basic Structure:
|
||||
.. rubric:: Basic Structure
|
||||
|
||||
All rules basically consist of the same structure:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF ... THEN ...
|
||||
|
||||
A rule always start with the IF, followed by the rule logic, and is closed by a THEN. All actions are put after the THEN.
|
||||
|
||||
.. versionadded:: 8.1.0
|
||||
|
||||
The IF / THEN logic can be expanded by an ELSE. The actions written after the ELSE will be executed if the logic contained in the first if block is false.
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF ... THEN ... ELSE ...
|
||||
|
||||
Or you can nest an infinite number of IF/ELSE conditions by using adding the END keyword
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF ... THEN IF ... THEN ... ELSE ... END ELSE IF ... THEN ... ELSE ... END END
|
||||
|
||||
.. _True or False:
|
||||
|
||||
.. rubric:: True or False
|
||||
|
||||
Let us start with how pilight handles succeeding or failing conditions. pilight converts each logical mathematical and logical step into a true or false. The final condition must be true before triggering an action. If the final result is false, the action is skipped. These two examples will both succeed:
|
||||
|
||||
:event-success:`Succeeds`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF (1 == 1) == True THEN
|
||||
|
||||
:event-success:`Succeeds`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF (1 == 1) != False THEN
|
||||
|
||||
These two examples will both fail:
|
||||
|
||||
:event-fail:`Fails`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF (1 == 0) IS True THEN
|
||||
|
||||
:event-fail:`Fails`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF (1 != 1) IS False THEN
|
||||
|
||||
.. _AND and OR:
|
||||
.. rubric:: AND and OR
|
||||
|
||||
In the first examples we only used one condition but this does not allow us to make very advanced and flexible rules. Therefore we need to be able to combine several conditions in a single rule. This is possible by combining them with AND and OR operators. Let us take a look at some basic examples:
|
||||
|
||||
:event-fail:`Fails`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF 1 == 1 AND 1 == 2 THEN ...
|
||||
|
||||
:event-success:`Succeeds`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF 1 == 1 OR 1 == 2 THEN ...
|
||||
|
||||
:event-fail:`Fails`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF 1 == 2 OR 1 == 1 AND 2 == 3 THEN ...
|
||||
|
||||
:event-success:`Succeeds`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF 1 == 1 OR 1 == 1 AND 2 == 3 THEN ...
|
||||
|
||||
:event-fail:`Fails`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF 1 == 2 AND 1 == 1 OR 2 == 3 THEN ...
|
||||
|
||||
:event-success:`Succeeds`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF 1 == 1 AND 2 == 2 OR 2 == 3 THEN ...
|
||||
|
||||
In the first two examples only a single AND and OR operator is used. In the rest of the examples we see multiple AND and OR operators. pilight follows standard operator associativity rules in parsing AND and OR operators.
|
||||
|
||||
.. _Hooks:
|
||||
.. rubric:: Hooks
|
||||
|
||||
As we saw in our first examples, hooks can be used inside pilight rules. This can be useful to better structure and combine the various conditions of our rules. Let us create even more complex rules and see how hooks can change the outcome of a rule without changing the conditions.
|
||||
|
||||
:event-success:`Succeeds`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF 1 == 2 OR 2 == 3 AND 2 == 3 OR 1 == 1 THEN ...
|
||||
|
||||
:event-fail:`Fails`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF (1 == 2 OR 2 == 3) AND (2 == 3 OR 1 == 1) THEN ...
|
||||
|
||||
Operator
|
||||
--------
|
||||
|
||||
Various mathematical operators can be used to do calculations inside our rules. A list of these operators can be found further on in this manual. pilight follows standard operator associativity rules in parsing mathematical operators. Let us just show some basic self-explanatory examples:
|
||||
|
||||
:event-success:`Succeeds`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF 1 + 1 == 2 THEN ...
|
||||
|
||||
:event-success:`Succeeds`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF 2 % 2 == 0 THEN ...
|
||||
|
||||
:event-success:`Succeeds`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF 1 < 10 THEN ...
|
||||
|
||||
:event-fail:`Fails`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF 10 / 2 == 4 THEN ...
|
||||
|
||||
String and Concatenation
|
||||
------------------------
|
||||
|
||||
.. versionadded:: 8.1.0
|
||||
|
||||
pilight parses individual components inside a rule by looking at queues like spaces, comma's, hooks, and preserved words (e.g. actions or functions). In any case, pilight can be forces to parse any of these components as strings by enclosing them into quotes.
|
||||
|
||||
:event-success:`Succeeds`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF 1 + 1 == 3 - 1 THEN ...
|
||||
|
||||
In this case, pilight will compare the outcome of both formulas (which is 2) with each other for further parsing. We can also tell pilight to compare the same formula but now with strings:
|
||||
|
||||
:event-fail:`Fails`
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF '1 + 1' == '3 - 1' THEN ...
|
||||
|
||||
The same formula parsed with two strings will now fail because both strings are not equal anymore.
|
||||
|
||||
It is important to understand how to enforce string parsing when working with functions. The following example with give a syntax error, because the DATE_ADD function only expects two arguments delimited by a comma when the first argument is a datetime device. However, pilight sees the ``+1`` and ``HOUR`` as two separate string that normally should be delimited by a comma. Would be add that comma, we would still call the DATE_ADD function with the wrong parameter count.
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF DATE_ADD(datetime, +1 HOUR) == ...
|
||||
|
||||
The rule above should be written like this instead so the ``+1`` and ``HOUR`` are parsed like ``+1 HOUR``.
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF DATE_ADD(datetime, '+1 HOUR') == ...
|
||||
|
||||
Another issue arises when strings and device values or functions need to be combined like in this example:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF ... THEN label DEVICE alarm TO the alarm was trigger at DATE_FORMAT(datetime, %Y-%m-%d)
|
||||
|
||||
This rule will trigger a syntax error because the TO argument only expects one string, but five strings and a function were given. To make this into one string we need to use quotes and the concatenate ``.`` operator:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF ... THEN label DEVICE alarm TO 'the alarm was trigger at' . DATE_FORMAT(datetime, %Y-%m-%d)
|
||||
|
||||
Another scenario in which we want to explicitly cast a keyword into a string is given in this example:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF ... THEN label DEVICE label TO on
|
||||
|
||||
The ``label`` device is parsed by pilight as the label action because it's a reserved keyword. pilight does allow using label as a device name when casting it as a string like this:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF ... THEN label DEVICE 'label' TO on
|
||||
|
||||
As shown above, keywords or operators can be parsed into strings so pilight will ignore their default meaning.
|
||||
|
||||
Devices
|
||||
-------
|
||||
|
||||
pilight rules are quite useless if we cannot work with live data. This live data comes from our devices in and around the house. So let us say we have a switch called switch and we use this configured device to create a rule like this:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF switch.state IS on THEN ...
|
||||
|
||||
Depending on the actual state of the switch this rule will succeed or fail. Let us now use a dimmer device called *dimmer*.
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF dimmer.dimlevel > 10 THEN ...
|
||||
|
||||
Again, this rule will succeed or fail depending on the actual dimlevel of the configured dimmer device. These two examples can of course be combined:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF switch.state IS on AND dimmer.dimlevel > 10 THEN ...
|
||||
|
||||
As you can also see, the fields (*state* or *dimlevel*) we can use depends on the device we are using inside our rules. A switch does not have a *dimlevel* field but a dimmer does have a *state* field.
|
||||
|
||||
.. versionadded:: 8.0 rules based on received codes
|
||||
|
||||
Some devices are only used inside rules. Configuring them as explicit devices might sometimes feel a bit bloated. Therefor, pilight allows you to trigger rules based on received codes instead of device updates:
|
||||
|
||||
.. deprecated:: 8.1.0
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF archtech_switch.state IS on AND archtech_switch.id == 123456 AND arctech_switch.unit == 0 THEN ...
|
||||
|
||||
.. versionadded:: 8.1.0
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF archtech_switch.state == on AND archtech_switch.id == 123456 AND arctech_switch.unit == 0 THEN ...
|
||||
|
||||
In this case, an action will be triggered as soon as an ``archtech_switch`` code is received with a specific state, id, and unitcode. The ``arctech_switch`` doesn't have to be configured as an explicit device for this rule to work.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
In some cases, standard operators limit us in writing our rules. For example, calculating with time is a hideous task considering that hours do not go above 24, minute and seconds do not go above 60, and there are no negative numbers. Other functionality like randomization are also not possible in the standard event operators. This more advanced functionality is added in the form of function. A simple example:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF datetime.hour == RANDOM(21, 23) THEN ...
|
||||
|
||||
As we can see in this example we use the RANDOM function to check if the hour is either 21, 22, or 23. This allows us to trigger an action on random hours each day. Actions can also be nested for more advanced logic:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF datetime.hour == RANDOM(RANDOM(21, 22), RANDOM(22, 23)) THEN ...
|
||||
|
||||
The output of this RANDOM function is the same as with the previous example, but the idea should be clear.
|
||||
|
||||
Actions
|
||||
-------
|
||||
|
||||
Actions are the final goal of our rules. These actions tell pilight what should happen when certain conditions have been met. A rule can contain unlimited number of actions and each action can trigger an unlimited number of devices. First two examples of basic actions triggering a switch called *lamp* and a dimmer called *ambientLight*:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF ... THEN switch DEVICE lamp TO on
|
||||
IF ... THEN dim DEVICE ambientLight TO 10
|
||||
|
||||
Both actions only trigger a single device. However, if we wanted to trigger both device to just on we can combine them in a single action:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF ... THEN switch DEVICE lamp AND ambientLight TO on
|
||||
|
||||
As we can see here, the switch action takes at least the DEVICE and TO parameters. In case of the switch action, several values (as in devices) can be combined by separating them with ANDs. We can also combine dim and switch action would we want to switch the *lamp* to on and dim the *ambientLight* to dimlevel 10 based on the same condition:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF ... THEN switch DEVICE lamp TO on AND dim DEVICE ambientLight TO 10
|
||||
|
||||
We can combine an unlimited number of actions like this. Again we see that we use the AND to combine several actions. We can also switch several devices across several actions in a single rule. Let's say we have a relay connected to our television set called television that we want to turn on as well.
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF ... THEN switch DEVICE lamp AND television TO on AND dim DEVICE ambientLight TO 10
|
||||
|
||||
.. versionadded:: 8.1.0
|
||||
|
||||
As described earlier, actions can also be trigger based on a false condition like this:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF ... THEN switch DEVICE lamp AND television TO on ELSE dim DEVICE ambientLight TO 10 END
|
||||
|
||||
Using Device Parameters
|
||||
-----------------------
|
||||
|
||||
Device parameters can be used as rule input almost everywhere. Let us look at a few examples to demonstrate this:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF 1 == 1 THEN dim DEVICE dimmer TO dimmerMax.dimlevel FOR dimmerDuration.dimlevel
|
||||
|
||||
In this case we use three dimmer devices. One dimmer called dimmer that we actually want to dim, and two dimmers that changes the way this rule behaves. The dimmerMax device tells pilight to what value the dimmer should dim. The dimmerDuration device tells pilight how long it should take to reach that dimlevel. Another example:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF 1 == 1 THEN switch DEVICE lamp1 TO lamp2.state
|
||||
|
||||
In this case we want to switch the device lamp1 to the same state as the device lamp2.
|
||||
|
||||
Device parameters can also be used in function:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF RANDOM(randomLow.dimlevel, randomHigh.dimlevel) == 10 THEN switch DEVICE lamp1 TO on
|
||||
|
||||
In this case we use two dimmers called randomLow and randomHigh to dynamically change the input of the RANDOM function used in this rule. A comprehensive and advanced example:
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF sunriseset.sunset == DATE_FORMAT(DATE_ADD(datetime, +1 HOUR), \"%Y-%m-%d %H:%M:%S\", %H.%M) THEN switch DEVICE lamp1 TO on
|
||||
|
||||
.. versionchanged:: 8.1.0
|
||||
|
||||
.. code-block:: guess
|
||||
|
||||
IF sunriseset.sunset == DATE_FORMAT(DATE_ADD(datetime, '+1 HOUR'), '%Y-%m-%d %H:%M:%S', %H.%M) THEN switch DEVICE lamp1 TO on
|
||||
Reference in new issue
Block a user