<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Peter H</title>
    <description>The latest articles on DEV Community by Peter H (@pharris).</description>
    <link>https://dev.to/pharris</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3894818%2Fb34dafca-e23c-4b6d-9fdd-4f91d5bb4f59.png</url>
      <title>DEV Community: Peter H</title>
      <link>https://dev.to/pharris</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pharris"/>
    <language>en</language>
    <item>
      <title>Turn a PZEM-004T + Raspberry Pi into a Full Energy Monitor — No SSH, No Docker, One Click</title>
      <dc:creator>Peter H</dc:creator>
      <pubDate>Wed, 16 Sep 2026 23:42:23 +0000</pubDate>
      <link>https://dev.to/pharris/from-pzem-004t-to-a-full-energy-monitor-1g5f</link>
      <guid>https://dev.to/pharris/from-pzem-004t-to-a-full-energy-monitor-1g5f</guid>
      <description>&lt;p&gt;A PZEM-004T energy monitor with live dashboard, local history, and Home Assistant integration, built as an Orbit OS app instead of Docker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Story
&lt;/h2&gt;

&lt;p&gt;A guided-setup, Home-Assistant-ready energy monitor for PZEM-004T meters, built on a real embedded device without ever touching a Dockerfile.&lt;/p&gt;

&lt;p&gt;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 &lt;strong&gt;PZEM Monitor&lt;/strong&gt;: a web dashboard with live readings, local history you can chart or export, and Home Assistant integration that needs zero YAML to set up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things used in this project
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hardware&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Raspberry Pi 4 Model B running Orbit OS&lt;/li&gt;
&lt;li&gt;One or more PZEM-004T v3.0 AC energy meters&lt;/li&gt;
&lt;li&gt;USB-to-UART adapter&lt;/li&gt;
&lt;li&gt;Wiring/jumper cables to the meter(s) (a shared UART bus supports multiple meters)&lt;/li&gt;
&lt;li&gt;Power supply for the device&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Software&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="//www.orbit-os.org"&gt;Orbit OS&lt;/a&gt; running on the device (version 26.20260710.1118)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.orbit-os.org/downloads.html" rel="noopener noreferrer"&gt;Orbit Studio&lt;/a&gt; v1.9.2 (VS Code extension) to create, run, and package the app&lt;/li&gt;
&lt;li&gt;MQTT broker + Home Assistant (optional, only for the HA integration)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wiring the PZEM-004T
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgsbwipmgmy031xqxy05k.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgsbwipmgmy031xqxy05k.jpg" alt=" " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wiring Diagram&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faw1b99cj9oknnwzi4wyf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faw1b99cj9oknnwzi4wyf.png" alt=" " width="654" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The PZEM-004T v3.0 has a simple 4-pin TTL interface for communication, separate from the AC terminals it's actually measuring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TX&lt;/strong&gt; → RX on the USB-to-UART adapter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RX&lt;/strong&gt; → TX on the USB-to-UART adapter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GND&lt;/strong&gt; → GND&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5V&lt;/strong&gt; → powers the meter's communication interface&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;One of the useful things about the PZEM-004T is that &lt;strong&gt;multiple meters can share the same UART bus&lt;/strong&gt;, 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What PZEM Monitor is, and why I built it
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;That's what &lt;strong&gt;PZEM Monitor&lt;/strong&gt; is: an app that turns a device into a dedicated, always-on energy meter reader for one or more PZEM-004T sensors.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;IMAGEM&lt;/p&gt;

&lt;p&gt;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 -&amp;gt; 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Setup wizard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjxctv75pwwbk6tjnrtdu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjxctv75pwwbk6tjnrtdu.png" alt=" " width="800" height="1778"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh5jqiqavfdztw0jp4ri8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh5jqiqavfdztw0jp4ri8.png" alt=" " width="800" height="1778"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wiring several meters onto one bus doesn't mean I have to remember which address is already taken; the wizard tracks that for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Live dashboard
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6zsiz0s8i3aq3zyry9rm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6zsiz0s8i3aq3zyry9rm.png" alt=" " width="800" height="1778"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  History
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxzmq8pxpigzba2x0kbz0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxzmq8pxpigzba2x0kbz0.png" alt=" " width="800" height="1778"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Home Assistant, zero YAML
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpr2706ppe84y7372uw3h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpr2706ppe84y7372uw3h.png" alt=" " width="800" height="1778"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built it for Orbit OS instead of Docker
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Orbit OS sidesteps that entirely. Apps run as signed &lt;strong&gt;.orb&lt;/strong&gt; 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 &lt;strong&gt;4.5MB&lt;/strong&gt;. That's what a small app looks like when it isn't shipping a container's worth of Linux underneath it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmqvpue1tq0dl2pu5w3ex.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmqvpue1tq0dl2pu5w3ex.png" alt=" " width="493" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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..&lt;/p&gt;

&lt;p&gt;The &lt;a href="//store.orbit-os.org"&gt;Orbit OS Store&lt;/a&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzg3do7dq5pymfdzdr6pz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzg3do7dq5pymfdzdr6pz.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While developing, Orbit Studio can push the .orb straight to a device on the network instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building it: the development experience
&lt;/h2&gt;

&lt;p&gt;The whole workflow lived inside &lt;a href="https://www.orbit-os.org/downloads.html" rel="noopener noreferrer"&gt;Orbit Studio&lt;/a&gt;, 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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1da3icycfdcdm09kr8ms.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1da3icycfdcdm09kr8ms.png" alt=" " width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create Project&lt;/strong&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/8BTXqhzp6jM?si=Lpgzw2IROruTSBuO" rel="noopener noreferrer"&gt;Youtube Video _ Orbit Studio Develop Apps Remotely in Real-Time — Raspberry Pi &amp;amp; Arduino UNO Q&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run App&lt;/strong&gt; 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.&lt;/p&gt;

&lt;p&gt;The meter and the device were real the whole time. I just never had to package or install anything to test against them.&lt;/p&gt;

&lt;p&gt;Once a piece actually worked, &lt;strong&gt;Deploy&lt;/strong&gt; was one click: Orbit Studio built the .orb, signed it with a dev certificate, and installed it straight onto the device.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F311n8xsvh887sntufoq4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F311n8xsvh887sntufoq4.png" alt=" " width="799" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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 &lt;strong&gt;Device Log&lt;/strong&gt; 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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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 &lt;strong&gt;Trusted App&lt;/strong&gt; badge on the listing), and the Orbit OS team reviews it before it goes live.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff7v393ipocb1tns9ehyc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff7v393ipocb1tns9ehyc.png" alt=" " width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The PZEM-004T's general address was the real surprise&lt;/strong&gt;. 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.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Orbit OS's "run against real hardware without deploying" model took a moment to click.&lt;/strong&gt; 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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Getting comfortable trusting the shared UART bus took longer than I expected.&lt;/strong&gt; Polling several meters reliably off one line, without them stepping on each other, needed more care than I assumed going in.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The deploy step itself was easier than I expected.&lt;/strong&gt; 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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Local storage and optional MQTT were a deliberate choice, not a default.&lt;/strong&gt; 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.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where it stands now
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing PZEM Monitor
&lt;/h2&gt;

