Initialisation depot

This commit is contained in:
Serge NOEL
2026-08-05 09:14:31 +02:00
commit fd3fc380d8
10 changed files with 350 additions and 0 deletions
+52
View File
@@ -0,0 +1,52 @@
#include "MqttManager.h"
#include <Arduino.h>
MqttManager* MqttManager::instance = nullptr;
MqttManager::MqttManager() {}
void MqttManager::begin(const char* server, uint16_t port, MessageCallback cb) {
serverAddr = server;
serverPort = port;
messageCb = cb;
client.setServer(serverAddr, serverPort);
instance = this;
client.setCallback(MqttManager::staticCallback);
}
void MqttManager::staticCallback(char* topic, byte* payload, unsigned int length) {
if (instance && instance->messageCb) instance->messageCb(topic, payload, length);
}
void MqttManager::connect() {
while (!client.connected()) {
Serial.print("Connecting to MQTT...");
if (client.connect("esp32-dcc")) {
Serial.println("connected");
} else {
Serial.print("failed rc=");
Serial.print(client.state());
Serial.println("; retrying in 2s");
delay(2000);
}
}
}
void MqttManager::loop() {
if (WiFi.status() == WL_CONNECTED) {
if (!client.connected()) connect();
client.loop();
}
}
bool MqttManager::publish(const char* topic, const char* payload) {
if (!client.connected()) return false;
return client.publish(topic, payload);
}
bool MqttManager::subscribe(const char* topic) {
if (!client.connected()) return false;
return client.subscribe(topic);
}
bool MqttManager::connected() { return client.connected(); }
+90
View File
@@ -0,0 +1,90 @@
#include "WifiManager.h"
#include "config.h"
#include <Preferences.h>
#include <functional>
static const char* AP_SSID = DEFAULT_AP_SSID;
WifiManager::WifiManager(): ssid(""), pass(""), apMode(false) {}
void WifiManager::loadCredentials() {
Preferences prefs;
prefs.begin("dcc", true);
ssid = prefs.getString("ssid", "");
pass = prefs.getString("pass", "");
prefs.end();
}
void WifiManager::saveCredentials(const String &s, const String &p) {
Preferences prefs;
prefs.begin("dcc", false);
prefs.putString("ssid", s);
prefs.putString("pass", p);
prefs.end();
}
void WifiManager::startAP() {
apMode = true;
WiFi.mode(WIFI_AP);
WiFi.softAP(AP_SSID);
IPAddress ip = WiFi.softAPIP();
Serial.print("AP started: ");
Serial.println(AP_SSID);
Serial.print("Configure at http://");
Serial.println(ip);
server.on("/", std::bind(&WifiManager::handleRoot, this));
server.on("/save", std::bind(&WifiManager::handleSave, this));
server.begin();
}
void WifiManager::handleRoot() {
String page = "<html><body><h1>Configure WiFi</h1>"
"<form action=\"/save\" method=\"POST\">"
"SSID: <input name=\"ssid\"><br>"
"Password: <input name=\"pass\" type=\"password\"><br>"
"<input type=\"submit\" value=\"Save\"></form></body></html>";
server.send(200, "text/html", page);
}
void WifiManager::handleSave() {
if (server.hasArg("ssid")) {
String s = server.arg("ssid");
String p = server.arg("pass");
saveCredentials(s, p);
String resp = "<html><body>Saved. Rebooting...</body></html>";
server.send(200, "text/html", resp);
delay(1000);
ESP.restart();
} else {
server.send(400, "text/plain", "Missing ssid");
}
}
void WifiManager::begin() {
loadCredentials();
if (ssid.length() > 0) {
Serial.print("Connecting to WiFi");
WiFi.begin(ssid.c_str(), pass.c_str());
unsigned long start = millis();
while (WiFi.status() != WL_CONNECTED && millis() - start < 10000) {
delay(250);
Serial.print('.');
}
Serial.println();
}
if (WiFi.status() == WL_CONNECTED) {
Serial.print("WiFi connected, IP: ");
Serial.println(WiFi.localIP());
apMode = false;
} else {
startAP();
}
}
bool WifiManager::isConnected() { return WiFi.status() == WL_CONNECTED; }
void WifiManager::loop() { if (apMode) server.handleClient(); }
String WifiManager::getSSID() { return ssid; }
String WifiManager::getPassword() { return pass; }
+70
View File
@@ -0,0 +1,70 @@
#include <Arduino.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include "config.h"
#include "Dcc.h"
#include "WifiManager.h"
#include "MqttManager.h"
WifiManager wifiManager;
MqttManager mqttManager;
static bool mqttSubscribed = false;
void onMqttMessage(char* topic, uint8_t* payload, unsigned int length) {
StaticJsonDocument<256> doc;
DeserializationError err = deserializeJson(doc, payload, length);
if (err) {
Serial.println("Invalid JSON in MQTT message");
return;
}
if (strcmp(topic, MQTT_TOPIC_CMD) == 0) {
uint16_t addr = doc["address"] | 0;
bool state = doc["state"] | false;
String id = doc["id"] | "";
auto pkt = Dcc::generateAccessoryPacket(addr, state);
Dcc::sendPacket(pkt, DCC_OUTPUT_PIN);
// send ACK
StaticJsonDocument<128> ack;
ack["id"] = id;
ack["status"] = "sent";
char buf[128];
size_t n = serializeJson(ack, buf);
mqttManager.publish(MQTT_TOPIC_STATUS, buf);
}
if (strcmp(topic, MQTT_TOPIC_RESPONSE) == 0) {
// forward any response to status topic
// ensure payload is null-terminated
String resp;
for (unsigned int i = 0; i < length; ++i) resp += (char)payload[i];
mqttManager.publish(MQTT_TOPIC_STATUS, resp.c_str());
}
}
void setup() {
Serial.begin(115200);
pinMode(DCC_OUTPUT_PIN, OUTPUT);
digitalWrite(DCC_OUTPUT_PIN, LOW);
wifiManager.begin();
// MQTT manager can be started even if WiFi is not connected yet; it will connect when possible
mqttManager.begin(MQTT_SERVER, MQTT_PORT, onMqttMessage);
}
void loop() {
wifiManager.loop();
mqttManager.loop();
if (wifiManager.isConnected() && mqttManager.connected() && !mqttSubscribed) {
mqttManager.subscribe(MQTT_TOPIC_CMD);
mqttManager.subscribe(MQTT_TOPIC_RESPONSE);
mqttManager.publish(MQTT_TOPIC_STATUS, "ready");
mqttSubscribed = true;
}
}