-
Notifications
You must be signed in to change notification settings - Fork 2
SolarNet API global objects
This page documents objects used throughout the SolarQuery, SolarIn, and SolarUser APIs.
| Object | Description |
|---|---|
| Datum | The fundamental time-stamped data structure collected by SolarNetwork. |
| Datum samples | The measurement fact data structure collected by SolarNetwork. |
| Datum auxiliary | Special events associated with a time-stamped data stream. |
| Device operating states | Standarized device operating state enumeration. |
| Sky conditions | Standarized atmospheric sky conditions enumeration. |
| Metadata | Common metadata structure associated with users, nodes, and data streams. |
| Metadata filter | Common metadata search filter syntax. |
| Security policy | Rules and constraints for security tokens. |
| Wildcard patterns | Wildcard syntax used in security policies and various queries. |
| Setting specifier | API for UI metadata. |
The datum is the fundamental time-stamped data structure collected by SolarNodes and stored in SolarNetwork. It has a flexible structure with the following core properties:
| Property | Type | Description |
|---|---|---|
nodeId |
number | A unique ID assigned to nodes by SolarNetwork. |
sourceId |
string | A node-unique identifier that defines a single stream of data from a specific source, up to 64 characters long. |
created |
date | A time stamp of when the datum was collected, or the date the datum is associated with. |
samples |
datum samples | The measurements. |
A datum is uniquely identified by the three combined properties (nodeId, sourceId, created).
Source IDs are arbitrary strings used to distinguish different sources of data within a single node.
For example, a node might collect data from an energy meter on source ID Meter and a solar
inverter on Solar. SolarNetwork does not place any restrictions on source ID values, other than a
64-character limit. However, there is are some conventions used within SolarNetwork that are useful
to follow, especially for larger deployment of nodes with many source IDs:
- Use as short as possible IDs, for example
Meter1is better thanSchneider ION6200 Meter - Main Building. - Use a path-like structure to encode a logical hierarchy, in least specific to most specific
order. For example
/S1/B1/M1could imply the first meter in the first building on the first site. - Avoid using wildcard special characters.
The path-like structure becomes useful in places where wildcard patterns are used, like security policies or datum queries. It is generally worthwhile to spend some time planning on a source ID scheme to use when starting a new project with SolarNetwork.
The datum object contains a datum samples structure within it that holds the measurements obtained for a datum. A datum sample is a collection of named properties, for example:
{
"watts": 123,
"wattHours": 987654321,
"mode": "auto"
}Internally, the properties are further organized into three classifications: i
for instantaneous, a for accumulating, and s for status. These
classifications help SolarNetwork understand how to aggregate the datum samples
over time. When SolarNode uploads a datum to SolarNetwork, the sample will
include the classification groups. The previous example would thus more
accurately be represented like this:
{
"i": {
"watts": 123
},
"a": {
"wattHours": 987654321
},
"s": {
"mode": "auto"
}
}Normally you won't have to deal with these classifications, however, as SolarNetwork hides them when returning datum data through the SolarQuery API. You might come across them in some SolarNode plugins that allow configuring dynamic sample properties to collect, when SolarNode can't implicitly know which classification to use. Some APIs do, however, require fully classified sample objects, like those dealing with datum auxiliary objects.
Although SolarNetwork allows for arbitrary property names in the datum samples it collects, there are several standard property names that you should consider using when appropriate.
| Property | Units | Classif. | Description |
|---|---|---|---|
opState |
s |
A standardized device operating state code. | |
opStates |
s |
A bitmask of hardware-specific operating state code values. |
| Property | Units | Classif. | Description |
|---|---|---|---|
apparentPower |
VA | i |
An apparent power reading, in volt-amperes. |
current |
A | i |
An electric current reading, in amperes. |
dcPower |
W | i |
A DC power reading, in watts. |
dcVoltage |
V | i |
A DC electric potential reading, in volts. |
effectivePowerFactor |
VA | i |
An effective power factor reading. |
frequency |
Hz | i |
An AC frequency, in hertz. |
lineVoltage |
V | i |
An AC phase electric potential reading, between two phases, in volts. |
neutralCurrent |
A | i |
A neutral current reading, in amperes. |
phase |
s |
An AC phase value, one of: PhaseA, PhaseB, PhaseC, Total. | |
phaseVoltage |
i |
An AC phase electric potential reading, one phase and neutral, in volts. | |
powerFactor |
i |
A power factor reading. | |
reactivePower |
var | i |
A reactive power reading, in reactive volt-amperes. |
voltage |
V | i |
An electric potential reading, in volts. |
wattHours |
Wh | a |
An energy reading, in watt-hours. For example a "lifetime" accumulating value from a power meter or PV inverter. |
watts |
W | i |
A real or active power reading, in watts. |
| Property | Units | Classif. | Description |
|---|---|---|---|
atm |
Pa | i |
Atmospheric pressure, in pascals |
dew |
C | i |
A dew point, in degrees Celsius. |
humidity |
% | i |
A relative humidity as an integer percentage (0 - 100). |
irradiance |
W/m^2 | i |
Solar irradiance, in watt per meter squared. |
sky |
s |
A textual description of the sky conditions, e.g. "clear", "cloudy". | |
skies |
s |
A bitmask of standardized sky condition codes. | |
temp |
C | i |
A temperature, in degrees Celsius. |
visibility |
m | i |
A visibility distance, in meters. |
The following values represent a standarized set of operating states for devices, typically devices being monitored by nodes:
| Name | Code | Description |
|---|---|---|
Unknown |
0 |
An unknown state. |
Normal |
1 |
Normal operating state. |
Starting |
2 |
A startup/initializing state. |
Standby |
3 |
A standby/low power state. |
Shutdown |
4 |
A shutdown/off state. |
Fault |
5 |
A faulty state. |
Disabled |
6 |
A disabled state. |
Recovery |
7 |
A recovery state. |
Override |
8 |
An overridden state. |
The following values represent a standarized set of sky conditions:
| Name | Code | Description |
|---|---|---|
Clear |
1 |
Clear sky. |
ScatteredClouds |
2 |
Scattered/few clouds. |
Cloudy |
3 |
Mostly cloudy. |
Fog |
4 |
Fog. |
Drizzle |
5 |
Drizzle/light rain. |
ScatteredShowers |
6 |
Very occasional/light rain. |
Showers |
7 |
Occasional/light rain |
Rain |
8 |
Mostly rain. |
Hail |
9 |
Hail. |
ScatteredSnow |
10 |
Occasional/light snow. |
Snow |
11 |
Mostly snow. |
Storm |
12 |
Storm. |
SevereStorm |
13 |
Servere storm. |
Thunder |
14 |
Thunder/lightning storm. |
Windy |
15 |
Windy. |
Hazy |
16 |
Hazy. |
Tornado |
17 |
Tornado. |
Hurricane |
18 |
Hurricane. |
Dusty |
19 |
Dust/sand storm. |
Datum auxiliary records represent special events that occur at a specific point in time for a
specific node and datum source. The record contains a final property that holds the final data
associated with the datum source at the event date, and a start property that holds the starting
data. These records are used by some SolarQuery API methods when calculating differences in a datum
source between two points in time.
| Property | Type | Description |
|---|---|---|
created |
string | The event date, in yyyy-MM-dd HH:mm:ss.SSS'Z' format in the UTC time zone. Note that when posting this value may also be specified as a millisecond epoch number value. |
nodeId |
number | The node ID. |
sourceId |
string | The source ID. |
type |
string | The datum auxiliary type. |
updated |
string | The record last modified date, in yyyy-MM-dd HH:mm:ss.SSS'Z' format in the UTC time zone. |
notes |
string | A comment to include that describes the event record. |
final |
object | A general datum sample representing the final data associated with the datum immediately before the created date. |
start |
object | A general datum sample representing the starting data associated with the datum at the created date. |
meta |
object | An optional metadata object for client application use. |
Note that both the final and start general datum sample objects currently support only the accumulating (a) property set.
Here's an example datum auxiliary object used for a Reset event, where a meter was replaced so that
the energy reading went from 12345789 in the old meter to 123 in the new meter, expressed as JSON:
{
"success": true,
"data": {
"created": "2019-02-06 18:35:50.943Z",
"nodeId": 11,
"sourceId": "Foo",
"type": "Reset",
"updated": "2019-02-06 18:35:51.165Z",
"notes": "Meter replaced.",
"final": {
"a": {
"wattHours": 123456789
}
},
"start": {
"a": {
"wattHours": 123
}
},
"meta": {
"m": {
"foo": "bar"
}
}
}
}It helps to think of datum auxiliary records as part of the stream of data represented by their associated datum source. Imagine a datum stream where a meter is replaced. There will be a gap in time between meter readings while the meter is removed and then replaced, and the readings drop back to nearly zero once readings are captured again from the new meter. This scenario would like this:
| Date | Reading (Wh) | Difference Prev |
|---|---|---|
| 2014-03-01 19:53:17 | 5631504 | 0 |
| 2014-03-01 19:53:18 | 5631518 | 14 |
| 2014-03-01 21:02:30 | 44555 | -5586963 |
| 2014-03-01 19:53:18 | 44567 | 12 |
If we want to know the overall amount of energy reported by this meter, adding the Difference Prev column yields
0 + 14 - 5,586,963 + 12 = -5,586,937 Wh
This is obviously not correct. Let's add a datum auxiliary record for the meter replacement, like this:
| Date | Final Reading (Wh) | Starting Reading (Wh) |
|---|---|---|
| 2014-03-01 20:00:00 | 5632000 | 0 |
Now we can merge that record with the original datum stream, resulting in a "split" stream:
| Date | Reading (Wh) | Difference Prev |
|---|---|---|
| 2014-03-01 19:53:17 | 5631504 | 0 |
| 2014-03-01 19:53:18 | 5631518 | 14 |
| 2014-03-01 20:00:00 | 5632000 | 496 |
| Date | Reading (Wh) | Difference Prev |
|---|---|---|
| 2014-03-01 20:00:00 | 0 | 0 |
| 2014-03-01 21:02:30 | 44555 | 44555 |
| 2014-03-01 19:53:18 | 44567 | 12 |
Adding up the Difference Prev column of both portions of the split stream yields
0 + 14 + 496 + 0 + 44,555 + 12 = 45,077 Wh
That is a much better answer.
In SolarNetwork metadata can be associated with the following items:
- users
- nodes
- node datum sources
- node datum auxiliary
Metadata objects share a common structure across all these items:
| Property | Type | Description |
|---|---|---|
m |
object | An arbitrary object data structure. Traditionally this was meant to be used as a single-level key/value pair style object. |
pm |
object | An arbitrary object of objects data structure. Traditionally this was meant to be used as a true multi-level tree of key/value pairs and values. |
t |
array | An array of strings to be treated as a set of tags. Duplicate values are discarded. |
For each associated object type, typically unique ID, creation date, and modification date
properties are also available. For example a node metadata object includes a nodeId property.
Here's an example metadata object, expressed as JSON:
{
"created" : "2016-11-11 07:57:46.561Z",
"updated" : "2016-11-13 19:31:53.225Z",
"m" : {
"building" : "Warehouse",
"room" : "Office"
},
"pm" : {
"hours": {
"M-F" : "08:00-18:00",
"Sa-Su" : "10:00-14:00"
},
"managers": {
"John" : "[email protected]",
"Jane" : "[email protected]"
}
},
"t" : [
"operations",
"red"
]
}Some API method accept a metadata filter string, which is written much like a LDAP search filter. In its simplest form a filter is composed of a key path, a comparison operator, and a value, enclosed in parentheses, like this:
(t=operations)
Here the key path is t, the comparison operator is =, and the value is operations. The
filter could be described as find metadata with a tag equal to "operations". More complex filters
can be formed by joining two or more of this basic form with a logic operator, like this:
(&(t=operations)(m/room=Office))
Here the logic operator is & which stands for a logical and operation. The filter could be
described as find metadata with a tag equal to "operations" AND a "room" property equal to
"Office".
The supported comparison operators are:
| Operator | Description |
|---|---|
= |
Exact equality match. |
< |
Less than; numerically when applied to number values or lexicographically when applied to strings. |
<= |
Less than or equal to; numerically when applied to number values or lexicographically when applied to strings. |
> |
Greater than; numerically when applied to number values or lexicographically when applied to strings. |
>= |
Greater than or equal to; numerically when applied to number values or lexicographically when applied to strings. |
~= |
Regular expression match; patterns follow the JavaScript regular expression syntax. |
The supported logic operators are:
| Operator | Description |
|---|---|
& |
Logical "and" |
| ` | ` |
! |
Logical negation, or "not" |
The key path of each component in a metadata filter is a URL-like path starting at the root of the
metadata object. Path separators represent descending into nested objects. A leading / is assumed,
and can be omitted if desired. Using the example metadata object above, here are key key paths
available:
| Key path | Value |
|---|---|
/created |
2016-11-11 07:57:46.561Z |
/updated |
2016-11-13 19:31:53.225Z |
/m/building |
Warehouse |
/m/room |
Office |
/pm/hours/M-F |
08:00-18:00 |
/pm/hours/Sa-Su |
10:00-14:00 |
/pm/managers/John |
[email protected] |
/pm/managers/Jane |
[email protected] |
/t |
Array of [operations, red] |
For array property values such as the /t path, all values in the array are considered for
matching.
A special ** path segment may be used in a key path, which represents 0 or more segments of any
name. The last path segment may be specified as * which represents any property name. Here are
some examples of wildcards using the same metadata example:
| Key path | Matching paths |
|---|---|
/m/* |
/m/building, /m/room
|
/pm/hours/* |
/pm/hours/M-F, /pm/hours/Sa-Su
|
/**/John |
/pm/managers/John |
/**/managers/* |
/pm/managers/John, /pm/managers/Jane
|
Security policy objects can be associated with security tokens. In general security policies are permissive by default, and are configured with rules that restrict access. A policy object contains the following items:
| Parameter | Type | Description |
|---|---|---|
nodeIds |
array of numbers | A list of node IDs the policy restricts access to. If not specified, all nodes associated with the token's account are allowed. |
sourceIds |
array of strings | A list of datum source IDs the policy restricts access to. Wildcard patterns are permitted. Access to a datum source implies access to any associated datum source metadata. If not specified, all source IDs associated with the token's account are allowed. |
minAggregation |
string | A minimum datum aggregation type to restrict access to. If not specified, all levels of aggregate data are allowed, including raw data. |
nodeMetadataPaths |
array of strings | A list of node metadata paths to restrict access to. Wildcard patterns are permitted. The metadata structure is treated like a path using object keys as path segment names. If not specified, all node metadata is allowed. |
userMetadataPaths |
array of strings | A list of user metadata paths to restrict access to. Wildcard patterns are permitted. The metadata structure is treated like a path using object keys as path segment names. If not specified, all user metadata is allowed. |
apiPaths |
array of strings | A list of API URL paths to restrict access to. API paths represent SolarNetwork API URL paths, starting after the /pub or /sec path segment. Wildcard patterns are permitted. Access to a particular API is allowed as long as some path pattern matches. A path can start with ! to negate the path so that paths that do not match are allowed. If not specified, all user metadata is allowed. |
Wildcard patterns are used in places like security policies, metadata queries, and datum queries.
The values a wildcard pattern is compared to are treated like URL paths, using / as path
delimiters. The text between the path delimiters are called path segments. The following special
characters can be used in wildcard patterns:
| Special | Description |
|---|---|
? |
Match a single character in a path segment. |
* |
Match zero or more characters in a single path segment. |
** |
Match zero or more path segments. |
Here are some example source ID wildcard patterns and how they would be interpreted, using the following source IDs:
/power/power/meter/power/meter/1/switch/1/switch/2/switch/3/a/switch/3/b/basement/bedroom/lights/basement/bedroom/heater/basement/tvroom/lights/basement/tvroom/heater/ground/dining/lights
| Pattern | Matches |
|---|---|
/power/** |
/power, /power/meter, and /power/meter/1
|
/power/* |
/power/meter |
/**/1 |
/power/meter/1 and /switch/1
|
/**/lights |
/basement/bedroom/lights, /basement/tvroom/lights, and /ground/dining/lights
|
/basement/**/lights |
/basement/bedroom/lights, /basement/tvroom/lights
|
Here are some example metadata wildcard patterns and how they would be interpreted, using the following metadata object:
{
"m" : {
"building" : "Warehouse",
"room" : "Office"
},
"pm" : {
"hours": {
"M-F" : "08:00-18:00",
"Sa-Su" : "10:00-14:00",
"holiday" : {
"M-F" : "09:00-17:00",
"Sa-Su" : "Closed"
}
},
"managers": {
"John" : "[email protected]",
"Jane" : "[email protected]"
},
"building" : {
"floors" : 3,
"employees" : 48
}
}
}| Pattern | Matches |
|---|---|
/m/* |
/m/building, and /m/room
|
/** |
everything |
/pm/hours/* |
/pm/hours/M-F and /pm/hours/Sa-Su
|
/**/building/** |
/m/building, /pm/building/floors, and /pm/building/employees
|
Some SolarNetwork APIs return lists of setting specifier objects, which are metadata objects that describe the configurable properties of a service. When calling an API method that uses such a service, the request can include parameters for the described settings. Applications can also use the settings to render a friendly UI for accessing the service.
For example, imagine an API /upload that requires credentials to upload data somewhere. SolarNetwork
could expose an API like /upload/settings that returns information about what the supported
settings are, like this:
[
{
"type": "net.solarnetwork.settings.TextFieldSettingSpecifier",
"key": "username",
"defaultValue": "",
"secureTextEntry": false
},
{
"type": "net.solarnetwork.settings.TextFieldSettingSpecifier",
"key": "password",
"defaultValue": "",
"secureTextEntry": true
}
]This result informs the caller that username and password parameters are used. Thus invoking the API might look like
/upload?username=foo&password=bar.
| Property | Type | Description |
|---|---|---|
key |
string | The name of the configurable setting. |
type |
string | The type of data entry the setting represents. |
The supported setting types are:
| Type | Description |
|---|---|
net.solarnetwork.settings.TextFieldSettingSpecifier |
A simple string setting. |
net.solarnetwork.settings.ToggleSettingSpecifier |
A boolean on/off setting. |
- SolarNetwork API access
- SolarNetwork API authentication
- SolarNetwork API rate limiting
- 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 Secrets API
- SolarUser SolarFlux API