&lt;p&gt;**Don't have Orbit OS on a device yet? **Follow the &lt;a href="https://www.orbit-os.org/getting_started.html#gs-install" rel="noopener noreferrer"&gt;Orbit OS installation guide&lt;/a&gt; first, then come back here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Already have Orbit OS running?&lt;/strong&gt; Installing PZEM Monitor is a browser-only process, no file transfer, no SSH:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Sign in (or create a free account) at &lt;a href="//store.orbit-os.org"&gt;store.orbit-os.org&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link your device to your account so it appears as an install target.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Find PZEM Monitor in the Store, click &lt;strong&gt;Install&lt;/strong&gt;, and select the device you want to install it on.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;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.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full details on account setup and device linking are available in the &lt;a href="https://www.orbit-os.org/getting_started.html" rel="noopener noreferrer"&gt;Orbit OS getting started guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg0vc8n6nhhkumsxtyjle.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg0vc8n6nhhkumsxtyjle.png" alt=" " width="800" height="559"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;PZEM Monitor: &lt;a href="//store.orbit-os.org"&gt;Store&lt;/a&gt;&lt;br&gt;
Orbit OS: &lt;a href="//www.orbit-os.org"&gt;website&lt;/a&gt;&lt;br&gt;
Orbit OS Youtube: &lt;a href="https://www.youtube.com/@orbit-os-edge" rel="noopener noreferrer"&gt;Channel&lt;/a&gt;&lt;/p&gt;

</description>
      <category>iot</category>
      <category>raspberrypi</category>
      <category>linux</category>
      <category>go</category>
    </item>
    <item>
      <title>I connected Cursor IDE to a Raspberry Pi via MCP — controlled relays and read an I2C sensor in natural language</title>
      <dc:creator>Peter H</dc:creator>
      <pubDate>Thu, 11 Jun 2026 15:21:05 +0000</pubDate>
      <link>https://dev.to/pharris/i-connected-cursor-ide-to-a-raspberry-pi-via-mcp-controlled-relays-and-read-an-i2c-sensor-in-23ba</link>
      <guid>https://dev.to/pharris/i-connected-cursor-ide-to-a-raspberry-pi-via-mcp-controlled-relays-and-read-an-i2c-sensor-in-23ba</guid>
      <description>&lt;p&gt;If you've ever set up a Raspberry Pi project, you know the drill — SSH into the device, write custom scripts, debug GPIO issues, repeat. It works, but it's tedious.&lt;/p&gt;

&lt;p&gt;I wanted to try something different: what if an AI assistant could talk directly to the hardware?&lt;/p&gt;

&lt;p&gt;This is what I built — a Raspberry Pi with a 2-relay HAT and a BMP280 pressure sensor, controlled entirely via natural language through Cursor AI using the Model Context Protocol (MCP).&lt;/p&gt;

&lt;p&gt;No SSH. No custom scripts. Just ask.&lt;/p&gt;

&lt;p&gt;Here's the demo in action:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/PaKN3fWGJWk?si=nFGmwtecihj2VDOb" rel="noopener noreferrer"&gt;https://youtu.be/PaKN3fWGJWk?si=nFGmwtecihj2VDOb&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What is MCP?
&lt;/h2&gt;

&lt;p&gt;The Model Context Protocol (MCP) is an open standard that lets AI assistants connect to external tools and services. Think of it as a bridge between an AI client (like Cursor) and a system that exposes a set of tools the AI can call.&lt;/p&gt;

&lt;p&gt;In this case, the "system" is a Raspberry Pi running Orbit OS — an Android-like platform for embedded Linux that exposes device capabilities as secure APIs.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hardware:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Raspberry Pi 4&lt;/li&gt;
&lt;li&gt;2-relay HAT (Relay 1 = GPIO5, Relay 2 = GPIO6, active-low)&lt;/li&gt;
&lt;li&gt;BMP280 pressure/temperature sensor (I2C bus 1, address 0x77)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Software:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Orbit OS (Community Edition)&lt;/li&gt;
&lt;li&gt;MCP Server app — installed from the Orbit OS Store in one click&lt;/li&gt;
&lt;li&gt;Cursor AI with MCP configured&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Installing the MCP Server
&lt;/h2&gt;

&lt;p&gt;The MCP Server app is available on the Orbit OS Store. One click to install — no Docker, no SSH, no configuration files.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiai1llzodi63fuvu1okx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiai1llzodi63fuvu1okx.png" alt=" " width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once installed, the device exposes an MCP endpoint at:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6in8d1ndlanxqafhqxwy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6in8d1ndlanxqafhqxwy.png" alt=" " width="800" height="1056"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;http://&amp;lt;DEVICE_IP&amp;gt;:9999/mcp
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To connect Cursor, add this to your MCP config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"orbit-os"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://&amp;lt;DEVICE_IP&amp;gt;:9999/mcp"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the entire setup.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the AI can do
&lt;/h2&gt;

