Cloud Integrations - SolarNetwork/solarnetwork GitHub Wiki
SolarNetwork provides a fully-managed cloud service integration layer that allows you to work with external services within SolarNetwork.
SolarNetwork has support for the following cloud services:
| Service | Supported features |
|---|---|
| AlsoEnergy | Cloud Datum Stream |
| eGauge | Cloud Datum Stream |
| Enphase | Cloud Datum Stream |
| Fronius | Cloud Datum Stream |
| Locus Energy (AlsoEnergy) | Cloud Datum Stream |
| OpenWeatherMap | Cloud Datum Stream |
| SMA | Cloud Datum Stream |
| SolarEdge | Cloud Datum Stream |
| Solcast | Cloud Datum Stream |
| SolrenView (Solectria) | Cloud Datum Stream |
If you do not see a cloud integration for the service you would like to integrate with, email us!
The Cloud Datum Stream integration allows you to acquire data from external systems, when you do not have a SolarNode edge device delpoyed to collect the data directly. Some device manufacturers have deployed their own cloud services that their devices publish data to, so a Cloud Datum Stream integration can help to get that data into SolarNetwork.
The system works like this:
- Create a Cloud Integration configuration for a supported cloud service with details like credentials for accessing the service.
- Create a Cloud Datum Stream Mapping configuration that maps the service's data attributes into datum stream properties.
- Create a Cloud Datum Stream configuration that defines a SolarNetwork datum stream with a node ID, source ID, and details like the frequency at which you would like to collect the data (if the integration requires polling for data), along with the Cloud Datum Stream Mapping to use.
- If the service requires polling for data, create a Cloud Datum Stream Poll Task configuration to start collecting the data. You could optionally create one more more Cloud Datum Stream Rake Task configurations to validate the polled data after a time delay.
Once these steps are completed, SolarNetwork will work automatically to collect the data into SolarNetwork, where you can access it with all the APIs SolarNetwork offers.
Within SolarNetwork, the following entities are managed via the SolarUser Cloud Integrations API:
| Entity | Description |
|---|---|
| Cloud Integration | A cloud service to integrate with, and the details like credentials necessary to access the service. For example "Locus Energy". |
| Cloud Datum Stream Mapping | A group of Cloud Datum Stream Mapping Property entities associated with a specific Cloud Integration. For example "Inverter device". |
| Cloud Datum Stream Mapping Property | Maps a single cloud service data attribute to a SolarNetwork datum property. For example "AC power". |
| Cloud Datum Stream | SolarNetwork datum stream details such as node ID and source ID, associated with a Cloud Datum Stream Mapping. |
| Cloud Datum Stream Poll Task | For cloud services that require polling for data, details about the state of the polling task. |
| Cloud Datum Stream Rake Task | For cloud services that require polling for data, an optional polling validation task. |
The Cloud Integration entity represents a cloud service to integrate with, and the details like
credentials necessary to access the service. The serviceIdentifier property is configured with the
identifier of a supported service. The supported services can be listed with the Integration
Services list endpoint.
See the Cloud Integration API for more information.
The Cloud Datum Stream Mapping entity represents a group of Cloud Datum Stream Mapping Property entities that represents the mapping of a set of cloud data values to a complete SolarNetwork datum stream.
See the Cloud Datum Stream Mapping API for more information.
The Cloud Datum Stream Mapping Property entity represents a mapping of a single cloud data value to a SolarNetwork datum stream property, or an expression that derives a value from other cloud data values.
See the Cloud Datum Stream Mapping Property API for more information.
To discover the possible valueReference values that can be configured on Cloud Datum Stream
Mapping Property entities, SolarNetwork provides a
Data Values API that models a tree-like
hierarchy of cloud serice components you can query. Conceptually the tree can be visualized like
this:
The lowest leaf nodes within the tree provide a reference value that can be used as
valueReference values. Below is an example diagram that shows how a cloud service's data value
model could be represented by this structure. Each box represents a Data Value, with it's name
and identifiers on the left side with its associated metadata on the right side:
The Cloud Datum Stream entity represents a mapping of cloud data values to a SolarNetwork datum
stream. The serviceIdentifier property is configured with the identifier of a supported Cloud
Datum Stream service. The supported services can be listed with the Datum Stream Services
list endpoint.
The Cloud Datum Stream Poll Task entity represents the runtime state of a datum stream poll task, specific to a Cloud Datum Stream.
See the Cloud Datum Stream Poll Task API for more information.
The Cloud Datum Stream Rake Task entity represents the runtime state of a datum stream polling validation (called rake) task, specific to a Cloud Datum Stream. This task compares a time-delayed snapshot of data from the cloud provider against what was already collected in SolarNetwork, and can be used to pick up data changes that might occur after a stream's poll task has collected the data. Any number of rake tasks can be configured on a stream.
See the Cloud Datum Stream Rake Task API for more information.
The various Cloud Integration services generate application events. The following event tags are used:
| Tag | Description |
|---|---|
c2c |
All events include this tag, representing the Cloud Integrations system |
error |
If the event relates to an error, this tag is included |
auth |
For authentication and authorization events |
expr |
For Expression related events |
http |
For HTTP related events |
poll |
For poll task related events |
rake |
For rake task related events |
The following standard event data properties are used:
| Property | Description |
|---|---|
configId |
A primary key for an entity related to the event |
subId |
A secondary primary key for an entity related to the event |
message |
An additional detail message |
source |
A reference to the cause of the event, such as the location of an error |
The following Cloud Datum Stream service properties are common across many cloud integrations.
| Property | Description |
|---|---|
energyValidationThreshold |
An optional expected energy multiplication factor threshold to use by the energy-spike validation. Defaults to 10.0. |
placeholders |
An optional Map of placeholder names with asscoiated values, to make available to Datum Stream Mapping Property value references |
operationalDateRanges |
A map or comma-delimited mapping list of component IDs to associated date ranges representing the time span the component was operational. When equipment is replaced or added to a system, configuring this setting can improve the performance of the integration. |
sourceIdMap |
A map or comma-delimited mapping list of component IDs to associated source ID values. |
timeGapValidationThreshold |
An optional time duration threshold to use by the time-gap validation. Can be specified as an ISO 8601 duration string or an whole number of seconds. Defaults to PT72H (72 hours). |
validationIgnore |
A list, or comma-delimited string, of validation types to disable. By default all validation types are enabled. |
The operationalDateRanges service property is a map or comma-delimited mapping list of component
IDs to associated date ranges representing the time span the component was operational. When
equipment is replaced or added in a system, configuring this setting can improve the performance of
the integration by allowing SolarNetwork to avoid making requests for equipment data that has no
data for a given period of time (becuase it was not operational then).
The interval syntax is a string like START_DATE/END_DATE where either date is an optional
timestamp. A missing timestamp represents "all time". The START_DATE represents an inclusive
date, END_DATE represents an exclusive date. Each interval is formatted as an ISO 8601
timestamp, although a space may be used instead of a T for the date/time delimiter. The overall
interval represents the date range the equipment is/was present/operational. Conversely, for any
date outside the given interval the equipment is/was not present/operational.
Here are some examples of operational date range values:
| Example | Description |
|---|---|
2020-01-01T05:00:00Z/2025-01-01T05:00:00Z |
equipment was operational over a fixed date range |
/2025-01-01T05:00:00Z |
equipment stopped being operational at a given date, and is considered operational for all time before this date |
2020-01-01T05:00:00Z/ |
equipment started being operational at a given date, and is considered operational for all time after this date |
/ |
equipment is operational for all time; this is the default if no operational date range specified so is typically omitted from the overall mapping |
Here is an example of a Cloud Datum Stream making use of this service property:
{
"name": "Example Cloud Datum Stream",
"datumStreamMappingId": 1,
"schedule": "0 0/15 * * * *",
"kind": "n",
"objectId": 123,
"sourceId": "unused",
"serviceIdentifier": "s10k.c2c.ds.sma",
"serviceProperties": {
"sourceIdMap": {
"/1111111/2222222": "/INV/1",
"/1111111/3333333": "/INV/1",
"/1111111/4444444": "/INV/2",
"/1111111/5555555": "/INV/2"
},
"placeholders": {"systemId": "1111111"},
"operationalDateRanges": {
"/1111111/2222222": "2023-06-23T15:00:00Z/",
"/1111111/3333333": "/2023-06-23T15:00:00Z",
"/1111111/4444444": "/2022-12-13T05:00Z",
"/1111111/5555555": "2022-12-21T05:00Z/"
}
}
}In this example, the system has 2 inverters, but both were replaced over time. Inverter 4444444
was replaced in Dec 2022 by 5555555 and inverter 2222222 in June 2023 by 3333333.
The sourceIdMap service property is supported by most Cloud Datum Stream services, for explicitly
mapping a data value reference for a component to a specific source ID. This mapping can be
specified as a map or comma-delimited mapping list of component references to associated source ID
values. The exact nature of a "component" is service-specific, but commonly it consists of a
two-level data value reference to a "site" and "device". Typically this matches with the supported
placeholders on the service.
💡 Note that when configuring a
sourceIdMapproperty thesourceIdsetting configured on the Cloud Datum Stream itself is typically ignored. It is a required setting, however, so using a value likeunusedcan be a useful reminder of this fact.
For example, a service with systemId and deviceId component reference values could express a
sourceIdMap service property as a JSON object like:
{"/12345/67890":"S1/INV", "/23456/78901":"S2/INV"}or a string like:
"/12345/67890=S1/INV, /23456/78901=S2/INV"A complete example of the Datum Stream could look like this:
{
"enabled": true,
"name": "SMA Site 12345",
"datumStreamMappingId": 1,
"schedule": "1800",
"kind": "n",
"objectId": 123,
"sourceId": "unused",
"serviceIdentifier": "s10k.c2c.ds.sma",
"serviceProperties": {
"sourceIdMap": {
"/12345/67890": "S1/INV",
"/23456/78901": "S2/INV"
}
}
}The sourceId setting would not be used, and SolarNetwork would generate 2 datum streams:
S1/INVS2/INV
☝️ When
sourceIdMapis configured, only the sources explicitly defined will be generated into datum streams, and all other potential sources will be ignored.
When an explicit sourceIdMap service property is configured, a set of service-specific
placeholders are automatically generated from the component reference mapping keys.
Continuing with our example service, the following placeholders would be available:
{systemId}{deviceId}
This means you can configure value references that take advantage of those placeholders in the
stream's associated datum property mappings. For example, given the previous sourceIdMap example:
{
"sourceIdMap": {
"/12345/67890": "S1/INV",
"/23456/78901": "S2/INV"
}
}and a set of property mappings like this:
| Value Reference | SolarNetwork Property | Property Type |
|---|---|---|
/{systemId}/{deviceId}/PowerAc/activePower |
watts |
i |
/{systemId}/{deviceId}/EnergyAndPowerPv/pvGeneration |
wh |
i |
Then both the S1/INV and S2/INV datum streams would be resolved. The effective value
references taking the placeholders into account are:
| Effective Value Reference | SolarNetwork Property | Property Type |
|---|---|---|
/12345/67890/PowerAc/activePower |
watts |
i |
/12345/67890/EnergyAndPowerPv/pvGeneration |
wh |
i |
/23456/78901/PowerAc/activePower |
watts |
i |
/23456/78901/EnergyAndPowerPv/pvGeneration |
wh |
i |
The following validation types are commonly supported by Cloud Datum Stream services:
| Validation | Description |
|---|---|
| energy-spike | Identify unusually large energy values. |
| time-gap | Identify gaps of time in a datum stream. |
The validationIgnore Cloud Datum Stream service property can be used to disable validations. This is specified as a list of validation types.
For example, to disable the energy-spike and time-gap validations, you would configure a Cloud Datum Stream service properties like this:
{
"serviceProperties": {
"validationIgnore": ["energy-spkie", "time-gap"]
}
}Alternatively a comma-delimited string property could be used, so the same thing could be configured like this:
{
"serviceProperties": {
"validationIgnore": "energy-spkie,time-gap"
}
}The energy-spike validation identifies unusually large energy values. If the value is more than
energyValidationThreshold times what the rated
power size of a device would be able to produce, the value is treated as invalid and a Mark
auxiliary record will be created.
Here is an example auxiliary record generated by this validation:
{
"type": "Mark",
"kind": "n",
"objectId": 123,
"sourceId": "S1/INV",
"timestamp": "2023-12-08 08:25:00Z",
"notes": "Energy reading [727447.0] more than 10.0x larger than expected max [640.0] from device rating [7680].",
"metadata": {
"m": {
"type": "data-validation",
"subTypes": ["energy-spike"],
"generatedBy": "SolarNetwork"
},
"pm": {
"energy-spike": {
"source": {
"ref": "/12345/67890/EnergyAndPowerPv/pvGeneration",
"uri": "https://monitoring.smaapis.de/v1/devices/67890/measurements/sets/EnergyAndPowerPv/Day?Date=2025-07-08&ReturnEnergyValues=true",
"value": 727447.0
},
"duration": 300000,
"ratedPower": 7680,
"dataValueThreshold": 6400.0
}
}
}
}The /pm/energy-spike metadata object contains the following properties:
| Property | Type | Description |
|---|---|---|
dataValueThreshold |
number | The calculated maximum energy threshold allowed in Wh before generating the spike record. The expected maximum energy can be calculated as ratedPower × (duration ÷ 3600000). |
duration |
number | The number of milliseconds represented in the energy reading. |
ratedPower |
number | The device rated power in W, used to calculate the dataValueThreshold value. |
source |
object | Details about the source data that triggered the validation event. See below for more details. |
The source property is an object with the following properties:
| Property | Type | Description |
|---|---|---|
ref |
The Cloud Datum Stream Mapping Property reference where the spike was discovered. | |
uri |
The URI that returned the given reference. | |
value |
The reported energy value, in Wh. |
The time-gap validation identify gaps of time in a datum stream. If the difference in time between
two datum within a given stream (object and source ID) is larger than
timeGapValidationThreshold then two Mark
auxiliary records will be created for both the starting and ending ends of the time gap.
Here is an example pair of auxiliary records generated by this validation:
[
{
"type": "Mark",
"kind": "n",
"objectId": 123,
"sourceId": "S1/INV",
"timestamp": "2023-12-08 08:25:00Z",
"notes": "Time gap 21114600s not within threshold PT72H.",
"metadata": {
"m": {
"type": "data-validation",
"subTypes": ["time-gap"],
"generatedBy": "SolarNetwork"
},
"pm": {
"time-gap": {
"source": {
"ref": "/12345/67890/PowerAc/activePower",
"uri": "https://monitoring.smaapis.de/v1/devices/67890/measurements/sets/PowerAc/Day?Date=2024-08-08&ReturnEnergyValues=false",
"value": 21114600000
},
"correlationId": "f55c20f5-4a57-4606-8cfa-cb01380f256e",
"position": "start",
"timestamp": "2024-08-08 17:35:00Z",
"duration": 21114600000,
"dataValueThreshold": "PT72H"
}
}
}
},
{
"type": "Mark",
"kind": "n",
"objectId": 123,
"sourceId": "S1/INV",
"timestamp": "2024-08-08 17:35:00Z",
"notes": "Time gap 21114600s not within threshold PT72H.",
"metadata": {
"m": {
"type": "data-validation",
"subTypes": ["time-gap"],
"generatedBy": "SolarNetwork"
},
"pm": {
"time-gap": {
"source": {
"ref": "/12345/67890/PowerAc/activePower",
"uri": "https://monitoring.smaapis.de/v1/devices/67890/measurements/sets/PowerAc/Day?Date=2024-08-08&ReturnEnergyValues=false",
"value": 21114600000
},
"correlationId": "f55c20f5-4a57-4606-8cfa-cb01380f256e",
"position": "end",
"timestamp": "2023-12-08 08:25:00Z",
"duration": 21114600000,
"dataValueThreshold": "PT72H"
}
}
}
}
]The /pm/time-gap metadata object contains the following properties:
| Property | Type | Description |
|---|---|---|
correlationId |
string | A unique ID that the start and end pair of time-gap datum auxiliary records will share, so you can reliably relate the two. |
dataValueThreshold |
duration | An ISO 8601 duration representing the minimum time threshold used for generating the time-gap records. SolarNetwork will only generate records for gaps in time of at least this much. |
duration |
number | The number of milliseconds in the time gap, between the start and end position events. |
position |
string | One of start or end representing the starting and ending datum in the time gap. The start position is the start of the time gap (the last datum reported before the gap in time), while the end position is the end of the gap (the first datum reported after the gap in time). |
source |
object | Details about the source data that triggered the validation event. See below for more details. |
timestamp |
timestamp | The date of the related datum. For a start position record, this is the date of the end position. For an end position record, this is the date of the start position. |
The source property is an object with the following properties:
| Property | Type | Description |
|---|---|---|
ref |
The Cloud Datum Stream Mapping Property reference where the time gap was discovered. | |
uri |
The URI that returned the given reference. | |
value |
The number of milliseconds between this datum and the previous datum within the same datum stream (the time gap). |