#include "WiFi.h"
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <DS1307RTC.h>
#include <TimeLib.h>
#include "Pins.h"
#include "lcdSymbols.h"
#include "MainLight.h"
#include "NightLight.h"
#include "AlarmClock.h"
#include "Display.h"
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const String url = "http://worldtimeapi.org/api/timezone/Europe/Moscow.json";
HTTPClient http;
MainLight M_Light(MAIN_LIGHT);
NightLight N_Light(NIGHT_LIGHT);
AlarmClock Alarm(ALARM_RELAY, ALARM_PIN);
Display MainDisplay(BUTTON_UP, BUTTON_DOWN, BUTTON_L, BUTTON_R, BUTTON_MENU);
time_t GetUnixTime(){
time_t unixTime = 0;
time_t offset = 0;
if(WiFi.status() == WL_CONNECTED){
http.begin(url);
int httpCode = http.GET();
if (httpCode > 0) {
StaticJsonDocument<768> doc;
DeserializationError error = deserializeJson(doc, http.getString());
if (error) {
return -1;
}
unixTime = doc["unixtime"];
offset = doc["raw_offset"];
http.end();
}
}
else if(WiFi.status() != WL_CONNECTED){
return -1;
}
return unixTime + offset;
}
void setup() {
Serial.begin(115200);
pinMode(BUTTON_LIGHT, INPUT);
pinMode(MOTION_SENS, INPUT);
getlcd().init();
getlcd().backlight();
getlcd().createChar(0, up);
getlcd().createChar(1, down);
getlcd().createChar(2, yes);
getlcd().createChar(3, no);
getlcd().createChar(4, lightBulbOn);
getlcd().createChar(5, lightBulbOff);
getlcd().createChar(6, menu);
getlcd().createChar(7, back);
Alarm.Time[0] = 8;
Alarm.Time[1] = 15;
WiFi.begin(ssid, password);
int i = 0;
while (WiFi.status() != WL_CONNECTED) {
if(i == 10) break;
i++;
delay(1000);
Serial.println("Connecting to Wi-Fi...");
}
if(WiFi.status() == WL_CONNECTED){
Serial.println("Wi-Fi connection is established!");
}
else{
Serial.println("Couldn't connect to Wi-Fi!");
}
time_t Time = GetUnixTime();
Serial.println(Time);
if(Time >= 0){
RTC.set(Time);
setSyncProvider(RTC.get); // the function to get the time from the RTC
}
else{
setSyncProvider(0);
setTime(1702537200);
}
}
void loop()
{
static uint32_t currentTime = RTC.get();
static uint32_t newTime;
M_Light.ButtonControl(BUTTON_LIGHT);
if(digitalRead(MOTION_SENS) == HIGH || M_Light.MotionDetected || N_Light.MotionDetected){
if(M_Light.IsDaytime(hour(), minute()) && M_Light.IsOnIfMotion){
M_Light.MotionControl();
}
else if(N_Light.IsNighttime(hour(), minute()) && N_Light.IsOnIfMotion){
N_Light.MotionControl();
}
}
if(Alarm.Enabled){
if(Alarm.IsAlarmTime(hour(), minute()) || Alarm.CurrentState == HIGH){
Alarm.Exec();
}
}
MainDisplay.ButtonMenu();
if(MainDisplay.GetState() == STATE_IDLE){
MainDisplay.PrintTime(MAIN_LIGHT, hour(), minute(), second(), day(), month(), year());
}
else if(MainDisplay.GetState() == STATE_MENU){
MainDisplay.PrintMenu();
}
else if(MainDisplay.GetState() == STATE_EDIT){
switch (MainDisplay.GetCurrentItem()){
case MENU_NULL:
break;
case NIGHT_SENS:
MainDisplay.PrintParam_Bool(N_Light.IsOnIfMotion);
break;
case NIGHT_DUR:
MainDisplay.PrintParam_Duration(N_Light.DurTime, 10, 60);
break;
case MAIN_SENS:
MainDisplay.PrintParam_Bool(M_Light.IsOnIfMotion);
break;
case MAIN_DUR:
MainDisplay.PrintParam_Duration(M_Light.DurTime, 10, 600);
break;
case ALARM_TIME:
MainDisplay.PrintParam_Time(Alarm.Time[0], Alarm.Time[1]);
break;
case ALARM_ONOFF:
MainDisplay.PrintParam_Bool(Alarm.Enabled);
break;
case ALARM_DUR:
MainDisplay.PrintParam_Duration(Alarm.DurTime, 10, 600);
break;
case SSID:
MainDisplay.PrintParam_Text(ssid);
break;
case PASS:
MainDisplay.PrintParam_Text(password);
break;
case SET_TIME:
newTime = currentTime;
MainDisplay.PrintParam_DateTime(hour(), minute(), second(), day(), month(), year(), newTime);
if(currentTime != newTime){
currentTime = newTime;
setTime(currentTime);
}
break;
default:
break;
}
}
}