mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-04 02:09:30 +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
|
||||
|
||||
if (mqtt_enabled) {
|
||||
init_mqtt();
|
||||
if (!init_mqtt()) {
|
||||
return;
|
||||
}
|
||||
|
||||
xTaskCreatePinnedToCore((TaskFunction_t)&mqtt_loop, "mqtt_loop", 4096, NULL, TASK_MQTT_PRIO, &mqtt_loop_task,
|
||||
esp32hal->WIFICORE());
|
||||
|
|
|
@ -35,9 +35,14 @@ IPAddress gateway(192, 168, 10, 1);
|
|||
IPAddress subnet(255, 255, 255, 0);
|
||||
|
||||
// MQTT
|
||||
const char* mqtt_user = MQTT_USER; // Set in USER_SECRETS.h
|
||||
const char* mqtt_password = MQTT_PASSWORD; // Set in USER_SECRETS.h
|
||||
#ifdef MQTT_MANUAL_TOPIC_OBJECT_NAME
|
||||
#ifdef COMMON_IMAGE
|
||||
std::string mqtt_user;
|
||||
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 =
|
||||
"BE"; // Custom MQTT topic name. Previously, the name was automatically set to "battery-emulator_esp32-XXXXXX"
|
||||
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"
|
||||
const char* ha_device_id =
|
||||
"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) */
|
||||
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);
|
||||
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
|
||||
|
||||
settings.end();
|
||||
|
|
|
@ -63,6 +63,18 @@ class BatteryEmulatorSettingsStore {
|
|||
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; }
|
||||
|
||||
private:
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <Arduino.h>
|
||||
#include <WiFi.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <src/communication/nvm/comm_nvm.h>
|
||||
#include <list>
|
||||
#include "../../../USER_SECRETS.h"
|
||||
#include "../../../USER_SETTINGS.h"
|
||||
|
@ -29,6 +30,25 @@ const bool ha_autodiscovery_enabled_default = false;
|
|||
|
||||
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_handle_t client;
|
||||
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) {
|
||||
create_battery_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
|
||||
topic_name = mqtt_topic_name;
|
||||
object_id_prefix = mqtt_object_id_prefix;
|
||||
device_name = mqtt_device_name;
|
||||
device_id = ha_device_id;
|
||||
#else
|
||||
#endif
|
||||
} else {
|
||||
// Use default naming based on WiFi hostname for topic, object ID prefix, and device name
|
||||
topic_name = "battery-emulator_" + String(WiFi.getHostname());
|
||||
object_id_prefix = String(WiFi.getHostname()) + String("_");
|
||||
device_name = "BatteryEmulator_" + String(WiFi.getHostname());
|
||||
device_id = "battery-emulator";
|
||||
#endif
|
||||
}
|
||||
|
||||
String clientId = String("BatteryEmulatorClient-") + WiFi.getHostname();
|
||||
|
||||
mqtt_cfg.broker.address.transport = MQTT_TRANSPORT_OVER_TCP;
|
||||
mqtt_cfg.broker.address.hostname = MQTT_SERVER;
|
||||
mqtt_cfg.broker.address.port = MQTT_PORT;
|
||||
mqtt_cfg.broker.address.hostname = mqtt_server.c_str();
|
||||
mqtt_cfg.broker.address.port = mqtt_port;
|
||||
mqtt_cfg.credentials.client_id = clientId.c_str();
|
||||
mqtt_cfg.credentials.username = MQTT_USER;
|
||||
mqtt_cfg.credentials.authentication.password = MQTT_PASSWORD;
|
||||
mqtt_cfg.credentials.username = mqtt_user.c_str();
|
||||
mqtt_cfg.credentials.authentication.password = mqtt_password.c_str();
|
||||
lwt_topic = topic_name + "/status";
|
||||
mqtt_cfg.session.last_will.topic = lwt_topic.c_str();
|
||||
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.network.timeout_ms = MQTT_TIMEOUT;
|
||||
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) {
|
||||
|
|
|
@ -42,8 +42,10 @@
|
|||
|
||||
extern const char* version_number; // The current software version, used for mqtt
|
||||
|
||||
extern const char* mqtt_user;
|
||||
extern const char* mqtt_password;
|
||||
extern std::string mqtt_server;
|
||||
extern std::string mqtt_user;
|
||||
extern std::string mqtt_password;
|
||||
extern int mqtt_port;
|
||||
extern const char* mqtt_topic_name;
|
||||
extern const char* mqtt_object_id_prefix;
|
||||
extern const char* mqtt_device_name;
|
||||
|
@ -51,7 +53,7 @@ extern const char* ha_device_id;
|
|||
|
||||
extern char mqtt_msg[MQTT_MSG_BUFFER_SIZE];
|
||||
|
||||
void init_mqtt(void);
|
||||
bool init_mqtt(void);
|
||||
void mqtt_loop(void);
|
||||
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) {
|
||||
if (var == "X") {
|
||||
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 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");
|
||||
|
||||
content +=
|
||||
|
|
|
@ -403,8 +403,10 @@ void init_webserver() {
|
|||
bool newValue;
|
||||
};
|
||||
|
||||
const char* boolSettingNames[] = {"DBLBTR", "CNTCTRL", "CNTCTRLDBL", "PWMCNTCTRL", "PERBMSRESET",
|
||||
"REMBMSRESET", "CANFDASCAN", "WIFIAPENABLED", "MQTTENABLED", "HADISC"};
|
||||
const char* boolSettingNames[] = {
|
||||
"DBLBTR", "CNTCTRL", "CNTCTRLDBL", "PWMCNTCTRL", "PERBMSRESET", "REMBMSRESET",
|
||||
"CANFDASCAN", "WIFIAPENABLED", "MQTTENABLED", "HADISC", "MQTTTOPICS",
|
||||
};
|
||||
|
||||
// Handles the form POST from UI to save settings of the common image
|
||||
server.on("/saveSettings", HTTP_POST, [boolSettingNames](AsyncWebServerRequest* request) {
|
||||
|
@ -449,6 +451,23 @@ void init_webserver() {
|
|||
} else if (p->name() == "SHUNTCOMM") {
|
||||
auto type = static_cast<comm_interface>(atoi(p->value().c_str()));
|
||||
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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue