ES12248.ES12248

class ES12248.ES12248

Modbus RTU driver for the ES12248 temperature and humidity sensor.

Talks to the ES12248 industrial probe over RS-485 using Modbus RTU. The sensor measures ambient air temperature (degrees Celsius) and relative humidity (percent RH); both quantities are exposed via dedicated getter methods that return floating-point values scaled from the raw register integers.

Internally, register reads are wrapped in a small retry loop (up to three attempts with a 0.5 s pause between failures) and the most recent decoded reading is cached on self.data. If a parse step fails after a successful transport-level read, the cached value is returned as a graceful fallback instead of propagating the exception.

Variables:
  • DEBUG (bool) – Class-level flag that enables verbose Modbus transaction and parsed-value logging when True.

  • client (pymodbus.client.sync.ModbusSerialClient | None) – Active Modbus serial client created by initialize(), or None before initialization or after close().

  • SLAVE_ID (int) – Modbus slave (unit) ID used in every read. Set by initialize(); defaults to 1.

  • data (dict[str, float | None]) – Cached sensor data dictionary with "temperature" and "humidity" keys holding the last successfully decoded readings in physical units.

Example

>>> from drivers.ES12248.ES12248 import ES12248
>>> sensor = ES12248()
>>> sensor.initialize()
True
>>> sensor.get_temperature()
24.7
>>> sensor.get_humidity()
51.2
>>> sensor.close()

Note

Although conceptually a sensor driver in the same family as classes derived from SensorBase.SensorBase.GenericSensor, this class is currently standalone and does not inherit from that base.

Construct an uninitialized ES12248 driver instance.

Sets up internal state with no active Modbus client and an empty reading cache. The constructor does not open any serial port; call initialize() to establish communication with the sensor.

Parameters:

None.

Returns:

This is an initializer and returns None implicitly.

Return type:

None

Raises:

None – Constructing the object never raises; failures are deferred to initialize().

Example

>>> from drivers.ES12248.ES12248 import ES12248
>>> sensor = ES12248()
>>> sensor.client is None
True
>>> sensor.data
{'temperature': None, 'humidity': None}

Note

SLAVE_ID is initialized to 1 here and will be overwritten by initialize() if a different slave ID is supplied.

_read_registers(address=0, count=2)

Read a contiguous block of Modbus holding registers with retries.

Sends a read_holding_registers request to the configured slave (self.SLAVE_ID) starting at address for count registers. The request is retried up to three times if the transport layer raises an exception or the response indicates an error, with a 0.5-second pause between attempts.

Parameters:
  • address (int) – Zero-based starting address of the first holding register to read. Defaults to 0 (temperature register).

  • count (int) – Number of consecutive 16-bit registers to read. Defaults to 2.

Returns:

The list of raw 16-bit register values returned by the sensor on success, or None if all three attempts failed (either because of repeated transport exceptions or because the Modbus response reported an error).

Return type:

list[int] | None

Raises:

None – Per-attempt exceptions are logged and counted as retries; they are not re-raised to the caller.

Example

>>> from drivers.ES12248.ES12248 import ES12248
>>> sensor = ES12248()
>>> sensor.initialize()
True
>>> registers = sensor._read_registers(address=0, count=2)
>>> len(registers) if registers is not None else None
2

Note

Despite the leading underscore this helper is fully usable by subclasses or by maintenance scripts that need a low-level register read; the name only signals that it is not part of the stable public driver surface.

close()

Close the Modbus serial connection if one is currently open.

Releases the underlying serial port held by self.client by delegating to ModbusSerialClient.close(). The call is a no-op when no client has been created (for example when initialize() was never called or already failed).

Parameters:

None.

Returns:

This method does not return a value.

Return type:

None

Raises:

None – Any exception raised by the Modbus client during close() would propagate, but in normal operation this call is idempotent and safe to invoke from finally blocks.

Example

