И снова привет! В прошлом уроке мы посмотрели проект для смартфона “Погодная станция”. Сегодня будем делать более сложный проект: “Куб времени”. Это устройство для тайм-менеджмента, которое поможет вам вести лог собственных занятий и знать, сколько времени вы тратите на работу, учебу, чтение, спорт, игры и другие занятия, а также планировать ваш день. Интересный гаджет и хороший пример для обучения программированию.
В ходе работы над проектом мы начнем писать свои собственные программы в Node-RED, более детально изучим возможности Termux (эмулятора среды Linux под смартфон) и запрограммируем сценарий, задействующий сенсорику смартфона!
![](https://habrastorage.org/getpro/habr/upload_files/ddc/62d/357/ddc62d3572f13dfdcd2bf049cf4284ee.png)
Этот урок - часть курса Galaxy Upcycling - новая жизнь старого смартфона, практико-ориентированные сюжеты которого показывают как, в рамках концепции Upcycling, превратить старые Android-смартфоны в интересные, небанальные, красивые и полезные устройства.
Текст написан по мотивам видео:
Основы Node-RED
Для начала - небольшое введение в среду визуального программирования Node-RED, которую мы установили в прошлом уроке. Начнем писать в ней самые простые программы.
В Node-RED программа называется потоком (flow) и состоит из отдельных узлов (node). Узлы соединяются друг с другом путём перетаскивания связи между ними. Через эти связи идут сообщения (messages), у которых есть названия (topic) и полезная нагрузка (payload).
Слева находится палитра узлов:
![](https://habrastorage.org/getpro/habr/upload_files/9ae/fcb/fd5/9aefcbfd5c0ab9c322fae3d2529c31da.png)
Самый важный узел - это отладочный узел (debug). Я рекомендую в любой непонятной ситуации пользоваться им. Если передадите в него сообщение, оно выведется в отладочной консоли, и вы сможете обнаружить и исправить ошибку.
Сделаем самый простой поток из двух узлов: Inject (вбросить в поток сообщение) и Debug (отладка).
![](https://habrastorage.org/getpro/habr/upload_files/24f/a7c/faf/24fa7cfaf9e2d4c19ee0a7e1e357a991.png)
После того как мы разместили и соединили несколько узлов, программу нужно развернуть (deploy), после чего начнется ее выполнение.
![](https://habrastorage.org/getpro/habr/upload_files/d63/e31/e36/d63e31e3653734950b93ac79cc5ca55a.png)
Нажатием кнопки на узле “Метка времени” можно запустить поток на выполнение. Мы видим, что в отладочной консоли каждый раз появляется сообщение с указанием текущего времени (Timestamp).
![](https://habrastorage.org/getpro/habr/upload_files/fc7/e94/3a0/fc7e943a0e508c77d70d733f875c3fc3.png)
Там могут быть любые данные, не обязательно время. Вы можете заставить узел отправлять что угодно, к примеру цифру 5, это делается в настройках узла (двойной клик мышью).
![](https://habrastorage.org/getpro/habr/upload_files/3d7/781/346/3d77813462a9941f28e092e75032fd5c.png)
Один из самых полезных узлов - функция (function). В нем можно писать любой код на языке JavaScript.
![](https://habrastorage.org/getpro/habr/upload_files/622/b58/83b/622b5883bb23558ee774ef167ed17c7c.png)
Например, я могу добавить туда простейший код, который умножает на два все, что приходит в узел, и тогда в узел debug будет приходить уже десятка, а не пятерка.
![](https://habrastorage.org/getpro/habr/upload_files/688/ad3/e2d/688ad3e2d64a339d80e99f26e8b00865.png)
Вся программа, написанная в Node-RED, представляет собой текст в JSON-разметке, то есть один большой текстовый файл. Поэтому, чтобы импортировать стороннюю программу, достаточно нажать на “Импорт” и вставить целиком ее текст. Так же легко можно экспортировать свою программу и поделиться ей.
В целом, Node-RED удобно использовать в учебных целях, а также для быстрого прототипирования. Для сложных проектов визуальное программирование не очень подходит, для них обычно пишут код в текстовом формате. Но для небольших проектов Node-RED - дружественная к пользователю, простая и визуально приятная среда.
Доступ к периферийным устройствам смартфона через Termux-API
Чтобы двигаться дальше у вас на смартфоне должна быть установлена программа Termux. Если вы не знаете, как это сделать, перейдите прямо сейчас к уроку “Погодная станция”.
Установим дополнительный программный пакет Termux-API, он скачивается с F-Droid: https://f-droid.org/en/packages/com.termux.api/. Нужно дать ему все возможные разрешения. Также установите в консоли Termux соответствующий пакет:
apt install termux-api
Введите в консоли команду termux-sensor -l, и вы увидите потрясающий список сенсоров! Очень круто, что у сенсоров указаны конкретные модели, а, значит, вы можете о каждом из них подробнее узнать в официальной документации от производителя. Список на разных смартфонах получится разный, в зависимости от аппаратного обеспечения каждого конкретного устройства.
![Пример сенсорной начинки флагманского смартфона Samsung S22 Пример сенсорной начинки флагманского смартфона Samsung S22](https://habrastorage.org/getpro/habr/upload_files/cf9/aa3/aeb/cf9aa3aeb667c5cecf40276bca3c8413.png)
Чтобы вывести показания конкретного сенсора, воспользуйтесь командой с ключом -s и впишите название сенсора. В моем примере я вывожу показания акселерометра:
termux-sensor -s "LSM6DSO Accelerometer"
![](https://habrastorage.org/getpro/habr/upload_files/ef2/548/432/ef2548432dd1a6073bd78cbbab8141ca.png)
Видно, что они идут в широко известном формате данных JSON, а, значит, их легко разобрать и выделить только интересующее нас значение. Остановить процесс можно, как и в обычном Линуксе, командой CTRL-C.
Чтобы получить одно значение, можно запустить команду с ключом -n равным 1:
termux-sensor -s "LSM6DSO Accelerometer" -n 1
Выводим показания сенсоров в Node-RED
Возвращаемся к разработке в среде Node-RED! Ставим в ней пакет узлов для работы с Termux-API: https://flows.nodered.org/node/node-red-contrib-termux-api
В левой панели появятся новые узлы, относящиеся к функционалу смартфона.
![](https://habrastorage.org/getpro/habr/upload_files/cca/f56/640/ccaf566409a58e9de0d5f219c4aa3c43.png)
Для примера посмотрим, как работает узел vibrate - включение вибромотора телефона. Поставим timestamp и из него переход в узел vibrate. Как только кликнем на узел timestamp, увидим, что телефон завибрировал.
![](https://habrastorage.org/getpro/habr/upload_files/857/c5a/882/857c5a88253dde8bc2224dd78594beeb.png)
Теперь сделаем так, чтобы показания нашего сенсора появлялись в Node-RED.
Любую консольную команду можно запустить на выполнение через узел exec и получить результат. Выберите слева такой узел и перетащите его на панель программы. Выход узла exec соедините с узлом отладки (debug). Вот как это будет выглядеть:
![](https://habrastorage.org/getpro/habr/upload_files/ead/150/d92/ead150d92ab346c27d9569efc283ed2a.png)
Теперь в окошке справа вы увидите показания сенсора:
![](https://habrastorage.org/getpro/habr/upload_files/27b/eeb/456/27beeb456dc22f347aa11a1aadf0a201.png)
Видно, что в отладочном окне объект на выходе узла exec содержит текстовую строку из трех значений: x, y и z.
Для удобства я сразу переименовала узел, чтобы он назывался “Получить данные с акселерометра”. Переименовать узел можно, открыв параметры узла двойным кликом и изменив строку “Имя”.
![](https://habrastorage.org/getpro/habr/upload_files/fd2/fd9/769/fd2fd9769dce56eae36820f1ef504082.png)
Чтобы работать не со строкой, а с массивом значений, передадим нашу строку в функцию json. Это стандартная функция, она делает из строки в формате JSON объект JavaScript.
![](https://habrastorage.org/getpro/habr/upload_files/d28/5f0/44b/d285f044b6abaa91ff11594a58ba0f18.png)
В результате этого у нас на узле debug будет уже не текстовая строка, а объект JavaScript:
![](https://habrastorage.org/getpro/habr/upload_files/cec/8dd/722/cec8dd722511d50ab80fd0b2fbd2f373.png)
Узнаем грань кубика из показаний акселерометра
Напишем простую функцию, которая по полученным значениям x, y и z, –покажет, на какой из шести граней стоит наш кубик.
Для этого сделаем узел function, в котором и начнем писать нашу функцию.
![](https://habrastorage.org/getpro/habr/upload_files/8a8/303/e96/8a8303e96c191510e17116b7a766ab2c.png)
Для начала “вытащим” значения x, y, z из массива. Есть небольшая тонкость. Поскольку в названии сенсора стоит пробел ("LSM6DSO Accelerometer"), то при попытке к нему обратиться в коде возникнет ошибка. Поэтому его нужно всегда указывать в кавычках, пример: msg.payload["LSM6DSO Accelerometer"]:
var accelerometer = msg.payload["LSM6DSO Accelerometer"];
var x = accelerometer.values[0];
var y = accelerometer.values[1];
var z = accelerometer.values[2];
Теперь я воспользуюсь готовым кодом, чтобы из показаний акселерометра вычислить сторону кубика. Этот код я не придумала сама, а взяла готовый из видео-инструкции на YouTube о том, как сделать “умный игральный кубик” от канала Playful Technology. Этот код очень наглядный и понятный.
var accelerometer = msg.payload["LSM6DSO Accelerometer"];
var x = accelerometer.values[0];
var y = accelerometer.values[1];
var z = accelerometer.values[2];
var side=0;
if (Math.abs(x) > Math.abs(y) && Math.abs(x) > Math.abs(z)) {
if (x > 0) {side = 0}
else side = 1;
}
if (Math.abs(y) > Math.abs(x) && Math.abs(y) > Math.abs(z)) {
if (y > 0) { side = 2 }
else side = 3;
}
if (Math.abs(z) > Math.abs(x) && Math.abs(z) > Math.abs(y)) {
if (z > 0) { side = 4 }
else side = 5;
}
msg.payload = side;
return msg;
Запустив код, мы видим, что в консоль будет печататься грань, на которой стоит кубик.
Теперь сделаем эту программу циклической. Пусть она в цикле опрашивает смартфон и выдает сообщение с гранью кубика, только если грань поменялась.
![](https://habrastorage.org/getpro/habr/upload_files/269/07b/f72/26907bf7290ce743dc331c2b705f84c9.png)
Я добавила глобальную переменную prev_side и теперь печатаю грань кубика и обновляю глобальную переменную, только если грань поменялась.
В Node-RED можно выводить отладочную информацию рядом с узлом, например, такой строкой:
node.status({fill:"red",shape:"dot",text:"red"})
В результате вместе с текстом будет выведен красный кружок, и это можно использовать для визуальной индикации.
Чтобы не переполнять отладочную консоль текстом, советую выводить грань по ходу потока, рядом с узлом, где вычисляется грань.
Подключаем трекер времени Toggl
Остался последний шаг: сделаем куб трекинга времени. Например, мы хотим отследить, сколько времени в день тратим на чтение, бытовые дела и занятия спортом. Нарисуем или напишем названия этих активностей на гранях кубика. Будем поворачивать кубик каждый раз, когда меняем занятие. Такое устройство очень полезно для хронических прокрастинаторов. Понаблюдав за собой при помощи этого кубика, вы поймете, куда уходит ваше основное время.
Как учитывать время, затраченное на дела? Для этого существуют готовые решения. Я решила воспользоваться бесплатным веб-сервисом Toggl, в нем уже есть необходимые мне функции: установка и сброса таймера, назначение меток таймерам, вывод статистики.
![Пример статистики по временным затратам в Toggl Пример статистики по временным затратам в Toggl](https://habrastorage.org/getpro/habr/upload_files/f7d/244/21e/f7d24421e2228376d535a9c4d1281096.png)
Я соединю этот сервис с Node-RED, чтобы установка и сброс таймеров в Toggl осуществлялись не нажатием кнопки на сайте или в мобильном приложении, а происходили как реакция на сигнал о переворачивании кубика на другую сторону.
В Node-RED есть пакет node-red-contrib-toggl, установите его через “Управление палитрой”. После установки у вас в среде появятся новые узлы.
![](https://habrastorage.org/getpro/habr/upload_files/436/6c0/5a3/4366c05a3aa38f78fa1192176bcc1eb7.png)
В параметрах узла start timer увидите, что нужно добавить конфигурационный файл.
![](https://habrastorage.org/getpro/habr/upload_files/104/323/7af/1043237af0f6e176eacead7e04b0009f.png)
Нажав на “карандашик”, увидите, что предлагается добавить новый API-ключ.
Где его взять: захожу на сайт Toggl, меня интересует продукт Toggl Track. Регистрация бесплатна. В настройках своего профиля я могу посмотреть API-ключ, при помощи которого очень легко настроить интеграцию со сторонним сервисом.
![](https://habrastorage.org/getpro/habr/upload_files/320/5c3/0ba/3205c30ba1a23c29ddaffe40f3dc2f6a.png)
Пропишите этот API-ключ в настройках узла Toggl и затем совершите развертывание потока (не обращайте внимания на сообщение об ошибке), чтобы в узле Toggl появился выбор Workspace (рабочей среды). Выберите свою среду и проект, который будет запускаться, например, “Чтение”.
Всё почти готово! Теперь осталось реализовать следующую логику: остановка существующего таймера, старт нового таймера. Одну грань можно оставить без таймера - это будет сброс куба (остановка всех запущенных таймеров).
Я ставлю узел “Get running timer” и в настройках включаю галочку на “send false if no running timer”, чтобы не генерировалось сообщение об ошибке. В нашем случае отсутствие таймера - это не ошибка, а вполне штатная ситуация. Если таймер запущен, то при смене грани кубика я его сбрасываю. Затем совершаю выбор, какой новый таймер запустить.
Есть один не самый простой момент - это когда мы добавляем условный оператор и смотрим, не является ли имя таймера равным false. Здесь нужно сравнивать именно как выражение, а не как строку (по умолчанию).
![](https://habrastorage.org/getpro/habr/upload_files/c5f/5ad/84e/c5f5ad84e2feb45d084d997b48821c92.png)
В завершение давайте добавим обратную связь. Можно добавить вибрацию, чтобы поворот куба сопровождался обратной связью от телефона.
Корпус я сделала из картонной коробки, на гранях написала занятия, смартфон вклеила на двусторонний скотч. Это годится как самый первый прототип. Потом можете дорабатывать кубик дальше, если вам понравится устройство.
![](https://habrastorage.org/getpro/habr/upload_files/17b/cc6/d9a/17bcc6d9a3a727c8681ff5ff28d37c8c.png)
Скачать мой код можно по ссылке: https://gist.github.com/tatyanavolkova/3b75d501fa0d67a62e2d4e1b11633abf
Заключение
Вот такой куб времени у меня получился, он поможет вам измерять затраты самого ценного и невосполнимого ресурса – времени; планировать ваш день будет проще.
Получается, что покупать дорогие одноплатные компьютеры необязательно, если вы хотите проверить какую-то гипотезу, протестировать несложный код или сделать любительский проект с киберфизическим устройством. Оказывается, что для некоторых таких задач вполне хватит смартфона. Теперь вы можете сделать очень и очень многое, а наш курс Galaxy Upcycling даст вам массу интересных идей. Удачи!
Другие статьи этого цикла:
Несложные оптические трюки со смартфоном: голограмма и проектор
Новый год не за горами: делаем супергирлянду на базе ESP и WLED, управляем со смартфона
Linux на смартфоне: делаем экран погодной станции, используя Termux и Node-RED
![](https://habrastorage.org/getpro/habr/upload_files/10d/f57/050/10df57050d040c6e0852f7e4b87dee8a.png)
Татьяна Волкова
Куратор образовательных программ Samsung Innovation Campus
#SIC_Russia_2023 #enabling_people #SamsungInnovationCampus