This commit is contained in:
Patrick Haßel 2024-04-11 13:43:09 +02:00
parent 5373bbd4a5
commit d29cb632ec
10 changed files with 273 additions and 102 deletions

View File

@ -5,11 +5,13 @@
#include "mqtt.h"
#include "log.h"
#include "data.h"
#include "config.h"
void setup() {
delay(500);
Serial.begin(115200);
info("Startup...");
configSetup();
mqttSetup();
wifiSetup();
patrixSetup();

49
lib/patrix/config.cpp Normal file
View File

@ -0,0 +1,49 @@
#include "config.h"
#include "log.h"
#include <nvs_flash.h>
Preferences config;
void configSetup() {
config.begin("config", false);
const String &stored = config.getString("HOSTNAME", "");
if (!stored.equals(HOSTNAME)) {
error(R"([WARNING] Stored config hostname mismatch: "%s" != "%s" [WARNING])", stored.c_str(), HOSTNAME);
}
}
void configReset() {
info("[CONFIG RESET]");
config.end();
nvs_flash_erase();
nvs_flash_init();
config.begin("config", false);
config.putString("HOSTNAME", HOSTNAME);
configLoad();
}
String configGetString(const char *name, const char *fallback, bool allowEmpty) {
if (!config.isKey(name)) {
return fallback;
}
String value = config.getString(name);
if (!allowEmpty && value.isEmpty()) {
return fallback;
}
return value;
}
bool configPutString(const char *name, const char *value) {
return config.putString(name, value) == strlen(value);
}
double configGetDouble(const char *name, double fallback) {
if (!config.isKey(name)) {
return fallback;
}
return config.getDouble(name);
}
bool configPutDouble(const char *name, double fallback) {
return config.value(name, fallback) == 0;
}

20
lib/patrix/config.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef SENSOR3_CONFIG_H
#define SENSOR3_CONFIG_H
#include <Preferences.h>
void configSetup();
void configReset();
void configLoad();
String configGetString(const char *name, const char *fallback, bool allowEmpty);
bool configPutString(const char *name, const char *value);
double configGetDouble(const char *name, double fallback);
bool configPutDouble(const char *name, double value);
#endif

View File

@ -5,11 +5,26 @@
#include <WiFi.h>
#include "mqtt.h"
#include "wifi.h"
#include "config.h"
char consoleBuffer[64] = "";
char *consoleBufferW = consoleBuffer;
void _debug();
void _reboot();
void _usage();
void _info();
void _wifi();
void _mqtt();
void _setConfigString(const char *name, bool allowEmpty);
const char *getFlashChipMode();
void consoleLoop() {
@ -45,84 +60,143 @@ void consoleLoop() {
}
}
void consoleHandle(const char *cmd) {
if (strcmp(cmd, "help") == 0) {
info("help : print this help");
info("info : print system info");
info("reboot : reboot system");
info("wifi : reconnect wifi");
info("mqtt : reconnect mqtt");
info("debug : toggle debug log");
} else if (strcmp(cmd, "info") == 0) {
uint64_t millis = getUptimeMillis();
uint64_t seconds = millis / 1000;
uint32_t minutes = seconds / 60;
uint32_t hours = minutes / 60;
uint16_t days = hours / 24;
char datetime[26];
getDateTime(datetime, sizeof datetime);
info("WiFi:");
info(" hostname: %s", HOSTNAME);
info(" mac: %s", WiFi.macAddress().c_str());
info(" ip: %s", WiFi.localIP().toString().c_str());
info(" gateway: %s", WiFi.gatewayIP().toString().c_str());
info(" ssid: %s", WiFi.SSID().c_str());
info(" bssid: %s", WiFi.BSSIDstr().c_str());
info(" rssi: %d", WiFi.RSSI());
info("Time:");
info(" uptime: %dd %2dh %2dm %2ds", days, hours % 24, minutes % 60, seconds % 60);
info(" sys: %s", datetime);
info("Chip:");
info(" model: %s", ESP.getChipModel());
info(" cores: %d", ESP.getChipCores());
info(" freq: %d", ESP.getCpuFreqMHz());
info("Flash:");
info(" mode: %s", getFlashChipMode());
info(" size: %d", ESP.getFlashChipSize());
info(" speed: %d", ESP.getFlashChipSpeed());
info("Heap:");
info(" size: %d", ESP.getHeapSize());
info(" free: %d", ESP.getFreeHeap());
info(" minFree: %d", ESP.getMinFreeHeap());
info(" maxAlloc: %d", ESP.getMaxAllocHeap());
info("PS RAM:");
info(" size: %d", ESP.getPsramSize());
info(" free: %d", ESP.getFreePsram());
info(" minFree: %d", ESP.getMinFreePsram());
info(" maxAlloc: %d", ESP.getMaxAllocPsram());
info("SDK:");
info(" size: %d", ESP.getSketchSize());
info(" free: %d", ESP.getFreeSketchSpace());
info(" MD5: %s", ESP.getSketchMD5().c_str());
info("SDK:");
info(" version: %s", ESP.getSdkVersion());
} else if (strcmp(cmd, "reboot") == 0) {
info("Rebooting...");
delay(500);
yield();
ESP.restart();
} else if (strcmp(cmd, "wifi") == 0) {
info("Reconnecting WiFi...");
wifiConnect();
} else if (strcmp(cmd, "mqtt") == 0) {
info("Reconnecting MQTT...");
mqttDisconnect();
} else if (strcmp(cmd, "debug") == 0) {
setDebugEnabled(!isDebugEnabled());
info("DEBUG: %s", isDebugEnabled() ? "ON" : "OFF");
void consoleHandle(char *cmd) {
char *first = strtok(cmd, " ");
if (strcmp(first, "help") == 0) {
_usage();
} else if (strcmp(first, "wifi") == 0) {
_wifi();
} else if (strcmp(first, "mqtt") == 0) {
_mqtt();
} else if (strcmp(first, "info") == 0) {
_info();
} else if (strcmp(first, "reboot") == 0) {
_reboot();
} else if (strcmp(first, "debug") == 0) {
_debug();
} else if (strcmp(first, "config reset") == 0) {
configReset();
} else if (!patrix_command((char *) cmd)) {
info("Unknown command: %s", cmd);
}
}
void _usage() {
info("help");
info("info");
info("debug");
info("reboot");
info("config reset");
info("wifi reconnect");
info("wifi ssid <SSID>");
info("wifi pkey <PKEY>");
info("mqtt reconnect");
info("mqtt host <HOST>");
}
void _debug() {
setDebugEnabled(!isDebugEnabled());
info("DEBUG: %s", isDebugEnabled() ? "ON" : "OFF");
}
void _reboot() {
info("Rebooting...");
delay(500);
yield();
ESP.restart();
}
void _mqtt() {
char *sub = strtok(nullptr, " ");
if (strcmp(sub, "reconnect") == 0) {
info("Reconnecting MQTT...");
mqttDisconnect();
} else if (strcmp(sub, "host") == 0) {
_setConfigString("MQTT_HOST", false);
}
}
void _wifi() {
char *sub = strtok(nullptr, " ");
if (strcmp(sub, "reconnect") == 0) {
info("Reconnecting WiFi...");
wifiConnect();
} else if (strcmp(sub, "ssid") == 0) {
_setConfigString("WIFI_SSID", false);
} else if (strcmp(sub, "pkey") == 0) {
_setConfigString("WIFI_PKEY", false);
}
}
void _setConfigString(const char *name, bool allowEmpty) {
char *value = strtok(nullptr, "");
if (!allowEmpty && strcmp(value, "") == 0) {
error(R"(Value for "%s" cannot be empty!")", name);
return;
}
if (!configPutString(name, value)) {
error(R"(Failed to persist "%s" = "%s")", name, value);
return;
}
info(R"(Set "%s" to "%s")", name, value);
}
void _info() {
uint64_t millis = getUptimeMillis();
uint64_t seconds = millis / 1000;
uint32_t minutes = seconds / 60;
uint32_t hours = minutes / 60;
uint16_t days = hours / 24;
char datetime[26];
getDateTime(datetime, sizeof datetime);
info("WiFi:");
info(" hostname: %s", HOSTNAME);
info(" mac: %s", WiFi.macAddress().c_str());
info(" ip: %s", WiFi.localIP().toString().c_str());
info(" gateway: %s", WiFi.gatewayIP().toString().c_str());
info(" ssid: %s", WiFi.SSID().c_str());
info(" bssid: %s", WiFi.BSSIDstr().c_str());
info(" rssi: %d", WiFi.RSSI());
info("Time:");
info(" uptime: %dd %2dh %2dm %2ds", days, hours % 24, minutes % 60, seconds % 60);
info(" sys: %s", datetime);
info("Chip:");
info(" model: %s", ESP.getChipModel());
info(" cores: %d", ESP.getChipCores());
info(" freq: %d", ESP.getCpuFreqMHz());
info("Flash:");
info(" mode: %s", getFlashChipMode());
info(" size: %d", ESP.getFlashChipSize());
info(" speed: %d", ESP.getFlashChipSpeed());
info("Heap:");
info(" size: %d", ESP.getHeapSize());
info(" free: %d", ESP.getFreeHeap());
info(" minFree: %d", ESP.getMinFreeHeap());
info(" maxAlloc: %d", ESP.getMaxAllocHeap());
info("PS RAM:");
info(" size: %d", ESP.getPsramSize());
info(" free: %d", ESP.getFreePsram());
info(" minFree: %d", ESP.getMinFreePsram());
info(" maxAlloc: %d", ESP.getMaxAllocPsram());
info("SDK:");
info(" size: %d", ESP.getSketchSize());
info(" free: %d", ESP.getFreeSketchSpace());
info(" MD5: %s", ESP.getSketchMD5().c_str());
info("SDK:");
info(" version: %s", ESP.getSdkVersion());
}
const char *getFlashChipMode() {
switch (ESP.getFlashChipMode()) {
case FM_QIO:

View File

@ -3,7 +3,7 @@
void consoleLoop();
void consoleHandle(const char *cmd);
void consoleHandle(char *cmd);
bool patrix_command(char *cmd);

View File

@ -36,7 +36,7 @@ void dataLoop() {
}
JsonDocument json;
json["timestamp"] = dataRead->timestamp;
json["value"] = dataRead->value;
json["putDouble"] = dataRead->value;
if (mqttPublishData(dataRead->name, json)) {
dataRead = (dataRead - data + 1) % ENTRY_COUNT + data;
dataCount--;

View File

@ -5,6 +5,7 @@
#include "console.h"
#include "wifi.h"
#include "log.h"
#include "config.h"
#define CONNECT_TIMEOUT_MILLISECONDS 5000
@ -48,9 +49,10 @@ void mqttLoop() {
}
if (isWiFiConnected() && isTimeSet() && !connected && (mqttLastConnectTry == 0 || millis() - mqttLastConnectTry > CONNECT_TIMEOUT_MILLISECONDS)) {
error("MQTT connecting MQTT host: %s", MQTT_HOST);
String host = configGetString("MQTT_HOST", MQTT_HOST, false);
error("MQTT connecting MQTT host: %s", host.c_str());
mqttLastConnectTry = millis();
mqtt.setServer(MQTT_HOST, 1883);
mqtt.setServer(host.c_str(), 1883);
if (!mqtt.connect(HOSTNAME, logTopic, 0, false, "MQTT disconnected")) {
error("MQTT FAILED TO CONNECT");
return;

View File

@ -2,6 +2,7 @@
#include "log.h"
#include "mqtt.h"
#include "console.h"
#include "config.h"
#include <WiFi.h>
#include <ArduinoOTA.h>
@ -55,12 +56,15 @@ void wifiConnect() {
WiFi.setAutoReconnect(false);
yield();
info("WIFI connecting: %s", WIFI_SSID);
String ssid = configGetString("WIFI_SSID", WIFI_SSID, false);
String pkey = configGetString("WIFI_PKEY", WIFI_PKEY, false);
info("WIFI connecting: %s", ssid.c_str());
WiFiClass::hostname(HOSTNAME);
yield();
WiFi.begin(WIFI_SSID, WIFI_PKEY);
WiFi.begin(ssid, pkey);
yield();
}

View File

@ -29,7 +29,7 @@ monitor_port = ${COMMON.monitor_port}
monitor_speed = ${COMMON.monitor_speed}
monitor_filters = ${COMMON.monitor_filters}
lib_deps = ${COMMON.lib_deps}
build_flags = -D HOSTNAME=\"DEV\" -D WIFI_SSID=\"${COMMON.WIFI_SSID}\" -D WIFI_PKEY=\"${COMMON.WIFI_PKEY}\" -D OTA_PASSWORD=\"OtaAuthPatrixDEV\" -D BOOT_DELAY=true -D DEBUG_LOG=true
build_flags = -D HOSTNAME=\"DEV\" -D WIFI_SSID=\"${COMMON.WIFI_SSID}\" -D WIFI_PKEY=\"${COMMON.WIFI_PKEY}\" -D OTA_PASSWORD=\"OtaAuthPatrixDEV\" -D BOOT_DELAY=false -D DEBUG_LOG=false
[env:Fermenter]
upload_port = 10.0.0.138

View File

@ -2,6 +2,7 @@
#include "sensors/Dallas.h"
#include "sensors/DallasSensor.h"
#include "ArduPID.h"
#include "config.h"
#include <Arduino.h>
#define CONTROL_GPIO 4
@ -27,9 +28,9 @@ double integral = 0;
double derivative = 0;
bool setDouble(const char *name, double *destinationPtr, double min, double max);
void patrixSetup() {
configLoad();
analogWriteResolution(CONTROL_PWM_BITS);
pid.begin(&temperatureCurrent, &heaterPWM, &temperatureTarget, proportional, integral, derivative);
@ -37,10 +38,9 @@ void patrixSetup() {
pid.start();
}
void patrixLoop() {
dallas.loop();
sensor.loop();
// dallas.loop();
// sensor.loop();
temperatureCurrent = sensor.getLastValue();
if (!isnan(temperatureCurrent)) {
@ -66,22 +66,8 @@ void patrixLoop() {
}
}
bool patrix_command(char *cmd) {
const char *first = strtok(cmd, " ");
if (strcmp(first, "target") == 0) {
return setDouble("target", &temperatureTarget, -10, 80);
} else if (strcmp(first, "p") == 0) {
return setDouble("proportional", &proportional, NAN, NAN);
} else if (strcmp(first, "i") == 0) {
return setDouble("integral", &integral, NAN, NAN);
} else if (strcmp(first, "p") == 0) {
return setDouble("derivative", &derivative, NAN, NAN);
}
return false;
}
bool setDouble(const char *name, double *destinationPtr, double min, double max) {
const char *valueStr = strtok(nullptr, nullptr);
const char *valueStr = strtok(nullptr, "");
if (valueStr == nullptr) {
error("Missing value for \"%s\"", name);
return false;
@ -95,7 +81,41 @@ bool setDouble(const char *name, double *destinationPtr, double min, double max)
error("Value out of range for \"%s\" [%f..%f]: %f", name, min, max, value);
return false;
}
*destinationPtr = value;
info("Value for \"%s\" set to: %f", name, value);
if (*destinationPtr != value) {
*destinationPtr = value;
info("Value for \"%s\" set to: %f", name, value);
configPutDouble(name, value);
} else {
info("Value for \"%s\" unchanged: %f", name, value);
}
return true;
}
bool patrix_command(char *cmd) {
const char *first = strtok(cmd, " ");
bool result = false;
if (strcmp(first, "over") == 0) {
result = setDouble("over", &temperatureMaxOvershoot, 0, 20);
} else if (strcmp(first, "target") == 0) {
result = setDouble("target", &temperatureTarget, -10, 60);
} else if (strcmp(first, "p") == 0) {
result = setDouble("p", &proportional, NAN, NAN);
} else if (strcmp(first, "i") == 0) {
result = setDouble("i", &integral, NAN, NAN);
} else if (strcmp(first, "d") == 0) {
result = setDouble("d", &derivative, NAN, NAN);
}
if (result) {
pid.setCoefficients(proportional, integral, derivative);
}
return result;
}
void configLoad() {
proportional = configGetDouble("p", 1);
integral = configGetDouble("i", 0);
derivative = configGetDouble("d", 0);
temperatureTarget = configGetDouble("target", 31);
temperatureMaxOvershoot = configGetDouble("over", 5);
pid.setCoefficients(proportional, integral, derivative);
}