#include #include #include #include #include #include //chime mode 1 ship, 2 traditional, 3 traditional with quarters struct Config{ char ssid[64]; char wifi_pass[64]; char tz[64]; int quiet_start_hour; int quiet_start_min; int quiet_end_hour; int quiet_end_min; int ChimeMode; }; Config config; Timezone EST; bool chimed = 0; bool quietTime = 0; long interval = 1000; long previousMillis = 0; AsyncWebServer server(80); void setup() { Serial.begin(115200); Serial.println(""); //Load FS and load config file if (!LittleFS.begin()){ Serial.println("ERROR"); return; } loadConfiguration(); //connect to WiFi Serial.printf("Connecting to %s ", config.ssid); WiFi.hostname("BellChimerESP"); WiFi.begin(config.ssid, config.wifi_pass); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } int ip = WiFi.localIP(); Serial.println("CONNECTED"); Serial.println(WiFi.localIP()); //init ntp, get the time and set timezone waitForSync(); EST.setLocation(config.tz); Serial.printf("Timezone set to: %s", config.tz); //Serve Index server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(LittleFS, "/index.html"); }); server.begin(); } void checkTime() { //Checks if it's currently during a quiet period if (!checkQuiet()) { Serial.println("NOT QUIET"); //gets the current hour/minute int hours = EST.hour(); int minutes = EST.minute(); //checks what mode the chime is in and passes the hour/minute if (config.ChimeMode == 1) { ship(hours, minutes); } } else { Serial.println("QUIET"); } } void loadConfiguration() { //open config.json File configFile = LittleFS.open("/config.json", "r"); if(!configFile){ Serial.println("failed to open configFile"); //return; } //init arduinojson and deserialize file StaticJsonDocument<300> doc; DeserializationError error = deserializeJson(doc, configFile); if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.f_str()); return; } //copy json values to config structure strlcpy(config.ssid, doc["ssid"], sizeof(config.ssid)); strlcpy(config.wifi_pass, doc["wifi_pass"], sizeof(config.wifi_pass)); strlcpy(config.tz, doc["tz"], sizeof(config.tz)); config.quiet_start_hour = doc["quiet_start_hour"]; config.quiet_start_min = doc["quiet_start_min"]; config.quiet_end_hour = doc["quiet_end_hour"]; config.quiet_end_min = doc["quiet_end_min"]; config.ChimeMode = doc["ChimeMode"]; return; } bool checkQuiet() { //get current time int hours = EST.hour(); int minutes = EST.minute(); //convert times into minutes unsigned currentTime = (hours *60) + minutes; unsigned startTime = (config.quiet_start_hour *60) + config.quiet_start_min; unsigned endTime = (config.quiet_end_hour *60) + config.quiet_end_min; boolean quiet; //No quiet time sets the config values to -1, which skips the entire time check if (config.quiet_start_hour >= 0) { //if it doesn't overflow into tomorrow if (endTime > startTime) { quiet = (currentTime >= startTime && currentTime < endTime); } //if it does go into tomorrow else { quiet = (currentTime >= startTime || currentTime < endTime); } } else { quiet = 0; } return quiet; } void loop() { unsigned long currentMillis = millis(); if (currentMillis - previousMillis > interval) { previousMillis = currentMillis; checkTime(); } }