Hackster is hosting Hackster Holidays, Finale: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Tuesday!Stream Hackster Holidays, Finale on Tuesday!
Chris Roberts
Published

IoT Refrigerator Tracker

An IoT device used to monitor when a refrigerator is opened. Great for tracking when you are snacking or to catch pesky thieves!

BeginnerFull instructions provided2,556
IoT Refrigerator Tracker

Things used in this project

Story

Read more

Code

fridgeAlarm.ino

C/C++
Main sketch used in the Refrigerator Monitor
#include <SPI.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <Wire.h>			// Needed by Energia for Tiva C LaunchPad 
#include "OPT3001.h"
#define USE_USCI_B1
#include <Temboo.h>
#include "TembooAccount.h" // Contains Temboo account information


unsigned long epoch; //Variable created to hold epoch time, used for the timestamp in google drive
opt3001 opt3001; //Declare the optical sensor on the Educational booster pack
WiFiClient client;

// The number of times to trigger the action if the condition is met
// We limit this so you won't use all of your Temboo calls while testing
int maxCalls = 10; //Change this value if you want the code to run indefinitely

// The number of times this Choreo has been run so far in this sketch
int calls = 0;

unsigned int readings = 0;
int maxLUX = 100; //Value used to determine which lux values trigger the choreo
int timeZoneShift = -5; //number of hours difference from GMT
void setup() {
  Serial.begin(9600);
  opt3001.begin();//initialize the optical sensor
  int wifiStatus = WL_IDLE_STATUS;

  // Determine if the WiFi Shield is present
  Serial.print("\n\nShield:");
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("FAIL");

    // If there's no WiFi shield, stop here
    while(true);
  }

  Serial.println("OK");

  // Try to connect to the local WiFi network
  while(wifiStatus != WL_CONNECTED) {
    Serial.print("WiFi:");
    wifiStatus = WiFi.begin(WIFI_SSID, WPA_PASSWORD);

    if (wifiStatus == WL_CONNECTED) {
      Serial.println("OK");
    } else {
      Serial.println("FAIL");
    }
    delay(5000);
  }

  // Initialize pins

  Serial.println("Setup complete.\n");
}

void loop() {
  //read from the optical sensor
  readings = opt3001.readResult();
  Serial.print("Lux Readings: ");
  Serial.println(readings,DEC);

  if (readings >= maxLUX) {
    if (calls < maxCalls) {
      Serial.println("\nTriggered! Calling appendRow Choreo...");
       runAppendRow(readings);
      calls++;
    } else {
      Serial.println("\nTriggered! Skipping to save Temboo calls. Adjust maxCalls as required.");
    }
  }
  delay(250);
}

void runAppendRow(int input) {
  TembooChoreo AppendRowChoreo(client);

  // Set Temboo account credentials
  AppendRowChoreo.setAccountName(TEMBOO_ACCOUNT);
  AppendRowChoreo.setAppKeyName(TEMBOO_APP_KEY_NAME);
  AppendRowChoreo.setAppKey(TEMBOO_APP_KEY);

  // Set Choreo inputs
  String ClientSecretValue = "Replace with your own Secret Value";    //EDIT NEEDED
  AppendRowChoreo.addInput("ClientSecret", ClientSecretValue);
  String RefreshTokenValue = "Replace with your own Refresh token";  // EDIT NEEDED
  AppendRowChoreo.addInput("RefreshToken", RefreshTokenValue);
  String RowDataValue = "=(("+String(epoch)+"+("+timeZoneShift+"*3600))/86400)+25569,"+String(input);
  AppendRowChoreo.addInput("RowData", RowDataValue);
  String SpreadsheetTitleValue = "Replace with Spreadsheet Title";    //EDIT NEEDED
  AppendRowChoreo.addInput("SpreadsheetTitle", SpreadsheetTitleValue);
  String ClientIDValue = "Replace with your Client ID";               //EDIT NEEDED
  AppendRowChoreo.addInput("ClientID", ClientIDValue);

  // Identify the Choreo to run
  AppendRowChoreo.setChoreo("/Library/Google/Spreadsheets/AppendRow");

  // Run the Choreo
  unsigned int returnCode = AppendRowChoreo.run();

  // Read and print the error message
  while (AppendRowChoreo.available()) {
    char c = AppendRowChoreo.read();
    Serial.print(c);
  }
  Serial.println();
  AppendRowChoreo.close();
}

epochTime.ino

C/C++
Used to find epoch time, runs in parallel with fridgeAlarm.ino
/*
 Udp NTP Client
Code adapted from github resource found here:
https://github.com/energia/Energia/blob/master/hardware/msp432/libraries/WiFi/examples/WiFiUdpNtpClient/WiFiUdpNtpClient.ino
 
 Modified 1 July 2014
 by Noah Luskey
 This code is in the public domain.
 */

unsigned int localPort = 2390;      // local port to listen for UDP packets
IPAddress timeServer(129,6,15,30); // time.nist.gov NTP server, can be changed.  Other servers can be found at http://tf.nist.gov/tf-cgi/servers.cgi
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets

// A UDP instance to let us send and receive packets over UDP
WiFiUDP Udp;

void epochSetup()
{
  delay(10000); //give WiFi time to initialize in the main function
  Udp.begin(localPort);
}

void epochLoop()
{
  sendNTPpacket(timeServer); // send an NTP packet to a time server
  // wait to see if a reply is available
  delay(1000);
  if ( Udp.parsePacket() ) {
    // We've received a packet, read the data from it
    Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer

    //the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, esxtract the two words:

    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    // combine the four bytes (two words) into a long integer
    // this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord;
    // now convert NTP time into everyday time:
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;
    // subtract seventy years:
    epoch = secsSince1900 - seventyYears;
    delay(2000);
  }
}

// send an NTP request to the time server at the given address
unsigned long 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();
}

Credits

Chris Roberts
8 projects • 21 followers
I am an applications engineer with Texas Instruments working with the Launchpad by trade, and a maker by passion!

Comments