This commit is contained in:
openshwprojects
2023-02-22 15:19:25 +01:00
5 changed files with 119 additions and 60 deletions

View File

@ -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/
@ -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;
}
}
@ -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);
@ -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
@ -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;
}

View File

@ -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.

View File

@ -22,7 +22,7 @@
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
@ -30,12 +30,12 @@ static char SUBMIT_AND_END_FORM[] = "<br><input type=\"submit\" value=\"Submit\"
#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
@ -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);
}
@ -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>");
@ -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";
}
@ -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());
@ -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)
@ -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);
@ -1608,7 +1609,7 @@ 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;
@ -1616,6 +1617,7 @@ void doHomeAssistantDiscovery(const char *topic, http_request_t *request) {
bool ledDriverChipRunning;
HassDeviceInfo* dev_info = NULL;
bool measuringPower = false;
bool measuringBattery = false;
struct cJSON_Hooks hooks;
bool discoveryQueued = false;
@ -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);
@ -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));
@ -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);
@ -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");
@ -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;
@ -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);
@ -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);
}
@ -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",
@ -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