# djazil4ik/solar-inverter-monitoring architecture

> Architecture diagram of the GitHub repository djazil4ik/solar-inverter-monitoring, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-26). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/djazil4ik/solar-inverter-monitoring
- Repository: https://github.com/djazil4ik/solar-inverter-monitoring

## Overview

Solar Inverters Monitoring polls configured Deye and DAH Solar devices, stores readings as time-series data, and presents live, historical, and energy-stat views to authenticated users. The main path is inverter polling → register decoding → persistence and WebSocket dispatch → dashboard; REST endpoints provide inverter lists, history, and stats. The README documents the API capabilities, while sampled source confirms the polling, persistence, dispatch, dashboard requests, and JWT client behavior. Views, serializers, and WebSocket consumer internals were not sampled, so their detailed wiring is limited to documented behavior.

Main entry points: [`backend/monitoring/management/commands/run_polling.py`](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/management/commands/run_polling.py) (Polling loop), [`backend/monitoring/views.py`](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/views.py) (REST views), [`frontend/src/components/Dashboard.jsx`](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/frontend/src/components/Dashboard.jsx) (Monitoring dashboard), [`frontend/src/services/api.js`](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/frontend/src/services/api.js) (API client)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ingest["Inverter ingestion"]
  node_poller["Polling loop<br/>[run_polling.py]"]
  node_reader["Modbus reader<br/>[inverter_reader.py]"]
  node_registermaps["Register maps"]
end

subgraph group_backend["Backend data services"]
  node_inverters["Inverter registry<br/>[models.py]"]
  node_readings["Reading models<br/>[models.py]"]
  node_apiurls["API routes<br/>[urls.py]"]
  node_views["REST views<br/>[views.py]"]
  node_serializers["Response serializers<br/>[serializers.py]"]
  node_jwt["JWT authentication<br/>[urls.py]"]
end

subgraph group_frontend["Web dashboard"]
  node_login["Login screen<br/>[Login.jsx]"]
  node_guard["Route protection<br/>[ProtectedRoute.jsx]"]
  node_app["React routes<br/>[App.jsx]"]
  node_api["API client<br/>[api.js]"]
  node_dashboard["Monitoring dashboard<br/>[Dashboard.jsx]"]
end

subgraph group_runtime["Live delivery"]
  node_channelredis["Channel layer<br/>[settings.py]"]
  node_consumer["WebSocket consumer<br/>[consumers.py]"]
  node_wsroutes["WebSocket routes<br/>[routing.py]"]
end

node_operator(("User"))
node_device{{"Solar inverter"}}
node_timescale[("TimescaleDB")]
node_redis[("Redis")]

node_poller -->|"loads active"| node_inverters
node_poller -->|"polls through"| node_reader
node_reader -->|"parses using"| node_registermaps
node_reader -->|"reads registers"| node_device
node_poller -->|"writes readings"| node_readings
node_inverters -->|"reads registry"| node_timescale
node_readings -->|"stores time series"| node_timescale
node_poller -->|"dispatches updates"| node_channelredis
node_channelredis -->|"uses"| node_redis
node_wsroutes -->|"routes sockets"| node_consumer
node_consumer -->|"receives updates"| node_channelredis
node_operator -->|"opens dashboard"| node_app
node_app -->|"routes to"| node_login
node_app -->|"protects dashboard"| node_guard
node_guard -->|"allows access"| node_dashboard
node_login -->|"requests tokens"| node_api
node_dashboard -->|"requests data"| node_api
node_api -->|"calls REST API"| node_apiurls
node_apiurls -->|"routes requests"| node_views
node_views -->|"queries readings"| node_readings
node_views -->|"lists inverters"| node_inverters
node_views -->|"formats responses"| node_serializers
node_serializers -->|"returns JSON"| node_api
node_apiurls -->|"routes token requests"| node_jwt
node_dashboard -->|"connects live"| node_wsroutes
node_consumer -->|"pushes readings"| node_dashboard

click node_poller "https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/management/commands/run_polling.py"
click node_reader "https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/inverter_reader.py"
click node_registermaps "https://github.com/djazil4ik/solar-inverter-monitoring/tree/master/backend/monitoring/configs"
click node_inverters "https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/models.py"
click node_readings "https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/models.py"
click node_apiurls "https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/urls.py"
click node_views "https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/views.py"
click node_serializers "https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/serializers.py"
click node_jwt "https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/core/urls.py"
click node_channelredis "https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/core/settings.py"
click node_consumer "https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/consumers.py"
click node_wsroutes "https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/routing.py"
click node_login "https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/frontend/src/components/Login.jsx"
click node_guard "https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/frontend/src/components/ProtectedRoute.jsx"
click node_app "https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/frontend/src/App.jsx"
click node_api "https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/frontend/src/services/api.js"
click node_dashboard "https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/frontend/src/components/Dashboard.jsx"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_poller,node_reader,node_registermaps,node_operator toneBlue
class node_inverters,node_readings,node_apiurls,node_views,node_serializers,node_jwt,node_timescale,node_redis toneAmber
class node_login,node_guard,node_app,node_api,node_dashboard toneMint
class node_channelredis,node_consumer,node_wsroutes toneRose
class node_device toneIndigo
```

## Components

### Inverter ingestion

- [Polling loop](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/management/commands/run_polling.py): `backend/monitoring/management/commands/run_polling.py`
- [Modbus reader](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/inverter_reader.py): `backend/monitoring/inverter_reader.py`
- [Register maps](https://github.com/djazil4ik/solar-inverter-monitoring/tree/master/backend/monitoring/configs): `backend/monitoring/configs`

### Backend data services

- [Inverter registry](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/models.py): `backend/monitoring/models.py`
- [Reading models](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/models.py): `backend/monitoring/models.py`
- [API routes](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/urls.py): `backend/monitoring/urls.py`
- [REST views](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/views.py): `backend/monitoring/views.py`
- [Response serializers](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/serializers.py): `backend/monitoring/serializers.py`
- [JWT authentication](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/core/urls.py): `backend/core/urls.py`

### Web dashboard

- [Login screen](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/frontend/src/components/Login.jsx): `frontend/src/components/Login.jsx`
- [Route protection](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/frontend/src/components/ProtectedRoute.jsx): `frontend/src/components/ProtectedRoute.jsx`
- [React routes](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/frontend/src/App.jsx): `frontend/src/App.jsx`
- [API client](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/frontend/src/services/api.js): `frontend/src/services/api.js`
- [Monitoring dashboard](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/frontend/src/components/Dashboard.jsx): `frontend/src/components/Dashboard.jsx`

### Live delivery

- [Channel layer](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/core/settings.py): `backend/core/settings.py`
- [WebSocket consumer](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/consumers.py): `backend/monitoring/consumers.py`
- [WebSocket routes](https://github.com/djazil4ik/solar-inverter-monitoring/blob/master/backend/monitoring/routing.py): `backend/monitoring/routing.py`

### Other components

- **User**
- **Solar inverter**
- **TimescaleDB**
- **Redis**

## Connections

- Polling loop → Inverter registry: loads active
- Polling loop → Modbus reader: polls through
- Modbus reader → Register maps: parses using
- Modbus reader → Solar inverter: reads registers
- Polling loop → Reading models: writes readings
- Inverter registry → TimescaleDB: reads registry
- Reading models → TimescaleDB: stores time series
- Polling loop → Channel layer: dispatches updates
- Channel layer → Redis: uses
- WebSocket routes → WebSocket consumer: routes sockets
- WebSocket consumer → Channel layer: receives updates
- User → React routes: opens dashboard
- React routes → Login screen: routes to
- React routes → Route protection: protects dashboard
- Route protection → Monitoring dashboard: allows access
- Login screen → API client: requests tokens
- Monitoring dashboard → API client: requests data
- API client → API routes: calls REST API
- API routes → REST views: routes requests
- REST views → Reading models: queries readings
- REST views → Inverter registry: lists inverters
- REST views → Response serializers: formats responses
- Response serializers → API client: returns JSON
- API routes → JWT authentication: routes token requests
- Monitoring dashboard → WebSocket routes: connects live
- WebSocket consumer → Monitoring dashboard: pushes readings
