This commit is contained in:
Ken Van Hoeylandt 2026-08-08 21:43:46 +02:00
parent 87f4985037
commit e1fb827548
15 changed files with 167 additions and 507 deletions

View File

@ -5,9 +5,10 @@ idf_component_register(
"Libraries/TactilityFreeRtos/Include"
"Libraries/lvgl/include"
"Libraries/minmea/include"
"Libraries/minitar/include"
"Modules/lvgl-module/include"
# DRIVER_INCLUDE_DIRS_PLACEHOLDER
REQUIRES esp_timer minitar app-module crypt-module gps-module lvgl-module lvgl-window-manager-module service-module
REQUIRES esp_timer app-module crypt-module gps-module lvgl-module lvgl-window-manager-module service-module
)
# Regular and core features
@ -15,8 +16,10 @@ add_prebuilt_library(TactilityC Libraries/TactilityC/binary/libTactilityC.a)
add_prebuilt_library(TactilityKernel Libraries/TactilityKernel/binary/libTactilityKernel.a)
add_prebuilt_library(lvgl Libraries/lvgl/binary/liblvgl.a)
add_prebuilt_library(minmea Libraries/minmea/binary/libminmea.a)
add_prebuilt_library(minitar Libraries/minitar/binary/libminitar.a)
target_link_libraries(${COMPONENT_LIB} INTERFACE TactilityC)
target_link_libraries(${COMPONENT_LIB} INTERFACE TactilityKernel)
target_link_libraries(${COMPONENT_LIB} INTERFACE lvgl)
target_link_libraries(${COMPONENT_LIB} INTERFACE minmea)
target_link_libraries(${COMPONENT_LIB} INTERFACE minitar)

View File

@ -185,6 +185,10 @@ def main():
# elf_loader
{'src': 'Libraries/elf_loader/elf_loader.cmake', 'dst': 'Libraries/elf_loader/'},
{'src': 'Libraries/elf_loader/license.txt', 'dst': 'Libraries/elf_loader/'},
# minitar
{'src': 'build/esp-idf/minitar/libminitar.a', 'dst': 'Libraries/minitar/binary/'},
{'src': 'Libraries/minitar/minitar/minitar.h', 'dst': 'Libraries/minitar/include/'},
{'src': 'Libraries/minitar/minitar/LICENSE*', 'dst': 'Libraries/minitar/'},
# minmea
{'src': 'build/esp-idf/minmea/libminmea.a', 'dst': 'Libraries/minmea/binary/'},
{'src': 'Libraries/minmea/Include/**', 'dst': 'Libraries/minmea/include/'},

View File

@ -1,10 +1,3 @@
dependencies:
- Platforms/platform-esp32
# Add all driver modules because the generic devices are used to build the SDK
- Drivers/bm8563-module
- Drivers/bmi270-module
- Drivers/mpu6886-module
- Drivers/pi4ioe5v6408-module
- Drivers/qmi8658-module
- Drivers/rx8130ce-module
dts: generic,esp32.dts

View File

@ -1,10 +1,3 @@
dependencies:
- Platforms/platform-esp32
# Add all driver modules because the generic devices are used to build the SDK
- Drivers/bm8563-module
- Drivers/bmi270-module
- Drivers/mpu6886-module
- Drivers/pi4ioe5v6408-module
- Drivers/qmi8658-module
- Drivers/rx8130ce-module
dts: generic,esp32c6.dts

View File

@ -1,11 +1,3 @@
dependencies:
- Platforms/platform-esp32
# Add all driver modules because the generic devices are used to build the SDK
- Drivers/bm8563-module
- Drivers/bmi270-module
- Drivers/mpu6886-module
- Drivers/pi4ioe5v6408-module
- Drivers/qmi8658-module
- Drivers/rx8130ce-module
- Drivers/sc2356-module
dts: generic,esp32p4.dts

View File

@ -1,10 +1,3 @@
dependencies:
- Platforms/platform-esp32
# Add all driver modules because the generic devices are used to build the SDK
- Drivers/bm8563-module
- Drivers/bmi270-module
- Drivers/mpu6886-module
- Drivers/pi4ioe5v6408-module
- Drivers/qmi8658-module
- Drivers/rx8130ce-module
dts: generic,esp32s3.dts

