mirror of
https://github.com/skoelle/moonweb-site.git
synced 2026-09-18 01:10:25 +00:00
initial commit
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
---
|
||||
title: "AirPlay Audio"
|
||||
section: "smarthome"
|
||||
parent: "/"
|
||||
description: "Multi-room AirPlay receivers with software volume boost on Raspberry Pi devices."
|
||||
layout: base.njk
|
||||
---
|
||||
<h1>AirPlay Audio</h1>
|
||||
<div class="detail-content">
|
||||
|
||||
<p>Two Raspberry Pis run AirPlay receivers so any Apple device in the flat
|
||||
can stream audio to the kitchen or the bathroom without a dedicated
|
||||
speaker app.</p>
|
||||
|
||||
<h2>Setup</h2>
|
||||
<table>
|
||||
<tr><th>Location</th><th>Hardware</th><th>AirPlay version</th><th>Runs as</th></tr>
|
||||
<tr><td>Kitchen</td><td>Raspberry Pi 3B</td><td>AirPlay 2</td><td>Docker container (shairport-sync)</td></tr>
|
||||
<tr><td>Bathroom</td><td>Raspberry Pi Zero W</td><td>AirPlay 1</td><td>Native systemd service (older OS, legacy repo)</td></tr>
|
||||
</table>
|
||||
|
||||
<h2>The volume-boost problem</h2>
|
||||
<p>Both Pis' analog audio output is too quiet at full hardware volume, so
|
||||
a software mixer stage (<code>+20 dB</code> via an ALSA softvol plugin) sits between
|
||||
shairport-sync and the hardware. The hardware mixer itself is deliberately
|
||||
left fixed at 100% / 0 dB, and shairport-sync only ever adjusts its own
|
||||
internal software volume — this avoids the volume jumps and mixer
|
||||
conflicts that show up when multiple layers all try to control loudness.</p>
|
||||
|
||||
<h2>Bathroom-specific integration</h2>
|
||||
<p>The bathroom Pi also runs a small custom tool that starts an internet
|
||||
radio stream automatically when its light sensor detects the light has
|
||||
been switched on. A simple flag file signals whether AirPlay is currently
|
||||
active, so the automatic radio stream politely stays off while someone is
|
||||
actively AirPlaying — and resumes its normal behavior as soon as the
|
||||
AirPlay session ends.</p>
|
||||
|
||||
<h2>Why this design</h2>
|
||||
<ul>
|
||||
<li>Software-only volume control avoids ALSA mixer conflicts across two different loudness sources.</li>
|
||||
<li>The flag-file handoff is trivial to implement and doesn't need a message broker for something this simple.</li>
|
||||
<li>Docker on the kitchen Pi keeps that receiver easy to update; the bathroom Pi's older OS made a native install more reliable than fighting Docker on legacy hardware.</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
title: "Balkon Pi"
|
||||
section: "smarthome"
|
||||
parent: "/"
|
||||
description: "Balcony sensor, lighting, and audio automation running on a Raspberry Pi Zero W."
|
||||
layout: base.njk
|
||||
---
|
||||
<h1>Balkon Pi</h1>
|
||||
<div class="detail-content">
|
||||
|
||||
<p>A Raspberry Pi Zero W mounted near the balcony acts as a small,
|
||||
self-contained smart-balcony controller: light control, an internet
|
||||
radio player, sensor readings, and its own backup/monitoring, all on
|
||||
very modest hardware.</p>
|
||||
|
||||
<h2>What it does</h2>
|
||||
<ul>
|
||||
<li><strong>Audio output</strong> via a DIY PWM-to-analog circuit on two GPIO pins — the Pi Zero has no built-in audio jack, so this is a well-known community workaround using a small RC filter.</li>
|
||||
<li><strong>Physical controls</strong>: a push button for the balcony light and a toggle switch for music playback, read directly via GPIO.</li>
|
||||
<li><strong>HTTP communication</strong> with an ESP32-based balcony light controller.</li>
|
||||
<li><strong>Internet radio</strong> via a lightweight command-line audio player, controlled by a small custom tool ported from an earlier bathroom-Pi project.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Monitoring & backup, even on tiny hardware</h2>
|
||||
<p>Despite the very limited RAM, this Pi still participates in the same
|
||||
Prometheus monitoring pattern as the rest of the fleet — with the metrics
|
||||
collector's default configuration trimmed down to only the essential
|
||||
collectors, since the full default set noticeably overloaded the CPU on
|
||||
this specific board. It also runs a nightly rsync backup of its own
|
||||
configuration to the NAS over the internal network.</p>
|
||||
|
||||
<h2>Planned next steps</h2>
|
||||
<ul>
|
||||
<li>Adding a USB webcam stream, mirroring the pattern already used for the 3D printer.</li>
|
||||
<li>Migrating onto the planned isolated IoT network segment once that's fully set up.</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,19 @@
|
||||
const path = require("path");
|
||||
|
||||
module.exports = function (eleventyConfig) {
|
||||
eleventyConfig.addPassthroughCopy({ "shared/theme-smarthome.css": "theme.css" });
|
||||
eleventyConfig.addPassthroughCopy({ "shared/base.css": "shared-base.css" });
|
||||
eleventyConfig.addPassthroughCopy({ "shared/favicon/smarthome.svg": "favicon.svg" });
|
||||
|
||||
return {
|
||||
dir: {
|
||||
input: "smarthome",
|
||||
includes: "../shared/_includes",
|
||||
output: "dist/smarthome"
|
||||
},
|
||||
serverOptions: {
|
||||
host: "0.0.0.0",
|
||||
port: 8083
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: "Home Control Buttons"
|
||||
section: "smarthome"
|
||||
description: "Overview of the central buttons dashboard used to control lighting, smart plugs, music, network devices and monitoring shortcuts around the apartment."
|
||||
layout: base.njk
|
||||
---
|
||||
<a class="back-link" href="/">← Back to infra overview</a>
|
||||
<h1>Home Control Buttons</h1>
|
||||
<div class="detail-content">
|
||||
|
||||
<p>Instead of jumping between multiple apps and web UIs, I built a single static HTML page with grouped buttons that trigger actions or link directly to the relevant tool for every physical device and service in the apartment. It's the fastest way to switch lights, kill music, check a sensor or jump into an admin dashboard from a phone or tablet without hunting through bookmarks.</p>
|
||||
|
||||
<h2>Lighting & ambience</h2>
|
||||
<ul>
|
||||
<li><strong>Balkon</strong> — LED on/off toggle for the balcony lighting.</li>
|
||||
<li><strong>Beleuchtung (all rooms)</strong> — global "all on"/"all off" shortcut plus per-room toggles for living room and kitchen lighting.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Music controls</h2>
|
||||
<ul>
|
||||
<li><strong>Kitchen</strong> — quick buttons for SomaFM, a classical station, and an off switch, all routed to the kitchen speaker.</li>
|
||||
<li><strong>Living room</strong> — the same SomaFM/classical options plus dedicated Lounge, 2000s and Deluxe stations, and an off switch.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Tasmota smart plugs</h2>
|
||||
<ul>
|
||||
<li><strong>TasmoAdmin</strong> — link straight into the central Tasmota device dashboard for firmware and config management.</li>
|
||||
<li><strong>Power strips (Gosund P1)</strong> — two multi-outlet strips covering the home-office network gear and backup drive, and the iMac corner with its peripherals.</li>
|
||||
<li><strong>Single sockets (SP112)</strong> — four individually switchable outlets covering hallway, kitchen, dryer and washing machine circuits, each also powering an associated LED matrix or small Pi.</li>
|
||||
<li><strong>Other plug families</strong> — additional Nous, Eightree (ESP32-based), Athom and IDS smart plugs cover spare capacity, living-room seating/desk outlets, storage room, kitchen appliances, and a few legacy TV/PC outlets (several currently marked defective).</li>
|
||||
</ul>
|
||||
|
||||
<h2>Special devices & status</h2>
|
||||
<ul>
|
||||
<li><strong>Tasmota RF Bridge / Delock</strong> — bridges RF-only devices (like the home-office 3D printer plug) into the Tasmota/MQTT ecosystem.</li>
|
||||
<li><strong>LED Matrix restarts</strong> — one-click restart buttons for each room's LED matrix display, avoiding a manual power-cycle.</li>
|
||||
<li><strong>Healthchecks & version info</strong> — direct links into the Healthchecks dashboard and a version/status overview for the connected devices.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Network shortcuts</h2>
|
||||
<ul>
|
||||
<li><strong>Routers & mesh</strong> — quick links to the main Fritzbox and its mesh repeaters covering different floors and the kitchen/IoT band.</li>
|
||||
<li><strong>Switches</strong> — direct access to each Zyxel switch's admin page (server room, living room, PowerLAN, OpenWRT segment).</li>
|
||||
<li><strong>OpenWRT & mini router</strong> — links into the OpenWRT admin UI and the small travel router used for testing.</li>
|
||||
<li><strong>Sensors & MQTT</strong> — shortcuts to server-room and balcony sensor readings, bathroom analog values, and background worker/API status pages (HTML and JSON views).</li>
|
||||
</ul>
|
||||
|
||||
<p class="redacted-note">This dashboard is intentionally simple: static HTML, no login, meant purely for convenience on the local network rather than as a secured control surface. Device names and room assignments are shown for structure; a few outlets are currently unused or marked defective and simply act as placeholders for future devices.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
title: "HomematicIP + MQTT"
|
||||
section: "smarthome"
|
||||
parent: "/"
|
||||
description: "How HomematicIP room sensors are bridged into MQTT and stored in InfluxDB for dashboards."
|
||||
layout: base.njk
|
||||
---
|
||||
<h1>HomematicIP + MQTT</h1>
|
||||
<div class="detail-content">
|
||||
|
||||
<p>HomematicIP room thermostats (living room, bedroom, home office) report
|
||||
temperature and humidity into the smart home dashboard via a small,
|
||||
deliberately low-tech bridge: <strong>Home Assistant → MQTT → InfluxDB</strong>.</p>
|
||||
|
||||
<h2>Why this path, and not a direct integration</h2>
|
||||
<p>A dedicated HomematicIP-to-MQTT exporter used to run as a standalone
|
||||
Docker container, but the underlying Python library lost compatibility
|
||||
with HomematicIP's cloud API and hasn't been maintained since 2022. Home
|
||||
Assistant, on the other hand, ships an actively maintained HomematicIP
|
||||
Cloud integration — so instead of chasing a broken exporter, the bridge
|
||||
now runs as native Home Assistant automations that simply republish
|
||||
sensor state changes to MQTT.</p>
|
||||
|
||||
<h2>How it works</h2>
|
||||
<ol>
|
||||
<li>Home Assistant automations trigger on thermostat state changes.</li>
|
||||
<li>Each automation publishes the current temperature and humidity to a per-room MQTT topic.</li>
|
||||
<li>A small .NET background service subscribes to those topics and writes the values into InfluxDB, tagged by room and sensor type.</li>
|
||||
<li>Grafana reads from InfluxDB for the temperature/humidity dashboards.</li>
|
||||
</ol>
|
||||
|
||||
<h2>Why this is worth documenting</h2>
|
||||
<ul>
|
||||
<li>No extra Docker container or unmaintained library dependency.</li>
|
||||
<li>Cloud-API changes are absorbed by Home Assistant's own maintainers, not by custom code.</li>
|
||||
<li>The MQTT bridge is just configuration (automations), not a service that needs its own uptime monitoring.</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
title: "Smarthome"
|
||||
section: "smarthome"
|
||||
description: "Smart home projects: Home Assistant, MQTT sensors, AirPlay audio, OctoPrint, and energy monitoring."
|
||||
layout: base.njk
|
||||
sections:
|
||||
- heading: "Control & Automation"
|
||||
cards:
|
||||
- title: "Home dashboard"
|
||||
summary: "Lighting, music, and Tasmota device control shown on the home dashboard."
|
||||
href: "/home-dashboard-controls/"
|
||||
- title: "Tasmota & energy monitoring"
|
||||
summary: "Smart plugs and power monitoring across the flat, feeding daily usage stats."
|
||||
href: "/tasmota-energy/"
|
||||
- title: "HomematicIP + MQTT"
|
||||
summary: "How HomematicIP room sensors are bridged into MQTT and stored in InfluxDB."
|
||||
href: "/homematic-mqtt/"
|
||||
- title: "Balkon Pi"
|
||||
summary: "Balcony sensor, lighting, and audio automation unit."
|
||||
href: "/balkonpi/"
|
||||
- heading: "Dashboards & Hardware"
|
||||
cards:
|
||||
- title: "LED Matrix"
|
||||
summary: "ESP32 LED matrix displays around the flat. Full write-up currently lives on the CV site."
|
||||
href: "https://stefankoelle.de/ledmatrix/"
|
||||
- title: "WT32-SC01 dashboard"
|
||||
summary: "Touch dashboard on a compact ESP32-S3 display."
|
||||
href: "https://github.com/skoelle/wt32sc01-dashboard"
|
||||
- title: "M5Stack dashboard"
|
||||
summary: "ESP32 dashboard showing weather, calendar, and MVG departures."
|
||||
href: "https://github.com/skoelle/m5stack-dashboard"
|
||||
- heading: "Personal services"
|
||||
cards:
|
||||
- title: "iCloud Contacts Sync"
|
||||
summary: "Private iCloud contacts synced into the homelab, with birthday notifier and web UI."
|
||||
href: "https://github.com/skoelle/icloud-contacts-sync"
|
||||
- title: "MVG departures"
|
||||
summary: "Compact Munich transit departure monitor for desktop and mobile."
|
||||
href: "https://github.com/skoelle/mvg-departures"
|
||||
- title: "Google Calendar sync"
|
||||
summary: "Private calendar synced into the homelab with notifer and web interface."
|
||||
href: "https://github.com/skoelle/calender_sync"
|
||||
- title: "Focus App"
|
||||
summary: "A clean, modern todo application with drag & drop reordering."
|
||||
href: "https://github.com/skoelle/focusapp"
|
||||
- heading: "Media"
|
||||
cards:
|
||||
- title: "AirPlay audio"
|
||||
summary: "Multi-room AirPlay receivers with software volume boost."
|
||||
href: "/airplay-audio/"
|
||||
- title: "OctoPrint"
|
||||
summary: "Remote 3D printer control and camera streaming."
|
||||
href: "/octoprint/"
|
||||
- title: "TubeArchivist"
|
||||
summary: "Self-hosted YouTube archiving running on the Synology."
|
||||
href: "/tubearchivist/"
|
||||
---
|
||||
{% include "card-grid.njk" %}
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: "OctoPrint"
|
||||
section: "smarthome"
|
||||
parent: "/"
|
||||
description: "Remote 3D printer control and camera streaming with OctoPrint on Raspberry Pi."
|
||||
layout: base.njk
|
||||
---
|
||||
<h1>OctoPrint</h1>
|
||||
<div class="detail-content">
|
||||
|
||||
<p>A Raspberry Pi 3B runs OctoPrint for remote 3D-printer control, plus a
|
||||
live camera stream so print progress can be checked without walking over
|
||||
to the printer.</p>
|
||||
|
||||
<h2>Current setup</h2>
|
||||
<ul>
|
||||
<li><strong>OctoPrint</strong> runs as a Docker container — the main remote control interface for the printer.</li>
|
||||
<li><strong>Camera streaming</strong> is handled by a lightweight camera-server project, exposing both an HLS stream and an MJPEG stream, the latter wired directly into OctoPrint's webcam panel.</li>
|
||||
<li><strong>Container management</strong> (Portainer, cAdvisor, a node exporter) runs alongside, giving the same monitoring pattern as the rest of the fleet.</li>
|
||||
</ul>
|
||||
|
||||
<h2>History</h2>
|
||||
<p>This Pi originally also had a small status display attached; the
|
||||
display was later moved to the backup Pi (which benefits more from local,
|
||||
no-network status output) once this Pi's camera stream took over as the
|
||||
primary way to check on things remotely. The unit was also renamed at
|
||||
that point to better reflect its now-singular focus on the printer.</p>
|
||||
|
||||
<h2>Notable OS lesson</h2>
|
||||
<p>After moving this Pi to a newer OS release, boot configuration files
|
||||
moved to a new path — editing the old path silently does nothing, which
|
||||
is an easy trap when following older notes or tutorials for the same
|
||||
hardware.</p>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
title: "Tasmota & Energy Monitoring"
|
||||
section: "smarthome"
|
||||
parent: "/"
|
||||
description: "Smart plugs and power monitoring across the flat with daily usage statistics."
|
||||
layout: base.njk
|
||||
---
|
||||
<h1>Tasmota & Energy Monitoring</h1>
|
||||
<div class="detail-content">
|
||||
|
||||
<p>Power monitoring across the flat runs on a mix of Tasmota-flashed smart
|
||||
plugs, tracking accumulated kWh per device and feeding daily usage
|
||||
figures into the home dashboard.</p>
|
||||
|
||||
<h2>What's metered</h2>
|
||||
<table>
|
||||
<tr><th>Device type</th><th>Typical use</th><th>Rough daily usage</th></tr>
|
||||
<tr><td>Fridge plug</td><td>Kitchen appliance monitoring</td><td>~0.8 kWh/day (very stable)</td></tr>
|
||||
<tr><td>Dishwasher plug</td><td>Appliance monitoring</td><td>~1.2 kWh/day (varies with use)</td></tr>
|
||||
<tr><td>Office/desk plug</td><td>Workstation + peripherals</td><td>~1.2-1.7 kWh/day</td></tr>
|
||||
<tr><td>Entertainment plugs (TV, Apple TV)</td><td>Media devices</td><td>Very low, Apple TV especially so</td></tr>
|
||||
<tr><td>LED matrix displays</td><td>Ambient info displays</td><td>~0.04 kWh/day each</td></tr>
|
||||
</table>
|
||||
|
||||
<h2>Multi-socket power strips</h2>
|
||||
<p>Several rooms use multi-outlet smart power strips (each socket
|
||||
individually switchable and metered) rather than single smart plugs — this
|
||||
keeps things like "washing machine + dryer" or "office desk cluster" on
|
||||
one strip while still tracking each socket's consumption separately.</p>
|
||||
|
||||
<h2>Flashing process</h2>
|
||||
<p>New devices go through a standard conversion flow (from the
|
||||
manufacturer's original cloud-dependent firmware to Tasmota) using a
|
||||
well-documented community process. It occasionally fails on the first
|
||||
attempt due to a transient Wi-Fi handshake issue — retrying resolves it
|
||||
without any special handling.</p>
|
||||
|
||||
<h2>What this data is used for</h2>
|
||||
<ul>
|
||||
<li>Spotting appliances with unexpectedly high standby draw.</li>
|
||||
<li>Sanity-checking that "turned off" devices are actually drawing near-zero power.</li>
|
||||
<li>Feeding the home dashboard's live power figures alongside the climate sensors.</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
title: "TubeArchivist"
|
||||
section: "smarthome"
|
||||
parent: "/"
|
||||
description: "Self-hosted YouTube archiving and media management running on the Synology NAS."
|
||||
layout: base.njk
|
||||
---
|
||||
<h1>TubeArchivist</h1>
|
||||
<div class="detail-content">
|
||||
|
||||
<p>TubeArchivist runs on the Synology NAS via Docker Compose, self-hosting
|
||||
a searchable archive of downloaded YouTube content (Elasticsearch +
|
||||
Redis + the TubeArchivist app itself).</p>
|
||||
|
||||
<h2>Why this needed real troubleshooting</h2>
|
||||
<p>Running Elasticsearch on Synology's DSM kernel isn't fully
|
||||
straightforward: newer Elasticsearch releases require a Linux kernel
|
||||
feature (SECCOMP) that Synology's kernel doesn't compile in. The fix is
|
||||
version-pinning Elasticsearch to the last release that still works
|
||||
without it, rather than fighting the kernel.</p>
|
||||
|
||||
<h2>Other Synology-specific quirks</h2>
|
||||
<ul>
|
||||
<li>Synology's Container Manager doesn't always auto-join containers to the same Docker network even when they're defined in one Compose file — an explicit named network avoids silent connectivity failures between the app, Elasticsearch, and Redis.</li>
|
||||
<li>A version upgrade of the app itself required a very specific step-by-step path (skipping versions breaks the database migration) rather than jumping straight to the latest release.</li>
|
||||
</ul>
|
||||
|
||||
<h2>What's backed up</h2>
|
||||
<table>
|
||||
<tr><th>Data</th><th>Included in NAS backup?</th></tr>
|
||||
<tr><td>Downloaded media files</td><td>Yes, via the NAS's own backup volumes</td></tr>
|
||||
<tr><td>Elasticsearch metadata/index</td><td>Yes, via the NAS's own backup volumes</td></tr>
|
||||
<tr><td>Redis cache</td><td>No — safe to delete/rebuild, only holds session data</td></tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
Reference in New Issue
Block a user