14 KiB
Пролог
Yandex api немного запутоно.
Использование формата json логично для api, но не когда вы работайте на c.
И даже так, видно что разработчики пытались сделать api ответы, а именно все девайсы и группы с комнатами максемально не избыточным.
И это накладовает некоторые проблемы.
Устройство может как и явно говорить включенно оно или нет (True/False), так и не иметь явного стстуса (None).
Или например лампочки имеют цвет, и когда они белые мы явно можем задать температуру цвета в келвенах, но когда кампочка имеет другой цвет, то тут только hsv или если лампа воспроизводит какуето анимированую палитру, то
Возможности
Взаимодействие
- Включить/выключить устройство. ✅
- Изменить яркость. ✅
- Изменить канделы. ✅
- Изменить цвет. ✅
- Изменить цветовой профиль/сценарий. ❌
Получить данные
- Имя. ✅
- Псевдонимы. ❌
- Работает ли. ✅
- Яркость. ✅
- Минимальная яркостью ✅
- Максимальная яркость. ✅
- Сила канделы. ✅
- Максимальные канделы. ✅
- Минимальные канделы. ✅
- Поддерживает цвета ? ✅
- Какой цвет сейчас. ✅
- Поддерживает ли профиль/сценарий. ❌
- Какие есть профили/сценарии. ❌
- Список групп и устройств в них. ✅
Архитектурные реализации.
- Очистка памяти. ❔
- Асинхронность. ❌
API
Так мы получаем структуру нашего API
struct ya_api api = ya_api_create("Authorization: TOKEN");
Это даст тебе список девайсов, сейчас у тебя их нет!
api.list_devices(&api);
Это пример как ты можешь получить имя всех девайсов.
for (int i = 0; i != api.data.devs->len; i++){
printf("%s\n", api.data.devs->dev[i]->name);
}
Вы также можете относительно удобно отправить любой API запрос через
ya_api_recvest("https://api.iot.yandex.net/v1.0/user/info", NULL, api.data.tocen)
Данная процедура вернёт реквест. Третим пораметром вы можете передать ваш хэдерс, обычно это JSON.
Так вы можете сключать и выключать устройство:
api.on_off(api.data.devs->dev[6]);
Вы можете это делать с группой, использовав данную конструкцию:
for (int i = 0; i != api.data.groups->len; i++){
printf("ГРУППА: %s\n", api.data.groups->group[i]->name);
for (int a = 0; a != api.data.groups->group[i]->devs->len; a++){
struct ya_dev_struct *dev = api.data.groups->group[i]->devs->dev[a];
printf("\tДЕВAЙС: %s\n", dev->name);
api.on_off(dev);
}
}
Также вы можете менять температуру, яркость и свет:
api.kelvin(dev, 6500);
Изменить свет модно данной командой
api.hsv(dev, 284,93,80);
Получить цвет можно данным условием:
struct color_struct *color = dev->capabilities->color_setting->color;
printf("HSV = %i %i %i\n", color->h, color->s, color->v);
если ваше устройство сейчас не отоброжает цвеоной цвет, например включён сценарий или цвет задан в кельвинах, то вы получити такой ответ:
HSV = -1 -1 -1
Узнать, какой именно тип цвета сейчас работает можно спомошью данной функции, где 1 это kelvin, 2 это color, 3 это сценарий.
Вы также захотите понять, что это за устройство, вы можете сделать это так:
printf("\tДЕВAЙС %s: %s\n", dev->type, dev->name);
Вы получити такой ответ:
ДЕВЫЙС devices.types.light: Люстра
Наверное вы бы это претпочли получать как то иначе, но как по мне, так болие уневерсально, хоть вам и придётся менять свой код если Яндекс захочет изменить это.
{
"name": "Люстра",
"room": "78dfb6d2-2183-439c-8fbe-c7a101b5ef02",
"groups": [
"afedc785-dd02-46e6-a347-458a7121da49"
],
"capabilities": [
{
"parameters": {
"random_access": true,
"instance": "brightness",
"unit": "unit.percent",
"looped": false,
"range": {
"min": 1,
"max": 100,
"precision": 1
}
},
"state": {
"value": 100,
"instance": "brightness"
},
"last_updated": 1722379725.960000,
"reportable": true,
"type": "devices.capabilities.range",
"retrievable": true
},
{
"parameters": {
"color_scene": {
"scenes": [
{
"id": "alice"
},
{
"id": "party"
},
{
"id": "jungle"
},
{
"id": "neon"
},
{
"id": "night"
},
{
"id": "ocean"
},
{
"id": "romance"
},
{
"id": "candle"
},
{
"id": "siren"
},
{
"id": "alarm"
},
{
"id": "fantasy"
},
{
"id": "reading"
}
]
},
"color_model": "hsv",
"temperature_k": {
"min": 1500,
"max": 6500
}
},
"state": {
"value": {
"v": 100,
"s": 96,
"h": 135
},
"instance": "hsv"
},
"last_updated": 1722379725.960000,
"reportable": true,
"type": "devices.capabilities.color_setting",
"retrievable": true
},
{
"parameters": {
"split": false
},
"state": {
"value": true,
"instance": "on"
},
"last_updated": 1722378636.990000,
"reportable": true,
"type": "devices.capabilities.on_off",
"retrievable": true
}
],
"id": "0a924ae6-b9d7-4d17-a836-ef280c771b3b",
"external_id": "47408080381f8d56fdfc",
"type": "devices.types.light",
"skill_id": "T",
"household_id": "8deb9854-5790-4036-bde3-ba7ad355624c"
},
"color_model": "hsv",
"temperature_k": {
"min": 1500,
"max": 6500
}
},
"state": {
"value": {
"v": 100,
"s": 96,
"h": 135
},
"instance": "hsv"
},
"last_updated": 1722379725.960000,
"reportable": true,
"type": "devices.capabilities.color_setting",
"retrievable": true
},
{
"parameters": {
"split": false
},
"state": {
"value": true,
"instance": "on"
},
"last_updated": 1722378636.990000,
"reportable": true,
"type": "devices.capabilities.on_off",
"retrievable": true
}
//////////
"color_model": "hsv",
"temperature_k": {
"min": 1500,
"max": 6500
}
},
"state": {
"value": 4500,
"instance": "temperature_k"
},
"last_updated": 1722379815.697000,
"reportable": true,
"type": "devices.capabilities.color_setting",
"retrievable": true
},
{
"parameters": {
"split": false
},
"state": {
"value": true,
"instance": "on"
},
"last_updated": 1722378637.454000,
"reportable": true,
"type": "devices.capabilities.on_off",
"retrievable": true
}
/////////////
"color_model": "hsv",
"temperature_k": {
"min": 1500,
"max": 6500
}
},
"state": {
"value": "neon",
"instance": "scene"
},
"last_updated": 1722380508.054000,
"reportable": true,
"type": "devices.capabilities.color_setting",
"retrievable": true
},
{
"parameters": {
"split": false
},
"state": {
"value": true,
"instance": "on"
},
"last_updated": 1722378636.990000,
"reportable": true,
"type": "devices.capabilities.on_off",
"retrievable": true
}
graph LR
A[api] -->B1(data)
B1 -->Bs2(tocen)
B1 -->B2(devs)
B2 --> C(["dev[int]"])
B2 --> C1[len]
C --> D1[id]
C --> D2[name]
C --> D4[room]
C --> D5[type]
C --> CI1[capabilities]
CI1 --> CI1F[color_setting]
CI1F --> CI1F4[color_target]
CI1F --> CI1F1[color]
CI1F1 --> CI1F1A1[v]
CI1F1 --> CI1F1A2[s]
CI1F1 --> CI1F1A3[h]
CI1F --> CI1F2[temperature_k]
CI1F2 --> CI1F2H1[value]
CI1F2 --> CI1F2H2[min]
CI1F2 --> CI1F2H3[max]
CI1F --> CI1F3[scenes]
CI1F3 --> CI1F3A(["scenes[int]"])
CI1 --> CI2F[on_off]
CI2F --> CI2F1[value]
CI1 --> CI3F[range]
CI3F --> CI3F1[value]
CI3F --> CI3F2[min]
CI3F --> CI3F3[max]
C --> D3((groups))
graph LR
A[api] -->B1(data)
B1 -->Bs2(tocen)
B1 -->B2(devs)
B2 --> C(["dev[int]"])
B2 --> C1[len]
C --> D1[id]
C --> D2[name]
C --> D4[room]
C --> D5[type]
C --> CI1[capabilities]
CI1 --> CI1F[color_setting]
CI1F --> CI1F1[color]
CI1F --> CI1F2[temperature_k]
CI1F2 --> CI1F2H1[value]
CI1F2 --> CI1F2H2[min]
CI1F2 --> CI1F2H3[max]
CI1F --> CI1F3[scenes]
CI1 --> CI2F[on_off]
CI2F --> CI2F1[value]
CI1 --> CI3F[range]
CI3F --> CI3F1[value]
CI3F --> CI3F2[min]
CI3F --> CI3F3[max]
C --> D3((groups))
graph LR
A[Hard edge] -->B(Round edge)
B --> C{Decision}
C -->|One| D[Result one]
C -->|Two| E[Result two]
%% Example with selection of syntaxes
gantt
dateFormat YYYY-MM-DD
title Adding GANTT diagram functionality to mermaid
section A section
Completed task :done, des1, 2014-01-06,2014-01-08
Active task :active, des2, 2014-01-09, 3d
Future task : des3, after des2, 5d
Future task2 : des4, after des3, 5d
section Critical tasks
Completed task in the critical line :crit, done, 2014-01-06,24h
Implement parser and jison :crit, done, after des1, 2d
Create tests for parser :crit, active, 3d
Future task in critical line :crit, 5d
Create tests for renderer :2d
Add to mermaid :1d
section Documentation
Describe gantt syntax :active, a1, after des1, 3d
Add gantt diagram to demo page :after a1 , 20h
Add another diagram to demo page :doc1, after a1 , 48h
section Last section
Describe gantt syntax :after doc1, 3d
Add gantt diagram to demo page : 20h
Add another diagram to demo page : 48h
classDiagram
Animal <|-- Duck
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
stateDiagram
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
pie
title Pie Chart
"Dogs" : 386
"Cats" : 85
"Rats" : 150
requirementDiagram
requirement test_req {
id: 1
text: the test text.
risk: high
verifymethod: test
}
element test_entity {
type: simulation
}
test_entity - satisfies -> test_req