构建

各不相同的传感器,汇于一块屏幕之上

作者: makemind · 2026年5月14日

一间温室上会挂好几个传感器。温度、湿度、CO2。再加上换气窗、阀门这些会动的东西。

刚装的时候这不是问题。三个就把三个写进代码。问题在三年后来。 温度计坏了,换成另一个产品。那个产品按华氏测。再加一个 CO2 传感器。再加一个阀门。

如果每次都得改控制代码,那这间温室就成了离开装它的人就修不了的东西。

节点自己说自己是什么

这个样例里,每个节点用六个字段声明自己。

printf("%s{\"id\":\"%s\",\"role\":\"%s\",\"kind\":\"%s\","
       "\"model\":\"%s\",\"unit\":\"%s\",\"value\":%.1f}",
       i ? "," : "", n->id, n->role, n->kind, n->model,
       n->unit, n->value);

id · role · kind · model · unit · value

unit 作为一个字段存在,是关键。 按华氏测的温度计就说华氏。它不会为了别人方便先替你换算成摄氏。硬件只诚实地说自己知道的,对齐这件事在上面做。

对齐的地方只有一处

/// The value moved into the unit the rules use.
///
/// This is the only place in this sample that knows about units, and it
/// decides from the unit a node declared, not from a model number. A sensor
/// nobody has ever heard of still states its unit, so it lands here exactly.
double get canonicalValue {
  switch (unit) {
    case 'F':
      return (value - 32) * 5 / 9;
    default:
      return value;
  }
}

要是按型号分支,这个地方立刻变成一份 清单。每买一个新产品就多一行,而清单上没有的产品进来时,会悄悄地用错值。

unit,第一次见的产品也自己对得上。

规则不认识零件号

一条种植规则七行。

Rule(
  name: 'vent above 26C',
  whenKind: 'temperature',
  above: 26.0,
  thenKind: 'vent',
  setTo: 80.0,
  elseSetTo: 0.0,
),

没写是哪个传感器。 也没写是哪个继电器。只有读的值的 种类 和要动的东西的 种类

不管是 TH-100 还是 FX-200,只要 kindtemperature,这条规则就看它。

真的换了一次

装机 A —— 摄氏温度计,三个节点。

A: discovered 3 nodes — t1:temperature:TH-100(C), h1:humidity:HM-20(pct), v1:vent:VT-9(pct)
A: vent above 26C: 26.1 -> v1=80.0
3 nodes — TH-100 摄氏, HM-20, VT-9
3 nodes — TH-100 摄氏, HM-20, VT-9
规则生效后 — vent 80%
规则生效后 — vent 80%

现在把温度计 换成华氏型号,再 加上 一个 CO2 传感器和一个阀门。

=== pass B: probe swapped for a Fahrenheit model, two nodes added ===
    server code: unchanged   rules: unchanged   rebuild: none
B: discovered 5 nodes — t1:temperature:FX-200(F), h1:humidity:HM-20(pct),
   c1:co2:CO-5(ppm), v1:vent:VT-9(pct), w1:valve:WV-3(pct)
B: vent above 26C: 26.1 -> v1=80.0   ·   water below 60% humidity: 62.8 -> w1=0.0
5 nodes — FX-200 华氏, CO-5 ppm, 新增 WV-3
5 nodes — FX-200 华氏, CO-5 ppm, 新增 WV-3
两条规则生效 — vent 80%, valve 0%
两条规则生效 — vent 80%, valve 0%

服务端代码没改。规则没改。没有重编译。

而且 vent above 26C 在两次装机里 都是在 26.1 触发的。 因为华氏传感器送来的值在一个地方被搬成了摄氏。没有那一个地方,华氏 79 度就会直接越过 26 度的阈值,换气窗会一直开着。

此内容需要开发者或更高等级

登录并升级您的方案即可继续阅读。

查看方案
Twitter