xiaomi-mqtt v0.5.2
xiaomi-mqtt
A Bridge between the Xiaomi Mi Smart Home Gateway and the Mqtt broker.
Xiaomi-mqtt exchanges data between the xiaomi gateway and the mqtt-broker at a low-level, principally based on the device sid (Security Identifier?). The automation and dashboard tasks are implemented at a higher level. Node-RED is the perfect tool to use for this purpose.
Installation
sudo npm install -g xiaomi-mqttInstallation from GitHub
Clone the source repository directly from GitHub to a local folder:
git clone https://github.com/cflurin/xiaomi-mqtt.gitLocal Installation:
cd xiaomi-mqtt
npm installConfiguration
Copy the config.json file to the .xiaomi-mqtt folder inside of your home folder.
mkdir ~/.xiaomi-mqtt
cp config.json ~/.xiaomi-mqtt/On Linux the full path for your config.json would be ~/.xiaomi-mqtt/config.json.
Edit ~/xiaomi-mqtt/config.json to fit your requirements:
{
"xiaomi": {
"serverPort": 9898,
"multicastAddress": "224.0.0.50",
"multicastPort": 4321,
"password": "FFF..."
},
"mqtt": {
"url": "mqtt://127.0.0.1",
"port": 1883,
"username": "foo",
"password": "bar",
"topic_mode": "short",
"topic_prefix": "xiaomi"
},
"loglevel": "info",
"heartbeatfreq": 6,
"dataFormat": "parsed"
}"topic_mode": <"short"> | <"full"> | <"both">shortdefaultfullallow you to do some topic filtering directly on client side.both2 topics are sent,shortandfull.
"loglevel": <"debug"> | <"info"> | <"warn"> | <"error">Replace 127.0.0.1 with the address of your mqtt broker.
Set dataFormat to raw to get data without parsing.
By default the gateway send heartbeat every 10s which can do some pollution when testing/debug, the counter parameter in config named heartbeatfreq avoid this, in the example above set to 6 means only send a MQTT message each 6 heartbeat, so each 60s. Note this apply only to gateway heartbeat not the device's one.
Usage (global installation)
Use xiaomi-mqtt or xm to run xiaomi-mqtt.
Use ctrl c to stop xiaomi-mqtt.
Usage (local installation)
In the xiaomi-mqtt folder.
Use npm start to run xiaomi-mqtt.
Use ctrl c to stop xiaomi-mqtt.
mqtt API
If the configuration option topic_mode is set to short or both, the data (payload) is sent/received in a JSON format using following topics:
- xiaomi/from
- xiaomi/to/read
- xiaomi/to/write
- xiaomi/to/get_id_list
Note: Have look at: How to benefit of the full topic option
Howto examples
At start and stop xiaomi-mqtt sends following messages.
start
topic: xiaomi/from
payload: {"cmd":"xm","msg":"xiaomi-mqtt started."}and
topic: xiaomi/from
payload:
{
"cmd":"get_id_list_ack",
"sid":"fff...",
"data":["158d00017118ac","158d0001a2eb66","158d0001f35b90","158d0001e52516"]
}stop
topic: xiaomi/from
payload: {"cmd":"xm","msg":"xiaomi-mqtt stopped."}heartbeat
gateway
topic: xiaomi/from
payload:
{
"cmd": "heartbeat",
"model": "gateway",
"sid": "fff...",
"short_id": "0",
"token": "v4GeGCO9TBpTUlVy",
"data": {
"ip": "127.0.0.1"
}
}cube
topic: xiaomi/from
payload:
{
"cmd": "heartbeat",
"model": "cube",
"sid": "158d0003102db5",
"short_id": 46605,
"data": {
"voltage": 2985
}
}reporting
Xiaomi-mqtt sends periodically or on events device reports.
gateway
topic: xiaomi/from
payload:
{
"cmd": "report",
"model": "gateway",
"sid": "fff...",
"short_id": 0,
"data": {
"rgb": 0,
"illumination": 1292
}
}sensor_ht
topic: xiaomi/from
payload:
{
"cmd":"report",
"model":"sensor_ht",
"sid":"158d0001a2eb66",
"short_id":30124,
"data":{"voltage":3005,"temperature":16.7,"humidity":null}
}"data": {"voltage":3005,"temperature":16.7,"humidity":null}
or
"data": {"voltage":3005,"temperature":null,"humidity":51.7}magnet
topic: xiaomi/from
payload:
{
"cmd": "report",
"model": "magnet",
"sid": "158d0001f3651f",
"short_id": 57029,
"data": {
"status": "close"
}
}"status": "close", "open"switch
topic: xiaomi/from
payload:
{
"cmd":"report",
"model":"switch",
"sid":"158d0001f35b90",
"short_id":46517,
"data":{"status":"click"}
}"status": "click", "double_click", "long_click_press", "long_click_release"86sw2
topic: xiaomi/from
payload:
{
"cmd":"report",
"model":"86sw2",
"sid":"158d0001f55b88",
"short_id":33911,
"data":{"channel_0":"click"}
}"data":{"channel_0":"click"}
or
"data":{"channel_1":"click"}cube
topic: xiaomi/from
payload:
{
"cmd":"report",
"model":"cube",
"sid":"158d0003102db5",
"short_id":46605,
"data":{"status":"move"}
}"status": "move", "flip90", "flip180", "tape_twice", "shake_air", "alert"
or
"rotate": "99,999", "-99.999"read
gateway
topic: xiaomi/to/read
payload: {"sid":"fff..."}response
topic: xiaomi/from
payload:
{
"cmd":"read_ack",
"model":"gateway",
"sid":"fff...",
"short_id":0,
"data":{"rgb":0,"illumination":1292,"proto_version":"1.0.9"}
}sensor_ht
topic: xiaomi/to/read
payload: {"sid":"158d00017118ac"}response
topic: xiaomi/from
payload:
{
"cmd":"read_ack",
"model":"sensor_ht",
"sid":"158d00017118ac",
"short_id":48290,
"data":{"voltage":2985,"temperature":19,"humidity":46.3}
}switch
topic: xiaomi/to/read
payload: {"sid":"158d0001f35b90"}response
topic: xiaomi/from
payload:
{
"cmd":"read_ack",
"model":"switch",
"sid":"158d0001f35b90",
"short_id":46517,
"data":{"voltage":3112}
}write
topic: xiaomi/to/write
payload:
{
"cmd": "write",
"model": "gateway",
"sid": "fff...",
"data": {
"rgb": "1000FF00"
}
}Note: rgb = brightness green - each hex 00 to FF
response
topic: xiaomi/from
payload:
{
"cmd":"write_ack",
"model":"gateway",
"sid":"fff...",
"short_id":0,
"data":{"rgb":268500736,"illumination":1292,"proto_version":"1.0.9"}
}get_id_list:
topic: xiaomi/to/get_id_list
payload: {"sid":"fff..."}Note: sid = gateway sid.
response
topic: xiaomi/from
payload:
{
"cmd":"get_id_list_ack",
"sid":"fff...",
"data":["158d00017118ac","158d0001a2eb66","158d0001f35b90","158d0001e52516"]
}Tested devices (models):
- gateway
- sensor_ht
- motion
- sensor_motion.aq2
- sensor_wleak.aq1
- magnet
- switch
- 86sw1
- 86sw2
- cube
- ctrl_neutral1
- ctrl_neutral2
- ctrl_ln1.aq1
Note: Untested devices using the same format will also send a payload.
Node-RED examples
basic

write gateway

Flow:
[{"id":"9339669d.8e38b8","type":"mqtt out","z":"d0877ed4.9e0cc","name":"","topic":"xiaomi/to/write","qos":"","retain":"","broker":"325f5be5.555734","x":560,"y":480,"wires":[]},{"id":"c508a302.61467","type":"ui_colour_picker","z":"d0877ed4.9e0cc","name":"","label":"gateway color","group":"4d5fcade.c527d4","format":"hex","outformat":"string","showSwatch":true,"showPicker":false,"showValue":true,"showAlpha":false,"showLightness":true,"dynOutput":"false","order":0,"width":0,"height":0,"passthru":true,"topic":"","x":220,"y":480,"wires":[["dcd9ac95.fd93"]]},{"id":"dcd9ac95.fd93","type":"template","z":"d0877ed4.9e0cc","name":"map","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{\n \"cmd\": \"write\",\n \"model\": \"gateway\",\n \"sid\": \"fff...\",\n \"data\": {\n \"rgb\": \"10{{payload}}\"\n }\n}","output":"json","x":390,"y":480,"wires":[["9339669d.8e38b8"]]},{"id":"325f5be5.555734","type":"mqtt-broker","z":"","broker":"127.0.0.1","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""},{"id":"4d5fcade.c527d4","type":"ui_group","z":"","name":"Xiaomi","tab":"f3d46e49.beaec","order":1,"disp":true,"width":"6"},{"id":"f3d46e49.beaec","type":"ui_tab","z":"","name":"Main","icon":"dashboard","order":1}]
Flow:
[{"id":"aacbdba0.0519f8","type":"inject","z":"d0877ed4.9e0cc","name":"doorbell","topic":"","payload":"{\"cmd\":\"write\",\"model\":\"gateway\",\"sid\":\"fff...\",\"short_id\":0,\"key\":\"8\",\"data\":{\"mid\":10}}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":580,"wires":[["83a2b4f.eb0d748"]]},{"id":"8f56c43e.16c048","type":"inject","z":"d0877ed4.9e0cc","name":"police","topic":"","payload":"{\"cmd\":\"write\",\"model\":\"gateway\",\"sid\":\"fff...\",\"short_id\":0,\"key\":\"8\",\"data\":{\"mid\":1}}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":620,"wires":[["83a2b4f.eb0d748"]]},{"id":"83a2b4f.eb0d748","type":"mqtt out","z":"d0877ed4.9e0cc","name":"","topic":"xiaomi/to/write","qos":"","retain":"","broker":"325f5be5.555734","x":340,"y":580,"wires":[]},{"id":"325f5be5.555734","type":"mqtt-broker","z":"","broker":"192.168.0.35","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""}]