Added individual LED control to API and WebUI
This commit is contained in:
parent
ef70203834
commit
1ad97b9b71
6 changed files with 139 additions and 16 deletions
2
data
2
data
|
@ -1 +1 @@
|
||||||
Subproject commit 58fa1e7ecb49388bc4b59444ab3f5af7b3219699
|
Subproject commit d3c6e52f3f5bae6054f8fc05b241a1e9b0a6ca1c
|
|
@ -209,7 +209,7 @@ void finishSetup()
|
||||||
|
|
||||||
if (preferences.getBool("ledStatus", false))
|
if (preferences.getBool("ledStatus", false))
|
||||||
{
|
{
|
||||||
setLights(preferences.getUInt("ledColor", 0xFFCC00));
|
restoreLedState();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -250,18 +250,44 @@ void setLights(uint32_t color)
|
||||||
{
|
{
|
||||||
|
|
||||||
bool ledStatus = true;
|
bool ledStatus = true;
|
||||||
if (color == pixels.Color(0, 0, 0))
|
|
||||||
{
|
|
||||||
ledStatus = false;
|
|
||||||
} else {
|
|
||||||
preferences.putUInt("ledColor", color);
|
|
||||||
}
|
|
||||||
preferences.putBool("ledStatus", ledStatus);
|
|
||||||
|
|
||||||
for (int i = 0; i < NEOPIXEL_COUNT; i++)
|
for (int i = 0; i < NEOPIXEL_COUNT; i++)
|
||||||
{
|
{
|
||||||
pixels.setPixelColor(i, color);
|
pixels.setPixelColor(i, color);
|
||||||
}
|
}
|
||||||
|
pixels.show();
|
||||||
|
|
||||||
|
if (color == pixels.Color(0, 0, 0))
|
||||||
|
{
|
||||||
|
ledStatus = false;
|
||||||
|
} else {
|
||||||
|
saveLedState();
|
||||||
|
}
|
||||||
|
preferences.putBool("ledStatus", ledStatus);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveLedState() {
|
||||||
|
for (int i = 0; i < pixels.numPixels(); i++)
|
||||||
|
{
|
||||||
|
int pixelColor = pixels.getPixelColor(i);
|
||||||
|
char key[12];
|
||||||
|
snprintf(key, 12, "%s%d", "ledColor_", i);
|
||||||
|
preferences.putUInt(key, pixelColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
xTaskNotifyGive(eventSourceTaskHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void restoreLedState() {
|
||||||
|
for (int i = 0; i < pixels.numPixels(); i++)
|
||||||
|
{
|
||||||
|
char key[12];
|
||||||
|
snprintf(key, 12, "%s%d", "ledColor_", i);
|
||||||
|
uint pixelColor = preferences.getUInt(key, pixels.Color(0,0,0));
|
||||||
|
pixels.setPixelColor(i, pixelColor);
|
||||||
|
}
|
||||||
|
|
||||||
pixels.show();
|
pixels.show();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <Adafruit_NeoPixel.h>
|
#include <Adafruit_NeoPixel.h>
|
||||||
|
#include <freertos/FreeRTOS.h>
|
||||||
|
#include <freertos/task.h>
|
||||||
|
#include "webserver.hpp"
|
||||||
#include "shared.hpp"
|
#include "shared.hpp"
|
||||||
|
|
||||||
#ifndef NEOPIXEL_PIN
|
#ifndef NEOPIXEL_PIN
|
||||||
|
@ -38,6 +41,8 @@ void blinkDelay(int d, int times);
|
||||||
void blinkDelayColor(int d, int times, uint r, uint g, uint b);
|
void blinkDelayColor(int d, int times, uint r, uint g, uint b);
|
||||||
void blinkDelayTwoColor(int d, int times, uint32_t c1, uint32_t c2);
|
void blinkDelayTwoColor(int d, int times, uint32_t c1, uint32_t c2);
|
||||||
void clearLeds();
|
void clearLeds();
|
||||||
|
void saveLedState();
|
||||||
|
void restoreLedState();
|
||||||
QueueHandle_t getLedTaskQueue();
|
QueueHandle_t getLedTaskQueue();
|
||||||
bool queueLedEffect(uint effect);
|
bool queueLedEffect(uint effect);
|
||||||
void setLights(int r, int g, int b);
|
void setLights(int r, int g, int b);
|
||||||
|
|
|
@ -6,7 +6,6 @@ TaskHandle_t eventSourceTaskHandle;
|
||||||
|
|
||||||
void setupWebserver()
|
void setupWebserver()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
events.onConnect([](AsyncEventSourceClient *client)
|
events.onConnect([](AsyncEventSourceClient *client)
|
||||||
{ client->send("welcome", NULL, millis(), 1000); });
|
{ client->send("welcome", NULL, millis(), 1000); });
|
||||||
|
@ -39,6 +38,9 @@ void setupWebserver()
|
||||||
AsyncCallbackJsonWebHandler *handler = new AsyncCallbackJsonWebHandler("/api/show/custom", onApiShowTextAdvanced);
|
AsyncCallbackJsonWebHandler *handler = new AsyncCallbackJsonWebHandler("/api/show/custom", onApiShowTextAdvanced);
|
||||||
server.addHandler(handler);
|
server.addHandler(handler);
|
||||||
|
|
||||||
|
AsyncCallbackJsonWebHandler *lightsJsonHandler = new AsyncCallbackJsonWebHandler("/api/lights", onApiLightsSetJson);
|
||||||
|
server.addHandler(lightsJsonHandler);
|
||||||
|
|
||||||
server.on("/api/lights/off", HTTP_GET, onApiLightsOff);
|
server.on("/api/lights/off", HTTP_GET, onApiLightsOff);
|
||||||
server.on("/api/lights/color", HTTP_GET, onApiLightsSetColor);
|
server.on("/api/lights/color", HTTP_GET, onApiLightsSetColor);
|
||||||
server.on("/api/lights", HTTP_GET, onApiLightsStatus);
|
server.on("/api/lights", HTTP_GET, onApiLightsStatus);
|
||||||
|
@ -109,15 +111,16 @@ StaticJsonDocument<512> getLedStatusObject()
|
||||||
{
|
{
|
||||||
StaticJsonDocument<512> root;
|
StaticJsonDocument<512> root;
|
||||||
JsonArray colors = root.createNestedArray("data");
|
JsonArray colors = root.createNestedArray("data");
|
||||||
// Adafruit_NeoPixel pix = getPixels();
|
// Adafruit_NeoPixel pix = getPixels();
|
||||||
|
|
||||||
for (uint i = 0; i < pixels.numPixels(); i++) {
|
for (uint i = 0; i < pixels.numPixels(); i++)
|
||||||
uint32_t pixColor = pixels.getPixelColor(i);
|
{
|
||||||
|
uint32_t pixColor = pixels.getPixelColor(pixels.numPixels() - i - 1);
|
||||||
uint alpha = (pixColor >> 24) & 0xFF;
|
uint alpha = (pixColor >> 24) & 0xFF;
|
||||||
uint red = (pixColor >> 16) & 0xFF;
|
uint red = (pixColor >> 16) & 0xFF;
|
||||||
uint green = (pixColor >> 8) & 0xFF;
|
uint green = (pixColor >> 8) & 0xFF;
|
||||||
uint blue = pixColor & 0xFF;
|
uint blue = pixColor & 0xFF;
|
||||||
char hexColor[8];
|
char hexColor[8];
|
||||||
sprintf(hexColor, "#%02X%02X%02X", red, green, blue);
|
sprintf(hexColor, "#%02X%02X%02X", red, green, blue);
|
||||||
|
|
||||||
JsonObject object = colors.createNestedObject();
|
JsonObject object = colors.createNestedObject();
|
||||||
|
@ -677,7 +680,7 @@ void onApiLightsStatus(AsyncWebServerRequest *request)
|
||||||
{
|
{
|
||||||
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
||||||
|
|
||||||
serializeJson(getLedStatusObject(), *response);
|
serializeJson(getLedStatusObject()["data"], *response);
|
||||||
|
|
||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
@ -708,19 +711,107 @@ void onApiLightsSetColor(AsyncWebServerRequest *request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onApiLightsSetJson(AsyncWebServerRequest *request, JsonVariant &json)
|
||||||
|
{
|
||||||
|
if (request->method() == HTTP_PATCH) {
|
||||||
|
|
||||||
|
JsonArray lights = json.as<JsonArray>();
|
||||||
|
|
||||||
|
if (lights.size() != pixels.numPixels())
|
||||||
|
{
|
||||||
|
Serial.printf("Invalid values for LED set %d\n", lights.size());
|
||||||
|
request->send(400);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint i = 0; i < pixels.numPixels(); i++)
|
||||||
|
{
|
||||||
|
unsigned int red, green, blue;
|
||||||
|
|
||||||
|
if (lights[i].containsKey("red") && lights[i].containsKey("green") && lights[i].containsKey("blue"))
|
||||||
|
{
|
||||||
|
|
||||||
|
red = lights[i]["red"].as<uint>();
|
||||||
|
green = lights[i]["green"].as<uint>();
|
||||||
|
blue = lights[i]["blue"].as<uint>();
|
||||||
|
}
|
||||||
|
else if (lights[i].containsKey("hex"))
|
||||||
|
{
|
||||||
|
if (!sscanf(lights[i]["hex"].as<String>().c_str(), "#%02X%02X%02X", &red, &green, &blue) == 3)
|
||||||
|
{
|
||||||
|
Serial.printf("Invalid hex for LED %d\n", i);
|
||||||
|
request->send(400);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Serial.printf("No valid color for LED %d\n", i);
|
||||||
|
request->send(400);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixels.setPixelColor((pixels.numPixels() - i - 1), pixels.Color(
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue));
|
||||||
|
}
|
||||||
|
|
||||||
|
pixels.show();
|
||||||
|
saveLedState();
|
||||||
|
|
||||||
|
request->send(200);
|
||||||
|
} else {
|
||||||
|
request->send(404);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void onIndex(AsyncWebServerRequest *request) { request->send(LittleFS, "/index.html", String(), false); }
|
void onIndex(AsyncWebServerRequest *request) { request->send(LittleFS, "/index.html", String(), false); }
|
||||||
|
|
||||||
void onNotFound(AsyncWebServerRequest *request)
|
void onNotFound(AsyncWebServerRequest *request)
|
||||||
{
|
{
|
||||||
|
// Serial.printf("NotFound, URL[%s]\n", request->url());
|
||||||
|
|
||||||
|
// Serial.printf("NotFound, METHOD[%s]\n", request->methodToString());
|
||||||
|
|
||||||
|
// int headers = request->headers();
|
||||||
|
// int i;
|
||||||
|
// for (i = 0; i < headers; i++)
|
||||||
|
// {
|
||||||
|
// AsyncWebHeader *h = request->getHeader(i);
|
||||||
|
// Serial.printf("NotFound HEADER[%s]: %s\n", h->name().c_str(), h->value().c_str());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// int params = request->params();
|
||||||
|
// for (int i = 0; i < params; i++)
|
||||||
|
// {
|
||||||
|
// AsyncWebParameter *p = request->getParam(i);
|
||||||
|
// if (p->isFile())
|
||||||
|
// { // p->isPost() is also true
|
||||||
|
// Serial.printf("NotFound FILE[%s]: %s, size: %u\n", p->name().c_str(), p->value().c_str(), p->size());
|
||||||
|
// }
|
||||||
|
// else if (p->isPost())
|
||||||
|
// {
|
||||||
|
// Serial.printf("NotFound POST[%s]: %s\n", p->name().c_str(), p->value().c_str());
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// Serial.printf("NotFound GET[%s]: %s\n", p->name().c_str(), p->value().c_str());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
// Access-Control-Request-Method == POST might be better
|
// Access-Control-Request-Method == POST might be better
|
||||||
|
|
||||||
if (request->method() == HTTP_OPTIONS || request->hasHeader("Sec-Fetch-Mode"))
|
if (request->method() == HTTP_OPTIONS || request->hasHeader("Sec-Fetch-Mode"))
|
||||||
{
|
{
|
||||||
|
// Serial.printf("NotFound, Return[%d]\n", 200);
|
||||||
|
|
||||||
request->send(200);
|
request->send(200);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
request->send(200);
|
// Serial.printf("NotFound, Return[%d]\n", 404);
|
||||||
|
request->send(404);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ void onApiFullRefresh(AsyncWebServerRequest *request);
|
||||||
void onApiLightsStatus(AsyncWebServerRequest *request);
|
void onApiLightsStatus(AsyncWebServerRequest *request);
|
||||||
void onApiLightsOff(AsyncWebServerRequest *request);
|
void onApiLightsOff(AsyncWebServerRequest *request);
|
||||||
void onApiLightsSetColor(AsyncWebServerRequest *request);
|
void onApiLightsSetColor(AsyncWebServerRequest *request);
|
||||||
|
void onApiLightsSetJson(AsyncWebServerRequest *request, JsonVariant &json);
|
||||||
|
|
||||||
|
|
||||||
void onApiRestart(AsyncWebServerRequest *request);
|
void onApiRestart(AsyncWebServerRequest *request);
|
||||||
|
|
Loading…
Reference in a new issue