View File

@ -1,55 +0,0 @@
/**
* @brief key-value storage for general purpose.
* Maps strings on a fixed set of data types.
*/
#pragma once
#include <cstdint>
#include <string>
namespace tt {
/**
* A dictionary that maps keys (strings) onto several atomary types.
* Thin C++ wrapper around TactilityKernel's C Bundle (tactility/bundle.h).
*/
class Bundle final {
// Actually a TactilityKernel ::Bundle* (tactility/bundle.h), cast in Bundle.cpp - kept as
// void* here rather than a forward-declared `struct Bundle*` so this header doesn't put a
// second, unqualified `Bundle` name in scope: any TU with `using namespace tt;` in effect
// (e.g. tests) would then find both `::Bundle` and `tt::Bundle` for a bare `Bundle` lookup
// and fail with "reference to 'Bundle' is ambiguous".
void* handle;
public:
Bundle();
Bundle(const Bundle& bundle);
Bundle& operator=(const Bundle& bundle);
~Bundle();
bool getBool(const std::string& key) const;
int32_t getInt32(const std::string& key) const;
int64_t getInt64(const std::string& key) const;
std::string getString(const std::string& key) const;
bool hasBool(const std::string& key) const;
bool hasInt32(const std::string& key) const;
bool hasInt64(const std::string& key) const;
bool hasString(const std::string& key) const;
bool optBool(const std::string& key, bool& out) const;
bool optInt32(const std::string& key, int32_t& out) const;
bool optInt64(const std::string& key, int64_t& out) const;
bool optString(const std::string& key, std::string& out) const;
void putBool(const std::string& key, bool value);
void putInt32(const std::string& key, int32_t value);
void putInt64(const std::string& key, int64_t value);
void putString(const std::string& key, const std::string& value);
};
} // namespace

View File

@ -1,41 +0,0 @@
#pragma once
#include <cstdint>
#include <string>
namespace tt {
/**
* Settings that persist on NVS flash for ESP32.
* On simulator, the settings are only in-memory.
*
* Note that on ESP32, there are limitations:
* - namespace name is limited by NVS_NS_NAME_MAX_SIZE (generally 16 characters)
* - key is limited by NVS_KEY_NAME_MAX_SIZE (generally 16 characters)
*/
class Preferences {
const char* namespace_;
public:
explicit Preferences(const char* namespace_) {
this->namespace_ = namespace_;
}
bool hasBool(const std::string& key) const;
bool hasInt32(const std::string& key) const;
bool hasInt64(const std::string& key) const;
bool hasString(const std::string& key) const;
bool optBool(const std::string& key, bool& out) const;
bool optInt32(const std::string& key, int32_t& out) const;
bool optInt64(const std::string& key, int64_t& out) const;
bool optString(const std::string& key, std::string& out) const;
void putBool(const std::string& key, bool value);
void putInt32(const std::string& key, int32_t value);
void putInt64(const std::string& key, int64_t value);
void putString(const std::string& key, const std::string& value);
};
} // namespace

View File

