外观
lib-his 库参考
原文: https://finproducts.atlassian.net/wiki/spaces/JIDD3/pages/34793423262/FIN+5.3.1+lib-his 中文整理基于 FIN 5.3.1
导读: 历史学家核心功能
以下为 API 参考,保留英文以便对照源码;目录已列出(英文标题便于检索);概述已尽量中译。
目录(导读)
- lib
- meta
- docs
- tags
- apps
- funcs
- views
- def
- supertypes
- Overview
- Sizing
- Precision
- Configuration
- Writing
- Queries
- Read Grid
- Query TimeZone
- Appending N/A
- His Grid Shape
- His Period Shape
- Computed Histories
- hisFuncWritable
- Totalized
- Totalized Rollovers
- Computed Totalized Points
- Consumption Data
- OnWrite
- Forecast
- covAvg(val, ts, acc)
- discreteBoolPeriods(val, ts, acc)
- discreteEnumPeriods(val, ts, acc)
- discretePeriods(val, ts, acc)
- durTrue(val, ts, acc)
- hisClear(hisArg, span)
- hisClip(src)
- hisInterpolate(src)
- hisJoin(grids, opts: {})
- hisRead(hisRefs, dates, opts: {})
- hisRemove(hisRec, spans)
- hisRewrite(hisArg, fn)
- hisRollup(src, fold, interval)
- hisRollupAuto(src, interval: null, foldFinder: null)
- hisRollups(src, folds, interval)
- hisSync(timeout: null)
- hisWrite(data, hisRec, opts: null)
- parseDiscreteBoolPeriods(val)
- parseDiscreteEnumPeriods(val, rec: null)
- parseDiscretePeriods(val)
- enum
- src
概述(中译)
历史学家核心功能
API 正文(英文)
docs
Overview • Sizing • Precision • Configuration • Writing • Queries • His Grid Shape • His Period Shape • Computed Histories • Totalized • Consumption Data • OnWrite • Forecast
tags
| hisAppendNA | Specifies the amount of time after a history point's hisEnd that the hisRead() function should append an NA |
| hisEnd | Timestamp of newest item in history |
| hisFunc | Axon expression used to create a computed history |
| hisFuncWritable | Allow writing raw data to a point that has the hisFunc tag |
| hisInterpolateMode | Explicitly configures the interpolation mode to use for this point |
| hisInterval | The interval at which sampled or consumption data is collected |
| hisOnWrite | Axon expression to trap and map history data before writing to the historian database |
| hisRollupAutoMinInterval | Forces hisRollupAuto() to do a rollup using this interval when none is specified and the range of the source history grid is less than 2 days |
| hisRollupFunc | Function name to use for hisRollupAuto() |
| hisRollupInterval | Indicates the roll-up interval in his grid column meta-data |
| hisSize | Approximate number of timestamp/value pairs stored in history |
| hisStart | Timestamp of oldest item in history |
| hisTotalizedRollover | Defines the rollover value for a totalized history - see totalized |
| hisTsPrecision | Controls the precision used to store timetamps in the historian |
| periods | Timeline of on/off periods encoded as Base64 via discretePeriods() |
apps
| his | Views used to visualize and analyze historical point data |
funcs
| covAvg | Folding function for generating a time weighted average on change-of-value histories (where hisInterpolate() is "cov") |
| discreteBoolPeriods | Fold timestamp/bool value pairs into an encoded Str of discrete minutely intervals |
| discreteEnumPeriods | Fold timestamp/enum Str value pairs into an encoded Str of discrete minutely intervals |
| discretePeriods | Fold timestamp/bool value pairs into an encoded Str of discrete minutely intervals |
| durTrue | Fold function for folding timestamp/bool value pairs into durations when true (runtime) |
| hisClear | Clear the history items in the given range |
| hisClip | Remove the rows with leading/trailing timestamps from the actual query range |
| hisInterpolate | Interpolate all the null value cells for each timestamp |
| hisJoin | Given a list of history grids, join them by the ts timestamp column |
| hisRead | Query history for an arbitrary range |
| hisRemove | Remove items from a history using a timestamp or timestamp range |
| hisRewrite | Rewrite every item of a history using the given transformation function |
| hisRollup | Roll up a history grid over discrete intervals of time with the given fold function |
| hisRollupAuto | Automatically chooses the best rollup interval and the best rollup fold function for each history |
| hisRollups | Perform a series of rollups over discrete intervals |
| hisSync | Block until any pending history writes/clears are completed |
| hisWrite | Asynchronously write the specified timestamp/value pairs to the history |
| parseDiscreteBoolPeriods | Parse a Base64 encoded timeline of discrete Bool periods as encoded by discreteBoolPeriods() |
| parseDiscreteEnumPeriods | Parse a base64 encoded string timeline of discrete enum periods as encoded by discreteEnumPeriods() |
| parseDiscretePeriods | Parse a base64 encoded string timeline of discrete periods as encoded by discretePeriods() |
views
| hisChart | Visualize historical point data as a graphical chart |
| hisCompare | Visualize historical point data from two different spans |
| hisCorrelate | Chart a linear correlation of historical point data |
| hisEquip | Visualize historical point data of a single equipment |
| hisImport | Import point history data into the local project database |
| hisTable | Visualize historical point data as a table |
def
app:his
Views used to visualize and analyze historical point data
meta
| def | app:his |
| disKey | ui::historian |
| icon | his |
| is | app |
| lib | lib:his |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| app | UI application grouping of views |
lib his
Overview
The history extension implements the SkySpark historian or time-series database which is is optimized to store and query large volumes of timestamp/value pairs which are typically associated with sensor data. The history extension is built with the following basic design:
- Points which are historized are tagged with
histo indicate that historical data is available - Timestamp/value pairs for the point are stored to Folio using a highly compressed binary format optimized for time-series data
- The history extension provides a rich Axon library to query and analyze the historical data
The following value types of histories are supported:
- Bool
- Number (encoded as int or float)
- Str
- Coord
Also see hisKit which provides a rich library to perform analytics on time series data stored in the historian.
Sizing
Historical data tends to consume the bulk of the disk space in a typical application. Due to the compression algorithms used there is no exact formula for calculating disk space. Analysis of projects has shown an average about 1.5 bytes per timestamp sample which equates to about 51KB per year per point for 15min interval data.
Precision
By default the SkySpark historian stores timestamps with one second precision. If you have timestamps measured in milliseconds (or smaller) they will be floored to the nearest second during storage. You can turn on millisecond precision for timestamps by adding the hisTsPrecision tag.
Analog data is currently stored using a 32-bit floating point number. If your original data was 64-bit floating point, accuracy may be lost.
If your application requires higher precision, please let us know.
Configuration
History records use the following tags:
his: marker tagtz: timezone of the timestamps as a city name from the Olson timezone database (seeTimeZone)kind: indicates expected scalar value type; must be "Number", "Bool", or "Str"unit: numeric histories must define a unit tag with the unit identifier; this unit is assigned to all numbers read from the history and checked during history writes
Writing
The historian is designed to batch write histories to the disk. To achieve the best performance the history data should be sorted and written in "append-only mode" (always writing data with newer timestamps).
If the historian detects out-of-order data it will automatically re-sort the data to ensure items are always ordered by timestamp. However this can be expensive because it requires decompressing the history data for that chunk into memory to re-sort it. So always try to work in append-only mode. If an out-of-order write is performed, a warning with the message "[his] Out of order" is logged. You can suppress this warning by passing in {noWarn} for the options.
The historian will also attempt to detect duplicate items. If an item with the same timestamp is detected, then the old one is discarded and replaced by the new item. Note that this feature has the same performance implications as out-of-order data. Note that timestamps are floored to the closest second or millisecond based on the precision before checking for duplicate timestamps.
You can write history data using the hisWrite() Axon function or with the HTTP API. Here is a simple example which writes some CSV data into a history:
// import history data from CSV file where timestamps
// are formatted as 2010-10-02T13:00
ioReadCsv(`io/his.csv`)
.map(row => {ts: parseDateTime(row->ts, "YYYY-MM-DD'T'hh:mm", "New_York"),
val: parseNumber(row->val)})
.hisWrite(hisId)You must have the tz and kind tags properly configured on your history record before you write any items. If a conflict is detected then the system will raise an exception on write. If you happen to write a series of items incorrectly (such as using wrong timezone), you can rewrite the history using the hisRewrite() function.
Queries
All history queries begin with the hisRead() function. This function takes a set of recs with the his tag, a date range, and a set of options. The function returns the historical data as a grid joined by timestamp.
The input piped to the hisRead function is quite flexible:
readAll(zoneTemp).hisRead(null) // grid of history recs
read(zoneTemp).hisRead(null) // single history rec
hisRead(@13cb8334-b4721633, null) // Ref
hisRead([@13cb8334-b4721633], null) // list of RefsIf a list or grid of records is passed to hisRead, only the records which implement the his marker tag are used (the others are silently ignored).
The date/time range used with hisRead is likewise very flexible:
hisRead(src, null) // all the records found
hisRead(src, 2010) // entire year of 2010
hisRead(src, 2010-03) // entire month of March 2010
hisRead(src, 2010-03-05) // entire day of March 5th, 2010
hisRead(src, 2010-01-01..2010-03-01) // date range Jan 1st to Mar 31st
hisRead(src, today) // any of the core time funcs can be usedYou may use an optional third parameter to pass in additional options to the query such as a limit on the number of rows returned.
Read Grid
When a read is performed, the result is returned as a grid joined by timestamp. The timestamp column is named ts, and each record passed into hisRead becomes a column named v0, v1, etc. The meta for each value column is the history record itself. Consider this example:
// let's assume two zone temps in our database:
{dis:"East Wing", zoneTemp, his, ... }
{dis:"West Wing", zoneTemp, his, ... }
// read two zone temps, and get their historical data for yesterday
r: readAll(zoneTemp).sort("dis").hisRead(yesterday)The resulting grid might look something like:
ts v0 v1
----- ---- ----
00:05 72.3 74.1
00:10 72.4 74.1
00:15 74.2
00:16 72.5
00:30 72.6 74.1
... ... ...Note the ts column contains full DateTimes, but to keep things simple we are only showing time of day here. Since we sorted the records by their dis tag in the example, so we know that v0 is "East Wing" and v1 is "West Wing". The meta dictionaries for the two value columns are the records passed into the hisRead function. For example:
r.col("v0")->dis // evaluates to "East Wing"
r.col("v1")->dis // evaluates to "West Wing"The rows of the query grid are joined by timestamp. If samples have the exact same timestamp then they are joined into the same row. Unless your data is aligned to the second, then the join will be sparse. Value columns without a sample for a given timestamp will have null for that row. In the example above, we can see that 00:05, 00:10, and 00:30 are joined by an aligned timestamp. However 00:15 and 00:16 are sparse.
The hisRead function returns raw data - the actual samples stored into the historian. Typically unless you are charting a 24-hour period or less, then you will pipe hisRead into additional history functions to perform rollups, maps, and filters.
Query TimeZone
All history records are required to implement the tz tag. When performing a history query, all the values are joined by a single ts column. If the set of histories shares the exact same tz value, then the resulting ts column will be in that timezone.
If however you perform a query across multiple timezones, then the timestamp is normalized into the "Etc/Rel" timezone (see TimeZone.rel). This is a special timezone which indicates relative time of day (as opposed to absolute time). If you wish to normalize to an explicit timezone then pass it as an option to the hisRead function.
Let's take an example:
Data for tz:"New_York"
12:00 75
13:00 76
14:00 77
15:00 78
Data for tz:"Chicago"
12:00 85
13:00 86
14:00 87
15:00 88By default if were to perform a hisRead on these two records they would be joined as follows:
// query the records
hisRead(src, date)
// resulting join
ts v0 v1
----- -- --
12:00 75 85
13:00 76 86
14:00 77 87
15:00 78 88If however we wished to join these timestamps by New_York time, then the Chicago data would be one hour behind:
// query the records
hisRead(src, date, {tz:"New_York})
// resulting join
ts v0 v1
----- -- --
12:00 75
13:00 76 85
14:00 77 86
15:00 78 87
16:00 88Note that the data is joined by absolute time. When its 2pm in New York, it is 1pm Chicago.
Appending N/A
When dealing with data that is synchronized, we frequently wish to write rules that gracefully handle lags in the data synchronization. For example, a COV point is assumed to have the same value as its last value, even if we haven't synchronized the data for 24 hours. So we may want our rules to skip running if we don't have up-to-date data yet. You can use the hisAppendNA tag to help identify this condition.
When you do a hisRead on a point that has the hisAppendNA tag, an NA value will be appended if
rec["hisEnd"] + rec["hisAppendNA"] < span.endFor example,
// history point
hisEnd: 2016-01-14 01:30 EST
hisAppendNA: 30min
// history data
ts val
2016-01-14 00:00 0
2016-01-14 00:30 30
2016-01-14 01:00 100
2016-01-14 01:30 130
hisRead(rec, 2016-01-14)
// result
ts val
2016-01-14 00:00 0
2016-01-14 00:30 30
2016-01-14 01:00 100
2016-01-14 01:30 130
2016-01-14 02:00 NA <-- NA appendedThe hisRead appended NA because
(2016-01-14 1:30 EST) + 30min < (2016-01-15 00:00 EST)If, however, hisAppendNA had been 24hr, no NA would have been appended since the hisRead span.end is within the 24hr threshold.
His Grid Shape
Most functions which consume history data require grids to be shaped a specific way we call a his grid. His grids have the following restrictions:
- First column must be called
tsand contain only ordered DateTimes with the same timezone - Zero or more value columns, typically named
v0,v1, etc - Grid meta must define a
hisStartandhisEndtags
Results from hisRead() or the built-in history functions will automatically shape his grids properly. However if you are constructing history data yourself, then you will need to adhere to these restrictions.
His Period Shape
Some functions expect to work with history grids where the values are durations. This special grid shape is called a his period grid. In order to be considered a "normalized" his period grid, the following must be true
- The grid must meet all the conditions of the his grid shape with the constraint that values must be durations.
- The periods must not overlap. In the case where you have overlapping periods, you can use the
hisPeriodNormalize()func to merge overlapping periods.
Computed Histories
A normal history record stores its samples as a set of timestamp/value pairs to disk. But on occasion it is preferable to compute a history's samples on demand using a function. Histories which generate their samples on demand are called computed histories. A computed history is configured just like a standard history with the addition of a hisFunc tag which is an Axon expression which evaluates to a function with the following parameters:
rec: the history record itselfdates: a date time rangeopts: currently not usedyieldthe generator sink function which takes DateTime timestamp and value A computed history may also return an optional Dict of metadata that will be merged into the result his grid meta. Note that you cannot override "his" meta tags; they will take precedence.
Suppose we wish to create a computed history which simulates a fixed occupied schedule where occupancy begins at 8am and ends at 10pm. First we create a new function called "occupancyHisFunc":
(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
// Returns some metadata
return {foo:"bar"}
endHere we are using the eachDay() function to iterate all the days within the date time range. For each day we yield a history item of true at 8am and false at 10pm. Now we create the computed history record:
{dis:"Occupancy", his, kind:"Bool", tz:"Chicago", hisFunc:"occupancyHisFunc"}We can test it using the standard hisRead() function:
read(dis == "Occupancy").hisRead(pastWeek)You can use partial application to parameterize your history functions on a per record basis. Lets take the function above and add start/end time parameters:
(rec, dates, opts, yield, startTime:8:00, endTime:22:00) => do
tz: rec->tz
eachDay(dates) day => do
yield(dateTime(day, startTime, tz), true)
yield(dateTime(day, endTime, tz), false)
end
endWe can use partial application to bind start, end times to our function:
{dis:"Occupancy Params", his, kind:"Bool", tz:"New_York",
hisFunc:"occupancyHisFunc(_, _, _, _, 6:00, 23:00)"}Lets consider another example. Suppose our site doesn't have a single site level electric meter, but instead has two meters for each of the wings. Let's construct a computed history which sums the demand from each meter:
(rec, dates, opts, yield) => do
readAll(kw and wing)
.hisRead(dates)
.foldCols(["v0", "v1"], "val", sum)
.each(row => yield(row->ts, row->val))
endLets review the code above line by line. The first line does a readAll() to read the two sub-meters which we've assumed have been marked with the wing tag. The next line performs a standard hisRead() on the two histories. The foldCols() call sums the "v0" and "v1" columns into a single "val" column. Lastly we iterate the rows via each() and yield the timestamp and summed values. Note in production this function would require that the sub-meters have data perfectly aligned by timestamp - in practice we would probably need an extra interpolation step.
hisFuncWritable
Normally, a computed point is not writable. However, sometimes it is desirable to store "raw" data about a point in the historian, but use a computed point as the default view of that data. You can use the hisFunc tag on a point with storage, but to enable writes you must also apply the hisFuncWritable tag to the point.
IMPORTANT: To read the underlying data for your computed history, you need to pass the {-hisFunc} option to your hisRead(). If you don't do this, your computed func will be called over-and-over again resulting in a stack overflow error. You could also use the {raw} option, but be aware that {raw} disables all transformations on your underlying data (e.g. timestamp shifting for consumption points).
(rec, dates, opts, yield) => do
// read underlying data
his: rec.hisRead(dates, opts.set("hisFunc", removeMarker()))
... do computations on underlying his data ...
endSee the computed totalized points section for a real-world example of using the hisFuncWritable tag.
Totalized
It is common in some logs to store an continuously incrementing stream of totalized values. For example electrical consumption is often stored like this:
ts val
----- --------
08:00 1000 kWh
09:00 1057 kWh
10:00 1206 kWh
11:00 1321 kWh
12:00 1404 kWhThe electrical consumption of each hour is actually the delta between each sample. For example 57kWh was used between 8am and 9am. If we tried to sum our consumption using a function like hisRollup() we would get incorrect results using the data in its totalized form.
In this case, you can add the hisTotalized marker to the history record and the hisRead() function will automatically convert the samples to compute the delta. For example the records above would be read as:
ts val
----- --------
08:00 null
09:00 57 kWh // 1057 - 1000
10:00 149 kWh // 1206 - 1057
11:00 115 kWh // 1321 - 1206
12:00 83 kWh // 1404 - 1321Note that boundary records are computed as null. This means that unlike other histories we don't necessarily get the value immediately before a given history.
Totalized Rollovers
When using a totalized history, a rollover occurs anytime that that a sample is read which is less than the previous value (negative delta). By default a rollover will use the new value without computing a delta. If you add the hisTotalizedRollover tag then the new value will be the computed as follows:
delta = (rollover - previous) + currentConsider this example with the raw data:
ts val
----- ------
08:00 10 kWh
09:00 15 kWh
10:00 4 kWh
11:00 7 kWhWithout a rollover definition, we will compute the delta values as:
ts val
----- ------
08:00 null
09:00 5 kWh // 15 - 10
10:00 4 kWh // ignore last value, and use 4 as delta
11:00 3 kWh // 7 - 4Or if we define hisTotalizedRollover: 20 then the deltas are:
ts val
----- ------
08:00 null
09:00 5 kWh // 15 - 10
10:00 9 kWh // (20 - 15) + 4
11:00 3 kWh // 7 - 4Computed Totalized Points
Sometimes the behavior of a totalized meter is too complex for the standard rollover logic described above to work. For example, net-metered buildings, or thermal systems with heat recovery or potential reverse flow will frequently generate valid negative deltas. There are also cases where meters will generate large positive deltas that need to be handled as a special case.
In these instances, you can make use of a special feature of computed points. You can use a standard writable point to store the raw, totalized data. Then, apply the hisFunc tag to that point to use a computed history to handle all the complex logic for how you want to handle the deltas. To use a hisFunc with a writable point, you must also apply the hisFuncWritable tag to the point. See the hisFuncWritable section for details.
The following is an example of how this feature could be used to configure how negative and positive deltas are handled. See the first three comments in this forum thread for more background.
// His Point
point
his
hisFuncWritable
hisFunc: computeDeltas
hisTotalizedDeltaMin: -50
hisTotalizedDeltaMax: 1000
... other tags ...
// computeDeltas() hisFunc
(rec, dates, opts, yield) =>
// get custom configuration from his rec
deltaMin: rec["hisTotalizedDeltaMin"]
if (deltaMin == null) deltaMin = 0
deltaMax: rec["hisTotalizedDeltaMax"]
if (deltaMax == null) deltaMax = posInf()
// read raw totalized data - make sure you pass the {-hisFunc} option!!!
rawData: rec.hisRead(dates, {-hisFunc, -hisTotalized})
// compute deltas
prev: null
rawData.each row => do
// handle first value (or nulls in data)
if (prev == null) prev = row
// compute delta
delta: row->v0 - prev->v0
// handle rollover
if ((delta < deltaMin) or (delta > deltaMax)) do
if (rec.has("hisTotalizedOnRollover")) do
delta = rec->hisTotalizedOnRollover
else if (rec.has("hisTotalizedRollover")) do
delta = rec->hisTotalizedRollover + delta
else do
delta = row->v0
end
end
// yield result
yield(row->ts, delta)
// reset previous row
prev = row
endConsumption Data
Consumption data is unique in that the timestamp of the logged data value indicates the end of an interval. All functions that work with historical data in SkySpark assume that a timestamp indicates the start of an interval. Therefore, history points that model consumption data should be tagged with hisMode set to "consumption". When you do a hisRead() on a consumption point, the data will automatically be normalized so that timestamps indicate the start of an interval. For example, given this raw data:
23:45 10
00:00 20
00:15 30
00:30 40
00:45 50
01:00 60
01:15 70When we perform a hisRead on the data above, we would get:
23:45 20
00:00 30
00:15 40
00:30 50
00:45 60
01:00 70In addition to affecting a timestamp shift, consumption points imply:
- A rollup behavior (
sum()) - An interpolation behavior (
apportion)
The canonical use-case for consumption points is energy (kWh) data. Therefore you should not use hisMode=consumption simply to achieve a timestamp shift. If you just need a timestamp shift, but the rollup and interpolation behavior does not apply to your point (e.g. a rolling demand point), you should consider using hisOnWrite instead.
OnWrite
You can register an Axon function on a history record to receive a callback before data is written to the historian database. This feature allows:
- data cleanup
- timezone conversion from source data
- kind conversion (such as mapping 1/0 to true/false)
- unit conversion from source data
To register a write callback, create a hisOnWrite tag on the history record with a string which evaluates to an Axon function that takes a history data grid and Dict record for the point being written. The history data grid has a ts and val column. The function must return the mapped data to write to the database. The on write callback is only invoked when writing new data via hisWrite().
Here are some simple examples of on write callbacks:
// convert source data to configured timezone
(his, rec) => do
his.map r => r.set("ts", r->ts.toTimeZone(rec->tz))
end
// convert 0 to false and anything else to true
(his) => do
his.map r => r.set("val", r->val != 0)
endForecast
The Folio historian provides special support for forecast items. Forecast items allow management of future forecast data to be integrated seamlessly with persistent time-series data. Summary of forecast characteristics:
- stored transiently (cleared on restart)
- written using the
{forecast}option - write semantics is always replacement of forecast items
- forecast items do not effect
hisSize,hisStart, orhisEndtags - hisRead will append forecast items when
{forecast}option is specified - hisRead will read only forecast items using
{forecastOnly}option - reads automatically clip forecast to now or latest persistent timestamp
To write forecast data, use the forecast tag in your hisWrite options:
hisWrite(data, id, {forecast})When using the forecast option, it overwrites any previous forecast data. The forecast data is stored transiently and will be cleared if the VM is restarted. Writing forecast items does not modify the hisSize, hisStart, or hisEnd tags - these tags only represent the persistent items.
The default behavior for hisRead only returns persistent items. You can force forecast items to be appended with the forecast option tag. Or you can use the forecastOnly tag to only return transient forecast items. Forecast data is automatically clipped by the current timestamp or the latest persistent item. Forecast items are not filtered by the time span.
// read today persistent data plus forecast items
hisRead(pt, today, {forecast})
// read only forecast items
hisRead(pt, today, {forecastOnly})Note: reading forecast items will not work correctly using a null span. Always use an explicit span such as today when working with forecast data.
def
func:covAvg
covAvg(val, ts, acc)
Folding function for generating a time weighted average on change-of-value histories (where hisInterpolate() is "cov"). The average is calcualted by weighting each sample with its ratio of duration in the the overall interval. For example given the following time/value pairs:
00:00 10
02:00 30
12:00 70If performing a 1day rollup with the data above, the point had a value of 10 for 2 hours, a value of 30 for ten hours, and a value of 70 for 12 hours (until end of day). The time weighted COV average would be 48.3:
10 * (2/24) + 30 * (10/24) + 70 * (12/24)If any value in the rollup interval is na(), then the result is na().
meta
| def | func:covAvg |
| disKey | ui::covAvg |
| foldOn | Number |
| is | func |
| lib | lib:his |
| name | covAvg |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:discreteBoolPeriods
discreteBoolPeriods(val, ts, acc)
Fold timestamp/bool value pairs into an encoded Str of discrete minutely intervals. This rollup is similar to discretePeriods() with the same Base64 encoding. There are two significant differences:
- This rollup supports NA data
- Instead of encoding offset/duration pairs, the encoding is offset/ordinal pairs. The ordinal values map as
{0: false, 1: true, 2: NA}
Also see parseDiscreteBoolPeriods() and Etc.discretePeriods.
meta
| def | func:discreteBoolPeriods |
| foldOn | Bool |
| is | func |
| lib | lib:his |
| name | discreteBoolPeriods |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:discreteEnumPeriods
discreteEnumPeriods(val, ts, acc)
Fold timestamp/enum Str value pairs into an encoded Str of discrete minutely intervals. This rollup works very similar to discretePeriods() with the same Base64 encoding. The difference is that instead of offset/duration pairs, the encoding is offset/ordinal pairs. The ordinal values map the position of each string value in the point's enum tag. If a string value is not mapped by enum then a value of 0xff (255) is used for the ordinal. If a string value is NA, then a value of 0xfff (4095) is used for the ordinal.
Also see parseDiscreteEnumPeriods() and Etc.discretePeriods.
meta
| def | func:discreteEnumPeriods |
| foldOn | Str |
| is | func |
| lib | lib:his |
| name | discreteEnumPeriods |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:discretePeriods
discretePeriods(val, ts, acc)
Fold timestamp/bool value pairs into an encoded Str of discrete minutely intervals. The string encoding is based on 12-bit minutely start/duration pairs. Each 12-bit minute offset/duration is encoded using two 6-bit ASCII characters encoded by the Base64 table. Also see parseDiscretePeriods() and Etc.discretePeriods.
Here is the Fantom code which decodes a string to iterate a period where time is offset in minutes from base timestamp and dur is duration of period in minutes (assuming a minutely interval).
static Void decodePeriod(Str str, |Int time, Int dur| f)
{
for (i := 0; i<str.size; i += 4)
{
time := fromBase64[str[i+0]].shiftl(6) + fromBase64[str[i+1]]
dur := fromBase64[str[i+2]].shiftl(6) + fromBase64[str[i+3]]
f(time, dur)
}
}
// base64 lookup tables
static const Str toBase64 :=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
static const Int[] fromBase64
static
{
list := Int[,].fill(0, 128)
toBase64.each |ch, i| { list[ch] = i }
fromBase64 = list
}Note: the encoding size of 12-bits limits representations to offsets of 4095 minutes or roughly 2.8 days. Using using rollup intervals over 1day cannot be represented using this encoding and will be silently truncated past 2.8 days.
meta
| def | func:discretePeriods |
| foldOn | Bool |
| is | func |
| lib | lib:his |
| name | discretePeriods |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:durTrue
durTrue(val, ts, acc)
Fold function for folding timestamp/bool value pairs into durations when true (runtime). This is a rollup function of arity 3, so it can only be used with history rollups. na() is treated like false, and terminates a true period.
meta
| def | func:durTrue |
| foldOn | Bool |
| is | func |
| lib | lib:his |
| name | durTrue |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:hisClear
hisClear(hisArg, span)
Clear the history items in the given range. This function has similiar semantics as hisRemove() except:
- it supports multiple history records as a target
- it only supports a single span or null
WARNING: once the data is cleared, there is NO recovery!!!
The hisArg contains the list of histories to query using any value supported by the toRecList() function. See hisRead().
The span can be any non-null span accepted by hisRead() or null. A null value will delete all the history data for each point. Unlike hisRemove() the span cannot be a list nor a single DateTime.
The result of this function is unspecified and may change.
meta
| admin | ✓ |
| def | func:hisClear |
| is | func |
| lib | lib:his |
| name | hisClear |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:hisClip
hisClip(src)
Remove the rows with leading/trailing timestamps from the actual query range. The query range is defined as inclusive of meta.hisStart and exclusive of meta.hisEnd. These meta tags are derived from the dates range passed to the hisRead() function.
Example:
hisRead(points, dates).hisClipmeta
| def | func:hisClip |
| is | func |
| lib | lib:his |
| name | hisClip |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:hisInterpolate
hisInterpolate(src)
Interpolate all the null value cells for each timestamp. See Interpolation for details.
meta
| def | func:hisInterpolate |
| is | func |
| lib | lib:his |
| name | hisInterpolate |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:hisJoin
hisJoin(grids, opts: {})
Given a list of history grids, join them by the ts timestamp column. This function automatically renames columns to ensure each column in result has a unique name. Grid meta is merged in order of grids parameter, however all "hisX" meta tags are stripped, and new hisStart and hisEnd are computed based on a merged range.
The following options are supported:
tz: specifies the timezone for thetscolumn for the join. If omitted, and all the histories have the same timezone then that is the timezone used byts. Otherwise histories are joined by relative time of day using "Etc/Rel". If an explicit timezone other than "Etc/Rel" is specified, then timestamps are joined by absolute time.
Example:
a: hisRead(pointA, dates)
b: hisRead(pointB, dates)
hisJoin([a, b])meta
| def | func:hisJoin |
| is | func |
| lib | lib:his |
| name | hisJoin |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:hisRead
hisRead(hisRefs, dates, opts: {})
Query history for an arbitrary range. The result is a grid with a column called "ts", and multiple "v0", "v1", etc columns with the values joined by timestamp.
The hisRefs contains the list of histories to query using any value supported by the toRecList() function:
- Ref or Ref[] to his
- Dict/Row or Dict[]/Row[] of his
- Grid of his
Any records which don't support the his tag are silently ignored. If no records with the his tag are specified then an exception is thrown.
The dates specifies the start/ending times of the query:
- if start is null, then we use oldest item
- if end is null, then we use most recent item
- if start is Date, then we use midnight of that day
- if end is Date, then we use midnight of next after
- otherwise start/end must be DateTimes
The following convenience values are also allowed for range:
- Date: convenience for
date..date - null: convenience for
null..null - Int: if between 1900 and 2100 convenience for entire year
- Fn: function is resolved to one of the above
todayvstoday()
The result always includes the previous item immediately before the range, and immediately after the range. The leading/trailing values are often needed to interpret the first/last values of the result. If leading/trailing values are not desired, then pipe the result of this function to hisClip()
The following options are supported:
limit: used to cap the number of records generated by the query. The default is 10,000. You may use Remove.val to indicate no limit such as{-limit}.tz: specifies the timezone for thetscolumn used to join multiple histories. If omitted, and all the histories have the same timezone then that is the timezone used byts. Otherwise histories are joined by relative time of day using "Etc/Rel". If an explicit timezone other than "Etc/Rel" is specified, then timestamps are joined by absolute time.hisTotalized: set to Remove.val to disable delta reads of of hisTotalized recs (reads raw values); in Axon you can specify this like{-hisTotalized}.hisMode: set to Remove.val to force all reads to behave as though the hisMode tag was not set on the rec; in Axon you can specify this like{-hisMode}.hisAppendNA: set to Remove.val to disable the append NA threshold on histories that have this tag.; in Axon you specify this like{-hisAppendNA}. SeehisAppendNAfor details.hisFunc: set to Remove.val to disable the computed function for this point. Can only be used on writable computed points. In Axon you can specify this like{-hisFunc}.raw: set to Marker.val to disable all transformations of the history read; in Axon you can specify this like{raw}. This option is equivalent to{-hisTotalized, -hisMode, -hisAppendNA, -hisFunc}.forecast: include forecast itemsforecastOnly: include only forecast items
Note that the query limit is applied to the pipeline, not the raw hisRead. So if hisRead is piped directly to a hisRollup, the limit will apply to the number of rollup rows, not raw rows. Unless configured in opts, the default limit is 10,000. This value may be overridden by applying the hisLimit tag on the HisExt record. If the limit is hit and more data is available, then grid meta has the limit and more tags defined.
Also see his.
meta
| def | func:hisRead |
| haystackApi | Read time series data to historian |
| is | func |
| lib | lib:his |
| name | hisRead |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:hisRemove
hisRemove(hisRec, spans)
Remove items from a history using a timestamp or timestamp range. This function blocks until the remove is complete.
WARNING: once the data is removed, there is NO recovery!!!
The hisRec supports anything accepted by toRec(). Note this function only works on one record at a time.
The spans argument can be any non-null span accepted by hisRead() or a list of such spans. If a single DateTime is used then just that item is removed, otherwise any items within the span's inclusive start time and exclusive end time are removed. Note that timestamps are normalized according to the record's hisTsPrecision.
This function is best used for fine grained removal. Also see the hisClear() function for removing multiple points or the entire history.
The result of this function is unspecified and may change.
Examples:
hisRemove(pt, ts) // remove single item
hisRemove(pt, startTs..endTs) // remove span of items
hisRemove(pt, [ts1, ts2]) // remove list of timestampsmeta
| admin | ✓ |
| def | func:hisRemove |
| is | func |
| lib | lib:his |
| name | hisRemove |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:hisRewrite
hisRewrite(hisArg, fn)
Rewrite every item of a history using the given transformation function. This function will automatically update the kind, tz, and unit tag if the mapping function returns a new timezone, new value type, or new unit. The mapping function takes (val, ts, his) and returns new items as tuple list of [ts, val] or null to omit a specific writing item.
CAUTION: This function will read and rewrite every item and there is no undo, so use it with care!
The hisArg contains the list of histories to rewrite using any value supported by the toRecList() function. See hisRead().
Return a grid with a row for each history converted. The following columns are included:
- id: of the history record
- dis: dis string of the history record
- numRewritten: number of history items rewritten
Side effects:
- rewrites every history item
- clears context read cache
Examples:
// to convert to New_York timezone
hisRewrite(hisId) (val, ts) => [ts.toTimeZone("New_York"), val]
// convert numbers to bool if non-zero
hisRewrite(hisId) (val, ts) => [ts, val != 0]
// convert units
hisRewrite(hisId) (val, ts) => [ts, val.to("kW")]meta
| admin | ✓ |
| def | func:hisRewrite |
| is | func |
| lib | lib:his |
| name | hisRewrite |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:hisRollup
hisRollup(src, fold, interval)
Roll up a history grid over discrete intervals of time with the given fold function. The src must be a history grid created from hisRead() or some transformation of it.
Rollups are inclusive of start and exclusive of end times. For example a daily rollup includes midnight of the current day, but excludes midnight of the next day. All the items found within the interval are passed to the folding function to compute a timestamp/val pair with each timestamp aligned to the start of the interval. Use the string "*" to rollup the entire grid as one big interval.
For example a rollup interval of 1day over a one year range would calculate 365 (or 366 if leap year) items with the start time being midnight of each day. Interval rules:
- Less 1day: use absolute time, aligned off start (example 1hr)
- 1day: daily rollup, aligned off midnight
- 1wk: weekly rollup, aligned off midnight on Sunday
- 1mo: monthly rollup, aligned off midnight on 1st of month
- 3mo: quarterly rollup, aligned off midnight on 1st of 3 month intervals
- 1yr: yearly rollup, aligned off midnight Jan 1st
- Anything else is an error
See core::fold for how folding functions work. History rollups also support rollup functions with arity of 3 (val, ts, acc).
This function will work with forecast data provided one of the following is true:
- You did the initial
hisRead()with the{forecast}option - The column metadata for the value has a
hisEndin the future - The data comes from a computed point (
hisFunc) - The data does not come from a demo database
meta
| def | func:hisRollup |
| is | func |
| lib | lib:his |
| name | hisRollup |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:hisRollupAuto
hisRollupAuto(src, interval: null, foldFinder: null)
Automatically chooses the best rollup interval and the best rollup fold function for each history.
If null is passed for the interval, then the following automatic selection is made:
- less 2days: Check each history rec to see if any specify the
hisRollupAutoMinIntervaltag and take the maximum value. Otherwise, no rollup is applied and the raw history grid is returned. - one week: 10min interval
- one month: 1hour interval
- over one month: daily interval
The rollup function applied to each history is determined as follows:
- if foldFinder parameter is specified, it is called for each history to get fold function. If it returns null we check next step
- if
hisRollupFuncis defined on the history, then use it - Select fold function based on kind:
- Bool:
discreteBoolPeriods() - Number with
hisModeof "cov":covAvg() - Number pick based on unit's quantity:
- power:
max - volume, energy:
sum() - default:
avg
- power:
- Str with enum tag:
discreteEnumPeriods() - fallback to
count()
- Bool:
If your history has no data or is a computed history, you should explicitly specify the kind or hisRollupFunc to ensure a suitable rollup is selected.
If a rollup is applied, then the following tags are automatically applied to the resulting grid:
hisRollupInterval: applied to grid.meta interval used for the rolluphisRollup: applied to col.meta of each value column (such as "avg")hisRollupDis: applied to col.meta for each rollup, if all the columns have the same rollup, then it is applied to grid.meta also
Examples:
// over 1hr intervals
src.hisRead(pastWeek).hisRollupAuto
// over 6hr intervals
src.hisRead(pastMonth).hisRollupAuto
// explicit 1day intervals
src.hisRead(pastMonth).hisRollupAuto(1day)
// explicit fold finder, uses max for all columns
src.hisRead(pastMonth).hisRollupAuto(null, his => max)meta
| def | func:hisRollupAuto |
| is | func |
| lib | lib:his |
| name | hisRollupAuto |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:hisRollups
hisRollups(src, folds, interval)
Perform a series of rollups over discrete intervals. This function works just like hisRollup(), but takes a list of folding functions. Instead of a single value per input history, there are a series of columns for each folding function. For example if the input has a v0 and v1 column and the folding functions are [min, max], then the resulting grid will have v0_min, v0_max, v1_min, and v1_max.
meta
| def | func:hisRollups |
| is | func |
| lib | lib:his |
| name | hisRollups |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:hisSync
hisSync(timeout: null)
Block until any pending history writes/clears are completed.
meta
| admin | ✓ |
| def | func:hisSync |
| is | func |
| lib | lib:his |
| name | hisSync |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:hisWrite
hisWrite(data, hisRec, opts: null)
Asynchronously write the specified timestamp/value pairs to the history. The timestamps must match tz of history. If the history has a unit tag, then the items have either a null or matching unit. Return future which may be used to track when write completes - the value of the future subject to change.
Writing data with existing timestamps will replace the current data with the new data. Note that timestamp comparison happens after normalizing timestamps to closest second or millisecond.
The data may be one of the following:
- Dict with
tsandvaltags; writes one pair to the history - List of Dicts with
tsandvaltags; writes the list of items to the history - Grid where first column is
tsand second column (may be named anything) is the values
The hisRec parameter may be:
- Ref of history to write to
- Rec of history to write to
Options:
noWarn: suppress out of order warning loggingforecast: set to marker to write as forecast data
Side effects:
- updates his rec tags hisSize, hisStart, etc
- clears context read cache
See documentation for more details.
meta
| admin | ✓ |
| def | func:hisWrite |
| haystackApi | Write time series data to historian |
| is | func |
| lib | lib:his |
| name | hisWrite |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:parseDiscreteBoolPeriods
parseDiscreteBoolPeriods(val)
Parse a Base64 encoded timeline of discrete Bool periods as encoded by discreteBoolPeriods(). Return a grid of minutely offsets and Bool/NA values with the columns offset and val. If val is null, then return null.
meta
| def | func:parseDiscreteBoolPeriods |
| is | func |
| lib | lib:his |
| name | parseDiscreteBoolPeriods |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:parseDiscreteEnumPeriods
parseDiscreteEnumPeriods(val, rec: null)
Parse a base64 encoded string timeline of discrete enum periods as encoded by discreteEnumPeriods(). Return a grid of minutely offsets and enum ordinal values with the columns offset and ordinal. If the rec is passed with the enum tag, then an additional name column specifies the ordinal to name mapping. If val is null, then return null.
meta
| def | func:parseDiscreteEnumPeriods |
| is | func |
| lib | lib:his |
| name | parseDiscreteEnumPeriods |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:parseDiscretePeriods
parseDiscretePeriods(val)
Parse a base64 encoded string timeline of discrete periods as encoded by discretePeriods(). Return a grid of minutely offsets and duration with the columns offset and dur. If val is null, then return null.
meta
| def | func:parseDiscretePeriods |
| is | func |
| lib | lib:his |
| name | parseDiscretePeriods |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
hisAppendNA
Specifies the amount of time after a history point's hisEnd that the hisRead() function should append an NA. See Appending N/A for details.
meta
| def | hisAppendNA |
| is | duration |
| lib | lib:his |
| tagOn | his-point |
supertypes
| val | Data value type |
| scalar | Scalar is an atomic value kind |
| number | Integer or floating point numbers annotated with an optional unit |
| duration | Number with a unit of time |
def
hisEnd
Timestamp of newest item in history
meta
| def | hisEnd |
| is | dateTime |
| lib | lib:his |
| tagOn | his-point |
| transient | ✓ |
supertypes
| val | Data value type |
| scalar | Scalar is an atomic value kind |
| dateTime | ISO 8601 timestamp followed by timezone identifier |
def
hisFunc
Axon expression used to create a computed history.
meta
| def | hisFunc |
| is | str |
| lib | lib:his |
supertypes
| val | Data value type |
| scalar | Scalar is an atomic value kind |
| str | Unicode string of characters |
def
hisFuncWritable
Allow writing raw data to a point that has the hisFunc tag.
meta
| def | hisFuncWritable |
| is | marker |
| lib | lib:his |
supertypes
| marker | Marker labels a dict with typing information |
def
hisInterpolateMode
Explicitly configures the interpolation mode to use for this point. See interpolation.
meta
| def | hisInterpolateMode |
| enum | See below |
| is | str |
| lib | lib:his |
| tagOn | his-point |
enum
| linear | |
| cov | |
| consumption |
supertypes
| val | Data value type |
| scalar | Scalar is an atomic value kind |
| str | Unicode string of characters |
def
hisInterval
The interval at which sampled or consumption data is collected.
meta
| def | hisInterval |
| is | duration |
| lib | lib:his |
supertypes
| val | Data value type |
| scalar | Scalar is an atomic value kind |
| number | Integer or floating point numbers annotated with an optional unit |
| duration | Number with a unit of time |
def
hisOnWrite
Axon expression to trap and map history data before writing to the historian database. The string must evaluate to a function which takes a history grid and optional record and returns a mapped grid. See onWrite.
meta
| def | hisOnWrite |
| is | str |
| lib | lib:his |
supertypes
| val | Data value type |
| scalar | Scalar is an atomic value kind |
| str | Unicode string of characters |
def
hisRollupAutoMinInterval
Forces hisRollupAuto() to do a rollup using this interval when none is specified and the range of the source history grid is less than 2 days. This tag is primarly intended to be used on high frequency histories such as secondly collections to ensure that querying a single day doesn't result in an overwhelming amount of data.
meta
| def | hisRollupAutoMinInterval |
| is | duration |
| lib | lib:his |
| tagOn | his-point |
supertypes
| val | Data value type |
| scalar | Scalar is an atomic value kind |
| number | Integer or floating point numbers annotated with an optional unit |
| duration | Number with a unit of time |
def
hisRollupFunc
Function name to use for hisRollupAuto()
meta
| def | hisRollupFunc |
| is | str |
| lib | lib:his |
supertypes
| val | Data value type |
| scalar | Scalar is an atomic value kind |
| str | Unicode string of characters |
def
hisRollupInterval
Indicates the roll-up interval in his grid column meta-data.
meta
| def | hisRollupInterval |
| is | duration |
| lib | lib:his |
supertypes
| val | Data value type |
| scalar | Scalar is an atomic value kind |
| number | Integer or floating point numbers annotated with an optional unit |
| duration | Number with a unit of time |
def
hisSize
Approximate number of timestamp/value pairs stored in history
meta
| def | hisSize |
| is | int |
| lib | lib:his |
| tagOn | his-point |
| transient | ✓ |
supertypes
| val | Data value type |
| scalar | Scalar is an atomic value kind |
| number | Integer or floating point numbers annotated with an optional unit |
| int | Unitless integer number |
def
hisStart
Timestamp of oldest item in history
meta
| def | hisStart |
| is | dateTime |
| lib | lib:his |
| tagOn | his-point |
| transient | ✓ |
supertypes
| val | Data value type |
| scalar | Scalar is an atomic value kind |
| dateTime | ISO 8601 timestamp followed by timezone identifier |
def
hisTotalizedRollover
Defines the rollover value for a totalized history - see totalized.
meta
| def | hisTotalizedRollover |
| is | number |
| lib | lib:his |
supertypes
| val | Data value type |
| scalar | Scalar is an atomic value kind |
| number | Integer or floating point numbers annotated with an optional unit |
def
hisTsPrecision
Controls the precision used to store timetamps in the historian. Supported values are 1sec and 1ms, any other value will raise an exception on hisWrite(). If omitted, then the default of 1sec is used.
meta
| def | hisTsPrecision |
| is | duration |
| lib | lib:his |
supertypes
| val | Data value type |
| scalar | Scalar is an atomic value kind |
| number | Integer or floating point numbers annotated with an optional unit |
| duration | Number with a unit of time |
def
periods
Timeline of on/off periods encoded as Base64 via discretePeriods().
meta
| def | periods |
| is | str |
| lib | lib:his |
supertypes
| val | Data value type |
| scalar | Scalar is an atomic value kind |
| str | Unicode string of characters |
def
view:hisChart
Visualize historical point data as a graphical chart
meta
| appName | his |
| def | view:hisChart |
| disKey | ui::chart |
| icon | view |
| is | view |
| lib | lib:his |
| order | 100 |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| view | Fresco UI view |
src
view: { inherit:"chart" }
points: { var input kind:"Ref<anyPoint>[]" navCluster navSelAny share }
span: { var input kind:"Span" defVal:Span("today") share }
opts: { var input kind:"Dict" disKey:"ui::options" templateName:"hisDataOpts" defVal:{} share }
details: { action:"uiMisc::HisDataDetails.invoke" disKey:"ui::details" }
menu: { action:"uiContextMenu" selInput:"points" }
data: { expr:"hisDataView({{points}}, {{span}}, {{opts}})" }def
view:hisCompare
Visualize historical point data from two different spans
meta
| appName | his |
| def | view:hisCompare |
| disKey | ui::compare |
| icon | view |
| is | view |
| lib | lib:his |
| order | 180 |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| view | Fresco UI view |
src
view: { inherit:"chart"}
points: { var input kind:"Ref<anyPoint>[]" navCluster navSelAny share }
span1: { var input kind:"Span" defVal:Span("today") share }
span2: { var input kind:"Span" defVal:Span("yesterday") share }
opts: { var input kind:"Dict" disKey:"ui::options" templateName:"hisDataOpts" defVal:{} share }
details: { action:"uiMisc::HisDataDetails.invoke" disKey:"ui::details" }
menu: { action:"uiContextMenu" selInput:"points" }
data: { expr:"hisCompareView({{points}}, {{span1}}, {{span2}}, {{opts}})" }def
view:hisCorrelate
Chart a linear correlation of historical point data
meta
| appName | his |
| def | view:hisCorrelate |
| disKey | ui::correlate |
| icon | view |
| is | view |
| lib | lib:his |
| order | 190 |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| view | Fresco UI view |
src
view: { inherit:"tile"}
uiViewBar: { var kind:"Dict" defVal:{} showVarLabels:T }
layout: { var kind:"Str" defVal:"grid 1x5; 0 0 1 2; 0 2 1 3" }
xaxis: { var input kind:"Ref<anyPoint>" navCluster disKey:"ui::xAxis" }
yaxis: { var input kind:"Ref<anyPoint>" navCluster disKey:"ui::yAxis" }
span: { var input kind:"Span" defVal:Span("today") share dis:"" }
filter: Trio:
var
input
kind:"Dict"
disKey:"ui::filter"
templateName:"hisCorrelateFilter"
defVal: Trio:
days:"all"
opts: Trio:
var
input
kind:"Dict"
disKey:"ui::options"
templateName:"hisCorrelateOpts"
defVal: Trio:
rollup: {fold:"auto" interval:"auto"}
reg: Trio:
view: { inherit:"chart" }
xaxis: { var binding:"../xaxis" }
yaxis: { var binding:"../yaxis" }
span: { var binding:"../span" }
filter: { var binding:"../filter" }
opts: { var binding:"../opts" }
data: { expr:"hisCorrelate({{xaxis}}, {{yaxis}}, {{span}}, {{filter}}, {{opts}}).first->reg" }
his: Trio:
view: { inherit:"chart" }
xaxis: { var binding:"../xaxis" }
yaxis: { var binding:"../yaxis" }
span: { var binding:"../span" }
filter: { var binding:"../filter" }
opts: { var binding:"../opts" }
data: { expr:"hisCorrelate({{xaxis}}, {{yaxis}}, {{span}}, {{filter}}, {{opts}}).first->his" }def
view:hisEquip
Visualize historical point data of a single equipment
meta
| appName | his |
| def | view:hisEquip |
| disKey | ui::equip |
| icon | view |
| is | view |
| lib | lib:his |
| order | 200 |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| view | Fresco UI view |
src
view: { inherit:"chart" }
equip: { var input kind:"Ref<equip>" navCluster share }
span: { var input kind:"Span" defVal:Span("today") share }
opts: { var input kind:"Dict" disKey:"ui::options" templateName:"hisEquipOpts" defVal:{showWeather:T} }
menu: { action:"uiContextMenu" selInput:"equip" }
data: { expr:"hisEquip({{equip}}, {{span}}, {{opts}})" }def
view:hisImport
Import point history data into the local project database
meta
| admin | ✓ |
| appName | his |
| def | view:hisImport |
| disKey | ui::import |
| icon | view |
| is | view |
| lib | lib:his |
| order | 801 |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| view | Fresco UI view |
src
point: { var input kind:"Ref<anyPoint>" saveWithDis defVal:@null }
view: { uiType:"uiMisc::HisImportView" }
menu: { action:"uiContextMenu" selInput:"point" }
data: { expr:"hisImportView({{point}})" }def
view:hisTable
Visualize historical point data as a table
meta
| appName | his |
| def | view:hisTable |
| disKey | ui::table |
| icon | view |
| is | view |
| lib | lib:his |
| order | 111 |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| view | Fresco UI view |
src
view: { inherit:"table"}
points: { var input kind:"Ref<anyPoint>[]" navCluster navSelAny share }
span: { var input kind:"Span" defVal:Span("today") share }
opts: { var input kind:"Dict" disKey:"ui::options" templateName:"hisDataOpts" defVal:{} share }
details: { action:"uiMisc::HisDataDetails.invoke" disKey:"ui::details" }
menu: { action:"uiContextMenu" selInput:"points" }
data: { expr:"hisDataView({{points}}, {{span}}, {{opts}})" }