senml — Sensor Markup Language

Dieses Modul implementiert einen kleinen Encoder/Decoder für die Sensor Markup Language (SenML, RFC 8428). SenML ist ein Medientyp für Sensormessungen und Geräteparameter: Jedes „Pack“ ist eine Liste von „Records“, wobei jeder Record einen Namen, eine Einheit, einen Wert, einen Zeitstempel und optional eine Summe trägt.

Die Implementierung unterstützt sowohl die JSON- als auch die CBOR-Darstellung und erlaubt das Verschachteln von Packs, sodass ein einzelnes Root-Pack ein Gateway beschreiben kann, das mehreren Geräten vorgeschaltet ist. Eingehende Payloads können Aktuator-Callbacks auf bestehenden Records auslösen.

Beispielverwendung:

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())

Klassen

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

Repräsentiert ein SenML-Pack – eine Sammlung von SenmlRecord-Instanzen und optional weiteren untergeordneten SenmlPack-Objekten. Wenn ein Pack nur Records enthält, repräsentiert es ein einzelnes Gerät; wenn es weitere Packs enthält, fungiert es als Gateway.

name ist der SenML-Basisname (bn), der für jeden in diesem Pack enthaltenen Record verwendet wird.

callback wird von from_json / from_cbor aufgerufen, sobald ein eingehender Record einen zuvor unbekannten Sensor benennt; der neue SenmlRecord wird als erstes Argument übergeben und (bei verschachtelten Packs) das ursprüngliche Geräte-Pack als device=.... Es wird typischerweise zur Verarbeitung von Aktuator-Befehlen verwendet.

SenmlPack-Instanzen sind iterierbar – die Iteration liefert jeden Record in Einfügereihenfolge – und können als Kontextmanager verwendet werden, sodass sich das Pack beim Verlassen selbst aus seinem übergeordneten Element entfernt.

name: str

Der Basisname (bn) des Packs.

base_value: int | float | None

Optionaler Basiswert (bv), der beim Kodieren zum numerischen Wert jedes Records addiert und beim Dekodieren subtrahiert wird. Das Setzen eines nicht-numerischen Werts löst Exception aus.

base_time: int | float | None

Optionale Basiszeit (bt), die zum Zeitstempel jedes Records addiert wird.

base_sum: int | float | None

Optionale Basissumme (bs), die zum Summenfeld jedes Records addiert wird.

base_unit: str | None

Optionale Basiseinheit (bu) – typischerweise ein Wert aus SenmlUnits.

actuate

Der zum Konstruktionszeitpunkt angegebene Callback. Kann zur Laufzeit neu zugewiesen werden.

add(item: SenmlRecord | SenmlPack) None

Fügt item zu diesem Pack hinzu. item muss ein SenmlRecord oder ein weiteres SenmlPack sein und darf nicht bereits zu einem anderen übergeordneten Element gehören; andernfalls wird Exception ausgelöst.

remove(item: SenmlRecord | SenmlPack) None

Entfernt item aus diesem Pack. Exception wird ausgelöst, wenn item kein untergeordnetes Element dieses Packs ist.

clear() None

Entfernt jeden Record/jedes Sub-Pack aus diesem Pack und löst deren Referenz auf das übergeordnete Element auf.

from_json(data: str) None

Parst ein SenML/JSON-Dokument und führt die Records in dieses Pack zusammen. Records, die bereits existieren (über den Namen abgeglichen), lösen SenmlRecord.do_actuate() aus; neue Records werden angehängt und der Pack-weite callback wird aufgerufen.

to_json() str

Rendert das Pack und seine untergeordneten Elemente zu einem SenML/JSON-String.

from_cbor(data: bytes) None

Parst eine SenML/CBOR-Bytefolge und führt die Records in dieses Pack zusammen.

to_cbor() bytes

Rendert das Pack und seine untergeordneten Elemente zu einer SenML/CBOR-Bytefolge.

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

Interner Helfer, der beim Parsen eingehender Daten aufgerufen wird, wenn kein vorhandener Record zu einem Eintrag passt. Fügt einen neuen SenmlRecord zu device (oder zu diesem Pack) hinzu und leitet ihn an den callback weiter.

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

Repräsentiert eine einzelne Messung innerhalb eines SenmlPack.

name ist der SenML-Record-Name (n).

Die folgenden Schlüsselwortargumente werden akzeptiert:

  • valuebool, int, float, str oder bytearray. Andere Typen lösen Exception aus.

  • time – numerischer Zeitstempel (t).

  • unit – ein Einheiten-String, typischerweise ein Element von SenmlUnits.

  • sum – numerische integrierte Summe (s).

  • update_time – maximale Zeit, bevor der Sensor eine neue Messung liefert (ut).

  • callback – Funktion, die aufgerufen wird, wenn eine eingehende Payload diesen Record aktualisiert. Sie erhält den SenmlRecord als einziges Argument.

SenmlRecord kann als Kontextmanager verwendet werden, sodass er sich beim Verlassen selbst aus seinem übergeordneten Pack entfernt.

name: str

Record-Name (n).

value

Der aktuelle Wert. Bei einer Neuzuweisung wird der Typ geprüft; nur bool, Zahlen, str und bytearray werden akzeptiert. Um die gerenderte Genauigkeit eines Float-Werts zu steuern, runden Sie vor der Zuweisung, z. B. record.value = round(x, 2).

unit: str | None

Einheiten-String (u).

time: int | float | None

Mit dieser Messung verknüpfter Zeitstempel (t).

update_time: int | float | None

Maximale Zeit, bevor der Sensor eine aktualisierte Messung liefert (ut).

sum: int | float | None

Integriertes Summenfeld (s).

actuate