@ -1,113 +0,0 @@
#include "Tactility/Bundle.h"
#include <tactility/bundle.h>
#include <vector>
namespace tt {
namespace {
::Bundle* as_kernel(void* handle) { return static_cast<::Bundle*>(handle); }
} // namespace
Bundle::Bundle() : handle(bundle_alloc()) {}
Bundle::Bundle(const Bundle& bundle) : handle(bundle_clone(as_kernel(bundle.handle))) {}
Bundle& Bundle::operator=(const Bundle& bundle) {
if (this != &bundle) {
::Bundle* cloned = bundle_clone(as_kernel(bundle.handle));
bundle_free(as_kernel(handle));
handle = cloned;
}
return *this;
}
Bundle::~Bundle() {
bundle_free(as_kernel(handle));
}
bool Bundle::getBool(const std::string& key) const {
return bundle_get_bool(as_kernel(handle), key.c_str());
}
int32_t Bundle::getInt32(const std::string& key) const {
return bundle_get_int32(as_kernel(handle), key.c_str());
}
int64_t Bundle::getInt64(const std::string& key) const {
return bundle_get_int64(as_kernel(handle), key.c_str());
}
std::string Bundle::getString(const std::string& key) const {
// bundle_get_string() needs a bounded buffer; grow and retry until it fits.
std::vector<char> buffer(64);
while (true) {
error_t error = bundle_get_string(as_kernel(handle), key.c_str(), buffer.data(), buffer.size());
if (error == ERROR_NONE) {
return std::string(buffer.data());
}
buffer.resize(buffer.size() * 2);
}
}
bool Bundle::hasBool(const std::string& key) const {
return bundle_has_bool(as_kernel(handle), key.c_str());
}
bool Bundle::hasInt32(const std::string& key) const {
return bundle_has_int32(as_kernel(handle), key.c_str());
}
bool Bundle::hasInt64(const std::string& key) const {
return bundle_has_int64(as_kernel(handle), key.c_str());
}
bool Bundle::hasString(const std::string& key) const {
return bundle_has_string(as_kernel(handle), key.c_str());
}
bool Bundle::optBool(const std::string& key, bool& out) const {
return bundle_opt_bool(as_kernel(handle), key.c_str(), &out);
}
bool Bundle::optInt32(const std::string& key, int32_t& out) const {
return bundle_opt_int32(as_kernel(handle), key.c_str(), &out);
}
bool Bundle::optInt64(const std::string& key, int64_t& out) const {
return bundle_opt_int64(as_kernel(handle), key.c_str(), &out);
}
bool Bundle::optString(const std::string& key, std::string& out) const {
std::vector<char> buffer(64);
while (true) {
error_t error = bundle_opt_string(as_kernel(handle), key.c_str(), buffer.data(), buffer.size());
if (error == ERROR_NONE) {
out = buffer.data();
return true;
}
if (error == ERROR_NOT_FOUND) {
return false;
}
buffer.resize(buffer.size() * 2);
}
}
void Bundle::putBool(const std::string& key, bool value) {
bundle_put_bool(as_kernel(handle), key.c_str(), value);
}
void Bundle::putInt32(const std::string& key, int32_t value) {
bundle_put_int32(as_kernel(handle), key.c_str(), value);
}
void Bundle::putInt64(const std::string& key, int64_t value) {
bundle_put_int64(as_kernel(handle), key.c_str(), value);
}
void Bundle::putString(const std::string& key, const std::string& value) {
bundle_put_string(as_kernel(handle), key.c_str(), value.c_str());
}
} // namespace

View File

@ -1,147 +0,0 @@
#ifdef ESP_PLATFORM
#include <Tactility/Preferences.h>
#include <Tactility/TactilityCore.h>
#include <nvs_flash.h>
#include <tactility/log.h>
namespace tt {
constexpr auto* TAG = "Preferences";
bool Preferences::optBool(const std::string& key, bool& out) const {
nvs_handle_t handle;
if (nvs_open(namespace_, NVS_READWRITE, &handle) != ESP_OK) {
LOG_E(TAG, "Failed to open namespace %s", namespace_);
return false;
} else {
uint8_t out_number;
bool success = nvs_get_u8(handle, key.c_str(), &out_number) == ESP_OK;
nvs_close(handle);
if (success) {
out = (bool)out_number;
}
return success;
}
}
bool Preferences::optInt32(const std::string& key, int32_t& out) const {
nvs_handle_t handle;
if (nvs_open(namespace_, NVS_READWRITE, &handle) != ESP_OK) {
LOG_E(TAG, "Failed to open namespace %s", namespace_);
return false;
} else {
bool success = nvs_get_i32(handle, key.c_str(), &out) == ESP_OK;
nvs_close(handle);
return success;
}
}
bool Preferences::optInt64(const std::string& key, int64_t& out) const {
nvs_handle_t handle;
if (nvs_open(namespace_, NVS_READWRITE, &handle) != ESP_OK) {
LOG_E(TAG, "Failed to open namespace %s", namespace_);
return false;
} else {
bool success = nvs_get_i64(handle, key.c_str(), &out) == ESP_OK;
nvs_close(handle);
return success;
}
}
bool Preferences::optString(const std::string& key, std::string& out) const {
nvs_handle_t handle;
if (nvs_open(namespace_, NVS_READWRITE, &handle) != ESP_OK) {
LOG_E(TAG, "Failed to open namespace %s", namespace_);
return false;
} else {
size_t out_size = 256;
char* out_data = static_cast<char*>(malloc(out_size));
bool success = nvs_get_str(handle, key.c_str(), out_data, &out_size) == ESP_OK;
nvs_close(handle);
out = out_data;
free(out_data);
return success;
}
}
bool Preferences::hasBool(const std::string& key) const {
bool temp;
return optBool(key, temp);
}
bool Preferences::hasInt32(const std::string& key) const {
int32_t temp;
return optInt32(key, temp);
}
bool Preferences::hasInt64(const std::string& key) const {
int64_t temp;
return optInt64(key, temp);
}
bool Preferences::hasString(const std::string& key) const {
std::string temp;
return optString(key, temp);
}
void Preferences::putBool(const std::string& key, bool value) {
nvs_handle_t handle;
if (nvs_open(namespace_, NVS_READWRITE, &handle) == ESP_OK) {
if (nvs_set_u8(handle, key.c_str(), value) != ESP_OK) {
LOG_E(TAG, "Failed to set %s:%s", namespace_, key.c_str());
} else if (nvs_commit(handle) != ESP_OK) {
LOG_E(TAG, "Failed to commit %s:%s", namespace_, key.c_str());
}
nvs_close(handle);
} else {
LOG_E(TAG, "Failed to open namespace %s", namespace_);
}
}
void Preferences::putInt32(const std::string& key, int32_t value) {
nvs_handle_t handle;
if (nvs_open(namespace_, NVS_READWRITE, &handle) == ESP_OK) {
if (nvs_set_i32(handle, key.c_str(), value) != ESP_OK) {
LOG_E(TAG, "Failed to set %s:%s", namespace_, key.c_str());
} else if (nvs_commit(handle) != ESP_OK) {
LOG_E(TAG, "Failed to commit %s:%s", namespace_, key.c_str());
}
nvs_close(handle);
} else {
LOG_E(TAG, "Failed to open namespace %s", namespace_);
}
}
void Preferences::putInt64(const std::string& key, int64_t value) {
nvs_handle_t handle;
if (nvs_open(namespace_, NVS_READWRITE, &handle) == ESP_OK) {
if (nvs_set_i64(handle, key.c_str(), value) != ESP_OK) {
LOG_E(TAG, "Failed to set %s:%s", namespace_, key.c_str());
} else if (nvs_commit(handle) != ESP_OK) {
LOG_E(TAG, "Failed to commit %s:%s", namespace_, key.c_str());
}
nvs_close(handle);
} else {
LOG_E(TAG, "Failed to open namespace %s", namespace_);
}
}
void Preferences::putString(const std::string& key, const std::string& text) {
nvs_handle_t handle;
if (nvs_open(namespace_, NVS_READWRITE, &handle) == ESP_OK) {
if (nvs_set_str(handle, key.c_str(), text.c_str()) != ESP_OK) {
LOG_E(TAG, "Failed to set %s:%s", namespace_, key.c_str());
} else if (nvs_commit(handle) != ESP_OK) {
LOG_E(TAG, "Failed to commit %s:%s", namespace_, key.c_str());
}
nvs_close(handle);
} else {
LOG_E(TAG, "Failed to open namespace %s", namespace_);
}
}
} // namespace
#endif

View File