&lt;p&gt;The MCP Server exposes tools that the AI can call directly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;System&lt;/strong&gt; — device info, OS/runtime info, live metrics&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPIO&lt;/strong&gt; — list pins, set direction, read/write state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I2C&lt;/strong&gt; — scan bus, transfer bytes directly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apps&lt;/strong&gt; — list, install, uninstall .orb packages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Power&lt;/strong&gt; — reboot or shutdown the device&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update&lt;/strong&gt; — OTA install, factory reset&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And more — WiFi, Bluetooth, SPI, UART, PWM, Ethernet.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Demo
&lt;/h2&gt;

&lt;p&gt;Before starting the demo, I told Cursor the relay mapping and that there's an I2C device on bus 1 to be discovered. The AI was instructed to always call the MCP tools — never simulate hardware states.&lt;/p&gt;

&lt;h3&gt;
  
  
  Device Info
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Me: Give me the device info

Cursor: Device info — Raspberry Pi 4:
OS: Orbit OS | Kernel: Linux ARM64
CPU: Cortex-A72 | RAM: 1GB
Storage: 16GB | Architecture: ARM64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  System Health
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Me: Is the device healthy?

Cursor: Device health check:
✓ CPU temp: 42°C — normal
✓ RAM usage: 14% — normal
✓ Storage: 34% — normal
Device is healthy.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  GPIO Enumeration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Me: List all available GPIO lines

Cursor: [fetches live GPIO list from the device via MCP]
GPIO5 — input, unused
GPIO6 — input, unused
GPIO17 — input, unused
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Relay Control
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Me: I have a 2-relay HAT. Relay 1 is GPIO5, Relay 2 is GPIO6. Both active-low. Take note.

Cursor: Understood.
Relay 1 = GPIO5 | Relay 2 = GPIO6 | Logic: active-low.
Ready when you want to control them.

Me: Turn on all relays

Cursor: Turning on all relays.
✓ GPIO5 low, GPIO6 low — active-low applied.
Relay 1 = ON, Relay 2 = ON.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The relay LEDs light up physically on the HAT.&lt;/p&gt;

&lt;h3&gt;
  
  
  I2C Scan
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Me: Scan the I2C bus and tell me what you find

Cursor: Scanning I2C bus 1...
✓ Device found at 0x77 — BMP280 (temperature and pressure sensor).
Ready to read.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI discovers the sensor on its own — no prior knowledge of the address.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sensor Reading
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Me: Read the current temperature and pressure

Cursor: Reading BMP280 @ 0x77, bus 1:

TX: [0xF7] → RX: [0x56, 0x91, 0x20]
📊 Pressure: 961.2 hPa

TX: [0xFA] → RX: [0x83, 0x01, 0x00]
🌡️ Temperature: 25.6°C

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqc7ncs3sk8u1lqei7i8h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqc7ncs3sk8u1lqei7i8h.png" alt=" " width="799" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The raw I2C bytes are shown alongside the decoded values — the AI reads the registers directly using the MCP I2C transfer tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  Remote Reboot
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Me: Turn off all relays and reboot the device

Cursor: Turning off all relays and rebooting.
✓ GPIO5 high, GPIO6 high — both relays OFF.
Rebooting now — device back online in ~30 seconds.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yes, it actually reboots.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;The interesting part here isn't just the demo — it's what it represents.&lt;/p&gt;

&lt;p&gt;Traditionally, interacting with embedded hardware requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Knowledge of GPIO numbering, I2C addresses, register maps&lt;/li&gt;
&lt;li&gt;Custom scripts for every operation&lt;/li&gt;
&lt;li&gt;SSH access and terminal familiarity
With MCP + Orbit OS, the AI handles all of that. You describe what you want in natural language, and the AI translates it into the correct hardware operations via the MCP tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The I2C sensor reading is a good example of this. I didn't tell the AI which registers to read, what the raw bytes meant, or how to convert them into temperature and pressure values. I just asked for a reading. The AI knew the BMP280 chip by name, looked up the register map from its own knowledge, transferred the bytes directly via the MCP I2C tool, and converted the raw values — all on its own.&lt;/p&gt;

