Skip to content

Commit

Permalink
[HASS] Adding Battery driver discovery ang sensor avty flag (#685)
Browse files Browse the repository at this point in the history
* Adding Battery driver discovery
Adding Flag for sensor avaibility publish

* correct hass.h

* correct call for other platform than beken

* Change Typo availability and Battery for driver

* Forget the pin description
  • Loading branch information
Dheenhasty authored Feb 22, 2023
1 parent 8441770 commit 993cd60
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 60 deletions.
4 changes: 2 additions & 2 deletions src/driver/drv_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ static driver_t g_drivers[] = {
{ "CHT8305", CHT8305_Init, CHT8305_OnEverySecond, CHT8305_AppendInformationToHTTPIndexPage, NULL, NULL, NULL, false },
{ "MAX72XX", DRV_MAX72XX_Init, NULL, NULL, NULL, NULL, NULL, false },
{ "SHT3X", SHT3X_Init, NULL, SHT3X_AppendInformationToHTTPIndexPage, NULL, SHT3X_StopDriver, NULL, false },
{ "BATTERY", Batt_Init, Batt_OnEverySecond, Batt_AppendInformationToHTTPIndexPage, NULL, Batt_StopDriver, NULL, false },
{ "Battery", Batt_Init, Batt_OnEverySecond, Batt_AppendInformationToHTTPIndexPage, NULL, Batt_StopDriver, NULL, false },
#endif
{ "Bridge", Bridge_driver_Init, NULL, NULL, Bridge_driver_QuickFrame, Bridge_driver_DeInit, Bridge_driver_OnChannelChanged, false }
{ "Bridge", Bridge_driver_Init, NULL, NULL, Bridge_driver_QuickFrame, Bridge_driver_DeInit, Bridge_driver_OnChannelChanged, false }
};

static const int g_numDrivers = sizeof(g_drivers) / sizeof(g_drivers[0]);
Expand Down
43 changes: 39 additions & 4 deletions src/httpserver/hass.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "../logging/logging.h"
#include "../hal/hal_wifi.h"
#include "../driver/drv_public.h"
#include "../new_pins.h"

/*
Abbreviated node names - https://www.home-assistant.io/docs/mqtt/discovery/
Expand Down Expand Up @@ -57,6 +58,12 @@ void hass_populate_unique_id(ENTITY_TYPE type, int index, char* uniq_id) {
case HUMIDITY_SENSOR:
sprintf(uniq_id, "%s_%s_%d", longDeviceName, "humidity", index);
break;
case BATTERY_SENSOR:
sprintf(uniq_id, "%s_%s_%d", longDeviceName, "battery", index);
break;
case BATTERY_VOLTAGE_SENSOR:
sprintf(uniq_id, "%s_%s_%d", longDeviceName, "voltage", index);
break;
}
}

Expand Down Expand Up @@ -90,6 +97,8 @@ void hass_populate_device_config_channel(ENTITY_TYPE type, char* uniq_id, HassDe
break;

case POWER_SENSOR:
case BATTERY_SENSOR:
case BATTERY_VOLTAGE_SENSOR:
case TEMPERATURE_SENSOR:
case HUMIDITY_SENSOR:
sprintf(info->channel, "sensor/%s/config", uniq_id);
Expand Down Expand Up @@ -177,10 +186,23 @@ HassDeviceInfo* hass_init_device_info(ENTITY_TYPE type, int index, char* payload
isSensor = true;
sprintf(g_hassBuffer, "%s Humidity", CFG_GetShortDeviceName());
break;
case BATTERY_SENSOR:
isSensor = true;
sprintf(g_hassBuffer, "%s Battery", CFG_GetShortDeviceName());
break;
case BATTERY_VOLTAGE_SENSOR:
isSensor = true;
sprintf(g_hassBuffer, "%s Voltage", CFG_GetShortDeviceName());
break;
}
cJSON_AddStringToObject(info->root, "name", g_hassBuffer);
cJSON_AddStringToObject(info->root, "~", CFG_GetMQTTClientId()); //base topic
cJSON_AddStringToObject(info->root, "avty_t", "~/connected"); //availability_topic, `online` value is broadcasted
// remove availability information for sensor to keep last value visible on Home Assistant
bool flagavty = false;
flagavty = CFG_HasFlag(OBK_FLAG_NOT_PUBLISH_AVAILABILITY_SENSOR);
if (!isSensor || !flagavty) {
cJSON_AddStringToObject(info->root, "avty_t", "~/connected"); //availability_topic, `online` value is broadcasted
}

if (!isSensor) { //Sensors (except binary_sensor) don't use payload
cJSON_AddStringToObject(info->root, "pl_on", payload_on); //payload_on
Expand Down Expand Up @@ -338,19 +360,32 @@ HassDeviceInfo* hass_init_sensor_device_info(ENTITY_TYPE type, int channel) {
//https://www.home-assistant.io/integrations/sensor.mqtt/ refers to value_template (val_tpl)
//{{ float(value)*0.1 }} for value=12 give 1.2000000000000002, using round() to limit the decimal places
cJSON_AddStringToObject(info->root, "val_tpl", "{{ float(value)*0.1|round(2) }}");
sprintf(g_hassBuffer, "~/%d/get", channel);
cJSON_AddStringToObject(info->root, STATE_TOPIC_KEY, g_hassBuffer);
break;
case HUMIDITY_SENSOR:
cJSON_AddStringToObject(info->root, "dev_cla", "humidity");
cJSON_AddStringToObject(info->root, "unit_of_meas", "%");
sprintf(g_hassBuffer, "~/%d/get", channel);
cJSON_AddStringToObject(info->root, STATE_TOPIC_KEY, g_hassBuffer);
break;
case BATTERY_SENSOR:
cJSON_AddStringToObject(info->root, "dev_cla", "battery");
cJSON_AddStringToObject(info->root, "unit_of_meas", "%");
cJSON_AddStringToObject(info->root, STATE_TOPIC_KEY, "~/battery/get");
break;
case BATTERY_VOLTAGE_SENSOR:
cJSON_AddStringToObject(info->root, "dev_cla", "voltage");
cJSON_AddStringToObject(info->root, "unit_of_meas", "mV");
cJSON_AddStringToObject(info->root, STATE_TOPIC_KEY, "~/voltage/get");
break;

default:
sprintf(g_hassBuffer, "~/%d/get", channel);
cJSON_AddStringToObject(info->root, STATE_TOPIC_KEY, g_hassBuffer);
return NULL;
}

sprintf(g_hassBuffer, "~/%d/get", channel);
cJSON_AddStringToObject(info->root, STATE_TOPIC_KEY, g_hassBuffer);

cJSON_AddStringToObject(info->root, "stat_cla", "measurement");
return info;
}
Expand Down
8 changes: 7 additions & 1 deletion src/httpserver/hass.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ typedef enum {
/// @brief Temperature sensor
TEMPERATURE_SENSOR,
/// @brief Humidity sensor
HUMIDITY_SENSOR
HUMIDITY_SENSOR,

/// @brief Battery level sensor in perc
BATTERY_SENSOR,
/// @brief Battery votage sensor in mV
BATTERY_VOLTAGE_SENSOR

} ENTITY_TYPE;

//unique_id is defined in hass_populate_unique_id and is based on CFG_GetDeviceName() whose size is CGF_DEVICE_NAME_SIZE.
Expand Down
61 changes: 39 additions & 22 deletions src/httpserver/http_fns.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@
static char SUBMIT_AND_END_FORM[] = "<br><input type=\"submit\" value=\"Submit\"></form>";

#ifdef WINDOWS
// nothing
// nothing
#elif PLATFORM_BL602

#elif PLATFORM_W600 || PLATFORM_W800

#elif PLATFORM_XR809
#include <image/flash.h>
#elif defined(PLATFORM_BK7231N)
// tuya-iotos-embeded-sdk-wifi-ble-bk7231n/sdk/include/tuya_hal_storage.h
// tuya-iotos-embeded-sdk-wifi-ble-bk7231n/sdk/include/tuya_hal_storage.h
#include "tuya_hal_storage.h"
#include "BkDriverFlash.h"
#else
// REALLY? A typo in Tuya SDK? Storge?
// tuya-iotos-embeded-sdk-wifi-ble-bk7231t/platforms/bk7231t/tuya_os_adapter/include/driver/tuya_hal_storge.h
// REALLY? A typo in Tuya SDK? Storge?
// tuya-iotos-embeded-sdk-wifi-ble-bk7231t/platforms/bk7231t/tuya_os_adapter/include/driver/tuya_hal_storge.h
#include "tuya_hal_storge.h"
#include "BkDriverFlash.h"
#endif
Expand Down Expand Up @@ -134,10 +134,10 @@ void postFormAction(http_request_t* request, char* action, char* value) {
hprintf255(request, "<form action=\"%s\"><input type=\"submit\" value=\"%s\"/></form>", action, value);
}

void poststr_h2(http_request_t* request, const char *content) {
void poststr_h2(http_request_t* request, const char* content) {
hprintf255(request, "<h2>%s</h2>", content);
}
void poststr_h4(http_request_t* request, const char *content) {
void poststr_h4(http_request_t* request, const char* content) {
hprintf255(request, "<h4>%s</h4>", content);
}

Expand Down Expand Up @@ -374,7 +374,7 @@ int http_fn_index(http_request_t* request) {
// DHT pin has two channels - temperature and humidity
poststr(request, "<tr><td>");
iValue = CHANNEL_Get(PIN_GetPinChannelForPinIndex(i));
hprintf255(request, "Sensor %s on pin %i temperature %.2fC", PIN_RoleToString(role), i, (float)(iValue*0.1f));
hprintf255(request, "Sensor %s on pin %i temperature %.2fC", PIN_RoleToString(role), i, (float)(iValue * 0.1f));
iValue = CHANNEL_Get(PIN_GetPinChannel2ForPinIndex(i));
hprintf255(request, ", humidity %.1f%%<br>", (float)iValue);
poststr(request, "</td></tr>");
Expand Down Expand Up @@ -855,12 +855,13 @@ int http_fn_index(http_request_t* request) {
hprintf255(request, "<h5>MQTT State: not configured<br>");
}
else {
const char *stateStr;
const char *colorStr;
const char* stateStr;
const char* colorStr;
if (mqtt_reconnect > 0) {
stateStr = "awaiting reconnect";
colorStr = "orange";
} else if (Main_HasMQTTConnected() == 1) {
}
else if (Main_HasMQTTConnected() == 1) {
stateStr = "connected";
colorStr = "green";
}
Expand All @@ -869,7 +870,7 @@ int http_fn_index(http_request_t* request) {
colorStr = "yellow";
}
hprintf255(request, "<h5>MQTT State: <span style=\"color:%s\">%s</span> RES: %d(%s)<br>", colorStr,
stateStr,MQTT_GetConnectResult(), get_error_name(MQTT_GetConnectResult()));
stateStr, MQTT_GetConnectResult(), get_error_name(MQTT_GetConnectResult()));
hprintf255(request, "MQTT ErrMsg: %s <br>", (MQTT_GetStatusMessage() != NULL) ? MQTT_GetStatusMessage() : "");
hprintf255(request, "MQTT Stats:CONN: %d PUB: %d RECV: %d ERR: %d </h5>", MQTT_GetConnectEvents(),
MQTT_GetPublishEventCounter(), MQTT_GetReceivedEventCounter(), MQTT_GetPublishErrorCounter());
Expand Down Expand Up @@ -1424,7 +1425,7 @@ int http_fn_flash_read_tool(http_request_t* request) {
poststr(request, NULL);
return 0;
}
const char *CMD_GetResultString(commandResult_t r) {
const char* CMD_GetResultString(commandResult_t r) {
if (r == CMD_RES_OK)
return "OK";
if (r == CMD_RES_EMPTY_STRING)
Expand All @@ -1444,9 +1445,9 @@ void LOG_SetCommandHTTPRedirectReply(http_request_t* request);

int http_fn_cmd_tool(http_request_t* request) {
commandResult_t res;
const char *resStr;
const char* resStr;
char tmpA[128];
char *long_str_alloced = 0;
char* long_str_alloced = 0;
int commandLen;

http_setup(request, httpMimeTypeHTML);
Expand Down Expand Up @@ -1608,14 +1609,15 @@ int http_fn_cfg_quick(http_request_t* request) {
return 0;
}

void doHomeAssistantDiscovery(const char *topic, http_request_t *request) {
void doHomeAssistantDiscovery(const char* topic, http_request_t* request) {
int i;
int relayCount;
int pwmCount;
int dInputCount;
bool ledDriverChipRunning;
HassDeviceInfo* dev_info = NULL;
bool measuringPower = false;
bool measuringBattery = false;
struct cJSON_Hooks hooks;
bool discoveryQueued = false;

Expand All @@ -1626,6 +1628,9 @@ void doHomeAssistantDiscovery(const char *topic, http_request_t *request) {
#ifndef OBK_DISABLE_ALL_DRIVERS
measuringPower = DRV_IsMeasuringPower();
#endif
#if defined(PLATFORM_BEKEN) || defined(WINDOWS)
measuringBattery = DRV_IsRunning("Battery");
#endif

get_Relay_PWM_Count(&relayCount, &pwmCount, &dInputCount);

Expand Down Expand Up @@ -1710,6 +1715,18 @@ void doHomeAssistantDiscovery(const char *topic, http_request_t *request) {
}
#endif

if (measuringBattery == true) {
dev_info = hass_init_sensor_device_info(BATTERY_SENSOR, 0);
MQTT_QueuePublish(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN);
hass_free_device_info(dev_info);

dev_info = hass_init_sensor_device_info(BATTERY_VOLTAGE_SENSOR, 0);
MQTT_QueuePublish(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN);
hass_free_device_info(dev_info);

discoveryQueued = true;
}

for (i = 0; i < PLATFORM_GPIO_MAX; i++) {
if (IS_PIN_DHT_ROLE(g_cfg.pins.roles[i]) || IS_PIN_TEMP_HUM_SENSOR_ROLE(g_cfg.pins.roles[i])) {
dev_info = hass_init_sensor_device_info(TEMPERATURE_SENSOR, PIN_GetPinChannelForPinIndex(i));
Expand All @@ -1728,7 +1745,7 @@ void doHomeAssistantDiscovery(const char *topic, http_request_t *request) {
MQTT_InvokeCommandAtEnd(PublishChannels);
}
else {
const char *msg = "No relay, PWM, sensor or power driver running.";
const char* msg = "No relay, PWM, sensor or power driver running.";
if (request) {
poststr(request, msg);
poststr(request, NULL);
Expand Down Expand Up @@ -1787,7 +1804,7 @@ void http_generate_cw_cfg(http_request_t* request, const char* clientId) {
http_generate_singleColor_cfg(request, clientId);
}

void hprintf_qos_payload(http_request_t* request, const char *clientId){
void hprintf_qos_payload(http_request_t* request, const char* clientId) {
poststr(request, " qos: 1\n");
poststr(request, " payload_on: 1\n");
poststr(request, " payload_off: 0\n");
Expand Down Expand Up @@ -1968,7 +1985,7 @@ int http_fn_ha_cfg(http_request_t* request) {
return 0;
}

const char *skipToNextWord(const char *p) {
const char* skipToNextWord(const char* p) {
while (isWhiteSpace(*p) == false) {
if (*p == 0)
return p;
Expand All @@ -1984,7 +2001,7 @@ const char *skipToNextWord(const char *p) {

int http_fn_cm(http_request_t* request) {
char tmpA[128];
char *long_str_alloced = 0;
char* long_str_alloced = 0;
int commandLen;

http_setup(request, httpMimeTypeJson);
Expand Down Expand Up @@ -2189,7 +2206,7 @@ int http_fn_cfg_pins(http_request_t* request) {
}
// Secondary linked channel
// For button, is relay index to toggle on double click
if (si == IOR_Button || si == IOR_Button_n || IS_PIN_DHT_ROLE(si) || IS_PIN_TEMP_HUM_SENSOR_ROLE(si) )
if (si == IOR_Button || si == IOR_Button_n || IS_PIN_DHT_ROLE(si) || IS_PIN_TEMP_HUM_SENSOR_ROLE(si))
{
hprintf255(request, "<input class=\"hele\" name=\"e%i\" type=\"text\" value=\"%i\"/>", i, ch2);
}
Expand Down Expand Up @@ -2244,7 +2261,7 @@ const char* g_obk_flagNames[] = {
"[LED] Use old linear brightness mode, ignore gamma ramp",
"[MQTT] Apply channel type multiplier on (if any) on channel value before publishing it",
"[MQTT] In HA discovery, add relays as lights",
"error",
"[HASS] Deactivate avty_t flag for sensor when publishing to HASS (permit to keep value)",
"error",
"error",
"error",
Expand Down Expand Up @@ -2474,7 +2491,7 @@ int http_fn_cfg_dgr(http_request_t* request) {

void XR809_RequestOTAHTTP(const char* s);

void OTA_RequestDownloadFromHTTP(const char *s) {
void OTA_RequestDownloadFromHTTP(const char* s) {
#if WINDOWS

#elif PLATFORM_BL602
Expand Down
Loading

0 comments on commit 993cd60

Please sign in to comment.