← all posts
// smart-home · tts

Local text-to-speech makes smart-home replies resilient

A Raspberry Pi or an Orange Pi doesn't have the headroom for a text-to-speech model that pauses before it starts talking. On a board this size, the number that decides the project isn't voice quality, it's time to first audio. Get that backwards and you'll ship something that sounds impressive in a demo and useless in the hallway.

Small-board AI gets argued about from two extremes. Neither is useful. One side treats the board like a shrunken gaming PC. The other writes it off as too weak to matter. What actually works is narrower: a quiet, bounded job that runs next to the sensors, keeps answering with no cloud account in the loop, and barely draws any power.

Picture a Home Assistant server feeding a few plain audio satellites around the house. The board matters less than the appliance built around it: storage, power supply, cooling, the OS image, radio or accelerator support, and the service that consumes the result. A model running once from a shell prompt is still several decisions away from a household feature.

What counts as one job

Write the job in four lines before buying hardware: event, input, output, deadline. "Add AI to the camera" is a wish, not a job. "When a parcel sits inside the porch zone for twenty seconds, produce one local notification with a thumbnail" is a job, and short enough to show which half of the pipeline never needed a model at all. Most of what people bolt a language model onto is a threshold and a timer in costume.

Log the field, not the demo

The first real experiment isn't synthesis quality. It's pre-generating common phrases, caching them, and timing first audio rather than total render time. Test with the actual room: the real mic, camera angle, sensor, language, network. Edge deployments amplify ordinary variation more than a lab bench ever shows: evening light, a television running speech, a warm cabinet, a weak cable, a busy Home Assistant database can all move the result more than a model revision does. Keep a short record every time you test.

FieldWhy it matters
Board, OS, power, coolingCheap boards fail from the enclosure inward
Model artifact, runtime versionGives a regression a suspect list
Real input, expected actionTies the test to something recognizable
Cold/warm latency, sustained rateFirst request after idle is what gets judged
False action, missed action, recovery pathAccuracy alone says nothing about safety

Accuracy isn't the finish line for a household feature. You need to know whether it produces duplicate notifications, survives a reboot, reconnects once the network returns, and behaves safely when the inference service isn't there. Anything other people rely on needs visible state and a manual fallback. Nobody should have to know which container crashed to turn on a light.

Nothing generative guards the lock

The failure I keep seeing: someone points the best model they have at every door and timer announcement, including the ones that matter. Generative output is fine for interpreting a loose request, summarizing history, or ranking options. It should never be the only thing protecting a lock, heater, alarm, valve, battery, or person. Ranges, permissions, timeouts, confirmations, and device interlocks belong in plain deterministic code. Treat everything the model reads as data, not instruction: camera text, calendar entries, webpages, MQTT payloads, voice transcripts. A model that treats a scraped calendar entry as a command is a bug waiting to happen.

Privacy is a supply chain, not a switch

Local inference stops one thing: the upload. It does nothing about the recordings, event logs, thumbnails, backups, and remote dashboards that can still carry a copy of what got said in your kitchen. Decide on purpose what gets collected, how long it stays, who can retrieve it, and what happens during debugging. The most private frame is the one the camera never captures. The next best is discarded the moment the bounded decision it fed into is made.

Run it like plumbing

Use a service manager or a small, pinned container definition, not a script someone remembers to restart. Keep configuration separate from the model files. Write a health check that proves the function actually works, not just that something holds a port. Back up the controller state, export the model hashes, and keep a known-good storage image for any node installed somewhere inconvenient.

Power and heat belong in the same acceptance test. Run long enough for the enclosure to reach a steady state and measure at the wall with normal peripherals attached. If the board throttles, swaps, corrupts storage, or monopolizes the home-automation host, it isn't ready, however good one clean inference run looked. Match voice quality to the message, keep common replies instant, and when the model goes down, the automation should get plainer, not stop.

Plenty of cheap boards can run a model; that was never the hard part. The hard part is one small capability that still works after the benchmark window closes and the board disappears into a cupboard. Next, before calling it finished: pull the network cable for an evening and listen to what the porch light actually says on its own.

#tts#voice-assistant#local-ai