SensorBase.SensorBase¶
Abstract base class defining the interface for all Oizom sensor wrappers.
This module hosts GenericSensor, the abstract base class (ABC) that
every sensor wrapper in OzWrapper (battery, dust, noise, weather,
vibration, GPS, MPPT, soil, radiation, and roughly forty more) must inherit
from. The ABC pins down a uniform four-method lifecycle so the orchestrator
in Sensor.Sensor can drive any sensor type without special-casing
hardware specifics. All ~70 hardware drivers in drivers are reached
only through wrappers that subclass this class.
Lifecycle protocol (in call order):
initialize()– receive the device configuration the Gateway returned for this wrapper and stash any per-run state (calibration offsets, enable flags, last-known values for continuity across reboots).initializeSensor()– bring up a single physical sensor entry from the configuration (typically called byinitialize()once per"en": 1entry). Configures I2C/SPI/UART buses, instantiates the underlying driver, and verifies the device responds.getSensorReading()– perform one measurement cycle, read every initialized hardware sensor, apply averaging/calibration, and return a flat{parameter: value}mapping. Must be non-raising; on hardware error wrappers return zero-filled values so the data pipeline keeps flowing.putSensorValue()– merge this wrapper’s readings into the outbound payload dictionary that the orchestrator assembles across every active wrapper. Should callgetSensorReading()once per invocation.
The non-abstract helper putInitvalues() is an optional hook used by
wrappers that need to inject startup defaults or last-known values into the
first payload sent after boot.
Example
Minimal subclass implementing every abstract method:
from SensorBase import GenericSensor
class OzTemp(GenericSensor):
partNumber = "pn"
parameter = "temp"
def initialize(self, config, init_value):
for sensor in config.get("temp", []):
if sensor.get("en") == 1:
self.initializeSensor(sensor)
def initializeSensor(self, sensor):
# bring up the underlying driver, save handle on self
...
def getSensorReading(self):
return {"temp": 25.3, "hum": 60.0}
def putSensorValue(self, value):
value.update(self.getSensorReading())
return value
Note
Lifecycle methods run on the firmware’s scheduler thread, not the
HTTP/Gateway thread. Implementations must be re-entrant only with
respect to themselves: a single wrapper instance will never have two
of these methods executing concurrently, but other wrapper instances
may be running their own lifecycle methods in parallel on other
threads. Blocking I2C/SPI/UART reads inside getSensorReading()
will delay the next scheduled iteration, so individual reads should
be kept short and any long-running averaging done with bounded
in-memory buffers.
Classes¶
Abstract base class for all Oizom sensor wrappers. |