Skip to content

Commit

Permalink
Improve config serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
stnkl committed Mar 24, 2022
1 parent 63b16e9 commit 7d09a3b
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 158 deletions.
44 changes: 36 additions & 8 deletions src/Config.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "Config.h"

#include "SerialOut.h"
#include "FastLEDHub.h"

#include <FS.h>

Expand Down Expand Up @@ -32,7 +34,7 @@ bool ConfigClass::initialize()

bool ConfigClass::parseJson(const char *input)
{
DynamicJsonDocument doc(2048);
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, input);

if (doc.containsKey("timeZone"))
Expand Down Expand Up @@ -84,7 +86,7 @@ bool ConfigClass::parseJson(const char *input)
return !error;
}

DynamicJsonDocument ConfigClass::getJson(DynamicJsonDocument doc)
void ConfigClass::getUserConfigJson(JsonDocument &doc)
{
doc["timeZone"] = timeZone;
doc["summerTime"] = summerTime;
Expand All @@ -109,16 +111,42 @@ DynamicJsonDocument ConfigClass::getJson(DynamicJsonDocument doc)
{
sliderValueArray.add(sliderValues.get(i));
}
}

return doc;
void ConfigClass::getApplicationStateJson(JsonDocument &doc)
{
doc["status"] = String(FastLEDHub.status);
doc["currentAnimation"] = FastLEDHub.currentAnimation ? FastLEDHub.currentAnimation->getName() : "";
JsonArray animations = doc.createNestedArray("animations");
for (uint8_t i = 0; i < FastLEDHub.animations.size(); i++)
{
animations.add(FastLEDHub.animations.get(i)->getName());
}
JsonArray sliders = doc.createNestedArray("sliders");
for (uint8_t i = 0; i < FastLEDHub.sliders.size(); i++)
{
JsonObject slider = sliders.createNestedObject();
slider["name"] = FastLEDHub.sliders.get(i)->name;
slider["min"] = FastLEDHub.sliders.get(i)->min;
slider["max"] = FastLEDHub.sliders.get(i)->max;
slider["step"] = FastLEDHub.sliders.get(i)->step;
slider["value"] = FastLEDHub.sliders.get(i)->value;
}
}

String ConfigClass::getJsonString()
String ConfigClass::asString(bool includeApplicationState)
{
DynamicJsonDocument doc(2048);
doc = getJson(doc);
DynamicJsonDocument doc(3072);

getUserConfigJson(doc);

if (includeApplicationState)
{
getApplicationStateJson(doc);
}

String buffer = "";
serializeJson(doc, buffer);
serializeJsonPretty(doc, buffer);
return buffer;
}

Expand All @@ -131,7 +159,7 @@ bool ConfigClass::save()
return false;
}

configFile.println(getJsonString());
configFile.println(asString());
configFile.close();

