Axon - lib:his
In this page are presented some useful example about how manage histories with axon functions
- 1 Summary
- 2 Examples/Exercises
- 3 His Computed: Generate Fake histories
- 4 His Imported: Write\Read his to\from csv file
- 5 His Collected
- 5.1 Sampled
- 5.2 Change Of Value
- 5.3 Consumption
- 5.3.1 Tags usually required
- 5.3.2 Tags usually required
- 5.3.3 Tags usually required
- 5.4 Read Raw his data in span:date..date
- 5.5 Read Raw his data in span:dateTime..dateTime
- 5.6 Read his data in span:dateTime..dateTime with rollup
- 5.7 Read his data in span:date..date with rollup and interpolate
- 6 lib:his Functions
Summary
There are different ways to handle histories in FIN:
His Computed: used to indicate that histories are generate with function;
His Imported: used to indicate that histories have been imported, usually from a csv file;
His Collected: used to indicate that histories are collect from curVal;
His Synchronized: used to populate histories from the device that the point originated from. (Example TODO)
There are three differents hisMode:
“sampled” (default)
“cov”
“consumption“
Point Type (examples) | hisMode | kind | hisTotalized | rollup fold (usually) |
|
|---|---|---|---|---|---|
power or temp or … | “sampled” | “Number” |
| max, min, avg |
|
setpoint or … | “cov” | “Number” |
| max, min, avg |
|
run or … | “cov” | “Bool” |
|
|
|
energy or … | “consumption” | “Number” | M | sum, avg, min, max |
|
Examples/Exercises
In the examples below, there are some examples about how configure and use the different history types.
It’s suggested to follow each chapter with the suggested order, since some concepts/results are reused from previous chapters.
His Computed: Generate Fake histories
Create the function you want to use to create your fake histories: Computed Histories
Examples (you can upload them using folio update of trio files):
hisMode:“sampled”
name:powerHisFunc
func
demoData
hisFuncReady
doc:
Generate fake energy histories each day at fixed hours inside
the dates span
It's appliable to a point with kind==\"Number\" and unit:\"kW\"
NOTE: THIS IS JUST AN EXAMPLE. J2 DOESN T ENSURE THAT THIS
FUNC IT'S USABLE IN A REAL ENVIRONMENT
src:
(rec, dates, opts, yield) => do
tz: rec->tz
eachDay(dates) day => do
(0..23).each hour => do
ts:dateTime(day, time(hour.as(1h),0,0), tz)
val:random(0..10).as(1kW)
echo("ts:"+ts+" | val:"+val)
//TryCatch handles the time change usually takes place in March
try yield(ts, val) catch echo("SKIPPED!! --> ts:"+ts+" | val:"+val)
end
end
endhisMode:“cov”
name:occupancyHisFunc
func
demoData
hisFuncReady
doc:
Generate a fake occupancy history (true or false) each day at
fixed hours inside the dates span.
It's appliable to a point with kind==\"Bool\"
NOTE: THIS IS JUST AN EXAMPLE. J2 DOESN T ENSURE THAT THIS
FUNC IT'S USABLE IN A REAL ENVIRONMENT
src:
(rec, dates, opts, yield) => do
tz: rec->tz
eachDay(dates) day => do
yield(dateTime(day, 8:00, tz), true)
yield(dateTime(day, 22:00, tz), false)
end
end
name:setpointHisFunc
func
demoData
hisFuncReady
doc:
Generate fake setpoint histories each day at fixed hours inside
the dates span
It's appliable to a point with kind=="Number" and unit:"°C"
NOTE: THIS IS JUST AN EXAMPLE. J2 DOESN'T ENSURE THAT THIS
FUNC IT'S USABLE IN A REAL ENVIRONMENT
src:
(rec, dates, opts, yield) => do
tz: rec->tz
eachDay(dates) day => do
yield(dateTime(day, 8:00, tz), 20°C)
yield(dateTime(day, 22:00, tz), 16°C)
end
end
hisMode:“consumption”
name:energyHisFunc
func
demoData
hisFuncReady
doc:
Generate fake energy histories each day at fixed hours inside
the dates span
It's appliable to a point with kind==\"Number\" and unit:\"kWh\"
NOTE: THIS IS JUST AN EXAMPLE. J2 DOESN'T ENSURE THAT THIS
FUNC IT'S USABLE IN A REAL ENVIRONMENT
src:
(rec, dates, opts, yield) => do
tz: rec->tz
val: 0kWh
offset:() => random(0..10).as(1kWh)
eachDay(dates) day => do
(0..23).each hour => do
ts:dateTime(day, time(hour.as(1h),0,0), tz)
echo("ts:"+ts+" | val:"+val)
//TryCatch handles the time change usually takes place in March
try yield(ts, val) catch echo("SKIPPED!! --> ts:"+ts+" | val:"+val)
val = val + offset()
end
end
end
Create 4 points:
{navName:"Computed Power", kind=="Number", /* hisMode:“sampled” not required since it's the default */, ... }{navName:"Computed Occupancy", kind=="Bool", hisMode:"cov", ... }{navName:"Computed Setpoint", kind=="Number", hisMode:"cov", ... }{navName:"Computed Energy", kind=="Number", hisMode:"consumption", hisTotalized, ... }
“unit” tag is not required since the history is created by hisFunc. Anyway, it should be better to add the proper one to the points.
For each point enabled history and set to
hisType:"computed"Point Property Sheet | History andhisFunc:"powerHisFunc"hisFunc:"occupancyHisFunc"hisFunc:"setpointHisFunc"hisFunc:"energyHisFunc"
Test the results using in Folio
read(navName=="Computed Power").hisRead(today())read(navName=="Computed Occupancy").hisRead(lastWeek())read(navName=="Computed Setpoint").hisRead(pastMonth())read(navName=="Computed Energy").hisRead(thisYear(), {-limit})
If a point has the hisFunc tag (i.e. it is a computed point) the function itself is completely responsible for generating the desired history output. The his read is essentially delegated to the his func.
It means that reading the histories of the Energy Point returns like the “row” his data, so an increasing value and not a “~collected” one.
His Imported: Write\Read his to\from csv file
It could be useful to write and read points to/from a csv file. Here an example of how to do it. This requires to already have configured points as indicated in Generate Fake histories chapter.
Write: You can use one of these functions (in Folio) to write your CSV file in the folder
..\{{FIN_FolderName}}\var\proj\{{projName}}\io\{{fileName.csv}}read(navName=="Computed Power").hisRead(thisYear(), {-limit}).addColMeta("ts", {dis:"ts"}).addColMeta("v0", {dis:"val"}).ioWriteCsv(`io/hisPower.csv`)read(navName=="Computed Occupancy").hisRead(thisYear(), {-limit}).addColMeta("ts", {dis:"ts"}).addColMeta("v0", {dis:"val"}).ioWriteCsv(`io/hisOccupancy.csv`)read(navName=="Computed Setpoint").hisRead(thisYear(), {-limit}).addColMeta("ts", {dis:"ts"}).addColMeta("v0", {dis:"val"}).ioWriteCsv(`io/hisSetpoint.csv`)read(navName=="Computed Energy").hisRead(thisYear(), {-limit}).addColMeta("ts", {dis:"ts"}).addColMeta("v0", {dis:"val"}).ioWriteCsv(`io/hisEnergy.csv`)
Why .addColMeta("ts", {dis:"ts"}).addColMeta("v0", {dis:"val"}) ?
These funcs are used to change the names of the columns in the target csv file.
By default ioWriteCsv set as col name the dis value of the grid column return by hisRead(..)
Example before addColMeta:
read(navName=="Computed Power").hisRead(today()).col("ts").meta("dis").dis >>> "Timestamp"read(navName=="Computed Power").hisRead(today()).col("ts").meta("dis").dis >>> "New Site Computed Points Computed Power"
Example after addColMeta:
read(navName=="Computed Power").hisRead(today()).addColMeta("ts", {dis:"ts"}).addColMeta("v0", {dis:"val"}).col("ts").meta("dis").dis >>> "ts"read(navName=="Computed Power").hisRead(today()).addColMeta("ts", {dis:"ts"}).addColMeta("v0", {dis:"val"}).col("ts").meta("dis").dis >>> "val"
Create 4 new points
{navName:"From Csv Power", unit:"kW", kind=="Number", /* hisMode:“sampled” not required since it's the default */, ... }{navName:"From Csv Occupancy", kind=="Bool", hisMode:"cov", ... }{navName:"From Csv Setpoint", unit:"°C", kind=="Number", hisMode:"cov", ... }{navName:"From Csv Energy", unit:"kWh", kind=="Number", hisMode:"consumption", hisTotalized, ... }
For each point enable the history as
Import the following function that will be used to read csv
name:writeHisFromCsv func doc: Read the csv file containg histories. The csv must contains 2 columns: "ts": with data stored with format "YYYY-MM-DDThh:mm:ssz", that is the default one you have exporting DateTime values "val": contains the values as Str Inputs: - hisPoint: the point where you want to write histories to - csvUri: the URI of the csv, it should be something like `io/fileName.csv` - parseFunc: is the function used to parse the value stored in csv file as a Str. (parseNumber, parseBool, ..) - format: is the format of the DateTime value in the "ts" column. An example could be:"YYYY-MM-DDThh:mm:ssz" NOTE: THIS IS JUST AN EXAMPLE. J2 DOESN T ENSURE THAT THIS FUNC IT'S USABLE IN A REAL ENVIRONMENT src: (hisPoint, csvUri, parseFunc:parseNumber, format:"YYYY-MM-DDThh:mm:ssz") => do hisPoint= hisPoint.toRec csv:ioReadCsv(csvUri) csv.map(row => do ts:parseDateTime(row->ts, format, hisPoint->tz) val:parseFunc(row->val) return {ts:ts, val:val} end).hisWrite(hisPoint) end
Read: Populate the 4 points his with
read(navName=="Imported Power").writeHisFromCsv(`io/hisPower.csv`)read(navName=="Imported Occupancy").writeHisFromCsv(`io/hisOccupancy.csv`, parseBool)read(navName=="Imported Setpoint").writeHisFromCsv(`io/hisSetpoint.csv`)read(navName=="Imported Energy").writeHisFromCsv(`io/hisEnergy.csv`)
Test the results using in Folio
read(navName=="Imported Power").hisRead(today())read(navName=="Imported Occupancy").hisRead(lastWeek())read(navName=="Imported Setpoint").hisRead(pastMonth())read(navName=="Imported Energy").hisRead(thisYear(), {-limit})
His Collected
Usually these kind of points are sensors that you need to historicize.
There are 3 main types of collecting data like these:
Sampled
Change Of Value [COV]
Consumption
Based on these types, a point have different tags
Sampled
Change Of Value
Consumption
Points Examples:
Temperatures
Power
Instant Flow
Points Examples:
Occupancy
Set Point
On Off
Points Examples:
Energy
Flow-Volume
Tags usually required
hishisMode:"sampled"//Usually it’s not required since it’s the default value
Tags usually required
hishisMode:"cov"
Tags usually required
hishisMode:"consumption"hisTotalized
Read Raw his data in span:date..date
Here we are reading history data with hisRead → opts:{raw}
Span:
2021-10-08
Point: Power
Notes:
Func:
read(navName=="Imported Power").hisRead(2021-10-08, {raw})
ts | val |
|---|---|
2021-10-07T23:00:00+02:00 Berlin | 8kW |
2021-10-08T00:00:00+02:00 Berlin | 10kW |
2021-10-08T01:00:00+02:00 Berlin | 9kW |
2021-10-08T02:00:00+02:00 Berlin | 4kW |
2021-10-08T03:00:00+02:00 Berlin | 3kW |
2021-10-08T04:00:00+02:00 Berlin | 6kW |
2021-10-08T05:00:00+02:00 Berlin | 10kW |
2021-10-08T06:00:00+02:00 Berlin | 4kW |
2021-10-08T07:00:00+02:00 Berlin | 6kW |
2021-10-08T08:00:00+02:00 Berlin | 7kW |
2021-10-08T09:00:00+02:00 Berlin | 7kW |
2021-10-08T10:00:00+02:00 Berlin | 5kW |
2021-10-08T11:00:00+02:00 Berlin | 5kW |
2021-10-08T12:00:00+02:00 Berlin | 1kW |
2021-10-08T13:00:00+02:00 Berlin | 3kW |
2021-10-08T14:00:00+02:00 Berlin | 3kW |
2021-10-08T15:00:00+02:00 Berlin | 7kW |
2021-10-08T16:00:00+02:00 Berlin | 1kW |
2021-10-08T17:00:00+02:00 Berlin | 10kW |
2021-10-08T18:00:00+02:00 Berlin | 7kW |
2021-10-08T19:00:00+02:00 Berlin | 1kW |
2021-10-08T20:00:00+02:00 Berlin | 7kW |
2021-10-08T21:00:00+02:00 Berlin | 10kW |
2021-10-08T22:00:00+02:00 Berlin | 2kW |
2021-10-08T23:00:00+02:00 Berlin | 8kW |
2021-10-09T00:00:00+02:00 Berlin | 9kW |
2021-10-09T01:00:00+02:00 Berlin | 2kW |
Point: Setpoint
Notes:
Func:
read(navName=="Imported Setpoint").hisRead(2021-10-08, {raw})
ts | val |
|---|---|
2021-10-07T22:00:00+02:00 Berlin | 16°C |
2021-10-08T08:00:00+02:00 Berlin | 20°C |
2021-10-08T22:00:00+02:00 Berlin | 16°C |
2021-10-09T08:00:00+02:00 Berlin | 20°C |
2021-10-09T22:00:00+02:00 Berlin | 16°C |
Point: Energy
Notes:
Func:
read(navName=="Imported Energy").hisRead(2021-10-08, {raw})
ts | val |
2021-10-07T23:00:00+02:00 Berlin | 33679kWh |
2021-10-08T00:00:00+02:00 Berlin | 33683kWh |
2021-10-08T01:00:00+02:00 Berlin | 33686kWh |
2021-10-08T02:00:00+02:00 Berlin | 33689kWh |
2021-10-08T03:00:00+02:00 Berlin | 33692kWh |
2021-10-08T04:00:00+02:00 Berlin | 33697kWh |
2021-10-08T05:00:00+02:00 Berlin | 33701kWh |
2021-10-08T06:00:00+02:00 Berlin | 33707kWh |
2021-10-08T07:00:00+02:00 Berlin | 33707kWh |
2021-10-08T08:00:00+02:00 Berlin | 33715kWh |
2021-10-08T09:00:00+02:00 Berlin | 33724kWh |
2021-10-08T10:00:00+02:00 Berlin | 33728kWh |
2021-10-08T11:00:00+02:00 Berlin | 33737kWh |
2021-10-08T12:00:00+02:00 Berlin | 33744kWh |
2021-10-08T13:00:00+02:00 Berlin | 33745kWh |
2021-10-08T14:00:00+02:00 Berlin | 33748kWh |
2021-10-08T15:00:00+02:00 Berlin | 33748kWh |
2021-10-08T16:00:00+02:00 Berlin | 33753kWh |
2021-10-08T17:00:00+02:00 Berlin | 33763kWh |
2021-10-08T18:00:00+02:00 Berlin | 33772kWh |
2021-10-08T19:00:00+02:00 Berlin | 33777kWh |
2021-10-08T20:00:00+02:00 Berlin | 33785kWh |
2021-10-08T21:00:00+02:00 Berlin | 33787kWh |
2021-10-08T22:00:00+02:00 Berlin | 33787kWh |
2021-10-08T23:00:00+02:00 Berlin | 33793kWh |
2021-10-09T00:00:00+02:00 Berlin | 33796kWh |
2021-10-09T01:00:00+02:00 Berlin | 33797kWh |
In the hisRead documentation you can find these notes:
- if start is Date, then we use midnight of that day