-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSunSimulation.cpp
executable file
·121 lines (94 loc) · 3.43 KB
/
SunSimulation.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
// SunSimulation
// Copyright Artem Botnev 2018
// MIT License
#include "SunSimulation.h"
TimeSet::TimeSet(uint8_t hour, uint8_t minute, uint16_t duration) {
_hour = hour;
_minute = minute;
_duration = duration;
}
uint8_t TimeSet::getHour() {
return _hour;
}
uint8_t TimeSet::getMinute() {
return _minute;
}
uint16_t TimeSet::getDuration() {
return _duration;
}
SunSimulation::SunSimulation(TimeSet *sunRise, TimeSet *sunSet) {
_sunRise = sunRise;
_sunSet = sunSet;
}
SunSimulation::SunSimulation(TimeSet *sunRise, TimeSet *sunSet, uint8_t *brightness)
: SunSimulation(sunRise, sunSet) {
_brightness = brightness;
}
const char *SunSimulation::regimenInit() {
if (haveTimeError(_sunRise) || haveTimeError(_sunSet)) {
return "time input error";
}
// get time (seconds) since sunrise start
_endRise = _sunRise->getDuration() * 60;
_startSet = getSecondsFromStart(_sunRise, _sunSet->getHour(), _sunSet->getMinute(), 0);
if (_startSet < 60) {
return "time input error, too small a gap between sunrise and sunset";
}
_endSet = _startSet + _sunSet->getDuration() * 60;
if (_endSet > DAY_SECONDS || _endRise > _startSet) {
return "time input error, intersection of sunrise and sunset regiments";
}
_optionsOk = true;
_startPoint = _sunRise;
return "successful initialization";
}
const char *SunSimulation::reloadRegimen(TimeSet *sunRise, TimeSet *sunSet) {
delete _sunRise;
delete _sunSet;
_sunRise = sunRise;
_sunSet = sunSet;
return regimenInit();
}
uint8_t SunSimulation::changeBrightness(uint8_t hour, uint8_t minute, uint8_t second, uint8_t *brightness) {
if (!_optionsOk) {
// errors of initialisation
return 0;
}
uint32_t currentSecond = getSecondsFromStart(_startPoint, hour, minute, second);
if (currentSecond > _endRise && currentSecond < _startSet) {
*brightness = PWM_MAX;
} else if (currentSecond > _endSet) {
*brightness = 0;
} else if (currentSecond <= _endRise) {
*brightness = PWM_MAX * currentSecond / _endRise;
} else if (currentSecond >= _startSet && currentSecond <= _endSet) {
uint32_t curFromStart = currentSecond - _startSet;
uint32_t setDuration = _endSet - _startSet;
*brightness = PWM_MAX - (PWM_MAX * curFromStart / setDuration);
}
return *brightness;
}
uint8_t SunSimulation::changeBrightness(uint8_t hour, uint8_t minute, uint8_t second) {
return changeBrightness(hour, minute, second, _brightness);
}
bool SunSimulation::haveTimeError(TimeSet *set) {
return set->getHour() > 23 || set->getMinute() > 59 || set->getDuration() > 120 || set->getDuration() < 5;
}
uint32_t SunSimulation::getSecondsFromStart(TimeSet *sunRise, uint32_t curHour, uint32_t curMinute, uint32_t curSecond) {
// seconds
uint32_t gap;
if (sunRise->getHour() < curHour) {
gap = ((curHour - sunRise->getHour()) * 60 + curMinute - sunRise->getMinute()) * 60
+ curSecond;
} else if (sunRise->getHour() > curHour) {
gap = ((24 - sunRise->getHour() + curHour) * 60 + curMinute - sunRise->getMinute())
* 60 + curSecond;
} else {
if (sunRise->getMinute() <= curMinute) {
gap = curMinute * 60 + curSecond - sunRise->getMinute() * 60;
} else {
gap = (24 * 60 - ((sunRise->getMinute() - curMinute))) * 60 - curSecond;
}
}
return gap;
}