This project brings AWS Lambda-style compute to the smart-building edge β letting you deploy, control, and orchestrate Python automation agents next to your BACnet systems. Each agent runs as its own OS process, fully isolated with its own Python environment, while Linux manages scheduling just like microservices. Through the FastAPI Swagger UI, you can upload agent ZIPs, start/stop them, tail logs, and run multiple optimization agents in parallel with confidence.
Be sure to check out these related projects that are designed to work hand-in-hand as a smart-building edge microservice ecosystem π
- diy-bacnet-server β a lightweight FastAPI + bacpypes3 BACnet/IP server that exposes a JSON-RPC API for reading, writing, and supervising BACnet devices at the edge.
- diy-edge-lambda-agents β a collection of edge βLambda-styleβ HVAC optimization agents (optimal start, Guideline 36, FDD tools, testing agents, etc.) packaged as deployable ZIP workloads.
- diy-edge-lambda-manager β a local βAWS Lambda-likeβ runtime for the edge that lets you upload, run, stop, and monitor agents via a clean FastAPI + Swagger UI, using real Linux subprocess execution under the hood.
Together, these projects form a modular, production-ready edge automation platform, ideal for real-world smart-building IoT deployments β supporting safe validation workflows today while scaling to advanced supervisory logic like Guideline 36, Optimal Start, and future analytics-driven control strategies.
- Docker Desktop (Windows / macOS / Linux)
- Docker Engine β₯ 20.x
Verify Docker Engine:
docker version
Verify Docker Compose (V2):
docker compose version
Note: This project uses the modern
docker composecommand (with a space).
Because this project builds the BACnet server from source using a relative path, you must clone both repositories into the same parent directory (side-by-side).
Both folders must sit in the same parent directory (usually your home folder ~):
/home/ben/ (or ~/)
β
βββ diy-bacnet-server/ <-- Clone 1
β βββ Dockerfile
β βββ ...
β
βββ diy-edge-lambda-manager/ <-- Clone 2 (You run commands here)
βββ docker-compose.yml
βββ ...
Run this block of commands to set it up perfectly:
# 1. Go to your home directory
cd ~
# 2. Clone the BACnet Server (The dependency)
git clone https://github.com/bbartling/diy-bacnet-server.git
# 3. Clone the Manager (The main app)
git clone https://github.com/bbartling/diy-edge-lambda-manager.git
This project uses Caddy as a reverse proxy to provide HTTPS encryption and Password Authentication. The backend services are locked down to localhost so they cannot be accessed without logging in.
We do not store plain-text passwords. Run this temporary container to generate a secure hash for your desired password (replace mypassword below):
docker run --rm caddy caddy hash-password --plaintext mypassword
Copy the output string (it looks like $2a$14$....). You will need it in the next step.
Create a new file named Caddyfile in the project root (or copy the example).
cp Caddyfile.example Caddyfile
nano Caddyfile
- Update the IP: Replace
192.168.X.Xwith your edge devices actual static IP address. - Update the Hash: Replace the default hash with the string you generated in Step 1.
Build and start the secure stack:
docker compose up -d --build
Because we are using secure HTTPS with a self-signed certificate on a local network, your browser will warn you the first time.
- Dashboard:
https://<YOUR_PI_IP>/
- Note: Accept the "Not Secure" / "Privacy" warning in your browser.
- Login: User
admin, and the password you chose in Step 1.
- BACnet API Docs:
https://<YOUR_PI_IP>:8443/docs
- Requires the same login.
Stick to
docker compose up -das the single source of truth for running the app.
This bash script will:
- Pull latest changes from both repos
- Stop running containers
- Rebuild & restart the stack via Docker Compose
- Optionally prune unused Docker junk
Use this when you simply want to refresh code and restart:
cd ~/diy-edge-lambda-manager
./edge_stack_update.sh- Pulls latest Git changes
- Restarts BACnet server
- Restarts Edge Lambda Manager
- Preserves agents and data
- Verifies Web Apps Are Alive with a
localhostCurl Test
If youβve been doing lots of rebuilds and want to reclaim disk space:
cd ~/diy-edge-lambda-manager
./edge_stack_update.sh --prune
This triggers a standard update, then runs docker system prune -f at the end, which safely removes:
- Stopped containers
- Unused networks
- Dangling images (old versions of your builds)
- Build cache
By default, the script exits early if git says "Already up to date" and containers are running. To override this and force a full rebuild (e.g., if you changed a .env file or just want a fresh start):
./edge_stack_update.sh --force
Pro Tip: You can combine them to force a rebuild and clean up afterward:
./edge_stack_update.sh --force --prune# 1. Rebuild only the manager image (force no cache to pick up new files)
docker compose build --no-cache edge-lambda-manager
# 2. Recreate just the manager container (Docker automatically stops the old one)
docker compose up -d edge-lambda-manager
# 3. Check logs
docker compose logs -f edge-lambda-manager# 1. Stop and remove all containers
docker compose down
# 2. Rebuild ALL images from scratch
docker compose build --no-cache
# 3. Start everything in the background
docker compose up -d
# 4. Check logs for both services
docker compose logs -fUse this to verify your API, dashboard, and system status are working correctly without stopping, restarting, or rebuilding anything.
# 1. Run the test suite inside the running manager container
docker compose exec edge-lambda-manager python -m pytest manager/testsServices come back automatically:
| Service | URL |
|---|---|
| BACnet JSON-RPC + Swagger | http://<edge-ip>:8080/docs |
| Edge Lambda Manager UI | http://<edge-ip>:8081/docs |
Even though the Edge Lambda Manager safely handles process lifecyclesβand Docker automatically kills all child agents if the container restartsβyou can still inspect the raw processes directly from your host machine. Since Docker containers share the Linux kernel, the agent processes are visible from the main host Linux terminal.
Run this on your host linux IoT edge device (outside Docker):
ps aux | grep lambda_function.pyTROUBLESHOOTING: What to look for ...
- Normal: You should see exactly one process for each agent you have started (e.g., 2 processes if you have 2 agents running).
- Zombie Check: If you see more processes than you have running agents, or a process exists for an agent you stopped, you have found an "orphan."
- The Fix: If you ever find orphaned processes, simply restarting the manager container (
docker compose restart edge-lambda-manager) is guaranteed to wipe them out.
Everything here is MIT Licensed β free, open source, and made for the BAS community.
Use it, remix it, or improve it β just share it forward so others can benefit too. π₯°π
γMIT Licenseγ
Copyright 2025 Ben Bartling
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
