vent.io.devices package

Submodules

vent.io.devices.base module

Base classes & functions used throughout vent.io.devices

Classes

ADS1015([address, i2c_bus, pig])

ADS1015 16 bit, 4 Channel Analog to Digital Converter.

ADS1115([address, i2c_bus, pig])

ADS1115 16 bit, 4 Channel Analog to Digital Converter.

I2CDevice(i2c_address, i2c_bus[, pig])

A class wrapper for pigpio I2C handles.

IODeviceBase(pig)

Abstract base Class for pigpio handles (or whatever other GPIO library

SPIDevice(channel, baudrate[, pig])

A class wrapper for pigpio SPI handles.

Functions

be16_to_native(data[, signed])

Unpacks a bytes-like object respecting big-endianness of outside world and returns an int according to signed.

native16_to_be(word[, signed])

Packs an int into bytes after swapping endianness.

class vent.io.devices.base.IODeviceBase(pig: vent.io.devices.base.PigpioConnection = None)[source]

Bases: object

Abstract base Class for pigpio handles (or whatever other GPIO library we end up using)

Note: pigpio commands return -144 if an error is encountered while attempting to communicate with the demon. TODO would be to recognize when that occurs and handle it gracefully, i.e. kill the daemon, restart it, and reopen the python interface(s)

Initializes the pigpio python bindings object if necessary, and checks that it is actually running.

Parameters

pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

Methods

__init__(pig)

Initializes the pigpio python bindings object if necessary, and checks that it is actually running.

_close()

Closes an I2C/SPI (or potentially Serial) connection

Attributes

handle

Pigpiod handle associated with device (only for i2c/spi)

pig

The pigpio python bindings object

pigpiod_ok

Returns True if pigpiod is running and False if not

__init__(pig: vent.io.devices.base.PigpioConnection = None)[source]

Initializes the pigpio python bindings object if necessary, and checks that it is actually running.

Parameters

pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

property pig

The pigpio python bindings object

property handle

Pigpiod handle associated with device (only for i2c/spi)

property pigpiod_ok

Returns True if pigpiod is running and False if not

_close()[source]

Closes an I2C/SPI (or potentially Serial) connection

class vent.io.devices.base.I2CDevice(i2c_address, i2c_bus, pig=None)[source]

Bases: vent.io.devices.base.IODeviceBase

A class wrapper for pigpio I2C handles. Defines several methods used for reading from and writing to device registers. Defines helper classes Register and ValueField for handling the manipulation of arbitrary registers.

Note: The Raspberry Pi uses LE byte-ordering, while the outside world tends to use BE (at least, the sensors in use so far all do). Thus, bytes need to be swapped from native (LE) ordering to BE prior to being written to an i2c device, and bytes recieved need to be swapped from BE into native (LE). All methods except read_device and write_device perform this automatically. The methods read_device and write_device do NOT byteswap and return bytearrays rather than the unsigned 16-bit int used by the other read/write methods.

Initializes pigpio bindings and opens i2c connection.

Parameters
  • i2c_address (int) – I2C address of the device. (e.g., i2c_address=0x50)

  • i2c_bus (int) – The I2C bus to use. Should probably be set to 1 on Raspberry Pi.

  • pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

Classes

Register(fields, values)

Describes a writable configuration register.

Methods

__init__(i2c_address, i2c_bus[, pig])

Initializes pigpio bindings and opens i2c connection.

_close()

Extends superclass method.

_open(i2c_bus, i2c_address)

Opens i2c connection given i2c bus and address.

read_device([count])

Read a specified number of bytes directly from the the device without specifying or changing the register.

read_register(register[, signed])

Read 2 bytes from the specified register and byteswap the result.

write_device(word[, signed])

Write 2 bytes to the device without specifying register.

write_register(register, word[, signed])

Write 2 bytes to the specified register.

__init__(i2c_address, i2c_bus, pig=None)[source]

Initializes pigpio bindings and opens i2c connection.

Parameters
  • i2c_address (int) – I2C address of the device. (e.g., i2c_address=0x50)

  • i2c_bus (int) – The I2C bus to use. Should probably be set to 1 on Raspberry Pi.

  • pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

_open(i2c_bus, i2c_address)[source]

Opens i2c connection given i2c bus and address.

_close()[source]

Extends superclass method. Checks that pigpiod is connected and if a handle has been set - if so, closes an i2c connection.

read_device(count=2)tuple[source]

Read a specified number of bytes directly from the the device without specifying or changing the register. Does NOT perform LE/BE conversion.

Parameters

count (int) – The number of bytes to read from the device.

Returns

a tuple of the number of bytes read and a bytearray containing the bytes. If there was an error the number of bytes read will be less than zero (and will contain the error code).

Return type

tuple

write_device(word, signed=False)[source]

Write 2 bytes to the device without specifying register. DOES perform LE/BE conversion.

Parameters
  • word (int) – The integer representation of the data to write.

  • signed (bool) – Whether or not word is signed.

read_register(register, signed=False)int[source]

Read 2 bytes from the specified register and byteswap the result.

Parameters
  • register (int) – The index of the register to read.

  • signed (bool) – Whether or not the data to read is expected to be signed.

Returns

integer representation of 16 bit register contents.

Return type

int

write_register(register, word, signed=False)[source]

Write 2 bytes to the specified register. Byteswaps.

Parameters
  • register (int) – The index of the register to write to

  • word (int) – The unsigned 16 bit integer to write to the register (must be consistent with ‘signed’)

  • signed (bool) – Whether or not ‘word’ is signed

class Register(fields, values)[source]

Bases: object

Describes a writable configuration register. Has dynamically defined attributes corresponding to the fields described by the passed arguments. Takes as arguments two tuples of equal length, the first of which names each field and the second being a tuple of tuples containing the (human readable) possible settings & values for each field.

Note: The initializer reverses the fields & their values because a human reads the register, as drawn in the datasheet, from left to right - however, the fields furthest to the left are the most significant bits of the register.

Initializer which loads (dynamically defined) attributes from tuples.

Parameters
  • fields (tuple) – A tuple containing the names of the register’s value fields

  • values (tuple) – A tuple of tuples containing the possible values for each value field. Length must match the length of fields. If there are redundant values for a field specified in the datasheet, be sure to include them. (e.g., a field takes values A: 0b00, B: 0b01, and C: 0b10; but the value for 0b11 is either not specified by the datasheet or is listed redundantly as C: 0b11 -> values should list both the 3rd and 4th possible values as ‘C’ like so: (‘A’, ‘B’, ‘C’, ‘C’)

__init__(fields, values)[source]

Initializer which loads (dynamically defined) attributes from tuples.

Parameters
  • fields (tuple) – A tuple containing the names of the register’s value fields

  • values (tuple) – A tuple of tuples containing the possible values for each value field. Length must match the length of fields. If there are redundant values for a field specified in the datasheet, be sure to include them. (e.g., a field takes values A: 0b00, B: 0b01, and C: 0b10; but the value for 0b11 is either not specified by the datasheet or is listed redundantly as C: 0b11 -> values should list both the 3rd and 4th possible values as ‘C’ like so: (‘A’, ‘B’, ‘C’, ‘C’)

unpack(cfg)collections.OrderedDict[source]

Given the contents of a register in integer form, returns a dict of fields and their current settings.

Parameters

cfg (int) – An integer representing a possible configuration value for the register

pack(cfg, **kwargs)int[source]

Given an initial integer representation of a register and an arbitrary number of field=value settings, returns an integer representation of the register incorporating the new settings.

Parameters
  • cfg (int) – An integer representing a possible configuration value for the register

  • **kwargs – The register fields & values to patch into cfg. Takes keyword arguments of the form: field=value

class ValueField(offset, mask, values)[source]

Bases: object

Describes a configurable value field in a writable register.

Instantiates a value field of a register given the bit offset, mask, and list of possible values.

Parameters
  • offset (int) – The offset bits of the value field in the register, i.e. the distance from LSB

  • mask (int) – integer representation of the value field mask (w/o offset)

  • values (OrderedDict) – The possible values that the field can take.

__init__(offset, mask, values)[source]

Instantiates a value field of a register given the bit offset, mask, and list of possible values.

Parameters
  • offset (int) – The offset bits of the value field in the register, i.e. the distance from LSB

  • mask (int) – integer representation of the value field mask (w/o offset)

  • values (OrderedDict) – The possible values that the field can take.

unpack(cfg)[source]

Extracts the ValueField’s setting from cfg & returns the result in a human readable form.

Parameters

cfg (int) – An integer representing a possible configuration value for the register

extract(cfg)int[source]

Extracts setting from passed 16-bit config & returns integer representation.

Parameters

cfg (int) – An integer representing a possible configuration value for the register

pack(value)int[source]

Takes a human-readable ValueField setting and returns the corresponding bit-shifted integer.

Parameters

value (int) – The integer representation of value bit-shifted by the ValueField’s offset

Returns

The integer representation of the ValueField setting according to value

Return type

int

insert(cfg, value)int[source]

Validates and performs bitwise replacement with the human-readable ValueField setting and integer representation of the register configuration.

Parameters
  • cfg (int) – An integer representing a possible configuration value for the register

  • value (object) – The human readable representation of the desired ValueField setting. Must match a value in ValueField._values; if not, throws a ValueError

Returns

The integer representation of the Register’s configuration with the value of ValueField patched

according the value

Return type

int

class vent.io.devices.base.SPIDevice(channel, baudrate, pig=None)[source]

Bases: vent.io.devices.base.IODeviceBase

A class wrapper for pigpio SPI handles. Not really implemented.

Instantiates an SPIDevice on SPI channel with baudrate and, optionally, pigpio.pi = pig.

Parameters
  • channel (int) – The SPI channel

  • baudrate (int) – SPI baudrate

  • pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

Methods

__init__(channel, baudrate[, pig])

Instantiates an SPIDevice on SPI channel with baudrate and, optionally, pigpio.pi = pig.

_close()

Extends superclass method.

_open(channel, baudrate)

Opens an SPI connection and sets the pigpiod handle.

__init__(channel, baudrate, pig=None)[source]

Instantiates an SPIDevice on SPI channel with baudrate and, optionally, pigpio.pi = pig.

Parameters
  • channel (int) – The SPI channel

  • baudrate (int) – SPI baudrate

  • pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

_open(channel, baudrate)[source]

Opens an SPI connection and sets the pigpiod handle.

Parameters
  • channel (int) – The SPI channel

  • baudrate (int) – SPI baudrate

_close()[source]

Extends superclass method. Checks that pigpiod is connected and if a handle has been set - if so, closes an SPI connection.

class vent.io.devices.base.ADS1115(address=72, i2c_bus=1, pig=None)[source]

Bases: vent.io.devices.base.I2CDevice

ADS1115 16 bit, 4 Channel Analog to Digital Converter. Datasheet:

Attributes

USER_CONFIGURABLE_FIELDS

Note: The Conversion Register is read-only and contains a 16bit representation of the requested value (provided the conversion is ready).

_CONFIG_FIELDS

Built-in immutable sequence.

_CONFIG_VALUES

Built-in immutable sequence.

_DEFAULT_ADDRESS

int([x]) -> integer

_DEFAULT_VALUES

dict() -> new empty dictionary

_POINTER_FIELDS

Built-in immutable sequence.

_POINTER_VALUES

Config Register (R/W)

_TIMEOUT

Address Pointer Register (write-only)

cfg

Returns the contents (as a 16-bit unsigned integer) of the configuration that will be written to the config register when read_conversion() is next called.

config

Returns the Register object of the config register.

Methods

__init__([address, i2c_bus, pig])

Initializes registers: Pointer register is write only, config is R/W.

_read_conversion(**kwargs)

Backend for read_conversion.

_read_last_cfg()

Reads the config register and returns the contents as a 16-bit unsigned integer; updates internal record _last_cfg.

_ready()

Return status of ADC conversion; True indicates the conversion is complete and the results ready to be read.

print_config()

Returns the human-readable configuration for the next read.

read_conversion(**kwargs)

Returns a voltage (expressed as a float) corresponding to a channel on the ADC.

Default Values:

Default configuration for vent: 0xC3E3 Default configuration on power-up: 0x8583

Initializes registers: Pointer register is write only, config is R/W. Sets initial value of _last_cfg to what is actually on the ADS.Packs default settings into _cfg, but does not actually write to ADC - that occurs when read_conversion() is called.

Parameters
  • address (int) – I2C address of the device. (e.g., i2c_address=0x48)

  • i2c_bus (int) – The I2C bus to use. Should probably be set to 1 on Raspberry Pi.

  • pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

_DEFAULT_ADDRESS = 72
_DEFAULT_VALUES = {'DR': 860, 'MODE': 'SINGLE', 'MUX': 0, 'PGA': 4.096}
_TIMEOUT = 1

Address Pointer Register (write-only)

_POINTER_FIELDS = ('P',)
_POINTER_VALUES = (('CONVERSION', 'CONFIG', 'LO_THRESH', 'HIGH_THRESH'),)

Config Register (R/W)

_CONFIG_FIELDS = ('OS', 'MUX', 'PGA', 'MODE', 'DR', 'COMP_MODE', 'COMP_POL', 'COMP_LAT', 'COMP_QUE')
_CONFIG_VALUES = (('NO_EFFECT', 'START_CONVERSION'), ((0, 1), (0, 3), (1, 3), (2, 3), 0, 1, 2, 3), (6.144, 4.096, 2.048, 1.024, 0.512, 0.256, 0.256, 0.256), ('CONTINUOUS', 'SINGLE'), (8, 16, 32, 64, 128, 250, 475, 860), ('TRADIONAL', 'WINDOW'), ('ACTIVE_LOW', 'ACTIVE_HIGH'), ('NONLATCHING', 'LATCHING'), (1, 2, 3, 'DISABLE'))
USER_CONFIGURABLE_FIELDS = ('MUX', 'PGA', 'MODE', 'DR')

Note: The Conversion Register is read-only and contains a 16bit representation of the requested value (provided the conversion is ready).

The Lo-thresh & Hi-thresh Registers are not Utilized here. However, their function and usage are described in the datasheet. Should you want to extend the functionality implemented here.

__init__(address=72, i2c_bus=1, pig=None)[source]

Initializes registers: Pointer register is write only, config is R/W. Sets initial value of _last_cfg to what is actually on the ADS.Packs default settings into _cfg, but does not actually write to ADC - that occurs when read_conversion() is called.

Parameters
  • address (int) – I2C address of the device. (e.g., i2c_address=0x48)

  • i2c_bus (int) – The I2C bus to use. Should probably be set to 1 on Raspberry Pi.

  • pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

read_conversion(**kwargs)float[source]

Returns a voltage (expressed as a float) corresponding to a channel on the ADC. The channel to read from, along with the gain, mode, and sample rate of the conversion may be may be specified as optional parameters. If read_conversion() is called with no parameters, the resulting voltage corresponds to the channel last read from and the same conversion settings.

Parameters
  • MUX – The pin to read from in single channel mode: e.g., 0, 1, 2, 3 or, a tuple of pins over which to make a differential reading. e.g., (0, 1), (0, 3), (1, 3), (2, 3)

  • PGA – The full scale voltage (FSV) corresponding to a programmable gain setting. e.g., (6.144, 4.096, 2.048, 1.024, 0.512, 0.256, 0.256, 0.256)

  • MODE – Whether to set the ADC to continuous conversion mode, or operate in single-shot mode. e.g., ‘CONTINUOUS’, ‘SINGLE’

  • DR – The data rate to make the conversion at; units: samples per second. e.g., 8, 16, 32, 64, 128, 250, 475, 860

print_config()collections.OrderedDict[source]

Returns the human-readable configuration for the next read.

Returns

an ordered dictionary of the form {field: value}, ordered from MSB -> LSB

Return type

OrderedDict

property config

Returns the Register object of the config register.

Returns

The Register object initialized for the ADS1115.

Return type

vent.io.devices.I2CDevice.Register

property cfg

Returns the contents (as a 16-bit unsigned integer) of the configuration that will be written to the config register when read_conversion() is next called.

_read_conversion(**kwargs)int[source]

Backend for read_conversion. Returns the contents of the 16-bit conversion register as an unsigned integer.

If no parameters are passed, one of two things can happen:

  1. If the ADC is in single-shot (mode=’SINGLE’) conversion mode, _last_cfg is written to the config register; once the ADC indicates it is ready, the contents of the conversion register are read and the result is returned.

  2. If the ADC is in CONTINUOUS mode, the contents of the conversion register are read immediately and returned.

If any of channel, gain, mode, or data_rate are specified as parameters, a new _cfg is packed and written to the config register; once the ADC indicates it is ready, the contents of the conversion register are read and the result is returned.

Note: In continuous mode, data can be read from the conversion register of the ADS1115 at any time and always reflects the most recently completed conversion. So says the datasheet.

Parameters

**kwargs – see documentation of vent.io.devices.ADS1115.read_conversion

_read_last_cfg()int[source]

Reads the config register and returns the contents as a 16-bit unsigned integer; updates internal record _last_cfg.

_ready()bool[source]

Return status of ADC conversion; True indicates the conversion is complete and the results ready to be read.

class vent.io.devices.base.ADS1015(address=72, i2c_bus=1, pig=None)[source]

Bases: vent.io.devices.base.ADS1115

ADS1015 16 bit, 4 Channel Analog to Digital Converter. Datasheet:

Attributes

USER_CONFIGURABLE_FIELDS

Built-in immutable sequence.

_CONFIG_FIELDS

Built-in immutable sequence.

_CONFIG_VALUES

Built-in immutable sequence.

_DEFAULT_ADDRESS

int([x]) -> integer

_DEFAULT_VALUES

Address Pointer Register (write-only)

_POINTER_FIELDS

Built-in immutable sequence.

_POINTER_VALUES

Config Register (R/W)

Methods

__init__([address, i2c_bus, pig])

See: vent.io.devices.ADS1115.__init__

Basically the same device as the ADS1115, except has 12 bit resolution instead of 16, and has different (faster) data rates. The difference in data rates is handled by overloading _CONFIG_VALUES. The difference in resolution is irrelevant for implementation.

See: vent.io.devices.ADS1115.__init__

_DEFAULT_ADDRESS = 72
_DEFAULT_VALUES = {'DR': 3300, 'MODE': 'SINGLE', 'MUX': 0, 'PGA': 4.096}

Address Pointer Register (write-only)

_POINTER_FIELDS = ('P',)
_POINTER_VALUES = (('CONVERSION', 'CONFIG', 'LO_THRESH', 'HIGH_THRESH'),)

Config Register (R/W)

_CONFIG_FIELDS = ('OS', 'MUX', 'PGA', 'MODE', 'DR', 'COMP_MODE', 'COMP_POL', 'COMP_LAT', 'COMP_QUE')
_CONFIG_VALUES = (('NO_EFFECT', 'START_CONVERSION'), ((0, 1), (0, 3), (1, 3), (2, 3), 0, 1, 2, 3), (6.144, 4.096, 2.048, 1.024, 0.512, 0.256, 0.256, 0.256), ('CONTINUOUS', 'SINGLE'), (128, 250, 490, 920, 1600, 2400, 3300, 3300), ('TRADIONAL', 'WINDOW'), ('ACTIVE_LOW', 'ACTIVE_HIGH'), ('NONLATCHING', 'LATCHING'), (1, 2, 3, 'DISABLE'))
USER_CONFIGURABLE_FIELDS = ('MUX', 'PGA', 'MODE', 'DR')
__init__(address=72, i2c_bus=1, pig=None)[source]

See: vent.io.devices.ADS1115.__init__

vent.io.devices.base.be16_to_native(data, signed=False)int[source]

Unpacks a bytes-like object respecting big-endianness of outside world and returns an int according to signed.

Parameters
  • data – bytes-like object. The data to be unpacked & converted

  • signed (bool) – Whether or not data is signed

vent.io.devices.base.native16_to_be(word, signed=False)bytes[source]

Packs an int into bytes after swapping endianness.

Parameters
  • signed (bool) – Whether or not data is signed

  • word (int) – The integer representation to converted and packed into bytes

vent.io.devices.pins module

Classes

PWMOutput(pin[, initial_duty, frequency, pig])

A pin configured to output a PWM signal.

Pin(pin[, pig])

Base Class wrapping pigpio methods for interacting with GPIO pins on the raspberry pi.

class vent.io.devices.pins.Pin(pin, pig=None)[source]

Bases: vent.io.devices.base.IODeviceBase

Base Class wrapping pigpio methods for interacting with GPIO pins on the raspberry pi. Subclasses include InputPin, OutputPin; along with any specialized pins or specific devices defined in vent.io.actuators & vent.io.sensors (note: actuators and sensors do not need to be tied to a GPIO pin and may instead be interfaced through an ADC or I2C).

This is an abstract base class. The subclasses InputPin and OutputPin extend Pin into a usable form.

Inherits attributes and methods from IODeviceBase.

Parameters
  • pin (int) – The number of the pin to use

  • pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

Attributes

_PIGPIO_MODES

dict() -> new empty dictionary

mode

The currently active pigpio mode of the pin.

Methods

__init__(pin[, pig])

Inherits attributes and methods from IODeviceBase.

read()

Returns the value of the pin: usually 0 or 1 but can be overridden by subclass.

toggle()

If pin is on, turn it off.

write(value)

Sets the value of the Pin.

_PIGPIO_MODES = {'ALT0': 4, 'ALT1': 5, 'ALT2': 6, 'ALT3': 7, 'ALT4': 3, 'ALT5': 2, 'INPUT': 0, 'OUTPUT': 1}
__init__(pin, pig=None)[source]

Inherits attributes and methods from IODeviceBase.

Parameters
  • pin (int) – The number of the pin to use

  • pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

property mode

The currently active pigpio mode of the pin.

toggle()[source]

If pin is on, turn it off. If it’s off, turn it on. Do not raise a warning when pin is read in this way.

read()int[source]

Returns the value of the pin: usually 0 or 1 but can be overridden by subclass.

write(value)[source]

Sets the value of the Pin. Usually 0 or 1 but behavior differs for some subclasses.

Parameters

value – The value to write to the pin. Can be either 1 to turn on the pin or 0 to turn it off.

class vent.io.devices.pins.PWMOutput(pin, initial_duty=0, frequency=None, pig=None)[source]

Bases: vent.io.devices.pins.Pin

A pin configured to output a PWM signal. Can be configured to use either a hardware-generated or software-generated signal. Overrides parent methods read() and write().

Inherits attributes from parent Pin, then sets PWM frequency & initial duty (use defaults if None)

Parameters
  • pin (int) – The number of the pin to use. Hardware PWM pins are 12, 13, 18, and 19.

  • initial_duty (float) – The initial duty cycle of the pin. Must be between 0 and 1.

  • frequency (float) – The PWM frequency to use.

  • pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

Attributes

_DEFAULT_FREQUENCY

int([x]) -> integer

_DEFAULT_SOFT_FREQ

int([x]) -> integer

_HARDWARE_PWM_PINS

Built-in immutable sequence.

duty

Returns the PWM duty cycle (pulled straight from pigpiod) mapped to the range [0-1]

frequency

Return the current PWM frequency active on the pin.

hardware_enabled

Return true if this is a hardware-enabled PWM pin; False if not.

Methods

_PWMOutput__hardware_pwm(frequency, duty)

Used for pins where hardware pwm is available.

_PWMOutput__pwm(frequency, duty)

Sets a PWM frequency and duty using either hardware or software generated PWM according to the value of self.hardware_enabled.

_PWMOutput__software_pwm(frequency, duty)

Used for pins where hardware PWM is NOT available.

__init__(pin[, initial_duty, frequency, pig])

Inherits attributes from parent Pin, then sets PWM frequency & initial duty (use defaults if None)

_duty()

Returns the pigpio integer representation of the duty cycle.

read()

Overridden to return duty cycle instead of reading the value on the pin.

write(value)

Overridden to write duty cycle.

_DEFAULT_FREQUENCY = 20000
_DEFAULT_SOFT_FREQ = 2000
_HARDWARE_PWM_PINS = (12, 13, 18, 19)
__init__(pin, initial_duty=0, frequency=None, pig=None)[source]

Inherits attributes from parent Pin, then sets PWM frequency & initial duty (use defaults if None)

Parameters
  • pin (int) – The number of the pin to use. Hardware PWM pins are 12, 13, 18, and 19.

  • initial_duty (float) – The initial duty cycle of the pin. Must be between 0 and 1.

  • frequency (float) – The PWM frequency to use.

  • pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

property hardware_enabled

Return true if this is a hardware-enabled PWM pin; False if not. The Raspberry Pi only supports hardware- generated PWM on pins 12, 13, 18, and 19, so generally hardware_enabled will be true if this is one of those, and false if it is not. However, hardware_enabled can also by dynamically set to False if for some reason pigpio is unable to start a hardware PWM (i.e. if the clock is unavailable or in use or something)

property frequency

Return the current PWM frequency active on the pin.

_duty()int[source]

Returns the pigpio integer representation of the duty cycle.

property duty

Returns the PWM duty cycle (pulled straight from pigpiod) mapped to the range [0-1]

read()float[source]

Overridden to return duty cycle instead of reading the value on the pin.

write(value)[source]

Overridden to write duty cycle.

Parameters

value (float) – See PWMOutput.duty

_PWMOutput__hardware_pwm(frequency, duty)

Used for pins where hardware pwm is available. -Tries to write a hardware pwm. result == 0 if it succeeds. -Sets hardware_enabled flag to indicate success or failure

Parameters
  • frequency – A new PWM frequency to use.

  • duty (int) – The PWM duty cycle to set. Must be between 0 and 1.

_PWMOutput__pwm(frequency, duty)

Sets a PWM frequency and duty using either hardware or software generated PWM according to the value of self.hardware_enabled. If hardware_enabled, starts a hardware pwm with the requested duty. If not hardware_enabled, or if there is a problem setting a hardware generated PWM, starts a software PWM.

Parameters
  • frequency (float) – A new PWM frequency to use.

  • duty (float) – The PWM duty cycle to set. Must be between 0 and 1.

_PWMOutput__software_pwm(frequency, duty)

Used for pins where hardware PWM is NOT available.

Parameters
  • frequency – A new PWM frequency to use.

  • duty (int) – A pigpio integer representation of duty cycle

vent.io.devices.sensors module

Classes

AnalogSensor(adc, **kwargs)

Generalized class describing an analog sensor attached to the ADS1115 analog to digital converter.

DLiteSensor(adc, **kwargs)

D-Lite flow sensor setup.

SFM3200([address, i2c_bus, pig])

I2C Inspiratory flow sensor manufactured by Sensirion AG.

Sensor()

Abstract base Class describing generalized sensors.

SimSensor([low, high, pig])

TODO Stub simulated sensor.

class vent.io.devices.sensors.Sensor[source]

Bases: abc.ABC

Abstract base Class describing generalized sensors. Defines a mechanism for limited internal storage of recent observations and methods to pull that data out for external use.

Upon creation, calls update() to ensure that if get is called there will be something to return.

Attributes

_DEFAULT_STORED_OBSERVATIONS

int([x]) -> integer

data

Returns all Locally-stored observations.

maxlen_data

Returns the number of observations kept in the Sensor’s internal ndarray.

Methods

__init__()

Upon creation, calls update() to ensure that if get is called there will be something to return.

_clear()

Resets the sensors internal memory.

_convert(raw)

Converts a raw reading from a sensor in whatever format the device communicates with into a meaningful result.

_raw_read()

Requests a new observation from the device and returns the raw result in whatever format/units the device communicates with.

_read()

Calls _raw_read and scales the result before returning it.

_verify(value)

Validate reading and throw exception/alarm if sensor does not appear to be working correctly.

age()

Returns the time in seconds since the last sensor update, or -1 if never updated.

get([average])

Return the most recent sensor reading, or an average of readings since last get().

reset()

Resets the sensors internal memory.

update()

Make a sensor reading, verify that it makes sense and store the result internally.

_DEFAULT_STORED_OBSERVATIONS = 128
__init__()[source]

Upon creation, calls update() to ensure that if get is called there will be something to return.

update()float[source]

Make a sensor reading, verify that it makes sense and store the result internally. Returns True if reading was verified and False if something went wrong.

get(average=False)float[source]

Return the most recent sensor reading, or an average of readings since last get(). Clears internal memory so as not to have stale data.

age()float[source]

Returns the time in seconds since the last sensor update, or -1 if never updated.

reset()[source]

Resets the sensors internal memory. May be overloaded by subclasses to extend functionality specific to a device.

_clear()[source]

Resets the sensors internal memory.

property data

Returns all Locally-stored observations.

Returns

An array of timestamped observations arranged oldest to newest.

Return type

np.array

property maxlen_data

Returns the number of observations kept in the Sensor’s internal ndarray. Once the ndarray has been filled, the sensor begins overwriting the oldest elements of the ndarray with new observations such that the size of the internal storage stays constant.

_read()float[source]

Calls _raw_read and scales the result before returning it.

abstract _verify(value)[source]

Validate reading and throw exception/alarm if sensor does not appear to be working correctly.

abstract _convert(raw)[source]

Converts a raw reading from a sensor in whatever format the device communicates with into a meaningful result.

abstract _raw_read()[source]

Requests a new observation from the device and returns the raw result in whatever format/units the device communicates with.

_abc_impl = <_abc_data object>
class vent.io.devices.sensors.AnalogSensor(adc, **kwargs)[source]

Bases: vent.io.devices.sensors.Sensor

Generalized class describing an analog sensor attached to the ADS1115 analog to digital converter. Inherits from the sensor base class and extends with functionality specific to analog sensors attached to the ADS1115. If instantiated without a subclass, conceptually represents a voltmeter with a normalized output.

Links analog sensor on the ADC with configuration options specified. If no options are specified, it assumes the settings currently on the ADC.

Parameters
  • adc (vent.io.devices.ADS1115) – The adc object to which the AnalogSensor is attached

  • **kwargsfield=value - see vent.io.devices.ADS1115 for additional documentation. Strongly suggested to specify MUX=adc_pin here unless you know what you’re doing.

Attributes

_DEFAULT_CALIBRATION

dict() -> new empty dictionary

_DEFAULT_offset_voltage

int([x]) -> integer

_DEFAULT_output_span

int([x]) -> integer

Methods

__init__(adc, **kwargs)

Links analog sensor on the ADC with configuration options specified.

_check_and_set_attr(**kwargs)

Checks to see if arguments passed to __init__ are recognized as user configurable or calibration fields.

_convert(raw)

Scales raw voltage into the range 0 - 1.

_fill_attr()

Examines self to see if there are any fields identified as user configurable or calibration that have not been write (i.e.

_raw_read()

Builds kwargs from configured fields to pass along to adc, then calls adc.read_conversion(), which returns a raw voltage.

_read()

Returns a value in the range of 0 - 1 corresponding to a fraction of the full input range of the sensor.

_verify(value)

Checks to make sure sensor reading was indeed in [0, 1].

calibrate(**kwargs)

Sets the calibration of the sensor, either to the values contained in the passed tuple or by some routine; the current routine is pretty rudimentary and only calibrates offset voltage.

_DEFAULT_offset_voltage = 0
_DEFAULT_output_span = 5
_DEFAULT_CALIBRATION = {'conversion_factor': 1, 'offset_voltage': 0, 'output_span': 5}
__init__(adc, **kwargs)[source]

Links analog sensor on the ADC with configuration options specified. If no options are specified, it assumes the settings currently on the ADC.

Parameters
  • adc (vent.io.devices.ADS1115) – The adc object to which the AnalogSensor is attached

  • **kwargsfield=value - see vent.io.devices.ADS1115 for additional documentation. Strongly suggested to specify MUX=adc_pin here unless you know what you’re doing.

calibrate(**kwargs)[source]

Sets the calibration of the sensor, either to the values contained in the passed tuple or by some routine; the current routine is pretty rudimentary and only calibrates offset voltage.

Parameters

**kwargs – calibration_field=value, where calibration field is one of the following: ‘offset_voltage’, output_span’ or ‘conversion_factor’

_read()float[source]

Returns a value in the range of 0 - 1 corresponding to a fraction of the full input range of the sensor.

_verify(value)bool[source]

Checks to make sure sensor reading was indeed in [0, 1].

Parameters

value (float) – Sensor reading to validate

_convert(raw)float[source]

Scales raw voltage into the range 0 - 1.

Parameters

raw (float) – The raw sensor reading to convert.

_raw_read()float[source]

Builds kwargs from configured fields to pass along to adc, then calls adc.read_conversion(), which returns a raw voltage.

_fill_attr()[source]

Examines self to see if there are any fields identified as user configurable or calibration that have not been write (i.e. were not passed to __init__ as **kwargs). If a field is missing, grabs the default value either from the ADC or from _DEFAULT_CALIBRATION and sets it as an attribute.

_check_and_set_attr(**kwargs)[source]

Checks to see if arguments passed to __init__ are recognized as user configurable or calibration fields. If so, write the value as an attribute like: self.KEY = VALUE. Keeps track of how many attributes are write in this way; if at the end there unknown arguments leftover, raises a TypeError; otherwise, calls _fill_attr() to fill in fields that were not passed as arguments.

Parameters

**kwargsfield=value - see vent.io.devices.ADS1115 for additional documentation

_abc_impl = <_abc_data object>
class vent.io.devices.sensors.DLiteSensor(adc, **kwargs)[source]

Bases: vent.io.devices.sensors.AnalogSensor

D-Lite flow sensor setup. This consists of the GE D-Lite sensor configured with vacuum lines running to an analog differential pressure sensor.

Links analog sensor on the ADC with configuration options specified. If no options are specified, it assumes the settings currently on the ADC.

Parameters
  • adc (vent.io.devices.ADS1115) – The adc object to which the AnalogSensor is attached

  • **kwargsfield=value - see vent.io.devices.ADS1115 for additional documentation. Strongly suggested to specify MUX=adc_pin here unless you know what you’re doing.

Methods

_convert(raw)

Converts the raw differential voltage signal to a measurement of flow in liters-per-minute (LPM).

calibrate(**kwargs)

Do not run a calibration routine.

_convert(raw)float[source]

Converts the raw differential voltage signal to a measurement of flow in liters-per-minute (LPM).

We calibrate the D-Lite flow readings using the (pre-calibrated) Sensirion flow sensor (see SFM3200).

Parameters

raw (float) – The raw sensor reading to convert.

calibrate(**kwargs)[source]

Do not run a calibration routine. Overrides attempt to calibrate.

_abc_impl = <_abc_data object>
class vent.io.devices.sensors.SFM3200(address=64, i2c_bus=1, pig=None)[source]

Bases: vent.io.devices.sensors.Sensor, vent.io.devices.base.I2CDevice

I2C Inspiratory flow sensor manufactured by Sensirion AG. Range: +/- 250 SLM Datasheet:

Attributes

_DEFAULT_ADDRESS

int([x]) -> integer

_FLOW_OFFSET

int([x]) -> integer

_FLOW_SCALE_FACTOR

int([x]) -> integer

Methods

__init__([address, i2c_bus, pig])

param address

The I2C Address of the SFM3200 (usually 0x40)

_convert(raw)

Overloaded to replace with device-specific protocol.

_raw_read()

Performs an read on the sensor, converts received bytearray, discards the last two bytes (crc values - could implement in future), and returns a signed int converted from the big endian two complement that remains.

_start()

Device specific:Sends the ‘start measurement’ command to the sensor.

_verify(value)

No further verification needed for this sensor.

reset()

Extended to add device specific behavior: Asks the sensor to perform a soft reset.

https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/

… 5_Mass_Flow_Meters/Datasheets/Sensirion_Mass_Flow_Meters_SFM3200_Datasheet.pdf

Parameters
  • address (int) – The I2C Address of the SFM3200 (usually 0x40)

  • i2c_bus (int) – The I2C Bus to use (usually 1 on the Raspberry Pi)

  • pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

_DEFAULT_ADDRESS = 64
_FLOW_OFFSET = 32768
_FLOW_SCALE_FACTOR = 120
__init__(address=64, i2c_bus=1, pig=None)[source]
Parameters
  • address (int) – The I2C Address of the SFM3200 (usually 0x40)

  • i2c_bus (int) – The I2C Bus to use (usually 1 on the Raspberry Pi)

  • pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

reset()[source]

Extended to add device specific behavior: Asks the sensor to perform a soft reset. 80 ms soft reset time.

_start()[source]

Device specific:Sends the ‘start measurement’ command to the sensor. Start-up time once command has been recieved is ‘less than 100ms’

_verify(value)bool[source]

No further verification needed for this sensor. Onboard chip handles all that. Could throw in a CRC8 checker instead of discarding them in _convert().

Parameters

value (float) – The sensor reading to verify.

_convert(raw)float[source]

Overloaded to replace with device-specific protocol. Convert raw int to a flow reading having type float with units slm. Implementation differs from parent for clarity and consistency with source material.

Source:
https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/

… 5_Mass_Flow_Meters/Application_Notes/Sensirion_Mass_Flo_Meters_SFM3xxx_I2C_Functional_Description.pdf

Parameters

raw (int) – The raw value read from the SFM3200

_raw_read()int[source]

Performs an read on the sensor, converts received bytearray, discards the last two bytes (crc values - could implement in future), and returns a signed int converted from the big endian two complement that remains.

_abc_impl = <_abc_data object>
class vent.io.devices.sensors.SimSensor(low=0, high=100, pig=None)[source]

Bases: vent.io.devices.sensors.Sensor

TODO Stub simulated sensor.

Parameters
  • low – Lower-bound of possible sensor values

  • high – Upper-bound of possible sensor values

  • pig (PigpioConnection) – Ignored.

Methods

__init__([low, high, pig])

TODO Stub simulated sensor.

_convert(raw)

Does nothing for a simulated sensor.

_raw_read()

Initializes randomly, otherwise does a random walk-ish thing.

_verify(value)

Usually verifies sensor readings but occasionally misbehaves.

__init__(low=0, high=100, pig=None)[source]

TODO Stub simulated sensor.

Parameters
  • low – Lower-bound of possible sensor values

  • high – Upper-bound of possible sensor values

  • pig (PigpioConnection) – Ignored.

_verify(value)bool[source]

Usually verifies sensor readings but occasionally misbehaves.

Parameters

value (float) – The sensor reading to verify

_convert(raw)float[source]

Does nothing for a simulated sensor. Returns what it is passed.

Parameters

raw (float) – The raw value to convert

_abc_impl = <_abc_data object>
_raw_read()float[source]

Initializes randomly, otherwise does a random walk-ish thing.

vent.io.devices.valves module

Classes

OnOffValve(pin[, form, pig])

An extension of vent.io.iobase.Pin which uses valve terminology for its methods.

PWMControlValve(pin[, form, frequency, …])

An extension of PWMOutput which incorporates linear compensation of the valve’s response.

SimControlValve([pin, form, frequency, …])

stub: a simulated linear control valve

SimOnOffValve([pin, form, pig])

stub: a simulated on/off valve

SolenoidBase([form])

An abstract baseclass that defines methods using valve terminology.

class vent.io.devices.valves.SolenoidBase(form='Normally Closed')[source]

Bases: abc.ABC

An abstract baseclass that defines methods using valve terminology. Also allows configuring both normally _open and normally closed valves (called the “form” of the valve).

Parameters

form (str) – The form of the solenoid; can be either Normally Open or Normally Closed

Attributes

_FORMS

dict() -> new empty dictionary

form

Returns the human-readable form of the valve.

is_open

Returns True if valve is open, False if it is closed

Methods

__init__([form])

param form

The form of the solenoid; can be either Normally Open or Normally Closed

close()

De-energizes valve if Normally Closed.

open()

Energizes valve if Normally Closed.

_FORMS = {'Normally Closed': 0, 'Normally Open': 1}
__init__(form='Normally Closed')[source]
Parameters

form (str) – The form of the solenoid; can be either Normally Open or Normally Closed

property form

Returns the human-readable form of the valve.

abstract open()[source]

Energizes valve if Normally Closed. De-energizes if Normally Open.

abstract close()[source]

De-energizes valve if Normally Closed. Energizes if Normally Open.

abstract property is_open

Returns True if valve is open, False if it is closed

_abc_impl = <_abc_data object>
class vent.io.devices.valves.OnOffValve(pin, form='Normally Closed', pig=None)[source]

Bases: vent.io.devices.valves.SolenoidBase, vent.io.devices.pins.Pin

An extension of vent.io.iobase.Pin which uses valve terminology for its methods. Also allows configuring both normally _open and normally closed valves (called the “form” of the valve).

Parameters
  • pin (int) – The number of the pin to use

  • form (str) – The form of the solenoid; can be either Normally Open or Normally Closed

  • pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

Attributes

_FORMS

dict() -> new empty dictionary

is_open

Implements parent’s abstractmethod; returns True if valve is open, False if it is closed

Methods

__init__(pin[, form, pig])

param pin

The number of the pin to use

close()

De-energizes valve if Normally Closed.

open()

Energizes valve if Normally Closed.

_FORMS = {'Normally Closed': 0, 'Normally Open': 1}
__init__(pin, form='Normally Closed', pig=None)[source]
Parameters
  • pin (int) – The number of the pin to use

  • form (str) – The form of the solenoid; can be either Normally Open or Normally Closed

  • pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

open()[source]

Energizes valve if Normally Closed. De-energizes if Normally Open.

close()[source]

De-energizes valve if Normally Closed. Energizes if Normally Open.

property is_open

Implements parent’s abstractmethod; returns True if valve is open, False if it is closed

_abc_impl = <_abc_data object>
class vent.io.devices.valves.PWMControlValve(pin, form='Normally Closed', frequency=None, response=None, pig=None)[source]

Bases: vent.io.devices.valves.SolenoidBase, vent.io.devices.pins.PWMOutput

An extension of PWMOutput which incorporates linear compensation of the valve’s response.

Parameters
  • pin (int) – The number of the pin to use

  • form (str) – The form of the solenoid; can be either Normally Open or Normally Closed

  • frequency (float) – The PWM frequency to use.

  • response (str) – “/path/to/response/curve/file”

  • pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

Methods

__init__(pin[, form, frequency, response, pig])

param pin

The number of the pin to use

_load_valve_response(response_path)

Loads and applies a response curve of the form f(setpoint) = duty.

close()

Implements parent’s abstractmethod; fully closes the valve

inverse_response(duty_cycle[, rising])

Inverse of response.

open()

Implements parent’s abstractmethod; fully opens the valve

response(setpoint[, rising])

Setpoint takes a value in the range (0,100) so as not to confuse with duty cycle, which takes a value in the range (0,1).

Attributes

is_open

Implements parent’s abstractmethod; returns True if valve is open, False if it is closed

setpoint

The linearized setpoint corresponding to the current duty cycle according to the valve’s response curve

__init__(pin, form='Normally Closed', frequency=None, response=None, pig=None)[source]
Parameters
  • pin (int) – The number of the pin to use

  • form (str) – The form of the solenoid; can be either Normally Open or Normally Closed

  • frequency (float) – The PWM frequency to use.

  • response (str) – “/path/to/response/curve/file”

  • pig (PigpioConnection) – pigpiod connection to use; if not specified, a new one is established

property is_open

Implements parent’s abstractmethod; returns True if valve is open, False if it is closed

open()[source]

Implements parent’s abstractmethod; fully opens the valve

close()[source]

Implements parent’s abstractmethod; fully closes the valve

property setpoint

The linearized setpoint corresponding to the current duty cycle according to the valve’s response curve

Returns

A number between 0 and 1 representing the current flow as a proportion of maximum

Return type

float

response(setpoint, rising=True)[source]

Setpoint takes a value in the range (0,100) so as not to confuse with duty cycle, which takes a value in the range (0,1). Response curves are specific to individual valves and are to be implemented by subclasses. Different curves are calibrated to ‘rising = True’ (valves opening) or’rising = False’ (valves closing), as different characteristic flow behavior can be observed.

Parameters
  • setpoint (float) – A number between 0 and 1 representing how much to open the valve

  • rising (bool) – Whether or not the requested setpoint is higher than the last (rising = True), or the opposite (Rising = False)

Returns

The PWM duty cycle corresponding to the requested setpoint

Return type

float

inverse_response(duty_cycle, rising=True)[source]

Inverse of response. Given a duty cycle in the range (0,1), returns the corresponding linear setpoint in the range (0,100).

Parameters
  • duty_cycle – The PWM duty cycle

  • rising (bool) – Whether or not the requested setpoint is higher than the last (rising = True), or the opposite (Rising = False)

Returns

The setpoint of the valve corresponding to duty_cycle

Return type

float

_load_valve_response(response_path)[source]

Loads and applies a response curve of the form f(setpoint) = duty. A response curve maps the underlying PWM duty cycle duty onto the normalized variable setpoint representing the flow through the valve as a percentage of its maximum.

Flow through a proportional valve may be nonlinear with respect to [PWM] duty cycle, if the valve itself does not include its own electronics to linearize response wrt/ input. Absent on-board compensation of response, a proportional solenoid with likely not respond [flow] at all below some minimum threshold duty cycle. Above this threshold, the proportional valve begins to open and its response resembles a sigmoid: just past the threshold there is a region where flow increases exponentially wrt/ duty cycle, this is followed by a region of pseudo-linear response that begins to taper off, eventually approaching the valve’s maximum flow asymptotically as the duty cycle approaches 100% and the valve opens fully.

Parameters

response_path – ‘path/to/binary/response/file’ - if response_path is None, defaults to setpoint = duty

_abc_impl = <_abc_data object>
class vent.io.devices.valves.SimOnOffValve(pin=None, form='Normally Closed', pig=None)[source]

Bases: vent.io.devices.valves.SolenoidBase

stub: a simulated on/off valve

Args: form (str): The form of the solenoid; can be either Normally Open or Normally Closed

Attributes

is_open

Returns True if valve is open, False if it is closed

Methods

close()

De-energizes valve if Normally Closed.

open()

Energizes valve if Normally Closed.

open()[source]

Energizes valve if Normally Closed. De-energizes if Normally Open.

close()[source]

De-energizes valve if Normally Closed. Energizes if Normally Open.

property is_open

Returns True if valve is open, False if it is closed

_abc_impl = <_abc_data object>
class vent.io.devices.valves.SimControlValve(pin=None, form='Normally Closed', frequency=None, response=None, pig=None)[source]

Bases: vent.io.devices.valves.SolenoidBase

stub: a simulated linear control valve

Parameters
  • pin (int) – (unused for sim)

  • form (str) – The form of the solenoid; can be either Normally Open or Normally Closed

  • frequency (float) – (unused for sim)

  • response (str) – (unused for sim) # TODO implement this (requires refactor)

  • pig (PigpioConnection) – (unused for sim)

Methods

__init__([pin, form, frequency, response, pig])

param pin

(unused for sim)

close()

Implements parent’s abstractmethod; fully closes the valve

open()

Implements parent’s abstractmethod; fully opens the valve

Attributes

is_open

Implements parent’s abstractmethod; returns True if valve is open, False if it is closed

setpoint

The requested linearized set-point of the valve.

__init__(pin=None, form='Normally Closed', frequency=None, response=None, pig=None)[source]
Parameters
  • pin (int) – (unused for sim)

  • form (str) – The form of the solenoid; can be either Normally Open or Normally Closed

  • frequency (float) – (unused for sim)

  • response (str) – (unused for sim) # TODO implement this (requires refactor)

  • pig (PigpioConnection) – (unused for sim)

property is_open

Implements parent’s abstractmethod; returns True if valve is open, False if it is closed FIXME: Needs refactor; duplicate property to PWMControlValve.is_open

_abc_impl = <_abc_data object>
open()[source]

Implements parent’s abstractmethod; fully opens the valve FIXME: Needs refactor; duplicate method to PWMControlValve.open()

close()[source]

Implements parent’s abstractmethod; fully closes the valve FIXME: Needs refactor; duplicate method to PWMControlValve.close()

property setpoint

The requested linearized set-point of the valve.

Returns

A number between 0 and 1 representing the current flow as a proportion of maximum

Return type

float

Module contents

A module for ventilator hardware device drivers