Skip to content

Commit c381907

Browse files
authored
Merge pull request #1 from ladywhiskers/fix-dry-code-and-weekend-night-logic-8195736116672518629
Refactor time logic to be DRY and fix weekend night transitions
2 parents 1ab4cff + cefbc64 commit c381907

3 files changed

Lines changed: 78 additions & 23 deletions

File tree

childrens-clock.yaml

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -98,26 +98,16 @@ sensor:
9898
icon: mdi:percent
9999
update_interval: 5s
100100
lambda: |
101-
float now = id(current_time_decimal).state;
102-
int day_of_week = id(sntp_time).now().day_of_week;
103-
float percent;
104-
int currentstate = id(current_state).state;
105-
// TODO: improve logic so progress is calculated right on friday and sunday nights
106-
107-
if (day_of_week == SAT || day_of_week == SUN) {
108-
if (currentstate == AMBER) {
109-
percent = CalculateProgress(now, TimeAsDecimal(id(weekend_bedtime).hour, id(weekend_bedtime).minute), TimeAsDecimal(id(weekend_go).hour, id(weekend_go).minute));
110-
} else {
111-
percent = CalculateProgress(now, TimeAsDecimal(id(weekend_bedtime).hour, id(weekend_bedtime).minute), TimeAsDecimal(id(weekend_wake).hour, id(weekend_wake).minute));
112-
}
113-
} else {
114-
if (currentstate == AMBER) {
115-
percent = CalculateProgress(now, TimeAsDecimal(id(weekday_wake).hour, id(weekday_wake).minute), TimeAsDecimal(id(weekday_go).hour, id(weekday_go).minute));
116-
} else {
117-
percent = CalculateProgress(now, TimeAsDecimal(id(weekday_bedtime).hour, id(weekday_bedtime).minute), TimeAsDecimal(id(weekday_wake).hour, id(weekday_wake).minute));
118-
}
119-
}
120-
return percent;
101+
return GetProgress(
102+
id(sntp_time).now().day_of_week,
103+
id(current_time_decimal).state,
104+
TimeAsDecimal(id(weekday_go).hour, id(weekday_go).minute),
105+
TimeAsDecimal(id(weekday_wake).hour, id(weekday_wake).minute),
106+
TimeAsDecimal(id(weekday_bedtime).hour, id(weekday_bedtime).minute),
107+
TimeAsDecimal(id(weekend_go).hour, id(weekend_go).minute),
108+
TimeAsDecimal(id(weekend_wake).hour, id(weekend_wake).minute),
109+
TimeAsDecimal(id(weekend_bedtime).hour, id(weekend_bedtime).minute)
110+
);
121111
122112
- name: Current time as decimal
123113
disabled_by_default: true

src/childrensclock.h

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,9 @@ const int FRI = 6;
6565
const int SAT = 7;
6666

6767
int GetState(int dayOfWeek, float currentTime, float weekday_go, float weekday_wake, float weekday_bedtime, float weekend_go, float weekend_wake, float weekend_bedtime) {
68-
// Determine current day type: weekday or weekend
69-
int isWeekend = (dayOfWeek == SAT || dayOfWeek == SUN);
68+
int isWeekend = !IsWeekday(dayOfWeek);
7069
int isWeekendNight = (dayOfWeek == FRI || dayOfWeek == SAT);
7170

72-
// Determine time thresholds based on the day type
7371
float goTime = isWeekend ? weekend_go : weekday_go;
7472
float wakeTime = isWeekend ? weekend_wake : weekday_wake;
7573
float bedtime = isWeekendNight ? weekend_bedtime : weekday_bedtime;
@@ -83,3 +81,39 @@ int GetState(int dayOfWeek, float currentTime, float weekday_go, float weekday_w
8381
return RED; // Resting period
8482
}
8583
}
84+
85+
float GetProgress(int dayOfWeek, float currentTime, float weekday_go, float weekday_wake, float weekday_bedtime, float weekend_go, float weekend_wake, float weekend_bedtime) {
86+
int currentstate = GetState(dayOfWeek, currentTime, weekday_go, weekday_wake, weekday_bedtime, weekend_go, weekend_wake, weekend_bedtime);
87+
88+
if (currentstate == AMBER) {
89+
int isWeekend = !IsWeekday(dayOfWeek);
90+
float wakeTime = isWeekend ? weekend_wake : weekday_wake;
91+
float goTime = isWeekend ? weekend_go : weekday_go;
92+
return CalculateProgress(currentTime, wakeTime, goTime);
93+
} else {
94+
// We are in the RED state. This can be before wake (morning) or after bed (evening).
95+
int isWeekend = !IsWeekday(dayOfWeek);
96+
float wakeTime = isWeekend ? weekend_wake : weekday_wake;
97+
int isWeekendNight = (dayOfWeek == FRI || dayOfWeek == SAT);
98+
float bedtime = isWeekendNight ? weekend_bedtime : weekday_bedtime;
99+
100+
float startBedtime;
101+
float endWaketime;
102+
103+
if (currentTime < wakeTime) {
104+
// It's morning. We woke up from yesterday's bedtime.
105+
int yesterday = (dayOfWeek == SUN) ? SAT : (dayOfWeek - 1);
106+
int isYesterdayWeekendNight = (yesterday == FRI || yesterday == SAT);
107+
startBedtime = isYesterdayWeekendNight ? weekend_bedtime : weekday_bedtime;
108+
endWaketime = wakeTime; // Today's wake time
109+
} else {
110+
// It's evening. We will wake up to tomorrow's wake time.
111+
int tomorrow = (dayOfWeek == SAT) ? SUN : (dayOfWeek + 1);
112+
int isTomorrowWeekend = !IsWeekday(tomorrow);
113+
startBedtime = bedtime; // Today's bedtime
114+
endWaketime = isTomorrowWeekend ? weekend_wake : weekday_wake;
115+
}
116+
117+
return CalculateProgress(currentTime, startBedtime, endWaketime);
118+
}
119+
}

