-
Notifications
You must be signed in to change notification settings - Fork 2
/
Schedule.cpp
171 lines (147 loc) · 4.11 KB
/
Schedule.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#include "Schedule.h"
// Default constructor
Schedule::Schedule()
{
this->numberOfEvents = 0;
this->events = NULL;
}
/**
* Updates the schedule.
*
* This method reads the events from storage and populates the array of events.
*/
void Schedule::update()
{
Serial.println("Updating schedule...");
// read events from storage
DynamicJsonDocument doc = readEvents();
// get the number of events
this->numberOfEvents = doc.size();
if (this->numberOfEvents == 0)
{
Serial.println("No events found.");
return;
}
// create array of events
this->events = new Event[this->numberOfEvents];
// populate array of events
for (int i = 0; i < this->numberOfEvents; i++)
{
time_t start = convertStringToUnixTime(doc[i]["start"]);
time_t end = convertStringToUnixTime(doc[i]["end"]);
String note = doc[i]["note"];
int stage = note.substring(6).toInt();
this->events[i] = Event(start, end, stage);
}
Serial.println("Schedule updated.");
}
/**
* Checks if currently loadshedding.
*
* @return True if any loadshedding event is occuring, false otherwise.
*/
boolean Schedule::isCurrentlyLoadshedding()
{
time_t now = getUnixTime();
for (int i = 0; i < this->numberOfEvents; i++)
{
if (this->events[i].isCurrentlyOccuring())
{
return true;
}
}
return false;
}
/**
* Gets the number of seconds until the next transition.
*
* @return The number of seconds until the next (soonest) transition. If no transition is scheduled, returns -1.
*/
int Schedule::getSecondsUntilNextTransition()
{
int secondsUntilNextTransition = INT_MAX;
for (int i = 0; i < this->numberOfEvents; i++)
{
int currentSecondsUntilNextTransition = this->events[i].getSecondsUntilNextTransition();
if (currentSecondsUntilNextTransition > 0 && currentSecondsUntilNextTransition < secondsUntilNextTransition)
{
secondsUntilNextTransition = currentSecondsUntilNextTransition;
}
}
if (secondsUntilNextTransition == INT_MAX)
{
return -1;
}
return secondsUntilNextTransition;
}
/**
* Gets the highest stage of current/upcoming loadshedding events.
*
* @return The highest upcoming stage of loadshedding.
*/
int Schedule::getHighestUpcomingStage()
{
int highestStage = 0;
for (int i = 0; i < this->numberOfEvents; i++)
{
time_t eventEnd = this->events[i].end;
int eventStage = this->events[i].stage;
// check if event ends in the future
if (eventEnd > getUnixTime())
{
if (eventStage > highestStage)
{
highestStage = eventStage;
}
}
}
return highestStage;
}
/**
* Checks if the given Unix time falls on the same day as today.
*
* @param time The Unix time to check.
* @return True if the given time is today, false otherwise.
*/
boolean isToday(time_t time)
{
// get Unix time for start of today
struct tm startOfToday;
getLocalTime(&startOfToday);
startOfToday.tm_hour = 0;
startOfToday.tm_min = 0;
startOfToday.tm_sec = 0;
time_t startOfTodayUnixTime = mktime(&startOfToday);
// get Unix time for end of today
struct tm endOfToday;
getLocalTime(&endOfToday);
endOfToday.tm_hour = 23;
endOfToday.tm_min = 59;
endOfToday.tm_sec = 59;
time_t endOfTodayUnixTime = mktime(&endOfToday);
return time >= startOfTodayUnixTime && time <= endOfTodayUnixTime;
}
/**
* Gets the highest stage of loadshedding for today.
*
* @return The highest stage of loadshedding for today.
*/
int Schedule::getHighestStageOfToday()
{
int highestStage = 0;
for (int i = 0; i < this->numberOfEvents; i++)
{
time_t eventStart = this->events[i].start;
int eventStage = this->events[i].stage;
// check if event starts today
if (isToday(eventStart))
{
// Serial.println("Event starts today.");
if (eventStage > highestStage)
{
highestStage = eventStage;
}
}
}
return highestStage;
}