.. _caspia_meadow_protocol: ############### Meadow Protocol ############### *********** What is it? *********** Meadow is a protocol built on top of MQTT used for communication between core parts of Caspia's home automation system. Generally, there are two types of meadow clients. *Gateways* - those, who provide access to some services (lights, heating...) and *Consumers* - those, who just want to control those services. Each service has some characteristics. For example, service of a type `light` has characteristic `is_on` and optinally `brightness`, `saturation`, `hue`. Characteristic is like a variable - it has its *type* (json, number, string, ...), *permissions* (writable, readable, notifiable) and some other metadata. *Consumers* can read a value of a characteristic, write a value to it or subscribe for its changes (notifications). ************* Specification ************* Service ======= Service is identified by a name. Names are strings and *must* follow this from: ``type`` @ ``path`` * ``type`` is the service's type (for example "light") * ``path`` denotes the (usually) physical location of the service (for example *basement.kitchen.table*). The only allowed letters are ``[a-z]``, ``_`` and ``.``. Examples: - ``light@basement.kitchen.table`` - ``button@basement.kitchen.entrance`` - ``node@basement.kitchen.entrance`` Grammar: | ``name`` -> ``type`` @ ``path`` | ``type`` -> *[a-z,-]+* | ``path`` -> ``path-component`` | ``path-component`` . ``path`` | ``path-component`` -> *[a-z,_]+* Subscribing for a characteristic notifications ============================================== Notifications are published (by gateway) to topic ``notification/{service}/{characteristic}``. - Standard notification .. code-block:: yaml { "val": , "extra": { } # value metadata } - Error notification (``val`` key is missing) .. code-block:: yaml { "code": 104, "message": "sensor failure", "extra": { } # dictionary with error metadata } Reading a value =============== 1. Consumer generates a unique identifier ``req_id`` (UUID) for this transaction. #. Consumer subscribes to a topic ``response/{service}/{characteristic}/{req_id}`` where it expects a response from the service's gateway. #. Consumer publishes read request to a topic ``read/{service}/{characteristic}``: .. code-block:: yaml { "req_id": } #. Gateway is subscribed to the ``read/{service}/{Characteristic}``, so it processes the request and publishes a response to the topic ``response/{service}/{characteristic}/{req_id}``. - On *success* .. code-block:: yaml { "val": , "extra": { } # dictionary with optional metadata } - On *error* (``val`` key is missing) .. code-block:: yaml { "code": -1, "message": "unknown error", "extra": { } # dictionary with error metadata } #. Consumer unsubscribes from the ``response...`` topic. Writing a value =============== 1. Consumer generates a unique identifier ``req_id`` (UUID) for this transaction. 2. Consumer subscribes to a topic ``response/{service}/{characteristic}/{req_id}`` where it expects a response from the service's gateway. 3. Consumer publishes write request to a topic ``write/{service}/{characteristic}``: .. code-block:: yaml { "req_id": , "val": , "extra": { } # optional write metadata } 4. Gateway is subscribed to the ``write/{service}/{Characteristic}``, so it processes the request and publishes a response to the topic ``response/{service}/{characteristic}/{req_id}``. - On *success* .. code-block:: yaml { } - On *error* (``val`` key is missing) .. code-block:: yaml { "code": -1, "message": "unknown error", "extra": { } # dictionary with error metadata } #. Consumer unsubscribes from the ``response...`` topic. .. todo:: Add docs how to publish a gateway, request rules, etc.