跳到主要内容
版本:开发版

计算指标

计算指标是设备配置文件上的一种指标,它的值由公式计算得出,而不是由设备上报。上报 voltage 和 current 的电表,可以有一个计算指标 power_kw,公式为 voltage * current / 1000。此后 power_kw 会像设备自己上报的测量值一样被存储、绘制成图表、触发告警并显示在设备上。本章面向编写设备配置文件的人员,介绍什么是计算指标、如何编写、公式语言,以及公式无法产生值时会发生什么。

计算指标默认关闭。实例运维人员需要为你所在租户的套餐等级设置一个大于零的上限才能启用。参见启用计算指标。

什么是计算指标​

  • 公式读取一次上报中的指标:设备在同一次测量中一起上报的测量值、同一配置文件中的其他计算指标(参见串联计算指标),还可以读取设备自身携带的数字,例如校准系数(参见设备常量)。它不会读取更早的上报、其他设备或时钟。
  • 一次上报(一个样本)是一条消息在同一时刻携带的全部测量值,无论设备把它们拆分成了多少个条目。像 Sparkplug 和 LwM2M 设备那样每个条目只含一个指标的设备,只要这些指标的时刻相同,针对其中两个指标的公式同样会被计算。时刻必须完全一致:设备逐个打时间戳的指标,即使只相差一毫秒,也是各自独立的样本,公式不会跨样本读取。公式也只读取该消息携带的指标,因此只上报变化值的设备(Sparkplug 节点通常如此)只有在所有输入同时到达时才会得到计算值。如果同一指标在同一时刻出现两次,公式使用其中第一个值;两个值仍会按原样存储。
  • 结果在上报到达时只计算一次(或之后由回填为尚无值的上报补算),并作为普通测量值与设备上报的值一起存储。仪表板、历史记录、导出、设备的最新值和检测规则读取它的方式与其他指标相同,都是通过它的键。回填的值只出现在仪表板、历史记录和导出中;它不会改变最新值,也永远不会被检测规则评估。
  • **已存储的值不会被改变。**编辑公式并发布配置文件,只会改变之后到达的上报的计算结果;已经存储的值保留计算它们时生效的那个公式。回填只会为尚无值的过去上报补充值。
  • 指标是测量指标还是计算指标,在创建时就已确定。你可以编辑计算指标的公式,但不能把测量指标改为计算指标,反过来也不行。请删除它并新建一个。
  • 设备不能覆盖计算出的值。如果设备以某个计算指标的键上报了值,设备的值会被丢弃,保留计算得到的值。
  • 将仪表板小组件绑定到设备时,小组件的 Measurements(测量)字段会列出该设备已发布配置文件所声明的指标,并为计算指标显示 Calculated(计算)标记。选择某个指标即可将其加入或移出小组件;你仍然可以手动输入任意键。

编写计算指标​

打开一个设备配置文件,选择 Metrics(指标)选项卡(参见指标),然后选择 New metric(新建指标)。

  1. 将 Kind(类型)设为 Calculated(计算)。这个选择是最终的,因此编辑指标时它会被锁定。
  2. 填写 Metric key(指标键)、Token(令牌)和 Data type(数据类型):Double、Integer 或 Boolean。公式必须产生恰好该类型的结果(参见类型)。计算指标不能是字符串。
  3. 可选地设置 Unit(单位),以及 Min(最小值)和 Max(最大值)。超出该范围的结果会被跳过,不会存储。
  4. 输入 Formula(公式)。
  5. 选择 Create metric(创建指标)。

计算指标在指标列表中带有 Calculated(计算)标记。

与配置文件的所有编辑一样,新增或修改的公式只有在你发布版本之后才会对设备生效。

边输入边检查公式​

你输入时,公式框会请服务器检查公式,使用的是发布时检查公式、并在真实上报上计算公式的同一个编译器。公式框下方会显示:

  • 编译错误:如果公式无效,会用文字说明;
  • 估算成本与上限 100 的对比。估算成本高于 100 的公式会被拒绝;
  • 警告:警告不会阻止发布。例如,已发布的版本将该键声明为测量指标(因此设备可能正在上报它,这些值会被丢弃)、量级达到 1e12 或更大的结果无法存储,或单位不会被换算。