&lt;p&gt;This opens up embedded Linux hardware to a much wider audience — developers who know AI tools but don't have deep embedded experience can now interact with real hardware without the usual friction.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Orbit OS?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://orbit-os.org" rel="noopener noreferrer"&gt;Orbit OS&lt;/a&gt; is a recent open-core platform for embedded Linux and edge devices — inspired by Android's architecture.&lt;/p&gt;

&lt;p&gt;One of the core goals behind it is to accelerate embedded hardware development by removing the complexity of deployment, updates, and infrastructure — so developers focus only on their app logic. Just like Android lets you build mobile apps without knowing how the Linux kernel works underneath, Orbit OS lets you build applications and services for embedded Linux without needing any Linux knowledge at all.&lt;/p&gt;

&lt;p&gt;It provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A lightweight runtime (Gravity RT) that manages app lifecycle, hardware access, and OTA updates&lt;/li&gt;
&lt;li&gt;A multi-language SDK (Go, Python, Java, C++) for building apps&lt;/li&gt;
&lt;li&gt;An App Store for one-click distribution of &lt;code&gt;.orb&lt;/code&gt; packages&lt;/li&gt;
&lt;li&gt;Built-in AI inference support (TFLite, ONNX)
Community Edition supports Raspberry Pi 3, 4, 5, Zero 2W and Arduino UNO Q.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Beyond these officially listed boards, any ARM Linux device (armv6, armv7, or arm64) can be certified to run Orbit OS — for example, Banana Pi, Orange Pi, BeagleBone, and NVIDIA Jetson boards.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🔗 &lt;a href="https://store.orbit-os.org/app/app-mcp-server" rel="noopener noreferrer"&gt;MCP Server on Orbit OS Store&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔗 &lt;a href="https://orbit-os.org" rel="noopener noreferrer"&gt;Orbit OS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🎥 &lt;a href="https://youtu.be/PaKN3fWGJWk?si=nFGmwtecihj2VDOb" rel="noopener noreferrer"&gt;Demo Video&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  - 🎬 &lt;a href="https://youtube.com/@orbit-os-edge" rel="noopener noreferrer"&gt;YouTube — @orbit-os-edge&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;*Have questions or want to build something on Orbit OS?&lt;/p&gt;

</description>
      <category>raspberrypi</category>
      <category>mcp</category>
      <category>cursor</category>
      <category>ai</category>
    </item>
    <item>
      <title>Building an Android-like Platform for Embedded Linux Devices — Without Docker</title>
      <dc:creator>Peter H</dc:creator>
      <pubDate>Thu, 07 May 2026 21:26:25 +0000</pubDate>
      <link>https://dev.to/pharris/building-an-android-like-platform-for-embedded-linux-devices-without-docker-l57</link>
      <guid>https://dev.to/pharris/building-an-android-like-platform-for-embedded-linux-devices-without-docker-l57</guid>
      <description>&lt;h1&gt;
  
  
  Building an Android-like Platform for Embedded Linux Devices — Without Docker
&lt;/h1&gt;

&lt;p&gt;Every embedded Linux project seems to start the same way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSH into the device&lt;/li&gt;
&lt;li&gt;Install dependencies&lt;/li&gt;
&lt;li&gt;Configure services&lt;/li&gt;
&lt;li&gt;Set up OTA updates&lt;/li&gt;
&lt;li&gt;Handle networking&lt;/li&gt;
&lt;li&gt;Build custom APIs&lt;/li&gt;
&lt;li&gt;Repeat everything again for the next project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After rebuilding the same infrastructure multiple times across different edge and IoT projects, we decided to create a platform that abstracts all of that into a unified runtime.&lt;/p&gt;

