Xiaomi miio получение токена для доступа к устройству
miio — проприетарный шифрованный сетевой протокол для взаимодействия Wi-Fi устройств компании Xiaomi и ее суббрендов с приложением Mi Home в локальной сети. Для интеграции устройств с альтернативными системами автоматизации в подавляющем большинстве случаев необходим token для доступа к устройству. Что бы получить token устройство должно быть привязано к учетной записи Xiaomi в приложении Mi Home.
- Универсальный способ #1 — Xiaomi cloud token extractor
- Универсальный способ #2 — модифицированный Mi Home от vevs для Android
- Универсальный способ #3 — Mi Home v5.4.49 для Android
- Xiaomi Mi Gateway 2 (DGNWG02LM)
- Xiaomi Mijia Universal Remote control (MJYKQ01CM)
- Xiaomi Mijia Bedside Lamp (MJCTD01YL)
- Xiaomi Mijia 1C Sweeping Vacuum Cleaner (STYTJ01ZHM)
- Скачать
Универсальный способ #1 — Xiaomi cloud token extractor
Самый простой и быстрый способ получения token’а на данный момент для всех устройств компании Xiaomi использование утилиты Xiaomi cloud token extractor. В случае OS Windows это утилита, в случае использования Unix/Linux это скрипт, написанный на Python. Проект выложен на GitHub.
Для Ubuntu и Raspberry Pi установка Pyton3 и необходимых компонентов будет выглядеть так:
$ sudo apt-get install python3 python3-pip $ pip3 install pycryptodome pybase64 requests
$ wget https://github.com/PiotrMachowski/Xiaomi-cloud-tokens-extractor/raw/master/token_extractor.py
$ python3 token_extractor.py
При запуске утилита/скрипт попросит авторизоваться учетной записью Xiaomi. Необходимы:
- E-mail или User ID Xiaomi
- Пароль от учетной записи
- Выбрать страну привязки устройств, можно оставить пустым, и программа проверит для всех перечисленных стран
$ python3 token_extractor.py Username (email or user ID): my_xiaomi_mail_or_user_id Password: my_xiaomi_password Country (one of: ru, us, tw, sg, cn, de) Leave empty to check all available: Logging in. Logged in. Devices found for country "cn": --------- NAME: Xiaomi Mi Gateway v.2 ID: XXXXXXXX IP: 192.168.XXX.XXX TOKEN: 1234567890abcdef1234567890abcdef MODEL: lumi.gateway.v3 --------- NAME: Mi IR Remote control ID: XXXXXXXXX IP: 192.168.XXX.XXX TOKEN: 1234567890abcdef1234567890abcdef MODEL: chuangmi.remote.v2 --------- NAME: Miji Robot Vacuum Cleaner 1C ID: XXXXXXXXX IP: 192.168.XXX.XXX TOKEN: 1234567890abcdef1234567890abcdef MODEL: dreame.vacuum.mc1808
Огромным плюсом этого метода является то, что помимо подключенных Wi-Fi устройств, утилита показывает подключенные Bluetooth устройства, подключенные к шлюзам ZigBee устройства, созданные пульты для Mi IR Remote control.
--------- NAME: Xiaomi Mijia BLE Temperature and Humidity Sensor ID: blt.3.ubsv8hlXXXXX IP: XXX.XXX.XXX.XXX TOKEN: 1234567890abcdef123456789 MODEL: cleargrass.sensor_ht.dk1 --------- NAME: Aqara Smart Wall Socket ID: lumi.158d000XXXXXXX IP: TOKEN: MODEL: lumi.ctrl_86plug.aq1
Это удобно использовать для определения ID ZigBee устройств.
Универсальный способ #2 — модифицированный Mi Home от vevs для Android
Mi Home от vevs — модифицированный Mi Home с переводом действий, условий и статусов (русский и английский языки), подробнее в блоге автора.
- Удаляем оригинальный Mi Home
- Скачиваем и устанавливаем последнюю версию Mi Home от vevs для Android
- Запускаем установленное приложение Mi Home
- Авторизуемся в приложении Mi Home
- Открываем плагин необходимого устройства
- Настройки -> Дополнительные настройки -> Информация о сети
- В самом низу поле «Токен»
Универсальный способ #3 — Mi Home v5.4.49 для Android
Способ достаточно старый, но все еще действенный. Mi Home версии v5.4.49 для Android ведет логи взаимодействия с устройствами, логи хранятся в папке /Smarthome/logs в виде текстовых файлов. Порядок действий следующий:
- Скачиваем и устанавливаем Mi Home v5.4.49 для Android. Если есть второе устройство, то лучше все операции делать на нем, иначе придется удалить текущую версию Mi Home
- Запускаем установленное приложение Mi Home
- Авторизуемся в приложении Mi Home
- Для надежности открываем необходимое устройство в Mi Home
- В менеджере файлов переходим в папку /Smarthome/logs
- Открываем текстовый log файл
- Просматриваем содержимое log файла, ищем по слову token
В папке может быть несколько текстовых файлов, просматриваем их все или удаляем всё содержимое папки и запускаем Mi Home v5.4.49 заново.
Результат просмотра log файла:
- Для Xiaomi Mi Gateway v.2 — token«:»1234567890abcdef1234567890abcdef«,»longitude»:»XX.XXXXXXX»,»latitude»:»XX.XXXXXXX»,»name»:»Xiaomi Mi Gateway v.2″,
- Для Mi IR Remote control — token«:»1234567890abcdef1234567890abcdef«,»longitude»:»XX.XXXXXXXX»,»latitude»:»XX.XXXXXXXX»,»name»:»Mi IR Remote control»
Для моего пылесоса Mijia Robot Vacuum Cleaner 1C токен тоже есть в лог файле, но в плагин управления попасть нельзя т.к. не поддерживается версией приложения. Но это не важно, главное результат получить token.
Список устройств и методы с помощью которых мне удалось получить токен.
Xiaomi Mi Gateway 2 (DGNWG02LM)

