
[{"content":"This guide shows how to build a small USB dongle that plays the Chrome Dino game automatically. The device appears as a standard USB keyboard, reads two light sensors on the monitor, and sends jump/duck keys with speed-adaptive timing. No browser extension, no host script, and no mechanical key press hardware.\nPrototype hardware: Digispark ATtiny85 with two LM393 LDR sensor boards (upper and lower obstacle sensing). Why this approach # Common Dino bot methods have tradeoffs:\nApproach Typical drawback JavaScript injection Browser-dependent and easy to detect Servo or solenoid key presser Bulky, noisy, mechanical wear MCU + host-side Python script Requires extra software running on the PC This design is fully self-contained: the host only sees a generic USB HID keyboard.\nWhat is unique in this build # Many Dino projects exist, but this implementation combines a few practical differences in one low-cost setup:\nNo host software at runtime: the external MCU enumerates as a standard USB HID keyboard. No mechanical key press actuator: no servo/solenoid pressing the spacebar. Dual-obstacle handling: two vertically stacked LDR sensors support both jump and duck decisions. Speed adaptation in firmware: timing is derived from obstacle envelope width, so behavior stays usable as game speed increases. Bill of materials # Digispark ATtiny85 board (~2 to 5 USD) 2x LM393 LDR comparator modules (~1 USD each) Jumper wires (~1 USD) Tape or small clip mount for sensor placement on the monitor System overview # Lower sensor tracks ground-level obstacles (cactus zone) Upper sensor tracks bird-height obstacles ATtiny85 classifies obstacle type and sends key press over USB HID Lower sensor pulse envelope width is used to estimate game speed System overview: obstacle zones on the monitor, dual LM393 sensors, Digispark ATtiny85 firmware logic, and USB HID key output to host. Wiring # LM393 pin Digispark pin Lower D0 PB2 (D2) Upper D0 PB0 (D0) VCC (both) 5V GND (both) GND Wiring detail: lower LM393 D0 to PB2, upper LM393 D0 to PB0, with shared 5V and GND. Build and flash # Clone and build:\ngit clone https://github.com/hackboxguy/chrome-dinoplayer.git cd chrome-dinoplayer make all Flash with Micronucleus bootloader:\nmake upload If your udev setup does not need sudo:\nmake upload SUDO=\u0026#39;\u0026#39; Tip Run make upload first, then plug in the Digispark when prompted.\nBuild prerequisites (Debian/Ubuntu):\nsudo apt install gcc-avr avr-libc libusb-1.0-0-dev pkg-config Quick start (pre-built firmware already in repo):\nmake micronucleus sudo tools/micronucleus/micronucleus --run hex/dino-player-v1.hex Sensor placement and calibration # Reference frame used to align the upper and lower sensors against bird and cactus obstacle zones. Open chrome://dino and keep the game in day mode during setup. Place both sensors at the same horizontal position, slightly ahead of the dino. Align lower sensor to cactus height. Align upper sensor to bird flight height. Adjust LM393 potentiometers so white background is \u0026ldquo;clear\u0026rdquo; and dark obstacle is \u0026ldquo;triggered\u0026rdquo;. If your LM393 module polarity is inverted, change OBSTACLE_IS_LOW in firmware.\nKey success considerations # Two setup points decide whether the bot actually plays well or fails randomly:\nVertical sensor alignment: keep both sensors at the same horizontal X position, with lower aligned to cactus zone and upper aligned to bird zone. Distance from dino (tested setup): in my build, the sensor pair works best at about 30 mm to 40 mm ahead of the dino (to the right), which provides enough lead time for action. Per-monitor potentiometer tuning: tune each LM393 threshold based on your monitor brightness/contrast and ambient light. A setting that works on one display or room lighting may fail on another. Tip After initial tuning, test at least 20 to 30 obstacle events and fine-adjust the potentiometers in small steps for faster and cleaner trigger transitions.\nDetection logic # The two vertically stacked sensors produce a simple decision table:\nLower Upper Action Triggered Triggered Jump (space) Triggered Clear Jump (space) Clear Triggered Duck (down arrow) Clear Clear No action Rule used in firmware:\nUpper triggered without lower -\u0026gt; duck Any lower trigger -\u0026gt; jump Adaptive speed timing (envelope tracking) # Game speed increases over time. Fixed delay becomes inaccurate, so firmware tracks the lower-sensor obstacle envelope width and adapts jump timing.\nFork gaps inside cactus shapes are merged using a short gap threshold Recent envelope widths are stored in a rolling window Rolling minimum is used as a stable speed reference Jump delay is scaled and clamped between min/max bounds jump_delay = clamp(rolling_min * scale_factor, MIN_JUMP_DELAY, MAX_JUMP_DELAY) This keeps timing usable from early game to high score speeds.\nDisable day/night inversion in Chrome # Night mode flips contrast and can cause false triggers with LDR-based detection. In DevTools Console, run:\nRunner.getInstance().invert = function(reset) {}; Note Run this after each game restart because the function is reset on reload.\nUseful tuning constants # All values are in src/main.c:\nConstant Default Purpose KEY_HOLD_MS 80 Jump key hold duration DUCK_HOLD_MS 200 Duck key hold duration COOLDOWN_MS 400 Minimum time between actions GAP_THRESHOLD_MS 30 Merge short gaps inside one obstacle envelope ENVELOPE_HISTORY 5 Rolling window size for speed estimate MIN_JUMP_DELAY 10 Lower bound for adaptive jump delay MAX_JUMP_DELAY 150 Upper bound for adaptive jump delay Troubleshooting # Device not detected as keyboard: check USB cable/port and Digispark bootloader state. Random jumps or ducks: re-tune LM393 thresholds and re-check sensor alignment. Missed obstacles at high speed: reduce MAX_JUMP_DELAY or tweak scale factor. Build failure: install AVR toolchain and libusb development package. Where this is useful # USB gadget experimentation with ATtiny85 and V-USB Low-cost embedded vision-by-threshold prototypes Hardware-only input automation projects hackboxguy/chrome-dinoplayer digispark attiny85 based dino game player C 6 0 ","date":"7 March 2026","externalUrl":null,"permalink":"/blog/chrome-dino-auto-player/","section":"Blog","summary":"","title":"Build a Chrome Dino Auto-Player with Digispark ATtiny85","type":"blog"},{"content":"Minecraft multiplayer at home — no accounts, no native client, just a browser.\nEaglercraftX is an open-source browser port of Minecraft 1.8.8. This project packages it into a Docker container so players can join from any device on your local network using Chrome or Firefox.\nNote The initial build requires internet to download server components. After setup, gameplay works entirely on your home LAN without internet.\nEaglercraftX Docker server: browser-based Minecraft on your home LAN — no native client needed. Why not just use a public Eaglercraft server? # Public Eaglercraft servers are free and easy to find — but they come with risks that parents should understand. When your child connects to someone else\u0026rsquo;s server, the server operator controls the web client code running in the browser. Unlike official Minecraft from the Microsoft Store, there\u0026rsquo;s no app store vetting.\nWhat can go wrong on public servers:\nAggressive ads and popups — many public servers monetize through intrusive ads and fake \u0026ldquo;download\u0026rdquo; buttons that kids click without thinking Malicious redirects — the served JavaScript can redirect to phishing pages or fake \u0026ldquo;Your computer is infected\u0026rdquo; scareware that tricks kids into downloading actual malware Credential phishing — fake login forms that harvest email/passwords kids might reuse on other sites Background crypto mining — browser-based mining scripts running silently while the kid plays Note Modern browser sandboxing prevents JavaScript from silently installing software. The real risk is social engineering — convincing an uninformed user to click, download, or enter credentials. Kids are especially vulnerable to this.\nSelf-hosting greatly reduces these risks: you control the client code, there are no third-party scripts, no ads, and no external network traffic. Combined with LAN-only access (or VPN for remote play), your attack surface drops to near zero.\nWhy this setup works for families # Browser-based client — no native launcher install on any device Local multiplayer on your home network Simple Docker lifecycle (up, down, logs) Persistent worlds and logs in ./data Optional admin dashboard for server visibility What you get # Game/browser endpoint: http://YOUR_SERVER_IP:8081 Admin dashboard endpoint: http://YOUR_SERVER_IP:8082 Included plugins: Plan Player Analytics Vault LuckPerms EssentialsX (+ Chat + Spawn) WorldEdit WorldGuard Prerequisites # Docker and git installed 4 GB+ free RAM Free ports: 8081 (game) and 8082 (dashboard) sudo apt-get update sudo apt-get install -y docker.io docker-compose docker-buildx git sudo usermod -aG docker $USER # Log out and back in for the group change to take effect sudo pacman -S docker docker-compose docker-buildx git sudo systemctl enable --now docker sudo usermod -aG docker $USER # Log out and back in for the group change to take effect Note Last tested on 2026-02-28 with Docker 27.5, Docker Compose 2.32, on Ubuntu 24.04.\n5-step setup # 1) Clone the repository # git clone https://github.com/hackboxguy/eaglercraft-docker.git cd eaglercraft-docker 2) Build the Docker image # docker build -t eaglercraftx-server:local . This downloads and assembles all server components. It takes 5–15 minutes depending on your internet speed. You\u0026rsquo;ll see a lot of output — that\u0026rsquo;s normal. When it\u0026rsquo;s done, you should see:\nSuccessfully tagged eaglercraftx-server:local 3) Start the stack # docker compose up -d Tip If you have the older standalone Docker Compose, use docker-compose (with hyphen) instead of docker compose. Both work the same way.\n4) Watch startup logs # docker compose logs -f eaglercraft Wait for:\nAll services started successfully! Open in browser: http://\u0026lt;IP\u0026gt;:8081 5) Join from browser # On host machine: http://localhost:8081 On other home devices: http://YOUR_SERVER_IP:8081 You\u0026rsquo;ll see the EaglercraftX title screen — a Minecraft-style menu. Enter any username (no account needed), click Multiplayer, and the local server is already pre-configured in the list. Click it and join.\nFind your host IP:\nhostname -I | awk \u0026#39;{print $1}\u0026#39; Want Minecraft 1.12.2 instead? # The default setup runs 1.8.8 — stable and well-tested. If you want newer gameplay features (horses, dual-wielding, elytra, shields, observers, and more), there\u0026rsquo;s an experimental 1.12.2 branch with a simpler single-process architecture.\n1.8.8 (default) 1.12.2 (experimental) Branch main v1.12.2 Server engine PandaSpigot + BungeeCord Paper (single process) Game content Classic PvP, lighter on resources More blocks, mobs, and mechanics Stability Mature, well-tested Newer, still being refined To try 1.12.2, just change the clone and build commands:\ngit clone -b v1.12.2 https://github.com/hackboxguy/eaglercraft-docker.git cd eaglercraft-docker docker build -t eaglercraft-1.12.2-server:local . docker compose up -d Everything else in this guide (dashboard, safety, backups, ports) applies to both versions. The only other difference is the server console command — see the Server console section below.\nBrowser-based client (no native install) # Every player joins directly in Chrome/Firefox using the Eaglercraft web client served by your local Docker stack. This eliminates setup friction for kids and guests — no downloads, no Java, no launcher.\nParent/Admin controls # Admin dashboard # Open http://YOUR_SERVER_IP:8082 to monitor:\nPlayer activity Session history Server performance trends Plan Player Analytics dashboard — track player activity, session history, and server performance from a browser. Tip If you don\u0026rsquo;t need the dashboard accessible from other devices, bind it to localhost only by changing the port mapping in docker-compose.yml from 8082:8804 to 127.0.0.1:8082:8804. This prevents other LAN devices from accessing the admin panel.\nServer console # docker exec -it eaglercraftx-server supervisorctl fg spigot Detach without stopping server: Ctrl+C\ndocker attach eaglercraft-1.12.2-server Detach without stopping server: Ctrl+P then Ctrl+Q\nUseful commands (both versions):\nlist op PlayerName whitelist add PlayerName ban PlayerName Family safety checklist # Warning Keep the server on your private home LAN only Do not expose ports 8081 or 8082 directly to the public internet If remote access is needed, use a VPN overlay instead of public port-forwarding Use whitelist/admin controls for known players Back up worlds regularly Backups # Backup everything:\ntar -czf eaglercraft-backup-$(date +%Y%m%d).tar.gz data/ Restore:\ntar -xzf eaglercraft-backup-YYYYMMDD.tar.gz Daily operations # Action Command Start docker compose up -d Stop docker compose down Status docker compose ps Logs docker compose logs -f eaglercraft Troubleshooting # Port/listener check:\nss -tlnp | grep -E \u0026#39;8081|8082\u0026#39; Service status and logs:\ndocker exec eaglercraftx-server supervisorctl status docker compose logs eaglercraft docker exec eaglercraftx-server tail -f /opt/eaglercraft/logs/spigot.log docker exec eaglercraftx-server tail -f /opt/eaglercraft/logs/bungee.log docker compose logs eaglercraft docker exec eaglercraft-1.12.2-server tail -f /opt/eaglercraft/logs/server.log Known limitations # Initial build requires internet to download server components The build pulls upstream artifacts (server JARs, plugins) at build time — exact binaries may change between builds unless pinned or checksummed This setup prioritizes LAN simplicity, not hardened internet hosting Legal note # Note This project is for educational and research use. Ensure your use and any redistribution comply with applicable laws, upstream licenses, and intellectual property requirements. Not affiliated with Mojang or Microsoft.\nhackboxguy/eaglercraft-docker A complete, self-contained Eaglercraft server that runs Minecraft v1.8.8 in web browsers without requiring Minecraft accounts or installations. Perfect for offline family gaming! Dockerfile 2 0 ","date":"28 February 2026","externalUrl":null,"permalink":"/blog/eaglercraft-server/","section":"Blog","summary":"","title":"Browser-Based Minecraft at Home: Offline EaglercraftX with Docker","type":"blog"},{"content":"This project turns a cheap Digispark ATtiny85 USB dongle and a KY-040 rotary encoder into a dedicated hardware volume knob. Rotate clockwise for volume up, counter-clockwise for volume down, press to mute. It enumerates as a standard USB HID Consumer Control device — no custom driver, no desktop app. Linux, Windows, and many Android devices recognise it out of the box.\n3D render of the assembled volume knob — Digispark ATtiny85 USB board with KY-040 rotary encoder. The finished USB volume knob — plug in and it works immediately as a standard HID device. Why Build This? # Keyboard shortcuts work, but a physical knob is better when you are:\nSwitching between headphones and speakers On a call and need instant mute Using a media PC or mini server with no easy keyboard access Tired of digging into software mixer panels For around 5–10 USD in parts you get a dedicated hardware control that is always there.\nParts # Everything needed: Digispark ATtiny85 USB board, KY-040 rotary encoder module, and jumper wires. Digispark ATtiny85 USB board — ~2 USD KY-040 rotary encoder module — ~1 USD Jumper wires (female-to-female) — ~1 USD Optional: 3D-printed case or aftermarket knob for a cleaner finish Wiring # Connection diagram: KY-040 rotary encoder wired to the Digispark ATtiny85 USB board. Rotary Encoder Digispark ATtiny85 CLK P5 (PB5) DT P2 (PB2) SW P0 (PB0) + 5V GND GND ATtiny85 pin mapping used by this project:\n+-\\/-+ ENC_A (CLK) PB5 1| |8 Vcc USB D- PB3 2| |7 PB2 ENC_B (DT) USB D+ PB4 3| |6 PB1 GND 4| |5 PB0 ENC_SW (SW) +----+ Note Note: PB5 is used as GPIO for encoder input in this design (RSTDISBL fuse context applies when programming bare chips). Digispark boards typically ship in a suitable configuration already.\nAssembly # The build is straightforward — solder the five wires between the encoder module and the Digispark board as shown in the wiring table above, then attach a knob cap. The numbered steps below show the full process from bare parts to finished device:\nAssembly steps 1–12: from bare components to a finished USB volume knob ready to plug in. Firmware # The firmware sends standard HID Consumer Control usages:\nHID Usage Function 0xE9 Volume Increment 0xEA Volume Decrement 0xE2 Mute Because these are standard HID usages, the host OS handles them natively — no custom driver needed.\nBuild and Flash # Clone the repository and build the firmware and uploader:\ngit clone https://github.com/hackboxguy/attiny85-hid-rotary-knob.git cd attiny85-hid-rotary-knob make all This builds main.hex (firmware) and tools/micronucleus/micronucleus (uploader).\nFlash via Micronucleus bootloader:\nmake upload Tip Tip: After running make upload, you will see \u0026ldquo;Waiting for device\u0026hellip;\u0026rdquo;. Plug in the Digispark within 60 seconds — the upload starts automatically once the bootloader is detected.\nIf your setup does not require sudo:\nmake upload SUDO=\u0026#39;\u0026#39; Note Note: Digispark boards come with the Micronucleus bootloader pre-installed — just plug in and upload. This blog assumes a board with a working bootloader. If you have a blank ATtiny85 chip without Micronucleus, flashing the bootloader requires an ISP programmer and is outside the scope of this guide.\nTip Build prerequisites: Install gcc-avr, avr-libc, binutils-avr, libusb-1.0-0-dev, and pkg-config before running make.\nPlatform Compatibility # Linux # Works out of the box as a USB HID media control device. Desktop environments map it immediately to system volume and mute. Good fit for Ubuntu/Debian desktops, Arch with Wayland or X11, and Raspberry Pi media boxes.\nWindows # Also works without drivers as a standard media-control device. If you briefly see \u0026ldquo;USB device not recognized\u0026rdquo; right after plugging in, that is the short Micronucleus bootloader window before the firmware enumerates. After handoff, the knob works normally.\nAndroid # Works on Android devices that support USB OTG and HID media keys. You need a USB-C OTG adapter (or Micro-USB OTG on older phones) and OTG host support enabled on the device.\nNote Android caveats: Behaviour can vary by OEM/ROM. Some devices only react when the screen is unlocked, and mute handling may differ across apps.\nTroubleshooting # Build fails with missing AVR tools — Install the prerequisites listed in the Build and Flash section above. Linux error -71 during USB enumeration — Reflash or repair the bootloader. See the repository troubleshooting section. No response to rotation — Check CLK/DT wiring first (most common issue), then confirm the encoder module GND and 5V connections. Going Further # The firmware is intentionally simple and stable, but the hardware supports extensions:\nMulti-mode knob (volume / media transport / brightness) Long-press and double-click actions Mode indicator LED Additional HID report descriptors Start with a practical tool, then evolve it into a custom desktop controller.\nhackboxguy/attiny85-hid-rotary-knob Turn your digispark attiny85 usb dongle into an USB volume control knob for PCs C 16 1 ","date":"18 February 2026","externalUrl":null,"permalink":"/blog/diy-hid-knob/","section":"Blog","summary":"","title":"Build a Low-Cost DIY USB Volume Knob with Digispark ATtiny85","type":"blog"},{"content":"This is version 2 of my multi-screen Raspberry Pi infotainment project. The first version (DIY In-Car Infotainment) required a separate pocket router for DHCP, DNS, and DLNA. This version eliminates that dependency — one prebuilt SD card image works for all terminals, and the system configures itself automatically at boot.\nWhat\u0026rsquo;s New in v2.1 # Touch-friendly OSD controls — New \u0026ldquo;Sync\u0026rdquo; and \u0026ldquo;Stop All\u0026rdquo; buttons in Kodi\u0026rsquo;s video player OSD. Tap the screen to show controls, tap Sync to synchronize all screens. Master-only visibility — OSD sync buttons automatically hide on slave devices (only visible on master with USB mounted). Keyboard shortcut — Press \u0026lsquo;S\u0026rsquo; during video playback to trigger sync immediately. No startup prompts — Pre-configured Addons database eliminates \u0026ldquo;Do you want to enable this addon?\u0026rdquo; popups. Accurate device count — Fixed duplicate localhost counting (shows correct 3/3 instead of 4/4). Minimal dual-screen setup — Just two Pi4s connected with a direct Ethernet cable — no PoE switch needed for small deployments. Note v2.0 features: Self-hosted DHCP/DNS/NTP/DLNA on master Pi, automatic master election via USB detection, one SD card image for all terminals.\nMinimal Dual-Screen Setup # For a quick two-screen deployment, you don\u0026rsquo;t need a PoE switch — just connect two Pi4s directly with an Ethernet cable:\nMinimal setup: Two Pi4s connected directly via Ethernet. The Pi with USB storage becomes master automatically. What you need:\n2× Raspberry Pi 4 with touch displays 2× MicroSD cards (same image on both) 1× Ethernet cable (any length, crossover not required) 1× USB storage with media files 2× Power supplies (5V/3A each) How it works:\nDownload the pre-built SD card image (v2.1) and flash it to both cards using balenaEtcher or Rufus Connect the two Pi4s with a standard Ethernet cable Attach USB storage to one Pi (this becomes the master) Power on both — master provides DHCP, DLNA, and NTP to the slave Both terminals launch Kodi and show the DLNA media library From here, use the touch-screen OSD controls to sync playback across both screens.\nTip Scaling up? Add a PoE switch for 3+ screens — see Multi-Screen Setup (3+ Screens with PoE Switch) below.\nMulti-Screen Setup (3+ Screens with PoE Switch) # System diagram: One master Pi (with USB media) provides DHCP, DNS, NTP, and DLNA to all client terminals via a PoE switch. A typical deployment uses:\n1 master Pi4 terminal (with USB media attached) 3 client Pi4 terminals 1 PoE switch (5-port or larger) The topology is a pure star connection: every terminal connects directly to the PoE switch via a single Ethernet cable that provides both power and network. No AV matrix or special head-end hardware required.\nHow It Works # PoE switch powers on All Pi4 terminals boot from identical SD cards Each terminal checks for USB storage The terminal with USB media becomes the master automatically Master starts DHCP (192.168.8.100-200), DNS, NTP, and DLNA services Client terminals get their IP address, time sync, and media access from master All terminals launch Kodi and connect to the DLNA source Users choose Personal Mode or Sync Mode Two Operating Modes # Personal Mode # Each user gets their own screen and audio path:\nAnalog headset via 3.5mm jack, or Bluetooth headset This feels similar to in-flight seatback entertainment. Each passenger independently browses the DLNA media library in Kodi and plays whatever they want.\nSync Mode # When shared viewing is needed, the master terminal can synchronize all clients using touch-screen OSD controls:\nStart playing a video on the master (the Pi with USB storage) Tap the screen (or press any key) to show the OSD Tap Sync — all screens open the same video at the same position Tap Stop All — stops playback on all screens simultaneously Kodi video player OSD on master device showing the custom Sync and Stop All buttons (highlighted). These buttons only appear on the master Pi. Keyboard shortcut: Press \u0026lsquo;S\u0026rsquo; during video playback to trigger sync immediately without showing the OSD.\nNote Non-touch displays? Connect a mini 3-key USB keyboard to the master. Press KEY_1 to sync, KEY_2 to stop all. The OSD buttons are hidden on slave devices — only the master shows them.\nMaster audio can feed a central sound system (vehicle speakers, room PA, etc.) for group viewing.\nHardware List # For a 4-terminal setup:\nComponent Qty Notes Raspberry Pi 4 (4GB) 4 2GB works but 4GB recommended PoE HAT 4 Official or compatible 802.3af HAT MicroSD card (32GB+) 4 Class 10 or faster Full HD touch display 4 7\u0026quot; to 10\u0026quot; HDMI displays work well PoE switch 1 5-port minimum, 802.3af/at Ethernet cables 4 Up to 50m runs supported USB storage 1 NTFS, FAT32, or ext4 formatted 3-key USB keyboard (optional) 1 Only needed for non-touch displays; touch screens use OSD buttons Note Compared to v1, you no longer need the GL-MT300N-V2 pocket router — the master Pi handles all network services.\nReal-World Use Cases # In-Car / Fleet Passenger Infotainment # Ideal for vehicles with multiple passengers:\nEach passenger watches independent content with personal audio One key press switches everyone to synchronized shared playback Master audio routes to vehicle speakers for group viewing Gives both freedom (personal playback) and coordination (sync playback) in one system.\nMulti-Room Shared Viewing # Multi-room use case: synchronized playback across overflow rooms, halls, or training centers. For venues where people are spread across rooms:\nHouse of worship overflow rooms Community halls Training centers Small campuses A single PoE star network keeps wiring simple and operations predictable.\nQuick Start # Option 1: Pre-built Image (Recommended)\nDownload the pre-built SD card image (v2.1) (~1.2GB) Flash the image to all SD cards using balenaEtcher or Rufus Insert SD cards into Pi4 terminals Connect all terminals to PoE switch Insert USB media (NTFS, FAT32, or ext4) into one terminal Power on the PoE switch Wait for all terminals to boot into Kodi Option 2: Manual Installation\nOn an existing Raspberry Pi OS Lite installation:\ngit clone https://github.com/hackboxguy/media-mux.git cd media-mux sudo ./setup.sh # System reboots after base installation # After reboot, login again and run: cd media-mux sudo ./setup-selfhosted.sh sudo reboot Troubleshooting # DLNA source shows \u0026ldquo;Couldn\u0026rsquo;t connect to network server\u0026rdquo; # Check if master terminal has USB media attached Verify minidlna is running: pgrep -f minidlnad Check master log: cat /var/log/media-mux-selfhosted.log Ensure USB is mounted: mount | grep /media/usb Client terminal not getting IP address # Verify master booted first and has USB attached Check dnsmasq is running on master: systemctl status dnsmasq Try rebooting the client terminal Time is wrong on client terminals # Wait a few minutes after boot for NTP sync Check chrony status: chronyc sources Verify master chrony is running: pgrep -f chronyd Sync playback not working # Ensure you are triggering sync from the master (the Pi with USB storage) Touch screen: Tap screen to show OSD, tap Sync button Keyboard: Press \u0026lsquo;S\u0026rsquo; during playback, or KEY_1 on 3-key keyboard Check kodisync log on master: cat /var/log/kodisync.log Verify all clients are on the same network (192.168.8.x) OSD Sync/Stop buttons not visible # Buttons only appear on the master (Pi with USB storage attached) Slave devices do not show these buttons by design If master doesn\u0026rsquo;t show buttons, verify USB is mounted: mount | grep /media/usb USB media not detected # Supported formats: NTFS, FAT32, ext4 Check dmesg for USB detection: dmesg | grep -i usb Try a different USB port or cable Current Limitations # The system works reliably for practical deployments, but there are areas for future improvement:\nNo automatic master failover if master is disconnected No web dashboard for status monitoring Role is determined by USB presence (no manual pinning) hackboxguy/media-mux Raspberry Pi Media player customization scripts C\u0026#43;\u0026#43; 4 0 ","date":"7 February 2026","externalUrl":null,"permalink":"/blog/pi4-multiscreen-infotainment/","section":"Blog","summary":"","title":"One Cable, Many Screens: A Self-Hosting PoE Raspberry Pi 4 Infotainment System","type":"blog"},{"content":"VMBOX packages web applications and runtime dependencies into a self-contained VirtualBox VM. Teams can deliver internal tools as a portable OVA artifact with browser-first access, reducing per-app EXE/MSI/DEB installation work on managed endpoints.\nThe Problem # If you\u0026rsquo;ve ever tried to deploy a custom tool on managed Windows laptops, you know the pain. Installing Python, setting up dependencies, dealing with Group Policy restrictions, getting IT approval for a new .msi — it all takes longer than writing the tool itself.\nContainer workflows can also solve packaging, but they often require Docker/Desktop approval, daemon operation, and additional endpoint permissions. In tightly managed enterprise environments, a VM artifact is often easier to deploy and support.\nVMBOX takes a different approach. It wraps the full application stack — OS, runtime, dependencies, and web UI — into a single VirtualBox image. When VirtualBox is available, users can import an .ova, start the VM, and access the tool in a browser with predictable setup steps.\nWhat is VMBOX? # VMBOX is a build system for generating minimal Alpine Linux-based VirtualBox images. Reference builds are lightweight (often around ~150MB compressed), boot quickly on modern hardware, and expose functionality through browser-accessible web interfaces without requiring a full desktop environment.\nAt its core, VMBOX provides:\nImmutable root filesystem — SquashFS-based read-only rootfs with OverlayFS for runtime changes Persistent data partition — Separate ext4 partition for user data and configurations Optional APP partition — A dedicated read-only SquashFS partition for deploying custom web apps and services Factory reset — One-click reset that restores the system to its original state without reimporting the OVA System management dashboard — Built-in web UI for monitoring CPU, memory, disk, network, and managing applications Cross-platform portability — Export as OVA for use on Windows, macOS, or Linux System Architecture # VMBOX uses a multi-partition disk layout designed for reliability and easy updates:\nVMBOX disk layout: BOOT (FAT32) loads the kernel, ROOTFS (SquashFS) holds the immutable Alpine system, DATA (ext4) stores persistent state via OverlayFS, and APP (SquashFS) contains custom applications. The BOOT partition contains the Syslinux bootloader, kernel, and initramfs. The ROOTFS partition is a read-only SquashFS image of Alpine Linux with all base services. The DATA partition provides persistent read-write storage — it holds the OverlayFS upper layer, user home directories, and application data. The optional APP partition is another read-only SquashFS image containing your custom web applications, mounted at /app.\nDuring boot, the initramfs merges the read-only ROOTFS with the read-write DATA partition using OverlayFS. This means the system always has a clean base to fall back to — a factory reset simply wipes the overlay, and on the next reboot you\u0026rsquo;re back to a pristine state.\nApp Delivery as a Single Artifact # The core idea behind VMBOX is that deploying a web application should not require each end user to install and maintain app-specific host runtimes. Compare a traditional rollout with VMBOX:\nTraditional Deployment VMBOX Deployment Install Python/Node runtime Import .ova file Install dependencies Start VM Configure environment Open browser to localhost:8000 Deal with OS-specific issues Done. Navigate endpoint policy approvals Write platform-specific installers This works for any application that can be accessed through a browser: business dashboards, LLM-powered tools, internal APIs, operational utilities, and optional hardware-facing interfaces. Any web framework/runtime that fits your packaging flow can be delivered as a VMBOX image.\nNote Compared with container-first distribution, VMBOX trades daemon/image orchestration for a portable VM artifact and browser-based access. The operating model is straightforward: import, start, and connect.\nSystem Management Dashboard # Every VMBOX image ships with a built-in system management web UI at http://localhost:8000. After boot, sign in (reference builds use admin/brb0x) and change the password on first use. The dashboard provides real-time monitoring and control without requiring SSH for routine operations:\nThe System Management Dashboard: real-time CPU, memory, and disk monitoring, application status, log viewer, and system actions — all accessible from the browser. The dashboard uses Server-Sent Events for 1-second live updates and includes:\nCPU / Memory / Disk gauges with visual progress bars Network statistics — real-time RX/TX traffic Applications panel — status and control of all apps from the APP partition Log viewer — search, filter, clear, and download logs System actions — change password, reboot, factory reset Optional: USB Passthrough for Embedded/Hardware Workflows # For embedded and hardware teams, VMBOX can optionally enable VirtualBox USB passthrough with automatic device filters. This allows selected USB devices to be forwarded to the VM for serial, ADB, or CAN workflows when host policy permits:\nFTDI FT232/FT2232 (VID 0403) — common serial adapters Silicon Labs CP210x (VID 10C4) — USB-to-UART bridges WCH CH340/CH341 (VID 1A86) — budget serial adapters Prolific PL2303 (VID 067B) — serial adapters PCAN-USB (VID 0C72) — CAN bus adapters (optional) Arduino boards (VID 2341) — development boards When passthrough is enabled, a compatible USB adapter can appear inside the VM within seconds. Combined with a web-based terminal or device UI packaged in APP, teams can access hardware workflows through the browser without installing per-tool UI apps on each host.\nNote USB 2.0/3.0 passthrough requires the VirtualBox Extension Pack; USB 1.1 works without it.\nRemote Collaboration via VPN # VMBOX can be paired with an approved VPN or internal network path (for example WireGuard, Tailscale, or enterprise VPN) to enable remote collaboration. Once the VM is reachable, colleagues can access web-based tools through a browser without local app installation.\nThis supports distributed teams and shared lab resources: one engineer can host the VM near equipment, while others access dashboards and tools remotely in scheduled sessions.\nGetting Started # Building a VMBOX image requires a Linux host with standard tools (parted, squashfs-tools, syslinux, virtualbox). The example below builds a demo image with two bundled apps (hello-world and web-terminal):\nClone the repository git clone https://github.com/hackboxguy/vmbox.git cd vmbox Build the base rootfs sudo ./build.sh --mode=base --output=/tmp/alpine-build --version=1.0.1 Build the APP partition sudo ./scripts/build-app-partition.sh \\ --packages=configs/hello-web-terminal-package.txt \\ --output=/tmp/alpine-build/app \\ --rootfs=/tmp/alpine-build/rootfs Create disk image with APP partition sudo ./scripts/03-create-image.sh \\ --rootfs=/tmp/alpine-build/rootfs \\ --output=/tmp/alpine-build \\ --ospart=600M \\ --datapart=200M \\ --apppart=300M \\ --appdir=/tmp/alpine-build/app/app Fix ownership of build output sudo chown -R $(id -u):$(id -g) /tmp/alpine-build Convert to VirtualBox VM ./scripts/04-convert-to-vbox.sh \\ --input=/tmp/alpine-build/alpine-vbox.raw \\ --vmname=vmbox-hello-webterm-demo \\ --appdir=/tmp/alpine-build/app/app \\ --force \\ --memory=1024 Start the VM on Linux VBoxManage startvm \u0026#34;vmbox-hello-webterm-demo\u0026#34; --type headless Or export as OVA for distribution VBoxManage export \u0026#34;vmbox-hello-webterm-demo\u0026#34; -o \u0026#34;vmbox-hello-webterm-demo.ova\u0026#34; After boot completes (typically ~30-60 seconds depending on host resources), open http://localhost:8000 to access the System Management Dashboard.\nTip Add --serial to step 6 to see boot messages in the terminal. To package your own apps, create a custom package list and pass it to build-app-partition.sh in step 3. See the repository README for the full build guide and the VM App Design Guide for creating custom web apps.\nUse Cases # Internal tool distribution — Package web dashboards, APIs, and line-of-business tools as portable VMs Enterprise self-hosted apps — Deliver browser-based workflows without per-user host dependency setup LLM-powered applications — Deliver AI-driven tools as self-contained VMs that run locally without cloud dependencies Lab equipment interfaces — Browser-based control panels for test setups shared across teams Optional embedded/hardware workspaces — Web-based serial terminals, CAN tools, and device management where USB passthrough is enabled Training and demos — Hand out OVA files that work identically on every machine hackboxguy/vmbox Alpine-Linux based virtual-machine creator scripts Shell 0 0 ","date":"17 February 2026","externalUrl":null,"permalink":"/blog/vmbox/","section":"Blog","summary":"","title":"VMBOX: Deliver Web Apps as Self-Contained Virtual Machines","type":"blog"},{"content":"Bring Minecraft-style adventures home — no internet needed.\nIf your kids love sandbox building games but you\u0026rsquo;d rather keep playtime inside your home network, Luanti (an open-source Minetest fork) plus this Dockerized home server is a perfect fit.\nIt ships with two kid-friendly game worlds — Mineclonia and VoxeLibre — including curated mods, texture packs, and a built-in web admin (mtui) so parents can manage everything from a browser.\nNote No Microsoft/Mojang accounts, no public exposure — just a small PC or NAS on your LAN.\nLuanti Docker game server running on a home LAN. Why it\u0026rsquo;s great for families # Runs completely offline on your home LAN — safe from random internet players One admin login for parents; individual accounts for kids Easy web dashboard (mtui) to add users, reset passwords, watch chat, and tweak mods Optional LAN-optimized settings for smoother Wi-Fi gameplay Quick start (Docker) # git clone https://github.com/hackboxguy/minetest-home-server.git cd minetest-home-server GAME_SEED=44569 ADMIN_PASSWORD=supersecret docker-compose up -d Tip ADMIN_PASSWORD sets your first admin password — change it to your own secret. Want a custom admin name? Add ADMIN_USER=yourname GAME_SEED — use any number of your choice to start a new world.\nMineclonia listens on port 30000; VoxeLibre on 30001.\nConnect using your server\u0026rsquo;s LAN IP, for example: 192.168.1.2:30000\nCreate player accounts # Option 1: Web admin (mtui) — Recommended # Open http://\u0026lt;server-ip\u0026gt;:8000 (Mineclonia) or :8001 (VoxeLibre) Log in with your admin account Create users and set passwords Option 2: Command-line helper (uses default \u0026ndash;user=admin) # ./tools/luanti-cli.sh \\ --url=http://192.168.1.2:8000 \\ --password=supersecret \\ --command=\u0026#39;/setpassword user1 user1pw\u0026#39; Repeat for each child, then grant basic permissions via console or mtui:\n/grant user1 interact LAN-only performance mode # If you\u0026rsquo;re only playing at home, use the LAN-tuned compose file for faster terrain loading:\ndocker-compose down docker-compose -f docker-compose.offline.yml up -d Puzzle chest adventures (great for learning) # Note As admin, run /chestmode in-game Select a difficulty (general knowledge, science, math, tech, or random) Enable chest mode and place bright pink puzzle chests by left clicking the mouse button Players must answer questions to unlock chests and earn points The top three players appear on a scoreboard — great motivation for kids! How kids join # Direct connect to your local server (e.g., 192.168.1.2):\nMineclonia 192.168.1.2:30000 VoxeLibre 192.168.1.2:30001 Kids sign in using the usernames and passwords you created.\nParent tips # Note Use mtui to reset passwords or monitor in-game chat Mix free play with puzzle chests for quick learning moments Install the Luanti client on kids\u0026rsquo; PCs (Windows or Linux) Keep your admin password private — kids use their own accounts That\u0026rsquo;s it! Spin it up, create a few accounts, and enjoy cozy offline family adventures.\nhackboxguy/minetest-home-server A self hosted minetest-docker-container Lua 1 0 ","date":"6 January 2026","externalUrl":null,"permalink":"/blog/luanti-server/","section":"Blog","summary":"","title":"Offline Luanti Game Server with Docker for Families","type":"blog"},{"content":"","date":"7 March 2026","externalUrl":null,"permalink":"/tags/attiny85/","section":"Tags","summary":"","title":"ATtiny85","type":"tags"},{"content":"","date":"7 March 2026","externalUrl":null,"permalink":"/blog/","section":"Blog","summary":"","title":"Blog","type":"blog"},{"content":"","date":"7 March 2026","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","date":"7 March 2026","externalUrl":null,"permalink":"/tags/chrome-dino/","section":"Tags","summary":"","title":"Chrome Dino","type":"tags"},{"content":"","date":"7 March 2026","externalUrl":null,"permalink":"/tags/digispark/","section":"Tags","summary":"","title":"Digispark","type":"tags"},{"content":"","date":"7 March 2026","externalUrl":null,"permalink":"/categories/embedded/","section":"Categories","summary":"","title":"Embedded","type":"categories"},{"content":"","date":"7 March 2026","externalUrl":null,"permalink":"/tags/lm393/","section":"Tags","summary":"","title":"LM393","type":"tags"},{"content":"","date":"7 March 2026","externalUrl":null,"permalink":"/","section":"Open Source Embedded Hacks","summary":"","title":"Open Source Embedded Hacks","type":"page"},{"content":"","date":"7 March 2026","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"7 March 2026","externalUrl":null,"permalink":"/tags/usb-hid/","section":"Tags","summary":"","title":"USB HID","type":"tags"},{"content":"","date":"7 March 2026","externalUrl":null,"permalink":"/tags/v-usb/","section":"Tags","summary":"","title":"V-USB","type":"tags"},{"content":"","date":"28 February 2026","externalUrl":null,"permalink":"/tags/docker/","section":"Tags","summary":"","title":"Docker","type":"tags"},{"content":"","date":"28 February 2026","externalUrl":null,"permalink":"/tags/eaglercraftx/","section":"Tags","summary":"","title":"EaglercraftX","type":"tags"},{"content":"","date":"28 February 2026","externalUrl":null,"permalink":"/tags/family/","section":"Tags","summary":"","title":"Family","type":"tags"},{"content":"","date":"28 February 2026","externalUrl":null,"permalink":"/tags/game-server/","section":"Tags","summary":"","title":"Game Server","type":"tags"},{"content":"","date":"28 February 2026","externalUrl":null,"permalink":"/categories/gaming/","section":"Categories","summary":"","title":"Gaming","type":"categories"},{"content":"","date":"28 February 2026","externalUrl":null,"permalink":"/tags/minecraft/","section":"Tags","summary":"","title":"Minecraft","type":"tags"},{"content":"","date":"28 February 2026","externalUrl":null,"permalink":"/tags/offline/","section":"Tags","summary":"","title":"Offline","type":"tags"},{"content":"","date":"18 February 2026","externalUrl":null,"permalink":"/tags/diy/","section":"Tags","summary":"","title":"DIY","type":"tags"},{"content":"","date":"18 February 2026","externalUrl":null,"permalink":"/tags/rotary-encoder/","section":"Tags","summary":"","title":"Rotary Encoder","type":"tags"},{"content":"","date":"18 February 2026","externalUrl":null,"permalink":"/tags/volume-control/","section":"Tags","summary":"","title":"Volume Control","type":"tags"},{"content":"","date":"17 February 2026","externalUrl":null,"permalink":"/tags/alpine-linux/","section":"Tags","summary":"","title":"Alpine Linux","type":"tags"},{"content":"","date":"17 February 2026","externalUrl":null,"permalink":"/tags/enterprise-it/","section":"Tags","summary":"","title":"Enterprise IT","type":"tags"},{"content":"","date":"17 February 2026","externalUrl":null,"permalink":"/tags/ova/","section":"Tags","summary":"","title":"OVA","type":"tags"},{"content":"","date":"17 February 2026","externalUrl":null,"permalink":"/tags/self-hosted/","section":"Tags","summary":"","title":"Self-Hosted","type":"tags"},{"content":"","date":"17 February 2026","externalUrl":null,"permalink":"/tags/virtualbox/","section":"Tags","summary":"","title":"VirtualBox","type":"tags"},{"content":"","date":"17 February 2026","externalUrl":null,"permalink":"/tags/web-apps/","section":"Tags","summary":"","title":"Web Apps","type":"tags"},{"content":"","date":"7 February 2026","externalUrl":null,"permalink":"/tags/dlna/","section":"Tags","summary":"","title":"DLNA","type":"tags"},{"content":"","date":"7 February 2026","externalUrl":null,"permalink":"/tags/infotainment/","section":"Tags","summary":"","title":"Infotainment","type":"tags"},{"content":"","date":"7 February 2026","externalUrl":null,"permalink":"/tags/kodi/","section":"Tags","summary":"","title":"Kodi","type":"tags"},{"content":"","date":"7 February 2026","externalUrl":null,"permalink":"/tags/multi-screen/","section":"Tags","summary":"","title":"Multi-Screen","type":"tags"},{"content":"","date":"7 February 2026","externalUrl":null,"permalink":"/categories/multimedia/","section":"Categories","summary":"","title":"Multimedia","type":"categories"},{"content":"","date":"7 February 2026","externalUrl":null,"permalink":"/tags/poe/","section":"Tags","summary":"","title":"PoE","type":"tags"},{"content":"","date":"7 February 2026","externalUrl":null,"permalink":"/tags/raspberry-pi/","section":"Tags","summary":"","title":"Raspberry Pi","type":"tags"},{"content":"","date":"7 February 2026","externalUrl":null,"permalink":"/tags/self-hosting/","section":"Tags","summary":"","title":"Self-Hosting","type":"tags"},{"content":"","date":"2 February 2026","externalUrl":null,"permalink":"/categories/embedded--iot/","section":"Categories","summary":"","title":"Embedded \u0026 IoT","type":"categories"},{"content":"","date":"2 February 2026","externalUrl":null,"permalink":"/tags/gl-mt300n-v2/","section":"Tags","summary":"","title":"GL-MT300N-V2","type":"tags"},{"content":"","date":"2 February 2026","externalUrl":null,"permalink":"/tags/hardware-bring-up/","section":"Tags","summary":"","title":"Hardware Bring-Up","type":"tags"},{"content":"","date":"2 February 2026","externalUrl":null,"permalink":"/tags/lab-automation/","section":"Tags","summary":"","title":"Lab Automation","type":"tags"},{"content":"","date":"2 February 2026","externalUrl":null,"permalink":"/tags/networking/","section":"Tags","summary":"","title":"Networking","type":"tags"},{"content":"","date":"2 February 2026","externalUrl":null,"permalink":"/tags/openwrt/","section":"Tags","summary":"","title":"OpenWrt","type":"tags"},{"content":"","date":"2 February 2026","externalUrl":null,"permalink":"/series/pocket-router-hacks/","section":"Series","summary":"","title":"Pocket Router Hacks","type":"series"},{"content":"","date":"2 February 2026","externalUrl":null,"permalink":"/tags/remote-debugging/","section":"Tags","summary":"","title":"Remote Debugging","type":"tags"},{"content":"A compact \u0026ldquo;lab-in-a-box\u0026rdquo; that turns a $30 GL-MT300N-V2 pocket router into a remote hardware bring-up station. You get serial console, PoE power control, SD card image swapping, USB power cycling, PiKVM video/keyboard, and a camera feed over a single box.\nNote Quick start: Flash the Remote-Kit firmware, log in at http://192.168.20.1, wire in PoE switch + PiKVM, then update port-forwards to match device IPs.\nWhat Remote-Kit does # Serial terminal to the DUT over SSH (screen) Virtual SD card image loading via SDWire (no physical card swaps) Remote USB power cycle (Tasmota-based XY-WSUSB) PoE power on/off and power measurements (Netgear GS308EP) PiKVM remote display + USB keyboard/mouse emulation Optional USB webcam stream for bench visibility FTP/TFTP for bootloader RAM loading System overview # Example bench wiring for a Pi 4 DUT with PoE power, PiKVM, SDWire, and camera. Warning Security note: Default credentials — Remote-Kit SSH: root / remote-kit-000, PoE switch (GS308EP): password, WiFi SSID/key: remote-kit-000 / remote-kit-000. Change all default passwords before exposing any service to your corporate or public network.\nHardware (Bill of Materials) # Below is a reference setup for a Raspberry Pi 4 as DUT. Prices are from the time of writing and will vary.\nItem Qty Unit Price (EUR) Notes GL.iNet GL-MT300N-V2 1 30 Remote-Kit router 5V MicroUSB PSU (router) 1 10 5V/3A adapter Netgear GS308EP PoE switch 1 90 PoE power control + measurements 5V PoE splitter (USB-C) 2 15 Power PiKVM + DUT 3-port USB hub 1 5 Any basic hub USB flash drive (16 GB) 1 10 Image storage Raspberry Pi 4 2 50 One for PiKVM, one as DUT MicroSD card (16 GB+) 1 10 PiKVM image Geekwork PiKVM kit 1 85 PiKVM hardware USB webcam (UVC) 1 70 Bench visibility Tasmota WiFi smart socket 1 10 Power control (alt to PoE) USB-TTL serial adapter 1 15 Serial console Sinilink XY-WSUSB dongle 1 8 USB power cycle (Tasmota) SDWire (SD card mux) 1 90 Virtual SD card swapping Firmware and services # Custom OpenWrt image for GL-MT300N-V2 Port forwarding for PiKVM, PoE switch, camera, and smart plugs SSH access for scripted automation Utilities: screen, ntgrrc, SDWire scripts Setup steps # Flash the Remote-Kit firmware to the GL-MT300N-V2 (source on GitHub). Connect your PC to the LAN side and log in to http://192.168.20.1. Connect WiFi accessories (smart socket, XY-WSUSB) to SSID remote-kit-000 (key: remote-kit-000). Wire PoE switch, PiKVM, SDWire, and camera to the LAN ports. Change the default GS308EP password from password to something secure. Update port-forwards in OpenWrt to match your device IPs. The firmware ships with these default port-forward rules (all via the router\u0026rsquo;s LAN IP):\nService Port OpenWrt UI 80 USB webcam 8080 PoE switch (GS308EP) 8081 PiKVM 4433 Nous smart socket 8082 XY-WSUSB dongle 8083 Setup diagram for overwriting OEM firmware and wiring up the Remote-Kit router. Note Access points: OpenWrt UI on http://remote-kit-000, PiKVM on https://remote-kit-000:4433, PoE switch on http://remote-kit-000:8081.\nCommon remote workflows # 1) Load a new SD image onto the DUT # ssh root@remote-kit-000 #pw: remote-kit-000 root@remote-kit-000:~# wget -O /mnt/sda1/libreelec-image.img.gz https://releases.libreelec.tv/LibreELEC-RPi4.aarch64-11.95.1.img.gz root@remote-kit-000:~# ntgrrc login --password Remotekit000 --address GS308EP root@remote-kit-000:~# ntgrrc poe set -p 1 --power disable --address GS308EP root@remote-kit-000:~# sd-wire-load-image.sh /mnt/sda1/libreelec-image.img.gz root@remote-kit-000:~# ntgrrc login --password Remotekit000 --address GS308EP root@remote-kit-000:~# ntgrrc poe set -p 1 --power enable --address GS308EP root@remote-kit-000:~# #LibreElec will now boot on Pi-4-DUT - you can see this booting from a remote location using PiKVM\u0026#39;s WebUI. 2) Power cycle the DUT (PoE) # ssh root@remote-kit-000 #pw: remote-kit-000 ntgrrc login --password Remotekit000 --address GS308EP ntgrrc poe set -p 1 --power disable --address GS308EP ntgrrc poe set -p 1 --power enable --address GS308EP 3) Open serial console # ssh root@remote-kit-000 #pw: remote-kit-000 screen -R serial /dev/ttyUSB0 115200 4) Simulate Ethernet cable unplug # ssh root@remote-kit-000 #pw: remote-kit-000 ntgrrc login --password Remotekit000 --address GS308EP ntgrrc port set -p 1 -s \u0026#39;Disable\u0026#39; --address GS308EP #unplug ntgrrc port set -p 1 -s \u0026#39;Auto\u0026#39; --address GS308EP #plug 5) Measure PoE power draw # ssh root@remote-kit-000 #pw: remote-kit-000 ntgrrc login --password Remotekit000 --address GS308EP ntgrrc poe status --address GS308EP #print status in table format ntgrrc poe status --address GS308EP -f json #print in json format Tip Large images: The router has limited RAM — do not decompress multi-GB images on it. For large files (e.g. raspios-bookworm-arm64.img.xz at 2.4 GB): decompress on your PC first, then scp the raw .img to /mnt/sda1/, and run sd-wire-load-image.sh.\nUse cases # Remote OS image testing for embedded boards Regression testing of bootloaders and kernels Remote lab access for distributed teams Automated power and peripheral cycling in CI pipelines hackboxguy/remote-kit Remote HW bringup, testing and debugging toolkit null 1 0 Remote-Kit firmware (.bin)\n","date":"2 February 2026","externalUrl":null,"permalink":"/blog/remote-kit/","section":"Blog","summary":"","title":"Remote-Kit: Pocket Router for Remote Hardware Bring-up","type":"blog"},{"content":"","date":"2 February 2026","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"},{"content":"","date":"25 January 2026","externalUrl":null,"permalink":"/tags/bme680/","section":"Tags","summary":"","title":"BME680","type":"tags"},{"content":"","date":"25 January 2026","externalUrl":null,"permalink":"/tags/can-bus/","section":"Tags","summary":"","title":"CAN Bus","type":"tags"},{"content":"Ambient Light + Air Quality + More — a reliable, low-cost sensor network for home, lab, and in-vehicle prototypes, built around CAN with OTA updates and multi-node management.\nWhy CAN for sensors? # CAN was designed for noisy, distributed environments and it shines when you want dependable, multi-drop communication over long cables. That makes it a strong backbone not only for vehicles, but also for home automation and lab setups where Wi-Fi can be unreliable or too power-hungry.\nThis project builds a CAN-based sensor node and a companion display client that together provide:\nAmbient light, temperature, humidity, pressure, IAQ, CO₂eq, VOC Multi-node addressing (up to 16 nodes on the same bus) Batch operations: --all and --nodes=0,1,2 targeting for discovery, monitoring, OTA, reboot, and more A/B OTA firmware updates over CAN (~3.5 KB/s) with partition verification Live dashboard monitor (updates in-place) and physical node identification (LED blink) Device management and automated sanity testing with a CLI tool System overview # The system has three pieces:\nSensor nodes — ESP32-C3 + ALS + BME680/BME688 + CAN transceiver Monitor/display node — ESP32-C3 + OLED + CAN transceiver Host tool — can-sensor-tool for monitoring, management, and OTA (Linux / SocketCAN) All nodes communicate at 500 kbps over a standard CAN bus.\nSystem overview: sensor nodes + monitor node + CAN-USB adapter + RJ-11 junction board. Hardware design # Core components # ESP32-C3 SuperMini (~$2 board) SN65HVD230 CAN transceiver (3.3 V native — no level-shifting needed) ALS sensor: VEML7700 or OPT3001 (board footprint supports either; mount only one) BME680/BME688 for temperature, humidity, pressure, and IAQ data On-board buck converter: 6–30 V input (12 V typical), generates stable 5 V / 3.3 V locally Power-over-CAN using 6P4C (RJ-11) # The system uses a two-pair telephone cable: one pair for CAN-H / CAN-L, one pair for power. Simple, low-cost, and practical. Tested reliably to 15 m with standard RJ-11 cables.\nRJ-11 junction board — low-cost two-pair power + CAN distribution. This is a ready-made off-the-shelf board available from common electronics marketplaces. Sensor board # Sensor board: ESP32-C3, ALS, BME680, SN65HVD230, buck converter, RJ-11. 3D render of the sensor board PCB. Sensor board sub-modules breakdown. Monitor board # Monitor board with OLED display showing live sensor values. 3D render of the monitor board PCB. Monitor board sub-modules breakdown. Sensor auto-detection (one firmware, many boards) # The sensor firmware auto-detects what\u0026rsquo;s connected at boot:\nALS: VEML7700 (0–120 K lux) or OPT3001 (0–83 K lux) Environmental: BME680 or BME688 A single firmware image works across all hardware variants — no build-time configuration needed.\nCAN architecture (high-level) # Each node gets 32 CAN message IDs (0x20 spacing):\n0x100–0x10F: sensor data for Node 0 (ALS at +0x00, ENV at +0x01, AIQ at +0x02, …) 0x110–0x11F: control/management for Node 0 (stop, start, reboot, OTA, discovery, …) The same layout repeats at +0x20 per node, supporting up to 16 nodes on a single bus. Reserved offsets are available for future sensor types (gas selectivity, mm-wave presence, etc.).\nFull frame layouts and byte-level formats are documented in the repo README.\nReal measurements (sample log) # The default can-sensor-tool monitor shows a live dashboard that updates in-place — no scrolling. With --all, it displays all discovered nodes side by side. Add --verbose for a scrolling log useful for debugging:\n$ can-sensor-tool --all monitor --verbose [Node 0] ALS (OPT3001): 79 lux, seq=13, config=201, status=OK [Node 0] ENV: 24.83°C, 38% RH, 991.2 hPa, status=OK [Node 0] AIQ: IAQ=50 (Good), accuracy=0, CO2=500 ppm, VOC=0 ppm, status=OK [Node 1] ALS (OPT3001): 192 lux, seq=20, config=203, status=OK [Node 1] ENV: 25.09°C, 36% RH, 991.2 hPa, status=OK [Node 1] AIQ: IAQ=50 (Good), accuracy=0, CO2=500 ppm, VOC=0 ppm, status=OK [Node 2] ALS (OPT3001): 0 lux, seq=24, config=200, status=OK [Node 2] ENV: 25.15°C, 35% RH, 991.2 hPa, status=OK Over this run, three nodes on the same bus report concurrently — light levels range from 0 (near-dark) to ~192 lux while temperature stays around 25 °C. IAQ reported \u0026ldquo;Good\u0026rdquo; with CO₂eq at 500 ppm throughout.\nAutomated sanity testing # The can-sensor-tool includes a sanity-test command that exercises the full node lifecycle in one shot — discovery, start/stop, interval accuracy, reboot, node-ID change, factory reset, OTA update, and final re-discovery:\n$ can-sensor-tool sanity-test ./build/esp32-can-sensor.bin [1/9] Discovery... PASS: Node 0 responds to PING [2/9] Device Info... PASS: FW v1.0.1, sensors=0x13, ALS=OPT3001, partition=ota_1 (valid) [3/9] Start/Stop... PASS: Received 3 ALS msgs in 3s, 0 after STOP [4/9] Monitor Interval... PASS: Average interval: 977 ms (target: 1000 ms) [5/9] Reboot... PASS: Node rebooted and recovered in 2005 ms [6/9] Set Node ID... PASS: Successfully changed 0-\u0026gt;1-\u0026gt;0 [7/9] Factory Reset... PASS: Factory reset completed in 2204 ms [8/9] OTA Update... PASS: OTA OK, node booted v1.0.1 on ota_0 (3.2 KB/s, 106369 ms) [9/9] Final Discovery... PASS: Node 0 still responds after all tests Results: 9/9 passed, 0 failed This makes it practical to validate firmware changes end-to-end before deploying to multiple nodes.\nDevice management + OTA over CAN # The can-sensor-tool handles discovery, monitoring, and A/B OTA firmware updates over the CAN bus. With --all or --nodes=0,1,2, most commands target multiple nodes in one invocation.\nMulti-node operations # can-sensor-tool --all info — query all nodes on the bus can-sensor-tool --all monitor — live dashboard with all nodes updating in-place can-sensor-tool --nodes=0,2 reboot — reboot specific nodes can-sensor-tool --all identify — blink the onboard LED on every node for 5 seconds (useful for figuring out which board is which in a multi-node setup) A/B OTA with partition verification # Each OTA update writes to the inactive partition slot, reboots into it, and keeps the previous slot as a rollback target. If the new firmware fails to validate on first boot, the bootloader automatically reverts after 3 attempts.\nThe tool now verifies the update end-to-end: it queries the active partition before the update, waits for the node to reboot, then confirms the node booted from the alternate partition. Batch updates (--all update) run sequentially — each node must come back online before the next update starts, preventing CAN bus disruption from rebooting nodes.\n$ can-sensor-tool --all update ./build/esp32-can-sensor.bin Discovering nodes on can0... Found 3 node(s): 0 1 2 --- OTA Update: Node 0 (1/3) --- Current partition: ota_1 Uploading: [==============================] 100% (334704/334704) 3.6 KB/s Waiting for node 0 to reboot... Node 0 back online (3.6s) Partition switched: ota_1 -\u0026gt; ota_0 (v1.0.2) --- OTA Update: Node 1 (2/3) --- Current partition: ota_1 Uploading: [==============================] 100% (334704/334704) 3.6 KB/s Waiting for node 1 to reboot... Node 1 back online (3.6s) Partition switched: ota_1 -\u0026gt; ota_0 (v1.0.2) --- OTA Update: Node 2 (3/3) --- Current partition: ota_0 Uploading: [==============================] 100% (334704/334704) 3.5 KB/s Waiting for node 2 to reboot... Node 2 back online (3.5s) Partition switched: ota_0 -\u0026gt; ota_1 (v1.0.2) --- OTA Update Summary --- Node 0: OK (ota_1 -\u0026gt; ota_0 (v1.0.2)) Node 1: OK (ota_1 -\u0026gt; ota_0 (v1.0.2)) Node 2: OK (ota_0 -\u0026gt; ota_1 (v1.0.2)) Total: 3/3 succeeded In testing, OTA reaches ~3.5–3.6 KB/s. A ~335 KB firmware image completes in ~93 seconds per node. All three nodes updated and verified in under 5 minutes total.\nUse cases # Home \u0026amp; Lab # Multi-room light + environment monitoring Low-cost wiring with RJ-11 and a junction board Central monitoring on OLED or a PC via SocketCAN In-vehicle prototype (POC) # Rugged wiring and noise-tolerant communication Deterministic update rates across multiple nodes OTA updates without pulling nodes from the vehicle In-vehicle smart ambient sensing # Monitor cabin temperature, humidity, IAQ, CO₂eq, VOC, and BME688-based gas signals for passenger comfort and safety Feed IVI/ADAS systems with real-time ambient conditions for alerts or policy decisions Use ambient light data to adjust in-vehicle displays — HDR10+ Adaptive and Dolby Vision perform real-time dynamic tone-mapping that requires a continuous ambient light input to optimize frame rendering on the display (the HDR10+ Automotive spec mandates this ambient light feed) Add human presence detection (planned) to enable occupancy-aware safety and convenience features Enterprise / larger infrastructure # CAN as a reliable wired sensor backbone Up to 16 nodes per bus today; extendable with multiple bus segments Current limitations and roadmap # Current # No formal environmental or long-term reliability testing yet Human presence detection (mmWave) not implemented Planned # Add mmWave human presence sensor Expand other sensor types using reserved CAN offsets BSEC licensing note # Tip BME680/BME688 air-quality outputs use Bosch Sensortec\u0026rsquo;s BSEC 2.x library, which is proprietary and not included in this repo. To enable it, download the BSEC zip from Bosch, accept their license, and pass it to build.sh (see BME680_SETUP.md in the repo).\nBuild and flash (sensor board) # Install ESP-IDF and download the Bosch BSEC library (e.g. bsec2-6-1-0_generic_release_22102024.zip). Connect the ESP32-C3 board to your PC via USB. Clone the sensor firmware repo and build: git clone https://github.com/hackboxguy/Esp32-CAN-ALS.git cd Esp32-CAN-ALS ./build.sh --target=esp32c3 --idfpath=$HOME/esp/esp-idf/ \\ --version=1.0.1 \\ --bsecpath=/path/to/bsec2-6-1-0_generic_release_22102024.zip ./build.sh --flash Build and flash (monitor board) # Install ESP-IDF. Connect the ESP32-C3 board to your PC via USB. Clone the display client repo and build: git clone https://github.com/hackboxguy/Esp32-CAN-Disp-Client.git cd Esp32-CAN-Disp-Client idf.py set-target esp32c3 idf.py build flash hackboxguy/Esp32-CAN-ALS CAN based in-vehicle ambient light sensor firmware for ESP32 C 1 0 ","date":"25 January 2026","externalUrl":null,"permalink":"/blog/can-sensor/","section":"Blog","summary":"","title":"CAN Bus Multi-Sensor Node with ESP32 and KiCad PCB","type":"blog"},{"content":"","date":"25 January 2026","externalUrl":null,"permalink":"/tags/esp32/","section":"Tags","summary":"","title":"ESP32","type":"tags"},{"content":"","date":"25 January 2026","externalUrl":null,"permalink":"/tags/iot/","section":"Tags","summary":"","title":"IoT","type":"tags"},{"content":"","date":"25 January 2026","externalUrl":null,"permalink":"/tags/kicad/","section":"Tags","summary":"","title":"KiCad","type":"tags"},{"content":"","date":"25 January 2026","externalUrl":null,"permalink":"/tags/ota/","section":"Tags","summary":"","title":"OTA","type":"tags"},{"content":"","date":"25 January 2026","externalUrl":null,"permalink":"/tags/pcb-design/","section":"Tags","summary":"","title":"PCB Design","type":"tags"},{"content":"","date":"25 January 2026","externalUrl":null,"permalink":"/tags/sensors/","section":"Tags","summary":"","title":"Sensors","type":"tags"},{"content":"","date":"17 January 2026","externalUrl":null,"permalink":"/tags/alexa/","section":"Tags","summary":"","title":"Alexa","type":"tags"},{"content":"If you run Domoticz and have an Amazon Echo, this is one of the simplest ways to get voice control while keeping device commands on your local network — no cloud subscriptions, no Alexa skills, no Philips account.\nNote Alexa still uses the internet for speech recognition, but device control stays on your LAN.\nArchitecture overview: voice command → Echo discovers a Hue-bridge emulator → commands are translated to Domoticz API calls → devices respond (locally). What you get # No Philips Hue cloud — emulates a Hue Bridge locally No third-party Alexa skills — Echo\u0026rsquo;s native Hue support handles discovery No subscriptions — runs on any Raspberry Pi or Linux box you already own Local device control — commands stay on your LAN (Echo → Emulator → Domoticz) The problem with typical Alexa integrations # A lot of smart-home voice control flows through vendor clouds and Alexa skills: you install a skill, link accounts, and every action takes a detour through the internet. That can add latency, create privacy concerns, and introduce dependencies on services that can change, break, or become paid.\nIf you already run Domoticz, the question is natural: why can\u0026rsquo;t Alexa talk to your system directly? The answer is: it can — if you present your devices in a way Alexa already understands.\nWhat is Domoticz Hue Emulator? # Domoticz Hue Emulator is a lightweight Python service that emulates a Philips Hue Bridge on your local network. Amazon Echo devices have native support for Hue bridges, which means Alexa can discover and control devices without an Alexa skill.\nThe emulator makes Alexa believe it\u0026rsquo;s talking to a Hue bridge, but behind the scenes it translates those requests into Domoticz API calls for your switches, dimmers, RGB lights, and scenes/groups.\nHow it fits together # Voice Command → Amazon Echo → (local Hue protocol) Hue Emulator (Python) → Domoticz API → Switches / Dimmers / RGB Lights / Scenes Features at a glance # On/Off control for switches Dimming (brightness control) for dimmers and RGB lights RGB color control (e.g., \u0026ldquo;set lamp to red\u0026rdquo;, \u0026ldquo;warm white\u0026rdquo;) Scenes/Groups support for controlling multiple devices at once Easy YAML configuration Runs as a systemd service (auto-start) Voice command examples # Basic on/off # \u0026ldquo;Alexa, turn on Living Room Light\u0026rdquo; \u0026ldquo;Alexa, turn off Kitchen Light\u0026rdquo; Dimming (dimmer/rgb types) # \u0026ldquo;Alexa, set Bedroom Light to 50 percent\u0026rdquo; \u0026ldquo;Alexa, dim Living Room Light\u0026rdquo; \u0026ldquo;Alexa, brighten Bedroom Light\u0026rdquo; Colors (rgb type only) # \u0026ldquo;Alexa, set Lamp to red\u0026rdquo; \u0026ldquo;Alexa, set Lamp to blue\u0026rdquo; \u0026ldquo;Alexa, set Lamp to warm white\u0026rdquo; Scenes and groups # \u0026ldquo;Alexa, turn on All Lights\u0026rdquo; \u0026ldquo;Alexa, turn off All Lights\u0026rdquo; (groups only) Requirements # Raspberry Pi or any Linux server on the same network as your Echo Domoticz running with devices configured Python 3.7+ Port 80 available (required by the Hue Bridge protocol) Tip If port 80 is in use by Apache, Nginx, or another service, you must stop or reconfigure it for the emulator to work.\nInstallation \u0026amp; setup # 1) Clone the repository # git clone https://github.com/hackboxguy/domoticz-hue-emulator.git cd domoticz-hue-emulator 2) Install (or test with a dry run) # # Test installation (dry run) sudo ./install.sh --domoticz-user=YOUR_USER --domoticz-pw=YOUR_PW --dryrun # Install sudo ./install.sh --domoticz-user=YOUR_USER --domoticz-pw=YOUR_PW 3) Configure your devices in alexa-devices.yaml # Add your Domoticz devices by name, IDX, and type (switch, dimmer, rgb). You can find IDX values in Domoticz under Setup \u0026gt; Devices.\ndomoticz: url: \u0026#34;http://localhost:8080\u0026#34; username: \u0026#34;admin\u0026#34; password: \u0026#34;yourpassword\u0026#34; devices: - name: \u0026#34;Living Room Light\u0026#34; idx: 10 type: dimmer - name: \u0026#34;RGB Lamp\u0026#34; idx: 30 type: rgb 4) Restart the service # sudo systemctl restart domoticz-hue-emulator 5) Discover devices # Now the fun part:\n\u0026#34;Alexa, discover devices\u0026#34; Within seconds, your Domoticz devices should appear inside Alexa as controllable lights.\nTip Scenes vs groups: In Domoticz, Scenes only support ON (activate), while Groups support ON and OFF. If you need voice control to turn devices both on and off, create a Domoticz group.\nScenes, groups, and routines # The emulator supports Domoticz scenes/groups so you can control multiple devices with a single command. It also pairs nicely with Alexa Routines for custom phrases like \u0026ldquo;Alexa, let\u0026rsquo;s start the party\u0026rdquo; — mapped to a Domoticz scene or group.\nTroubleshooting # Alexa doesn\u0026rsquo;t discover devices # Confirm the service is running: sudo systemctl status domoticz-hue-emulator Verify port 80 is available: sudo ss -tlnp | grep :80 Check logs for SSDP activity: sudo journalctl -u domoticz-hue-emulator -f Device shows \u0026ldquo;not responding\u0026rdquo; # Verify Domoticz is reachable: curl http://localhost:8080 Confirm the device IDX is correct in alexa-devices.yaml Review logs for API errors: sudo journalctl -u domoticz-hue-emulator -f Port 80 already in use # Stop or reconfigure the conflicting service (often Apache, Nginx, or another bridge).\nHow it works (under the hood) # SSDP discovery: the emulator answers Alexa\u0026rsquo;s UPnP/SSDP discovery requests (UDP 1900), announcing itself as a Hue Bridge. Hue API emulation: Alexa reads Hue-compatible JSON describing your Domoticz devices as \u0026ldquo;lights\u0026rdquo;. Command translation: Alexa commands are translated into Domoticz API calls (on/off, brightness, color). Local device control: commands stay on your LAN (Echo → Emulator → Domoticz). Alexa still uses the internet for speech recognition. hackboxguy/domoticz-hue-emulator A set of scripts and configs to enable Amazon echo(alexa) based voice command integration with domoticz home server Python 0 0 ","date":"17 January 2026","externalUrl":null,"permalink":"/blog/hue-emulator/","section":"Blog","summary":"","title":"Alexa Controls Domoticz via Philips Hue Emulator","type":"blog"},{"content":"","date":"17 January 2026","externalUrl":null,"permalink":"/tags/domoticz/","section":"Tags","summary":"","title":"Domoticz","type":"tags"},{"content":"","date":"17 January 2026","externalUrl":null,"permalink":"/categories/home-automation/","section":"Categories","summary":"","title":"Home Automation","type":"categories"},{"content":"","date":"17 January 2026","externalUrl":null,"permalink":"/tags/philips-hue/","section":"Tags","summary":"","title":"Philips Hue","type":"tags"},{"content":"","date":"17 January 2026","externalUrl":null,"permalink":"/tags/python/","section":"Tags","summary":"","title":"Python","type":"tags"},{"content":"","date":"17 January 2026","externalUrl":null,"permalink":"/tags/smart-home/","section":"Tags","summary":"","title":"Smart Home","type":"tags"},{"content":"","date":"17 January 2026","externalUrl":null,"permalink":"/tags/voice-control/","section":"Tags","summary":"","title":"Voice Control","type":"tags"},{"content":"","date":"6 January 2026","externalUrl":null,"permalink":"/tags/luanti/","section":"Tags","summary":"","title":"Luanti","type":"tags"},{"content":"","date":"6 January 2026","externalUrl":null,"permalink":"/tags/mineclonia/","section":"Tags","summary":"","title":"Mineclonia","type":"tags"},{"content":"","date":"6 January 2026","externalUrl":null,"permalink":"/tags/minetest/","section":"Tags","summary":"","title":"Minetest","type":"tags"},{"content":"","date":"6 January 2026","externalUrl":null,"permalink":"/tags/voxelibre/","section":"Tags","summary":"","title":"VoxeLibre","type":"tags"},{"content":"","date":"19 April 2024","externalUrl":null,"permalink":"/tags/car/","section":"Tags","summary":"","title":"Car","type":"tags"},{"content":"Build your own in-car entertainment system — individual touch displays for each passenger, streaming multimedia over a local network with no internet required. Using off-the-shelf hardware and open-source software, each screen costs around $180–$200.\nWhat\u0026rsquo;s New (Feb 2026) # Pre-built SD card image — Download, flash, and boot. No manual installation needed. Download here (~1.2GB) Rock-solid sync — Integrated kodisync for frame-accurate synchronization. Now achieves sub-10ms sync spread (vs. multiple attempts needed before) Auto-negotiation — No more manual master/slave configuration. Each Pi generates a unique hostname from its MAC address and devices auto-discover each other One image for all — Flash the same image to all SD cards. No per-device configuration required Complete wiring diagram: PoE switch powers each Raspberry Pi + touch screen over a single Ethernet cable. How it works # The system uses a distributed architecture — no central multi-head controller needed. Each passenger screen is an independent Raspberry Pi 4 running Kodi, powered and networked through a single Ethernet cable via Power over Ethernet (PoE). A pocket router acts as the DLNA/DHCP server, serving media files from a USB drive to all screens on the local network.\nWhat you need # Component Role PoE switch Powers and networks all Raspberry Pi screens over single Ethernet cables GL-MT300N-V2 pocket router DLNA media server + DHCP server (see pocket router DLNA guide) Raspberry Pi 4 + PoE HAT Media player endpoint (one per passenger screen) Full HD touch display Passenger-facing screen (one per seat) USB media drive Stores multimedia files, plugged into the pocket router Why this architecture # Single-cable per screen — PoE eliminates separate power cables, simplifying in-car wiring Distributed decoding — each Raspberry Pi handles its own multimedia decoding and rendering, so there is no central bottleneck Easily scalable — add more screens by swapping in a PoE switch with more ports Fully offline — works in areas with no mobile coverage; all content is served locally Individual or shared playback — each passenger can browse and play their own content, or all screens can be synchronized Cost per screen # Note Each passenger display costs approximately $180–$200, including the Raspberry Pi 4, PoE HAT, and a full HD touch screen. The PoE switch and pocket router are shared across all screens.\nSoftware stack # Kodi — open-source media player running on each Raspberry Pi, with DLNA client support built in OpenWrt + minidlna — runs on the pocket router, serving media files over DLNA Raspberry Pi OS — base operating system for the Pi endpoints media-mux — synchronization software that coordinates playback across all screens Tip For the DLNA server setup on the pocket router, see the companion post: Transforming Your GL-MT300N-V2 Pocket Router into a DLNA Multimedia Server.\nInstallation # Option 1: Pre-built Image (Recommended)\nThe easiest way to get started — download and flash the same image to all SD cards:\nDownload the pre-built image (~1.2GB) Flash to each SD card using balenaEtcher or Rufus Insert SD cards into your Raspberry Pi 4\u0026rsquo;s and boot That\u0026rsquo;s it! Each Pi automatically generates a unique hostname and discovers other devices on the network.\nOption 2: Manual Installation\nFor custom setups, you can install on an existing Raspberry Pi OS. See the manual installation guide for step-by-step instructions.\nHow sync works # Connect a 3-key USB keyboard to any Raspberry Pi — this becomes the sync trigger device. Press KEY_1 to synchronize all screens:\nThe sync script reads the currently playing media and position from the trigger device Discovers all media-mux devices on the network via Avahi/mDNS Opens the same media file on all devices Uses kodisync to pause all players at the exact same frame Seeks all players to the same position and resumes playback simultaneously Note Sync accuracy: The system achieves sub-200ms synchronization, typically with less than 10ms spread between devices. This is a significant improvement over the earlier version shown in the video, which required multiple sync attempts.\nhackboxguy/media-mux Raspberry Pi Media player customization scripts C\u0026#43;\u0026#43; 4 0 github.com/hackboxguy/multiscreen-media\nTip Version 2 now available: A self-hosting version that eliminates the pocket router. One Pi becomes the master automatically, providing DHCP, DNS, NTP, and DLNA. See Self-Hosting PoE Raspberry Pi 4 Infotainment System.\n","date":"19 April 2024","externalUrl":null,"permalink":"/blog/diy-car-infotainment/","section":"Blog","summary":"","title":"DIY In-Car Infotainment with Raspberry Pi and Kodi","type":"blog"},{"content":"","date":"16 April 2024","externalUrl":null,"permalink":"/tags/aws-iot/","section":"Tags","summary":"","title":"AWS IoT","type":"tags"},{"content":"","date":"16 April 2024","externalUrl":null,"permalink":"/tags/c++/","section":"Tags","summary":"","title":"C++","type":"tags"},{"content":"","date":"16 April 2024","externalUrl":null,"permalink":"/tags/cloud/","section":"Tags","summary":"","title":"Cloud","type":"tags"},{"content":"","date":"16 April 2024","externalUrl":null,"permalink":"/tags/embedded-linux/","section":"Tags","summary":"","title":"Embedded Linux","type":"tags"},{"content":"While the internet is flooded with hello-world examples and simulations demonstrating the connection and message exchange between AWS-IoT Devices and AWS-IoT-Core using various programming languages like Python, C, C++, and Java, some of us beginners, students, or enthusiasts find true satisfaction in delving into the world of connected devices through hands-on interactions with physical components. The real excitement lies in experiencing the tangible effects firsthand, rather than merely observing basic hello-world messages on a computer screen.\nDemo Video # How It Works # In this video, I introduce an engaging approach for exploring AWS-IoT connectivity and its real-world implications using affordable and readily available hardware components sourced from online stores. For this demonstration, I use an affordable (~$30) GL.iNet pocket router as an IoT End-Node.\nThis router runs on a custom-built OpenWRT Linux image and hosts an AWS IoT device agent service based on the aws-iot-device-sdk-cpp-v2. The WebUI of this custom Linux image allows you to easily configure and provision AWS IoT-specific settings such as:\nDevice certificates and private keys AWS IoT Endpoints Publish/subscribe topic trigger events Custom scripts to control hardware accessories (switches, relays, LEDs, sensors) hackboxguy/aws-iot-demo aws-iot publish/subscribe demo on embedded linux hw null 2 0 ","date":"16 April 2024","externalUrl":null,"permalink":"/blog/aws-iot/","section":"Blog","summary":"","title":"Getting Started with AWS IoT on OpenWrt Routers","type":"blog"},{"content":"","date":"16 April 2024","externalUrl":null,"permalink":"/tags/gl.inet/","section":"Tags","summary":"","title":"GL.iNet","type":"tags"},{"content":"","date":"16 April 2024","externalUrl":null,"permalink":"/tags/mqtt/","section":"Tags","summary":"","title":"MQTT","type":"tags"},{"content":"","date":"10 March 2024","externalUrl":null,"permalink":"/tags/in-car-entertainment/","section":"Tags","summary":"","title":"In-Car Entertainment","type":"tags"},{"content":"","date":"10 March 2024","externalUrl":null,"permalink":"/tags/media-server/","section":"Tags","summary":"","title":"Media Server","type":"tags"},{"content":"","date":"10 March 2024","externalUrl":null,"permalink":"/categories/networking/","section":"Categories","summary":"","title":"Networking","type":"categories"},{"content":"","date":"10 March 2024","externalUrl":null,"permalink":"/tags/pocket-router/","section":"Tags","summary":"","title":"Pocket Router","type":"tags"},{"content":"Turn a ~$30 GL-MT300N-V2 pocket router into a standalone DLNA media server — no internet required. Flash a custom OpenWrt firmware, plug in a USB drive with your media files, and any device on the Wi-Fi hotspot can stream via VLC or any DLNA client.\nIn-car setup: pocket router powered by a 12 V-to-5 V adapter, paired with a USB media drive. All smart devices on the hotspot can stream via DLNA. What you need # GL-MT300N-V2 pocket router (~$30) USB flash drive or USB hard drive (NTFS formatted) 5 V DC power source (USB charger, power bank, or 12 V-to-5 V adapter for car use) VLC Player (or any DLNA client) on your smartphone or tablet Setup steps # Download the custom firmware — get gl-mt300nv2-dlnasrv.bin (~13 MB), an OpenWrt-based image with DLNA pre-configured. Flash the firmware — replace the OEM firmware on your GL-MT300N-V2 with the downloaded gl-mt300nv2-dlnasrv.bin file. Prepare your media disk — format a USB drive as NTFS and copy your media files into Audio/, Video/, and Photo/ folders. Power on — attach the media disk to the router\u0026rsquo;s USB port and power the router with a 5 V source. Connect to Wi-Fi — the router broadcasts a hotspot with SSID dlnaserver and password goodlife. Open VLC — install VLC Player on your device, connect to the hotspot, and navigate to Local Network. The DLNA server (penguin icon) will appear with all your media files. Tip Default credentials: SSID = dlnaserver, password = goodlife. These are for initial setup only — change them immediately (see Security section below).\nStep-by-step screenshots # The following image walks through the full flashing and configuration process in 16 slides:\nComplete setup walkthrough: firmware flash, USB disk preparation, Wi-Fi connection, and VLC media browsing. After following all 16 slides, connect your smartphone or tablet to the dlnaserver hotspot (password goodlife) and open VLC to browse media over the local network.\nVLC Player on Android showing the DLNA server and available media files. In-car infotainment use case # For those with an extensive multimedia collection, this compact DLNA server works well as an in-car infotainment system. Passengers can stream local media on their smartphones or tablets via the shared Wi-Fi hotspot — no mobile data or internet connection needed. This is especially useful during long drives through areas with poor network coverage.\nThe setup is simple: a pocket router powered by a 12 V-to-5 V DC adapter, paired with a USB media drive. When powered on, it creates a Wi-Fi hotspot and serves files over DLNA to all connected devices.\nSecurity # Warning Change the default credentials immediately. Modify the web UI login password, Wi-Fi SSID, and Wi-Fi password through the standard OpenWrt web interface at http://192.168.8.1.\ngithub.com/hackboxguy/openwrt-wrapper\ngl-mt300nv2-dlnasrv.bin\n","date":"10 March 2024","externalUrl":null,"permalink":"/blog/pocket-router-dlna/","section":"Blog","summary":"","title":"Pocket Router as a Portable DLNA Media Server","type":"blog"},{"content":"","date":"10 March 2024","externalUrl":null,"permalink":"/tags/vlc/","section":"Tags","summary":"","title":"VLC","type":"tags"},{"content":"","date":"22 June 2023","externalUrl":null,"permalink":"/tags/esp8266/","section":"Tags","summary":"","title":"ESP8266","type":"tags"},{"content":"","date":"22 June 2023","externalUrl":null,"permalink":"/tags/gpio/","section":"Tags","summary":"","title":"GPIO","type":"tags"},{"content":"","date":"22 June 2023","externalUrl":null,"permalink":"/tags/headless/","section":"Tags","summary":"","title":"Headless","type":"tags"},{"content":"","date":"22 June 2023","externalUrl":null,"permalink":"/tags/led/","section":"Tags","summary":"","title":"LED","type":"tags"},{"content":"","date":"22 June 2023","externalUrl":null,"permalink":"/tags/pushbutton/","section":"Tags","summary":"","title":"Pushbutton","type":"tags"},{"content":"How to interface rugged metal pushbuttons with LED rings to a headless Raspberry Pi — using the built-in triggerhappy daemon to invoke scripts on button press and provide LED feedback, with no display or keyboard needed.\nConnection diagram — two pushbuttons wired to Raspberry Pi GPIO pins. How it works # Instead of userspace I/O libraries, this approach uses the triggerhappy daemon (built into Raspbian) to map standard key codes from /dev/input/eventX to scripts via /etc/triggerhappy/triggers.d/actions.conf.\nOverview of the steps:\nConnect pushbuttons to Raspberry Pi GPIOs as shown in the connection diagram Prepare a Raspberry Pi OS Lite SD card using Raspberry Pi Imager SSH into the Raspberry Pi Add dtoverlay config lines to /boot/config Create push-buttons.conf under /etc/triggerhappy/triggers.d/ Modify /lib/systemd/system/triggerhappy.service to run as the pi user Create action scripts configured in push-buttons.conf Reboot and press a button to see the configured action invoked Prepare the SD card # Download the Raspberry Pi Imager Open the app → CHOOSE OS → Raspberry Pi OS (Other) → Raspberry Pi OS Lite (32-bit) Insert the SD card and click CHOOSE STORAGE Press Ctrl + Shift + X to open advanced options Set hostname, enable SSH, username/password, and local time settings as shown below, then click SAVE Click WRITE to create the bootable SD card Raspberry Pi Imager — advanced options for headless setup. Setup and demo # Connect two pushbuttons to Raspberry Pi GPIO pins as shown in the connection diagram Insert the SD card, connect the Pi to your local DHCP network, and power on SSH in: ssh pi@my-raspi-001 (use the password from the Imager advanced options) Run the following commands: sudo apt-get install -y git esptool git clone https://github.com/hackboxguy/pi-pushbtn-demo.git cd pi-pushbtn-demo sudo ./setup.sh sudo reboot Running the setup commands on the Raspberry Pi. Wait ~40 seconds for the Pi to reboot. Press one pushbutton — its LED ring blinks at ~2 Hz. Press the other button — its LED starts blinking and the first one stops.\nExtending the demo # Instead of just blinking LEDs, the buttons can invoke real tasks. For example, to flash different firmware binaries to an ESP8266 (e.g. Wemos D1 Mini) on button press, replace the action scripts:\ncp /home/pi/pi-pushbtn-demo/flash-esp-1hz.sh /home/pi/pi-pushbtn-demo/key-pressed-down.sh cp /home/pi/pi-pushbtn-demo/flash-esp-4hz.sh /home/pi/pi-pushbtn-demo/key-pressed-up.sh After this change, pressing a button blinks the LED ring for ~30 seconds (indicating the Wemos D1 Mini is being flashed), then stops when flashing completes. See the 1 Hz flash script and 4 Hz flash script for details.\nComplete setup — rugged metal pushbuttons connected to the Raspberry Pi. hackboxguy/pi-pushbtn-demo Push-button-demo-for-raspberrypi Shell 0 0 ","date":"22 June 2023","externalUrl":null,"permalink":"/blog/raspi-metal-button/","section":"Blog","summary":"","title":"Rugged Metal Buttons with LED Rings on Raspberry Pi","type":"blog"},{"content":"","date":"22 June 2023","externalUrl":null,"permalink":"/tags/triggerhappy/","section":"Tags","summary":"","title":"Triggerhappy","type":"tags"},{"content":"","date":"18 November 2022","externalUrl":null,"permalink":"/tags/2fa/","section":"Tags","summary":"","title":"2FA","type":"tags"},{"content":"","date":"18 November 2022","externalUrl":null,"permalink":"/tags/3g-modem/","section":"Tags","summary":"","title":"3G Modem","type":"tags"},{"content":"","date":"18 November 2022","externalUrl":null,"permalink":"/tags/bridge/","section":"Tags","summary":"","title":"Bridge","type":"tags"},{"content":"Bridge your mobile SMS with XMPP instant messaging so you can read and send text messages from anywhere over the internet. The primary use case: receiving 2FA verification codes while travelling internationally, without roaming or asking someone at home to read them out for you.\nSetup overview — a Raspberry Pi with a USB 3G modem bridges SMS to XMPP via a public Jabber server. The setup uses a Raspberry Pi with a Huawei E173 (or E303) USB 3G dongle and an encrypted XMPP connection to deliver SMS securely to your phone\u0026rsquo;s chat app. All code is open source, and you can use any public Jabber server (or host your own with Prosody).\nPreparing the SD card # Download the Raspberry Pi Imager Open it and select: CHOOSE OS → Raspberry Pi OS (Other) → Raspberry Pi OS Lite (32-bit) Select your SD card via CHOOSE STORAGE Press Ctrl + Shift + X to open the advanced options Set hostname, enable SSH, username, password, and timezone as shown below, then click SAVE Click WRITE to create the bootable SD card Raspberry Pi Imager — advanced options for hostname, SSH, and credentials. Setting up the Raspberry Pi # Insert your SIM card (PIN lock must be disabled) into the Huawei E173/E303 dongle and connect it to the Raspberry Pi Keep the Pi powered on and connected to your home internet 24/7 Once booted, SSH in: ssh pi@my-raspi-001 Install the XMPP remote agent: sudo apt-get install -y git git clone --recursive https://github.com/hackboxguy/xmpp-remote-agent.git cd xmpp-remote-agent ./setup.sh -u raspi-sim-1@jabber.de -p my-raspi-xmpp-secret-pw sudo reboot; exit Tip Replace the example XMPP username and password with your own credentials. The setup.sh script may take 10–15 minutes on a Raspberry Pi 1.\nOn your phone\u0026rsquo;s Xabber app (Android or iOS), log in with your XMPP account (e.g. john.doe@jabber.de). The Raspberry Pi should appear online — send help to get the list of available commands.\nReading SMS # smsupdate # fetch SMS from SIM to cache (wait for Success response) smstotal # show number of cached messages smsget 0 # read the first message Sending SMS # smssend +919876543210 this is a test message Deleting SMS # When the SIM memory is full, new messages stop arriving. Delete all stored messages with:\nsmsdeleteall Voice dialling and USSD codes # Ring a GSM phone (caller ID shows as SIM-1\u0026rsquo;s number, no audio — ringing only):\ndialvoice +919876543210 Check prepaid balance or send other USSD codes:\ndialussd *100# # send USSD code (wait for Success response) readussd # read the carrier\u0026#39;s response How it works internally # Two services run on the Raspberry Pi:\nbboxsmsrv — based on libgammu, handles SMS read/write/delete via the USB 3G modem xmproxysrv — based on libgloox, acts as a headless XMPP client that logs into the Jabber server and maintains an always-on connection When a 2FA SMS arrives, it is stored in the SIM memory by the 3G modem. On your phone\u0026rsquo;s Xabber app, you send smsupdate → xmproxysrv parses the command and asks bboxsmsrv to fetch messages from the SIM → once complete, a Success response is sent back → you then read the messages with smsget.\nFor sending, the flow reverses: your chat message travels through the XMPP server to xmproxysrv, which hands it to bboxsmsrv, which sends the SMS via the 3G modem — delivering an SMS to any phone number without roaming charges.\nhackboxguy/xmpp-remote-agent Installer scripts for deploying xmpp based remote again on Linux machines Shell 0 0 github.com/hackboxguy/brbox\n","date":"18 November 2022","externalUrl":null,"permalink":"/blog/sms-xmpp-bridge/","section":"Blog","summary":"","title":"Bridge SMS to XMPP: Receive 2FA Codes Abroad","type":"blog"},{"content":"","date":"18 November 2022","externalUrl":null,"permalink":"/tags/jabber/","section":"Tags","summary":"","title":"Jabber","type":"tags"},{"content":"","date":"18 November 2022","externalUrl":null,"permalink":"/tags/sms/","section":"Tags","summary":"","title":"SMS","type":"tags"},{"content":"","date":"18 November 2022","externalUrl":null,"permalink":"/tags/xmpp/","section":"Tags","summary":"","title":"XMPP","type":"tags"},{"content":"How to flash a ~$30 GL.iNet MT300N-V2 pocket router with a custom OpenWrt image that includes the AWS IoT Device SDK and an aws-iot-pubsub-demo application — turning it into an AWS IoT Edge device that can feed local sensor data to the cloud.\nGL.iNet MT300N-V2 pocket router — ready to become an AWS IoT Edge device. Quick overview # Three steps to turn your pocket router into an AWS IoT Edge device:\nFlash the OEM firmware with the custom gl-mt300nv2-awsiot-demo.bin Upload your AWS-generated device certificate and private key via the web UI Reboot and watch Hello World messages published to your AWS IoT Core Flashing the firmware # Step 1 — Connect your PC to the pocket router via Ethernet and power it on. Wait for the LED to stop blinking.\nSetup: PC connected to the pocket router via Ethernet cable. Step 2 — Open http://192.168.8.1/cgi-bin/luci/admin/system/flashops in your browser (or follow GL.iNet\u0026rsquo;s onboarding process).\nStep 3 — Find the firmware upgrade menu and flash with gl-mt300nv2-awsiot-demo.bin.\nWarning Important: Disable \u0026ldquo;Keep settings\u0026rdquo; — you want to start with default settings.\nStep 4 — Wait about 2 minutes until the LEDs stop blinking.\nStep 5 — Disconnect and reconnect the Ethernet cable on your PC so it gets a new IP in the 192.168.20.x range.\nStep 6 — Navigate to http://192.168.20.1 — you should see the new web UI:\nCustom firmware web UI after successful flash. AWS IoT configuration # Step 7 — Upload your device certificate and private key files through the web UI:\nUpload your AWS-generated device certificate and private key. Step 8 — Go to AWS-IoT → Service Settings, enter your endpoint, and click Save \u0026amp; Apply.\nTip Before clicking Save \u0026amp; Apply, ensure your security policies on console.aws.amazon.com are set up correctly (see Step 10 below).\nService Settings — enter your AWS IoT endpoint here. Step 9 — Check the Service Log. If everything is configured correctly, you should see a \u0026ldquo;connection success\u0026rdquo; message:\nService Log — \u0026ldquo;connection success\u0026rdquo; confirms the router is connected to AWS IoT Core. Step 10 — On console.aws.amazon.com, ensure your security policies are set correctly:\nAWS IoT security policies — required permissions for the device. Testing publish and subscribe # Step 11 — On console.aws.amazon.com, subscribe to topic test/topic to see Hello World messages published from your pocket router. By default, the demo publishes 10 messages at 5-second intervals. To publish continuously, increase the Publish Count in the Service Settings page.\nAWS IoT Core — Hello World messages arriving from the pocket router. Step 12 — To test the subscribe action, publish a JSON message to topic test/topic_led from the AWS console to control the router\u0026rsquo;s LED:\n{\u0026#34;powerstate\u0026#34; : \u0026#34;on\u0026#34;} {\u0026#34;powerstate\u0026#34; : \u0026#34;off\u0026#34;} Publishing LED control commands from the AWS IoT console. Other use cases # The pocket router can act as a gateway between AWS IoT Core and local Wi-Fi or USB-connected devices:\nPossible use cases — the pocket router bridges local devices to AWS IoT Core. github.com/hackboxguy/openwrt-wrapper\ngl-mt300nv2-awsiot-demo.bin\n","date":"9 October 2022","externalUrl":null,"permalink":"/blog/pocket-router-aws/","section":"Blog","summary":"","title":"$30 Pocket Router as an AWS IoT Edge Device","type":"blog"},{"content":"","date":"9 October 2022","externalUrl":null,"permalink":"/tags/edge-device/","section":"Tags","summary":"","title":"Edge Device","type":"tags"},{"content":"","date":"2 October 2022","externalUrl":null,"permalink":"/tags/beaglebone/","section":"Tags","summary":"","title":"BeagleBone","type":"tags"},{"content":"","date":"2 October 2022","externalUrl":null,"permalink":"/tags/buildroot/","section":"Tags","summary":"","title":"Buildroot","type":"tags"},{"content":"","date":"2 October 2022","externalUrl":null,"permalink":"/tags/latency/","section":"Tags","summary":"","title":"Latency","type":"tags"},{"content":"A ready-to-use bootable SD card image for BeagleBone Black/Green with a fully preemptible Linux kernel (PREEMPT_RT) — includes a gpio-test program that mirrors an input signal to a GPIO output pin for measuring scheduler latency with an oscilloscope.\nOscilloscope view — yellow is the input signal, blue is the GPIO output. The phase difference indicates scheduler latency. Note Thanks to Maxime Chevallier of Bootlin for providing the gpio-test demo utility during PREEMPT_RT training.\nSetup diagram # Setup diagram — signal generator feeds the BeagleBone, oscilloscope measures input vs output. Items needed # BeagleBone Black or Green +5 V power adapter Micro SD card (1 GB or larger) Programmable signal generator board 2-channel oscilloscope Jumper wires Instructions # Prepare the setup as shown in the diagram (set signal generator to 100 Hz, 50% duty cycle) Download sdcard-beaglebone-preemptrt-demo.img.xz (~25 MB) Write the image to a micro SD card using Balena Etcher Insert the SD card into the BeagleBone and power on After boot, the oscilloscope shows two square waves with a phase difference — yellow (input) and blue (output from BeagleBone) The phase difference indicates the latency introduced by the scheduler while running the preemptrt-gpiotest program Tip On startup, /etc/init.d/S99PreemptrtGpioTester invokes:\nchrt -r 99 /usr/sbin/preemptrt-gpiotest gpiochip0 28 gpiochip0 17 h p This starts the gpio-test utility at real-time priority 99.\nMeasuring latency under load # The gpio-test program mirrors a GPIO input to an output — the phase difference between the two signals shows how fast the scheduler delivers context to your application. Jitter on the output signal (measured in oscilloscope persist mode) indicates the best and worst case scheduler latency under different load conditions (network traffic, interrupts, etc.).\nPersist mode — showing best and worst case scheduler latency under load. For further details on PREEMPT_RT, see Bootlin\u0026rsquo;s PREEMPT_RT training material.\nBuilding from source # Detailed build instructions are available in the git repository. Cross-compile instructions for modifying and running a customized gpio-test utility are also available.\nhackboxguy/preemptrt-gpiotest A gpio based test utility for measuring the latency on Linux-preempt-rt system C 2 0 github.com/hackboxguy/br-wrapper\nsdcard-beaglebone-preemptrt-demo.img.xz\n","date":"2 October 2022","externalUrl":null,"permalink":"/blog/raspi-preempt-rt/","section":"Blog","summary":"","title":"Measuring PREEMPT_RT Latency with an Oscilloscope","type":"blog"},{"content":"","date":"2 October 2022","externalUrl":null,"permalink":"/tags/oscilloscope/","section":"Tags","summary":"","title":"Oscilloscope","type":"tags"},{"content":"","date":"2 October 2022","externalUrl":null,"permalink":"/tags/preempt_rt/","section":"Tags","summary":"","title":"PREEMPT_RT","type":"tags"},{"content":"","date":"2 October 2022","externalUrl":null,"permalink":"/tags/real-time-linux/","section":"Tags","summary":"","title":"Real-Time Linux","type":"tags"},{"content":"Six simple steps to get an AWS IoT Device SDK demo running on a Raspberry Pi 4 — using a lightweight custom Linux image built with Buildroot (just under 25 MB).\nQuick start # Download sdcard-pi4-aws-iot-demo.img.xz (~25 MB) Write the image to an SD card using Balena Etcher Unplug and re-plug the SD card so the boot partition appears on your PC Open aws-iot-pubsub-agent.conf and set your AWS IoT endpoint Copy your AWS-generated device certificate (xyz-certificate.pem) and private key (xyz-private.pem.key) to the boot partition Insert the SD card into the Raspberry Pi 4, power on — the aws-iot-pubsub-agent will start publishing messages to your AWS IoT Core The following image shows steps 4, 5, and 6 in detail:\nSteps 4–6: configure endpoint, copy certificates, and boot the Pi. AWS cloud preparation # Before booting the Pi, set up the following on console.aws.amazon.com:\nCreate an AWS IoT account (payment details required even for the free tier) Navigate to IoT Core Go to Manage → All Devices → Things → Create Thing Download the device certificate and private key (copy these to the SD card boot partition as described in step 5 above) Go to Settings and note your Endpoint (needed for step 4 above) Go to Security → Policies and create a policy with 4 entries as shown below: AWS IoT security policy — required permissions for the device. Building the image from source # Two commands to build the SD card image (detailed instructions in the git repository):\nmake -C buildroot BR2_EXTERNAL=../ BR2_DL_DIR=../../br-dl O=../../br-output raspberrypi4_aws_iot_defconfig make -C buildroot BR2_EXTERNAL=../ BR2_DL_DIR=../../br-dl O=../../br-output Buildroot customizations # Key changes in the Raspberry Pi 4 Buildroot config for this AWS demo image:\nEnabled Dropbear SSH for remote debugging without monitor/keyboard Added Buildroot package for aws-iot-device-sdk-cpp-v2 Added Buildroot package for aws-iot-pubsub-agent Enabled chrony for time sync (required for TLS handshake) Enabled SDK dependencies (host-cmake, libcurl, openssl, util-linux) Included AmazonRootCA1.pem in /etc/ Added aws-iot-pubsub-agent.conf to rootfs for the agent startup script Added /etc/init.d/S03MountBoot to mount the boot partition at /mnt/certs (contains certificates, key, and config) Included startup script for aws-iot-pubsub-agent After booting # Connect the Raspberry Pi 4 to a DHCP network with internet access Find the Pi on your network using hostname buildroot or its assigned IP Log in via SSH: ssh root@192.168.x.y (password: brb0x) Check the publish log: cat /tmp/aws-iot-pubsub-agent.log To modify the aws-iot-pubsub-agent code, see how to cross-compile and run on target Note If everything is configured correctly (SD card and AWS security policies), Hello World! messages will appear on your AWS IoT Core console:\nAWS IoT Core — Hello World messages arriving from the Raspberry Pi 4. github.com/hackboxguy/br-wrapper\nsdcard-pi4-aws-iot-demo.img.xz\n","date":"24 September 2022","externalUrl":null,"permalink":"/blog/raspi-iot-sdk/","section":"Blog","summary":"","title":"AWS IoT on Raspberry Pi with 25 MB Buildroot Linux","type":"blog"},{"content":"","date":"24 September 2022","externalUrl":null,"permalink":"/tags/custom-linux/","section":"Tags","summary":"","title":"Custom Linux","type":"tags"},{"content":"","date":"24 September 2022","externalUrl":null,"permalink":"/tags/embedded/","section":"Tags","summary":"","title":"Embedded","type":"tags"},{"content":"","date":"24 September 2022","externalUrl":null,"permalink":"/tags/iot-sdk/","section":"Tags","summary":"","title":"IoT SDK","type":"tags"},{"content":"","date":"3 July 2020","externalUrl":null,"permalink":"/tags/cc2531/","section":"Tags","summary":"","title":"CC2531","type":"tags"},{"content":"A one-script installer that turns a Raspberry Pi + CC2531 USB adapter into a vendor-neutral Zigbee home automation gateway running Domoticz — supporting 800+ Zigbee devices from any manufacturer.\nRaspberry Pi with CC2531 USB Zigbee adapter — the complete Pimoticz hardware. The problem # Cheap Zigbee home automation devices are everywhere, but they\u0026rsquo;re locked to the manufacturer\u0026rsquo;s gateway — limiting you to a small set of supported devices. With commercial off-the-shelf (COTS) hardware, you can build your own vendor-neutral gateway, but it requires setting up multiple components:\nRaspberry Pi CC2531 USB Zigbee adapter (with Koenkk firmware, ~$12 on Amazon) Raspberry Pi OS (32-bit) Node.js (v12 or higher) zigbee2mqtt Mosquitto MQTT broker Domoticz zigbee2mqtt plugin for Domoticz For beginners, getting all these components working together is a challenging task. Pimoticz simplifies this with an automated installer script — in about 5 minutes you should be ready to pair your first Zigbee device.\nItems needed # Raspberry Pi Micro SD card 5V power adapter CC2531 USB Zigbee adapter Warning Important: To avoid the CC2531 programming setup, buy a pre-programmed USB adapter with Koenkk firmware (CC2531_DEFAULT_20190608.zip or higher).\nRaspberry Pi OS setup # Tip CC2531 USB adapter, keyboard, mouse, monitor, and internet connection are only needed during the initial setup.\nStep 1 — Prepare the SD card using Raspberry Pi Imager and install Raspberry Pi OS 32-bit.\nStep 2 — Insert the SD card, connect keyboard/mouse/monitor and internet to your Raspberry Pi, then power on.\nStep 3 — On first boot, the setup wizard will guide you through:\nLanguage and keyboard layout (important for correct local time — Domoticz needs it) Set a new password for the pi user Black border check (not important — Raspi will run headless after setup) Wi-Fi setup (skip if using Ethernet) Software update (optional — can skip to save time) Reboot to apply settings Pimoticz software stack — zigbee2mqtt, Mosquitto, and Domoticz working together. Pimoticz installation # Open a terminal on the Raspberry Pi (locally or via SSH) and run:\ngit clone https://github.com/hackboxguy/pimoticz.git cd /home/pi/pimoticz sudo ./setup.sh -h my-pimoticz # -h hostname is optional # wait ~5 minutes for setup to complete sudo reboot Setup script in progress — installing all dependencies automatically. After reboot, open a browser and navigate to http://127.0.0.1:8080 or http://my-pimoticz:8080 — Domoticz will show the detected CC2531 Zigbee coordinator.\nDomoticz running on Pimoticz — CC2531 Zigbee coordinator detected and ready to pair devices. Note Your Pimoticz gateway is ready. You can now pair Zigbee devices from any manufacturer — Xiaomi, IKEA, Philips Hue, Sonoff, and 800+ more.\nhackboxguy/pimoticz domoticz on raspi Shell 0 0 ","date":"3 July 2020","externalUrl":null,"permalink":"/blog/pimoticz/","section":"Blog","summary":"","title":"Vendor-Neutral Zigbee Gateway with Raspberry Pi","type":"blog"},{"content":"","date":"3 July 2020","externalUrl":null,"permalink":"/tags/zigbee/","section":"Tags","summary":"","title":"Zigbee","type":"tags"},{"content":"","date":"3 July 2020","externalUrl":null,"permalink":"/tags/zigbee2mqtt/","section":"Tags","summary":"","title":"Zigbee2mqtt","type":"tags"},{"content":"","date":"27 February 2020","externalUrl":null,"permalink":"/tags/digital-signage/","section":"Tags","summary":"","title":"Digital Signage","type":"tags"},{"content":"","date":"27 February 2020","externalUrl":null,"permalink":"/tags/hdmi/","section":"Tags","summary":"","title":"HDMI","type":"tags"},{"content":"","date":"27 February 2020","externalUrl":null,"permalink":"/tags/media-player/","section":"Tags","summary":"","title":"Media Player","type":"tags"},{"content":"","date":"27 February 2020","externalUrl":null,"permalink":"/tags/pi-zero/","section":"Tags","summary":"","title":"Pi Zero","type":"tags"},{"content":"","date":"27 February 2020","externalUrl":null,"permalink":"/tags/yarmp/","section":"Tags","summary":"","title":"YARMP","type":"tags"},{"content":"A lightweight Buildroot-based media player image (\u0026lt;65 MB) for Raspberry Pi that autoplays video, audio, or images in a loop — booting in under 20 seconds.\nSupports all Pi 1 variants (Pi Zero, Pi Zero W, Pi A/B, Pi A+/B+) Works on older Pis with just 256 MB RAM and a 1 GB SD card Autoplays media from the internal SD card or an external FAT-formatted USB drive Battery-powered Pi Zero running YARMP as a digital photo album on a 7-inch LCD — under $50 total. Quick start — 3 steps # Download raspi-yarmp.img.xz to your PC Write the image to an SD card using Balena Etcher Insert the SD card into your Pi and power on — the default video starts playing in a loop Step 1: Select the YARMP image in Balena Etcher. Step 2: Select the SD card as target. Step 3: Flash the image to the SD card. Flashing in progress. Flash complete — SD card is ready. Playing your own media # Remove the SD card from the Pi and plug it into your PC Browse to USRDAT:\\media-files\\ and find sample-video.mkv Delete or back up the sample file, then add your own media (video, audio, or images) to the media-files directory Insert the SD card back into the Pi and power on — your media plays in a loop Tip If you can\u0026rsquo;t find the USRDAT drive on Windows, try a USB SD card reader or mount it on Linux. Alternatively, copy your media to a FAT-formatted USB drive and plug it into the Pi — on boot, external USB media takes priority over the internal SD card.\nPlayback priority # When multiple media types are present, YARMP follows this priority order:\nVideo files (highest priority) Audio files (e.g. MP3) Image files (e.g. JPG, PNG) If no media is found on USB or SD card, the default BBC motion gallery video plays Seamless looping # By default, a single video file plays in seamless loop mode — no black screen between loops. For multiple videos to play seamlessly, merge them into one file using the melt tool.\nFor photo slideshows, adjust the display delay by editing /mnt/userdata/rc.local on the Pi (look for the fbv command line section).\nUse cases # Digital signage Portable HDMI audio/video test source (Pi Zero + battery bank) Art installations — display your work on a loop Museum exhibits — low-cost media playback Science projects — small HDMI display with custom content Digital photo album on an HDMI display Hardware photos # Pi Zero with 7-inch LCD — front view. Pi Zero with 7-inch LCD — rear view showing battery bank. raspi-yarmp.img.xz\n","date":"27 February 2020","externalUrl":null,"permalink":"/blog/raspi-media-player/","section":"Blog","summary":"","title":"YARMP: Lightweight Raspberry Pi Media Player","type":"blog"},{"content":"","date":"25 September 2019","externalUrl":null,"permalink":"/tags/dc-dc-converter/","section":"Tags","summary":"","title":"DC-DC Converter","type":"tags"},{"content":"How to power a Raspberry Pi 3/4 over an Ethernet cable (up to 100 m) using passive PoE — with off-the-shelf parts costing under ~$2.\nComplete setup — Raspberry Pi powered over Ethernet via passive PoE. Warning Warning: This uses passive PoE with T568B wiring:\nBlue / Blue-White → + (positive) terminal of DC supply Brown-White / Brown → − (negative) terminal of DC supply If you don\u0026rsquo;t know what passive PoE is, do not proceed — buy a proper PoE HAT instead. Parts needed # 1. PoE injector cable (~$0.80)\nPoE injector cable — splits power and data onto the Ethernet cable. Connector detail of the PoE injector cable. Wiring detail of the PoE injector cable. 2. DC-DC buck converter (~$0.50) — look for Hesai brand on AliExpress, 12–24 V input, 5 V / 3 A output.\nDC-DC buck converter — 12–24 V input to 5 V / 3 A output. Assembly # 3. Solder jumper wires — Cut female-to-female jumper wire into 4 pieces and solder to the buck converter as shown:\nJumper wires soldered to the DC-DC buck converter. Wiring diagram — connecting the buck converter to the PoE splitter. 4. Heatshrink and connect — Cover the DC-DC converter in a heatshrink sleeve and connect to the Raspberry Pi:\nDC-DC converter in heatshrink sleeve, connected to the Raspberry Pi. 5. Final setup — Feed 12 V DC and network into the PoE injector, then run a CAT-5 cable (up to 100 m) between the injector and the Raspberry Pi:\nComplete setup — 12 V DC + network through PoE injector to Raspberry Pi over CAT-5. ","date":"25 September 2019","externalUrl":null,"permalink":"/blog/raspi-poe/","section":"Blog","summary":"","title":"DIY Passive PoE for Raspberry Pi Under $2","type":"blog"},{"content":"","date":"25 September 2019","externalUrl":null,"permalink":"/tags/ethernet/","section":"Tags","summary":"","title":"Ethernet","type":"tags"},{"content":"","date":"25 September 2019","externalUrl":null,"permalink":"/tags/passive-poe/","section":"Tags","summary":"","title":"Passive PoE","type":"tags"},{"content":"","date":"25 September 2019","externalUrl":null,"permalink":"/tags/power/","section":"Tags","summary":"","title":"Power","type":"tags"},{"content":"","date":"24 August 2019","externalUrl":null,"permalink":"/tags/a5-v11/","section":"Tags","summary":"","title":"A5-V11","type":"tags"},{"content":"","date":"24 August 2019","externalUrl":null,"permalink":"/tags/firmware/","section":"Tags","summary":"","title":"Firmware","type":"tags"},{"content":"Step-by-step guide to replace the stock Qualcomm firmware on an A5-V11 pocket router (~$5) with OpenWrt, giving you a fully hackable Linux device.\nWhat you need # A5-V11 pocket router (Qualcomm variant) FAT-formatted USB flash drive PC with Ethernet port Ethernet cable 5 V USB power source Step 1 — Prepare the USB drive # Download and unzip a5-v11-openwrt.zip onto a FAT-formatted USB flash drive.\nWarning Important: Do not just copy the .zip file — extract it so the folder containing openwrt-factory.bin, the bootloader, and update scripts sits at the root of the drive.\nStep 2 — Connect the hardware # Wire up the A5-V11, USB drive, PC, and power as shown:\nHardware setup: A5-V11 router with USB flash drive, Ethernet to PC, and 5 V power. Step 3 — Power on and wait # Apply 5 V power. The RED LED stays on for a few seconds, then the BLUE LED starts blinking (takes about 1 minute from power-on). Your PC should receive an IP in the 192.168.100.x range from the router\u0026rsquo;s DHCP server.\nStep 4 — Verify Qualcomm firmware # Open the router\u0026rsquo;s web UI and confirm it shows the Qualcomm interface:\nQualcomm OEM web interface — confirm your router shows this page before continuing. Qualcomm firmware detail page. Warning Stop here if your router\u0026rsquo;s web page looks different from the screenshots above. You may have a Chinese firmware variant — follow this other guide instead.\nStep 5 — Telnet in and flash # Open a telnet session to the router using PuTTY or a terminal:\nTelnet session to the A5-V11 router. Run the firmware flash commands as shown:\nRunning the OpenWrt flash commands via telnet. Step 6 — Reboot into OpenWrt # After reboot, wait about a minute. OpenWrt will boot and your PC will get an IP in the 192.168.1.x range. Open a browser and you should see the OpenWrt LuCI interface:\nOpenWrt LuCI login screen — use the defaultrootuser with no password. OpenWrt dashboard. From here you can flash your own custom OpenWrt variant via System → Backup/Flash Firmware. Tip Next step: You can now overwrite this base OpenWrt image with your own custom build via the System → Backup/Flash Firmware menu.\ngithub.com/hackboxguy/downloads — a5-v11-openwrt.zip\n","date":"24 August 2019","externalUrl":null,"permalink":"/blog/a5v11-openwrt/","section":"Blog","summary":"","title":"Flash OpenWrt on the A5-V11 Pocket Router","type":"blog"},{"content":"","date":"24 August 2019","externalUrl":null,"permalink":"/tags/flashing/","section":"Tags","summary":"","title":"Flashing","type":"tags"},{"content":"","date":"24 August 2019","externalUrl":null,"permalink":"/tags/router/","section":"Tags","summary":"","title":"Router","type":"tags"},{"content":"","date":"3 January 2019","externalUrl":null,"permalink":"/tags/esp-12f/","section":"Tags","summary":"","title":"ESP-12F","type":"tags"},{"content":"","date":"3 January 2019","externalUrl":null,"permalink":"/tags/led-lights/","section":"Tags","summary":"","title":"LED Lights","type":"tags"},{"content":"","date":"3 January 2019","externalUrl":null,"permalink":"/tags/mosfet/","section":"Tags","summary":"","title":"MOSFET","type":"tags"},{"content":"","date":"3 January 2019","externalUrl":null,"permalink":"/tags/tasmota/","section":"Tags","summary":"","title":"Tasmota","type":"tags"},{"content":"A DIY Wi-Fi-controlled 5 V switcher for USB LED fairy lights, built around an ESP-12F module running Tasmota firmware. Powered by a battery bank, it lets you toggle garden lights remotely from your phone — no 230 V wiring outdoors and no freezing walks to the power outlet.\nThe lights # \u0026ldquo;USB Fairy Lights\u0026rdquo; or \u0026ldquo;USB String Lights\u0026rdquo; — 10 m / 100 LEDs, available from China for under ~$3. They are 5 V USB-powered and weather-proof (except the USB connector).\nThe 100-LED circuit with 5.1 Ohm series resistor — consumes ~1.8 W at 5 V. Close-up of a single LED — brightness difference between first and last LED is barely noticeable from a distance. The ESP-12F 5 V switcher # An ESP-12F module with a MOSFET switches the USB 5 V supply to the LED string. Running Tasmota firmware, it connects to your Wi-Fi network and can be controlled from a phone or any MQTT/HTTP client.\nComplete setup — battery bank, ESP-12F switcher, and LED fairy lights. Tip With Tasmota\u0026rsquo;s default configuration (no deep sleep), the battery bank needs recharging every few days. A larger battery and ESP8266 deep sleep could extend runtime to weeks.\nAssembly # Note Before starting, ensure the ESP-12F module is pre-programmed with Tasmota (or any OTA-capable firmware). See ESP-12F programming guide for first-time flashing.\nItems needed:\nStep 1:\nStep 2:\nStep 3:\nStep 4:\nStep 5:\nStep 6:\nStep 7:\nStep 8:\nStep 9:\nFinal assembly:\nCompleted setup — ESP-12F switcher between battery bank and LED fairy lights. ","date":"3 January 2019","externalUrl":null,"permalink":"/blog/wifi-led-switcher/","section":"Blog","summary":"","title":"Wi-Fi LED Fairy Light Controller with ESP8266","type":"blog"},{"content":"","date":"3 January 2019","externalUrl":null,"permalink":"/tags/wifi/","section":"Tags","summary":"","title":"WiFi","type":"tags"},{"content":"A custom OpenWrt firmware (autom8box) that packs router + Domoticz server + MQTT broker into an all-in-one home automation gateway running on a ~$20 off-the-shelf GL-MT300N-V2 pocket router.\nSystem overview: GL-MT300N-V2 running autom8box firmware as Wi-Fi AP, MQTT broker, and Domoticz server. The problem # Wi-Fi based home automation products are cheaper than Zigbee or Z-Wave, but they typically require internet connectivity. Letting cloud servers control your home devices is not ideal — internet should be optional, not mandatory.\nThanks to the open-source community (Tasmota, ESPurna, etc.) for helping jailbreak devices like Sonoff, Blitzwolf, and Teckin. But jailbreaking solves only part of the problem — you still need a home automation gateway: Wi-Fi access point + MQTT broker + automation server (Domoticz, OpenHAB, etc.).\nWhat autom8box provides # Wi-Fi access point — dedicated network for your IoT devices DHCP and DNS server — automatic network configuration MQTT broker (Mosquitto) — message bus for IoT devices Domoticz — home automation dashboard and rules engine GL-MT300N-V2 (~$20) — compact pocket router running the autom8box firmware. Tip Limitations: Limited Wi-Fi range and a reduced set of Domoticz plugins due to the 16 MB flash limit. But it\u0026rsquo;s a good starting point for low-budget home automation.\nFlashing steps # Step 1 — Download autom8box-mt300nv2.bin.\nStep 2 — Power on the GL-MT300N-V2 and wait for its SSID to appear (shown as GL-MT300N-V2-xxx).\nOEM SSID appearing in the Wi-Fi list. Step 3 — Connect to the SSID. When prompted for a password, enter goodlife (printed on the device\u0026rsquo;s back sticker).\nEnter the default Wi-Fi password. Step 4 — Once connected, you should see the confirmation message:\nSuccessfully connected to the router. Step 5 — Open a browser and navigate to:\nhttp://192.168.8.1/cgi-bin/luci/admin/system/flashops\nLuCI login — leave the password box empty and click \u0026ldquo;Login\u0026rdquo;. Step 6 — In the firmware update section, uncheck \u0026ldquo;Keep settings\u0026rdquo;, choose autom8box-mt300nv2.bin, then click \u0026ldquo;Flash Image\u0026rdquo;.\nFirmware upload — uncheck \u0026ldquo;Keep settings\u0026rdquo; and select the autom8box binary. File selected — ready to flash. Step 7 — Click \u0026ldquo;Proceed\u0026rdquo; to confirm:\nConfirm flashing — click \u0026ldquo;Proceed\u0026rdquo;. Step 8 — Wait about 2 minutes for the flash to complete:\nFirmware flashing in progress — wait for the device to reboot. Step 9 — After reboot, a new SSID autom8box will appear. Connect with password goodlife.\nThe new autom8box SSID is now visible. Step 10 — Open http://192.168.8.1:8080 in your browser — Domoticz is ready:\nDomoticz home automation dashboard — running entirely on the pocket router. Post-setup security # SSH credentials: user root, password goodlife\nChange root password:\npasswd root Change Wi-Fi password:\nuci set wireless.default_radio0.key=my-new-password uci commit wireless wifi Change SSID:\nuci set wireless.default_radio0.ssid=my-new-ssid uci commit wireless wifi Warning Important: autom8box does not auto-save the Domoticz database. After configuring your devices, SSH in and run reboot — during reboot the database is saved from RAM to the persistent partition. A hard power cut without rebooting may lose your configuration.\ngithub.com/hackboxguy/lede-a5v11\nautom8box-mt300nv2.bin\n","date":"1 January 2019","externalUrl":null,"permalink":"/blog/domoticz-gateway/","section":"Blog","summary":"","title":"$20 Pocket Router as Domoticz Smart Home Gateway","type":"blog"},{"content":"","date":"1 January 2019","externalUrl":null,"permalink":"/tags/gl-mt300n/","section":"Tags","summary":"","title":"GL-MT300N","type":"tags"},{"content":" Albert David Prolinix is my personal lab and blog where I document hands-on embedded projects, from custom PCBs and firmware to Linux-based systems for automotive and IoT applications.\nBy day I work as a System Architect at Harman, designing automotive display architectures, real-time video pipelines, and embedded platform software. Outside of work, I build open-source tools and hardware — CAN-based sensor nodes, pocket router hacks, DIY infotainment systems, and whatever else lands on the workbench.\nWhat you\u0026rsquo;ll find here # Embedded Linux projects (Buildroot, OpenWrt, kernel/driver work) Custom PCB designs with KiCad IoT and home automation builds Firmware for ESP32, ATtiny85, and other microcontrollers Practical tutorials with schematics, BOMs, and source code Start here # CAN Bus Multi-Sensor Node with ESP32 and KiCad PCB — full hardware + firmware + OTA project One Cable, Many Screens: A Self-Hosting PoE Raspberry Pi 4 Infotainment System — multi-screen Raspberry Pi architecture Remote-Kit: Pocket Router for Remote Hardware Bring-up — remote lab workflows and automation Alexa Controls Domoticz via Philips Hue Emulator — local-first home automation voice control Build a Low-Cost DIY USB Volume Knob with Digispark ATtiny85 — quick, affordable microcontroller build What you can expect # Practical, build-first guides instead of theory-only writeups Cost-conscious part choices and off-the-shelf components Reusable scripts, GitHub repositories, and troubleshooting notes Clear focus on self-hosting, reliability, and local control Connect # GitHub: hackboxguy YouTube: @hackboxguy X: @hackboxguy LinkedIn: Albert David ","externalUrl":null,"permalink":"/about/","section":"Open Source Embedded Hacks","summary":"About Albert David and Prolinix","title":"About","type":"page"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"A collection of open-source embedded systems, IoT, and home automation projects. Each project includes hardware designs, firmware, build guides, and GitHub repositories.\nEmbedded \u0026amp; IoT # CAN Bus Multi-Sensor Node with ESP32 and KiCad PCB 25 January 2026\u0026middot;8 mins\u0026middot; loading \u0026middot; loading Embedded CAN Bus ESP32 BME680 Sensors IoT OTA PCB Design KiCad VMBOX: Deliver Web Apps as Self-Contained Virtual Machines 17 February 2026\u0026middot;6 mins\u0026middot; loading \u0026middot; loading Embedded VirtualBox Alpine Linux Web Apps Self-Hosted Enterprise IT OVA Remote-Kit: Pocket Router for Remote Hardware Bring-up 2 February 2026\u0026middot;4 mins\u0026middot; loading \u0026middot; loading Embedded \u0026amp; IoT OpenWrt GL-MT300N-V2 Remote Debugging Hardware Bring-Up Lab Automation Networking Rugged Metal Buttons with LED Rings on Raspberry Pi 22 June 2023\u0026middot;2 mins\u0026middot; loading \u0026middot; loading Embedded Raspberry Pi GPIO Pushbutton Triggerhappy LED Headless ESP8266 Build a Low-Cost DIY USB Volume Knob with Digispark ATtiny85 18 February 2026\u0026middot;4 mins\u0026middot; loading \u0026middot; loading Embedded ATtiny85 Digispark USB HID Rotary Encoder DIY Volume Control Home Automation # Alexa Controls Domoticz via Philips Hue Emulator 17 January 2026\u0026middot;5 mins\u0026middot; loading \u0026middot; loading Home Automation Alexa Philips Hue Domoticz Smart Home Voice Control Python Vendor-Neutral Zigbee Gateway with Raspberry Pi 3 July 2020\u0026middot;3 mins\u0026middot; loading \u0026middot; loading Home Automation Zigbee Raspberry Pi Domoticz CC2531 MQTT Zigbee2mqtt $20 Pocket Router as Domoticz Smart Home Gateway 1 January 2019\u0026middot;3 mins\u0026middot; loading \u0026middot; loading Home Automation Domoticz MQTT OpenWrt GL-MT300N Tasmota IoT Smart Home Wi-Fi LED Fairy Light Controller with ESP8266 3 January 2019\u0026middot;2 mins\u0026middot; loading \u0026middot; loading Home Automation ESP8266 Tasmota LED Lights WiFi DIY ESP-12F MOSFET IoT Multimedia # One Cable, Many Screens: A Self-Hosting PoE Raspberry Pi 4 Infotainment System 7 February 2026\u0026middot;7 mins\u0026middot; loading \u0026middot; loading Multimedia Raspberry Pi Infotainment PoE Kodi DLNA Multi-Screen Self-Hosting DIY DIY In-Car Infotainment with Raspberry Pi and Kodi 19 April 2024\u0026middot;4 mins\u0026middot; loading \u0026middot; loading Multimedia Raspberry Pi Kodi DLNA PoE Infotainment Car DIY OpenWrt YARMP: Lightweight Raspberry Pi Media Player 27 February 2020\u0026middot;3 mins\u0026middot; loading \u0026middot; loading Multimedia Raspberry Pi Media Player Buildroot Pi Zero Digital Signage HDMI YARMP Networking # Pocket Router as a Portable DLNA Media Server 10 March 2024\u0026middot;3 mins\u0026middot; loading \u0026middot; loading Networking DLNA OpenWrt GL-MT300N-V2 Media Server Pocket Router VLC In-Car Entertainment $30 Pocket Router as an AWS IoT Edge Device 9 October 2022\u0026middot;3 mins\u0026middot; loading \u0026middot; loading Embedded \u0026amp; IoT AWS IoT OpenWrt GL-MT300N-V2 Pocket Router MQTT Edge Device IoT DIY Passive PoE for Raspberry Pi Under $2 25 September 2019\u0026middot;2 mins\u0026middot; loading \u0026middot; loading Networking Raspberry Pi PoE Passive PoE DC-DC Converter Ethernet Power DIY Flash OpenWrt on the A5-V11 Pocket Router 24 August 2019\u0026middot;2 mins\u0026middot; loading \u0026middot; loading Networking OpenWrt A5-V11 Router Firmware Flashing DIY Embedded Linux Bridge SMS to XMPP: Receive 2FA Codes Abroad 18 November 2022\u0026middot;3 mins\u0026middot; loading \u0026middot; loading Networking SMS XMPP Raspberry Pi 2FA Jabber 3G Modem Bridge Self-Hosted Cloud \u0026amp; IoT SDKs # Getting Started with AWS IoT on OpenWrt Routers 16 April 2024\u0026middot;1 min\u0026middot; loading \u0026middot; loading Embedded \u0026amp; IoT AWS IoT OpenWrt GL.iNet MQTT Embedded Linux IoT Cloud C\u0026#43;\u0026#43; AWS IoT on Raspberry Pi with 25 MB Buildroot Linux 24 September 2022\u0026middot;3 mins\u0026middot; loading \u0026middot; loading Embedded \u0026amp; IoT Raspberry Pi AWS IoT Buildroot Custom Linux IoT SDK Embedded MQTT Other # Offline Luanti Game Server with Docker for Families 6 January 2026\u0026middot;3 mins\u0026middot; loading \u0026middot; loading Gaming Luanti Minetest Docker Game Server Mineclonia VoxeLibre Offline Family Measuring PREEMPT_RT Latency with an Oscilloscope 2 October 2022\u0026middot;2 mins\u0026middot; loading \u0026middot; loading Embedded PREEMPT_RT BeagleBone Real-Time Linux Latency GPIO Buildroot Oscilloscope ","externalUrl":null,"permalink":"/projects/","section":"Projects","summary":"","title":"Projects","type":"projects"}]