A PZEM-004T energy monitor with live dashboard, local history, and Home Assistant integration, built as an Orbit OS app instead of Docker.
Story
A guided-setup, Home-Assistant-ready energy monitor for PZEM-004T meters, built on a real embedded device without ever touching a Dockerfile.
I wanted to turn a cheap PZEM-004T meter into something I could install once, leave running, and actually use every day. I wired one up to a Raspberry Pi running Orbit OS, and what came out the other end is PZEM Monitor: a web dashboard with live readings, local history you can chart or export, and Home Assistant integration that needs zero YAML to set up.
Things used in this project
Hardware
- Raspberry Pi 4 Model B running Orbit OS
- One or more PZEM-004T v3.0 AC energy meters
- USB-to-UART adapter
- Wiring/jumper cables to the meter(s) (a shared UART bus supports multiple meters)
- Power supply for the device
Software
- Orbit OS running on the device (version 26.20260710.1118)
- Orbit Studio v1.9.2 (VS Code extension) to create, run, and package the app
- MQTT broker + Home Assistant (optional, only for the HA integration)
Wiring the PZEM-004T
The PZEM-004T v3.0 has a simple 4-pin TTL interface for communication, separate from the AC terminals it's actually measuring:
- TX → RX on the USB-to-UART adapter
- RX → TX on the USB-to-UART adapter
- GND → GND
- 5V → powers the meter's communication interface
The adapter then plugs into the Raspberry Pi over USB, which is what PZEM Monitor's setup wizard sees as a serial port to connect to.
One of the useful things about the PZEM-004T is that multiple meters can share the same UART bus, so you don't need one adapter per meter. Each meter gets its own Modbus address, and the app handles polling them one by one over the shared line. That's exactly what the setup wizard's address-assignment step is for: connect one meter at a time, let the wizard assign it a free address, then move on to the next.
What PZEM Monitor is, and why I built it
I wanted to know what my appliances were really drawing. Not an estimate. Not a monthly total from the utility bill. Live voltage, current, and power, per circuit, with history I could check later. A PZEM-004T wired onto a main panel, a solar inverter, or a single appliance turns "I wonder how much that's using" into a real number on a screen.
PZEM-004T meters are cheap and accurate enough for this job. They speak Modbus-RTU over a plain UART, so the sensor side was never the hard part. What I kept putting off was everything around the sensor: something to poll it, somewhere to store the history, a web UI to look at it, and ideally a bridge into Home Assistant, all without sending my electricity data to someone else's cloud. I also wanted to check the dashboard from outside the house sometimes, without opening anything up to the internet myself.
That's what PZEM Monitor is: an app that turns a device into a dedicated, always-on energy meter reader for one or more PZEM-004T sensors.
I also had a Raspberry Pi free, and building this doubled as my excuse to learn how to build a real app for Orbit OS, not just a "hello world." I liked Orbit OS for a second reason, too: I wanted to build an app that other people could simply try for themselves, install it on their own device and have it up and running within minutes, with no build toolchain, no configuration files to edit by hand, no scripts to run, and no cloning repositories or manual compilation steps. The experience is much like Android — just open the Orbit OS Store from anywhere, find the app, install it remotely onto your device, and it's running. No terminal, no setup, nothing to configure.
IMAGEM
If the app turns out to be useful to someone, I want them to be able to use it anywhere in the world. And I want to keep improving it over time, knowing that shipping an update doesn't have to be complicated for them or for me. It comes down to one simple flow: I publish -> users receive. I push a new version to the store, and it just shows up on their device, with nothing for them to do and nothing for me to chase.
What it does
Setup wizard
Pick a serial port, connect one meter at a time, and the wizard finds it and assigns it a unique Modbus address before moving to the next meter.
Wiring several meters onto one bus doesn't mean I have to remember which address is already taken; the wizard tracks that for me.
Live dashboard
One card per meter: online/offline status, and while online, voltage, current, power, frequency, power factor, and accumulated energy in kWh, refreshed automatically with nothing to click.
History
Readings are logged to an on-device database on a schedule I control, with automatic cleanup after a set retention period. I can chart or table any range (24 hours, 7 days, 30 days, everything) and export any of it to CSV.
Home Assistant, zero YAML
Turn on MQTT, point it at my broker, and every meter shows up in HA automatically via MQTT discovery: one device per meter, with energy reported correctly as an ever-increasing total.
It's also built for unattended operation: if a meter is missing or the UART is misconfigured, the app doesn't crash. It keeps serving the dashboard and settings pages, so I can fix the problem from a browser instead of needing a shell on the device. Everything runs on-device, and nothing leaves the network unless I turn MQTT on myself.
Why I built it for Orbit OS instead of Docker
My first instinct for an always-on service with a web UI is usually: put it in a container, docker run, done. But for this particular application, Docker felt like a poor fit for the target hardware: it assumes a daemon can run all the time, that pulling a few hundred MB from a registry is cheap, and that storage is basically free. On a device running off an SD card or eMMC, on a slow connection, with a fraction of a server's RAM, those assumptions get expensive fast: the daemon alone is memory I don't have to spare, and every image drags in a full base-OS layer on top of what the app actually needs.
Orbit OS sidesteps that entirely. Apps run as signed .orb packages (an .orb works a lot like an Android .apk), self-contained, with no base-OS layer to carry. PZEM Monitor's own build, binary and web assets and manifest and signature included, comes out to just 4.5MB. That's what a small app looks like when it isn't shipping a container's worth of Linux underneath it.
The app also only needs one thing from the device: the UART port the meters are wired to. PZEM Monitor's manifest declares exactly three capabilities: basic device info for the status page, UART access to talk to the meters, and Launcher access to show its web UI. The runtime enforces that nothing else is reachable, no ability to change network settings, no filesystem access outside its own data directory. A typical container tends to lean on broad device access just to reach one interface it needs; here the app's access is scoped to exactly what it uses, declared up front.
The other thing I'd have had to build myself with Docker is a fleet story: a shared registry, an update mechanism, a way to keep devices in sync, all as extra infrastructure on top of the app itself..
The Orbit OS Store solves that at the platform level: push a new version, and every device in the field that has the application installed and automatic updates enabled will automatically receive the new version, with no deployment scripts or SSHing into devices one by one.
While developing, Orbit Studio can push the .orb straight to a device on the network instead.
Building it: the development experience
The whole workflow lived inside Orbit Studio, a VS Code extension that covers the full lifecycle: creating the project, running it against real hardware, and deploying it, all without leaving the editor.
Create Project scaffolded the app: pick the SDK language (Go, in my case; Java, Python, and C++ are also supported), give it a name, point it at my device's IP on the local network, and pick an SDK version. A minute later I had a full project structure with the right manifest, ready to run.
Youtube Video _ Orbit Studio Develop Apps Remotely in Real-Time — Raspberry Pi & Arduino UNO Q
Run App is the part that changed how I worked. It doesn't deploy anything. My code kept running on my own laptop, but every hardware call it made went out over the network (TCP/mTLS) to the real device and came back with real data: real UART bytes from the meter, in real time. I could tweak the polling loop, print a raw Modbus frame, and rerun in seconds. No image build, no flashing, no SSH session.
The meter and the device were real the whole time. I just never had to package or install anything to test against them.
Once a piece actually worked, Deploy was one click: Orbit Studio built the .orb, signed it with a dev certificate, and installed it straight onto the device.
From that point the app stopped being driven by my laptop and started running natively on the device, supervised by the runtime, fully autonomous. A Device Log view streamed its output into VS Code's Output panel whenever I wanted to watch it live, and once installed it showed up as a tile in the device's Launcher (http://), the same as any other installed app. From there I could also check its status or uninstall it.
That's the whole loop, start to finish: scaffold, iterate live against real hardware, one-click package, sign, and install. No registry, no push/pull, no docker-compose.
Deploying to my own device is one thing; getting it in front of other people is a separate step, and it happens outside Orbit Studio entirely. The Store's Developer area has a submission flow for that: build the .orb, submit it for review (or submit the source directly, which earns a Trusted App badge on the listing), and the Orbit OS team reviews it before it goes live.
I had a confirmation back within a day, and once I approved the listing myself, PZEM Monitor was live in the Store, ready for anyone to install remotely with one click on their own devices.
What I learned
The PZEM-004T's general address was the real surprise. Every unit answers on a fixed address (0xF8) no matter what address it's currently assigned, which isn't standard Modbus behavior. Once I understood that, multi-meter setup got a lot simpler; before that, it just looked like a meter that wasn't responding.
Orbit OS's "run against real hardware without deploying" model took a moment to click. I kept expecting to need a build step before I could test anything. Once it sank in that my laptop could drive real UART traffic directly, it changed how often I was willing to just try something.
Getting comfortable trusting the shared UART bus took longer than I expected. Polling several meters reliably off one line, without them stepping on each other, needed more care than I assumed going in.
The deploy step itself was easier than I expected. After years of flashing images and SSHing into boxes, going from working code to a signed package running on the device in one click still feels a little unreal.
Local storage and optional MQTT were a deliberate choice, not a default. I wanted the app fully useful with nothing configured beyond wiring, and Home Assistant to be something I opted into, not something the app assumed I wanted.
Where it stands now
Getting PZEM Monitor application into the Store isn't the finish line for me. It's the start of the fun part. I want to keep this project alive: chasing down every little rough edge, polishing the parts that only reveal themselves once real people are running it on real meters in real homes, and pushing updates out through the Store the way I described above, without anyone having to lift a finger for it.
More than anything, I'm looking forward to hearing from whoever ends up using it. Every setup is a little different: different meters, different panels, different things people care about seeing on a dashboard. I'd love for those differences to shape where this app goes next. If someone wants a feature that isn't there yet, I want to hear about it and build it. This is very much a living project, and I'm planning to keep growing it for as long as people find it useful.
One direction I'm genuinely excited about is widening what the app can talk to. PZEM-004T is where this started, but the Modbus foundation underneath it isn't tied to one meter, and I'd love to see PZEM Monitor grow to support other meters too, and maybe one day reach beyond hobbyist hardware into the industrial-grade meters that speak the same language.
Orbit OS is opening a device certification program: a path for independent makers and small shops to ship hardware that's certified for the ecosystem. It took me a second read to see what that actually means. A certified device carries a guarantee — plug it in and Orbit OS apps run on it correctly from first boot. And whoever built it didn't have to write the operating system, the signed update pipeline, the security model, or the store that ships the app. That part already exists.
And it keeps existing after the product ships. When the app gets a new version, it reaches the device exactly the way an app update reaches an Android phone: through the store, automatically. The person who built the hardware doesn't have to do anything for that to happen.
Which is why I've started entertaining an idea I'd have dropped a year ago. PZEM Monitor is an app today. It could be a product: a small purpose-built board with one or two PZEM-004T sensors already wired in, shipped with the app pre-installed. No wiring, no serial port to hunt for. Power it up and the numbers arrive.
I'm not building it yet. But what would have killed the idea before was never the board — it was everything around the board. And that isn't mine to solve anymore.
Installing PZEM Monitor
**Don't have Orbit OS on a device yet? **Follow the Orbit OS installation guide first, then come back here.
Already have Orbit OS running? Installing PZEM Monitor is a browser-only process, no file transfer, no SSH:
Sign in (or create a free account) at store.orbit-os.org.
Link your device to your account so it appears as an install target.
Find PZEM Monitor in the Store, click Install, and select the device you want to install it on.
Confirm. The .orb is delivered and installed remotely, and the PZEM Monitor tile will appear in the device's Launcher, ready to run the setup wizard.
Full details on account setup and device linking are available in the Orbit OS getting started guide.
Have a PZEM-004T and an Orbit OS device? Give it a try. I'd love to hear about your setup and what you'd like to see added next.
PZEM Monitor: Store
Orbit OS: website
Orbit OS Youtube: Channel













Top comments (0)