# -*- coding: utf-8 -*-
# (c) Copyright 2021 Sensirion AG, Switzerland
##############################################################################
##############################################################################
# _____ _ _ _______ _____ ____ _ _
# / ____| /\ | | | |__ __|_ _/ __ \| \ | |
# | | / \ | | | | | | | || | | | \| |
# | | / /\ \| | | | | | | || | | | . ` |
# | |____ / ____ \ |__| | | | _| || |__| | |\ |
# \_____/_/ \_\____/ |_| |_____\____/|_| \_|
#
# THIS FILE IS AUTOMATICALLY GENERATED AND MUST NOT BE EDITED MANUALLY!
#
# Generator: sensirion-i2c-interface-generator 0.3.0
# Product: SGP41
# Version: 0.1.0
#
##############################################################################
##############################################################################
# flake8: noqa
from __future__ import absolute_import, division, print_function
import logging
from struct import pack, unpack
from sensirion_i2c_driver import SensirionI2cCommand, CrcCalculator
from sensirion_i2c_sgp4x.sgp41.response_types import Sgp41SrawVoc, Sgp41SrawNox
log = logging.getLogger(__name__)
[docs]class Sgp41I2cCmdBase(SensirionI2cCommand):
"""
SGP41 I²C base command.
"""
[docs] def __init__(self, command, tx_data, rx_length, read_delay, timeout,
post_processing_time=0.0):
"""
Constructs a new SGP41 I²C command.
:param int/None command:
The command ID to be sent to the device. None means that no
command will be sent, i.e. only ``tx_data`` (if not None) will
be sent. No CRC is added to these bytes since the command ID
usually already contains a CRC.
:param bytes-like/list/None tx_data:
Bytes to be extended with CRCs and then sent to the I²C device.
None means that no write header will be sent at all (if ``command``
is None too). An empty list means to send the write header (even if
``command`` is None), but without data following it.
:param int/None rx_length:
Number of bytes to be read from the I²C device, including CRC
bytes. None means that no read header is sent at all. Zero means
to send the read header, but without reading any data.
:param float read_delay:
Delay (in Seconds) to be inserted between the end of the write
operation and the beginning of the read operation. This is needed
if the device needs some time to prepare the RX data, e.g. if it
has to perform a measurement. Set to 0.0 to indicate that no delay
is needed, i.e. the device does not need any processing time.
:param float timeout:
Timeout (in Seconds) to be used in case of clock stretching. If the
device stretches the clock longer than this value, the transceive
operation will be aborted with a timeout error. Set to 0.0 to
indicate that the device will not stretch the clock for this
command.
:param float post_processing_time:
Maximum time in seconds the device needs for post processing of
this command until it is ready to receive the next command. For
example after a device reset command, the device might need some
time until it is ready again. Usually this is 0.0s, i.e. no post
processing is needed.
"""
super(Sgp41I2cCmdBase, self).__init__(
command=command,
tx_data=tx_data,
rx_length=rx_length,
read_delay=read_delay,
timeout=timeout,
crc=CrcCalculator(8, 0x31, 0xFF, 0x00),
command_bytes=2,
post_processing_time=post_processing_time,
)
[docs]class Sgp41I2cCmdExecuteConditioning(Sgp41I2cCmdBase):
"""
SGP41 Execute Conditioning I²C Command
This command starts the conditioning, i.e., the VOC pixel will be operated
at the same temperature as it is by calling the sgp41_measure_raw command
while the NOx pixel will be operated at a different temperature for
conditioning. This command returns only the measured raw signal of the VOC
pixel SRAW_VOC as 2 bytes (+ 1 CRC byte).
"""
[docs] def __init__(self, default_rh, default_t):
"""
Constructor.
:param int default_rh:
Default conditions for relative humidty.
:param int default_t:
Default conditions for temperature.
"""
super(Sgp41I2cCmdExecuteConditioning, self).__init__(
command=0x2612,
tx_data=b"".join([pack(">H", default_rh),
pack(">H", default_t)]),
rx_length=3,
read_delay=0.05,
timeout=0,
post_processing_time=0.0,
)
[docs] def interpret_response(self, data):
"""
Validates the CRCs of the received data from the device and returns
the interpreted data.
:param bytes data:
Received raw bytes from the read operation.
:return: the raw signal SRAW_VOC
in ticks which is proportional to the logarithm of the
resistance of the sensing element.
:rtype: :py:class:`~sensirion_i2c_sgp4x.sgp41.response_types.Sgp41SrawVoc`
:raise ~sensirion_i2c_driver.errors.I2cChecksumError:
If a received CRC was wrong.
"""
# check and remove CRCs
checked_data = Sgp41I2cCmdBase.interpret_response(self, data)
# convert raw received data into proper data types
sraw_voc = int(unpack(">H", checked_data[0:2])[0]) # uint16
return Sgp41SrawVoc(sraw_voc)
[docs]class Sgp41I2cCmdMeasureRawSignals(Sgp41I2cCmdBase):
"""
SGP41 Measure Raw Signals I²C Command
This command starts/continues the VOC+NOx measurement mode
"""
[docs] def __init__(self, relative_humidity, temperature):
"""
Constructor.
:param int relative_humidity:
Leaves humidity compensation disabled by sending the default value
0x8000 (50%RH) or enables humidity compensation when sending the
relative humidity in ticks (ticks = %RH * 65535 / 100)
:param int temperature:
Leaves humidity compensation disabled by sending the default value
0x6666 (25 degC) or enables humidity compensation when sending the
temperature in ticks (ticks = (degC + 45) * 65535 / 175)
"""
super(Sgp41I2cCmdMeasureRawSignals, self).__init__(
command=0x2619,
tx_data=b"".join([pack(">H", relative_humidity),
pack(">H", temperature)]),
rx_length=6,
read_delay=0.05,
timeout=0,
post_processing_time=0.0,
)
[docs] def interpret_response(self, data):
"""
Validates the CRCs of the received data from the device and returns
the interpreted data.
:param bytes data:
Received raw bytes from the read operation.
:return:
- sraw_voc (:py:class:`~sensirion_i2c_sgp4x.sgp41.response_types.Sgp41SrawVoc`) -
the raw signal SRAW_VOC in
ticks which is proportional to the logarithm of the resistance of
the sensing element.
- sraw_nox (:py:class:`~sensirion_i2c_sgp4x.sgp41.response_types.Sgp41SrawNox`) -
the raw signal SRAW_NOX in
ticks which is proportional to the logarithm of the resistance of
the sensing element.
:rtype: tuple
:raise ~sensirion_i2c_driver.errors.I2cChecksumError:
If a received CRC was wrong.
"""
# check and remove CRCs
checked_data = Sgp41I2cCmdBase.interpret_response(self, data)
# convert raw received data into proper data types
sraw_voc = int(unpack(">H", checked_data[0:2])[0]) # uint16
sraw_nox = int(unpack(">H", checked_data[2:4])[0]) # uint16
return Sgp41SrawVoc(sraw_voc), Sgp41SrawNox(sraw_nox)
[docs]class Sgp41I2cCmdExecuteSelfTest(Sgp41I2cCmdBase):
"""
SGP41 Execute Self Test I²C Command
This command triggers the built-in self-test checking for integrity of both
hotplate and MOX material and returns the result of this test as 2 bytes
"""
[docs] def __init__(self):
"""
Constructor.
"""
super(Sgp41I2cCmdExecuteSelfTest, self).__init__(
command=0x280E,
tx_data=None,
rx_length=3,
read_delay=0.32,
timeout=0,
post_processing_time=0.0,
)
[docs] def interpret_response(self, data):
"""
Validates the CRCs of the received data from the device and returns
the interpreted data.
:param bytes data:
Received raw bytes from the read operation.
:return: 0xXX 0xYY: ignore most significant byte 0xXX. The four least
significant bits of the least significant byte 0xYY provide
information if the self-test has or has not passed for each
individual pixel. All zero mean all tests passed successfully.
Check the datasheet for more detailed information.
:rtype: int
:raise ~sensirion_i2c_driver.errors.I2cChecksumError:
If a received CRC was wrong.
"""
# check and remove CRCs
checked_data = Sgp41I2cCmdBase.interpret_response(self, data)
# convert raw received data into proper data types
test_result = int(unpack(">H", checked_data[0:2])[0]) # uint16
return test_result
[docs]class Sgp41I2cCmdTurnHeaterOff(Sgp41I2cCmdBase):
"""
SGP41 Turn Heater Off I²C Command
This command turns the hotplate off and stops the measurement.
Subsequently, the sensor enters the idle mode.
"""
[docs] def __init__(self):
"""
Constructor.
"""
super(Sgp41I2cCmdTurnHeaterOff, self).__init__(
command=0x3615,
tx_data=None,
rx_length=None,
read_delay=0.0,
timeout=0,
post_processing_time=0.001,
)
[docs]class Sgp41I2cCmdGetSerialNumber(Sgp41I2cCmdBase):
"""
SGP41 Get Serial Number I²C Command
This command provides the decimal serial number of the SGP41 chip by
returning 3x2 bytes.
"""
[docs] def __init__(self):
"""
Constructor.
"""
super(Sgp41I2cCmdGetSerialNumber, self).__init__(
command=0x3682,
tx_data=None,
rx_length=9,
read_delay=0.001,
timeout=0,
post_processing_time=0.0,
)
[docs] def interpret_response(self, data):
"""
Validates the CRCs of the received data from the device and returns
the interpreted data.
:param bytes data:
Received raw bytes from the read operation.
:return: 48-bit unique serial number
:rtype: list(int)
:raise ~sensirion_i2c_driver.errors.I2cChecksumError:
If a received CRC was wrong.
"""
# check and remove CRCs
checked_data = Sgp41I2cCmdBase.interpret_response(self, data)
# convert raw received data into proper data types
serial_number = [int(ii) for ii in
unpack(">{}H".format(len(checked_data[0:6]) // 2), checked_data[0:6])] # list(uint16)
return serial_number