Cover image preview Cover image

The Architecture of HomeGenie (Ep. 2) - Harmony through Modularity

by Gene — posted on 28 September 2018

It's been a few months since my last post about the origins of HomeGenie and how the Multi Input Gateway (MIG) was born. If you missed it, we talked about Wii Remotes, Silverlight, and moving away from HTTP bottlenecks towards a more fluid communication.

Today, I want to talk about lightness. Or rather, how to find balance and well-being in a growing project through cooperation.

If you take a look at the recent commit history in the mig-service-dotnet repository, you might notice a rather significant change that happened just a few days ago:

commit 704e847e9c7686c5519036b55600652ab4f4daa5
Author: Generoso Martello 
Date:   Mon Sep 24 21:58:23 2018 +0200

    detached MIG.HomeAutomation and MIG.Protocols to own repos

This single line of log actually represents a profound architectural shift for HomeGenie, moving towards a healthier and more distributed ecosystem. Let me explain why I decided to distribute the responsibilities of the core.

The Burden of the "All-in-One"

When you start a project, keeping everything in a single repository feels incredibly convenient. You change a core interface, you instantly update the protocol wrapper, and you hit compile. Everything is in one place.

But as HomeGenie grew, the MIG core started to carry too much weight. It was holding the core I/O routing logic, the WebSocket gateways, but also the highly specific code for UPnP, X10, Insteon, and the massive Z-Wave protocol.

This created a couple of issues that were hindering the fluidity of the project:

  1. Unnecessary Baggage: Why should a user (or a developer) who only wants to use HomeGenie for simple MQTT messaging be forced to download and compile heavy Z-Wave databases and Serial Port libraries?
  2. Maintenance Frictions: Serial port handling across different OSes (Windows, Linux, and Mono on ARM boards like the Raspberry Pi) is naturally tricky. Whenever I needed to fix a low-level serial port detail, I had to bump the version of the entire MIG core, affecting parts of the system that had nothing to do with it.

It was time to give each piece its own breathing room.

Distributing Responsibilities

Over the last few weeks, I’ve been busy extracting the protocol-specific logic out of the main repository, delegating tasks to independent, specialized actors.

I created standalone repositories for these essential pieces of the puzzle:

By isolating the Z-Wave and SerialPort logic into their own independent .NET libraries, something beautiful happened. Not only did the HomeGenie core become much lighter and faster to compile, but these libraries are now fully independent NuGet packages.

This is the true spirit of sharing. Now, if another developer out there is building a completely unrelated .NET application and just needs a rock-solid, portable library to talk to a Z-Wave dongle or to read a serial port on a Raspberry Pi, they can simply pull zwave-lib-dotnet via NuGet. They don't need to know anything about HomeGenie. They just benefit from the shared work.

A Harmonious Mindset

If you've been reading my recent posts about zuix.js and component-based web development, you will definitely see a pattern here.

What I am doing with the backend architecture of HomeGenie is exactly the same concept I've applied to the frontend with zuix.js. It's about independent entities cooperating smoothly to build a greater whole.

On the web, we load isolated .html/.css/.js widgets only when they are needed on the dashboard, keeping the DOM light and responsive. On the backend, MIG now acts simply as a peaceful "orchestrator" or bus, dynamically loading MIG.HomeAutomation modules and protocol libraries only if the user actually invites them to participate in their setup.

💡 Developer Takeaway

Keeping all your code in a single, monolithic structure might seem easier at first, but it ultimately restricts growth and sharing.

If you find yourself writing a generic utility (like a serial port handler) inside a domain-specific application (like a smart home hub), give it its own space. Make it a standalone library. By distributing tasks and focusing on modularity, you create a healthier environment for your codebase, and you foster an open-source ecosystem where everyone can share, collaborate, and benefit.

Well, that's it for today's architectural thoughts. Time to go outside and get some fresh air!

Talk to you soon =)

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