Setup Guide

Agrogat software configuration — environment variables, PostgreSQL migrations, sync to central, and verification.

Configuration reference for Agrogat after the application is installed on a server or edge node.

> Raspberry Pi 4/5 hardware deployment: follow the step-by-step guide in setup-hardware.md.


Requirements

  • PHP 8.1+ with pdo_pgsql and json
  • PostgreSQL 14+ (16 recommended on Ubuntu 24.04)
  • Apache or Nginx with document root pointing at the application directory
  • Writable data/ directory for simulator settings

Directory layout

CODE
/var/www/html/agrogat/
├── .env                    # Secrets — never commit to git
├── .env.example
├── bootstrap.php           # Loads .env
├── db.php                  # PDO connection
├── index.php               # Public landing (SEO)
├── dashboard.php           # Operator dashboard (requires login)
├── welcome.php             # Landing page content (included by index.php)
├── login.php               # Sign in
├── ingest.php              # Public sensor ingest (API key)
├── lib/                    # Auth, gateway, geo, operations
├── api/                    # JSON API for dashboard
├── migrations/             # PostgreSQL schema (run in order)
├── scripts/                # Admin, migrate, sync, seed
└── docs/                   # Documentation (HTML renderers)

Configuration (.env)

Copy the template and edit:

BASH
cp .env.example .env
nano .env
INI
# Database
DB_HOST=localhost
DB_PORT=5432
DB_NAME=agrogat_iot
DB_USER=trat_admin
DB_PASS=your-strong-password

# API (external sensors → ingest.php)
INGEST_API_KEY=your-secret-api-key

# This gateway instance — must match gateways.code in the database
GATEWAY_CODE=TRAT-GATEWAY-001

# Cluster label (shown in dashboard header)
GATEWAY_CLUSTER=TRAT

# Edge gateway badge on welcome page (optional)
# IS_EDGE_GATEWAY=1

# Sync to central (optional — see below)
# CENTRAL_SYNC_URL=https://central.example.com/api/sync_receive.php
# SYNC_API_KEY=shared-secret-with-central
# SYNC_BATCH_SIZE=250
# SYNC_INTERVAL_SECONDS=300
# SYNC_ENTITIES_ENABLE=0

SYNC_INTERVAL_SECONDS is documentation only — cron defines the actual interval. Use the same SYNC_API_KEY on central and all gateways that push data.

GATEWAY_CODE is used by ingest.php and the simulator to set sensor_data.gateway_id. The same value must exist in gateways.code (seed in migration 002 or created in the dashboard).

Generate API keys

BASH
php -r "echo bin2hex(random_bytes(32));"

Use one value for INGEST_API_KEY; generate a separate (or shared) value for SYNC_API_KEY when sync is enabled.


Database and migrations

Full schema: database.md.

Recommended: run all migrations with the bundled script:

BASH
sudo ./scripts/migrate_postgres.sh agrogat_iot

Order executed:

  1. 001_clients_and_sensors.sql
  2. 001b_sensor_data.sqlrequired before 002
  3. 002_gateways_users.sql
  4. 003_gateways_latitude_longitude.sql
  5. 004_sync_replication.sql — when using central sync
  6. 005_sync_entity_watermark.sql — when pushing clients/sensors

Manual example:

BASH
sudo -u postgres psql -d agrogat_iot -f migrations/001_clients_and_sensors.sql
sudo -u postgres psql -d agrogat_iot -f migrations/001b_sensor_data.sql
sudo -u postgres psql -d agrogat_iot -f migrations/002_gateways_users.sql
# … continue through 005

Gateway → central sync

Feature Status
Local ingest Yes — ingest.php
Push readings to central Yes — scripts/sync_push_to_central.php + api/sync_receive.php
Push to multiple URLs Yes — CENTRAL_SYNC_URL + optional GATEWAY_PEER_SYNC_URLS
Push clients/sensors Yes — SYNC_ENTITIES_ENABLE=1 + migration 005
Automatic mesh between peers Partial — same batch can POST to multiple URLs

On each edge gateway:

  • CENTRAL_SYNC_URL — full URL to central api/sync_receive.php
  • SYNC_API_KEY — shared secret (must match central)
  • Optional: GATEWAY_PEER_SYNC_URLS, SYNC_BATCH_SIZE, SYNC_ENTITIES_ENABLE=1

On central:

  • Set SYNC_API_KEY (same value)
  • Leave CENTRAL_SYNC_URL empty if central does not push further
  • Register active gateways rows matching edge GATEWAY_CODE values

Cron example (every 5 minutes):

CRON
*/5 * * * * www-data /usr/bin/php /var/www/html/agrogat/scripts/sync_push_to_central.php >> /var/log/agrogat-sync.log 2>&1
*/15 * * * * www-data /usr/bin/php /var/www/html/agrogat/scripts/sync_push_entities_to_central.php >> /var/log/agrogat-sync-entities.log 2>&1

Manual test:

BASH
sudo -u www-data php /var/www/html/agrogat/scripts/sync_push_to_central.php

First administrator

After migration 002 creates the users table:

BASH
cd /var/www/html/agrogat
php scripts/create_admin.php admin@example.com 'YourStrongPassword'

Or set ADMIN_EMAIL and ADMIN_PASSWORD in .env before running the script.


File permissions

BASH
chmod 640 /var/www/html/agrogat/.env
sudo chown $USER:www-data /var/www/html/agrogat/.env
sudo chown -R www-data:www-data /var/www/html/agrogat/data
chmod 775 /var/www/html/agrogat/data

Verification

Ingest:

BASH
# Load key from .env on the server (do not paste secrets into public terminals)
set -a && source /var/www/html/agrogat/.env && set +a

curl -s -X POST http://localhost/ingest.php \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ${INGEST_API_KEY}" \
  -d '{"sensor_id":"test-001","payload":{"temp":22.5}}'

Expected: {"status":"success","id":"…"}

Dashboard: open /login.php, sign in, verify tabs load.

Dragino LSE01: see sensors-dragino-lse01.md. Runtime defaults live in lib/operations.php.


Docker (development / staging)

BASH
cp .env.docker.example .env
docker compose up -d --build
docker compose exec app php scripts/create_admin.php admin@example.com 'YourPassword'

Dashboard: http://localhost:8080


Guide Use when
setup-hardware.md Deploying on Raspberry Pi 4/5 + Ubuntu 24.04
deploy-agrogat.md Rsync deploy to remote Linux server
api.md API endpoints and payloads