WebSocket API

This article covers the device WebSocket API for local network access. For remote access via the cloud, see the Cloud API. Client libraries are available for Python and Go.

Authentication

Local access

Connect directly to your SolarAssistant device on your local network using your device password. A password must be configured on the device before the API can be used - see the local password guide for instructions.

Cloud access

When accessing a SolarAssistant unit via the cloud, requests go through two layers of security. See the site authorize API or sacli authorize for details.

Connecting

The WebSocket API streams live metrics as they update. The examples below assume your device's IP address is 192.168.0.100. You can find your device's IP address in the access overview.

ws://192.168.0.100/api/socket/websocket?password=<password>

After connecting, use the events below. The ref field is a client-chosen identifier echoed back in the server's reply, allowing you to match responses to requests. Using "phx_join" instead of "join" is also accepted for full compatibility with Phoenix Channels. Client libraries are available in C#, Python, JavaScript (docs, npm), Java/Kotlin and Swift.

SENDjoinStart receiving metrics

Joins the metrics channel. By default a curated set of common metrics is streamed. Pass a topics filter to subscribe to specific topics only.

Payload fields
topicsarrayList of topic filters, e.g. [{"topic": "total/*"}, {"topic": "battery_1/*"}]. Omit to receive the default set.
Example
{"topic": "metrics", "event": "join", "payload": {}, "ref": "1"}
With topic filter
{
  "topic": "metrics",
  "event": "join",
  "payload": {"topics": [{"topic": "total/*"}, {"topic": "battery_1/*"}]},
  "ref": "1"
}
SENDtopicsSet which metrics to receive

Changes the topic subscription after joining, without rejoining the channel.

Payload fields
topicsarrayrequiredList of topic filters. Use [{"topic": "*"}] to receive all topics.
Example
{
  "topic": "metrics",
  "event": "topics",
  "payload": {"topics": [{"topic": "*"}]},
  "ref": "2"
}

Add max_frequency_s to any filter to throttle update frequency for that topic:

{"topics": [{"topic": "total/*", "max_frequency_s": 5}]}
RECVdefinitionReceive metric metadata from server

Sent once per topic after joining with metadata describing the metric.

Example
{
  "event": "definition",
  "payload": {"definitions": [
    {"topic": "total/pv_power", "device": "Totals", "group": "Status", "name": "PV power", "unit": "W"}
  ]}
}
RECVdataReceive metric values from server

Sent each time metric values update.

Example
{
  "event": "data",
  "payload": {"metrics": [
    {"topic": "total/pv_power", "value": 1240},
    {"topic": "total/load_power", "value": 940}
  ]}
}
SENDsetWrite a setting

Sends a new value to the inverter. The topic format matches the metrics topics.

Payload fields
topicstringrequiredThe metric topic to write, e.g. inverter_1/output_source_priority.
valuestringrequiredThe new value to set.
Example
{
  "topic": "metrics",
  "event": "set",
  "payload": {"topic": "inverter_1/output_source_priority", "value": "Utility first"},
  "ref": "3"
}
RECVset_resultReceive result of set command

Sent in response to a set event. On failure the payload includes a result of "error" and a message describing the problem.

Example
{
  "event": "set_result",
  "payload": {"topic": "inverter_1/output_source_priority", "result": "ok"}
}

Topic structure

Topics follow the same structure as MQTT. Metrics are grouped under total/, inverter_1/, inverter_2/, battery_1/, etc. Some common topics:

TopicDescription
total/pv_powerCombined PV power across all inverters (W)
total/load_powerTotal load power (W)
total/grid_powerGrid power, negative = export (W)
total/battery_powerBattery power, negative = charging (W)
total/battery_state_of_chargeBattery state of charge (%)
inverter_1/device_modeCurrent inverter mode
battery_1/voltageBattery voltage (V)