AngelHack 2016 в Санкт-Петербурге: Sailfish OS IoT project

История о том, как я поучаствовал в AngelHack 2016 в Санкт-Петербурге, в котором собранная мной команда выиграла в номинации от Открытой Мобильной Платформы “на лучшее использование платформы Sailfish OS”!

sailfish_winners

Disclamer

Проект, с которым мы выиграли в хакатоне, посвящен разработкам для Sailfish OS, позволяющим реализовывать концепции Internet of Things. Мы делали прототип домашнего потребительского устройства на основе WiFi-модуля ESP8266, для Arduino-прошивки поднимали CoAP-сервер с опциями observe и discovery.

Смело пролистывайте лирические вступления до частей с деталями реализации (ближе к середине)!

Заранее прошу прощения за то, что по всему тексту могут встречаться неаргументированные, субъективные и провокационные высказывания насчет каких-либо технологий, в которых я при этом, скорее всего, плохо разбираюсь.

Как Jolla Sailfish стал моим телефоном

Из приятно впечатливших меня телефонов у меня когда-то были:

Но однажды пару-тройку лет назад в Петербурге в minijack моей N9 попало немного воды с проезжающего мимо гидроцикла, и как-то совсем неудачно – стал вопрос о замене всей платы.

Омраченный происшествием с любимой N9, я не захотел сразу искать Jolla. Сначала я решил попробовать ранний Windows Phone… Через пару дней вернул новый телефон продавцам (вернул без проблем). После посмотрел в сторону Android: нашел китайский IP67-защищенный Lenovo S750 на Android 4.2, залил на него прошивку с оболочкой MIUI и более-менее довольный ходил с ним примерно год, но скучал по N9. Захотев поиграться, я выяснил, что от MTK-процессоров в ближайшем будущем не жди никаких Cyanogen-ов, как и обновлений от Lenovo – и стало скучно. Позже телефон вдобавок перестал ловить сеть, и, скорее всего, требуется что-то подобное. Оказалось, что Android мне мало чем интересен, я не особенно жалую Java. Продуцию же Apple я и до этого обходил стороной.

На десктопах у меня к тому времени уже продолжительное время стояли кеды со всякими арчлинуксами, и, как я не оттягивал время, мне жутко интересен был Jolla Sailfish. Мне понравился их интерфейс сразу, еще по первым презентациям, но немного смущали всякие слоганы #unlike, хотелось чего-то поскромнее. В итоге я все-таки купил Jolla Sailfish в официальном магазине, когда они еще были там, и до сих пор хожу с ним, не нарадуюсь.

Jolla Sailfish terminal screenshot Jolla Sailfish desktop screenshot le me as hipsta Jolla Sailfish text editing screenshot

Как я узнал о хакатоне AngelHack и номинации от Открытой Мобильной Платформы

О хакатоне я узнал из рассылок FRUCT-а. О FRUCT узнать было несложно, когда приехал Петербург и интересуешься Qt и мобильными линуксами. Мое знакомство с FRUCT состоялось на одном из митапов по TizenOS. Но Tizen мне не приглянулся иконками и html-приложениями.

tizen old bage

Позже я посещал первый meetup от FRUCT по Sailfish в Петербурге и другие мероприятия, а в рассылке о хакатоне было объявлено, что за день до самого мероприятия пройдет еще один (второй) митап для разработчиков. За организацию всех мероприятий, связанных с мобильными linux-based устройствами и не только – организаторам FRUCT, конечно, отдельная благодарность. На обоих митапах по Sailfish, кстати, были представители Jolla и Открытой Мобильной Платформы, что приятно, т.к. можно было расспрашивать их о чем угодно.

Например, я расспрашивал про отношение Silica и Qt Quick Controls. Как я понял, исторически получилось, что первое начало развиваться до появления второго. А их объединение оценивается как слабо осуществимое на практике, т.к. имеет смысл для очень ограниченного круга задач с интерфейсами (слишком различается взаимодействие с десктопом и тач-мобильными-жестами). Но, если захотеть, то самому, конечно, можно сделать для конкретного приложения общие для десктопа и тач-скрина мобильных устройств компоненты. Мечтать[1,2] о чем-то вроде стиля Silica для Qt labs Controls и скором обновлении Qt в системе до 5.6 всё равно приятно.

