Пишем игру на LUA для часов Xiaomi Redmi Watch 4.Часть 1. Знакомство с экосистемой Xiaomi

от автора

Retro Game Duck Hunt written on LUA

Retro Game Duck Hunt written on LUA

Всем привет, меня зовут Алексей Ляховский, я на протяжение последних 10 лет занимаюсь изучением, разработкой и развитием экосистемы часов Xiaomi для глобального сообщества.

Я разобрал формат циферблатов Xiaomi последних поколений, сделал распаковщик циферблатов, и компилятор их для оригинального старого редактора циферблатов Xiaomi, сделал мод MiFitness, где активные пользователи сообщества создают и публикуют кастом циферблаты для часов, собрал из китайского IDE отдельный автономный эмулятор часов, для проверки циферблатов и приложений, модифицирую и дорабатываю оригинальные прошивки часов, а так же создаю приложения для данных моделей на JerryScript и LUA, о чем мы познакомимся подробнее чуть позже на примере данной игры.

Что такое часы Xiaomi сейчас

Как известно, Xiaomi выпускает довольно неплохие часы и браслеты, но у этой компании есть ряд особенностей и решений, которые, с моей точки зрения, не позволяют стать #1 в данном виде девайсов.

Вот некоторые из них:

  • полное игнорирование глобального сообщества и их потребностей (эта тема вообще типична для многих китайских компаний, и будем честны, их внутренний рынок позволяет себя так вести) а, именно, отсутствие форматирования даты, начало недели классически у них с понедельника, языковая поддержка даже если есть, она с ошибками, которые очень долго исправляют, если исправляют вообще, нет поддержки сообщений для чего либо, кроме их WeChat, порой даже нет иконок приложений, а сколько я разбирал багов, которые банально правятся конфигурацией, это просто не сосчитать, подразделение QA у них явно слабое.

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

  • NFC модуль, он классически не распаивается на плате для глобал моделей, нет возможности в заводском исполнении использовать карты доступа и проездные (те самые Mifare карты), классически у Xiaomi — это платежные карты, Xiaomi Pay теперь это называется, и ключи и проездные для Китая, и никак иначе. Лично для меня это всегда весомая причина покупать именно китайскую модель, потому что лично мне нравится пользоваться как ключами (Москвенок, домофоны) так и картами типа Тройка.

  • При столь богатом внутреннем устройстве и API для приложений — почти полное или практически полное отсутствие SDK для разработчиков, доступ на самом деле есть у разработчиков с китайским ID — и ситуация не меняется никак с годами, а китайские разработчики банально не знают что такое i18n, чтобы быстро и незатратно делать поддержку приложений для глобальных пользователей.

  • Отключение или даже полное исключение движков приложений из глобальных версий часов, из-за лени или отсутствия интереса у менеджмента Xiaomi развивать это направление.

При всем при этом мне очень нравятся современные часы Xiaomi, потому что система используемая внутри, очень привлекательна для различных доработок и интеграций.

HyperOS и с чем ее едят

Сначала давайте познакомимся, что такое HyperOS в часах Xiaomi и на что следует обратить внимание в первую очередь.
Итак, самое первое и важное HyperOS — это маркетинговое название и стремление компании сформировать свой узнаваемые единый бренд, и это понятно, что же внутри у разных моделей и часов на самом деле?

Компания Xiaomi это крупный агрегатор, у которого на подряде работает ряд компаний в данном направлении, если раньше это был партнер Huami, который после mb7 ушел в полностью независимое направление.
Модели Mi Watch, Watch S1, S1 Active производила небезызвестная нам компания 70mai.
Сейчас же это ряд компаний: Longcheer, Sifli и еще ряд неизвестных мне подрядчиков.
Несмотря на то, что интерфейс устройств одинаковый внешне, внутри это очень разные устройства и железу и программному обеспечению.

В 2021/2022 компания Xiaomi году начала выделять бренд VelaOS своей операционной системы, первые часы, запущенные на базе этой системы, это Watch S1 Pro.

