Управление устройствами умного дома Яндекс своими скриптами - «Умные Решения» » Умный Дом и решения
Управление устройствами умного дома Яндекс своими скриптами - «Умные Решения»
Что такое Умный дом — это система домашних устройств, связанных между собой и выполняющих действия по команде человека или даже без его участия, по расписанию или сигналу от датчика. Некоторые умные дома управляются через приложения и голосом через умные колонки, другие — с помощью отдельных устройств. Задачи тоже могут быть разными: повысить комфорт, сэкономить время или обеспечить безопасность..

Новинки / Производитель / Яндекс / Бренд / СТАТЬИ / Смарт.ТВ / Умные Решения

Управление устройствами умного дома Яндекс своими скриптами - «Умные Решения»

  • Douglas
  • 26-янв-2024, 12:17
  • 0 комментариев
  • 2 531 просмотров

В статье пойдёт речь о самом базовом управлении устройствами умного дома Яндекс - а именно функции включения/выключения, т.к. ничего больше мне не нужно, но из базы довольно легко с помощью документации, научиться управлять и другими свойствами. Может этот материал не на статью вовсе, но вот захотелось поделиться. За код не ругайте сильно - я не настоящий программист. Код написан на простейшем PHP.

Управление устройствами умного дома Яндекс своими скриптами - «Умные Решения»
AI: Управление устройствами умного дома своими скриптами на PHP

Зачем?

Захотелось мне как-то настроить один сценарий, который нельзя сделать через Алису. А что делать в таких ситуациях? Разумеется нужно писать свои скрипты.

Если кому интересно - функция выключения обогревателя в пиковый тариф электроэнергии при использовании трёхтарифного счётчика и включения обратно по окончании пикового тарифы, но только в случае, если он был включен до этого.

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

Поиск решений

Начать решил с API Яндекса. Благо с этим проблем нет, нашлось довольно быстро:

https://yandex.ru/dev/dialogs/smart-home/doc/concepts/platform-quickstart.html

Однако документация довольно скудна на рабочие примеры.

Хорошее дело - прежде чем писать что-то своё, попытаться найти что-то готовое на Github или еще где-то. Честно признаюсь, искал не очень глубоко, но натыкался в основном на варианты, когда нужно наоборот прикрутить свой "умный дом" к Алисе, что бы можно было из Алисы управлять им командами.

Регистрация

Как сказано в документации, нужно зарегистрироваться в oauth по ссылке https://oauth.yandex.ru/client/new/

Важная странность, на которую я потратил бездарно несколько часов. Нужно регистрироваться сразу по ссылке, а не пытаться в дальнейшем в интерфейсе нажимать на кнопку "создать приложение" - оно почему-то пытается создать приложение в контексте "id", в url видно другую ссылку https://oauth.yandex.ru/client/new/id и в таком случае не получается задать нужные права для будущего приложения.

Заполняем данные:

Регистрация oauth Yandex

Название любое.

Галочка - веб-сервисы.

Redirect URI - ссылка, куда будет происходить переадресация после успешной авторизации. В моём случае я использую специально подготовленную веб-страницу на моём сервере, но для начала можно использовать http://oauth.yandex.ru/verification_code - этот URL просто отобразит на странице код, когда будет нужно.

Доступ к данным - согласно документации: iot:viewiot:control

По сути авторизоваться для работы скриптов надо один раз, токен даётся на год, затем его вроде как можно продлять автоматически, функцию для этого я написал, но пока не было возможности проверить.

Создаём приложение, заходим в него:

Обратим внимание на ClientID и Client secret - они пригодятся. Можно никуда не записывать - они всегда доступны на странице приложения.

Получение токена

Из консоли это можно сделать так

$ curl "https://oauth.yandex.ru/authorize?response_type=code&client_id=&force_confirm=no&scope=iot:view iot:control"
Found. Redirecting to https://passport.yandex.ru/auth?retpath=https%3A%2F%2Foauth.yandex.ru%2Fauthorize%3Fresponse_type%3Dcode%26client_id%3D%253Cclient_id%253E%26force_confirm%3Dno%26scope%3Diot%3Aview%2520iot%3Acontrol&noreturn=1&origin=oauth[/code]

Далее идём в браузере по:

https://passport.yandex.ru/auth?retpath=https%3A%2F%2Foauth.yandex.ru%2Fauthorize%3Fresponse_type%3Dcode%26client_id%3D%253Cclient_id%253E%26force_confirm%3Dno%26scope%3Diot%3Aview%2520iot%3Acontrol&noreturn=1&origin=oauth

Авторизуемся и получаем код - код вы увидите после редиректа на страницу http://oauth.yandex.ru/verification_code , в случае если у вас еще не готова более автоматизированная страница авторизации.

