Project tutorial
Weather forecast station with LYT led bulb and IFTTT

Weather forecast station with LYT led bulb and IFTTT © GPL3+

Build your own weather forecast station using Authometion LYT led bulb, LYTWiFi arduino shield and IFTTT for remote control.

  • 3,141 views
  • 0 comments
  • 2 respects

Components and supplies

Necessary tools and machines

USB to serial converter

Apps and online services

About this project

Project abstract

This project will allow you to build your own weather forecast station using a RGBW led bulb as weather condition and\or temperature indicator. Using the visual communication different light colours can give information about the current weather condition when you wake up in the morning or information about temperature at a specific time. Different weather information can be provided by the weather channel on the IFTTT environment that is used for the remote control of the led bulb for turning ON\OFF and colour changing.

Once the system setup is complete you will be able to have a complete remote control of your led bulb with an easy additional configuration of specific IFTTT DO buttons.

How it works

The LYT led bulb is a radio led bulb that can be controlled by an Arduino board with a specific software and using a LYTWiFi shield. By default specific commands can be sent to the LYT bulb using the serial interface of the Arduino board (i.e. by the Arduino IDE).

The LYTWiFi shield has also an ESP8266 module with a standard firmware version that is used to connect the shield to the network by a WiFi interface. In this project the ESP8266 standard firmware will be replaced by a specific version that allow the system to receive specific commands for the LYT bulb from the network.

Using the IFTTT automation web service, specific commands for the LYT bulb will be sent on the base of the weather condition and temperature at specific time or during the day.

For a complete system setup follow the steps below.

Note

The project has been developed using the following version of the software  development environment:

  • Arduino IDE ver. ver. 1.6.8.
  • ESP8266 board manager ver. 2.0.0.

STEP 1. Create an email account for your LYTWIFI shield

First of all an email account is needed for the commands to be sent for the control of the LYT bulb. The mail server must be POP3 and allow non-encrypted data (server port = 110).

Once the account is created the following data is needed for the customization of the LYTWiFi firmware:

  • mail server name
  • mail server port
  • email address
  • email password

STEP 2. CREATE AN IFTTT ACCOUNT

An IFTTT account must be created. Once the account is created you can define the "recipes" for the weather forecast updates.

Once the account is created you have to connect to the channel that is needed for the project:

  • MAKER channel
  • Weather channel

Once connected to the MAKER channel keep aside the key associated to your account connection to the channel for the following customization of LYTWiFi firmware.

STEP 3. Customize LYTWIFI firmaware

Before LYTWiFi firmware update, the code must be customized with parameters of:

  • your WiFi connection
  • your email account
  • your IFTTT MAKER channel connection key

In details two different code are available for ESP8266 firmware update:

  • demo_firmware_esp8266_ifttt_thermometer
  • demo_firmware_esp8266_ifttt_remote_control

For both code apply the modifications to the following blocks of code with your own parameters:

Mail Server

const char pop_server[] =<mail server name>;
const int  pop_port     = <mail server port>;
const char pop_user[]   = <email address>;
const char pop_pass[]   = <email password>; 

WiFi connection

// Connect to the specified AccessPoint
WiFiMulti.addAP(<SSID>, <password>);

MAKER channel web request

  • http.begin("https://maker.ifttt.com/trigger/lytwifi_thermometer_on/with/key/<MAKER channel key>");
  • http.begin("https://maker.ifttt.com/trigger/lytwifi_remote_control_on/with/key/<MAKER channel key>");

STEP 4. Arduino and LYTWIFI shield firmware download

Both Arduino and LYTWiFi shield must be programmed. Use Arduino IDE for both software\firmware updates.

Arduino UNO board must be loaded with the demo_firmware_lytwifi_2 code. This code has minor modifications respect to the official Authometion sample code for the control of LYT led bulb. Program Arduino UNO board using Arduino IDE.

For the firmware update of the LYTWiFI shield an external USB to serial converter is needed. As described in the LYTWiFi shield manual, for ESP8266 programming set the following jumper configuration:

  • remove JP1, JP2, JP3
  • set JP4 G0-GND connection
  • connect serial port to shield: Rx->JP1 central Wire, Tx->JP2 central wire, GND to some  GND connection

Once programmed set the jumper configuration in the default mode:

  • remove serial converter connection to the board
  • set JP1, JP2, JP3
  • remove JP4 G0-GND connection

In the following figure the configuration for the programming mode and default mode.

Set Arduino IDE to program a "Generic ESP8266 module" choosing from Tools-> Board menu and selecting the correct port for the USB to serial converter you have installed. You can program the LYTWiFi shield with one of the example code on the base of the project example you want to run.

In the following the specific instructions for the different examples.

EX1 - Thermometer application

To run the thermometer application first of all upload the demo_firmware_esp8266_ifttt_thermometer to the LYTWiFi shield.

Create IFTTT recipes

Now the IFTTT recipes for the application must be created.

First a recipe for the notifications of the system start will be created. The recipe will send a notification to your mobile device when the system with the thermometer application is turned ON. IFTTT mobile app is required on your mobile device.

Select "Create" from the user menu to start the recipe creation procedure:

  • select "this" to define the trigger of the recipe
  • select MAKER channel
  • select "Receive a web request"
  • set "lytwifi_thermometer_on" as event name and create the trigger
  • select "that" to define the action of the recipe
  • select IF Notifications channel. Connect to the channel if not connected
  • select "Send a notification"
  • set notification message and create the action
  • set the recipe title and create the recipe

A second recipe will be created for message sending to LYTWiFi using email. The recipe will send an email to LYTWiFi shield with data about the current temperatue at the time that you specify.

Select "Create" from the user menu to start a new recipe creation procedure:

  • select "this" to define the trigger of the recipe
  • select Weather channel
  • select "Today's weather report"
  • set the time for the current temperature report and create the trigger
  • select "that" to define the action of the recipe
  • select Gmail channel. Connect to the channel if not connected
  • select "Send an email"
  • set the address to send the email. This is the email address that has been defined for the LYTWiFi shield
  • set the following mail subject "ARDUINO " and add CurrentTempCelsius from the add ingredient button. The complete subject must be "ARDUINO {{CurrentTempCelsius}}"
  • set a blank mail body
  • set a blank mail attachment
  • select "Create action"
  • set the recipe title
  • check "Receive notifications when recipe runs"
  • select "Create the recipe"

After the creation of this two recipes reset the Arduino board to restart the system. If system is correctly configured:

  • after board reset a notification on your mobile device will alert you that the lytwifi_thermometer application is started
  • at the time that you specified in the recipe the colour of the led bulb will be set on the base of the current temperature

For system testing the second recipe can be turned OFF, the time for the report can be changed and then turned ON again for a new temperature report.

Applying simple modifications to the LYTWiFi firmware you can define your own temperature ranges in number dimension and associated colour.

EX2 - Weather station

To run the weather station application first of all upload the demo_firmware_esp8266_ifttt_remote_control to the LYTWiFi shield.

Create IFTTT recipes

Now the IFTTT recipes for the application must be created.

First of all a recipe for the notifications of the system start will be created. The recipe will send a notification to your mobile device when the system with the weather station application is turned ON and send an email to LYTWiFi with a command for LYT led bulb turn ON.

Select "Create" from the user menu to start the recipe creation procedure:

  • select "this" to define the trigger of the recipe
  • select MAKER channel
  • select "Receive a web request"
  • set "lytwifi_remote_control_on" as event name and create the trigger
  • select "that" to define the action of the recipe
  • select Gmail channel. Connect to the channel if not connected
  • select "Send an email"
  • set the address to send the email. This is the email address that has been defined for the LYTWiFi shield
  • set the following mail subject "ARDUINO PON,0,0,1
  • set a blank mail body
  • set a blank mail attachment
  • select "Create action"
  • set the recipe title (i.e. LYTWiFi remote control ON!)
  • check "Receive notifications when recipe runs"
  • select "Create the recipe"

A second recipe will be created for message sending to LYTWiFi using email. The recipe will send an email to LYTWiFi shield when current weather condition changes to "Clear" with a command for LYT led bulb colour setting to green.

Select "Create" from the user menu to start the recipe creation procedure:

  • select "this" to define the trigger of the recipe
  • select Weather channel
  • select "Current condition changes to"
  • set the "Clear" condition change and create the trigger
  • select "that" to define the action of the recipe
  • select Gmail channel. Connect to the channel if not connected
  • select "Send an email"
  • set the address to send the email. This is the email address that has been defined for the LYTWiFi shield
  • set the following mail subject "ARDUINO RGB,0,0,0,255,0,1"
  • set a blank mail body
  • set a blank mail attachment
  • select "Create action"
  • set the recipe title as "If current condition changes to clear, then set LYT green"
  • check "Receive notifications when recipe runs"
  • select "Create the recipe"

