image

Приветствую!


Есть такая замечательная библиотека python-miio, позволяющая управлять многими гаджетами Xiaomi: пылесосом, очистителем/увлажнителем воздуха, лампами и тд. В процессе чтения документации я наткнулся на в целом бесполезную, но занятную возможность заменить стандартную озвучку робота-пылесоса на свою. А поскольку на Гиктаймс мне доселе ничего подобного не попадалось, и бытовые гаджеты Xiaomi пользуются популярностью, я решил, что возможно описание процесса окажется для кого-то полезным.

0. python-miio


Начинается все с библиотеки. Как минимум она хороша тем, что позволяет отказаться от проприетарного приложения Xiaomi и вообще закрыть IoT гаджетам доступ в интернет, ограничившись изолированной локалкой.

Помимо Python 3 для установки потребуются libffi-dev libssl-dev.

Выполняем:

pip3 install -U setuptools
pip3 install python-miio

На маке и Debian (Raspberry Pi) больше никаких зависимостей не потребовалось.

1. Токены устройств


Для общения с девайсами Xiaomi нужно получить токены устройств (в данном случае пылесоса), это, пожалуй, самая унылая часть. Возможно, ее получится избежать, выполнив

mirobo discover --handshake 1

, но у меня данный способ не сработал, поэтому ставим официальное приложение MiHome, регистрируемся, добавляем пылесос штатным образом, затем

в случае iOS:
  • делаем незашифрованный бэкап через iTunes
  • открываем бэкап с помощью iBackup Viewer (софтина платная, но нашим целям ограничения бесплатной версии не помешают), в нем выбираем просмотр файловой системы (raw files) и ищем приложение Xiaomi MiHome (com.xiaomi.mihome). Извлекаем один файл с названием <цифры>_mihome.sqlite
  • полученную БД открываем, например, DB Browser for SQLite. Оттуда можно извлечь параметры для всех устройств, в частности нужный нам токен (поле ZTOKEN).
  • далее открываем Терминал и выполняем
    echo '0: <извлеченный_токен>' | xxd -r -p | openssl enc -d -aes-128-ecb -nopad -nosalt -K 00000000000000000000000000000000


в случае Android:
Понадобится adb. Делаем бэкап базы

adb backup -noapk com.xiaomi.smarthome -f backup.ab

с помощью ADB Backup Extractor извлекаем содержимое

java -jar Android\ Backup\ Utilities/Android\ Backup\ Extractor/android-backup-extractor-20171005-bin/abe.jar unpack backup.ab unpacked.tar

и распаковываем

tar -xvf unpacked.tar

из полученной БД с помощью, например, DB Browser for SQLite извлекаем нужный нам токен (поле ZTOKEN).

Вместо просмотра полученных баз вручную, можно воспользоваться инструментом из библиотеки python-miio, должно работать с базами и с Android и с iOS:

miio-extract-tokens <файл_бд>

Самая скучная часть позади, впереди часть творческая.

2. Озвучка


Я воспользовался готовым скриптом. Клонируем к себе, понадобится только папка dustcloud/devices/xiaomi.vacuum/audio_generator. Отредактируем скрипт generate_audio.py. Я все проделывал на Маке и, соответственно, использовал его генератор речи, но понадобилось внести пару правок:

84.  os.system("say -v <голос> -o " + path + " --data-format=LEI16@22050 " + text)

С голосом все просто, выбираете тот, какой нравится (весь список можно посмотреть, набрав в Терминале)

say -v ?

Я поставил русский голос Milena. Обратите внимание на параметр --data-format, в оригинальном скрипте автор использует LEF32@22050, но у меня при таком атрибуте робот выдавал тишину. Глянув вывод ffmpeg, я увидел, что в оригинальной озвучке используется pcm_s16le, поэтому я сменил в скрипте параметр на LEI16, после чего все заработало. У меня первое поколение пылесоса, возможно на втором другой формат звуковых файлов, тем не менее, если робот молчит, рекомендую в первую очередь убедиться, что звуковые файлы имеют одинаковые параметры.

Поправив скрипт, идем в ./language, где хранятся списки фраз. Дублируем любую, переименовываем в audio_ru.csv и правим как душе угодно. После запускаем скрипт

