Public Access
Add four Steins;Gate pages; shuffle the page rotation hourly
Divergence meter (Nixie tubes, world lines and clock), a D-mail sent through the Phone Microwave using the panel's Message text, the Future Gadget Lab inventory with live sensors, and a world line chart of today's solar power. Original pixel art in tools/steins_sprites.py; the sprite tool is shared between themes and Sprite, sprite(), polar() and arc() move to el512_pages.h. HomeData gains the message and a 24 h solar history in 15-minute slots. The rotation now walks all pages in a random order that is reshuffled every hour (Still Alive stays out, Now playing is skipped when idle). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e9b91c5628
commit
1e8a9a5958
11 files changed
+1057
-76
No files matched your search
@@ -2,6 +2,7 @@
|
||||
// Home Assistant values they show, and small drawing helpers.
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <cstdarg>
|
||||
@@ -10,6 +11,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "esphome/components/display/display.h"
|
||||
#include "esphome/core/time.h"
|
||||
|
||||
namespace esphome::el512 {
|
||||
|
||||
@@ -30,7 +32,38 @@ struct HomeData {
|
||||
float house{NAN}; // W
|
||||
float grid{NAN}; // W, > 0 = import
|
||||
std::string agenda; // sensor.el512_agenda events: "day|time|title;..."
|
||||
std::string message; // the panel's Message text
|
||||
Reading rooms[4];
|
||||
|
||||
// Today's solar power in 15-minute slots (highest value seen per slot; -1 =
|
||||
// no data yet). Fed by record(), once a second from YAML.
|
||||
static constexpr int SLOTS = 96;
|
||||
float solar_slots[SLOTS];
|
||||
int slots_day{-1};
|
||||
|
||||
HomeData() {
|
||||
for (auto &s : this->solar_slots)
|
||||
s = -1;
|
||||
}
|
||||
void record(ESPTime now) {
|
||||
if (!now.is_valid())
|
||||
return;
|
||||
if (now.day_of_year != this->slots_day) {
|
||||
this->slots_day = now.day_of_year;
|
||||
for (auto &s : this->solar_slots)
|
||||
s = -1;
|
||||
}
|
||||
float &slot = this->solar_slots[now.hour * 4 + now.minute / 15];
|
||||
if (!std::isnan(this->solar))
|
||||
slot = std::max(slot, this->solar);
|
||||
}
|
||||
};
|
||||
|
||||
// 1-bit sprite: rows of '#' (lit) and anything else (dark). Generated by the
|
||||
// tools/*_sprites.py files.
|
||||
struct Sprite {
|
||||
uint8_t w, h;
|
||||
const char *const *rows;
|
||||
};
|
||||
|
||||
namespace fx {
|
||||
@@ -68,5 +101,42 @@ inline int text_width(display::Display &it, display::BaseFont *font, const char
|
||||
return w;
|
||||
}
|
||||
|
||||
// Draw a sprite (optionally only its first `rows` rows), scaled up in blocks.
|
||||
inline void sprite(display::Display &it, const Sprite &s, int x, int y, int scale = 1, int rows = -1,
|
||||
Color color = display::COLOR_ON) {
|
||||
const int h = rows < 0 ? s.h : std::min<int>(rows, s.h);
|
||||
for (int r = 0; r < h; r++) {
|
||||
for (int c = 0; c < s.w; c++) {
|
||||
if (s.rows[r][c] != '#')
|
||||
continue;
|
||||
if (scale == 1)
|
||||
it.draw_pixel_at(x + c, y + r, color);
|
||||
else
|
||||
it.filled_rectangle(x + c * scale, y + r * scale, scale, scale, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Point on a circle; angle in degrees, 0 = up, clockwise.
|
||||
inline void polar(int cx, int cy, float r, float a, int *x, int *y) {
|
||||
constexpr float DEG = 3.14159265f / 180.0f;
|
||||
*x = cx + (int) std::lround(r * std::sin(a * DEG));
|
||||
*y = cy - (int) std::lround(r * std::cos(a * DEG));
|
||||
}
|
||||
|
||||
// Circular arc from angle a0 to a1 (degrees, as polar()).
|
||||
inline void arc(display::Display &it, int cx, int cy, float r, float a0, float a1) {
|
||||
const int steps = std::max(2, (int) (std::fabs(a1 - a0) / 5));
|
||||
int px, py;
|
||||
polar(cx, cy, r, a0, &px, &py);
|
||||
for (int i = 1; i <= steps; i++) {
|
||||
int nx, ny;
|
||||
polar(cx, cy, r, a0 + (a1 - a0) * i / steps, &nx, &ny);
|
||||
it.line(px, py, nx, ny);
|
||||
px = nx;
|
||||
py = ny;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace fx
|
||||
} // namespace esphome::el512
|
||||
Reference in new issue
Block a user