senml --- 传感器标记语言(Sensor Markup Language)

本模块实现了一个用于传感器标记语言(SenML,RFC 8428)的小型编码器/解码器。SenML 是一种用于传感器测量值和设备参数的媒体类型:每个“pack”是一个“record”列表,其中每条 record 都带有名称、单位、值、时间戳以及可选的累加值。

该实现同时支持 JSON 和 CBOR 两种表示形式,并允许将 pack 嵌套,从而使单个根 pack 能够描述一个面向多台设备的网关。入站负载可以驱动现有 record 上的执行器回调。

示例用法:

from senml import SenmlPack, SenmlRecord, SenmlUnits

# A pack collects readings for one device, identified by URN.
pack = SenmlPack("urn:dev:mac:0024befffe804ff1")

# Add a temperature reading in degrees Celsius.
pack.add(SenmlRecord(
    "temperature",
    unit=SenmlUnits.SENML_UNIT_DEGREES_CELSIUS,
    value=23.4,
))

# Add a humidity reading in %RH.
pack.add(SenmlRecord(
    "humidity",
    unit=SenmlUnits.SENML_UNIT_RELATIVE_HUMIDITY,
    value=51.2,
))

# Render the pack as a SenML/JSON document.
print(pack.to_json())

class senml.SenmlPack(name: str, callback=None)

表示一个 SenML pack —— 由若干 SenmlRecord 实例以及可选的其他子 SenmlPack 对象组成的集合。当某个 pack 仅包含 record 时,它表示单台设备;当它包含其他 pack 时,则充当网关。

name 是 SenML 基础名称(bn),用于此 pack 中包含的每条 record。

callbackfrom_json / from_cbor 中被调用,每当一条入站 record 命名了一个先前未知的传感器时触发;新建的 SenmlRecord 作为第一个参数传入,(对于嵌套 pack)发起方设备 pack 则通过 device=... 传入。它通常用于处理执行器命令。

SenmlPack 实例是可迭代的 —— 迭代会按插入顺序逐个产出 record —— 并且可以用作上下文管理器,从而在退出时让该 pack 将自身从其父级中移除。

name: str

该 pack 的基础名称(bn)。

base_value: int | float | None

可选的基础值(bv),在编码时加到每条 record 的数值上,在解码时再减去。设置为非数值会引发 Exception

base_time: int | float | None

可选的基础时间(bt),加到每条 record 的时间戳上。

base_sum: int | float | None

可选的基础累加值(bs),加到每条 record 的 sum 字段上。

base_unit: str | None

可选的基础单位(bu)—— 通常取自 SenmlUnits 中的某个值。

actuate

构造时提供的回调。可在运行时重新赋值。

add(item: SenmlRecord | SenmlPack) None

item 追加到此 pack。item 必须是 SenmlRecord 或另一个 SenmlPack,且不能已经属于其他父级;否则会引发 Exception

remove(item: SenmlRecord | SenmlPack) None

从此 pack 中移除 item。如果 item 不是此 pack 的子项,则会引发 Exception

clear() None

从此 pack 中移除每一条 record/子 pack,并解除它们对父级的引用。

from_json(data: str) None

解析一个 SenML/JSON 文档并将其中的 record 合并到此 pack 中。已存在(按名称匹配)的 record 会触发 SenmlRecord.do_actuate();新的 record 会被追加,并调用 pack 级别的 callback

to_json() str

将该 pack 及其子项渲染为一个 SenML/JSON 字符串。

from_cbor(data: bytes) None

解析一个 SenML/CBOR 字节串并将其中的 record 合并到此 pack 中。

to_cbor() bytes

将该 pack 及其子项渲染为一个 SenML/CBOR 字节串。

do_actuate(raw: dict, naming_map: dict, device: SenmlPack | None = None) None

在解析入站数据时,当没有现有 record 与某个条目匹配时调用的内部辅助方法。它会向 device(或向此 pack)添加一条新的 SenmlRecord,并将其转发给 callback

class senml.SenmlRecord(name: str, **kwargs)

表示 SenmlPack 内部的单次测量。

name 是 SenML record 名称(n)。

可接受以下关键字参数:

  • value —— boolintfloatstrbytearray。其他类型会引发 Exception

  • time —— 数值时间戳(t)。

  • unit —— 单位字符串,通常是 SenmlUnits 的某个成员。

  • sum —— 数值积分累加值(s)。

  • update_time —— 传感器提供新读数之前的最长时间(ut)。

  • callback —— 当入站负载更新此 record 时调用的函数。它接收 SenmlRecord 作为唯一参数。

SenmlRecord 可以用作上下文管理器,从而在退出时将自身从其父 pack 中移除。

name: str

Record 名称(n)。

value

当前值。重新赋值时会检查类型;仅接受 bool、数字、strbytearray。要控制浮点值渲染时的精度,请在赋值前先四舍五入,例如 record.value = round(x, 2)

unit: str | None

单位字符串(u)。

time: int | float | None

与此次测量关联的时间戳(t)。

update_time: int | float | None

传感器提供更新读数之前的最长时间(ut)。

sum: int | float | None

积分累加值字段(s)。

actuate

构造时提供的回调。可在运行时重新赋值。

do_actuate(raw: dict, naming_map: dict) None