Токен можно получить с помощью методов #1, #2 и #3 описанных выше.
Получить токен для региона Китай можно в программе Mi Home любой версии, пока писал статью на версии Mi Home v5.9.19 обновился плагин для шлюза, из которого похоже вырезали доступ к режиму разработчика. Но в версии Mi Home v.5.8.40 плагин шлюза версии v.2.77.1 , для включения режима разработчика и получения сведений он нам сгодится.
- Скачиваем и устанавливаем Mi Home v5.8.40 для Android. Если есть второе устройство, то лучше все операции делать на нем, иначе придется удалить текущую версию Mi Home
- Запускаем установленное приложение Mi Home
- Авторизуемся в приложении Mi Home
- Открываем плагин шлюза Xiaomi Mi Gateway 2
- Нажимаем три точки в правом верхнем углу
- Сведения -> Информация о шлюзе, если пункты меню «Протокол связи локальной сети» и «Информация о шлюзе» отсутствуют, то пять раз нажимаем на пункт Версия плагина: 2.XX.X пока не появятся указанные пункты меню.
Токены miIO-устройств
Токен — это уникальная 32-ухзначная последовательность символов, используемая для формирования ключа шифрования. Наличие и знание токена — это обязательное условие успешного управления miIO-устройством средствами модуля.
В целом процедура добавления нового устройства в приложение Mihome выглядит так:
- Включаем новое устройство в сеть. Оно создает свою открытую точку доступа.
- Приложение Mihome производит поиск новых wifi-сетей, и если находит, то предлагает добавить устройство.
- При добавлении телефон подключается к точке доступа, созданной устройством.
- Mihome посылает hello-пакет устройству.
- Устройство, получив hello-пакет, отправляет ответ на него, в котором содержится токен.
- Mihome получает ответ, сохраняет токен в свою базу данных и отправляет устройству команду на подключение к wifi-сети и пароль от нее.
- Устройство перезагружается и цепляется к целевой wifi-сети. Телефон также переключается обратно на основную точку доступа.
- Mihome и устройство обмениваются пакетами по протоколу miIO, зашифрованного на основе полученного ранее токена.
- После привязки устройства к Mihome устройства в большинстве случаев перестают транслировать свой токен в ответ на hello-пакеты. Это зависит от логики, зашитой в прошивку устройства, и версии этой прошивки. Одни устройства всегда, на любой версии прошивки, открыто отдают свой токен. Вторые отдают токен только до определенной версии прошивки, а после обновления перестают. Ну а третьи сообщают свой токен только в режиме инициализации, т.е. до привязки к Mihome и подключения к wifi-сети.
Исходя из вышеуказанной процедуры, можно рассмотреть несколько базовых подходов получения токенов устройств.
- Произвести поиск устройств в сети с помощью отправки широковещательного hello-пакета (handshake discover) и получить токен в ответном пакете от устройства.
- Извлечь токены из базы данных или кеш-файлов приложения Mihome на смартфоне.
- Сбросить устройство (или удалить из Mihome) и получить токен в режиме инициализации устройства аналогично первому способу через handshake discover.
Рассмотрим эти подходы подробнее.
Поиск устройств в сети (handshake discover)
Данный способ штатно предусмотрен в модуле Xiaomi miIO. Модуль выполняет периодический (или ручной) поиск устройств в домашней локальной сети, и если в ответных сообщениях от найденных устройств содержатся их токены, то модуль автоматически их получает и сохраняет в своих настройках.
Но, как было сказано ранее, не все так хорошо, как хотелось бы. Большинство устройств не сообщают открыто свои токены, поэтому приходится пользоваться другими способами.
База данных и кеш-файлы Mihome
Самый простой вариант — это воспользоваться кастомной сборкой Mihome от vevs (только для андроида).
Брать здесь http://www.kapiba.ru/2017/11/mi-home.html
В Mihome нужно зайти в раздел Информация о сети нужного устройства, в котором наряду с информацией о подключении к wifi точке доступа также будет строка с токеном. Бонусом получаем руссифицированный Mihome.
С другими вариациями этого подхода можно ознакомиться на Форуме.
Сброс устройства и последующая инициализация
Суть заключается в том, что предварительно нужно сбросить устройство (если оно уже было подключено к домашней сети), а затем подключиться к открытой точке доступа, которую оно создает в режиме инициализации.
В этом случае лучше воспользоваться ПК с wifi-адаптером и приложением для Windows MiHomeAdmin, которое можно скачать на Форуме.
Если Windows не подходит, то можно воспользоваться утилитой miio-cli.php в составе библиотеки php-miio. Или кросс-платформенными приложениями (в т.ч. под iOS, Android), которые позволяют отправить UDP-пакет нужной нам структуры. Примерами таким приложений могут быть Packet Sender, Packet Handler. Подробно эти варианты расписаны на Форуме.
Но у этого способа есть один нюанс — некоторые хитрые устройства меняют свой токен в момент последующей привязки к Mihome. Для таких устройств подойдет только вариант №2 — база Mihome. Так отличаются пылесос, wifi-радио и, возможно, еще какие-то другие.
Катаемся на Xiaomi Vacuum Cleaner
Вот и пришли новогодние праздники, а с ними и куча свободного времени, да еще и умный пылесос угодил ко мне в руки. Как только я увидел в приложении MiHome ручное управление, я сразу понял, что хочу сделать: будем управлять пылесосом с помощью геймпада Dualshock v4!
Шаг 1, тащим токен, прошиваем (опционально)
Ставим пропатченное приложение MiHome, которое будет показывать нам токен, далее выбираем рутованную прошивку, скачиваем, ставим python-miio (pip install python-miio), пробуем установить прошивку с помощью mirobo —ip %ip% —token %token% update-firmware %filename% и на этом моменте у меня все сломалось. Пылесос отчаянно отказывался обновляться, после нескольких часов гугления я попробовал посмотреть отладочный вывод mirobo и о чудо! Из-за того, что у меня на ноутбуке установлено несколько адаптеров, он пытался раздать прошивку в сети адаптера VirtualBox Host-Only. Далее я просто поднял файловый сервер и выполнил эту команду: mirobo —ip=%ip% —token=%token% raw-command miIO.ota » . Прошивка встала где-то за 10 минут, доступ по ssh работал
Шаг 2, пытаемся покататься на роботе
import miio ip = '' token = '' bot = miio.vacuum.Vacuum(ip, token) bot.manual_start() bot.manual_control(0, 0.3, 2000) # move forward with max speed for 2 seconds bot.manual_control(90, 0, 1000) # rotate bot.manual_stop()
На этом этапе пылесос должен сказать Using remote controls (или что-то подобное в зависимости от прошивки), подергаться и остановиться
Шаг 3, подключаем Dualshock
После небольшого исследования было решено использовать pygame
Смотрим, какие кнопки/стикеры за что отвечают
BUTTON_SQUARE = 0 BUTTON_X = 1 BUTTON_CIRCLE = 2 BUTTON_TRIANGLE = 3 def init_joystick(): pygame.init() pygame.joystick.init() controller = pygame.joystick.Joystick(0) controller.init() return controller def main(): controller = init_joystick() bot = miio.vacuum.Vacuum(ip, token) modes = ['manual', 'home', 'spot', 'cleaning', 'unk'] mode = 'unk' axis = [0.00 for _ in range(6)] flag = True button = [False for _ in range(14)] print('Press start to start!') while flag: for event in pygame.event.get(): if event.type == pygame.JOYAXISMOTION: axis[event.axis] = round(event.value,2) elif event.type == pygame.JOYBUTTONDOWN: button[event.button] = True # Touchpad to exit if event.button == 13: flag = False elif event.type == pygame.JOYBUTTONUP: if mode == 'unk': print('Ready to go! Press X to start manual mode') if event.button == BUTTON_X: mode = 'manual' bot.manual_start() elif mode == 'manual': if event.button == BUTTON_TRIANGLE: bot.manual_stop() mode = 'unk' elif event.button == BUTTON_X: play_sound('http://192.168.1.43:8080/dejavu.mp3') # see ya later elif event.button == BUTTON_CIRCLE: # stop sound play_sound(';') if mode == 'manual': try: move_robot(bot, button, axis) # see ya in the next step except: bot.manual_start() pass time.sleep(0.01)
Пока в move_robot можно сделать просто print(axis) и проверить, что джойстик работает.
Далее нам нужно сделать так, чтобы робот ездил при нажатии на кнопки/стики, я выбрал левый стик по оси Y (вверх -1, вниз 1) для скорости и правый стик по оси X для угла, получилась примерно такая функция
def translate(value, leftMin, leftMax, rightMin, rightMax): leftSpan = leftMax - leftMin rightSpan = rightMax - rightMin valueScaled = float(value - leftMin) / float(leftSpan) return rightMin + (valueScaled * rightSpan) def move_robot(bot, buttons, axis): rot = 0 val = 0 to_min, to_max = -0.3, 0.3 # Right stick X if axis[2] != 0: rot = -translate(axis[2], -1, 1, -90, 90) if abs(rot) < 8: rot = 0 # Left stick Y, -1 up, 1 down if axis[1] != 0: val = -translate(axis[1], -1, 1, to_min, to_max) if abs(val) < 0.07: val = 0 if rot or val: bot.manual_control(rot, val, 150)
Запускаем скрипт, жмем Х на контроллере и робот должен ездить и поворачивать
На этом этапе у меня возникла проблема: почему-то если нажать левый стик вперед до конца и попытаться повернуть, он не будет поворачивать, придется сначала сбросить скорость, если попытаться уменьшить значения маппинга, например поставить -0.29, 0.29, он начнет ездить по кругу, пока не изменится положение левого стикера, я так и не разобрался, в чем тут проблема
Шаг 4, добавим музыки
Заходим по ssh на нашего робота и смотрим, какие скриптовые языки тут есть.
Питона не было, а устанавливать его я смысла не видел, зато нашел перл, для нашей небольшой задачки подойдет.
Далее устанавливаем sox:
sudo apt-get install sox, libsox-fmt-mp3
и пишем небольшой сервер на перле:
#!/usr/bin/perl use IO::Socket::INET; $| = 1; my $socket = new IO::Socket::INET ( LocalHost => '0.0.0.0', LocalPort => '7777', Proto => 'tcp', Listen => 2, Reuse => 1 ); die "cannot create socket $!\n" unless $socket; print "server waiting for client connection on port 7777\n"; while(1) < my $client_socket = $socket->accept(); my $client_address = $client_socket->peerhost(); my $client_port = $client_socket->peerport(); print "connection from $client_address:$client_port\n"; my $data = ""; $client_socket->recv($data, 256); print "received data: $data\n"; my @urls = split /;/, $data; system("killall play > /dev/null"); $data = "ok"; $client_socket->send($data); shutdown($client_socket, 1); if ( $urls[0] ne "") < system("play -q -v 0.4 " . $urls[0] . " &"); >> $socket->close();
sudo perl sound_server.pl
у себя в консольке делаем что-то вроде
import socket ip = '' s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((ip, 7777)) s.sendall(b'http://%local_ip%:%local_port%/test.mp3;') s.close()
И через пылесос должен заиграть наш test.mp3 (соответственно, нужно поднять файловый сервер на нашей локальной машине).
Наша функция play_sound() будет делать практически то же самое, только будет sendall(url+';'), url — аргумент функции.
Самый простой способ получения miio токена