Спрашивал еще про tracker и планы на его будущее в Sailfish. Насколько я уяснил, он хорошо себя показал при работе с метаданными о мультимедиа-коллекции пользователя, но никто особо заморачиваться с ним не хочет. Убирать его не собираются, но и полностью покрывать им всю систему – тоже. Тем более, что всякие фэйсбуки не дают по своим правилам что-то свободно скачивать с их серваков и нормально кэшировать (тут могу сильно ошибаться). Мне вопрос интересен, т.к. я люблю RDF/Semantic Web/etc, да и в рассылках на смежные темы шел разговор.

Время перед хакатоном

Пролистав весь список зарегистрированных проектов я увидел, что ни одного из них по Sailfish не было. Немного подождав, я зарегистрировался сам, но ни заявок в команду, ни проектов-конкуретов не увидел.

Отсутствие конкурентов смущало, т.к. сложно было решить, к чему готовиться. Отсутствие заявок в команду – тоже, т.к. до последнего я не был уверен, что смогу участвовать в хакатоне оба дня. Даты хакатона в Петербурге: 11-12 июня, а 13-е – мой День рождения.

Празднование Дня рождения с друзьями планировалось в ночь с 12-го на 13 июня еще до того, как я узнал о хакатоне, было забронировано место, приглашены гости. Поэтому я очень переживал, что не успеваю на самую важную часть хакатона (презентацию результатов), и хотел поскорее собрать команду, которая смогла бы представить результаты без меня, если понадобится.

За день до митапа для разработчиков (за 2 дня до хакатона) на мой проект откликнулся дизайнер. Я объяснил ему, что да как насчет проекта и того, что я хочу уехать вечером с главной части для подготовки Д.Р. Сказал, что готов взять его к себе. Он ответил, что один человек на демонстрации – не очень хорошо, но что больше никого все равно искать не стоит, чтобы доля каждого от еще невыигранного приза была выше.

Приехав на митап разработчиков (1 день до хакатона) я встретил там знакомого по первому митапу – Вову. Он сказал, что тоже хочет участвовать, и спросил, есть ли у меня проект. Не смотря на то, что дизайнер предлагал никого больше не брать, я сказал Вове, что хочу взять его к себе и объяснил ситуацию насчет того, что пока не знаю, успеваю ли сам.

После митапа выяснилось, что один из моих друзей сильно приболел и не сможет прийти на праздник. Из-за этого решили все перенести, когда он выздоровит, всё удачно. Друг поправился через пару недель и собрал всех уже на свой Д.Р. Время на выходных полностью освободилось для хакатона. Я сказал дизайнеру, извинившись, что его брать не буду, оставив только Вову.

Хакатон

Не имея особенного опыта участия в подобных мероприятиях, я набрал походный рюкзак свяких Arduino-подобных железок, Raspberry Pi, прочей мелочи, паяльников и тому подобного. И захватил спальный мешок и зубную щетку. В итоге спать мы не ложились (хотя свободных кресел и диванов было предостаточно), а из железок приспособили только одну. Но это был очень необычный опыт – ехать на хакатон со спальником.

Регистрация, сбор команды

Я старался приехать как можно раньше, и пришел на место еще до того, как открылась регистрация. В здании мне сразу понравилось, было чисто и светло (какой-то из корпусов ВШЭ, арендованный на время мероприятия). На пуфиках у столов с регистрацией уже сидели несколько ребят-участников и Слава из Jolla.

Слава пошутил, что призы нужно давать всем, кто вообще решил прийти на первый хакатон по Sailfish, но Кирилл из Открытой Мобильной платформы объяснил, что это обсуждалось, и конечное решение в ОМП было за один крупный приз.

Вова пришел. За чаем в столовой выяснилось, что у нас у обоих есть забытый богом (и сотрудниками Toshiba) клёвый смартбук: Toshiba AC100 (у меня 117-ый, у него 116-ый). Я очень люблю корпус/железо этого устройства (и очень не долюбливаю его программную часть), поэтому мне этот факт запомнился.

Kirill from OMP at AngelHack

Перед началом хакатона нужно было выступить как лидер проекта, рассказав об идеях и о том, нужны ли тебе еще люди (максимум: 4 человека в команде). У меня в заявках был еще разработчик, и он пришел. Заранее немного прогуглив информацию о нем, мне показалось, что я не хотел бы брать его в команду (очень субъективно, без каких-либо причин). Позже я сильно переживал, что не беру того, кто сам попросился ко мне, но всё-таки не поменял своего решения.

Этот человек решил оставаться и тоже участвовать в номинации по Sailfish, так что он был первым соперником (он не был в какой-то команде, был один).

