MQTT AdapterAb
The MQTT adapter exposes an MQTT topic hierarchy for publishing messages and events to the 2Smart Standalone convention.
Configuration object format
module.exports = {
extension: { // required field
// transform describes adapter rules: how homie convention topics correlates with any other MQTT convention topics
// transform is an object or dictionary, where key is one of the subtopics of the next formats:
// - <node-id>/$<node-attribute>
// - <node-id>/<sensor-id>
// - <node-id>/<sensor-id>/$<attribute>
// - <node-id>/$<property-type>/<property-id>
// - <node-id>/$<property-type>/<property-id>/$<attribute>
// where:
// <node-attribute> - "state"
// <property-type> - "options" or "telemetry"
// <attribute> - one of the available property attributes
// examples:
// - camera/$state
// - camera/vertical-position
// - temperature/outside-temperature/$unit
// - temperature/$options/availability
// - temperature/$telemetry/inside-temperature/$unit
//
// key describe to which homie topic apply the rule
// the value by key is an object that has next format:
// {
// state: { // object that explain from which topic get the value and how to transform it before setting
// topic: 'your/mqtt/convention/state/topic', // topic from which get the value
// transformer: (value) => { // function that will be applied to the value received from the state topic
// return value;
// }
// },
// command: { // object that explain to which topic publish the value and how to transform it
// topic : 'your/mqtt/convention/command/topic' // topic to which publish the value
// transformer: (value) => { // function that will be applied to the value that we published to the command topic
// return value;
// }
// }
// }
transform: { // required field
'node-id/$state': {
state: {
topic: 'your/mqtt/convention/node/state/attribute/topic',
transformer: (state) => {
const statesMapping = {
'off': 'lost',
'on': 'ready'
};
return statesMapping[state];
}
}
},
'node-id/sensor-id': {
state: {
topic: 'your/mqtt/convention/sensor/state/topic',
transformer: (value) => {
// make some value modification if needed
return value;
}
},
command: {
topic: 'your/mqtt/convention/sensor/command/topic',
transformer: (value) => {
// make some value modification if needed
return value;
}
}
},
'node-id/sensor-id/$unit': { // may be another sensor attribute you want
state: {
topic: 'your/mqtt/convention/sensor/unit/state/topic',
transformer: (value) => {
// make some value modification if needed
return value;
}
},
command: {
topic: 'your/mqtt/convention/sensor/unit/command/topic',
transformer: (value) => {
// make some value modification if needed
return value;
}
}
},
'node-id/$options/option-id': {
state: {
topic: 'your/mqtt/convention/option/state/topic',
transformer: (value) => {
// make some value modification if needed
return value;
}
},
command: {
topic: 'your/mqtt/convention/option/command/topic',
transformer: (value) => {
// make some value modification if needed
return value;
}
}
},
'node-id/$options/option-id/$unit': { // may be another option attribute you want
state: {
topic: 'your/mqtt/convention/option/unit/state/topic',
transformer: (value) => {
// make some value modification if needed
return value;
}
},
command: {
topic: 'your/mqtt/convention/option/unit/command/topic',
transformer: (value) => {
// make some value modification if needed
return value;
}
}
},
'node-id/$telemetry/telemetry-id': {
state: {
topic: 'your/mqtt/convention/telemetry/state/topic',
transformer: (value) => {
// make some value modification if needed
return value;
}
},
command: {
topic: 'your/mqtt/convention/telemetry/command/topic',
transformer: (value) => {
// make some value modification if needed
return value;
}
}
},
'node-id/$telemetry/telemetry-id/$unit': { // may be another telemetry attribute you want
state: {
topic: 'your/mqtt/convention/telemetry/unit/state/topic',
transformer: (value) => {
// make some value modification if needed
return value;
}
},
command: {
topic: 'your/mqtt/convention/telemetry/unit/command/topic',
transformer: (value) => {
// make some value modification if needed
return value;
}
}
}
}
},
deviceConfig: { // required field
nodes: [ // required field, must contain one node object at least
{
id: 'node-id', // required field
name: 'node-name', // required field
sensors: [ // optional field(if is present, must contain one sensor object at least)
{
id: 'sensor-id', // required field
name: 'sensor-name',
dataType: 'integer',
settable: 'true',
retained: 'true'
},
// put another sensors here
],
options: [ // optional field(if is present, must contain one option object at least)
{
id: 'option-id', // required field
name: 'option-name',
dataType: 'integer',
settable: 'true',
retained: 'true'
},
// put another options here
],
telemetry: [ // optional field(if is present, must contain one telemetry object at least)
{
id: 'telemetry-id', // required field
name: 'telemetry-name',
dataType: 'integer',
settable: 'true',
retained: 'true'
},
// put another telemetry here
]
}
]
}
};
Example
As an example, the standard ESPHome firmware will be considered below.
Requirements
- Installed the latest version of ESPHome https://esphome.io/guides/installing_esphome.html
- Developer ESP32 board, for example esp32doit-devkit-v1.
- MQTT Explorer http://mqtt-explorer.com/
- Running 2Smart Standalone project with installed MQTT Adapter bridge
Uploading firmware to the board
Connect the devboard to your computer and follow this instruction: https://esphome.io/guides/getting_started_command_line.html
After the First uploading, change your configuration file livingroom.yaml:
esphome:
name: test
esp32:
board: esp32doit-devkit-v1
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
password: ""
ota:
password: ""
wifi:
ssid: "Your SSID Wi-Fi"
password: "Your PASS Wi-Fi"
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Test Fallback Hotspot"
password: "J5mUCG8cn2OD"
captive_portal:
mqtt:
id: mqtt_bridge
broker: Your2smartServerIP
port: 1883
username: Your2smartServerUsername
password: Your2smartServerPassword
switch:
- platform: gpio
name: "Blue led"
pin: 2
Flash your board using the following command:
esphome livingroom.yaml run
After successful uploading, you will see logs from the board. Connect to the broker with MQTT Explorer and look at the connected device.
Use configuration object format and look to MQTT Explorer. You can write a config for MQTT Adapter to adapt topics on the 2Smart Standalone convention.
Attention! An MQTT topic consists of one or more topic levels, separated by the slash character (/). A topic level ID MAY ONLY contain lowercase letters from a to z, numbers from 0 to 9, and the hyphen character (-).
module.exports = {
extension: {
transform: {
'switch/gpio2' : {
state : {
topic : 'test/switch/gpio2/state',
transformer : (value) => {
if (value === 'ON') return true;
return false;
}
},
command : {
topic : 'test/switch/gpio2/command',
transformer : (value) => {
if (value === 'true') return 'ON';
return 'OFF';
}
}
},
}
},
deviceConfig: {
nodes: [
{
id : 'switch',
name : 'switch',
sensors : [
{
id : 'gpio2',
name : 'gpio2',
dataType : 'boolean',
settable : 'true',
retained : 'true'
}
]
}
]
}
}
Save and run the MQTT Adapter bridge. If there are no errors, then will add a new device to the dashboard.