>>> from drivers.ES12248.ES12248 import ES12248
>>> sensor = ES12248()
>>> sensor.initialize()
True
>>> sensor.close()

Note

After close(), the cached self.data dictionary still holds the last successfully decoded readings, so they remain available for read-only inspection even after the serial port is released.

get_humidity()

Read the current relative humidity from the ES12248.

Issues a Modbus holding-register read of register 1 (one register), interprets the resulting 16-bit value as humidity * 100, and converts it to percent relative humidity by dividing by 100.0. The decoded value is cached on self.data["humidity"] for use as a fallback by subsequent calls.

Parameters:

None.

Returns:

Measured relative humidity in percent (%RH). Returns None if the underlying Modbus read fails after all retries. If decoding fails after a successful read, the previously cached humidity is returned instead (which may itself be None).

Return type:

float | None

Raises:

None – Parse errors are caught, logged, and converted into a cached-value fallback so callers can safely poll the sensor in a loop without handling exceptions.

Example

>>> from drivers.ES12248.ES12248 import ES12248
>>> sensor = ES12248()
>>> sensor.initialize()
True
>>> humidity_rh = sensor.get_humidity()
>>> 0.0 <= humidity_rh <= 100.0
True

Note

The ES12248 reports relative humidity, not absolute humidity; convert to dew-point or absolute units in downstream code if required.

get_temperature()

Read the current ambient temperature from the ES12248.

Issues a Modbus holding-register read of register 0 (one register), interprets the resulting 16-bit value as temperature * 100, and converts it to degrees Celsius by dividing by 100.0. The decoded value is cached on self.data["temperature"] for use as a fallback by subsequent calls.

Parameters:

None.

Returns:

Measured temperature in degrees Celsius. Returns None if the underlying Modbus read fails after all retries. If decoding fails after a successful read, the previously cached temperature is returned instead (which may itself be None).

Return type:

float | None

Raises:

None – Parse errors are caught, logged, and converted into a cached-value fallback so callers can safely poll the sensor in a loop without handling exceptions.

Example

>>> from drivers.ES12248.ES12248 import ES12248
>>> sensor = ES12248()
>>> sensor.initialize()
True
>>> temperature_c = sensor.get_temperature()
>>> isinstance(temperature_c, float)
True

Note

The raw integer register value is also logged via utils.oizom_logger.OizomLogger at debug level so users can audit scaling without enabling the verbose DEBUG flag.

initialize(port='/dev/ttyAMA2', baud=9600, slave_id=1)

Open the Modbus RTU serial connection to the ES12248 sensor.

Stores the supplied Modbus slave ID, constructs a ModbusSerialClient configured for RTU framing on the given serial port and baud rate with a 2-second transaction timeout, and attempts to open the underlying serial port via client.connect().

Parameters:
  • port (str) – Serial device path bound to the RS-485 transceiver connected to the ES12248 (for example "/dev/ttyAMA2" or "/dev/ttyUSB0"). Defaults to "/dev/ttyAMA2".

  • baud (int) – Serial baud rate in bits per second. Must match the sensor’s configured speed. Defaults to 9600.

  • slave_id (int) – Modbus unit / slave address of the ES12248 on the bus. Defaults to 1.

Returns:

True if the serial port was opened successfully, False if the underlying connect() call reported failure or an exception was caught.

Return type:

bool

Raises:

None – All exceptions raised while constructing or connecting the Modbus client are caught, logged via utils.oizom_logger.OizomLogger, and converted to a False return value so callers can branch on success without try/except blocks.

Example

>>> from drivers.ES12248.ES12248 import ES12248
>>> sensor = ES12248()
>>> sensor.initialize(port="/dev/ttyAMA2", baud=9600, slave_id=1)
True

Note

On systems using newer pymodbus versions the ModbusSerialClient method keyword may have been removed; this driver targets the legacy synchronous API that still accepts method="rtu".

DEBUG = False
SLAVE_ID = 1
client = None
data