ESP8266 NodeMCU WiFi IoT Garage Door Opener Relay with Cayenne

ESP8266 NodeMCU WiFi Garage Door Opener Relay

ESP8266 NodeMCU WiFi IoT Garage Door Opener Relay with Cayenne

Wait! Didn’t you already do a post on an ESP8266 NodeMCU Garage Door Opener? Yup, I did! But for that post here we used the online IoT service/app Blynk. This new post makes some additions and also explores a new online IoT service called Cayenne. As a matter of fact, I have at least 2 more ESP8266 Garage Door posts planned as I feel it’s a great project to test out these IoT platforms. The next one will likely be using thinger.io and the fourth one will probably be using the Homie MQTT Framework. I am open to suggestion for other platforms to try out!

(Cayenne was offering $50 Participation Prize for Projects using Cayenne submitted in September & October: http://www.cayenne-mydevices.com/resources/articles/announcing-cayennes-maker-contest-50-participation-prize-200-grand-prize/  although I did not enter it.)

A few changes since the ESP8266 NodeMCU Relay WiFi Garage Door Opener with Blynk post:

  • Added DHT22/AM3202 Temperature & Humidity Sensor
  • Added Gl5537 Light Sensor
  • Added MQTT to send data to my OpenHab install.
  • Added ability for OpenHab to also open/control the Garage Door.

I should note again that my install and code is specific for a Marantec Garage Door Opener. You may need to modify this code for your particular Garage Door Opener and this will likely void your warranty!

Here’s a video of it in action:

*Disclaimer: Most if not all links on this page will be Affiliate Links. This helps pay for things like website hosting and more bits & gadgets to write about.

Picture of Garadget Wifi Smartphone Open Source Garage Door Opener

If after reading this post, you decide that you don’t want to DIY, but you DO want to stick with an Open Source solution, then please check out Garadget by SoftComplex (shown above) which is based on the Particle Photon! There is even a Garadget Addon Binding for OpenHab and Garadget now has an Alexa Skill -> “Alexa, tell Garadget to close all the doors.”

ESP8266 NodeMCU WiFi IoT Garage Door Opener Relay with MQTT & Cayenne

Parts List:

ESP8266 NodeMCU HiLetgo new Version from Amazon $8

Uxcell a13071200ux0770 Relay Shield Module $4.99 from Amazon.

DHT22 or AM2302 Temperature/Humidity Sensor $9.99 for version with built in pull up resistor

GL5537 Light Sensor $6.99 or cheaper for 20 units

10K Resistor for Gl5537 Light Sensor

1K Resistor for Active Buzzer

Assorted Breadboards – I bought a pack on Amazon for $10.99 but you probably  have a few extra laying around.

Ksmile 20M 20AWG 66ft Extension Cable Wire Cord for Led Strips Single Colour 3528 5050, 2 Pin Red/Black Hookup Wire 12V DC to connect to Garage Door Opener.

(I only needed about 1 foot and you may already have suitable wire laying around.)

3M Scotch Heavy Duty Mounting Tape, 1-Inch by 125-Inch (314) holds up to 5 lbs – $4.39 on Amazon

Elegoo 120pcs Multicolored Dupont Wire 40pin Male to Female, 40pin Male to Male, 40pin Female to Female Breadboard Jumper Wires Ribbon Cables Kit  $8.68

I also used an Active Buzzer I had from this SunFounder Project Super Starter Kit for Raspberry Pi 3, 2 & Model B+  but you can purchase buzzer by itself for a lot cheaper without the kit.( 10 Active buzzers for $8 on Amazon )

I am using my Alarm Sensor which is connected to OpenHab Home Automation to let me know if the door is opened or closed, but you may want to add something like this Security Garage Door Rolling Gate Magnet Alarm Reed Switch and connect it to the ESP8266 to know if the door is opened or closed. I plan to add one soon as a back up to my alarm sensor.

I like to use Amazon Prime for parts because I am impatient, but you can probably save some money if you order a lot of these parts from Ebay, Bangood or AliExpress.

Screenshot of ESP8266 NodeMCU Garage Door Opener Cayenne IoT

Cayenne tout’s themselves as the “The World’s First Drag-and-Drop IoT Project Builder”. They have a web-based dashboard as well as Android and iOS app. The latter is important to me as I’d like to be able to control and monitor my IoT things when I’m not home. They also have SMS & Email alerts based on triggered events; i.e. text me if the garage door is opened.

Screenshot of ESP8266 NodeMCU Garage Door Opener Cayenne IoT Android App

I am not using the Scheduling function in this Garage Door project but do see where it could be useful.

I do really like the data graphing!

screenshot of esp8266 nodemcu garage door opener cayenne iot data graphing

Right now you can sign up for a FREE Beta account here: https://www.cayenne-mydevices.com/signup/

I asked and Cayenne told me they may add some optional freemium-style pricing, but the actual product will stay gratis for makers and devs. “We make money by licensing to companies and white labeling.”

The Cayenne Dashboard supports setting up a Raspberry Pi or an Arduino. There is no specific ESP8266 device, but choosing Arduino Uno with WiFi Shield works for me.

Cayenne will give you a TOKEN which you will need to input into the Arduino sketch.

Screenshot of esp8266 cayenne setup screen with token

List of official support hardware is here: https://www.cayenne-mydevices.com/Supported-Hardware/

Cayenne requires the Blynk libraries along with the Cayenne libraries.

My #includes for this project look like this(I’ll post the entire code a little further down):

#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space

#include <ESP8266WiFi.h>
#include "CayenneDefines.h"
#include "BlynkSimpleEsp8266.h"
#include "CayenneWiFiClient.h"

#include <Wire.h>
#include <PubSubClient.h>
#include <DHT.h>
#define DHTTYPE DHT22
#define DHTPIN 4
#define VIRTUAL_PIN V1
#define VIRTUAL_PIN V2
#define VIRTUAL_PIN V3
#define VIRTUAL_PIN V4
#define VIRTUAL_PIN V5
#define VIRTUAL_PIN V6
#define REST 1000 //Rest Between Inhalations.

Similar to Blynk, you can read and write to Virtual Pins. To write my Temperature and Humidity values to Cayenne the code looks like this:

    String TempF;
    String Humid;
    TempF = String(temp_f);
    Humid = String(humidity);
    Cayenne.virtualWrite(V1, temp_f);
    Cayenne.virtualWrite(V2, humidity);

To send a command from Cayenne to my ESP8266 to trigger the garage door relay the code looks like this:

CAYENNE_IN(V3)
{
  // get value sent from dashboard
  int currentValue = getValue.asInt(); // 0 to 1

  // assuming you wire your relay as normally open
  if (currentValue == ) {
    digitalWrite(13, HIGH);
  } else {
    CloseGarage();
    }
}

void CloseGarage() {
  //Beep Buzzer & Flash Lights
     unsigned char i, j ;// define variables
      for (i = ; i <12; i++)
      {
      digitalWrite (buzzer, LOW) ; // Turn buzzer ON
      delay (300) ;// Delay 10ms
      digitalWrite (buzzer, HIGH) ;// turn buzzer OFF
      delay (75) ;// delay 10ms
    }
      for (i = ; i <15; i++)
      {
      digitalWrite(13, LOW); // GPIO13 Closes Relay
      digitalWrite (buzzer, LOW) ; // Turn buzzer ON
      delay (75) ;// Delay 10ms
      digitalWrite(13, HIGH);
      digitalWrite (buzzer, HIGH) ;// turn buzzer OFF
      delay (150) ;// delay 10ms
      }
      delay(1500);
      Serial.println("Closing Garage!");
      digitalWrite(13, LOW); //Close Relay = Close Garage Door
      delay(750);
      digitalWrite(13, HIGH);     
}

Pretty simple right? On the Cayenne Dashboard, you will reference the same Virtual Pins to display you Data in a widget or activate a button.

While Cayenne has many built-in devices and sensors, for me it worked better creating a generic widget and choosing the appropriate virtual pin as shown below:

screenshot of ESP8266 NodeMCU WiFi Garage Door Opener Cayenne IoT Temperature Widget.jpg

I like the ability to set colors for different temperature ranges. I would like to see some “cold” oriented colors such as blue added.

At the time I set up this project, Cayenne had an On/Off Switch but not a momentary switch which is what I wanted to activate the Garage Door. I found a work around using their Trigger functionality.

Related Read ->  ESP8266 NodeMCU Relay WiFi Garage Door Opener with Blynk

When the switch is turned on, turn it off! Simple! I think with future improvements to Cayenne we could have a button that says “Close” when the Garage Door is open and “Open” when the Garage Door is closed. If Cayenne adds this functionality, I will update this post.

Screenshot ESP8266 NodeMCU WiFi Garage Door Opener Cayenne IoT Momentary Switch Trigger

Here are my widget settings for the button:

Screenshot of ESP8266 NodeMCU WiFi Garage Door Opener Cayenne IoT Button

 

My sketch below includes using MQTT but you do NOT need this to use it with Cayenne. I use MQTT to also use the ESP8266 with my OpenHab Home Automation install. Also, Cayenne is working on there implementation which will hopefully be available soon.

You will need to install the following Arduino Libraries: DHT, Blynk, Cayenne, PubSubClient MQTT(PubSubClient not needed if you ar NOT using MQTT):

Screenshot ESP8266 DHT Temperature Humidity Sensor Arduino Library Screenshot of ESP8266 Blynk Arduino Library

Screenshot ESP8266 Cayenne Arduino Library Screenshot of ESP8266 PubSubClient MQTT Arduino Library

 

After you have those libraries installed,  here is the entire sketch for this project.

*Note: If you are not using MQTT, then click here use this Non-MQTT Sketch instead.

The Fritzing Wiring can be found below the code.

 

/*   ********************************************************************************************
          Garage Door Opener with Warning Light and Buzzer for Marantec with Cayenne IoT
          Author: Rich Plakas / Austin, TX - USA
          Reviewed: October 31, 2016
 *   ********************************************************************************************
*/
#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space

#include <ESP8266WiFi.h>
#include "CayenneDefines.h"
#include "BlynkSimpleEsp8266.h"
#include "CayenneWiFiClient.h"

#include <Wire.h>
#include <PubSubClient.h> //mqtt
#include <DHT.h>
#define DHTTYPE DHT22
#define DHTPIN 4
#define VIRTUAL_PIN V1
#define VIRTUAL_PIN V2
#define VIRTUAL_PIN V3
#define VIRTUAL_PIN V4
#define VIRTUAL_PIN V5
#define VIRTUAL_PIN V6
#define REST 1000    //Rest Between Inhalations.

int lightPin = 0;  //define a pin for Photo resistor
int buzzer = 5 ;// connect the I/O pin on the buzzer to this

// MQTT Server
const char* mqtt_server = "192.168.1.100"; //Your MQTT Server IP

DHT dht(DHTPIN, DHTTYPE, 20);
float humidity, temp_f;  // Values read from sensor - See more at: http://www.esp8266.com/viewtopic.php?f=29&t=8746#sthash.X8sbMBjM.dpuf

// Generally, you should use "unsigned long" for variables that hold time
unsigned long previousMillis = 0; 
unsigned long lastTempUpdate = 0;   
const long interval = 5000;

// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
char token[] = "Your Cayenne Access Token";
// Your network name and password.
char ssid[] = "Your WiFI Access Pont Name";
char password[] = "Your WiFi Password";

// MQTT 
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
char msgF[50];
char msgH[50];
int value = 0;

int gState = 0;
long rssi;
IPAddress ip;
char message_buff[100];

void callback(char* topic, byte* payload, unsigned int length) {  
  int i = ;
  for (i = ; i < length; i++) {
    message_buff[i] = payload[i];
  Serial.print((char)payload[i]);
   }
  Serial.println(); 
  message_buff[i] = '\0';
  String msgString = String(message_buff);
  Serial.println("Inbound: " + String(topic) +":"+ msgString);
  Serial.println(); 

  // Display Current Garage Door Status from DSC - OpenHab
  
  if ( msgString == "OPEN" ) {
      OpenGarage();
      Serial.print("Opening from MQTT");
    } 
  else if ( msgString == "CLOSE" ) { 
      CloseGarage();
      Serial.println("Closing from MQTT!");
  }
  else if ( msgString == "OPENED" ) {
      Serial.println("Garage Status Update: Open. Setting gState to 1");
      gState = 1;
  }
  else if ( msgString == "CLOSED" ) {
      Serial.println("Garage Status Update: Closed. Setting gState to 2");
      gState = 2;
  }
  else {
      Serial.print("No MQTT Update Recognized: ");
      Serial.println(msgString);
      gState = ;
  }
  Serial.print("MQTT gState:");
  Serial.println(gState);
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266Client")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
    //  client.publish("outTopic", "hello world");
      // ... and resubscribe
      client.subscribe("sm_garage/relay1");
      client.subscribe("sm_garage/status");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}


void setup()
{
  digitalWrite(13, HIGH); //GPIO13
  pinMode(13, OUTPUT);       // Pin connected to the Relay
  digitalWrite(5, HIGH); //GPIO5
  pinMode(buzzer, OUTPUT);       // Pin connected to the Buzzer
  Serial.begin(230400);
  Cayenne.begin(token, ssid, password);
  //MQTT 
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  client.subscribe("sm_garage/relay1");
  client.subscribe("sm_garage/status");
  dht.begin();
  Serial.print("Setup Gstate:");
  Serial.println(gState);
}



// ==============( Void Loop  ) ====================================

void loop() {
  
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  Cayenne.run();
  unsigned long now = millis();
  if ( now - lastTempUpdate > 60000 ) {  
    String MyIp;  
    String Both;
    MyIp =  "IP: " + String(WiFi.localIP()[]) + "." + String(WiFi.localIP()[1]) + "." + String(WiFi.localIP()[2]) + "." + String(WiFi.localIP()[3]);
    String MyWiFi;
    MyWiFi = "WiFi: " + String(WiFi.RSSI());
    Serial.println(MyIp);
    Serial.println(MyWiFi);
    gettemperature();
    Serial.print("Sending temperature:");
    Serial.println(temp_f);
    dtostrf(temp_f , 3, 2, msgF);
    client.publish("sm_garage/temperature", msgF);
    //gettemperature();
    Serial.print("Sending humidity:");
    Serial.println(humidity);
    dtostrf(humidity , 2, 2, msgH);
    client.publish("sm_garage/humidity", msgH);
    lastTempUpdate = now;
    Serial.print("Loop Garage State: ");
    Serial.println(gState);
    switch (gState) {
       case 1:
       Cayenne.virtualWrite(V4, 100);
       break;
       case 2 : 
       Cayenne.virtualWrite(V4, 0);
       break;
       default:
       Cayenne.virtualWrite(V4, 50);
       break;
    }  
  }
   
}

void gettemperature() {
  // Wait at least 2 seconds seconds between measurements.
  // if the difference between the current time and last time you read
  // the sensor is bigger than the interval you set, read the sensor
  // Works better than delay for things happening elsewhere also
  /*unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis >= interval) { 
    // save the last time you read the sensor 
    previousMillis = currentMillis;   */

    // Reading temperature for humidity takes about 250 milliseconds!
    // Sensor readings may also be up to 2 seconds 'old' (it's a very slow sensor)
    humidity = dht.readHumidity();<          // Read humidity (percent)
    temp_f = dht.readTemperature(true);     // Read temperature as Farenheight
    
    
    // Check if any reads failed and exit early (to try again).
    if (isnan(humidity) || isnan(temp_f)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }
    String TempF;
    String Humid;
    TempF = String(temp_f);
    Humid = String(humidity);
    Cayenne.virtualWrite(V1, temp_f);
    Cayenne.virtualWrite(V2, humidity);

    int lightsensor = analogRead(lightPin);
    float voltage = lightsensor;
    
    Cayenne.virtualWrite(V6, voltage);
    Serial.print("Ambient Light: ");
    Serial.println(analogRead(lightPin)); 
    Serial.print("Luminosity: ");
    Serial.println(voltage);
}

CAYENNE_IN(V3)
{
  // get value sent from dashboard
  int currentValue = getValue.asInt(); // 0 to 1

  // assuming you wire your relay as normally open
  if (currentValue == ) {
    digitalWrite(13, HIGH);
  } else {
    CloseGarage();
    }
}

void CloseGarage() {
  //Beep Buzzer & Flash Lights to warn about Garage Door Closing
     unsigned char i, j ;// define variables
      for (i = ; i <12; i++)
      {
      digitalWrite (buzzer, LOW) ; // Turn buzzer ON
      delay (300) ;// Delay 300ms
      digitalWrite (buzzer, HIGH) ;// turn buzzer OFF
      delay (75) ;// delay 75ms
    }
      for (i = ; i <15; i++) 
      {
      digitalWrite(13, LOW); // GPIO13 Closes Relay
      digitalWrite (buzzer, LOW) ; // Turn buzzer ON
      delay (75) ;// Delay 75ms to turn Garage Door Light Onn/Off
      digitalWrite(13, HIGH);
      digitalWrite (buzzer, HIGH) ;// turn buzzer OFF
      delay (150) ;// delay 150ms
      }
      delay(1500);
      Serial.println("Closing Garage!");
      digitalWrite(13, LOW); //Close Relay = Close Garage Door
      delay(750);
      digitalWrite(13, HIGH);     
}

void OpenGarage() {  
      Serial.println("Opening Garage!"); //
      digitalWrite(13, LOW); //Close Relay = Close Garage Door
      delay(750);
      digitalWrite(13, HIGH);     
}

Have the Arduino Serial Monitor Open before you upload the Sketch. After uploading you should see something similar to this in the Serial Monitor:

[10013] Connecting to "Your Access Point Name"
[18517] Connected to WiFi
[18517] My IP: 192.168.1.11
Setup Gstate:0
[18517] Connecting to arduino.mydevices.com:8442
[21878] Ready (ping: 1117ms).

Once you see the “Ready”, the Cayenne Web Dashboard will change to “What’s Next” where you can start adding your Devices – Custom Widgets. You can also click on the Setting Gear Icon and rename the Device to ESP8266 Garage or whatever you like.

Related Read ->  How to Use Alexa (Echo) with Chamberlain MYQ using OpenHab & IFTTT

Here is a quick walk through video of how to do this(sorry my audio wasn’t recording):

 

SCreenshot esp8266 cayenne after setup screen and esp8266 connected

Code improvements and/or questions are always welcome!

Here is the Fritzing Sketch:

Picture of ESP8266 NodeMCU Garage Door Opener Relay IoT Fritzing.jpg

 

You’ll need to parallel the two wires coming from your Garage Door button into the relay Normally Opened ports. On my Marantec Opener, shorting these two wires quickly (less than 75ms) turns the opener light on or off(I found this out by accident!) I use that in my code to blink the light with the buzzer as a warning that the Garage Door is about to close:

for (i = ; i <15; i++)
      {
      digitalWrite(13, LOW); // GPIO13 Closes Relay
      digitalWrite (buzzer, LOW) ; // Turn buzzer ON
      delay (75) ;// Delay 75ms to turn Garage Door Light Onn/Off
      digitalWrite(13, HIGH);
      digitalWrite (buzzer, HIGH) ;// turn buzzer OFF
      delay (150) ;// delay 150ms
      }

OpenHab Settings

Screenshot of ESP8266 OpenHab Garage Door Screenshot of ESP8266 OpenHab Garage Door Temps

Here are the garage settings for my default.items file:

Switch SmallGarageDoorSwitch "Small Garage Door" (Garages) { mqtt=">[mosquitto:sm_garage/relay1:command:ON:OPEN],>[mosquitto:sm_garage/relay1:command:OFF:CLOSE]" }
Number SmallGarageTemp "Small Garage Temp [%.1f °F]" (Garages) { mqtt="<[mosquitto:sm_garage/temperature:state:default]" }
Number SmallGarageHumid "Small Garage Humid [%.1f %%]" (Garages) { mqtt="<[mosquitto:sm_garage/humidity:state:default]" }

And here are the settings for the default.sitemap:

Switch item=SmallGarageDoorSwitch icon="garagedoor-closed" label="Small Garage Door Closed" visibility=[ZONE17_GENERAL_STATUS=="CLOSED"] mappings=[ON="Open"]
Switch item=SmallGarageDoorSwitch icon="garagedoor-open" label="Small Garage Door Open" visibility=[ZONE17_GENERAL_STATUS=="OPEN"] mappings=[OFF="Close"]

Frame label="Temperature and Humidity" {
Text item=Homie1Temp icon="temperature"
Text item=Homie1Humid icon="water"
Text item=Chip1Temp icon="temperature"
Text item=Chip1Humid icon="water"
Text item=SmallGarageTemp icon="temperature"
Text item=SmallGarageHumid icon="water"
}

Picture of ESP8266 NodeMCU WiFi Garage Door Opener Relay Wiring

Picture of ESP8266 NodeMCU WiFi Garage Door Opener Relay Wiring Closeup

 

1 Star2 Stars3 Stars4 Stars5 Stars (3 votes, average: 5.00 out of 5)
Loading...

Reminder, some links in the post might be affiliate links, so I’ll make some coffee/beer/gadget/website hosting money if you buy anything. You get it at the normal price, though!

 


 

Arduino Sketch for Use Without MQTT

/*   ********************************************************************************************
          Garage Door Opener with Warning Light and Buzzer for Marantec
          using Cayenn IoT Framework - No MQTT
          Author: Rich Plakas / Austin, TX - USA
          Reviewed: November 1, 2016
 *   ********************************************************************************************
*/
#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space

#include <ESP8266WiFi.h>
#include "CayenneDefines.h"
#include "BlynkSimpleEsp8266.h"
#include "CayenneWiFiClient.h"

#include <Wire.h>
#include <DHT.h>
#define DHTTYPE DHT22
#define DHTPIN 4
#define VIRTUAL_PIN V1
#define VIRTUAL_PIN V2
#define VIRTUAL_PIN V3
#define VIRTUAL_PIN V4
#define VIRTUAL_PIN V5
#define VIRTUAL_PIN V6
#define REST 1000    //Rest Between Inhalations.

int lightPin = 0;  //define a pin for Photo resistor
int buzzer = 5 ;// connect the I/O pin on the buzzer to this

DHT dht(DHTPIN, DHTTYPE, 20);
float humidity, temp_f;  // Values read from sensor - See more at: http://www.esp8266.com/viewtopic.php?f=29&t=8746#sthash.X8sbMBjM.dpuf

// Generally, you should use "unsigned long" for variables that hold time
unsigned long previousMillis = 0;
unsigned long lastTempUpdate = 0;
const long interval = 5000;

// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
char token[] = "Enter Your Auth Token Here";

// Your network name and password.
char ssid[] = "Enter Your Access Point Name";
char password[] = "Enter Your Access Point Password";

int value = 0;
int gState = 0;
long rssi;
IPAddress ip;

void setup()
{
  digitalWrite(13, HIGH); //GPIO13
  pinMode(13, OUTPUT);       // Pin connected to the Relay
  digitalWrite(5, HIGH); //GPIO5
  pinMode(buzzer, OUTPUT);       // Pin connected to the Buzzer
  Serial.begin(230400);
  Cayenne.begin(token, ssid, password);
  dht.begin();
  Serial.print("Setup Gstate:");
  Serial.println(gState);
}



// ==============( Void Loop  ) ====================================

void loop() {
  Cayenne.run();
  unsigned long now = millis();
  if ( now - lastTempUpdate > 60000 ) {  
    String MyIp;  
    String Both;
    MyIp =  "IP: " + String(WiFi.localIP()[]) + "." + String(WiFi.localIP()[1]) + "." + String(WiFi.localIP()[2]) + "." + String(WiFi.localIP()[3]);
    String MyWiFi;
    MyWiFi = "WiFi: " + String(WiFi.RSSI());
    Serial.println(MyIp);
    Serial.println(MyWiFi);
    gettemperature();
    Serial.print("Sending temperature:");
    Serial.println(temp_f);
    Serial.print("Sending humidity:");
    Serial.println(humidity);
    lastTempUpdate = now;
    switch (gState) {
       case 1:
       Cayenne.virtualWrite(V4, 100);
       break;
       case 2 : 
       Cayenne.virtualWrite(V4, 0);
       break;
       default:
       Cayenne.virtualWrite(V4, 50);
       break;
    }  
  }
   
}

void gettemperature() {
  // Wait at least 2 seconds seconds between measurements.
  // if the difference between the current time and last time you read
  // the sensor is bigger than the interval you set, read the sensor
  // Works better than delay for things happening elsewhere also
  /*unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis >= interval) { 
    // save the last time you read the sensor 
    previousMillis = currentMillis;   */

    // Reading temperature for humidity takes about 250 milliseconds!
    // Sensor readings may also be up to 2 seconds 'old' (it's a very slow sensor)
    humidity = dht.readHumidity();          // Read humidity (percent)
    temp_f = dht.readTemperature(true);     // Read temperature as Farenheight
    
    
    // Check if any reads failed and exit early (to try again).
    if (isnan(humidity) || isnan(temp_f)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }
    String TempF;
    String Humid;
    TempF = String(temp_f);
    Humid = String(humidity);
    Cayenne.virtualWrite(V1, temp_f);
    Cayenne.virtualWrite(V2, humidity);

    int lightsensor = analogRead(lightPin);
    float voltage = lightsensor;
    
    Cayenne.virtualWrite(V6, voltage);
    Serial.print("Ambient Light: ");
    Serial.println(analogRead(lightPin)); 
    Serial.print("Luminosity: ");
    Serial.println(voltage);
}

CAYENNE_IN(V3)
{
  // get value sent from dashboard
  int currentValue = getValue.asInt(); // 0 to 1

  // assuming you wire your relay as normally open
  if (currentValue == ) {
    digitalWrite(13, HIGH);
  } else {
    CloseGarage();
    }
}

void CloseGarage() {
  //Beep Buzzer & Flash Lights to warn about Garage Door Closing
     unsigned char i, j ;// define variables
      for (i = ; i <12; i++)
      {
      digitalWrite (buzzer, LOW) ; // Turn buzzer ON
      delay (300) ;// Delay 300ms
      digitalWrite (buzzer, HIGH) ;// turn buzzer OFF
      delay (75) ;// delay 75ms
    }
      for (i = ; i <15; i++) 
      {
      digitalWrite(13, LOW); // GPIO13 Closes Relay
      digitalWrite (buzzer, LOW) ; // Turn buzzer ON
      delay (75) ;// Delay 75ms to turn Garage Door Light Onn/Off
      digitalWrite(13, HIGH);
      digitalWrite (buzzer, HIGH) ;// turn buzzer OFF
      delay (150) ;// delay 150ms
      }
      delay(1500);
      Serial.println("Closing Garage!");
      digitalWrite(13, LOW); //Close Relay = Close Garage Door
      delay(750);
      digitalWrite(13, HIGH);     
}

void OpenGarage() {  
      Serial.println("Opening Garage!"); //
      digitalWrite(13, LOW); //Close Relay = Close Garage Door
      delay(750);
      digitalWrite(13, HIGH);     
}