После выступления мне пришло уведомление о новой заявке от разработчика. Так я познакомился с Петром. По текущей работе он занимался питоном и rpg-играми, а также имел опыт с плюсами, ранее занимался исследовательской деятельностью. С первых минут общения я решил, что нужно его звать к себе, и не пожалел. Мы очень хорошо сработались, как мне кажется. Он поговорил с ребятами со всех доступных команд и остался с нами.

Начало работы, идея проекта

Каждой команде выделили огромные просторные места, бесплатное питание (обеды, ужины и закуски/попить/фрукты на ночь). Хакатон занял несколько этажей, в каждой аудитории было по паре команд. Мы были по соседству с ребятами, занимающимися VR/AR-проектами, все приветливые. Первое, что пришло в голову – спорсить их про недавний на то время видос “HYPER-REALITY”, который мне очень нравится. Так и познакомились, обменялись контактами.

В рамках проекта задумка была такая:

  1. Взять дешевые WiFi-модули ESP8266, подключить на них все датчики и актуаторы, что успеем (диоды-лампочки, серво-приводы, датчики температуры и влажности, кнопки, пьезо-пищалки, датчики освещенности, кнопки)
  2. Прошить Arduino-прошивку в модули, используя существующие наработки для протокола CoAP.
  3. Подготовить мобильный клиент для Sailfish, позволяющий обнаруживать CoAP-устройства в локальной сети, работать с их ресурсами, подписываться на происходящие изменения, базируясь на Qt-библиотеке для CoAP.
  4. Посмотреть в сторону таких проектов, как Saera и прикрутить голосовые команды к нашему мобильному клиенту.
  5. ???
  6. По возможности не попасть в упоминание @internetofshit в твиттерах.

Было решено распределить время следующим образом:

У меня был свой смартфон Jolla Sailfish, но при этом всем выдали рабочий прототип новых моделей Intex / Jolla C.

Эксперты-судьи из ОМП и Jolla дружелюбно помогали всем участникам. Обсуждали идеи, советовали, как их лучше развить.

Кирилл подсказывал, как, например, удачнее связать QML и C++ логику, давал советы по SDK. У Пети установщик SDK для linux не завелся на его ноуте, из-за каких-то особенностей с драйверами для WiFi – ушел в бесконечное ожидание. Не долго думая, запустили live-образ с флэшки, подготовленный Кириллом. Кстати, не забывайте включать аппаратную виртуализацию в загрузчике, она нужна Virtualbox из SDK. К которым, если что, можно подключиться по ssh.

Слава подготавливал VNC-сервер для удобной демонстрации на будущих презентациях, подкидывал дополнительных идей по работе с атмосферами и смс-ками. И еще поднял нам на Jolla C дополнительную WiFi-сетку. Как и в большинстве универов, где я был раньше, в этом тоже были параноидально закрыты все порты, кроме 80 и вроде 22.

at work

Т.к. можно было принимать участие в нескольких номинациях, мы выбрали еще номинацию Google с их beacon-маячками и Physical Web. Но быстро отказались от этой затеи, т.к. у меня были подозрения, что с текущей версией BlueZ или чем-то подобным на устройстве могут возникнуть дополнительные сложности, которые мы не осилим по времени. Эксперт с гугла приходил к нам, создал впечатление отлично разбирающего в своем деле специалисте. Он посоветовал нам также посмотреть в сторону Firebase для хранения данных с датчиков, и сказал, что в текущей версии она должна уметь работать и локально при временном отсутствии интернетов (на что мы больше всего ориентировались). Но мы не посмотрели, т.к. я планировал использовать знакомый мне CoAP и организовывать более простую по архитектуре систему. Возможно, напрасно, и сейчас Firebase у меня в todo и закладках.

Мы создали команду на гитхабе и взялись за дело.

CoAP (RFC 7252 Constrained Application Protocol)

CoAP – бинарный протокол, работающий поверх UDP (При желании – поверх TCP или даже SMS). Для безопасности предлагается DTLS. Разрабатывается для систем с ограниченными ресурсами, близок по областям применения к MQTT. Вот тут разработчик библиотеки на Си для микроконтроллеров хорошо сравнивает их.

Если грубо, то CoAP – больше для взаимодействия один-на-один с устройством в духе REST, а MQTT – для организации потока событий многие-ко-многим через промежуточные узлы.

Ребята, работающие над Wireshark, напрямую взаимодействуют с авторами стандарта и поддерживают развитие CoAP, поэтому протокол поддерживается приложением из коробки. Это очень удобно при отладке.