根据一个原始的入站 SenML 字典更新此 record,并在存在时调用执行器回调。

class senml.SenmlBase

SenmlPackSenmlRecord 共享的公共基类。它本身不暴露任何公共 API;其存在的意义在于让 SenmlPack.add() 能够验证某个 item 属于 SenML 层次结构。

class senml.SenmlUnits

一个命名空间类,其类属性为 RFC 8428 所定义的 SenML 单位符号。每个属性都解析为该单位的字符串代码,适合赋值给 SenmlRecord.unitSenmlPack.base_unit

SENML_UNIT_METER: str

"m" —— 米。

SENML_UNIT_KILOGRAM: str

"kg" —— 千克。

SENML_UNIT_GRAM: str

"g" —— 克。

SENML_UNIT_SECOND: str

"s" —— 秒。

SENML_UNIT_AMPERE: str

"A" —— 安培。

SENML_UNIT_KELVIN: str

"K" —— 开尔文。

SENML_UNIT_CANDELA: str

"cd" —— 坎德拉。

SENML_UNIT_MOLE: str

"mol" —— 摩尔。

SENML_UNIT_HERTZ: str

"Hz" —— 赫兹。

SENML_UNIT_RADIAN: str

"rad" —— 弧度。

SENML_UNIT_STERADIAN: str

"sr" —— 球面度。

SENML_UNIT_NEWTON: str

"N" —— 牛顿。

SENML_UNIT_PASCAL: str

"Pa" —— 帕斯卡。

SENML_UNIT_JOULE: str

"J" —— 焦耳。

SENML_UNIT_WATT: str

"W" —— 瓦特。

SENML_UNIT_COULOMB: str

"C" —— 库仑。

SENML_UNIT_VOLT: str

"V" —— 伏特。

SENML_UNIT_FARAD: str

"F" —— 法拉。

SENML_UNIT_OHM: str

"Ohm" —— 欧姆。

SENML_UNIT_SIEMENS: str

"S" —— 西门子。

SENML_UNIT_WEBER: str

"Wb" —— 韦伯。

SENML_UNIT_TESLA: str

"T" —— 特斯拉。

SENML_UNIT_HENRY: str

"H" —— 亨利。

SENML_UNIT_DEGREES_CELSIUS: str

"Cel" —— 摄氏度。

SENML_UNIT_LUMEN: str

"lm" —— 流明。

SENML_UNIT_LUX: str

"lx" —— 勒克斯。

SENML_UNIT_BECQUEREL: str

"Bq" —— 贝可勒尔。

SENML_UNIT_GRAY: str

"Gy" —— 戈瑞。

SENML_UNIT_SIEVERT: str

"Sv" —— 希沃特。

SENML_UNIT_KATAL: str

"kat" —— 卡特。

SENML_UNIT_SQUARE_METER: str

"m2" —— 平方米。

SENML_UNIT_CUBIC_METER: str

"m3" —— 立方米。

SENML_UNIT_LITER: str

"l" —— 升。

SENML_UNIT_VELOCITY: str

"m/s" —— 速度。

SENML_UNIT_ACCELERATION: str

"m/s2" —— 加速度。

SENML_UNIT_CUBIC_METER_PER_SECOND: str

"m3/s" —— 体积流量。

SENML_UNIT_LITER_PER_SECOND: str

"l/s" —— 升每秒。

SENML_UNIT_WATT_PER_SQUARE_METER: str

"W/m2" —— 辐照度。

SENML_UNIT_CANDELA_PER_SQUARE_METER: str

"cd/m2" —— 亮度。

SENML_UNIT_BIT: str

"bit" —— 比特。

SENML_UNIT_BIT_PER_SECOND: str

"bit/s" —— 比特每秒。

SENML_UNIT_DEGREES_LATITUDE: str

"lat" —— 纬度(度)。

SENML_UNIT_DEGREES_LONGITUDE: str

"lon" —— 经度(度)。

SENML_UNIT_PH: str

"pH" —— 酸度(pH)。

SENML_UNIT_DECIBEL: str

"db" —— 分贝。

SENML_UNIT_DECIBEL_RELATIVE_TO_1_W: str

"dBW" —— 相对于 1 W 的分贝。

SENML_UNIT_BEL: str

"Bspl" —— 贝尔(声压级)。

SENML_UNIT_COUNTER: str

"count" —— 计数器。

SENML_UNIT_RATIO: str

"//" —— 比率(无量纲)。

SENML_UNIT_RELATIVE_HUMIDITY: str

"%RH" —— 相对湿度。

SENML_UNIT_PERCENTAGE_REMAINING_BATTERY_LEVEL: str

"%EL" —— 以百分比表示的剩余电量。

SENML_UNIT_SECONDS_REMAINING_BATTERY_LEVEL: str

"EL" —— 以秒为单位的剩余电量。

SENML_UNIT_EVENT_RATE_PER_SECOND: str

"1/s" —— 每秒事件率。

SENML_UNIT_EVENT_RATE_PER_MINUTE: str

"1/min" —— 每分钟事件率。

SENML_UNIT_BPM: str

"beat/min" —— 每分钟心跳数。

SENML_UNIT_BEATS: str

"beats" —— 心跳次数。

SENML_UNIT_SIEMENS_PER_METER: str

"S/m" —— 西门子每米(电导率)。