ποΈ System Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SNOW CRYSTAL (Yacht) β
β β
β ββββββββββββββββββββ ββββββββββββββββββββ β
β β SmartShunt 500A β β Quattro 48/5000 β β
β β Battery Monitor β β Inverter/Charger β β
β ββββββββββ¬ββββββββββ ββββββββββ¬ββββββββββ β
β β BLE β BLE β
β ββββββββββββ¬ββββββββββββββ β
β βΌ β
β ββββββββββββββββββββ β
β β Raspberry Pi β β Scans every 60 seconds β
β β victron_monitor β β
β ββββββββββ¬ββββββββββ β
β β WiFi β
ββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββ
β HTTPS POST
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β VPS4 (Cloud Server) β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β snow-victron container β β
β β β β
β β βββββββββββββββ βββββββββββββββ ββββββββββββββββββββββββ β
β β β Express.js β β SQLite β β Alert Engine ββ β
β β β API Server ββββ Database ββββ β’ Pi Watchdog ββ β
β β β :3080 β β β β β’ Smart Charging ββ β
β β βββββββββββββββ βββββββββββββββ β β’ Escalation ββ β
β β ββββββββββββ¬ββββββββββββ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββ β
β β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββ
β
ββββββββββββββββββββββββββββββββββββββββΌββββββββββββ
β β β
βΌ βΌ βΌ
ββββββββββββββ ββββββββββββββ ββββββββββ
β Matrix β β Twilio β β Vapi β
β (Chat) β β (SMS) β β (Call) β
ββββββββββββββ ββββββββββββββ ββββββββββ
π Monitored Devices
SmartShunt SmartShunt 500A/50mV
Battery monitor that measures current flow through a precision shunt resistor.
| Parameter | Description | Unit |
| State of Charge (SoC) | Battery level percentage | % |
| Voltage | Battery bank voltage | V |
| Current | Current flow (+charge, -discharge) | A |
| Power | Calculated: voltage Γ current | W |
| Consumed Ah | Amp-hours consumed since full | Ah |
| Time Remaining | Estimated time to empty | minutes |
| Temperature | Battery temp (if aux sensor) | Β°C |
Quattro Quattro 48/5000/70-2x100 120V
Inverter/charger that converts AC shore power to DC for charging, and DC to AC for loads.
| Parameter | Description | Unit |
| Device State | Operating mode (Off, Bulk, Absorption, Float, Inverting) | enum |
| AC Input State | Shore power connection status | enum |
| AC In Power | Power drawn from shore | W |
| AC Out Power | Power delivered to AC loads | W |
| Battery Current | Charger current to batteries | A |
| Battery Temp | Temperature sensor reading | Β°C |
| SoC | State of charge (if configured) | % |
π Alert System
Alerts are sent via multiple channels to ensure delivery:
Channels: Matrix (instant message), SMS (text message), Voice Call (Spanish, escalation only)
| Alert |
Trigger |
Message |
Escalation |
| πͺ« Low Battery |
SoC drops below 45% |
"Snow Crystal battery low: X%" |
No |
| π Start Charging |
Not enough time to reach 100% by 9:30 AM |
"Start charging NOW to be full by..." |
Yes (voice call) |
| β‘ Charge Complete |
SoC β₯99% + Float mode + Shore connected |
"Charging complete! Disconnect shore power" |
Yes (voice call) |
| π‘ Pi Offline |
No data received for 2+ hours |
"Pi offline! Check power/WiFi" |
No |
Alert Reset Conditions
- Low Battery: Resets when SoC rises above 50%
- Start Charging: Resets when charging begins (Bulk/Absorption mode)
- Charge Complete: Resets when shore power disconnected or SoC drops below 95%
- Pi Offline: Resets immediately when data is received
π Voice Call Escalation
For critical charging alerts, the system will escalate to a voice call if no action is taken.
SMS/Matrix Alert Sent
β
ββββ Wait 10 minutes
β
βΌ
Check: Did charge state change?
β
ββββ YES βββΊ No action needed β
β
ββββ NO
β
ββββ Is it 8AM-10PM? βββΊ NO βββΊ Skip call
β
ββββ YES
β
ββββ Calls today < 2? βββΊ NO βββΊ Skip call
β
ββββ YES
β
βΌ
π Voice Call (Spanish)
"Hola! Te llamo del sistema
del barco Snow Crystal..."
Voice Call Script (Spanish)
For Start Charging:
"Hola! Te llamo del sistema del barco Snow Crystal. Es hora de conectar la energΓa de tierra para cargar las baterΓas.
El barco necesita estar completamente cargado para las nueve y media de la maΓ±ana.
Por favor revisa el mensaje de texto que te enviΓ©. ΒΏPuedes conectar el cargador pronto?"
For Charge Complete:
"Hola! Te llamo del sistema del barco Snow Crystal. Las baterΓas ya estΓ‘n completamente cargadas.
Por favor desconecta la energΓa de tierra para evitar la electrΓ³lisis.
Revisa el mensaje de texto. ΒΏPuedes desconectarlo cuando puedas?"
Limits: Maximum 2 calls per day per alert type. Calls only between 8:00 AM and 10:00 PM.
π Smart Charging Logic
The system calculates when charging must start to reach 100% by the target time.
Charge Time Formula
hours_needed = (100 - current_soc) / 100 Γ capacity_ah / charge_rate_a + buffer
Example:
Current SoC: 60%
Capacity: 400 Ah
Charge Rate: 50 A
Buffer: 0.5 hours
hours_needed = (100 - 60) / 100 Γ 400 / 50 + 0.5
= 0.40 Γ 400 / 50 + 0.5
= 160 / 50 + 0.5
= 3.2 + 0.5
= 3.7 hours
Current Configuration
| Battery Capacity | 400 Ah |
| Charge Rate | 50 A (conservative; max is 70A) |
| Target Time | 9:30 AM (Eastern) |
| Low SoC Threshold | 45% |
When Alert Triggers
If hours_needed β₯ hours_until_target AND shore power is not connected AND not already charging:
π Snow Crystal: Start charging NOW to be full by 9:30 AM. Current: 60%, need ~3.7 hours.
π Pi Watchdog
Monitors the Raspberry Pi's connectivity and alerts if data stops flowing.
| Check Interval | Every 30 minutes |
| Offline Threshold | 2 hours without data |
| Alert Repeat | Every 2 hours while offline |
Common Causes
- Pi lost power (check shore power / inverter)
- WiFi disconnected (marina network issue)
- Bluetooth failure (restart Pi)
- Monitor service crashed (SSH and restart)
π API Reference
Public Endpoints
| Endpoint | Description |
GET /health | Server status, config, alert state |
GET /data/latest | Latest reading from all devices |
GET /data/history?range=-24 hours | Historical readings |
GET /alerts/state | Current alert and escalation state |
GET /alerts/history | Alert history (last 50) |
GET /escalations/history | Voice call history |
Protected Endpoints (require X-Api-Token header)
| Endpoint | Description |
POST /data | Receive readings from Pi |
POST /alerts/reset | Reset all alert flags |
POST /alerts/test/:type | Test an alert (charge_complete, start_charging, call) |
βοΈ Configuration
All settings are configured via environment variables in .env:
| Variable | Default | Description |
| BATTERY_CAPACITY_AH | 400 | Total battery bank capacity |
| CHARGE_RATE_A | 50 | Expected charge current |
| TARGET_CHARGE_TIME_HOUR | 9 | Hour to be fully charged |
| TARGET_CHARGE_TIME_MIN | 30 | Minute to be fully charged |
| LOW_SOC_THRESHOLD | 45 | Alert when SoC below this |
| PI_OFFLINE_THRESHOLD_MS | 7200000 | 2 hours in milliseconds |
| ESCALATION_DELAY_MS | 600000 | 10 minutes before voice call |
| ESCALATION_MAX_CALLS | 2 | Max calls per day per alert |
| ESCALATION_START_HOUR | 8 | Earliest hour for calls |
| ESCALATION_END_HOUR | 22 | Latest hour for calls |
Note: Phone numbers and API tokens are stored securely in environment variables and are not displayed here.