Run an entire house on the edge device and let the AI agent manage it through the MCP protocol. This direction coincides with the Agent ecosystem that our .NET community has been promoting recently, and it is worth talking about.
Recently, I found an interesting warehouse called SmartHaus on GitHub, and I forked a copy (github.com/geffzhang/SmartHaus). What attracted me was its positioning description: Agentic-on-the-Edge smart home implementation w/ Microsoft Agent Framework & Model Context Protocol. Translated into human words: run an entire house on an edge device and let the AI agent manage it through the MCP protocol. This direction coincides with the Agent ecosystem that our .NET community has been promoting recently, and it is worth talking about.
I just happened to read Y00’s article “KNX Lighting System Principles and Development Examples Based on KNX.net” in the blog park a while ago. It was about that he took on a small project and connected KNX lighting to the .NET backend. As a result, he was frustrated by the building control logic of “group address”, “ETS” and “broadcast plus filtering” for several days. There is a sentence at the end of that article that impressed me deeply: KNX is not the same idea as consumer-grade wireless solutions. It pursues certainty, long life, and cross-vendor interoperability at the expense of wiring costs and debugging thresholds.
These two things collided, so I cloned the source code of SmartHaus over the weekend and looked through it. Thirty-two projects, more than 540 C# files, and 36,000 lines of code. After reading it, my feelings are a bit complicated: this may be the most “non-demo” AI smart home project I have ever seen – others use Python to wrap a layer of Home Assistant’s API and dare to post videos. This author wrote all the leader election of the KNX bus, message deduplication, and blind travel tracking, and then threw the large model out of the system. By the way, the warehouse is all in English, so this article will walk through it for everyone.
Spend two minutes to understand KNX first, otherwise you won’t be able to understand it later
If you are like me before and your understanding of KNX is limited to “a very expensive smart home bus”, I suggest you read Y00’s article first, which is very thorough. Here are just three of the most critical pieces of information:
Between KNX switch panel and lampNo direct wire connection. The panel is connected to the KNX bus (a twisted pair that transmits signals and 29V DC power supply at the same time), and the lamp is connected to the 220V strong current circuit controlled by the actuator. The two are logically tied together by the “group address”.
The control method isbroadcast plus filter. Click the panel, and the panel sends a message with a group address to the bus. All devices on the bus can receive it, but only the actuator listening to this group address will act. Therefore, even if the central control in the KNX system is disconnected, the lights can still be turned on – the functional logic does not rely on the central controller.
The binding relationship between the device and the group address is burned in at one time using the official configuration software ETS. This project file exported by ETS will appear repeatedly later, so remember it.
What exactly is SmartHaus?
The original author is f2calv, whose real name is Alex Vincent, an old man who maintains the CasCap series of .NET open source libraries all year round. The warehouse was only built in April this year. It is under the MIT protocol and is based on .NET 10. The first sentence of the README honestly states: This is an early proof of concept. The interface will change at any time and no support is provided.
But the list of devices it connects to is anything but “proof of concept”: Buderus heat pump heating, Fronius photovoltaic inverter, KNX building control bus, DoorBird door station, UniFi Protect camera, Miele appliances, Shelly smart sockets, WiZ light bulbs, Sicce aquarium pump, plus the edge host’s own CPU, GPU and GPIO. It can be seen that this is a family bucket of a European single-family house. The author really lives in the code he wrote.
The main line of the entire system is actually just one:Device events come in and AI commands go out. I redrawn an architecture diagram based on the source code. It will be much smoother to look at the diagram first and then read the text:

