Public Access
Plex page: play/pause state and progress per stream
The EL512 Plex streams sensor now reads the Plex media players (media_player.plex_*) every 5 s: who, title, playing/paused, position and duration, falling back to the server sensor's list without them. The Plex page shows a play/pause icon, position / duration and a thin progress bar per stream (dotted while paused), counting on between updates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1e8a9a5958
commit
921a4c3aa6
2 files changed
+71
-7
No files matched your search
@@ -62,6 +62,9 @@ globals:
|
||||
- id: np_updated
|
||||
type: uint32_t
|
||||
initial_value: "0"
|
||||
- id: plex_updated
|
||||
type: uint32_t
|
||||
initial_value: "0"
|
||||
# Themed pages (Cyberpunk, KonoSuba, Steins;Gate): their fonts and the home data they show.
|
||||
- id: cp_fonts
|
||||
type: el512::cyber::Fonts
|
||||
@@ -141,6 +144,8 @@ font:
|
||||
size: 18
|
||||
glyphs:
|
||||
- "\U000F054B" # umbrella-outline
|
||||
- "\U000F040A" # play
|
||||
- "\U000F03E4" # pause
|
||||
# Cyberpunk pages
|
||||
- file: "gfonts://Orbitron@700"
|
||||
id: f_cp_title
|
||||
@@ -238,6 +243,8 @@ text_sensor:
|
||||
id: plex_streams
|
||||
entity_id: sensor.el512_plex_streams
|
||||
attribute: streams
|
||||
on_value:
|
||||
- lambda: id(plex_updated) = millis();
|
||||
- platform: homeassistant
|
||||
id: plex_update
|
||||
entity_id: update.plex_media_server_mangavalkserver
|
||||
@@ -686,11 +693,43 @@ display:
|
||||
it.print(326, 140, id(f_m), TextAlign::CENTER, online ? "Nobody is watching" : "Server offline");
|
||||
return;
|
||||
}
|
||||
// Per stream: play/pause, who, time, title and a progress bar
|
||||
// (who|title|state|pos|dur; the server-sensor fallback has no state).
|
||||
int y = 50;
|
||||
for (auto &s : streams) {
|
||||
if (y > 256 - 48) break;
|
||||
it.print(152, y, id(f_s), TextAlign::TOP_LEFT, el512::fit(id(f_s), el512::field(s, 0), 352).c_str());
|
||||
it.print(152, y + 18, id(f_m), TextAlign::TOP_LEFT, el512::fit(id(f_m), el512::field(s, 1), 352).c_str());
|
||||
auto f = el512::split(s, '|');
|
||||
f.resize(5);
|
||||
const bool playing = f[2] == "playing", paused = f[2] == "paused";
|
||||
const int dur = atoi(f[4].c_str());
|
||||
int pos = atoi(f[3].c_str());
|
||||
if (playing) pos += (int) ((millis() - id(plex_updated)) / 1000);
|
||||
pos = std::min(pos, dur);
|
||||
int x = 152;
|
||||
if (playing || paused) {
|
||||
it.print(150, y - 1, id(icons_s), TextAlign::TOP_LEFT, paused ? "\U000F03E4" : "\U000F040A");
|
||||
x = 172;
|
||||
}
|
||||
std::string when;
|
||||
if (dur > 0) when = el512::mmss(pos) + " / " + el512::mmss(dur);
|
||||
int tw = 0, tx, ty, th;
|
||||
if (!when.empty()) {
|
||||
it.get_text_bounds(0, 0, when.c_str(), id(f_s), TextAlign::TOP_LEFT, &tx, &ty, &tw, &th);
|
||||
it.print(504, y, id(f_s), TextAlign::TOP_RIGHT, when.c_str());
|
||||
}
|
||||
it.print(x, y, id(f_s), TextAlign::TOP_LEFT, el512::fit(id(f_s), f[0], 504 - x - tw - 10).c_str());
|
||||
it.print(152, y + 17, id(f_m), TextAlign::TOP_LEFT, el512::fit(id(f_m), f[1], 352).c_str());
|
||||
if (dur > 0) {
|
||||
const int w = 352 * pos / dur;
|
||||
if (paused) {
|
||||
// Paused: hollow bar with a dotted fill.
|
||||
it.rectangle(152, y + 42, 352, 5);
|
||||
for (int px = 154; px < 152 + w; px += 2) it.draw_pixel_at(px, y + 44);
|
||||
} else {
|
||||
it.horizontal_line(152, y + 44, 352);
|
||||
it.filled_rectangle(152, y + 42, w, 5);
|
||||
}
|
||||
}
|
||||
y += 50;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user