Madrobots
Компания
82,83
рейтинг
13 августа 2014 в 20:33

Разное → Pebble + Marlight: управляем светом жестами из песочницы


Привет, Хабр и хабровчане. Хочу рассказать об одном эксперименте, который провел на днях. Очень мне понравились два девайса из статей от Madrobots: лампы Marlight и часы Pebble. Причем понравились именно тем, что конфигурируемы, т.е. подвластны так сказать воле и воображению хозяина. Пока ребенок на даче, решил я устроить ему сюрприз и показать настоящую современную «техномагию», а именно: управление светом жестами.

Задача: с помощью неких движений выбирать комнату, а затем взмахом руки или включаем, или выключаем свет в выбранной комнате.

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

Многие из статей, что я здесь читал… Они классные! Читаются на одном дыхании и кажется, что господи – ведь так же просто все, чего ж я сам-то не сделаю так же. Собственно именно такие мысли и натолкнули меня на вот это все, что ниже описано. НО! Есть одно важное «но». Я хотел помимо конечного результата описать еще свои мытарства в областях, в которых я, строго говоря, ничего не смыслю. Я никогда не писал под php и js, а c++ был в институте и очень давно. Кому-то покажется, что я очень много внимания уделяю элементарным вещам, а может даже в некоторых моментах я откровенно ошибаюсь или что-то понимаю не правильно, однако я добился поставленной задачи и хотел продемонстрировать не только результат (возможно не такой уж и впечатляющий), но и путь, которым я к нему шел.

Итак, что у нас есть из железа:

  • наручные часы pebble с акселерометром
  • телефон с iOS на борту
  • комп с виндой, выполняющий функции сервера (т.е. включенный 24х7)
  • wi-fi коннектор marlight, подключенный к домашнему wi-fi и имеющий статический IP
  • освещение в квартире на базе ламп marlight (8шт) в каждой комнате(3)


Лампы купил сразу все. Здесь. Не дешево конечно, но они все же экономичные по энергопотреблению, а менять – так уж все сразу. Так что у меня четыре лампы в большой комнате, три в детской и одна в спальне (мало! Надо минимум три – световой поток одной лампы в максимальной яркости: 500 люмен, что не дотягивает даже до 50 ваттной лампы накаливания). Каждая комната – отдельный канал на коннекторе, и даже еще один остается на расширение: в ванную, например (pebble же водонепрницаемые… Чем плохо: лежишь в ванной и управляешь светом! Правда, придется сделать больше функций, чем просто включение-выключение).

C wifi-коннектором вышла легкая заминка: при включении он предлагает выбрать тип шифрования и не смотря на наличие инструкции в которой в качестве примера показано WPA2, в списке выбора такого варианта не обнаруживается. Однако специалисты тех. поддержки магазина мне разъяснили, что выбирать тип шифрования не надо – мол указываешь SSID, пароль и вуаля – коннектор в сети. Собственно все это было и есть в инструкции у них на сайте.

Биндинг ламп на конкретный канал так же не вызвало затруднений – благо я уже знал, где лежит инструкция! (Что характерно – в бумажке, что шла с коннектором процедура была описана несколько иначе – так вот работает именно та, что на сайте продавца).

Протестировав штатное iOS-приложение, я убедился, что могу управлять освещением с телефона (что само по себе уже удивительно), причем мне для этого не надо переключать сеть, как было бы, будь коннектор в stand-alone режиме. Пора переходить к тому, что я раньше никогда не делал: настраивать web-сервер.

Зачем web-сервер, спросите вы? А потому, что в упомянутой выше статье про лампочки была ссылка на php-скрипт, который при получении GET (и POST) запросов – пересылает соответствующий udp-пакет коннектору, заставляя того выполнить то или иное действие с освещением. Я кстати вполне допускаю, учитывая архитектуру pebble, о которой речь пойдет чуть ниже, что без сервера можно было обойтись, но… Я был вполне уверен, что http-запрос с часов инициировать можно, а вот на счет всего остального уверен не был.

Запустить php под IIS7 мне помогла вот эта хабра-статья. В принципе ничего сложного, главный урок, который я для себя извлек: у MS весьма своеобразное представление о user-frendly экране об ошибке. Только отключив эту опцию, я понял, что php у меня работает, а ошибки следует искать в скрипте (вернее в отсутствии библиотеки sockets, которую скрипт использует). Пробуем через localhost – бинго! Работает.

Установив на pebble/телефон приложение smartwatch+ пробую http-запросы. Конечно же натыкаюсь на брандмауэр, после добавления нужного порта в исключения – я таки могу уже управлять светом в комнате используя часы. Правда, со сторонним приложением. Значит нам пора в cloudpebble.net

С этого момента хабр ответы на возникающие вопросы не давал, пришлось гуглить. Гуглил я много и далеко не всегда результативно, пока не набрел на вот этот замечательный ресурс. Беглого просмотра оказалось достаточно, что бы понять, что это то, что нам нужно. И вот тут меня ждал сюрприз! Оказывается sdk pebble предоставляет возможность разработать решение, включающее в себя связку из кода, исполняемого как на часах, так и на телефоне! Уже потом я нагуглил, что у них так же есть наработки по js-приложению, которое полностью исполняется на телефоне, используя pebble сугубо как устройство вывода, но сейчас речь не об этом.
Итак, зачем же нам использовать два устройства и как это работает. Ну, по задумке у нас на часах акселерометр и именно его мы и хотим использовать в качестве управляющего устройства. А вот http-запрос… Даже если предположить, что это возможно напрямую (использую телефон в качестве условного «роутера»), то это неоправданно сложно. Возникает вопрос: зачем? Если реализован механизм обмена сообщениями, и на каждой из сторон может быть выполнен свой код? Как показала практика http запрос на стороне телефона – не просто, а очень просто!

Начнем пожалуй. В качестве темплейта нового приложения воспользуемся демкой из sdk pebble – appMessage. У нас сразу создастся два исходника — .c для часов и .js для телефона. Да-да, на телефоне используется java-sсript (помните, я упомянул, что вполне вероятно можно udp-пакеты управляющие напрямую слать на коннектор? Я просто не силен в js, поэтому понятия не имею можно ли это сделать и если можно, то как, но… Что-то мне подсказывает, что если есть в php, то должно быть и в js. Разве что возможности виртуальной машины в приложении pebble могут быть сильно урезаны).

Вот как выглядит мой файл .js (от дефортного он отличается, прямо скажем, не сильно):
// Событие при запуске - можно протестировать доступность URL... Но я просто шлю сообщение
Pebble.addEventListener("ready",
                        function(e) {
                          Pebble.sendAppMessage({0: “Ready!”});
                        });

// Обработка входящих сообщений: отправляем GET запрос, посылаем "эхо" обратно на часы
Pebble.addEventListener("appmessage",
                        function(e) {
                          var msg = e.payload.message; // SETTINGS : PEBBLE KIT JS : MESSAGE KEYS
                          var req = new XMLHttpRequest();
                          req.open('GET', "http://srv:8080/marlight.php?command="+msg, true);
                          req.send(null);
                          Pebble.sendAppMessage({0: msg});
                        });

Знаете, что я долго не мог понять? Что такое e.payload.message. Нет, серьезно! Я понимаю, что мы как-то передаем сообщение, что эта вот конструкция должна то, что мы передаем возвращать, но… Как? Как видно из исходника модуля для часов мы по сути передаем словарь, где значения идут по индексу… Оказывается дело в этом:



Это настройки именно для этого проекта в облачной IDE. И именно это связывает e.payload.message и MESSAGE_KEY в строчке dict_write_cstring(iter, MESSAGE_KEY, command), модуля для часов, и там и там некое осмысленно представление индекса.

В общем, не суть. Все тут понятно – при получении сообщения, мы извлекаем из него строку команды, которая должна дополнить имеющийся у нас URL, для получения конкретного GET-запроса, который заставит наш скрипт попросить коннектор переключить лампочки! Круто. На всякий случай шлем «эхо» обратно на часы.

Так, переходив в модуль .c, который соответственно исполняется на часах. Процедура отправки сообщения с часов на телефон у нас есть по дефолту:

/* Запись сообщения (параметр command) в буфер и отправка на телефон */
void send_message(char* command){
	DictionaryIterator *iter; // создание словаря
	app_message_outbox_begin(&iter); // начало сообщения
	dict_write_cstring(iter, MESSAGE_KEY, command); // отправка команды на телефон
  dict_write_end(iter); // конец сообщения
  app_message_outbox_send(); //отправка
}

Ну, почти по дефолту… Все, что я сделал с этой процедурой – это добавил параметр-команду и заменил тип отправляемого пакета на строковый… О эти строки в С++! Кто не работал с указателями, кто не пытался вывести число в строку, тому не понять. Но благодаря примерам и SDK, я все же выяснил, что функция snprintf поддерживается, поэтому вывод форматированного текста (с преобразованием числа в строку) на экран, хоть и не так прост, как в привычных языках высокого уровня, но все же понятен:

  channel = 1; // по умолчанию у нас включен 1-ый канал
  snprintf(channel_s, sizeof("Channel: 0"), "Channel: %d", channel);
  text_layer_set_text(channel_layer, channel_s);  /* показываем сообщение при запуске программы */     


Я привел только само преобразование и вывод текста, инициализацию текстового слоя полностью можно посмотреть в статье про программирование под Pebble или в исходнике, ссылку на который я приведу в конце статьи.


Попробовав переслать пару статичных команд, и убедившись, что это работает – я перешел к самой сути: акселерометру. Что собственно такое акселерометр? В SDK есть пример работы с ним – часы по тамеру получают значение ускорения для каждой из трех осей и применяют его к паре десятков «дисков», которые имеют условную массу в зависимости от размера, а, следовательно, инерцию. Все это отрисовывается на экране часов.

Диски двигаются при наклоне в ту или иною сторону – все красиво… Но так сразу даже и не понятно, что из этого следует и как это применить на практике. Тогда я взял и тупо вывел данные текущего ускорения по осям в лог!

 /* структура для хранения значений ускорения по всем трем осям */
  AccelData accel = (AccelData) { .x = 0, .y = 0, .z = 0 };
  /* для начала получим текущее значение ускорений */
  accel_service_peek(&accel);
  APP_LOG(APP_LOG_LEVEL_DEBUG, "x:%d, y:%d, z:%d", accel.x, accel.y, accel.z);


Лирическое отступление: команда вывода в лог APP_LOG(APP_LOG_LEVEL_DEBUG, «SPARTAAA!!!»); встречается в исходниках часто, однако не так очевидно, где же этот самый лог! Ну, во-первых, это кнопочка VIEW LOGS после загрузки приложения на телефон:

А во-вторых, лог можно найти в меню: COMPILATION – VIEW APP LOGS.


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

Итак, ускорение свободного падения с точки зрения акселерометра pebble равно 1000 ± 100 пунктов. Думаю именно так и задумывалось при калибровке. Значит порогом срабатывания можно считать 900 при совпадении направления оси и ускорения, и -900 когда ось и вектор ускорения полностью противоположны. Промежуточные значения пока рассматривать не будем.

Создадим структуру для хранения состояния осей, опишем возможные состояния, а так же заведем константу для гравитации:
typedef struct Vector {
  int x, y, z;
} Vector;

static Vector current; 	//текущее состояние

/* Состояния осей акселерометра */
enum{
  HYRO_NN = 0, // нейтральное
  HYRO_UP = 1, // повернута вверх
  HYRO_DN = 2  // повернута вниз
};

#define GRAVITY 900 // Ускорение свободного падения с точки зрения акселерометра pebble 1000 +/- 100 

Тогда инициализацию состояния можно было бы прописать как:
  if (accel.x > GRAVITY) current.x = HYRO_DN; 
  else if (accel.x < -GRAVITY) current.x = HYRO_UP;
  else current.x = HYRO_NN;
  if (accel.y > GRAVITY) current.y = HYRO_DN; 
  else if (accel.y < -GRAVITY) current.y = HYRO_UP;
  else new.y = HYRO_NN;
  if (accel.z > GRAVITY) current.z = HYRO_DN; 
  else if (accel.z < -GRAVITY) current.z = HYRO_UP;
  else new.z = HYRO_NN;

Допустим. Однако нам нужен триггер, т.е. событие, на которое можно будет выдать ОДНОКРАТНУЮ реакцию (скажем, подняли руку, или повернули запястье). А значит нам нужно не столько состояние осей, сколько их изменение. Следовательно, нам надо хранить предыдущее измерение, что бы было с чем сравнивать, и обновлять его только если оно изменилось:
static Vector old; 	    //старое
static Vector new; 	    //новое

  if (accel.x > GRAVITY) new.x = HYRO_DN;  
  else if (accel.x < -GRAVITY) new.x = HYRO_UP;
  else new.x = HYRO_NN;
  if (accel.y > GRAVITY) new.y = HYRO_DN; 
  else if (accel.y < -GRAVITY) new.y = HYRO_UP;
  else new.y = HYRO_NN;
  if (accel.z > GRAVITY) new.z = HYRO_DN; 
  else if (accel.z < -GRAVITY) new.z = HYRO_UP;
  else new.z = HYRO_NN;

Теперь мы можем проверить изменилось ли состояние, и если да, то как изменилось. Если так, как задумано, то выполняем действие:
  if (old.x!= new.x) { /* если оно изменилось по оси х */
    /* проверим, как именно изменилось */
    if (new.x == HYRO_UP){ // если руку подняли 
      snprintf(command_s, sizeof("ON_0"), "ON_%d", channel); // то надо послать команду включения
      send_message(command_s);  /* посылаем сообщение */
      text_layer_set_text(command_layer, command_s);  /* показываем сообщение */
    } 
    if (new.x == HYRO_DN){ // если руку опустили
      snprintf(command_s, sizeof("OFF_0"), "OFF_%d", channel); // то надо выключить
      send_message(command_s);  /* посылаем сообщение */
      text_layer_set_text(command_layer, command_s);  /* показываем сообщение */
    } 
    /* зафиксируем изменение */
    old.x = new.x;
  }
  if (old.y!= new.y) { /* если оно изменилось по оси y */
    /* проверим, как именно изменилось */
    if (new.y == HYRO_DN){ // если повернули кисть влево 
      channel++; // то следующий по порядку канал 
      if (channel == 5) channel = 1; // по кругу
      snprintf(channel_s, sizeof("Channel: 0"), "Channel: %d", channel);
   		APP_LOG(APP_LOG_LEVEL_DEBUG, channel_s);  
      text_layer_set_text(channel_layer, channel_s);  /* показываем сообщение */
    } 
    if (new.y == HYRO_UP){ // если повернули кисть вправо 
      channel--; // то предыдущий канал 
      if (channel == 0) channel = 4; // по кругу
      snprintf(channel_s, sizeof("Channel: 0"), "Channel: %d", channel);
   		APP_LOG(APP_LOG_LEVEL_DEBUG, channel_s);  
      text_layer_set_text(channel_layer, channel_s);  /* показываем сообщение */
    } 
    /* зафиксируем изменение */
    old.y = new.y;
  }
  if (old.z!= new.z) {  /* если оно изменилось по оси z */
    /* пока просто зафиксируем изменение */
     old.z = new.z;
  } 


Пробуем:


Работает!

Эпилог. Поставленная в начале задача выполнена. Думаю многие хотели бы знать, насколько это функционально – переключать свет жестом. Да в общем-то не очень. Практика показывает, что в 80% случаев проще всего пользоваться обычным выключателем. Необходимость удаленного включения/выключения/настройки света может возникнуть только тогда, когда ты, допустим, удобно устроился у телевизора, или лег спать и тебе лень вставать… В таком случае управление с часов удобнее, чем с мобильника (мобильника под рукой может и не быть), однако жесты… Жесты это скорее WOW-эффект. Даже с добавлением «горячих клавиш» от pebblebits (позволяет запустить до четырех приложений не через меню, а нажатием комбинации кнопок), гораздо практичнее было бы грамотно организованное меню, предоставляющее быстрый и интуитивно-понятный доступ к основным функциям освещения. И тем не менее, я считаю этот проект для себя очень удачным. По нескольким причинам. Во-первых, развернутый web-сервер, управляемый GET-запросами – очень классная штука. Он может получать команду не только и не столько от часов, но от чего угодно: от датчиков движения и/или освещенности до какого-то обработчика голосовых команд. Так же по аналогии со скриптом marlight.php, я могу накидать скрипт, выполняющий действия, выходящие далеко за пределы управления освещением. Вполне допускаю, что для большинства здесь присутствующих это азы, но для меня опыт был полезен. Ну и конечно pebble! В ходе проекта я научился строить приложения для часов, которые умеют общаться с внешним миром, что открывает действительно широкие перспективы для их использования. Конечно, мне очень помогли статьи по программированию pebble, которые были на Хабре ранее (а MagicPebble я установил в часы на постоянной основе), но все эти примеры оставляют умные часы вещью в себе, при том, что простейший в общем-то код делает их частью общей «экосистемы» девайсов в доме.