Далее с этим кодом, получаем сам токен:

curl -H "Authorization: Basic $(echo -n "<ClientID>:<Client secret>"|base64 -w 0)" -d "grant_type=authorization_code&code=<code>" "https://oauth.yandex.ru/token"

В ответ вы получите JSON с токеном и некоторыми нужными параметрами:

{
"token_type": "bearer",
"access_token": "AQAAAACy1C6ZAAAAfa6vDLuItEy8pg-iIpnDxIs",
"expires_in": 124234123534,
"refresh_token": "1:GN686QVt0mmakDd9:A4pYuW9LGk0_UnlrMIWklkAuJkUWbq27loFekJVmSYrdfzdePBy7:A-2dHOmBxiXgajnD-kYOwQ"
}

token_type - другого я и не видел

access_token - тот самый Oauth токен

expires_in - время в секунда до протухания

refresh_token - токен с которым можно обновить основной токен и вроде как время протухания в том числе.

Мой способ получения токена на PHP. Данный файлик (например iot_yandex_auth.php) нужно (при желании) разместить на своем веб сервере. Можно наверное этого и не делать и обойтись авторизацией курлом. Да и вроде функция обновления токена должна по идее работать.

Код iot_yandex_auth.php
<?php
$client_id="";
$client_secret="";
$file="private_folder_kae6iev_taex/iot_yandex_token.json";

function universal_curl($url,$headers,$data = "",$method = ""){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
if($method!=""){
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
}
if($data!=""){
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($ch, CURLOPT_FAILonerror, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
$result = json_decode($result,true);
curl_close($ch);
return $result;
}
if(isset($_GET["code"])&&is_numeric($_GET["code"])){
$auth=base64_encode($client_id.":".$client_secret);
$headers=["Authorization: Basic ".$auth];
$url="https://oauth.yandex.ru/token";
$data="grant_type=authorization_code&code=".$_GET["code"];
$response=universal_curl($url,$headers,$data);
if(isset($response["access_token"])){
$response["expires"]=$response["expires_in"]+time();
if(file_put_contents($file, json_encode($response))){
echo "Success";
}
exit;
}
}

$url="https://oauth.yandex.ru/authorize?response_type=code&client_id=".$client_id."&force_confirm=yes&scope=iot:view iot:control";
header('Location: '.$url);[/code]

идём на https://ownsite.ru/iot_yandex_auth.php

В случае если в GET запросе кода нет, страница переадресует куда надо, если есть - то сходит в Яндекс, получит токен и положит в папку на сервере.

Обратите внимание, что $client_id и $client_secret надо заполнить, а так же $file при текущем конфиге будет указывать на папку в / вашего сайта. В этом случае файлик будет доступен со всего интернета, хорошо бы прикрыть локацию или как-то сделать более красиво. Можно и нужно еще где-то выше положить, что бы локация была не доступна из интернета в принципе.

Еще может быть не очевидно, но нужно, чтоб права позволяли писать в $file вашему веб-серверу и файл не сможет создаться - вы увидите об этом ошибку в errors вашего веб-сервера.

Еще при записи JSON в файлик, я добавляю туда параметр expires, т.к. мне не очевидно, что иначе делать с expires_in и как понять, когда именно токен просрочится.

Так же эта локация должна быть доступна для скриптов, которые уже непосредственно будут управлять вашим умным домом.

Управление

Всё готово, можно начать управлять.

Создаём файлик функций, например functions.php - где-то еще, например в /opt/scripts/smart_home

Не забываем поменять $yandex_iot_client_id, $yandex_iot_client_secret и $yandex_iot_file на актуальные.

Код functions.php
<?php
$yandex_iot_client_id="";
$yandex_iot_client_secret="";
$yandex_iot_file="/var/www/ownsite.ru/private_folder_kae6iev_taex/iot_yandex_token.json";

function universal_curl($url,$headers,$data = "",$method = ""){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
if($method!=""){
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
}
if($data!=""){
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($ch, CURLOPT_FAILonerror, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
$result = json_decode($result,true);
curl_close($ch);
return $result;
}

function universal_yandex_iot($function,$headers_add = array(),$data = "",$method = ""){
$iot_api_url="https://api.iot.yandex.net";
$url=$iot_api_url.$function;
$headers=array_merge(array("Authorization: Bearer ".get_yandex_iot_token()),$headers_add);
return(universal_curl($url,$headers,$data,$method));
}

function get_yandex_iot_power_state($device_id){
$function="/v1.0/devices/".$device_id;
$result=universal_yandex_iot($function);
if(isset($result["capabilities"])){
foreach($result["capabilities"] as $capability){
if($capability["type"]=="devices.capabilities.on_off"){
if($capability["state"]["value"]==""){
return(0);
}elseif($capability["state"]["value"]=="1"){
return(1);
}else{
return(-1);
}
}
}
}else{
return(-1);
}
}

function get_yandex_iot_info(){
$function="/v1.0/user/info";
$result=universal_yandex_iot($function);
return($result);
}

function yandex_iot_power_change($device_id,$state){
$function="/v1.0/devices/actions";
$headers=["Content-Type: application/json"];
$data='{"devices":[{"id":"'.$device_id.'","actions":[{"type":"devices.capabilities.on_off","state":{"instance":"on","value":'.$state.'}}]}]}';
$result=universal_yandex_iot($function,$headers,$data);
if(isset($result["status"])&&$result["status"]=="ok"){
return(true);
}else{
return(false);
}
}

function get_yandex_iot_token(){
global $yandex_iot_file;
$token=file_get_contents($yandex_iot_file);
$token_arr=json_decode($token,true);
if($token_arr["expires"]-time()<20995200){
update_yandex_iot_token();
}
return($token_arr["access_token"]);
}

function update_yandex_iot_token(){
global $yandex_iot_file,$yandex_iot_client_id,$yandex_iot_client_secret;
$token=file_get_contents($yandex_iot_file);
$token_arr=json_decode($token,true);
$url="https://oauth.yandex.ru/token";
$auth=base64_encode($yandex_iot_client_id.":".$yandex_iot_client_secret);
$headers=["Authorization: Basic ".$auth,"application/x-www-form-urlencoded"];
$data="grant_type=refresh_token&refresh_token=".$token_arr["refresh_token"];
$response=universal_curl($url,$headers,$data);
if(isset($response["access_token"])){
$response["expires"]=$response["expires_in"]+time();
if(file_put_contents($yandex_iot_file, json_encode($response))){
return(true);
}
}else{
return(false);
}
}
?>[/code]

universal_curl - универсальный курл

universal_yandex_iot - адаптация универсального курла для Яндекса

get_yandex_iot_power_state - получение состояния питания

get_yandex_iot_info - получает вообще всю информацию по умному дому, все возможности, device_id и прочее.

yandex_iot_power_change - изменение состояния питания

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

update_yandex_iot_token - обновление токена (попытка). Тут так же при записи JSON в файлик, я добавляю туда параметр expires, т.к. мне не очевидно, что иначе делать с expires_in и как понять, когда именно токен просрочится.

Создаём тестовый файл, например yandex_test.php.

<?php
require_once('functions.php');

//print_r(get_yandex_iot_info());
//exit;
echo get_yandex_iot_power_state("")."";
echo yandex_iot_power_change("","false")."";
sleep(1);
echo get_yandex_iot_power_state("")."";
echo yandex_iot_power_change("","true")."";
?>[/code]

Включаем-выключаем что-нибудь, радуемся что работает.

Кстати sleep(1) - это для того, чтоб Яндекс у себя внутри успел обновить статус. Не моментально меняется.

Дополнительно можно управлять не только питанием, но и другими параметрами изучив документацию https://yandex.ru/dev/dialogs/smart-home/doc/concepts/platform-protocol.html. Мне нужна пока что только функция управления питанием, но имея базу - остальное докрутить не составляет труда.


В статье пойдёт речь о самом базовом управлении устройствами умного дома Яндекс - а именно функции включения/выключения, т.к. ничего больше мне не нужно, но из базы довольно легко с помощью документации, научиться управлять и другими свойствами. Может этот материал не на статью вовсе, но вот захотелось поделиться. За код не ругайте сильно - я не настоящий программист. Код написан на простейшем PHP. AI: Управление устройствами умного дома своими скриптами на PHP Зачем? Захотелось мне как-то настроить один сценарий, который нельзя сделать через Алису. А что делать в таких ситуациях? Разумеется нужно писать свои скрипты. Если кому интересно - функция выключения обогревателя в пиковый тариф электроэнергии при использовании трёхтарифного счётчика и включения обратно по окончании пикового тарифы, но только в случае, если он был включен до этого. Да, в мире существуют вещи типа Home Assistant, но пока мне лень ставить, да и как-то обходился без него. Пока для себя не осознал, зачем он мне. И кажется там именно такой сценарий всё равно нельзя сделать. Важно включать, только если он до отключения был включен. Если до наступления пикового времени прибор не был включен, то и включать его обратно не надо по завершению пикового времени. Поиск решений Начать решил с API Яндекса. Благо с этим проблем нет, нашлось довольно быстро: Однако документация довольно скудна на рабочие примеры. Хорошее дело - прежде чем писать что-то своё, попытаться найти что-то готовое на Github или еще где-то. Честно признаюсь, искал не очень глубоко, но натыкался в основном на варианты, когда нужно наоборот прикрутить свой

Цитирование статьи, картинки - фото скриншот - Rambler News Service.
Иллюстрация к статье - Яндекс. Картинки.
Есть вопросы. Напишите нам.
Общие правила  поведения на сайте.
В статье пойдёт речь о самом базовом управлении устройствами умного дома Яндекс - а именно функции включения/выключения, т.к. ничего больше мне не нужно, но из базы довольно легко с помощью документации, научиться управлять и другими свойствами. Может этот материал не на статью вовсе, но вот захотелось поделиться. За код не ругайте сильно - я не настоящий программист. Код написан на простейшем PHP. AI: Управление устройствами умного дома своими скриптами на PHP Зачем? Захотелось мне как-то настроить один сценарий, который нельзя сделать через Алису. А что делать в таких ситуациях? Разумеется нужно писать свои скрипты. Если кому интересно - функция выключения обогревателя в пиковый тариф электроэнергии при использовании трёхтарифного счётчика и включения обратно по окончании пикового тарифы, но только в случае, если он был включен до этого. Да, в мире существуют вещи типа Home Assistant, но пока мне лень ставить, да и как-то обходился без него. Пока для себя не осознал, зачем он мне. И кажется там именно такой сценарий всё равно нельзя сделать. Важно включать, только если он до отключения был включен. Если до наступления пикового времени прибор не был включен, то и включать его обратно не надо по завершению пикового времени. Поиск решений Начать решил с API Яндекса. Благо с этим проблем нет, нашлось довольно быстро: Однако документация довольно скудна на рабочие примеры. Хорошее дело - прежде чем писать что-то своё, попытаться найти что-то готовое на Github или еще где-то. Честно признаюсь, искал не очень глубоко, но натыкался в основном на варианты, когда нужно наоборот прикрутить свой


Комментарии (0)
img
С наступающими праздниками! - «Умный Дом»

31 Дек Дорогие пользователи! С наступающими праздниками! В этот особенный и волшебный период мы, команда Aqara, хотим от всей души поблагодарить вас

Категории сайта
Разное

Производитель и новинки производства

Это не только возможность управлять лампочкой со смартфона, а слаженная, незаметная для Вас, работа всех систем дома как инструментов в оркестре.

       
img
Новинки / Умный Дом и решения / Производитель / Умная Лампочка / Бренд / Смарт.ТВ / Zigbee / СБЕР / Умные Решения / Умное Реле
Умный дом EKF: всё, что нужно для автоматизации и безопасности жилья - «Умный Дом и решения»

Сегодня мы расскажем вам об «Умном доме» бренда EKF. Раньше мы уже делали пару обзоров умных гаджетов этого бренда, но с тех пор у них появились

img
Производитель / Новинки / Умные Решения
Представлен Matter 1.5.1 для камер. Что нового? - «Умный Дом и решения»

Альянс стандартов подключения (CSA) выпустил небольшое обновление спецификации - Matter 1.5.1. Апдейт улучшает недавно представленные функции из

img
Новинки / Xiaomi / Смарт.ТВ / Производитель / Умный Дом и решения / Умные Решения
Xiaomi показала домашнюю камеру с 12-кратным зумом и функцией ночного видения - «Умный Дом и решения»

Компания Xiaomi представила новую камеру Smart Camera 4 Max AI Zoom Edition. По мнению разработчиков, устройство является самой продвинутой умной

img
Новинки / Бренд / Sprut.hub / Умный Дом и решения / Производитель / Смарт.ТВ
Обновление программного обеспечения Wirenboard wb-2602 - «Умный Дом и решения»

Кажется неинтересным просто переписывать новости разработки с сайта Wirenboard, но в этом обновлении столько классного, что я хотел бы это сделать.

img
Новинки / Смарт.ТВ / Xiaomi / Производитель / Умный Дом и решения / Умные Решения
Домашняя камера Smart Camera 4 Max AI Zoom Edition от Xiaomi выглядит просто потрясающе - «Умный Дом и решения»

Xiaomi представила новую камеру для домашнего видеонаблюдения — Smart Camera 4 Max AI Zoom Edition с функцией ночного зрения. Устройство выделяется

  • Ford
  • 3-04-2026, 11:05
  • 8
img
Новинки / Aqara / Производитель / Умный Дом и решения / Умные Решения
Датчик вибрации Aqara T1: новый уровень безопасности для умного дома - «Умный Дом и решения»

Российский дистрибьютор объявил о запуске на отечественном рынке датчика вибрации Aqara T1 — компактного устройства для систем умного дома...

Top.Mail.Ru