Smart Home Energy Manager (SHEM). This repository presents a SPADE-based multi-agent system in which a solar sensing agent and a home energy manager coordinate battery usage under both nominal and stress conditions.
multi-agent-systems • fipa-acl • finite-state-machine • agent-oriented-programming • asynchronous-agents • smart-home • energy-optimization
This project leverages Agent-Oriented Programming (AOP), a paradigm pioneered by Yoav Shoham, which structures software as interacting, autonomous entities (agents) rather than passive objects. Unlike Object-Oriented Programming where objects are invoked by others, AOP models systems as active agents that maintain internal beliefs, perceive environments, and communicate via formal semantics (like FIPA-ACL).
The system architecture and interaction protocols were rigorously designed using the Prometheus Methodology, authored by Lin Padgham and Michael Winikoff. This theoretical design was then brought to life using the SPADE (Smart Python Agent Development Environment) framework, created by Javi Palanca, Vicente Julian, Gustavo Terrasa, and Carlos Carrascosa. SPADE allows us to implement asynchronous, XMPP-based multi-agent systems efficiently in Python.
After a month of deeply studying the Official Prometheus Methodology, I designed and implemented SHEM from the ground up. My goal was to move beyond theory, reinforcing my grasp of Agent-Oriented Software Engineering (AOSE) while sharpening my system-level design and architectural decision-making.
This project models a smart home as a distributed, intelligent system built on explicit perception, communication, and control layers:
- SolarAgent: Operates as a simple reflex agent, performing periodic sensing and publishing symbolic solar-state updates.
- HomeManagerAgent: Acts as the BDI-style "brain," maintaining internal beliefs and applying robust finite-state control for proactive battery management.
- WeatherEnvironment: Provides a mathematically challenging simulation, featuring both stochastic baseline behavior and a bounded Day 6 stress profile.
- Evaluation Pipeline: Autonomously records runtime metrics and logs performance indicators to validate the system's rationality and robustness.
To provide a comprehensive view of the system's architecture and runtime behavior, I have deployed a dedicated Documentation Portal and an Interactive Design Explorer.
- Live Documentation Portal: The central hub for all technical assets, including PDF presentations, design reports, and interactive tools.
- Prometheus Design Explorer: A specialized learning tool that traverses the three core phases of the Prometheus Methodology (System Specification, Architectural Design, and Detailed Design) through an intuitive, card-based interface.
- The Experience: Read the article on LinkedIn
- main.py: The primary entry point for running the open-ended simulation.
- stress_test.py: Runs bounded evaluation scenarios under variable weather conditions.
- plots.py: Generates performance dashboards and metric visualizations.
- agents/: Contains the autonomous
SolarAgentandHomeManagerAgent. - core/: Houses the stochastic
WeatherEnvironmentand evaluationlogger. - docs/DesignReport.md: Detailed technical whitepaper covering the BDI architecture, Prometheus methodology, and AUML interaction design.
- docs/PresentationFile.pdf: High-level slide deck summarizing the system's goals and implementation.
- docs/index.html: The Documentation Portal (central landing page).
- docs/rpdi.html: The Prometheus Design Learning Explorer (interactive side-product).
shem-mas-spade/
├── agents/
│ ├── __init__.py
│ ├── manager_agent.py
│ └── solar_agent.py
├── core/
│ ├── __init__.py
│ ├── environment.py
│ └── logger.py
├── main.py
├── plots.py
├── requirements.txt
├── stress_test.py
└── README.md
graph TD
WE[Weather Environment] -->|Senses Wattage| SA(SolarAgent: Simple Reflex)
SA -->|FIPA-ACL INFORM| HM(HomeManagerAgent: FSM)
HM -->|Maintains State| HM
HM -->|Log Transition| EL[Evaluation Logger]
SA -->|Log Perception| EL
# 1. Create and activate a virtual environment
python3 -m venv .venv
source .venv/bin/activate
# 2. Install dependencies
pip install -r requirements.txt
# 3. Start the built-in SPADE XMPP server (keep this running)
spade run
# 4. In a new terminal, run the stress test scenario
python stress_test.pyThis implementation demonstrates core principles of Multi-Agent Systems in practice.
| Concept | Theory Applied in This Repo | Concrete Implementation |
|---|---|---|
| Perception & Environment Modeling | Agents reason over an external environment instead of fixed inputs. | WeatherEnvironment models solar conditions and exposes percepts as wattage, weather, and phase. |
| Reactive Agent Behavior | Condition-action rules drive immediate response to percepts. | SolarAgent classifies each reading as LOW or OPTIMAL and acts without long-horizon planning. |
| Reactive Control with FSM | Reactive behavior can also be structured as explicit states. | HomeManagerAgent uses an FSM with IDLE, CHARGING, SYSTEM_CHECK, and EMERGENCY states. |
| Agent Communication | Agents exchange structured symbolic messages rather than shared variables. | SolarAgent sends FIPA-ACL INFORM messages and HomeManagerAgent filters them with a SPADE Template. |
| System Evaluation | Multi-agent systems should be evaluated under stress with measurable metrics. | Day/Night stress logic, CSV logging, grid-energy estimate, safety violation counting, and reaction-time measurement. |
| Packaging & Documentation | A finished MAS should be runnable, documented, and ready for deployment. | Final README, dependency list, stress-test entry point, and optional plotting script. |
- Implements a simple reflex agent.
- Senses the environment every cycle and converts wattage into LOW or OPTIMAL.
- Sends FIPA-ACL INFORM messages to the manager with extra evaluation metadata.
- Implements a model-based controller with a finite-state machine.
- Tracks battery level, solar status, and battery health as internal beliefs.
- Logs every state transition together with current battery level and reaction time.
- Supports normal probabilistic weather behavior through its cloudy probability parameter.
- Implements the evaluation profile:
- T=0-10: high sunlight
- T=11-15: cloud stress with 80% cloud probability
- T=16-24: zero sunlight
- Writes structured runtime results to evaluation_results.csv.
- Tracks three summary metrics:
- Total Grid Energy Saved
- Battery Safety Violations
- Average Reaction Time
The end-of-run summary is built from the logger in core/logger.py and timing metadata exchanged between agents.
This metric accumulates two contributors over time:
- Solar contribution (per sensing cycle):
solar_saved = min(wattage / 100, 8.0)min(...)applies a cap so one very high-wattage moment does not dominate the total score.- The
8.0value is an evaluation/scoring normalization cap, not a physical limit on solar generation. - Logged by
log_solar_cycle(...).
- Battery support contribution (per manager state transition):
battery_support = max(0, previous_battery_level - current_battery_level)max(0, ...)prevents negative contribution when battery level increases.- Logged by
log_state_transition(...).
Final value:
Total Grid Energy Saved = sum(solar_saved) + sum(battery_support)
At each manager transition, an unsafe condition is defined as:
battery_level < safe_battery_threshold(default threshold: 20), orbattery_health != "HEALTHY"
The violation counter increases only when the system enters an unsafe period (safe → unsafe edge), not on every unsafe timestep. This avoids overcounting a continuous unsafe streak.
When the SolarAgent sends an INFORM, it includes sent_at = time.perf_counter() in message metadata. On receipt, HomeManagerAgent computes:
reaction_time_ms = (time.perf_counter() - sent_at) * 1000
Only transitions with a measured value are included. The final summary reports:
Average Reaction Time = arithmetic mean of collected reaction_time_ms values- If no timing samples exist, the project reports
0.0 ms.
python3 -m venv .venv-wsl
source .venv-wsl/bin/activatepip install -r requirements.txtSPADE 4+ includes a built-in XMPP server natively in Python, eliminating the need to install OS-level servers like Prosody or ejabberd for development.
Standard Setup (Recommended): Open a new terminal window, activate your virtual environment, and start the local server:
spade runNote: Keep this terminal open while running your agents. The built-in server automatically handles agent registration and message routing on port 5222.
Legacy OS-Level Setup (Optional): If you prefer running a production-grade external XMPP server (ejabberd or Prosody), you can use the included bash script:
bash setup-xmpp.shIf your XMPP server is not localhost, set environment variables before running the app:
export XMPP_DOMAIN=your-xmpp-hostname
export SOLAR_AGENT_JID=solar_sensor@your-xmpp-hostname
export MANAGER_AGENT_JID=home_manager@your-xmpp-hostname
export SOLAR_AGENT_PASSWORD=sensor123
export MANAGER_AGENT_PASSWORD=manager123python main.pyThe stress test runs a scripted multi-phase scenario to systematically evaluate system behavior under varying weather and battery conditions. Each phase presents different environmental conditions:
- HIGH_SUNLIGHT: Clear skies with maximum solar generation (900-1200 W).
- CLOUD_STRESS: Variable cloud cover (configurable probability) with reduced wattage (80-950 W).
- ZERO_SUNLIGHT: Night phase with no solar generation (0 W).
Basic run:
python stress_test.pyOptional configuration:
python stress_test.py --steps 60 --high-sunlight-duration 15 --cloud-stress-duration 20 --cloudy-probability 0.95Configurable stress-test parameters:
--steps: total number of stress-test steps (default25)--high-sunlight-duration: number of HIGH_SUNLIGHT timesteps at start (default10)--cloud-stress-duration: number of CLOUD_STRESS steps after high sunlight (default5)--cloudy-probability: cloud probability in the environment (default0.8)
Suggested stress-test presets:
# Baseline (reference): evaluation day original profile
python stress_test.py --steps 25 --high-sunlight-duration 10 --cloud-stress-duration 5 --cloudy-probability 0.8
# Extended cloud pressure with longer sunlight
# Tests system resilience under sustained cloud stress and longer charging windows.
python stress_test.py --steps 60 --high-sunlight-duration 15 --cloud-stress-duration 20 --cloudy-probability 0.95
# Maximum cloud stress during extended stress window
# Tests battery management under severe cloud conditions (100% cloud probability).
python stress_test.py --steps 50 --high-sunlight-duration 8 --cloud-stress-duration 25 --cloudy-probability 1.0
# Best-case control comparison (clear skies)
# Validates charging and idle behavior without cloud interference.
python stress_test.py --steps 30 --high-sunlight-duration 12 --cloud-stress-duration 5 --cloudy-probability 0.0Output and results:
- Total Grid Energy Saved: X units
- Battery Safety Violations: X times
- Average Reaction Time: X ms
It also writes per-step evaluation records to evaluation_results.csv.
After a stress test has produced evaluation_results.csv, run:
python plots.pyThis generates battery_level_over_time.png in the project root.
The following findings are derived from the an evaluation_results.csv run earlier on:
- Total Grid Energy Saved: 103.88 units
- Battery Safety Violations: 0 times
- Average Reaction Time: 0.73 ms
Interpretation of these results:
- The Day/Night profile maintained safe battery operation throughout this recorded run.
- The manager responded to incoming solar updates with sub-millisecond average latency, indicating low communication overhead in the local setup.
- Grid-energy savings remained positive across high-sun, cloud-stress, and zero-sunlight periods, showing that the hybrid solar-plus-battery policy maintained useful autonomy.
Successful execution would produce:
- an updated evaluation_results.csv
- Console summary of grid savings, safety violations, and reaction time
- Optional battery_level_over_time.png when plots.py is used
- JIDs and passwords are currently hardcoded for local evaluation.
- The project assumes localhost XMPP connectivity unless credentials in main.py are changed.
- The plotting script is intentionally lightweight and only depends on the evaluation_results.csv
Single command to set up everything:
cd /mnt/q/blipping-projects/shem-mas-spade
bash setup-xmpp.sh
source .venv-wsl/bin/activate
python main.pyWhat the setup script does:
- Attempts to install and start ejabberd (if available)
- Falls back to Prosody with TLS disabled if ejabberd unavailable/fails
- Registers both agent accounts (solar_sensor and home_manager)
- Creates Python virtual environment
- Installs all Python dependencies from requirements.txt
If the script fails:
Try the manual setup:
cd /mnt/q/blipping-projects/shem-mas-spade
# Install XMPP server (choose one)
sudo apt update && sudo apt install -y python3-venv python3-pip ejabberd
# OR: sudo apt update && sudo apt install -y python3-venv python3-pip prosody
# If using Prosody, disable TLS
sudo sed -i 's/"tls";/--"tls";/g' /etc/prosody/prosody.cfg.lua
# Start XMPP server
sudo service ejabberd start # for ejabberd
# OR: sudo service prosody restart # for Prosody
# Register agents (choose command matching your XMPP server)
# For ejabberd:
sudo ejabberdctl register solar_sensor localhost sensor123
sudo ejabberdctl register home_manager localhost manager123
# For Prosody:
# echo "sensor123" | sudo prosodyctl adduser solar_sensor@localhost
# echo "manager123" | sudo prosodyctl adduser home_manager@localhost
# Setup Python environment
python3 -m venv .venv-wsl
source .venv-wsl/bin/activate
python -m pip install -U pip setuptools wheel
pip install -r requirements.txt
# Run the app
python main.py- Add GIF demonstration of the running MAS simulation app to the Project Summary.
Designing systems like intelligent agents, an approach different from object oriented.