@ -1,84 +0,0 @@
#ifndef ESP_PLATFOM
#include <Tactility/Preferences.h>
#include <Tactility/Bundle.h>
namespace tt {
static Bundle preferences;
/**
* Creates a string that is effectively "namespace:key" so we can create a single map (bundle)
* to store all the key/value pairs.
*
* @param[in] namespace
* @param[in] key
* @param[out] out
*/
std::string get_bundle_key(const std::string& namespace_, const std::string& key) {
return namespace_ + ':' + key;
}
bool Preferences::hasBool(const std::string& key) const {
std::string bundle_key = get_bundle_key(namespace_, key);
return preferences.hasBool(bundle_key);
}
bool Preferences::hasInt32(const std::string& key) const {
std::string bundle_key = get_bundle_key(namespace_, key);
return preferences.hasInt32(bundle_key);
}
bool Preferences::hasInt64(const std::string& key) const {
std::string bundle_key = get_bundle_key(namespace_, key);
return preferences.hasInt64(bundle_key);
}
bool Preferences::hasString(const std::string& key) const {
std::string bundle_key = get_bundle_key(namespace_, key);
return preferences.hasString(bundle_key);
}
bool Preferences::optBool(const std::string& key, bool& out) const {
std::string bundle_key = get_bundle_key(namespace_, key);
return preferences.optBool(bundle_key, out);
}
bool Preferences::optInt32(const std::string& key, int32_t& out) const {
std::string bundle_key = get_bundle_key(namespace_, key);
return preferences.optInt32(bundle_key, out);
}
bool Preferences::optInt64(const std::string& key, int64_t& out) const {
std::string bundle_key = get_bundle_key(namespace_, key);
return preferences.optInt64(bundle_key, out);
}
bool Preferences::optString(const std::string& key, std::string& out) const {
std::string bundle_key = get_bundle_key(namespace_, key);
return preferences.optString(bundle_key, out);
}
void Preferences::putBool(const std::string& key, bool value) {
std::string bundle_key = get_bundle_key(namespace_, key);
return preferences.putBool(bundle_key, value);
}
void Preferences::putInt32(const std::string& key, int32_t value) {
std::string bundle_key = get_bundle_key(namespace_, key);
return preferences.putInt32(bundle_key, value);
}
void Preferences::putInt64(const std::string& key, int64_t value) {
std::string bundle_key = get_bundle_key(namespace_, key);
return preferences.putInt64(bundle_key, value);
}
void Preferences::putString(const std::string& key, const std::string& value) {
std::string bundle_key = get_bundle_key(namespace_, key);
return preferences.putString(bundle_key, value);
}
#endif
} // namespace

View File