公式编译通过后,样本面板会列出公式读取的测量指标。为每个指标输入一个值,面板就会显示公式会产生的值,或者它不产生值的原因。如果公式读取了其他计算指标,面板还会显示它所依赖的链,并要求输入整条链读取的测量指标:其中的计算指标会根据你的样本按顺序计算出来,与上报到达时完全一致。如果公式读取设备常量,面板还会列出一个 Device constants(设备常量)分组:为每个常量输入设备元数据中会有的数字;留空则可以看到没有该常量的设备会得到什么。样本由你手工输入,不会存储任何内容。

用最近的历史数据试算公式​

在样本下方,Try it on recent history(用最近的历史数据试算)会在一台设备已存储的上报上运行公式。输入 Device token(设备令牌),选择一个时间窗口(最近 1、24 或 168 小时),然后选择 Run on history(在历史上运行)。面板会显示它评估了多少个样本、其中多少产生了值、多少被跳过以及原因,并列出最新的 50 个样本,包括公式读取的输入和得到的结果。一个样本是一条消息在同一时刻携带的那些上报,这正是上报到达时公式所看到的内容。不会存储任何内容。

  • 输入是已存储的值,保留 8 位小数(参见存储与精度)。上报到达时计算的值使用的是设备发送的全精度值,因此对于小数位多于 8 位的输入,两者可能不同:电流 0.000000015 A 会被存储为 0.00000002。面板会在每个结果上注明这一点,它显示的是预览,而不是将要存储的值。
  • 只显示公式读取的指标;一条消息若不含其中任何一个,就不算一个样本。公式读取的计算指标,取的是每条上报到达时为它存储的值(来自当时已发布的公式),而不是用草稿重新计算的值。
  • 如果公式读取设备常量,面板会对所有样本使用所输入设备的当前元数据,而不是该设备在每条上报被记录时的值。面板会在结果下方注明这一点。设备元数据中没有的常量会使其样本变为 missing_input。
  • 时间窗口最长 7 天。包含超过 50,000 个样本或超过 250,000 个输入值的窗口会被拒绝,而不是被截断。请选择更短的窗口。
  • 它需要读取该设备事件的权限。仅限部分客户的成员只能看到设备属于其中某个客户期间记录的上报。

发布检查会拒绝什么​

发布配置文件时会检查每个计算指标,并一次性报告所有问题。在以下情况下,配置文件会被拒绝:

  • 公式无法编译,或产生的类型与声明的类型不符;
  • 公式读取的键不是同一配置文件中已声明的指标;
  • 计算指标之间互相读取形成循环(消息会指出循环,例如 a -> b -> a),或某个指标读取它自己;
  • 计算指标的链超过 4 个(消息会指出这条链);
  • 公式没有读取任何指标(设备常量不是指标);
  • 公式读取的设备常量超过 8 个,或同一配置文件的所有公式合计读取超过 32 个;
  • 公式长度超过 1,024 字节,估算成本高于 100,或同一配置文件所有公式的成本合计超过 1,000。一条链上的公式在每次上报时都会全部计算,因此一条链的成本是其各公式成本之和;
  • 计算指标的 Min 大于 Max,声明了允许值列表,或其数据类型不是 Double、Integer 或 Boolean;
  • 同一个键被声明了两次;
  • 配置文件的计算指标数量超过你所在租户的套餐等级允许的数量。

规则预览中的计算指标​

当你预览检测规则时(规则表单或自动化画布上的 Preview against history(基于历史预览)),预览会使用配置文件草稿中的计算指标。每条回放的上报都会用草稿中的公式,根据其测量值重新计算计算指标,取代它到达时存储的值。因此,针对你刚添加或编辑的计算指标的规则,会以你发布后该指标将具有的值进行预览;草稿中已不存在的计算指标在预览中没有值。预览会说明重新计算了多少条上报,以及有多少个公式结果没有产生值。互相读取的计算指标会按依赖顺序重新计算,与上报到达时一致。

读取设备常量的公式,会用每台设备的当前元数据重新计算,元数据在你运行预览时读取。因此,以较早的值存储的上报会按今天的值预览,可能与当时存储的值不同。元数据中没有某个常量的设备,其上报没有值。如果无法读取这些常量,或配置文件的设备超过 10,000 台,结果会明确说明,而不会用默认值计算。

重新计算读取的是设备发送时的原始全精度值,因此它给出的值与已发布公式对该上报计算的值相同。有两件事它无法还原:上报到达时已被丢弃的值(例如设备以当时属于计算指标的键发送的值),以及测量指标定义的变化。只有计算值会被重新计算。预览计算的任何内容都不会被存储,也不会进入正在运行的规则。

公式语言​

公式使用一种小型表达式语言编写。它没有循环、没有字符串,也没有状态,因此每个公式都在很小且有界的时间内运行。

输入​

配置文件的每个测量指标都是一个以其键命名的变量,例如 voltage 或 temp,它可以读取的每个计算指标也是(参见串联计算指标)。不是普通标识符的键,例如 flow-rate,要写成 m["flow-rate"] 读取,并包上与其类型对应的转换:double(m["flow-rate"])、int(m["count"]) 或 bool(m["door"])。

运算符​

类别运算符
算术+ - * / % 以及一元 -
比较== != < <= > >=
逻辑&& || !
条件condition ? a : b

数学函数​

math.abs(x)、math.floor(x)、math.ceil(x)、math.round(x)(一半的情况向远离零的方向取整)、math.sqrt(x)、math.pow(x, n)、math.min(a, b)、math.max(a, b) 和 math.clamp(x, low, high)。

math.pow 只接受整数指数:math.pow(x, 2) 可以使用,math.pow(x, 0.5) 不行。小数次幂在不同处理器架构上可能在最后一位出现差异,而存储的值不应取决于由哪台机器计算。需要平方根时,请使用 math.sqrt。

存在性判断​

has(m.fan) 和 "fan" in m 用来判断一次上报是否带有 fan 的值。你可以借此为缺失的输入给出明确的默认值:has(m.fan) ? fan : 0.0。

串联计算指标​

公式可以按键读取同一配置文件中的另一个计算指标,读取方式与测量指标完全相同。有功功率、视在功率和功率因数构成一条由三个指标组成的链:

键公式
kvavoltage * current / 1000.0
kwkva * pf_in
pfkw / kva
  • 一条链最多包含 4 个计算指标。 只读取测量指标的公式是长度为 1 的链,上面的 kw 长度为 2,pf 为 3。发布时会拒绝更长的链并指出它。计算指标之间也不能直接或经由其他指标形成循环,发布时会指出该循环。
  • 它们按依赖顺序计算,每次上报计算一次,与你声明它们的顺序无关。每个公式都在它所读取的内容之后运行。
  • 下游公式读取的是该上报所记录的值。 kva 的结果在被 kw 读取之前,已经按其数据类型格式化,因此 Integer 指标是整数,Boolean 就是 1 或 0;kw 读取的正是该上报中 kva 的值,也就是检测规则和实时视图看到的值。随后存储会将其四舍五入到 8 位小数(参见存储与精度),因此对于小数位多于 8 位的值,历史记录中显示的 kva 比计算 kw 时所用的值精度更低。
  • 如果上游指标没有产生值,读取它的公式也不会产生值。 若 kva 被跳过,kw 会以 missing_input 被跳过,经由它的 pf 也是如此。要给这样的公式提供备用值,请像对待任何输入一样先判断:has(m.kva) ? kva : 0.0。
  • 设备不能提供链中的某一环。 设备以计算指标的键发送的值会被丢弃,因此永远不会到达读取该键的公式。
  • 上报的标识不会改变:计算值(无论是否串联)都不属于标识的一部分,因此重发的上报仍会被识别为同一条上报。
  • 串联的值与其他计算值一样,由上报和当时生效的配置文件版本计算得出,因此同一条上报在每个副本和每次预览中得到相同的值。

设备常量​

公式可以读取属于某台设备而不是某次上报的数字,例如校准系数或电流互感器变比。写法是 device. 加名称:voltage * device.calibration。名称不是普通标识符时,写成 device["ct-ratio"]。device 这个名称为此保留:键为 device 的测量指标要通过 m 读取,并包上与其类型对应的转换,例如 double(m["device"])。

这个数字来自设备的元数据。编辑设备,把常量以同名的 JSON 数字放进它的元数据:

{ "site": "north plant", "calibration": 1.02 }
  • 在公式里写出常量名就是声明它。 配置文件上不需要再设置别的。发布时无法知道哪些设备带有哪些常量,只会检查公式能否编译、是否把常量当作数字使用。
  • 每个常量都是 double。整数就是没有小数部分的 double,int(device.step) 会把它读成整数。只读取常量而不读取任何测量指标的公式会被拒绝。
  • 一个公式最多读取 8 个常量,同一配置文件的所有公式合计最多 32 个。
  • 常量必须是 JSON 数字。写成文本的数字("1.02")、布尔值、null、对象或列表都不是数字,也绝不会被转换。
  • 与测量输入一样,除非公式对常量做了存在性判断,否则它是必需的。元数据中没有它的设备会以 missing_input 被跳过;其中的值不是有限数的设备会以 invalid_input 被跳过。需要默认值时,请先判断:has(device.calibration) ? device.calibration : 1.0,或 "calibration" in device。
  • 值会固化在结果中。 常量在上报到达时读取,计算出的值与其他值一样存储。之后编辑设备的元数据,只会改变此后到达的上报的计算结果(服务可能需要几秒钟才能看到变化),绝不会改变已存储的值。
  • 每台设备有自己的常量,所以同一类型的两台设备可以有不同的值,同一个公式会给每台设备各自的结果。

类型​

公式会按指标的数据类型检查,检查十分严格:

  • 整数和 double 可以在 + - * / 以及大小比较中混用(整数会被提升)。它们不能在 == 或 != 中混用,也不能出现在 condition ? a : b 的两个分支中:与 double 比较时,请写 80.0 而不是 80。
  • Double 指标的公式必须产生 double。产生整数的公式需要使用 double(...)。
  • Integer 指标的公式必须产生整数。用 int(...) 转换 double。math.sqrt 和 math.pow 返回 double,因此用于 Integer 指标时要包上 int()。
  • Boolean 指标的公式必须产生布尔值,例如 temp > 80.0 && fan == 0。布尔值以 1 和 0 存储。

不可用的内容​

字符串(m["key"] 中作为键的情况除外)、列表、映射、时间和时长、随机数、推导式、正则表达式,以及任何读取上报之外内容的东西。

公式不产生值时​

如果公式无法为某次上报产生值,该指标在这次上报中会被跳过。上报的其余部分照常存储,而且绝不会用其他值代替:没有默认值,也不会补零。原因如下:

原因含义
missing_input公式读取的某个输入不在这次上报中,或它读取的某个设备常量不在设备的元数据中。除非公式用 has() 或 in 判断过它,否则该输入或常量是必需的。
invalid_input输入存在,但对其类型而言不是有效值;或设备常量存在,但不是数字。
non_finite某个数不是有限值:输入或设备常量不是有限数、除以零、结果对 double 来说太大,或对负数取平方根。
div_zero整数除以零,或对零取余。
overflow整数结果或转换超出 64 位。
range结果超出了该指标的 Min 和 Max。
unstorable结果的量级达到 1e12 或更大,测量值无法以这样的量级存储。
eval_error其他任何失败,例如 math.clamp 的上下界颠倒。

不携带公式任何输入的上报不算跳过。 设备常常把各项指标分成多条消息发送(每秒一次温度、每小时一次电量)。只有当一条上报携带了公式所依赖的至少一个测量指标(直接依赖,或经由其读取的计算指标间接依赖)时,才会对该公式求值;一条一个都不携带的上报根本不属于这个公式,既不计算,也不计入 calcmetric_skipped_total。因此 missing_input 的含义是:上报携带了公式的部分输入,却缺少必需的某一个。对所读取的每个输入都用 has() 判断的公式,或未经判断的输入只有此类计算指标的公式,仍像以前一样对每条上报求值。

无论操作数的顺序如何,缺失的输入都会被发现。temp > 80.0 || fan > 1 在没有 fan 的上报上会被跳过,即使较高温度的上报会使前半部分为真。如果你希望公式在没有 fan 时也能工作,请用 has() 判断它。

检查指标是否在计算​

公式可以通过编译并发布,却始终不产生任何值,例如它读取的输入以另一个名称到达。在配置文件的版本选项卡上,使用中的计算指标区块会针对生效版本的每个计算指标,显示是否正在存储它的值。该区块面向拥有设备和事件读取权限的人员;仅限客户范围的用户看不到它,因为这些计数覆盖整个租户。已被替换的版本没有区块,因为没有设备会解析它。

