figments: renderer: move power management directly into the renderer
This commit is contained in:
parent
6e138175be
commit
6797889b4c
@ -1,7 +1,6 @@
|
||||
{
|
||||
"version": 1,
|
||||
"tasks": [
|
||||
"Power",
|
||||
"Renderer",
|
||||
"U8Display",
|
||||
"WiFi",
|
||||
|
@ -3,7 +3,6 @@
|
||||
"tasks": [
|
||||
"Bluetooth",
|
||||
"Renderer",
|
||||
"Power",
|
||||
"Serial"
|
||||
],
|
||||
"scenes": {
|
||||
|
@ -3,7 +3,6 @@
|
||||
"tasks": [
|
||||
"WiFi",
|
||||
"Renderer",
|
||||
"Power",
|
||||
"MQTT",
|
||||
"ArduinoOTA",
|
||||
"UpdateStatusAnimation",
|
||||
|
@ -18,7 +18,12 @@ Renderer::lastFigmentName()
|
||||
void
|
||||
Renderer::loop()
|
||||
{
|
||||
m_powerState.update();
|
||||
m_brightness.update();
|
||||
|
||||
uint16_t totalPower = 0;
|
||||
for(Display* dpy : m_displays) {
|
||||
totalPower += calculate_unscaled_power_mW(dpy->pixelBacking(), dpy->pixelCount());
|
||||
for(Figment* figment : m_figments) {
|
||||
if (figment->state == Task::Running) {
|
||||
#if defined(BOARD_ESP32) or defined(BOARD_ESP8266)
|
||||
@ -38,10 +43,42 @@ Renderer::loop()
|
||||
}
|
||||
};
|
||||
}
|
||||
FastLED.show();
|
||||
const uint8_t videoBrightness = brighten8_video(m_powerState);
|
||||
FastLED.show(powerScale(videoBrightness, totalPower));
|
||||
FastLED.countFPS();
|
||||
}
|
||||
|
||||
void
|
||||
Renderer::handleEvent(const InputEvent& evt)
|
||||
{
|
||||
switch (evt.intent) {
|
||||
case InputEvent::PowerToggle:
|
||||
m_powerState = m_powerState.value() <= 128 ? 255 : 0;
|
||||
Log.notice("Power toggled to %t", m_powerState);
|
||||
break;
|
||||
case InputEvent::SetPower:
|
||||
m_powerState = evt.asInt() == 0 ? 0 : 255;
|
||||
Log.notice("Power state is now %t", m_powerState);
|
||||
break;
|
||||
case InputEvent::SetBrightness:
|
||||
m_brightness = evt.asInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
Renderer::powerScale(uint8_t target, uint32_t totalPower) const
|
||||
{
|
||||
if (m_powerManaged) {
|
||||
uint32_t requested = ((uint32_t)totalPower * target) / 256;
|
||||
if (requested > totalPower) {
|
||||
return (uint32_t)((uint8_t)(target) * (uint32_t)(totalPower)) / ((uint32_t)(requested));
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
void
|
||||
Renderer::onStart()
|
||||
{
|
||||
@ -50,3 +87,27 @@ Renderer::onStart()
|
||||
}
|
||||
FastLED.show();
|
||||
}
|
||||
|
||||
void
|
||||
Renderer::doOn(Args& args, Print& print)
|
||||
{}
|
||||
|
||||
void
|
||||
Renderer::doOff(Args& args, Print& print)
|
||||
{}
|
||||
|
||||
void
|
||||
Renderer::doBrightness(Args& args, Print& print)
|
||||
{}
|
||||
|
||||
const std::vector<Command>&
|
||||
Renderer::commands() const
|
||||
{
|
||||
static const std::vector<Command> _commands = {
|
||||
Command{"brightness", &Renderer::doBrightness},
|
||||
Command{"on", &Renderer::doOn},
|
||||
Command{"off", &Renderer::doOff}
|
||||
};
|
||||
|
||||
return _commands;
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
#include "./Figment.h"
|
||||
#include "./Animation.h"
|
||||
#include "./Input.h"
|
||||
#include <vector>
|
||||
|
||||
class Display;
|
||||
@ -9,10 +11,26 @@ public:
|
||||
|
||||
void loop() override;
|
||||
void onStart() override;
|
||||
void handleEvent(const InputEvent& evt) override;
|
||||
|
||||
static const char* lastFigmentName();
|
||||
|
||||
const std::vector<Command>& commands() const override;
|
||||
|
||||
private:
|
||||
const std::vector<Figment*> m_figments;
|
||||
const std::vector<Display*> m_displays;
|
||||
|
||||
AnimatedNumber m_powerState = 255;
|
||||
AnimatedNumber m_brightness = 255;
|
||||
bool m_powerManaged = true;
|
||||
|
||||
uint8_t m_voltage;
|
||||
uint8_t m_milliamps;
|
||||
|
||||
uint8_t powerScale(uint8_t target, uint32_t totalPower) const;
|
||||
|
||||
void doBrightness(Args& args, Print& print);
|
||||
void doOn(Args& args, Print& print);
|
||||
void doOff(Args& args, Print& print);
|
||||
};
|
||||
|
@ -1,52 +0,0 @@
|
||||
#include "./Power.h"
|
||||
#include "../Static.h"
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
void
|
||||
doBrightness(Args& args, Print& out)
|
||||
{
|
||||
String nextVal = args[1];
|
||||
uint8_t newBrightness = (uint8_t)atoi(nextVal.c_str());
|
||||
MainLoop::instance()->dispatch(InputEvent{InputEvent::SetBrightness, newBrightness});
|
||||
}
|
||||
|
||||
void
|
||||
doOn(Args& args, Print& out)
|
||||
{
|
||||
MainLoop::instance()->dispatch(InputEvent{InputEvent::SetPower, 255});
|
||||
}
|
||||
|
||||
void
|
||||
doOff(Args& args, Print& out)
|
||||
{
|
||||
MainLoop::instance()->dispatch(InputEvent{InputEvent::SetPower, 0});
|
||||
}
|
||||
|
||||
void
|
||||
doForceBrightness(Args& args, Print& out)
|
||||
{
|
||||
String nextVal = args[1];
|
||||
uint8_t newBrightness = (uint8_t)atoi(nextVal.c_str());
|
||||
Static<Power>::instance()->forceBrightness(newBrightness);
|
||||
}
|
||||
|
||||
void
|
||||
Power::handleConfigChange(const Configuration& config)
|
||||
{
|
||||
m_milliamps = config.get("power.milliamps", m_milliamps);
|
||||
m_voltage = config.get("power.volts", m_voltage);
|
||||
m_useBPM = config.get("power.useBPM", m_useBPM);
|
||||
|
||||
if (m_voltage == 0 || m_milliamps == 0) {
|
||||
Log.notice("power: Impossible power config: %dma @ %dv", m_milliamps, m_voltage);
|
||||
m_valid = false;
|
||||
} else {
|
||||
Log.notice("power: Configured to use %dma @ %dv", m_milliamps, m_voltage);
|
||||
m_valid = true;
|
||||
FastLED.setMaxPowerInVoltsAndMilliamps(m_voltage, m_milliamps);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STATIC_ALLOC(Power);
|
||||
STATIC_TASK(Power);
|
@ -1,65 +0,0 @@
|
||||
#pragma once
|
||||
#include <Figments.h>
|
||||
#include "../Config.h"
|
||||
|
||||
class Power: public Figment, ConfigTaskMixin {
|
||||
public:
|
||||
Power() : Figment("Power") {state = Task::Running;}
|
||||
|
||||
void handleEvent(const InputEvent& evt) override {
|
||||
switch (evt.intent) {
|
||||
case InputEvent::PowerToggle:
|
||||
m_powerState = m_powerState.value() <= 128 ? 255 : 0;
|
||||
m_forced = false;
|
||||
Log.notice("Power toggled to %t", m_powerState);
|
||||
break;
|
||||
case InputEvent::SetPower:
|
||||
m_powerState = evt.asInt() == 0 ? 0 : 255;
|
||||
m_forced = false;
|
||||
Log.notice("Power state is now %t", m_powerState);
|
||||
break;
|
||||
case InputEvent::SetBrightness:
|
||||
m_brightness = evt.asInt();
|
||||
m_forced = false;
|
||||
break;
|
||||
case InputEvent::Beat:
|
||||
m_beatDecay.set(0, 255);
|
||||
break;
|
||||
default:
|
||||
ConfigTaskMixin::handleEvent(evt);
|
||||
}
|
||||
}
|
||||
|
||||
void handleConfigChange(const Configuration& config) override;
|
||||
|
||||
void loop() override {
|
||||
ConfigTaskMixin::loop();
|
||||
m_powerState.update();
|
||||
m_brightness.update();
|
||||
EVERY_N_MILLISECONDS(20) {
|
||||
m_beatDecay.update(13);
|
||||
}
|
||||
}
|
||||
|
||||
void render(Display* dpy) const override {
|
||||
if (F_LIKELY(m_valid && !m_forced)) {
|
||||
const uint8_t decayedBrightness = scale8((uint8_t)m_brightness, m_useBPM ? ease8InOutCubic((uint8_t)m_beatDecay) : 255);
|
||||
const uint8_t clippedBrightness = std::min(decayedBrightness, (uint8_t)255);
|
||||
const uint8_t scaledBrightness = scale8(m_powerState, clippedBrightness);
|
||||
const uint8_t videoBrightness = brighten8_video(scaledBrightness);
|
||||
const uint8_t powerBrightness = calculate_max_brightness_for_power_mW(videoBrightness, m_voltage * m_milliamps);
|
||||
FastLED.setBrightness(powerBrightness);
|
||||
}
|
||||
}
|
||||
|
||||
void forceBrightness(uint8_t v);
|
||||
private:
|
||||
AnimatedNumber m_powerState = 255;
|
||||
AnimatedNumber m_brightness = 255;
|
||||
AnimatedNumber m_beatDecay = 255;
|
||||
uint8_t m_voltage = 5;
|
||||
uint16_t m_milliamps = 500;
|
||||
bool m_valid = true;
|
||||
bool m_useBPM = false;
|
||||
bool m_forced = false;
|
||||
};
|
Loading…
Reference in New Issue
Block a user