@ -1,7 +1,6 @@
#include <Tactility/app/i2cscanner/I2cHelpers.h>
#include <Tactility/app/i2cscanner/I2cScannerPrivate.h>
#include <Tactility/LogMessages.h>
#include <Tactility/Preferences.h>
#include <Tactility/RecursiveMutex.h>
#include <Tactility/Timer.h>
@ -13,6 +12,8 @@
#include <tactility/drivers/i2c_controller.h>
#include <tactility/log.h>
#include <tactility/paths.h>
#include <tactility/preferences.h>
#include <cassert>
#include <format>
@ -52,15 +53,40 @@ struct Context {
#define PREFERENCES_BUS_INDEX_KEY "bus"
bool getPreferencesPath(std::string& outPath) {
char root[128];
if (paths_get_user_data_path(root, sizeof(root)) != ERROR_NONE) {
return false;
}
outPath = std::string(root) + "/i2c_scanner.properties";
return true;
}
void setLastBusIndex(int32_t index) {
auto prefs = Preferences("i2c_scanner");
prefs.putInt32(PREFERENCES_BUS_INDEX_KEY, index);
std::string path;
if (!getPreferencesPath(path)) {
return;
}
Preferences* prefs = preferences_open(path.c_str());
if (prefs == nullptr) {
return;
}
preferences_put_int32(prefs, PREFERENCES_BUS_INDEX_KEY, index);
preferences_close(prefs);
}
int32_t getLastBusIndex() {
auto prefs = Preferences("i2c_scanner");
std::string path;
if (!getPreferencesPath(path)) {
return 0;
}
Preferences* prefs = preferences_open(path.c_str());
if (prefs == nullptr) {
return 0;
}
int32_t index = 0;
prefs.optInt32(PREFERENCES_BUS_INDEX_KEY, index);
preferences_opt_int32(prefs, PREFERENCES_BUS_INDEX_KEY, &index);
preferences_close(prefs);
return index;
}

View File

@ -1,5 +1,4 @@
#include <Tactility/app/setup/Setup.h>
#include <Tactility/Preferences.h>
#include <Tactility/StringUtils.h>
#include <Tactility/app/timezone/TimeZone.h>
#include <Tactility/app/wifimanage/WifiManage.h>
@ -11,6 +10,9 @@
#include <lvgl_window_manager/window_manager.h>
#include <tactility/paths.h>
#include <tactility/preferences.h>
#include <lvgl/fonts.h>
#include <lvgl/lvgl.h>
#include <lvgl.h>
@ -33,18 +35,47 @@ extern const ::AppManifest manifest;
constexpr auto* PREFERENCES_NAMESPACE = "setup";
constexpr auto* PREFERENCES_KEY_COMPLETED = "completed";
namespace {
bool getPreferencesPath(std::string& outPath) {
char root[128];
if (paths_get_user_data_path(root, sizeof(root)) != ERROR_NONE) {
return false;
}
outPath = std::string(root) + "/" + PREFERENCES_NAMESPACE + ".properties";
return true;
}
} // namespace
bool isCompleted() {
Preferences preferences(PREFERENCES_NAMESPACE);
std::string path;
if (!getPreferencesPath(path)) {
return false;
}
Preferences* preferences = preferences_open(path.c_str());
if (preferences == nullptr) {
return false;
}
bool completed = false;
preferences.optBool(PREFERENCES_KEY_COMPLETED, completed);
preferences_opt_bool(preferences, PREFERENCES_KEY_COMPLETED, &completed);
preferences_close(preferences);
return completed;
}
namespace {
void markCompleted() {
Preferences preferences(PREFERENCES_NAMESPACE);
preferences.putBool(PREFERENCES_KEY_COMPLETED, true);
std::string path;
if (!getPreferencesPath(path)) {
return;
}
Preferences* preferences = preferences_open(path.c_str());
if (preferences == nullptr) {
return;
}
preferences_put_bool(preferences, PREFERENCES_KEY_COMPLETED, true);
preferences_close(preferences);
}
enum class Phase {

View File

@ -1,9 +1,10 @@
#include <Tactility/network/NtpPrivate.h>
#include <Tactility/Preferences.h>
#include <tactility/log.h>
#include <tactility/paths.h>
#include <tactility/preferences.h>
#include <memory>
#include <string>
#ifdef ESP_PLATFORM
#include <Tactility/TactilityCore.h>
@ -20,24 +21,49 @@ static bool processedSyncEvent = false;
#ifdef ESP_PLATFORM
static bool getPreferencesPath(std::string& outPath) {
char root[128];
if (paths_get_user_data_path(root, sizeof(root)) != ERROR_NONE) {
return false;
}
outPath = std::string(root) + "/time.properties";
return true;
}
void storeTimeInNvs() {
time_t now;
time(&now);
auto preferences = std::make_unique<Preferences>("time");
preferences->putInt64("syncTime", now);
std::string path;
if (!getPreferencesPath(path)) {
return;
}
Preferences* preferences = preferences_open(path.c_str());
if (preferences == nullptr) {
return;
}
preferences_put_int64(preferences, "syncTime", now);
preferences_close(preferences);
LOG_I(TAG, "Stored time %ld", (long)now);
}
void setTimeFromNvs() {
auto preferences = std::make_unique<Preferences>("time");
time_t synced_time;
if (preferences->optInt64("syncTime", synced_time)) {
std::string path;
if (!getPreferencesPath(path)) {
return;
}
Preferences* preferences = preferences_open(path.c_str());
if (preferences == nullptr) {
return;
}
int64_t synced_time = 0;
if (preferences_opt_int64(preferences, "syncTime", &synced_time)) {
LOG_I(TAG, "Restoring last known time to %ld", (long)synced_time);
timeval get_nvs_time;
get_nvs_time.tv_sec = synced_time;
settimeofday(&get_nvs_time, nullptr);
}
preferences_close(preferences);
}
static void onTimeSynced(timeval* tv) {

View File

@ -1,8 +1,9 @@
#include <Tactility/settings/Time.h>
#include <Tactility/Preferences.h>
#include <Tactility/settings/SystemSettings.h>
#include <tactility/paths.h>
#include <tactility/preferences.h>
#include <tactility/system_event.h>
#ifdef ESP_PLATFORM
@ -17,6 +18,21 @@ constexpr auto* TIMEZONE_PREFERENCES_KEY_NAME = "tz_name";
constexpr auto* TIMEZONE_PREFERENCES_KEY_CODE = "tz_code";
constexpr auto* TIMEZONE_PREFERENCES_KEY_TIME24 = "tz_time24";
namespace {
// Same "time" namespace/file that Ntp.cpp's storeTimeInNvs()/setTimeFromNvs() use for
// "syncTime" - matches the shared NVS namespace this used to be.
bool getPreferencesPath(std::string& outPath) {
char root[128];
if (paths_get_user_data_path(root, sizeof(root)) != ERROR_NONE) {
return false;
}
outPath = std::string(root) + "/" + TIME_SETTINGS_NAMESPACE + ".properties";
return true;
}
} // namespace
void initTimeZone() {
#ifdef ESP_PLATFORM
auto code= getTimeZoneCode();
@ -28,9 +44,15 @@ void initTimeZone() {
}
void setTimeZone(const std::string& name, const std::string& code) {
Preferences preferences(TIME_SETTINGS_NAMESPACE);
preferences.putString(TIMEZONE_PREFERENCES_KEY_NAME, name);
preferences.putString(TIMEZONE_PREFERENCES_KEY_CODE, code);
std::string path;
if (getPreferencesPath(path)) {
Preferences* preferences = preferences_open(path.c_str());
if (preferences != nullptr) {
preferences_put_string(preferences, TIMEZONE_PREFERENCES_KEY_NAME, name.c_str());
preferences_put_string(preferences, TIMEZONE_PREFERENCES_KEY_CODE, code.c_str());
preferences_close(preferences);
}
}
#ifdef ESP_PLATFORM
setenv("TZ", code.c_str(), 1);
@ -41,32 +63,49 @@ void setTimeZone(const std::string& name, const std::string& code) {
}
std::string getTimeZoneName() {
Preferences preferences(TIME_SETTINGS_NAMESPACE);
std::string result;
if (preferences.optString(TIMEZONE_PREFERENCES_KEY_NAME, result)) {
return result;
} else {
return "Europe/Amsterdam";
std::string path;
if (getPreferencesPath(path)) {
Preferences* preferences = preferences_open(path.c_str());
if (preferences != nullptr) {
char buffer[64];
error_t error = preferences_opt_string(preferences, TIMEZONE_PREFERENCES_KEY_NAME, buffer, sizeof(buffer));
preferences_close(preferences);
if (error == ERROR_NONE) {
return buffer;
}
}
}
return "Europe/Amsterdam";
}
bool hasTimeZone() {
Preferences preferences(TIME_SETTINGS_NAMESPACE);
std::string timezone;
if (!preferences.optString(TIMEZONE_PREFERENCES_KEY_NAME, timezone)) {
std::string path;
if (!getPreferencesPath(path)) {
return false;
}
return !timezone.empty();
Preferences* preferences = preferences_open(path.c_str());
if (preferences == nullptr) {
return false;
}
bool has = preferences_has_string(preferences, TIMEZONE_PREFERENCES_KEY_NAME);
preferences_close(preferences);
return has;
}
std::string getTimeZoneCode() {
Preferences preferences(TIME_SETTINGS_NAMESPACE);
std::string result;
if (preferences.optString(TIMEZONE_PREFERENCES_KEY_CODE, result)) {
return result;
} else {
return "CET-1CEST,M3.5.0,M10.5.0/3"; // Default: Europe/Amsterdam
std::string path;
if (getPreferencesPath(path)) {
Preferences* preferences = preferences_open(path.c_str());
if (preferences != nullptr) {
char buffer[64];
error_t error = preferences_opt_string(preferences, TIMEZONE_PREFERENCES_KEY_CODE, buffer, sizeof(buffer));
preferences_close(preferences);
if (error == ERROR_NONE) {
return buffer;
}
}
}
return "CET-1CEST,M3.5.0,M10.5.0/3"; // Default: Europe/Amsterdam
}
bool isTimeFormat24Hour() {