return true;
Expand Down
41 changes: 9 additions & 32 deletions src/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,72 +7,49 @@
class ConfigClass
{
public:
/// Time zone
int8_t timeZone = 0;
/// Summer time (0 = false, 1 = true)
int8_t summerTime = 0;
/// Longitude
float longitude = 0;
/// Latitude
float latitude = 0;
// Alarm functionality enabled
bool alarmEnabled = false;
/// Alarm duration in minutes
uint16_t alarmDuration = 1;
/// Alarm time hour
uint8_t alarmHour = 0;
/// Alarm time minute
uint8_t alarmMinute = 0;
/// Animation during alarm duration (while the brightness increases)
String alarmAnimation = "Color";
/// Animation triggered after the alarm duration has ended
String postAlarmAnimation = "Color";
/// Sunset functionality enabled
bool sunsetEnabled = false;
/// Sunset duration in minutes
uint16_t sunsetDuration = 1;
/// Sunset time hour
int8_t sunsetHour = 0;
/// Sunset time minute
int8_t sunsetMinute = 0;
/// Sunset time offset in minutes relative to the
/// automatically obtained local sunset time
int16_t sunsetOffset = 0;
/// Sunset animation
String sunsetAnimation = "Color";
/// Startup animation that gets triggered when powering up the device
String startupAnimation = "";
/// Lastly used color for Color animation
String color = "ffffff";
/// Slider values
LinkedList<int16_t> sliderValues;

/// Initialize config object by mounting file system and
/// reading the config file.
/// Initialize config object by reading the config file.
/// @return True if successful
bool initialize();

/// Save config to file system
/// @return True if successful
bool save();

/// Parse a JSON char array and apply its values to the
/// config state.
/// Parse a JSON char array and apply its values to the config.
/// @param input JSON char array
/// @return True if successful
bool parseJson(const char *input);

/// Get config state contained in a DynamicJsonDocument
/// @return DynamicJsonDocument containing config
DynamicJsonDocument getJson(DynamicJsonDocument doc);

/// Get config state serialized as a JSON string
/// @return JSON string
String getJsonString();
/// Get config and (optional) application state as JSON String.
/// @param includeApplicationState Wether to include application state
/// @return JSON String
String asString(bool includeApplicationState = false);

private:
/// Constant config filename
const String configFilename = "/config.txt";

void getUserConfigJson(JsonDocument &doc);
void getApplicationStateJson(JsonDocument &doc);
};

