-
Notifications
You must be signed in to change notification settings - Fork 2
SolarFlux API
SolarFlux is a real-time publish/subscribe system based on the MQTT protocol. SolarNodes can publish the data they collect to SolarFlux and then applications can subscribe to receive that data from SolarFlux.
You can try out the SolarFlux Demo app to see the datum being captured by any of your nodes.
SolarNode devices can post data to SolarFlux via the SolarFlux Upload Service
plugin. Nodes use their ID as the MQTT client ID and also provide their client certificate on
mqtts
connections.
Messages can be published with the MQTT retained
flag set, which means the most recently published
datum is saved by SolarFlux. When an application subscribes to a topic it will immediately receive
any retained message for that topic. In this way, SolarFlux can provide a "most recent" snapshot of
all datum across all nodes and sources.
The SolarFlux Upload Service plugin posts every datum captured by other plugins up to SolarFlux, using MQTT topics named with the node ID and datum source ID, according to this pattern:
node/N/datum/A/S
In this pattern N
is a node ID , A
is an aggregate key, and S
is a source ID. SolarNode
datum are always published with a 0
aggregate key which represents the raw (or no) aggregation
level. Note that any leading /
in a source ID is stripped from the topic name.
Example topics look like:
node/1/datum/0/Meter
node/2/datum/0/Building1/Room1/Light1
node/2/datum/0/Building1/Room1/Light2
The datum messages published by the SolarFlux Upload Service plugin are CBOR encoded indefinite-length maps. These are easily converted to JSON objects. The map keys are the datum property names. All datum have the following properties at a minimum:
Property | Type | Description |
---|---|---|
sourceId |
String | The SolarNetwork source ID. |
created |
Number | The datum date as milliseconds since the epoch, typically the time it was captured at. |
You might also see the following properties:
Property | Type | Description |
---|---|---|
_DatumType |
String | The SolarNode internal name of the primary datum type. |
_DatumTypes |
Array<String> | An array of SolarNode internal names of all datum types the datum implements. |
Here's an example datum message, expressed as JSON:
{
"_DatumType": "net.solarnetwork.node.domain.ACEnergyDatum",
"_DatumTypes": [
"net.solarnetwork.node.domain.ACEnergyDatum",
"net.solarnetwork.node.domain.EnergyDatum",
"net.solarnetwork.node.domain.Datum",
"net.solarnetwork.node.domain.GeneralDatum"
],
"apparentPower": 2797,
"created": 1545167905344,
"current": 11.800409317016602,
"phase": "PhaseB",
"phaseVoltage": 409.89337158203125,
"powerFactor": 1.2999000549316406,
"reactivePower": -1996,
"realPower": 1958,
"sourceId": "Ph2",
"voltage": 236.9553680419922,
"watts": 1958
}
SolarNetwork automatically publishes aggregate datum to SolarFlux, regardless if SolarNodes are publishing raw datum to SolarFlux. SolarNetwork continuously computes and updates the aggregate data and publishes those updates to SolarFlux.
Messages are published with the MQTT retained
flag set, which means the most recently published
datum is saved by SolarFlux. When an application subscribes to a topic it will immediately receive
any retained message for that topic. In this way, SolarFlux will provide a "most recent" snapshot of
all aggregate datum across all nodes and sources.
The MQTT topics used follow the same pattern as outlined previously:
node/N/datum/A/S
In this pattern N
is a node ID , A
is an aggregate key, and S
is a source ID. Note
that any leading /
in a source ID is stripped from the topic name. The aggregate key values
supported by SolarFlux are:
Aggregate | Topic Key | Description |
---|---|---|
Hour | h |
The current hour. |
Day | d |
The current day, in the time zone of the node the topic is for. |
Month | M |
The current month, in the time zone of the node the topic is for. |
Example topics look like:
node/1/datum/h/Meter
node/2/datum/d/Building1/Room1/Light1
node/2/datum/M/Building1/Room1/Light2
The messages are CBOR encoded objects in the same form as outlined for the raw datum messages previously. They might contain additional aggregate properties derived from the raw data, as calculated by SolarNetwork.
All aggregate datum have the following properties at a minimum:
Property | Type | Description |
---|---|---|
nodeId |
Number | The node ID. |
sourceId |
String | The datum source ID. |
created |
Number | The aggregate datum date as milliseconds since the epoch. |
localDate |
String | The aggregate datum date as yyyy-MM-dd format in the time zone of the node. |
localTime |
String | The aggregate datum time as HH:mm format in the time zone of the node. |
Here's an example aggregate datum message, expressed as JSON:
{
"created": 1573023600000,
"nodeId": 108,
"sourceId": "DB",
"localDate": "2019-11-06",
"localTime": "20:00",
"watts": 2097.409,
"watts_max": 3776,
"watts_min": 1118,
"wattHours": 2005.855,
"wattHoursReverse": 0
}
SolarNetwork-generated user events are published to SolarFlux, and can be subscribed to with a User security token. The MQTT topics used follow this pattern:
user/U/event/T
In this pattern U
is a user ID and T
is an event tag. There can be any number of tags with an event, so multiple /T
sub-topic levels can be included.
For example, the MQTT topic would be user/123/event/ocpp/charger/forbidden
for the following user event:
{
"created" : 1716593105081,
"data" : {
"cp" : "chgr-001",
"error" : "HTTP Authorization header not provided (no credentials provided)."
},
"eventId" : "018facec-18b9-7afc-b722-d2f1bd371d3c",
"tags" : [ "ocpp", "charger", "forbidden" ],
"userId" : 123
}
Applications wishing to subscribe to SolarFlux data can do so by using MQTT, directly or via a WebSocket connection.
For applications that can access MQTT directly, the connection details for the default SolarFlux service are as follows:
Property | Value | Description |
---|---|---|
URL | mqtts://fluxion.solarnetwork.net:8885 | The MQTT URL to connect to. This uses TLS encryption. |
Client ID | token + | This must start with the same token value used for the Username property, followed by anything. The maximum length is 40 characters. |
Username | token | A SolarNetwork security token. |
Password | secret or signature | A SolarNetwork security token or a SolarNetwork V2 signature derived from the token and its associated secret, extended with a Date=D attribute. |
Here's an example shell script that uses mosquitto_sub
to subscribe to SolarFlux,
xxd
to decode the payload from hex, and cbor2json.rb
to decode the CBOR
into JSON, sort of like tail -f
for SolarFlux:
#!/bin/sh
mosquitto_sub -V mqttv31 --cafile /usr/local/etc/openssl/cert.pem \
-h fluxion.solarnetwork.net -p 8885 -q 0 \
-i '<<security token>>_<<random suffix>>' \
-u '<<security token>>' \
-P '<<token secret>>' \
-F '%t %x' \
-t 'node/+/datum/0/#' | (
while read -r LINE; do
echo "$(date)" $(echo "$LINE" |cut -d' ' -f1) $(echo "$LINE" |cut -d' ' -f2 |xxd -r -p |cbor2json.rb)
done;
)
Replace <<security token>>
and <<random suffix>>
and <<token secret>>
with valid credentials.
Example output looks like:
Sat 14 Dec 2019 16:54:16 NZDT user/1/node/2/datum/0/Main { "sourceId": "Main", "phase": "Total",
"reactivePower": -289, "created": 1576295598681, "apparentPower": 590,
"frequency": 49.967018127441406, "voltage": 238.205810546875, "current": 2.476088285446167,
"effectivePowerFactor": -0.8716593384742737, "watts": 515, "realPower": 515,
"wattHours": 34688636, "wattHoursReverse": 0, "powerFactor": 1.1283409595489502 }
For applications such as web apps that cannot access MQTT directly, MQTT via a WebSocket connection can be used. The connection details for the default SolarFlux service are:
Property | Value | Description |
---|---|---|
URL | wss://flux.solarnetwork.net/mqtt | The WebSocket URL to connect to. This uses TLS encryption. |
Client ID | token + | This must start with the same token value used for the Username property, followed by anything. The maximum length is 40 characters. |
Username | token | A SolarNetwork security token. |
Password | secret or signature | A SolarNetwork security token or a SolarNetwork V2 signature derived from the token and its associated secret, extended with a Date=D attribute. |
Some consideration must be given to the Client ID used when connecting to SolarFlux, as they must be unique across all connections to SolarFlux. If you connect to SolarFlux with the same Client ID as one that is already used by another connection, the previous connection will be dropped. Often a randomized Client ID value is appropriate.
The SolarFlux Demo app appends a random UUID (to the required token prefix) for each connection, which is a pretty safe way to ensure no two clients use the same Client ID value for an application where the number of connecting clients is not limited.
If you are developing an application that maintains a stable connection to SolarFlux, then it can be safe to append a simple static value that uniquely identifies the application to the required token prefix.
Using token signature passwords can be advantageous for applications that aren't allowed access to a
token secret directly. In this situation, some external mechanism must be provided that can give the
application either a token signing key for the application to generate the signature with, or the
actual signature value. The password signature is a SolarNetwork V2 signature, extended with a
Date=D
attribute. The request data used to sign the token request must be the following:
Property | Value | Description |
---|---|---|
Verb | GET |
The canonical request HTTP verb. |
Path | /solarflux/auth |
The canonical request URI. |
Host | data.solarnetwork.net |
The signed Host header value. |
Date | The signed X-SN-Date header value. The date must also be provided in the final signature as a Date=D attribute. See below for more details. |
Thus the canonical headers are Host
and X-SN-Date
and these must both be included as signed
headers in the signature.
The final signature value must include an additional Date=D
attribute, where D
is a Unix epoch value, i.e. the number of seconds since 1 Jan, 1970. Note this is
not specified in milliseconds, as is the default in programming languages like Java and
JavaScript.
An example MQTT password thus looks like this:
SNWS2 Credential=a09sjds09wu9wjsd9uy2,SignedHeaders=host;x-sn-date,Signature=4d56e33d69300c163f414ee688e9771eabce45d5a425e480a8cc605e97263919,Date=1545069502
The signature can be shortened to include just the Signature
and Date
attributes, if desired. Thus the following
MQTT password is equivalent to the previous example:
Signature=4d56e33d69300c163f414ee688e9771eabce45d5a425e480a8cc605e97263919,Date=1545069502
Also note the the order of the attributes is not significant. Thus the following MQTT password is equivalent to the previous example:
Date=1545069502,Signature=4d56e33d69300c163f414ee688e9771eabce45d5a425e480a8cc605e97263919
- SolarNetwork API access
- SolarNetwork API authentication
- SolarNetwork global objects
- SolarNetwork aggregation
- SolarFlux API
- SolarIn API
- SolarQuery API
-
SolarUser API
- SolarUser enumerated types
- SolarUser datum expire API
- SolarUser datum export API
- SolarUser datum import API
- SolarUser event hook API
- SolarUser location request API
- SolarUser Cloud Integrations API
- SolarUser DIN API
- SolarUser DNP3 API
- SolarUser ININ API
- SolarUser OCPP API
- SolarUser OSCP API
- SolarUser SolarFlux API