spejsiot/ledcontroller/app/application.cpp

107 lines
3.3 KiB
C++

#include <user_config.h>
#include <SmingCore/SmingCore.h>
#include <algorithm>
#include <SpejsNode.h>
extern "C" {
#include "ws2812_i2s.h"
}
#define LEDS_CNT 150
enum LEDMode {
IDLE,
OFF,
WHITE,
STROBE,
BRIGHT,
TEST,
};
class LEDEndpoint : public Endpoint {
private:
struct __attribute__((packed)) {
uint8_t g;
uint8_t r;
uint8_t b;
} leds[LEDS_CNT];
enum LEDMode currentMode = LEDMode::IDLE;
Timer animationTimer;
void animate() {
/*if (i % 50 == 0)
WDT.alive();*/
static int frameCounter = 0;
frameCounter++;
for(int i = 0; i < LEDS_CNT; i++) {
switch(currentMode) {
case LEDMode::IDLE:
leds[i].r = std::max(sin(i * 2*PI/LEDS_CNT - millis() / 1000.0)/2 * 255, 0.0);
leds[i].g = std::max(sin(i * 2*PI/LEDS_CNT + millis() / 500.0)/2 * 255, 0.0);
leds[i].b = std::max(sin(i * 2*PI/LEDS_CNT + millis() / 420.0)/2 * 255, 0.0);
break;
case LEDMode::TEST:
leds[i].r = std::min(std::max((sin(i * 2*PI/LEDS_CNT - millis() / 1000.0)/2 + 0.2) * 255, 0.0), 255.0);
leds[i].g = std::min(std::max((sin(i * 2*PI/LEDS_CNT + millis() / 500.0)/2 + 0.2) * 255, 0.0), 255.0);
leds[i].b = std::min(std::max((sin(i * 2*PI/LEDS_CNT + millis() / 420.0)/2 + 0.2) * 255, 0.0), 255.0);
break;
case LEDMode::BRIGHT:
leds[i].r = std::min(std::max((sin(i * 2*PI/LEDS_CNT - millis() / 1000.0)/4 + 0.5) * 255, 0.0), 255.0);
leds[i].g = std::min(std::max((sin(i * 2*PI/LEDS_CNT + millis() / 500.0)/4 + 0.5) * 255, 0.0), 255.0);
leds[i].b = std::min(std::max((sin(i * 2*PI/LEDS_CNT + millis() / 420.0)/4 + 0.5) * 255, 0.0), 255.0);
break;
case LEDMode::OFF:
leds[i].r = leds[i].g = leds[i].b = 0;
break;
case LEDMode::WHITE:
leds[i].r = leds[i].g = leds[i].b = 255;
break;
case LEDMode::STROBE:
leds[i].r = leds[i].g = leds[i].b = (frameCounter % 2) ? 255 : 0;
break;
}
}
ws2812_push((uint8_t*) leds, sizeof(leds));
}
public:
LEDEndpoint() : Endpoint("leds", {
{"mode", "enum", true, "idle,off,white,strobe,bright,test", "Current LED mode"},
}) {
animationTimer.initializeMs(50, TimerDelegate(&LEDEndpoint::animate, this)).start();
ws2812_init();
}
EndpointResult onValue(String property, String value) {
if (property != "mode") {
return 400;
}
if (value == "idle") currentMode = LEDMode::IDLE;
else if (value == "off") currentMode = LEDMode::OFF;
else if (value == "white") currentMode = LEDMode::WHITE;
else if (value == "strobe") currentMode = LEDMode::STROBE;
else if (value == "bright") currentMode = LEDMode::BRIGHT;
else if (value == "test") currentMode = LEDMode::TEST;
else {
return 400;
}
notify("mode", value);
return 200;
}
};
SpejsNode node("ledcontroller");
void init()
{
node.init();
node.registerEndpoint("leds", new LEDEndpoint());
}