Ajout partie Web

This commit is contained in:
Serge NOEL
2026-03-11 17:36:58 +01:00
parent 59f7ae7ab3
commit 7a7d33864c
2 changed files with 117 additions and 17 deletions

View File

@@ -12,11 +12,33 @@ Thermostat thermostat;
float currentTemp = 0.0;
/**
* Initialize serial, load configuration and presets, connect to WiFi and MQTT, and set up the thermostat.
*
*/
void setup() {
Serial.begin(115200);
// Retrieve config from EEPROM, connect to WiFi and MQTT, and set up thermostat presets
load_config();
// Debug: print current config and actions
Serial.println("--- Thermostat Unit Startup ---");
Serial.print("WiFi SSID: "); Serial.println(wifi_ssid);
Serial.print("MQTT Server: "); Serial.println(mqtt_server);
Serial.print("MQTT Port: "); Serial.println(mqtt_port);
Serial.print("MQTT User: "); Serial.println(mqtt_user);
Serial.print("MQTT Device ID: "); Serial.println(mqtt_device_id);
Serial.print("MQTT Temp Topic: "); Serial.println(mqtt_temp_topic);
Serial.print("Temp Sensor ID: "); Serial.println(temp_sensor_id);
Serial.print("Preset Confort: "); Serial.println(preset_confort);
Serial.print("Preset Eco: "); Serial.println(preset_eco);
Serial.print("Preset Boost: "); Serial.println(preset_boost);
Serial.print("Preset Hors Gel: "); Serial.println(preset_hors_gel);
Serial.println("Connecting to WiFi...");
// setup wifi and mqtt, and load presets into thermostat
setup_web_config();
WiFi.begin(wifi_ssid.c_str(), wifi_pass.c_str());
Serial.println("Connecting to MQTT...");
mqttClient.setServer(mqtt_server.c_str(), mqtt_port);
setup_mqtt(mqttClient);
load_presets();
@@ -24,13 +46,19 @@ void setup() {
thermostat.setPresetTemp(MODE_ECO, preset_eco);
thermostat.setPresetTemp(MODE_BOOST, preset_boost);
thermostat.setPresetTemp(MODE_HORS_GEL, preset_hors_gel);
// Retreive current temp from MQTT (if available) and set initial mode to lastvalue (stored in EEPROM) or MODE_OFF if not available
thermostat.setMode(MODE_OFF);
}
void loop() {
handle_web_config();
// Ask Mqtt to process incoming messages and maintain connection
mqtt_loop(mqttClient);
// Update thermostat state based on current temp and publish state to MQTT
thermostat.update(currentTemp);
// Publish state to MQTT every second (or on state change, if you want to optimize)
mqtt_publish_state(mqttClient, thermostat.getMode(), thermostat.getTargetTemp(), thermostat.isHeating());
// Delay to avoid flooding MQTT with messages. Adjust as needed for your use case (e.g., publish on state change
// instead of every loop).
delay(1000);
}

View File

@@ -15,22 +15,32 @@ bool shouldSaveConfigFlag = false;
#define CFG_EEPROM_SIZE 512
#define CFG_STRLEN 32
/**
* Config struct for EEPROM storage.
*/
struct ConfigData {
char wifi_ssid[CFG_STRLEN];
char wifi_pass[CFG_STRLEN];
char mqtt_server[CFG_STRLEN];
char mqtt_user[CFG_STRLEN];
char mqtt_pass[CFG_STRLEN];
char temp_sensor_id[CFG_STRLEN];
char mqtt_device_id[CFG_STRLEN];
char mqtt_temp_topic[CFG_STRLEN];
int mqtt_port;
float preset_confort;
float preset_eco;
float preset_boost;
float preset_hors_gel;
char wifi_ssid[CFG_STRLEN]; // Wifi SSID
char wifi_pass[CFG_STRLEN]; // Wifi Password
char mqtt_server[CFG_STRLEN]; // MQTT Server
char mqtt_user[CFG_STRLEN]; // MQTT User
char mqtt_pass[CFG_STRLEN]; // MQTT Password
char temp_sensor_id[CFG_STRLEN]; // Temperature Sensor ID
char mqtt_device_id[CFG_STRLEN]; // MQTT Device ID
char mqtt_temp_topic[CFG_STRLEN]; // MQTT Temperature Topic
int mqtt_port; // MQTT Port
float preset_confort; // Confort Mode Temperature
float preset_eco; // Eco Mode Temperature
float preset_boost; // Boost Mode Temperature
float preset_hors_gel; // Hors Gel Mode Temperature
};
/**
* Config saving. In a production system, consider adding error handling and validation (e.g., check string lengths,
* valid port range, etc.).
* NB: config is stored as a struct for simplicity, but this means that any change to the struct layout will
* break existing configs. In a production system, consider using a more robust format (
*/
void save_config() {
ConfigData cfg;
memset(&cfg, 0, sizeof(cfg));
@@ -52,6 +62,12 @@ void save_config() {
EEPROM.commit();
}
/**
* Config loading with basic validation. If invalid, defaults will be used and saved on next web config save.
* NB: config is stored as a struct for simplicity, but this means that any change to the struct layout will break
* existing configs. In a production system, consider using a more robust format (e.g., JSON with versioning).
*
*/
void load_config() {
ConfigData cfg;
EEPROM.begin(CFG_EEPROM_START + sizeof(ConfigData));
@@ -74,12 +90,68 @@ void load_config() {
}
}
/**
* Web config setup. This will block until WiFi is configured, which is fine for initial setup but may not be ideal
* for all use cases.
*
* If config parameters are defined in EEPROm, try to connect to WiFi. If connection fails, start config portal.
* If parameters are not defined, start config portal directly.
* On config save, set shouldSaveConfigFlag to true so that main loop can save the config to EEPROM.
* This is a bit of a hack, but it allows us to avoid blocking the main loop while waiting for user input.
*/
void setup_web_config() {
WiFiManager wm;
// Add custom parameters for MQTT, presets, sensor id
// On save, set shouldSaveConfigFlag = true
wm.autoConnect("ThermostatConfig");
if (shouldSaveConfigFlag) save_config();
// WiFiManagerParameter: id, placeholder, default, length
WiFiManagerParameter custom_mqtt_server("mqtt_server", "MQTT Server", mqtt_server.c_str(), CFG_STRLEN);
WiFiManagerParameter custom_mqtt_port("mqtt_port", "MQTT Port", String(mqtt_port).c_str(), 6);
WiFiManagerParameter custom_mqtt_user("mqtt_user", "MQTT User", mqtt_user.c_str(), CFG_STRLEN);
WiFiManagerParameter custom_mqtt_pass("mqtt_pass", "MQTT Password", mqtt_pass.c_str(), CFG_STRLEN);
WiFiManagerParameter custom_temp_sensor_id("temp_sensor_id", "Temp Sensor ID", temp_sensor_id.c_str(), CFG_STRLEN);
WiFiManagerParameter custom_mqtt_device_id("mqtt_device_id", "MQTT Device ID", mqtt_device_id.c_str(), CFG_STRLEN);
WiFiManagerParameter custom_mqtt_temp_topic("mqtt_temp_topic", "MQTT Temp Topic", mqtt_temp_topic.c_str(), CFG_STRLEN);
WiFiManagerParameter custom_preset_confort("preset_confort", "Preset Confort", String(preset_confort).c_str(), 8);
WiFiManagerParameter custom_preset_eco("preset_eco", "Preset Eco", String(preset_eco).c_str(), 8);
WiFiManagerParameter custom_preset_boost("preset_boost", "Preset Boost", String(preset_boost).c_str(), 8);
WiFiManagerParameter custom_preset_hors_gel("preset_hors_gel", "Preset Hors Gel", String(preset_hors_gel).c_str(), 8);
wm.addParameter(&custom_mqtt_server);
wm.addParameter(&custom_mqtt_port);
wm.addParameter(&custom_mqtt_user);
wm.addParameter(&custom_mqtt_pass);
wm.addParameter(&custom_temp_sensor_id);
wm.addParameter(&custom_mqtt_device_id);
wm.addParameter(&custom_mqtt_temp_topic);
wm.addParameter(&custom_preset_confort);
wm.addParameter(&custom_preset_eco);
wm.addParameter(&custom_preset_boost);
wm.addParameter(&custom_preset_hors_gel);
wm.setSaveConfigCallback([]() {
shouldSaveConfigFlag = true;
});
if (!wm.autoConnect("ThermostatConfig")) {
// If failed to connect or configure, restart or handle error
ESP.restart();
}
// If config was changed, update variables and save
if (shouldSaveConfigFlag) {
mqtt_server = custom_mqtt_server.getValue();
mqtt_port = String(custom_mqtt_port.getValue()).toInt();
mqtt_user = custom_mqtt_user.getValue();
mqtt_pass = custom_mqtt_pass.getValue();
temp_sensor_id = custom_temp_sensor_id.getValue();
mqtt_device_id = custom_mqtt_device_id.getValue();
mqtt_temp_topic = custom_mqtt_temp_topic.getValue();
preset_confort = String(custom_preset_confort.getValue()).toFloat();
preset_eco = String(custom_preset_eco.getValue()).toFloat();
preset_boost = String(custom_preset_boost.getValue()).toFloat();
preset_hors_gel = String(custom_preset_hors_gel.getValue()).toFloat();
save_config();
shouldSaveConfigFlag = false;
}
}
void handle_web_config() {