Многофункциональный навык УДЯ на Zeit Now

Материал из База знаний
Перейти к навигации Перейти к поиску



Внимание! Навык разрабатывался для себя и опубликован как есть. 
Буду очень рад обратной связи при тестировании и доработках. 
Работа "без сучка и задоринки" не гарантируется =)


Предисловие

Рассмотрим управление устройствами Умного дома Яндекс через http-запросы с помощью собственного приватного навыка. Не стоит пугаться показанного способа, он очень прост.

Да, есть прекрасный навык "Домовенок Кузя", но наш вариант подойдет тем, кто хочет быстро, легко и бесплатно поднять навык собственный, чтобы быть более уверенным в связи Умного дома Яндекса со своими устройствами.


Что может навык?

Навык умеет:

  • Управлять устройствами через http-запросы.
  • Поддерживать такие типы устройств, как:
    • "Выключатель",
    • "Розетка",
    • "Лампа",
    • "Другое" (кастомное многофункциональное устройство).
    • "Сцена" - устройство-сцена, выполняющее отправку списка http-запросов при включении
  • Принимать статусы состояния устройств.


Поддерживаются варианты подключения:

  • Blynk
  • IFTTT, кроме типа значений "Range" ("ползунок")
  • Any - устройства, которые управляются http-запросами в разных форматах (вариативно) - Требуется тестирование


Наши действия (для нетерпеливых)

  1. Заливаем архив с навыком в свой репозиторий github
  2. Подключаем учетную запись github к Zeit Now
  3. Создаем навык УДЯ
  4. Настраиваем файл конфига устройств device.txt
В статье много "начальной" информации; ведь не все, кто столкнулся с УДЯ, сразу имеют нужные знания. Поэтому опишем процесс как можно подробнее.
Бывалые могут просто промотать понятные им места)

От слов - к делу!


Регистрируемся на github.com

  1. Cкачиваем файлы навыка по ссылке.
  2. Переходим по ссылке регистрации на github.
  3. Вводим Username (Имя пользователя), Email address (свой e-mail) и password (пароль), и нажимаем кнопку "Create account".
  4. Выбираем бесплатный аккаунт, нажав кнопку Choose Free.
  5. Теперь можно выбрать, для чего вы планируете использовать аккаунт (а можно и не выбирать =) ).
  6. Нажимаем кнопку Complete Setup (появится предложение проверить свой почтовый ящик на наличие письма активации).
  7. Переходим в почту, нажимаем в письме активации кнопку Verify email address.
  8. После перехода по ссылке будет предложено создать новый репозиторий. Для этого потребуется:
    • придумать и указать имя-ссылку нового репозитория,
    • обязательно отметить, что репозиторий приватный (нам же не нужно, чтобы кто то видел наши токены и ссылки на устройства)!
    • ...и нажать Create repository.
Репозиторий создан, теперь в него требуется загрузить файлы нашего навыка. 
Это можно сделать установив git на пк, настроить, и заpushить в свой репозиторий. Шучу. 
Просто выбираем ссылку  uploading an existing file, а потом ссылку choose your files.
Загружаем файлы навыка (см иллюстрацию 3).


Регистрируемся на Zeit Now и запускаем сервер

Теперь подключим наш репозиторий к серверу Zeit Now:

  1. Переходим по ссылке регистрации, и выбираем Continue with GitHub.
  2. Подключаем репозиторий, нажав на кнопку Authorize Now by ZEIT.
  3. В следующем окне заполняем требуемые данные и соглашаемся со всем, пока нам не предложат создать проект (Create a new project).
  4. Выбираем From Git Repository.
  5. На предложение установить модуль для связи с GitHub жмём Install Now For GitHub и выбираем Only select repositories.
  6. Из выпадающего списка выбираем свой репозиторий.
  7. Нажимаем кнопку Install.
  8. Модуль подключен, осталось создать проект с нашим навыком: нажимаем New Project From GitHub.
  9. Выбираем репозиторий кнопкой Select и импортируем кнопкой Import.
  10. Задаём имя проекта (посложнее, чтоб не пересекалось с другими именами проектов Zeit).
  11. Корневую папку (ROOT) оставляем, как есть.
Если все в порядке, индикатор проекта станет бирюзовым, и появится ссылка на наш навык.


Создаем приватный навык УДЯ

Для создания навыка УДЯ перейдём в кабинет разработчика платформы Диалогов.

  1. Жмём большую кнопку "Создать навык", выбираем тип навыка "Умный дом".
  2. Заполняем информацию о навыке (см рис 2, 3, 4), где:
    • Endpoint URL - Url из раздела DOMAINS в кабинете ZEIT. При этом обязательно ставим https:// в начале.
    • "Не показывать в каталоге" - ставим галочку (чтобы обойтись без долгой модерации, а сам навык не попал в общий каталог).
  3. Нажав кнопку "Изменить", указываем:
    • Идентификатор приложения - любая строка (можно пару раз упасть головой на клавиатуру);
    • Секрет приложения - поступаем так же;
    • URL авторизации - ссылка, которую указывали в Endpoint URL
    • URL для получения токена - ссылка вида: https://ссылка_навыка/token
    • URL для обновления токена - ссылка вида: https://ссылка_навыка/refresh
    • Идентификатор группы действий - read,home:lights
  4. Нажимаем "Сохранить" в окне "Создание связки аккаунтов" и в настройках нашего навыка.
  5. Подтверждаем указанную нами электронную почту;
  6. Подать навык на модерацию. Если не забыли указать, что навык приватный - она будет мгновенной.
  7. После прохождения модерации нажимаем "Опубликовать".

Теперь наш навык должен появиться в списке навыков при добавлении устройств в Умный дом Яндекса (УДЯ).

Навык создан и работает! Перейти к самому вкусному - настройке.


Настройка навыка и добавление устройств

В файле config.py указываем префикс пользователя и токен для IFTTT (если он будет использоваться).

Если все работает - строку с blynk_ip лучше не трогать!!! Её значение должно оставаться как blynk_ip = "139.59.206.133"

Настройка завершена.


Как редактировать конфиги для добавления устройств

Устройства добавляются через редактирование файла devices.txt (должен находиться в корне репозитория GitHub).

Самый простой способ - редактирование в GitHub. Для этого:

  • Перейдём к своему репозиторию;
  • Кликнем в файл для редактирования (в нашем случае devices.txt);
  • Жмём иконку с карандашом справа сверху;
  • Редактируем файл;
  • Применяем изменения, нажав "Commit changes";
  • Ждём ~20-30 сек (пока изменения применятся в Zeit Now).



Добавляем устройства в device.txt

Отредактируем device.txt. Главные правила:

  1. Одна строка = 1 устройство.
  2. Порядок параметров менять нельзя.
  3. Кавычки - это важно. Если их нет у параметра в примере - это тоже важно!

Если что-то не работает - читать с пункта 1.


Простейшее устройство Blynk без запроса статуса

"id устройства", "Имя устройства", "Описание", "Комната", "Разработчик", "Модель", "Версия железа", "Версия ПО", "Выключатель", "blynk", "Номер пина V2", "токен Blynk", "nostatus"

Разберём по параметрам:

  • "id устройства" - идентификатор, по которому УДЯ будет их различать (например, "Blink002").
  • "Имя устройства" - так устройство будет отображаться в списке устройств (например, "Выключатель").
  • "Описание" - например, "Выключатель верхнего света в комнате через Blynk".
  • "Комната" - комната, к которой относится устройство (например, "Коридор").
  • "Разработчик" - Имя разработчика или компании. Например, "Домашний хэндмэйд".
  • "Модель" - модель устройства. Например, "BlNodemcu10"
  • "Вер.железа" - Версия сборки. Например "1.0"
  • "Вер. софта" - Версия прошивки. Например "2.00.15"
  • "Тип" - Тип устройства (как устройство будет определено в УДЯ).