test/TestMain.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,37 @@ void testGetState(void) {
111111

112112
}
113113

114+
void testGetProgress(void) {
115+
float weekday_go = 8;
116+
float weekday_wake = 7;
117+
float weekday_bedtime = 18;
118+
119+
float weekend_go = 9;
120+
float weekend_wake = 8;
121+
float weekend_bedtime = 19;
122+
123+
// Monday 3am (bedtime 18, wake 7 -> total 13h, 18 to 3 is 9h. 9/13 = ~69%)
124+
TEST_ASSERT_FLOAT_WITHIN(1.0, 69.2, GetProgress(MON, 3, weekday_go, weekday_wake, weekday_bedtime, weekend_go, weekend_wake, weekend_bedtime));
125+
126+
// Friday 6pm (GREEN, 100% since out of bounds for amber/red)
127+
TEST_ASSERT_EQUAL_FLOAT(100.0, GetProgress(FRI, 18, weekday_go, weekday_wake, weekday_bedtime, weekend_go, weekend_wake, weekend_bedtime));
128+
129+
// Saturday 7:30am (RED, bedtime 19, wake 8 -> total 13h, 19 to 7.5 is 12.5h. 12.5/13 = ~96%)
130+
TEST_ASSERT_FLOAT_WITHIN(1.0, 96.1, GetProgress(SAT, 7.5, weekday_go, weekday_wake, weekday_bedtime, weekend_go, weekend_wake, weekend_bedtime));
131+
132+
// Saturday 8:30am (AMBER, wake 8, go 9 -> total 1h, 8 to 8.5 is 0.5h. 0.5/1 = 50%)
133+
TEST_ASSERT_EQUAL_FLOAT(50.0, GetProgress(SAT, 8.5, weekday_go, weekday_wake, weekday_bedtime, weekend_go, weekend_wake, weekend_bedtime));
134+
135+
// Friday 3:00am (RED, yesterday Thursday, so startBedtime is weekday_bedtime 18. wake is weekday_wake 7. Total 13h. 18 to 3 is 9h. 9/13 = ~69%)
136+
TEST_ASSERT_FLOAT_WITHIN(1.0, 69.2, GetProgress(FRI, 3.0, weekday_go, weekday_wake, weekday_bedtime, weekend_go, weekend_wake, weekend_bedtime));
137+
138+
// Sunday 8:00pm (RED, evening. today Sunday, tomorrow Monday. so endWaketime is weekday_wake 7. bedtime is weekday_bedtime 18. Total 13h. 18 to 20 is 2h. 2/13 = ~15%)
139+
TEST_ASSERT_FLOAT_WITHIN(1.0, 15.3, GetProgress(SUN, 20.0, weekday_go, weekday_wake, weekday_bedtime, weekend_go, weekend_wake, weekend_bedtime));
140+
141+
// Sunday 3:00am (RED, yesterday Saturday, so startBedtime is weekend_bedtime 19. wake is weekend_wake 8. Total 13h. 19 to 3 is 8h. 8/13 = ~61%)
142+
TEST_ASSERT_FLOAT_WITHIN(1.0, 61.5, GetProgress(SUN, 3.0, weekday_go, weekday_wake, weekday_bedtime, weekend_go, weekend_wake, weekend_bedtime));
143+
}
144+
114145

115146
// void testGetColor(void) {
116147
// TEST_ASSERT_EQUAL_STRING("GREEN", GetColor(50, 64));

0 commit comments

Comments
 (0)