Last active
September 27, 2022 16:30
-
-
Save ItKindaWorks/23c550db3552ce018118594375356a20 to your computer and use it in GitHub Desktop.
An ESP8266 script to send a push notification when started up notifying the user that a fire alarm has been set off. Video link here: https://youtu.be/48rV7RkM_2U
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
smokeAlert.ino | |
Copyright (c) 2018 ItKindaWorks All right reserved. | |
github.com/ItKindaWorks | |
smokeAlert.ino is free software: you can redistribute it and/or modify | |
it under the terms of the GNU General Public License as published by | |
the Free Software Foundation, either version 3 of the License, or | |
(at your option) any later version. | |
smokeAlert.ino is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU General Public License for more details. | |
You should have received a copy of the GNU General Public License | |
along with smokeAlert.ino. If not, see <http://www.gnu.org/licenses/>. | |
https://youtu.be/48rV7RkM_2U | |
*/ | |
#include "ESPHelper.h" | |
#include "Metro.h" | |
#include <TimeLib.h> | |
#include <WiFiUdp.h> | |
#include <EspProwl.h> | |
//setup macros for time | |
#define SECOND 1000L | |
#define MINUTE SECOND * 60L | |
#define HOUR MINUTE * 60L | |
//timers for turn off | |
Metro minRun = Metro(1 * MINUTE); | |
Metro maxRun = Metro(5 * MINUTE); | |
//NTP setup vars | |
static const char ntpServerName[] = "us.pool.ntp.org"; | |
const int timeZone = -5; | |
WiFiUDP Udp; | |
unsigned int localPort = 8888; // local port to listen for UDP packets | |
time_t getNtpTime(); | |
void sendNTPpacket(IPAddress &address); | |
//ESPHelper | |
netInfo homeNet = { .mqttHost = "YOUR MQTT-IP", //can be blank if not using MQTT | |
.mqttUser = "YOUR MQTT USERNAME", //can be blank | |
.mqttPass = "YOUR MQTT PASSWORD", //can be blank | |
.mqttPort = 1883, //default port for MQTT is 1883 - only chance if needed. | |
.ssid = "YOUR SSID", | |
.pass = "YOUR NETWORK PASS", | |
.otaPassword = "YOUR OTA PASS", | |
.hostname = "NEW-ESP8266"}; | |
ESPHelper myESP(&homeNet); | |
//initDone keeps track of initialization finished or not | |
bool initDone = false; | |
//done keeps track of whether the device has finished the task | |
bool done = false; | |
void setup() { | |
myESP.OTA_enable(); | |
myESP.OTA_setPassword("mauimaui"); | |
myESP.OTA_setHostnameWithVersion(homeNet.hostname); | |
myESP.enableHeartbeat(LED_BUILTIN); //01 ledPin | |
myESP.begin(); | |
myESP.setCallback(callback); | |
Udp.begin(localPort); | |
setSyncProvider(getNtpTime); | |
setSyncInterval(300); | |
EspProwl.begin(); | |
EspProwl.setApiKey("YOUR PROWL API KEY"); | |
EspProwl.setApplicationName("ESP Smoke Alarm"); | |
} | |
void loop(){ | |
if(myESP.loop() == FULL_CONNECTION){ | |
//once we have a full connection trigger some extra setup | |
if(!initDone){ | |
delay(500); | |
//setup the NTP connection and get the current time | |
setupNTP(); | |
delay(500); | |
//only set initDone to true if the time is set | |
if(timeStatus() != timeNotSet){ | |
initDone = true; | |
} | |
} | |
//if were not done running the code that we need to finish executing and we are done initializing | |
if(!done && initDone){ | |
//generate a char array to store the data being published | |
char timeStamp[30]; | |
//fill the array with the time data | |
createTimeString(timeStamp, 30); | |
//create a string that will be published | |
String pubString = String("Smoke Alarm set off at "); | |
//add the timestamp to the string | |
pubString += timeStamp; | |
//convert the string to a char array that can be published/pushed to IOS | |
char message[50]; | |
pubString.toCharArray(message, 50); | |
//publish/push the message to IOS | |
myESP.publish("/home/fire", message, true); | |
EspProwl.push("ESP Fire Alarm", message, 0); | |
done = true; | |
} | |
//send the ESP to deep sleep (to be woken up by pulling rst low) | |
if((minRun.check() && done) || maxRun.check()){ | |
ESP.deepSleep(0, WAKE_RF_DEFAULT); | |
} | |
} | |
yield(); | |
} | |
void callback(char* topic, uint8_t* payload, unsigned int length) { | |
} | |
//generate a str with the current date/time | |
void createTimeString(char* buf, int length){ | |
time_t t = now(); | |
String timeString = String(hour(t)); | |
timeString += ":"; | |
timeString += minute(t); | |
timeString += ":"; | |
timeString += second(t); | |
timeString += " "; | |
timeString += month(t); | |
timeString += "/"; | |
timeString += day(t); | |
timeString += "/"; | |
timeString += year(t); | |
timeString.toCharArray(buf, length); | |
} | |
/*-------- NTP code ----------*/ | |
void setupNTP(){ | |
delay(200); | |
Udp.begin(localPort); | |
setSyncProvider(getNtpTime); | |
setSyncInterval(300); | |
} | |
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message | |
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets | |
time_t getNtpTime() | |
{ | |
IPAddress ntpServerIP; // NTP server's ip address | |
while (Udp.parsePacket() > 0) ; // discard any previously received packets | |
//Serial.println("Transmit NTP Request"); | |
// get a random server from the pool | |
WiFi.hostByName(ntpServerName, ntpServerIP); | |
//Serial.print(ntpServerName); | |
//Serial.print(": "); | |
//Serial.println(ntpServerIP); | |
sendNTPpacket(ntpServerIP); | |
uint32_t beginWait = millis(); | |
while (millis() - beginWait < 1500) { | |
int size = Udp.parsePacket(); | |
if (size >= NTP_PACKET_SIZE) { | |
//Serial.println("Receive NTP Response"); | |
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer | |
unsigned long secsSince1900; | |
// convert four bytes starting at location 40 to a long integer | |
secsSince1900 = (unsigned long)packetBuffer[40] << 24; | |
secsSince1900 |= (unsigned long)packetBuffer[41] << 16; | |
secsSince1900 |= (unsigned long)packetBuffer[42] << 8; | |
secsSince1900 |= (unsigned long)packetBuffer[43]; | |
return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR; | |
} | |
} | |
//Serial.println("No NTP Response :-("); | |
return 0; // return 0 if unable to get the time | |
} | |
// send an NTP request to the time server at the given address | |
void sendNTPpacket(IPAddress &address) | |
{ | |
// set all bytes in the buffer to 0 | |
memset(packetBuffer, 0, NTP_PACKET_SIZE); | |
// Initialize values needed to form NTP request | |
// (see URL above for details on the packets) | |
packetBuffer[0] = 0b11100011; // LI, Version, Mode | |
packetBuffer[1] = 0; // Stratum, or type of clock | |
packetBuffer[2] = 6; // Polling Interval | |
packetBuffer[3] = 0xEC; // Peer Clock Precision | |
// 8 bytes of zero for Root Delay & Root Dispersion | |
packetBuffer[12] = 49; | |
packetBuffer[13] = 0x4E; | |
packetBuffer[14] = 49; | |
packetBuffer[15] = 52; | |
// all NTP fields have been given values, now | |
// you can send a packet requesting a timestamp: | |
Udp.beginPacket(address, 123); //NTP requests are to port 123 | |
Udp.write(packetBuffer, NTP_PACKET_SIZE); | |
Udp.endPacket(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment