public-espnow2mqtt/002-espnow2mqtt_receiver/src/mqtt_publish_gw_data.h
Zygfryd Homonto 023e7a8339 initial gitea
2024-05-18 14:07:37 +01:00

1286 lines
45 KiB
C

#pragma once
/*
mqtt functions for gateway
*/
// this device (gateway) definition to be able to create devices in HA
#define CREATE_GW_MQTT_DEVICE \
dev = config.createNestedObject("device"); \
dev["ids"]=MQTT_DEVICE_IDENTIFIER; \
dev["name"]=String(ROLE_NAME) + " (" + String(DEVICE_ID) + ")"; \
dev["mdl"] =String(DEV_MODEL); \
dev["mf"]="ZH"; \
dev["sw"]= String(ZH_PROG_VERSION)+ "," + String(__DATE__) + " " + String(__TIME__);
// gateway status config - sent by heartbeat() periodically to HA
bool mqtt_publish_gw_status_config()
{
if (!mqtt_connected) return false; // no mqtt - leaving
if (mqtt_publish_gw_status_config_sent) return true; // config published already - no need to repeat, if deleted from HA restart GW
bool publish_status = false; //changes locally in each config publish
bool total_publish_status = true; //changes globally in each config publish when any fails
// mac
char mac_conf_topic[80];
snprintf(mac_conf_topic,sizeof(mac_conf_topic),"homeassistant/sensor/%s/mac/config",HOSTNAME);
if (debug_mode) Serial.println("mac_conf_topic="+String(mac_conf_topic));
char mac_name[30];
snprintf(mac_name,sizeof(mac_name),"%s_mac",HOSTNAME);
if (debug_mode) Serial.println("mac_name="+String(mac_name));
// ip
char ip_conf_topic[80];
snprintf(ip_conf_topic,sizeof(ip_conf_topic),"homeassistant/sensor/%s/ip/config",HOSTNAME);
if (debug_mode) Serial.println("ip_conf_topic="+String(ip_conf_topic));
char ip_name[30];
snprintf(ip_name,sizeof(ip_name),"%s_ip",HOSTNAME);
if (debug_mode) Serial.println("ip_name="+String(ip_name));
// status
char status_conf_topic[80];
snprintf(status_conf_topic,sizeof(status_conf_topic),"homeassistant/sensor/%s/status/config",HOSTNAME);
if (debug_mode) Serial.println("status_conf_topic="+String(status_conf_topic));
char status_name[30];
snprintf(status_name,sizeof(status_name),"%s_mystatus",HOSTNAME);
if (debug_mode) Serial.println("status_name="+String(status_name));
// uptime
char uptime_conf_topic[80];
snprintf(uptime_conf_topic,sizeof(uptime_conf_topic),"homeassistant/sensor/%s/uptime/config",HOSTNAME);
if (debug_mode) Serial.println("uptime_conf_topic="+String(uptime_conf_topic));
char uptime_name[30];
snprintf(uptime_name,sizeof(uptime_name),"%s_uptime",HOSTNAME);
if (debug_mode) Serial.println("uptime_name="+String(uptime_name));
// version
char version_conf_topic[80];
snprintf(version_conf_topic,sizeof(version_conf_topic),"homeassistant/sensor/%s/version/config",HOSTNAME);
if (debug_mode) Serial.println("version_conf_topic="+String(version_conf_topic));
char version_name[30];
snprintf(version_name,sizeof(version_name),"%s_version",HOSTNAME);
if (debug_mode) Serial.println("version_name="+String(version_name));
// rssi of gateway<->AP
char rssi_conf_topic[80];
snprintf(rssi_conf_topic,sizeof(rssi_conf_topic),"homeassistant/sensor/%s/rssi/config",HOSTNAME);
if (debug_mode) Serial.println("rssi_conf_topic="+String(rssi_conf_topic));
char rssi_name[30];
snprintf(rssi_name,sizeof(rssi_name),"%s_rssi",HOSTNAME);
if (debug_mode) Serial.println("rssi_name="+String(rssi_name));
// common topic
char status_state_topic[80];
snprintf(status_state_topic,sizeof(status_state_topic),"%s/%s/sensor/state",MQTT_TOP_LEVEL_TOPIC,HOSTNAME);
if (debug_mode) Serial.println("status_state_topic="+String(status_state_topic));
StaticJsonDocument<JSON_CONFIG_SIZE> config;
JsonObject dev;
int size_c;
char config_json[JSON_CONFIG_SIZE];
// gw mac config
config.clear();
config["name"] = "mac";
config["stat_t"] = status_state_topic;
config["val_tpl"] = "{{value_json.mac}}";
config["uniq_id"] = mac_name;
config["obj_id"] = mac_name;
config["frc_upd"] = "true";
config["entity_category"] = "diagnostic";
// config["exp_aft"] = HEARTBEAT_INTERVAL_S * 3;
CREATE_GW_MQTT_DEVICE
size_c = serializeJson(config, config_json);
if (!mqttc.publish(mac_conf_topic,(uint8_t*)config_json,strlen(config_json), true))
{
publish_status = false; total_publish_status = false;
Serial.printf("[%s]: PUBLISH FAILED for %s\n",__func__,mac_conf_topic);
} else
{
publish_status = true;
if (debug_mode) {Serial.printf("[%s]: PUBLISH SUCCESSFULL for %s\n",__func__,mac_conf_topic);}
}
if (debug_mode) {
Serial.println("\n============ DEBUG CONFIG MAC ============");
Serial.println("Size of mac config="+String(size_c)+" bytes");
Serial.println("Serialised config_json:");
Serial.println(config_json);
Serial.println("serializeJsonPretty");
serializeJsonPretty(config, Serial);
if (publish_status) {
Serial.println("\n MAC CONFIG OK");
} else
{
Serial.println("\n PRETTYONTIME CONFIG UNSUCCESSFULL");
}
Serial.println("============ DEBUG CONFIG MAC END ========\n");
}
// gw ip config
config.clear();
config["name"] = "ip";
config["stat_t"] = status_state_topic;
config["val_tpl"] = "{{value_json.ip}}";
config["uniq_id"] = ip_name;
config["obj_id"] = ip_name;
config["frc_upd"] = "true";
config["entity_category"] = "diagnostic";
// config["exp_aft"] = HEARTBEAT_INTERVAL_S * 3;
CREATE_GW_MQTT_DEVICE
size_c = serializeJson(config, config_json);
if (!mqttc.publish(ip_conf_topic,(uint8_t*)config_json,strlen(config_json), true))
{
publish_status = false; total_publish_status = false;
Serial.printf("[%s]: PUBLISH FAILED for %s\n",__func__,ip_conf_topic);
} else
{
publish_status = true;
if (debug_mode) {Serial.printf("[%s]: PUBLISH SUCCESSFULL for %s\n",__func__,ip_conf_topic);}
}
if (debug_mode) {
Serial.println("\n============ DEBUG CONFIG IP ============");
Serial.println("Size of ip config="+String(size_c)+" bytes");
Serial.println("Serialised config_json:");
Serial.println(config_json);
Serial.println("serializeJsonPretty");
serializeJsonPretty(config, Serial);
if (publish_status) {
Serial.println("\n IP CONFIG OK");
} else
{
Serial.println("\n PRETTYONTIME CONFIG UNSUCCESSFULL");
}
Serial.println("============ DEBUG CONFIG IP END ========\n");
}
// status config
config.clear();
config["name"] = "my_status";
config["stat_t"] = status_state_topic;
config["qos"] = 2;
config["uniq_id"] = status_name;
config["obj_id"] = status_name;
config["val_tpl"] = "{{value_json.status}}";
config["frc_upd"] = "true";
config["entity_category"] = "diagnostic";
// config["exp_aft"] = HEARTBEAT_INTERVAL_S * 3;
CREATE_GW_MQTT_DEVICE
size_c = serializeJson(config, config_json);
if (!mqttc.publish(status_conf_topic,(uint8_t*)config_json,strlen(config_json), true))
{
publish_status = false; total_publish_status = false;
Serial.printf("[%s]: PUBLISH FAILED for %s\n",__func__,status_conf_topic);
} else
{
publish_status = true;
if (debug_mode) {Serial.printf("[%s]: PUBLISH SUCCESSFULL for %s\n",__func__,status_conf_topic);}
}
if (debug_mode) {
Serial.println("\n============ DEBUG [STATUS] CONFIG: ============");
Serial.println("Size of config_json="+String(size_c)+" bytes");
Serial.println("Serialised config_json:");
Serial.println(config_json);
Serial.println("serializeJsonPretty(config, Serial)");
serializeJsonPretty(config, Serial);
if (publish_status) {
Serial.println("\n CONFIG published OK");
} else
{
Serial.println("\n CONFIG UNSUCCESSFULL");
}
Serial.println("============ DEBUG [STATUS] CONFIG END ========\n");
}
// uptime config
config.clear();
config["name"] = "uptime";
config["stat_t"] = status_state_topic;
config["qos"] = 2;
config["retain"] = "true";
config["uniq_id"] = uptime_name;
config["obj_id"] = uptime_name;
config["val_tpl"] = "{{value_json.uptime}}";
config["frc_upd"] = "true";
config["entity_category"] = "diagnostic";
// config["exp_aft"] = HEARTBEAT_INTERVAL_S * 3;
CREATE_GW_MQTT_DEVICE
size_c = serializeJson(config, config_json);
if (!mqttc.publish(uptime_conf_topic,(uint8_t*)config_json,strlen(config_json), true))
{
publish_status = false; total_publish_status = false;
Serial.printf("[%s]: PUBLISH FAILED for %s\n",__func__,uptime_conf_topic);
} else
{
publish_status = true;
if (debug_mode) {Serial.printf("[%s]: PUBLISH SUCCESSFULL for %s\n",__func__,uptime_conf_topic);}
}
if (debug_mode) {
Serial.println("\n============ DEBUG [UPTIME] CONFIG: ============");
Serial.println("Size of config_json="+String(size_c)+" bytes");
Serial.println("Serialised config_json:");
Serial.println(config_json);
Serial.println("serializeJsonPretty(config, Serial)");
serializeJsonPretty(config, Serial);
if (publish_status) {
Serial.println("\n CONFIG published OK");
} else
{
Serial.println("\n CONFIG UNSUCCESSFULL");
}
Serial.println("============ DEBUG [UPTIME] CONFIG END ========\n");
}
// version config
config.clear();
config["name"] = "version";
config["stat_t"] = status_state_topic;
config["qos"] = 2;
config["retain"] = "true";
config["uniq_id"] = version_name;
config["obj_id"] = version_name;
config["val_tpl"] = "{{value_json.version}}";
config["frc_upd"] = "true";
config["entity_category"] = "diagnostic";
// config["exp_aft"] = HEARTBEAT_INTERVAL_S * 3;
CREATE_GW_MQTT_DEVICE
size_c = serializeJson(config, config_json);
if (!mqttc.publish(version_conf_topic,(uint8_t*)config_json,strlen(config_json), true))
{
publish_status = false; total_publish_status = false;
Serial.printf("[%s]: PUBLISH FAILED for %s\n",__func__,version_conf_topic);
} else
{
publish_status = true;
if (debug_mode) {Serial.printf("[%s]: PUBLISH SUCCESSFULL for %s\n",__func__,version_conf_topic);}
}
if (debug_mode) {
Serial.println("\n============ DEBUG [ZH_PROG_VERSION] CONFIG: ============");
Serial.println("Size of config_json="+String(size_c)+" bytes");
Serial.println("Serialised config_json:");
Serial.println(config_json);
Serial.println("serializeJsonPretty(config, Serial)");
serializeJsonPretty(config, Serial);
if (publish_status) {
Serial.println("\n CONFIG published OK");
} else
{
Serial.println("\n CONFIG UNSUCCESSFULL");
}
Serial.println("============ DEBUG [ZH_PROG_VERSION] CONFIG END ========\n");
}
// rssi config
config.clear();
config["name"] = "rssi";
config["dev_cla"] = "signal_strength";
config["stat_cla"] = "measurement";
config["stat_t"] = status_state_topic;
config["unit_of_meas"] = "dBm";
config["val_tpl"] = "{{value_json.rssi}}";
config["uniq_id"] = rssi_name;
config["obj_id"] = rssi_name;
config["frc_upd"] = "true";
config["entity_category"] = "diagnostic";
// config["exp_aft"] = HEARTBEAT_INTERVAL_S * 3;
CREATE_GW_MQTT_DEVICE
size_c = serializeJson(config, config_json);
if (!mqttc.publish(rssi_conf_topic,(uint8_t*)config_json,strlen(config_json), true))
{
publish_status = false; total_publish_status = false;
Serial.printf("[%s]: PUBLISH FAILED for %s\n",__func__,rssi_conf_topic);
} else
{
publish_status = true;
if (debug_mode) {Serial.printf("[%s]: PUBLISH SUCCESSFULL for %s\n",__func__,rssi_conf_topic);}
}
if (debug_mode) {
Serial.println("\n============ DEBUG [RSSI] CONFIG ============");
Serial.println("Size of config="+String(size_c)+" bytes");
Serial.println("Serialised config_json:");
Serial.println(config_json);
Serial.println("serializeJsonPretty");
serializeJsonPretty(config, Serial);
if (publish_status) {
Serial.println("\n CONFIG published OK");
} else
{
Serial.println("\n CONFIG UNSUCCESSFULL");
}
Serial.println("============ DEBUG [RSSI] CONFIG END ========\n");
}
mqtt_publish_gw_status_config_sent = total_publish_status;
return total_publish_status;
}
// gateway status value
bool mqtt_publish_gw_status_values(const char* status)
{
// debug_mode = true;
if (!mqtt_connected) return false;
bool publish_status = false;
char status_state_topic[80];
snprintf(status_state_topic,sizeof(status_state_topic),"%s/%s/sensor/state",MQTT_TOP_LEVEL_TOPIC,HOSTNAME);
if (debug_mode) Serial.println("status_state_topic="+String(status_state_topic));
// decoupled inside publish_config()
if (!mqtt_publish_gw_status_config()){
Serial.println("\n GW STATUS CONFIG NOT published");
return false;
}
StaticJsonDocument<JSON_PAYLOAD_SIZE> payload;
payload["status"] = status;
payload["rssi"] = WiFi.RSSI();
payload["mac"] = WiFi.macAddress();
IPAddress ip = WiFi.localIP();
char ip_char[30];
snprintf(ip_char,sizeof(ip_char),"%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
payload["ip"] = ip_char;
// Serial.print("IP=");Serial.println(WiFi.localIP());
// Serial.print("ip_char=");Serial.println(ip_char);
char ret_clk[60];
uptime(ret_clk);
payload["uptime"] = ret_clk;
payload["version"] = ZH_PROG_VERSION;
char payload_json[JSON_PAYLOAD_SIZE];
int size_pl = serializeJson(payload, payload_json);
#if (RETAIN_GATEWAY_DATA == 1)
if (!mqttc.publish(status_state_topic,(uint8_t*)payload_json,strlen(payload_json), true))
#else
if (!mqttc.publish(status_state_topic,(uint8_t*)payload_json,strlen(payload_json), false))
#endif
{
publish_status = false;
Serial.printf("[%s]: PUBLISH FAILED for %s\n",__func__,status_state_topic);
} else
{
publish_status = true;
if (debug_mode) {Serial.printf("[%s]: PUBLISH SUCCESSFULL for %s\n",__func__,status_state_topic);}
}
if (debug_mode) {
Serial.println("\n============ DEBUG [STATUS] PAYLOAD ============");
Serial.println("Size of payload="+String(size_pl)+" bytes");
Serial.println("Serialised payload_json:");
Serial.println(payload_json);
Serial.println("serializeJsonPretty");
serializeJsonPretty(payload, Serial);
if (publish_status) {
Serial.println("\n STATUS VALUES published OK");
} else
{
Serial.println("\n STATUS VALUES NOT published");
}
Serial.println("============ DEBUG [STATUS] PAYLOAD END ========\n");
}
#if (USE_WEB_SERIAL == 1)
if (print2web) WebSerial.println(payload_json);
#endif
return publish_status;
}
// stop/start updating HA with sensors data - switch on HA
bool mqtt_publish_switch_publish_config()
{
if (!mqtt_connected) return false; // no mqtt - leaving
if (mqtt_publish_switch_publish_config_sent) return true; // config published already - no need to repeat, if deleted from HA restart GW
bool publish_status = false; //changes locally in each config publish
bool total_publish_status = true; //changes globally in each config publish when any fails
char publish_conf_topic[80];
snprintf(publish_conf_topic,sizeof(publish_conf_topic),"homeassistant/switch/%s/publish/config",HOSTNAME);
if (debug_mode) Serial.println("publish_conf_topic="+String(publish_conf_topic));
char publish_name[30];
snprintf(publish_name,sizeof(publish_name),"%s_publish",HOSTNAME);
if (debug_mode) Serial.println("publish_name="+String(publish_name));
char publish_state_topic[80];
snprintf(publish_state_topic,sizeof(publish_state_topic),"%s/%s/switch/publish",MQTT_TOP_LEVEL_TOPIC,HOSTNAME);
if (debug_mode) Serial.println("publish_state_topic="+String(publish_state_topic));
char publish_cmd_topic[80];
snprintf(publish_cmd_topic,sizeof(publish_cmd_topic),"%s/%s/cmd/publish",MQTT_TOP_LEVEL_TOPIC,HOSTNAME);
if (debug_mode) Serial.println("restart_cmd_topic="+String(publish_cmd_topic));
StaticJsonDocument<JSON_CONFIG_SIZE> config;
JsonObject dev;
int size_c;
char config_json[JSON_CONFIG_SIZE];
/*
MQTT sensor or binary_sensor configuration with an entity_category explicitly
set to config will fail to set up. Maintainers should set the entity_category
ttribute to diagnostic or omit the config attribute.
*/
// publish config
config.clear();
config["name"] = "publish";
config["stat_t"] = publish_state_topic;
config["command_topic"] = publish_cmd_topic;
config["payload_on"] = "ON";
config["payload_off"] = "OFF";
// config["optimistic"] = "true";
config["qos"] = "2";
config["retain"] = "true";
config["device_class"] = "switch";
config["uniq_id"] = publish_name;
config["obj_id"] = publish_name;
config["entity_category"] = "config";
config["val_tpl"] = "{{value_json.publish}}";
// config["exp_aft"] = HEARTBEAT_INTERVAL_S * 3;
CREATE_GW_MQTT_DEVICE
size_c = serializeJson(config, config_json);
if (!mqttc.publish(publish_conf_topic,(uint8_t*)config_json,strlen(config_json), true))
{
publish_status = false; total_publish_status = false;
Serial.printf("[%s]: PUBLISH FAILED for %s\n",__func__,publish_conf_topic);
} else
{
publish_status = true;
if (debug_mode) {Serial.printf("[%s]: PUBLISH SUCCESSFULL for %s\n",__func__,publish_conf_topic);}
}
if (debug_mode) {
Serial.println("\n============ DEBUG [PUBLISH SWITCH] CONFIG ============");
Serial.println("Size of config_json="+String(size_c)+" bytes");
Serial.println("Serialised config_json:");
Serial.println(config_json);
Serial.println("serializeJsonPretty(config, Serial)");
serializeJsonPretty(config, Serial);
if (publish_status) {
Serial.println("\n CONFIG published OK");
} else
{
Serial.println("\n CONFIG UNSUCCESSFULL");
}
Serial.println("============ DEBUG [PUBLISH SWITCH] CONFIG END ========\n");
}
mqtt_publish_switch_publish_config_sent = total_publish_status;
return total_publish_status;
}
bool mqtt_publish_switch_publish_values()
{
if (!mqtt_connected) return false;
bool publish_status = false;
char publish_state_topic[80];
snprintf(publish_state_topic,sizeof(publish_state_topic),"%s/%s/switch/publish",MQTT_TOP_LEVEL_TOPIC,HOSTNAME);
if (debug_mode) Serial.println("publish_state_topic="+String(publish_state_topic));
// managed inside publish_config()
if (!mqtt_publish_switch_publish_config())
{
Serial.printf("[%s]: PUBLISH CONFIG NOT published, leaving\n",__func__);
return false;
}
StaticJsonDocument<JSON_PAYLOAD_SIZE> payload;
if (publish_sensors_to_ha) {payload["publish"] = "ON";} else {payload["publish"] = "OFF";}
char payload_json[JSON_PAYLOAD_SIZE];
int size_pl = serializeJson(payload, payload_json);
#if (RETAIN_GATEWAY_DATA == 1)
if (!mqttc.publish(publish_state_topic,(uint8_t*)payload_json,strlen(payload_json), true))
#else
if (!mqttc.publish(publish_state_topic,(uint8_t*)payload_json,strlen(payload_json), false))
#endif
{
publish_status = false;
Serial.printf("[%s]: PUBLISH FAILED for %s\n",__func__,publish_state_topic);
} else
{
publish_status = true;
if (debug_mode) {Serial.printf("[%s]: PUBLISH SUCCESSFULL for %s\n",__func__,publish_state_topic);}
}
if (debug_mode) {
Serial.println("\n============ DEBUG: [PUBLISH SWITCH] PAYLOAD ============");
Serial.println("Size of payload="+String(size_pl)+" bytes");
Serial.println("Serialised payload_json:");
Serial.println(payload_json);
Serial.println("serializeJsonPretty");
serializeJsonPretty(payload, Serial);
if (publish_status) {
Serial.println("\n publish VALUES published OK");
} else
{
Serial.println("\n publish VALUES NOT published");
}
Serial.println("============ DEBUG: [PUBLISH SWITCH] END ========\n");
}
#if (USE_WEB_SERIAL == 1)
if (print2web) WebSerial.println(payload_json);
#endif
return publish_status;
}
// periodic update of everything from gateway
void heartbeat()
{
unsigned long function_start = millis();
bool publish_status = true;
set_gateway_led_level(1);
char pretty_ontime[17]; // "999d 24h 60m 60s" = 16 characters
ConvertSectoDay(millis()/1000,pretty_ontime);
Serial.printf("[%s]: updating GW status %s after boot...",__func__,pretty_ontime);
if (calibration_in_progress)
{
publish_status = publish_status && mqtt_publish_gw_status_values("calibration");
} else
{
publish_status = publish_status && mqtt_publish_gw_status_values("online");
}
// initial, one time only configs - for universal functions only - for fixed ones it is done in publish_config()
if (!mqtt_publish_button_update_config_sent)
{
bool tmp1 = mqtt_publish_button_config("update");
mqtt_publish_button_update_config_sent = tmp1;
publish_status = publish_status && tmp1;
}
if (!mqtt_publish_button_config_reset_sent)
{
bool tmp1 = mqtt_publish_button_config("reset");
mqtt_publish_button_config_reset_sent = tmp1;
publish_status = publish_status && tmp1;
}
if (!mqtt_publish_button_config_reset_cmd_queue_sent)
{
bool tmp1 = mqtt_publish_button_config("reset_cmd_queue");
mqtt_publish_button_config_reset_cmd_queue_sent = tmp1;
publish_status = publish_status && tmp1;
}
if (!mqtt_publish_light_config_sensors_sent)
{
bool tmp1 = mqtt_publish_light_config("led_sensors",false);
mqtt_publish_light_config_sensors_sent = tmp1;
publish_status = publish_status && tmp1;
}
if (!mqtt_publish_light_config_gateway_sent)
{
bool tmp1 = mqtt_publish_light_config("led_gateway",false);
mqtt_publish_light_config_gateway_sent = tmp1;
publish_status = publish_status && tmp1;
}
if (!mqtt_publish_light_config_standby_sent)
{
bool tmp1 = mqtt_publish_light_config("led_standby",false);
mqtt_publish_light_config_standby_sent = tmp1;
publish_status = publish_status && tmp1;
}
if (!mqtt_publish_text_sensor_value_available_sent)
{
bool tmp1 = mqtt_publish_text_sensor_config("available");
mqtt_publish_text_sensor_value_available_sent = tmp1;
publish_status = publish_status && tmp1;
}
if (!mqtt_publish_switch_publish_config_sent)
{
bool tmp1 = mqtt_publish_switch_publish_config();
mqtt_publish_switch_publish_config_sent = tmp1;
publish_status = publish_status && tmp1;
}
if (!mqtt_publish_text_sensor_value_queue_size_sent)
{
bool tmp1 = mqtt_publish_text_sensor_config("cmd_queue_size");
mqtt_publish_text_sensor_value_queue_size_sent = tmp1;
publish_status = publish_status && tmp1;
}
if (!mqtt_publish_text_sensor_value_last_updated_sensor_sent)
{
bool tmp1 = mqtt_publish_text_sensor_config("last");
mqtt_publish_text_sensor_value_last_updated_sensor_sent = tmp1;
publish_status = publish_status && tmp1;
}
// restart button left with config always so it is possible to restart from HA after deletion
// if (!mqtt_publish_button_restart_config_sent)
// {
bool tmp1 = mqtt_publish_button_config("restart");
mqtt_publish_button_restart_config_sent = tmp1;
publish_status = publish_status && tmp1;
// }
// publish initial value of the switch
publish_status = publish_status && mqtt_publish_switch_publish_values();
// publish periodic available
publish_status = publish_status && mqtt_publish_text_sensor_value("available","online");
if (!mqtt_published_to_ha)
{
if (publish_status)
{
mqtt_published_to_ha = true;
write_badbootcount(0);
}
}
#if (USE_BMP280 == 1)
char pressure_chr[10]; char tempbmp280_chr[10];
measure_temp_pressure(pressure_chr,tempbmp280_chr);
publish_status = publish_status && mqtt_publish_sensor_with_unit_value("airpressure","hPa",pressure_chr);
publish_status = publish_status && mqtt_publish_sensor_with_unit_value("bmp280_temperature","°C",tempbmp280_chr);
#endif
#if (MEASURE_LUX == 1)
char lux[7];
get_lux(lux);
publish_status = publish_status && mqtt_publish_sensor_with_unit_value("lux","lx",lux);
#endif
#if (USE_MHZ19_CO2 == 1)
if (co2_received)
publish_status = publish_status && mqtt_publish_sensor_with_unit_value("co2", "ppm",co2);
#endif
int queue_count = uxQueueMessagesWaiting(queue);
// send queue status
if (!publish_sensors_to_ha)
{
char queue_status[20];
snprintf(queue_status, sizeof(queue_status), "queue: %d/%d",queue_count,MAX_QUEUE_COUNT);
publish_status = publish_status && mqtt_publish_text_sensor_value("last",queue_status);
}
// send warning
if (queue_count == MAX_QUEUE_COUNT)
{
Serial.printf("[%s]: ERROR: queue is full!\n",__func__);
publish_status = publish_status && mqtt_publish_text_sensor_value("last","N/A");
}
if (publish_status)
{
Serial.println("SUCCESSFULL");
} else
{
Serial.println("FAILED");
}
u_int8_t queue_commands_count = uxQueueMessagesWaiting(queue_commands);
char queue_size_char[4];
// check if correction works it as it was counting time from restart ;-)
// reset the queue with commands for senders if timeout expired, count from last command received
if (queue_commands_count > 0)
{
if ((millis() - last_cmd_received) >= (COMMAND_QUEUE_TIMEOUT_S * 1000))
{
xQueueReset( queue_commands );
queue_commands_count = uxQueueMessagesWaiting(queue_commands);
snprintf(queue_size_char,sizeof(queue_size_char),"%d",queue_commands_count);
mqtt_publish_text_sensor_value("cmd_queue_size", queue_size_char);
}
}
snprintf(queue_size_char,sizeof(queue_size_char),"%d",queue_commands_count);
mqtt_publish_text_sensor_value("cmd_queue_size", queue_size_char);
#ifdef DEBUG
Serial.printf("[%s]: Commands for senders in the queue: %d\n",__func__,queue_commands_count);
#endif
// reset the queue with commands for senders if queue is full
if (queue_commands_count >= MAX_QUEUE_COMMANDS_COUNT)
{
publish_status = publish_status && mqtt_publish_gw_status_values("cmd queue FULL");
Serial.print("MAX_QUEUE_COMMANDS_COUNT reached: ");Serial.println(queue_commands_count);
Serial.println("resetting the queue with commands for senders...");
xQueueReset( queue_commands );
queue_commands_count = uxQueueMessagesWaiting(queue_commands);
#ifdef DEBUG
Serial.print("New commands in the queue: ");Serial.println(queue_commands_count);
#endif
publish_status = publish_status && mqtt_publish_gw_status_values("online");
}
// reset the queue with commands for senders if queue is full END
set_gateway_led_level(0);
// Serial.printf(" -> it took %ums\n",(millis()-function_start));
}
// ================== UNIVERSAL FUNCTIONS ========================
// universal button on HA - config
bool mqtt_publish_button_config(const char* button)
{
if (!mqtt_connected) return false;
bool debug_mode = false;
bool publish_status = false; //changes locally in each config publish
bool total_publish_status = true; //changes globally in each config publish when any fails
char button_conf_topic[100];
snprintf(button_conf_topic,sizeof(button_conf_topic),"homeassistant/button/%s/%s/config",HOSTNAME,button);
if (debug_mode) Serial.println("button_conf_topic="+String(button_conf_topic));
char button_name[30];
snprintf(button_name,sizeof(button_name),"%s_%s",HOSTNAME,button);
if (debug_mode) Serial.println("button_name="+String(button_name));
char button_state_topic[80];
snprintf(button_state_topic,sizeof(button_state_topic),"%s/%s/button/%s",MQTT_TOP_LEVEL_TOPIC,HOSTNAME,button);
if (debug_mode) Serial.println("button_state_topic="+String(button_state_topic));
char button_cmd_topic[80];
snprintf(button_cmd_topic,sizeof(button_cmd_topic),"%s/%s/cmd/%s",MQTT_TOP_LEVEL_TOPIC,HOSTNAME,button);
if (debug_mode) Serial.println("button_cmd_topic="+String(button_cmd_topic));
char button_val_tpl[30];
snprintf(button_val_tpl,sizeof(button_val_tpl),"{{value_json.%s}}",button);
if (debug_mode) Serial.println("button_val_tpl="+String(button_val_tpl));
StaticJsonDocument<JSON_CONFIG_SIZE> config;
JsonObject dev;
int size_c;
char config_json[JSON_CONFIG_SIZE];
// button config
config.clear();
config["name"] = button;
config["command_topic"] = button_cmd_topic;
config["payload_press"] = "ON";
config["qos"] = "2";
config["retain"] = "false";
config["uniq_id"] = button_name;
config["obj_id"] = button_name;
config["val_tpl"] = button_val_tpl;
// config["exp_aft"] = HEARTBEAT_INTERVAL_S * 3;
CREATE_GW_MQTT_DEVICE
size_c = serializeJson(config, config_json);
if (!mqttc.publish(button_conf_topic,(uint8_t*)config_json,strlen(config_json), true))
{
publish_status = false; total_publish_status = false;
Serial.printf("[%s]: PUBLISH FAILED for %s\n",__func__,button_conf_topic);
} else
{
publish_status = true;
if (debug_mode) {Serial.printf("[%s]: PUBLISH SUCCESSFULL for %s\n",__func__,button_conf_topic);}
}
if (debug_mode) {
Serial.println("\n============ DEBUG [BUTTON] CONFIG: ============");
Serial.println("Size of config_json="+String(size_c)+" bytes");
Serial.println("Serialised config_json:");
Serial.println(config_json);
Serial.println("serializeJsonPretty(config, Serial)");
serializeJsonPretty(config, Serial);
if (publish_status) {
Serial.println("\n BUTTON CONFIG published OK");
} else
{
Serial.println("\n BUTTON CONFIG UNSUCCESSFULL");
}
Serial.println("============ DEBUG [BUTTON] CONFIG END ========\n");
}
return total_publish_status;
}
// universal standalone text sensor on HA - config
bool mqtt_publish_text_sensor_config(const char* text_sensor)
{
if (!mqtt_connected) return false;
bool debug_mode = false;
bool publish_status = false; //changes locally in each config publish
bool total_publish_status = true; //changes globally in each config publish when any fails
char text_sensor_conf_topic[100];
snprintf(text_sensor_conf_topic,sizeof(text_sensor_conf_topic),"homeassistant/sensor/%s/%s/config",HOSTNAME,text_sensor);
if (debug_mode) Serial.println("text_sensor_conf_topic="+String(text_sensor_conf_topic));
char text_sensor_name[30];
snprintf(text_sensor_name,sizeof(text_sensor_name),"%s_%s",HOSTNAME,text_sensor);
if (debug_mode) Serial.println("text_sensor_name="+String(text_sensor_name));
char text_sensor_state_topic[80];
if (strcmp(text_sensor,"available")== 0)
{
snprintf(text_sensor_state_topic,sizeof(text_sensor_state_topic),"%s/%s/%s",MQTT_TOP_LEVEL_TOPIC,HOSTNAME,text_sensor);
} else
{
snprintf(text_sensor_state_topic,sizeof(text_sensor_state_topic),"%s/%s/sensor/%s",MQTT_TOP_LEVEL_TOPIC,HOSTNAME,text_sensor);
}
// snprintf(text_sensor_state_topic,sizeof(text_sensor_state_topic),"%s/%s/sensor/%s",MQTT_TOP_LEVEL_TOPIC,HOSTNAME,text_sensor);
if (debug_mode) Serial.println("text_sensor_state_topic="+String(text_sensor_state_topic));
char text_sensor_val_tpl[30];
snprintf(text_sensor_val_tpl,sizeof(text_sensor_val_tpl),"{{value_json.%s}}",text_sensor);
if (debug_mode) Serial.println("text_sensor_val_tpl="+String(text_sensor_val_tpl));
StaticJsonDocument<JSON_CONFIG_SIZE> config;
JsonObject dev;
int size_c;
char config_json[JSON_CONFIG_SIZE];
// text_sensor config
config.clear();
config["name"] = text_sensor;
config["qos"] = "2";
config["retain"] = "true";
config["uniq_id"] = text_sensor_name;
config["obj_id"] = text_sensor_name;
config["val_tpl"] = text_sensor_val_tpl;
config["stat_t"] = text_sensor_state_topic;
config["frc_upd"] = "true";
if (strcmp(text_sensor,"available")== 0)
{
config["entity_category"] = "diagnostic";
}
// config["exp_aft"] = HEARTBEAT_INTERVAL_S * 3;
CREATE_GW_MQTT_DEVICE
size_c = serializeJson(config, config_json);
if (!mqttc.publish(text_sensor_conf_topic,(uint8_t*)config_json,strlen(config_json), true))
{
publish_status = false; total_publish_status = false;
Serial.printf("[%s]: PUBLISH FAILED for %s\n",__func__,text_sensor_conf_topic);
} else
{
publish_status = true;
if (debug_mode) {Serial.printf("[%s]: PUBLISH SUCCESSFULL for %s\n",__func__,text_sensor_conf_topic);}
}
if (debug_mode) {
Serial.println("\n============ DEBUG [text_sensor] CONFIG: ============");
Serial.println("Size of config_json="+String(size_c)+" bytes");
Serial.println("Serialised config_json:");
Serial.println(config_json);
Serial.println("serializeJsonPretty(config, Serial)");
serializeJsonPretty(config, Serial);
if (publish_status) {
Serial.println("\n text_sensor CONFIG published OK");
} else
{
Serial.println("\n text_sensor CONFIG UNSUCCESSFULL");
}
Serial.println("============ DEBUG [text_sensor] CONFIG END ========\n");
}
return total_publish_status;
}
// universal standalone text sensor on HA - publish value
bool mqtt_publish_text_sensor_value(const char* text_sensor, const char* text_sensor_value)
{
if (!mqtt_connected) return false;
bool debug_mode = false;
bool publish_status = false;
char text_sensor_state_topic[80];
if (strcmp(text_sensor,"available")== 0)
{
snprintf(text_sensor_state_topic,sizeof(text_sensor_state_topic),"%s/%s/%s",MQTT_TOP_LEVEL_TOPIC,HOSTNAME,text_sensor);
} else
{
snprintf(text_sensor_state_topic,sizeof(text_sensor_state_topic),"%s/%s/sensor/%s",MQTT_TOP_LEVEL_TOPIC,HOSTNAME,text_sensor);
}
// snprintf(text_sensor_state_topic,sizeof(text_sensor_state_topic),"%s/%s/sensor/%s",MQTT_TOP_LEVEL_TOPIC,HOSTNAME,text_sensor);
if (debug_mode) Serial.println("text_sensor_state_topic="+String(text_sensor_state_topic));
// decoupled from here
// if (!mqtt_publish_text_sensor_config(text_sensor))
// {
// Serial.printf("[%s]: PUBLISH CONFIG NOT published, leaving\n",__func__);
// return false;
// }
StaticJsonDocument<JSON_PAYLOAD_SIZE> payload;
payload[text_sensor] = text_sensor_value;
char payload_json[JSON_PAYLOAD_SIZE];
int size_pl = serializeJson(payload, payload_json);
#if (RETAIN_GATEWAY_DATA == 1)
if (!mqttc.publish(text_sensor_state_topic,(uint8_t*)payload_json,strlen(payload_json), true))
#else
if (!mqttc.publish(text_sensor_state_topic,(uint8_t*)payload_json,strlen(payload_json), false))
#endif
{
publish_status = false;
Serial.printf("[%s]: PUBLISH FAILED for %s\n",__func__,text_sensor_state_topic);
} else
{
publish_status = true;
if (debug_mode) {Serial.printf("[%s]: PUBLISH SUCCESSFULL for %s\n",__func__,text_sensor_state_topic);}
}
if (debug_mode) {
Serial.println("\n============ DEBUG [text_sensor_value] PAYLOAD ============");
Serial.println("Size of payload="+String(size_pl)+" bytes");
Serial.println("Serialised payload_json:");
Serial.println(payload_json);
Serial.println("serializeJsonPretty");
serializeJsonPretty(payload, Serial);
if (publish_status) {
Serial.println("\n text_sensor_value VALUES published OK");
} else
{
Serial.println("\n text_sensor_value VALUES NOT published");
}
Serial.println("============ DEBUG [text_sensor_value] PAYLOAD END ========\n");
}
return publish_status;
}
// universal standalone sensor with unit on HA - config
bool mqtt_publish_sensor_with_unit_config(const char* sensor_with_unit, const char* sensor_unit)
{
if (!mqtt_connected) return false;
bool debug_mode = false;
bool publish_status = false; //changes locally in each config publish
bool total_publish_status = true; //changes globally in each config publish when any fails
char sensor_with_unit_conf_topic[150];
snprintf(sensor_with_unit_conf_topic,sizeof(sensor_with_unit_conf_topic),"homeassistant/sensor/%s/%s/config",HOSTNAME,sensor_with_unit);
if (debug_mode) Serial.println("sensor_with_unit_conf_topic="+String(sensor_with_unit_conf_topic));
char sensor_with_unit_name[100];
snprintf(sensor_with_unit_name,sizeof(sensor_with_unit_name),"%s_%s",HOSTNAME,sensor_with_unit);
if (debug_mode) Serial.println("sensor_with_unit_name="+String(sensor_with_unit_name));
char sensor_with_unit_state_topic[100];
snprintf(sensor_with_unit_state_topic,sizeof(sensor_with_unit_state_topic),"%s/%s/sensor/%s",MQTT_TOP_LEVEL_TOPIC,HOSTNAME,sensor_with_unit);
if (debug_mode) Serial.println("sensor_with_unit_state_topic="+String(sensor_with_unit_state_topic));
char sensor_with_unit_val_tpl[100];
snprintf(sensor_with_unit_val_tpl,sizeof(sensor_with_unit_val_tpl),"{{value_json.%s}}",sensor_with_unit);
if (debug_mode) Serial.println("sensor_with_unit_val_tpl="+String(sensor_with_unit_val_tpl));
StaticJsonDocument<JSON_CONFIG_SIZE> config;
JsonObject dev;
int size_c;
char config_json[JSON_CONFIG_SIZE];
// sensor_with_unit config
config.clear();
config["name"] = sensor_with_unit;
config["qos"] = "2";
config["retain"] = "true";
config["uniq_id"] = sensor_with_unit_name;
config["obj_id"] = sensor_with_unit_name;
config["val_tpl"] = sensor_with_unit_val_tpl;
config["stat_t"] = sensor_with_unit_state_topic;
config["frc_upd"] = "true";
config["unit_of_meas"] = sensor_unit;
// config["exp_aft"] = HEARTBEAT_INTERVAL_S * 3;
CREATE_GW_MQTT_DEVICE
size_c = serializeJson(config, config_json);
if (!mqttc.publish(sensor_with_unit_conf_topic,(uint8_t*)config_json,strlen(config_json), true))
{
publish_status = false; total_publish_status = false;
Serial.printf("[%s]: PUBLISH FAILED for %s\n",__func__,sensor_with_unit_conf_topic);
} else
{
publish_status = true;
if (debug_mode) {Serial.printf("[%s]: PUBLISH SUCCESSFULL for %s\n",__func__,sensor_with_unit_conf_topic);}
}
if (debug_mode) {
Serial.println("\n============ DEBUG [sensor_with_unit] CONFIG: ============");
Serial.println("Size of config_json="+String(size_c)+" bytes");
Serial.println("Serialised config_json:");
Serial.println(config_json);
Serial.println("serializeJsonPretty(config, Serial)");
serializeJsonPretty(config, Serial);
if (publish_status) {
Serial.println("\n sensor_with_unit CONFIG published OK");
} else
{
Serial.println("\n sensor_with_unit CONFIG UNSUCCESSFULL");
}
Serial.println("============ DEBUG [sensor_with_unit] CONFIG END ========\n");
}
return total_publish_status;
}
// universal standalone sensor with unit on HA - publish value - value is float - not string!
bool mqtt_publish_sensor_with_unit_value(const char* sensor_with_unit, const char* sensor_unit, const char* sensor_with_unit_value)
{
if (!mqtt_connected) return false;
bool debug_mode = false;
bool publish_status = false;
char sensor_with_unit_state_topic[80];
snprintf(sensor_with_unit_state_topic,sizeof(sensor_with_unit_state_topic),"%s/%s/sensor/%s",MQTT_TOP_LEVEL_TOPIC,HOSTNAME,sensor_with_unit);
if (debug_mode) Serial.println("sensor_with_unit_state_topic="+String(sensor_with_unit_state_topic));
// decoupled from here
// if (!mqtt_publish_sensor_with_unit_config(sensor_with_unit, sensor_unit))
// {
// Serial.printf("[%s]: PUBLISH CONFIG NOT published, leaving\n",__func__);
// return false;
// }
StaticJsonDocument<JSON_PAYLOAD_SIZE> payload;
payload[sensor_with_unit] = sensor_with_unit_value;
char payload_json[JSON_PAYLOAD_SIZE];
int size_pl = serializeJson(payload, payload_json);
#if (RETAIN_GATEWAY_DATA == 1)
if (!mqttc.publish(sensor_with_unit_state_topic,(uint8_t*)payload_json,strlen(payload_json), true))
#else
if (!mqttc.publish(sensor_with_unit_state_topic,(uint8_t*)payload_json,strlen(payload_json), false))
#endif
{
publish_status = false;
Serial.printf("[%s]: PUBLISH FAILED for %s\n",__func__,sensor_with_unit_state_topic);
} else
{
publish_status = true;
if (debug_mode) {Serial.printf("[%s]: PUBLISH SUCCESSFULL for %s\n",__func__,sensor_with_unit_state_topic);}
}
if (debug_mode) {
Serial.println("\n============ DEBUG [sensor_with_unit_value] PAYLOAD ============");
Serial.println("Size of payload="+String(size_pl)+" bytes");
Serial.println("Serialised payload_json:");
Serial.println(payload_json);
Serial.println("serializeJsonPretty");
serializeJsonPretty(payload, Serial);
if (publish_status) {
Serial.println("\n sensor_with_unit_value VALUES published OK");
} else
{
Serial.println("\n sensor_with_unit_value VALUES NOT published");
}
Serial.println("============ DEBUG [sensor_with_unit_value] PAYLOAD END ========\n");
}
return publish_status;
}
// universal light on HA - config
bool mqtt_publish_light_config(const char* light, bool optimistic)
{
if (!mqtt_connected) return false;
bool debug_mode = false;
bool publish_status = false; //changes locally in each config publish
bool total_publish_status = true; //changes globally in each config publish when any fails
char light_conf_topic[100];
snprintf(light_conf_topic,sizeof(light_conf_topic),"homeassistant/light/%s/%s/config",HOSTNAME,light);
if (debug_mode) Serial.println("light_conf_topic="+String(light_conf_topic));
char light_name[60];
snprintf(light_name,sizeof(light_name),"%s_%s",HOSTNAME,light);
if (debug_mode) Serial.println("light_name="+String(light_name));
char light_state_topic[80];
snprintf(light_state_topic,sizeof(light_state_topic),"%s/%s/light/%s/state",MQTT_TOP_LEVEL_TOPIC,HOSTNAME,light);
if (debug_mode) Serial.println("light_state_topic="+String(light_state_topic));
char light_cmd_topic[80];
snprintf(light_cmd_topic,sizeof(light_cmd_topic),"%s/%s/light/%s/cmd/switch",MQTT_TOP_LEVEL_TOPIC,HOSTNAME,light);
if (debug_mode) Serial.println("light_cmd_topic="+String(light_cmd_topic));
char light_val_tpl[60];
snprintf(light_val_tpl,sizeof(light_val_tpl),"{{value_json.light}}");
if (debug_mode) Serial.println("light_val_tpl="+String(light_val_tpl));
char brightness_cmd_topic[80];
snprintf(brightness_cmd_topic,sizeof(brightness_cmd_topic),"%s/%s/light/%s/cmd/brightness",MQTT_TOP_LEVEL_TOPIC,HOSTNAME,light);
if (debug_mode) Serial.println("brightness_cmd_topic="+String(brightness_cmd_topic));
char brightness_val_tpl[60];
snprintf(brightness_val_tpl,sizeof(brightness_val_tpl),"{{value_json.brightness}}");
if (debug_mode) Serial.println("brightness_val_tpl="+String(brightness_val_tpl));
StaticJsonDocument<JSON_CONFIG_SIZE> config;
JsonObject dev;
int size_c;
char config_json[JSON_CONFIG_SIZE];
config.clear();
config["name"]=light;
config["dev_cla"] = "light";
config["state_topic"]=light_state_topic;
config["command_topic"]=light_cmd_topic;
config["state_value_template"]="{{value_json.state}}";
config["brightness_state_topic"]=light_state_topic;
config["brightness_command_topic"]=brightness_cmd_topic;
config["brightness_value_template"]="{{value_json.brightness}}";
config["payload_on"] = "ON";
config["payload_off"] = "OFF";
if (optimistic)
config["optimistic"] = "true";
else
config["optimistic"] = "false";;
config["qos"] = "2";
config["retain"] = "true";
config["uniq_id"]=light_name;
config["obj_id"]=light_name;
config["frc_upd"] = "true";
// config["exp_aft"] = HEARTBEAT_INTERVAL_S * 3;
CREATE_GW_MQTT_DEVICE
size_c = serializeJson(config, config_json);
if (!mqttc.publish(light_conf_topic,(uint8_t*)config_json,strlen(config_json), true))
{
publish_status = false; total_publish_status = false;
Serial.printf("[%s]: PUBLISH FAILED for %s\n",__func__,light_conf_topic);
} else
{
publish_status = true;
if (debug_mode) {Serial.printf("[%s]: PUBLISH SUCCESSFULL for %s\n",__func__,light_conf_topic);}
}
if (debug_mode) {
Serial.println("\n============ DEBUG [light] CONFIG: ============");
Serial.println("Size of config_json="+String(size_c)+" bytes");
Serial.println("Serialised config_json:");
Serial.println(config_json);
Serial.println("serializeJsonPretty(config, Serial)");
serializeJsonPretty(config, Serial);
if (publish_status) {
Serial.println("\n light CONFIG published OK");
} else
{
Serial.println("\n light CONFIG UNSUCCESSFULL");
}
Serial.println("============ DEBUG [light] CONFIG END ========\n");
}
return total_publish_status;
}
// universal light on HA - values
bool mqtt_publish_light_values(const char* light, bool power, u_int8_t brightness)
{
if (!mqtt_connected) return false;
bool debug_mode = false;
bool publish_status = false;
char light_state_topic[80];
snprintf(light_state_topic,sizeof(light_state_topic),"%s/%s/light/%s/state",MQTT_TOP_LEVEL_TOPIC,HOSTNAME,light);
if (debug_mode) Serial.println("light_state_topic="+String(light_state_topic));
// decoupled from here to avoid repetitions
// if (!mqtt_publish_light_config(light, false))
// {
// Serial.printf("[%s]: PUBLISH CONFIG NOT published, leaving\n",__func__);
// return false;
// }
StaticJsonDocument<JSON_PAYLOAD_SIZE> payload;
if (power) payload["state"] = "ON"; else payload["state"] = "OFF";
payload["brightness"] = brightness;
char payload_json[JSON_PAYLOAD_SIZE];
int size_pl = serializeJson(payload, payload_json);
#if (RETAIN_GATEWAY_DATA == 1)
if (!mqttc.publish(light_state_topic,(uint8_t*)payload_json,strlen(payload_json), true))
#else
if (!mqttc.publish(light_state_topic,(uint8_t*)payload_json,strlen(payload_json), false))
#endif
{
publish_status = false;
Serial.printf("[%s]: PUBLISH FAILED for %s\n",__func__,light_state_topic);
} else
{
publish_status = true;
if (debug_mode) {Serial.printf("[%s]: PUBLISH SUCCESSFULL for %s\n",__func__,light_state_topic);}
}
if (debug_mode) {
Serial.println("\n============ DEBUG [mqtt_publish_light_values] PAYLOAD ============");
Serial.println("Size of payload="+String(size_pl)+" bytes");
Serial.println("Serialised payload_json:");
Serial.println(payload_json);
Serial.println("serializeJsonPretty");
serializeJsonPretty(payload, Serial);
if (publish_status) {
Serial.println("\n mqtt_publish_light_values VALUES published OK");
} else
{
Serial.println("\n mqtt_publish_light_values VALUES NOT published");
}
Serial.println("============ DEBUG [mqtt_publish_light_values] PAYLOAD END ========\n");
}
return publish_status;
}
// ================== UNIVERSAL FUNCTIONS ======================== END