Skip to the content.

Architecture

Overview

Elsignal is an open electricity data and energy signal platform for Sweden.

The platform provides normalized electricity price data, smart time windows, practical energy recommendations, grid-support signals, solar self-consumption signals and automation-friendly flags through a public and partner-ready API.

Elsignal is designed to be used by:

The API is the core product.

Home Assistant, Homey, MQTT, webhooks, the public website and future mobile apps are clients that use the API. They are not the only target platforms.

Elsignal should not only expose raw electricity price data. It should help users and systems understand when it is a good time to use flexible electricity.

Examples:

Elsignal provides signals, recommendations and time windows.

The user, local system, connected product or external integration decides what action to take.


Core principles

1. API first

Elsignal should be designed around a stable, documented and versioned API.

All clients should use the same core data model and signal logic.

Example clients:

The API should not be designed only for one frontend, one mobile app or one smart home platform.


2. Data first

Elsignal does not primarily control devices.

Instead, it provides data, signals, recommendations and time windows that other systems can use.

Examples:

Elsignal should answer both technical and practical questions.

Technical example:

What is the current price level in SE3?

Practical example:

Is this a good time to wash clothes, charge the EV or heat water?


3. Period-based price model

Elsignal should use a period-based price model.

The internal data model should not assume that all price periods are exactly one hour.

For Swedish electricity price data, 15-minute price periods should be treated as the primary resolution.

The API and website may also expose hourly summaries or hourly aggregations for simpler views, but the underlying model should support arbitrary time periods.

Each price period should have:

Example period:

{
  "start": "2026-05-19T00:00:00+02:00",
  "end": "2026-05-19T00:15:00+02:00",
  "spot_price": 0.48,
  "currency": "SEK",
  "area": "SE3",
  "price_level": "cheap",
  "price_score": 92,
  "flags": {
    "good_time_to_consume": true,
    "avoid_consumption": false
  }
}

This makes the platform suitable for:


4. Daily planning model

Elsignal should primarily use a daily planning model.

The goal is not that clients constantly poll the API for small updates. Instead, Elsignal should provide complete daily plans that clients can cache and use locally.

A client should normally fetch data:

This makes the platform more scalable, reliable and suitable for integrations, apps and connected products.

After tomorrow’s electricity prices are available, normally after 14:00 Swedish time, Elsignal should be able to generate a plan for the next day.

That plan can include:

The API should still support normal requests, but the recommended integration pattern should be to fetch a complete plan and use it locally.

Elsignal should therefore be more than a simple real-time electricity price API. It should provide a useful energy plan that clients can act on locally.


5. User stays in control

In the first versions, Elsignal should not directly switch user equipment on or off.

The user’s own system, integration or connected product decides how to act on the data.

Examples:

Elsignal provides the signal.

The client performs the action.


6. Simple recommendations first, optional automation later

Elsignal should support both simple user-facing recommendations and more advanced automation use cases.

For ordinary users, Elsignal should explain when it is a good time to use flexible electricity, for example:

For advanced users and integrations, the same signals should later be usable through:

Automation should always be optional.

Elsignal provides signals, recommendations and time windows. The user, local system, connected product or external integration decides what action to take.


7. Ecosystem first

Elsignal should not be locked to a single smart home ecosystem.

Home Assistant and Homey are important, but the platform should also be useful for manufacturers, mobile apps, energy services, partner products and other systems.

The architecture should make it easy for external products to connect.

Elsignal should be neutral in relation to manufacturers and device types.


8. Mobile and tablet ready

Elsignal should be designed so that mobile phones and tablets are supported from the beginning.

A dedicated mobile app is not required for the first MVP, but the frontend and API should be built in a way that does not block future mobile apps.

The public website should be responsive and work well on:

The API should be client-neutral and suitable for:

The frontend should avoid desktop-only assumptions.

Important views should be usable on small screens:

A future mobile app should be able to use the same API endpoints as the website and integrations.


