# nerontad/pyrosense architecture

> Architecture diagram of the GitHub repository nerontad/pyrosense, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-20). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/nerontad/pyrosense
- Repository: https://github.com/nerontad/pyrosense

## Overview

1. **Monorepo with three main execution domains**
   - `backend/`: Python API and event-processing core.
   - `frontend/`: React/Vite single-page app for operators.
   - `frontend/arduino/sensor_node/`: embedded sensor firmware that feeds the IoT side.
   - The project’s purpose is explicit: fuse **camera-based vision** and **environmental sensors** to reduce false alarms.

2. **Backend is the system hub**
   - `backend/app/main.py` and `run.py` are the application entrypoints.
   - The backend is organized as a layered API service: **routers → services → repositories → database**.
   - `config.py`, `.env.example`, and `middleware/security.py` indicate environment-driven configuration and request/security controls at the API boundary.

3. **API surface is split by domain**
   - Routers expose distinct bounded contexts: `auth`, `usuario`, `camara`, `dispositivo`, `ubicacion`, `lectura`, `alerta`, `tipos`, `vision`, `telegram`, and `websocket`.
   - This suggests the backend is not a single generic API; it is domain-based, with separate flows for identity, asset management, telemetry, alerts, and real-time delivery.

4. **Core domain data model is persisted via repositories**
   - Repository classes exist per major entity: `usuario`, `camara`, `dispositivo`, `ubicacion`, `lectura`, `alerta`, `tipo_dispositivo`, and `video_alerta`.
   - `database/connection.py` is the persistence boundary.
   - The design implies a relational persistence layer accessed through repository abstraction rather than direct DB access from routers.

5. **Sensor/IoT ingestion path**
   - `services/mqtt_client.py` is the likely ingress for sensor telemetry from Arduino/IoT nodes.
   - `lectura` routes and repository indicate incoming sensor readings are stored and later used by alert logic.
   - The frontend Arduino node is a separate producer of environmental data, not part of the web UI runtime.

6. **Vision pipeline for camera-based detection**
   - `services/vision_service.py`, `video_service.py`, `stream_service.py`, and `utils/crypto_rtsp.py` form the camera/stream subsystem.
   - `best.onnx` is the model artifact for inference, so vision is running as an ONNX-based detection pipeline.
   - Camera streams are likely RTSP-based and may use encrypted RTSP credential handling.

7. **Alert fusion and decisioning is centralized**
   - `services/motor_alertas.py` is the key orchestration component that likely combines:
     - sensor readings,
     - vision detections,
     - alert thresholds/heuristics,
     - and persistence of alert events.
   - This is the architectural center of the “reduce false alarms by fusing two evidence sources” requirement.

8. **Notification delivery is multi-channel**
   - `services/notificacion/` contains a strategy-style notification subsystem with Telegram and WebSocket implementations.
   - `telegram_service.py` and `routers/telegram.py` expose Telegram-specific integration and webhook/retry handling.
   - `websocket.py` plus frontend WebSocket hooks indicate live alert updates to connected dashboards.

9. **Frontend is an operator console, not the processing layer**
   - Built with React/Vite (`src/main.jsx`, `App.jsx`, `pages/`, `components/`).
   - Pages cover login, dashboard, alerts, cameras, devices, profile, registration, and password recovery.
   - `AuthContext`, `PrivateRoute`, and `useWebSocket` show that the UI depends on backend auth plus real-time alert streams.
   - `frontend/src/services/api.js` is the HTTP boundary to the backend API.

10. **External integrations matter to the architecture**
   - **Telegram**: outbound alerts and webhook handling.
   - **Firebase**: present in both backend and frontend, likely for cloud messaging/auth/storage support or auxiliary integration.
   - **MQTT**: sensor transport layer between embedded devices and backend.
   - **IP cameras / RTSP**: primary visual input source.

11. **Operational and delivery boundaries**
   - Backend is containerized via `backend/Dockerfile`.
   - Frontend has its own `docker-compose.yml` and `vercel.json`, showing it can be deployed separately from the backend.
   - This is a split-deployment system: operator UI and backend service are independently deployable.

12. **Testing focuses on the critical signal-processing and integration paths**
   - Tests cover alert logic, MQTT behavior, notification strategy, Telegram retry/webhook flows, schema validation, crypto/RTSP utility behavior, and vision postprocessing (`letterbox`, `nms`).
   - That test distribution reinforces the architectural center: sensor ingestion, vision inference, and alert dissemination.

