OHMq Specifications

Specifications for integrating third-party devices.

To facilitate the integration of third-party devices compatible with the MQTT protocol, specifications have been defined to easily communicate with an Ohm Automation home automation system.

MQTT Protocol

Communication occurs over the local network using the MQTT protocol and requires adherence to a specific format for topics and payloads.

Topics

Topics are generally defined as follows:

ohmq/<device_id>/<message_type>/<category>/<item_id>

Where:

  • ohmq: required prefix.

  • device_id: ID of the device to integrate, which must be unique. It is preferable to use the MAC address without the :.

  • message_type: defines the type of message, such as a state message (state) or command (command).

  • category: if the message is directed at a specific element, it indicates its category (e.g., board, output, etc.).

  • item_id: ID of the board element to which the message refers.

For example, the topic ohmq/a861a504ab/command/output/R1 refers to a message to execute a command on the output with ID R1 belonging to the device a861a504ab (a more specific example will follow).

item_id refers to the element ID, which is typically aligned with the coding assigned to it (e.g., written on the terminal); there are no strict constraints on the format of the ID, but it must be unique to the device. If the output represents the first relay on the board, its coding (and thus its ID) might be R1.

There is also a "universal" topic that all boards supporting OHMq specifications must subscribe to:

ohmq/universe

Messages sent to this topic must be handled by all devices, and in particular, all boards must support the Discovery.

Payload

The payload is generally in JSON format, and its content varies depending on the type of message.

The two main types of messages are:

  • state: state message.

  • command: command message.

Command Messages

Command messages must always contain the action field, which defines the operation to be performed. For example, to turn on an output, the message would be:

{
    "action": "on"
}

Important Command messages must always be sent with the retain setting set to false, as they should not be stored but only have value at the moment they are sent.

State Messages

State messages must be sent to notify the system of a change in the state of a given element. For example, after turning on a light, the message might be:

{
    "on": true,
    "value": 255
}

When a button is pressed, the message would be:

{
    "value": 1
}

Important State messages require the retain setting to be true, allowing the state to be recovered later.

Discovery

All boards must support this functionality as it is the official way to allow the system to discover the boards.

To ensure this function, boards must subscribe to the ohmq/universe topic and respond with their configuration to the following message:

{
    "action": "announce"
}

The configuration must be sent in JSON format and should look something like:

{
    "id": "a861a504ab",
    "name": "Example",
    "model": "ESP32",
    "ip": "192.168.0.x",
    "mac": "00:00:00:00:00",
    "supported_commands": ["find", "set_network", "set_name", "restart"],
    "outputs": [{"code": "R1", "n": 14}],
    "inputs": [{"code": "I1", "n": 16}],
    "sensors": [{"code": "S1", "n": 2}]
}

Fields of particular interest include:

  • supported_commands: indicates the types of commands supported by the board (e.g., find indicates the ability to be visually located, perhaps with a flashing or color-changing LED).

  • outputs / inputs: the list of outputs/inputs managed by the board.

The configuration message should be sent to the following topic:

ohmq/<device_id>/hi

mDNS

To enable quicker and easier implementation, support is provided for the _mqtt._tcp.local. service of mDNS, allowing connection to the broker using ohmb-master.local as the hostname and 1883 as the port.

Categories

The main categories are:

  • board: represents the board.

  • output: for managing outputs.

  • input: for managing digital inputs.

  • sensor: for managing analog inputs.

board

The topic for sending commands to the board is:

ohmb/<device_id>/command/board

Commands must always include the action parameter, which defines the operation to be performed. Here are the main operations and their corresponding payload.

find

This operation allows physically locating the board, useful if there are many devices and it is necessary to identify the correct one for wiring.

The message sent to the board will simply be:

{
    "action": "find"
}

After receiving this message, any action that allows the visual identification of the device can be performed, such as making a dedicated LED flash.

restart

This operation requires restarting the board, and the message sent will be:

{
    "action": "restart"
}

set_name

To ensure easy identification of the board in the configuration app, it is recommended to assign a name that allows for easy differentiation between boards. Therefore, the board must support the set_name command and implement a strategy for saving the assigned name.

The message received by the board will look like:

{
    "action": "set_name",
    "name": "Board 1"
}

output

Each output is defined as follows:

{
    "code": "R1",
    "n": 10
}

Where code indicates the user-visible coding, such as on the terminal, and n represents the pin number used on the microcontroller.

When sending the board configuration, it is essential to include at least the code parameter, as it is used for MQTT communication.

Commands

The topic for commands sent to an output is:

ohmb/<device_id>/command/output/<item_id>

For simplicity and convenience, the board can subscribe to the topic ohmb/<device_id>/command/output/+, using the _wildcard_ +.

As with the board, commands should be sent in JSON format with the action parameter, and include:

  • on: to activate.

  • off: to deactivate.

  • toggle: to change the state.

  • set: to set a value between 0 and 255 for analog outputs.

  • preset: to set the value of an analog output without activating it, so it takes the desired value only after a subsequent activation.

For example:

{
    "action": "set",
    "value": 120
}

State

The state of the output should be sent to the topic:

ohmb/<device_id>/state/output/<item_id>

It is crucial to send the state every time the element's value changes.

The state should be sent as follows:

{
    "is_on": false,
    "value": 210
}

For digital (binary) outputs, the value parameter will be 0 (when off) or 255 (when on).

The is_on parameter indicates whether the output is on or off. The value parameter must be sent for analog outputs, even when the element is off, as it helps restore the previous state upon reactivation.

input

Each input is defined as follows:

{
    "code": "I1",
    "n": 16
}

Where code indicates the user-visible coding, such as on the terminal, and n represents the pin number used on the microcontroller.

When sending the board configuration, it is essential to include at least the code parameter, as it is used for MQTT communication.

State

The state of the input should be sent to the topic:

ohmb/<device_id>/state/input/<item_id>

It is crucial to send the state every time the element's value changes.

The state should be sent as follows:

{
    "value": 1
}

Items in the input category are understood as digital (binary) inputs, so they only assume values 0 and 1. For analog inputs, refer to the sensor category.

sensor

Each sensor (analog input) is defined as follows:

{
    "code": "S1",
    "n": 2
}

Where code indicates the user-visible coding, such as on the terminal, and n represents the pin number used on the microcontroller.

When sending the board configuration, it is essential to include at least the code parameter, as it is used for MQTT communication.

State

The state of the sensor should be sent to the topic:

ohmb/<device_id>/state/sensor/<item_id>

For sensors, it is advisable to limit the frequency of data transmission to avoid overloading the MQTT Broker. Except for certain types of sensors (e.g., alarm sensors), there is generally no advantage in sending real-time state changes. It is therefore advisable to implement filters (e.g., exponential smoothing).

The state should be sent as follows:

{
    "value": 22.5
}

Last updated