Протокол, в свою очередь, позволяет организовать ресурсы и доступ к ним по Link-формату. В общем, это очень похоже на легкий бинарный HTTP (есть те же GET, POST, PUT, DELETE и стандартные ответы ошибок), с возможностью обнаруживать доступные сервера, получать список их ресурсов и метаданные о них и подписываться на изменения.

Для тестов есть публичные сервера coap.me и еще один с observe-ресурсами из вуза в Швейцарии. А также куча приложений, библиотек и плагин для Firefox.

Мы собирались использовать набор библиотек Arduino, для него уже была готова библиотека microcoap, фокусирующаяся на экономии ресурсов. Поддержки подписок на ресурсы для получения информации об их изменении добавлено не было, поэтому я худо-бедно добавил ее сам до хакатона в рамках своей работы в аспирантуре.

ESP8266

ESP8266 – мега-популярный дешевый WiFi-модуль (SoC) от Espressif. Революция в мире IoT и тому подобное. К осени ждем от них ESP32 с BLE.

Для ESP8266 некто Иван Грохотков поддерживает шикарную Arduino-совместимость (берут SDK устройства и пишут реализацию ардуиновских библиотек).

Для хакатона я принес несколько ESP8266, подключал диод-лампочку и подготавливал CoAP-ресурсы:

Конечно, еще несколько датчиков и актуаторов приспособить было уже быстрее, но дошли мы только до первого.

Мобильный клиент Sailfish

Для мобильного клиента мы поискали библиотеки для CoAP на Qt и нашли qcoap и qtcoap. Выбрали второй, т.к. дома до хакатона у меня быстрее получилось поднять его на десктопном приложении, но оба проекта интересные. Я показал их Вове и пояснял какие-то идеи, а он занимался логикой поиска устройств и доступа к кокретным ресурсам, а также организацией нативных Silica-страничек интерфейса.

Он форкал позже qtcoap в нашу команду на гитхабе, т.к. ему не нравилась его архитектура, кажется (но могу путать).

Qt-библиотеки подключались достаточно легко. Т.к. мы торопились, подключали статически все недостающие файлы с дополнително подготовленным .pro-файлом, не создавая отдельные rpm-пакеты. Но, если что-то необходимое было доступно в OpenRepos, брали оттуда готовые бинарники.

sailfish client sailfish client

Голосовое управление

Перед хакатоном я нашел проект Saera[1,2,3,4]. На Jolla 1 дома у меня все запустилось и работало. Если использовать локальное распознавание голоса (на основе Sphinx и Julius, понятное дело), то оно очень уступает публичным веб-распознавалкам голоса. Возможно, если добавить в качестве опорных записей свой голос, то будет получше, но у меня было в районе 4-х корректных срабатываний из 10-ти на английскую речь (Julius показался успешнее, чем Sphinx). Если же в конфигах (~/.config/saera/setting.json) прописать распознавание через интернет:

    "internet_voice":True,
    "internet_voice_engine":"Houndify"

– дела заметно меняются в хорошую сторону (предлагается использовать разные доступные сервера: Wit, Google, Houndify, – все они норм).

Но на Jolla C аналоге – не получилось запустить. Мы пытались: сначала пакеты качались почему-то миллиард лет (хотя обычно всё ок), потом были какие-то сложности с библиотеками, в которых мы не успели разобраться. После Петя его форкал, патчил, переносил на 3-ий питон – чтобы упростить и просто использовать Houndify, оставив готовый интерфейс. Мы получали доступ по ssh к смартфону ssh nemo@device_ip и разбирались с пакетами с помощью pkcon и питоновскими модулями через pip (и со 2-ым, и с 3-им).

Но на гитхабе, возможно, была не совсем актуальная по сравнению с собранной в OpenRepos версия. Не осилили, в общем. Хотя все средства есть для этого, даже gdb поставился в пару команд.

В итоге решили, что быстрее будет сделать собственные запросы к Houndify (все равно это простые http-запросы). Я советовал Пете именно этот сервис, потому что люблю их SoundHound и не люблю Shazam. У меня уже был девелоперский аккаунт, и мы использовали его ключи.

Сначала мы взяли плюсовую библиотеку, доступную от авторов Houndify, и она работала. Но не понятно, зачем мы заморачивались с ней и ее классами и типами, когда можно было делать всё доступными средствами Qt и даже QML/JS.

hacking

Ночь, hacking time

Ближе к вечеру начали ощущаться сложности.

at work

