Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Heroku Status Lights Monitor - Arduino Software
/*
Heroku Office Status Monitor
What it is: Arduino + Ethernet Shield
What it does: Networked device that provides status monitoring.
Components:
- Status site monitor
HTTP GET to http://outage-lights.herokuapp.com/status to consume current Heroku Platform status.
Go to http://outage-lights.herokuapp.com/ to see if this system is currently working.
- Local Override
A simple web server that turns pin 8 on when it recieves
a GET request to `/on` and turns that pin off when
it receives a GET request to `/off`.
- Trigger Failure when unable to connect to the web.
by Chris Continanza
*/
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(10,10,10,102);
//Heroku's Public raw IP endpoint FTW
IPAddress status_server(174,129,212,2);
int heartbeat_port = 80;
/* Deprectated: this was used when status and hearbeat were
* separate endonpoints.
int heartbeat_delay_millis = 5000;
int heartbeat_tolerance = 1000;
int last_heartbeat = 0;
*/
int status_delay_millis = 5000;
int status_tolerance = 1000;
int last_status = 0;
int http_failures_limit = 25;
boolean http_on = false;
boolean status_on = false;
int http_failures = 0;
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
int LED = 8;
void setup()
{
pinMode(LED, OUTPUT);
// open the serial port
Serial.begin(9600);
/*
// Not using DHCP so we have a static connection
// start the Ethernet connection:
Uncomment this block to use DHCP.
Serial.println("Trying to get an IP address using DHCP");
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
}
*/
// connect w. static ip - this is assigned at the router
// and makes connecting to the manual override easier.
Ethernet.begin(mac, ip);
// print your local IP address to Serial for debugging.
Serial.print("My IP address: ");
IPAddress my_ip = Ethernet.localIP();
for (byte thisByte = 0; thisByte < 4; thisByte++) {
// print the value of each byte of the IP address:
Serial.print(my_ip[thisByte], DEC);
Serial.print(".");
}
Serial.println();
// start listening for clients
server.begin();
}
/* HTTP Helper method
takes an EthernetClient object and returns a String.
it reads the next HTTP Response from the client one byte at a time.
*/
String readHTTPResponse(EthernetClient _client) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
boolean httpBody = false;
//string for fetching data from address
String httpRequest = "";
while (_client.connected()) {
if (_client.available()) {
char c = _client.read();
if(httpBody){
httpRequest.concat(c);
}
if (c == '\n' && httpBody){
return httpRequest;
}
if (c == '\n' && currentLineIsBlank) {
httpBody = true;
}
if (c == '\n') {
// you're starting a new lineu
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
}
/* HTTP Helper method
takes an EthernetClient object and returns a String.
it reads the next HTTP Request from the client one byte at a time.
*/
String readHTTPRequest(EthernetClient _client) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
//string for fetching data from address
String httpRequest = "";
while (_client.connected()) {
if (_client.available()) {
char c = _client.read();
httpRequest.concat(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
return httpRequest;
}
if (c == '\n') {
// you're starting a new lineu
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
}
/* Application loop
*/
void loop()
{
int time = millis();
if(status_on || http_on || http_failures > http_failures_limit){
digitalWrite(LED, HIGH); // set the LED on
}
else{
digitalWrite(LED, LOW); // set the LED off
}
//some delay logic
if((time % status_delay_millis < status_tolerance) &&
(time - last_status > status_delay_millis)){
last_status = time;
/* fire off a GET request to status */
EthernetClient status_client;
status_on = false;
if (status_client.connect(status_server, 80)) {
http_failures = 0;
Serial.println("connected to status");
// Make a HTTP request:
status_client.println("GET /status HTTP/1.0");
status_client.println("Host: outage-lights.herokuapp.com");
status_client.println("Authorization: Basic ---------------");
status_client.println();
String response = readHTTPResponse(status_client);
Serial.println(response);
Serial.println(response.indexOf("red"));
// If its red, turn the switch on.
// could probably make this my own response...
if(response.indexOf("red") == -1){
Serial.println("Status clear - LED OFF");
}
else {
Serial.println("Status red! - LED ON");
status_on = true;
}
}
else {
//count failures cus you didn't get a connection to the server
http_failures++;
Serial.println("connection to status failed");
}
//make sure you write all those bytes.
status_client.flush();
//aaaaaand give it some time
delay(10);
//cleanup
status_client.stop();
}
// Check if an HTTP request came in.
EthernetClient client = server.available();
if (client) {
String httpRequest = readHTTPRequest(client);
Serial.print(httpRequest);
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
//send an HTML response
if(httpRequest.startsWith("GET /on")){
Serial.println("HTTP Request - LED ON");
client.print("<h1>Outage Lights On</h1>");
http_on = true;
}
else if(httpRequest.startsWith("GET /off")){
Serial.println("HTTP Request - LED OFF");
client.print("<h1>Outage Lights Off</h1>");
http_on = false;
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
}
/*
Deprecated: heartbeat is assumed when GET goes to /status
//send the Heartbet request for monitoring.
EthernetClient heartbeat;
//delay logic
if((time % heartbeat_delay_millis < heartbeat_tolerance) &&
(time - last_heartbeat > heartbeat_delay_millis)){
Serial.println("heartbeat");
last_heartbeat = time;
// connect to Heroku via direct IP connection
// writing HTTP packet to the Socket like a boss
if (heartbeat.connect(heartbeat_server, heartbeat_port)) {
Serial.println("heartbeat connected");
http_failures = 0;
// Make an HTTP request:
heartbeat.println("POST /heartbeat HTTP/1.0");
heartbeat.println("Host: outage-lights-heartbeat.herokuapp.com");
heartbeat.println("Content-Length: 0");
heartbeat.println("Authorization: Basic -�-------------");
heartbeat.println();
heartbeat.println();
Serial.println("heartbeat sent");
}
else {
//you didn't get a connection to the server:
Serial.println("heartbeat connection failed");
http_failures++;
}
//flush and clean up after yourself
heartbeat.flush();
delay(50);
heartbeat.stop();
}
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.