cyberslak
/lightsout
/amendments
/7
ha: make functions fallible, use preferences, add ha_get_entities
cyberslak made amendment 7 25 days ago
--- ha.c Fri Mar 7 15:03:33 2025
+++ ha.c Sun Mar 9 23:03:13 2025
@@ -7,26 +7,36 @@
#include "dbuf.h"
#include "cJSON.h"
#include "ha.h"
+#include "preferences.h"
-const char ha_hostname[] = "192.168.1.188";
-short ha_port = 8123;
-const char token[] = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmOTQ4MmEyOWFjNTc0Y2IwOGRjYzllMTE1YTU2Y2QyYSIsImlhdCI6MTc0MDIzNjgyMSwiZXhwIjoyMDU1NTk2ODIxfQ.539PmkpOmnV-Je7g7C1ZY0lpwuMUp2Cc2sYYFNrvb00";
+#define FAIL_TO(label) { ret = -1; goto label; }
+extern PrefHandle gPreferences;
+
short ha_get_entity_state(const char* id, struct entity_state* out)
{
- EndpointRef ep = net_connect(ha_hostname, ha_port);
+ EndpointRef ep;
struct dbuf respBuf;
char* json_str;
cJSON *json, *attrs, *brightness, *name;
-
char tmpBuf[128];
+ short ret = 0;
snprintf(tmpBuf, sizeof(tmpBuf), "/api/states/%s", id);
- respBuf = net_get(ep, tmpBuf, token);
+ HLock((Handle)gPreferences);
+ ep = net_connect((**gPreferences).server_name, (**gPreferences).port);
+ if (!ep) FAIL_TO(noresp)
+
+ respBuf = net_get(ep, tmpBuf, (**gPreferences).token);
+
json_str = net_http_response_content((const char*)respBuf.buf);
+ if (!json_str) FAIL_TO(nojson)
+
json = cJSON_Parse(json_str);
+ if (!json) FAIL_TO(nojson)
+
attrs = cJSON_GetObjectItemCaseSensitive(json, "attributes");
brightness = cJSON_GetObjectItemCaseSensitive(attrs, "brightness");
name = cJSON_GetObjectItemCaseSensitive(attrs, "friendly_name");
@@ -44,39 +54,120 @@ short ha_get_entity_state(const char* id, struct entit
}
cJSON_Delete(json);
-
+nojson:
db_destroy(&respBuf);
OTCloseProvider(ep);
-
- return 0;
+noresp:
+ HUnlock((Handle)gPreferences);
+ return ret;
}
-void ha_set_entity_state(const char* id, struct entity_state *st)
+short ha_set_entity_state(const char* id, struct entity_state *st)
{
- EndpointRef ep = net_connect(ha_hostname, ha_port);
+ EndpointRef ep;
struct dbuf respBuf;
char tmpBuf[512];
+ short ret = 0;
snprintf(tmpBuf, sizeof(tmpBuf),
"{\"entity_id\": \"%s\", \"brightness\": %d}", id, st->brightness);
- respBuf = net_post(ep, "/api/services/light/turn_on", token, tmpBuf);
+ HLock((Handle)gPreferences);
+ ep = net_connect((**gPreferences).server_name, (**gPreferences).port);
+ if (!ep) FAIL_TO(noresp)
+ respBuf = net_post(ep, "/api/services/light/turn_on", (**gPreferences).token, tmpBuf);
+
+ OTCloseProvider(ep);
db_destroy(&respBuf);
+noresp:
+ HUnlock((Handle)gPreferences);
+ return ret;
+}
+
+short ha_get_entities(list_t *ents)
+{
+ EndpointRef ep;
+ struct dbuf respBuf;
+ const char* json_str;
+ cJSON *json, *entity;
+ short ret = 0;
+
+ list_init(ents);
+
+ HLock((Handle)gPreferences);
+
+ ep = net_connect((**gPreferences).server_name, (**gPreferences).port);
+ if (!ep) FAIL_TO(noresp)
+
+ respBuf = net_get(ep, "/api/states", (**gPreferences).token);
+
+ json_str = net_http_response_content((const char*)respBuf.buf);
+ if (!json_str) FAIL_TO(nojson)
+
+ json = cJSON_Parse(json_str);
+
+ if (!json) FAIL_TO(nojson)
+
+ cJSON_ArrayForEach(entity, json)
+ {
+ cJSON* id = cJSON_GetObjectItem(entity, "entity_id");
+ cJSON* attrs = cJSON_GetObjectItem(entity, "attributes");
+ cJSON* name = cJSON_GetObjectItem(attrs, "friendly_name");
+
+ if (!cJSON_IsString(id))
+ {
+ die("No entity id?");
+ }
+ if (strncmp(id->valuestring, "light.", 6) == 0)
+ {
+ struct entity* ent = xmalloc(sizeof(struct entity));
+ strlcpy(ent->id, id->valuestring, 128);
+ strlcpy(ent->state.name, name->valuestring, 128);
+ list_add(ents, &ent->node);
+ ret++;
+ }
+ }
+
+ cJSON_Delete(json);
+nojson:
OTCloseProvider(ep);
+ db_destroy(&respBuf);
+noresp:
+ HUnlock((Handle)gPreferences);
+ return ret;
}
-struct list ha_get_entities()
+short ha_test_prefs()
{
- EndpointRef ep = net_connect(ha_hostname, ha_port);
+ EndpointRef ep;
struct dbuf respBuf;
+ short ret = 0;
const char* json_str;
- cJSON* json;
+ cJSON *json, *msg;
- respBuf = net_get(ep, "/api/states", token);
+ HLock((Handle)gPreferences);
+ ep = net_connect((**gPreferences).server_name, (**gPreferences).port);
+
+ if (!ep) FAIL_TO(noresp)
+
+ respBuf = net_get(ep, "/api/", (**gPreferences).token);
json_str = net_http_response_content((const char*)respBuf.buf);
+ if (!json_str) FAIL_TO(nojson)
json = cJSON_Parse(json_str);
+ if (!json) FAIL_TO(nojson);
+ msg = cJSON_GetObjectItem(json, "message");
+ if (strncmp(msg->valuestring, "API running.", 12) != 0)
+ FAIL_TO(fail);
+
+fail:
+ cJSON_Delete(json);
+nojson:
+ OTCloseProvider(ep);
db_destroy(&respBuf);
+noresp:
+ HUnlock((Handle)gPreferences);
+ return ret;
}
--- ha.h Tue Mar 4 21:20:33 2025
+++ ha.h Sat Mar 8 21:09:14 2025
@@ -3,9 +3,12 @@
#include "list.h"
#include "entity.h"
-/* Get the entity state from the server.
- */
-short ha_get_entity_state(const char* id, struct entity_state* out);
+/* Get the entity state from the server. */
+short ha_get_entity_state(const char* id, struct entity_state* st);
/* Update the server-side entity state. */
-void ha_set_entity_state(const char* id, struct entity_state* s);
+short ha_set_entity_state(const char* id, struct entity_state* st);
+
+short ha_get_entities(list_t *ents);
+
+short ha_test_prefs();