Структура VelaOS

Структура VelaOS

Итак, ядро VelaOS — это Apache NuttX — это RTOS (операционная система реального времени) с открытым исходным кодом, разработанная для встраиваемых систем. Она ориентирована на совместимость с POSIX (стандартами UNIX-подобных ОС), что делает её удобной для разработчиков, привыкших к Linux/UNIX-среде.

В часах на базе этой системы у разработчиков есть доступ к shell системы, и вы можете взаимодействовать как со стандартными приложениями shell NuttX так и дополнительными приложениями прошивки часов.
Выглядит это примерно вот так:

NuttX shell

NuttX shell

В качестве графической библиотеки система использует lvgl, это очень популярный фреймворк для embedded устройств, это важно, потому что имплементация LUA, о которой мы будем говорить, тоже использует его.

Следующая часть VelaOS:
эта два встроенных движка для приложений: Aiot-JS и LUA.
И вот эта часть самая интересная и занимательная, и классически вы не услышите нигде ни в каких обзорах никакой информации об этом. А именно эта часть и отвечает за переход часов из категории фитнес-браслет в умные часы.

И запоминаем опять важный аспект, все дешевые модели Xiaomi хотя и называются HyperOS, в маркетинговом нейминге, не являются VelaOS устройствами, они используют дешевое железо и имеют ограниченный функционал, никаких NuttX OS и движков приложений там нет в помине.

как правило, это устройства стоимостью ниже 40$:
Mi Band 8, Mi Band 9 Active, Redmi Watch 5 Active, Redmi Watch 5 Lite,

исключение только Mi Band 9 и последующие Mi Band 10 будет тоже
на базе VelaOS => true HyperOS, это имиджевый продукт Xiaomi и самый массовый,
Mi Band 9 на сегодня самое лучшее устройство компании по цена/возможности.

Aiot-JS приложения

3rd party apps в часах — это те самые приложения, которые работают на этой движке, база этого — это JerryScript — очень популярная и пожалуй одна из самых старых реализаций для embedded устройств. Сначала компания 70mai внедрила первой их в часы Watch S1 — это полная копия приложений Huawei для их системы LiteOS/HarmonyOS, IDE это калька DevEco Studio oт Huawei.

Вот простой пример на приложения на базе этой системы и API часов.

Huawei DevEco, 3rd party app HAP (Huawei fast app)

Huawei DevEco, 3rd party app HAP (Huawei fast app)

Компания Longcheer же развила этот фреймфорк и он стал называться AiotJS. Для разработки уже используется fork VSCode и интегрированным туда эмулятором для отладки приложений Aiot IDE — текущая версия 1.6

Здесь гайд от Xiaomi как использовать ее, на китайском, на англ версию у меня не получается переключиться, хотя часть Vela API точно есть на английском.

Пример приложения Aiot IDE

Пример приложения Aiot IDE

Для эмуляции используется qemu совместно с Android Virtual Device подсистемой, эмулятор построен на базе системы часов Watch S3 — ярким и типичным представителей семейства часов на VelaOS.

Ура, VelaOS документация обновилась, и теперь даже доступен ряд примеров приложений

Примеры Aiot-JS приложения на github/gitee

Примеры Aiot-JS приложения на github/gitee

Вот ссылка на эти примеры, можете сами посмотреть как тут все устроено,
как выглядит UI и работа с API часов https://iot.mi.com/vela/quickapp/zh/samples/

Ну и тут опять появляется ньюанс, вы не сможете нормально прогрузить готовые приложения в часы, для этого вас нужна регистрация у китайцев с китайским номером,
естественно я давно решил эту проблему специальным приложением модом официального приложения MiFitness.

LUA приложения

По мне самая мощная и интересная часть, это движок LUA.

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

1. Имеет доступ к shell системы, через стандартный модуль библиотеки os.execute()
2. Использует практически прямой вызовы lgvl функций.
3. Имеет ряд готовых UI элементов.

В часах Redmi Watch 4 я развил этот функционал, и LUA приложения можно запускать как приложения, а это очень мощный инструмент для быстрого развития функционала часов.

