Ассортимент светильников Philips Hue, безусловно, не дешев ( есть несколько альтернатив, стоят того, стоят. ), но одна вещь, которую я действительно ценю, это хорошо документированный API о создании собственных приложений Hue. Сегодня я покажу вам, как управлять подсветкой Hue от Arduino, а затем добавлю простой датчик движения.
Почему мы это делаем? Потому что системы домашней автоматизации могут быть довольно жесткими и дорогими. Изучая, как управлять Hue от Arduino, вы открываете двери для множества индивидуальных проектов домашней автоматизации, которые просто не могут быть побеждены готовыми компонентами. Если совместное хакерство — не ваше дело, попробуйте эти 8 великолепных приложений Hue вместо этого.
Система оттенков
Давайте немного разберемся с техникой, чтобы вы знали основные системы, с которыми вы работаете. Подсветка создает ячеистую сеть , используя протокол беспроводной связи малого радиуса действия под названием ZigBee — в частности, они сертифицированы ZigBee Light Link , что означает, что другие продукты ZLL также должны работать вместе с Hue (теоретически).
Несмотря на техническую ограниченность, функция ячеистой сети в ZigBee означает, что каждая новая лампочка расширяет сеть, передавая сообщения другим лампам. Это означает, что если у вас возникли проблемы с управлением источником света на другой стороне дома, попробуйте установить другой источник света между ними.
Zigbee — отличный протокол, но он сильно отличается от Wi-Fi или проводной компьютерной сети, поэтому нам необходим мост Philips Hue Bridge, чтобы объединить их вместе. Мост Hue выполняет модифицированную прошивку Linux с открытым исходным кодом, которая транслирует базовый веб-сервер.
Именно взаимодействуя с этим локальным веб-сервером, вы можете узнать текущее состояние индикаторов и управлять ими.
Это красивая простая система, созревшая для проектов DIY. Престижность Philips за то, что сделал эту вещь такой взломанной.
Начиная
Прежде чем вы сможете получить доступ к документации API, вам необходимо зарегистрироваться в качестве разработчика . Это бесплатно, но вы должны принять условия. Сделай это сейчас.
Любой, кто знаком со стандартными веб-сервисами или Javascript, должен уметь работать с Hue: все данные передаются и принимаются в виде пакетов JSON.
Чтобы увидеть это в действии, вам нужно знать IP-адрес вашего моста Хюэ. Есть несколько способов сделать это:
- Посмотрите на таблицу назначения адресов DHCP в интерфейсе администратора вашего роутера
- Запустите программу сетевого сопоставления, такую как IP Scanner Home
- Попробуйте брокерский инструмент Philips UPnP
- Пинг «philips-hue.home»
Когда вы закончите, введите его в адресную строку браузера, добавив к URL-адресу файл debug / clip.html . В моем случае это было:
http://192.168.1.216/debug/clip.html
Это инструмент отладки, который позволяет отправлять и получать пакеты JSON через простой веб-интерфейс. Первым шагом является включение профиля разработчика на самом Hue Bridge, который по умолчанию отключен по соображениям безопасности. Вставьте следующее в поле BODY, оставьте URL-адрес как / api / и отправьте запрос POST, нажав кнопку « Отправить»:
{"devicetype":"test user","username":"newdeveloper"}
Когда вы в первый раз сделаете это, вы увидите «ответную ссылку не нажата» где-то в ответе. Это функция безопасности, которая требует, чтобы каждое новое приложение, которое вы используете, было физически авторизовано. Идите и найдите свой мост, нажмите кнопку и отправьте тот же запрос еще раз в течение 30 секунд . На этот раз вы получите другой ответ, и пользователь будет авторизован. Если вы хотите использовать другое имя пользователя, прочитайте документы API о создании пользователей . Пока этого будет достаточно.
Как только ваш пользователь настроен, базовый URL, с которым вы должны взаимодействовать, становится / api / newdeveloper / . Вы можете отправить запрос GET, чтобы узнать все, что ваш мост знает о подключенных источниках света, сигналах тревоги, сценах и кратком журнале приложений, которые использовались. Вот образец информации о состоянии, которая содержится в одной лампочке.
"state": { "on": true, "bri": 254, "hue": 14910, "sat": 144, "effect": "none", "xy": [ 0.4596, 0.4105 ], "ct": 369, "alert": "none", "colormode": "ct", "reachable": false }, "type": "Extended color light", "name": "Bedroom 1", "modelid": "LCT001",
Обратите внимание, что «вкл.»: Истинное состояние на самом деле не показывает, включена лампочка или нет; только то, что в соответствии с настройками моста, он должен быть включен. «Достижимый»: значение «ложь» может указывать на то, что лампа находится слишком далеко или просто выключена с помощью выключателя питания.
Последний пример, прежде чем мы интегрируем это в Arduino: убедитесь, что один из ваших источников света виден и включен, и что вы знаете, какой это номер. Измените URL на / api / newdevelopers / lights / 1 / state (изменив номер на ваш свет) и отправьте запрос PUT со следующими данными:
{"hue": 50100,"sat":255,"bri":255}
Вы должны увидеть, как ваш свет реагирует так:
То, что вы сделали, это выдвинули новое состояние в колбу. Вы также можете добавить «переходное время», которое является примитивным методом анимации, показывающим, сколько секунд вы хотите, чтобы изменение состояния заняло.
Цвет можно установить несколькими различными способами , но, к сожалению, простого способа отправки значения RGB не существует. В приведенном выше примере мы послали оттенок , насыщенность и яркость. Попробуйте изменить значение оттенка и снова отправить запрос PUT.
Работа от Arduino
Существует существующая библиотека Hue / Arduino под названием ArduinoHue, на которую сами Philips ссылаются в документации API, но проблема с этой библиотекой заключается в том, что она связывается через USB-соединение с вашим ПК, который также должен постоянно запускать приложение Python. Эхх Вы можете также позволить своему компьютеру запустить весь процесс в этот момент и полностью отключить Arduino.
Вместо этого я покажу вам, как управлять Hue от Arduino, используя щит Ethernet . Ваш Arduino не должен быть подключен к компьютеру, поэтому он может работать независимо везде, где вы можете подключить кабель Ethernet. На самом деле, он также должен работать со щитом Wi-Fi, но мне не с чем играть.
Если вы хотите пропустить, полный пример кода приведен ниже или доступен здесь . Я адаптировал это на примере, опубликованном Гилсоном Огайме . Если вы никогда раньше не играли со своим щитом Ethernet, возможно, вы захотите быстро пройтись по учебному пособию по веб-клиенту — я предполагаю, что вы немного знакомы с этим, и не буду описывать код, используемый для создания сети. IP и т. Д. Мы также показали, как создать мини-веб-сервер с сетевым экраном Ethernet. веб-сервер с сетевым экраном. веб-сервер с сетевым экраном. .
/* | |
Talking to Hue from an Arduino | |
By James Bruce (.com) | |
Adapted from code by Gilson Oguime. https://github.com/oguime/Hue_W5100_HT6P20B/blob/master/Hue_W5100_HT6P20B.ino | |
*/ | |
#include <SPI.h> | |
#include <Ethernet.h> | |
// Hue constants | |
const char hueHubIP[] = "192.168.1.216"; // Hue hub IP | |
const char hueUsername[] = "newdeveloper"; // Hue username | |
const int hueHubPort = 80; | |
// PIR | |
int pir = 2; | |
boolean activated = false; | |
// Hue variables | |
boolean hueOn; // on/off | |
int hueBri; // brightness value | |
long hueHue; // hue value | |
String hueCmd; // Hue command | |
unsigned long buffer=0; //buffer for received data storage | |
unsigned long addr; | |
// Ethernet | |
byte mac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 }; // W5100 MAC address | |
IPAddress ip(192,168,1,2); // Arduino IP | |
EthernetClient client; | |
/* | |
Setup | |
*/ | |
void setup() | |
{ | |
Serial.begin(9600); | |
Ethernet.begin(mac,ip); | |
pinMode(pir,INPUT); | |
delay(2000); | |
Serial.println("Ready."); | |
} | |
void loop() | |
{ | |
if(digitalRead(pir) == 1){ | |
Serial.println("activated"); | |
// A series of four sample commands, which colour fades two lights between red and pink. Read up on the Hue API | |
// documentation for more details on the exact commands to be used, but note that quote marks must be escaped. | |
String command = "{\"on\": true,\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}"; | |
setHue(1,command); | |
command = "{\"on\": true,\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}"; | |
setHue(2,command); | |
command = "{\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}"; | |
setHue(1,command); | |
command = "{\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}"; | |
setHue(2,command); | |
// so we can track state | |
activated = true; | |
} | |
else{ | |
activated = false; | |
Serial.println("deactivated"); | |
//was activated, so send a single off command | |
String command = "{\"on\": false}"; | |
setHue(1,command); | |
setHue(2,command); | |
} | |
} | |
/* setHue() is our main command function, which needs to be passed a light number and a | |
* properly formatted command string in JSON format (basically a Javascript style array of variables | |
* and values. It then makes a simple HTTP PUT request to the Bridge at the IP specified at the start. | |
*/ | |
boolean setHue(int lightNum,String command) | |
{ | |
if (client.connect(hueHubIP, hueHubPort)) | |
{ | |
while (client.connected()) | |
{ | |
client.print("PUT /api/"); | |
client.print(hueUsername); | |
client.print("/lights/"); | |
client.print(lightNum); // hueLight zero based, add 1 | |
client.println("/state HTTP/1.1"); | |
client.println("keep-alive"); | |
client.print("Host: "); | |
client.println(hueHubIP); | |
client.print("Content-Length: "); | |
client.println(command.length()); | |
client.println("Content-Type: text/plain;charset=UTF-8"); | |
client.println(); // blank line before body | |
client.println(command); // Hue command | |
} | |
client.stop(); | |
return true; // command executed | |
} | |
else | |
return false; // command failed | |
} | |
/* A helper function in case your logic depends on the current state of the light. | |
* This sets a number of global variables which you can check to find out if a light is currently on or not | |
* and the hue etc. Not needed just to send out commands | |
*/ | |
boolean getHue(int lightNum) | |
{ | |
if (client.connect(hueHubIP, hueHubPort)) | |
{ | |
client.print("GET /api/"); | |
client.print(hueUsername); | |
client.print("/lights/"); | |
client.print(lightNum); | |
client.println(" HTTP/1.1"); | |
client.print("Host: "); | |
client.println(hueHubIP); | |
client.println("Content-type: application/json"); | |
client.println("keep-alive"); | |
client.println(); | |
while (client.connected()) | |
{ | |
if (client.available()) | |
{ | |
client.findUntil("\"on\":", "\0"); | |
hueOn = (client.readStringUntil(',') == "true"); // if light is on, set variable to true | |
client.findUntil("\"bri\":", "\0"); | |
hueBri = client.readStringUntil(',').toInt(); // set variable to brightness value | |
client.findUntil("\"hue\":", "\0"); | |
hueHue = client.readStringUntil(',').toInt(); // set variable to hue value | |
break; // not capturing other light attributes yet | |
} | |
} | |
client.stop(); | |
return true; // captured on,bri,hue | |
} | |
else | |
return false; // error reading on,bri,hue | |
} | |
Создание государственных изменений
Создание нового состояния для отправки на лампочки является простым случаем создания новой строковой переменной и экранирования всех двойных кавычек. Я также добавил функцию random (), чтобы создать несколько динамическую анимацию. Попробуйте сделать переменную оттенка случайной для разных цветов.
String command = "{\"on":true,\"hue\":50100,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
Отправка команды
Чтобы на самом деле отправить команду, у вас есть вспомогательная функция setHue (), которая принимает в качестве аргумента номер света и командную строку, например:
setHue(1,command);
Все, что он делает, это подключается к мосту, выплевывает команду в виде запроса PUT вместе со всей другой ерундой, связанной с созданием HTTP-запроса.
client.print("PUT /api/"); client.print(hueUsername); client.print("/lights/"); client.print(lightNum); client.println("/state HTTP/1.1"); client.println("keep-alive"); client.print("Host: "); client.println(hueHubIP); client.print("Content-Length: "); client.println(command.length()); client.println("Content-Type: text/plain;charset=UTF-8"); client.println(); // blank line before body client.println(command); // Hue command
Добавление датчика движения
Наконец, я подключил простой датчик движения HC-SR501 к цифровому выводу ввода / вывода 2. При обнаружении движения на мост перебрасывается серия состояний для 2 лампочек, чтобы создать медленную, динамическую анимацию. Когда датчик движения деактивируется, обе команды отправляются по одной. В идеале они должны были бы вернуться в состояние, в котором они находились до того, как было обнаружено движение, но логика не настолько разумна - мы просто собираемся включать и выключать их.
Ограничения
Хотя по общему признанию неоптимизированный код, для сетевого интерфейса Arduino требуется почти секунда, чтобы отправить единственный командный запрос. Я тестировал ту же команду с Mac, используя то же соединение Ethernet, и она была способна в десять-двадцать раз превышать эту скорость ( вот AppleScript на случай, если вы захотите протестировать). Следовательно, любая быстрая анимация (я пытался создать эффект мерцающей свечи) просто невозможна в Arduino. Это не должно быть проблемой для большинства проектов, только для высокоскоростной анимации света, но хорошо знать об этом ограничении.
Также трудно полностью разобрать любой ответ JSON, который вы получите с моста; на Arduino недостаточно ОЗУ для хранения всех необработанных данных. По этой причине вы можете ограничиться отправкой.
Взломать оттенок
Теперь, когда вы обладаете знаниями о том, как управлять Hue полностью независимо, это открывает мир взломов домашней автоматизации Hue. Реальный вопрос: что вы будете делать?