Опытные пользователи о нем знают. Новичкам сэкономит нервы.
Мы уже не раз рассказывали о том, как можно получить тот самый злосчастный Miio-токен, но давайте признаемся, что существует единственный самый простой и верный способ.
Перед этим напомним, что Miio-токен требуется для взаимодействия со всеми wi-fi устройствами экосистемы Xiaomi. Среди них: увлажнители, пылесосы, очистители воздуха, лампочки, кондиционеры, обогреватели, хабы, розетки и т.д.
С одной стороны это очень хорошо — единый протокол работы для целого пласта устройств. С другой стороны плохо — потому что добыть тот самый токен с каждым годом становится всё сложнее.
Если раньше нам было достаточно выполнить команду miio discover, чтобы добыть токен, то теперь мы видим в ответах только знаки вопросов.
Точно также и с другим методом, о котором мы писали — многие устройства меняют токен после подключения к вашей wi-fi сети.
Поэтому последнее время я пользуюсь единственным простым и рабочим способом добыть токен — с помощью модифицированного .apk Mi Home.
Люди с шапочкой из фольги, консперологи и переживающие за слив своих персональных данных — выходим из чата
Инструкция
- либо телефон на Android (это позволит вам сэкономить чуть больше времени)
- либо компьютер (неважно PC или Mac)
Т.к. я не владею ни Android ни Windows, то дальше инструкция будет описана на примере MacOS.
- Идем на сайт https://www.bignox.com и скачиваем эмулятор Android.
- Устанавливаем эмулятор и ждем его запуска. (на двух компьютерах я столкнулся с одним и тем же поведением — при первом запуске загрузка доходит до 99% и перестает двигаться дальше. Закрываем, открываем заново — вуа-ля)

- После запуска эмулятора идем на сайт https://www.kapiba.ru/, находим там самую актуальную версию модифицированного Mi Home и скачиваем apk по ссылке. Актуальная ссылка на момент написания статьи.
- Устанавливаем apk — кнопка для установки см. на скриншоте

- Устанавливаем, выбираем сервер, на котором было добавлено устройство (не забываем, что это эмулятор Android, поэтому все действия выполняем эмулируя движение пальцем — т.е. прокрутка списка осуществляется как на телефоне — зажатием и перетягиванием), авторизовываемся, ждем загрузки устройств.
- Дальше выбираем устройств, нажимаем на «***» выбираем «Дополнительные настройки», дальше «Информация о сети» и внизу находим «Токен».

- Переписываем токен. Вот и всё — дальше можете использовать данный токен в нужных вам целях.
Остальные методы можно найти здесь.