To put it into detail: Each device integration is a feature service, which polls the device or collects webhooks, and throws events to a set of pluggable “event sinks” – Redis, Azure Tables, Blob, and SignalR, each taking what it needs. Redis streams then feed domain events to the communication pipeline, which connects to two external services: Signal gateway signalizr and multi-tenant agent runtime agentizr. The user posts a message in the Signal group, and the large model in the agent runtime determines which tool to call. The tool calls back the interface exposed by SmartHaus through the MCP protocol, and finally falls on the device.
Pay attention to a boundary division. I think this is the most sober design decision in the whole project:SmartHaus does not construct large model proxies itself. The README is very straightforward. Agent definition, sessions, which model to choose, and key management are all matters of the external Agent Runtime. SmartHaus just turns your house into a set of useful tools. The big model will be this year and that next year, and the bus and heat pump will not be replaced.
The four most worth-seeing places in the source code
1. KNX integration: Go directly to the official SDK and take it seriously
Y00 used KNX.net, a community library, for his blog. He himself said that “the API is not complicated and is sufficient.” SmartHaus’s KNX library directly references Knx.Falcon.Sdk – the official Falcon SDK of the KNX Association, the kind that requires a license fee for commercial projects – plus Tiveria.Home.Knx as a supplement. Both KNXnet/IP access methods, Tunneling and Routing, are implemented.
What really made me stop and read carefully were these paragraphs:
When deploying multiple copies, Redis RedLock is used for leader election. Only the instance that grabs the leader holds the bus connection, and the standby copy does not even consume the queue of outgoing commands. There is a dedicated reconnection channel for bus disconnection, which can be restored one by one according to the area/line topology of KNX. Incoming packets must go through deduplication filters divided by service families. Because Falcon’s events are synchronous callbacks, the author also left a TODO in the code. Frankly, he would rather not add a bound before thinking about the backpressure strategy – “silent discarding is unsafe.” This kind of comment shows that I have been tricked at first glance.
The most interesting thing is the resolution of group addresses. KNX itself doesn’t matter how you name the group address, SmartHaus has set a set of hyphen segmentation specifications: the floor uses the German abbreviation KG/EG/OG/DG (basement, first floor, second floor, top floor), and the categories are divided into eight categories: lighting LI, blinds BL, heating HZ, socket SD, plus room, orientation, and lamp type. The XML exported by ETS is fed in and the frozen dictionary is matched piece by piece.If there are remaining segments after parsing, it means that the naming is not compliant, and the entire address will be skipped directly.。
Even more ruthless is the iron rule established for AI programming assistants in copilot-instructions.md: KNX project files are the only source of fact for naming. The name is wrong, go back to ETS to change it, and re-export it after changing it.You are not allowed to manually modify the exported files, and you are not allowed to compensate for incorrect metadata in the code.. I have seen too many projects that are built with patches in the code. This discipline of “pollution control at the source” can honestly illustrate the quality of the project better than any architecture diagram.
2. MCP tool layer: sixty-nine tools, all of which are written “fool-proof”
After counting, the ten domain services in CasCap.Backend exposed a total of sixty-nine MCP tools: twenty-one KNX buses, fifteen smart lighting, nine home appliances, eight front doors, seven photovoltaics… covering heating, hot water, blinds, door locks, cameras, and aquarium pumps.
Tool design is more realistic, just pick a few examples.
All write operations take the dryRun parameter. For large models, you can first “dry run” to verify the parameters and confirm that there are no problems before actually issuing them. This is the first gate to prevent AI hand slippage.
Moving the blinds is a long movement, physically taking nearly a minute. Waiting will delay the conversation, so we created a tracked operation: the tool immediately returns “Moved has started”, and then pushes the completion message back to the chat after the trip is completed. Even more detailed is the processing of the blade angle – there will be problems with the moving blade before the vertical stroke stops, so the position command is sent out first in the code, and the blade command is sent later.
The Description of the tool is not for humans, but for large models, and domain knowledge is directly filled in it. For example, the description of the blind tool says in black and white: “Note that according to KNX convention, 0 equals fully open and 100 equals fully closed. When closing the blinds for privacy, remember to set the blade angle to 100.” Even the anti-illusion clarification that “the closing magnetic sensor is not a lock sensor and cannot detect whether the lock is locked” is included in the description of the front door status tool.
Even the error report for verification failure is written to the model. If you ask a group of blinds to go to a certain location, but there is no location control address in the group, the error message returned will look like this: This group has no POS address and cannot be moved; the individual blinds below can be moved, and you can control them one by one; or adjust get_house_shutter_states first to find out.The error message itself is the next step for large models.——This is the first time I’ve seen someone do this detail so thoroughly.
In addition to tools, there are also premade prompts such as MCP prompts: SummariseHeatingStatus, CheckHotWater, and CheckSystemHealth, which solidify high-frequency tasks such as “inspecting the heating system” into templates, and users can trigger the complete inspection process in one sentence.
3. Agent layer: the breath of life in the system prompt words
The user’s entrance is the Signal group chat. There is a screenshot in the warehouse that I looked at several times (see the picture below, which can be used directly when publishing): the user asked “How is the heating, how is the energy situation, is the front door closed?” The orchestration agent called Smart Haus ran on the local Ollama’s qwen3.5:9b, and turned around to consult three sub-agents – the heating agent used OpenAI gpt-5-mini, the energy agent used AzureOpenAI gpt-4o-mini, and the security agent used local qwen. 58.7 seconds, three tool calls, 23.3KB of context, and finally put together a structured home status report. The local small model serves as the scheduler and the cloud model serves as the expert. This combination is very pragmatic.

