This README was generated with Nim to Markdown
Library for working with Xiaomi IOT devices.
- nim >= 0.19.0
- multicast >= 0.1.1
- nimcrypto >= 0.3.2
Xiaomi IOT devices are supported. The following devices has been thoroughly tested:
You can interact with the Xiaomi devices in 3 ways:
- Read - Asking for a status, e.g. is the door open (door sensor)
- Report - Awaiting an action, e.g. when the door opens, it sends a notification (door sensor)
- Write - Send a message to the device (only some devices accepted this), e.g. play a sound (gateway)
All you Xiaomi devices are connected to a gateway. It is through this gateway, we are communicating with each of the devices. Each devices is identified with a SID.
But before we get started, you need to acquire your devices SID.
Get the gateways SID
import xiaomi
xiaomiConnect()
echo xiaomiGatewayGetSid()
Get the devices SID
import xiaomi
xiaomiConnect()
echo xiaomiDiscover()
There are numerous ways to read. Some proc's just read the next message, some waits for a specific device, etc.
Read the next message sent
import xiaomi
xiaomiConnect()
echo xiaomiReadMessage()
Request a device status and read the reply
import xiaomi
xiaomiConnect()
echo xiaomiReadDevice("device-SID")
Read the next message from custom-x This will await that the cmd = "heartbeat" and the model = "gateway".
import xiaomi
xiaomiConnect()
echo xiaomiReadCustom("heartbeat", "gateway")
Read messages forever
import xiaomi
xiaomiConnect()
xiaomiListenForever()
For PIR sensors you will receive a report, when there's motion or there hasn't been motion for 300 seconds.
For magnet sensors you will receive a report when they are connected (close
) and disconnected (open
).
Read next report
import xiaomi
xiaomiConnect()
echo xiaomiReportAck()
Read next report for device
import xiaomi
xiaomiConnect()
echo xiaomiReadReport("device-SID")
To write to a device, we need to exchange an encrypted key with the gateway based on an ever-changing token. We are utilizing nimcrypto AES CBC 128 to do this.
But before we can generate the key, you need to gather you gateway password. Follow this guide Domotics or the bullets below. Remember to write the key down.
- Install the Xiaomi app
- Set the region to Mainland China under Settings->Locale
- You can set the language to English, even though the region is China
- Sign in/Make an account
- Select your Gateway in the app
- Tap the 3 dots in top right corner
- Click About
- Tap on the version repeatedly until a new menu appear
- Click on Wireless communication protocol
- Enable the this and write down you password and press Ok
If you need to write to a device, insert your password in the global variable at the top of your code:
xiaomiGatewayPassword = "secretPassword"
The gateways token is changing all the time. You therefore need to the generate the encrypted key before each writing.
This is done with:
xiaomiTokenRefresh()
xiaomiSecretUpdate()
OR
xiaomiTokenRefresh(true)
OR while writing
xiaomiWrite("device-SID", "message", true)
There are 2 main elements you can write to the gateway - the light and sound.
Light writing
import xiaomi
xiaomiGatewayPassword = "secretPassword"
xiaomiTokenRefresh()
xiaomiWrite(xiaomiGatewaySid, "\"rgb\": 4294914304")
Light options
To assign a RGB color, you have to use the Android() color format.
You can convert HEX to Android() at this website.
- Red =
4294914304
- Green =
4283359807
- Purple =
4283637131
- Yellow =
4292211292
- Blue =
4283327469
- Off =
0
Sound writing
import xiaomi
xiaomiGatewayPassword = "secretPassword"
xiaomiTokenRefresh()
xiaomiWrite(xiaomiGatewaySid, "\"mid\": 7, \"vol\": 4")
Sound options
The volume is in percentage, whereas 10 = 100%.
The following sounds are available:
Alarms:
- 0 - Police car 1
- 1 - Police car 2
- 2 - Accident
- 3 - Countdown
- 4 - Ghost
- 5 - Sniper rifle
- 6 - Battle
- 7 - Air raid
- 8 - Bark
Doorbells
- 10 - Doorbell
- 11 - Knock at a door
- 12 - Amuse
- 13 - Alarm clock
Alarm clock
- 20 - MiMix
- 21 - Enthusiastic
- 22 - GuitarClassic
- 23 - IceWorldPiano
- 24 - LeisureTime
- 25 - ChildHood
- 26 - MorningStream
- 27 - MusicBox
- 28 - Orange
- 29 - Thinker
proc xiaomiSecretUpdate*(password = xiaomiGatewayPassword, token = xiaomiGatewayToken) =
Update encrypt the secret for writing
proc xiaomiTokenRefresh*(updateKey = false) =
Wait for updated Gateway token. This does also populate the gateway sid.
proc xiaomiWrite*(sid, message: string, updateKey = false) =
Send a write command to the specified "sid" with a "message".
proc xiaomiSendRead*(deviceSid: string) =
Tell the device to reply with it's status. This proc does not read the reply, only ask the device for sending a message with it's status and the cmd = read_ack.
proc xiaomiSend*(message: string) =
Send a custom message
proc xiaomiReadMessage*(): string =
Read a single Xiaomi message and return it.
proc xiaomiReadCustom*(cmd = "", model = "", sid = ""): string =
Tell the device to reply with status. and return the reply if the custom parameters are fulfilled. It is optional to specify the parameters. Example: cmd => heartbeat model => gateway
proc xiaomiReadDevice*(deviceSid: string): string =
Tell the device to reply with it's status and return the reply.
proc xiaomiReadAck*(deviceSid = ""): string =
Return next message with cmd = "read_ack". This is useful after telling a device to reply with it's status
proc xiaomiReadReport*(deviceSid = ""): string =
Return next message with cmd = "report". This is useful if you are waiting for a sensor to reply with a change
proc xiaomiGatewayGetSid*(): string =
Get the gateway's sid
proc xiaomiGatewayGetToken*(): string =
Get the gateway's token
proc xiaomiDiscover*(): string =
Discover xiaomi devices
proc xiaomiUpdateToken*(message: string): string =
Updates the gateway token if possible and returns the data
proc xiaomiListenForever*() =
Listen for Xiaomi mesages
proc xiaomiDisconnect*() =
Close connection to multicast
proc xiaomiConnect*() =
Initialize socket