&lt;p&gt;That platform became Orbit OS.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Orbit OS?
&lt;/h2&gt;

&lt;p&gt;Orbit OS is an embedded Linux platform designed to bring an Android-like experience to edge devices such as Raspberry Pi systems and other ARM-based hardware.&lt;/p&gt;

&lt;p&gt;Instead of using Docker containers, Orbit OS uses a lightweight native runtime called Gravity RT and a custom package format called .orb.&lt;/p&gt;

&lt;p&gt;The idea is simple:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8r3jov12gkfth89kbvqz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8r3jov12gkfth89kbvqz.jpg" alt=" " width="800" height="680"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install Orbit OS once, and the device gains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remote application deployment&lt;/li&gt;
&lt;li&gt;OTA updates&lt;/li&gt;
&lt;li&gt;Fleet management&lt;/li&gt;
&lt;li&gt;Sandboxed applications&lt;/li&gt;
&lt;li&gt;Unified hardware APIs&lt;/li&gt;
&lt;li&gt;Built-in Edge AI support (TFLite &amp;amp; ONNX)&lt;/li&gt;
&lt;li&gt;Application Store&lt;/li&gt;
&lt;li&gt;Real-time remote development tools&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Not Docker?
&lt;/h2&gt;

&lt;p&gt;Most existing edge platforms are built around containers.&lt;/p&gt;

&lt;p&gt;Containers are powerful, but for constrained edge devices they also introduce additional RAM, storage, startup, management overhead, and OTA size.&lt;/p&gt;

&lt;p&gt;Orbit OS was designed for environments where devices may only have 128–256MB of RAM available.&lt;/p&gt;

&lt;p&gt;Instead of Docker, applications run directly through Gravity RT using lightweight .orb packages (like Android .apk).&lt;/p&gt;

&lt;p&gt;This allows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lower memory usage&lt;/li&gt;
&lt;li&gt;Faster startup&lt;/li&gt;
&lt;li&gt;Smaller packages&lt;/li&gt;
&lt;li&gt;Native hardware access&lt;/li&gt;
&lt;li&gt;Simpler deployment model&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Gravity RT Architecture
&lt;/h2&gt;

&lt;p&gt;Gravity RT runs on top of an existing Linux distribution and acts as the system runtime for all applications.&lt;/p&gt;

&lt;p&gt;Core architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hardware
└── Linux
    └── Gravity RT
        ├── Gravity Server (Go)
        ├── gRPC APIs
        ├── UDS communication
        ├── mTLS external APIs
        ├── Lazy-loaded JVM
        ├── Lazy-loaded Python VM
        └── Built-in TFLite and ONNX runtime
            └── Orbit OS Ecosystem
                ├── Unified Multi-language .orb packages
                ├── Orbit Studio
                ├── Orbit OS Store (Certified Aplications)
                └── Orbit OS HW Marketplace* (Certified Hardware Devices) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Gravity Server is written in Go and remains always active as the parent process for all .orb applications.&lt;/p&gt;

&lt;p&gt;It manages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Application lifecycle&lt;/li&gt;
&lt;li&gt;Restart policies&lt;/li&gt;
&lt;li&gt;OTA coordination&lt;/li&gt;
&lt;li&gt;Security&lt;/li&gt;
&lt;li&gt;Logging&lt;/li&gt;
&lt;li&gt;Package management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkn73en8kh93887mo2pjz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkn73en8kh93887mo2pjz.jpg" alt=" " width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-Time Remote Development
&lt;/h2&gt;

&lt;p&gt;One of the most interesting parts of Orbit OS is the development workflow.&lt;/p&gt;

&lt;p&gt;Traditional embedded development usually looks like this:&lt;/p&gt;

&lt;p&gt;Write code → Compile → Deploy → Run → Debug → Repeat&lt;/p&gt;

&lt;p&gt;Orbit OS changes this model completely.&lt;/p&gt;

