Hardware components | ||||||
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
I recreate this project "Arduino, Monitoring Door-Opening via Gmail", but instead of hard-coded email address, I make an web user interface to let user add/delete multiple email address via web.
Working FlowAdding/Deleting Email from Email List
User ----(email)----> Web ----------> Arduino --------> EEPROM
Sending Email Notification (when an event occurs)
- Reading email list from EEPROM
- Sending notifications to each email address one by one.
Similar to this project https://www.hackster.io/phpoc_man/arduino-set-schedule-via-web-ea5902
If you are new to Arduino, you can get started with Arduino Tutorials for newbie.
#include "SPI.h"
#include "Phpoc.h"
#include <EEPROM.h>
#ifndef EOF
#define EOF (-1)
#endif
#define CMD_ARDUINO_DEL 0
#define CMD_ARDUINO_GET 1
#define CMD_ARDUINO_ADD 2
#define CMD_WEB_CLR 5
#define CMD_WEB_UPD 6
#define MAX_NUM_EMAIL 10
class EepromCSV
{
public:
void clear(void);
int line(void);
String readLine(int line);
void writeLine(String lineStr);
};
EepromCSV EepromCSV;
PhpocServer webServer(80);
String emailArray[MAX_NUM_EMAIL];
int numEmail;
int lastState = 1;
unsigned long lastUpdateTime;
void setup() {
Serial.begin(9600);
while(!Serial)
;
Phpoc.begin(PF_LOG_SPI | PF_LOG_NET);
webServer.beginWebSocket("arduino");
Serial.print("WebSocket server address : ");
Serial.println(Phpoc.localIP());
//EepromCSV.clear();
eepromToEmailList(); // load email from EEPROM
lastState = digitalRead(A0);
lastUpdateTime = millis();
}
void loop() {
checkEmailListUpdate(); // check whether there is any config command from Web or not.
int currentState = digitalRead(A0);
if((millis() - lastUpdateTime) > 1000) // 1 second
{
if(lastState != currentState)
{
if (lastState == 1 && currentState == 0)
{ // if door is opened...
for(int i = 0; i < numEmail; i++)
{
sendRelayGmail(emailArray[i]);
delay(1000);
}
lastUpdateTime = millis();
}
else
if(lastState == 0 && currentState == 1)
{ // if door is closed...
// Write codes in the same way
}
lastState = currentState;
}
}
}
void sendRelayGmail(String emailAddress)
{
PhpocEmail email;
char charEmailAddr[50];
emailAddress.toCharArray(charEmailAddr, emailAddress.length() + 1);
email.setOutgoingServer("smtp.gmail.com", 587);
email.setOutgoingLogin("example@gmail.com", "example_password");
email.setFrom("example@gmail.com", "From Arduino Gmail");
email.setTo(charEmailAddr, "To Whom It May Concern");
email.setSubject(F("Door is opened. [#905]")); // Mail Subject
// Mail Contents
email.beginMessage();
email.println(F("#905"));
email.println("");
email.println(F("Door is opened."));
email.endMessage();
if (email.send() > 0) // Send Email
Serial.print(F("Your Mail has been sent successfully to "));
else
Serial.print(F("Your Mail is not sent to "));
Serial.println(emailAddress);
}
void eepromToEmailList(void) {
int lineCount = EepromCSV.line();
if(lineCount > MAX_NUM_EMAIL)
lineCount = MAX_NUM_EMAIL;
for(int i = 0; i < lineCount; i++)
{
String line;
line = EepromCSV.readLine(i);
emailArray[i] = line.substring(0, line.indexOf("\n"));
}
numEmail = lineCount;
}
void sendToWeb(String data) {
char wbuf[50];
data.toCharArray(wbuf, data.length() + 1);
webServer.write(wbuf, data.length());
}
void checkEmailListUpdate(void) {
// wait for a new client:
PhpocClient client = webServer.available();
if (client)
{
// read a string that is terminated by a carriage return and a newline
// characters:
String data = client.readLine();
if(data)
{
String email;
int cmd;
cmd = data.substring(0, 1).toInt();
if(cmd == CMD_ARDUINO_GET)
{
int lineCount = EepromCSV.line();
sendToWeb(String(CMD_WEB_CLR) + ",0\n"); /* tell web clear to load new email */
for(int i = 0; i < lineCount; i++)
{
email = EepromCSV.readLine(i); /* read email from EEPROM one by one */
sendToWeb(String(CMD_WEB_UPD) + "," + email + "\n"); /* send email to Web */
}
}
else
if(cmd == CMD_ARDUINO_DEL)
{
email = data.substring(2, data.indexOf("\r\n"));
EepromCSV.clear(); /* clear to update new email */
for(int i = 0; i < numEmail; i++)
{
if(!emailArray[i].equals(email))
EepromCSV.writeLine( emailArray[i]); /* write email to EEPROM */
}
eepromToEmailList(); /* reload email from EEPROM */
}
else
if(cmd == CMD_ARDUINO_ADD)
{
email = data.substring(2, data.lastIndexOf("\r\n"));
if(email.length())
{
EepromCSV.writeLine(email); /* write email to EEPROM */
eepromToEmailList(); /* reload email from EEPROM */
}
}
}
}
}
void EepromCSV::clear(void) {
EEPROM.write(0, EOF);
Serial.println(F("EepromCSV::clear"));
}
int EepromCSV::line(void) {
int lineCount = 0;
int address = 0;
char value;
while(1) {
value = EEPROM.read(address++);
if(value == '\n')
lineCount++;
else if(value == EOF)
return lineCount;
}
}
String EepromCSV::readLine(int line) {
String retStr = "";
char value;
int lineIndx = 0;
int address = 0;
while(lineIndx < line) {
value = EEPROM.read(address++);
if(value == '\n')
lineIndx++;
else if (value == EOF) {
return "";
}
}
while(1) {
value = EEPROM.read(address++);
if(value == '\n' || value == EOF)
{
Serial.print(F("EepromCSV::readLine:"));
Serial.println(retStr);
return retStr;
}
else
retStr += value;
}
}
void EepromCSV::writeLine(String lineStr) { /* add new line at the end of CSV file*/
int address, length;
address = 0;
length = lineStr.length();
while((char)EEPROM.read(address++) != EOF)
;
address--;
for(int i = 0; i < length; i++)
EEPROM.write(address++, lineStr.charAt(i));
EEPROM.write(address++, '\n');
EEPROM.write(address, EOF);
Serial.print(F("EepromCSV::writeLine:"));
Serial.println(lineStr);
}
<!DOCTYPE html>
<html>
<head>
<title>Arduino - Configure via Web</title>
<meta name="viewport" content="width=device-width, initial-scale=0.7, maximum-scale=0.7">
<meta charset="utf-8">
<style>
body { text-align: center; font-size: 100%; font-family: Roboto;}
#header { background-color: #00979d; color: white; padding: 5px; margin-bottom: 15px}
h2 { font-weight: bold; font-size: 120%; }
table th { font-weight: bold; font-size: 120%; border-bottom: 8px solid #00979d; }
table td { font-weight: bold; font-size: 120%; height: 40px; }
select, input { font-size: 100%; font-family: Roboto;}
.button { border-top: 10px solid white; font-size:130%; background-color: red; color:white;}
</style>
<script>
var CMD_ARDUINO_DEL = 0;
var CMD_ARDUINO_GET = 1;
var CMD_ARDUINO_ADD = 2;
var CMD_WEB_CLR = 5;
var CMD_WEB_UPD = 6;
var dayLookupTable = ["", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
var email_list = new Array();
var ws = null;
var buffer = "";
function init() {
if(ws == null) {
var ws_host_addr = "<?echo _SERVER("HTTP_HOST")?>";
if((navigator.platform.indexOf("Win") != -1) && (ws_host_addr.charAt(0) == "[")) {
// network resource identifier to UNC path name conversion
ws_host_addr = ws_host_addr.replace(/[\[\]]/g, '');
ws_host_addr = ws_host_addr.replace(/:/g, "-");
ws_host_addr += ".ipv6-literal.net";
}
ws = new WebSocket("ws://" + ws_host_addr + "/arduino", "text.phpoc");
ws.onopen = ws_onopen;
ws.onclose = ws_onclose;
ws.onmessage = ws_onmessage;
}
else
ws.close();
}
function ws_onopen() {
setTimeout(function() {
ws.send(CMD_ARDUINO_GET + ",0\r\n");
}, 100);
}
function ws_onclose() {
ws.onopen = null;
ws.onclose = null;
ws.onmessage = null;
ws = null;
alert("Not connected to Arduino!");
}
function ws_onmessage(e_msg) {
e_msg = e_msg || window.event; // MessageEvent
buffer += e_msg.data;
buffer = buffer.replace(/\r\n/g, "\n");
buffer = buffer.replace(/\r/g, "\n");
console.log(buffer);
while(buffer.indexOf("\n") == 0)
buffer = buffer.substr(1);
while(buffer.indexOf("\n") >= 0) { // because multiple update data may come at the same time
var data = buffer.substr(0, buffer.indexOf("\n"));
buffer = buffer.substr(buffer.indexOf("\n") + 1);
var arr = data.split(",");
var cmd = parseInt(arr[0]);
if(cmd == CMD_WEB_CLR) {
email_list = new Array();
var emailTable = document.getElementById("emailTable");
while( emailTable.rows.length > 2)
emailTable.deleteRow(1);
}
else if(cmd == CMD_WEB_UPD) {
var email = arr[1];
email_list.push(email);
var emailTable = document.getElementById("emailTable");
var numRow = emailTable.rows.length;
var newRow = emailTable.insertRow(numRow - 1);
newRow.insertCell().innerHTML = email;
newRow.insertCell().innerHTML = '<span style="color:red;" onclick="deleteEmail(this)">delete</span>';
newRow.cells[0].style.paddingRight="50px"
newRow.cells[0].style.textAlign = "right";
newRow.style.color = "#1E90FF";
}
}
}
function deleteEmail(event) {
var rowIndex = event.parentElement.parentElement.rowIndex;
document.getElementById("emailTable").deleteRow(rowIndex);
var email = email_list[rowIndex - 1];
email_list.splice(rowIndex - 1, 1);
if(ws == null)
alert("Not connected to Arduino!");
else
ws.send(CMD_ARDUINO_DEL + "," + email + "\r\n");
}
function addEmail(event) {
var emailTable = document.getElementById("emailTable");
var rowIndex = event.parentElement.parentElement.rowIndex;
var row = emailTable.rows[rowIndex];
var email = row.cells[0].childNodes[0].value;
if(!email)
return;
row.cells[0].innerHTML = email;
row.cells[1].innerHTML = '<span style="font-size:120%; color:red;" onclick="deleteEmail(this)">delete</span>';
row.cells[0].style.paddingRight="50px"
row.cells[0].style.textAlign = "right";
row.style.color = "#1E90FF";
email_list.push(email);
if(ws == null)
alert("Not connected to Arduino!");
else
ws.send(CMD_ARDUINO_ADD + "," + email + "\r\n");
}
function newEmail() {
var emailTable = document.getElementById("emailTable");
var numRow = emailTable.rows.length;
var newRow = emailTable.insertRow(numRow - 1);
var cell0 = newRow.insertCell();
var cell1 = newRow.insertCell();
cell0.innerHTML = '<input type="email" name="email" style="border-color: red; width:80%">';
cell1.innerHTML = '<span style="color:red;" onclick="addEmail(this)">add</span>';
}
window.onload = init;
</script>
</head>
<body>
<div id="header">
<span style="font-size:150%; font-weight: bold;">ARDUINO - EMAIL LIST</span><br>
<span style="font-size:130%; font-weight: normal;">Web To EEPROM</span>
</div>
<table id="emailTable" style="width:100%; table-layout:fixed;">
<tr>
<th>EMAIL ADDRESS</th>
<th width="30%">ADD / DELETE</th>
</tr>
<tr>
<td class="button" colspan="2" onclick="newEmail(this)">NEW</td>
</tr>
</table>
<br>
<h2>
</h2>
</body>
</html>




_ztBMuBhMHo.jpg?auto=compress%2Cformat&w=48&h=48&fit=fill&bg=ffffff)





Comments