The agent’s system prompt words (there are public examples in docs/agent-examples) are very life-like:
During the day (from 7 a.m. to 10 p.m.), you can proactively send at most one message per hour, and shut up at night—unless there are safety incidents such as smoke alarms or equipment failures. Unimportant events are digested silently, and important ones are gathered together into one briefing. Voting tools must be used when providing options to users.Never list options in text; After the voting results come back, close the voting and then execute it. You are only allowed to provide actions that you really have the tools to perform – no drawing is allowed.
When a voice message comes in, it is first converted into text by whisper (whisper.cpp or WhisperAsr service will do, and Azure can be switched in the configuration) and then fed to the model. Replies can be sent back to voice using TTS. When the camera captures a person, UniFi Protect’s webhook calls in, FFmpeg cuts out the clip, and it can also be sent to the visual agent to identify “who is at the door.”
4. Engineering: One person maintains the team’s formation
The thirteen function switches (Buderus, Comms, Knx, Fronius…) are separated by commas in the configuration. Functions without hardware cannot be turned on and will not be initialized blindly.
You don’t need real equipment to experience it:docker compose --profile demo up --build With one command, Redis, Azurite (a local simulator of Azure storage), and OpenTelemetry are all bucketed together, and then curling a simulated camera humanoid detection event is entered, and the entire event link can be viewed. There are .http files for each controller in the requests directory. Just click on the REST Client plug-in of VS Code.
The deployment side is a Helm chart plus a Grafana dashboard. The house overview, energy consumption, lighting, HVAC, and water pump dashboard JSON are all released with the warehouse. There is no shortage of CI, SonarQube quality gate, pre-commit, and test projects for each integrated library. The eight device client libraries are sent to NuGet separately. You don’t want to run the entire SmartHaus set. dotnet add package CasCap.Api.Fronius You can also take it back and poll your own inverter.
There are also two “endearingly honest” places. There is a sentence in the README: This README does not report an executed demo——This README does not claim that the above demo was actually run. The version notes say: Version 1.1deliberatelyIncompatible changes have been introduced in minor versions. Consumers are asked to recompile and migrate. I have seen too many projects hide breaking changes, and I am willing to trust this kind of honesty.
By the way, a meta-level observation: This project itself is a model room for AI-assisted development. Copilot-instructions, shared instruction libraries, and design documents also include a complete plan for introducing Squad (a human-led AI development team) and speckit. One person and an AI team maintain a system of 36,000 lines of code running in a real house – this matter itself is as worthy of consideration as the content of the project.
Pour some basins of cold water on it
Don’t be in a hurry to go online right after star is finished, the threshold must be clearly stated.
To run the full set, you really need to have a bunch of European hardware—Buderus heat pumps, Fronius inverters, and a house with KNX bus. If you don’t have hardware, you can only play the demo file, which does not include AI dialogue. The communication function requires the deployment of two additional services, agentizr and signalizr. Although these two services are also open source, the ecosystem is basically limited to the author alone.
The group address naming convention is the author’s own convention. If you want to reuse the KNX part, your ETS project must be renamed according to his rules, otherwise the parser will skip your address directly. The project itself also said that in the early PoC, the interface changes at any time.
Another point is that the “smartness” of the entire system depends on the external agent runtime, and the SmartHaus warehouse itself does not contain any model orchestration code – if you expect Jarvis to work out of the box, you will be disappointed.
Two final words
I have seen too many “AI smart home” demonstrations in the past two years. Most of them are large models with function calling and a layer of ready-made platform API behind them. After the demonstration, there is nothing more. SmartHaus in turn: four-layer pipelines, leader election, message deduplication, dry run verification, and trip tracking. All efforts are focused on the device side, and the large model is the most replaceable part of the entire system.
I quite agree with this sequence.AI is easy, houses are difficult. The more rigorous the tool layer is, the more reliable the model connected to it will be. If the tool layer is fooled, no matter how powerful the model is, it will only produce erroneous switching instructions faster.
If you have a .NET background and are interested in building control, Internet of Things, or AI Agent engineering, this repository is worth adding to your favorites and slowly browsing. Even if you don’t run, you will gain a lot by just reading the code of the KNX library and MCP tool layer. If you find it useful, please give it a star or forward it to your friends who are engaged in smart hardware.
Related links