&lt;p&gt;With Orbit Studio (VS Code extension), developers write code locally while executing directly against real hardware in real time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyflyb0ca5c6j6l0fu9ww.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyflyb0ca5c6j6l0fu9ww.jpg" alt=" " width="800" height="439"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Laptop
├── Write code locally
├── SDK connects to device via gRPC/mTLS
├── Code runs on live hardware instantly
├── Logs stream back in real time
└── Generate the .orb package only when ready
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The device becomes a real-time execution target instead of a deployment target.&lt;/p&gt;

&lt;p&gt;No SSH.&lt;br&gt;&lt;br&gt;
No file transfers.&lt;br&gt;&lt;br&gt;
No deployment loop during development.&lt;/p&gt;

&lt;p&gt;▶️ &lt;a href="https://youtu.be/8BTXqhzp6jM?si=FW6I2TrrC2WNRiUn" rel="noopener noreferrer"&gt;Orbit OS — Orbit Studio First App | Real-Time Remote Development, GPIO LED Control &amp;amp; Deploy&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The .orb Package Format
&lt;/h2&gt;

&lt;p&gt;Orbit OS applications are distributed as signed .orb packages.&lt;/p&gt;

&lt;p&gt;A package contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Executable binaries&lt;/li&gt;
&lt;li&gt;NV data like AI models&lt;/li&gt;
&lt;li&gt;Resources&lt;/li&gt;
&lt;li&gt;Manifest&lt;/li&gt;
&lt;li&gt;Cryptographic signatures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The structure is intentionally similar to Android APKs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built-In Edge AI
&lt;/h2&gt;

&lt;p&gt;TensorFlow Lite and ONNX support are included directly in the platform,&lt;br&gt;
accessible via the AI Manager SDK API.&lt;/p&gt;

&lt;p&gt;Applications do not need to bundle inference runtimes or manage dependencies.&lt;br&gt;
Apps only bring the model and the logic — the platform handles the rest.&lt;/p&gt;

&lt;p&gt;The AI Manager automatically selects the correct backend based on the model type:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.tflite&lt;/code&gt; models → TensorFlow Lite runtime&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.onnx&lt;/code&gt; models → ONNX runtime&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Current AI applications already available in the Store:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;YOLOv8 object detection&lt;/li&gt;
&lt;li&gt;Face recognition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All inference runs locally on-device. No cloud. No external APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  OTA Updates
&lt;/h2&gt;

&lt;p&gt;Orbit OS uses OSTree for runtime updates.&lt;/p&gt;

&lt;p&gt;This provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Atomic updates&lt;/li&gt;
&lt;li&gt;Rollback support&lt;/li&gt;
&lt;li&gt;Immutable runtime layers&lt;/li&gt;
&lt;li&gt;Safe recovery&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The runtime can update itself without rebooting the full Linux system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Orbit OS Store
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwuaj8k90oonbb3n772zl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwuaj8k90oonbb3n772zl.jpg" alt=" " width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Orbit OS includes a centralized application store where developers can publish .orb applications and users can remotely install them across devices linked to their account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftaziva5uokxy4s8xhbui.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftaziva5uokxy4s8xhbui.jpg" alt=" " width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Features currently implemented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One-click installation&lt;/li&gt;
&lt;li&gt;Remote deployment&lt;/li&gt;
&lt;li&gt;App updates&lt;/li&gt;
&lt;li&gt;OTA runtime updates&lt;/li&gt;
&lt;li&gt;Fleet management&lt;/li&gt;
&lt;li&gt;Multi-device deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Apps Available Today
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;KS0212 4-Channel Relay Shield&lt;/strong&gt; — Web UI, Modbus TCP server, MQTT with Home Assistant auto-discovery. One click, zero configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mochi MQTT Broker&lt;/strong&gt; — Lightweight MQTT broker with integrated Web UI. Configure ports, users and settings from the browser.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edge AI — Smart Image Detection&lt;/strong&gt; — YOLOv8 COCO object detection using TFLite. Runs locally, no cloud, no external APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edge AI — Face Recognition&lt;/strong&gt; — Real-time face recognition with any connected camera. Enroll faces in under 10 seconds. 100% offline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Server&lt;/strong&gt; — Manage your device with AI Agents.&lt;/li&gt;
&lt;li&gt;And more...&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  App Example — Edge AI Smart Image Detection
&lt;/h3&gt;

