描绘时间序列
创建仪表板,并选择要描绘的时间序列。使用自定义查询以及筛选、聚合、粒度、算术运算和函数之类的高级功能处理时间序列。
创建仪表板
使用来自 Cognite Data Fusion (CDF) 的时间序列数据创建仪表板:
-
登录
Grafana实例,并创建仪表板。 -
使用主图表区域下方的查询选项卡为仪表板选择时间序列:
-
时间序列搜索 - 从指定时间序列获取数据。开始键入时间序列的名称或描述,并从下拉列表将其选中。
直接在查询中指定聚 合和粒度。默认情况下,聚合设置为 average,粒度通过图表的已选时段确定。
提示另一种方法:设置自定义标签,并使用格式
{{property}}
从该时间序列提取数据。你可以使用所有可用的时间序列属性定义标签,例如{{name}} - {{description}}
或{{metadata.key1}}
。 -
来自资产的时间序列 - 从与指定资产相关的时间序列获取数据。开始键入资产的名称或描述,并从下拉列表将其选中。或者,决定你是否要包括来自子资产的时间序列。
-
时间序列自定义查询 - 获取与查询匹配的时间序列。
-
-
与你的选择匹配的时间序列将呈现在图表区域中。根据需要调整时间范围以显示相关数据。
使用自定义查询
自定义查询可以更精细地控制时间序列数据的选择。你可以使用算术运算、函数,并指定用于获取合成时间序列的语法。本节还概括了与数据筛选相关的限制以及如何有效地使用正则表达式和服务器端筛选器。
定义查询
要请求时间序列,请使用其内部的参数指定查询。例如,要查询 id
等于 123
的时间序列,则指定 ts{id=123}
。
你可以使用 id
、externalId
或时间序列筛选器来请求时间序列。
对于合成时间序列,你可以指定多个属性类型:
bool
:ts{isString=true}
或ts{isStep=false}
string
或number
:ts{id=123}
或ts{externalId='external_123'}
array
:ts{assetIds=[123, 456]}
object
:ts{metadata={key1="value1", key2="value2"}}
要创建复杂的合成时间序列,你可以在单个查询中组合类型:
ts{name="test", assetSubtreeIds=[{id=123}, {externalId="external_123"}]}
筛选
查询还支持根据应用逻辑 AND
的时间序列属性进行筛选。例如,使用下面的查询来查找以下时间序列:
- 属于
id
等于123
的资产 name
以"Begin"
开头name
不以"end"
结束name
不等于"Begin query"
结束
ts{assetIds=[123], name=~"Begin.*", name!~".*end", name!="Begin query"}
查询语法包含不同类型的等式运算符:
=
- 严格等式。指定向CDF请求的时间序列的参数。与筛选属性结合使用。=!
- 严格不等式。使用不等于字符串的属性筛选所获取的时间序列。支持字符串、数值和布尔值。=~
– 正则表达式等式。使用与正则表达式匹配的属性筛选所获取的时间序列。支持字符串值。!~
- 正则表达式不等式。使用与正则表达式不匹配的属性筛选所获取的时间序列。支持字符串值。
你还可以筛选元数据:
ts{externalIdPrefix="test", metadata={key1="value1", key2=~"value2.*"}}
上面的查询请求符合下列条件的时间序列:
externalIdPrefix
等于"test"
metadata.key1
等于"value1"
metadata.key2
以"value2"
开头
查询限制
执行自定义查询时,请务必了解获取时间序列的基本限制:
-
客户端筛选:连接器在_客户端_应用正则表达式查询(
=~
代表匹配,!~
代表排除)和不精确不等式筛选器 (=!
)。此流程发生在从 Cognite Data Fusion (CDF) 初始检索最多 1,000 个时间序列项目之后。根据这种方法,如果总数超过 1,000,则可能并非所有相关时间序列都包含在获取的子集中。 -
服务器端筛选:为了缓解这种限制,建议尽可能使用_服务器端_筛选。这可以通过对特定时间序列筛选器属性应用严格等式筛选器 (
=
) 来实现。这样可以有效地缩小从 CDF 检索的时间序列集,确保后续客户端筛选器应用于更有针对性的数据集。这一点特别有用,可以确保所有相关时间序列(尤其是感兴趣的时间序列) 都包含在从 CDF 获取的初始数据集中。
在应用_正则表达式_或其他_客户端_筛选器之前,结合_服务器端_筛选与特定属性或元数据,以优化查询的范围。这种方法可明显增加在 Grafana 仪表板中选择所有感兴趣时间序列的几率。
聚合、粒度和对齐
你可以通过用户界面中的下拉列表为每个时间序列指定聚合和粒度。
例如,如果聚合设置为 average
,粒度等于 1h
,则所有查询都请求符合所选聚合和粒度的数据点。默认情况下,与合成时间序列的聚合校准为 1970 年 1 月 1 日星期四 00:00:00 UTC。
使用合成时间序列查询语法,你可以单独为每个时间序列定义聚合、粒度和对齐:
ts{externalId='houston.ro.REMOTE_AI[34]', alignment=1599609600000, aggregate='average', granularity='24h'}
上面的查询将覆盖在用户界面中设置的聚合和粒度。请参阅 API 文档,获得可支持聚合的列表。
算术运算
你可以应用算术运算来组合时间序列。例如:
ts{id=123} + ts{externalId="test"}
上述查询的结果是单幅绘图,它的数据点是每个时间序列的总和。
在此示例中,查询 ts{name~="test1.*"}
可以返回多个时间序列,我们假定它返回了三个时间序列, ID 分别为 111
、222
和 333
:
ts{name~="test1.*"} + ts{id=123}
查询的结果是三幅绘图,查询中的第一个和第二个表达式返回的是时间序列总和的组合。获得的绘图代表三个查询:
ts{id=111} + ts{id=123}
ts{id=222} + ts{id=123}
ts{id=333} + ts{id=123}
在下图中(请注意图表下方的标签),你可以看到此行为的示例(每个 ts{}
表达式返回两个时间序列)。
函数
我们支持各种函数,你可以将其应用于合成时间序列:
- 三角函数:
sin(ts{})
、cos(ts{})
、pi()
。 - 可变长度函数:
max(ts{}, ...)
、min(ts{}, ...)
、avg(ts{}, ...)
。 - 代数:
ln(ts{})
、pow(ts{}, exponent)
、sqrt(ts{})
、exp(ts{})
、abs(ts{})
。 - 错误处理:
on_error(ts{}, default_value)
。请参阅计算中的错误处理。 - 字符串时间序列:
map(expression, [list of strings to map from], [list of values to map to], default_value)
请参阅字符串时间序列。
计算中的错误处理
借助 on_error(ts{...})
函数,即使在出现例外的情况仍可实现图表渲染。它可处理以下类似的错误:
BAD_DOMAIN
- 如果提供了错误的输入范围。例如,除以零,或者负数的平方根。OVERFLOW
- 如果结果的绝对值大于 10^100。
如果遇到任何这些情况,CDF 会返回包含出错消息的错误字段,而不返回代表时间戳的值。为了避免这些问题,你可以将 on_error()
函数中的(子)表达括起来。
on_error(1/ts{externalId='canBeZero'}, 0)
字符串时间序列
map()
函数可以处理包含字符串值的时间序列,以将字符串转换为双精度数。例如,如果阀门的时间序列可能包含值 "OPEN"
或 "CLOSED"
,则可以将其转换成以下数字:
map(TS{externalId='stringstate'}, ['OPEN', 'CLOSED'], [1, 0], -1)
"OPEN"
映射为 1,"CLOSED"
映射为 0,其他映射为 -1。
目前不支持对字符串时间序列进行聚合。所有字符串时间序列都被视为阶梯时间序列。
单位转换
如果时间序列定义了 unitExternalId
,则在使用自定义查询来查询数据时,可以将其值转换为等量的不同单位。
示例:
{ts{externalId='temperature_f_houston', targetUnit='temperature:deg_c'} + ts{id='123', targetUnitSystem='SI'}}
你可以为每个时间序列或聚合选择 targetUnit
或 targetUnitSystem
。所选的目标单位必须与原始单位兼容。
使用合成时间序列查询数 据点时,将不会保留值的单位。这意味着可能会将温度时间序列中的值添加到距离时间序列中,虽然这样在物理上并不准确。
注意,如果尝试在标签字段中访问每个时间序列的 unit
或 unitExternalId
属性,Grafana 将返回时间序列的原始单位,而非数据点的单位。
显示来自数据模型实例的时间序列数据
你可以显示来自 CDF 数据模型实例的时间序列数据:
-
在数据模型选项卡上,选择数据模型和版本。
-
指定查询。
重要在包含时间序列的字段下方添加
__typename
和externalId
。在此示例中,是位于temperature
和pressure
下方:{
listPump {
items {
temperature {
__typename
externalId
}
pressure {
__typename
externalId
}
}
}
}