该区块根据已存储的读数统计。计算值与任何读数一样被存储,因此对每个指标,它会比较以该指标键存储的值的数量与其输入的读数数量(公式读取的测量指标,包括通过它所串联的计算指标读取的那些)。选择最近 24 小时或最近 168 小时(7 天)可切换窗口。不做任何抽样或估算。

状态含义
正在计算窗口内已存储该指标的值。
未确认窗口内已以该指标的键存储了值,但另一个配置文件也声明了同键的指标,因此这些值可能全部来自那个配置文件(见下文)。
未计算输入在窗口内有已存储的读数,但没有存储该指标的值。用**为什么?**查明原因。
无输入读数窗口内该指标及其输入都没有读数,因此没有可供计算的内容。
输入未知生效版本的公式无法在当前平台版本上运行(无法编译,或其数据类型无法计算),因此它不计算任何值,也无法读取其输入。不显示该指标的计数。

阅读计数时需要注意:

  • 计数从版本生效时开始。 更早存储的读数不可能由此版本计算,因此被排除,表格上方的一行会说明起始时间。对于在开始记录生效时间之前就已生效的版本,该时间取自配置文件的版本历史;它可能早于实际生效时间,但绝不会更晚,因此计数可能包含生效前不久的少量读数。
  • 分开发送的消息没有问题。 一台设备每秒发送一个指标、每小时发送另一个指标,并不意味着它在没有发送第二个指标的那些秒里"跳过"了公式。该区块从不与消息数量比较,只比较已存储的值与输入读数。
  • 计数按读数发生的时间统计,因此延迟转发的一批旧读数会落在它们所属的小时内。计数最多回溯到租户的测量数据保留期。
  • 与其他配置文件重名。 如果租户的另一个配置文件也声明了同键的指标,计数会包含该配置文件的读数,无法证明此公式在正常工作。该行会注明这一点;请改为在此配置文件的某台设备上使用为什么?。

询问原因​

**为什么?**会打开编写时使用的同一个"用最近的历史数据试算"视图,使用该指标在生效版本中的公式及该版本读取的输入(草稿可能不同)。输入一台报告了公式输入的设备的令牌并运行:它会在该设备已存储的读数上计算公式,并按原因统计未产生值的读数(参见公式不产生值时)。不会存储任何内容。

回填历史数据​

计算指标在上报到达时计算。因此,在定义它的版本发布之前已存储的上报没有该指标的值,那段时间的图表上会出现空缺。回填会为这些已存储的上报计算该指标并补上缺失的值,使过去时间段的图表和导出也能显示它。

启动回填​

打开配置文件,选择 Versions(版本)选项卡,在 Backfilling history(回填历史数据)下选择 Backfill history(回填历史)。启动和取消回填需要 device:write 权限,受客户范围限制的用户完全看不到这部分。发布一个新增了计算指标的版本后,控制台会询问一次是否为它回填历史数据。

  1. Version(版本)。使用其公式的已发布版本。默认打开当前生效的版本。草稿不能回填。
  2. Metrics to fill(要回填的指标)。所选版本中新增的指标(上一个已发布版本没有计算它们)会被选中。你也可以选择公式自更早版本以来发生变化的指标。它会被标出,因为此时回填会用本版本的公式为没有值的上报补值,而以旧公式存储的上报保留原值。如果某个指标读取了你没有选中的另一个计算指标,也会收到警告:那个指标可能保存着旧公式的值,新值将基于这些值计算。
  3. From / To(起止时间)。要回填的范围。默认是该版本生效之前的 30 天,即实时计算接手的位置。一个范围最长 90 天;更长的历史请分多次回填。
  4. Devices(设备)。可选。按令牌指定最多 1,000 台设备,留空则回填该配置文件的所有设备。

先试一台设备​

在回填整个设备群之前,请使用 Try one device first(先试一台设备):输入一台设备的令牌并启动。它只对这一台设备运行同样的回填。运行和重复运行都是安全的,因为回填绝不会改变已存储的值。打开该设备的图表,检查数值,然后再启动其余设备。已经回填过的设备会被计为已有值,不会重复写入。

