AmendHub

Download

cyberslak

/

lightsout

/

ha.c

 

(View History)

cyberslak   Handle missing brightness key, update entity positions with new scrollbar value after bar_remove Latest amendment: 24 on 2025-03-17

1 // SPDX-License-Identifier: MIT
2
3 #include <OpenTransport.h>
4 #include <OpenTptInternet.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include "net.h"
8 #include "util.h"
9 #include "dbuf.h"
10 #include "cJSON.h"
11 #include "ha.h"
12 #include "preferences.h"
13
14 #define FAIL_TO(label) { ret = -1; goto label; }
15
16 extern PrefHandle gPreferences;
17
18 short ha_get_entity_state(const char* id, struct entity_state* out)
19 {
20 EndpointRef ep;
21 struct dbuf respBuf;
22 char* json_str;
23 cJSON *json, *attrs, *brightness, *name;
24 char tmpBuf[128];
25 short ret = 0;
26
27 snprintf(tmpBuf, sizeof(tmpBuf), "/api/states/%s", id);
28
29 HLock((Handle)gPreferences);
30 ep = net_connect((**gPreferences).server_name, (**gPreferences).port);
31
32 if (!ep) FAIL_TO(noresp)
33
34 respBuf = net_get(ep, tmpBuf, (**gPreferences).token);
35
36 json_str = net_http_response_content((const char*)respBuf.buf);
37 if (!json_str) FAIL_TO(nojson)
38
39 json = cJSON_Parse(json_str);
40 if (!json) FAIL_TO(nojson)
41
42 attrs = cJSON_GetObjectItemCaseSensitive(json, "attributes");
43 brightness = cJSON_GetObjectItemCaseSensitive(attrs, "brightness");
44 name = cJSON_GetObjectItemCaseSensitive(attrs, "friendly_name");
45
46 if (!cJSON_IsNull(name))
47 {
48 snprintf(out->name, 128, "%s", name->valuestring);
49 }
50
51 if (brightness && !cJSON_IsNull(brightness))
52 {
53 out->brightness = brightness->valueint;
54
55 // Zigbee brightness range is 0x01-0xfe.
56 // Just map 0xfe to 0xff, so at least the slider
57 // looks full at 100%.
58 if (out->brightness == 254)
59 out->brightness = 255;
60 } else {
61 out->brightness = 0;
62 }
63
64 cJSON_Delete(json);
65 nojson:
66 db_destroy(&respBuf);
67 OTCloseProvider(ep);
68 noresp:
69 HUnlock((Handle)gPreferences);
70 return ret;
71 }
72
73 short ha_set_entity_state(const char* id, struct entity_state *st)
74 {
75 EndpointRef ep;
76 struct dbuf respBuf;
77 char tmpBuf[512];
78 short ret = 0;
79
80 snprintf(tmpBuf, sizeof(tmpBuf),
81 "{\"entity_id\": \"%s\", \"brightness\": %d}", id, st->brightness);
82
83 HLock((Handle)gPreferences);
84 ep = net_connect((**gPreferences).server_name, (**gPreferences).port);
85 if (!ep) FAIL_TO(noresp)
86
87 respBuf = net_post(ep, "/api/services/light/turn_on", (**gPreferences).token, tmpBuf);
88
89 OTCloseProvider(ep);
90 db_destroy(&respBuf);
91 noresp:
92 HUnlock((Handle)gPreferences);
93 return ret;
94 }
95
96 short ha_get_entities(list_t *ents)
97 {
98 EndpointRef ep;
99 struct dbuf respBuf;
100 const char* json_str;
101 cJSON *json, *entity;
102 short ret = 0;
103
104 list_init(ents);
105
106 HLock((Handle)gPreferences);
107
108 ep = net_connect((**gPreferences).server_name, (**gPreferences).port);
109 if (!ep) FAIL_TO(noresp)
110
111 respBuf = net_get(ep, "/api/states", (**gPreferences).token);
112
113 json_str = net_http_response_content((const char*)respBuf.buf);
114 if (!json_str) FAIL_TO(nojson)
115
116 json = cJSON_Parse(json_str);
117
118 if (!json) FAIL_TO(nojson)
119
120 cJSON_ArrayForEach(entity, json)
121 {
122 cJSON* id = cJSON_GetObjectItem(entity, "entity_id");
123 cJSON* attrs = cJSON_GetObjectItem(entity, "attributes");
124 cJSON* name = cJSON_GetObjectItem(attrs, "friendly_name");
125
126 if (!cJSON_IsString(id))
127 {
128 die("No entity id?");
129 }
130 if (strncmp(id->valuestring, "light.", 6) == 0)
131 {
132 struct entity* ent = xmalloc(sizeof(struct entity));
133 strlcpy(ent->id, id->valuestring, 128);
134 strlcpy(ent->state.name, name->valuestring, 128);
135 list_add(ents, &ent->node);
136 ret++;
137 }
138 }
139
140 cJSON_Delete(json);
141 nojson:
142 OTCloseProvider(ep);
143 db_destroy(&respBuf);
144 noresp:
145 HUnlock((Handle)gPreferences);
146 return ret;
147 }
148
149 short ha_test_prefs()
150 {
151 EndpointRef ep;
152 struct dbuf respBuf;
153 short ret = 0;
154 const char* json_str;
155 cJSON *json, *msg;
156
157 HLock((Handle)gPreferences);
158
159 ep = net_connect((**gPreferences).server_name, (**gPreferences).port);
160
161 if (!ep) FAIL_TO(noresp)
162
163 respBuf = net_get(ep, "/api/", (**gPreferences).token);
164 json_str = net_http_response_content((const char*)respBuf.buf);
165 if (!json_str) FAIL_TO(nojson)
166 json = cJSON_Parse(json_str);
167 if (!json) FAIL_TO(nojson);
168
169 msg = cJSON_GetObjectItem(json, "message");
170 if (strncmp(msg->valuestring, "API running.", 12) != 0)
171 FAIL_TO(fail);
172
173 fail:
174 cJSON_Delete(json);
175 nojson:
176 OTCloseProvider(ep);
177 db_destroy(&respBuf);
178 noresp:
179 HUnlock((Handle)gPreferences);
180 return ret;
181 }