Office kiosk dashboard, lounge media tablet and mobile — full build, code and screenshots

**:warning: Read this first: heavy use of AI tools, and why **

The dashboards, scripts, card templates, the Windows kiosk app and the booklet itself were produced with substantial help from Claude and Cowork (Anthropic), working interactively over several months.

I should be upfront about why, because it shapes what this is:

I wanted to learn what AI can actually do. Not the demos — what happens when you point it at a real, messy, long-running project with real hardware that misbehaves.

I wanted to learn to code and genuinely understand it, rather than paste things I couldn’t explain. Working through the failures in here taught me far more than the successes did. When something broke at 3am, I had to understand why to fix it.

And most of all, I wanted rid of the pile of separate apps. One for the solar, one for the battery, one for the lock, one for the vacuum, one for the doorbell, one for the blinds. That’s what started it — building the beginnings of an actual smart home rather than a phone full of apps that don’t talk to each other.

I’m not claiming full credit for this. I’m a nerd using nerdy tools to make more nerdy things work. The architecture and the decisions are mine, and I tested every bit of it in my house — but a lot of the code was written by AI, and pretending otherwise would be daft.

And nothing here takes anything away from the people who’ve built systems like this from their own knowledge. Genuine respect to them — their write-ups are what got me started, and they did it the hard way. This is just a different route to a similar place, and I’m sharing it in the same spirit.

What that means for you, practically:

  • The patterns work — this runs here daily and has done for months.
  • Every fault I document is one I actually hit, in a real house, with real hardware.
  • But this is not hand-written, peer-reviewed code. There’s no test suite. Nobody but me has read it.
  • Check anything before you run it. Especially the kiosk app, which is unsigned C# that will trip SmartScreen. Build it from source so you know what you’re running.
  • If you’re not comfortable reading code you didn’t write, take the ideas and implement them yourself. Honestly, that’s the better use of this.

What’s in it

Three control surfaces sharing one visual language:

  • A widescreen desk kiosk that auto-rotates through three pages, with a countdown ring drawn on the active nav button so you know when it’s about to change
  • A wall tablet in the lounge — lights, blinds, heating, AV, music
  • A phone dashboard with an audio zone picker for multi-room speakers

Driving: GivEnergy solar and battery (local Modbus, no cloud), an EV charger, Octopus Energy, Axle Energy, LG OLED, Onkyo amp, Sonos, Xbox, Fire TV, SwitchBot IR, Tuya, Govee, Somfy via Overkiz, Tapo, Nest, BlueAir, Roborock, Navimow, Ring, a Nuki lock over MQTT, and an Eaton UPS via NUT.

The bits I think are actually worth your time

Colour activity tiles from your amplifier’s real source, not an input_select. I did it the stored-state way first. It lies — my Music tile stayed lit while I was playing Xbox, because the input_select only ever held two of the five activities. The amp physically knows which input is live and cannot be wrong.

@property does not work inside shadow DOM. It’s document-scoped, so registering it inside a card is silently ignored — which invalidates your var(), which kills the whole conic-gradient, which means nothing animates and nothing appears in the console. Use SVG stroke-dashoffset instead. Cost me an evening.

Sliders take their colour from --tile-color, which HA sets inline from entity state. That’s why mine was blue when the amp was on and grey when off. Override it with !important; setting --control-slider-color alone does nothing.

Re-renders restart CSS animations. My progress ring crept forward, snapped back, crept a bit further, snapped back. Fix: fixed duration plus a negative animation-delay equal to elapsed time, so any re-render lands where it should.

Don’t run anything important as a side effect of a card rendering. My first rotation engine lived in a name: template on a 1s timer. On one page the card stopped re-rendering and rotation silently stopped — countdown ticking into negative numbers with nothing listening. Now it’s a persistent loop reading hass directly.

Trust measurements, not state words. My EV charger reports charging_state: "Charging" whenever a cable is attached. My energy card believed it, subtracted an inferred figure from house load, and told me the house was using zero watts. Only misbehaved during the overnight battery charge window, so I slept through it for weeks.

Check timestamps, not values. Most of my faults announced themselves the moment I looked at last_changed. Stale data looks exactly like real data.

Pause audio before anything else. My “everything off” turned off the TV, streamer and amp but not the speaker. Music kept streaming silently. At 02:59 the amp powered itself on and the house filled with Bruce Springsteen. I woke at 04:44 very confused.

Watchdogs for “alive but silent” integrations. Cloud doorbells keep a push listener that dies quietly — polled sensors keep updating while ding events freeze, so it looks perfectly healthy and simply never rings. The tell is one sensor moving while a related one is frozen.

Migration gotchas (thin client to mini PC): a Mosquitto add-on login didn’t survive the restore, so my lock couldn’t authenticate — and 1,013 restored retained MQTT messages meant HA displayed a convincing “locked” while the door was open. NUT needed the add-on restarted, not the integration. Two instances briefly polling one inverter over Modbus produced garbage.

What’s in the download

  • 29-page PDF with full screenshots of all three dashboards and a tagged kit list
  • Eight commented, genericised code files — activity scripts, battery and audio scripts, watchdog automations, the tile design system, the rotation controller, and write-ups of the shadow-DOM findings and the energy card
  • Full source of the Windows kiosk host app (WPF/.NET 8 + WebView2)

Everything’s genericised — placeholder entity IDs, no IPs, MACs, serials or tokens. Camera thumbnails and financial figures are redacted in the screenshots.

Prerequisites: button-card is doing nearly all the visual work. card-mod for styling native cards. Optionally custom-brand-icons for device logos.

Take it, break it, improve it. And if one of these patterns fails on your hardware, please say so in this thread — half the value here is the documented faults, and they only exist because things misbehaved in a real house.

Full Write Up and Documenation >

(PDF Version also there)

Code and Other Files > GitHub - davemarkmail-code/homeassistant · GitHub

As i said test take it apart use tiny bits , use none of it .. i had the vision on whati wanted but as stated im no expert and leaned heaverly on AI

Regards

Dave

This pdf doesn’t render for me…

Sorry aabout that , not sure why its ok for me w ill check - Alternate icloud link > ha-control-system-booklet.pdf

It just won’t render on linux then, as that link is a no go also.

Very stange :frowning:

Added Markdown – homeassistant/ha-control-system-booklet.md at 8d470dec650e6db65eec35c790f39cd384e239ef · davemarkmail-code/homeassistant · GitHub

Works great!