ioBroker-Skripte/AWTRIX Now Playing Sonos/ioBroker_awtrix_sonos_NowPlaying.js aktualisiert

Version 0.0.2
This commit is contained in:
2026-01-03 13:04:10 +00:00
parent 095564bef1
commit 7ff6e34f67

View File

@@ -1,9 +1,9 @@
/****************************************************** /******************************************************
* AWTRIX NowPlaying Sonos → AWTRIX Custom App * AWTRIX NowPlaying Sonos → AWTRIX Custom App
* Version 0.0.1 * Version 0.0.2
* Autor: Mike * Autor: Mike
* Zweck: Zeigt "🎵 Künstler — Titel (Album)" auf der AWTRIX * Zweck: Zeigt "🎵 Künstler — Titel (Album)" auf der AWTRIX
* Trigger: Änderungen an Sonos-Datenpunkten (Titel/Artist/Album) * Trigger: Änderungen an Sonos-Datenpunkten (Titel/Artist/Album/State)
******************************************************/ ******************************************************/
/*********** Einstellungen ***********/ /*********** Einstellungen ***********/
@@ -23,7 +23,8 @@ const TEXT_CASE = 2;
const DP = { const DP = {
title: "sonos.0.root.192_168_178_75.current_title", title: "sonos.0.root.192_168_178_75.current_title",
artist: "sonos.0.root.192_168_178_75.current_artist", artist: "sonos.0.root.192_168_178_75.current_artist",
album: "sonos.0.root.192_168_178_75.current_album" album: "sonos.0.root.192_168_178_75.current_album",
stateSimple: "sonos.0.root.192_168_178_75.state_simple" // true = spielt, false = kein Playback
}; };
/*************************************/ /*************************************/
@@ -33,6 +34,16 @@ function readVal(id) {
return st ? (st.val ?? "") : ""; return st ? (st.val ?? "") : "";
} }
function readBool(id) {
const st = getState(id);
return st ? !!st.val : false;
}
function isPlaying() {
// state_simple ist bereits Boolean: true = Wiedergabe
return readBool(DP.stateSimple);
}
function buildText(artist, title, album) { function buildText(artist, title, album) {
let base = ""; let base = "";
if (artist && title) base = `${artist}${title}`; if (artist && title) base = `${artist}${title}`;
@@ -44,7 +55,6 @@ function buildText(artist, title, album) {
} }
function sendMQTT(topic, payloadObj) { function sendMQTT(topic, payloadObj) {
// ioBroker als Broker → sendMessage2Client
sendTo(MQTT_INSTANCE, "sendMessage2Client", { sendTo(MQTT_INSTANCE, "sendMessage2Client", {
topic, topic,
message: JSON.stringify(payloadObj), message: JSON.stringify(payloadObj),
@@ -68,7 +78,7 @@ function publishCustom(text) {
function removeApp() { function removeApp() {
sendMQTT(`${AWTRIX_PREFIX}/custom/${APP_NAME}`, { name: APP_NAME, lifetime: 1 }); sendMQTT(`${AWTRIX_PREFIX}/custom/${APP_NAME}`, { name: APP_NAME, lifetime: 1 });
log("🛑 NowPlaying entfernt (keine Titelinfos)"); log("🛑 NowPlaying entfernt (kein Playback)");
} }
/*********** Kernlogik ***********/ /*********** Kernlogik ***********/
@@ -85,18 +95,22 @@ function stopKeepAlive() {
function startKeepAlive(text) { function startKeepAlive(text) {
stopKeepAlive(); stopKeepAlive();
// Erster Push sofort (sichtbar machen) // Erster Push sofort (sichtbar machen)
publishCustom(text); publishCustom(text);
// … und dann regelmäßig solange Titel vorhanden ist
// … und dann regelmäßig solange Titel vorhanden UND Playback aktiv
keepAliveTmr = setInterval(() => { keepAliveTmr = setInterval(() => {
// Wenn Titel leer geworden ist, sofort stoppen und App entfernen
const t = String(readVal(DP.title)).trim(); const t = String(readVal(DP.title)).trim();
if (!t) { const playing = isPlaying();
// Wenn kein Titel oder nicht mehr playing → sofort stoppen und App entfernen
if (!t || !playing) {
stopKeepAlive(); stopKeepAlive();
currentSig = ""; currentSig = "";
removeApp(); removeApp();
return; return;
} }
publishCustom(text); publishCustom(text);
}, KEEPALIVE_SEC * 1000); }, KEEPALIVE_SEC * 1000);
} }
@@ -105,9 +119,10 @@ function updateAwtrix() {
const title = String(readVal(DP.title)).trim(); const title = String(readVal(DP.title)).trim();
const artist = String(readVal(DP.artist)).trim(); const artist = String(readVal(DP.artist)).trim();
const album = String(readVal(DP.album)).trim(); const album = String(readVal(DP.album)).trim();
const playing = isPlaying();
// Kein Lied → alles aus // Kein Lied ODER Player nicht im Play-Status → alles aus
if (!title && !artist && !album) { if ((!title && !artist && !album) || !playing) {
stopKeepAlive(); stopKeepAlive();
if (currentSig) removeApp(); if (currentSig) removeApp();
currentSig = ""; currentSig = "";
@@ -122,8 +137,6 @@ function updateAwtrix() {
currentSig = sig; currentSig = sig;
log(`🎧 NowPlaying → ${text}`); log(`🎧 NowPlaying → ${text}`);
startKeepAlive(text); startKeepAlive(text);
} else {
// Gleicher Track: nichts weiter Keep-Alive tickt von selbst
} }
} }
@@ -133,7 +146,8 @@ function scheduleUpdate() {
debounceTmr = setTimeout(updateAwtrix, 200); debounceTmr = setTimeout(updateAwtrix, 200);
} }
on({ id: [DP.title, DP.artist, DP.album], change: "ne" }, scheduleUpdate); // Triggert jetzt auch auf state_simple
on({ id: [DP.title, DP.artist, DP.album, DP.stateSimple], change: "ne" }, scheduleUpdate);
// Beim Start einmal versuchen // Beim Start einmal versuchen
setTimeout(updateAwtrix, 1500); setTimeout(updateAwtrix, 1500);