Metainformationen zur Seite
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen RevisionVorhergehende Überarbeitung | |||
| iobroker:countdown_script_fuer_vis1 [06.01.2026] – kolja | iobroker:countdown_script_fuer_vis1 [06.01.2026] (aktuell) – kolja | ||
|---|---|---|---|
| Zeile 53: | Zeile 53: | ||
| ⚠️ NICHT kürzen, NICHT umformatieren | ⚠️ NICHT kürzen, NICHT umformatieren | ||
| < | < | ||
| + | |||
| + | <!-- ========================================================== | ||
| + | VIS Subscribe-Block (Pflicht!) | ||
| + | Jede OID, die du unten nutzt, MUSS hier stehen. | ||
| + | | ||
| + | <div style=" | ||
| + | {countdown.0.countdowns.Weihnachten.fullJson} | ||
| + | {countdown.0.countdowns.Silvester.fullJson} | ||
| + | {countdown.0.countdowns.SommerurlaubItalien.fullJson} | ||
| + | </ | ||
| + | |||
| + | <div style=" | ||
| + | <div id=" | ||
| + | Lade... | ||
| + | </ | ||
| + | |||
| + | <div style=" | ||
| + | |||
| + | <div id=" | ||
| + | Lade... | ||
| + | </ | ||
| + | </ | ||
| < | < | ||
| Zeile 58: | Zeile 80: | ||
| { | { | ||
| /* ========================================================== | /* ========================================================== | ||
| - | | + | |
| | | ||
| - | |||
| - | const OID_1 = " | ||
| - | const OID_2 = " | ||
| - | const OID_3 = " | ||
| const EMPTY_TEXT = " | const EMPTY_TEXT = " | ||
| + | |||
| + | // Wenn TRUE: Stunden werden ausgeblendet, | ||
| + | // (für days === 1 werden Stunden weiterhin angezeigt) | ||
| + | const HIDE_HOURS_IF_MORE_THAN_ONE_DAY = true; | ||
| + | |||
| + | // Wieviele Events sind AKTIV konfiguriert (max 8) | ||
| + | const EVENT_COUNT = 3; | ||
| /* ========================================================== | /* ========================================================== | ||
| - | | + | EVENT-DEFINITIONEN |
| + | | ||
| + | 1 = Weihnachten (Speziallogik) | ||
| + | 2 = Silvester | ||
| + | 3 = Generisch | ||
| + | | ||
| + | |||
| + | // ---------------- Event 1 ---------------- | ||
| + | const E1_OID | ||
| + | const E1_TYPE | ||
| + | const E1_TITLE = ""; | ||
| + | const E1_EMOJI = ""; | ||
| + | |||
| + | // ---------------- Event 2 ---------------- | ||
| + | const E2_OID | ||
| + | const E2_TYPE | ||
| + | const E2_TITLE = ""; | ||
| + | const E2_EMOJI = ""; | ||
| + | |||
| + | // ---------------- Event 3 ---------------- | ||
| + | const E3_OID | ||
| + | const E3_TYPE | ||
| + | const E3_TITLE = " | ||
| + | const E3_EMOJI = " | ||
| + | |||
| + | // ---------------- Event 4..8 (Vorlagen) ---------------- | ||
| + | const E4_OID | ||
| + | const E4_TYPE | ||
| + | const E4_TITLE = ""; | ||
| + | const E4_EMOJI = ""; | ||
| + | |||
| + | const E5_OID | ||
| + | const E5_TYPE | ||
| + | const E5_TITLE = ""; | ||
| + | const E5_EMOJI = ""; | ||
| + | |||
| + | const E6_OID | ||
| + | const E6_TYPE | ||
| + | const E6_TITLE = ""; | ||
| + | const E6_EMOJI = ""; | ||
| + | |||
| + | const E7_OID | ||
| + | const E7_TYPE | ||
| + | const E7_TITLE = ""; | ||
| + | const E7_EMOJI = ""; | ||
| + | |||
| + | const E8_OID | ||
| + | const E8_TYPE | ||
| + | const E8_TITLE = ""; | ||
| + | const E8_EMOJI = ""; | ||
| + | |||
| + | /* ========================================================== | ||
| + | HILFSFUNKTIONEN | ||
| | | ||
| Zeile 74: | Zeile 151: | ||
| { | { | ||
| const n = Number(x); | const n = Number(x); | ||
| - | | + | |
| + | | ||
| + | { | ||
| + | | ||
| + | } | ||
| return fallback; | return fallback; | ||
| } | } | ||
| Zeile 80: | Zeile 162: | ||
| function parseFullJson(val) | function parseFullJson(val) | ||
| { | { | ||
| - | if (val === null || val === undefined || val === "" | + | if (val === null || val === undefined || val === "" |
| + | { | ||
| + | | ||
| + | } | ||
| try | try | ||
| Zeile 89: | Zeile 174: | ||
| { | { | ||
| t = t.trim(); | t = t.trim(); | ||
| - | | + | |
| + | | ||
| + | { | ||
| + | | ||
| + | } | ||
| return JSON.parse(t); | return JSON.parse(t); | ||
| } | } | ||
| Zeile 108: | Zeile 198: | ||
| function dayWord(n) | function dayWord(n) | ||
| { | { | ||
| - | if (n === 1) return " | + | if (n === 1) |
| + | { | ||
| + | | ||
| + | } | ||
| return " | return " | ||
| } | } | ||
| Zeile 114: | Zeile 208: | ||
| function hourWord(n) | function hourWord(n) | ||
| { | { | ||
| - | if (n === 1) return " | + | if (n === 1) |
| + | { | ||
| + | | ||
| + | } | ||
| return " | return " | ||
| } | } | ||
| /* ========================================================== | /* ========================================================== | ||
| - | | + | EVENT-ZUGRIFF (ohne Arrays/ |
| + | | ||
| + | |||
| + | function getOid(i) | ||
| + | { | ||
| + | if (i === 1) return E1_OID; | ||
| + | if (i === 2) return E2_OID; | ||
| + | if (i === 3) return E3_OID; | ||
| + | if (i === 4) return E4_OID; | ||
| + | if (i === 5) return E5_OID; | ||
| + | if (i === 6) return E6_OID; | ||
| + | if (i === 7) return E7_OID; | ||
| + | if (i === 8) return E8_OID; | ||
| + | |||
| + | return ""; | ||
| + | } | ||
| + | |||
| + | function getType(i) | ||
| + | { | ||
| + | if (i === 1) return E1_TYPE; | ||
| + | if (i === 2) return E2_TYPE; | ||
| + | if (i === 3) return E3_TYPE; | ||
| + | if (i === 4) return E4_TYPE; | ||
| + | if (i === 5) return E5_TYPE; | ||
| + | if (i === 6) return E6_TYPE; | ||
| + | if (i === 7) return E7_TYPE; | ||
| + | if (i === 8) return E8_TYPE; | ||
| + | |||
| + | return 0; | ||
| + | } | ||
| + | |||
| + | function getTitle(i) | ||
| + | { | ||
| + | if (i === 1) return E1_TITLE; | ||
| + | if (i === 2) return E2_TITLE; | ||
| + | if (i === 3) return E3_TITLE; | ||
| + | if (i === 4) return E4_TITLE; | ||
| + | if (i === 5) return E5_TITLE; | ||
| + | if (i === 6) return E6_TITLE; | ||
| + | if (i === 7) return E7_TITLE; | ||
| + | if (i === 8) return E8_TITLE; | ||
| + | |||
| + | return ""; | ||
| + | } | ||
| + | |||
| + | function getEmoji(i) | ||
| + | { | ||
| + | if (i === 1) return E1_EMOJI; | ||
| + | if (i === 2) return E2_EMOJI; | ||
| + | if (i === 3) return E3_EMOJI; | ||
| + | if (i === 4) return E4_EMOJI; | ||
| + | if (i === 5) return E5_EMOJI; | ||
| + | if (i === 6) return E6_EMOJI; | ||
| + | if (i === 7) return E7_EMOJI; | ||
| + | if (i === 8) return E8_EMOJI; | ||
| + | |||
| + | return ""; | ||
| + | } | ||
| + | |||
| + | /* ========================================================== | ||
| + | RESTZEIT | ||
| | | ||
| Zeile 125: | Zeile 283: | ||
| { | { | ||
| const d = parseFullJson(val); | const d = parseFullJson(val); | ||
| - | | + | |
| + | | ||
| + | { | ||
| + | | ||
| + | } | ||
| if (d.total && d.total.seconds !== undefined) | if (d.total && d.total.seconds !== undefined) | ||
| Zeile 142: | Zeile 304: | ||
| function isExpired(val) | function isExpired(val) | ||
| { | { | ||
| - | return remainingSeconds(val) <= 0; | + | return |
| } | } | ||
| /* ========================================================== | /* ========================================================== | ||
| - | RENDER-FUNKTIONEN | + | FORMATTER: Zeittext mit optionalen Stunden |
| + | ---------------------------------------------------------- | ||
| + | Gibt nur den " | ||
| + | - "3 Tagen" (wenn days>1 und hideHours aktiv) | ||
| + | - "1 Tag und 5 Stunden" | ||
| + | | ||
| + | |||
| + | function formatDaysHours(days, | ||
| + | { | ||
| + | // Wenn konfiguriert: | ||
| + | if (HIDE_HOURS_IF_MORE_THAN_ONE_DAY) | ||
| + | { | ||
| + | if (days > 1) | ||
| + | { | ||
| + | return String(days) + " " + dayWord(days); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // Standard: Tage + Stunden | ||
| + | return String(days) + " " + dayWord(days) + " und " + String(hours) + " " + hourWord(hours); | ||
| + | } | ||
| + | |||
| + | /* ========================================================== | ||
| + | | ||
| | | ||
| Zeile 159: | Zeile 344: | ||
| } | } | ||
| - | if (!data) return EMPTY_TEXT; | + | if (!data) |
| + | { | ||
| + | | ||
| + | } | ||
| - | const days = safeNum(data.total.days, | + | const days = safeNum((data.total |
| - | const hours = safeNum(data.total.hours, | + | const hours = safeNum((data.hours !== undefined) ? data.hours : (data.total ? data.total.hours |
| + | const words = (data.inWords && data.inWords.long) ? data.inWords.long : ""; | ||
| + | |||
| + | if (now.getMonth() === 11 && now.getDate() === 23) | ||
| + | { | ||
| + | return "🎅 Weihnachten morgen" | ||
| + | } | ||
| + | |||
| + | if (days >= 1) | ||
| + | { | ||
| + | return "🎁 Weihnachten in " + formatDaysHours(days, | ||
| + | } | ||
| - | return "🎁 Weihnachten | + | return "🎄 Frohe Weihnachten |
| - | " | + | |
| } | } | ||
| Zeile 178: | Zeile 376: | ||
| } | } | ||
| - | if (!data) return | + | if (now.getMonth() === 0 && now.getDate() === 1) |
| + | { | ||
| + | | ||
| + | } | ||
| - | | + | |
| - | | + | { |
| + | return EMPTY_TEXT; | ||
| + | | ||
| - | return "🕛 Silvester | + | |
| - | | + | const hours = safeNum((data.hours !== undefined) ? data.hours : (data.total ? data.total.hours : undefined), 0); |
| + | const words = (data.inWords && data.inWords.long) ? data.inWords.long : ""; | ||
| + | |||
| + | if (now.getMonth() === 11 && now.getDate() === 30) | ||
| + | { | ||
| + | | ||
| + | } | ||
| + | |||
| + | if (days >= 1) | ||
| + | { | ||
| + | return | ||
| + | } | ||
| + | |||
| + | return | ||
| } | } | ||
| Zeile 190: | Zeile 406: | ||
| { | { | ||
| const data = parseFullJson(val); | const data = parseFullJson(val); | ||
| - | if (!data) return EMPTY_TEXT; | ||
| - | | + | |
| - | | + | { |
| + | return EMPTY_TEXT; | ||
| + | | ||
| - | | + | |
| - | " und " + hours + " " + hourWord(hours); | + | |
| - | } | + | const words = (data.inWords && data.inWords.long) ? data.inWords.long : ""; |
| - | /* ========================================================== | + | if (days === 1) |
| - | EVENTS | + | { |
| - | ========================================================== */ | + | return emoji + " " + title + " morgen" |
| + | } | ||
| - | const E1_OID | + | if (days >= 1) |
| - | const E2_OID = OID_2; | + | { |
| - | const E3_OID = OID_3; | + | return emoji + " " + title + " in " + formatDaysHours(days, |
| + | } | ||
| + | |||
| + | if (words) | ||
| + | { | ||
| + | return emoji + " " + title + subline(words); | ||
| + | } | ||
| + | |||
| + | return emoji + " " + title + " bald"; | ||
| + | } | ||
| - | function | + | function |
| { | { | ||
| - | | + | |
| - | if (i === 2) return renderSilvester(val); | + | |
| - | | + | if (t === 1) |
| - | return EMPTY_TEXT; | + | { |
| + | | ||
| + | } | ||
| + | |||
| + | if (t === 2) | ||
| + | { | ||
| + | | ||
| + | | ||
| + | |||
| + | | ||
| } | } | ||
| - | function | + | |
| + | | ||
| + | | ||
| + | |||
| + | | ||
| { | { | ||
| - | let b1 = -1; | + | let best1_i |
| - | let b2 = -1; | + | let best1_r |
| - | let r1 = 999999999; | + | |
| - | let r2 = 999999999; | + | |
| - | let r; | + | let best2_i = -1; |
| + | let best2_r = 999999999; | ||
| - | | + | |
| - | | + | |
| + | | ||
| { | { | ||
| - | | + | |
| - | | + | |
| + | if (oid) | ||
| + | { | ||
| + | const val = vis.states.attr(oid + " | ||
| + | |||
| + | if (!isExpired(val)) | ||
| + | { | ||
| + | const r = remainingSeconds(val); | ||
| + | |||
| + | if (r < best1_r) | ||
| + | { | ||
| + | best2_i = best1_i; | ||
| + | best2_r = best1_r; | ||
| + | |||
| + | best1_i = i; | ||
| + | best1_r = r; | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | if (r < best2_r) | ||
| + | { | ||
| + | best2_i = i; | ||
| + | best2_r = r; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | i = i + 1; | ||
| } | } | ||
| - | | + | |
| - | | + | } |
| + | |||
| + | function renderSlot(slotIndex, el) | ||
| + | { | ||
| + | const picks = pickTwoUpcoming().split("|"); | ||
| + | let idx = -1; | ||
| + | |||
| + | if (slotIndex === 1) | ||
| { | { | ||
| - | | + | |
| - | | + | } |
| + | else | ||
| + | { | ||
| + | | ||
| } | } | ||
| - | | + | if (idx < 1) |
| - | | + | |
| { | { | ||
| - | | + | |
| + | return; | ||
| } | } | ||
| - | | + | |
| + | const val = vis.states.attr(oid | ||
| + | |||
| + | el.innerHTML = renderByIndex(idx, val); | ||
| } | } | ||
| + | |||
| + | /* ========================================================== | ||
| + | START & BINDING | ||
| + | | ||
| function start() | function start() | ||
| Zeile 252: | Zeile 537: | ||
| const el2 = document.getElementById(" | const el2 = document.getElementById(" | ||
| - | | + | |
| { | { | ||
| - | | + | |
| + | { | ||
| + | renderSlot(1, el1); | ||
| + | } | ||
| - | | + | |
| - | | + | |
| + | renderSlot(2, el2); | ||
| + | } | ||
| - | | + | |
| - | | + | if (E2_OID) vis.states.bind(E2_OID + " |
| - | } | + | |
| + | if (E4_OID) vis.states.bind(E4_OID + " | ||
| + | if (E5_OID) vis.states.bind(E5_OID + " | ||
| + | if (E6_OID) vis.states.bind(E6_OID + " | ||
| + | if (E7_OID) vis.states.bind(E7_OID + " | ||
| + | if (E8_OID) vis.states.bind(E8_OID + " | ||
| - | | + | if (E1_OID) |
| - | vis.states.bind(E2_OID + " | + | if (E2_OID) |
| - | vis.states.bind(E3_OID + " | + | if (E3_OID) |
| + | if (E4_OID) vis.states.bind(E4_OID + " | ||
| + | if (E5_OID) vis.states.bind(E5_OID + " | ||
| + | if (E6_OID) vis.states.bind(E6_OID + " | ||
| + | if (E7_OID) vis.states.bind(E7_OID + " | ||
| + | if (E8_OID) vis.states.bind(E8_OID + " | ||
| - | update(); | + | updateSlot1(); |
| + | updateSlot2(); | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | setTimeout(start, | ||
| + | } | ||
| } | } | ||
| Zeile 281: | Zeile 587: | ||
| })(); | })(); | ||
| </ | </ | ||
| + | |||
| </ | </ | ||