Building LoRaWAN for farms? Skip pricey vendors—ChirpStack’s open-source LoRaWAN Network Server (LNS) is battle-tested, and pairing it with KhawTech’s NaLog creates a robust, scalable stack. Over 3 years (rugged sensors), we’ve deployed this in Isan: Sensors → ChirpStack → NaLog for dashboards/AI. Non-proprietary guide: High-level setup, Docker configs, API integrations, and gotchas. For partners/curious devs—no deep secrets, just what works in muddy fields. If you’re engineering agritech, this gets you from prototype to co-op cluster fast. Let’s roll: Install, config, integrate, troubleshoot.

Why ChirpStack + NaLog? The Open Stack for Farms

ChirpStack: Free LNS handling device registration, uplink/downlink, security. Handles 10k+ nodes; we use v4 for EUIs/ABPs. NaLog: Our SaaS brain (NaLog platform)—pulls payloads, runs edge-AI, feeds dashboards.

Why together?

  • Scalable: ChirpStack manages LoRa traffic; NaLog adds farm logic (AWD alerts).
  • Offline-Friendly: ChirpStack gateways buffer; NaLog syncs via MQTT/WebSocket.
  • Cost: Zero licensing—fits unit economics.

Our Yasothon setup: 200 sensors on one ChirpStack instance, piping to NaLog for 30% water savings. Check platform docs for starters.

Step 1: ChirpStack Setup — Docker for Quick Wins

Run ChirpStack on a VPS (DigitalOcean 5$/mo) or edge server. Docker-compose for ease:

# docker-compose.yml
version: '3.8'
services:
  chirpstack-application-server:
    image: chirpstack/chirpstack-application-server:latest
    ports:
      - '8080:8080'
    environment:
      - POSTGRES_DB=chirpstack_as
      # ... DB creds
    volumes:
      - ./configuration/chirpstack-application-server:/etc/chirpstack-application-server

  chirpstack-network-server:
    image: chirpstack/chirpstack-network-server:latest
    # ... similar config for gateway bridge, PostgreSQL, Redis

Commands:

git clone https://github.com/brocaar/chirpstack-docker
cd chirpstack-docker
docker-compose up -d

Access UI at localhost:8080. Add gateway (IP:1883 for MQTT), register devices (DevEUI from our sensors). Set ADR for battery life (LoRa coverage).

Diagram:

Gotcha: Thailand 915 MHz—config eu868 to us915. Firewall UDP 1700 for gateways.

Step 2: LNS Configuration — Devices, Security, Scaling

ChirpStack’s the LNS core—config for farm scale:

  • Device Profiles: Create for KhawTech sensors—ABPA/OTAA, 1-hour pings, confirmed uplinks for reliability.
    • Payload codec: Base64 decode (e.g., moisture as uint16: value = (bytes[0] << 8) | bytes[1];).
  • Security: AppKeys per cluster (rotate yearly). Integrates TLS for NaLog handoff.

  • Scaling: For 100+ gateways, cluster with PostgreSQL replication. We run on 4GB RAM for 1k nodes.

Example device add via API (Python requests):

import requests

url = 'http://localhost:8080/api/devices'
headers = {'Authorization': 'Bearer YOUR_API_TOKEN', 'Content-Type': 'application/json'}
data = {
    'deviceProfileID': 'your-profile-id',
    'name': 'AWD-Sensor-001',
    'devEUI': '0011223344556677'  # From sensor
}
response = requests.post(url, json=data, headers=headers)
print(response.json())

Ties to LoRa coverage: Covers 5-10km; config SF7 for range vs. battery trade-off.

Step 3: NaLog Integration — APIs, MQTT, Data Flow

NaLog subscribes to ChirpStack’s MQTT (topic: application/+/device/+/rx).

  • MQTT Bridge: Use Mosquitto or ChirpStack’s built-in. NaLog listens, parses payloads.

Example NaLog webhook (Node.js snippet, from nalog-farming repo):

const mqtt = require('mqtt');
const client = mqtt.connect('mqtt://chirpstack:1883', {
  username: 'app-token',
  password: 'token-secret'
});

client.on('message', (topic, message) => {
  const payload = JSON.parse(message.toString());
  const moisture = (payload.data[0] << 8) | payload.data[1];  // Decode
  // Send to NaLog API
  fetch('https://nalog.khawtech.com/api/sensor-data', {
    method: 'POST',
    headers: {'Authorization': 'Bearer NALOG_TOKEN'},
    body: JSON.stringify({ deviceID: payload.devEUI, moisture, timestamp: payload.time })
  });
});
  • Data Flow: Uplink → ChirpStack → MQTT → NaLog ingestion → edge-AI decision → dashboard/alert.
  • Downlinks: NaLog pushes configs (e.g., ping rate) via ChirpStack API.

For carbon credits: NaLog aggregates, exports to CSV/API for VCS.

Our stack: 99% uptime, <1s latency end-to-end. See LoRa integration guide for full schemas.

Troubleshooting: Common Pitfalls in Field Deploys

From Isan trenches:

  • Gateway Sync: Check NTP; desync kills ADR. Fix: ntpdate pool.ntp.org.
  • Payload Errors: Base64 decode fails? Validate hex. Tool: ChirpStack simulator.
  • Offline Handling: Buffer in ChirpStack; NaLog retries 3x.
  • Security: Rotate keys; use VPN for remote configs.
  • Scale Issues: Redis overload at 5k msgs/day—add sharding.

Tested in Yasothon: Fixed a flood-induced desync in hours via remote logs.

Join the Open Agtech Build

This stack’s open—fork ChirpStack, contribute to NaLog basics. KhawTech’s sharing to grow Thai IoT. Devs, let’s collaborate.

Engineer Your Farm Network

Questions on setup? [email protected]—free consult for partners. Building open tools for closed-loop farming.

Alberto Roura, KhawTech Founder. From Alibaba APIs to Isan LoRa nets—inspiring Thai devs to code the backbone of sustainable ag.