Cover image preview Cover image

The Architecture of HomeGenie (Ep. 1)

by Gene — posted on 15 February 2018

From Wii Remotes to 'Homebrew' Web Components

Today, I took a moment to look at the server logs and the HomeGenie codebase, and I figured it was the right time to write down some of the history behind this project. If you look at the GitHub repository for MIG (Multi Input Gateway), you'll see that the initial commit dates back to August 2015. But the truth is, to tell the story of how we got here, we have to jump back to 2009, during the golden age of SourceForge.net.

Back then, HomeGenie wasn't even an idea. I was experimenting with unconventional interfaces: I wanted to use Nintendo Wii controllers (Wii Remotes) or Microsoft Kinect depth sensors to control web applications. To do that, I was using the TUIO protocol.

MIG was born exactly for this purpose: it was a middleware. An "invisible" piece of software that sat in the middle, listened to signals from disparate hardware, normalized them, and routed them to other applications using a unified language. Without knowing it, I was writing the very first draft of what has today become HomeGenie's Universal API Bus.

The Silverlight Era, MIRIA SDK, and the DIY Multitouch Table

But how did MIG, back in those years, send Wii Remote motion data to a web page in real-time?

Today we take WebSockets for granted, but a decade ago, browsers were rigid, closed boxes. The only technically viable way to open a raw TCP communication channel to a web application was to use a plugin: Microsoft Silverlight.

So, I picked up Silverlight 2 and wrote an entire dedicated UI framework from scratch, which I called MIRIA SDK (if you dig deep enough, I believe it's still mentioned in the old official academic papers of the TUIO protocol!). The use case for all this? Pure hardware hacker madness: I physically built a multitouch table/display with my own hands. Keep in mind that at the time, commercial multitouch screens basically didn't exist. MIG read the physical inputs, translated them into TUIO, and streamed them via TCP to the MIRIA SDK running in the browser on this custom-built table. It was pure, handcrafted magic.

The Great GitHub Migration and the Obsession with Portability

Between 2014 and 2015, SourceForge started suffering from continuous DDoS attacks and prolonged downtimes. It had become unreliable, so I made the call to pack my bags and move everything to GitHub.

That migration was the perfect opportunity for a profound architectural rethink. The goal for the "new" MIG was clear: it needed to have as few dependencies as possible, and it had to run everywhere.

Let’s pause for a second to remember what "cross-platform" actually meant back then. Today we are starting to see the first concrete efforts from Microsoft to open up their ecosystem, but at the time, the idea that a .NET binary could run natively outside of Windows wasn't even remotely on their radar. The C# world was a walled garden. If you wanted to port your code to Linux or, even worse, to early ARM boards like the first-generation Raspberry Pi, you had only one true hero and ally: the Mono runtime.

Choosing C# for an embedded/IoT system was a real gamble, but I didn't want MIG to be a toy just for hardcore techies. It had to be a clean binary, capable of running smoothly on any architecture without forcing the user to compile complex C/C++ source code specific to each platform. I wanted to democratize home automation, and Mono allowed me to do just that.

Sleepless Nights: The Battle Against HTTP and SSE

Ditching Silverlight and moving to pure web interfaces brought back the problem of real-time communication. Reading through my logs from Autumn 2015, I'm reminded of a rather frustrating period. I was trying to get the backend to talk to the User Interface.

Initially, I relied on SSE (Server-Sent Events) over a classic HTTP protocol. On paper, it was a good idea, but in practice—especially on our beloved, resource-constrained ARM platforms running Mono—it turned into a nightmare. A few commits from that period speak for themselves:

- fix to WebService SSE not closing sockets in a CLOSE_WAIT state (October 2015)
- fixed SSE events concurrency bug (September 2015)
- fix to event propagation deadlock bug (September 2015)
- Fixed continuous 'event stream disconnected' issue occurring on some mono-arm platforms (November 2015)

The system kept tripping over itself. HTTP connections weren't closing properly, sockets were left hanging in CLOSE_WAIT (exhausting OS resources), and worse, concurrency issues were causing deadlocks across the entire event bus.

It was a clear sign that the paradigm had to change. Polling and artificially kept-open HTTP connections are not the right path for a reactive IoT system. That's why I've recently started laying the groundwork for native WebSocket (and MQTT protocol) integration. A truly asynchronous, bidirectional communication channel that is finally resolving our I/O bottlenecks.

5 Days of Pure Coding: The Birth of zuix.js

With the backend data transport issue (mostly) solved, the real bottleneck inevitably shifted to the user interface.

Currently, the HomeGenie UI is based on jQuery Mobile. It did a great job allowing me to quickly prototype a smartphone-friendly interface. But there was a massive functional problem: I wanted users to be able to write custom "widgets" (snippets of HTML/CSS/JS) directly from the HomeGenie UI and load them at will onto the dashboard.

With jQuery Mobile, handling the dynamic injection of these code snippets without collapsing the DOM was an absolute nightmare. No one in the frontend landscape is widely talking about Web Components yet (it's still a very green and experimental concept), but that was exactly what I needed: isolated, reusable, and independent components.

So, a couple of months ago, bridging late 2016 and early 2017, I had one of those creative bursts that every developer knows well. I locked myself in and, in 5 days of intense coding, I wrote a tiny library from scratch. I called it zuix.js.

In its primordial form, zuix.js is running right now inside HomeGenie's jQuery Mobile UI. It does exactly this: it takes a snippet of user-written code and renders it as an isolated widget on the dashboard. I didn't know it yet, but in those 5 days, I planted the seed for what I believe will become an essential library for the future of the project.

💡 Developer Takeaway

If there's one thing these years of development have taught me, it's this: Abstract your I/O as early as possible.

Creating a middleware (MIG) that exposes a unified "Bus" is what saved HomeGenie's architecture. When I decide to throw away SSE and switch to WebSockets, I only have to rewrite the transport gateways. The automation logic and the plugins don't notice a thing. Decoupling isn't just a theoretical design pattern; it's a shield against madness.

In the next dev diary entry, I’ll tell you about how I’m trying to extract and clean up the logic of the various protocols (Z-Wave, Serial, etc.) to make the core of the system leaner and more modular. Until next time!

-~=(glabs.it)=~- Home | Posts | About |