Skip to content

Commit

Permalink
notifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
root committed Jun 9, 2018
1 parent bdbc007 commit 242c6f9
Show file tree
Hide file tree
Showing 2 changed files with 283 additions and 19 deletions.
22 changes: 11 additions & 11 deletions doc/items.rst
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@ All units have oids like **unit:group/unit_id** i.e. *unit:light/room1/lamp1*
For the synchronization via :ref:`mqtt<MQTT>`, the following subjects are used
for units

* **[prefix/]unit/<group>/<unit_id>/status** unit status, integer
* **[prefix/]unit/<group>/<unit_id>/value** unit value
* **[prefix/]unit/<group>/<unit_id>/nstatus** new unit status (different from
* **[space/]unit/<group>/<unit_id>/status** unit status, integer
* **[space/]unit/<group>/<unit_id>/value** unit value
* **[space/]unit/<group>/<unit_id>/nstatus** new unit status (different from
status if action is started), integer
* **[prefix/]unit/<group>/<unit_id>/nvalue** new unit value
* **[prefix/]unit/<group>/<unit_id>/action_enabled** are actions enabled for the
* **[space/]unit/<group>/<unit_id>/nvalue** new unit value
* **[space/]unit/<group>/<unit_id>/action_enabled** are actions enabled for the
unit or not (boolean, True/False)

Unit parameters
Expand Down Expand Up @@ -264,8 +264,8 @@ All sensors have oids like **sensor:group/sensor_id** i.e. *sensor:temp/t1*
For the synchronization via :ref:`mqtt<MQTT>`, the following subjects are used
for units

* **[prefix/]sensor/<group>/<sensor_id>/status** sensor status, integer
* **[prefix/]sensor/<group>/<sensor_id>/value** sensor value
* **[space/]sensor/<group>/<sensor_id>/status** sensor status, integer
* **[space/]sensor/<group>/<sensor_id>/value** sensor value

Sensor parameters
~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -336,10 +336,10 @@ All logic variables have oids like **lvar:group/lvar_id** i.e.
For the synchronization via :ref:`mqtt<MQTT>`, the following subjects are used
for units

* **[prefix/]lvar/<group>/<lvar_id>/status** lvar status, integer
* **[prefix/]lvar/<group>/<lvar_id>/value** lvar value
* **[prefix/]lvar/<group>/<lvar_id>/set_time** last set time (unix timestamp)
* **[prefix/]lvar/<group>/<lvar_id>/expires** value expiration time (seconds)
* **[space/]lvar/<group>/<lvar_id>/status** lvar status, integer
* **[space/]lvar/<group>/<lvar_id>/value** lvar value
* **[space/]lvar/<group>/<lvar_id>/set_time** last set time (unix timestamp)
* **[space/]lvar/<group>/<lvar_id>/expires** value expiration time (seconds)

LVar parameters
~~~~~~~~~~~~~~~
Expand Down
280 changes: 272 additions & 8 deletions doc/notifiers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ the logic components to work correctly with the old value until the sensor
status data is updated correctly and sensor is back online or until the data is
expired.

action - unit action events
~~~~~~~~~~~~~~~~~~~~~~~~~~~
action - unit and macro action events
~~~~~~~~~~~~~~~~~~~~~~~~~~~----------

Every time the :ref:`unit<unit>` :ref:`action<uc_action>` changes its
:ref:`status<uc_queues>`, the notification server receives "action" event
notification.
Every time the :ref:`unit<unit>` :ref:`action<uc_action>` or :doc:`macro
action</lm/macros>` changes its :ref:`status<uc_queues>`, the notification
server receives "action" event notification.

The notification sends data similar to ones that can be obtained using UC API
ref:`result<uc_result>` command.
Expand Down Expand Up @@ -70,7 +70,7 @@ format:
(or hostname by default)
* **LEVEL** 10 - DEBUG, 20 - INFO, 30 - WARNING, 40 - ERROR or 50 for CRITICAL
* **PRODUCT_CODE** "uc" for :doc:`/uc/uc`, "lm" for :doc:`/lm/lm`, "sfa" for
:doc:`/sfa/sfa/`
:doc:`/sfa/sfa`
* **MODULE** a specific system module, e. g. 'unit'
* **MODULE_THREAD** the module thread, e. g. "_t_action_processor_lamp1"

Expand All @@ -84,7 +84,7 @@ Configuring the notification endpoints

The configuration is done using the :doc:`console commands</cli/cli>`
uc-notifier for :doc:`/uc/uc`, lm-notifier for :doc:`/lm/lm` and sfa-notifier
for :doc:`/sfa/sfa/`. Therefore, even if two controllers are set up in the same
for :doc:`/sfa/sfa`. Therefore, even if two controllers are set up in the same
folder on the same server, they have different notification endpoints
configurations.

Expand All @@ -104,7 +104,7 @@ target.
mqtt eva_1 Enabled eva:test@localhost:1883/lab
======== ======== ======== ========

Let's test the endpoint (for mqtt the system will try to publish [prefix]/test)
Let's test the endpoint (for mqtt the system will try to publish [space]/test)

# uc-notifier test -i eva_1
notifier eva_1 test passed
Expand Down Expand Up @@ -145,3 +145,267 @@ Except endpoint configuration, notifiers have some additional params:
* **collect_logs** this should be set to "true" for :doc:`/sfa/sfa`
:ref:`MQTT<mqtt>` notifiers if you want to collect the logs of the other
controllers and have the records available locally in SFA.

Setting up MQTT QoS
~~~~~~~~~~~~~~~~~~~

You may specify different :ref:`MQTT<mqtt>` QoS for the events with the
different subjects.

To set the same QoS for all events, use command:

uc-notifier set_prop -p qos -v Q

(where Q = 0, 1 or 2)

To set QoS for the specified subject, use command:

uc-notifier set_prop -p qos.<subject> -v Q

i.e.

uc-notifier set_prop -p qos.log -v 0

Quick facts about MQTT QoS:

* **0** the minimum system/network load but does not guarantee the message
delivery
* **1** guarantees the message delivery
* **2** the maximum system/network load which provides 100% guarantee of the
message delivery and the guarantee the particular message has been delivered
only once and have no duplicates.

Subscribing the notifier to events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

By default, the new notifier is not subscribed to any events. You can
review all the subscriptions using "get_config" command.

To subscribe notifier to the new subject, run:

uc-notifier subscribe <-p subject> [args]

(where subject is "state", "log" or "action")

When subscribing notifier to logs, you may use optional *-l LEVEL* param (10 -
DEBUG, 20 - INFO (by default), 30 - WARNING, 40 - ERROR, 50 - CRITICAL).

When subscribing notifier to state changes, you may also always specify item
types (comma separated) or use '#' for all types with *-v TYPES* param, groups
with *-g GROUPS*. Optionlly you may specify the particular items to subscribe
notifier to with *-I ITEMS*.

.. note::

For the each "state" subscription you must specify eitner types and groups
or item IDs.

Example:

uc-notifier subscribe -i test2 -p state -v '#' -g 'hall/#'

subscribes the notifier to the events of the status change of all the items in
the 'hall' group subgroups.

Subscription to "action" requires the params similar to "state". Additionally,
*-a '#'* should be specified to subscribe to all the action statuses or *-a
state1,state2,state3...* to subscribe to the certain statuses of the
:ref:`queued actions:<uc_queues>`.

In example, the following command will subscribe the notifier to the events of
all failed actions:

.. code-block:: bash
uc-notifier subscribe -i test2 -p action -v '#' -g '#' -a dead,refused,canceled,ignored,failed,terminated
Once created, the subscription can't be changed, but the new subscription to
the same subject replaces the configuration of the previous one.

To unsubscribe the notifier from the subject, run:

uc-notifier unsubscribe [-p subject]

if the subject is not specified, the notifier will be unsubscribed from all
notification subjects.

The countroller should be restarted to apply the new subscriptions
configuration.

.. _mqtt:

MQTT (mqtt)
-----------

MQTT is a major endpoint type used to link several EVA subsystems. For
instance, it enables :doc:`/lm/lm` and :doc:`/sfa/sfa` controllers to
receive the latest item status from :doc:`/uc/uc` servers. We test and use EVA
with `mosquitto http://mosquitto.org/`_ server, but you can use any server
supporting `MQTT http://mqtt.org/`_ protocol. As far as MQTT is the major type
of the EVA notification system, let us examine it detailed.

MQTT and state notifications
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:doc:`Items<items>` form in MQTT a subject hive so-called "EVA hive". Hive may
have a space i.e. "plant1/" to separate several EVA systems which use the same
MQTT server.

Item is state is stored in a hive with subject *SPACE/item_type/group/item_id*
and contains the item state data and some configuration params in the
:doc:`subtopics<items>`.

MQTT and action notifications
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:ref:`Unit<unit>` action notifications are sent to the topic

SPACE/unit/group/UNIT_ID/action

:doc:`Logic macros</lm/macros>` action notifications are sent to the topic

SPACE/lmacro/group/UNIT_ID/action

These messages include the serialized action information in JSON format. As
soon as action state is changed, the new notification is being sent.

MQTT and log notifications
~~~~~~~~~~~~~~~~~~~~~~~~~~

Log messages are sent to the MQTT server as JSON with the following MQTT
subject:

SPACE/log

It means that the common log subject is created for the one EVA space.

Any EVA server (usually it's a job for `/sfa/sfa`) can be a log collector,
collecting the reports from MQTT server (space/log), pass them further via the
local notification system and have available via API. In order to enable this
function, set param *collect_logs* to true in the notifier configuration:

sfa-notifier set_prop -i eva_1 -p collect_logs -v true

Use MQTT for updating the item states
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

MQTT is the only EVA notifier type performing two functions at once: both
sending and receiving messages.

:doc:`items` can use MQTT to change their state (for synchronization) if the
external controller can send active notifications under this protocol.

The items change their state to the state received from MQTT, if someone sends
it's state update to EVA hive with "status" or "value" subtopics.

To let the item receive MQTT state updates, set it's **mqtt_update**
configuration param to the local MQTT notificator ID, as well additionally
Optionally specify MQTT QoS using a semicolon (i.e. *eva_1:2*). QoS=1 is used by
default.

One item an be subscribed to the one MQTT notifier to get the state updates, but
different items on the same controller can be subscribed to the different MQTT
notifiers.

When remote controller is connected, :doc:`/lm/lm` and :doc:`/sfa/sfa` have
copies of the remote items and it's better to sync them in real time. The MQTT
notifier where state updates are received from is set in **mqtt_update**
configuration param of the connected controller, the value
**mqtt_update_default** from *lm.ini*/*sfa.ini* is used by default.

MQTT and unit actions
~~~~~~~~~~~~~~~~~~~~~

MQTT can be also used as API to send the actions to the :ref:`units<unit>`. In
order to send the action to the unit via MQTT, send the message with the
following subject: *[space]/<group>/<unit_id>/control* and the following body:

status value priority

value and priority parameters are optional. If value should be omitted, set it
to "none".

In case you need 100% reliability, it is not recommended to control units via
MQTT, because MQTT can only guarantee that the action has been received by MQTT
server, but not by the target :doc:`/uc/uc`. Additionally, you cannot obtain
action uuid and further monitor it.

To let unit responding to MQTT control messages, set it's configuration param
**mqtt_control** to the local MQTT ID. You may specify QoS as well via
semicolon, similary as for **mqtt_update**.

HTTP/POST (http-post)
---------------------

HTTP notifications can be transferred to servers which, for some reasons,
cannot work with MQTT in realtime, i.e. servers containing the third-party or
your own PHP web applications.

http-post notifier sends data to the URI specified in the configuration with
POST method, as www-form and in the following format:

* **k** notification key the remote app may use to authorize the sender
* **subject** event subject
* **data** event data array in JSON format

Your application must respond with the JSON if the event has ben porcessed
successfully:

.. code-block:: json
{ "result" : "OK" }
or if your app failed to process it:

.. code-block:: json
{ "result" : "ERROR" }
The event *data* field is always an array and may can contain either one
event or the several ones.

When EVA controllers test remote http-post endpoint, it sends the notification
with subject="test" and the remote app should respond with { "result": "OK" }.

HTTP/GET (http)
~~~~~~~~~~~~~~~

As with http-post, event notification can be transferred to the remote apps
using HTTP/GET method. In this case the only one event notification can be sent
at once.

ET notifications are similar to POST except that k (key), s (subject of the
message) and all the data fields are transferred directly in the query string.

Example:

.. code-block:: bash
GET http://server1/notify.php?k=secretkey&s=state&group=env&id=temp1&status=1&value=29.555&type=sensor&space=office
Your application must respond with the JSON if the event has ben porcessed
successfully:

.. code-block:: json
{ "result" : "OK" }
or if your app failed to process it:

.. code-block:: json
{ "result" : "ERROR" }
When EVA controllers test remote http-post endpoint, it sends the notification
with subject="test" and the remote app should respond with { "result": "OK" }.

http notifier configuration is similar to http-post one, except that the latter
has one additional parameter: **stop_on_error**. If it's set to true, when the
multiple notifications are being sent at once, the system will stop sending
them as soon as one of the notifications fails to be delivered.

HTTP/GET (http) is the simplest type of the notification server for the
personal use. It requires neither knowledge of some additional protocols nor
JSON decoding, your app may obtain all the data from the request query string.

0 comments on commit 242c6f9

Please sign in to comment.