Всего в навыке предусмотрено 4 типа устройства:

  • Выключатель - устройство которое может быть включено или выключено.
  • Розетка - устройство которое может быть включено или выключено. Но определится как розетка.
  • Лампа - устройство-лампочка. Определится как лампа и будет иметь настройку яркости (кроме IFTTT).
  • Другое - другое многофункциональное устройство. Поддерживает некоторые настройки и расширяет возможности, но об этом чуть ниже.
  • "blynk" - тип подключения. Есть 3 варианта: "blynk", "ifttt", "any". Где "any" - управление через http-запросы, не подходящие под шаблон blynk и ifttt.
Перечисленные выше параметры по порядку идентичны для всех типов подключений. Дальше:
  • "Номер пина" - Номер виртуального пина blynk. Например "V3"
  • "токен Blynk" - Токен от проекта blynk.
  • "nostatus" - Параметр запроса статуса устройства. Если значение="status" - то будем запрашивать текущее состояние устройства, любое другое значение (например "nostatus") - состояние не будет запрашиваться.


Заполнив шаблон, получим подобное этой строке:

"UD-001", "Выключатель", "Выключатель Блинк", "Комната", "Компания Иванов+", "BL100500", "2.15", "1.12.3", "выключатель", "blynk", "V2", "GYgyu7676HoiTig6t76G6t8", "nostatus"


Устройство "Лампа", управляемое типом "any"

Разберём более сложный пример:

"id устройства", "Имя устройства", "Описание", "Комната", "Разработчик", "Модель", "Версия железа", "Версия софта", "Лампа", "any", "ссылка на вкл", "ссылка на выкл", "status", "ссылка на поиск статуса вкл/выкл", "строка для поиска", "ссылка на управление яркостью, заменить на --val--", "ссылка на статус яркости", начальная строка поиска, конечная строка поиска, 250

Предположим, что у нас есть определенный формат http-запроса, где:

  • http://anuapi.com/value-true - ссылка на включение устройства;
  • http://anuapi.com/value-false - ссылка на выключение устройства;
  • http://anuapi.com/status - ссылка на статус лампочки (включена или нет?), по которому возвращается какой то текст (например: {value:"on"} или {value:"off"});
  • http://anyapi.com/brigh/?val=50 - ссылка на изменение яркости на значение 50;
  • http://anuapi.com/brigh/status - ссылка возвращающая значение яркости (например строку {value:"70"});
  • 250 - максимальный предел уровня яркости на устройстве (для некоторых светодиодных лент удобнее использовать не 100%, а уровень 255)

Получим строку такого вида:

"Noname02", "Лампочка", "Лампочка в туалете", "Туалет", "Левша", "LampTula1", "001", "003", "Лампа", "any", "http://anuapi.com/value-true", "http://anuapi.com/value-false", "status", "http://anuapi.com/status", "on", "http://anyapi.com/brigh/?val=--val--", "http://anuapi.com/brigh/status",value:",", 250

в которой после ссылки на запрос статуса вкл/выкл устройства, мы указали:

  • строку включенного устройства, которую стоит искать в ответе (в данном случае "on");
  • в конце - начальный и конечный шаблон для поиска значения яркости value:"," (искать нужное значение между value:" и ");
  • заменили значение 50 в ссылке на тэг --val-- (чтобы навык мог понять, куда подставить полученное от УДЯ значение).


Важно! Эти значения записываются без кавычек, т.к. зачастую кавычка - это крайний символ для поиска. Поэтому формат немного отличается.


Вот так легко добавляются устройства, главное - разобраться в формате записи =)

В текущей версии запись выглядит "не очень", зато даёт возможность быстро и без труда заполнить список устройств. В будущем, возможно, добавится и web-интерфейс для заполнения.

После того, как заполнены все описания, сохраняем device.txt и проверяем, добавились ли наши устройства в УДЯ.


Многофункциональное устройство "Другое"

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

"id-устройства","Имя устройства","Описание","Комната","Разработчик","Модель","Вер.железа","Вер.софта","Другое","Имя файла с умениями.txt"

где после типа устройства ("Другое") мы будем использовать новый файл конфига с умениями, который указываем последним параметром в файле device.txt. В конечном итоге строка для многофункционального устройства может выглядеть так:

"Anylamp-00","Хитрая лампа","Лампа с большими возможностями","Комната","ШизикИнтертейнмент","Alko11","09","03","Другое","anylamp.txt"

Теперь создадим файл конфига "anylamp.txt" для устройства с ID "Anylamp-00" и укажем его параметры. Файл так же загружаем в корневую директорию репозитория.


"Другое" имеет 3 вида умений:

  • "on_off" - умение включать/выключать устройство;
  • "toggle" - умение, при действии на которое можно получить одно текущее значение (например это кнопка);
  • "range" - изменение значения от минимального к максимальному и наоборот. Попросту - "ползунок" (например громкости, яркости). - Не работает с IFTTT;
  • "color_setting" - управление RGB. - Не работает с IFTTT, для ANY не поддерживается обработка статуса.

Предположим, мы создали файл конфига "other.txt". В данном файле (каждая строка - одно умение) создаем умение "on_off" для нашего устройства, которое управляется через blynk, и статус этого умения нас не интересует. Наш шаблон:

"тип умения","тип подключения","номер пина","токен Blynk","nostatus"

Заполним шаблон:

  • Тип умения "on_off",
  • Тип подключения "blynk",
  • Номер виртуального пина (например "V2"),
  • Токен проекта blynk (что-то вроде "GYUgu678T6g67OIjoijo8677tyg"),
  • Отсутствие запроса статуса "nostatus".

Получим строку вида:

"on_off","blynk","V2","GYUgu678T6g67OIjoijo8677tyg","nostatus"

С умениями "toggle" и "range" чуть сложнее, зато они добавляют мощные возможности. Для них Яндекс предлагает целый список "instance" (функций в этом умении).

  • Функции для "toggle" (что можно переключать):
    • "backlight" - подсветка
    • "controls_locked" - блокировка управления
    • "ionization" - ионизация
    • "keep_warm" - включение поддержания тепла
    • "mute" - режим "без звука"
    • "oscillation" - включение вращения
    • "pause" - пауза
  • Функции для "range" (что можно регулировать плавно):
    • "brightness" - яркость (в процентах)
    • "open" - открытие (в процентах)
    • "humidity" - влажность (в процентах)
    • "temperature" - температура (в градусах Цельсия)
    • "channel" - канал (без единиц измерения)
    • "volume" - громкость (без единиц измерения)

Для примера создадим умение "range" с функцией "влажность". Наш шаблон:

"умение","функция",0,100,10,"any","ссылка на управление (заменить число на --val--)","status","ссылка на статус",строка поиска начальная,строка поиска конечная,150

Расшифруем:

  • умение - "on_off", "range", итд;
  • функция - в нашем случае "Влажность", создастся "ползунок" с единицами в процентах;
  • 0 (без кавычек) - минимальное значение влажности
  • 100 (без кавычек) - максимальное значение влажности
  • 10 (без кавычек) - шаг с которым будут происходить изменения
  • "any" - подключение нетипизированного http-запроса
  • "ссылка на управление" - ссылка типа http://anyapi.com/hum/?val=50, где 50 мы меняем на --val--
  • "status" - уже знакомое нам указание на то, что мы хотим получать текущее состояние.
  • "ссылка на статус" - ссылка, по которой придет ответ со значением влажности http://anyapi.com/hum/status
  • строка поиска начальная (без кавычек) - строка после которой искать значение влажности, например lue:"
  • строка поиска конечная (без кавычек) - строка до которой искать значение влажности, например "
  • 150 (без кавычек) - максимальное значение влажности на устройстве (если нужно маппить значения и они разняться с максимальными в УДЯ)

Получим что-то такое:

"range","humidity",0,100,10,"any","http://anyapi.com/hum/?val=--val--","status","http://anyapi.com/hum/status",lue:",",150

Теперь рассмотрим функцию "color_setting" для управления RGB-подсветкой для устройства со сторонним api. Шаблон выглядит так:

"color_setting",255,255,255,"any","ссылка на управление (заменить значение red на --vr-- / green на --vg-- / blue на --vb--)","nostatus"

Расшифруем:

  • "color_setting" - наша функция (instance)
  • 255 (без кавычек) - максимальное значение красного (на случай, если не 255, а 100. Например, у меня для понижения расхода питания);
  • 255 (без кавычек) - максимальное значение зеленого (на случай, если не 255);
  • 255 (без кавычек) - максимальное значение синего (на случай, если не 255);
  • "any" - тип подключения нетипизированного http-запроса;
  • "ссылка на управление" - ссылка типа http://anyapi.com/hum/?val=50&val=150&val=100, где 50 мы меняем на --vr--, 150 мы меняем на --vg--, 100 мы меняем на --vb-- (r,g,b);
  • "nostatus" - указываем, что не хотим получать текущее состояние.

Получим что-то такое:

"color_setting",255,255,255,"any","http://anyapi.com/hum/?val=--vr--&val=--vg--&val=--vb--","nostatus"


Напомним: для каждого вида многофункционального устройства создаётся свой файл с умениями, который нужно загрузить в корень репозитория на GitHub, а его имя указывать в описании в device.txt


Устройство-сцена

Это специальные решения для выполнения нескольких http-запросов одновременно. При включении "устройства" происходит отправка нескольких запросов из указанного в devices.txt файла (Пример: sceneone.txt)

Для добавления устройства вносим в devices.txt строку типа:

"Noname03", "Сцена", "сцена для проверки", "Сценарии", "User", "Scen1", "001", "003", "Сцена", "sceneone.txt"

В корневой папке создать файл (в примере - sceneone.txt), в котором в несколько строк указать ссылки на вебхуки-действия (одна строка - один вебхук). Пример заполнения файла:

http://anyapi.com/hum/?val=1
http://anyapi.com/hum/?val=2
http://anyapi.com/hum/?val=true
http://anyapi.com/hum/?val=false


Некоторые вопросы и ответы

ЕЩЁ РАЗ: навык разрабатывался для себя, для проверки себя и главным критерием - сервиса, на котором можно контролировать работу навыка (поэтому Zeit Now); а главным требованием - простота добавления устройств и универсальность.<br>


Почему IFTTT не поддерживает "range"?

Во-первых, потому что у IFTTT другой формат передачи value и он пока не укладывался в голове(возможно потом). Во-вторых, в голову пока не пришло устройств, которые бы поддерживали прием вариативных значений по IFTTT, поэтому не увидел смысла.

Почему для IFTTT токен задается в config.py, а для blynk в каждом устройстве/умении?

Потому что аккаунт IFTTT обычно один, а у Blynk проектов с разными токенами может быть много.


Устройства не видны (видны, но УДЯ выдаёт ошибки)

Если навык определился успешно, но устройства не видны - скорее всего, вы их неправильно указали в device.txt или не указали вовсе. Совет: перечитать статью и проверить формат записи строк. Если видны, но есть ошибки, то есть смысл попробовать удалить устройство или отвязать и привязать заново аккаунт. Возможно при ваших последних изменениях параметры не прогрузились в УДЯ.


Как задаются token и code для запросов Яндекса?

Они генерируются при запуске сервера, так сделано для удобства.


Не могу добавить две яркости в одном устройстве

По стандарту УДЯ можно добавить только одно умение с одноименной функцией. То есть, одну "яркость", одну "влажность", один ползунок "громкости".


Формат IFTTT... что такое "хук вкл", "хук выкл" в device.txt?

Это названия вебхуков, которые вы задаете в IFTTT. Например "relayON". В остальном принцип схож с шаблонами any. При этом запрос статуса IFTTT-устройств происходит через сторонний http-запрос (если такой имеется).

Ну и наконец, надеюсь, что у вас все получится при создании собственного навыка, а если нет - буду очень рад обратной связи: