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

View File

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

View File

@ -4,6 +4,8 @@
#include <ArduinoJson.h>
#include <LittleFS.h>
#include "wifi.h"
#ifdef ESP8266
#include <ESP8266WebServer.h>
@ -18,63 +20,75 @@ WebServer server(80);
bool httpRunning = false;
void httpRelay(const int index, Relay &relay) {
const auto nameKey = String("name") + index;
if (server.hasArg(nameKey)) {
const auto name = server.arg(nameKey);
relay.setName(name);
}
File httpUploadFile;
const auto topicKey = String("topic") + index;
if (server.hasArg(topicKey)) {
const auto topic = server.arg(topicKey);
relay.setTopic(topic);
void httpString(const String &key, const std::function<void(const String &)> &modifier) {
if (server.hasArg(key)) {
const auto name = server.arg(key);
modifier(name);
}
}
const auto stateKey = String("state") + index;
if (server.hasArg(stateKey)) {
const auto state = server.arg(stateKey);
void httpBool(const String &key, const std::function<void(const bool &)> &modifier) {
if (server.hasArg(key)) {
const auto state = server.arg(key);
if (state == "true") {
relay.set(true);
modifier(true);
} else if (state == "false") {
relay.set(false);
modifier(false);
}
}
}
const auto initialKey = String("initial") + index;
if (server.hasArg(initialKey)) {
const auto initial = server.arg(initialKey);
if (initial == "OFF") {
relay.setInitial(INITIAL_OFF);
} else if (initial == "ON") {
relay.setInitial(INITIAL_ON);
} else if (initial == "CYCLE") {
relay.setInitial(INITIAL_CYCLE);
void httpLong(const String &key, const std::function<void(const long &)> &modifier) {
if (server.hasArg(key)) {
modifier(server.arg(key).toInt());
}
}
void httpInitial(const String &key, const std::function<void(const Initial &)> &modifier) {
httpString(key, [&modifier](const String &value) {
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;
if (server.hasArg(onCountKey)) {
const auto value = server.arg(onCountKey).toInt();
relay.setOnCount(value);
}
void httpRelay(const int index, Relay &relay) {
const String suffix(index);
httpString("name" + suffix, [&relay](const String &value) { relay.setName(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;
if (server.hasArg(onMillisKey)) {
const auto value = server.arg(onMillisKey).toInt();
relay.setOnMillis(value);
}
httpString("topic" + suffix, [&relay](const String &value) { relay.setTopic(value); });
const auto offMillisKey = String("offMillis") + index;
if (server.hasArg(offMillisKey)) {
const auto value = server.arg(offMillisKey).toInt();
relay.setOffMillis(value);
}
httpBool("gridPowerDeltaOnEnabled" + suffix, [&relay](const long &value) { relay.setGridPowerDeltaOnEnabled(value); });
httpLong("gridPowerDeltaOnThreshold" + suffix, [&relay](const long &value) { relay.setGridPowerDeltaOnThreshold(value); });
httpLong("gridPowerDeltaOnDelay" + suffix, [&relay](const long &value) { relay.setGridPowerDeltaOnDelay(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() {
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>();
relay0.json(relays.add<JsonObject>());
@ -90,27 +104,25 @@ void httpStatus() {
}
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);
#ifdef Sonoff4ChPro
httpRelay(1, relay1);
httpRelay(2, relay2);
httpRelay(3, relay3);
#endif
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) {
const auto upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
@ -138,10 +150,8 @@ void httpSetup() {
server.serveStatic("/", LittleFS, "/index.html");
server.serveStatic("/icon.svg", LittleFS, "/icon.svg");
server.on("/set", httpSet);
server.on("/set/", httpSet);
server.on("/off", httpOff);
server.on("/off/", httpOff);
server.on("/status", httpSet);
server.on("/status/", httpSet);
server.on("/upload/index", HTTP_POST, [] { server.send(200); }, [] { httpUpload("index.html"); });
server.on("/upload/icon", HTTP_POST, [] { server.send(200); }, [] { httpUpload("icon.svg"); });

View File

@ -1,16 +1,43 @@
#include "mqtt.h"
#ifdef ESP32
#include <WiFi.h>
#endif
#ifdef ESP8266
#include <ESP8266WiFi.h>
#endif
#include "config.h"
#include <WiFiClient.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";
WiFiClient wifiClient;
PubSubClient client(wifiClient);
String mqttHost = MQTT_HOST_FALLBACK;
long mqttPort = MQTT_PORT_FALLBACK;
String mqttUser = MQTT_USER_FALLBACK;
bool mqttShouldConnect = false;
unsigned long mqttLast = 0;
@ -48,19 +75,18 @@ void mqttLoop() {
Serial.println("[MQTT] Stopped.");
}
} else if (mqttShouldConnect) {
const auto host = configRead("/mqtt/host", "10.0.0.50", false);
if (host == "") {
mqttHost = configRead(MQTT_HOST_KEY, MQTT_HOST_FALLBACK, false);
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;
}
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());
client.setServer(host.c_str(), port);
Serial.printf("[MQTT] Connecting: %s:%ld\n", host.c_str(), port);
if (client.connect(id.c_str(), user.c_str(), pass.c_str())) {
client.setServer(mqttHost.c_str(), mqttPort);
Serial.printf("[MQTT] Connecting: %s:%ld\n", mqttHost.c_str(), mqttPort);
if (client.connect(WiFi.getHostname(), mqttUser.c_str(), mqttPass.c_str())) {
Serial.printf("[MQTT] Connected.\n");
client.subscribe(GRID_POWER_DELTA_TOPIC.c_str());
client.setCallback(mqttReceive);
@ -84,3 +110,34 @@ void mqttPublish(const String &topic, const JsonDocument &json) {
const auto size = serializeJson(json, buffer);
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);
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

View File

@ -3,18 +3,16 @@
#include "http.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>
#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;
unsigned long wifiLast = 0;
@ -28,9 +26,9 @@ void wifiConnect() {
status.cycle(500, 500);
const auto hostname = configRead(CONFIG_HOSTNAME, DEFAULT_HOSTNAME);
const auto wifiSSID = configRead(CONFIG_WIFI_SSID, DEFAULT_WIFI_SSID);
const auto wifiPass = configRead(CONFIG_WIFI_PASSWORD, DEFAULT_WIFI_PASSWORD, true, true);
const auto hostname = configRead(WIFI_HOSTNAME_KEY, WIFI_HOSTNAME_FALLBACK);
const auto wifiSSID = configRead(WIFI_SSID_KEY, WIFI_SSID_FALLBACK);
const auto wifiPass = configRead(WIFI_PASSWORD_KEY, WIFI_PASSWORD_FALLBACK, true, true);
Serial.printf("[WiFi] Connecting: \"%s\"\n", wifiSSID.c_str());
WiFi.hostname(hostname);
@ -69,20 +67,6 @@ void wifiLoop() {
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() {
#ifdef ESP32
esp_log_level_set("wifi", ESP_LOG_NONE);
@ -104,3 +88,17 @@ void wifiSetup() {
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
#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 wifiLoop();
void wifiSetHostname(const String &hostname);
#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
#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/index' -F "file=@index.html.min"
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/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/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/icon' -F "file=@icon.svg"