Configuration interface

This commit is contained in:
2025-12-03 20:11:12 +01:00
parent 3222cc349d
commit 74991a9107
8 changed files with 2864 additions and 64 deletions

View File

@@ -1,5 +1,6 @@
#include <Arduino.h>
#include <Preferences.h>
#include <ArduinoJson.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
@@ -12,6 +13,40 @@
#include "Nmea2kTwai.h"
#include <map>
#include "mbedtls/md.h" // for SHA256
#include <esp32/clk.h> // for cpu frequency
String get_sha256(String payload) {
byte shaResult[32];
mbedtls_md_context_t ctx;
mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256;
mbedtls_md_init(&ctx);
mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0);
mbedtls_md_starts(&ctx);
mbedtls_md_update(&ctx, (const unsigned char *) payload.c_str(), payload.length());
mbedtls_md_finish(&ctx, shaResult);
mbedtls_md_free(&ctx);
// convert to hex string
char buffer[sizeof(shaResult)*2 + 1];
const char hexmap[] = "0123456789abcdef";
for (int i = 0; i < sizeof(shaResult); i++) {
buffer[i*2] = hexmap[(shaResult[i] >> 4) & 0x0F];
buffer[i*2+1] = hexmap[shaResult[i] & 0x0F];
}
buffer[sizeof(buffer) - 1] = '\0';
String hash = String(buffer);
Serial.print("SHA256 payload: ");
Serial.print(payload);
Serial.println();
Serial.print("SHA256-Hash: ");
Serial.print(hash);
Serial.println();
return hash;
}
// Logging
static const char* TAG = "main.cpp";
@@ -51,10 +86,13 @@ void send_embedded_file(String name, AsyncWebServerRequest *request)
}
}
uint64_t chipid = ESP.getEfuseMac();
const char* wifi_ssid = "OBPKP61";
const char* wifi_pass = "keypad61";
AsyncWebServer server(80);
unsigned long lastSensor = 0;
unsigned long lastPrint = 0;
unsigned long counter = 0;
@@ -70,6 +108,8 @@ uint buzzerpower = 50; // TBD make use of this
SHT31 sht(SHT31_ADDRESS);
bool sht_available = false;
float temp = 0.0;
float hum = 0.0;
int nodeid; // NMEA2000 id on bus
Nmea2kTwai &NMEA2000=*(new Nmea2kTwai(CAN_TX, CAN_RX, CAN_RECOVERY_PERIOD));
@@ -80,45 +120,26 @@ String processor(const String& var) {
return "";
}
/* Low level wifi setup (alternative)
static void wifi_event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
// printf("Event nr: %ld!\n", event_id);
String uptime_with_unit() {
int64_t uptime = esp_timer_get_time() / 1000000;
String uptime_unit;
if (uptime < 120) {
uptime_unit = " seconds";
} else {
if (uptime < 2 * 3600) {
uptime /= 60;
uptime_unit = " minutes";
} else if (uptime < 2 * 3600 * 24) {
uptime /= 3600;
uptime_unit = " hours";
} else {
uptime /= 86400;
uptime_unit = " days";
}
}
return String(uptime) + " " + uptime_unit;
}
void wifi_init_softap()
{
esp_netif_init();
esp_event_loop_create_default();
esp_netif_create_default_wifi_ap();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, NULL);
esp_wifi_init(&cfg);
wifi_config_t wifi_config = {
.ap = {
.ssid = wifi_ssid,
.ssid_len = strlen(wifi_ssid),
.channel = WIFI_CHANNEL,
.password = wifi_pass,
.max_connection = WIFI_MAX_STA,
.authmode = WIFI_AUTH_WPA2_PSK,
.pmf_cfg = {
.required = true,
},
},
};
esp_wifi_set_mode(WIFI_MODE_AP);
esp_wifi_set_config(WIFI_IF_AP, &wifi_config);
esp_wifi_start();
ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d",
ESP_WIFI_SSID, ESP_WIFI_PASS, ESP_WIFI_CHANNEL);
}
*/
void setup() {
Serial.begin(115200);
@@ -167,16 +188,65 @@ void setup() {
send_embedded_file(it->first, request);
});
}
// WIP: API
/*
server.on("/api/status", HTTP_GET, [](AsyncWebServerRequest *request){
// API fast hack
server.on("/api/capabilities", HTTP_GET, [](AsyncWebServerRequest *request){
StaticJsonDocument<100> doc;
doc["temp"] = 22.3;
doc["ip"] = WiFi.localIP().toString();
doc["apPwChange"] = "true";
String out;
serializeJson(doc, out);
request->send(200, "application/json", out);
}); */
});
server.on("/api/checkpass", HTTP_GET, [](AsyncWebServerRequest *request){
StaticJsonDocument<100> doc;
doc["status"] = "FAILED";
String out;
serializeJson(doc, out);
request->send(200, "application/json", out);
});
server.on("/api/config", HTTP_GET, [](AsyncWebServerRequest *request){
StaticJsonDocument<100> doc;
doc["systemName"] = "Keypad1";
doc["version"] = "0.0";
doc["fwtype"] = "unknown";
doc["salt"] = "secret";
String out;
serializeJson(doc, out);
request->send(200, "application/json", out);
});
server.on("/api/resetconfig", HTTP_GET, [](AsyncWebServerRequest *request){
StaticJsonDocument<100> doc;
doc["status"] = "FAILED";
String out;
serializeJson(doc, out);
request->send(200, "application/json", out);
});
server.on("/api/status", HTTP_GET, [](AsyncWebServerRequest *request){
StaticJsonDocument<200> doc;
int cpu_freq = esp_clk_cpu_freq() / 1000000;
doc["cpuspeed"] = String(cpu_freq) + "MHz";
char ssid[13];
snprintf(ssid, 13, "%04X%08X", (uint16_t)(chipid >> 32), (uint32_t)chipid);
doc["chipid"] = String(ssid);
doc["uptime"] = uptime_with_unit();
doc["heap"]=(long)xPortGetFreeHeapSize();
doc["temp"] = String(temp, 1);
doc["hum"] = String(hum, 1);
doc["status"] = "OK";
String out;
serializeJson(doc, out);
request->send(200, "application/json", out);
});
server.on("/api/setconfig", HTTP_POST, [](AsyncWebServerRequest *request){
StaticJsonDocument<100> doc;
doc["status"] = "FAILED";
String out;
serializeJson(doc, out);
request->send(200, "application/json", out);
});
// TODO POST vom Client entgegennehmen
server.begin();
@@ -299,6 +369,9 @@ void setup() {
Serial.print(stat, HEX);
Serial.println();
// Additional tests
String passhash = get_sha256("secretTEST");
}
void loop() {
@@ -390,10 +463,9 @@ void loop() {
}
if (button > 0) {
sht.read();
Serial.print(sht.getTemperature(), 1);
Serial.print(temp, 1);
Serial.print("\t");
Serial.println(sht.getHumidity(), 1);
Serial.println(hum, 1);
// Debounce delay to avoid multiple triggers
delay(200);
}
@@ -402,6 +474,13 @@ void loop() {
// NMEA2000.loop();
// NMEA2000.ParseMessages();
if (millis() - lastSensor >= 5000) {
lastSensor = millis();
sht.read();
temp = sht.getTemperature();
hum = sht.getHumidity();
}
// development heartbeat
if (millis() - lastPrint >= 1000) {
lastPrint = millis();