Other three recipes must be created in the same way as the previous one:

  • "If current condition changes to cloudy, then set LYT blue" using "ARDUINO RGB,0,0,0,0,255,1"
  • "If current condition changes to snow, then set LYT red" using "ARDUINO RGB,0,0,255,0,0,1"
  • "If current condition changes to rai, then set LYT yellow" using "ARDUINO RGB,0,0,127,127,0,1"

After the creation of the recipes reset the Arduino board to restart the system. If system is correctly configured:

  • after board reset a notification on your mobile device will alert you that the lytwifi_remote_control application is started and if the LYT led bulb is OFF this will be turned ON
  • the colour of the led bulb will be set on the base of the current weather condition, and will be changed when condition changes

Applying simple modifications to the LYTWiFi firmware you can define your own colour code for the different weather condition. Other weather information can be provided by the IFTTT weather channel for different system usage (temperature, humidity).

EX3 - LYT remote control

With the same firmware used for the weather station application is possible to obtain a complete remote control for the LYT led bulb from your mobile device. Commands for LYT turning ON\OFF and colour setting can be sent from IFTTT web service using the DO buttons instead of IF recipes.

Do button can be used only from your mobile device. So the specific App has to be installed.

Create IFTTT DO buttons

Now the IFTTT DO buttons for the application must be created.

First of all a DO button for the LYT turn ON must be created. The button will send an email to LYTWiFi with a command for LYT led bulb turn ON.

From DO button mobile app select the recipe collection icon:

  • select + to add a new DO button
  • select channel tab
  • select Gmail channel
  • select "Create a New Recipe"
  • select "Send an Email"
  • set the title (i.e Turn LYT ON)
  • set the address to send the email. This is the email address that has been defined for the LYTWiFi shield
  • set the following mail subject "ARDUINO PON,0,0,1"
  • set a blank mail body
  • set a blank mail attachment
  • select "Add"

Other buttons must be created in the same way as the previous one:

  • "Turn LYT OFF" using "ARDUINO POF,0,0,1" as mail subject
  • "Set LYT mid white"using "ARDUINO SBR,0,0,127,1" as mail subject
  • "Set LYT min white"using "ARDUINO SBR,0,0,255,1" as mail subject
  • "Set LYT red"using "ARDUINO RGB,0,0,255,0,0,1" as mail subject
  • "Set LYT green"using "ARDUINO RGB,0,0,0,255,0,1" as mail subject
  • "Set LYT blue"using "ARDUINO RGB,0,0,0,0,255,1" as mail subject

After the creation of the recipes reset the Arduino board to restart the system. If system is correctly configured:

  • after board reset a notification on your mobile device will alert you that the lytwifi_remote_control application is started and if the LYT led bulb is OFF this will be turned ON
  • from your mobile device push one of the DO button created to change the status of the led bulb (i.e. set LYT colour red)
  • wait for the command detection from the LYTWiFi shield and verify that the led bulb changes its colour according to the last command

Note

The remote control in this project is not developed to be a real-time method. The command can take several seconds to be received by the shield due to the network connection and mail server status.

System Test and Debug

After the configuration you can test and debug your system using the serial debug port on the LYTWiFi shield. Both the firmware of the ESP8266 module uses this port to send message about its activity about connection status and command sent to the Arduino board for LYT bulb control.

Using the USB to serial converter used for ESP866 firmware update connect: 

  • Rx->JP4-G13 pin,
  • Tx->JP4-G14 pin
  • GND to some GND board connection.

Code

demo_firmware_lytwifi_2C/C++
The code to be uploaded to Arduino UNO board. Minor modifications to the official Authometion example code for LYT bulb control.
/*
 *      This program 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 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program 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 this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 Code by AUTHOMETION S.r.l.
 Version: 1.02
 Date: 14.10.2015
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/****************************************************************************************
 *                                                                                      *
 *                               !!!! INPORTANT NOTICE !!!                              *
 *                                                                                      *
 ****************************************************************************************
 *                                                                                      *
 * Please change the _SS_MAX_RX_BUFF value to 128 to use this sketch                    *
 * You can find _SS_MAX_RX_BUFF value in the following header file                      *
 * <Program dir>\Arduino\hardware\arduino\avr\libraries\SoftwareSerial\SoftwareSerial.h *
 *                                                                                      *
 ****************************************************************************************
 *                                                                                      *
 * To use LYT Shield with Arduino MEGA 2560 please connect following pins:              *
 *                                                                                      *
 *      Shield        MEGA 2560                                                         *
 *         5              A8                                                            *
 *        10              53                                                            *
 *        11              51                                                            *
 *        12              50                                                            *
 *        13              52                                                            *
 *                                                                                      *
 * In JP1, JP2 and JP3 insert jumpers to left side                                      *
 *                                                                                      *
 ****************************************************************************************/
 
#include <SPI.h>
#include <EEPROM.h>
#include <PL1167.h>
#include <LYTWiFi.h>
#include <Messenger.h>
#include <string.h>
#include "SoftwareSerial.h"
#include <WiFiInterrupt.h>
#include <stdlib.h>

#define PL1167_CS_PIN          10 // 10 for Arduino Uno, 53 for Arduino MEGA 2560
#define ESP8266_TCP_MUX        0
#define ESP8266_TCP_SEVER_PORT 5001
#define BUFFER_LENGTH          16

SoftwareSerial mySerial(5, 6); // RX (5 for Arduino Uno / 62(A8) for Arduino Mega 2560), TX (6)
LYTWiFi myNetWork(mySerial);
//LYTWiFi myNetWork;

//Redirect serial chars from Virt to WiFi serial port and vice versa 
uint8_t ui8BridgeOn=0;

//Where commands are coming from
uint8_t ui8WhoIs=0;

// Instantiate Messenger object with the message function and the default separator (the comma character)
Messenger SerWiFi=Messenger(',');
Messenger SerHW=Messenger(',');

char cBuf;
uint8_t ui8Counter;

// Define messenger function
void messageWiFi()
{
  char cBuffer[64];

  if(String(SerWiFi.buffer).indexOf(":")!=-1)
  {
    memset(cBuffer, '\0', MESSENGERBUFFERSIZE);
    strcpy(cBuffer, (String(SerWiFi.buffer).substring(String(SerWiFi.buffer).indexOf(":")+1, String(SerWiFi.buffer).indexOf("\r\n"))).c_str());
    strcpy(SerWiFi.buffer, cBuffer);
    ui8WhoIs=1;
    SerHW.setBufferString(SerWiFi.readBufferString());

  }
}