13. **Useful architecture diagram framing**
   - Left side: **Arduino sensor nodes** and **IP cameras** as data producers.
   - Center: **Backend API + services** performing ingestion, persistence, vision inference, alert fusion, and notification.
   - Right side: **React dashboard** consuming REST and WebSocket updates.
   - Bottom: **database** and **external services** (MQTT broker, Telegram, Firebase).

Main entry points: [`backend/app/services/motor_alertas.py`](https://github.com/nerontad/pyrosense/blob/main/backend/app/services/motor_alertas.py) (Alert motor), [`backend/app/main.py`](https://github.com/nerontad/pyrosense/blob/main/backend/app/main.py) (App entry), [`backend/app/services/vision_service.py`](https://github.com/nerontad/pyrosense/blob/main/backend/app/services/vision_service.py) (Vision pipeline), [`frontend/src/App.jsx`](https://github.com/nerontad/pyrosense/blob/main/frontend/src/App.jsx) (UI app)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_backend["Backend"]
  node_backend_entry["App entry<br/>python entrypoint<br/>[main.py]"]
  node_backend_config["Config<br/>[config.py]"]
  node_backend_security{{"Security<br/>middleware<br/>[security.py]"}}
  node_backend_routers["API routers<br/>domain routes"]
  node_backend_services["Services<br/>business logic"]
  node_backend_repos[("Repositories<br/>data access")]
  node_backend_db[("Database<br/>persistence<br/>[connection.py]")]
  node_backend_mqtt["MQTT client<br/>sensor ingress<br/>[mqtt_client.py]"]
  node_backend_vision["Vision pipeline<br/>cv inference<br/>[vision_service.py]"]
  node_backend_stream["Stream service<br/>rtsp stream<br/>[stream_service.py]"]
  node_backend_alerts{{"Alert motor<br/>fusion engine<br/>[motor_alertas.py]"}}
  node_backend_notify["Notifier<br/>delivery strategy"]
  node_backend_telegram["Telegram svc<br/>integration"]
  node_backend_realtime(("WebSocket<br/>push api<br/>[websocket.py]"))
end

subgraph group_frontend["Frontend"]
  node_frontend_app["UI app<br/>react spa<br/>[App.jsx]"]
  node_frontend_state["Auth & WS<br/>client state<br/>[AuthContext.jsx]"]
  node_frontend_pages["Pages<br/>views"]
  node_frontend_api["API client<br/>http client<br/>[api.js]"]
end

subgraph group_edge["Edge Devices"]
  node_arduino_node["Sensor node<br/>embedded firmware<br/>[sensor_node.ino]"]
end

subgraph group_external["External Systems"]
  node_camera_sources(("IP cameras<br/>video sources"))
  node_mqtt_broker["MQTT broker<br/>message broker"]
  node_telegram_api(("Telegram<br/>notification service"))
  node_firebase_svc(("Firebase<br/>cloud integration"))
  node_model_onnx["ONNX model<br/>ml artifact<br/>[best.onnx]"]
end

node_backend_entry -->|"loads"| node_backend_config
node_backend_entry -->|"applies"| node_backend_security
node_backend_entry -->|"mounts"| node_backend_routers
node_backend_routers -->|"calls"| node_backend_services
node_backend_services -->|"persists via"| node_backend_repos
node_backend_repos -->|"uses"| node_backend_db
node_backend_mqtt -->|"subscribes"| node_mqtt_broker
node_arduino_node -->|"publishes"| node_mqtt_broker
node_backend_mqtt -->|"feeds"| node_backend_alerts
node_backend_vision -->|"reads"| node_backend_stream
node_backend_stream -->|"connects to"| node_camera_sources
node_backend_vision -->|"infers with"| node_model_onnx
node_backend_vision -->|"feeds"| node_backend_alerts
node_backend_alerts -->|"stores alerts"| node_backend_repos
node_backend_alerts -->|"dispatches"| node_backend_notify
node_backend_notify -->|"uses"| node_backend_telegram
node_backend_telegram -->|"sends to"| node_telegram_api
node_backend_notify -->|"pushes"| node_backend_realtime
node_backend_realtime -->|"streams to"| node_frontend_state
node_frontend_app -->|"uses"| node_frontend_state
node_frontend_app -->|"renders"| node_frontend_pages
node_frontend_pages -->|"calls"| node_frontend_api
node_frontend_api -->|"requests"| node_backend_routers
node_backend_services -.->|"integrates"| node_firebase_svc
node_frontend_app -.->|"integrates"| node_firebase_svc

click node_backend_entry "https://github.com/nerontad/pyrosense/blob/main/backend/app/main.py"
click node_backend_config "https://github.com/nerontad/pyrosense/blob/main/backend/app/config.py"
click node_backend_security "https://github.com/nerontad/pyrosense/blob/main/backend/app/middleware/security.py"
click node_backend_routers "https://github.com/nerontad/pyrosense/tree/main/backend/app/routers"
click node_backend_services "https://github.com/nerontad/pyrosense/tree/main/backend/app/services"
click node_backend_repos "https://github.com/nerontad/pyrosense/tree/main/backend/app/repositories"
click node_backend_db "https://github.com/nerontad/pyrosense/blob/main/backend/app/database/connection.py"
click node_backend_mqtt "https://github.com/nerontad/pyrosense/blob/main/backend/app/services/mqtt_client.py"
click node_backend_vision "https://github.com/nerontad/pyrosense/blob/main/backend/app/services/vision_service.py"
click node_backend_stream "https://github.com/nerontad/pyrosense/blob/main/backend/app/services/stream_service.py"
click node_backend_alerts "https://github.com/nerontad/pyrosense/blob/main/backend/app/services/motor_alertas.py"
click node_backend_notify "https://github.com/nerontad/pyrosense/tree/main/backend/app/services/notificacion"
click node_backend_telegram "https://github.com/nerontad/pyrosense/blob/main/backend/app/services/telegram_service.py"
click node_backend_realtime "https://github.com/nerontad/pyrosense/blob/main/backend/app/routers/websocket.py"
click node_frontend_app "https://github.com/nerontad/pyrosense/blob/main/frontend/src/App.jsx"
click node_frontend_state "https://github.com/nerontad/pyrosense/blob/main/frontend/src/context/AuthContext.jsx"
click node_frontend_pages "https://github.com/nerontad/pyrosense/tree/main/frontend/src/pages"
click node_frontend_api "https://github.com/nerontad/pyrosense/blob/main/frontend/src/services/api.js"
click node_arduino_node "https://github.com/nerontad/pyrosense/blob/main/frontend/arduino/sensor_node/sensor_node.ino"
click node_firebase_svc "https://github.com/nerontad/pyrosense/blob/main/backend/app/services/firebase_service.py"
click node_model_onnx "https://github.com/nerontad/pyrosense/blob/main/best.onnx"

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_backend_entry,node_backend_config,node_backend_security,node_backend_routers,node_backend_services,node_backend_repos,node_backend_db,node_backend_mqtt,node_backend_vision,node_backend_stream,node_backend_alerts,node_backend_notify,node_backend_telegram,node_backend_realtime toneBlue
class node_frontend_app,node_frontend_state,node_frontend_pages,node_frontend_api toneAmber
class node_arduino_node toneMint
class node_camera_sources,node_mqtt_broker,node_telegram_api,node_firebase_svc,node_model_onnx toneRose
```

## Components

### Backend

Python API, persistence, and alert processing hub

- [App entry](https://github.com/nerontad/pyrosense/blob/main/backend/app/main.py): python entrypoint · Starts the API service and wires the application · `backend/app/main.py`
- [Config](https://github.com/nerontad/pyrosense/blob/main/backend/app/config.py): env config · Environment-driven settings and deployment configuration · `backend/app/config.py`
- [Security](https://github.com/nerontad/pyrosense/blob/main/backend/app/middleware/security.py): middleware · Request/security boundary for the API · `backend/app/middleware/security.py`
- [API routers](https://github.com/nerontad/pyrosense/tree/main/backend/app/routers): domain routes · HTTP surface split by business domain · `backend/app/routers`
- [Services](https://github.com/nerontad/pyrosense/tree/main/backend/app/services): business logic · Core orchestration for ingestion, vision, alerts, and delivery · `backend/app/services`
- [Repositories](https://github.com/nerontad/pyrosense/tree/main/backend/app/repositories): data access · Persistence abstraction for domain entities · `backend/app/repositories`
- [Database](https://github.com/nerontad/pyrosense/blob/main/backend/app/database/connection.py): persistence · Relational persistence boundary · `backend/app/database/connection.py`
- [MQTT client](https://github.com/nerontad/pyrosense/blob/main/backend/app/services/mqtt_client.py): sensor ingress · Consumes telemetry from IoT devices · `backend/app/services/mqtt_client.py`
- [Vision pipeline](https://github.com/nerontad/pyrosense/blob/main/backend/app/services/vision_service.py): cv inference · Camera stream processing and ONNX-based detection · `backend/app/services/vision_service.py`
- [Stream service](https://github.com/nerontad/pyrosense/blob/main/backend/app/services/stream_service.py): rtsp stream · Manages camera video input and stream handling · `backend/app/services/stream_service.py`
- [Alert motor](https://github.com/nerontad/pyrosense/blob/main/backend/app/services/motor_alertas.py): fusion engine · Combines sensor and vision evidence into alert decisions · `backend/app/services/motor_alertas.py`
- [Notifier](https://github.com/nerontad/pyrosense/tree/main/backend/app/services/notificacion): delivery strategy · Routes alert delivery to Telegram and WebSocket · `backend/app/services/notificacion`
- [Telegram svc](https://github.com/nerontad/pyrosense/blob/main/backend/app/services/telegram_service.py): integration · Telegram-specific outbound notifications and webhook handling · `backend/app/services/telegram_service.py`
- [WebSocket](https://github.com/nerontad/pyrosense/blob/main/backend/app/routers/websocket.py): push api · Live alert updates for connected clients · `backend/app/routers/websocket.py`

### Frontend

React operator console and browser runtime

- [UI app](https://github.com/nerontad/pyrosense/blob/main/frontend/src/App.jsx): react spa · Operator-facing single-page application · `frontend/src/App.jsx`
- [Auth & WS](https://github.com/nerontad/pyrosense/blob/main/frontend/src/context/AuthContext.jsx): client state · Authentication context and live update hooks · `frontend/src/context/AuthContext.jsx`
- [Pages](https://github.com/nerontad/pyrosense/tree/main/frontend/src/pages): views · Dashboards and operator workflows · `frontend/src/pages`
- [API client](https://github.com/nerontad/pyrosense/blob/main/frontend/src/services/api.js): http client · Browser boundary to backend REST endpoints · `frontend/src/services/api.js`

### Edge Devices

Embedded sensor producer

- [Sensor node](https://github.com/nerontad/pyrosense/blob/main/frontend/arduino/sensor_node/sensor_node.ino): embedded firmware · Arduino firmware publishing environmental readings · `frontend/arduino/sensor_node/sensor_node.ino`

### External Systems

Third-party brokers, services, and model artifact

- **IP cameras**: video sources · External camera inputs feeding the vision pipeline
- **MQTT broker**: message broker · Transport layer for sensor telemetry
- **Telegram**: notification service · Outbound messaging and webhook ecosystem
- [Firebase](https://github.com/nerontad/pyrosense/blob/main/backend/app/services/firebase_service.py): cloud integration · Auxiliary backend/frontend cloud dependency · `backend/app/services/firebase_service.py`
- [ONNX model](https://github.com/nerontad/pyrosense/blob/main/best.onnx): ml artifact · Detection model used by the vision subsystem · `best.onnx`

## Connections

- App entry → Config: loads · Bootstraps runtime settings from environment
- App entry → Security: applies · Installs API boundary controls
- App entry → API routers: mounts · Exposes domain HTTP routes
- API routers → Services: calls · Routes delegate to business logic
- Services → Repositories: persists via · Domain operations write and read through repositories
- Repositories → Database: uses · Repository layer reaches the database connection
- MQTT client → MQTT broker: subscribes · Consumes IoT telemetry from the broker
- Sensor node → MQTT broker: publishes · Sends environmental sensor readings
- MQTT client → Alert motor: feeds · Telemetry becomes alert inputs
- Vision pipeline → Stream service: reads · Vision pipeline consumes camera streams
- Stream service → IP cameras: connects to · Streams originate from IP cameras
- Vision pipeline → ONNX model: infers with · Runs detection against the ONNX model
- Vision pipeline → Alert motor: feeds · Detections contribute to fusion decisions
- Alert motor → Repositories: stores alerts · Alert events are persisted
- Alert motor → Notifier: dispatches · Chosen alerts are sent to notification channels
- Notifier → Telegram svc: uses · Telegram is one delivery strategy
- Telegram svc → Telegram: sends to · Outbound messages and webhook interactions
- Notifier → WebSocket: pushes · WebSocket updates for live dashboards
- WebSocket → Auth & WS: streams to · Browser subscribes to live alert updates
- UI app → Auth & WS: uses · UI depends on auth and WebSocket state
- UI app → Pages: renders · Operator screens are composed from pages
- Pages → API client: calls · Pages fetch and mutate backend data
- API client → API routers: requests · REST client targets the API surface
- Services → Firebase: integrates · Backend may use Firebase as an auxiliary service
- UI app → Firebase: integrates · Frontend also depends on Firebase features
