preliminary hass
This commit is contained in:
8
include/hass.h
Normal file
8
include/hass.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef HAS_WEBSOCKET_H
|
||||
#define HAS_WEBSOCKET_H
|
||||
|
||||
#define HASS_ADDRESS "home.drath.win"
|
||||
#define HASS_TOKEN "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI0MzUxMTZiY2VjNTg0MTI3OGI4YmU0NTY4ZGQ5MzIyYiIsImlhdCI6MTc1NzQzMDI0MCwiZXhwIjoyMDcyNzkwMjQwfQ.6wKTlxEA0FLWfv-qW35vewUSvTxdVrZWqFwHT5Khu6E"
|
||||
#define HASS_ENTITY "sensor.gniazdko_komputer_moc"
|
||||
|
||||
#endif
|
||||
155
src/hass.c
Normal file
155
src/hass.c
Normal file
@@ -0,0 +1,155 @@
|
||||
#include <libwebsockets.h>
|
||||
#include "log.h"
|
||||
#include "hass.h"
|
||||
|
||||
char tx[512];
|
||||
struct lws_context *context = nullptr;
|
||||
struct lws *websock = nullptr;
|
||||
float state;
|
||||
uint16_t id = 2;
|
||||
|
||||
static int callback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len);
|
||||
|
||||
static int callback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) {
|
||||
(void)user;
|
||||
(void)len;
|
||||
// ArduinoJson::JsonDocument json;
|
||||
switch (reason) {
|
||||
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: {
|
||||
applog(LOG_ERR, "websocket conn error: %s", in ? (char *)in : "(null)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// case LWS_CALLBACK_CLIENT_RECEIVE: {
|
||||
// ArduinoJson::deserializeJson(json, (char *)in);
|
||||
// std::string ha_type = json["type"].as<std::string>();
|
||||
// // std::println("[HomeAssistant] got event type: {} ", ha_type);
|
||||
//
|
||||
// if (ha_type == "auth_required") {
|
||||
// json.clear();
|
||||
// json["type"] = "auth";
|
||||
// json["access_token"] = HASS_TOKEN;
|
||||
// ArduinoJson::serializeJson(json, tx);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// if (ha_type == "auth_ok") {
|
||||
// std::println("[HomeAssistant] subscribing to entity \"{}\"", HASS_ENTITY);
|
||||
// json.clear();
|
||||
// json["id"] = id++;
|
||||
// json["type"] = "subscribe_entities";
|
||||
// json["entity_ids"][0] = HASS_ENTITY;
|
||||
// ArduinoJson::serializeJson(json, tx);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// if (ha_type == "result") {
|
||||
// if (json["success"].as<std::string>() == "false")
|
||||
// std::println("[HomeAssistant] api said success was \"false\" on message id {}", id - 1);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// if (ha_type == "event") {
|
||||
// state = json["event"]["c"][HASS_ENTITY]["+"]["s"].as<float>();
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// std::println("[HomeAssistant] unhandled event: {}", (char *)in);
|
||||
// break;
|
||||
// }
|
||||
|
||||
case LWS_CALLBACK_CLIENT_ESTABLISHED: {
|
||||
applog(LOG_INF, "Websocket connected");
|
||||
break;
|
||||
}
|
||||
|
||||
case LWS_CALLBACK_CLIENT_CLOSED: {
|
||||
applog(LOG_INF, "Websocket closed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
case LWS_CALLBACK_CLIENT_WRITEABLE: {
|
||||
/* skip whole callback if there's no tx to send */
|
||||
const size_t txlen = strlen(tx);
|
||||
|
||||
if (txlen > 0) {
|
||||
// std::println("[HomeAssistant] sending {}", tx);
|
||||
const size_t msgLen = LWS_PRE + txlen;
|
||||
unsigned char *buf = (unsigned char *)malloc(msgLen);
|
||||
if (buf) {
|
||||
memcpy(&buf[LWS_PRE], tx, txlen);
|
||||
lws_write(wsi, &buf[LWS_PRE], txlen, LWS_WRITE_TEXT);
|
||||
tx[0] = '\0';
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hass_connect() {
|
||||
struct lws_client_connect_info i = {};
|
||||
struct lws_context_creation_info info = {};
|
||||
|
||||
lws_set_log_level(LLL_ERR | LLL_WARN, lwsl_emit_syslog);
|
||||
|
||||
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"},
|
||||
{nullptr, nullptr, nullptr}};
|
||||
|
||||
info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
|
||||
info.port = CONTEXT_PORT_NO_LISTEN;
|
||||
info.protocols = protocols;
|
||||
info.fd_limit_per_thread = 1 + 1 + 1;
|
||||
info.extensions = extensions;
|
||||
|
||||
context = lws_create_context(&info);
|
||||
if (!context) {
|
||||
applog(LOG_ERR, "error creating context");
|
||||
return -1;
|
||||
}
|
||||
|
||||
i.context = context;
|
||||
i.port = 443;
|
||||
i.address = HASS_ADDRESS;
|
||||
i.path = "/api/websocket";
|
||||
i.host = i.address;
|
||||
i.origin = i.address;
|
||||
i.ssl_connection = LCCSCF_USE_SSL | LCCSCF_PRIORITIZE_READS;
|
||||
i.protocol = nullptr;
|
||||
i.local_protocol_name = "lws-minimal-client";
|
||||
|
||||
websock = lws_client_connect_via_info(&i);
|
||||
if (!websock) {
|
||||
applog(LOG_ERR, " error creating lws client");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hass_poll() {
|
||||
lws_service(context, 0);
|
||||
lws_callback_on_writable(websock);
|
||||
}
|
||||
|
||||
float hass_get() {
|
||||
return state;
|
||||
}
|
||||
|
||||
void hass_disconnect() {
|
||||
lws_context_destroy(context);
|
||||
}
|
||||
Reference in New Issue
Block a user