Compare commits

...

4 Commits

Author SHA1 Message Date
Kaloyan Danchev
d2f49e9130 Add Vaultwarden sync script for MikroTik cold standby
Syncs the Vaultwarden database, RSA key, and config from Unraid
to the MikroTik container standby instance via a temporary PHP
HTTP server. Designed for manual daily runs before maintenance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 11:21:24 +02:00
Kaloyan Danchev
4305657ad0 Add Bosch Home Connect integration to HA setup docs
Oven (HRG7784B1) and Washing Machine (WGB24400BY) added via OAuth2.
Both dashboards updated with Bosch appliance sections.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 19:23:46 +02:00
Kaloyan Danchev
5af3c9478b Add Home Assistant setup documentation
Covers HAOS VM setup, Xiaomi/Gree/Tuya integrations, visionOS theme,
Mushroom Cards dashboards (mobile + desktop), and known issues.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 11:30:17 +02:00
Kaloyan Danchev
c93f7da733 Add Unraid flash drive migration procedure
Flash drive on XTRM-U is failing. Created incident doc with complete
step-by-step procedure: backup retrieval (4 options), new USB prep via
Flash Creator, license transfer via Tools→Registration, post-migration
verification checklist, and prevention measures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 15:14:43 +02:00
5 changed files with 396 additions and 0 deletions

View File

@@ -6,6 +6,10 @@
## 2026-02-06
### Unraid Flash Drive Failure
- **[INCIDENT]** Unraid flash drive crashing - migration procedure created
- **[DOCS]** Created incident report with full flash drive replacement procedure
### Documentation Restructure
- **[DOCS]** Restructured docs/ from 23 files to clean 9-doc structure
- **[DOCS]** Archived 12 completed VLAN migration project docs to archive/vlan-migration/

View File