9. Explainable signals

Signals should be understandable.

A recommendation should include not only a value, but also a reason when possible.

Example:

{
  "signal": "good_time_to_consume",
  "combined_score": 91,
  "recommended_uses": [
    "washing_machine",
    "dishwasher",
    "ev_charging",
    "water_heater"
  ],
  "reason": "Low electricity price and favorable grid-support signal."
}

Swedish user interface example:

Bra tid att använda flexibel el. Priset är lågt och perioden är systemvänlig.

10. User chooses goal

Elsignal should support different optimization goals.

Supported planned values:

cost
grid_support
solar_self_consumption
balanced

Swedish labels:

API value Swedish label
cost Spara pengar
grid_support Stödja elsystemet
solar_self_consumption Använda mer egen solel
balanced Balanserat

This makes Elsignal useful for different types of users.

For hourly-price users, the focus may be direct cost optimization.

For fixed-price users, Elsignal should not claim direct hour-by-hour savings. Instead, the focus should be system benefit and moving flexible electricity use away from strained periods.


11. Sweden first, expandable later

The first version should focus on Sweden.

Initial scope:

The architecture should not prevent future expansion to other countries.


High-level architecture

                         ┌────────────────────┐
                         │   Public Website   │
                         │  Mobile / Tablet   │
                         └─────────┬──────────┘
                                   │
                                   ▼
┌─────────────────────────────────────────────────────┐
│                    Elsignal API                     │
│                                                     │
│  Public API                                         │
│  Partner API                                        │
│  User API                                           │
│  OpenAPI documentation                              │
└───────────────┬─────────────────────┬───────────────┘
                │                     │
                ▼                     ▼
┌────────────────────────┐   ┌────────────────────────┐
│   Signal Engine        │   │   User/Profile Engine   │
│                        │   │                        │
│ - price_score          │   │ - homes                 │
│ - grid_support_score   │   │ - contract type         │
│ - solar_score          │   │ - user capabilities     │
│ - weather_score        │   │ - preferred uses        │
│ - combined_score       │   │ - optimization goal     │
│ - recommendations      │   │ - notification settings │
│ - flags                │   │ - API keys              │
│ - daily plans          │   │                        │
└──────────────┬─────────┘   └──────────────┬─────────┘
               │                            │
               ▼                            ▼
┌────────────────────────┐   ┌────────────────────────┐
│   Price Data Service   │   │      Database          │
│                        │   │                        │
│ - fetch prices         │   │ - users                │
│ - normalize prices     │   │ - homes                │
│ - cache prices         │   │ - price data           │
│ - expose price periods │   │ - daily plans          │
│ - tomorrow plan input  │   │ - signals              │
└──────────────┬─────────┘   │ - partners             │
               │             │ - API keys             │
               ▼             └────────────────────────┘
┌────────────────────────┐
│   External Data Sources│
│                        │
│ - electricity prices   │
│ - future grid data     │
│ - future weather data  │
│ - future solar data    │
└────────────────────────┘

Main components

1. Public website

The public website is the user-facing entry point.

It should allow users to:

The public website should make Elsignal understandable without technical knowledge.

Examples of user-facing recommendations:

Bra läge att använda flexibel el.
Vänta gärna med elbilsladdning.
Bra fönster för varmvattenberedaren.
Den här perioden är bra om du vill stödja elnätet.

The public website should use the same API as all other clients.

The public website should be responsive from the beginning.

It should work well on:

In the first version, user settings such as selected electricity area and preferred display mode can be stored locally in the browser.

The first website may be a responsive web app. Later versions may add a progressive web app or native mobile apps.


2. Backend API

The backend API is the core of the platform.

It should expose:

Example endpoint groups:

/api/v1/public/...
/api/v1/users/...
/api/v1/signals/...
/api/v1/partners/...

The backend API should support both simple real-time queries and complete daily plans.

The recommended long-term integration pattern should be:

Fetch plan
Cache locally
Use locally
Refresh when needed

