Files

8.0 KiB

LitoralRegas Backend

Spring Boot backend for the LitoralRegas agricultural monitoring and control platform.

This backend communicates with agricultural controllers through Modbus, builds dynamic acquisition plans based on installed modules, collects live telemetry, stores historical data, and exposes APIs consumed by the frontend dashboard.


Features

  • Modbus TCP communication
  • Dynamic controller capability discovery
  • Sensor definition import system
  • Live telemetry acquisition
  • Telemetry cache layer
  • Historical telemetry storage
  • Climate module API
  • Meteorology module API
  • Irrigation module foundation
  • Historical chart aggregation endpoints
  • SQLite persistence

Technology Stack

  • Java 21
  • Spring Boot
  • Spring Web
  • Spring Data JPA
  • SQLite
  • Maven
  • Modbus TCP

Architecture Overview

Sensor Definitions
        ↓
Controller Capabilities
        ↓
Acquisition Plan Builder
        ↓
Telemetry Acquisition Scheduler
        ↓
Telemetry Cache
        ↓
Historian + Module APIs
        ↓
Frontend Dashboard

Core Concepts

Sensor Definitions

The sensor_definition table contains the full catalog of known sensors.

A controller installation may not use every sensor present in the catalog.

The acquisition plan decides which sensors are actually polled.


Controller Capabilities

Controller capabilities are read directly from Modbus registers.

Current capability model:

Register 6 → irrigationControllerCount
Register 7 → fertilizerChannelCount
Register 8 → feature flags
Register 9 → climateGreenhouseCount

Feature flags:

bit 0 → climateEnabled
bit 1 → irrigationEnabled
bit 2 → lightingEnabled

Acquisition Plan

The acquisition plan dynamically selects sensors based on:

  • Installed controller modules
  • Greenhouse count
  • Irrigation controller count
  • Sensor category
  • Modbus address ranges

This prevents polling sensors that do not exist in a specific installation.


Telemetry Cache

The telemetry cache stores the latest acquired value for each sensor.

Module APIs read from the cache instead of directly querying Modbus.


Historian

The historian stores telemetry over time.

It supports:

  • historical chart series
  • accumulated values
  • time range queries
  • future workspace/chart persistence

Project Structure

src/main/java/com/litoralregas/backend
├── acquisition
├── historian
├── modbus
├── modules
│   ├── climate
│   ├── irrigation
│   ├── meteo
│   └── shared
├── sensor
├── telemetry
└── config

Running the Backend

Requirements

  • Java 21+
  • Maven
  • SQLite
  • Reachable controller or Modbus simulator

Start Backend

mvn spring-boot:run

Default backend URL:

http://localhost:18450

Configuration

Main configuration file:

src/main/resources/application.yaml

Example acquisition scheduler configuration:

litoralregas:
  acquisition:
    scheduler:
      enabled: true
      fixed-delay-millis: 10000

Important:

YAML comments must be on a separate line.

Correct:

fixed-delay-millis: 10000
# Longer delay between acquisition cycles

Wrong:

fixed-delay-millis: 10000 // comment

Database

Current database engine:

SQLite

Main table:

CREATE TABLE sensor_definition (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name VARCHAR(255) NOT NULL,
    modbus_address INTEGER NOT NULL,
    bit_offset INTEGER,
    value_type VARCHAR(50) NOT NULL,
    unit VARCHAR(50),
    decimal_places INTEGER NOT NULL DEFAULT 0,
    category VARCHAR(100) NOT NULL,
    source_type VARCHAR(50) NOT NULL,
    polling_interval_seconds INTEGER NOT NULL DEFAULT 1,
    enabled BOOLEAN NOT NULL DEFAULT TRUE,
    created_at TIMESTAMP NOT NULL
);

Sensor Definition Import

Sensor definitions are imported from:

src/main/resources/config/sensor-map.txt

Run import manually:

curl -X POST http://localhost:18450/api/sensor-definition-import/run

The importer:

  • imports missing sensors
  • updates safe metadata
  • skips duplicates safely
  • supports clean reimports during development

Clean Development Reimport

To completely reset sensor definitions during development:

DELETE FROM sensor_definition;

DELETE FROM sqlite_sequence
WHERE name = 'sensor_definition';

Then re-run:

curl -X POST http://localhost:18450/api/sensor-definition-import/run

Main API Endpoints

Acquisition Plan

GET /api/acquisition/plan

Returns:

  • module availability
  • greenhouse count
  • irrigation controller count
  • selected sensor IDs

Latest Telemetry

GET /api/telemetry/latest

Returns latest cached telemetry values.


Meteo Module

GET /api/modules/meteo

Provides:

  • exterior temperature
  • exterior humidity
  • wind speed
  • wind direction
  • radiation
  • rain sensors
  • CO2 overview

Climate Module

GET /api/modules/climate

Provides:

  • greenhouse temperature
  • greenhouse humidity
  • CO2
  • ventilation
  • extractors
  • screens
  • windows
  • lighting sectors
  • soil humidity
  • soil temperature

Historical Accumulation

GET /api/historian/accumulated

Example:

GET /api/historian/accumulated?key=meteo.chuva.1&range=30d

Supported ranges:

7d
30d
month
year

Dynamic Module Strategy

Module availability is determined dynamically through:

ControllerCapabilities
        ↓
AcquisitionPlan
        ↓
TelemetryCache

This means:

  • climate sensors are only acquired if climate exists
  • irrigation sensors are only acquired if irrigation exists
  • lighting sensors are only acquired if lighting exists

The frontend should eventually use acquisition plan data to decide which sections to render.


Derived Sensors

Some sensors are virtual/computed values.

Examples:

DPV Estufa 1        → -121
Hum. Absoluta 1     → -141

These are NOT real Modbus registers.

Correct pipeline:

Raw temperature + humidity
        ↓
DerivedClimateService
        ↓
DPV / Absolute Humidity
        ↓
TelemetryCache + Historian

Negative Modbus addresses should never be polled directly.


Current Development Notes

Disconnected sensors may return unrealistic values.

Examples:

  • invalid temperature values
  • unrealistic humidity values
  • disconnected soil probes

This is expected in partially installed environments.

The backend currently exposes all acquired sensors.

The frontend chart builder will later allow users to choose only relevant variables.


Planned Improvements

Chart Variables API

Planned endpoint:

GET /api/charts/variables?module=climate

Expected response:

{
  "sensorId": 13,
  "name": "Temperatura estufa 1",
  "key": "temperatura.estufa.1",
  "historianKey": "climate.temperatura.estufa.1",
  "module": "climate",
  "unit": "C",
  "category": "CLIMATE"
}

Derived Climate Values

Future derived telemetry:

  • DPV
  • absolute humidity
  • dew point
  • climate alarms
  • sensor health

Workspace System

Planned chart workspace support:

  • save layouts
  • detachable charts
  • multi-monitor support
  • reusable chart presets
  • draggable variables

Useful Development Commands

Import Sensors

curl -X POST http://localhost:18450/api/sensor-definition-import/run

Check Acquisition Plan

curl http://localhost:18450/api/acquisition/plan

Check Meteo Module

curl http://localhost:18450/api/modules/meteo

Check Climate Module

curl http://localhost:18450/api/modules/climate

Check Latest Telemetry

curl http://localhost:18450/api/telemetry/latest

Current Status

The backend foundation is currently stable for:

  • sensor catalog import
  • Modbus acquisition
  • capability-based acquisition planning
  • telemetry cache
  • meteorology module
  • climate module
  • historical accumulation
  • frontend integration

Next major milestone:

Chart Variables API + Derived Climate Telemetry