Support config file on PC build

This commit is contained in:
Kuba Szczodrzyński 2024-02-07 14:24:11 +01:00
parent 96bfbf397b
commit 0e87f52c1f
No known key found for this signature in database
GPG Key ID: 43037AC62A600562
10 changed files with 138 additions and 44 deletions

View File

@ -214,7 +214,12 @@
/* Workarounds for PC build */
#if HASP_TARGET_PC
#ifndef __FlashStringHelper
#define __FlashStringHelper char
typedef char __FlashStringHelper;
#endif
#if defined(__cplusplus) && !defined(String)
#include <iostream>
using String = std::string;
#endif
#ifndef F

View File

@ -460,10 +460,12 @@ void dispatch_config(const char* topic, const char* payload, uint8_t source)
}
if(strcasecmp_P(topic, PSTR("debug")) == 0) {
#if HASP_TARGET_ARDUINO
if(update)
debugSetConfig(settings);
else
debugGetConfig(settings);
#endif
}
else if(strcasecmp_P(topic, PSTR("gui")) == 0) {
@ -734,7 +736,7 @@ void dispatch_parse_jsonl(std::istream& stream, uint8_t& saved_page_id)
void dispatch_parse_jsonl(const char*, const char* payload, uint8_t source)
{
if(source != TAG_MQTT) saved_jsonl_page = haspPages.get();
#if HASP_USE_CONFIG > 0
#if HASP_USE_CONFIG > 0 && HASP_TARGET_ARDUINO
CharStream stream((char*)payload);
// stream.setTimeout(10);
dispatch_parse_jsonl(stream, saved_jsonl_page);
@ -1510,7 +1512,7 @@ void dispatchSetup()
dispatch_add_command(PSTR("unzip"), filesystemUnzip);
#endif
#endif
#if HASP_USE_CONFIG > 0
#if HASP_USE_CONFIG > 0 && HASP_TARGET_ARDUINO
dispatch_add_command(PSTR("setupap"), oobeFakeSetup);
#endif
/* WARNING: remember to expand the commands array when adding new commands */

View File

@ -8,7 +8,9 @@
#include "hasp_config.h"
#include "hasp_debug.h"
#include "hasp_gui.h"
#if HASP_TARGET_ARDUINO
#include "hal/hasp_hal.h"
#endif
// #include "hasp_ota.h" included in conf
// #include "hasp_filesystem.h" included in conf
@ -21,7 +23,9 @@
#include "EEPROM.h"
#endif
#if HASP_USE_EEPROM > 0
#include "StreamUtils.h" // For EEPromStream
#endif
extern uint16_t dispatchTelePeriod;
extern uint32_t dispatchLastMillis;
@ -29,6 +33,7 @@ extern uint32_t dispatchLastMillis;
extern gui_conf_t gui_settings;
extern dispatch_conf_t dispatch_settings;
#if HASP_TARGET_ARDUINO
void confDebugSet(const __FlashStringHelper* fstr_name)
{
/*char buffer[128];
@ -36,6 +41,7 @@ void confDebugSet(const __FlashStringHelper* fstr_name)
debugPrintln(buffer);*/
LOG_VERBOSE(TAG_CONF, F(D_BULLET "%S set"), fstr_name);
}
#endif
void confDebugSet(const char* fstr_name)
{
/*char buffer[128];
@ -44,6 +50,7 @@ void confDebugSet(const char* fstr_name)
LOG_VERBOSE(TAG_CONF, F(D_BULLET "%s set"), fstr_name);
}
#if HASP_TARGET_ARDUINO
bool configSet(bool& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name)
{
if(!setting.isNull()) {
@ -130,6 +137,7 @@ bool configSet(char *value, size_t size, const JsonVariant& setting, const __Fla
}
return false;
}
#endif
bool configSet(bool& value, const JsonVariant& setting, const char* fstr_name)
{
@ -207,7 +215,9 @@ bool configSet(lv_color_t& value, const JsonVariant& setting, const char* fstr_n
void configSetupDebug(JsonDocument& settings)
{
#if HASP_TARGET_ARDUINO
debugSetup(settings[FPSTR(FP_DEBUG)]);
#endif
debugStart(); // Debug started, now we can use it; HASP header sent
}
@ -239,9 +249,9 @@ void configMaskPasswords(JsonDocument& settings)
DeserializationError configParseFile(String& configFile, JsonDocument& settings)
{
DeserializationError result = DeserializationError::InvalidInput;
#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0
File file = HASP_FS.open(configFile, "r");
DeserializationError result;
if(file) {
// size_t size = file.size();
@ -254,30 +264,51 @@ DeserializationError configParseFile(String& configFile, JsonDocument& settings)
return result;
}
return DeserializationError::InvalidInput;
#elif HASP_TARGET_PC
lv_fs_if_init();
lv_fs_file_t f;
lv_fs_res_t res;
lv_fs_open(&f, "L:/config.json", LV_FS_MODE_RD);
if(res == LV_FS_RES_OK) {
uint32_t size = 0, read = 0;
if(lv_fs_size(&f, &size) == LV_FS_RES_OK && size != 0) {
char* buf = (char*)malloc(size + 1);
if(lv_fs_read(&f, buf, size, &read) == LV_FS_RES_OK && read == size) {
result = deserializeJson(settings, buf);
}
}
lv_fs_close(&f);
return result;
}
LOG_ERROR(TAG_HASP, F("Opening config.json from FS failed %d"), res);
return result;
#else
return DeserializationError::InvalidInput;
return result;
#endif
}
DeserializationError configRead(JsonDocument& settings, bool setupdebug)
{
String configFile((char*)0);
String configFile;
configFile.reserve(32);
configFile = String(FPSTR(FP_HASP_CONFIG_FILE));
DeserializationError error;
#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0
if(setupdebug) configSetupDebug(settings); // Now we can use log
#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 || HASP_TARGET_PC
error = configParseFile(configFile, settings);
if(!error) {
String output, wifiPass, mqttPass, httpPass, wgPrivKey;
/* Load Debug params */
if(setupdebug) {
configSetupDebug(settings); // Now we can use log
LOG_INFO(TAG_CONF, F("SPI flash FS mounted"));
#if HASP_TARGET_ARDUINO
filesystemInfo();
filesystemList();
#endif
}
LOG_TRACE(TAG_CONF, F(D_FILE_LOADING), configFile.c_str());
@ -304,9 +335,6 @@ DeserializationError configRead(JsonDocument& settings, bool setupdebug)
#endif
// File does not exist or error reading file
if(setupdebug) configSetupDebug(settings); // Now we can use log
#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0
LOG_ERROR(TAG_CONF, F(D_FILE_LOAD_FAILED), configFile.c_str());
#endif
@ -360,11 +388,11 @@ void configBackupToEeprom()
*/
void configWrite()
{
String configFile((char*)0);
String configFile;
configFile.reserve(32);
configFile = String(FPSTR(FP_HASP_CONFIG_FILE));
String settingsChanged((char*)0);
String settingsChanged;
settingsChanged.reserve(128);
settingsChanged = F(D_CONFIG_CHANGED);
@ -462,6 +490,7 @@ void configWrite()
}
#endif
#if HASP_TARGET_ARDUINO
module = FPSTR(FP_DEBUG);
if(settings[module].as<JsonObject>().isNull()) settings.createNestedObject(module);
changed = debugGetConfig(settings[module]);
@ -470,6 +499,7 @@ void configWrite()
configOutput(settings[module], TAG_DEBG);
writefile = true;
}
#endif
if(settings[FPSTR(FP_GUI)].as<JsonObject>().isNull()) settings.createNestedObject(FPSTR(FP_GUI));
changed = guiGetConfig(settings[FPSTR(FP_GUI)]);
@ -561,9 +591,10 @@ void configSetup()
configRead(settings, true);
}
// #if HASP_USE_SPIFFS > 0
#if HASP_TARGET_ARDUINO
LOG_INFO(TAG_DEBG, F("Loading debug settings"));
debugSetConfig(settings[FPSTR(FP_DEBUG)]);
#endif
LOG_INFO(TAG_GPIO, F("Loading GUI settings"));
guiSetConfig(settings[FPSTR(FP_GUI)]);
LOG_INFO(TAG_HASP, F("Loading HASP settings"));
@ -615,15 +646,15 @@ void configLoop(void)
void configOutput(const JsonObject& settings, uint8_t tag)
{
String output((char*)0);
String output;
output.reserve(128);
serializeJson(settings, output);
String passmask((char*)0);
String passmask;
passmask.reserve(128);
passmask = F("\"pass\":\"" D_PASSWORD_MASK "\"");
String password((char*)0);
String password;
password.reserve(128);
String pass = F("pass");
@ -631,28 +662,48 @@ void configOutput(const JsonObject& settings, uint8_t tag)
password = F("\"pass\":\"");
password += settings[pass].as<String>();
password += F("\"");
#if HASP_TARGET_ARDUINO
output.replace(password, passmask);
#elif HASP_TARGET_PC
size_t pos = 0;
if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask);
#endif
}
if(!settings[FPSTR(FP_WIFI)][pass].isNull()) {
password = F("\"pass\":\"");
password += settings[FPSTR(FP_WIFI)][pass].as<String>();
password += F("\"");
#if HASP_TARGET_ARDUINO
output.replace(password, passmask);
#elif HASP_TARGET_PC
size_t pos = 0;
if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask);
#endif
}
if(!settings[FPSTR(FP_MQTT)][pass].isNull()) {
password = F("\"pass\":\"");
password += settings[FPSTR(FP_MQTT)][pass].as<String>();
password += F("\"");
#if HASP_TARGET_ARDUINO
output.replace(password, passmask);
#elif HASP_TARGET_PC
size_t pos = 0;
if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask);
#endif
}
if(!settings[FPSTR(FP_HTTP)][pass].isNull()) {
password = F("\"pass\":\"");
password += settings[FPSTR(FP_HTTP)][pass].as<String>();
password += F("\"");
#if HASP_TARGET_ARDUINO
output.replace(password, passmask);
#elif HASP_TARGET_PC
size_t pos = 0;
if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask);
#endif
}
if(!settings[FPSTR(FP_WG)][FPSTR(FP_CONFIG_PRIVATE_KEY)].isNull()) {
@ -660,7 +711,12 @@ void configOutput(const JsonObject& settings, uint8_t tag)
password += settings[FPSTR(FP_WG)][FPSTR(FP_CONFIG_PRIVATE_KEY)].as<String>();
password += F("\"");
passmask = F("\"privkey\":\"" D_PASSWORD_MASK "\"");
#if HASP_TARGET_ARDUINO
output.replace(password, passmask);
#elif HASP_TARGET_PC
size_t pos = 0;
if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask);
#endif
}
LOG_VERBOSE(tag, output.c_str());
@ -688,4 +744,4 @@ bool configClearEeprom()
#endif
}
#endif // HAS_USE_CONFIG
#endif // HAS_USE_CONFIG

