mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-04 18:29:48 +02:00
MQTT settings in the UI
This commit is contained in:
parent
693689e5af
commit
6cdcb08abb
8 changed files with 140 additions and 27 deletions
|
@ -128,7 +128,9 @@ void setup() {
|
||||||
// Start tasks
|
// Start tasks
|
||||||
|
|
||||||
if (mqtt_enabled) {
|
if (mqtt_enabled) {
|
||||||
init_mqtt();
|
if (!init_mqtt()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
xTaskCreatePinnedToCore((TaskFunction_t)&mqtt_loop, "mqtt_loop", 4096, NULL, TASK_MQTT_PRIO, &mqtt_loop_task,
|
xTaskCreatePinnedToCore((TaskFunction_t)&mqtt_loop, "mqtt_loop", 4096, NULL, TASK_MQTT_PRIO, &mqtt_loop_task,
|
||||||
esp32hal->WIFICORE());
|
esp32hal->WIFICORE());
|
||||||
|
|
|
@ -35,9 +35,14 @@ IPAddress gateway(192, 168, 10, 1);
|
||||||
IPAddress subnet(255, 255, 255, 0);
|
IPAddress subnet(255, 255, 255, 0);
|
||||||
|
|
||||||
// MQTT
|
// MQTT
|
||||||
const char* mqtt_user = MQTT_USER; // Set in USER_SECRETS.h
|
#ifdef COMMON_IMAGE
|
||||||
const char* mqtt_password = MQTT_PASSWORD; // Set in USER_SECRETS.h
|
std::string mqtt_user;
|
||||||
#ifdef MQTT_MANUAL_TOPIC_OBJECT_NAME
|
std::string mqtt_password;
|
||||||
|
#else
|
||||||
|
std::string mqtt_user = MQTT_USER; // Set in USER_SECRETS.h
|
||||||
|
std::string mqtt_password = MQTT_PASSWORD; // Set in USER_SECRETS.h
|
||||||
|
#endif
|
||||||
|
|
||||||
const char* mqtt_topic_name =
|
const char* mqtt_topic_name =
|
||||||
"BE"; // Custom MQTT topic name. Previously, the name was automatically set to "battery-emulator_esp32-XXXXXX"
|
"BE"; // Custom MQTT topic name. Previously, the name was automatically set to "battery-emulator_esp32-XXXXXX"
|
||||||
const char* mqtt_object_id_prefix =
|
const char* mqtt_object_id_prefix =
|
||||||
|
@ -46,7 +51,6 @@ const char* mqtt_device_name =
|
||||||
"Battery Emulator"; // Custom device name in Home Assistant. Previously, the name was automatically set to "BatteryEmulator_esp32-XXXXXX"
|
"Battery Emulator"; // Custom device name in Home Assistant. Previously, the name was automatically set to "BatteryEmulator_esp32-XXXXXX"
|
||||||
const char* ha_device_id =
|
const char* ha_device_id =
|
||||||
"battery-emulator"; // Custom device ID in Home Assistant. Previously, the ID was always "battery-emulator"
|
"battery-emulator"; // Custom device ID in Home Assistant. Previously, the ID was always "battery-emulator"
|
||||||
#endif // MQTT_MANUAL_TOPIC_OBJECT_NAME
|
|
||||||
|
|
||||||
/* Charger settings (Optional, when using generator charging) */
|
/* Charger settings (Optional, when using generator charging) */
|
||||||
volatile float CHARGER_SET_HV = 384; // Reasonably appropriate 4.0v per cell charging of a 96s pack
|
volatile float CHARGER_SET_HV = 384; // Reasonably appropriate 4.0v per cell charging of a 96s pack
|
||||||
|
|
|
@ -115,6 +115,11 @@ void init_stored_settings() {
|
||||||
mqtt_enabled = settings.getBool("MQTTENABLED", false);
|
mqtt_enabled = settings.getBool("MQTTENABLED", false);
|
||||||
ha_autodiscovery_enabled = settings.getBool("HADISC", false);
|
ha_autodiscovery_enabled = settings.getBool("HADISC", false);
|
||||||
|
|
||||||
|
mqtt_server = settings.getString("MQTTSERVER").c_str();
|
||||||
|
mqtt_port = settings.getUInt("MQTTPORT", 0);
|
||||||
|
mqtt_user = settings.getString("MQTTUSER").c_str();
|
||||||
|
mqtt_password = settings.getString("MQTTPASSWORD").c_str();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
settings.end();
|
settings.end();
|
||||||
|
|
|
@ -63,6 +63,18 @@ class BatteryEmulatorSettingsStore {
|
||||||
settingsUpdated = settingsUpdated || value != oldValue;
|
settingsUpdated = settingsUpdated || value != oldValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getString(const char* name) { return settings.getString(name, String()); }
|
||||||
|
|
||||||
|
String getString(const char* name, const char* defaultValue) {
|
||||||
|
return settings.getString(name, String(defaultValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveString(const char* name, const char* value) {
|
||||||
|
auto oldValue = settings.getString(name);
|
||||||
|
settings.putString(name, value);
|
||||||
|
settingsUpdated = settingsUpdated || String(value) != oldValue;
|
||||||
|
}
|
||||||
|
|
||||||
bool were_settings_updated() const { return settingsUpdated; }
|
bool were_settings_updated() const { return settingsUpdated; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <freertos/FreeRTOS.h>
|
#include <freertos/FreeRTOS.h>
|
||||||
|
#include <src/communication/nvm/comm_nvm.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include "../../../USER_SECRETS.h"
|
#include "../../../USER_SECRETS.h"
|
||||||
#include "../../../USER_SETTINGS.h"
|
#include "../../../USER_SETTINGS.h"
|
||||||
|
@ -29,6 +30,25 @@ const bool ha_autodiscovery_enabled_default = false;
|
||||||
|
|
||||||
bool ha_autodiscovery_enabled = ha_autodiscovery_enabled_default;
|
bool ha_autodiscovery_enabled = ha_autodiscovery_enabled_default;
|
||||||
|
|
||||||
|
#ifdef COMMON_IMAGE
|
||||||
|
const int mqtt_port_default = 0;
|
||||||
|
const char* mqtt_server_default = "";
|
||||||
|
#else
|
||||||
|
const int mqtt_port_default = MQTT_PORT;
|
||||||
|
const char* mqtt_server_default = MQTT_SERVER;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int mqtt_port = mqtt_port_default;
|
||||||
|
std::string mqtt_server = mqtt_server_default;
|
||||||
|
|
||||||
|
#ifdef MQTT_MANUAL_TOPIC_OBJECT_NAME
|
||||||
|
const bool mqtt_manual_topic_object_name_default = true;
|
||||||
|
#else
|
||||||
|
const bool mqtt_manual_topic_object_name_default = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool mqtt_manual_topic_object_name = mqtt_manual_topic_object_name_default;
|
||||||
|
|
||||||
esp_mqtt_client_config_t mqtt_cfg;
|
esp_mqtt_client_config_t mqtt_cfg;
|
||||||
esp_mqtt_client_handle_t client;
|
esp_mqtt_client_handle_t client;
|
||||||
char mqtt_msg[MQTT_MSG_BUFFER_SIZE];
|
char mqtt_msg[MQTT_MSG_BUFFER_SIZE];
|
||||||
|
@ -550,34 +570,42 @@ static void mqtt_event_handler(void* handler_args, esp_event_base_t base, int32_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_mqtt(void) {
|
bool init_mqtt(void) {
|
||||||
if (ha_autodiscovery_enabled) {
|
if (ha_autodiscovery_enabled) {
|
||||||
create_battery_sensor_configs();
|
create_battery_sensor_configs();
|
||||||
create_global_sensor_configs();
|
create_global_sensor_configs();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MQTT_MANUAL_TOPIC_OBJECT_NAME
|
if (mqtt_manual_topic_object_name) {
|
||||||
|
#ifdef COMMON_IMAGE
|
||||||
|
BatteryEmulatorSettingsStore settings;
|
||||||
|
topic_name = settings.getString("MQTTTOPIC", mqtt_topic_name);
|
||||||
|
object_id_prefix = settings.getString("MQTTOBJIDPREFIX", mqtt_object_id_prefix);
|
||||||
|
device_name = settings.getString("MQTTDEVICENAME", mqtt_device_name);
|
||||||
|
device_id = settings.getString("HADEVICEID", ha_device_id);
|
||||||
|
#else
|
||||||
// Use custom topic name, object ID prefix, and device name from user settings
|
// Use custom topic name, object ID prefix, and device name from user settings
|
||||||
topic_name = mqtt_topic_name;
|
topic_name = mqtt_topic_name;
|
||||||
object_id_prefix = mqtt_object_id_prefix;
|
object_id_prefix = mqtt_object_id_prefix;
|
||||||
device_name = mqtt_device_name;
|
device_name = mqtt_device_name;
|
||||||
device_id = ha_device_id;
|
device_id = ha_device_id;
|
||||||
#else
|
#endif
|
||||||
|
} else {
|
||||||
// Use default naming based on WiFi hostname for topic, object ID prefix, and device name
|
// Use default naming based on WiFi hostname for topic, object ID prefix, and device name
|
||||||
topic_name = "battery-emulator_" + String(WiFi.getHostname());
|
topic_name = "battery-emulator_" + String(WiFi.getHostname());
|
||||||
object_id_prefix = String(WiFi.getHostname()) + String("_");
|
object_id_prefix = String(WiFi.getHostname()) + String("_");
|
||||||
device_name = "BatteryEmulator_" + String(WiFi.getHostname());
|
device_name = "BatteryEmulator_" + String(WiFi.getHostname());
|
||||||
device_id = "battery-emulator";
|
device_id = "battery-emulator";
|
||||||
#endif
|
}
|
||||||
|
|
||||||
String clientId = String("BatteryEmulatorClient-") + WiFi.getHostname();
|
String clientId = String("BatteryEmulatorClient-") + WiFi.getHostname();
|
||||||
|
|
||||||
mqtt_cfg.broker.address.transport = MQTT_TRANSPORT_OVER_TCP;
|
mqtt_cfg.broker.address.transport = MQTT_TRANSPORT_OVER_TCP;
|
||||||
mqtt_cfg.broker.address.hostname = MQTT_SERVER;
|
mqtt_cfg.broker.address.hostname = mqtt_server.c_str();
|
||||||
mqtt_cfg.broker.address.port = MQTT_PORT;
|
mqtt_cfg.broker.address.port = mqtt_port;
|
||||||
mqtt_cfg.credentials.client_id = clientId.c_str();
|
mqtt_cfg.credentials.client_id = clientId.c_str();
|
||||||
mqtt_cfg.credentials.username = MQTT_USER;
|
mqtt_cfg.credentials.username = mqtt_user.c_str();
|
||||||
mqtt_cfg.credentials.authentication.password = MQTT_PASSWORD;
|
mqtt_cfg.credentials.authentication.password = mqtt_password.c_str();
|
||||||
lwt_topic = topic_name + "/status";
|
lwt_topic = topic_name + "/status";
|
||||||
mqtt_cfg.session.last_will.topic = lwt_topic.c_str();
|
mqtt_cfg.session.last_will.topic = lwt_topic.c_str();
|
||||||
mqtt_cfg.session.last_will.qos = 1;
|
mqtt_cfg.session.last_will.qos = 1;
|
||||||
|
@ -586,7 +614,16 @@ void init_mqtt(void) {
|
||||||
mqtt_cfg.session.last_will.msg_len = strlen(mqtt_cfg.session.last_will.msg);
|
mqtt_cfg.session.last_will.msg_len = strlen(mqtt_cfg.session.last_will.msg);
|
||||||
mqtt_cfg.network.timeout_ms = MQTT_TIMEOUT;
|
mqtt_cfg.network.timeout_ms = MQTT_TIMEOUT;
|
||||||
client = esp_mqtt_client_init(&mqtt_cfg);
|
client = esp_mqtt_client_init(&mqtt_cfg);
|
||||||
esp_mqtt_client_register_event(client, MQTT_EVENT_ANY, mqtt_event_handler, client);
|
|
||||||
|
if (client == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esp_mqtt_client_register_event(client, MQTT_EVENT_ANY, mqtt_event_handler, client) != ESP_OK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mqtt_loop(void) {
|
void mqtt_loop(void) {
|
||||||
|
|
|
@ -42,8 +42,10 @@
|
||||||
|
|
||||||
extern const char* version_number; // The current software version, used for mqtt
|
extern const char* version_number; // The current software version, used for mqtt
|
||||||
|
|
||||||
extern const char* mqtt_user;
|
extern std::string mqtt_server;
|
||||||
extern const char* mqtt_password;
|
extern std::string mqtt_user;
|
||||||
|
extern std::string mqtt_password;
|
||||||
|
extern int mqtt_port;
|
||||||
extern const char* mqtt_topic_name;
|
extern const char* mqtt_topic_name;
|
||||||
extern const char* mqtt_object_id_prefix;
|
extern const char* mqtt_object_id_prefix;
|
||||||
extern const char* mqtt_device_name;
|
extern const char* mqtt_device_name;
|
||||||
|
@ -51,7 +53,7 @@ extern const char* ha_device_id;
|
||||||
|
|
||||||
extern char mqtt_msg[MQTT_MSG_BUFFER_SIZE];
|
extern char mqtt_msg[MQTT_MSG_BUFFER_SIZE];
|
||||||
|
|
||||||
void init_mqtt(void);
|
bool init_mqtt(void);
|
||||||
void mqtt_loop(void);
|
void mqtt_loop(void);
|
||||||
bool mqtt_publish(const char* topic, const char* mqtt_msg, bool retain);
|
bool mqtt_publish(const char* topic, const char* mqtt_msg, bool retain);
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,26 @@ const char* name_for_button_type(STOP_BUTTON_BEHAVIOR behavior) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void render_textbox(String& content, const char* label, const char* name, BatteryEmulatorSettingsStore& settings,
|
||||||
|
bool password = false, bool number = false) {
|
||||||
|
content += "<label>";
|
||||||
|
content += label;
|
||||||
|
content += ": </label><input style='max-width: 250px;' ";
|
||||||
|
if (password) {
|
||||||
|
content += "type='password'";
|
||||||
|
} else {
|
||||||
|
content += "type='text'";
|
||||||
|
}
|
||||||
|
content += " name='";
|
||||||
|
content += name;
|
||||||
|
content += "' value=\"";
|
||||||
|
|
||||||
|
auto value = number ? String(settings.getUInt(name, 0)) : settings.getString(name);
|
||||||
|
value.replace("\"", """); // Escape quotes for HTML
|
||||||
|
content += value;
|
||||||
|
content += "\"/>";
|
||||||
|
}
|
||||||
|
|
||||||
String settings_processor(const String& var) {
|
String settings_processor(const String& var) {
|
||||||
if (var == "X") {
|
if (var == "X") {
|
||||||
String content = "";
|
String content = "";
|
||||||
|
@ -194,6 +214,18 @@ String settings_processor(const String& var) {
|
||||||
|
|
||||||
render_checkbox(content, "Enable WiFi AP", settings.getBool("WIFIAPENABLED"), "WIFIAPENABLED");
|
render_checkbox(content, "Enable WiFi AP", settings.getBool("WIFIAPENABLED"), "WIFIAPENABLED");
|
||||||
render_checkbox(content, "Enable MQTT", settings.getBool("MQTTENABLED"), "MQTTENABLED");
|
render_checkbox(content, "Enable MQTT", settings.getBool("MQTTENABLED"), "MQTTENABLED");
|
||||||
|
|
||||||
|
render_textbox(content, "MQTT server", "MQTTSERVER", settings);
|
||||||
|
render_textbox(content, "MQTT port", "MQTTPORT", settings, false, true);
|
||||||
|
render_textbox(content, "MQTT user", "MQTTUSER", settings);
|
||||||
|
render_textbox(content, "MQTT password", "MQTTPASSWORD", settings, true);
|
||||||
|
|
||||||
|
render_checkbox(content, "Customized MQTT topics", settings.getBool("MQTTTOPICS"), "MQTTTOPICS");
|
||||||
|
render_textbox(content, "MQTT topic name", "MQTTTOPIC", settings);
|
||||||
|
render_textbox(content, "Prefix for MQTT object ID", "MQTTOBJIDPREFIX", settings);
|
||||||
|
render_textbox(content, "HA device name", "MQTTDEVICENAME", settings);
|
||||||
|
render_textbox(content, "HA device ID", "HADEVICEID", settings);
|
||||||
|
|
||||||
render_checkbox(content, "Enable Home Assistant auto discovery", settings.getBool("HADISC"), "HADISC");
|
render_checkbox(content, "Enable Home Assistant auto discovery", settings.getBool("HADISC"), "HADISC");
|
||||||
|
|
||||||
content +=
|
content +=
|
||||||
|
|
|
@ -403,8 +403,10 @@ void init_webserver() {
|
||||||
bool newValue;
|
bool newValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* boolSettingNames[] = {"DBLBTR", "CNTCTRL", "CNTCTRLDBL", "PWMCNTCTRL", "PERBMSRESET",
|
const char* boolSettingNames[] = {
|
||||||
"REMBMSRESET", "CANFDASCAN", "WIFIAPENABLED", "MQTTENABLED", "HADISC"};
|
"DBLBTR", "CNTCTRL", "CNTCTRLDBL", "PWMCNTCTRL", "PERBMSRESET", "REMBMSRESET",
|
||||||
|
"CANFDASCAN", "WIFIAPENABLED", "MQTTENABLED", "HADISC", "MQTTTOPICS",
|
||||||
|
};
|
||||||
|
|
||||||
// Handles the form POST from UI to save settings of the common image
|
// Handles the form POST from UI to save settings of the common image
|
||||||
server.on("/saveSettings", HTTP_POST, [boolSettingNames](AsyncWebServerRequest* request) {
|
server.on("/saveSettings", HTTP_POST, [boolSettingNames](AsyncWebServerRequest* request) {
|
||||||
|
@ -449,6 +451,23 @@ void init_webserver() {
|
||||||
} else if (p->name() == "SHUNTCOMM") {
|
} else if (p->name() == "SHUNTCOMM") {
|
||||||
auto type = static_cast<comm_interface>(atoi(p->value().c_str()));
|
auto type = static_cast<comm_interface>(atoi(p->value().c_str()));
|
||||||
settings.saveUInt("SHUNTCOMM", (int)type);
|
settings.saveUInt("SHUNTCOMM", (int)type);
|
||||||
|
} else if (p->name() == "MQTTSERVER") {
|
||||||
|
settings.saveString("MQTTSERVER", p->value().c_str());
|
||||||
|
} else if (p->name() == "MQTTPORT") {
|
||||||
|
auto port = atoi(p->value().c_str());
|
||||||
|
settings.saveUInt("MQTTPORT", port);
|
||||||
|
} else if (p->name() == "MQTTUSER") {
|
||||||
|
settings.saveString("MQTTUSER", p->value().c_str());
|
||||||
|
} else if (p->name() == "MQTTPASSWORD") {
|
||||||
|
settings.saveString("MQTTPASSWORD", p->value().c_str());
|
||||||
|
} else if (p->name() == "MQTTTOPIC") {
|
||||||
|
settings.saveString("MQTTTOPIC", p->value().c_str());
|
||||||
|
} else if (p->name() == "MQTTOBJIDPREFIX") {
|
||||||
|
settings.saveString("MQTTOBJIDPREFIX", p->value().c_str());
|
||||||
|
} else if (p->name() == "MQTTDEVICENAME") {
|
||||||
|
settings.saveString("MQTTDEVICENAME", p->value().c_str());
|
||||||
|
} else if (p->name() == "HADEVICEID") {
|
||||||
|
settings.saveString("HADEVICEID", p->value().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& boolSetting : boolSettings) {
|
for (auto& boolSetting : boolSettings) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue