Ich hänge mich hier mal dran, wenn dir @hirschbrat das nicht gefällt, dann müsste ein Mod meinen Beitrag abtrennen.
Da ich IPSview nutze, ist die Anzeige von Kacheln nicht möglich, die Variablen aus den Modulen lassen sich zwar in eine View einbauen, aber die Sortierung gibt es nicht.
Also habe ich mich mal mit copilot und meinen Wissen auseinandergesetzt und folgendes gebaut.
Das obere sind einfach zwei Felder, die die Aufgabe anzeigen bzw. nach Bestätigung halt nicht mehr. Das nutze ich auch zur Hervorhebung in meinem Menü
um direkt zu sehen, das da etwas ansteht.
Das untere ist eine HTML Tabelle, die sehr flexibel Farben und Größen anpassbar verwendet.
Außerdem gibt es noch eine “Card”, die den nächsten Termin anzeigt, die ich in meiner Kopfzeile verwende

Der rote Badge “atmet” jeweils ein bischen, damit er noch auffälliger ist.
Das Script legt die Variablen für die Ausgaben unterhalb von sich selber an, sie können dann direkt in IPSview verwendet werden.
Es müssen nur die IDs aus diesem Modul oben gepflegt werden.
<?php
$parent = $_IPS['SELF']; // Variablen unterhalb des Skripts anlegen
// Werte laden
$blau = GetValue(21551);
$gelb = GetValue(50332);
$braun = GetValue(25508);
$grau = GetValue(22243);
$blau_date = GetValue(57435);
$gelb_date = GetValue(51344);
$braun_date = GetValue(14391);
$grau_date = GetValue(43486);
// Array mit CSS-Klassen
$MinKey = [
["wert"=>$grau, "datum"=>$grau_date, "css"=>"icon--gray", "label"=>"Restabfall"],
["wert"=>$gelb, "datum"=>$gelb_date, "css"=>"icon--yellow","label"=>"Leichtverpackungen"],
["wert"=>$blau, "datum"=>$blau_date, "css"=>"icon--blue", "label"=>"Papier"],
["wert"=>$braun, "datum"=>$braun_date, "css"=>"icon--brown", "label"=>"Bioabfall"]
];
// Sortieren nach Wert
usort($MinKey, fn($a, $b) => $a["wert"] <=> $b["wert"]);
$next = $MinKey[0]; // nächste Abholung
// Badge Funktion
function getBadge($wert) {
if ($wert == 0) return ['red', 'Heute'];
if ($wert == 1) return ['red', 'Morgen'];
if ($wert == 2) return ['yellow', 'Übermorgen'];
$einheit = ($wert == 1) ? 'Tag' : 'Tagen';
return ['green', "in $wert $einheit"];
}
// Tabellenzeile erzeugen
function renderRow($item) {
list($badgeClass, $badgeText) = getBadge($item["wert"]);
$dateFormatted = date("d.m.Y", $item["datum"]);
return "
<tr>
<td><svg class='icon {$item["css"]}'><use href='#icon-waste'></use></svg></td>
<td>{$item["label"]}</td>
<td>{$dateFormatted}</td>
<td><div class='badge {$badgeClass}'>{$badgeText}</div></td>
</tr>
";
}
//
// ------------------------------------------------------------
// HTML-KOPF
// ------------------------------------------------------------
//
$HTML_KOPF = "
<!DOCTYPE html>
<html lang='de'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<style>
:root {
--font-base: 1em;
--font-small: 0.85em;
--font-large: 1.2em;
/* Tabellen-Schriftgrößen */
--table-font: 1.2em;
--table-font-small: 1.0em;
/* CardNext Größe */
--card-size: 92px;
--icon-size: 56px;
/* Badge Farben */
--badge-green: #008000;
--badge-orange: #FF8000;
--badge-red: #FF0000;
/* Icon Farben */
--icon-gray: #666666;
--icon-yellow: #FFFF00;
--icon-blue: #0080ff;
--icon-brown: #8B4513;
}
body {
background:black;
color:white;
font-family: Arial;
font-size: var(--font-base);
margin:0;
padding:0;
}
/* Tabelle */
table.muell {
border-collapse: collapse;
width: 100%;
font-size: var(--table-font);
}
.muell th, .muell td {
padding: 6px;
vertical-align: middle;
text-align: left;
font-size: var(--table-font-small);
}
.muell tr {
border-bottom: 1px solid rgba(255,255,255,0.25);
}
.tr4 tr > :nth-child(4) {
text-align: right;
}
/* Badge (Tabelle) */
.badge {
border-radius: 5px;
min-width: 100px;
text-align: center;
float: right;
color: white;
padding: 4px 8px;
}
.badge.green { background-color: var(--badge-green); }
.badge.yellow { background-color: var(--badge-orange); }
.badge.red { background-color: var(--badge-red); }
/* Icons */
.icon { width: 32px; height: 32px; fill: currentColor; }
.icon--gray { color: var(--icon-gray); }
.icon--yellow{ color: var(--icon-yellow); }
.icon--blue { color: var(--icon-blue); }
.icon--brown { color: var(--icon-brown); }
/* CardNext */
.cardNext {
width: var(--card-size);
height: var(--card-size);
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
text-align: center;
overflow: hidden;
}
.cardNext .icon {
width: var(--icon-size);
height: var(--icon-size);
margin-top: 4px;
}
.cardNext-text {
font-size: var(--font-small);
font-weight: bold;
margin-bottom: 12px;
}
/* CardNext Badge-Farben */
.cardNext-text.green { color: var(--badge-green); }
.cardNext-text.yellow { color: var(--badge-orange); }
.cardNext-text.red { color: var(--badge-red); }
/* Pulsieren für Morgen */
.red {
animation: pulse 1.4s ease-in-out infinite;
}
@keyframes pulse {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.12); opacity: 0.85; }
100% { transform: scale(1); opacity: 1; }
}
.hidden { width:0; height:0; position:absolute; }
</style>
</head>
<body>
";
//
// ------------------------------------------------------------
// HTML-FUSS
// ------------------------------------------------------------
//
$HTML_FUSS = "
<svg xmlns='http://www.w3.org/2000/svg' class='hidden'>
<symbol id='icon-waste' viewBox='0 0 24 24'>
<path d='M3 6.386c0-.484.345-.877.771-.877h2.664c.529-.016.996-.399 1.176-.965l.115-.392c.07-.24.131-.449.217-.636.338-.739.964-1.252 1.687-1.383.183-.033.377-.033.599-.033h3.478c.223 0 .417 0 .6.033.723.131 1.349.644 1.687 1.383.086.187.147.396.217.636l.115.392c.18.566.739.949 1.268.965h2.572c.426 0 .771.393.771.877s-.345.877-.771.877H3.771C3.345 7.263 3 6.87 3 6.386z'/>
<path fill-rule='evenodd' clip-rule='evenodd' d='M11.596 22h.809c2.783 0 4.174 0 5.079-.886.905-.886.998-2.339 1.183-5.245l.267-4.188c.1-1.577.15-2.366-.304-2.865-.454-.5-1.22-.5-2.753-.5H8.124c-1.533 0-2.299 0-2.753.5-.454.499-.404 1.288-.304 2.865l.267 4.188c.185 2.906.278 4.359 1.183 5.245C7.421 22 8.813 22 11.596 22zm-1.35-9.811c-.041-.434-.408-.751-.82-.707-.412.043-.713.43-.671.864l.5 5.263c.041.434.409.751.821.707.412-.043.713-.430.671-.864l-.501-5.263zm4.328-.707c.412.043.713.430.671.864l-.5 5.263c-.041.434-.409.751-.821.707-.412-.043-.713-.430-.671-.864l.501-5.263c.041-.434.409-.751.821-.707z'/>
</symbol>
</svg>
</body>
</html>
";
//
// ------------------------------------------------------------
// TABELLEN-HTML
// ------------------------------------------------------------
//
$HTML_TABLE = "
<div class='cardL'>
<table class='muell tr4'>
<thead>
<tr>
<th></th>
<th>Abfuhr</th>
<th>Termin</th>
<th>Abholung</th>
</tr>
</thead>
<tbody>
";
foreach ($MinKey as $item) {
$HTML_TABLE .= renderRow($item);
}
$HTML_TABLE .= "
</tbody>
</table>
</div>
";
SetValue(
CreateVariableByIdent($parent, "html_table", "HTML Tabelle", 3, 10),
$HTML_KOPF . $HTML_TABLE . $HTML_FUSS
);
//
// ------------------------------------------------------------
// CARD-NEXT HTML
// ------------------------------------------------------------
//
list($badgeClass, $badgeText) = getBadge($next["wert"]);
$HTML_CARD = "
<div class='cardNext'>
<svg class='icon {$next["css"]}'><use href='#icon-waste'></use></svg>
<div class='cardNext-text {$badgeClass}'>{$badgeText}</div>
</div>
";
SetValue(
CreateVariableByIdent($parent, "html_card", "HTML CardNext", 3, 20),
$HTML_KOPF . $HTML_CARD . $HTML_FUSS
);
//
// ------------------------------------------------------------
// BENACHRICHTIGUNG
// ------------------------------------------------------------
//
$message = "";
foreach ($MinKey as $item) {
if ($item["wert"] == 1) {
$abholung = $item["label"];
$datum = date("d.m.Y", $item["datum"]);
$message = "$abholung rausstellen, Abholung am $datum";
SetValue(
CreateVariableByIdent($parent, "message_active", "Meldung anzeigen", 0, 40),
($message != "")
);
}
}
SetValue(
CreateVariableByIdent($parent, "message", "Meldung", 3, 30),
$message
);
//
// ------------------------------------------------------------
// Variablen ID holen bzw. Variable anlegen, falls noch nicht vorhanden
// ------------------------------------------------------------
//
function CreateVariableByIdent($parent, $ident, $name, $type, $position)
{
$vid = @IPS_GetObjectIDByIdent($ident, $parent);
if ($vid === false) {
$vid = IPS_CreateVariable($type);
IPS_SetParent($vid, $parent);
IPS_SetName($vid, $name);
IPS_SetIdent($vid, $ident);
IPS_SetPosition($vid, $position);
}
return $vid;
}
Das Scipt sollte ein Ergbnis bekommen, bei Aktualisierung einer der Variablen aus diesem Modul
damit die Variablen vom Script korrekt aktualisiert werden.
Ich nutze auch noch ein einfaches Script, das mir täglich um 17:30 eine Mail schickt, falls eine “Meldung” vorhanden ist. Also viel “Alarm” einen Tag vorher, damit ich keine Tonne vergesse.
Die verwendeten SVGs sind aus dem Modul [Modul] Abfallwirtschaft - Awido, Abfall+, Regio IT, MyMüll, MüllMax, ICS von @pitti .
Danke an euch beide, für die Basis, dadurch konnte ich mit etwas Unterstützung durch copilot das Script deutlich umfangreicher gestalten. Meine anderen Ausgaben sind meist deutlich primitiver.