// Define messenger function
void messageArduino() 
{
  uint8_t ui8Counter1, ui8Counter2, ui8Total;
  uint8_t ui8MODE   =0;
  uint8_t ui8ADDR_A =0;
  uint8_t ui8ADDR_B =0;
  uint8_t ui8ADDR_A1=0;
  uint8_t ui8ADDR_B1=0;
  uint8_t ui8PAR1   =0;
  uint8_t ui8PAR2   =0;
  uint8_t ui8PAR3   =0;
  uint8_t ui8DIM    =0;
  char    cBuffer1[BUFFER_LENGTH];
  char    cBuffer2[BUFFER_LENGTH];
  String  sBuffer1;
  String  sBuffer2;
  long    lBaud;
   
  // POWER ON LYT: PON,ADDR_A,ADDR_B,MODE
  if (SerHW.checkString("PON"))
  { 
    ui8ADDR_A=SerHW.readInt();
    ui8ADDR_B=SerHW.readInt();
    ui8MODE=SerHW.readInt();
    ui8PAR1=SerHW.readInt();
    memset(cBuffer2, '\0', BUFFER_LENGTH);
    if(myNetWork.ui8fSwitchOnAndCheck(ui8ADDR_A, ui8ADDR_B, ui8MODE, ui8PAR1)==C_ACK)
      memcpy(cBuffer2, F(" OK!"), 4);
    else
      memcpy(cBuffer2, F(" KO!"), 4);
    memset(cBuffer1, '\0', BUFFER_LENGTH);
    memcpy(cBuffer1, F("PON:"), 4);
    strcat(cBuffer1, cBuffer2);
    if(ui8WhoIs==1)
    {
      Serial.println(cBuffer1);
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, strlen(cBuffer1));      
    }
    else
      Serial.println(cBuffer1);
  }
  // POWER OFF LYT: POF,ADDR_A,ADDR_B,MODE
  else if(SerHW.checkString("POF"))
  { 
    ui8ADDR_A=SerHW.readInt();
    ui8ADDR_B=SerHW.readInt();
    ui8MODE=SerHW.readInt();
    ui8PAR1=SerHW.readInt();
    memset(cBuffer2, '\0', BUFFER_LENGTH);
    if(myNetWork.ui8fSwitchOffAndCheck(ui8ADDR_A, ui8ADDR_B, ui8MODE, ui8PAR1)==C_ACK)
      memcpy(cBuffer2, F(" OK!"), 4);
    else
      memcpy(cBuffer2, F(" KO!"), 4);
    memset(cBuffer1, '\0', BUFFER_LENGTH);
    memcpy(cBuffer1, F("POF:"), 4);
    strcat(cBuffer1, cBuffer2);
    if(ui8WhoIs==1)
    {
      Serial.println(cBuffer1);
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, strlen(cBuffer1));
    }
    else
      Serial.println(cBuffer1);
  }
  // SET RGB VALUES: RGB,ADDR_A,ADDR_B,PAR1,PAR2,PAR3,MODE
  else if(SerHW.checkString("RGB"))
  {
    ui8ADDR_A=SerHW.readInt();
    ui8ADDR_B=SerHW.readInt();
    ui8PAR1=SerHW.readInt();
    ui8PAR2=SerHW.readInt();
    ui8PAR3=SerHW.readInt();
    ui8MODE=SerHW.readInt();
    ui8DIM=SerHW.readInt();
    memset(cBuffer2, '\0', BUFFER_LENGTH);
    if(myNetWork.ui8fSetRGBValuesAndCheck(ui8ADDR_A, ui8ADDR_B, ui8PAR1, ui8PAR2, ui8PAR3, ui8MODE, ui8DIM)==C_ACK)
      memcpy(cBuffer2, F(" OK!"), 4);
    else
      memcpy(cBuffer2, F(" KO!"), 4);
    memset(cBuffer1, '\0', BUFFER_LENGTH);
    memcpy(cBuffer1, F("RGB:"), 4);
    strcat(cBuffer1, cBuffer2);
    if(ui8WhoIs==1)
    {
      Serial.println(cBuffer1);
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, strlen(cBuffer1));
    }
    else
      Serial.println(cBuffer1);
  }
  // SET BRIGHTNESS VALUE: SBR,ADDA,ADDB,PAR1,MODE,DIM
  else if(SerHW.checkString("SBR"))
  {
    ui8ADDR_A=SerHW.readInt();
    ui8ADDR_B=SerHW.readInt();
    ui8PAR2=SerHW.readInt();
    ui8MODE=SerHW.readInt();
    ui8DIM=SerHW.readInt();
    memset(cBuffer2, '\0', BUFFER_LENGTH);
    if(myNetWork.ui8fSetBrightnessValueAndCheck(ui8ADDR_A, ui8ADDR_B, ui8PAR2, ui8MODE, ui8DIM)==C_ACK)
      memcpy(cBuffer2, F(" OK!"), 4);
    else
      memcpy(cBuffer2, F(" KO!"), 4);
    memset(cBuffer1, '\0', BUFFER_LENGTH);
    memcpy(cBuffer1, F("SBR:"), 4);
    strcat(cBuffer1, cBuffer2);
    if(ui8WhoIs==1)
    {
      Serial.println(cBuffer1);
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, strlen(cBuffer1));
    }
    else
      Serial.println(cBuffer1);
  }
  // SET NEW ADDRESS: SEA,ADDR_A,ADDR_B,ADDR_A1,ADDR_B1
  else if(SerHW.checkString("SEA"))
  { 
    ui8ADDR_A=SerHW.readInt();
    ui8ADDR_B=SerHW.readInt();
    ui8ADDR_A1=SerHW.readInt();
    ui8ADDR_B1=SerHW.readInt();
    memset(cBuffer2, '\0', BUFFER_LENGTH);
    if(myNetWork.ui8fAddLampAddressAndCheck(ui8ADDR_A, ui8ADDR_B, ui8ADDR_A1, ui8ADDR_B1)==C_ACK)
      memcpy(cBuffer2, F(" OK!"), 4);
    else
      memcpy(cBuffer2, F(" KO!"), 4);
    memset(cBuffer1, '\0', BUFFER_LENGTH);
    memcpy(cBuffer1, F("SEA: "), 4);
    strcat(cBuffer1, cBuffer2);
    if(ui8WhoIs==1)
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, strlen(cBuffer1));
    else
      Serial.println(cBuffer1);
  }
  // DELETE ADDRESS: DEA,ADDR_A,ADDR_B,ADDR_A1,ADDR_B1
  else if(SerHW.checkString("DEA"))
  { 
    ui8ADDR_A=SerHW.readInt();
    ui8ADDR_B=SerHW.readInt();
    ui8ADDR_A1=SerHW.readInt();
    ui8ADDR_B1=SerHW.readInt();
    memset(cBuffer2, '\0', BUFFER_LENGTH);
    if(myNetWork.ui8fDeleteLampAddressAndCheck(ui8ADDR_A, ui8ADDR_B, ui8ADDR_A1, ui8ADDR_B1)==C_ACK)
      memcpy(cBuffer2, F(" OK!"), 4);
    else
      memcpy(cBuffer2, F(" KO!"), 4);
    memset(cBuffer1, '\0', BUFFER_LENGTH);
    memcpy(cBuffer1, F("DEA:"), 4);
    strcat(cBuffer1, cBuffer2);
    if(ui8WhoIs==1)
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, strlen(cBuffer1));
    else
      Serial.println(cBuffer1);
  }
  // RESET BULB: RES
  else if(SerHW.checkString("RES"))
  {
    memset(cBuffer2, '\0', BUFFER_LENGTH);
    if(myNetWork.ui8fResetLampAddressAndCheck()==C_ACK)
      memcpy(cBuffer2, F(" OK!"), 4);
    else
      memcpy(cBuffer2, F(" KO!"), 4);
    memset(cBuffer1, '\0', BUFFER_LENGTH);
    memcpy(cBuffer1, F("RES:"), 4);
    strcat(cBuffer1, cBuffer2);
    if(ui8WhoIs==1)
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, strlen(cBuffer1));
    else
      Serial.println(cBuffer1);
  }
  // READ ADDRESS TABLE: RAT,ADDR_A,ADDR_B
  else if(SerHW.checkString("RAT"))
  { 
    ui8ADDR_A=SerHW.readInt();
    ui8ADDR_B=SerHW.readInt();
    memset(cBuffer2, '\0', BUFFER_LENGTH);
    if(myNetWork.ui8fReadLampAddressTableAndCheck(ui8ADDR_A, ui8ADDR_B)==C_ACK)
      memcpy(cBuffer2, F(" OK!"), 4);
    else
      memcpy(cBuffer2, F(" KO!"), 4);
    if(ui8WhoIs==1)
    {
  		for(ui8Counter1=0; ui8Counter1<PROTOCOL_ADDRESS_TABLE_POSITIONS; ui8Counter1++)
  		{
        memset(cBuffer1, '\0', BUFFER_LENGTH);
        sprintf(cBuffer1, "(%2d,%2d)", myNetWork.LampAddressTable.ui8AddressTable[ui8Counter1][0], myNetWork.LampAddressTable.ui8AddressTable[ui8Counter1][1]);
        myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, strlen(cBuffer1));
        delay(100);
  		}
      memset(cBuffer1, '\0', BUFFER_LENGTH);
      memcpy(cBuffer1, F("RAT:"), 4);
      strcat(cBuffer1, cBuffer2);
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, strlen(cBuffer1));
    }
    else
    {
  		for(ui8Counter1=0; ui8Counter1<PROTOCOL_ADDRESS_TABLE_POSITIONS; ui8Counter1++)
  		{
    		Serial.print(F("("));
    		Serial.print(myNetWork.LampAddressTable.ui8AddressTable[ui8Counter1][0], DEC);
    		Serial.print(F(", "));
    		Serial.print(myNetWork.LampAddressTable.ui8AddressTable[ui8Counter1][1], DEC);
    		Serial.print(F(") "));
  		}
      Serial.println();
      memset(cBuffer1, '\0', BUFFER_LENGTH);
      memcpy(cBuffer1, F("RAT:"), 4);
      strcat(cBuffer1, cBuffer2);
      Serial.println(cBuffer1);
    }
  }
  // SAVE CURRENT STATE OF BULB: SAV,ADDR_A,ADDR_B,
  else if(SerHW.checkString("SAV"))
  { 
    ui8ADDR_A=SerHW.readInt();
    ui8ADDR_B=SerHW.readInt();
    memset(cBuffer2, '\0', BUFFER_LENGTH);
    if(myNetWork.ui8fSaveLampSettingsAndCheck(ui8ADDR_A, ui8ADDR_B)==C_ACK)
      memcpy(cBuffer2, F(" OK!"), 4);
    else
      memcpy(cBuffer2, F(" KO!"), 4);
    memset(cBuffer1, '\0', BUFFER_LENGTH);
    memcpy(cBuffer1, F("SAV:"), 4);
    strcat(cBuffer1, cBuffer2);
    if(ui8WhoIs==1)
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, strlen(cBuffer1));
    else
      Serial.println(cBuffer1);
  }
  // READ INFO STATUS: RIS,ADDR_A,ADDR_B
  else if(SerHW.checkString("RIS"))
  { 
    ui8ADDR_A=SerHW.readInt();
    ui8ADDR_B=SerHW.readInt();
    memset(cBuffer2, '\0', BUFFER_LENGTH);
    if(myNetWork.ui8fAskLampInfoStatusAndCheck(ui8ADDR_A, ui8ADDR_B)==C_ACK)
      memcpy(cBuffer2, F(" OK!"), 4);
    else
      memcpy(cBuffer2, F(" KO!"), 4);
    memset(cBuffer1, '\0', BUFFER_LENGTH);
    memcpy(cBuffer1, F("RIS:"), 4);
    strcat(cBuffer1, cBuffer2);
    if(ui8WhoIs==1)
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, strlen(cBuffer1));
    else
    {
   		Serial.print(F("Answers: "));
      for(ui8Counter1=0; ui8Counter1<PROTOCOL_ANSWER_LENGHT; ui8Counter1++)
      {
        Serial.print(myNetWork.ReceivedAnswer.AnswerStruct.ui8Answer[ui8Counter1], DEC);
        Serial.print(F(" "));
      }
     	Serial.println();
      Serial.println(cBuffer1);
    }
  }
  // SET SYNC WORD: SSW,ADDR_A,ADDR_B,ADDR_A1,ADDR_B1
  else if(SerHW.checkString("SSW"))
  {
    ui8ADDR_A=SerHW.readInt();
    ui8ADDR_B=SerHW.readInt();
    ui8ADDR_A1=SerHW.readInt();
    ui8ADDR_B1=SerHW.readInt();
    memset(cBuffer2, '\0', BUFFER_LENGTH);
    if(myNetWork.ui8fSetSyncWordAndCheck(ui8ADDR_A, ui8ADDR_B, ui8ADDR_A1, ui8ADDR_B1)==C_ACK)
      memcpy(cBuffer2, F(" OK!"), 4);
    else
      memcpy(cBuffer2, F(" KO!"), 4);
    memset(cBuffer1, '\0', BUFFER_LENGTH);
    memcpy(cBuffer1, F("SSW:"), 4);
    strcat(cBuffer1, cBuffer2);
    if(ui8WhoIs==1)
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, strlen(cBuffer1));
    else
      Serial.println(cBuffer1);
  }
  // SET LOCAL SYNC WORD: SLSW,ADDR_A,ADDR_B,MODE
  else if(SerHW.checkString("SLSW"))
  {
    ui8ADDR_A=SerHW.readInt();
    ui8ADDR_B=SerHW.readInt();
    ui8MODE=SerHW.readInt();
    myNetWork.vfSetLocalSyncWord(ui8ADDR_A, ui8ADDR_B, ui8MODE);
    if(ui8WhoIs==1)
    {
      memset(cBuffer1, '\0', BUFFER_LENGTH);
      memcpy(cBuffer1, F("SLSW!"), 5);
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, 5);
    }
    else
      Serial.println(F("SLSW!"));
  }
  // SET RGB VALUE IN FAST MODE: FRGB,ADDR_A,ADDR_B,PAR1,PAR2,PAR3
  else if(SerHW.checkString("FRGB"))
  {
    ui8ADDR_A=SerHW.readInt();
    ui8ADDR_B=SerHW.readInt();
    ui8PAR1=SerHW.readInt();
    ui8PAR2=SerHW.readInt();
    ui8PAR3=SerHW.readInt();
    while(Serial.available())
      Serial.read();
    while(Serial.available()==0)
    {
      myNetWork.ui8fSetRGBValuesAndCheck(ui8ADDR_A, ui8ADDR_B, ui8PAR1, 0, 0, C_MULTICAST);
      delay(100);
      myNetWork.ui8fSetRGBValuesAndCheck(ui8ADDR_A, ui8ADDR_B, 0, ui8PAR2, 0, C_MULTICAST);
      delay(100);
      myNetWork.ui8fSetRGBValuesAndCheck(ui8ADDR_A, ui8ADDR_B, 0, 0, ui8PAR3, C_MULTICAST);
      delay(100);
    }
    if(ui8WhoIs==1)
    {
      memset(cBuffer1, '\0', BUFFER_LENGTH);
      memcpy(cBuffer1, F("FRGB!"), 5);
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, 5);
    }
    else
      Serial.println(F("FRGB!"));
  }
  // SET LOCAL RADIO CHANNEL: SLRC,CHAN,MODE
  else if(SerHW.checkString("SLRC"))
  {
    ui8PAR1=SerHW.readInt();
    ui8MODE=SerHW.readInt();
    myNetWork.vfSetLocalChannel(ui8PAR1, ui8MODE);
    if(ui8WhoIs==1)
    {
      memset(cBuffer1, '\0', BUFFER_LENGTH);
      memcpy(cBuffer1, F("SLRC!"), 5);
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, 5);
    }
    else
      Serial.println(F("SLRC!"));
  }
  // SET RADIO CHANNEL OF LYT SHIELD: SRC,ADDR_A,ADDR_B,CHAN
  else if(SerHW.checkString("SRC"))
  {
    ui8ADDR_A=SerHW.readInt();
    ui8ADDR_B=SerHW.readInt();
    ui8PAR1=SerHW.readInt();
    memset(cBuffer2, '\0', BUFFER_LENGTH);
    if(myNetWork.ui8fSetChannelAndCheck(ui8ADDR_A, ui8ADDR_B, ui8PAR1)==C_ACK)
      memcpy(cBuffer2, F(" OK!"), 4);
    else
      memcpy(cBuffer2, F(" KO!"), 4);
    memset(cBuffer1, '\0', BUFFER_LENGTH);
    memcpy(cBuffer1, F("SRC:"), 4);
    strcat(cBuffer1, cBuffer2);
    if(ui8WhoIs==1)
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, strlen(cBuffer1));
    else
      Serial.println(cBuffer1);
  }
  // TEST RADIO CHANNEL EFFICENCY: TEST,ADDR_A,ADDR_B,CHAN
  else if(SerHW.checkString("TEST"))
  {
    ui8ADDR_A=SerHW.readInt();
    ui8ADDR_B=SerHW.readInt();
    ui8Counter1=SerHW.readInt();
    while(Serial.available())
      Serial.read();
    while((Serial.available()==0)&&(ui8Counter1<=127))
    {
      ui8Counter2=0;
      while((myNetWork.ui8fSetChannelAndCheck(ui8ADDR_A, ui8ADDR_B, ui8Counter1)!=C_ACK)&&(ui8Counter2<3))
      {
        delay(1000);
        ui8Counter2++;
      }
      if(ui8Counter2<3)
      {
        ui8Total=0;
        for(ui8Counter2=0; ui8Counter2<20; ui8Counter2++)
        {
          myNetWork.ui8fSetRGBValuesAndCheck(ui8ADDR_A, ui8ADDR_B, 10*ui8Counter2, 0, 0, C_UNICAST);
          ui8Total+=myNetWork.ui8SentCommandCounterMem;
          delay(500);
          if(Serial.available()!=0)
            break;
        }
        Serial.print("Channel: ");
        Serial.print(ui8Counter1);
        Serial.print(", Total number of sent commands: ");
        Serial.println(ui8Total);
        ui8Counter1++;
      }
      else
        break;
    }
    if(ui8WhoIs==1)
    {
      memset(cBuffer1, '\0', BUFFER_LENGTH);
      memcpy(cBuffer1, F("TEST!"), 5);
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, 5);
    }
    else
      Serial.println(F("TEST!"));
  }
  // ACTVATE BRIDGE between Serial and Virtual serial: BRIDGE
  else if(SerHW.checkString("BRIDGE")) 
  { 
    ui8BridgeOn=1;
    if(ui8WhoIs==1)
    {
      memset(cBuffer1, '\0', BUFFER_LENGTH);
      memcpy(cBuffer1, F("BRIDGE!"), 7);
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, 7);
    }
    else
      Serial.println(F("BRIDGE!"));
  }
  // Discover all available WiFi routers: LAP
  else if(SerHW.checkString("LAP"))
  {
    if(ui8WhoIs==0)
    {
      Serial.println(myNetWork.sfGetAPList_ESP8266());
      Serial.println(F("LAP!"));
    }
  }
  // Join ESP8266: JOI,SSID,PWD
  else if(SerHW.checkString("JOI"))
  {
    if(ui8WhoIs==0)
    {
      if(myNetWork.bfSetOprToStationSoftAP_ESP8266())
      {
        myNetWork.bfRestart_ESP8266();
        SerHW.copyString(cBuffer1, BUFFER_LENGTH);
        SerHW.copyString(cBuffer2, BUFFER_LENGTH);
        if(myNetWork.bfJoinAP_ESP8266(String(cBuffer1), String(cBuffer2)))
        {
          Serial.println(F("Join: OK"));
          delay(4000);
          myNetWork.vfGetLocalIP_ESP8266(sBuffer1, sBuffer2);
          Serial.print(F("Local IP Address :"));
          Serial.println(sBuffer1); 
          Serial.print(F("Local Mac Address:"));
          Serial.println(sBuffer2);
          delay(2000);
          if(myNetWork.bfEnableMUX_ESP8266())
          {
            delay(2000);
            if(myNetWork.bfStartTCPServer_ESP8266(ESP8266_TCP_SEVER_PORT))
              Serial.println(F("TCP Server: OK"));
            else
              Serial.println(F("TCP Server: FAIL"));
          }
          else
            Serial.println(F("TCP Server: FAIL"));
        }
        else
          Serial.println(F("Join: FAIL"));
      }
      else
        Serial.println(F("FAIL: ESP8266 not configured"));
      Serial.println(F("JOI!"));
    }
  }
  // Start a ESP8266 TCP server: STCP
  else if(SerHW.checkString("STCP"))
  {
    if(ui8WhoIs==0)
    {
      delay(2000);
      myNetWork.vfGetLocalIP_ESP8266(sBuffer1, sBuffer2);
      Serial.print(F("Local IP Address :"));
      Serial.println(sBuffer1);
      Serial.print(F("Local Mac Address:"));
      Serial.println(sBuffer2);
      delay(2000);
      if(atoi(sBuffer1.c_str())>0)
      {
        if(myNetWork.bfEnableMUX_ESP8266())
        {
          delay(2000);
          if(myNetWork.bfStartTCPServer_ESP8266(ESP8266_TCP_SEVER_PORT))
            Serial.println(F("TCP Server: OK"));
          else
            Serial.println(F("TCP Server: FAIL"));
        }
        else
          Serial.println(F("TCP Server: FAIL"));
      }
      else
        Serial.println(F("FAIL: ESP8266 not connected to network"));
      Serial.println(F("STCP!"));
    }
  }
  // Read IP and Mac Addresses of ESP8266: RIP
  else if(SerHW.checkString("RIP"))
  {
    if(ui8WhoIs==0)
    {
      myNetWork.vfGetLocalIP_ESP8266(sBuffer1, sBuffer2);
      Serial.print(F("Local IP Address :"));
      Serial.println(sBuffer1);
      Serial.print(F("Local Mac Address:"));
      Serial.println(sBuffer2);
      Serial.println(F("RIP!"));
   }
  }
  // Change Serial port baud rate (***SE ARRIVA DA WIFI CHE SUCCEDE***)
  else if(SerHW.checkString("UART")) 
  { 
    lBaud=SerHW.readLong();
    Serial.end();
    delay(200);
    Serial.begin(lBaud);
  }
  else if(SerHW.checkString("WDG")) 
  { 
    
  }
  else
  {
    if(ui8WhoIs==1)
    {
      Serial.print(F("UNK FROM ESP! "));
      Serial.println(SerHW.readBufferString());
      
      memset(cBuffer1, '\0', BUFFER_LENGTH);
      memcpy(cBuffer1, F("UNK!"), 4);
      myNetWork.bfSend_ESP8266(ESP8266_TCP_MUX, (const unsigned char*)cBuffer1, 4);

    }
    else
      Serial.println(F("UNK!"));    
  }
  ui8WhoIs=0;
}