Список LUA модулей Redmi Watch 4

Список LUA модулей Redmi Watch 4

Честно говоря, до часов Сяоми я никогда не сталкивался с языком LUA, хотя я придерживаюсь в разработке типизированных языков и откровенно не люблю использование везде и вся интерпретируемых, что сейчас крайне модно, но та быстрота с которой можно делать UI часов, который работает практические как написанные на нативном коде, я быстро полюбил разработку именно на нем в контексте данных устройств.

Пример Аналогового циферблата
local lvgl = require("lvgl") local dataman = require("dataman")  -- load our submodules require "image" require "root"  local function getItemsPosition()      local width = lvgl.HOR_RES()     local height = lvgl.VER_RES()  local imgPosition = {         background = { (width - 336) // 2, (height - 336) // 2 },         timeHour = { width // 2, height // 2 },         timeMinute = { width // 2, height // 2 },         timeSecond = { width // 2, height // 2 },     }      return imgPosition end  -- prepare main watchface fuction local function entry()      local root = createRoot()  local watchface = {}      -- setup watchface elements positions local pos = getItemsPosition()      -- create watchface elements     watchface.background = Image(root, "img_0001.png", pos.background)     watchface.timeHour =   HandImage(root, "arrHour.png", pos.timeHour)     watchface.timeMinute = HandImage(root, "arrMinute.png", pos.timeMinute)     watchface.timeSecond = HandImage(root, "arrSecond.png", pos.timeSecond)      -- attach events and setup update behaviour     dataman.subscribe("timeHour", watchface.timeHour.widget, function(obj, value) local hour = value // 0x100 local hourPos = 7200 // 24 * hour obj:set { angle = hourPos }     end)      dataman.subscribe("timeMinute", watchface.timeMinute.widget, function(obj, value) local min = value // 0x100 local minPos = 3600 // 60 * min         obj:set { angle = minPos }     end)      dataman.subscribe("timeSecond", watchface.timeSecond.widget, function(obj, value) local sec = value // 0x100 local secPos = 3600 // 60 * sec         obj:set { angle = secPos }     end)  end  -- execute watchface function entry() 

Вот простой пример аналогового циферблата, как видите понятный лаконичный код.
Сейчас LUA приложение это часть циферблата, т.е. он упаковывается в циферблат, устанавливается как циферблат и запускается как циферблат, в код часов встроен автоматический обработчик, который видит, что если файл имеет расширение .lua — то запускается интерпретатор LUA.

Но как я говорил, для часов Redmi Watch 4 я сделал специальную прошивку, в которую можно ставить LUA приложения как отельные сущности и такие вещи как утилиты, игры, приложения теперь можно запускать независимо от активного циферблата.

Для разработки приложений на LUA я использую тоже VSCode с аддонами для языка LUA, плюс 2 решения для отладки приложений, это полноценный отладчик под Windows/Ubuntu под x86 архитектура и эмулятор часов на базе qemu-avd-Watch S3.

Окружение для разработки мы разберем во второй части статьи.

Я надеюсь, вы теперь имеете больше представления как устроены часы Xiaomi/Redmi,
что такое HyperOS/Vela OS и какие приложения и как можно создавать.

Основные ссылки, если вы хотите самостоятельно
более глубоко ознакомится с материалами по этой теме
NuttX OS — https://nuttx.apache.org/
LVGL — https://lvgl.io/
VelaOS — https://iot.mi.com/vela/quickapp/zh/guide/
VelaOS app samples — https://iot.mi.com/vela/quickapp/zh/samples/
Xiaomi Watchface Editor (Easyface) — https://github.com/m0tral/EasyFace
Xiaomi Watch Emulator — https://github.com/m0tral/MiWatchEmulator

Мой Telegram-канал, посвященный часам Xiaomi
https://t.me/mi_watch_news а также чат https://t.me/mi_watch_int


ссылка на оригинал статьи https://habr.com/ru/articles/897742/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *