-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAlarmNotification.cpp
More file actions
230 lines (206 loc) · 5.76 KB
/
AlarmNotification.cpp
File metadata and controls
230 lines (206 loc) · 5.76 KB
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#include "AlarmNotification.h"
/*
* @brief Initialization function. Telegram bot and pin setup. At the end of the function
* sends a confirmation message
* @param
* @return
*/
void AlarmNotification::setupAlarmNotificationManager(const String &tg_token, int en_pin, int al_pin)
{
evtbuff = new eventbuffer::EventBuffer();
notify = new notifications::NotificationLib();
enabled_pin = en_pin;
alarm_pin = al_pin;
alarm_msg_latch = false;
alarm_en_latch = true;
// Setup pins
pinMode(enabled_pin, INPUT);
pinMode(alarm_pin, INPUT);
// notify to all available chats that the system has restarted
notify->send(startup_message);
evtbuff->add(eventbuffer::event_t::STARTED);
}
/*
* @brief Cyclic function. Check if a request has been sent through Telegram and It calls
* the appropriate processing function
* @param
* @return
*/
void AlarmNotification::checkNewRequests()
{
String msg;
bool newmsgreceived = notify->getCommand(msg);
if (newmsgreceived)
{
if (msg == "/status")
{
send_triggered_state();
}
else if (msg == "/log")
{
send_alarm_log();
}
}
}
/*
* @brief send a message through telegram reporting the state of the alarm
* (enabled/disabled)
* @param
* @return
*/
void AlarmNotification::send_triggered_state()
{
if(digitalRead(enabled_pin))
notify->send(alarm_en);
else
notify->send(alarm_dis);
}
/*
* @brief send the event log as Telegram message
* @param
* @return
*/
void AlarmNotification::send_alarm_log()
{
// get a iterator to the event buffer
eventbuffer::EventBuffer::iterator* itr = evtbuff->getIterator();
// create a string containing the final message starting from
// the LOG_HEADER string
String msg = String(LOG_HEADER);
// log should never be empty
if(!itr->empty())
{
// for each entry in the log, print a message based
// on the type of event
do
{
msg.concat("\n[");
msg.concat(itr->getDate());
msg.concat("]");
switch(itr->getEvent())
{
case eventbuffer::event_t::CONN_REST:
msg.concat(LOG_CONN_REST);
break;
case eventbuffer::event_t::CONN_LOST:
msg.concat(LOG_CONN_LOST);
break;
case eventbuffer::event_t::STARTED:
msg.concat(LOG_STARTED);
break;
case eventbuffer::event_t::ALARM_ENABLED:
msg.concat(LOG_ALARM_ENABLED);
break;
case eventbuffer::event_t::ALARM_DISABLED:
msg.concat(LOG_ALARM_DISABLED);
break;
case eventbuffer::event_t::ALARM_TRIGGERED:
msg.concat(LOG_ALARM_TRIGGERED);
break;
case eventbuffer::event_t::ALARM_BACKTONORMAL:
msg.concat(LOG_ALARM_BACKTONORMAL);
break;
}
}
while(itr->next());
}
else
{
// otherwise print empty log message
msg.concat(LOG_EMPTY);
}
// clear the iterator
delete itr;
// send the message through Telegram
notify->send(msg);
}
/*
* @brief cyclic function. Check the state of the alarm (enabled/disabled) and its condition
* (triggered/normal). Send a notification through Telegram if the alarm is triggered
* @param
* @return
*/
void AlarmNotification::checkAlarmState()
{
// verify alarm enabled status
bool alarm_enabled = digitalRead(enabled_pin);
// verify alarm triggering condition
bool alarm_triggered = digitalRead(alarm_pin);
if(alarm_enabled)
{
// if alarm enabled latch is not set, then this is
// the first read of an alarm enabled. A new event
// shall be added to the log
if(!alarm_en_latch)
{
// Set the latch to avoid log repetitions
alarm_en_latch = true;
// log alarm enabled
evtbuff->add(eventbuffer::event_t::ALARM_ENABLED);
}
// if alarm is triggered check latch state
// and store log and send message
if(alarm_triggered && !alarm_msg_latch)
{
// Set the latch to avoid message repetitions
alarm_msg_latch = true;
// send telegram notification only if wifi is
// connected (otherwise system will be blocked
// on message send
if(WiFi.status() == WL_CONNECTED)
{
notify->send(alarm_wrn);
}
// add alarm enabled to the event buffer
evtbuff->add(eventbuffer::event_t::ALARM_TRIGGERED);
}
}
// reset alarm message latch. Messages are
// allowed again
if(alarm_msg_latch && (!alarm_enabled || !alarm_triggered))
{
alarm_msg_latch = false;
evtbuff->add(eventbuffer::event_t::ALARM_BACKTONORMAL);
}
// reset alarm log latch. Store alarm log
if(alarm_en_latch && !alarm_enabled)
{
alarm_en_latch = false;
evtbuff->add(eventbuffer::event_t::ALARM_DISABLED);
}
}
/*
* @brief Cyclic function. Check the status of the WiFi network and try to
* reconnect in case of connection lost
* @param
* @return
*/
void AlarmNotification::checkAndReconnectWifi(int expiration_ms)
{
int elapsed = 0;
// verify that wifi is not connected
if(WiFi.status() != WL_CONNECTED)
{
// connect
WiFi.begin(WIFI_SSID, WIFI_KEY);
if(!evt_disconnect_latch)
{
evt_disconnect_latch = true;
evtbuff->add(eventbuffer::event_t::CONN_LOST);
}
}
// wait until connected or expired
while (WiFi.status() != WL_CONNECTED) {
delay(EVAL_TIME_MS);
elapsed += EVAL_TIME_MS;
if(expiration_ms > 0 && elapsed > expiration_ms)
{
break;
}
}
if(evt_disconnect_latch && WiFi.status() == WL_CONNECTED)
{
evtbuff->add(eventbuffer::event_t::CONN_REST);
evt_disconnect_latch = false;
}
}