extern ConfigClass Config;
162 changes: 86 additions & 76 deletions src/Fade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,89 @@
namespace Fade
{

FadeMode mode = FadeMode::NONE;
uint16_t targetBrightness = 0;
Ticker fadeTicker;
Ticker debounce;
namespace
{

FadeMode mode = FadeMode::NONE;
uint16_t targetBrightness = 0;
Ticker fadeTicker;
Ticker debounce;

void tick()
{
if (FastLEDHub.status == PAUSED)
return;

if (mode == FadeMode::ALARM && FastLEDHub.brightness10 == 1023)
{
if (Config.postAlarmAnimation != Config.alarmAnimation)
FastLEDHub.begin(FastLEDHub.getAnimation(Config.postAlarmAnimation));

stop();
PRINTLN("[FastLEDHub] End fade 'Alarm'");
}
else if (mode == FadeMode::SUNSET && FastLEDHub.brightness10 == targetBrightness)
{
stop();
PRINTLN("[FastLEDHub] End fade 'Sunset'");
}
else
{
FastLEDHub.brightness10++;
PRINTLN("[FastLEDHub] Fade brightness: " + String(FastLEDHub.brightness10));
}

FastLEDHub.brightness10 = FastLEDHub.brightness10;
}

void getSunsetTime()
{
PRINT("[FastLEDHub] Getting sunset time...");

WiFiClient client;
HTTPClient http;
String url = "http://api.sunrise-sunset.org/json?lat=" + String(Config.latitude) + "&lng=" + String(Config.longitude) + "&date=today&formatted=0";
http.begin(client, url);
String payload = "";
if (http.GET() > 0)
payload = http.getString();
http.end();

StaticJsonDocument<1024> doc;
deserializeJson(doc, payload);
if (doc.containsKey("results") && doc["results"].containsKey("sunset"))
{
String sunset = doc["results"]["sunset"].as<String>();
int16_t sunsetHour = (sunset.substring(11, 13).toInt() + Config.timeZone + Config.summerTime + 24) % 24;
int16_t sunsetMinute = sunset.substring(14, 16).toInt();
int16_t minutesSinceMidnight = sunsetHour * 60 + sunsetMinute;
minutesSinceMidnight = (minutesSinceMidnight + Config.sunsetOffset + 1440) % 1440;
Config.sunsetHour = minutesSinceMidnight / 60;
Config.sunsetMinute = minutesSinceMidnight % 60;
Config.save();
PRINTLN(" " + String(Config.sunsetHour) + ":" + String(Config.sunsetMinute));
}
else
{
PRINTLN("failed. Using last known time instead.");
}
}

bool getCurrentTime(int8_t *hour, int8_t *minute)
{
time_t n = time(nullptr);

if (!n)
return false;

tm *now = gmtime(&n);
*hour = (now->tm_hour + Config.timeZone + Config.summerTime) % 24;
*minute = now->tm_min;

return true;
}

} // namespace

void initialize()
{
Expand Down Expand Up @@ -54,7 +133,7 @@ namespace Fade
if (fadeMode == FadeMode::ALARM)
{
FastLEDHub.begin(FastLEDHub.getAnimation(Config.alarmAnimation));
fadeTicker.attach_ms(Config.alarmDuration * 60 * 1000 / 1024, tick);
fadeTicker.attach_ms(Config.alarmDuration * 60 * 1000 / 1023, tick);
PRINTLN("[FastLEDHub] Start fade 'Alarm'");
}
else if (fadeMode == FadeMode::SUNSET)
Expand All @@ -71,78 +150,9 @@ namespace Fade
mode = FadeMode::NONE;
}

void tick()
{
if (FastLEDHub.status == PAUSED)
return;

if (mode == FadeMode::ALARM && FastLEDHub.brightness10 == 1023)
{
if (Config.postAlarmAnimation != Config.alarmAnimation)
FastLEDHub.begin(FastLEDHub.getAnimation(Config.postAlarmAnimation));

stop();
PRINTLN("[FastLEDHub] End fade 'Alarm'");
}
else if (mode == FadeMode::SUNSET && FastLEDHub.brightness10 == targetBrightness)
{
stop();
PRINTLN("[FastLEDHub] End fade 'Sunset'");
}
else
{
FastLEDHub.brightness10++;
PRINTLN("[FastLEDHub] Fade brightness: " + String(FastLEDHub.brightness10));
}

FastLEDHub.brightness10 = FastLEDHub.brightness10;
}

void getSunsetTime()
FadeMode getMode()
{
PRINT("[FastLEDHub] Getting sunset time...");

WiFiClient client;
HTTPClient http;
String url = "http://api.sunrise-sunset.org/json?lat=" + String(Config.latitude) + "&lng=" + String(Config.longitude) + "&date=today&formatted=0";
http.begin(client, url);
String payload = "";
if (http.GET() > 0)
payload = http.getString();
http.end();

DynamicJsonDocument doc(2048);
deserializeJson(doc, payload);
if (doc.containsKey("results") && doc["results"].containsKey("sunset"))
{
String sunset = doc["results"]["sunset"].as<String>();
int16_t sunsetHour = (sunset.substring(11, 13).toInt() + Config.timeZone + Config.summerTime + 24) % 24;
int16_t sunsetMinute = sunset.substring(14, 16).toInt();
int16_t minutesSinceMidnight = sunsetHour * 60 + sunsetMinute;
minutesSinceMidnight = (minutesSinceMidnight + Config.sunsetOffset + 1440) % 1440;
Config.sunsetHour = minutesSinceMidnight / 60;
Config.sunsetMinute = minutesSinceMidnight % 60;
Config.save();
PRINTLN(" " + String(Config.sunsetHour) + ":" + String(Config.sunsetMinute));
}
else
{
PRINTLN("failed. Using last known time instead.");
}
}

bool getCurrentTime(int8_t *hour, int8_t *minute)
{
time_t n = time(nullptr);

if (!n)
return false;

tm *now = gmtime(&n);
*hour = (now->tm_hour + Config.timeZone + Config.summerTime) % 24;
*minute = now->tm_min;

return true;
return mode;
}

} // namespace Fade
8 changes: 1 addition & 7 deletions src/Fade.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

#include <Arduino.h>

class FastLEDHubClass;

namespace Fade
{

Expand All @@ -16,14 +14,10 @@ namespace Fade
SUNSET
};

extern FadeMode mode;

void tick();
void handle();
void begin(FadeMode fadeMode);
void stop();
void initialize();
void getSunsetTime();
bool getCurrentTime(int8_t *hour, int8_t *minute);
FadeMode getMode();

} // namespace Fade
Loading

0 comments on commit 7d09a3b

Please sign in to comment.