Elis Agent

An autonomous AI energy analyst running on Raspberry Pi — combining LangGraph orchestration, Tibber's smart energy API, and LLM-powered insights to deliver daily electricity analysis and actionable recommendations.

4 yrs Historical Data
~35K Data Rows (SQLite)
8 LangGraph Nodes
24/7 Autonomous Operation

Project Overview

Elis Agent is a fully autonomous, stateful AI agent designed to run headlessly on a Raspberry Pi. It performs a one-time seeding process to ingest four years of hourly electricity data, then executes a daily LangGraph-driven analysis loop — comparing current electricity prices against the 4-year baseline to surface insights, detect anomalies, and recommend when to run high-consumption appliances.

The name "Elis" is a nod to the Swedish electricity market. The agent integrates with the Tibber MCP server for energy data access and uses OpenRouter to power the LLM reasoning layer — acting as a "Senior Energy Strategist" that produces structured Markdown reports every day, automatically.

View on GitHub

Architecture — LangGraph Workflow

The agent is built as an 8-node LangGraph state machine. On first run, it seeds the local SQLite database with years of hourly data. Every subsequent run performs an incremental delta fetch, triggers the analysis pipeline, and generates a fresh HTML dashboard before committing results to storage.

1

initialization_node

Establishes a connection to the Tibber MCP server via the Python mcp SDK and discovers all available tools.

2

check_seed_status_node

Checks if historical data exists in the local SQLite database. If not, routes execution to the seeding node.

3

seeding_node

Fetches hourly consumption data back to 2022-04-01 in monthly/quarterly chunks. Checkpoints progress in SQLite so it can resume after interruption — essential for reliable Raspberry Pi operation.

4

fetch_daily_node

Fetches delta data (since last run) and today's spot prices via Tibber MCP tools, keeping the local dataset continuously up to date.

5

analysis_node

The LLM (acting as a "Senior Energy Strategist") compares current prices against the 4-year baseline — computing percentiles, peak/off-peak correlations, consumption anomalies, and savings opportunities.

6

reporting_node

Generates a Markdown summary for the user — including actionable recommendations such as optimal times to run the dishwasher or charge an EV.

7

dashboard_node

Renders a self-contained HTML dashboard for the current month — six Chart.js charts covering consumption, production, cost, and pricing. Writes dashboard-YYYY-MM.html to the reports directory and keeps a latest.html symlink updated for easy web server access.

8

storage_node

Commits the analysis results and computed baseline metrics to SQLite for longitudinal trend tracking and future reference.

Tibber MCP Integration

Elis Agent connects to the Tibber MCP Server via the Model Context Protocol, giving the LangGraph agent standardized, tool-callable access to live and historical energy data.

🏠
list-homes
List Tibber homes
get-consumption
Hourly usage data
☀️
get-production
Solar production data
💰
get-price-info
Current spot prices
📡
get-realtime
Live power readings
📊
get-historic
Custom resolution history
🔮
get-price-forecast
Today & tomorrow prices

Monthly HTML Dashboard

After each daily run the dashboard_node generates a fully self-contained HTML file — no backend, no dependencies beyond a CDN-served Chart.js — that can be served directly from the Raspberry Pi via nginx.

The dashbaord can, for example, be included in smart home systems such as Home Assistant

Elis Energy Dashboard showing monthly consumption, production, cost and price charts

The dashboard covers both consumption and solar production data (when available), and pulls the LLM's price-level classification and historical percentile directly into the header metrics — so at a glance you can see not just what happened, but how unusual it was relative to four years of data.

📊
Daily Consumption (bar)
💰
Daily Cost vs Profit (grouped bar)
📈
Avg Price per Day (line)
Consumption vs Cost (dual-axis)
☀️
Daily Production (bar)
🔄
Consumption vs Production (grouped bar)

Files are written to the reports/ directory as dashboard-YYYY-MM.html. A latest.html symlink is kept up to date so a web server can always serve the current month without knowing the filename.

Technology Stack

Python
LangGraph
MCP Protocol
Tibber API
OpenRouter
SQLite
LangChain
Raspberry Pi
python-dotenv
Chart.js

Data Model & Persistence

All data is stored locally in SQLite — a deliberate choice for headless Raspberry Pi deployment with no external database dependency. The schema is optimized for the ~35,000-row dataset produced by four years of hourly readings.

  • consumption_history table — timestamp, consumption_kwh, cost, unit_price with indexed timestamps for fast range queries
  • LangGraph SqliteSaver checkpointer — ensures the agent can resume after power loss or interruption mid-seeding
  • Pre-computed baseline_metrics — monthly and hourly averages are stored so the LLM works with summaries, not millions of raw rows
  • Daily analysis snapshots — each run's output is persisted for longitudinal trend comparisons

What the Agent Produces

Each day the reporting node emits a structured Markdown analysis. Example insights the agent surfaces:

  • "Today's spot price is in the 90th percentile of the last 4 years — avoid high-consumption appliances during peak hours"
  • Peak/off-peak price correlations against seasonal baselines
  • Calculated savings from 15-minute granular pricing vs daily average
  • Consumption anomaly detection compared to prior days and historical norms
  • Actionable scheduling — "Shift EV charging to 02:00–04:00 for optimal cost"

Deployment

Elis Agent is designed for autonomous, low-maintenance operation on a Raspberry Pi:

  • Runs as a cron job or persistent systemd service
  • Fully headless — all output written to agent.log for remote inspection
  • Configuration via .env file (TIBBER_TOKEN, OPENROUTER_API_KEY)
  • Rate-limit-aware seeding with time.sleep() between API chunks
  • Resumable seeding — tracks "Last Fetched Timestamp" in SQLite for crash recovery