回填做什么​

  • 只补充值。 已经有该指标值的上报保留原值,并计为已存在。已存储的值绝不会被改变。
  • 读取已存储的数据。 输入是已存储的上报(保留 8 位小数),设备常量则按回填处理到该设备时其元数据中的值读取。因此,回填得到的值在末几位上可能与上报到达时计算的值不同。任务中会注明这一点("8 decimal places")。
  • 不产生通知。 回填的值会出现在仪表板、历史记录和导出中,但不会改变设备的最新值,检测规则也永远看不到它,因此回填不会为过去的上报触发告警。
  • 长时间范围的图表在任务完成后更新。 读取预聚合数据(长时间范围)的图表,要等任务刷新这些数据后才会显示回填的值,这是任务的最后一步。
  • 不会早于设备创建时间。 时间早于设备创建的上报不会被回填,因此被重复使用的令牌不会得到早先那台设备的值。

限制​

限制值
范围最长 90 天,且结束时间不晚于当前时间。
保留期范围起点不能早于租户的测量值保留策略所允许的时间;这样的请求会被拒绝,而不是被缩短。任务运行期间过期的时间段会被跳过。
压缩的历史数据事件存储已压缩的历史数据(默认为 7 天之前)在此版本中会被跳过,并在任务上计数。
设备最多 1,000 台指定设备,或该配置文件的所有设备。
并发每个租户同时只能有一个活动(排队或运行中)的回填。启动第二个会被拒绝,并指出当前活动的那个。

查看任务​

任务面板列出每个回填的状态(排队、运行中、完成、已取消或失败)、已完成设备数与总数、写入的值数、查看过的上报数及其中已有值的数量,以及按原因统计的未计算项。原因包括公式不产生值时列出的那些,以及:

原因含义
ambiguous一条已存储的上报中同一输入出现两次且值不同,因此无法选出唯一的值。该上报不会写入任何内容。

面板还会统计被跳过的压缩历史时间段和超出保留期的时间段。Cancel(取消)会立即停止排队中的任务,并让运行中的任务在下一批处理时停止;已写入的值会保留。失败的任务会说明原因;启动新的回填即可继续,它会跳过已经填好的部分。

回填对已存储上报的分组方式与实时计算完全相同:一次上报是一条消息在同一时刻的全部测量值(参见什么是计算指标)。因此,对于 Sparkplug 或 LwM2M 设备分条目发送的两个指标,只要它们的时刻完全相同,针对它们的公式就会被回填,与实时计算一致。如果设备给它们打的时间戳不同(哪怕只差一毫秒),或者消息没有携带全部输入(例如只上报变化值的设备),则无论实时还是回填都不会产生值。

控制被禁用时​

当配置文件尚未发布任何版本,或当前生效的版本没有计算指标时,Backfill history 按钮会被禁用,并在旁边说明原因。当实例无法运行回填(例如运维人员关闭了回填工作进程)时,控制台会在页面打开时询问实例,按钮和对话框从一开始就处于禁用状态并说明原因。如果这个询问没能得到答复,而启动又被拒绝,则此后在你离开该页面之前,按钮和对话框都会保持禁用并说明原因。它不会因这些原因被隐藏。

存储与精度​

  • 测量值存储时,小数点前最多 12 位,小数点后 8 位。计算值在存储时会四舍五入到 8 位小数,量级达到 1e12 或更大的结果会以 unstorable 跳过。将 Min 和 Max 设在正负 999,999,999,999 之内,就等于告诉编辑器你清楚该范围,这条警告也就不再出现。
  • 计算值与任何测量值一样存储,因此遵循你所在租户的测量值保留策略。
  • 单位不会被换算或检查。公式把输入当作普通数字读取,结果只带你在计算指标上声明的单位。
  • 计算值由其读数、指标名称和时刻来标识,而不是由值本身标识。如果同一条消息为同一时刻携带了两个样本,则每个指标名称只会产生一行计算值,并保留最先写入的值。

启用计算指标​

单个配置文件可以发布多少个计算指标,由实例运维人员按套餐等级设置,位置是 Admin → Tiers 中的 Calculated metrics per profile。平台默认值为 0,表示计算指标处于关闭状态:你可以编写并测试公式,但发布含有计算指标的配置文件会被拒绝,并提示:

cannot publish device profile: it has N calculated metric(s), and calculated metrics are not enabled for this tenant's tier

当上限大于零但小于配置文件中的数量时,提示会说明该套餐等级每个配置文件允许的数量。任何套餐等级最多只能授予 32 个。如果你需要计算指标,请让运维人员提高上限。