&lt;p&gt;Edge AI – Smart Image Detection is an Orbit OS application that performs &lt;br&gt;
real-time object detection locally on edge devices using YOLOv8 TensorFlow &lt;br&gt;
Lite models.&lt;/p&gt;

&lt;p&gt;Users can remotely install the application from the Orbit OS Store with a &lt;br&gt;
single click on any device linked to their account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdk64he2v0r7bctr9h6f.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdk64he2v0r7bctr9h6f.jpg" alt=" " width="800" height="792"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After being installed in seconds, users can upload images directly from the browser, detect and label objects with bounding boxes, inspect inference timing, and view the raw JSON output generated by the AI service.&lt;/p&gt;

&lt;p&gt;The application runs entirely on-device through the Orbit OS AI Manager API using YOLOv8 / COCO TensorFlow Lite models, with no cloud processing, Docker containers, or manual setup required.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7tu3ba82oisf2cpcui7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7tu3ba82oisf2cpcui7.png" alt=" " width="800" height="1035"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This video demonstrates the application running simultaneously on two different devices: a Raspberry Pi 5 vs Arduino UNO Q.&lt;br&gt;
Same App, same Model. Different hardware, different performance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz283yw85c6ke4kuflf91.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz283yw85c6ke4kuflf91.jpg" alt=" " width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;▶️ &lt;a href="https://youtu.be/aiFJmosYVAI?si=ARqaGKb9iQTYtb5m" rel="noopener noreferrer"&gt;Orbit OS — Edge AI Object Detection | YOLOv8 | Raspberry Pi 5 &amp;amp; Arduino UNO Q &lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Current Status
&lt;/h2&gt;

&lt;p&gt;Currently supported:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Raspberry Pi 3,4,5,Zero 2W&lt;/li&gt;
&lt;li&gt;Arduino UNO Q&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SDKs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go (available)&lt;/li&gt;
&lt;li&gt;Java (beta)&lt;/li&gt;
&lt;li&gt;Python (beta)&lt;/li&gt;
&lt;li&gt;C++ (planned)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Orbit OS Community Edition and the Go SDK are now available.&lt;/p&gt;

&lt;p&gt;We are currently looking for developers interested in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Embedded Linux&lt;/li&gt;
&lt;li&gt;Edge AI&lt;/li&gt;
&lt;li&gt;Raspberry Pi&lt;/li&gt;
&lt;li&gt;Industrial IoT&lt;/li&gt;
&lt;li&gt;Runtime systems&lt;/li&gt;
&lt;li&gt;Remote deployment tooling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you build something with the SDK, we would love to hear about it — &lt;br&gt;
drop a comment or reach out at &lt;a href="mailto:info@orbit-os.org"&gt;info@orbit-os.org&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo Videos
&lt;/h2&gt;

&lt;p&gt;▶️ &lt;a href="https://youtube.com/@orbit-os-edge" rel="noopener noreferrer"&gt;https://youtube.com/@orbit-os-edge&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://www.orbit-os.org" rel="noopener noreferrer"&gt;https://www.orbit-os.org&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Store: &lt;a href="https://store.orbit-os.org" rel="noopener noreferrer"&gt;https://store.orbit-os.org&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Download: &lt;a href="https://www.orbit-os.org/downloads.html" rel="noopener noreferrer"&gt;https://www.orbit-os.org/downloads.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Getting Started: &lt;a href="https://www.orbit-os.org/getting_started.html" rel="noopener noreferrer"&gt;https://www.orbit-os.org/getting_started.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>raspberrypi</category>
      <category>arduino</category>
      <category>embeddedsystems</category>
    </item>
  </channel>
</rss>
