Source code for duct.sources.sensors.environment.mpl115

"""
.. module:: mpl115
   :platform: Any
   :synopsis: MPL115 i2c sensor

.. moduleauthor:: Colin Alston <colin@tamvera.com>
"""
from zope.interface import implementer

from duct.interfaces import IDuctSource
from duct.objects import Source
from duct.utils import wait
from duct.protocol import i2c

# MPL115A2 Register Address
PADC_MSB = 0x00
PADC_LSB = 0x01
TADC_MSB = 0x02
TACD_LSB = 0x03
A0_MSB = 0x04
A0_LSB = 0x05
B1_MSB = 0x06
B1_LSB = 0x07
B2_MSB = 0x08
B2_LSB = 0x09
C12_MSB = 0x0A
C12_LSB = 0x0B
CONVERT = 0x12


[docs] @implementer(IDuctSource) class MPL115(Source): """MPL115 temperature and pressure sensor This source was based on: https://github.com/FaBoPlatform/FaBoBarometer-MPL115-Python :param address: I2C address of the sensor (default 0x60) :type address: hex. :param smbus: Bus number (default 1) :type smbus: int. :param altitude: Altitude for correction (default 0) :type altitude: float. """ def __init__(self, *a, **kw): Source.__init__(self, *a, **kw) self.address = self.config.get('address', 0x60) self.bus = self.config.get('smbus', 1) self.altitude = self.config.get('altitude', 0.0) self.readCoefficients()
[docs] async def get(self): data = await self.readData() return [ self.createEvent('ok', 'HPA', round(data['hpa'], 2), prefix='hpa'), self.createEvent('ok', 'Temperature', round(data['temp'], 2), prefix='temp') ]
[docs] async def readCoefficients(self): """Read coefficients from sensor""" def _convert(data1, data2): value = data1 | (data2 << 8) if value & (1 << 16 - 1): value -= (1 << 16) return value async with i2c.transaction(self.bus, self.address) as iic: data = await iic.read_block(A0_MSB, 8) self.a0 = _convert(data[1], data[0]) self.b1 = _convert(data[3], data[2]) self.b2 = _convert(data[5], data[4]) self.c12 = _convert(data[7], data[6]) self.a0 = float(self.a0) / (1 << 3) self.b1 = float(self.b1) / (1 << 13) self.b2 = float(self.b2) / (1 << 14) self.c12 = float(self.c12) / (1 << 24)
[docs] async def readData(self): """Read data from the sensor returns dict containing 'hpa' and 'temp' values """ async with i2c.transaction(self.bus, self.address) as iic: await iic.write_byte_data(CONVERT, 0x01) await wait(3) data = await iic.read_block(PADC_MSB, 4) padc = ((data[0] << 8) | data[1]) >> 6 tadc = ((data[2] << 8) | data[3]) >> 6 pcomp = self.a0 + (self.b1 + self.c12 * tadc) * padc + self.b2 * tadc hpa = pcomp * ((1150.0 - 500.0) / 1023.0) + 500.0 hpa /= pow(1.0 - (self.altitude / 44330.0), 5.255) temp = 25.0 - (tadc - 512.0) / 5.35 return {'hpa': hpa, 'temp': temp}