@@ -0,0 +1,200 @@
# Incident: Unraid Flash Drive Failure
**Date:** 2026-02-06
**Severity:** P1 - Server at risk
**Status:** In Progress
**Affected:** XTRM-U (Unraid NAS)
---
## Symptoms
Unraid flash drive experiencing crashes/instability. Risk of complete failure and data loss of boot configuration.
---
## Migration Procedure: Replace Flash Drive
### Step 1: Retrieve Flash Backup
Try these options in order of preference:
**Option A - Fresh backup from WebGUI (if server still boots):**
1. Open http://192.168.10.20 in browser
2. Go to **Main** tab → click on **Flash** device
3. Under Flash Device Settings, click **FLASH BACKUP**
4. Download the ZIP file to your Mac
**Option B - Google Drive (daily Rclone backup):**
```bash
# From Mac (if rclone is installed)
rclone copy drive:Backups/unraid-flash ~/Desktop/unraid-flash-backup/
# Or download manually from Google Drive web UI
# Folder: Backups/unraid-flash
```
**Option C - Local backup on Unraid (if server boots but WebGUI broken):**
```bash
ssh -i ~/.ssh/id_ed25519_unraid root@192.168.10.20 -p 422
# Backup is at:
ls /mnt/user/Backup/unraid-flash/
# Copy it off the server:
scp -P 422 -i ~/.ssh/id_ed25519_unraid root@192.168.10.20:/mnt/user/Backup/unraid-flash/* ~/Desktop/unraid-flash-backup/
```
**Option D - Direct copy from failing drive:**
1. Shut down server
2. Remove flash drive, insert into Mac
3. Copy entire contents to `~/Desktop/unraid-flash-backup/`
---
### Step 2: Prepare New USB Drive
**Requirements:**
- USB 2.0 recommended (more reliable than USB 3.0 for this purpose)
- Capacity: 4 GB minimum, 32 GB maximum
- Reputable brand (SanDisk, Samsung, Kingston)
- Must have a unique hardware GUID
**Write the backup to new drive:**
1. Download [Unraid USB Flash Creator](https://unraid.net/download) for macOS
2. Insert new USB drive into Mac
3. Open Flash Creator
4. For **Operating System**, scroll down and select **"Use custom"**
5. Browse to your backup ZIP file from Step 1
6. Select the new USB drive as destination
7. Click **Write** and wait for completion
**If you don't have a backup ZIP** (only raw files from Option D):
1. In Flash Creator, select the Unraid OS version matching your current install
2. Write a fresh Unraid install to the new drive
3. After writing, mount the drive and copy your backed-up `config/` folder onto it, replacing the default one
---
### Step 3: Swap Drives and Boot
1. Shut down XTRM-U if still running
2. Remove the old (failing) flash drive
3. Insert the new USB drive
4. Power on the server
5. Wait for boot (1-2 minutes)
6. Try accessing WebGUI at http://192.168.10.20
**If WebGUI doesn't load:**
- Connect a monitor to the server to check boot messages
- Verify the USB drive is detected in BIOS
- Ensure boot order has USB first
---
### Step 4: Transfer License
You will see an "Invalid, missing or expired registration key" message. This is expected.
1. In WebGUI, go to **Tools → Registration**
2. Click **Replace Key**
3. Enter the email address associated with your Unraid account
4. Check your email for the confirmation/license key
5. Follow the link or paste the key file URL into the Registration page
6. Click **Done**
**Important warnings:**
- Replacing the key **permanently blacklists** the old USB drive - it can never be used with Unraid again
- First license transfer can be done at any time
- Subsequent transfers: once per 12 months via the automated system
- If you need another transfer within 12 months, contact [Unraid support](https://unraid.net/contact) with old GUID, new GUID, license key, and purchase email
**If you can't find your license:**
- Log into https://account.unraid.net to view your keys
- Check email for original purchase confirmation
---
### Step 5: Post-Migration Verification
Run through this checklist after the server is back up:
**Array & Storage:**
- [ ] WebGUI loads at http://192.168.10.20
- [ ] Array starts normally (Main tab → Start)
- [ ] All disks show healthy status
- [ ] Shares are accessible
**Docker & Services:**
```bash
ssh -i ~/.ssh/id_ed25519_unraid root@192.168.10.20 -p 422
# Check all containers
docker ps -a --format 'table {{.Names}}\t{{.Status}}'
# Start any stopped critical containers (in order):
docker start postgresql17 # Wait 30s
docker start Redis # Wait 10s
docker start traefik
docker start authentik authentik-worker
docker start vaultwarden
```
**Network:**
- [ ] SSH works: `ssh -i ~/.ssh/id_ed25519_unraid root@192.168.10.20 -p 422`
- [ ] DNS failover AdGuard reachable: http://192.168.10.10:3000
- [ ] AdGuard sync working (check `docker logs adguardhome-sync --tail 5`)
- [ ] External URLs working (https://xtrm-lab.org)
**Services checklist:**
- [ ] Traefik reverse proxy (https://xtrm-lab.org)
- [ ] Authentik SSO (https://auth.xtrm-lab.org)
- [ ] Gitea (https://git.xtrm-lab.org)
- [ ] Uptime Kuma (https://uptime.xtrm-lab.org)
- [ ] Vaultwarden (https://vault.xtrm-lab.org)
- [ ] Plex (https://plex.xtrm-lab.org)
**Backup:**
- [ ] Verify Rclone config still present: `rclone listremotes` (should show `drive:`)
- [ ] Test flash backup: trigger manual backup from WebGUI or User Scripts
- [ ] Verify cron schedule for flash backup is active
---
### Step 6: Prevention
After successful migration:
1. **Enable Unraid Connect** (if not already) for automated cloud flash backup:
- Settings → Management Access → Unraid Connect
- Sign in with your unraid.net account
- Enable Flash Backup
2. **Verify Rclone cron** is scheduled:
```bash
# Check user scripts plugin for flash backup schedule
ls /boot/config/plugins/user.scripts/scripts/
```
3. **Keep a spare USB drive** prepared with a fresh Unraid install - makes future recovery faster
4. **Test backup restoration** periodically - don't wait for a failure to discover your backup is incomplete
---
## References
- [Unraid Docs: Changing the Flash Device](https://docs.unraid.net/unraid-os/system-administration/maintain-and-update/changing-the-flash-device/)
- [Unraid Docs: Licensing FAQ](https://docs.unraid.net/unraid-os/troubleshooting/licensing-faq/)
- Internal: `docs/02-SERVICES-CRITICAL.md` (startup order)
---
## Resolution
*Update this section when migration is complete:*
- **Date resolved:**
- **New USB drive:**
- **License transferred:** Yes/No
- **Services verified:** Yes/No
- **Backup reconfigured:** Yes/No

View File

@@ -0,0 +1,120 @@
# Home Assistant Setup
**Status:** IN PROGRESS
**Priority:** High
**Started:** 2026-02-07
## Overview
Home Assistant OS (HAOS) running as a libvirt VM on Unraid, with custom dashboards, themes, and smart home integrations.
## Infrastructure
| Component | Detail |
|-----------|--------|
| VM | HAOS on libvirt (Unraid host) |
| IP | 192.168.10.50 (VLAN 10 — Management) |
| Access | Web UI at `http://192.168.10.50:8123` |
| VM Management | `virsh qemu-agent-command "Home Assistant"` from Unraid |
| Container | `homeassistant` Docker container inside HAOS |
## Completed
### Integrations
| Integration | Type | Devices | Notes |
|-------------|------|---------|-------|
| Gree AC (manual) | Custom component (`gree_manual`) | 1 AC unit | Cross-VLAN via L3 unicast; generic key `a3K8Bx%2r8Y7#xDh` |
| Xiaomi Miot | HACS integration (`xiaomi_miot`) | 11 devices | 2FA verification required; BLE sensors work via cloud |
| Tuya / Smart Life | Built-in | Smart Curtain, switches, lights | Paired via Smart Life QR code |
| Roborock | Via Xiaomi Miot | S7 Pro Ultra | On 192.168.31.x (Xiaomi router subnet) |
| Bosch Home Connect | Built-in (`home_connect`) | Oven, Washing Machine | OAuth2 via developer.home-connect.com |
**Xiaomi devices discovered:**
- 4x Miaomiaoce BLE temp/humidity sensors (Living Room, Kitchen, Boys Room, Bedroom)
- 2x Air Purifiers (Living Room — zhimi.mc1, Boys Room — cpa4)
- 1x Air Purifier 4 Compact (on VLAN 30)
- 1x Humidifier (Living Room — deerma.jsq2w)
- 1x Roborock S7 Pro Ultra
- 1x Xiaomi Router
- 1x Mi Smart Home Hub
**Bosch Home Connect devices:**
- Bosch Oven HRG7784B1 — temperature, door state, programs, child lock, remote control
- Bosch Washing Machine WGB24400BY — programs, progress, spin speed, temperature, remaining time, door state, child lock
### Theme — visionOS
| File | Path (inside HA) | Source |
|------|-------------------|--------|
| visionOS theme | `/config/themes/visionos.yaml` | [homeassistant-visionos-theme](https://github.com/Nezz/homeassistant-visionos-theme) |
| Liquid Glass theme | `/config/themes/liquid_glass.yaml` | Same repo |
| card-mod.js (v4.2.0) | `/config/www/card-mod.js` | Enables backdrop-filter CSS effects |
| Mushroom Cards (v5.0.10) | `/config/www/mushroom.js` | Clean card collection for dashboards |
- Both JS files registered as Lovelace resources via websocket API (`lovelace/resources/create`)
- visionOS set as default theme via startup automation in `automations.yaml`
### Dashboards
Two custom Lovelace dashboards (not the default Overview):
| Dashboard | URL Path | Columns | Optimized For |
|-----------|----------|---------|---------------|
| Mobile | `/dash-mobile` | 2 | Phone screens |
| Desktop | `/dash-desktop` | 4 | Desktop/tablet |
Both use **Sections** view type with **Mushroom Cards**. Created via HA websocket API (`lovelace/dashboards/create` + `lovelace/config/save`).
**Sections on both dashboards:**
1. **Header** — Title card + chips (weather, outside temp, vacuum status, phone battery)
2. **Climate Control** — Living Room thermostat, Kitchen thermostat, Gree AC
3. **Temperatures** — 4 indoor Miaomiaoce BLE sensors + outside temp/humidity
4. **Radiators** — Living Room, Main Bedroom, Girls Room
5. **Bosch Appliances** — Oven (status, temp, door) + Washer (status, time left, progress)
6. **Lights** — Living Room, Dining Room, Bedroom LED strip, Picture Frame lamp
7. **Switches** — Entrance (x2), Bathroom (x2), Kids Bathroom (x2), Boys Lamp
8. **Curtain & Vacuum** — Smart Curtain, Roborock S7, Vacuum battery
Desktop dashboard has expanded Bosch sections with program selectors, child lock, spin speed, wash temperature, and remote control status.
### Startup Automation
```yaml
# /config/automations.yaml
- id: set_visionos_theme
alias: "Set visionOS Theme on Startup"
trigger:
- platform: homeassistant
event: start
action:
- service: frontend.set_theme
data:
name: visionos
```
## Known Issues
| Issue | Detail | Workaround |
|-------|--------|------------|
| Xiaomi devices on 192.168.31.x unreachable | Air purifiers, humidifier, Roborock on Xiaomi router subnet | Switch to cloud-only polling in xiaomi_miot config |
| Cross-VLAN broadcast discovery | UDP broadcasts don't cross VLANs | Use manual IP config (e.g., `gree_manual` component) |
| `/config/www/` not served after creation | HA needs full core restart to detect new `www` directory | `ha core restart` from HAOS VM |
| `automations.yaml` syntax | Appending to `[]` creates invalid YAML | Always overwrite file, never append after `[]` |
## Pending Work
- [ ] Switch Xiaomi air purifiers/humidifier to cloud-only mode for reliable polling
- [ ] Add more dashboard sections as new devices are added
- [ ] Evaluate HACS frontend cards (mini-graph-card, apexcharts-card) for richer data display
- [ ] Set up HA mobile app companion for phone notifications and presence detection
## Technical Notes
- **File transfer to HA:** base64 encode → virsh guest-exec → docker exec -i tee (chunk at 50KB for large files)
- **HAOS minimal toolset:** Only `/usr/bin/curl`, `/sbin/ip` available — no wget/nc/python3/which
- **Dashboard URL paths:** Must contain a hyphen (e.g., `dash-mobile`, not `mobile`)
- **Lovelace resources:** Must be registered via websocket API, not by writing storage files directly
- **HA API token:** Generated JWT with HMAC-SHA256 from refresh token's `jwt_key` in `/config/.storage/auth`
- **Home Connect OAuth2:** Register app at developer.home-connect.com, use redirect URI `https://my.home-assistant.io/redirect/oauth`, disable "One Time Token Mode" (breaks HA token refresh)

View File

@@ -30,6 +30,12 @@ Planned changes, evaluations, and ideas not yet implemented.
| [CONSOLE-PORT-ETHER5.md](CONSOLE-PORT-ETHER5.md) | EVALUATING | Low | Console/serial port on HAP1 ether5 |
| [KVM-SWITCH-MAC-NOBARA.md](KVM-SWITCH-MAC-NOBARA.md) | EVALUATING | Medium | Software KVM for Mac/Nobara switching |
### Smart Home
| Document | Status | Priority | Description |
|----------|--------|----------|-------------|
| [HOME-ASSISTANT-SETUP.md](HOME-ASSISTANT-SETUP.md) | IN PROGRESS | High | HAOS VM, dashboards, themes, integrations |
### Applications
| Document | Status | Priority | Description |

66
scripts/vw-sync.sh Executable file
View File

@@ -0,0 +1,66 @@
#!/bin/bash
# Vaultwarden Sync: Unraid → MikroTik (cold standby)
# Run this from your Mac (must have VPN/network access to both devices)
#
# Usage: ./vw-sync.sh
# Syncs the Vaultwarden database from Unraid to MikroTik standby instance.
# The MikroTik container must be STOPPED during sync.
set -euo pipefail
UNRAID_SSH="ssh -i ~/.ssh/id_ed25519_unraid root@192.168.10.20 -p 422"
MIKROTIK_SSH="ssh -i ~/.ssh/mikrotik_key -p 2222 xtrm@192.168.10.1"
UNRAID_VW_PATH="/mnt/user/appdata/vaultwarden"
MIKROTIK_USB_PATH="usb1/vaultwarden/data"
HTTP_PORT=8888
echo "=== Vaultwarden Sync: Unraid → MikroTik ==="
echo ""
# 1. Check MikroTik container is stopped
echo "[1/5] Checking MikroTik Vaultwarden container status..."
STATUS=$($MIKROTIK_SSH ':foreach c in=[/container/find where name~"server"] do={:put [/container/get $c status]}' 2>/dev/null || echo "unknown")
if [ "$STATUS" = "running" ]; then
echo " Container is running. Stopping it..."
$MIKROTIK_SSH '/container/stop [find where name~"server"]'
sleep 5
fi
echo " Container is stopped."
# 2. Start temporary HTTP server on Unraid
echo "[2/5] Starting temp HTTP server on Unraid (port $HTTP_PORT)..."
$UNRAID_SSH "cd $UNRAID_VW_PATH && php -S 0.0.0.0:$HTTP_PORT &>/dev/null &"
sleep 2
# Verify it's responding
if ! $UNRAID_SSH "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:$HTTP_PORT/db.sqlite3" 2>/dev/null | grep -q "200"; then
echo " ERROR: HTTP server not responding. Aborting."
$UNRAID_SSH "pkill -f 'php -S' 2>/dev/null" || true
exit 1
fi
echo " HTTP server ready."
# 3. Fetch files to MikroTik
echo "[3/5] Syncing database to MikroTik..."
$MIKROTIK_SSH "/tool/fetch url=\"http://192.168.10.20:$HTTP_PORT/db.sqlite3\" dst-path=\"$MIKROTIK_USB_PATH/db.sqlite3\""
echo ""
echo "[4/5] Syncing RSA key and config..."
$MIKROTIK_SSH "/tool/fetch url=\"http://192.168.10.20:$HTTP_PORT/rsa_key.pem\" dst-path=\"$MIKROTIK_USB_PATH/rsa_key.pem\""
$MIKROTIK_SSH "/tool/fetch url=\"http://192.168.10.20:$HTTP_PORT/config.json\" dst-path=\"$MIKROTIK_USB_PATH/config.json\""
echo ""
# 5. Cleanup
echo "[5/5] Stopping HTTP server on Unraid..."
$UNRAID_SSH "pkill -f 'php -S' 2>/dev/null" || true
echo ""
echo "=== Sync complete! ==="
echo ""
echo "To START the standby Vaultwarden:"
echo " $MIKROTIK_SSH '/container/start [find where name~\"server\"]'"
echo ""
echo "To STOP it after maintenance:"
echo " $MIKROTIK_SSH '/container/stop [find where name~\"server\"]'"
echo ""
echo "Access URL: http://192.168.10.1:4743"