";
if (isOpen) {
message += "Le Bib est ouvert";
} else {
message += "Le Bib est Fermé";
}
message += "
";
server.send(200, "text/html", message);
Serial.print(" FreeHeapSize : ");
Serial.println(xPortGetFreeHeapSize());
}
// `/bibleds` POST request handler
void handleSetButton() {
if (!server.authenticate(button_user, button_password)) {
return server.requestAuthentication();
}
if (server.method() == HTTP_POST) {
Serial.println("received post request on /bibutton");
String postBody = server.arg("plain");
/* Disable printing the request body for prod
Serial.println(postBody);
*/
DynamicJsonDocument doc(512);
DeserializationError error = deserializeJson(doc, postBody);
if (error) {
Serial.print(F("Error parsing JSON "));
Serial.println(error.c_str());
String msg = error.c_str();
server.send(400, F("text/html"),
"Error while parsing json data! " + msg);
} else {
JsonObject postObj = doc.as();
forced_state = postObj["forceState"] | forced_state;
if ((forced_state != -1) && (forced_state != LOW) && (forced_state != HIGH)) {
forced_state = -1;
}
DynamicJsonDocument doc(512);
doc["forced_state"] = forced_state;
doc["button_state"] = button_state;
String buf;
serializeJson(doc, buf);
server.send(200, F("application/json"), buf);
Serial.print(F("done."));
}
}
}
// `/bibutton/leds` POST request handler
void handleSetLeds() {
if (!server.authenticate(leds_user, leds_password)) {
return server.requestAuthentication();
}
if (server.method() == HTTP_POST) {
Serial.println("received post request on /bibutton/leds");
String postBody = server.arg("plain");
/* Disable printing the request body for prod
Serial.println(postBody);
*/
DynamicJsonDocument doc(512);
DeserializationError error = deserializeJson(doc, postBody);
if (error) {
Serial.print(F("Error parsing JSON "));
Serial.println(error.c_str());
String msg = error.c_str();
server.send(400, F("text/html"),
"Error while parsing json data! " + msg);
} else {
JsonObject postObj = doc.as();
if (postObj.containsKey("index") && postObj.containsKey("count") && postObj.containsKey("values")) {
int index = postObj["index"] | -1;
int count = postObj["count"] | -1;
JsonArray values = postObj["values"];
if (index >= 0 && index < NUM_LEDS_1 && count > 0 && (index+count) <= NUM_LEDS_1) {
for (int i=0; i0) {
unsigned bit = val & 1;
if (bit == 1) {
leds_1[NUM_LEDS_1-1-i] = CHSV((i+heartbeat_index)%255,255,255);
} else {
leds_1[NUM_LEDS_1-1-i] = CRGB(0,0,0);
}
val >>= 1;
i++;
}
if (i 0) {
request_chen <<= 1;
clear_msb = (request_chen == 0);
}
}
// Setup the web OTA update library
void otaSetup(void) {
ElegantOTA.onStart([]() {
Serial.println("OTA update process started.");
});
// This is spitting out too many line to the serial line. Enable it only for debugging purpose.
// ElegantOTA.onProgress([](size_t current, size_t final) {
// Serial.printf("Progress: %u%%\n", (current * 100) / final);
// });
ElegantOTA.onEnd([](bool success) {
if (success) {
Serial.println("OTA update completed successfully.");
} else {
Serial.println("OTA update failed.");
}
});
ElegantOTA.begin(&server);
ElegantOTA.setAuth(ota_user, ota_password);
}
void webServerSetup() {
server.on("/", handleRoot);
server.on("/bibutton", HTTP_GET, handleGetBibbutton);
server.on("/bibutton", HTTP_POST, handleSetButton);
server.on("/bibleds", HTTP_POST, handleSetLeds);
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
}
// Main setup function
void setup() {
// Init serial port
Serial.begin(500000);
Serial.setDebugOutput(true);
Serial.println("Serial port initialized.");
// Safety delay
delay(1000);
// Setup Addressable LEDs
Serial.println("Setting-up the LEDs...");
FastLED.addLeds(leds_0, NUM_LEDS_0);
FastLED.addLeds(leds_1, NUM_LEDS_1);
FastLED.setBrightness(LEDS_BRIGHTNESS);
FastLED.show();
// Setup the GPIO of the bib button as an input with an integrated weak pull-up resistor
Serial.println("Setting-up the button GPIO...");
pinMode(BIB_BUTTON, INPUT_PULLDOWN);
// Setup the GPIOs of the traffic lights as output
pinMode(LIGHT_RED, OUTPUT);
pinMode(LIGHT_GREEN, OUTPUT);
pinMode(LIGHT_ORANGE, OUTPUT);
Serial.println("Setting-up the ethernet interface...");
// Initialize SPI with specified pin configuration
SPI.begin(W5500_SCK, W5500_MISO, W5500_MOSI);
// Initialize Ethernet using DHCP to obtain an IP address
Ethernet.init(driver);
if (Ethernet.begin(mac[SELECTED_MAC]) == 0) {
Serial.println("DHCP failed, falling back to static IP...");
// Initialize with static IP
Ethernet.begin(mac[SELECTED_MAC], myIP, myDNS, myGW, mySN);
} else {
is_network_ok = true;
}
// Print the assigned IP address
Serial.print("IP Address: ");
Serial.println(Ethernet.localIP());
//Setup mdns so that other hosts can resolve our .local DNS name
Serial.println("Setting-up the MDNS responder...");
if (!MDNS.begin(hostname)) {
Serial.println("Error setting up MDNS responder!");
}
Serial.println("Setting-up the web server...");
webServerSetup();
Serial.println("Setting-up the web OTA library...");
otaSetup();
Serial.println("Setup completed :-)");
}
// Main loop function
void loop() {
// Get current time
unsigned long current_time = micros();
// Check if it is time to update the heartbeat LED
if ((current_time - last_heartbeat_time) >= 1000*HEARTBEAT_PERIOD) {
// Update last heartbeat time
last_heartbeat_time = current_time;
// Increment the hue we are displaying on the board LED, and cycle back to 0 when reaching 256
heartbeat_index = (heartbeat_index + 1) % 256;
// Update the LED color in the FastLED array
leds_0[0] = CHSV(heartbeat_index,255,255);
// Read the bibutton status and turn on/off the red and green lights accordingly
button_state = digitalRead(BIB_BUTTON);
if ((forced_state < 0) || forced_state == button_state) {
forced_state = -1;
if (button_state == HIGH) {
digitalWrite(LIGHT_GREEN, HIGH);
digitalWrite(LIGHT_RED, LOW);
} else {
digitalWrite(LIGHT_GREEN, LOW);
digitalWrite(LIGHT_RED, HIGH);
}
} else {
digitalWrite(LIGHT_GREEN, HIGH);
digitalWrite(LIGHT_RED, HIGH);
}
// Turn on/off the orange light according to network connectivity status
if (!is_network_ok) {
digitalWrite(LIGHT_ORANGE, HIGH);
} else {
digitalWrite(LIGHT_ORANGE, LOW);
}
// Do something on the LED strip values
animateLedStrip();
// Update the LEDs with the values we set in the arrays
FastLED.show();
}
// Check if it is time to check the network connectivity
if ((current_time - last_ping_time) >= 1000*PING_PERIOD) {
// ToDo : move that to an asynchronous task as the ping can take a while if the internet is not reachable. But that is not that important, because if the net is down, our main purpose is borked anyway.
is_network_ok = Ping.ping(myProxy, 1);
if (is_network_ok) {
Serial.print("ping time: ");
Serial.print(Ping.averageTime());
Serial.println(" ms");
} else {
Serial.println("Failed to ping remote host!");
}
last_ping_time = micros();
}
// Do nothing for 1 ms
delay(1);
// Let the web server and the web OTA update library do their things
server.handleClient();
ElegantOTA.loop();
}