#include <WiFi.h>
#include <HTTPClient.h>
#include <LiquidCrystal_I2C.h>
#include <string.h>
struct UserData
{
String name;
String city;
String alarm;
};
struct WeatherData
{
String temperature;
};
struct TimeData
{
int hour;
int minute;
int second;
};
const char* k_ssid = "Wokwi-GUEST";
const char* k_password = "";
const String k_thingSpeakApi = "https://api.thingspeak.com/channels/1929706/feeds.json?results=1";
const String k_openWeatherMapApi = "http://api.openweathermap.org/data/2.5/weather?q=Sorocaba,br&APPID=cebc60ca0120bfe26aaadcc54c82481e&units=metric";
const String k_timeApi = "https://www.timeapi.io/api/Time/current/zone?timeZone=America/Sao_Paulo";
UserData m_currentUserData;
WeatherData m_currentWeatherData;
TimeData m_currentTimeData;
LiquidCrystal_I2C lcd(0x27, 16, 2);
HTTPClient http;
bool ringingAlarm = false;
void setup()
{
Serial.begin(115200);
initializeDisplay();
initializeWifi();
updateData();
}
void loop()
{
drawWelcomeRequestSetup();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Obrigada, " + m_currentUserData.name + "!");
delay(5000);
while(true)
{
if(ringingAlarm == false)
{
drawMainScreen();
if( m_currentTimeData.hour == m_currentUserData.alarm.substring(0, 2).toInt() &&
m_currentTimeData.minute == m_currentUserData.alarm.substring(3, 5).toInt())
{
ringingAlarm = true;
}
delay(1000);
}
else
{
ringAlarm();
drawAlarmScreen();
if(digitalRead(34) == 1)
{
ringingAlarm = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Bom dia, " + m_currentUserData.name + "!");
delay(5000);
updateData();
}
delay(1000);
}
updateClockTime();
}
}
void initializePins()
{
pinMode(34, INPUT);
pinMode(33, OUTPUT);
}
void initializeDisplay()
{
lcd.init();
lcd.backlight();
lcd.setCursor(2, 0);
}
void initializeWifi()
{
WiFi.begin(k_ssid, k_password, 6); // rede, senha e canal do WiFi
Serial.print("Conectando-se ao WiFi");
while (WiFi.status() != WL_CONNECTED)
{
delay(100);
Serial.print(".");
}
Serial.print("OK! IP=");
Serial.println(WiFi.localIP());
}
void updateData()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Buscando Usuario");
m_currentUserData = fetchUserData();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Buscando Clima");
m_currentWeatherData = fetchWeatherData();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Buscando Horario");
m_currentTimeData = fetchTimeData();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Dados Atualizados");
}
UserData fetchUserData()
{
UserData tempUserData;
int httpResponseCode;
http.begin(k_thingSpeakApi);
httpResponseCode = http.GET();
if(httpResponseCode > 0)
{
String payload = http.getString();
payload = payload.substring(payload.indexOf("feeds"));
String fetchedUserName = payload.substring(payload.indexOf("field1"));
fetchedUserName = fetchedUserName.substring(9, fetchedUserName.indexOf(",") - 1);
String fetchedUserCity = payload.substring(payload.indexOf("field2"));
fetchedUserCity = fetchedUserCity.substring(9, fetchedUserCity.indexOf(",") - 1);
String fetchedUserAlarm = payload.substring(payload.indexOf("field3"));
fetchedUserAlarm = fetchedUserAlarm.substring(9, fetchedUserAlarm.indexOf("}") - 1);
tempUserData.name = fetchedUserName;
tempUserData.city = fetchedUserCity;
tempUserData.alarm = fetchedUserAlarm;
}
return tempUserData;
}
WeatherData fetchWeatherData()
{
WeatherData tempWeatherData;
int httpResponseCode;
String apiRequestUrl = k_openWeatherMapApi;
apiRequestUrl.replace("CIDADE", m_currentUserData.city);
http.begin(apiRequestUrl);
httpResponseCode = http.GET();
if(httpResponseCode > 0)
{
String payload = http.getString();
String fetchedTemperature = payload.substring(payload.indexOf("temp"));
fetchedTemperature = fetchedTemperature.substring(6, fetchedTemperature.indexOf(","));
tempWeatherData.temperature = fetchedTemperature;
}
else
{
// Valor default pra demonstração no caso de a API não retornar valor.
tempWeatherData.temperature = 25;
}
return tempWeatherData;
}
TimeData fetchTimeData()
{
TimeData tempTimeData;
int httpResponseCode;
http.begin(k_timeApi);
httpResponseCode = http.GET();
if(httpResponseCode > 0)
{
String payload = http.getString();
String fetchedHour = payload.substring(payload.indexOf("hour"));
fetchedHour = fetchedHour.substring(6, fetchedHour.indexOf(","));
String fetchedMinute = payload.substring(payload.indexOf("minute"));
fetchedMinute = fetchedMinute.substring(8, fetchedMinute.indexOf(","));
String fetchedSecond = payload.substring(payload.indexOf("seconds"));
fetchedSecond = fetchedSecond.substring(9, fetchedSecond.indexOf(","));
tempTimeData.hour = fetchedHour.toInt();
tempTimeData.minute = fetchedMinute.toInt();
tempTimeData.second = fetchedSecond.toInt();
}
return tempTimeData;
}
void drawWelcomeRequestSetup()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Oi! Sou a Fanny!");
delay(3000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Configure-me");
lcd.setCursor(0, 1);
lcd.print("no app!");
delay(3000);
UserData newUserData;
do
{
newUserData = fetchUserData();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Aguardando");
lcd.setCursor(0, 1);
lcd.print("config...");
}
while ( newUserData.name == m_currentUserData.name &&
newUserData.city == m_currentUserData.city &&
newUserData.alarm == m_currentUserData.alarm);
updateData();
}
void drawMainScreen()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(m_currentTimeData.hour);
lcd.print(":");
lcd.print(m_currentTimeData.minute);
lcd.print(":");
lcd.print(m_currentTimeData.second);
lcd.setCursor(12, 0);
lcd.print(m_currentWeatherData.temperature);
lcd.print("C");
lcd.setCursor(0, 1);
if(m_currentWeatherData.temperature.toInt() >= 22)
{
lcd.print("Use roupas leves");
}
else
{
lcd.print("Agasalhe-se");
}
}
void drawAlarmScreen()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Acorda, " + m_currentUserData.name + "!");
}
void updateClockTime()
{
m_currentTimeData.second += 1;
if(m_currentTimeData.second >= 60)
{
m_currentTimeData.second = 0;
m_currentTimeData.minute += 1;
}
if(m_currentTimeData.minute >= 60)
{
m_currentTimeData.minute = 0;
m_currentTimeData.hour += 1;
}
if(m_currentTimeData.hour >= 24)
{
m_currentTimeData.hour = 0;
}
}
void ringAlarm()
{
// Gera erro: 'E (118316) gpio: gpio_set_level(226): GPIO output gpio_num error'
digitalWrite(33, 1);
delay(500);
digitalWrite(33, 0);
delay(500);
}