#include <LiquidCrystal.h>
#include <EEPROM.h>
#include <ESPAsyncWebServer.h>
#include <ArduinoJson.h>
#define ESPALEXA_ASYNC //it is important to define this before #include <Espalexa.h>!
#include <Espalexa.h>
#ifdef ARDUINO_ARCH_ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#else
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
// define the GPIO connected with Relays based on processor architecure
#ifdef ARDUINO_ARCH_ESP32
#define AlexaRelay01 19
#define AlexaRelay02 18
#define AlexaRelay03 5
#define AlexaRelay04 17
#define WiFiStatus 2
#else
#define AlexaRelay01 4 //D2
#define AlexaRelay02 0 //D3
#define AlexaRelay03 2 //D4
#define AlexaRelay04 14 //D5
#define WiFiStatus D0
#endif
//callback functions
void firstSwitchChanged(EspalexaDevice* dev);
void secondSwitchChanged(EspalexaDevice* dev);
void thirdSwitchChanged(EspalexaDevice* dev);
void fourthSwitchChanged(EspalexaDevice* dev);
// WiFi Credentials
const char* ssid = "XXXXXXXXX";
const char* password = "XXXXXXXXXX";
int WifiLEDBlink = 0;
const char* PARAM_MESSAGE = "message";
boolean SendResponse = false ;
// device names
String Device_1_Name = "S1";
String Device_2_Name = "S2";
String Device_3_Name = "S3";
String Device_4_Name = "S4";
boolean wifiConnected = false;
// These are for storing relaystates and not relaypin numbers, relay pin numbers are stored in AlexaRelay variables
int Relay01 = 1;
int Relay02 = 1;
int Relay03 = 1;
int Relay04 = 1;
Espalexa espalexa;
AsyncWebServer server(80);
// Set your Static IP address
IPAddress local_IP(192, 168, 150, 112);
// Set your Gateway IP address
IPAddress gateway(192, 168, 150, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(8, 8, 8, 8); // optional
IPAddress secondaryDNS(208, 67, 222, 222); // optional
void setup()
{
Serial.begin(115200);
delay(10);
EEPROM.begin(512);
//Prepare and Initialize GPIO4,0,2,14 PINS D2,D3,D4,D5 NodeMcu
pinMode(AlexaRelay01, OUTPUT);
digitalWrite(AlexaRelay01, EEPROM.read(256));
pinMode(AlexaRelay02, OUTPUT);
digitalWrite(AlexaRelay02, EEPROM.read(257));
pinMode(AlexaRelay03, OUTPUT);
digitalWrite(AlexaRelay03, EEPROM.read(258));
pinMode(AlexaRelay04, OUTPUT);
digitalWrite(AlexaRelay04, EEPROM.read(259));
//WiFi Status Blue Onboard LED
pinMode(WiFiStatus, OUTPUT);
//Initialize RelayStates with last power state stored in EEPROM
Relay01 = EEPROM.read(256);
Relay02 = EEPROM.read(257);
Relay03 = EEPROM.read(258);
Relay04 = EEPROM.read(259);
setOnOffRelay();
// Configures static IP address
if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
Serial.println("WARNING....STA Failed to configure static ip 192.168.150.112..");
}
WiFi.setSleep(false); //.setSleepMode(WIFI_NONE_SLEEP);
// Connect to WiFi network
Serial.println();
Serial.print("Conecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
if ( WifiLEDBlink == 1 ) {
digitalWrite(WiFiStatus, HIGH);// Turn Off OnBoard Blue LED
WifiLEDBlink = 0; //Toggle switch for led blink
delay(500);
} else if ( WifiLEDBlink == 0 ) {
digitalWrite(WiFiStatus, LOW);// Turn Off OnBoard Blue LED
WifiLEDBlink = 1; //Toggle switch for led blink
delay(500);
}
Serial.print(".");
}
digitalWrite(WiFiStatus, LOW);// Turn On OnBoard Blue LED
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address is : ");
Serial.println(WiFi.localIP());
if (WiFi.status() == WL_CONNECTED)
{
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
//request->send(200, "text/plain", "Shuk ba this is where you will return the relay states");
// Read the first line of the request
String req = request->url().c_str();
// Prepare the json response
AsyncResponseStream *response = request->beginResponseStream("application/json");
DynamicJsonDocument json(1024);
json["REL01"] = "" + String(Relay01) + "";
json["REL02"] = "" + String(Relay02) + "";
json["REL03"] = "" + String(Relay03) + "";
json["REL04"] = "" + String(Relay04) + "";
json["IP"] = WiFi.localIP().toString();
serializeJson(json, *response);
request->send(response);
});
server.on("/test", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", "This is an answer for test call you made, System is Up and Running fine..");
});
// Send a GET request to <IP>/get?message=<message>
server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
String message;
if (request->hasParam(PARAM_MESSAGE)) {
message = request->getParam(PARAM_MESSAGE)->value();
} else {
message = "No message sent";
}
request->send(200, "text/plain", "Hello, GET: " + message);
});
server.onNotFound([](AsyncWebServerRequest *request){
if (!espalexa.handleAlexaApiCall(request)) //if you don't know the URI, ask espalexa whether it is an Alexa control request
{
// Read the first line of the request
String req = request->url().c_str();
if (req.indexOf("Relay01=1") != -1) {
Relay01 = 1;
SendResponse = true ;
} else if (req.indexOf("Relay01=0") != -1) {
Relay01 = 0;
SendResponse = true ;
} else if (req.indexOf("Relay02=1") != -1) {
Relay02 = 1;
SendResponse = true ;
} else if (req.indexOf("Relay02=0") != -1) {
Relay02 = 0;
SendResponse = true ;
} else if (req.indexOf("Relay03=1") != -1) {
Relay03 = 1;
//espalexa.getDevice(2)->setValue(0);
SendResponse = true ;
} else if (req.indexOf("Relay03=0") != -1) {
Relay03 = 0;
//espalexa.getDevice(2)->setValue(255);
SendResponse = true ;
} else if (req.indexOf("Relay04=1") != -1) {
Relay04 = 1;
//espalexa.getDevice(3)->setValue(0);
SendResponse = true ;
} else if (req.indexOf("Relay04=0") != -1) {
Relay04 = 0;
//espalexa.getDevice(3)->setValue(255);
SendResponse = true ;
} else if (req.indexOf("Reboot") != -1) {
//March 03, 2022 added code snippet to restart the module
ESP.restart();
} else {
//whatever you want to do with 404s
request->send(404, "text/plain", "Not found");
}
setOnOffRelay();
if (SendResponse)
{
AsyncResponseStream *response = request->beginResponseStream("application/json");
DynamicJsonDocument json(1024);
json["REL01"] = "" + String(Relay01) + "";
json["REL02"] = "" + String(Relay02) + "";
json["REL03"] = "" + String(Relay03) + "";
json["REL04"] = "" + String(Relay04) + "";
json["IP"] = WiFi.localIP().toString();
serializeJson(json, *response);
request->send(response);
SendResponse = false;
}
}
});
// Define your devices here.
espalexa.addDevice(Device_1_Name, firstSwitchChanged, EspalexaDeviceType::onoff); //simplest definition, default state off
espalexa.addDevice(Device_2_Name, secondSwitchChanged, EspalexaDeviceType::onoff);
espalexa.addDevice(Device_3_Name, thirdSwitchChanged, EspalexaDeviceType::onoff);
espalexa.addDevice(Device_4_Name, fourthSwitchChanged, EspalexaDeviceType::onoff);
//give espalexa a pointer to your server object so it can use your server instead of creating its own
espalexa.begin(&server);
Serial.println("System is Now Alexa Enabled");
// Serial.println("01 = " + String(EEPROM.read(256)));
// Serial.println("02 = " + String(EEPROM.read(257)));
// Serial.println("03 = " + String(EEPROM.read(258)));
// Serial.println("04 = " + String(EEPROM.read(259)));
}
}
void loop()
{
espalexa.loop();
delay(1);
}
//our callback functions
void firstSwitchChanged(EspalexaDevice* d)
{
if (d == nullptr) return; //this is good practice, but not required
//Control the device
if (d->getValue())
{
digitalWrite(AlexaRelay01, HIGH);
EEPROM.write(256, HIGH);
EEPROM.commit();
Relay01 = HIGH;
Serial.println("Device1 ON");
}
else
{
digitalWrite(AlexaRelay01, LOW);
EEPROM.write(256, LOW);
EEPROM.commit();
Relay01 = LOW;
Serial.println("Device1 OFF");
}
}
void secondSwitchChanged(EspalexaDevice* d)
{
if (d == nullptr) return; //this is good practice, but not required
//Control the device
if (d->getValue())
{
digitalWrite(AlexaRelay02, HIGH);
EEPROM.write(257, HIGH);
EEPROM.commit();
Relay02 = HIGH;
Serial.println("Device2 ON");
}
else
{
digitalWrite(AlexaRelay02, LOW);
EEPROM.write(257, LOW);
EEPROM.commit();
Relay02 = LOW;
Serial.println("Device2 OFF");
}
}
void thirdSwitchChanged(EspalexaDevice* d)
{
if (d == nullptr) return; //this is good practice, but not required
//Control the device
if (d->getValue())
{
digitalWrite(AlexaRelay03, HIGH);
EEPROM.write(258, HIGH);
EEPROM.commit();
Relay03 = HIGH;
Serial.println("Device3 ON");
}
else
{
digitalWrite(AlexaRelay03, LOW);
EEPROM.write(258, LOW);
EEPROM.commit();
Relay03 = LOW;
Serial.println("Device3 OFF");
}
}
void fourthSwitchChanged(EspalexaDevice* d)
{
if (d == nullptr) return; //this is good practice, but not required
//Control the device
if (d->getValue())
{
digitalWrite(AlexaRelay04, HIGH);
EEPROM.write(259, HIGH);
EEPROM.commit();
Relay04 = HIGH;
Serial.println("Device4 ON");
}
else
{
digitalWrite(AlexaRelay04, LOW);
EEPROM.write(256, LOW);
EEPROM.commit();
Relay04 = LOW;
Serial.println("Device4 OFF");
}
}
void setOnOffRelay() { // Set GPIO according to the request
// Store state in EEPROM & then Set GPIO4 (D2) according to the request
EEPROM.write(256, Relay01);
digitalWrite(AlexaRelay01, Relay01);
// Store state in EEPROM & then Set GPIO0 (D3) according to the request
EEPROM.write(257, Relay02);
digitalWrite(AlexaRelay02, Relay02);
// Store state in EEPROM & then Set GPIO2 (D4) according to the request
EEPROM.write(258, Relay03);
digitalWrite(AlexaRelay03, Relay03);
// Store state in EEPROM & then Set GPIO14 (D5) according to the request
EEPROM.write(259, Relay04);
digitalWrite(AlexaRelay04, Relay04);
// Committ stored state from flash to EEPROM for power cycle initialization
EEPROM.commit();
// Serial.println(String(EEPROM.read(256)));
// Serial.println(String(EEPROM.read(257)));
// Serial.println(String(EEPROM.read(258)));
// Serial.println(String(EEPROM.read(259)));
}
I am using 30pin ESP32 variant (DOIT ESP32 DEVKIT V1), actual picture is as below:
Please help.