Home > The MMRC Convention
The MMRC Convention
Version: 0.1.0
Date: 20 Feb 2019
Heavily based on the Homie Convention by David Gräff and contributors. Thank you!
MQTT Restrictions
MMRC communicates through MQTT and is hence based on the basic principles of MQTT topic publication and subscription.
Topic IDs
An MQTT topic consists of one or more topic levels, separated by the slash character (/
).
A topic level ID MAY contain lowercase letters from a
to z
, numbers from 0
to 9
as well as the hyphen character (-
).
A topic level ID MUST NOT start or end with a hyphen (-
).
The special character $
is used and reserved for MMRC attributes.
Payload
- Every MQTT message payload MUST be sent as a UTF-8 encoded string
- The value published as payload MUST be valid for the respective property/attribute type as per the list below
String
- String types are limited to 268,435,456 characters
- An empty string (“”) is a valid payload
Integer
- Integer types are UTF-8 encoded string literal representations of 64-bit signed whole numbers
- Integers range from -9,223,372,036,854,775,808 (-263) to 9,223,372,036,854,775,807 (263-1)
- The payload may only contain whole numbers and the negation character “-“. No other characters including spaces (“ “) are permitted
- A string with just a negation sign (“-“) is not a valid payload
- An empty string (“”) is not a valid payload
Float
- Float types are UTF-8 encoded string literal representations of 64-bit signed floating point numbers
- Floats range from 2-1074 to (2-2-52)*21023
- The payload may only contain whole numbers, the negation character “-“, the exponent character “e” or “E” and the decimal separator “.”, no other characters, including spaces (“ “) are permitted
- The dot character (“.”) is the decimal separator (used if necessary) and may only have a single instance present in the payload
- Representations of numeric concepts such as “NaN” (Not a Number) and “Infinity” are not a valid payload
- A string with just a negation sign (“-“) is not a valid payload
- An empty string (“”) is not a valid payload
Boolean
- Booleans must be converted to the string literals “true” or “false”
- Representation is case sensitive, e.g. “TRUE” or “FALSE” are not valid payloads.
- An empty string (“”) is not a valid payload
Enum
- Enum payloads must be one of the values specified in the format definition of the property
- Enum payloads are case sensitive, e.g. “Car” will not match a format definition of “car”
- Payloads should have leading and trailing whitespace removed
- An empty string (“”) is not a valid payload
Color
- Color payload validity varies depending on the property format definition of either “rgb” or “hsv”
- Both payload types contain comma separated whole numbers of differing restricted ranges
- The encoded string may only contain whole numbers and the comma character “,”, no other characters are permitted, including spaces (“ “)
- Payloads for type “rgb” contains 3 comma separated values of numbers with a valid range between 0 and 255. e.g. 100,100,100
- Payloads for type “hsv” contains 3 comma separated values of numbers. The first number has a range of 0 to 360, the second and third numbers have a range of 0 to 100. e.g. 300,50,75
- An empty string (“”) is not a valid payload
QoS and retained messages
The nature of the MMRC convention makes it safe about duplicate messages, so the recommended QoS for reliability is QoS 1. All messages defined in this convention MUST be sent as retained, UNLESS stated otherwise.
Last will
MQTT only allows one last will message per connection.
MMRC requires a last will for the mmrc
/ device ID
/ $state
attribute, see Device Lifecycle.
As a consequence a new MQTT connection to the broker is required per published device.
Base Topic
The root topic for this convention is mmrc/
.
Topology
Devices: An instance of a physical piece of hardware is called a device. For example, a car, an Arduino/ESP8266 or a coffee machine.
Nodes:
A device can expose multiple nodes.
Nodes are independent or logically separable parts of a device.
For example, a car might expose a wheels
node, an engine
node and a lights
node.
Properties:
A node can have multiple properties.
Properties represent basic characteristics of the node/device, often given as numbers or finite states.
For example the wheels
node might expose an angle
property.
The engine
node might expose a speed
, direction
and temperature
property.
The lights
node might expose an intensity
and a color
property.
Attributes:
Devices, nodes and properties have specific attributes characterizing them.
Attributes are represented by topic identifier starting with $
.
The precise definition of attributes is important for the automatic discovery of devices following the MMRC convention.
Examples: A device might have an IP
attribute, a node will have a name
attribute, and a property will have a unit
attribute.
Devices
mmrc
/device ID
: this is the base topic of a device. Each device must have a unique device ID which adhere to the ID format.
Device Attributes
mmrc
/device ID
/$device-attribute
:
The following device attributes are mandatory and MUST be send, even if it is just an empty string.
Topic | Description |
---|---|
$name | Friendly name of the device |
$state | See Device Lifecycle |
$nodes | Nodes the device exposes, separated by , for multiple ones. |
Optional topics include:
Topic | Description |
---|---|
$mmrc | The implemented MMRC convention version |
$type | An identifier for the type of device used (example “esp8266” or “Arduino Uno”) |
For example, a device with an ID of super-car
that comprises of a wheels
, engine
and a lights
node would send:
mmrc/super-car/$mmrc → "2.1.0"
mmrc/super-car/$name → "Super car"
mmrc/super-car/$nodes → "wheels,engine,lights[]"
mmrc/super-car/$type → "esp8266"
mmrc/super-car/$state → "ready"
Device Lifecycle
The $state
device attribute represents the current state of the device.
There are 6 different states:
init
: this is the state the device is in when it is connected to the MQTT broker, but has not yet sent all MMRC messages and is not yet ready to operate. This state is optional, and may be sent if the device takes a long time to initialize, but wishes to announce to consumers that it is coming online.ready
: this is the state the device is in when it is connected to the MQTT broker, has sent all MMRC messages and is ready to operate.disconnected
: this is the state the device is in when it is cleanly disconnected from the MQTT broker. You must send this message before cleanly disconnecting.sleeping
: this is the state the device is in when the device is sleeping. You have to send this message before sleeping.lost
: this is the state the device is in when the device has been “badly” disconnected. You must define this message as LWT (last will).alert
: this is the state the device is in when connected to the MQTT broker, but something wrong is happening. E.g. a sensor is not providing data and needs human intervention. You have to send this message when something is wrong.
Nodes
mmrc
/device ID
/node ID
: this is the base topic of a node. Each node must have a unique node ID on a per-device basis which adhere to the ID format.
Node Attributes
mmrc
/device ID
/node ID
/$node-attribute
:
All listed attributes are required. A node attribute MUST be one of these:
Topic | Description |
---|---|
$name | Friendly name of the Node |
$type | Type of the node |
$properties | Exposed properties, separated by , for multiple ones. |
For example, our engine
node would send:
mmrc/super-car/engine/$name → "Car engine"
mmrc/super-car/engine/$type → "V8"
mmrc/super-car/engine/$properties → "speed,direction,temperature"
Properties
-
mmrc
/device ID
/node ID
/property ID
: this is the base topic of a property. Each property must have a unique property ID on a per-node basis which adhere to the ID format. -
A property payload (e.g. a sensor reading) is directly published to the property topic, e.g.:
mmrc/super-car/engine/temperature → "21.5"
Property Attributes
mmrc
/device ID
/node ID
/property ID
/$property-attribute
:
The following attributes are required:
Topic | Description | Payload type |
---|---|---|
$name | Friendly name of the property. | String |
$datatype | The data type. See Payloads. | Enum: [integer, float, boolean,string, enum, color] |
The following attributes are optional:
Topic | Description | Payload type |
---|---|---|
$format | Specifies restrictions or options for the given data type | See below |
$settable | Settable (true ). Default is read-only (false ) |
Boolean |
$retained | Non-retained (false ). Default is Retained (true ). |
Boolean |
For example, our temperature
property would send:
mmrc/super-car/engine/temperature/$name → "Engine temperature"
mmrc/super-car/engine/temperature/$settable → "false"
mmrc/super-car/engine/temperature/$unit → "°C"
mmrc/super-car/engine/temperature/$datatype → "float"
mmrc/super-car/engine/temperature/$format → "-20:120"
mmrc/super-car/engine/temperature → "21.5"
Settable and retained:
-
Properties can be settable. For example, you don’t want your
temperature
property to be settable in case of a temperature sensor (like the car example), but to be settable in case of a thermostat. -
Properties can be retained. A property is retained by default. A non-retained property would be useful for momentary events (door bell pressed).
A combination of those flags compiles into this list:
- retained + non-settable: The node publishes a property state (temperature sensor)
- retained + settable: The node publishes a property state, and can receive commands for the property (by controller or other party) (lamp power)
- non-retained + non-settable: The node publishes momentary events (door bell pressed)
- non-retained + settable: The node publishes momentary events, and can receive commands for the property (by controller or other party) (brew coffee)
Format:
- For
integer
andfloat
: Describes a range of payloads e.g.10:15
- For
enum
:payload,payload,payload
for enumerating all valid payloads. - For
color
:rgb
to provide colors in RGB format e.g.255,255,0
for yellow.hsv
to provide colors in HSV format e.g.60,100,100
for yellow.
Property command topic
mmrc
/device ID
/node ID
/property ID
/set
: The device must subscribe to this topic if the property is settable (in case of actuators for example).
A MMRC controller publishes to the set
command topic with non-retained messages only.
The assigned and processed payload must be reflected by the MMRC device in the property topic mmrc
/ device ID
/ node ID
/ property ID
as soon as possible.
This property state update not only informs other devices about the change but closes the control loop for the commanding controller, important for deterministic interaction with the client device.
To give an example: A kitchen-light
device exposing the light
node with a settable power
property subscribes to the topic mmrc/kitchen-light/light/power/set
for commands:
mmrc/kitchen-light/light/power/set ← "true"
In response the device will turn on the light and upon success update its power
property state accordingly:
mmrc/kitchen-light/light/power → "true"
Broadcast Channel
MMRC defines a broadcast channel, so a controller is able to broadcast a message to all MMRC devices:
mmrc
/$broadcast
/level
:level
is an arbitrary broadcast identifier. It must adhere to the ID format.
For example, you might want to broadcast an alert
event with the alert reason as the payload.
Devices are then free to react or not.
In our case, every buzzer of your home automation system would start buzzing.
mmrc/$broadcast/alert ← "Intruder detected"
Any other topic is not part of the MMRC convention.