Skip to main content

· 3 min read
Marius Andra

FrameOS started its life as a Python app that displays an image on a Pimoroni eInk display that's connected to a Raspberry Pi Zero W:

... and a web interface to edit and deploy apps over SSH to said Raspberry Pi:

I wrote it in Python, as that's what the e-ink display drivers came in. It took 40 seconds to refresh the display, so speed of rendering was not a concern.

In the meanwhile, I had added another screen to my house, a cute little Pimoroni HyperPixel 2.1 Round to control the hot water in the bathroom:

I was able to get FrameOS running on it at 2 FPS. While that's enough to show a clock with just seconds, it won't be enough if I want to add a temperature slider or any other interactive elements.

While an eventual rewrite of FrameOS in a compiled language seemed inevitable (why not get the speed and efficiency gains?), seeing how this Python MVP was already getting usage in the wild, I decided to jump the gun and rewrite it all in Nim already now. Doing it later would have been painful for everyone.

But why nim?

What sold me on it were 1) it's features, 2) the praise in the Nim 2.0 HN post, 3) the fact that it definitely is used for real time graphics, and 4) the fact that it has a great graphics library called pixie that supports both SVG and font rendering out of the box.

It's syntax is really friendly after just a bit of usage, it compiles really fast, it has great interop with C libraries, and did I mention it has a great graphics library?

If you imagine native-compiled type-annotated Python where nearly 100% of your code is business logic with no cruft, you're getting close to the Nim experience.

The closest thing to a useful SVG and font library in Python would have been pixie-python, but it's one version behind the nim version, and at this point, why bother with the extra layer of abstraction?

The other compiled languages I considered, like Rust, Zig, Mojo, and Go, all had their own issues, and none hit that sweet spot the way Nim did. Going deep into them would be a post of its own, so let's leave it for another time.

The rewrite

The rewrite was pretty straightforward. It of course took longer than expected, but after about a week of work, I now have something that is (almost) feature complete with the Python version that came before it, while being 10x as fast. 🔥🔥🔥

I also sneaked in a few new features: inline code snippets to override any value, and color fields.

Sadly the rewrite is not fully backwards compatible, as I took the opportunity to clean up some variable and other names. I ask for forgiveness, and hope the 10x wins in efficiency make it well worth it though. It's best to restart all scenes from scratch.

If you wish to remain on the old python version, make sure to stop using the latest docker tag, and instead pin to the last docker tag that starts with legacy-python-.

I hope you enjoy the new version, and I'm looking forward to seeing all the cool FrameOS apps in the wild. ❤️

The work is not done yet. The todo list keeps expanding.

· One min read
Marius Andra

You can now chat with GPT4 directly inside FrameOS when building apps:

ChatGPT and FrameOS

To enable this, simply set your OpenAI API key in the settings, and make sure you have access to GPT-4.

· One min read
Marius Andra

The first phase of FrameOS development is complete. The MVMVP milestone has been achieved, making it feature complete for my own home use.


You can now edit and deploy python code directly from FrameOS.

· 2 min read
Marius Andra

About a year ago we moved to a new house. The light-to-switch situation downstairs was unbelievably inconsistent. To fix that, I placed little Zigbee switches behind every light toggle, and taped Philips Hue Dimmer switches over the old physical ones. Thus began my journey into smart homes.

A year later, the biggest first world problem I had was losing time running around the house, closing all windows, before rushing out to pick up the kids from school. There's not a lot of crime around here, but if they get you, it's by learning your patterns of forgetfulness.

The obvious answer was to install Zigbee sensors on all the windows, and put a small screen next the front door.

Turns out Raspberry Pi powered color e-ink displays are actually not that expensive, so that's what I went with:

However the software side of things was rubbish.

Enter FrameOS.

It's a piece of software that SSH-s into a Raspberry Pi, and installs python scripts which display an image in a loop.

It has also slowly scope creeped its way into a visual programming environment on sorts:

This project is fresh, so expect things to break. But if you're interested in trying it out, check out the installation instructions