Skip to content

Commit 7d09a3b

Browse files
committed
Improve config serialization
1 parent 63b16e9 commit 7d09a3b

File tree

7 files changed

+141
-158
lines changed

7 files changed

+141
-158
lines changed

src/Config.cpp

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "Config.h"
2+
23
#include "SerialOut.h"
4+
#include "FastLEDHub.h"
35

46
#include <FS.h>
57

@@ -32,7 +34,7 @@ bool ConfigClass::initialize()
3234

3335
bool ConfigClass::parseJson(const char *input)
3436
{
35-
DynamicJsonDocument doc(2048);
37+
StaticJsonDocument<1024> doc;
3638
DeserializationError error = deserializeJson(doc, input);
3739

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

87-
DynamicJsonDocument ConfigClass::getJson(DynamicJsonDocument doc)
89+
void ConfigClass::getUserConfigJson(JsonDocument &doc)
8890
{
8991
doc["timeZone"] = timeZone;
9092
doc["summerTime"] = summerTime;
@@ -109,16 +111,42 @@ DynamicJsonDocument ConfigClass::getJson(DynamicJsonDocument doc)
109111
{
110112
sliderValueArray.add(sliderValues.get(i));
111113
}
114+
}
112115

113-
return doc;
116+
void ConfigClass::getApplicationStateJson(JsonDocument &doc)
117+
{
118+
doc["status"] = String(FastLEDHub.status);
119+
doc["currentAnimation"] = FastLEDHub.currentAnimation ? FastLEDHub.currentAnimation->getName() : "";
120+
JsonArray animations = doc.createNestedArray("animations");
121+
for (uint8_t i = 0; i < FastLEDHub.animations.size(); i++)
122+
{
123+
animations.add(FastLEDHub.animations.get(i)->getName());
124+
}
125+
JsonArray sliders = doc.createNestedArray("sliders");
126+
for (uint8_t i = 0; i < FastLEDHub.sliders.size(); i++)
127+
{
128+
JsonObject slider = sliders.createNestedObject();
129+
slider["name"] = FastLEDHub.sliders.get(i)->name;
130+
slider["min"] = FastLEDHub.sliders.get(i)->min;
131+
slider["max"] = FastLEDHub.sliders.get(i)->max;
132+
slider["step"] = FastLEDHub.sliders.get(i)->step;
133+
slider["value"] = FastLEDHub.sliders.get(i)->value;
134+
}
114135
}
115136

116-
String ConfigClass::getJsonString()
137+
String ConfigClass::asString(bool includeApplicationState)
117138
{
118-
DynamicJsonDocument doc(2048);
119-
doc = getJson(doc);
139+
DynamicJsonDocument doc(3072);
140+
141+
getUserConfigJson(doc);
142+
143+
if (includeApplicationState)
144+
{
145+
getApplicationStateJson(doc);
146+
}
147+
120148
String buffer = "";
121-
serializeJson(doc, buffer);
149+
serializeJsonPretty(doc, buffer);
122150
return buffer;
123151
}
124152

@@ -131,7 +159,7 @@ bool ConfigClass::save()
131159
return false;
132160
}
133161

134-
configFile.println(getJsonString());
162+
configFile.println(asString());
135163
configFile.close();
136164

137165
return true;

src/Config.h

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,72 +7,49 @@
77
class ConfigClass
88
{
99
public:
10-
/// Time zone
1110
int8_t timeZone = 0;
12-
/// Summer time (0 = false, 1 = true)
1311
int8_t summerTime = 0;
14-
/// Longitude
1512
float longitude = 0;
16-
/// Latitude
1713
float latitude = 0;
18-
// Alarm functionality enabled
1914
bool alarmEnabled = false;
20-
/// Alarm duration in minutes
2115
uint16_t alarmDuration = 1;
22-
/// Alarm time hour
2316
uint8_t alarmHour = 0;
24-
/// Alarm time minute
2517
uint8_t alarmMinute = 0;
26-
/// Animation during alarm duration (while the brightness increases)
2718
String alarmAnimation = "Color";
28-
/// Animation triggered after the alarm duration has ended
2919
String postAlarmAnimation = "Color";
30-
/// Sunset functionality enabled
3120
bool sunsetEnabled = false;
32-
/// Sunset duration in minutes
3321
uint16_t sunsetDuration = 1;
34-
/// Sunset time hour
3522
int8_t sunsetHour = 0;
36-
/// Sunset time minute
3723
int8_t sunsetMinute = 0;
38-
/// Sunset time offset in minutes relative to the
39-
/// automatically obtained local sunset time
4024
int16_t sunsetOffset = 0;
41-
/// Sunset animation
4225
String sunsetAnimation = "Color";
43-
/// Startup animation that gets triggered when powering up the device
4426
String startupAnimation = "";
45-
/// Lastly used color for Color animation
4627
String color = "ffffff";
47-
/// Slider values
4828
LinkedList<int16_t> sliderValues;
4929

50-
/// Initialize config object by mounting file system and
51-
/// reading the config file.
30+
/// Initialize config object by reading the config file.
5231
/// @return True if successful
5332
bool initialize();
5433

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

59-
/// Parse a JSON char array and apply its values to the
60-
/// config state.
38+
/// Parse a JSON char array and apply its values to the config.
6139
/// @param input JSON char array
6240
/// @return True if successful
6341
bool parseJson(const char *input);
6442

65-
/// Get config state contained in a DynamicJsonDocument
66-
/// @return DynamicJsonDocument containing config
67-
DynamicJsonDocument getJson(DynamicJsonDocument doc);
68-
69-
/// Get config state serialized as a JSON string
70-
/// @return JSON string
71-
String getJsonString();
43+
/// Get config and (optional) application state as JSON String.
44+
/// @param includeApplicationState Wether to include application state
45+
/// @return JSON String
46+
String asString(bool includeApplicationState = false);
7247

7348
private:
74-
/// Constant config filename
7549
const String configFilename = "/config.txt";
50+
51+
void getUserConfigJson(JsonDocument &doc);
52+
void getApplicationStateJson(JsonDocument &doc);
7653
};
7754

