Last active
August 4, 2020 03:54
-
-
Save savannahostrowski/3ff7c2f79b3f7ba1725043be15d2d22b to your computer and use it in GitHub Desktop.
A4 - Ambient Display
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
//--------------------------------------------- | |
// Contact Switch | |
//--------------------------------------------- | |
#include <ESP8266WiFi.h> // Requisite Libraries . . . | |
#include <PubSubClient.h> | |
#include <Wire.h> | |
#include <ArduinoJson.h> | |
#include "config.h" // include the configuration of credentials in the config.h file | |
#define MQTT_ENABLE 1 // for testing the sensor, set to 1 to enable posting data to the server | |
StaticJsonDocument<256> outputDoc; | |
////////// | |
//We need a 'truly' unique client ID for our esp8266, all client names on the server must be unique. | |
//Every device, app, other MQTT server, etc that connects to an MQTT server must have a unique client ID. | |
//This is the only way the server can keep every device separate and deal with them as individual devices/apps. | |
//The client ID is unique to the device. | |
////////// | |
char mac[6]; //A MAC address is a 'truly' unique ID for each device, lets use that as our 'truly' unique user ID!!! | |
char buffer[256]; // stores the data for the JSON document | |
unsigned long timer; // a timer for the MQTT server we don't want to flood it with data | |
// Create objects | |
WiFiClient espClient; | |
PubSubClient mqtt(espClient); | |
const int sensor = 4; | |
int currentDeskState = "down"; | |
int prevDeskState = "up"; | |
void setup() | |
{ | |
Serial.begin(115200); | |
Serial.println(); | |
Serial.print("This board is running: "); | |
Serial.println(F(__FILE__)); | |
Serial.print("Compiled: "); | |
Serial.println(F(__DATE__ " " __TIME__)); | |
pinMode(sensor, INPUT_PULLUP); | |
Serial.println("hello"); | |
if (MQTT_ENABLE) { | |
setup_wifi(); | |
mqtt.setServer(MQTT_SERVER, 1883); | |
} | |
timer = millis(); // start the timer | |
} | |
void loop(){ | |
if (millis() - timer > 5000) { //see if 5 seconds have elapsed since last message | |
currentDeskState = digitalRead(sensor); | |
String deskStateToPub = currentDeskState ? "down" : "up"; | |
if (currentDeskState != prevDeskState) { | |
outputDoc["deskState"] = deskStateToPub; | |
prevDeskState = currentDeskState; | |
serializeJson(outputDoc, buffer); | |
timer = millis(); // reset a 5-second timer | |
if (MQTT_ENABLE) { // if posting is turned on, post the data | |
if (!mqtt.connected()) { | |
reconnect(); | |
} | |
mqtt.publish(FEED, buffer); // post the data to the feed | |
Serial.println("Posted:"); | |
serializeJsonPretty(outputDoc, Serial); | |
Serial.println(); | |
mqtt.loop(); //this keeps the mqtt connection 'active' | |
} | |
} | |
} | |
} | |
/////SETUP_WIFI///// | |
void setup_wifi() { | |
delay(10); | |
// We start by connecting to a WiFi network | |
Serial.println(); | |
Serial.print("Connecting to "); | |
Serial.println(WIFI_SSID); | |
WiFi.begin(WIFI_SSID, WIFI_PASS); | |
while (WiFi.status() != WL_CONNECTED) { | |
delay(500); | |
Serial.print("."); | |
} | |
Serial.println(""); | |
Serial.println("WiFi connected."); | |
String temp = WiFi.macAddress(); //get the unique MAC address to use as MQTT client ID, a 'truly' unique ID. | |
temp.toCharArray(mac, 6); //.macAddress() returns a byte array 6 bytes representing the MAC address | |
} //5C:CF:7F:F0:B0:C1 for example | |
///CONNECT/RECONNECT///// Monitor the connection to MQTT server, if down, reconnect | |
void reconnect() { | |
// Loop until we're reconnected | |
while (!mqtt.connected()) { | |
Serial.print("Attempting MQTT connection..."); | |
if (mqtt.connect(mac, MQTT_TOKEN, MQTT_PASS)) { //<<---using MAC as client ID, always unique!!! | |
Serial.println("connected"); | |
mqtt.subscribe(FEED); | |
} else { | |
Serial.print("failed, rc="); | |
Serial.print(mqtt.state()); | |
Serial.println(" try again in 5 seconds"); | |
// Wait 5 seconds before retrying | |
delay(5000); | |
} | |
} | |
} | |
//--------------------------------------------- | |
// LIGHT | |
//--------------------------------------------- | |
#include <ESP8266WiFi.h> // Requisite Libraries . . . | |
#include <ESP8266HTTPClient.h> // HTTP Feather library | |
#include <PubSubClient.h> | |
#include <Wire.h> | |
#include "config.h" // include the configuration of credentials in the config.h file | |
//ArduinoJson can decode Unicode escape sequence, but this feature is disabled by default | |
//because it makes the code bigger. To enable it, you must define ARDUINOJSON_DECODE_UNICODE to 1 | |
#define ARDUINOJSON_DECODE_UNICODE 1 | |
#include <ArduinoJson.h> | |
#define MQTT_ENABLE 1 // for testing the sensor, set to 1 to enable posting data to the server | |
// Create objects for the ESP and MQTT clients | |
WiFiClient espClient; | |
PubSubClient mqtt(espClient); | |
char mac[12]; //A MAC address is a 'truly' unique ID for each device, lets use that as our 'truly' unique user ID!!! | |
unsigned long cbTimer; //A timer we will use for checking how long we've been sitting | |
int minsFactor = 60000; // This is used to convert milliseconds to minutes | |
// Configures the pins for the RGB LED | |
uint8_t bluePin = D5; | |
uint8_t greenPin = D6; | |
uint8_t redPin = D7; | |
// Stores all the RGB values for the LED | |
int colours[6][3] = { | |
{255, 0, 0}, //red | |
{0, 255, 0}, //green | |
{204, 204, 0}, //yellow | |
{0, 0, 255}, //blue | |
{80, 0, 80}, // purple | |
{0, 255, 255} // aqua | |
}; | |
String currentDeskState = "down"; // My desk is always down at the beginning of the day | |
String prevDeskState; //We will use this to see if the desk state has changed | |
int dayOfWeek; // Used to store the day of the week | |
int currentColourIdx = 1; // We will always start the colour of the light at green | |
// A function that takes in the RGB values to render a colour to set the pins on the LED | |
void setColour(int arr[3]) | |
{ | |
analogWrite(redPin, arr[0]); // Grabs the 0th index in the array (the red value) | |
analogWrite(greenPin, arr[1]); // Grabs the 1st index in the array (the green value) | |
analogWrite(bluePin, arr[2]); // Grabs the 2nd index in the array (the blue value) | |
}; | |
void setup() { | |
Serial.begin(115200); // Set the data rate in bits per second for serial data transmission and print that the program is starting | |
Serial.println("Starting!"); | |
//If MQTT is enabled | |
if (MQTT_ENABLE) { | |
setup_wifi(); //Set up WiFi | |
mqtt.setServer(MQTT_SERVER, 1883); //Set up server | |
mqtt.setCallback(callback); //Set up callback to be called when we received data from the subscribed MQTT feed | |
} | |
// Set up pins for the RGB LED | |
pinMode(redPin, OUTPUT); // red LED | |
pinMode(bluePin, OUTPUT); // blue LED | |
pinMode(greenPin, OUTPUT); // green LED | |
// Get the day of the week | |
dayOfWeek = getDayOfWeek(); | |
//If the day of the week is Saturday or Sunday | |
if(dayOfWeek == 0 or dayOfWeek == 6) { | |
// We do fun things! | |
cycleThroughColours(); | |
} | |
// Set the timer | |
cbTimer = millis(); | |
} | |
void loop() { | |
//If we haven't connected to MQTT, try again | |
if (!mqtt.connected()) { | |
reconnect(); | |
} | |
// If it's Saturday or Sunday, we want to don't want to do anything because we are cycling through colours! | |
if(dayOfWeek == 0 or dayOfWeek == 6) { | |
return; | |
} | |
// If it's a weekday then we check if the desk is up | |
if (currentDeskState == "up") { | |
setColour(colours[1]); //Set to green | |
} | |
else if (currentDeskState == "down") { //If the current desk state is down | |
if (millis() - cbTimer <= 15 * minsFactor) { //If the desk has been up for less than or equal to 15 mins | |
setColour(colours[1]); //Set to green | |
} | |
else if (millis() - cbTimer <= 45 * minsFactor) { //If the desk has been up for less than or equal to 30 mins | |
setColour(colours[2]); //Set to yellow | |
} | |
else if (millis() - cbTimer > 45 * minsFactor) { //If the desk has been up for less than or equal to 45 mins | |
setColour(colours[0]); //Set to red; time to stand! | |
} | |
} | |
mqtt.loop(); //this keeps the mqtt connection 'active' | |
} | |
// Called when we get data from the feed | |
void callback(char* topic, byte* payload, unsigned int length) { | |
StaticJsonDocument<256> doc; | |
// A better way, with error reporting too! | |
DeserializationError err = deserializeJson(doc, payload, length); | |
if (err) { //well what was it? | |
Serial.println("deserializeJson() failed, are you sure this message is JSON formatted?"); | |
Serial.print("Error code: "); | |
Serial.println(err.c_str()); | |
return; | |
} | |
// If a message is received on the topic esp32/output, you check if the message is either "on" or "off". | |
// Changes the output state according to the message | |
if (strcmp(topic, FEED) == 0) { | |
serializeJson(doc["deskState"], Serial); //Serialize the JSON to get the current desk state | |
prevDeskState = currentDeskState; //Set the previous state to the current state | |
currentDeskState = doc["deskState"].as<String>(); // Get the new desk state | |
cbTimer = millis(); //Reset the timer | |
} | |
} | |
/////SETUP_WIFI///// | |
void setup_wifi() { | |
delay(10); | |
// We start by connecting to a WiFi network | |
Serial.println(); | |
Serial.print("Connecting to "); | |
Serial.println(WIFI_SSID); | |
WiFi.begin(WIFI_SSID, WIFI_PASS); | |
while (WiFi.status() != WL_CONNECTED) { | |
delay(500); | |
Serial.print("."); | |
} | |
Serial.println(""); | |
Serial.println("WiFi connected."); | |
String temp = WiFi.macAddress(); //get the unique MAC address to use as MQTT client ID, a 'truly' unique ID. | |
temp.toCharArray(mac, 12); //.macAddress() returns a byte array 12 bytes representing the MAC address | |
} //5C:CF:7F:F0:B0:C1 for example | |
///CONNECT/RECONNECT///// Monitor the connection to MQTT server, if down, reconnect | |
void reconnect() { | |
// Loop until we're reconnected | |
while (!mqtt.connected()) { | |
Serial.print("Attempting MQTT connection..."); | |
if (mqtt.connect(mac, MQTT_TOKEN, MQTT_PASS)) { //<<---using MAC as client ID, always unique!!! | |
Serial.println("connected"); | |
mqtt.subscribe(FEED); //we are subscribing to 'theTopic' and all subtopics below that topic | |
} else { | |
Serial.print("failed, rc="); | |
Serial.print(mqtt.state()); | |
Serial.println(" try again in 5 seconds"); | |
// Wait 5 seconds before retrying | |
delay(5000); | |
} | |
} | |
} | |
// Helper that gets us the day of the week | |
int getDayOfWeek() { | |
// Instantiates a client object | |
HTTPClient theClient; | |
theClient.begin(DAY_OF_WEEK_URL); | |
// Make a GET request to the client | |
int httpCode = theClient.GET(); | |
Serial.println(httpCode); | |
// If we have a status code | |
if (httpCode > 0) | |
{ | |
// Status code is 200; request was successful | |
if (httpCode == 200) | |
{ | |
//Print to serial monitor that we got data from the endpoint | |
Serial.println("Received HTTP payload."); | |
// Instantiate the object to store the JSON document/blob | |
StaticJsonDocument<1024> doc; | |
// Get the JSON blob back from the endpoint (it's serialized at this point) | |
String payload = theClient.getString(); | |
Serial.println("Parsing..."); | |
// Derialize the payload into the doc variable | |
deserializeJson(doc, payload); | |
// Instantiates an error variable which we will check in the next line | |
DeserializationError error = deserializeJson(doc, payload); | |
// If there was an error | |
if (error) | |
{ | |
//Print that deserialization failed to the serial monitor | |
Serial.print("deserializeJson() failed with error code "); | |
// Derialization failed so we print the error | |
Serial.println(error.c_str()); | |
return -1; | |
} | |
// Get the day of the week by parsing the JSON | |
dayOfWeek = doc["day_of_week"].as<int>(); | |
} | |
else | |
{ | |
// Print that there's something wrong with the endpoint to the serial monitor | |
Serial.println("Something went wrong with connecting to the endpoint."); | |
} | |
} | |
// Return the day of the week | |
return dayOfWeek; | |
} | |
// A helper function to cycle colours | |
void cycleThroughColours() { | |
// Standard for loop; for each colour in the list of colours | |
for(int i = 0; i < sizeof(colours); i++) { | |
setColour(colours[i]); // Set the colour of the RGB LED to the colour | |
delay(2 * minsFactor); //Delay for 2 minutes before iterating again | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment