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

    {
        "val": <value>,
        "extra": { }  # value metadata
    }
    
  • Error notification (val key is missing)

    {
        "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.

  2. Consumer subscribes to a topic response/{service}/{characteristic}/{req_id} where it expects a response from the service’s gateway.

  3. Consumer publishes read request to a topic read/{service}/{characteristic}:

    { "req_id": <req_id> }
    
  4. 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

      {
          "val": <value>,
          "extra": { } # dictionary with optional metadata
      }
      
    • On error (val key is missing)

      {
          "code": -1,
          "message": "unknown error",
          "extra": { } # dictionary with error metadata
      }
      
  5. 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}:

    {
        "req_id": <req_id>,
        "val": <value>,
        "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

      { }
      
    • On error (val key is missing)

      {
          "code": -1,
          "message": "unknown error",
          "extra": { } # dictionary with error metadata
      }
      
  5. Consumer unsubscribes from the response... topic.

Todo

Add docs how to publish a gateway, request rules, etc.