Settings / System Setup
The System Setup panel is the single place where you configure how SETI AI talks to the outside world — alert channels, alarm thresholds, battery limits, energy pricing, charge schedules, and solar inverter connections.
Where to find it
System Setup is a widget, not a separate page. Open the SETI STACK
dashboard (from the Command Center top tabs, or by going
straight to the dashboard), open the left palette, and under the palette
look for System Setup (gear icon, CONFIG badge). Click it or drag it onto
the canvas to spawn the panel. It can be moved, resized, and saved with the rest
of your dashboard layout.
The panel is a stack of collapsible sections. The first section (Discord) is expanded on open; every other section starts collapsed — click a section heading to expand or collapse it. Each section has its own Save button, so you can configure one channel at a time. Channels that support it also have a Test button. A small toast in the corner confirms each save or test (green = ok, red = error).
All settings are stored server-side in the
system_settingstable (Postgres), so they persist across restarts and are shared by every browser. Saving callsPOST /api/notifications/settings; the panel loads current values fromGET /api/notifications/settingswhen it opens.
1. Discord
Send alerts to a Discord server, either through a webhook (simplest) or a bot (richer — supports a dedicated channel, a voice channel, and TTS).
| Field | What it does | Default |
|---|---|---|
| Enable Discord (toggle) | Master on/off for the Discord channel | Off |
| Use Bot (instead of webhook) (toggle) | Switches the form between webhook mode and bot mode. Off = webhook fields shown; On = bot fields shown | Off |
| Webhook URL | Discord webhook to post to (webhook mode). Format https://discord.com/api/webhooks/... |
empty |
| Application ID | Bot mode. Your app's client ID from the Discord Developer Portal → General | empty |
| Bot Token | Bot mode. From Developer Portal → Bot. Stored as a secret (password field); only re-sent if you type a new value | empty |
| Text Channel | Bot mode. Channel ID the bot posts to (right-click a channel → Copy ID) | empty |
| Voice Channel | Bot mode. Voice channel ID for voice/TTS announcements | empty |
| Enable TTS (toggle) | Bot mode. Speak alerts in the voice channel | Off |
| Invite Bot (link) | Appears automatically once an Application ID is entered. Opens the Discord OAuth invite (scope=bot, permission bitmask 3279872) so you can add the bot to your server |
— |
Buttons: Save (writes Discord settings) · Test (sends a test message to
the configured destination via POST /api/notifications/test).
Internal/private IPs and metadata addresses are blocked for webhook URLs (SSRF protection), so only real
discord.comwebhooks will work.
Stored keys: discord.enabled, discord.use_bot, discord.webhook_url,
discord.app_id, discord.bot_token, discord.bot_channel,
discord.voice_channel, discord.tts_enabled.
2. Slack
| Field | What it does | Default |
|---|---|---|
| Enable Slack (toggle) | Master on/off for Slack | Off |
| Webhook URL | Incoming webhook, format https://hooks.slack.com/services/... |
empty |
Buttons: Save · Test. Alerts post as a formatted Slack block message with a severity emoji header. Internal hosts are blocked (SSRF protection).
Stored keys: slack.enabled, slack.webhook_url.
3. Email (SMTP)
Send alerts by email over SMTP. Both a plain-text and an HTML version are sent; the HTML version is color-coded by severity.
| Field | What it does | Default |
|---|---|---|
| Enable Email (toggle) | Master on/off for email | Off |
| SMTP Host | Mail server hostname, e.g. smtp.gmail.com |
empty |
| Port | SMTP port | 587 |
| TLS | true/false — use STARTTLS. Anything other than the literal false is treated as true |
true |
| Username | SMTP login (often your email address) | empty |
| Password | SMTP password / app password. Secret (password field); only re-sent if you type a new value | empty |
| From | "From" address on outgoing mail. Falls back to Username if blank | empty |
| To (comma sep) | One or more recipient addresses, comma-separated | empty |
Buttons: Save · Test. Email won't send unless Enable Email is on and both SMTP Host and To are set. Internal SMTP hosts are blocked.
Stored keys: email.enabled, email.smtp_host, email.smtp_port,
email.smtp_tls, email.smtp_user, email.smtp_pass, email.from_addr,
email.to_addrs.
4. Alert Thresholds
The trigger points that fire battery alarms. After every Victron/VRM poll, the live battery metrics are checked against these values and a notification fires (through every enabled channel) when one is breached.
| Field | What it does | Default |
|---|---|---|
| Low Voltage (V) | Fires a critical alert when pack voltage falls to/below this | 48.2 |
| High Voltage (V) | Fires a warning alert when pack voltage reaches/exceeds this | 58.8 |
| Low SoC (%) | Fires a critical alert when state of charge falls to/below this | 20 |
| High Temp (C) | Fires a critical alert when battery temperature reaches/exceeds this | 45 |
| Cooldown (seconds) | Minimum time between repeat alerts for the same subject — prevents alarm spam | 300 |
| Notify on critical (toggle) | Allow critical-severity alerts to be sent | On |
| Notify on warning (toggle) | Allow warning-severity alerts to be sent | On |
| Notify on info (toggle) | Allow info-severity alerts to be sent | Off |
Button: Save.
Stored keys: notify.low_voltage, notify.high_voltage, notify.low_soc,
notify.high_temp, notify.cooldown_seconds, notify.on_critical,
notify.on_warning, notify.on_info.
5. Battery SoC Limits
Operating window for the battery, used by automation/charge logic (distinct from the Low SoC alarm above).
| Field | What it does | Default |
|---|---|---|
| Floor (min %) | Lowest state of charge the system should discharge to | 20 |
| Ceiling (max %) | Highest state of charge the system should charge to | 100 |
Button: Save. Stored keys: battery.soc_floor, battery.soc_ceiling.
6. Energy Cost
Electricity pricing used for cost and savings calculations across the dashboard.
| Field | What it does | Default |
|---|---|---|
| Rate ($/kWh) | Flat/base energy rate | 0.13 |
| Peak Rate | $/kWh during peak hours | 0.22 |
| Off-Peak | $/kWh outside peak hours | 0.08 |
| Peak Start (h) | Hour (0–23) peak pricing begins | 14 |
| Peak End (h) | Hour (0–23) peak pricing ends | 20 |
Button: Save. Stored keys: cost.rate_kwh, cost.peak_rate,
cost.offpeak_rate, cost.peak_start, cost.peak_end (currency is USD).
7. Charge Schedules
Time-of-day rules that charge or discharge the battery automatically — for example, charge to 100% overnight on off-peak power, then discharge during expensive peak hours. See Charge Scheduling.
The section lists existing schedules; each row shows an up arrow (charge, green) or down arrow (discharge, orange), the name, the time window and SoC target, an enabled/disabled indicator, and a trash button to delete it.
Add Schedule prompts for, in order:
| Prompt | Meaning | Suggested default |
|---|---|---|
| Schedule name | Friendly label | Off-Peak Charge |
| Mode | charge or discharge |
charge |
| Start hour (0–23) | When the rule begins | 0 |
| End hour (0–23) | When the rule ends | 6 |
| SoC target % | Charge up to / discharge down to this level | 100 for charge, 20 for discharge |
New schedules are created enabled. Backed by GET /api/schedules,
POST /api/schedules/save, POST /api/schedules/delete.
8. Inverters
Connect a solar inverter so SETI AI can read live PV/grid/battery power. Pick a Brand, fill in the fields that brand needs, Save, then Test the connection. See Inverter Drivers for the full driver notes.
Panel fields (generic):
| Field | What it does |
|---|---|
| Brand | One of the six supported brands (below). Default victron |
| IP Address | Local IP/host of the inverter (for Modbus/local-API brands) |
| API Key | Cloud API key/token (for cloud-portal brands). Secret field |
| Site/Plant ID | Site, plant, or system identifier used by the cloud API |
Test calls GET /api/energy/solar-inverter?brand=... and reports either the
live PV power (connected) or a "not configured / driver pending" note. Settings
save under inverter.<brand>.host, inverter.<brand>.api_key,
inverter.<brand>.site_id.
Supported brands and what each needs
| Brand | Connection | Needs |
|---|---|---|
| victron (default) | Victron VRM cloud (or Modbus TCP) | VRM token + installation ID (provided via server env) or a local Modbus host |
| sma | SMA Sunny Portal / ennexOS | api_key (Sunny Portal developer account) + plant_id (Site/Plant ID); or local host for ennexOS |
| solark (Sol-Ark) | Modbus TCP | host (inverter LAN IP) + port (default 8899) |
| enphase | Envoy local or Enphase cloud | local host (Envoy, /api/v1/production) or api_key + system_id (cloud OAuth v4) |
| solaredge | SolarEdge Monitoring API | api_key (monitoring portal) + site_id |
| schneider | Schneider Modbus or EcoStruxure | host (Modbus) or api_key + site_id (EcoStruxure Exchange API) |
Brand names are normalized (case-insensitive, dashes/spaces stripped), so
Sol-Ark,solark, andSOL ARKall resolve to thesolarkdriver. Any unrecognized brand falls back to the Victron VRM cache.
9. Notification History
A read-only log of the most recent notifications (latest 15 shown), newest
first. Each row shows the timestamp, a severity dot
(critical red / warning yellow / info blue), the subject, and the
delivery status (sent green / failed red / other). Backed by
GET /api/notifications/history?limit=15; the full log lives in the
notification_log table.
Quick reference — API endpoints
| Action | Endpoint |
|---|---|
| Load all settings | GET /api/notifications/settings |
| Save a section | POST /api/notifications/settings |
| Send test alert | POST /api/notifications/test ({channel}) |
| Test inverter | GET /api/energy/solar-inverter?brand=... |
| List schedules | GET /api/schedules |
| Add schedule | POST /api/schedules/save |
| Delete schedule | POST /api/schedules/delete |
| Notification history | GET /api/notifications/history?limit=N |