-
Notifications
You must be signed in to change notification settings - Fork 0
/
SupervisorSM.cpp
132 lines (108 loc) · 3.2 KB
/
SupervisorSM.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
#include "SupervisorSM.h"
#include <string>
// Constructor
SupervisorSM::SupervisorSM(int start, int end) {
startHour = start;
endHour = end;
}
void SupervisorSM::init(){
// startup in auto mode
isAuto = true;
// initialize state
if(isDayTime()) {
transitionTo(AUTO_OPEN);
}else {
transitionTo(AUTO_CLOSED);
}
// consume exit event so we don't do this the first time we enter runSM()
isExit = false;
}
/*********************** STATE MACHINE **************************************/
void SupervisorSM::runSM(std::bitset<SIZE_OF_FLAGS_ENUM> *flags) {
switch(currentState) {
case MANUAL_MODE:
if(isAuto) {
if(isDayTime()) {
transitionTo(AUTO_OPEN);
}else {
transitionTo(AUTO_CLOSED);
}
}
break;
case AUTO_OPEN:
if(isEntry) {
flags->set(COMMAND_OPEN_FLAG); // send an open door command
isEntry = false;
}
if(!isDayTime()){
transitionTo(AUTO_CLOSED);
} else if(!isAuto) {
transitionTo(MANUAL_MODE);
}
break;
case AUTO_CLOSED:
if(isEntry) {
flags->set(INIT_AUTOCLOSE_FLAG);
isEntry = false;
}
if(isDayTime()) {
transitionTo(AUTO_OPEN);
}else if(!isAuto) {
transitionTo(MANUAL_MODE);
}
break;
}
// ensure that isExit is false, if there were exit actions they should have been resolved by here
isExit = false;
}
SupervisorState_t SupervisorSM::getState() {
return currentState;
}
void SupervisorSM::transitionTo(SupervisorState_t to) {
char message[100];
sprintf(message, "SupervisorSM: Transitioning from %s to %s", SupervisorStateNames[currentState].c_str(), SupervisorStateNames[to].c_str());
Serial.println(message);
Particle.publish("Log", message);
currentState = to;
isEntry = true;
isExit = true;
char publishString[10];
sprintf(publishString, "%d", to);
// publish the event
Particle.publish("SupervisorState", publishString);
}
/*************** TIMER AND INTERRUPT CALLBACKS*********************/
/*************** GETTERS AND SETTERS *****************/
void SupervisorSM::setStartHour(int hour) {
if(hour >= endHour) {
Serial.printf("SupervisorSM: %i is not less than current end hour %i\n", hour, endHour);
}else if(hour<0 || hour>23) {
Serial.println("SupervisorSM: invalid hour");
} else{
startHour = hour;
}
}
void SupervisorSM::setEndHour(int hour) {
if(hour <= startHour) {
Serial.printf("SupervisorSM: %i is not greater than current start hour %i\n", hour, startHour);
}else if(hour<0 || hour>23) {
Serial.println("SupervisorSM: invalid hour");
} else{
endHour = hour;
}
}
int SupervisorSM::getStartHour() {
return startHour;
}
int SupervisorSM::getEndHour() {
return endHour;
}
bool SupervisorSM::isDayTime() {
return Time.hour() >= startHour && Time.hour() < endHour;
}
void SupervisorSM::setIsAuto(bool isauto) {
isAuto = isauto;
}
bool SupervisorSM::getIsAuto() {
return isAuto;
}