{"id":16971576,"url":"https://github.com/thomastjdev/nim_xiaomi","last_synced_at":"2025-03-21T20:16:17.525Z","repository":{"id":87657541,"uuid":"143921315","full_name":"ThomasTJdev/nim_xiaomi","owner":"ThomasTJdev","description":"Nim package for working with Xiaomi devices","archived":false,"fork":false,"pushed_at":"2019-02-15T18:04:30.000Z","size":16,"stargazers_count":4,"open_issues_count":2,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-26T14:48:37.902Z","etag":null,"topics":["nim","nim-lang","xiaomi","xiaomi-aqara","xiaomi-smart-home"],"latest_commit_sha":null,"homepage":null,"language":"Nim","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ThomasTJdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-07T20:03:20.000Z","updated_at":"2023-09-20T03:22:53.000Z","dependencies_parsed_at":"2023-03-13T18:40:18.482Z","dependency_job_id":null,"html_url":"https://github.com/ThomasTJdev/nim_xiaomi","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThomasTJdev%2Fnim_xiaomi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThomasTJdev%2Fnim_xiaomi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThomasTJdev%2Fnim_xiaomi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThomasTJdev%2Fnim_xiaomi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ThomasTJdev","download_url":"https://codeload.github.com/ThomasTJdev/nim_xiaomi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244860611,"owners_count":20522466,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["nim","nim-lang","xiaomi","xiaomi-aqara","xiaomi-smart-home"],"created_at":"2024-10-14T00:52:43.647Z","updated_at":"2025-03-21T20:16:17.517Z","avatar_url":"https://github.com/ThomasTJdev.png","language":"Nim","readme":"*This README was generated with [Nim to Markdown](https://github.com/ThomasTJdev/nimtomd)*\n\n# XIAOMI\n\nLibrary for working with Xiaomi IOT devices.\n\n## Requirements\n\n- nim \u003e= 0.19.0\n- multicast \u003e= 0.1.1\n- nimcrypto \u003e= 0.3.2\n\n## Devices\nXiaomi IOT devices are supported. The following devices has been thoroughly tested:\n\n  - [Gateway](https://www.lightinthebox.com/en/p/xiao-mi-multi-function-gateway-16-million-color-night-light-remote-control-connect-other-intelligent-devices_p5362296.html?prm=1.18.104.0)\n  - [Door/window sensor](https://www.lightinthebox.com/en/p/xiao-mi-door-and-window-sensor-millet-intelligent-home-suite-household-door-and-window-alarm-used-with-multi-function-gateway_p5362299.html?prm=1.18.104.0)\n  - [PIR sensor](https://www.lightinthebox.com/en/p/xaomi-aqara-human-body-sensor-infrared-detector-platform-infrared-detectorforhome_p6599215.html?prm=1.18.104.0)\n  - [Temperature \u0026 Humidity sensor](https://www.lightinthebox.com/en/p/original-xiaomi-temperature-and-humidity-sensor-real-time-monitoring-of-temperature-and-humidity-changes_p5376891.html?prm=1.18.104.0)\n\n## Working with Xiaomi\nYou can interact with the Xiaomi devices in 3 ways:\n1) **Read** - Asking for a status, e.g. is the door open (door sensor)\n2) **Report** - Awaiting an action, e.g. when the door opens, it sends a notification (door sensor)\n3) **Write** - Send a message to the device (only some devices accepted this), e.g. play a sound (gateway)\n\nAll 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.\n\n# Examples (basic)\n\n## Discover devices\nBut before we get started, you need to acquire your devices SID.\n\n**Get the gateways SID**\n```nim\n import xiaomi\n xiaomiConnect()\n echo xiaomiGatewayGetSid()\n```\n\n\n\n**Get the devices SID**\n```nim\n import xiaomi\n xiaomiConnect()\n echo xiaomiDiscover()\n```\n\n\n\n## Read\nThere are numerous ways to read. Some proc's just read the next message, some waits for a specific device, etc.\n\n**Read the next message sent**\n```nim\n import xiaomi\n xiaomiConnect()\n echo xiaomiReadMessage()\n```\n\n\n\n**Request a device status and read the reply**\n```nim\n import xiaomi\n xiaomiConnect()\n echo xiaomiReadDevice(\"device-SID\")\n```\n\n\n\n**Read the next message from custom-x**\nThis will await that the cmd = \"heartbeat\" and the model = \"gateway\".\n```nim\n import xiaomi\n xiaomiConnect()\n echo xiaomiReadCustom(\"heartbeat\", \"gateway\")\n```\n\n\n\n**Read messages forever**\n```nim\n import xiaomi\n xiaomiConnect()\n xiaomiListenForever()\n```\n\n\n\n## Report\n\nFor PIR sensors you will receive a report, when there's motion or there hasn't been motion for 300 seconds.\n\nFor magnet sensors you will receive a report when they are connected (`close`) and disconnected (`open`).\n\n**Read next report**\n```nim\n import xiaomi\n xiaomiConnect()\n echo xiaomiReportAck()\n```\n\n\n\n**Read next report for device**\n```nim\n import xiaomi\n xiaomiConnect()\n echo xiaomiReadReport(\"device-SID\")\n```\n\n\n\n# Write to a device\nTo 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.\n\n\n## Gateway password\nBut before we can generate the key, you need to gather you gateway password. Follow this guide [Domotics](https://www.domoticz.com/wiki/Xiaomi_Gateway_(Aqara)#Adding_the_Xiaomi_Gateway_to_Domoticz) or the bullets below. Remember to write the key down.\n\n1) Install the Xiaomi app\n2) Set the region to Mainland China under Settings-\u003eLocale\n3) You can set the language to English, even though the region is China\n4) Sign in/Make an account\n5) Select your Gateway in the app\n6) Tap the 3 dots in top right corner\n7) Click About\n8) Tap on the version repeatedly until a new menu appear\n9) Click on Wireless communication protocol\n10) Enable the this and write down you password and press Ok\n\n## Setting the password\nIf you need to write to a device, insert your password in the global variable at the top of your code:\n\n```nim\n xiaomiGatewayPassword = \"secretPassword\"\n```\n\n\n\n## Getting the encrypted key\nThe gateways token is changing all the time. You therefore need to the generate the encrypted key before each writing.\n\nThis is done with:\n```nim\n xiaomiTokenRefresh()\n xiaomiSecretUpdate()\n```\n\n\n\n**OR**\n```nim\n xiaomiTokenRefresh(true)\n```\n\n\n\n**OR while writing**\n```nim\n xiaomiWrite(\"device-SID\", \"message\", true)\n```\n\n\n\n## Gateway writing options\nThere are 2 main elements you can write to the gateway - the light and sound.\n\n**Light writing**\n\n```nim\n import xiaomi\n xiaomiGatewayPassword = \"secretPassword\"\n xiaomiTokenRefresh()\n xiaomiWrite(xiaomiGatewaySid, \"\\\"rgb\\\": 4294914304\")\n```\n\n\n\n**Light options**\n\nTo assign a RGB color, you have to use the Android() color format.\n\nYou can convert HEX to Android() at this [website](https://convertingcolors.com/android-color-4294914304.html).\n\n- Red = `4294914304`\n- Green = `4283359807`\n- Purple = `4283637131`\n- Yellow = `4292211292`\n- Blue = `4283327469`\n- Off = `0`\n\n\n**Sound writing**\n\n```nim\n import xiaomi\n xiaomiGatewayPassword = \"secretPassword\"\n xiaomiTokenRefresh()\n xiaomiWrite(xiaomiGatewaySid, \"\\\"mid\\\": 7, \\\"vol\\\": 4\")\n```\n\n\n\n**Sound options**\n\nThe volume is in percentage, whereas 10 = 100%.\n\nThe following sounds are available:\n\nAlarms:\n- 0 - Police car 1\n- 1 - Police car 2\n- 2 - Accident\n- 3 - Countdown\n- 4 - Ghost\n- 5 - Sniper rifle\n- 6 - Battle\n- 7 - Air raid\n- 8 - Bark\n\nDoorbells\n- 10 - Doorbell\n- 11 - Knock at a door\n- 12 - Amuse\n- 13 - Alarm clock\n\nAlarm clock\n- 20 - MiMix\n- 21 - Enthusiastic\n- 22 - GuitarClassic\n- 23 - IceWorldPiano\n- 24 - LeisureTime\n- 25 - ChildHood\n- 26 - MorningStream\n- 27 - MusicBox\n- 28 - Orange\n- 29 - Thinker\n# Types\n## Procs\n### proc xiaomiSecretUpdate*\n```nim\nproc xiaomiSecretUpdate*(password = xiaomiGatewayPassword, token = xiaomiGatewayToken) =\n```\nUpdate encrypt the secret for writing\n### proc xiaomiTokenRefresh*\n```nim\nproc xiaomiTokenRefresh*(updateKey = false) =\n```\nWait for updated Gateway token.\nThis does also populate the gateway sid.\n### proc xiaomiWrite*\n```nim\nproc xiaomiWrite*(sid, message: string, updateKey = false) =\n```\nSend a write command to the\nspecified \"sid\" with a \"message\".\n### proc xiaomiSendRead*\n```nim\nproc xiaomiSendRead*(deviceSid: string) =\n```\nTell the device to reply with it's status.\nThis proc does not read the reply, only\nask the device for sending a message with\nit's status and the cmd = read_ack.\n### proc xiaomiSend*\n```nim\nproc xiaomiSend*(message: string) =\n```\nSend a custom message\n### proc xiaomiReadMessage*\n```nim\nproc xiaomiReadMessage*(): string =\n```\nRead a single Xiaomi message\nand return it.\n### proc xiaomiReadCustom*\n```nim\nproc xiaomiReadCustom*(cmd = \"\", model = \"\", sid = \"\"): string =\n```\nTell the device to reply with status.\nand return the reply if the custom\nparameters are fulfilled.\nIt is optional to specify the parameters.\nExample:\n  cmd =\u003e heartbeat\n  model =\u003e gateway\n### proc xiaomiReadDevice*\n```nim\nproc xiaomiReadDevice*(deviceSid: string): string =\n```\nTell the device to reply with it's status\nand return the reply.\n### proc xiaomiReadAck*\n```nim\nproc xiaomiReadAck*(deviceSid = \"\"): string =\n```\nReturn next message with\ncmd = \"read_ack\". This is useful\nafter telling a device to reply\nwith it's status\n### proc xiaomiReadReport*\n```nim\nproc xiaomiReadReport*(deviceSid = \"\"): string =\n```\nReturn next message with\ncmd = \"report\". This is useful\nif you are waiting for a sensor\nto reply with a change\n### proc xiaomiGatewayGetSid*\n```nim\nproc xiaomiGatewayGetSid*(): string =\n```\nGet the gateway's sid\n### proc xiaomiGatewayGetToken*\n```nim\nproc xiaomiGatewayGetToken*(): string =\n```\nGet the gateway's token\n### proc xiaomiDiscover*\n```nim\nproc xiaomiDiscover*(): string =\n```\nDiscover xiaomi devices\n### proc xiaomiUpdateToken*\n```nim\nproc xiaomiUpdateToken*(message: string): string =\n```\nUpdates the gateway token if\npossible and returns the data\n### proc xiaomiListenForever*\n```nim\nproc xiaomiListenForever*() =\n```\nListen for Xiaomi mesages\n### proc xiaomiDisconnect*\n```nim\nproc xiaomiDisconnect*() =\n```\nClose connection to multicast\n### proc xiaomiConnect*\n```nim\nproc xiaomiConnect*() =\n```\nInitialize socket\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomastjdev%2Fnim_xiaomi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthomastjdev%2Fnim_xiaomi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomastjdev%2Fnim_xiaomi/lists"}