53. Expressions¶
Many SolarNode components support a general "expressions" framework that can be used to calculate values using a scripting language. SolarNode comes with the Spel scripting language by default, so this guide describes that language.
A common use case for expressions is to derive datum property values out of the raw property values captured from a device. In the SolarNode Setup App a typical datum data source component might present a configurable list of expression settings like this:
In this example, each time the data source captures a datum from the device it is communicating with
it will add a new watts
property by multiplying the captured amps
and volts
property values.
In essence the expression is like this code:
watts = amps × volts
53.1 Datum Expressions¶
Many SolarNode expressions are evaluated in the context of a datum, typically one captured from a device SolarNode is collecting data from. In this context, the expression supports accessing datum properties directly as expression variables, and some helpful functions are provided.
53.1.1 Datum property variables¶
All datum properties with simple names can be referred to directly as variables. Here simple just means a name that is also a legal variable name. The property classifications do not matter in this context: the expression will look for properties in all classifications.
For example, given a datum like this:
{
"i": {
"watts" : 123
},
"a": {
"wattHours" : 987654321
},
"s": {
"mode" : "auto"
}
}
The expression can use the variables watts
, wattHours
, and mode
.
53.1.2 Other variables¶
A datum expression will also provide the following variables:
Property | Type | Description |
---|---|---|
datum |
Datum |
A Datum object, in case you need direct access to the functions provided there. |
locId |
Number |
For location Datum, the location ID of the datum. |
meta |
DatumMetadataOperations |
Get datum metadata for the current source ID. |
parameters |
Map<String,Object> |
Simple map-based access to all parameters passed to the expression. The available parameters depend on the context of the expression evaluation, but often include things like placeholder values or parameters generated by previously evaluated expressions. These values are also available directly as variables, this is rarely needed but can be helpful for accessing dynamically-calculated property names or properties with names that are not legal variable names. |
props |
Map<String,Object> |
Simple map based access to all properties in datum . As datum properties are also available directly as variables, this is rarely needed but can be helpful for accessing dynamically-calculated property names or properties with names that are not legal variable names. |
sourceId |
String |
The source ID of the current datum. |
53.1.3 Functions¶
Some functions are provided to help with datum-related expressions.
53.1.3.1 Bit functions¶
The following functions help with bitwise integer manipulation operations:
Function | Arguments | Result | Description |
---|---|---|---|
and(n1,n2) |
Number , Number |
Number |
Bitwise and, i.e. (n1 & n2) |
andNot(n1,n2) |
Number , Number |
Number |
Bitwise and-not, i.e. (n1 & ~n2) |
narrow(n,s) |
Number , Number |
Number |
Return n as a reduced-size but equivalent number of a minimum power-of-two byte size s |
narrow8(n) |
Number |
Number |
Return n as a reduced-size but equivalent number narrowed to a minimum of 8-bits |
narrow16(n) |
Number |
Number |
Return n as a reduced-size but equivalent number narrowed to a minimum of 16-bits |
narrow32(n) |
Number |
Number |
Return n as a reduced-size but equivalent number narrowed to a minimum of 32-bits |
narrow64(n) |
Number |
Number |
Return n as a reduced-size but equivalent number narrowed to a minimum of 64-bits |
not(n) |
Number |
Number |
Bitwise not, i.e. (~n) |
or(n1,n2) |
Number , Number |
Number |
Bitwise or, i.e. (n1 | n2) |
shiftLeft(n,c) |
Number , Number |
Number |
Bitwise shift left, i.e. (n << c) |
shiftRight(n,c) |
Number , Number |
Number |
Bitwise shift left, i.e. (n >> c) |
testBit(n,i) |
Number , Number |
boolean |
Test if bit i is set in integer n , i.e. ((n & (1 << i)) != 0) |
xor(n1,n2) |
Number , Number |
Number |
Bitwise xor, i.e. (n1 ^ n2) |
Tip
All number arguments will be converted to BigInteger
values for the bitwise operations, and
BigInteger
values are returned.
53.1.3.2 Date time functions¶
The following functions help with creating and manipulating dates. The Temporal
type can be thought of as some kind of date type: it could be a LocalDate
(a date without any time zone), a LocalDateTime
(a date and time without any time zone), a ZonedDateTime
(a date and time in a specific time zone), or an Instant
(a date and time in the UTC
time zone).
53.1.3.2.1 Date creation functions¶
Function | Arguments | Result | Description |
---|---|---|---|
chronoUnit(name) |
String |
TemporalUnit |
Returns a TemporalUnit instance for a case-insensitive chronological unit name, one of NANOS , MICROS , MILLIS , SECONDS , MINUTES , HOURS , HALF_DAYS , DAYS , WEEKS , MONTHS , YEARS , DECADES , CENTURIES , MILLENNIA . |
date(value) |
String |
LocalDate |
Construct a date instance from a string in the form YYYY-MM-DD , for example date('2024-11-21') . |
date(year, month, day) |
int , int , int |
LocalDate |
Construct a date instance for a given year, month (1-12) and day (1-31). |
date(year, month, day, hour, minute) |
int , int , int , int , int |
LocalDateTime |
Construct a date and time instance for a given year, month (1-12), day (1-31), hour (0-23), and minute (0-59). |
date(year, month, day, hour, minute, second) |
int , int , int , int , int , int |
LocalDateTime |
Construct a date and time instance for a given year, month (1-12), day (1-31), hour (0-23), minute (0-59), and second (0-59). |
duration(amount) |
String |
TemporalAmount |
Parse an ISO 8601 style period or duration into a TemporalAmount . The period syntax supports PnYnMnD and PnW , where n is a number of years Y , months M , days D , or weeks W . For example P1Y2M3D represents 1 year and 2 months and 3 days, or P7D 7 days, or P4W 4 weeks. The duration syntax supports PnDTnHnMn.nS where n is a number of days D , hours H , minutes M , or fractional seconds S . For example PT15M represents 15 minutes, PT20.345S 20.345 seconds, -P6H3M -6 hours -3 minutes, P-6H3M -6 hours +3 minutes. |
now() |
LocalDateTime |
Get the local date and time when invoked. | |
now(zone) |
ZoneId|String |
LocalDateTime |
Get the date and time in a given time zone when invoked. The zone can be a ZoneId instance or a valid zone identifier as documented in the tz(zoneId) function below. |
nowTz() |
ZonedDateTime |
Get the absolute date and time when invoked in the node device's time zone. | |
nowTz(zone) |
ZoneId|String |
ZonedDateTime |
Get the absolute date and time when invoked in the zone time zone. The zone can be a ZoneId instance or a valid zone identifier as documented in the tz(zoneId) function below. |
time(value) |
String |
LocalTime |
Construct a time instance from a string in the form HH:mm:ss.SSS . Only the HH:mm portion is required. For example time('13:45') or time('13:45:43') . |
timestamp() |
Instant |
Get the absolute date and time when invoked, in the UTC time zone. |
|
timestamp(value) |
String |
Instant |
Construct an absolute date and time instance from a string in ISO 8601 form like YYYY-MM-DDTHH:mm:ss.SSS+00:00 . Only the YYYY-MM-DD portion is required. For example timestamp('2024-11-21T13:45:43') or timestamp('2024-11-21T13:45:43+13:00') . |
today() |
LocalDate |
Get the local date when invoked in the node device's time zone. | |
today(zone) |
ZoneId|String |
LocalDate |
Get the local date when invoked in the zone time zone. The zone can be a ZoneId instance or a valid zone identifier as documented in the tz(zoneId) function below. |
tz(zoneId) |
String |
ZoneId |
Parse a time zone identifier into a ZoneId instance. Identifiers like Pacific/Auckland and -10:00 are supported. |
53.1.3.2.2 Date manipulation functions¶
Function | Arguments | Result | Description |
---|---|---|---|
datePlus(date, amount, unit) |
Temporal , long , TemporalUnit|String |
Temporal |
Add a chronological unit of time to a date. The unit can be a TemporalUnit instance or a valid name as documented in the chronoUnit(name) function. For example: datePlus(date(2024,8,10), 1, "days") adds 1 day to 2024-08-10 resulting in 2024-08-11 . |
datePlus(date, amount) |
Temporal , TemporalAmount|String |
Temporal |
Add a duration to a date. The amount can be a TemporalAmount instance or a valid string representation as documented in the duration(amount) function. For example: datePlus(date(2024,8,10), "-P1Y") subtracts 1 year from 2024-08-10 resulting in 2023-08-10 . |
dateTruncate(date, unit) |
Temporal , TemporalUnit|String |
Temporal |
Round a date down (older) to a given unit. The unit can be a TemporalUnit instance or a valid name as documented in the chronoUnit(name) function. For example dateTruncate(date(2024,8,10), "months") truncates the date 2024-08-10 to the month, resulting in 2024-08-01 . |
dateTz(date) |
LocalDate|LocalDateTime |
ZonedDateTime |
Turns a local date, or local date and time, into an absolute date and time in the node device's time zone. If a LocalDate is given, the resulting time will be set to midnight of the given date. For example, for a node device in the Pacific/Auckland time zone dateTz(date(2024,8,10)) returns 2024-08-10 00:00 +12:00 . |
dateTz(date, zone) |
LocalDate|LocalDateTime , ZoneId|String |
ZonedDateTime |
Turn a local date, or local date and time, into an absolute date and time in a given time zone. If a LocalDate is given, the resulting time will be set to midnight of the given date . The zone can be a ZoneId instance or a valid zone identifier as documented in the tz(zoneId) function below. For example dateTz(date(2024,8,10), "Pacific/Honolulu") returns 2024-08-10 00:00 -10:00 . |
local(date) |
ZonedDateTime |
LocalDateTime |
Get the local date and time from a zoned date and time. |
localDate(date) |
ZonedDateTime |
LocalDate |
Get the local date from a zoned date and time. |
localTime(date) |
ZonedDateTime |
LocalTime |
Get the local time from a zoned date and time. |
timestamp(date) |
Temporal |
Instant |
Convert a date or date and time into a timestamp in the node device's time zone. |
timestamp(date, zone) |
Temporal , ZoneId|String |
Instant |
Convert a date or date and time into a timestamp in the zone time zone. The zone can be a ZoneId instance or a valid zone identifier as documented in the tz(zoneId) function below. |
53.1.3.2.3 Date range functions¶
Function | Arguments | Result | Description |
---|---|---|---|
durationBetween(date1,date1) |
Temporal , Temporal |
Duration |
Calculate the duration between two dates. |
secondsBetween(date1,date1) |
Temporal , Temporal |
long |
Calculate the number of whole seconds between two dates. |
minutesBetween(date1,date1) |
Temporal , Temporal |
long |
Calculate the number of whole minutes between two dates. |
hoursBetween(date1,date1) |
Temporal , Temporal |
long |
Calculate the number of whole hours between two dates. |
daysBetween(date1,date1) |
Temporal , Temporal |
long |
Calculate the number of whole days between two dates. |
monthsBetween(date1,date1) |
Temporal , Temporal |
double |
Calculate the number of fractional months between two dates. |
yearsBetween(date1,date1) |
Temporal , Temporal |
double |
Calculate the number of fractional years between two dates. |
53.1.3.3 Datum stream functions¶
The following functions deal with datum streams. The latest()
and offset()
functions give you
access to recently-captured datum from any SolarNode source, so you can refer to any datum stream
being generated in SolarNode. They return another datum expression root object, which means you have
access to all the variables and functions documented on this page with them as well.
SolarNode only maintains a limited history for each source, so do not rely on more than a few datum to be available via these method. This history is also cleared when SolarNode restarts.
Tip
These functions operate on datum after any configured datum filters have been applied. See the Unfiltered datum stream functions section for a set of similar functions that operate on datum before any filters are applied.
Function | Arguments | Result | Description |
---|---|---|---|
hasLatest(source) |
String |
boolean |
Returns true if a datum with source ID source is available via the latest(source) function. |
hasLatestMatching(pattern) |
String |
Collection<DatumExpressionRoot> |
Returns true if latestMatching(pattern) returns a non-empty collection. |
hasLatestOtherMatching(pattern) |
String |
Collection<DatumExpressionRoot> |
Returns true if latestOthersMatching(pattern) returns a non-empty collection. |
hasOffset(offset) |
int |
boolean |
Returns true if a datum is available via the offset(offset) function. |
hasOffset(source, offset) |
String , int |
boolean |
Returns true if a datum with source ID source is available via the offset(source,int) function. |
latest(source) |
String |
DatumExpressionRoot |
Provides access to the latest available datum matching the given source ID, or null if not available. This is a shortcut for calling offset(source,0) . |
latestMatching(pattern) |
String |
Collection<DatumExpressionRoot> |
Return a collection of the latest available datum matching a given source ID wildcard pattern. |
latestOthersMatching(pattern) |
String |
Collection<DatumExpressionRoot> |
Return a collection of the latest available datum matching a given source ID wildcard pattern, excluding the current datum if its source ID happens to match the pattern. |
offset(offset) |
int |
DatumExpressionRoot |
Provides access to a datum from the same stream as the current datum, offset by offset in time, or null if not available. Offset 1 means the datum just before this datum, and so on. |
offset(source, offset) |
String , int |
DatumExpressionRoot |
Provides access to an offset from the latest available datum matching the given source ID, or null if not available. Offset 0 represents the "latest" datum, 1 the one before that, and so on. |
selfAndLatestMatching(pattern) |
String |
Collection<DatumExpressionRoot> |
Return a collection of the latest available datum matching a given source ID wildcard pattern, including the current datum. The current datum will always be the first datum returned. |
slice(source, offset, count) |
String , int , int |
Collection<DatumExpressionRoot> |
Return a subset of the source datum stream history starting from offset from the latest available datum and including at most count values going backwards in time. The current datum will always be the first datum returned. |
53.1.3.4 Unfiltered datum stream functions¶
The following functions are similar to the datum stream functions except they deal with unfiltered datum streams, that is the raw datum captured by SolarNode sources before any filters have been applied.
Tip
One example where using the unfiltered datum stream functions is useful is when you have an
expression that accesses a property from a datum stream that has a
Downsample filter applied to it. The unfilteredLatest('meter/1')?.watts
expression would return the most recently captured watts
value while
latest('meter/1')?.watts
would return the most recently downsampled watts
value.
Function | Arguments | Result | Description |
---|---|---|---|
hasUnfilteredLatest(source) |
String |
boolean |
Returns true if a datum with source ID source is available via the unfilteredLatest(source) function. |
hasUnfilteredLatestMatching(pattern) |
String |
Collection<DatumExpressionRoot> |
Returns true if unfilteredLatestMatching(pattern) returns a non-empty collection. |
hasUnfilteredLatestOtherMatching(pattern) |
String |
Collection<DatumExpressionRoot> |
Returns true if unfilteredLatestOthersMatching(pattern) returns a non-empty collection. |
hasUnfilteredOffset(offset) |
int |
boolean |
Returns true if a datum is available via the offset(offset) function. |
hasUnfilteredOffset(source, offset) |
String , int |
boolean |
Returns true if a datum with source ID source is available via the unfilteredOffset(source,int) function. |
unfilteredLatest(source) |
String |
DatumExpressionRoot |
Provides access to the latest available datum matching the given source ID, or null if not available. This is a shortcut for calling unfilteredOffset(source,0) . |
unfilteredLatestMatching(pattern) |
String |
Collection<DatumExpressionRoot> |
Return a collection of the latest available datum matching a given source ID wildcard pattern. |
unfilteredLatestOthersMatching(pattern) |
String |
Collection<DatumExpressionRoot> |
Return a collection of the latest available datum matching a given source ID wildcard pattern, excluding the current datum if its source ID happens to match the pattern. |
unfilteredOffset(offset) |
int |
DatumExpressionRoot |
Provides access to a datum from the same stream as the current datum, offset by offset in time, or null if not available. Offset 1 means the datum just before this datum, and so on. |
unfilteredOffset(source, offset) |
String , int |
DatumExpressionRoot |
Provides access to an offset from the latest available datum matching the given source ID, or null if not available. Offset 0 represents the "latest" datum, 1 the one before that, and so on. |
selfAndUnfilteredLatestMatching(pattern) |
String |
Collection<DatumExpressionRoot> |
Return a collection of the latest available datum matching a given source ID wildcard pattern, including the current datum. The current datum will always be the first datum returned. |
unfilteredSlice(source, offset, count) |
String , int , int |
Collection<DatumExpressionRoot> |
Return a subset of the source datum stream history starting from offset from the latest available datum and including at most count values going backwards in time. The current datum will always be the first datum returned. |
53.1.3.5 Datum stream metadata functions¶
The following functions deal with datum stream metadata.
Function | Arguments | Result | Description |
---|---|---|---|
hasMeta() |
boolean |
Returns true if metadata for the current source ID is available. |
|
hasMeta(source) |
String |
boolean |
Returns true if meta(source) would return a non-null value. |
locMeta(locId, source) |
long , String |
DatumMetadataOperations |
Get datum metadata for a specific location datum stream. |
meta(source) |
String |
DatumMetadataOperations |
Get datum metadata for a specific source ID. |
metaMatching(pattern) |
String |
Collection<DatumMetadataOperations> |
Find datum metadata for sources matching a given source ID wildcard pattern. |
53.1.3.6 Math functions¶
Expressions support basic math operators like +
for addition and *
for
multiplication. The following functions help with other math operations:
Function | Arguments | Result | Description |
---|---|---|---|
avg(collection) |
Collection<Number> |
Number |
Calculate the average (mean) of a collection of numbers. Useful when combined with the group(pattern) function. |
cbrt(n) |
Number |
Number |
Calculate the cube root of a number. |
ceil(n) |
Number |
Number |
Round a number larger, to the nearest integer. |
ceil(n,significance) |
Number , Number |
Number |
Round a number larger, to the nearest integer multiple of significance . |
down(n) |
Number |
Number |
Round numbers towards zero, to the nearest integer. |
down(n,significance) |
Number , Number |
Number |
Round numbers towards zero, to the nearest integer multiple of significance . |
exp(n) |
Number |
Number |
Returns Euler's number e raised to the power of n . |
floor(n) |
Number |
Number |
Round a number smaller, to the nearest integer. |
floor(n,significance) |
Number , Number |
Number |
Round a number smaller, to the nearest integer multiple of significance . |
fracPart(n,digits) |
Number , Number |
Number |
Extract the fractional portion of a decimal number. The optional digits value will round the result to at most this many digits. For example fracPart(123.4567) would return 4567 . |
interp(x, x1, x2, y1, y2) |
Number , Number , Number , Number , Number |
Number |
Linearly interpolate x over the range x1 to x2 , mapped to output range from y1 to y2 . |
interp(x, x1, x2, y1, y2, scale) |
Number , Number , Number , Number , Number , Number |
Number |
Linearly interpolate x over the range x1 to x2 , mapped to output range from y1 to y2 rounding to at most scale decimal places. |
max(collection) |
Collection<Number> |
Number |
Return the largest value from a set of numbers. |
max(n1,n2) |
Number , Number |
Number |
Return the larger of two numbers. |
min(collection) |
Collection<Number> |
Number |
Return the smallest value from a set of numbers. |
min(n1,n2) |
Number , Number |
Number |
Return the smaler of two numbers. |
mround(n,significance) |
Number , Number |
Number |
Round a number to the nearest integer multiple of significance . |
pow(n,p) |
Number , Number |
Number |
Raise a number n to the power p . |
rms(collection) |
Collection<Number> |
Number |
Calculate the root-mean-square of a collection of numbers. |
round(n) |
Number |
Number |
Round a number to the nearest integer. |
round(n,digits) |
Number , Number |
Number |
Round a number to the nearest number with digits decimal digits. |
roundDown(n,digits) |
Number , Number |
Number |
Round a number towards zero to the nearest number with digits decimal digits. |
roundUp(n,digits) |
Number , Number |
Number |
Round a number away from zero to the nearest number with digits decimal digits. |
scaled(n,places) |
Number , Number |
Number |
Shift the decimal point of a number by places digits. Shifts left if n is negative, otherwise right. |
sqrt(n) |
Number |
Number |
Calculate the square root of a number. |
sum(collection) |
Collection<Number> |
Number |
Calculate the sum of a collection of numbers. Useful when combined with the group(pattern) function. |
up(n) |
Number |
Number |
Round numbers away from zero, to the nearest integer. |
up(n,significance) |
Number , Number |
Number |
Round numbers away from zero, to the nearest integer multiple of significance . |
wholePart(n) |
Number |
Number |
Extract the whole portion of a decimal number. For example wholePart(123.4567) would return 123 . |
53.1.3.7 Node metadata functions¶
All the Datum Metadata functions like metadataAtPath(path)
can be invoked
directly, operating on the node's own metadata instead of a datum stream's metadata.
53.1.3.8 Operational functions¶
The following functions deal with general SolarNode operations:
Function | Arguments | Result | Description |
---|---|---|---|
isOpMode(mode) |
String |
boolean |
Returns true if the mode operational mode is active. |
53.1.3.9 Property functions¶
The following functions help with expression properties (variables):
Function | Arguments | Result | Description |
---|---|---|---|
has(name) |
String |
boolean |
Returns true if a property named name is defined. Can be used to prevent expression errors on datum property variables that are missing. |
group(pattern) |
String |
Collection<Number> |
Creates a collection out of numbered properties whose name matches the given regular expression pattern . |
sort(collection,reverse,name...) |
Collection<?> , Boolean , String[] |
Collection<?> |
Sort a collection, optionally in reverse, by optional properties, returning the sorted collection. The second and third arguments are optional. If no name values are provided, the elements of the collection must be comparable (for example strings or numbers) and will be sorted in their natural order. If one or more name values are provided, each name property will be extracted from the collection elements and compared with each other to determine the order. The extracted property values must be comparable. |
53.1.3.10 Tariff schedule functions¶
The following functions help work with tariff schedules, which represent a set of time-based criteria with associated tariffs. A tariff in this scheme is nothing more than a set of one or more number values, each with an associated name.
Here is an example schedule with 4 tariffs each with a single price rate. The *
stands for any value:
Tariff | Month | Day | Weekday | Time | price |
---|---|---|---|---|---|
1 | Jan-Dec | * | Mon-Fri | 0-8 | 10.48 |
2 | Jan-Dec | * | Mon-Fri | 8-24 | 11.00 |
3 | Jan-Dec | * | Sat-Sun | 0-8 | 9.19 |
4 | Jan-Dec | * | Sat-Sun | 8-24 | 11.21 |
Assuming the above schedule were available with the identifier my-schedule
, here is an example expression that finds the price
rate at the time the expression is evaluated:
tariffSchedule('my-schedule')
.resolveTariff(now(), null)
.rates['price']
.amount
If the evuation time was 2024-08-10 13:00
then the expression would return 11.21
because that date matches tariff #4.
You can use the date time functions to find tariffs that match arbitrary dates, such as a date 1 month in the future:
tariffSchedule('my-schedule')
.resolveTariff(datePlus(now(), 1, 'months'), null)
.rates['price']
.amount
Here are the available tariff schedule expression functions:
Function | Arguments | Result | Description |
---|---|---|---|
tariffSchedule(id) |
String |
TariffSchedule |
Get the TariffSchedule associated with the id identifier value. |
tariffScheduleGroup(groupId) |
String |
Collection<TariffSchedule> |
Get a collection of TariffSchedule objects associated with a groupId group identifier value. |
53.1.3.10.1 TariffSchedule
object functions¶
The TariffSchedule
object provides the following functions:
Function | Arguments | Result | Description |
---|---|---|---|
resolveTariff(dateTime, parameters) |
LocalDateTime , Map<String,?> |
Tariff |
Resolve a Tariff for the given date and time, with an optional set of parameters (usually passing null is sufficient). |
rules() |
Collection<Tariff> |
Get the complete colleciton of tariffs defined in the tariff schedule. |
53.1.3.10.2 Tariff
object properties¶
The Tariff
object provides the following properties:
Property | Type | Description |
---|---|---|
rates |
Map<String,Rate> |
A mapping of tariff rate names to associated rate values. |
53.1.3.10.3 Rate
object properties¶
The Rate
object provides the following properties:
Property | Type | Description |
---|---|---|
amount |
Number |
Get the value of the rate. |
description |
String |
An optional description for the rate. |
id |
String |
A unique identifier for the rate within the tariff. |
53.2 Expression examples¶
Let's assume a captured datum like this, expressed as JSON:
{
"i" : {
"amps" : 4.2,
"volts" : 240.0
},
"a" : {
"reading" : 38009138
},
"s" : {
"state" : "Ok"
}
}
Then here are some example Spel expressions and the results they would produce:
Expression | Result | Comment |
---|---|---|
state |
Ok |
Returns the state status property directly, which is Ok . |
datum.s['state'] |
Ok |
Returns the state status property explicitly. |
props['state'] |
Ok |
Same result as datum.s['state'] but using the short-cut props accessor. |
amps * volts |
1008.0 |
Returns the result of multiplying the amps and volts properties together: 4.2 × 240.0 = 1008.0 . |
53.2.1 Datum stream history¶
Building on the previous example datum, let's assume an earlier datum for the same source ID had been collected with these properties (the classifications have been omitted for brevity):
{
"amps" : 3.1,
"volts" : 241.0,
"reading" : 38009130,
"state" : "Ok"
}
Then here are some example expressions and the results they would produce given the original datum example:
Expression | Result | Comment |
---|---|---|
hasOffset(1) |
true |
Returns true because of the earlier datum that is available. |
hasOffset(2) |
false |
Returns false because only one earlier datum is available. |
amps - offset(1).amps |
1.1 |
Computes the difference between the current and previous amps properties, which is 4.2 - 3.1 = 1.1 . |
53.2.2 Other datum stream history¶
Other datum stream histories collected by SolarNode can also be accessed via the
offset(source,offset)
function. Let's assume SolarNode is collecting a datum stream for the source
ID solar
, and had amassed the following history, in newest-to-oldest order:
[
{"amps" : 6.0, "volts" : 240.0 },
{"amps" : 5.9, "volts" : 239.9 }
]
Then here are some example expressions and the results they would produce given the original datum example:
Expression | Result | Comment |
---|---|---|
hasLatest('solar') |
true |
Returns true because of a datum for source solar is available. |
hasOffset('solar',2) |
false |
Returns false because only one earlier datum from the latest with source solar is available. |
(amps * volts) - (latest('solar').amps * latest('solar').volts) |
432.0 |
Computes the difference in energy between the latest solar datum and the current datum, which is (6.0 × 240.0) - (4.2 × 240.0) = 432.0 . |
If we add another datum stream for the source ID solar1
like this:
[
{"amps" : 1.0, "volts" : 240.0 }
]
If we also add another datum stream for the source ID solar2
like this:
[
{"amps" : 3.0, "volts" : 240.0 }
]
Then here are some example expressions and the results they would produce given the previous datum examples:
Expression | Result | Comment |
---|---|---|
sum(latestMatching('solar*').?[amps>1].![amps * volts]) |
2160 |
Returns the sum power of the latest solar and solar2 datum. The solar1 power is omitted because its amps property is not greater than 1 , so we end up with (6 * 240) + (3 * 240) = 2160 . |
53.3 Datum metadata¶
Some functions return DatumMetadataOperations
objects. These objects
provide metadata for things like a specific source ID on SolarNode.
53.3.1 Datum metadata properties¶
The properties available on datum metadata objects are:
Property | Type | Description |
---|---|---|
empty |
boolean |
Is true if the metadata does not contain any values. |
info |
Map<String,Object> |
Simple map based access to the general metadata (e.g. the keys of the m metadata map). |
infoKeys |
Set<String> |
The set of general metadata keys available (e.g. the keys of the m metadata map). |
propertyInfoKeys |
Set<String> |
The set of property metadata keys available (e.g. the keys of the pm metadata map). |
tags |
Set<String> |
A set of tags associated with the metadata. |
53.3.2 Datum metadata general info functions¶
The following functions available on datum metadata objects support access to the general
metadata (e.g. the m
metadata map):
Function | Arguments | Result | Description |
---|---|---|---|
getInfo(key) |
String |
Object |
Get the general metadata value for a specific key. |
getInfoNumber(key) |
String |
Number |
Get a general metadata value for a specific key as a Number . Other more specific number value functions are also available such as getInfoInteger(key) or getInfoBigDecimal(key) . |
getInfoString(key) |
String |
String |
Get a general metadata value for a specific key as a String . |
hasInfo(key) |
String |
boolean |
Returns true if a non-null general metadata value exists for the given key. |
53.3.3 Datum metadata property info functions¶
The following functions available on datum metadata objects support access to the property
metadata (e.g. the pm
metadata map):
Function | Arguments | Result | Description |
---|---|---|---|
getPropertyInfo(prop) |
String |
Map<String,Object> |
Get the property metadata for a specific property. |
getInfoNumber(prop,key) |
String , String |
Number |
Get a property metadata value for a specific property and key as a Number . Other more specific number value functions are also available such as getInfoInteger(prop,key) or getInfoBigDecimal(prop,key) . |
getInfoString(prop,key) |
String , String |
String |
Get a property metadata value for a specific property and key as a String . |
hasInfo(prop,key) |
String , String |
String |
Returns true if a non-null property metadata value exists for the given property and key. |
53.3.4 Datum metadata global functions¶
The following functions available on datum metadata objects support access to both general and property metadata:
Function | Arguments | Result | Description |
---|---|---|---|
differsFrom(metadata) |
DatumMetadataOperations |
boolean |
Returns true if the given metadata has any different values than the receiver. |
hasTag(tag) |
String |
boolean |
Returns true if the given tag is available. |
metadataAtPath(path) |
String |
Object |
Get the metadata value at a metadata key path. |
hasMetadataAtPath(path) |
String |
boolean |
Returns true if metadataAtPath(path) would return a non-null value. |