На Saera было потрачено много времени, когда можно было просто слать http-запросы средствами Qt. Из QML доступен готовый MediaPlayer, позволяющий воспроизводить и записывать аудио. Для записи аудио взяли QAudioRecorder и сделали к нему нужные интерфейсы в QML.

import QtQuick 2.0
import Sailfish.Silica 1.0
import QtMultimedia 5.0

Page {
...
    MediaPlayer {
        onSourceChanged: {
            play();
        }
    }
...
}

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

Работа над клиентом для Sailfish продвигалась небыстро из-за того, что Вове приходилось разбираться в новом протоколе и осваиваться в QML и C++ связках.

Для тестов на железе, пока сам возился с ESP8266, я по-быстрому включил Raspberry Pi 2 с WiFi-модулем и Arch Linux ARM на борту. Но при очередной переконфигурации что-то поломал и она стала недоступна по сетевому кабелю и потеряла нужные WiFi-сети, а времени было всё меньше.

Примерно в 5-6 утра мы получили сообщение от Houndify, что привысили лимит на дневное число запросов к их бесплатным сервисам. Пете пришлось быстро переделать всё под IBM Bluemix. Добавил синтез-озвучивание ответов от клиента.

Осваивание широковещательных запросов по CoAP и отображение результатов в интерфейсе продвигалось, но небыстро.

В белые ночи в комании хороших товарищей ночь пробежала незаметно. Но, когда у Пети прозвенел будильник “подъем”, а никто не ложился, я особенно почуствовал, как поджимает время. Кроме того, появилась еще команда, заинтересованная в номинации и клиенте под Sailfish для их сервиса.

Утро, подготовка к презентации

У нас были закуски и все необходимое, и мы кушали ночью. Ребята решили сходить на завтрак и передохнуть, я решил добить wifi-модуль. И он, наконец, поддался, начав запускаться.

pwm

Ребята merge-ли наработки по голосу и CoAP, я создавал слайды презентации. Она доступна тут без переделок и прекрас. Также доступно видео моего выступления.

Завершение мероприятия

Собирая все вещи и сохраняя презентацию, мы пропустили первых выступающих (они же победители в главной номинации, не по Sailfish), но после мероприятия поговорили с ними – они крутые, делали мобильный ассистент для людей с ограниченными возможностями.

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

Вова уехал по делам домой пораньше, мы остались с Петей ждать результатов и слушать еще выступающих. Это, естественно, была самая длинная часть. Из-за своего сумбурного выступления я до последней секунды переживал, что мы не выиграем. Разработчик, который был один, не представлял свой проект, но другая команда показала мобильный клиент для их сервиса по общению с иностранцами. Очень переживал и из-за того, как мало успевали на практике. Когда назвали нашу команду – “отлегло”, и из эмоций была огромная радость и благодарность организаторам.

После мы заполнили необходимые документы, поболтали по душам с остальными участниками, Кириллом и Славой, – и поехали с Петей по домам.

После хакатона

Я выспался, вернулся к работе и стал готовить эту статью и всякие дополнительные документы на получение приза. С этим, правда, возникли сложности, т.к. при подаче документов выяснилось, что кроме банковских реквизитов, сканов паспорта и номера ИНН необходимо предоставить скан свидетельства из налоговой. За ним пришлось ехать по месту жительства в другой город, как я не старался это сделать удалённо. Документы в итоге подал, но с задержкой. Но приз все равно получил, и разделили его поровну.

Нас позвали на Sailfish Community Event в Хельсинки. У Вовы была готова виза, и он смог выбраться побывать на этом мероприятии.

Кроме того, выяснилось через вк, что один парень с Ижевска занимается мобильным голосовым помощником, используя сервисы Яндекса. Мы договорились объединить усилия.

Я приблизился к планам по поддержке голосового функционала для мобильного клиента Pebble Time, чему очень рад.

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

В целом от хакатона остались только положительные впечатления, и я без раздумий хотел бы поучаствовать в чем-то подобном снова. Желательно, снова связанным с Qt, конечно :)

winner's certificate

Ресуры

 █████╗  █████╗  ██╗██████╗  ██████╗ 
██╔══██╗██╔══██╗███║╚════██╗██╔═══██╗
███████║███████║╚██║ █████╔╝██║   ██║
██╔══██║██╔══██║ ██║ ╚═══██╗██║▄▄ ██║
██║  ██║██║  ██║ ██║██████╔╝╚██████╔╝
╚═╝  ╚═╝╚═╝  ╚═╝ ╚═╝╚═════╝  ╚══▀▀═╝