Hallo zusammen,
Bin aktuell dabei mir eine MQTT-Steckdose zu bauen. Das Projekt ist eher als Lernprojekt zu verstehen, da es u.A. Shellies ja bereits als preiswerte Fertiglösung gibt. Am Ende soll es aber mit den gleichen Basisfunktionen daherkommen wie eben so ein Shelly 1, nur mit 2-4 Relays.
MQTT-Schnittstelle läuft prima und eigentlich ist er sogar schon seit 6 Monaten im Einsatz.
Nun wollte ich eine Config-Schnittstelle bauen über für HTTP-Requests mit der ESP8266WebServer-Bibliothek. Das Ergebnis sind JSON-Response Nachrichten (ebenfalls ähnlich Shelly):
void ServerConnection()
{
Serial.print("Start web-server ... ");
// Control Website
server.on("/", []() {
server.send(200, "text/html", "Testsite");
Serial.println("Opend homepage");
});
server.on("/settings", []() {
RequestTimeStamp = 1;
Serial.print("Request Settings -> [Start]: ");
Serial.print(millis());
if(server.args() > 0)
{
if (server.arg("mqtt_enable") != "") // ToDo
{
if(server.arg("mqtt_enable").equals("true"))
MQTTconfig.enable = true;
else
{
MQTTconfig.enable = false;
MQTT.disconnect();
}
saveMQTTconfig(MQTTconfigFile, MQTTconfig);
}
if (server.arg("mqtt_server") != "") // ok
{
if(server.arg("mqtt_server").indexOf(":") > 0 &&server.arg("mqtt_server").lastIndexOf(":") == server.arg("mqtt_server").indexOf(":"))
{
String tempMQTTserver = server.arg("mqtt_server").substring(0, server.arg("mqtt_server").indexOf(":"));
String tempMQTTport = server.arg("mqtt_server").substring(server.arg("mqtt_server").indexOf(":")+1,server.arg("mqtt_server").length());
MQTTconfig.server = tempMQTTserver;
MQTTconfig.port = tempMQTTport.toInt();
MQTT.disconnect();
saveMQTTconfig(MQTTconfigFile, MQTTconfig);
}
}
if (server.arg("mqtt_user") != "") //ok
{
MQTTconfig.user = server.arg("mqtt_user");
MQTT.disconnect();
saveMQTTconfig(MQTTconfigFile, MQTTconfig);
}
if (server.arg("mqtt_id") != "") //ok
{
MQTTconfig.clientID = server.arg("mqtt_id");
MQTT.disconnect();
saveMQTTconfig(MQTTconfigFile, MQTTconfig);
}
if (server.arg("mqtt_clean_session") != "") //ok
{
if(server.arg("mqtt_clean_session").equals("true"))
MQTTconfig.cleansession = true;
else
MQTTconfig.cleansession = false;
MQTT.disconnect();
saveMQTTconfig(MQTTconfigFile, MQTTconfig);
}
if (server.arg("mqtt_keep_alive") != "") //ok
{
if(server.arg("mqtt_keep_alive").toInt() >= 0)
MQTTconfig.keepalive = server.arg("mqtt_keep_alive").toInt();
else
MQTTconfig.keepalive = 0;
MQTT.disconnect();
saveMQTTconfig(MQTTconfigFile, MQTTconfig);
}
if (server.arg("mqtt_max_qos") != "")
{
if(server.arg("mqtt_max_qos").toInt() <= 2 && server.arg("mqtt_max_qos").toInt() >= 0)
MQTTconfig.maxqos = server.arg("mqtt_max_qos").toInt();
else
MQTTconfig.maxqos = 0;
MQTT.disconnect();
saveMQTTconfig(MQTTconfigFile, MQTTconfig);
}
if (server.arg("mqtt_update_period")!= "")
{
if(server.arg("mqtt_update_period").toInt() >= 0)
MQTTconfig.updateperiod = server.arg("mqtt_update_period").toInt()*1000;
else
MQTTconfig.updateperiod = 0;
MQTTcycleTimer.SetCountdown(MQTTconfig.updateperiod);
saveMQTTconfig(MQTTconfigFile, MQTTconfig);
}
}
String ResponseStr;
String MqttStr;
MqttStr = openJSON(MqttStr);
MqttStr = addJSONbool(MqttStr,"enable",MQTTconfig.enable); // ToDo
MqttStr = addJSONstr(MqttStr,"server",MQTTconfig.server + ":" + MQTTconfig.port); // ToDo
MqttStr = addJSONstr(MqttStr,"user",MQTTconfig.user); // ToDo
MqttStr = addJSONstr(MqttStr,"id",MQTTconfig.clientID);
MqttStr = addJSONbool(MqttStr,"clean_session",MQTTconfig.cleansession); // ToDo
MqttStr = addJSONint(MqttStr,"keep_alive",MQTTconfig.keepalive); // ToDo
MqttStr = addJSONint(MqttStr,"max_qos",MQTTconfig.maxqos); // ToDo
MqttStr = addJSONbool(MqttStr,"retain",MQTTconfig.retain); // ToDo
MqttStr = addJSONint(MqttStr,"update_period",MQTTconfig.updateperiod/1000); // ToDo
MqttStr = closeJSON(MqttStr);
ResponseStr = openJSON(ResponseStr);
ResponseStr = addJSONjson(ResponseStr,"mqtt",MqttStr);
ResponseStr = closeJSON(ResponseStr);
server.send(200, "text/json", ResponseStr.c_str());
Serial.print(" [End] ");
Serial.println(millis());
});
server.on("/ota", []() {
String ResponseStr;
ResponseStr = openJSON(ResponseStr);
ResponseStr = addJSONstr(ResponseStr,"status","idle");
ResponseStr = addJSONstr(ResponseStr,"old_version",SWversion);
ResponseStr = closeJSON(ResponseStr);
server.send(200, "text/json", ResponseStr.c_str());
});
server.onNotFound([]() {
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
Serial.println(message.c_str());
});
server.begin();
Serial.println("ok");
}
// Create JSON String
String openJSON(String JSONstr)
{
JSONstr = "{";
return JSONstr;
}
String closeJSON(String JSONstr)
{
if(JSONstr.endsWith(","))
JSONstr = JSONstr.substring(0, JSONstr.lastIndexOf(","));
JSONstr += "}";
return JSONstr;
}
String addJSONbool(String JSONstr, String Name, bool Value)
{
JSONstr += "\"" + Name + "\"" + ":\"";
if(JSONstr)
JSONstr += "true";
else
JSONstr += "false";
JSONstr += "\",";
return JSONstr;
}
String addJSONint(String JSONstr, String Name, int Value)
{
JSONstr += "\"" + Name + "\"" + ":\"" + Value + "\",";
return JSONstr;
}
String addJSONstr(String JSONstr, String Name, String Value)
{
JSONstr += "\"" + Name + "\"" + ":\"" + Value + "\",";
return JSONstr;
}
String addJSONjson(String JSONstr, String Name, String Value)
{
JSONstr += "\"" + Name + "\"" + ":" + Value + ",";
return JSONstr;
}
Ausgeführt wird er dann mit folgenden Befehlen in der Loop:
void setup()
{
// Set Wifi
startWifiConnection();
delay(250);
// Set Server
startServerConnection();
delay(250);
// Set MQTT
startMQTTconnection();
delay(250);
}
void loop()
{
iif(RequestTimeStamp == 0)
{
time1 = millis();
}
handleWifiConnection();
server.handleClient();
handleMQTTconnection();
if(RequestTimeStamp == 1)
{
RequestTimeStamp = 0;
Serial.print("Handle TimeStamp -> [Start]: ");
Serial.print(time1);
Serial.print(" [End]: ");
Serial.println(millis());
}
}
Wenn ich nun die seite >http://"host-ip"/settings> öffne, kommt eine JSON-String, den ich auswerten kann. Über GET-Befehle kann ich auch die Werte ändern.
Dummerweise dauert das Aufrufen der Seite oft Sekunden.
Der Code selbst wird aber schnell abgearbeitet. Hab mir mal mit Serial-Print zwei Zeiten gmessen:
-> Zeit innerhalb der Settings-Request-Funktion und der gesamte Loop-Zeitraum.
Der Log sagt, die Schleife dauert insgesamt nur 8ms, d.h. der Code ist nicht träge:
Request Settings -> [Start]: 16410 [End] 16413
Handle TimeStamp -> [Start]: 16406 [End]: 16414
Der Log wird auch unmittelbar nach dem Request angezeigt, erst dann vergehen Gedenksekunden.
Wo beginne ich mit der Fehlersuche? Normal ist es denke ich nicht oder?

