From 26a80566930e5d324c047e9e25a6aa090bbcd126 Mon Sep 17 00:00:00 2001 From: Drath Date: Sat, 13 Sep 2025 14:18:38 +0200 Subject: [PATCH] its a class now --- include/hass.hpp | 26 +++++++++++++----- src/hass.cpp | 70 +++++++++++++++++++++++++----------------------- 2 files changed, 56 insertions(+), 40 deletions(-) diff --git a/include/hass.hpp b/include/hass.hpp index 7ba7415..bce36ac 100644 --- a/include/hass.hpp +++ b/include/hass.hpp @@ -8,13 +8,27 @@ #include #include -#define HASS_ADDRESS "home.drath.win" #define HASS_TOKEN "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI0MzUxMTZiY2VjNTg0MTI3OGI4YmU0NTY4ZGQ5MzIyYiIsImlhdCI6MTc1NzQzMDI0MCwiZXhwIjoyMDcyNzkwMjQwfQ.6wKTlxEA0FLWfv-qW35vewUSvTxdVrZWqFwHT5Khu6E" -#define HASS_ENTITY "sensor.gniazdko_komputer_moc" -int hass_connect(); -void hass_service(int timeout_ms = 0); -float hass_get(); -void hass_disconnect(); +class HomeAssistant { + private: + std::string address; + std::string entity; + uint16_t id = 2; + std::string tx; + struct lws_context *context = NULL; + lws *websock = NULL; + void event_handler(struct lws *wsi, enum lws_callback_reasons reason, char *in); + static int callback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); + + public: + HomeAssistant(std::string addr, std::string ent); + ~HomeAssistant(); + + float state = 0.0f; + int connect(); + void service(int timeout_ms = 0); + void disconnect(); +}; #endif \ No newline at end of file diff --git a/src/hass.cpp b/src/hass.cpp index d9d697f..fb40c79 100644 --- a/src/hass.cpp +++ b/src/hass.cpp @@ -1,35 +1,24 @@ #include -std::string tx; -struct lws_context *context = NULL; -lws *websock = NULL; -float state; -uint16_t id = 2; +HomeAssistant::HomeAssistant(std::string addr, std::string ent) { + address = addr; + entity = ent; +} -static int callback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); +HomeAssistant::~HomeAssistant() { + disconnect(); +} -static const struct lws_protocols protocols[] = { - {"lws-minimal-client", callback, 0, 0, 0, NULL, 0}, - LWS_PROTOCOL_LIST_TERM}; - -static const struct lws_extension extensions[] = { - {"permessage-deflate", - lws_extension_callback_pm_deflate, - "permessage-deflate" - "; client_no_context_takeover" - "; client_max_window_bits"}, - {NULL, NULL, NULL}}; - -static int callback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { +void HomeAssistant::event_handler(struct lws *wsi, enum lws_callback_reasons reason, char *in) { ArduinoJson::JsonDocument json; switch (reason) { case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: { - std::println("[HomeAssistant] websocket conn error: {}", in ? (char *)in : "(null)"); - return -1; + std::println("[HomeAssistant] websocket conn error: {}", in ? in : "(null)"); + return; } case LWS_CALLBACK_CLIENT_RECEIVE: { - ArduinoJson::deserializeJson(json, (char *)in); + ArduinoJson::deserializeJson(json, in); std::string ha_type = json["type"].as(); // std::println("[HomeAssistant] got event type: {} ", ha_type); @@ -42,11 +31,11 @@ static int callback(struct lws *wsi, enum lws_callback_reasons reason, void *use } if (ha_type == "auth_ok") { - std::println("[HomeAssistant] subscribing to entity \"{}\"", HASS_ENTITY); + std::println("[HomeAssistant] subscribing to entity \"{}\"", entity); json.clear(); json["id"] = id++; json["type"] = "subscribe_entities"; - json["entity_ids"][0] = HASS_ENTITY; + json["entity_ids"][0] = entity.c_str(); ArduinoJson::serializeJson(json, tx); break; } @@ -58,7 +47,7 @@ static int callback(struct lws *wsi, enum lws_callback_reasons reason, void *use } if (ha_type == "event") { - state = json["event"]["c"][HASS_ENTITY]["+"]["s"].as(); + state = json["event"]["c"][entity]["+"]["s"].as(); break; } @@ -73,7 +62,7 @@ static int callback(struct lws *wsi, enum lws_callback_reasons reason, void *use case LWS_CALLBACK_CLIENT_CLOSED: { std::println("[HomeAssistant] Websocket closed"); - return -1; + return; } case LWS_CALLBACK_CLIENT_WRITEABLE: { @@ -96,11 +85,15 @@ static int callback(struct lws *wsi, enum lws_callback_reasons reason, void *use default: break; } +} +int HomeAssistant::callback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { + HomeAssistant *self = static_cast(user); + self->event_handler(wsi, reason, (char *)in); return 0; } -int hass_connect() { +int HomeAssistant::connect() { struct lws_client_connect_info i; struct lws_context_creation_info info; @@ -109,6 +102,18 @@ int hass_connect() { memset(&i, 0, sizeof(i)); memset(&info, 0, sizeof info); + static const struct lws_protocols protocols[] = { + {"lws-minimal-client", callback, sizeof(void *), 0, 0, NULL, 0}, + LWS_PROTOCOL_LIST_TERM}; + + static const struct lws_extension extensions[] = { + {"permessage-deflate", + lws_extension_callback_pm_deflate, + "permessage-deflate" + "; client_no_context_takeover" + "; client_max_window_bits"}, + {NULL, NULL, NULL}}; + info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; info.port = CONTEXT_PORT_NO_LISTEN; info.protocols = protocols; @@ -123,12 +128,13 @@ int hass_connect() { i.context = context; i.port = 443; - i.address = HASS_ADDRESS; + i.address = address.c_str(); i.path = "/api/websocket"; i.host = i.address; i.origin = i.address; i.ssl_connection = LCCSCF_USE_SSL | LCCSCF_PRIORITIZE_READS; i.protocol = NULL; + i.userdata = this; i.local_protocol_name = "lws-minimal-client"; websock = lws_client_connect_via_info(&i); @@ -139,15 +145,11 @@ int hass_connect() { return 0; } -void hass_service(int timeout_ms) { +void HomeAssistant::service(int timeout_ms) { lws_callback_on_writable(websock); lws_service(context, timeout_ms); } -float hass_get() { - return state; -} - -void hass_disconnect() { +void HomeAssistant::disconnect() { lws_context_destroy(context); } \ No newline at end of file