Assetwolf supports Phi, a simple language for running calculations and small programs in real-time.
Phi is based on Twig (version 2), more info at https://twig.symfony.com/doc/2.x/ which is a simplified form of PHP.
When data arrives from assets into an Assetwolf portal, your application may require some calculations to be made on that data. So to make this transparent, the calculations are performed in Phi, when the data arrives.
So an asset may have any number of incoming data fields, and any number of calculated fields. The values of the calculated fields are worked out by the Phi script for the asset.
Assets are usually arranged in groups, and those groups in a hierarchy.
For example, you may have a location, that contains floors, that contain rooms, that contain assets. (That example has four levels, but Assetwolf can handle any number of levels). Phi calculations can be put in place at any or all of these levels.
A specific location, floor, or room (in this example) are known as data pools. Data pools are a way of aggregating data from assets, with calculations bubbling up from assets at the "bottom", through levels of data pools, to a single location at the "top" of a hierarchy. The idea is, that Assetwolf can present data that is summarised, or aggregated for a location, or in any amount of detail, for the various data pools and levels below it.
Continuing this example: when all of the assets in a room have communicated once, or any one asset has communicated twice, the Phi script for the room is run, and those calculations are prepared for the level above, i.e. the floor.
Similarly, when all of the rooms on a floor have prepared their calculations (or one room has been calculated twice), the Phi script on the floor runs. And so on, going up the hierarchy, eventually to a location level. A location can also have a Phi script to make high level summaries of that location's activity, such as for management reporting.
Assetwolf supports metrics, which again can be calculated on any asset or data pool level, up to location level.
Metrics are calculated at regular intervals, such as every month, every day, every hour or every 10 minutes. These are typically used for key performance information, billing or other statistics.
Again, metrics are written in Phi.
Assetwolf supports alarms. It's possible to define triggers for alarms (and what procedure is then carried out).
Alarm triggers can be defined simply in the alarm trigger interface (such as some measured value exceeding an allowed range); but when more complex conditions need to be detected, Phi script can be written so as to cause a trigger to fire.
So in this way, complex rules can be written, that not only consider assets' conditions, but also data pools' conditions at any level, such as some mean value being exceeded.
Phi is different from regular Twig because it can access Assetwolf's own pools of data.
When a Phi script runs, for an asset, it can access:
The result is usually to set the values of various calculated fields for the asset, which then are available for the data pools above.
Similarly when a Phi script runs for a data pool, it can access:
Phi can perform scientific calculations on any of the above data (such as sine, cosine, mean, standard deviation, etc.), and simple program logic, such as "for" loops, and "if...else" logic.
You can see the Phi scripting interface when editing a Schema — a description of an asset type, or a data pool type — in an Assetwolf portal.
The Schemas page of an Assetwolf portal specifies:
Phi code is a language with C-style syntax. Variables can be defined like this:
a = 1 b = 'List of Important Bird Areas in Michigan'
String concatenation is done using the ~
operator:
message = greetingOfChoice ~ ' ' ~ recipient
...or the paste()
function (which automatically adds a space):
message = paste(greetingOfChoice, recipient)
You can use single or multi-line comments, e.g.:
#Single line comment (using a hash-sign) //Single line comment (using two forward-slashes) /* Multi-line comment */
You can use standard mathematical operations, e.g.:
a = 1 + 2 print(a) #3 a += 1 print(a) #4 a++ print(a) #5 a = 2 * 3 print(a) #6 a = 8 - 1 print(a) #7 a = 2 ^ 3 print(a) #8 a = 21 % 12 print(a) #9
While writing Phi code, you can use the print()
function to check the contents of variables. (This only has an effect while testing; the data-processor ignores this function.)
if
statements work like this:
shaken = true
stirred = false
speed = 12 if (shaken and not stirred) { beverage = 'cocktail' } else if (speed == 88) { beverage = 'cola' } else { beverage = 'tea' }
You can also use &&
, ||
and !
instead of and
, or
, and not
, e.g.:
if (shaken && !stirred) {
for
loops have three different forms:
#Fixed range for (i in 1:10) { print(i) } #Looping through an array numbers = [2, 3, 5, 7] for (p in numbers) { print(p) } #Looping through an object colors = {red: 0xff0000, green: 0x00ff00, blue: 0x0000ff} for (color, code in colors) { print(color, code) }
You can use continue
and break
in loops, e.g.:
primes = []
for (i in 1..100) {
if (i < 2) {
isPrime = false
} else if (i == 2) {
isPrime = true
} else {
isPrime = true
stop = i - 1
for (j in 2..stop) {
if (i % j == 0) {
isPrime = false
break
}
}
}
if (!isPrime) {
continue
}
primes[] = i
}