Der zum Konstruktionszeitpunkt angegebene Callback. Kann zur Laufzeit neu zugewiesen werden.

do_actuate(raw: dict, naming_map: dict) None

Aktualisiert diesen Record aus einem rohen eingehenden SenML-Dictionary und ruft, falls vorhanden, den Aktuator-Callback auf.

class senml.SenmlBase

Gemeinsame Basisklasse, die von SenmlPack und SenmlRecord genutzt wird. Sie stellt keine eigene öffentliche API bereit; sie existiert, damit SenmlPack.add() validieren kann, dass ein Element zur SenML-Hierarchie gehört.

class senml.SenmlUnits

Namespace-Klasse, deren Klassenattribute die durch RFC 8428 definierten SenML-Einheitensymbole sind. Jedes Attribut wird zum String-Code der Einheit aufgelöst, geeignet zur Zuweisung an SenmlRecord.unit oder SenmlPack.base_unit.

SENML_UNIT_METER: str

"m" – Meter.

SENML_UNIT_KILOGRAM: str

"kg" – Kilogramm.

SENML_UNIT_GRAM: str

"g" – Gramm.

SENML_UNIT_SECOND: str

"s" – Sekunde.

SENML_UNIT_AMPERE: str

"A" – Ampere.

SENML_UNIT_KELVIN: str

"K" – Kelvin.

SENML_UNIT_CANDELA: str

"cd" – Candela.

SENML_UNIT_MOLE: str

"mol" – Mol.

SENML_UNIT_HERTZ: str

"Hz" – Hertz.

SENML_UNIT_RADIAN: str

"rad" – Radiant.

SENML_UNIT_STERADIAN: str

"sr" – Steradiant.

SENML_UNIT_NEWTON: str

"N" – Newton.

SENML_UNIT_PASCAL: str

"Pa" – Pascal.

SENML_UNIT_JOULE: str

"J" – Joule.

SENML_UNIT_WATT: str

"W" – Watt.

SENML_UNIT_COULOMB: str

"C" – Coulomb.

SENML_UNIT_VOLT: str

"V" – Volt.

SENML_UNIT_FARAD: str

"F" – Farad.

SENML_UNIT_OHM: str

"Ohm" – Ohm.

SENML_UNIT_SIEMENS: str

"S" – Siemens.

SENML_UNIT_WEBER: str

"Wb" – Weber.

SENML_UNIT_TESLA: str

"T" – Tesla.

SENML_UNIT_HENRY: str

"H" – Henry.

SENML_UNIT_DEGREES_CELSIUS: str

"Cel" – Grad Celsius.

SENML_UNIT_LUMEN: str

"lm" – Lumen.

SENML_UNIT_LUX: str

"lx" – Lux.

SENML_UNIT_BECQUEREL: str

"Bq" – Becquerel.

SENML_UNIT_GRAY: str

"Gy" – Gray.

SENML_UNIT_SIEVERT: str

"Sv" – Sievert.

SENML_UNIT_KATAL: str

"kat" – Katal.

SENML_UNIT_SQUARE_METER: str

"m2" – Quadratmeter.

SENML_UNIT_CUBIC_METER: str

"m3" – Kubikmeter.

SENML_UNIT_LITER: str

"l" – Liter.

SENML_UNIT_VELOCITY: str

"m/s" – Geschwindigkeit.

SENML_UNIT_ACCELERATION: str

"m/s2" – Beschleunigung.

SENML_UNIT_CUBIC_METER_PER_SECOND: str

"m3/s" – Volumenstrom.

SENML_UNIT_LITER_PER_SECOND: str

"l/s" – Liter pro Sekunde.

SENML_UNIT_WATT_PER_SQUARE_METER: str

"W/m2" – Bestrahlungsstärke.

SENML_UNIT_CANDELA_PER_SQUARE_METER: str

"cd/m2" – Leuchtdichte.

SENML_UNIT_BIT: str

"bit" – Bit.

SENML_UNIT_BIT_PER_SECOND: str

"bit/s" – Bit pro Sekunde.

SENML_UNIT_DEGREES_LATITUDE: str

"lat" – Breitengrad.

SENML_UNIT_DEGREES_LONGITUDE: str

"lon" – Längengrad.

SENML_UNIT_PH: str

"pH" – Säuregrad (pH).

SENML_UNIT_DECIBEL: str

"db" – Dezibel.

SENML_UNIT_DECIBEL_RELATIVE_TO_1_W: str

"dBW" – Dezibel relativ zu 1 W.

SENML_UNIT_BEL: str

"Bspl" – Bel (Schalldruckpegel).

SENML_UNIT_COUNTER: str

"count" – Zähler.

SENML_UNIT_RATIO: str

"//" – Verhältnis (dimensionslos).

SENML_UNIT_RELATIVE_HUMIDITY: str

"%RH" – relative Luftfeuchtigkeit.

SENML_UNIT_PERCENTAGE_REMAINING_BATTERY_LEVEL: str

"%EL" – verbleibender Akkustand in Prozent.

SENML_UNIT_SECONDS_REMAINING_BATTERY_LEVEL: str

"EL" – verbleibender Akkustand in Sekunden.

SENML_UNIT_EVENT_RATE_PER_SECOND: str

"1/s" – Ereignisrate pro Sekunde.

SENML_UNIT_EVENT_RATE_PER_MINUTE: str

"1/min" – Ereignisrate pro Minute.

SENML_UNIT_BPM: str

"beat/min" – Schläge pro Minute.

SENML_UNIT_BEATS: str

"beats" – Schläge.

SENML_UNIT_SIEMENS_PER_METER: str

"S/m" – Siemens pro Meter (elektrische Leitfähigkeit).