Ссылки:
  1. Исходник для pebble на GitHub: PebbleToMarlight
  2. php-скрипт для сервера: marlight_php
  3. Генератор русской прошивки для pebble с доп. опциями:pebblebits.com
  4. Хороший набор примеров с разъяснениями:try { work(); } finally { code(); }
  5. Статьи на хабре по программированию pebble: раз, два, три.


P.S. Пока я писал эту статью, дважды обновилась прошивка pebble. Причем первый раз — с 2.3 на 2.4, что привело к невозможности загружать свои проекты на не обновленные часы, а так-как на pebblebits.com русского варианта не было — обновить до 2.4 означало бы отказаться от основной функции pebble: показывать звонки, сообщения, события и прочая, т.к. в оригинальной прошивке русский текст отображается квадратиками. Однако парни выложили новую платформу через неделю после выхода официальной, за что им глубокий респект!


Автор: @Nehc
Madrobots
рейтинг 82,83
Компания прекратила активность на сайте

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

  • 0
    Технически, можно обойтись одним-двумя экранами приложения (без жестов), если задействовать удержания и двойные нажатия всех четырёх кнопок на часах. Например, так:

    Нажатие кнопки «вверх» или «вниз» переключает активный канал (1, 2, 3, 4, all)
    Двойное нажатие «вверх» или «вниз» меняет яркость выбранного канала. Удержание — температуру.

    Нажатие кнопки «выбор» включает или выключает выбранный канал.

    Удержание кнопки «выбор» переключает выбранный канал в цветной режим.
    Цвет управляется нажатием кнопок «вверх-вниз». Двойное нажатие «вверх-вниз» — яркость цветного света. Удержание — выбор режимов, доступных в приложении на смартфоне.
    И т.д.

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

    P.S. Наш сотрудник уехал в отпуск и, как раз, пишет аналогичное приложение для Pebble. Возможно, у вас получится интереснее и удобнее. Впрочем, в статью неплохо было бы добавить инструкцию по установке такой системы, как у вас.

    P.P.S. C учётом того, что вы хотите докупать лампы — приходите в наш магазин на Горбушке и получите подарок. С любовью, ваши безумные роботы)
    • 0
      Выпросил таки подарок… Мне стыдно! Но все равно хочется… ) А что сказать-то? Продавцу?
      • 0
        Напишите мне на az@madrobots.ru. Поделюсь секретной фразой.
  • 0
    e.payload.message это просто ад какой-то. Оно мне подарило пару незабываемых часов в попытках понять, как же должна работать передача данных. Точнее саму передачу данных я понял, а вот парадигму — индекс/ключ я долго не мог понять. В итоге расковырял пример и долго матерился от простоты, и того, что эта простота не описана нормально в документации.

    встречается в исходниках часто, однако не так очевидно, где же этот самый лог!

    Лог можно смотреть в реальном времени на компе при установке SDK, там ключик есть специальный. И скриншоты там же снимать.
    • 0
      Фишка в том, что я так понял они сейчас не предлагают SDK на комп. Только облачное IDE. Или я не нашел. НО это не проблема — в облаке тоже вполне можно смотреть логи в реальном времени — я так и делал. А попасть туда можно вот как я написал — или сразу после инсталяции на часы, или потом через COMPILATION – VIEW APP LOGS.
      • 0
        Да ладно, вот SDK: developer.getpebble.com/download-sdk/
        После того как облачная хрень перестала меня пускать и удалила все мои проекты, я на нее обиделся и поставил нативный sdk.
        • 0
          Чувствую себя дураком, но по ссылке, у меня текст:

          1. Install the SDK
          GET STARTED ON CLOUDPEBBLE
          Detailed installation instructions are available for MacOS X and Linux or you can skip the download/configuration and Get Started with CloudPebble.

          т.е. он предлагает пойти в облако, или почитать инструкции для Мака и Линукса. Ради интереса пошел по ссылке Линукса, там и правда есть дистрибутив… Но у меня-то винда!
          • +1
            Оу, нет, это я теперь себя дураком чувствую. И правда, забыл что за пределами MacOS есть жизнь.
  • 0
    А под андроид все делать может Tasker+AutoPebble.
    • 0
      Да? Я читал в обзоре про «Универсальный комбайн: AutoPebble+Tasker+plugins», и что он может очень много, но в лоб про преобразование жестов в http-запросы не видел… В прочем это таки не важно, потому что для iPhone так не получится, насколько я понимаю… Вообще для iPhone на удивление мало умных часов. Pebble чуть ли не единственный вариант… Вероятно ребята из Купертино не очень охотно идут навстречу разработчикам в ввиду собственных разработок на эту тему! ))
      • 0
        Под андроид будет работать и без других плагинов, т.к. Таскер сам умеет делать http запросы.
        AutoPebble, при запущенном приложении на часах, может мониторить акселерометр и отправлять команды отдельно для движений по 3м осям. Хотя конечно проще повесить все на кнопки.
        • 0
          Круто. Надо поковырять Таскер. Как я понимаю там что-то связанное с голосовыми запросами тоже можно реализовать? Причем, желательно, в режиме «OK, Google», и далее команда. Тогда для управления светом (и не только) голосом осталось всего-ничего: какой-нибудь планшет на андроиде, который постоянно «слушает» и при узнавании команды отправляет http запрос… Хотя, я думаю, что такое вполне может быть есть уже готовое — надо только погуглить… Эх! Все уже украдено придумано до нас. (
  • 0
    Да давно уж есть. Но чтобы не ело батарейку, то только Moto X, на котором под активный микрофон выделено отдельное ядро. Tasker+AutoVoice вообще рулит…
    На том же канале у Doug Gregory есть демка управления умным домом через голос с LG G Watch. Ну а гуру в этом Armando Ferreira.

    Промазал веткой…
    • 0
      У меня ссылка на Tasker+AutoVoice не открывается… Или там просто ссылка на поисковый запрос по этим словам в Google? Ок, посмотрю. Спасибо, интересная тема! Только у меня сейчас андроид (взял поиграться) пишет, что Tasker не доступен в моей стране… Это потому, что у меня карты там никакой не подвязано, или это, страшно сказать — санкции западные? )
      • 0
        Англичанин закрыл доступ для нас по политическим взглядам.
        Russia is drifting rapidly towards an aggressive, isolationist dictatorship.
        It's not about Crimea/Ukraine specifically, but rather the internal situation in Russia. Repression of protest, removal of free press and media, increasing military budget, isolationism, encouraging nationalism, non-independent justice system etc.
        I live only a couple of borders away. Aggressive dictatorships are scary.

        По первой ссылке мой пост о том как добавить свои команды в Google Now. Для тестов можно использовать триальную версию с оффсайта. (и кстати самим же таскером можно сделать этот триал бесконечным =))
  • 0
    Nehc, после этой статьи я уже не удержался.

    Ну в общем управление жестами — действительно перебор. Назначение действий в Tasker решает. Сделал три кнопки — вкл, выкл, красный свет (вечером перед сном). Дополнительно в меню — поднять/опустить до упора цветовую температуру.

    Серверную часть в виде великолепного php скрипта поднял на виртуалке с Centos. В cron пока ввел следующее:

    */1 * * * *! ping -c 3 -W 1 192.168.0.13 &&! cat /root/phoneflag && wget -qO- localhost/marlight.php?command=ALL_OFF && echo «1» > /root/phoneflag
    Каждую минуту пинговать мой мобильник, если не пингуется и нет флага «хозяин ушел» — гасим свет и выставляем флаг «хозяин ушел».

    */1 10-23 * * * ping -c 3 -W 1 192.168.0.13 && cat /root/phoneflag && wget -qO- localhost/marlight.php?command=ALL_ON && rm -f /root/phoneflag
    Каждую минуту пинговать мой мобильник, если пингуется и есть флаг «хозяин уходил» — включаем свет и удаляем флаг. Но не ночью. Риск ложных срабатываний.

    */30 20-23 * * * for i in {0..15}; do wget -qO- localhost/marlight.php?command=TEMP_WARMER; sleep 0.2; done
    Вечером выставляем теплую цветовую температуру. Более элегантного решения задачи, без цикла, не нашел.

    */30 06-19 * * * for i in {0..15}; do wget -qO- localhost/marlight.php?command=TEMP_COLDER; sleep 0.2; done
    Днем выставляем низкую цветовую температуру.

    И да, я знаю, что крон под рутом с записью флагов в /root — отстой. Ничего страшного, сервер в доверенном периметре, в интернет не высунут.

    Еще в Tasker есть действие на включение света, как только подключился к своей вайфай сети (не ночью — ложные срабатывания не нужны). Еще одно правило — включение холодного света при срабатывании будильника sleep as android (описание API — sites.google.com/site/sleepasandroid/doc/developer-api), это тоже здорово, четыре лампы неплохо бьют в глаза.

    Общая задача — покрыть автоматикой все случаи, когда надо тянуться к выключателю (в данный момент выключателем являются часы). Пока не могу сообразить триггер для отключения света ночью при засыпании. Возможно, тут тоже поможет sleep as android, но как именно — пока не решил. Может быть, остановлюсь на классическом «дважды хлопнуть» (слушать будет компьютер, либо заряжающийся мобильник).

    И ведь действительно Marlight «лампочка для программиста». Программизмом надо заниматься на PHP, bash, Tasker и чем угодно другом попавшимся под руку. И придумать алгоритм, полностью автоматизирующий работу освещения — непростая задача.
    • 0
      Пока полевые испытания показали, что включение-выключение взмахом руки вполне практичны. Так же еще не пробовал, но собираюсь попробовать управлять таким образом яркостью. А вот переключение каналов поворотом кисти — не очень удобно, особенно ребенку, у которого маленькое запястье и часы болтаются — часто непроизвольное переключение каналов, что конечно нервирует остальных домашних. ) Собираюсь перевесить переключение каналов на кнопки, плюс выводить уже не номер канала, а название комнаты… Но это так — красивости!

      Я это к чему — кнопок на часах не много, а учитывая их «традиционное» использование (вверх/вниз — циклический перебор, центральная — подтверждение выбора и назад/отмена) — отказываться от жестов не стоит. Надо просто продумать эргономику…

      PS Плюсанул бы ваш комент, да я на хабре без году неделя — карма не та, что бы других оценивать… ))
      • 0
        Вот яркостью точно не стоит управлять. Эти лампы можно использовать только в крайних положениях цветовой температуры и при максимальной яркости, иначе они очень неслабо мерцают. Как говорят, особенно нехорошо это может быть для ребенка. Так что для управления яркостью просто гасите отдельные лампы.

        Я поначалу выставил среднюю цветовую температуру, где-то через полчаса появилось ощущение «что-то не так». Помахал пальцем перед лампами, посмотрел на них через камеру мобильника и немного обалдел от увиденного. Разумеется, опыт с осциллографом в изначальной статье полностью вылетел из головы.
        • 0
          Хм. Не заметил такого… Все же 240 Гц — довольно много, плюс матовый рассеиватель… Надо будет понаблюдать. Если и правда так, то это плохо, т.к. крайние положения цветовой температуры мне не нравятся. Или слишком неестественный цвет, или очень желтый.
          • 0
            240 герц — крайне мало и не годится для жилых помещений. Матовый рассеиватель — не конденсатор для фотонов и не будет задерживать фотоны для выравнивания освещения в моменты, когда светодиоды гаснут.

            Лично мне крайние положения нравятся. Днем холодный — почти неотличим от солнечного света. Раньше меня бесили две вещи — недостаточная освещенность комнаты при выключенном искусственном свете и сильный контраст между светом солнца и ламп. Вечером теплый — меньше синего спектра, меньше влияния на выработку мелатонина. Ну а перед сном включаем красный светодиод, тоже на полную.
            • 0
              Матовый рассеиватель — не конденсатор для фотонов и не будет задерживать фотоны для выравнивания освещения в моменты, когда светодиоды гаснут.

              Зато из-за площади нет прерывистого следа при взгляде на него. Но карандашный тест он все равно заваливает, да.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разное