β›΅ Snow Crystal Documentation

← Back to Dashboard

πŸ“– Contents

πŸ—οΈ 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.

ParameterDescriptionUnit
State of Charge (SoC)Battery level percentage%
VoltageBattery bank voltageV
CurrentCurrent flow (+charge, -discharge)A
PowerCalculated: voltage Γ— currentW
Consumed AhAmp-hours consumed since fullAh
Time RemainingEstimated time to emptyminutes
TemperatureBattery 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.

ParameterDescriptionUnit
Device StateOperating mode (Off, Bulk, Absorption, Float, Inverting)enum
AC Input StateShore power connection statusenum
AC In PowerPower drawn from shoreW
AC Out PowerPower delivered to AC loadsW
Battery CurrentCharger current to batteriesA
Battery TempTemperature sensor readingΒ°C
SoCState 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

πŸ“ž 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 Capacity400 Ah
Charge Rate50 A (conservative; max is 70A)
Target Time9:30 AM (Eastern)
Low SoC Threshold45%

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 IntervalEvery 30 minutes
Offline Threshold2 hours without data
Alert RepeatEvery 2 hours while offline

Common Causes

πŸ”Œ API Reference

Public Endpoints

EndpointDescription
GET /healthServer status, config, alert state
GET /data/latestLatest reading from all devices
GET /data/history?range=-24 hoursHistorical readings
GET /alerts/stateCurrent alert and escalation state
GET /alerts/historyAlert history (last 50)
GET /escalations/historyVoice call history

Protected Endpoints (require X-Api-Token header)

EndpointDescription
POST /dataReceive readings from Pi
POST /alerts/resetReset all alert flags
POST /alerts/test/:typeTest an alert (charge_complete, start_charging, call)

βš™οΈ Configuration

All settings are configured via environment variables in .env:

VariableDefaultDescription
BATTERY_CAPACITY_AH400Total battery bank capacity
CHARGE_RATE_A50Expected charge current
TARGET_CHARGE_TIME_HOUR9Hour to be fully charged
TARGET_CHARGE_TIME_MIN30Minute to be fully charged
LOW_SOC_THRESHOLD45Alert when SoC below this
PI_OFFLINE_THRESHOLD_MS72000002 hours in milliseconds
ESCALATION_DELAY_MS60000010 minutes before voice call
ESCALATION_MAX_CALLS2Max calls per day per alert
ESCALATION_START_HOUR8Earliest hour for calls
ESCALATION_END_HOUR22Latest hour for calls
Note: Phone numbers and API tokens are stored securely in environment variables and are not displayed here.