Source code for sensirion_shdlc_driver.device_base

# -*- coding: utf-8 -*-
# (c) Copyright 2019 Sensirion AG, Switzerland

from __future__ import absolute_import, division, print_function
from .errors import ShdlcDeviceError, SHDLC_DEVICE_ERROR_LIST

import logging
log = logging.getLogger(__name__)


[docs]class ShdlcDeviceBase(object): """ Base class for all SHDLC devices, providing only the basic functionality without implementing any SHDLC commands. The main purpose of this class is to allow derived classes to register their device-specific errors and to allow executing SHDLC commands. """
[docs] def __init__(self, connection, slave_address): """ Create an SHDLC device instance on an SHDLC connection. .. note:: This constructor does not communicate with the device, so it's possible to instantiate an object even if the device is not connected or powered yet. :param ~sensirion_shdlc_driver.connection.ShdlcConnection connection: The connection used for the communication. :param byte slave_address: The address of the device. """ super(ShdlcDeviceBase, self).__init__() self._connection = connection self._slave_address = slave_address self._last_error_flag = False self._device_errors = dict() self._register_device_errors(SHDLC_DEVICE_ERROR_LIST)
@property def connection(self): """ Get the used SHDLC connection. :return: The used SHDLC connection. :rtype: :py:class:`~sensirion_shdlc_driver.connection.ShdlcConnection` """ return self._connection @property def slave_address(self): """ Get the slave address (not read from the device!). :return: The slave address. :rtype: byte """ return self._slave_address @property def last_error_flag(self): """ Get the error flag which was received with the last response of the device. So this flag gets updated with every command sent to the device. If the flag is True, typically the derived classes provide a method to read the exact error reason from the device (the corresponding SHDLC command is called "Get Device Status"). .. note:: When creating an instance of :py:class:`~sensirion_shdlc_driver.device.ShdlcDeviceBase`, this property is initialized with ``False`` and will not be updated until you send the first command to the device. :return: True if the device indicated an error, False otherwise. :rtype: bool """ return self._last_error_flag
[docs] def execute(self, command): """ Execute an SHDLC command. :param ~sensirion_shdlc_driver.command.ShdlcCommand command: The command to execute. :return: The interpreted response of the executed command. """ try: data, err = self._connection.execute(self._slave_address, command) self._last_error_flag = err # Memorize error flag return data except ShdlcDeviceError as exc: assert exc.error_code != 0 raise self._get_device_error(exc.error_code)
def _register_device_errors(self, errors): """ Register new device errors for the connected device type. This method can (and should!) be called by subclasses of :py:class:`~sensirion_shdlc_driver.device.ShdlcDeviceBase` to register device-specific errors. :param list errors: A list of :py:class:`~sensirion_shdlc_driver.errors.ShdlcDeviceError` (or subclass) exception instances. """ for error in errors: self._device_errors[error.error_code] = error def _get_device_error(self, code): """ Get the device error exception object for a specific device error code. :param byte code: The device error code received from the device. :return: The corresponding exception object (:py:class:`~sensirion_shdlc_driver.errors.ShdlcDeviceError` or a subclass of it), or ``None`` if ``code`` is zero. :rtype: ShdlcDeviceError/None """ if code != 0: return self._device_errors.get(code, ShdlcDeviceError(code)) else: return None