./generate_audio.py

выбрав в интерактивном режиме наш файл с фразами (audio_ru.csv) и tts-движок. На выходе получим файл ru.pkg, который нужно залить на пылесос командой

mirobo install_sound ./ru.pkg

предварительно выполнив

export MIROBO_TOKEN=<токен>

и

export MIROBO_IP=<ip-адрес робота>

3. Задел на будущее


В принципе, все вышеописанное есть в документации к библиотеке python-miio, но, надеюсь, данный мини-мануал все же кому-нибудь пригодится) Пользуясь случаем, хочу спросить: интересна ли будет еще одна статья по «умному» дому? Дело в том, что я уже достаточно долгое время выстраиваю домашнюю экосистему на основе девайсов от Xiaomi и Philips, но без фирменных приложений, всем рулит Home Assistant. Занятие это вполне себе бесконечное, однако на данный момент система пришла к более-менее стабильному виду.

С одной стороны, на Geektimes полно подобных статей, с другой – я бы хотел больший упор сделать на опыт эксплуатации, косяки и ошибки, с которыми столкнулся. Возможно мой опыт уберег бы кого-то от таких же граблей, или подкинул новых идей.

Комментарии (22)


  1. demimurych
    01.05.2018 14:48
    +2

    Очень ждал видео, где оно катается и орет убить всех человеков


    1. iMisanthrope Автор
      01.05.2018 15:40

      Голос Milena из macOS орать, увы, не умеет. Есть идея обработать промежуточные wav-файлы, чтобы добиться сходства звучания с GLaDOS)


      1. boootloader
        01.05.2018 17:48

        В макоси много голосов, бездушный империалистический Zarvox вполне подходит, например :)


    1. Hile
      01.05.2018 16:55
      +1

      Голосом жены <_<


    1. Halt
      02.05.2018 09:24

      В интернетах есть запись, как такой пылесос катается и цитирует фразы голосом из «кожаных ублюдков». Только при детях лучше не слушать.



  1. vindy123
    01.05.2018 15:32

    Спасибо за первое приближение к этой теме) Возможно, стоит упомянуть, что на 4pda есть активное сообщество, занимающееся кастомизацией этих девайсов и клепанием голосовых пакетов. Интересно было бы услышать идеи по альтернативным сценариям использования пылика (плеер интернет радио, home automation server, что-то еще).


    1. iMisanthrope Автор
      01.05.2018 15:38

      На 4pda, если честно, заглядываю редко, но да, полезной инфы по девайса Xiaomi там вагон. Насчёт остального -так глубоко я пока не копал) Но в любом случае, делать из пылесоса сервер, имхо, странно) Я за unix-way, пусть каждая железка делает одно дело, зато делает хорошо. У меня в планах использовать для оповещений шлюз Xiaomi, есть очень толковая статья. А в дальнейшем отказаться от хабов Xiaomi и Philips, перейдя на собственный ZigBee шлюз.


      1. BurlakovSG
        01.05.2018 21:01

        А в дальнейшем отказаться от хабов Xiaomi и Philips, перейдя на собственный ZigBee шлюз.

        Вот с этого места поподробней, пожалуйста.)
        Видел как один француз сделал USB-донгл и как-то работает через него с устройствами ZigBee, но продает он его по вроде по 100 баксов, что я считаю очень дорого. Понятно, что объемы не такие большие, как у Сяоми, но шлюз стоит 20 баксов. Проще же его купить и расковырять его.
        Я взял один шлюз для опытов. Получается он состоит из четырех блоков — блок питания, свет, модуль Wi-Fi, модуль ZigBee. Я думал там в качестве Wi-Fi модуля используется чип на базе МТК7688, но там какой-то мало распространенный чип.


        1. iMisanthrope Автор
          01.05.2018 21:22

          Я нацелился на Raspbee от Dresden Elektronik (ссылка что-то не открывается, хотя недавно была рабочей, мб происки РКН). Готовая платка для Малины за 35$ (есть в виде usb-донгла за чуть дороже), в комплекте API и веб-морда, готовый образ для Малины. Поддерживает несколько стандартов ZigBee (есть ZLL, на котором работает Philips Hue и, например, ZHA; какой стандарт использует Xiaomi сейчас не вспомню, но тоже совместим с этой штукой).
          Железку уже заказал, как приедет, протестирую и напишу статейку. В первом приближении получится, что на одной Малине будет крутиться единый хаб для всех ZigBee устройств, а на второй «мозги» — Home Assistant. Далее можно будет попробовать уместить все на одной Малине. А может HA переедет на железо помощнее, а то с распознаванием образов с камеры Малина уже не очень хорошо справляется.
          Еще в дополнение заказал датчик движения и лампу Ikea Tradfri, по качеству они вроде норм (у меня основной причиной использования Hue вместо Xiaomi является отвратная цветовая температура последних), да и цена весьма приемлемая. Единственное, что смущает, Е26 цоколь, но, насколько я понял из описания, вкрутить его в Е27 патрон все же можно)


  1. airazol
    01.05.2018 18:39
    +1

    Голосовой пакет: «Кожанные ублюдки». Есть на 4PDA.
    Пример: youtu.be/N11vVUI6y84
    А вот еще с роботами Boston D. (это вообще самое смешное что я видел в жизни) www.youtube.com/watch?v=9BEBselBzXk&feature=youtu.be


  1. Valery35
    01.05.2018 21:12

    Жаль, у меня робот попроще.
    Очень хотел ему голос сварливой уборщицы «ходют тут всякие, опять насрали...»


  1. Baton34
    02.05.2018 06:01

    Начиная с какой-то версии mihome не хранит токен в своей базе (miio2.db) и извлечь его не получится. Рекомендуют поставить версию 5.0.31.


    1. iMisanthrope Автор
      02.05.2018 06:04

      На iOS крайняя версия — 4.7.7, проблем с извлечением базы не было. На андроиде не пробовал, но заметил, что при установке приложения и входе в аккаунт все устройства подтягиваются сами, заново добавлять не нужно, т.е токены, видимо, передаются через сервера Xiaomi.


      1. Baton34
        02.05.2018 09:51

        да, я писал про андроид-версию.


        1. iMisanthrope Автор
          02.05.2018 09:59

          По идее, если выполнить сброс Wi-Fi на пылесосе, т.е снова перевести его в режим сопряжения с приложением, то используя

          mirobo discover --handshake 1
          можно получить токен без участия приложения вообще.


  1. mavrikk
    02.05.2018 14:35

    Хмм… а способ получения токена, который описан в документации к Home Assistant не сработал? Я пользовался им для получения токенов устройств XIAOMI SMART POWER STRIP и XIAOMI CHUANGMI PLUG V1. Если коротко, то ставится модуль для nodejs под названием miio через npm install. После этого простой командой miio discover ищутся все устройства в сети и выдаются токены к ним.


    1. iMisanthrope Автор
      02.05.2018 14:37

      Я про него как раз и упоминал комментарием выше. Модуль npm, емнип – та же самая библиотека, только на node.js. У меня данный способ не сработал, возможно нужно было полностью сбросить устройство, чтобы оно перешло в режим pairing.


      1. mavrikk
        03.05.2018 08:41

        npm — это пакетный менеджер. а сам пакет называется miio. Возможно, miio на nodejs и python-miio это одно и то же, не могу судить, так как не пользовался python-miio, однако с miio на nodejs я нашел свои устройства, не сбрасывая их и не переводя в режим поиска. Возможно, что в целях защиты в роботе уже закрыли эту возможность, а может пакеты не совсем одинаковые ) Если есть возможность, то проверьте, пожалуйста


        1. iMisanthrope Автор
          03.05.2018 09:38

          Ну да, я имел ввиду модуль miio, коряво выразился. Протестирую обе библиотеки, с и без сброса устройств.


  1. ladomirr
    03.05.2018 06:37

    Полезно!
    P.S. Но слову «русификация» достаточно одной буквы «с».


    1. iMisanthrope Автор
      03.05.2018 09:36
      +1

      Вторая запасная, на случай аварийной ситуации с первой. Спасибо, поправил)