diff --git a/src/main.cpp b/src/main.cpp index d8f5d90..e81b731 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -42,14 +42,15 @@ static unsigned long mqttReconnectAt = 0; // --------------------------------------------------------------------------- static void loadConfig() { - if (!LittleFS.exists("/config.json")) return; + Serial.println("[CFG] loading config"); + if (!LittleFS.exists("/config.json")) { Serial.println("[CFG] no config file"); return; } File f = LittleFS.open("/config.json", "r"); - if (!f) return; + if (!f) { Serial.println("[CFG] failed to open"); return; } JsonDocument doc; DeserializationError err = deserializeJson(doc, f); f.close(); - if (err) return; + if (err) { Serial.printf("[CFG] parse error: %s\n", err.c_str()); return; } if (doc["hostname"].is()) strlcpy(hostname, doc["hostname"], sizeof(hostname)); @@ -72,6 +73,7 @@ static void loadConfig() { meters[i].maxDuty = m["maxD"] | 0.0f; meters[i].currentValue = m["current"] | 0.0f; } + Serial.printf("[CFG] loaded hostname=%s meters=%d mqtt_en=%d\n", hostname, meterCount, mqttCfg.enabled); } static void saveConfig() { @@ -98,6 +100,9 @@ static void saveConfig() { if (f) { serializeJson(doc, f); f.close(); + Serial.printf("[CFG] saved hostname=%s meters=%d mqtt_en=%d\n", hostname, meterCount, mqttCfg.enabled); + } else { + Serial.println("[CFG] save failed"); } } @@ -110,6 +115,7 @@ static void attachMeters() { if (meters[i].pin > 0) { ledcSetup(i, PWM_FREQ, PWM_RES); ledcAttachPin(meters[i].pin, i); + Serial.printf("[PWM] attach ch%d pin%d\n", i, meters[i].pin); } } } @@ -120,6 +126,7 @@ static void applyMeters() { float pct = meters[i].currentValue / 100.0f * meters[i].maxDuty / 100.0f; int duty = constrain((int)(pct * 1023), 0, 1023); ledcWrite(i, duty); + Serial.printf("[PWM] ch%d duty=%d (cur=%.1f maxD=%.1f)\n", i, duty, meters[i].currentValue, meters[i].maxDuty); } } @@ -131,6 +138,7 @@ static void mqttCallback(char* topic, byte* payload, unsigned int len) { String valStr; for (unsigned i = 0; i < len; i++) valStr += (char)payload[i]; float val = valStr.toFloat(); + Serial.printf("[MQTT] rcvd topic=%s payload=%s\n", topic, valStr.c_str()); // topic format: /meter//current/set or .../maxduty/set String t = String(topic); @@ -146,6 +154,7 @@ static void mqttCallback(char* topic, byte* payload, unsigned int len) { String suffix = t.substring(slash); if (suffix == "/current/set") { + Serial.printf("[MQTT] set meter%d current=%.1f\n", idx, val); meters[idx].currentValue = val; if (meters[idx].pin > 0 && meters[idx].maxDuty > 0) { float pct = val / 100.0f * meters[idx].maxDuty / 100.0f; @@ -153,6 +162,7 @@ static void mqttCallback(char* topic, byte* payload, unsigned int len) { } saveConfig(); } else if (suffix == "/maxduty/set") { + Serial.printf("[MQTT] set meter%d maxduty=%.1f\n", idx, val); meters[idx].maxDuty = constrain(val, 0, 100); attachMeters(); applyMeters(); @@ -165,7 +175,8 @@ static void mqttPublishCurrent(int idx) { char topic[128], val[16]; snprintf(topic, sizeof(topic), "%s/meter/%d/current", mqttCfg.prefix, idx); snprintf(val, sizeof(val), "%.1f", meters[idx].currentValue); - mqttClient.publish(topic, val, true); + bool ok = mqttClient.publish(topic, val, true); + Serial.printf("[MQTT] publish topic=%s val=%s ok=%d\n", topic, val, ok); } static void mqttSubscribe() { @@ -174,13 +185,19 @@ static void mqttSubscribe() { char t[128]; snprintf(t, sizeof(t), "%s/meter/%d/current/set", mqttCfg.prefix, i); mqttClient.subscribe(t); + Serial.printf("[MQTT] subscribed %s\n", t); snprintf(t, sizeof(t), "%s/meter/%d/maxduty/set", mqttCfg.prefix, i); mqttClient.subscribe(t); + Serial.printf("[MQTT] subscribed %s\n", t); } } static bool mqttConnect() { - if (!mqttCfg.enabled || strlen(mqttCfg.host) == 0 || strlen(mqttCfg.user) == 0 || strlen(mqttCfg.pass) == 0) return false; + if (!mqttCfg.enabled || strlen(mqttCfg.host) == 0 || strlen(mqttCfg.user) == 0 || strlen(mqttCfg.pass) == 0) { + Serial.printf("[MQTT] connect skipped en=%d host=%d user=%d pass=%d\n", + mqttCfg.enabled, strlen(mqttCfg.host) > 0, strlen(mqttCfg.user) > 0, strlen(mqttCfg.pass) > 0); + return false; + } char clientId[32]; { @@ -192,13 +209,14 @@ static bool mqttConnect() { mqttClient.setServer(mqttCfg.host, mqttCfg.port); mqttClient.setCallback(mqttCallback); + Serial.printf("[MQTT] connecting to %s:%d as %s\n", mqttCfg.host, mqttCfg.port, clientId); bool ok = mqttClient.connect(clientId, mqttCfg.user, mqttCfg.pass); if (ok) { - Serial.printf("MQTT connected to %s:%d\n", mqttCfg.host, mqttCfg.port); + Serial.printf("[MQTT] connected to %s:%d\n", mqttCfg.host, mqttCfg.port); mqttSubscribe(); } else { - Serial.printf("MQTT failed rc=%d\n", mqttClient.state()); + Serial.printf("[MQTT] failed rc=%d\n", mqttClient.state()); } return ok; } @@ -209,15 +227,17 @@ static void mqttLoop() { if (!mqttClient.connected()) { unsigned long now = millis(); if (now > mqttReconnectAt) { - // quick TCP probe with short timeout before the blocking MQTT connect + Serial.printf("[MQTT] probing %s:%d\n", mqttCfg.host, mqttCfg.port); WiFiClient probe; bool reachable = probe.connect(mqttCfg.host, mqttCfg.port, 1500); probe.stop(); if (reachable) { + Serial.println("[MQTT] probe OK, connecting"); if (mqttConnect()) mqttReconnectAt = 0; else mqttReconnectAt = now + 30000; } else { + Serial.println("[MQTT] probe failed, retry in 30s"); mqttReconnectAt = now + 30000; } } @@ -262,6 +282,7 @@ static String escHtml(const String& s) { // --------------------------------------------------------------------------- static void handleRoot() { + Serial.println("[HTTP] GET /"); String meterRows; for (int i = 0; i < meterCount; i++) { char maxStr[8], curStr[8]; @@ -364,9 +385,11 @@ static void handleRoot() { html += "document.querySelector('select[name=meter_count]').addEventListener('change',function(){this.form.submit();});"; html += ""; server.send(200, "text/html", html); + Serial.printf("[HTTP] GET / -> 200 (%u bytes)\n", html.length()); } static void handleConfig() { + Serial.println("[HTTP] POST /config"); if (server.hasArg("hostname")) { String val = server.arg("hostname"); val.trim(); @@ -386,8 +409,11 @@ static void handleConfig() { strlcpy(mqttCfg.pass, server.arg("mqtt_pass").c_str(), sizeof(mqttCfg.pass)); if (server.hasArg("mqtt_prefix")) strlcpy(mqttCfg.prefix, server.arg("mqtt_prefix").c_str(), sizeof(mqttCfg.prefix)); + Serial.printf("[HTTP] mqtt enabled host=%s port=%u user=%s prefix=%s\n", + mqttCfg.host, mqttCfg.port, mqttCfg.user, mqttCfg.prefix); } else { mqttCfg.enabled = false; + Serial.println("[HTTP] mqtt disabled"); } int newCount = meterCount; @@ -407,6 +433,8 @@ static void handleConfig() { meterCount = newCount; memcpy(meters, newMeters, sizeof(meters)); + for (int i = 0; i < meterCount; i++) + Serial.printf("[HTTP] meter%d pin=%d maxD=%.1f cur=%.1f\n", i, meters[i].pin, meters[i].maxDuty, meters[i].currentValue); saveConfig(); attachMeters(); @@ -421,11 +449,12 @@ static void handleConfig() { } static void handleSet() { - if (!server.hasArg("i") || !server.hasArg("v")) { server.send(400); return; } + if (!server.hasArg("i") || !server.hasArg("v")) { server.send(400); Serial.println("[HTTP] GET /set missing args"); return; } int idx = server.arg("i").toInt(); float val = server.arg("v").toFloat(); - if (idx < 0 || idx >= meterCount) { server.send(400); return; } + if (idx < 0 || idx >= meterCount) { server.send(400); Serial.printf("[HTTP] GET /set bad idx=%d\n", idx); return; } meters[idx].currentValue = val; + Serial.printf("[HTTP] GET /set meter%d=%.1f\n", idx, val); if (meters[idx].pin > 0 && meters[idx].maxDuty > 0) { float pct = val / 100.0f * meters[idx].maxDuty / 100.0f; int duty = constrain((int)(pct * 1023), 0, 1023); @@ -450,6 +479,7 @@ static void startServer() { void setup() { Serial.begin(115200); + Serial.println("\n\n=== M1730 boot ==="); LittleFS.begin(true); loadConfig(); @@ -457,6 +487,7 @@ void setup() { attachMeters(); applyMeters(); + Serial.println("[WIFI] starting WiFiManager"); WiFiManager wm; wm.setTitle("M1730"); @@ -467,17 +498,18 @@ void setup() { }); if (!wm.autoConnect("M1730")) { - Serial.println("WiFi failed, restarting"); + Serial.println("[WIFI] failed, restarting"); ESP.restart(); } + Serial.printf("[WIFI] connected, IP: %s\n", WiFi.localIP().toString().c_str()); strlcpy(hostname, hostnameParam.getValue(), sizeof(hostname)); saveConfig(); startServer(); startMDNS(); - mqttReconnectAt = 0; // handshake deferred to mqttLoop in loop() + mqttReconnectAt = 0; - Serial.printf("Board address: http://%s.local or http://%s\n", + Serial.printf("[BOOT] ready at http://%s.local or http://%s\n", hostname, WiFi.localIP().toString().c_str()); }