Node-RED based data collector for Victron SmartSolar MPPT controllers with InfluxDB replication to remote server.
This project runs on a Raspberry Pi Zero 2W and collects data from a Victron MPPT 75/15 charge controller via VE.Direct USB interface. Data is written to a local InfluxDB instance and automatically replicated to a remote VPS for long-term storage and visualization.
Complete Monitoring Stack:
This repository provides the edge data collection component. For the complete visualization and analysis stack, combine with: → victron-grafana-influx - Grafana dashboards, downsample tasks, and long-term storage
System:
- Edge: Raspberry Pi + Node-RED + local InfluxDB (7 days)
- VPS: InfluxDB (raw/5min/1hour buckets) + Grafana
- Replication: Automatic HTTPS sync
- Retention: 6 months raw, 2 years 5min, infinite 1hour
Features:
- VE.Direct USB protocol parser
- 10-second sampling interval
- Low power (~2W)
- Works with cheap FTDI adapters (~5-10€)
- Raspberry Pi Zero 2W (512MB RAM recommended)
- microSD Card: 16GB minimum, 32GB recommended
- USB-Serial Cable: FTDI FT232R adapter (3.3V logic level)
- NOT the expensive Victron VE.Direct USB cable!
- Generic FTDI USB-to-Serial adapter works fine (~5-10€)
- Must support 3.3V TTL serial (some are 5V only - check specs!)
- Connect: GND → GND, TX → RX (VE.Direct pin 2), RX → TX (VE.Direct pin 3)
- VE.Direct connector: 4-pin JST-PH 2.0mm pitch
- Power Supply: 5V/2A USB power adapter
- Victron Device: SmartSolar MPPT 75/15 (or compatible with VE.Direct port)
- Raspberry Pi OS Lite (64-bit, Debian 12)
- Node-RED v4.0+
- InfluxDB v2.x
- Node.js v18+
# Update system
sudo apt update && sudo apt upgrade -y
# Set hostname
sudo hostnamectl set-hostname victron-collector
# Configure timezone
sudo timedatectl set-timezone Europe/Berlin
# Enable SSH (if not already enabled)
sudo systemctl enable ssh
sudo systemctl start ssh# Add InfluxDB repository
wget -qO- https://repos.influxdata.com/influxdb.key | gpg --dearmor | sudo tee /usr/share/keyrings/influxdb-archive-keyring.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/influxdb-archive-keyring.gpg] https://repos.influxdata.com/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
# Install
sudo apt update
sudo apt install influxdb2 influxdb2-cli -y
# Start service
sudo systemctl enable influxdb
sudo systemctl start influxdb# Initial setup (interactive)
influx setup
# Enter:
# - Username: admin
# - Password: <secure-password>
# - Organization: <your-org-name>
# - Bucket: victron
# - Retention: 168h (7 days)
# Create API token for Node-RED
influx auth create \
--org <your-org-name> \
--write-bucket victron \
--description "Node-RED Write Token"
# Save the token! You'll need it for Node-RED configuration.# Install Node-RED using official script
bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
# Enable Node-RED service
sudo systemctl enable nodered
sudo systemctl start nodered
# Reduce memory limit for Pi Zero
sudo nano /lib/systemd/system/nodered.service
# Add line under [Service]:
# Environment="NODE_OPTIONS=--max-old-space-size=256"
# Reload and restart
sudo systemctl daemon-reload
sudo systemctl restart nodered# Access Node-RED web interface
# Open browser: http://<raspberry-pi-ip>:1880
# Enable projects mode
cd ~/.node-red
nano settings.js
# Find and uncomment:
editorTheme: {
projects: {
enabled: true
}
}
# Restart Node-RED
sudo systemctl restart nodered# SSH to Raspberry Pi
cd ~/.node-red
# Install required nodes
npm install node-red-contrib-influxdb
npm install node-red-contrib-victron-vedirect-usb
# Restart Node-RED
sudo systemctl restart nodered-
Clone this repository on your PC:
git clone https://github.com/simonbuehler/nodered-victron-edge-collector.git
-
In Node-RED web interface:
- Menu → Import → Select a file to import
- Choose
flows.jsonfrom cloned repo - Click "Import"
-
Configure InfluxDB connection:
- Double-click "batch influx" node
- Edit "Server" field:
- URL:
http://localhost:8086 - API Version:
2.0 - Organization:
<your-org-name> - Bucket:
victron - Token:
<token-from-step-3>
- URL:
- Click "Done" → "Deploy"
# Check if Victron MPPT is detected
ls -l /dev/ttyUSB*
# Should show: /dev/ttyUSB0
# Check device info
dmesg | grep -i "ttyUSB\|FTDI"
# Should show: FTDI USB Serial Device converter now attached to ttyUSB0
# Add user to plugdev group (if not already)
sudo usermod -aG plugdev pi# Check Node-RED logs
sudo journalctl -u nodered -f
# Query InfluxDB
influx query 'from(bucket:"victron") |> range(start: -5m)'
# Should show recent data from measurements:
# - ve_direct_battery
# - ve_direct_panel
# - ve_direct_load
# - ve_direct_today
# - ve_direct_victron# On Raspberry Pi, create remote connection
influx remote create \
--name vps-server \
--remote-url https://your-vps-domain.com:8086 \
--remote-org-id <remote-org-id> \
--remote-token <remote-api-token>
# Verify
influx remote list# Create replication from local to remote
influx replication create \
--name pi-to-vps \
--remote-id <remote-id-from-previous-step> \
--local-bucket-id <local-victron-bucket-id> \
--remote-bucket victron
# Verify
influx replication list
# Should show:
# - Remaining Bytes to be Synced: 0
# - Latest Status Code: 204# Local bucket ID
influx bucket list | grep victron
# Remote org ID (run on VPS or use API)
influx org list --host https://your-vps-domain.com:8086 --token <remote-token># Check replication status
influx replication list
# Check queue size (should be near 0 when synced)
# Current Queue Bytes on Disk: ~1-2 MB during normal operation
# Check InfluxDB logs for errors
sudo journalctl -u influxdb -f | grep -i replication| Field | Type | Unit | Description |
|---|---|---|---|
voltage |
integer | mV | Battery voltage |
current |
integer | mA | Battery current (±) |
power |
integer | mW | Battery power (calculated) |
| Field | Type | Unit | Description |
|---|---|---|---|
voltage |
integer | mV | Panel voltage |
current |
integer | mA | Panel current (calculated) |
power |
integer | W | Panel power |
| Field | Type | Unit | Description |
|---|---|---|---|
current |
integer | mA | Load current |
power |
integer | mW | Load power (calculated) |
status |
integer | - | Load switch (0=OFF, 1=ON) |
| Field | Type | Unit | Description |
|---|---|---|---|
yield |
integer | Wh | Today's energy yield |
power |
integer | W | Today's maximum power |
| Field | Type | Unit | Description |
|---|---|---|---|
CS_Status |
integer | - | Charge state (0-9) |
ERR_Status |
integer | - | Error code |
MPPT_Status |
integer | - | MPPT tracker mode (0-2) |
host: Always "Server1" (static, can be changed in function node)
CS_Status (Charge State):
0: Off2: Fault3: Bulk4: Absorption5: Float9: Inverting
MPPT_Status:
0: Off1: Voltage/Current limited2: MPPT active
┌─────────────────────────────────────────┐
│ Victron MPPT 75/15 │
│ (VE.Direct USB) │
└────────────────┬────────────────────────┘
│ FTDI USB-Serial (/dev/ttyUSB0)
↓
┌─────────────────────────────────────────┐
│ Raspberry Pi Zero 2W (Edge Device) │
│ 📦 THIS REPOSITORY │
│ │
│ ┌───────────────────────────────────┐ │
│ │ Node-RED (Port 1880) │ │
│ │ - VE.Direct Parser │ │
│ │ - Data Transformation │ │
│ │ - Batch Writer (10s) │ │
│ └──────────┬────────────────────────┘ │
│ ↓ │
│ ┌───────────────────────────────────┐ │
│ │ InfluxDB 2.x (Local Buffer) │ │
│ │ - Bucket: victron (168h) │ │
│ └──────────┬────────────────────────┘ │
│ │ │
└─────────────┼────────────────────────────┘
│ HTTPS Replication (automatic)
↓
┌─────────────────────────────────────────┐
│ VPS / Remote Server │
│ 📦 victron-grafana-influx │
│ │
│ ┌───────────────────────────────────┐ │
│ │ InfluxDB 2.x (Long-term Storage) │ │
│ │ - victron (180 days, raw) │ │
│ │ - victron_5m (730 days, 5min) │ │
│ │ - victron_1h (infinite, 1hour) │ │
│ │ - Downsample Tasks │ │
│ └──────────┬────────────────────────┘ │
│ ↓ │
│ ┌───────────────────────────────────┐ │
│ │ Grafana Dashboard │ │
│ │ - Dynamic bucket selection │ │
│ │ - Peak-preserving queries │ │
│ │ - 2+ years visualization │ │
│ └───────────────────────────────────┘ │
└─────────────────────────────────────────┘
Data Flow:
- Edge Collection (this repo): Raspberry Pi reads MPPT via USB every 10s
- Local Buffer: 7 days retention on Raspberry Pi
- Automatic Sync: InfluxDB replication to VPS (HTTPS)
- Downsampling (victron-grafana-influx): VPS creates 5min + 1hour aggregates
- Visualization (victron-grafana-influx): Grafana queries optimal bucket per time range
- victron-grafana-influx - Grafana dashboard and downsample tasks for VPS (companion project)
MIT
