#a2f740 — Public Fediverse posts
Live and recent posts from across the Fediverse tagged #a2f740, aggregated by home.social.
-
Für unser Sagiri-Infoterminal haben wir uns ein kleines Feature überlegt: die „Wetter-Ami“.
In charmanter Anlehnung an den klassischen „Wetter-Willi“ bekannter Heim-Wetterstationen zeigt unsere kleine Figur das aktuelle Wetter an, indem sie sich passend zur Temperatur kleidet.
Ursprünglich reichte unsere Skala von klirrenden -10 °C (Ami dick eingepackt im Schnee-Overall) bis hin zu sommerlichen 30 °C (Ami als fröhlicher Nacktspatz).
Doch dann knackten wir vor ein paar Wochen plötzlich die 35-Grad-Marke.
Das brachte uns ins Grübeln: Wie visualisiert man eine noch größere Hitze, wenn das Maskottchen eigentlich schon alle Hüllen fallen gelassen hat?
Die Lösung: Ami sitzt auf einem Eisblock, meditiert und genießt die Kühle. (Und bevor jetzt medizinische Bedenken wegen einer drohenden Nierenbeckenentzündung aufkommen – es geht hier rein um die Symbolik! 😉)
Vor ein paar Tagen dann die nächste Hiobsbotschaft der Wetterdienste: Es muss mit Temperaturen von über 40 °C gerechnet werden. Verdammt! Wie sollten wir da noch einmal nachschärfen?
Die Antwort ist so pragmatisch wie dramatisch: Wir belassen Ami auf ihrem Eisblock, entfachen aber um sie herum ein loderndes Höllenfeuer. Das Inferno ist optisch so gigantisch, dass einem schon beim bloßen Hinsehen der Schweiß ausbricht.
Und falls sich jemand fragt: Nein, 50 °C werden wir nicht mehr implementieren. Das wäre dann nur noch ein brennender Friedhof.
Für alle Technikinteressierten gibt es hier das kleine Programm für unsere Wetter-Ami. Wir haben aktuell sieben verschiedene Ami-Stile im Einsatz. Der folgende Code zeigt, wie die Website die entsprechenden Temperaturwerte direkt aus FHEM ausliest:
```
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Wetter-Ami & Home Control</title>
<style>
/* GRUNDSTRUKTUR */
body {
margin: 0;
padding: 0;
display: flex;
width: 100vw;
height: 100vh;
overflow: hidden;
background: transparent;
font-family: 'Segoe UI', Tahoma, sans-serif;
}/* SIDEBAR LINKS */
aside {
width: 280px;
height: 100vh;
background: rgba(240, 240, 240, 0.7);
padding: 15px;
box-sizing: border-box;
border-right: 1px solid rgba(0,0,0,0.1);
overflow-y: auto;
flex-shrink: 0;
}/* HAUPTBEREICH RECHTS */
main {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
}/* BUTTON STYLING */
cv-nav ul {
margin: 0;
padding: 0;
}cv-nav li {
list-style: none;
margin: 0 0 .6em 0;
padding: 0;
width: 100%;
}cv-nav a {
display: block;
padding: 1.2em 0.5em;
text-decoration: none;
font-weight: bold;
text-align: center;
border: 2px solid black;
border-radius: 12px;
box-shadow: 0 5px 10px white inset;
color: black;
background-color: #FCB900;
transition: all .2s ease-in-out;
cursor: pointer;
font-size: 1.1em;
}/* HOVER / TOUCH EFFEKT */
cv-nav a:hover,
cv-nav a:active {
color: black !important;
background-color: #a2f740;
transform: scale(1.02);
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
}/* RESPONSIVITÄT FÜR HANDYS */
@media (max-width: 800px) {
aside {
width: 200px;
padding: 10px;
}
cv-nav a {
font-size: 1em;
padding: 1.4em 0.3em;
}
#info-display { font-size: 1.5rem !important; }
}/* WETTER ANZEIGE */
#info-display {
position: absolute;
top: 20px;
font-size: 2.2rem;
font-weight: bold;
color: #333;
text-shadow: 1px 1px 2px white;
}#wetterbild {
max-width: 95%;
max-height: 70vh;
width: auto;
height: auto;
opacity: 0;
transition: opacity 0.5s ease-in-out;
}.visible { opacity: 1 !important; }
</style>
</head>
<body><aside>
<cv-nav>
<ul>
<li><a onclick="setFhem('Licht_Aus', 'on')">Alles AUS</a></li>
<li><a onclick="setFhem('Licht_Aus_Kamin', 'on')">Kaminzimmer AUS</a></li>
<li><a onclick="setFhem('Licht_Aus_Kueche', 'on')">Küche AUS</a></li>
<li><a onclick="setFhem('Licht_Eingang_Ost', 'off')">Außen AUS</a></li>
<li><a onclick="setFhem('Licht_Flur_oben', 'off')">Oben AUS</a></li>
<li><a onclick="setFhem('Licht_Aus_Salon', 'off')">Kino AUS</a></li>
<li><a onclick="setFhem('Licht_Schlafzimmer_Ron', 'toggle')">Nachttisch Ron</a></li>
<li><a onclick="setFhem('Licht_Schlafzimmer_Elisa', 'toggle')">Nachttisch Elisa</a></li>
<li><a onclick="setFhem('Licht_Aus_Schlafzimmer', 'on')">Schlafzimmer AUS</a></li>
<li><a onclick="setFhem('Licht_Aus_Dusche', 'off')">Dusche AUS</a></li>
<li><a onclick="setFhem('Licht_Aus_Bad', 'off')">Bad AUS</a></li>
<li><a onclick="location.reload()">Refresh</a></li>
</ul>
</cv-nav>
</aside><main>
<div id="info-display">--°C / --% Hum.</div>
<img id="wetterbild" src="" alt="Wetterbild">
</main><script>
const FHEM_BASE = "http://shinobu:8083/fhem";
const WETTER_DEVICE = "Wetter_FuchsbauIP";
const IMAGE_BASE = "http://lala/Wetter-Ami/";
// HIER: Anzahl der Grafiksets definieren
const NUMBER_OF_SETS = 7;async function setFhem(device, command) {
const url = `${FHEM_BASE}?cmd=set%20${device}%20${command}&XHR=1`;
try {
await fetch(url);
console.log(`Befehl an ${device}: ${command}`);
} catch (e) { console.error("Fehler:", e); }
}async function updateWeather() {
try {
const url = `${FHEM_BASE}?cmd=jsonList%20${WETTER_DEVICE}&XHR=1`;
const response = await fetch(url);
const data = await response.json();
if (!data.Results) return;
const readings = data.Results[0].Readings;const temp = readings["1.ACTUAL_TEMPERATURE"] ? parseFloat(readings["1.ACTUAL_TEMPERATURE"].Value) : 0;
const hum = readings["1.HUMIDITY"] ? parseInt(readings["1.HUMIDITY"].Value) : 0;
const rain = readings["1.RAINING"] ? readings["1.RAINING"].Value : "no";displayWeather(temp, hum, rain);
} catch (e) { console.error("Fehler:", e); }
}// NEU: Funktion zur Berechnung des tagesaktuellen Sets
function getCurrentSet() {
const now = new Date();
const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime();
const localDays = Math.floor(startOfDay / (1000 * 60 * 60 * 24));
return (localDays % NUMBER_OF_SETS) + 1;
}function displayWeather(t, h, isRaining) {
const img = document.getElementById('wetterbild');
const info = document.getElementById('info-display');
info.innerText = `${t.toFixed(1)}°C / ${h}% Hum.`;let nr = "";
if (t >= 40) nr = "000";
else if (t >= 35) nr = "00";
else if (t > 30) nr = "10";
else if (t > 28) nr = "20";
else if (t > 26) nr = "30";
else if (t > 24) nr = "40";
else if (t > 22) nr = "50";
else if (t > 20) nr = "60";
else if (t > 18) nr = "70";
else if (t > 15) nr = "80";
else if (t > 13) nr = "90";
else if (t > 10) nr = "100";
else if (t > 5) nr = "110";
else if (t > 0) nr = "120";
else if (t > -5) nr = "130";
else if (t > -10) nr = "140";
else nr = "150";const rainBool = (isRaining === true || isRaining === "yes" || isRaining === "1" || isRaining === "true");
// NEU: Aktuelles Set abfragen
const activeSet = getCurrentSet();// NEU: activeSet in die URL einbauen (z.B. http://lala/Wetter-Ami/2/100r.png)
img.src = `${IMAGE_BASE}${activeSet}/${nr}${rainBool ? "r" : ""}.png`;
img.onload = () => img.classList.add('visible');
}window.addEventListener('DOMContentLoaded', () => {
updateWeather();
setInterval(updateWeather, 60000);
});
</script></body>
</html>
```#fhem #wetterwilli #amichan #mizuno #sailormerkur #hitze #isgarnichtwarm