-
Notifications
You must be signed in to change notification settings - Fork 2
SolarIn API
The SolarIn API provides methods for nodes to post data they've collected into SolarNetwork. All
paths are relative to a /solarin
prefix. All dates and times are represented in the Gregorian
calendar system. Unless noted, all requests must provide a valid X.509 client certificate (and thus,
use TLS) -- typically issued as part of the SolarNode+SolarNetwork association process when nodes
are first deployed. This certificate determines what node is managed by the API calls.
Some legacy API endpoints are still available, but should be transitioned to the supported methods outlined here.
Verb | Endpoint | Description |
---|---|---|
POST |
/bulkCollector.do |
Upload JSON encoded datum in bulk. |
GET |
/identity.do |
Verify the identity of SolarNetwork and a SolarNode invitation. |
GET |
/priceLocationLookup.do |
Lookup the location ID of a price location based on search criteria. |
GET |
/weatherLocationLookup.do |
Lookup the location ID of a weather location based on search criteria. |
POST |
/api/v1/sec/cert/renew |
Renew a node's X.509 client certificate. |
GET |
/api/v1/sec/datum/meta/{nodeId}/{sourceId} |
Get metadata for a node datum source. |
POST |
/api/v1/sec/datum/meta/{nodeId}/{sourceId} |
Add metadata to a node datum source. |
GET |
/api/v1/sec/datum/meta/{objectId}/stream/{sourceId} |
Get metadata for a datum stream. |
GET |
/api/v1/sec/location |
Search for locations. |
GET |
/api/v1/sec/location/{locationId} |
Get a location. |
POST |
/api/v1/sec/location/update |
Update a node's own location. |
GET |
/api/v1/sec/location/view |
View a node's own location. |
GET |
/api/v1/sec/nodes/meta |
Get metadata for the node. |
POST |
/api/v1/sec/nodes/meta |
Add metadata for the node. |
This endpoint accepts a simple JSON array payload of JSON objects representing individual datum. Each datum type supports specific attributes representative of that type.
Note this endpoint accepts gzip
compressed body content. Just add a
Content-Encoding: gzip
HTTP header and then compress the JSON with the gzip
compression encoding.
POST | /bulkCollector.do |
---|---|
Content-Type | application/json |
Content-Encoding | Optional; supports gzip . |
An example JSON document is:
[
{"__type__":"PowerDatum", "created":1410064397000, "sourceId":"Solar", "watts":862, "wattHourReading":109298309 },
{"__type__":"ConsumptionDatum", "created":1410064398000, "sourceId":"Main", "watts": 862, "wattHourReading": 109298309 },
{"__type__":"InstructionStatus", "created":1410064399000, "instructionId":34982379, "status":"Completed" },
{"created":1410064399289,"sourceId":"Main","samples":{"i":{"watts":244},"s":{"ploc":2502287},"t":["consumption"]}},
{"created":1410064399289,"sourceId":"Office Temp","samples":{"i":{"temp":22.0},"t":["indoor"]}}
]
Note this example contains a mix of legacy typed node datum objects (the first two with "__type__":"PowerDatum"
and "__type__":"ConsumptionDatum"
and general node datum objects (the last two with the samples
properties). Support for the legacy format is deprecated and will be removed at some point. Note that only the node-specific ConsumptionDatum, PowerDatum, and HardwareControlDatum are considered legacy. Location-specific datum such as DayDatum, PriceDatum, and WeatherDatum are still valid.
For a description of the properties supported by the legacy typed node datum objects, see the Bulk upload XML datum section later on.
The JSON response is in this general form:
{
"success" : true,
"data" : {
"datum" : [ ... ],
"instructions": [ ... ]
}
}
The data.datum
array will contain objects with a minimum of an id
property that represents a server-assigned unique ID for the uploaded datum. There will be one object for every datum object uploaded, and the order will be the same as the order of the posted datum. Depending on the datum type, additional properties may be provided in the response.
The optional data.instructions
array will contain Instruction
objects for the node to execute.
For example, here is a response document after uploading one general datum object, where an instruction is also provided:
{
"success" : true,
"data" : {
"datum" : [ {
"nodeId" : 251,
"created" : "2017-08-08 22:13:50.321Z",
"sourceId" : "InverterA",
"id" : "2cb35d7ea8f9b1ee00c5591750a61e4d0f428f55"
} ],
"instructions" : [ {
"id" : 11537011,
"created" : "2017-08-08 21:59:11.084Z",
"topic" : "SetControlParameter",
"instructionDate" : "2017-08-08 21:59:11.084Z",
"state" : "Queued",
"parameters" : [ {
"name" : "/power/switch/1",
"value" : "1"
} ]
} ]
}
}
The following datum objects are supported by SolarIn.
The general node datum is a generic object that represents some form of data sampled by a node, specific to that node.
created | number | The datum date, represented as the number of milliseconds since the Unix epoch (midnight 1 Jan 1970 UTC). |
---|---|---|
sourceId | string | The node-unique ID of the datum. This represents some logical type associated with the sample, such as a name of the sensor the data was read from. This should be short and easily recognizable, such as "PV", "Mains", "Office", etcetera. The string can be at most 32 characters long. |
samples | object | The sampled data values. See the table below for detailed information on the supported properties. |
The samples
property is a JSON object that contains the following properties, all of which are optional:
Property | JSON type | Description |
---|---|---|
a | Object | Holds accumulating sample data. All values in this object must be JSON numbers. SolarNet will aggregate these values over time by computing their differences. |
i | Object | Holds instantaneous sample data. All values in this object must be JSON numbers. SolarNet will aggregate these values over time by computing their averages. |
s | Object | Holds status or static sample data. The values may be any JSON type. SolarNet will not aggregate these values over time. |
t | Array | Holds an array of tags. The tags must be JSON strings. |
The keys within each of the a
, i
, and s
objects can be any valid JSON
identifier, however there are many standardized keys
you should use when possible.
{
"created": 1410064399289,
"sourceId": "Office Temp",
"samples": {
"i": {
"temp": 22.0
},
"t": [
"indoor"
]
}
}
The general location datum is a generic object that represents some form of data sampled by a node, specific to a SolarNet location.
created | number | The datum date, represented as the number of milliseconds since the Unix epoch (midnight 1 Jan 1970 UTC). |
---|---|---|
locationId | number | The SolarNet-unique ID of the location associated with this datum. |
sourceId | string | The node-unique ID of the datum. This represents some logical type associated with the sample, such as a name of the sensor the data was read from. This should be short and easily recognizable, such as "PV", "Mains", "Office", etcetera. The string can be at most 32 characters long. |
samples | object | The sampled data values. See the general node datum table above for detailed information on the supported properties. |
{
"created" : 1502229600000,
"locationId" : 11536819,
"sourceId" : "NZ MetService",
"samples" : {
"i" : {
"temp" : 13.0,
"humidity" : 95,
"atm" : 100700
},
"s" : {
"sky" : "Windy"
}
}
}
A InstructionStatus
object represents the status of an instruction previously requested by SolarNet. When a node receives an Instruction
object in the response from this endpoint, it is expected to post updates on the status of handling that instruction back to SolarNet. The node does that by posting one of these datum objects.
__type__ | string | Must be the constant InstructionStatus . |
---|---|---|
created | number | The datum date, represented as the number of milliseconds since the Unix epoch (midnight 1 Jan 1970 UTC). |
instructionId | integer | The unique ID of the instruction (as originally provided by SolarNet). |
status | string | The instruction status, one of Received , Executing , Completed , or Declined . |
{
"__type__": "InstructionStatus",
"created": 1410064399000,
"instructionId": 34982379,
"status": "Completed"
}
The following datum objects are legacy types still supported by SolarIn, but that will be removed at some point in the future.
A DayDatum
object represents daily conditions such as sunrise and sunset. The locationId
attribute is required.
__type__ | string | Must be the constant DayDatum . |
---|---|---|
created | number | The datum date, represented as the number of milliseconds since the Unix epoch (midnight 1 Jan 1970 UTC). |
locationId | number | The SolarNet weather location ID to associate this datum with. |
sunrise | number | The time of sunrise, represented as the number of milliseconds since the Unix epoch (midnight 1 Jan 1970 UTC). Note that only the time portion of this date is used. |
sunset | number | The time of sunset, represented as the number of milliseconds since the Unix epoch (midnight 1 Jan 1970 UTC). Note that only the time portion of this date is used. |
{"__type__":"DayDatum", "created":1410004800000, "locationId":4298974, "sunrise":-19380000, "sunset":21720000}
A NodeControlInfo
object represents the status of a device a node is monitoring or controlling, such as a switch. The supported properties of this object are:
__type__ | string | Must be the constant NodeControlInfo . |
---|---|---|
created | number | The datum date, represented as the number of milliseconds since the Unix epoch (midnight 1 Jan 1970 UTC). |
controlId | string | The node-unique ID of the control. By convention these use path-like values, such as /power/switch/1 .
The string can be at most 32 characters long. |
value | string | The value of the control. |
type | string | One of Boolean , Float , Integer , or Percent . |
{"__type__":"NodeControlInfo", "created":1410064399000, "controlId":"/power/switch/1", "value":"true", "type":"Boolean"}
A PriceDatum
object represents a monetary cost. The locationId
attribute is required and represents a specific price location registered with SolarNetwork. The supported attributes are:
price | number | The price, for the associated price location. |
---|
{"__type__":"PriceDatum", "created":1410064399000, "price":12.57}
A WeatherDatum
object represents weather conditions. The locationId
attribute is required.
created | number | The datum date, represented as the number of milliseconds since the Unix epoch (midnight 1 Jan 1970 UTC). |
---|---|---|
temperatureCelsius | number | The air temperature, in Celsius. |
humidity | number | The relative humidity, as an integer percentage (0 - 100). |
barometricPressure | number | The barometric pressure, in millibars. |
barometerDelta | number | The barometric pressure, in millibars. |
skyConditions | string | The sky conditions, using general text. For example clear or rain. |
condition | string | The sky condition for the day, using normalized weather condition values. |
dewPoint | number | The dew point. |
uvIndex | integer | The UV index. |
visibility | number | The visibility, in kilometers. |
{"__type__":"WeatherDatum", "created":1410064399000, "skyConditions":"partly cloudy", "temperatureCelsius":19.2}
This method is used in the SolarNode setup process to associate the node with SolarNetwork via an invitation from SolarNetwork. A client X.509 certificate is not required for this method, and it does not need to be called using TLS when the username and key parameters are omitted. Calling in that form will respond only with basic public details on the SolarNetwork service at the requested host. When the username and key parameters are included, TLS should be used as in this case the user's email and security phrase are included in the response.
GET | /identity.do |
---|---|
username |
When checking an invitation, the SolarNetwork account email from the SolarNode invitation. |
key |
When checking an invitation, the SolarNode invitation key, as generated by SolarNetwork. |
The response will be XML and includes the following properties:
Property | Type | Description |
---|---|---|
host |
string | The DNS name or IP address to use for SolarIn. |
port |
number | The network port to use for SolarIn. |
forceTLS |
boolean | If true then TLS is required, even if the port is not the standard port of 443 . |
identityKey |
string | Some information about the SolarIn service that can be manually verified during the SolarNode association process. |
termsOfService |
string | The terms of service for SolarNetwork. |
networkServiceURLs |
object | A mapping of SolarNetwork service keys to associated URLs. |
networkServiceURLs/entry/@key |
string | A SolarNetwork service key. |
networkServiceURLs/entry/value/@value |
string | A SolarNetwork service URL. |
Here's an example XML response when no username/key are provided:
<BasicNetworkIdentity
host="in.solarnetwork.net"
port="443"
forceTLS="true"
identityKey="Server in.solarnetwork.net ..."
termsOfService="SolarNetwork is ...">
<networkServiceURLs>
<entry key="solaruser">
<value type="String" value="https://data.solarnetwork.net/solaruser" />
</entry>
<entry key="solarquery">
<value type="String" value="https://data.solarnetwork.net/solarquery" />
</entry>
<entry key="solarin-mqtt">
<value type="String" value="mqtts://queue.solarnetwork.net:8883" />
</entry>
</networkServiceURLs>
</BasicNetworkIdentity>
Here's an example XML response is when a valid username/key are provided:
<BasicNetworkIdentity
forceTLS="true"
host="in.solarnetwork.net"
port="11444"
identityKey="..."
termsOfService="..."
confirmationKey="11908udhjlsi3093y7039u3"
securityPhrase="It's hard to see the forest when the trees block the view."
username="foo@localhost">
</BasicNetworkIdentity>
The networkServiceURLs
SolarNetwork service keys can include:
Key | Description |
---|---|
solaruser |
The SolarUser API base URL. |
solarquery |
The SolarQuery API base URL. |
solarin-mqtt |
A SolarIn MQTT URL, if supported. |
This method is used to look up a price location ID based on a search criteria. The price location ID can then be used to associate that location with PriceDatum
posted to SolarIn. A client X.509 certificate is not required for this method, and it does not need to be called using TLS. All query parameters are joined together using a logical and operand.
GET | /priceLocationLookup.do |
---|---|
sourceName | A weather source to filter the results by. |
locationName | The location name to filter the results by. |
An example XML response is:
<?xml version="1.0" encoding="UTF-8"?>
<PriceLocation created="2011-02-21T08:44:15Z" currency="NZD" id="2502287" locationId="2502287"
locationName="HAY2201" name="HAY2201" sourceName="electricityinfo.co.nz"
timeZoneId="Pacific/Auckland" unit="MWh">
<PriceSource created="2011-02-21T08:44:15Z" id="2502285" name="electricityinfo.co.nz"/>
</PriceLocation>
This method is used to look up a weather location ID based on a search criteria. The weather location ID can then be used to associate that location with WeatherDatum
posted to SolarIn. A client X.509 certificate is not required for this method, and it does not need to be called using TLS. All query parameters are joined together using a logical and operand.
GET | /weatherLocationLookup.do |
---|---|
sourceName | A weather source to filter the results by. |
locationName | The location name to filter the results by. |
location.country | An optional 2-character ISO 3166 country code to filter the results by. |
location.region | An optional region name to filter the results by. |
location.stateOrProvince | An optional state/province name to filter the results by. |
location.postalCode | An optional postal code to filter the results by. |
An example XML response is:
<?xml version="1.0" encoding="UTF-8"?>
<result>
<WeatherLocation created="2009-09-14T00:48:03Z" id="301026" sourceData="NZXX0049">
<SolarLocation country="NZ" created="2009-09-14T00:48:03Z" id="301026" latitude="-41.2952" longitude="174.7895" name="Wellington" postalCode="6011" region="Wellington" timeZoneId="Pacific/Auckland"/>
<WeatherSource created="2009-09-14T00:48:03Z" id="301023" name="weather.com"/>
</WeatherLocation>
</result>
This method allows a node's X.509 client certificate to be renewed. This method can be
called either as a normal form post, or as a multipart/form-data
request. The renewal
process is asynchronous, and this method will return before completing the renewal process.
Once the certificate has been renewed, SolarNetwork will issue a
RenewCertificate
instruction for
the node, which will contain the renewed certificate for SolarNode to install.
POST | /api/v1/sec/cert/renew |
---|---|
password |
The PKCS12 certificate keystore password. |
keystore |
A PKCS12 keystore with the nodes active private key and signed certificate. This must be Base64 encoded when using a normal form post, or just the raw data when using a multipart request. |
This endpoint returns the node datum metadata for a specific node and source.
GET | /solarin/api/v1/sec/datum/meta/{nodeId}/{sourceId} |
---|---|
nodeId |
The node ID to get metadata for. |
sourceId |
The source ID to get metadata for. The source ID may alternatively be specified as a query parameter, e.g. datum/meta/123?sourceId=Foo . |
{
"success": true,
"data": {
"results": [
{
"created": "2017-02-27 04:41:17.510Z",
"updated": "2017-02-27 05:01:32.198Z",
"nodeId": 250,
"sourceId": "MockMeterA",
"m": {
"num": 12
},
"pm": {
"room": {
"foo": "bar"
}
},
"t": [
"green",
"yellow"
],
}
],
"returnedResultCount": 1,
"startingOffset": 0,
"totalResults": 1
}
}
This endpoint allows updating existing node datum metadata by adding new values (or replacing existing values). The request body should be a JSON metadata document with values you want to merge into any existing values. If no metadata exists, it will be created.
POST | /solarin/api/v1/sec/datum/meta/{nodeId}/{sourceId} |
---|---|
nodeId |
The node ID to update metadata for. |
sourceId |
The source ID to update metadata for. The source ID may alternatively be specified as a query parameter, e.g. datum/meta/123?sourceId=Foo . |
This endpoint returns the node metadata.
GET | /solarin/api/v1/sec/nodes/meta |
---|
{
"success": true,
"data": {
"created": "2017-02-27 04:41:17.510Z",
"updated": "2017-02-27 05:01:32.198Z",
"nodeId": 250,
"m": {
"num": 12
},
"pm": {
"room": {
"foo": "bar"
}
}
}
}
GET | /solarin/api/v1/sec/datum/meta/{objectId}/stream/{sourceId} |
---|---|
objectId |
The node or location ID to get metadata for. |
sourceId |
The source ID to get metadata for. The source ID may alternatively be specified as a query parameter, e.g. datum/meta/123/stream?sourceId=Foo . |
kind |
An optional query parameter for the datum stream kind, one of Node or Location . If not provided then a Node kind will be looked up first, and if not found a Location kind will be assumed. |
This endpoint returns the datum stream metadata for a specific node/location and source.
{
"success": true,
"data": {
"streamId": "a66e3344-3791-4113-afff-22b44eb3c833",
"objectId": 123,
"sourceId": "meter/a",
"zone": "Pacific/Auckland",
"kind": "n",
"location": {
"country": "NZ",
"region": "Wellington",
"locality": "Wellington",
"zone": "Pacific/Auckland"
},
"i": ["current","voltage","watts"],
"a": ["wattHours"]
}
}
This endpoint allows updating existing node metadata by adding new values (or replacing existing values). The request body should be a JSON metadata document with values you want to merge into any existing values. If no metadata exists, it will be created.
POST | /solarin/api/v1/sec/nodes/meta |
---|
This endpoint allows a node to query for locations so a location ID can be associated with location datum. For example a weather data source would need to provide the location ID associated with the weather data it collects.
GET | /api/v1/sec/location |
---|---|
query |
A general full-text search value. |
locationId |
A specific location ID to filter by. |
sourceId |
A specific source ID to filter by. |
tags |
A tag, or comma-delimited list of tags, to filter by. Multiple tags parameters are also allowed. |
The response contains a list of matching location metadata. See Location view for more details.
This endpoint allows a node to query for a specific location or all locations for a source.
GET | /api/v1/sec/location/{locationId} |
---|---|
sourceId |
A specific source ID to filter by. |
The response contains a list of matching location metadata with the following properties:
Property | Description |
---|---|
locationId |
The unique identifier for the location. |
sourceId |
A source identifier. |
location |
A location object. |
This endpoint allows a node to update its own location details.
POST | /api/v1/sec/location/update |
---|
The request body must be a JSON location object with the location properties to update. Note that only the following properties are supported:
Name | Type | Description |
---|---|---|
latitude |
number | A decimal latitude value. |
longitude |
number | A decimal longitude value. |
elevation |
number | An elevation, in meters. |
An example request body looks like this:
{"latitude":51.178882,"longitude":-1.828409,"elevation":100}
This endpoint allows a node to view its own location details.
GET | /api/v1/sec/location/view |
---|
The response will be a JSON location object with the location properties configured for the node.
An example response looks like this:
{
"success":true,
"data":{"latitude":51.178882,"longitude":-1.828409,"elevation":100}
}
- 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