more http configuration

This commit is contained in:
Patrick Haßel 2025-09-03 11:09:34 +02:00
parent f72c04b9b3
commit 46fcc4b872
8 changed files with 185 additions and 106 deletions

View File

@ -228,12 +228,12 @@
timeout = setTimeout(() => request(), 2000); timeout = setTimeout(() => request(), 2000);
const r = new XMLHttpRequest(); const r = new XMLHttpRequest();
r.open("GET", getUrl(`set?${query}`)); r.open("GET", getUrl(`status?${query}`));
r.onreadystatechange = () => { r.onreadystatechange = () => {
if (r.readyState === 4 && r.status === 200) { if (r.readyState === 4 && r.status === 200) {
data = JSON.parse(r.response); data = JSON.parse(r.response);
dataAge = Date.now(); dataAge = Date.now();
title.innerText = data.hostname; title.innerText = data.wifi.hostname;
for (let index = 0; index < data.relays.length; index++) { for (let index = 0; index < data.relays.length; index++) {
const relayData = data.relays[index]; const relayData = data.relays[index];
const relayTag = document.getElementById("relay" + index) || create(index); const relayTag = document.getElementById("relay" + index) || create(index);

View File

@ -9,12 +9,12 @@ lib_deps = bblanchon/ArduinoJson @ 7.4.2
[Sonoff4ChPro] [Sonoff4ChPro]
platform = espressif8266 platform = espressif8266
board = esp8285 board = esp8285
build_flags = -D Sonoff4ChPro build_flags = -D Sonoff4ChPro -D WIFI_HOSTNAME_FALLBACK=\"PatrixSonoff4ChPro\"
[GosundSP111] [GosundSP111]
platform = espressif8266 platform = espressif8266
board = esp8285 board = esp8285
build_flags = -D GosundSP111 build_flags = -D GosundSP111 -D WIFI_HOSTNAME_FALLBACK=\"PatrixGosundSP111\"
[ESP32_TEST] [ESP32_TEST]
platform = espressif32 platform = espressif32

View File

@ -4,6 +4,8 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <LittleFS.h> #include <LittleFS.h>
#include "wifi.h"
#ifdef ESP8266 #ifdef ESP8266
#include <ESP8266WebServer.h> #include <ESP8266WebServer.h>
@ -18,63 +20,75 @@ WebServer server(80);
bool httpRunning = false; bool httpRunning = false;
void httpRelay(const int index, Relay &relay) { File httpUploadFile;
const auto nameKey = String("name") + index;
if (server.hasArg(nameKey)) {
const auto name = server.arg(nameKey);
relay.setName(name);
}
const auto topicKey = String("topic") + index; void httpString(const String &key, const std::function<void(const String &)> &modifier) {
if (server.hasArg(topicKey)) { if (server.hasArg(key)) {
const auto topic = server.arg(topicKey); const auto name = server.arg(key);
relay.setTopic(topic); modifier(name);
} }
}
const auto stateKey = String("state") + index; void httpBool(const String &key, const std::function<void(const bool &)> &modifier) {
if (server.hasArg(stateKey)) { if (server.hasArg(key)) {
const auto state = server.arg(stateKey); const auto state = server.arg(key);
if (state == "true") { if (state == "true") {
relay.set(true); modifier(true);
} else if (state == "false") { } else if (state == "false") {
relay.set(false); modifier(false);
} }
} }
}
const auto initialKey = String("initial") + index; void httpLong(const String &key, const std::function<void(const long &)> &modifier) {
if (server.hasArg(initialKey)) { if (server.hasArg(key)) {
const auto initial = server.arg(initialKey); modifier(server.arg(key).toInt());
if (initial == "OFF") { }
relay.setInitial(INITIAL_OFF); }
} else if (initial == "ON") {
relay.setInitial(INITIAL_ON); void httpInitial(const String &key, const std::function<void(const Initial &)> &modifier) {
} else if (initial == "CYCLE") { httpString(key, [&modifier](const String &value) {
relay.setInitial(INITIAL_CYCLE); if (value == "OFF") {
modifier(INITIAL_OFF);
} else if (value == "ON") {
modifier(INITIAL_ON);
} else if (value == "CYCLE") {
modifier(INITIAL_CYCLE);
} }
} });
}
const auto onCountKey = String("onCount") + index; void httpRelay(const int index, Relay &relay) {
if (server.hasArg(onCountKey)) { const String suffix(index);
const auto value = server.arg(onCountKey).toInt(); httpString("name" + suffix, [&relay](const String &value) { relay.setName(value); });
relay.setOnCount(value); httpInitial("initial" + suffix, [&relay](const Initial &value) { relay.setInitial(value); });
} httpLong("onCount" + suffix, [&relay](const long &value) { relay.setOnCount(value); });
httpLong("onMillis" + suffix, [&relay](const long &value) { relay.setOnMillis(value); });
httpLong("offMillis" + suffix, [&relay](const long &value) { relay.setOffMillis(value); });
const auto onMillisKey = String("onMillis") + index; httpString("topic" + suffix, [&relay](const String &value) { relay.setTopic(value); });
if (server.hasArg(onMillisKey)) {
const auto value = server.arg(onMillisKey).toInt();
relay.setOnMillis(value);
}
const auto offMillisKey = String("offMillis") + index; httpBool("gridPowerDeltaOnEnabled" + suffix, [&relay](const long &value) { relay.setGridPowerDeltaOnEnabled(value); });
if (server.hasArg(offMillisKey)) { httpLong("gridPowerDeltaOnThreshold" + suffix, [&relay](const long &value) { relay.setGridPowerDeltaOnThreshold(value); });
const auto value = server.arg(offMillisKey).toInt(); httpLong("gridPowerDeltaOnDelay" + suffix, [&relay](const long &value) { relay.setGridPowerDeltaOnDelay(value); });
relay.setOffMillis(value); httpBool("gridPowerDeltaOffEnabled" + suffix, [&relay](const long &value) { relay.setGridPowerDeltaOffEnabled(value); });
} httpLong("gridPowerDeltaOffThreshold" + suffix, [&relay](const long &value) { relay.setGridPowerDeltaOffThreshold(value); });
httpLong("gridPowerDeltaOffDelay" + suffix, [&relay](const long &value) { relay.setGridPowerDeltaOffDelay(value); });
httpBool("state" + suffix, [&relay](const bool &value) { relay.set(value); });
} }
void httpStatus() { void httpStatus() {
JsonDocument json; JsonDocument json;
json["hostname"] = WiFi.getHostname();
const auto wifi = json["wifi"].to<JsonObject>();
wifi["hostname"] = WiFi.getHostname();
wifi["ssid"] = WiFi.SSID();
const auto mqtt = json["mqtt"].to<JsonObject>();
mqtt["user"] = getMqttUser();
mqtt["host"] = getMqttHost();
mqtt["port"] = getMqttPort();
const auto relays = json["relays"].to<JsonArray>(); const auto relays = json["relays"].to<JsonArray>();
relay0.json(relays.add<JsonObject>()); relay0.json(relays.add<JsonObject>());
@ -90,27 +104,25 @@ void httpStatus() {
} }
void httpSet() { void httpSet() {
httpString("wifiHostname", wifiSetHostname);
httpString("wifiSSID", wifiSetSSID);
httpString("wifiPassword", wifiSetPassword);
httpString("mqttHost", mqttSetHost);
httpLong("mqttPort", mqttSetPort);
httpString("mqttUser", mqttSetUser);
httpString("mqttPassword", mqttSetPassword);
httpRelay(0, relay0); httpRelay(0, relay0);
#ifdef Sonoff4ChPro #ifdef Sonoff4ChPro
httpRelay(1, relay1); httpRelay(1, relay1);
httpRelay(2, relay2); httpRelay(2, relay2);
httpRelay(3, relay3); httpRelay(3, relay3);
#endif #endif
httpStatus(); httpStatus();
} }
void httpOff() {
relay0.set(false);
#ifdef Sonoff4ChPro
relay1.set(false);
relay2.set(false);
relay3.set(false);
#endif
httpStatus();
}
File httpUploadFile;
void httpUpload(const char *name) { void httpUpload(const char *name) {
const auto upload = server.upload(); const auto upload = server.upload();
if (upload.status == UPLOAD_FILE_START) { if (upload.status == UPLOAD_FILE_START) {
@ -138,10 +150,8 @@ void httpSetup() {
server.serveStatic("/", LittleFS, "/index.html"); server.serveStatic("/", LittleFS, "/index.html");
server.serveStatic("/icon.svg", LittleFS, "/icon.svg"); server.serveStatic("/icon.svg", LittleFS, "/icon.svg");
server.on("/set", httpSet); server.on("/status", httpSet);
server.on("/set/", httpSet); server.on("/status/", httpSet);
server.on("/off", httpOff);
server.on("/off/", httpOff);
server.on("/upload/index", HTTP_POST, [] { server.send(200); }, [] { httpUpload("index.html"); }); server.on("/upload/index", HTTP_POST, [] { server.send(200); }, [] { httpUpload("index.html"); });
server.on("/upload/icon", HTTP_POST, [] { server.send(200); }, [] { httpUpload("icon.svg"); }); server.on("/upload/icon", HTTP_POST, [] { server.send(200); }, [] { httpUpload("icon.svg"); });

View File

@ -1,16 +1,43 @@
#include "mqtt.h" #include "mqtt.h"
#ifdef ESP32
#include <WiFi.h>
#endif
#ifdef ESP8266
#include <ESP8266WiFi.h>
#endif
#include "config.h" #include "config.h"
#include <WiFiClient.h> #include <WiFiClient.h>
#include "PubSubClient.h" #include "PubSubClient.h"
#define MQTT_HOST_KEY "/mqtt/host"
#define MQTT_HOST_FALLBACK "10.0.0.50"
#define MQTT_PORT_KEY "/mqtt/port"
#define MQTT_PORT_FALLBACK 1883
#define MQTT_USER_KEY "/mqtt/user"
#define MQTT_USER_FALLBACK ""
#define MQTT_PASSWORD_KEY "/mqtt/password"
#define MQTT_PASSWORD_FALLBACK ""
const String GRID_POWER_DELTA_TOPIC = "electricity/grid/power/signed/w"; const String GRID_POWER_DELTA_TOPIC = "electricity/grid/power/signed/w";
WiFiClient wifiClient; WiFiClient wifiClient;
PubSubClient client(wifiClient); PubSubClient client(wifiClient);
String mqttHost = MQTT_HOST_FALLBACK;
long mqttPort = MQTT_PORT_FALLBACK;
String mqttUser = MQTT_USER_FALLBACK;
bool mqttShouldConnect = false; bool mqttShouldConnect = false;
unsigned long mqttLast = 0; unsigned long mqttLast = 0;
@ -48,19 +75,18 @@ void mqttLoop() {
Serial.println("[MQTT] Stopped."); Serial.println("[MQTT] Stopped.");
} }
} else if (mqttShouldConnect) { } else if (mqttShouldConnect) {
const auto host = configRead("/mqtt/host", "10.0.0.50", false); mqttHost = configRead(MQTT_HOST_KEY, MQTT_HOST_FALLBACK, false);
if (host == "") { mqttPort = configRead(MQTT_PORT_KEY, MQTT_PORT_FALLBACK, true);
mqttUser = configRead(MQTT_USER_KEY, MQTT_USER_FALLBACK);
const auto mqttPass = configRead(MQTT_PASSWORD_KEY, MQTT_PASSWORD_FALLBACK, true, true);
if (mqttHost == "") {
return; return;
} }
if (mqttLast == 0 || millis() - mqttLast >= 3000) { if (mqttLast == 0 || millis() - mqttLast >= 3000) {
const auto id = configRead("/mqtt/id", "test");
const auto user = configRead("/mqtt/user", "");
const auto pass = configRead("/mqtt/pass", "", true, true);
const auto port = configRead("/mqtt/port", 1883L);
mqttLast = max(1UL, millis()); mqttLast = max(1UL, millis());
client.setServer(host.c_str(), port); client.setServer(mqttHost.c_str(), mqttPort);
Serial.printf("[MQTT] Connecting: %s:%ld\n", host.c_str(), port); Serial.printf("[MQTT] Connecting: %s:%ld\n", mqttHost.c_str(), mqttPort);
if (client.connect(id.c_str(), user.c_str(), pass.c_str())) { if (client.connect(WiFi.getHostname(), mqttUser.c_str(), mqttPass.c_str())) {
Serial.printf("[MQTT] Connected.\n"); Serial.printf("[MQTT] Connected.\n");
client.subscribe(GRID_POWER_DELTA_TOPIC.c_str()); client.subscribe(GRID_POWER_DELTA_TOPIC.c_str());
client.setCallback(mqttReceive); client.setCallback(mqttReceive);
@ -84,3 +110,34 @@ void mqttPublish(const String &topic, const JsonDocument &json) {
const auto size = serializeJson(json, buffer); const auto size = serializeJson(json, buffer);
client.publish(topic.c_str(), buffer, size); client.publish(topic.c_str(), buffer, size);
} }
String getMqttUser() {
return mqttUser;
}
String getMqttHost() {
return mqttHost;
}
long getMqttPort() {
return mqttPort;
}
void mqttSetHost(const String &value) {
mqttHost = value;
configWrite(MQTT_HOST_KEY, String(MQTT_HOST_FALLBACK), value);
}
void mqttSetPort(const long &value) {
mqttPort = value;
configWrite(MQTT_PORT_KEY,MQTT_HOST_FALLBACK, value);
}
void mqttSetUser(const String &value) {
mqttUser = value;
configWrite(MQTT_USER_KEY, String(MQTT_HOST_FALLBACK), value);
}
void mqttSetPassword(const String &value) {
configWrite(MQTT_PASSWORD_KEY,MQTT_HOST_FALLBACK, value, true);
}

View File

@ -15,4 +15,18 @@ void mqttStop();
void mqttPublish(const String &topic, const JsonDocument &json); void mqttPublish(const String &topic, const JsonDocument &json);
String getMqttUser();
String getMqttHost();
long getMqttPort();
void mqttSetHost(const String &value);
void mqttSetPort(const long &value);
void mqttSetUser(const String &value);
void mqttSetPassword(const String &value);
#endif #endif

View File

@ -3,18 +3,16 @@
#include "http.h" #include "http.h"
#include "io.h" #include "io.h"
#define CONFIG_HOSTNAME "/wifi/hostname"
#define CONFIG_WIFI_SSID "/wifi/ssid"
#define CONFIG_WIFI_PASSWORD "/wifi/password"
#ifndef DEFAULT_HOSTNAME
#define DEFAULT_HOSTNAME "PatrixSonoff4ChPro"
#endif
#define DEFAULT_WIFI_SSID "HappyNet"
#define DEFAULT_WIFI_PASSWORD "1Grausame!Sackratte7"
#include <ArduinoOTA.h> #include <ArduinoOTA.h>
#define WIFI_HOSTNAME_KEY "/wifi/hostname"
#define WIFI_SSID_KEY "/wifi/ssid"
#define WIFI_SSID_FALLBACK "HappyNet"
#define WIFI_PASSWORD_KEY "/wifi/password"
#define WIFI_PASSWORD_FALLBACK "1Grausame!Sackratte7"
bool wifiConnected = false; bool wifiConnected = false;
unsigned long wifiLast = 0; unsigned long wifiLast = 0;
@ -28,9 +26,9 @@ void wifiConnect() {
status.cycle(500, 500); status.cycle(500, 500);
const auto hostname = configRead(CONFIG_HOSTNAME, DEFAULT_HOSTNAME); const auto hostname = configRead(WIFI_HOSTNAME_KEY, WIFI_HOSTNAME_FALLBACK);
const auto wifiSSID = configRead(CONFIG_WIFI_SSID, DEFAULT_WIFI_SSID); const auto wifiSSID = configRead(WIFI_SSID_KEY, WIFI_SSID_FALLBACK);
const auto wifiPass = configRead(CONFIG_WIFI_PASSWORD, DEFAULT_WIFI_PASSWORD, true, true); const auto wifiPass = configRead(WIFI_PASSWORD_KEY, WIFI_PASSWORD_FALLBACK, true, true);
Serial.printf("[WiFi] Connecting: \"%s\"\n", wifiSSID.c_str()); Serial.printf("[WiFi] Connecting: \"%s\"\n", wifiSSID.c_str());
WiFi.hostname(hostname); WiFi.hostname(hostname);
@ -69,20 +67,6 @@ void wifiLoop() {
wifiConnected = connected; wifiConnected = connected;
} }
void wifiChangeHostname(const char *hostname) {
if (configWrite(CONFIG_HOSTNAME, DEFAULT_HOSTNAME, hostname)) {
WiFi.setHostname(hostname);
}
}
void wifiChangeSSID(const char *ssid) {
configWrite(CONFIG_WIFI_SSID, DEFAULT_WIFI_SSID, ssid);
}
void wifiChangePassword(const char *password) {
configWrite(CONFIG_WIFI_PASSWORD, DEFAULT_WIFI_PASSWORD, password, true);
}
void wifiSetup() { void wifiSetup() {
#ifdef ESP32 #ifdef ESP32
esp_log_level_set("wifi", ESP_LOG_NONE); esp_log_level_set("wifi", ESP_LOG_NONE);
@ -104,3 +88,17 @@ void wifiSetup() {
status.set(false); status.set(false);
}); });
} }
void wifiSetHostname(const String &hostname) {
if (configWrite(WIFI_HOSTNAME_KEY, WIFI_HOSTNAME_FALLBACK, hostname.c_str())) {
WiFi.setHostname(hostname.c_str());
}
}
void wifiSetSSID(const String &ssid) {
configWrite(WIFI_SSID_KEY, WIFI_SSID_FALLBACK, ssid.c_str());
}
void wifiSetPassword(const String &password) {
configWrite(WIFI_PASSWORD_KEY, WIFI_PASSWORD_FALLBACK, password, true);
}

View File

@ -1,14 +1,16 @@
#ifndef WIFI_H #ifndef WIFI_H
#define WIFI_H #define WIFI_H
void wifiChangeHostname(const char *hostname); #include <WString.h>
void wifiChangeSSID(const char *ssid); void wifiSetSSID(const String &ssid);
void wifiChangePassword(const char *password); void wifiSetPassword(const String &password);
void wifiSetup(); void wifiSetup();
void wifiLoop(); void wifiLoop();
void wifiSetHostname(const String &hostname);
#endif #endif

View File

@ -4,11 +4,9 @@ cd "$(dirname "$0")" || exit 1
minify index.html | sed 's|http://10.42.0.204||g' > index.html.min || exit 2 minify index.html | sed 's|http://10.42.0.204||g' > index.html.min || exit 2
#curl -s 'http://10.42.0.204/upload/index' -F "file=@index.html.min" curl -s 'http://10.42.0.204/upload/index' -F "file=@index.html.min"
#curl -s 'http://10.42.0.204/upload/icon' -F "file=@icon.svg" curl -s 'http://10.42.0.204/upload/icon' -F "file=@icon.svg"
#curl -s 'http://10.0.0.178/upload/index' -F "file=@index.html.min" #curl -s 'http://10.0.0.178/upload/index' -F "file=@index.html.min"
#curl -s 'http://10.0.0.178/upload/icon' -F "file=@icon.svg" #curl -s 'http://10.0.0.178/upload/icon' -F "file=@icon.svg"
#curl -s 'http://10.0.0.179/upload/index' -F "file=@index.html.min"
curl -s 'http://10.0.0.179/upload/index' -F "file=@index.html.min" #curl -s 'http://10.0.0.179/upload/icon' -F "file=@icon.svg"
curl -s 'http://10.0.0.179/upload/icon' -F "file=@icon.svg"