View File

@ -25,13 +25,15 @@ void configOutput(const JsonObject& settings, uint8_t tag);
bool configClearEeprom(void);
/* ===== Getter and Setter Functions ===== */
#if HASP_TARGET_ARDUINO
bool configSet(bool& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
bool configSet(int8_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
bool configSet(uint8_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
bool configSet(uint16_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
bool configSet(int32_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
bool configSet(lv_color_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
bool configSet(char *value, size_t size, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
bool configSet(char* value, size_t size, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
#endif
bool configSet(bool& value, const JsonVariant& setting, const char* fstr_name);
bool configSet(int8_t& value, const JsonVariant& setting, const char* fstr_name);
bool configSet(uint8_t& value, const JsonVariant& setting, const char* fstr_name);
@ -41,8 +43,10 @@ bool configSet(lv_color_t& value, const JsonVariant& setting, const char* fstr_n
void configMaskPasswords(JsonDocument& settings);
/* ===== Read/Write Configuration ===== */
#if HASP_TARGET_ARDUINO
void configSetConfig(JsonObject& settings);
void configGetConfig(JsonDocument& settings);
#endif
/* json keys used in the configfile */
const char FP_CONFIG_STARTPAGE[] PROGMEM = "startpage";
@ -107,4 +111,4 @@ const char FP_OTA[] PROGMEM = "ota";
#endif
#endif // HASP_USE_CONFIG
#endif // HASP_USE_CONFIG

View File

@ -8,12 +8,12 @@
#include "hasp_debug.h"
#include "hasp_macro.h"
#if(!defined(WINDOWS)) && (!defined(POSIX))
#if HASP_TARGET_ARDUINO
#define debug_print(io, ...) io->printf(__VA_ARGS__)
#define debug_newline(io) io->println()
#else
#elif HASP_TARGET_PC
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
@ -21,6 +21,17 @@
#define debug_print(io, ...) fprintf(stdout, __VA_ARGS__)
#define debug_newline(io) fprintf(stdout, "\n")
#if defined(WINDOWS)
#include <windows.h>
#include <direct.h>
#define cwd _getcwd
#endif
#if defined(POSIX)
#include <unistd.h>
#define cwd getcwd
#endif
#endif
bool debugAnsiCodes = false;
@ -121,6 +132,8 @@ void debugStart(void)
debugPrintHaspHeader(NULL);
debug_newline();
char curdir[PATH_MAX];
LOG_INFO(TAG_DEBG, F("Configuration directory: %s"), cwd(curdir, sizeof(curdir)));
LOG_INFO(TAG_DEBG, F("Environment: " PIOENV));
LOG_INFO(TAG_DEBG, F("Console started"));
@ -445,4 +458,4 @@ void debugPrintPrefix(uint8_t tag, int level, Print* _logOutput)
#else
debug_print(_logOutput, PSTR(" %s: "), buffer);
#endif
}
}

View File

@ -207,21 +207,7 @@ static inline void gui_init_images()
static inline void gui_init_filesystems()
{
#if LV_USE_FS_IF != 0
//_lv_fs_init(); // lvgl File System -- not needed, it done in lv_init() when LV_USE_FILESYSTEM is set
LOG_VERBOSE(TAG_LVGL, F("Filesystem : " D_SETTING_ENABLED));
lv_fs_if_init(); // auxiliary file system drivers
// filesystem_list_path("L:/");
lv_fs_file_t f;
lv_fs_res_t res;
res = lv_fs_open(&f, "L:/config.json", LV_FS_MODE_RD);
if(res == LV_FS_RES_OK) {
LOG_VERBOSE(TAG_HASP, F("TEST Opening config.json OK"));
lv_fs_close(&f);
} else {
LOG_ERROR(TAG_HASP, F("TEST Opening config.json from FS failed %d"), res);
}
#else
LOG_VERBOSE(TAG_LVGL, F("Filesystem : " D_SETTING_DISABLED));
#endif

View File

@ -112,15 +112,15 @@ void InitializeConsoleOutput()
void setup()
{
// Load Settings
// Init debug log
// debug_init();
// Initialize lvgl environment
lv_init();
lv_log_register_print_cb(debugLvglLogEvent);
// Read & Apply User Configuration
#if HASP_USE_CONFIG > 0
configSetup();
#endif
haspDevice.init(); // hardware setup
haspDevice.show_info(); // debug info
// hal_setup();

View File

@ -8,12 +8,14 @@
#if HASP_USE_MQTT > 0
#ifdef HASP_USE_PAHO
#if !HASP_USE_CONFIG
const char FP_CONFIG_HOST[] PROGMEM = "host";
const char FP_CONFIG_PORT[] PROGMEM = "port";
const char FP_CONFIG_NAME[] PROGMEM = "name";
const char FP_CONFIG_USER[] PROGMEM = "user";
const char FP_CONFIG_PASS[] PROGMEM = "pass";
const char FP_CONFIG_GROUP[] PROGMEM = "group";
#endif
/*******************************************************************************
* Copyright (c) 2012, 2020 IBM Corp.
@ -411,6 +413,32 @@ void mqtt_get_info(JsonDocument& doc)
info[F(D_INFO_FAILED)] = mqttFailedCount;
}
bool mqttGetConfig(const JsonObject& settings)
{
bool changed = false;
if(strcmp(haspDevice.get_hostname(), settings[FPSTR(FP_CONFIG_NAME)].as<String>().c_str()) != 0) changed = true;
settings[FPSTR(FP_CONFIG_NAME)] = haspDevice.get_hostname();
if(mqttGroupName != settings[FPSTR(FP_CONFIG_GROUP)].as<String>()) changed = true;
settings[FPSTR(FP_CONFIG_GROUP)] = mqttGroupName;
if(mqttServer != settings[FPSTR(FP_CONFIG_HOST)].as<String>()) changed = true;
settings[FPSTR(FP_CONFIG_HOST)] = mqttServer;
if(mqttPort != settings[FPSTR(FP_CONFIG_PORT)].as<uint16_t>()) changed = true;
settings[FPSTR(FP_CONFIG_PORT)] = mqttPort;
if(mqttUsername != settings[FPSTR(FP_CONFIG_USER)].as<String>()) changed = true;
settings[FPSTR(FP_CONFIG_USER)] = mqttUsername;
if(mqttPassword != settings[FPSTR(FP_CONFIG_PASS)].as<String>()) changed = true;
settings[FPSTR(FP_CONFIG_PASS)] = mqttPassword;
if(changed) configOutput(settings, TAG_MQTT);
return changed;
}
/** Set MQTT Configuration.
*
* Read the settings from json and sets the application variables.

View File

@ -22,7 +22,7 @@ build_flags =
-D HASP_USE_LITTLEFS=0
-D HASP_USE_EEPROM=0
-D HASP_USE_GPIO=1
-D HASP_USE_CONFIG=0 ; Standalone application, as library
-D HASP_USE_CONFIG=1 ; Standalone application, as library
-D HASP_USE_DEBUG=1
-D HASP_USE_PNGDECODE=1
-D HASP_USE_BMPDECODE=1

View File

@ -26,7 +26,7 @@ build_flags =
-D HASP_USE_LITTLEFS=0
-D HASP_USE_EEPROM=0
-D HASP_USE_GPIO=1
-D HASP_USE_CONFIG=0 ; Standalone application, as library
-D HASP_USE_CONFIG=1 ; Standalone application, as library
-D HASP_USE_DEBUG=1
-D HASP_USE_PNGDECODE=1
-D HASP_USE_BMPDECODE=1