The API should be suitable for:


3. Price data service

The price data service is responsible for:

Initial support:

The price data service should treat price data as time periods, not fixed hours.

Future support:

The price data service should support daily planning.

When tomorrow’s prices are available, normally after 14:00 Swedish time, the service should fetch, normalize and cache them so that the signal engine can generate a complete plan for the next day.

Clients should not need to repeatedly ask for individual price points during the day if they already have a valid cached plan.


4. Signal engine

The signal engine turns raw price data into useful signals, recommendations and daily plans.

Initial signals:

Future signals:

The signal engine should also be able to generate daily plans.

A daily plan should include all relevant information a client needs to operate locally for a given day.

Example daily plan contents:


5. User/profile engine

The user/profile engine handles optional personalization.

A user can configure:

The platform should still work without a user account.

Without an account, settings can be stored locally in the browser or passed as query parameters to the API.

In later versions, saved user profiles can be used to generate more personalized daily plans.

User profiles should be usable across:


6. Partner API

The Partner API allows external manufacturers and service providers to connect products.

Examples:

Partner API requirements:

Partner products should be encouraged to fetch complete plans and cache them locally, rather than polling the API unnecessarily.


7. Integrations

Integrations are clients of the API.

Planned integrations:

Integrations should not duplicate business logic unnecessarily.

The central logic should live in the backend signal engine.

Integrations should normally fetch a complete daily plan:

The integration should then expose the data locally as sensors, binary sensors, attributes, events, MQTT messages, webhook events or other platform-specific objects.

Shelly, Ohmigo and similar products should be treated as examples of possible clients or local automation targets, not as required dependencies.

Recommended model:

Elsignal API
    ↓
local integration, webhook, MQTT or script
    ↓
Shelly, Ohmigo or another device performs the action

8. Mobile app / PWA

A dedicated mobile app is not required for the first MVP.

However, Elsignal should be designed so that mobile apps can be added later without redesigning the backend.

Possible future mobile approaches:

The first step should be a responsive website that works well on mobile and tablet.

A future mobile app should support:

Mobile-specific future features may include:

These features are not required for the first MVP.


Data flow

Public price data flow

External price source
        │
        ▼
Price Data Service
        │
        ▼
Normalize and cache price data
        │
        ▼
Signal Engine
        │
        ▼
Public API
        │
        ▼
Website / mobile / tablet / clients / integrations

Daily plan data flow

Tomorrow prices available
        │
        ▼
Price Data Service
        │
        ▼
Normalize and cache tomorrow prices
        │
        ▼
Signal Engine
        │
        ▼
Generate daily plan
        │
        ▼
Public API / Partner API / User API
        │
        ▼
Clients cache and use plan locally

User-specific signal flow

User profile
        │
        ▼
Home settings and capabilities
        │
        ▼
Price data + profile data
        │
        ▼
Signal Engine
        │
        ▼
Personalized signals / daily plan
        │
        ▼
API clients

Partner product flow

Partner product / cloud service
        │
        ▼
Partner API request
        │
        ▼
Device profile + area + duration
        │
        ▼
Signal Engine
        │
        ▼
Recommended windows, flags and daily plan
        │
        ▼
Partner product decides what to do

Optional automation flow

Elsignal signal / daily plan
        │
        ▼
API / MQTT / webhook / integration
        │
        ▼
Local system or connected product
        │
        ▼
User-approved action

Examples:

Elsignal should not be the direct cloud controller in the first versions.


API layers

Public API

The Public API is for basic access.

It should support:

Example:

GET /api/v1/public/prices/SE3/summary

Future daily plan examples:

GET /api/v1/public/plans/SE3/today
GET /api/v1/public/plans/SE3/tomorrow

Alternative future structure:

GET /api/v1/public/areas/SE3/plan
GET /api/v1/public/areas/SE3/plan/today
GET /api/v1/public/areas/SE3/plan/tomorrow