7855
extern ConfigClass Config;

src/Fade.cpp

Lines changed: 86 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,89 @@
1111
namespace Fade
1212
{
1313

14-
FadeMode mode = FadeMode::NONE;
15-
uint16_t targetBrightness = 0;
16-
Ticker fadeTicker;
17-
Ticker debounce;
14+
namespace
15+
{
16+
17+
FadeMode mode = FadeMode::NONE;
18+
uint16_t targetBrightness = 0;
19+
Ticker fadeTicker;
20+
Ticker debounce;
21+
22+
void tick()
23+
{
24+
if (FastLEDHub.status == PAUSED)
25+
return;
26+
27+
if (mode == FadeMode::ALARM && FastLEDHub.brightness10 == 1023)
28+
{
29+
if (Config.postAlarmAnimation != Config.alarmAnimation)
30+
FastLEDHub.begin(FastLEDHub.getAnimation(Config.postAlarmAnimation));
31+
32+
stop();
33+
PRINTLN("[FastLEDHub] End fade 'Alarm'");
34+
}
35+
else if (mode == FadeMode::SUNSET && FastLEDHub.brightness10 == targetBrightness)
36+
{
37+
stop();
38+
PRINTLN("[FastLEDHub] End fade 'Sunset'");
39+
}
40+
else
41+
{
42+
FastLEDHub.brightness10++;
43+
PRINTLN("[FastLEDHub] Fade brightness: " + String(FastLEDHub.brightness10));
44+
}
45+
46+
FastLEDHub.brightness10 = FastLEDHub.brightness10;
47+
}
48+
49+
void getSunsetTime()
50+
{
51+
PRINT("[FastLEDHub] Getting sunset time...");
52+
53+
WiFiClient client;
54+
HTTPClient http;
55+
String url = "http://api.sunrise-sunset.org/json?lat=" + String(Config.latitude) + "&lng=" + String(Config.longitude) + "&date=today&formatted=0";
56+
http.begin(client, url);
57+
String payload = "";
58+
if (http.GET() > 0)
59+
payload = http.getString();
60+
http.end();
61+
62+
StaticJsonDocument<1024> doc;
63+
deserializeJson(doc, payload);
64+
if (doc.containsKey("results") && doc["results"].containsKey("sunset"))
65+
{
66+
String sunset = doc["results"]["sunset"].as<String>();
67+
int16_t sunsetHour = (sunset.substring(11, 13).toInt() + Config.timeZone + Config.summerTime + 24) % 24;
68+
int16_t sunsetMinute = sunset.substring(14, 16).toInt();
69+
int16_t minutesSinceMidnight = sunsetHour * 60 + sunsetMinute;
70+
minutesSinceMidnight = (minutesSinceMidnight + Config.sunsetOffset + 1440) % 1440;
71+
Config.sunsetHour = minutesSinceMidnight / 60;
72+
Config.sunsetMinute = minutesSinceMidnight % 60;
73+
Config.save();
74+
PRINTLN(" " + String(Config.sunsetHour) + ":" + String(Config.sunsetMinute));
75+
}
76+
else
77+
{
78+
PRINTLN("failed. Using last known time instead.");
79+
}
80+
}
81+
82+
bool getCurrentTime(int8_t *hour, int8_t *minute)
83+
{
84+
time_t n = time(nullptr);
85+
86+
if (!n)
87+
return false;
88+
89+
tm *now = gmtime(&n);
90+
*hour = (now->tm_hour + Config.timeZone + Config.summerTime) % 24;
91+
*minute = now->tm_min;
92+
93+
return true;
94+
}
95+
96+
} // namespace
1897

1998
void initialize()
2099
{
@@ -54,7 +133,7 @@ namespace Fade
54133
if (fadeMode == FadeMode::ALARM)
55134
{
56135
FastLEDHub.begin(FastLEDHub.getAnimation(Config.alarmAnimation));
57-
fadeTicker.attach_ms(Config.alarmDuration * 60 * 1000 / 1024, tick);
136+
fadeTicker.attach_ms(Config.alarmDuration * 60 * 1000 / 1023, tick);
58137
PRINTLN("[FastLEDHub] Start fade 'Alarm'");
59138
}
60139
else if (fadeMode == FadeMode::SUNSET)
@@ -71,78 +150,9 @@ namespace Fade
71150
mode = FadeMode::NONE;
72151
}
73152

74-
void tick()
75-
{
76-
if (FastLEDHub.status == PAUSED)
77-
return;
78-
79-
if (mode == FadeMode::ALARM && FastLEDHub.brightness10 == 1023)
80-
{
81-
if (Config.postAlarmAnimation != Config.alarmAnimation)
82-
FastLEDHub.begin(FastLEDHub.getAnimation(Config.postAlarmAnimation));
83-
84-
stop();
85-
PRINTLN("[FastLEDHub] End fade 'Alarm'");
86-
}
87-
else if (mode == FadeMode::SUNSET && FastLEDHub.brightness10 == targetBrightness)
88-
{
89-
stop();
90-
PRINTLN("[FastLEDHub] End fade 'Sunset'");
91-
}
92-
else
93-
{
94-
FastLEDHub.brightness10++;
95-
PRINTLN("[FastLEDHub] Fade brightness: " + String(FastLEDHub.brightness10));
96-
}
97-
98-
FastLEDHub.brightness10 = FastLEDHub.brightness10;
99-
}
100-
101-
void getSunsetTime()
153+
FadeMode getMode()
102154
{
103-
PRINT("[FastLEDHub] Getting sunset time...");
104-
105-
WiFiClient client;
106-
HTTPClient http;
107-
String url = "http://api.sunrise-sunset.org/json?lat=" + String(Config.latitude) + "&lng=" + String(Config.longitude) + "&date=today&formatted=0";
108-
http.begin(client, url);
109-
String payload = "";
110-
if (http.GET() > 0)
111-
payload = http.getString();
112-
http.end();
113-
114-
DynamicJsonDocument doc(2048);
115-
deserializeJson(doc, payload);
116-
if (doc.containsKey("results") && doc["results"].containsKey("sunset"))
117-
{
118-
String sunset = doc["results"]["sunset"].as<String>();
119-
int16_t sunsetHour = (sunset.substring(11, 13).toInt() + Config.timeZone + Config.summerTime + 24) % 24;
120-
int16_t sunsetMinute = sunset.substring(14, 16).toInt();
121-
int16_t minutesSinceMidnight = sunsetHour * 60 + sunsetMinute;
122-
minutesSinceMidnight = (minutesSinceMidnight + Config.sunsetOffset + 1440) % 1440;
123-
Config.sunsetHour = minutesSinceMidnight / 60;
124-
Config.sunsetMinute = minutesSinceMidnight % 60;
125-
Config.save();
126-
PRINTLN(" " + String(Config.sunsetHour) + ":" + String(Config.sunsetMinute));
127-
}
128-
else
129-
{
130-
PRINTLN("failed. Using last known time instead.");
131-
}
132-
}
133-
134-
bool getCurrentTime(int8_t *hour, int8_t *minute)
135-
{
136-
time_t n = time(nullptr);
137-
138-
if (!n)
139-
return false;
140-
141-
tm *now = gmtime(&n);
142-
*hour = (now->tm_hour + Config.timeZone + Config.summerTime) % 24;
143-
*minute = now->tm_min;
144-
145-
return true;
155+
return mode;
146156
}
147157

148158
} // namespace Fade

src/Fade.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
#include <Arduino.h>
66

7-
class FastLEDHubClass;
8-
97
namespace Fade
108
{
119

@@ -16,14 +14,10 @@ namespace Fade
1614
SUNSET
1715
};
1816

19-
extern FadeMode mode;
20-
21-
void tick();
2217
void handle();
2318
void begin(FadeMode fadeMode);
2419
void stop();
2520
void initialize();
26-
void getSunsetTime();
27-
bool getCurrentTime(int8_t *hour, int8_t *minute);
21+
FadeMode getMode();
2822

2923
} // namespace Fade

0 commit comments

Comments
 (0)