void setup() 
{
  // Initialize Serial Communications
  mySerial.begin(9600);
  Serial.begin(9600, SERIAL_8N1);

  myNetWork.vfInitialize(PL1167_CS_PIN);
//  vfISRInit(&myNetWork);
  vfISRInit();
   
  SerWiFi.attach(messageWiFi);
  SerHW.attach(messageArduino);
  delay(500);
}

void loop() 
{
  while (Serial.available()) 
  {
    if(ui8BridgeOn==0)
      SerHW.process(Serial.read());
    else
    {
      cBuf=Serial.read();
      if(cBuf=='!')
        ui8BridgeOn=0;
      else
        mySerial.print(cBuf);
    }
  }
  while (mySerial.available())
  {
    if(ui8BridgeOn==0)
      SerWiFi.process(mySerial.read());
    else
    {
      cBuf=mySerial.read();
      if(cBuf=='!')
        ui8BridgeOn=0;
      else
        Serial.print(cBuf);
    }
  }
}
demo_firmware_esp8266_ifttt_thermometerC/C++
The code to be uploaded to ESP8266 module of the LYTWiFi arduino shield for using of LYT led bulb as a thermometer.
/*
 *      This program 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 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program 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 this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 Code by AUTHOMETION S.r.l.
 Version: 0.00
 Date: 01.08.2016
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
// Using EmailPop3 sketch from Arduino playground as guideline:

#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

#include <ESP8266HTTPClient.h>
#include <SoftwareSerial.h>

//#define USE_SERIAL Serial
#define USE_SERIAL srvTerm
#define ARDUINO_IF  Serial

SoftwareSerial  srvTerm(14,13);


// Use comments to enable or disable this define for debug messages
//#define DEBUG_POP
 
// Use comments to enable or disable the deleting of the mail
#define ENABLE_DELETE_POP

ESP8266WiFiMulti WiFiMulti;
bool sent(false);


// The mac address must be an unique number
byte mac[] = { 0xDE, 0x36, 0x5F, 0x0A, 0x19, 0x83 };  
// change network settings to yours
IPAddress ip( 0, 0, 0, 0);    
IPAddress gateway( 0, 0, 0, 0 );
IPAddress subnet( 0, 0, 0, 0 );

// Set the server POP3 address, the port, the user and password.
// The POP3 mail server is something like this:
//     mail.yourdomain.com, pop.yourdomain.com, pop3.yourdomain.com
// Using PROGMEM for these causes a fail when trying to connect and log in.
const char pop_server[] = <pop server name>;
const int  pop_port     = 110;
const char pop_user[]   = <email address>;
const char pop_pass[]   = <email password>;


// The number of milliseconds timeout for parseInt() and find().
// The response time for the Server can still be 10 seconds.
#define POP_TIMEOUT 10000
#define POP_TIMEOUT_DEFAULT 10000

WiFiClient  client;

void CheckEmail();
int getEmail( char *pBuf, int nBufSize);
boolean readOk( boolean readAll);
void readRemaining();
void popFail();

void setup() {

  ARDUINO_IF.begin(9600);
  ARDUINO_IF.flush();

  USE_SERIAL.begin(9600);
  USE_SERIAL.flush();
  // USE_SERIAL.setDebugOutput(true);

  USE_SERIAL.println();
  USE_SERIAL.println();
  USE_SERIAL.println();

  for(uint8_t t = 4; t > 0; t--)
  {
      USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
      USE_SERIAL.flush();
      delay(1000);
  }

  // Connect to the specified AccessPoint
  WiFiMulti.addAP(<SSID>, <password>);

  delay(3000);

  if((WiFiMulti.run() == WL_CONNECTED))
  {
    // Get current connection parameters.
    ip      = WiFi.localIP();
    gateway = WiFi.gatewayIP();
    subnet  = WiFi.subnetMask();

    // print your local IP address.
    USE_SERIAL.println(F( "WiFi started."));
    USE_SERIAL.print(F( "Local IP = "));
    USE_SERIAL.println(ip);
    USE_SERIAL.print(F( "Gateway IP = "));
    USE_SERIAL.println(gateway);
    USE_SERIAL.print(F( "Subnet Mask = "));
    USE_SERIAL.println(subnet);
  }
}

void loop()
{

  if (!sent)
  {
    // wait for WiFi connection
    if((WiFiMulti.run() == WL_CONNECTED))
    {
      HTTPClient http;

      USE_SERIAL.print("[HTTP] begin...\n");

      http.begin("https://maker.ifttt.com/trigger/lytwifi_thermometer_on/with/key/<maker channel key>"); //HTTP


      USE_SERIAL.print("[HTTP] GET...\n");
      // start connection and send HTTP header
      int httpCode = http.GET();
      if(httpCode)
      {
        // HTTP header has been send and Server response header has been handled
        USE_SERIAL.printf("[HTTP] GET... code = %d\n", httpCode);

        // file found at server
        if(httpCode == 200)
        {
          String payload = http.getString();
          USE_SERIAL.println(payload);

          sent = true;
        }
      }
      else
      {
        USE_SERIAL.print("[HTTP] GET... failed, no connection or no HTTP server\n");
      }
    }
    else  USE_SERIAL.print("No connection...\n");
  }

  delay(5000);

  CheckEmail();

}

void CheckEmail()
{
  // Create a buffer to receive the commands in (that is the Subject of the mail).
  char buffer[32];
 
  // The getEmail gets the text of the mail Subject into the buffer.
  // The valid number of received characters are returned.
  // If the return value is < 0, it is an error.
  int n = getEmail( buffer, sizeof(buffer));

  if( n<0)
  {
    USE_SERIAL.print(F("Email POP3 failed, error = "));
    USE_SERIAL.println( n);
  }
  else
  {
    if( n == 0)
    {
      USE_SERIAL.println(F("Ready, nothing to do."));
    }
    else
    {
      // 'n' is > 0, a command received.
      //Serial.print(F("Email checked, Command = \""));
      //Serial.print( buffer);
      //Serial.println(F("\""));

      //Serial.print(F("Email checked, Command: \r\n"));
      char cmd[32] = ":";
      int temp = atoi(buffer); 
      if (temp < 18)
        strcat(cmd,"RGB,0,0,0,0,255,1");
      else if ((temp>=18)&&(temp<25))
        strcat(cmd,"RGB,0,0,0,255,0,1");
      else if ((temp>=25)&&(temp<30))
        strcat(cmd,"RGB,0,0,127,127,0,1");
      else if (temp>=30)
        strcat(cmd,"RGB,0,0,255,0,0,1");     

            
      USE_SERIAL.println(cmd);
      ARDUINO_IF.println(cmd);

    }
  }
}

// getEmail
// --------
// Find an email on a mail server, using POP3.
// The Subject should start with "ARDUINO " and the text
// after that is copied into pBuf.
//
// The data in pBuf is only valid if the return value is not an error
// (an error is return value less than zero).
//
int getEmail( char *pBuf, int nBufSize)
{
  // nBytes is the number of bytes that is returned by getEmail.
  int nBytes = 0;
 
  // Connect to server
  // client.connect returns '1' if okay, or negative number if error.
  //    SUCCESS 1
  //    0     (error, unknown timeout, perhaps an error in the library)
  //    TIMED_OUT -1
  //    INVALID_SERVER -2
  //    TRUNCATED -3
  //    INVALID_RESPONSE -4
  //    -5    (there is no mail server at that IP address and port)
  // The string for the server must be a normal string in sram, no PROGMEM allowed.
  int nError = client.connect( pop_server, pop_port);
 
  // During testing, a value of zero was sometimes returned.
  // This is not according to the documentation and it is an error.
  // Therefor the non-error value '0' is turned into a negative number to
  // indicate an error.
  if( nError == 0)
    return( -200);
 
  // Only a value of 1 is okay.
  if( nError != 1)
    return( nError);
 
#ifdef DEBUG_POP
  USE_SERIAL.println(F("connected"));
#endif
 
  // The server should respond with "+OK" and maybe more text after that.
  // Check if "+OK" can be read.
  // The parameter 'true' is to read also everything after the "+OK".
  if(!readOk( true))
    return -102;
 
#ifdef DEBUG_POP
  USE_SERIAL.println(F("command USER"));
#endif
  client.print(F( "USER "));
  client.println( pop_user);
  if(!readOk( true))
    return -103;
 
#ifdef DEBUG_POP
  USE_SERIAL.println(F("command PASS"));
#endif
  client.print(F( "PASS "));
  client.println( pop_pass);
  if(!readOk( true))
    return -104;
 
#ifdef DEBUG_POP
  USE_SERIAL.println(F("command STAT"));
#endif  
  client.println(F( "STAT"));
  if(!readOk( false))
    return -105;
 
  // The whole line was like this: "+OK 3 15343"
  // It means that 3 emails are waiting with a total size of 15343.
  // At this moment, the "+OK" is read, but nothing else.
  // Check if there is a space after "+OK".
  char c = client.read();
  if( c != ' ')
    return -106;
 
  client.setTimeout( POP_TIMEOUT);       // set timeout lower for parseInt
  // Read the number of emails that are on the server.
  int nMails = client.parseInt();
  client.setTimeout( POP_TIMEOUT_DEFAULT);  // restore timeout to 1 second
 
  // Read the remaining of the response to STAT.
  readRemaining();
 
#ifdef DEBUG_POP
  USE_SERIAL.print(F( "Number of emails="));
  USE_SERIAL.println( nMails);
#endif
 
  // Test if there are emails waiting.
  if( nMails == 0)
  {
    // No emails, but no error. Set buffer to empty string.
    nBytes = 0;               // the returned value
    pBuf[0] = '\0';           // set empty string
  }
  else if( nMails > 0)
  {
    // emails are waiting.
    // Scan the emails until the first is found with the keyword "ARDUINO " at the
    // beginning of the "Subject: ".
 
    boolean found_and_ready = false;
    for( int nMailNumber = 1; nMailNumber <= nMails && !found_and_ready; nMailNumber++)
    {
      // The command RETR <x> gets the whole mail.
      // The command TOP <x> <size> gets the header plus 'size' of the body.
 
#ifdef DEBUG_POP
      USE_SERIAL.print(F( "command TOP "));
      USE_SERIAL.print( nMailNumber);
      USE_SERIAL.println(F( " 0"));
#endif    
      client.print(F( "TOP "));
      client.print( nMailNumber);
      client.println(F( " 0"));
 
      // Use readOk with parameter 'false' to stop reading after "+OK".
      if(!readOk( false))
        return -107;
      // The header of the email is waiting to be read, use the Stream.find() to look for the Subject.
      // The text "Subject: " should be at the beginning of a line, but that is not tested.
      // The first found text "Subject: " is assumed to be the real subject.
      // I have checked many years of emails, and the text is always "Subject: ", and never "SUBJECT: ".
      // At the moment, it is not possible to use the F() macro for Stream.find
      // Only the email that starts with "ARDUINO " at the start of the Subject is used.
 
      client.setTimeout( POP_TIMEOUT);      // set short timeout for find().
      // find() returns true if found and false if not.
      boolean foundsubject = client.find( "Subject: ARDUINO ");
      client.setTimeout( POP_TIMEOUT_DEFAULT);   // restore timeout to 1 second
 
      if( foundsubject)
      {
#ifdef DEBUG_POP
        USE_SERIAL.println(F("Found an email for me"));
#endif        
 
        // Read the remaining subject (that is the command for the Arduino) into a buffer.
        // Every line from the mail server should end with CR + LF,
        // but to be sure, both CR and LF are checked.
        // Alternative:
        //    client.readBytesUntil('\r', pBuf, nBufSize);
 
        // The last position in the buffer is reserved for the zero terminator.
        // So read data until (nBufSize-1).
        int i;
        for( i = 0; i < (nBufSize-1) && client.available(); i++)
        {
          char c = client.read();
          if (c == '\r' || c == '\n')
            break;
          pBuf[i] = c;
        }
        // Add zero terminator
        pBuf[i] = '\0';
        nBytes = i;     // the number of received bytes is returned by the getEmail() function.
 
        // More text of the header could be following the Subject.
        // That is read and disregarded.
        readRemaining();
 
#ifdef DEBUG_POP
        USE_SERIAL.print(F( "Subject = \"ARDUINO "));
        USE_SERIAL.print( pBuf);
        USE_SERIAL.println(F( "\""));
#endif
 
#ifdef ENABLE_DELETE_POP
        // Delete the just read message.
#ifdef DEBUG_POP
        USE_SERIAL.print(F( "command DELE "));
        USE_SERIAL.println( nMailNumber);
#endif    
        client.print(F( "DELE "));
        client.println( nMailNumber);
        if(!readOk( true))
          return -108;
#endif
 
        // Everything is okay, the mail is read and deleted.
        // Ready for now, don't process the remaining emails.
        found_and_ready = true;
      }
      else
      {
#ifdef DEBUG_POP
        USE_SERIAL.println(F("No ARDUINO keyword in subject"));
#endif        
        // This email has no "Subject: ARDUINO ".
        // But the remaining text has still to be read and disregarded.
        readRemaining();
      }
    }
  }
 
#ifdef DEBUG_POP
  USE_SERIAL.println(F( "Sending QUIT"));
#endif  
  client.println(F( "QUIT"));
 
  // After "QUIT", the server still respons with "+OK",
  // but after that, the connection might get lost.
  // So don't read everything after "+OK" (use parameter 'false' for readOk).
  if(!readOk( false))
    return -109;
 
  client.stop();
 
#ifdef DEBUG_POP
  USE_SERIAL.println(F("normally disconnected"));
#endif
 
  return( nBytes);
}
 
 
// Read the response from the mail server.
// That is "+OK" if everything is okay.
// Parameter 'readAll' is to read every character after the "+OK".
boolean readOk( boolean readAll)
{
  // Check the response "+OK" from the mail server
  // In most cases that is followed by a space and more text, but not always.
  // In case of an error the text "-ERR" is received.
 
  int loopCount = 0;
  char bufOk[4];
 
  // Wait for response of mail server, with a timout.
  while(!client.available())
  {
    delay(1);
    loopCount++;
 
    // if nothing received for 10 seconds, timeout
    if(loopCount > 20000)
    {
      client.stop();
#ifdef DEBUG_POP
      USE_SERIAL.println(F("\nTimeout"));
#endif      
      return false;
    }
  }
 
  // Read the first three bytes.
  client.readBytes(bufOk, 3);
 
#ifdef DEBUG_POP
  USE_SERIAL.write(bufOk, 3);
  USE_SERIAL.println();
#endif
 
  // Is it "+OK" ?
  if( strncmp( bufOk, "+OK", 3) != 0)
  {
    popFail();
    return false;
  }
 
  // When the text after "+OK" is not needed, everything
  // else can be read and disregarded
  // (or shown in the serial monitor during debugging).
  if( readAll)
    readRemaining();
 
  return true;
}
 
 
void readRemaining()
{
  // This function is called after checking the "+OK".
  // It reads everything from the server, until no more text is
  // available.
 
  while(client.available())
  {
    char c = client.read();
#ifdef DEBUG_POP_EXTRA  
    USE_SERIAL.print( c);
#endif    
  }
  return;
}
 
 
void popFail()
{
  int loopCount = 0;
 
#ifdef DEBUG_POP
  USE_SERIAL.println(F("popFail"));
#endif
 
  while(!client.available())
  {
    delay(1);
    loopCount++;
 
    // if nothing received for 10 seconds, timeout
    if(loopCount > 10000)
    {
      client.stop();
#ifdef DEBUG_POP
      USE_SERIAL.println(F("\nTimeout"));
#endif      
      return;
    }
  }
 
  client.stop();
 
#ifdef DEBUG_POP
  USE_SERIAL.println(F("disconnected due to fail"));
#endif  
}
demo_firmware_esp8266_ifttt_remote_controlC/C++
The code to be uploaded to ESP8266 module of the LYTWiFi Arduino shield for complete LYT led bulb remote control and weather forecast usage.
/*
 *      This program 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 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program 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 this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 Code by AUTHOMETION S.r.l.
 Version: 0.00
 Date: 01.08.2016
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
// Using EmailPop3 sketch from Arduino playground as guideline:

#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

#include <ESP8266HTTPClient.h>
#include <SoftwareSerial.h>

//#define USE_SERIAL Serial
#define USE_SERIAL srvTerm
#define ARDUINO_IF  Serial

SoftwareSerial  srvTerm(14,13);


// Use comments to enable or disable this define for debug messages
//#define DEBUG_POP
 
// Use comments to enable or disable the deleting of the mail
#define ENABLE_DELETE_POP

ESP8266WiFiMulti WiFiMulti;
bool sent(false);


// The mac address must be an unique number
byte mac[] = { 0xDE, 0x36, 0x5F, 0x0A, 0x19, 0x83 };  
// change network settings to yours
IPAddress ip( 0, 0, 0, 0);    
IPAddress gateway( 0, 0, 0, 0 );
IPAddress subnet( 0, 0, 0, 0 );

// Set the server POP3 address, the port, the user and password.
// The POP3 mail server is something like this:
//     mail.yourdomain.com, pop.yourdomain.com, pop3.yourdomain.com
// Using PROGMEM for these causes a fail when trying to connect and log in.
const char pop_server[] = <pop mail server>;
const int  pop_port     = 110;
const char pop_user[]   = <email address>;
const char pop_pass[]   = <email password>;

 
// The number of milliseconds timeout for parseInt() and find().
// The response time for the Server can still be 10 seconds.
#define POP_TIMEOUT 10000
#define POP_TIMEOUT_DEFAULT 10000

WiFiClient  client;

void CheckEmail();
int getEmail( char *pBuf, int nBufSize);
boolean readOk( boolean readAll);
void readRemaining();
void popFail();

void setup() {

  ARDUINO_IF.begin(9600);
  ARDUINO_IF.flush();

  USE_SERIAL.begin(9600);
  USE_SERIAL.flush();
  // USE_SERIAL.setDebugOutput(true);

  USE_SERIAL.println();
  USE_SERIAL.println();
  USE_SERIAL.println();

  for(uint8_t t = 4; t > 0; t--)
  {
      USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
      USE_SERIAL.flush();
      delay(1000);
  }

  // Connect to the specified AccessPoint
  WiFiMulti.addAP(<SSID>, <password>);

  delay(3000);

  if((WiFiMulti.run() == WL_CONNECTED))
  {
    // Get current connection parameters.
    ip      = WiFi.localIP();
    gateway = WiFi.gatewayIP();
    subnet  = WiFi.subnetMask();

    // print your local IP address.
    USE_SERIAL.println(F( "WiFi started."));
    USE_SERIAL.print(F( "Local IP = "));
    USE_SERIAL.println(ip);
    USE_SERIAL.print(F( "Gateway IP = "));
    USE_SERIAL.println(gateway);
    USE_SERIAL.print(F( "Subnet Mask = "));
    USE_SERIAL.println(subnet);
  }
}

void loop()
{

  if (!sent)
  {
    // wait for WiFi connection
    if((WiFiMulti.run() == WL_CONNECTED))
    {
      HTTPClient http;

      USE_SERIAL.print("[HTTP] begin...\n");
      // configure traged server and url
      //http.begin("192.168.1.12", 443, "/test.html", true, "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS

      http.begin("https://maker.ifttt.com/trigger/lytwifi_remote_control_on/with/key/<maker channel key>"); //HTTP


      USE_SERIAL.print("[HTTP] GET...\n");
      // start connection and send HTTP header
      int httpCode = http.GET();
      if(httpCode)
      {
        // HTTP header has been send and Server response header has been handled
        USE_SERIAL.printf("[HTTP] GET... code = %d\n", httpCode);

        // file found at server
        if(httpCode == 200)
        {
          String payload = http.getString();
          USE_SERIAL.println(payload);

          sent = true;
        }
      }
      else
      {
        USE_SERIAL.print("[HTTP] GET... failed, no connection or no HTTP server\n");
      }
    }
    else  USE_SERIAL.print("No connection...\n");
  }

  delay(5000);

  CheckEmail();

}

void CheckEmail()
{
  // Create a buffer to receive the commands in (that is the Subject of the mail).
  char buffer[32];
 
  // The getEmail gets the text of the mail Subject into the buffer.
  // The valid number of received characters are returned.
  // If the return value is < 0, it is an error.
  int n = getEmail( buffer, sizeof(buffer));

  if( n<0)
  {
    USE_SERIAL.print(F("Email POP3 failed, error = "));
    USE_SERIAL.println( n);
  }
  else
  {
    if( n == 0)
    {
      USE_SERIAL.println(F("Ready, nothing to do."));
    }
    else
    {
      // 'n' is > 0, a command received.
      //Serial.print(F("Email checked, Command = \""));
      //Serial.print( buffer);
      //Serial.println(F("\""));

      //Serial.print(F("Email checked, Command: \r\n"));
      char temp[32] = ":";
      strcat(temp,buffer);
      USE_SERIAL.println(temp);

      ARDUINO_IF.println(temp);

    }
  }
}

// getEmail
// --------
// Find an email on a mail server, using POP3.
// The Subject should start with "ARDUINO " and the text
// after that is copied into pBuf.
//
// The data in pBuf is only valid if the return value is not an error
// (an error is return value less than zero).
//
int getEmail( char *pBuf, int nBufSize)
{
  // nBytes is the number of bytes that is returned by getEmail.
  int nBytes = 0;
 
  // Connect to server
  // client.connect returns '1' if okay, or negative number if error.
  //    SUCCESS 1
  //    0     (error, unknown timeout, perhaps an error in the library)
  //    TIMED_OUT -1
  //    INVALID_SERVER -2
  //    TRUNCATED -3
  //    INVALID_RESPONSE -4
  //    -5    (there is no mail server at that IP address and port)
  // The string for the server must be a normal string in sram, no PROGMEM allowed.
  int nError = client.connect( pop_server, pop_port);
 
  // During testing, a value of zero was sometimes returned.
  // This is not according to the documentation and it is an error.
  // Therefor the non-error value '0' is turned into a negative number to
  // indicate an error.
  if( nError == 0)
    return( -200);
 
  // Only a value of 1 is okay.
  if( nError != 1)
    return( nError);
 
#ifdef DEBUG_POP
  USE_SERIAL.println(F("connected"));
#endif
 
  // The server should respond with "+OK" and maybe more text after that.
  // Check if "+OK" can be read.
  // The parameter 'true' is to read also everything after the "+OK".
  if(!readOk( true))
    return -102;
 
#ifdef DEBUG_POP
  USE_SERIAL.println(F("command USER"));
#endif
  client.print(F( "USER "));
  client.println( pop_user);
  if(!readOk( true))
    return -103;
 
#ifdef DEBUG_POP
  USE_SERIAL.println(F("command PASS"));
#endif
  client.print(F( "PASS "));
  client.println( pop_pass);
  if(!readOk( true))
    return -104;
 
#ifdef DEBUG_POP
  USE_SERIAL.println(F("command STAT"));
#endif  
  client.println(F( "STAT"));
  if(!readOk( false))
    return -105;
 
  // The whole line was like this: "+OK 3 15343"
  // It means that 3 emails are waiting with a total size of 15343.
  // At this moment, the "+OK" is read, but nothing else.
  // Check if there is a space after "+OK".
  char c = client.read();
  if( c != ' ')
    return -106;
 
  client.setTimeout( POP_TIMEOUT);       // set timeout lower for parseInt
  // Read the number of emails that are on the server.
  int nMails = client.parseInt();
  client.setTimeout( POP_TIMEOUT_DEFAULT);  // restore timeout to 1 second
 
  // Read the remaining of the response to STAT.
  readRemaining();
 
#ifdef DEBUG_POP
  USE_SERIAL.print(F( "Number of emails="));
  USE_SERIAL.println( nMails);
#endif
 
  // Test if there are emails waiting.
  if( nMails == 0)
  {
    // No emails, but no error. Set buffer to empty string.
    nBytes = 0;               // the returned value
    pBuf[0] = '\0';           // set empty string
  }
  else if( nMails > 0)
  {
    // emails are waiting.
    // Scan the emails until the first is found with the keyword "ARDUINO " at the
    // beginning of the "Subject: ".
 
    boolean found_and_ready = false;
    for( int nMailNumber = 1; nMailNumber <= nMails && !found_and_ready; nMailNumber++)
    {
      // The command RETR <x> gets the whole mail.
      // The command TOP <x> <size> gets the header plus 'size' of the body.
 
#ifdef DEBUG_POP
      USE_SERIAL.print(F( "command TOP "));
      USE_SERIAL.print( nMailNumber);
      USE_SERIAL.println(F( " 0"));
#endif    
      client.print(F( "TOP "));
      client.print( nMailNumber);
      client.println(F( " 0"));
 
      // Use readOk with parameter 'false' to stop reading after "+OK".
      if(!readOk( false))
        return -107;
      // The header of the email is waiting to be read, use the Stream.find() to look for the Subject.
      // The text "Subject: " should be at the beginning of a line, but that is not tested.
      // The first found text "Subject: " is assumed to be the real subject.
      // I have checked many years of emails, and the text is always "Subject: ", and never "SUBJECT: ".
      // At the moment, it is not possible to use the F() macro for Stream.find
      // Only the email that starts with "ARDUINO " at the start of the Subject is used.
 
      client.setTimeout( POP_TIMEOUT);      // set short timeout for find().
      // find() returns true if found and false if not.
      boolean foundsubject = client.find( "Subject: ARDUINO ");
      client.setTimeout( POP_TIMEOUT_DEFAULT);   // restore timeout to 1 second
 
      if( foundsubject)
      {
#ifdef DEBUG_POP
        USE_SERIAL.println(F("Found an email for me"));
#endif        
 
        // Read the remaining subject (that is the command for the Arduino) into a buffer.
        // Every line from the mail server should end with CR + LF,
        // but to be sure, both CR and LF are checked.
        // Alternative:
        //    client.readBytesUntil('\r', pBuf, nBufSize);
 
        // The last position in the buffer is reserved for the zero terminator.
        // So read data until (nBufSize-1).
        int i;
        for( i = 0; i < (nBufSize-1) && client.available(); i++)
        {
          char c = client.read();
          if (c == '\r' || c == '\n')
            break;
          pBuf[i] = c;
        }
        // Add zero terminator
        pBuf[i] = '\0';
        nBytes = i;     // the number of received bytes is returned by the getEmail() function.
 
        // More text of the header could be following the Subject.
        // That is read and disregarded.
        readRemaining();
 
#ifdef DEBUG_POP
        USE_SERIAL.print(F( "Subject = \"ARDUINO "));
        USE_SERIAL.print( pBuf);
        USE_SERIAL.println(F( "\""));
#endif
 
#ifdef ENABLE_DELETE_POP
        // Delete the just read message.
#ifdef DEBUG_POP
        USE_SERIAL.print(F( "command DELE "));
        USE_SERIAL.println( nMailNumber);
#endif    
        client.print(F( "DELE "));
        client.println( nMailNumber);
        if(!readOk( true))
          return -108;
#endif
 
        // Everything is okay, the mail is read and deleted.
        // Ready for now, don't process the remaining emails.
        found_and_ready = true;
      }
      else
      {
#ifdef DEBUG_POP
        USE_SERIAL.println(F("No ARDUINO keyword in subject"));
#endif        
        // This email has no "Subject: ARDUINO ".
        // But the remaining text has still to be read and disregarded.
        readRemaining();
      }
    }
  }
 
#ifdef DEBUG_POP
  USE_SERIAL.println(F( "Sending QUIT"));
#endif  
  client.println(F( "QUIT"));
 
  // After "QUIT", the server still respons with "+OK",
  // but after that, the connection might get lost.
  // So don't read everything after "+OK" (use parameter 'false' for readOk).
  if(!readOk( false))
    return -109;
 
  client.stop();
 
#ifdef DEBUG_POP
  USE_SERIAL.println(F("normally disconnected"));
#endif
 
  return( nBytes);
}
 
 
// Read the response from the mail server.
// That is "+OK" if everything is okay.
// Parameter 'readAll' is to read every character after the "+OK".
boolean readOk( boolean readAll)
{
  // Check the response "+OK" from the mail server
  // In most cases that is followed by a space and more text, but not always.
  // In case of an error the text "-ERR" is received.
 
  int loopCount = 0;
  char bufOk[4];
 
  // Wait for response of mail server, with a timout.
  while(!client.available())
  {
    delay(1);
    loopCount++;
 
    // if nothing received for 10 seconds, timeout
    if(loopCount > 20000)
    {
      client.stop();
#ifdef DEBUG_POP
      USE_SERIAL.println(F("\nTimeout"));
#endif      
      return false;
    }
  }
 
  // Read the first three bytes.
  client.readBytes(bufOk, 3);
 
#ifdef DEBUG_POP
  USE_SERIAL.write(bufOk, 3);
  USE_SERIAL.println();
#endif
 
  // Is it "+OK" ?
  if( strncmp( bufOk, "+OK", 3) != 0)
  {
    popFail();
    return false;
  }
 
  // When the text after "+OK" is not needed, everything
  // else can be read and disregarded
  // (or shown in the serial monitor during debugging).
  if( readAll)
    readRemaining();
 
  return true;
}
 
 
void readRemaining()
{
  // This function is called after checking the "+OK".
  // It reads everything from the server, until no more text is
  // available.
 
  while(client.available())
  {
    char c = client.read();
#ifdef DEBUG_POP_EXTRA  
    USE_SERIAL.print( c);
#endif    
  }
  return;
}
 
 
void popFail()
{
  int loopCount = 0;
 
#ifdef DEBUG_POP
  USE_SERIAL.println(F("popFail"));
#endif
 
  while(!client.available())
  {
    delay(1);
    loopCount++;
 
    // if nothing received for 10 seconds, timeout
    if(loopCount > 10000)
    {
      client.stop();
#ifdef DEBUG_POP
      USE_SERIAL.println(F("\nTimeout"));
#endif      
      return;
    }
  }
 
  client.stop();
 
#ifdef DEBUG_POP
  USE_SERIAL.println(F("disconnected due to fail"));
#endif  
}

Comments

Similar projects you might like

Laundry IFTTT Alert

Project tutorial by danvanf

  • 3,461 views
  • 0 comments
  • 12 respects

Wireless weather station (Arduino + ESP8266 + Thingspeak)

Project tutorial by Alin-Constantin Paun

  • 8,864 views
  • 2 comments
  • 11 respects

Arduino Weather Station v1.0 (BMP280)

Project tutorial by Gabriele Scordamaglia

  • 7,314 views
  • 15 comments
  • 43 respects

Multifunctional RGB LED Light

by PauliusPlus

  • 6,569 views
  • 1 comment
  • 29 respects

Making a Cheap Aquarium Parameters Controller

Project tutorial by Boisse Martin

  • 5,025 views
  • 3 comments
  • 16 respects

IOT On Air Sign

Project tutorial by 4 developers

  • 1,998 views
  • 0 comments
  • 8 respects
Add projectSign up / Login