The exact endpoint structure can be finalized later, but the concept of complete daily plans should be part of the architecture from the start.


User API

The User API is for logged-in users.

It should support:

Example:

GET /api/v1/users/me/homes
GET /api/v1/homes/{home_id}/signals/summary
GET /api/v1/homes/{home_id}/plans/tomorrow

Partner API

The Partner API is for manufacturers and commercial integrations.

It should support:

Example:

GET /api/v1/signals/summary?area=SE3&device_type=ev_charger&duration=PT4H
GET /api/v1/plans/tomorrow?area=SE3&device_type=ev_charger&duration=PT4H

Suggested technology stack

Backend

Recommended stack:

Why:

For the first MVP, the backend can be simpler and does not need a full database from day one.

A simple in-memory cache or file-based cache can be enough while the project is tested locally.


Frontend

Recommended stack:

Why:

The frontend should be responsive from the beginning.

It should work well on:

The frontend should be able to show:

The frontend should avoid desktop-only layouts.

Important design considerations:

The first version can be a responsive web app.

Later versions may add:


Hosting

Initial hosting:

Later hosting:

Possible backend hosting options:

The architecture should allow Elsignal to start small and later move to more scalable hosting.


Suggested repository structure

elsignal/
├── README.md
├── ROADMAP.md
├── ARCHITECTURE.md
├── API.md
├── DATA_MODEL.md
├── docs/
│   ├── index.md
│   ├── api.md
│   ├── integrations.md
│   └── partners.md
├── backend/
│   ├── app/
│   │   ├── api/
│   │   ├── prices/
│   │   ├── signals/
│   │   ├── users/
│   │   ├── partners/
│   │   └── core/
│   ├── tests/
│   └── pyproject.toml
├── frontend/
│   ├── app/
│   ├── components/
│   ├── lib/
│   └── package.json
├── mobile/
│   └── README.md
├── integrations/
│   ├── homeassistant/
│   ├── homey/
│   ├── mqtt/
│   ├── webhooks/
│   └── examples/
└── docker-compose.yml

The mobile/ directory does not need to contain a real app in the first MVP.

It can initially contain planning notes for future PWA, iOS and Android support.


Signal model

Elsignal should expose different signal types.

Price-based signals

Examples:


Practical recommendation signals

Examples:

Planned recommendation fields:

recommendation.level
recommendation.message
recommendation.recommended_uses
recommendation.avoid_uses
recommendation.reason

Example:

{
  "recommendation": {
    "level": "good",
    "message": "Good time to use flexible electricity.",
    "recommended_uses": [
      "washing_machine",
      "dishwasher",
      "ev_charging",
      "water_heater"
    ],
    "avoid_uses": [],
    "reason": "Low price and favorable grid-support signal."
  }
}

Grid-support signals

Examples:

These are especially useful for users with fixed-price contracts.

For fixed-price users, Elsignal should not claim direct hour-by-hour savings. Instead, it should focus on system benefit and helping users move flexible electricity use away from strained periods.


Solar signals

Examples:

These are useful for users with solar panels.


Weather signals

Examples:

Weather should be a future complementary signal.

It should not replace the electricity price signal, but it can improve recommendations.


Battery signals

Examples:

Battery signals are future features.

The first MVP should not include battery control.


Combined signals

Examples:

The combined score can weigh:


Device and use model

Elsignal should support both device types and recommended use cases.

Device types

Planned API values:

washing_machine
dishwasher
water_heater
ev_charger
heat_pump
battery
solar_inverter
generic_switch
smart_relay
energy_manager
home_automation

Planned API values:

washing_machine
dishwasher
ev_charging
water_heater
heat_pump_preheating
battery_charging
solar_self_consumption
generic_flexible_load
grid_support

These values can be used by:


Usage levels

Elsignal should support different levels of use.

Planned values:

recommendation
notification
api
webhook
mqtt
integration
script

Meaning:

Value Description
recommendation User only sees advice in the website, app or API
notification User receives a notification, for example email, app notification or another channel
api External system reads the API
webhook Elsignal or a connected service triggers a webhook
mqtt Signals are published to MQTT
integration Used by Home Assistant, Homey or similar systems
script Used by custom scripts or local automation

Automation is optional and should not be required for basic use.


Price levels

Elsignal should classify electricity prices into simple levels.

Suggested API values:

cheap
normal
expensive

Suggested default model:

The public website can show these levels using simple Swedish labels:

Suggested colors:

These colors should be used consistently in the price graph and the electricity price clock.


Daily plan model

A daily plan is a complete package of price data, signals and recommendations for one electricity area and one date.

The purpose of a daily plan is to reduce unnecessary API calls and make integrations easier.

A daily plan should answer questions such as:

A daily plan should be based on price periods, not hardcoded hours.

For Sweden, those periods are normally 15-minute periods.

Example daily plan response

{
  "area": "SE3",
  "timezone": "Europe/Stockholm",
  "date": "2026-05-19",
  "generated_at": "2026-05-18T14:10:00+02:00",
  "valid_from": "2026-05-19T00:00:00+02:00",
  "valid_to": "2026-05-20T00:00:00+02:00",
  "data_status": "complete",
  "resolution": "PT15M",
  "thresholds": {
    "p30": 0.52,
    "p80": 1.34
  },
  "periods": [
    {
      "start": "2026-05-19T00:00:00+02:00",
      "end": "2026-05-19T00:15:00+02:00",
      "spot_price": 0.48,
      "currency": "SEK",
      "price_level": "cheap",
      "price_score": 92,
      "flags": {
        "is_cheap": true,
        "is_expensive": false,
        "good_time_to_consume": true,
        "avoid_consumption": false
      }
    }
  ],
  "best_windows": {
    "cheapest_3h": {
      "start": "2026-05-19T02:00:00+02:00",
      "end": "2026-05-19T05:00:00+02:00",
      "duration": "PT3H",
      "average_price": 0.47,
      "combined_score": 91,
      "reason": "Lowest average price and good combined score."
    }
  },
  "recommendation": {
    "level": "good",
    "message": "There are good flexible consumption windows today.",
    "recommended_uses": [
      "washing_machine",
      "dishwasher",
      "ev_charging",
      "water_heater"
    ],
    "reason": "Several periods have low price and good signal score."
  },
  "flags": {
    "has_tomorrow_prices": true,
    "is_complete": true
  }
}

Example summary response

{
  "area": "SE3",
  "timezone": "Europe/Stockholm",
  "resolution": "PT15M",
  "current": {
    "start": "2026-05-18T14:00:00+02:00",
    "end": "2026-05-18T14:15:00+02:00",
    "spot_price": 1.24,
    "price_level": "normal",
    "price_score": 55,
    "grid_support_score": 42,
    "solar_score": 30,
    "combined_score": 46
  },
  "thresholds": {
    "p30": 0.62,
    "p80": 1.42
  },
  "best_windows": {
    "3h": {
      "start": "2026-05-18T02:00:00+02:00",
      "end": "2026-05-18T05:00:00+02:00",
      "duration": "PT3H",
      "average_price": 0.48,
      "combined_score": 91
    }
  },
  "recommendation": {
    "level": "normal",
    "message": "It is okay to use electricity now, but there may be better periods later.",
    "recommended_uses": [],
    "avoid_uses": [],
    "reason": "Current price is normal."
  },
  "flags": {
    "is_cheap_now": false,
    "is_expensive_now": false,
    "good_time_to_consume": false,
    "avoid_consumption": false,
    "is_in_best_3h_window": false,
    "has_tomorrow_prices": true
  }
}

Website visualization model

The public website should make electricity price data easy to understand.

Initial visualizations:

Price graph

The daily price graph should show the selected day.

It should include:

The graph should work on small screens.

For mobile views, the graph may use simplified labels and horizontal scrolling if needed.

Electricity price clock

The electricity price clock should show the day as a circular 24-hour view.

Each period or hour block should be colored by price level:

The current period should be highlighted when viewing today.

For mobile views, the electricity price clock should be readable without requiring a large desktop screen.

Recommendation card

The website should include a simple recommendation card.

Examples:

Bra läge nu
Det är ett bra tillfälle att använda flexibel el.
Passar till exempel för tvätt, disk, varmvatten och elbilsladdning.
Vänta gärna
Elen är dyr just nu. Vänta gärna med flexibel elanvändning om det är möjligt.
Systemvänligt läge
Den här perioden är lämplig om du vill stödja elnätet.

Display modes

Suggested API/frontend values:

graph
price_clock
both

In the first version, the preferred display mode can be stored locally in the browser.

In later versions, it can be saved to the user profile.


User settings model

Users should be able to configure basic settings.

Initial settings:

Later settings:

Electricity areas

API values:

SE1
SE2
SE3
SE4

Suggested Swedish UI labels:

Elområde 1 – SE1
Elområde 2 – SE2
Elområde 3 – SE3
Elområde 4 – SE4

Contract types

API values:

hourly
variable
fixed
mixed
unknown

Suggested Swedish UI labels:

API value Swedish label
hourly Timpris
variable Rörligt pris
fixed Fastpris
mixed Mixavtal
unknown Vet ej

Optimization goals

API values:

cost
grid_support
solar_self_consumption
balanced

Suggested Swedish UI labels:

API value Swedish label
cost Spara pengar
grid_support Stödja elsystemet
solar_self_consumption Använda mer egen solel
balanced Balanserat

Preferred flexible uses

API values:

washing_machine
dishwasher
ev_charging
water_heater
heat_pump_preheating
battery_charging
solar_self_consumption
generic_flexible_load

Suggested Swedish UI labels:

API value Swedish label
washing_machine Tvättmaskin
dishwasher Diskmaskin
ev_charging Elbilsladdning
water_heater Varmvattenberedare
heat_pump_preheating Förvärmning av hus
battery_charging Batteriladdning
solar_self_consumption Använda egen solel
generic_flexible_load Annan flexibel förbrukning

Safety and responsibility

Elsignal should be careful with direct control.

The platform should initially provide signals and recommendations only.

Actual control should happen in the user’s local system or in the connected product.

This reduces risk and makes the platform easier to trust.

Recommended wording:

Avoid describing Elsignal as a cloud service that directly switches private devices on or off in the first versions.


Security principles

Important security principles:

For future mobile apps:


Caching principles

Caching is central to the architecture.

Elsignal should cache:

Recommended cache behavior:

Suggested response fields:

generated_at
valid_from
valid_to
data_status
cache_status
resolution

Possible data_status values:

pending
partial
complete
stale
error

Mobile apps, tablet apps, integrations and partner products should be encouraged to cache daily plans locally.


Versioning

The API should be versioned from the beginning.

Example:

/api/v1/...

Breaking changes should be introduced only in new major API versions.

The project should maintain:

The API should be stable enough that future mobile apps and partner products can rely on it.


First MVP architecture

The first MVP should be intentionally simple.

Minimum components:

Price fetcher
        │
        ▼
Price analyzer
        │
        ▼
Public API
        │
        ▼
Simple responsive website

First MVP features:

Simple recommendation fields may include:

good_time_to_consume
avoid_consumption
recommended_uses
reason
price_level
best_window

No account system is required in the first MVP.

No partner system is required in the first MVP.

No MQTT system is required in the first MVP.

No webhook system is required in the first MVP.

No Shelly integration is required in the first MVP.

No Ohmigo integration is required in the first MVP.

No script execution is required in the first MVP.

No direct device control is required in the first MVP.

A database is not required in the first MVP.

The first MVP can use simple local caching while the project is tested.

The first website should still be usable on mobile phones and tablets.


Future architecture

Later versions can add:

```