def main(): # MCP4725 defaults to address 0x60 address = 0x7f # Initialize I2C (SMBus) bus = SMBus(1) ''' For some reason, sends the offset/register as if it was at the head of the data array. ''' while True: print("Writing 1") try: bus.write_i2c_block_data(address, 5, [1, 1, 0, 0, 1, 1, 0, 0]) except OSError: print("OSError: Failed to write to specified peripheral") sleep(1) print("Writing 0") try: bus.write_i2c_block_data(address, 1, [0, 0, 1, 1, 0, 0, 1, 1]) except OSError: print("OSError: Failed to write to specified peripheral") sleep(1)
class I2cBus(BaseI2cDriver.I2cBus): def __init__(self, bus_id): super().__init__(bus_id) try: self.bus = SMBus(bus_id) except Exception as e: raise InvalidDriverError( 'Unable to initialize i2c connection with bus {}. Check if i2c bus is avalable.'.format(bus_id), e) def close(self): if self.bus is not None: self.bus.close() def read_byte(self, addr: int, register: int) -> int: return self.bus.read_byte_data(addr, register) def read_word(self, addr: int, register: int) -> int: return self.bus.read_word_data(addr, register) def read_block(self, addr: int, register, length: int) -> List[int]: return self.bus.read_i2c_block_data(addr, register, length) def write_byte_data(self, addr, register, value): self.bus.write_byte_data(addr, register, value) def write_word_data(self, addr, register, value): self.bus.write_word_data(addr, register, value) def write_block_data(self, addr, register, data): self.bus.write_i2c_block_data(addr, register, data)
class MCP4725(object): """Base functionality for MCP4725 digital to analog converter.""" def __init__(self, address): """Create an instance of the MCP4725 DAC.""" self._device = SMBus(1) self._address = address def set_voltage(self, value, persist=False): """Set the output voltage to specified value. Value is a 12-bit number (0-4095) that is used to calculate the output voltage from: Vout = (VDD*value)/4096 I.e. the output voltage is the VDD reference scaled by value/4096. If persist is true it will save the voltage value in EEPROM so it continues after reset (default is false, no persistence). """ # Clamp value to an unsigned 12-bit value. if value > 4095: value = 4095 if value < 0: value = 0 reg_data = [(value >> 4) & 0xFF, (value << 4) & 0xFF] if persist: self._device.write_i2c_block_data(self._address, WRITEDACEEPROM, reg_data) else: self._device.write_i2c_block_data(self._address, WRITEDAC, reg_data)
def set_dac_value(bus_number: int, address: int, percent_value: int, i2c_delay, sensor_name: str = 'Unknown'): if address is None: logger.warning( 'Sensor {} i2c bus address is not configured.'.format(sensor_name)) return validate_percent_value(value=percent_value) logger.debug('Instanciating SMBus: {}'.format(bus_number)) bus = SMBus(bus_number) logger.debug('done.') reg_write_dac = 0x40 # Create our 12-bit number representing relative voltage max_voltage = 0xFFF rate = percent_value / 100 voltage = int(max_voltage * rate) & 0xFFF logger.debug('Voltage: {0} ({1} %)'.format(voltage, percent_value)) # Shift everything left by 4 bits and separate bytes msg = (voltage & 0xff0) >> 4 msg = [msg, (msg & 0xf) << 4] # Write out I2C command: address, reg_write_dac, msg[0], msg[1] logger.debug( 'Writing block data to i2c address {0}: [0] => {1}, [1] => {2}'.format( str(hex(address)), str(hex(msg[0])), str(hex(msg[1])))) bus.write_i2c_block_data(address, reg_write_dac, msg) time.sleep(i2c_delay) logger.debug('done.')
class I2C(object): """ This is just a wrapper around i2c. There are so many implementations. """ def __init__(self, address, bus=1): self.i2c = SMBus(bus) self.address = address def __del__(self): self.i2c.close() def read8(self, reg): b = self.i2c.read_byte_data(self.address, reg) return b def read_block(self, reg, size): block = self.i2c.read_i2c_block_data(self.address, reg, size) return block def write_block(self, reg, data): self.i2c.write_i2c_block_data(self.address, reg, data) def write8(self, reg, data): # print(hex(self.address), reg, data) self.i2c.write_byte_data(self.address, reg, data)
class UsSensor: def __init__(self): self.bus = SMBus(0) self.address = 0x48 data = [0b10000100, 0x83] self.bus.write_i2c_block_data(0x48, 0x01, data) #time.sleep(0.5) def USMeasure(self): # self.bus.write_byte_data(self.address, 0, 0b10010000) # self.bus.write_byte_data(self.address, 1, 0b10000001) # self.bus.write_byte_data(self.address, 2, 0b10000100) # self.bus.write_byte_data(self.address, 3, 0b10000011) # self.bus.write_byte_data(self.address, 0, 0b10010000) # firsthalf = self.bus.read_byte_data(self.address, 1, 0b00000000) # secondhalf = self.bus.read_byte_data(self.address, 2, 0b10010001) # tempstr = str(firsthalf) + str(secondhalf) # integerObtained = int(tempstr) # return integerObtained # data = [0b10000010,0x83] # self.bus.write_i2c_block_data(0x48, 0x01, data) # time.sleep(0.5) data = self.bus.read_i2c_block_data(0x48, 0x00, 2) raw_adc = data[0] * 256 + data[1] if raw_adc > 32767: raw_adc -= 65535 raw_adc = float(raw_adc) d = raw_adc / 8 * 520 / 3270 * 10 #converts to mm return d
def read_eeprom(): """Return a class representing EEPROM contents, or none.""" try: i2c = SMBus(1) i2c.write_i2c_block_data(EEP_ADRESS, 0x00, [0x00]) return EPDType.from_bytes(i2c.read_i2c_block_data(0x50, 0, 29)) except IOError: return None
class HwRpiI2cHw(HwI2cHalMlx90632): support_buffer = False pass def __init__(self, channel=1): if isinstance(channel, str) and channel.startswith("I2C-"): channel = int(channel[4:]) if channel == 1 and platform.machine().startswith('armv'): os.system('raspi-gpio set 2 a0') os.system('raspi-gpio set 3 a0') self.i2c = SMBus(channel) def connect(self): pass def disconnect(self): pass def i2c_read(self, i2c_addr, addr, count=1, unpack_format='H'): addr_msb = addr >> 8 & 0x00FF addr_lsb = addr & 0x00FF write = i2c_msg.write(i2c_addr, [addr_msb, addr_lsb]) read = i2c_msg.read(i2c_addr, count * 2) self.i2c.i2c_rdwr(write, read) if unpack_format is None: return bytes(list(read)) results = struct.unpack(">{}{}".format(count, unpack_format), bytes(list(read))) if count == 1: return results[0] return results def i2c_write(self, i2c_addr, addr, data): cmd = [] reg_msb = addr >> 8 cmd.append(addr & 0x00FF) if type(data) is list: for d in data: cmd.append((d >> 8) & 0x00FF) cmd.append(d & 0x00FF) else: cmd.append((data >> 8) & 0x00FF) cmd.append(data & 0x00FF) # print(reg_msb, cmd) self.i2c.write_i2c_block_data(i2c_addr, reg_msb, cmd) if (addr & 0xFF00) == 0x2400: # Wait after EEWRITE! time.sleep(0.010) # 10ms return 0 def get_hardware_id(self): return "Raspberry Pi I2C Hardware"
class i2c_messages(): def __init__(self, addr, bus_number, suppress_errors=True): self.addr = addr self.bus = SMBus(bus_number) self.suppress_errors = suppress_errors def write_array(self, array): try: self.bus.write_i2c_block_data(self.addr, array[0], array[1:]) except OSError: print("OSError could not send")
def write_i2c_block_data(self, register: int, data: Iterable) -> None: """ allows additional parameter types :param register: register address/command :param data: data to write """ if isinstance(data, int): data = bytes(data, ) elif not isinstance(data, bytes): data = bytes(data) SMBus.write_i2c_block_data(self, self.device_addr, register, data)
class ArduinoMotor: def __init__(self, addr=0x8): self.arduino_i2c_addr = addr self.i2c_bus = SMBus(1) def send_data(self, data): # send the throttle first data_new = [ord('t'), int(data["throttle"])] self.i2c_bus.write_i2c_block_data(self.arduino_i2c_addr, 0, data_new) # senf the steering angle next data_new = [ord('s'), int(data["steer"])] self.i2c_bus.write_i2c_block_data(self.arduino_i2c_addr, 0, data_new)
def read_eeprom(i2c_bus=None): """Return a class representing EEPROM contents, or none.""" try: if i2c_bus is None: try: from smbus2 import SMBus except ImportError: raise ImportError('This library requires the smbus2 module\nInstall with: sudo pip install smbus2') i2c_bus = SMBus(1) i2c_bus.write_i2c_block_data(EEP_ADDRESS, 0x00, [0x00]) return EPDType.from_bytes(i2c_bus.read_i2c_block_data(EEP_ADDRESS, 0, 29)) except IOError: return None
def getTempAndHumidityData(): import time from smbus2 import SMBus SHT31_ADDRESS = 0x45 bus = SMBus(1) bus.write_i2c_block_data(SHT31_ADDRESS, 0x2C, [0x06]) time.sleep(0.25) data = bus.read_i2c_block_data(SHT31_ADDRESS, 0x00, 6) bus.close() rawTemp = data[0] * 256 + data[1] temp = -45 + (175 * rawTemp / 65535.0) humidity = 100 * (data[3] * 256 + data[4]) / 65535.0 return temp, humidity
class ArduinoMotor: def __init__(self, addr): self.state = {"throttle": 100, "steer": 90, "direction": "forward"} self.arduino_i2c_addr = addr self.i2c_bus = SMBus(1) def send_data(self): print(self.state) # send the throttle first data = [ord('t'), int(self.state["throttle"])] self.i2c_bus.write_i2c_block_data(self.arduino_i2c_addr, 0, data) # senf the steering angle next data = [ord('s'), int(self.state["steer"])] self.i2c_bus.write_i2c_block_data(self.arduino_i2c_addr, 0, data)
def setup_leon_fan(): bus = SMBus(7, force=True) # http://www.ti.com/lit/ds/symlink/tusb320.pdf for i in [0, 1, 2, 3]: print("FAN SPEED", i) if i == 0: ret = bus.write_i2c_block_data(0x67, 0xa, [0]) else: ret = bus.write_i2c_block_data(0x67, 0xa, [0x20]) ret = bus.write_i2c_block_data(0x67, 0x8, [(i - 1) << 6]) time.sleep(1) bus.close()
def set_eon_fan(val): global LEON, last_eon_fan_val if last_eon_fan_val is None or last_eon_fan_val != val: bus = SMBus(7, force=True) if LEON: i = [0x1, 0x3 | 0, 0x3 | 0x08, 0x3 | 0x10][val] bus.write_i2c_block_data(0x3d, 0, [i]) else: bus.write_byte_data(0x21, 0x04, 0x2) bus.write_byte_data(0x21, 0x03, (val * 2) + 1) bus.write_byte_data(0x21, 0x04, 0x4) bus.close() last_eon_fan_val = val
def get_fan_type(): if not setup_fan(): return bus = SMBus(7, force=True) try: # alternate type bus.write_i2c_block_data(0x3d, 0, [0x1]) print("Alternate type detected") return except IOError: # tusb320 type print("tusb320 type detected") bus.close()
class MCP9808: def __init__(self, bus, addr, resolution=0x03): self.addr = addr self.res = resolution self.bus = SMBus(bus) self.init() # Initialise the MCP9808 with resolution for continuous readings def init(self): # Write config config = [0x00, 0x00] self.bus.write_i2c_block_data(self.addr, 0x01, config) # Write resolution if ((self.res > 0x03) or (self.res < 0)): self.res = 0x03 self.bus.write_byte_data(self.addr, 0x08, self.res) # Read Device ID/Revision register rid = self.bus.read_byte_data(self.addr, 0x07) tmp = self.bus.read_i2c_block_data(self.addr, 0x06, 2) mid = ((tmp[0] & 0x1F) * 256) + tmp[1] #print "Init MCP9808 Manufacurer ID: 0x{:04x}, Device ID: 0x{:02x}".format(mid, rid) # Obtain temperature reading def t_read(self): # Final celcius temp ctemp = 0.0 # Obtain temp reading in binary tin = self.bus.read_i2c_block_data(self.addr, 0x05, 2) bt = ((tin[0] & 0x1F) * 256) + tin[1] # Check if two's comp if (bt > 4095): bt -= 8192 # Multiply by resolution if (self.res == 0x00): ctemp = bt * 0.5 elif (self.res == 0x01): ctemp = bt * 0.25 elif (self.res == 0x02): ctemp = bt * 0.125 elif (self.res == 0x03): ctemp = bt * 0.0625 else: ctemp = bt * 0.0625 # Round and format return "{:.2f}".format(round(ctemp, 2))
class RaspberryI2c(I2c): '''@brief version to actually use the I2C bus ''' def __init__(self, bus_id): '''@brief constructor ''' super(RaspberryI2c, self).__init__(bus_id) from smbus2 import SMBus self._bus = SMBus(bus='/dev/i2c-%d' % bus_id) def _write(self, address, register, data): self._bus.write_i2c_block_data(address, register, data) def _read(self, address, register, length): return bytes(self._bus.read_i2c_block_data(address, register, length)) def _close(self): self._bus.close()
class Device(object): """Class for communicating with an I2C device using the adafruit-pureio pure python smbus library, or other smbus compatible I2C interface. Allows reading and writing 8-bit, 16-bit, and byte array values to registers on the device.""" def __init__(self, address, busnum): """Create an instance of the I2C device at the specified address on the specified I2C bus number.""" self._address = address self._bus = SMBus(busnum) self._logger = logging.getLogger('Rover_log') def writeByte(self, value): """Write an 8-bit value""" value = value & 0xFF self._bus.write_byte(self._address, register, value) self._logger.debug("Wrote 0x%02X to register 0x%02X", value, register) def write8(self, value, register=0): """Write an 8-bit value to the specified register. use register 0 if not needed""" value = value & 0xFF self._bus.write_byte_data(self._address, register, value) self._logger.debug("Wrote 0x%02X to register 0x%02X", value, register) def readU8(self, register=0): """Read an unsigned byte from the specified register. use 0 if egister is not needed""" result = self._bus.read_byte_data(self._address, register) & 0xFF self._logger.debug("Read 0x%02X from register 0x%02X", result, register) return result def writeList(self, data, register=0): """Write bytes to the specified register. Use 0 if register is not needed""" self._bus.write_i2c_block_data(self._address, register, data) self._logger.debug("Wrote to register 0x%02X: %s", register, data) def readList(self, length, register=0): """Read a length number of bytes from the specified register, use 0 if register is not needed. Results will be returned as a bytearray.""" results = self._bus.read_i2c_block_data(self._address, register, length) self._logger.debug("Read the following from register 0x%02X: %s", register, results) return results
class Hardware(threading.Thread): def __init__(self, callbackFunction): threading.Thread.__init__(self) self._switches_ = Switch(False) self._callbackFunction_ = callbackFunction self._ARDUINO_ADRESS_ = 0x08 # start i2c bus self._i2cBus_ = SMBus(1) self._bigKnob_ = BigKnob() self._stationId_ = 0 self.start() self._setOutputLEDInit_() self._stationChanged_ = False def _getInputStates_(self): # update needed ... #switchByte = self._i2cBus_.read_byte_data(self._ARDUINO_ADRESS_,1) switchByte = 0xFF self._modeSwitch_ = Switch(bool(switchByte%0x01)) self._frequencyBand1Active = bool(switchByte%0x02) self._frequencyBand2Active = bool(switchByte%0x04) self._frequencyBand3Active = not (self._frequencyBand1Active or self._frequencyBand2Active) oldStationId = self._stationId_ self._stationId_ = self._bigKnob_.getActualStation() if self._stationId_ != oldStationId: self._stationChanged_ = True def _setOutputLEDInit_(self): self._ledData_ = [0x0C] self._i2cBus_.write_i2c_block_data(self._ARDUINO_ADRESS_,0,self._ledData_) def run(self): while True: time.sleep(0.02) self._getInputStates_() if self._stationChanged_: self._stationChanged_ = False print("station changed") print(self._stationId_) print("NEW CHANNEL!") self._callbackFunction_(self._stationId_,"FM")
class HwRpiI2cHw(HwI2cHalMlx90640): support_buffer = False pass def __init__(self, channel=1): if isinstance(channel, str) and channel.startswith("I2C-"): channel = int(channel[4:]) if channel == 1 and platform.machine().startswith('armv'): os.system('raspi-gpio set 2 a0') os.system('raspi-gpio set 3 a0') self.i2c = SMBus(channel) def connect(self): pass def i2c_read(self, i2c_addr, addr, count=2): addr_msb = addr >> 8 & 0x00FF addr_lsb = addr & 0x00FF write = i2c_msg.write(i2c_addr, [addr_msb, addr_lsb]) read = i2c_msg.read(i2c_addr, count) self.i2c.i2c_rdwr(write, read) return bytes(list(read)), 0 def i2c_write(self, i2c_addr, addr, data): cmd = [] reg_msb = addr >> 8 cmd.append(addr & 0x00FF) for d in data: cmd.append(d) self.i2c.write_i2c_block_data(i2c_addr, reg_msb, cmd) return 0 def get_hardware_id(self): return "Raspberry Pi I2C Hardware"
def set_eon_fan(val): global last_eon_fan_val if last_eon_fan_val is None or last_eon_fan_val != val: bus = SMBus(7, force=True) try: i = [0x1, 0x3 | 0, 0x3 | 0x08, 0x3 | 0x10][val] bus.write_i2c_block_data(0x3d, 0, [i]) except OSError: # tusb320 if val == 0: bus.write_i2c_block_data(0x67, 0xa, [0]) else: bus.write_i2c_block_data(0x67, 0xa, [0x20]) bus.write_i2c_block_data(0x67, 0x8, [(val - 1) << 6]) bus.close() last_eon_fan_val = val
def handle_check_system(self, message): self.speak_dialog('check.system') time.sleep(3) # wait because mycroft is using pixels bus = SMBus(1) pixels = [] for i in range(6): pixels.append(255) pixels.append(0) pixels.append(0) bus.write_i2c_block_data(address, 0, pixels) bus.write_i2c_block_data(address, 6, pixels) time.sleep(2) response = self.ask_yesno('check_colors', data={"color": "red"}) if response == 'yes': self.speak_dialog('color_checked', data={"color": "red"}) else: self.speak_dialog('color_invalid', data={"color": "red"}) time.sleep(4) # green pixels = [] for i in range(6): pixels.append(0) pixels.append(255) pixels.append(0) bus.write_i2c_block_data(address, 0, pixels) bus.write_i2c_block_data(address, 6, pixels) time.sleep(4) response = self.ask_yesno('check_colors', data={"color": "green"}) if response == 'yes': self.speak_dialog('color_checked', data={"color": "green"}) else: self.speak_dialog('color_invalid', data={"color": "green"}) time.sleep(4) # blue pixels = [] for i in range(6): pixels.append(0) pixels.append(0) pixels.append(255) bus.write_i2c_block_data(address, 0, pixels) bus.write_i2c_block_data(address, 6, pixels) time.sleep(5) response = self.ask_yesno('check_colors', data={"color": "blue"}) if response == 'yes': self.speak_dialog('color_checked', data={"color": "blue"}) else: self.speak_dialog('color_invalid', data={"color": "blue"}) bus.close()
def setup_leon_fan(): bus = SMBus(7, force=True) # https://www.nxp.com/docs/en/data-sheet/PTN5150.pdf j = 0 for i in [0x1, 0x3 | 0, 0x3 | 0x08, 0x3 | 0x10]: print("FAN SPEED", j) ret = bus.read_i2c_block_data(0x3d, 0, 4) print(ret) ret = bus.write_i2c_block_data(0x3d, 0, [i]) time.sleep(1) ret = bus.read_i2c_block_data(0x3d, 0, 4) print(ret) j += 1 bus.close()
def set_eon_fan(self, speed: int) -> None: if self.fan_speed != speed: # FIXME: this is such an ugly hack to get the right index val = speed // 16384 bus = SMBus(7, force=True) try: i = [0x1, 0x3 | 0, 0x3 | 0x08, 0x3 | 0x10][val] bus.write_i2c_block_data(0x3d, 0, [i]) except OSError: # tusb320 if val == 0: bus.write_i2c_block_data(0x67, 0xa, [0]) else: bus.write_i2c_block_data(0x67, 0xa, [0x20]) bus.write_i2c_block_data(0x67, 0x8, [(val - 1) << 6]) bus.close() self.fan_speed = speed
def set_comp(self, ah): msg = [SGP30_SET_AH] # start with command LSB # we don't want to completely turn off compensation when humididty is very low # per datasheet page 8/15 minimum value is 1/256 g/M^3 #if ah < 0.1: # ah = 0.01 # Enviro's very low winter time AH values may be causing large baseline offsets # testing limiting minimum AH value to 1g/M^3 if ah < 1.0: ah = 1.0 ah_i = int(ah // 1) # integer byte ah_i &= 0xff ah_d = int((ah % 1) * 256.0) # decimal byte ah_d &= 0xff ah_comp = [ah_i, ah_d] # in SGP30 format ah_crc = self.crc8(ah_comp) # addend crc byte ah_comp.append(ah_crc) # add AH data list to message list msg.extend(ah_comp) print "sgp30.set_comp(): set AH: %.1f" % (ah) print "sgp30.set_comp(): AH regs. 0x%02x 0x%02x" % (ah_i, ah_d) try: bus = SMBus(I2CBUS) resp = bus.write_i2c_block_data(self.I2Caddr, SGP30_MSB, msg) bus.close() time.sleep(0.01) # log AH value f = open(self.FptrAH, "w") f.write("%3.1f" % ah) f.close() except: bus.close() print "sgp30.set_comp() failed"
def set_eon_fan(val): global LEON, last_eon_fan_val if last_eon_fan_val is None or last_eon_fan_val != val: bus = SMBus(7, force=True) if LEON: try: i = [0x1, 0x3 | 0, 0x3 | 0x08, 0x3 | 0x10][val] bus.write_i2c_block_data(0x3d, 0, [i]) except IOError: # tusb320 if val == 0: bus.write_i2c_block_data(0x67, 0xa, [0]) else: bus.write_i2c_block_data(0x67, 0xa, [0x20]) bus.write_i2c_block_data(0x67, 0x8, [(val - 1) << 6]) else: bus.write_byte_data(0x21, 0x04, 0x2) bus.write_byte_data(0x21, 0x03, (val * 2) + 1) bus.write_byte_data(0x21, 0x04, 0x4) bus.close() last_eon_fan_val = val
def set_baseline(self, baseline_voc, baseline_co2): # tVOC baseline word first + crc # eCO2 baseline word second + crc baseline = [0x00] * 2 msg = [SGP30_SET_BASE] # start with command LSB # VOC first baseline[0] = (baseline_voc & 0xff00) >> 8 baseline[0] &= 0xff baseline[1] = baseline_voc & 0xff msg.extend(baseline) msg.append(self.crc8(baseline)) # Then eCO2 baseline[0] = (baseline_co2 & 0xff00) >> 8 baseline[0] &= 0xff baseline[1] = baseline_co2 & 0xff msg.extend(baseline) msg.append(self.crc8(baseline)) print "sgp30.set_baseline() voc: %02x %02x crc: %02x" % ( msg[1], msg[2], msg[3]) print "sgp30.set_baseline() co2: %02x %02x crc: %02x" % ( msg[4], msg[5], msg[6]) try: bus = SMBus(I2CBUS) resp = bus.write_i2c_block_data(self.I2Caddr, SGP30_MSB, msg) bus.close() time.sleep(0.01) except: bus.close() print "sgp30.set_baseline() failed"
class InputModule(AbstractInput): """ A sensor support class that measures the AM2320's humidity and temperature and calculates the dew point """ def __init__(self, input_dev, testing=False): super(InputModule, self).__init__() self.logger = logging.getLogger('mycodo.inputs.am2320') self.powered = False self.sensor = None self.i2c_address = 0x5C if not testing: from smbus2 import SMBus self.logger = logging.getLogger( 'mycodo.am2320_{id}'.format( id=input_dev.unique_id.split('-')[0])) self.device_measurements = db_retrieve_table_daemon( DeviceMeasurements).filter( DeviceMeasurements.device_id == input_dev.unique_id) self.i2c_bus = input_dev.i2c_bus self.power_output_id = input_dev.power_output_id self.start_sensor() self.sensor = SMBus(self.i2c_bus) def get_measurement(self): """ Gets the humidity and temperature """ return_dict = measurements_dict.copy() temperature, humidity = self.read() if self.is_enabled(0): return_dict[0]['value'] = temperature if self.is_enabled(1): return_dict[1]['value'] = humidity if (self.is_enabled(2) and self.is_enabled(0) and self.is_enabled(1)): return_dict[2]['value'] = calculate_dewpoint( return_dict[0]['value'], return_dict[1]['value']) if (self.is_enabled(3) and self.is_enabled(0) and self.is_enabled(1)): return_dict[3]['value'] = calculate_vapor_pressure_deficit( return_dict[0]['value'], return_dict[1]['value']) return return_dict def read(self): try: self.sensor.write_i2c_block_data( self.i2c_address, 0x03, [0x00, 0x04]) except OSError as e: self.logger.error(e) time.sleep(0.02) blocks = self.sensor.read_i2c_block_data(self.i2c_address, 0, 6) humidity = ((blocks[2] << 8) + blocks[3]) / 10.0 temperature = ((blocks[4] << 8) + blocks[5]) / 10.0 return temperature, humidity def setup(self): try: self.sensor.write_i2c_block_data(self.i2c_address, 0x00, []) except OSError as e: self.logger.error(e) time.sleep(0.1)
class InputModule(AbstractInput): """ A sensor support class that measures the AM2320's humidity and temperature and calculates the dew point """ def __init__(self, input_dev, testing=False): super(InputModule, self).__init__() self.setup_logger(testing=testing, name=__name__, input_dev=input_dev) self.powered = False self.sensor = None self.i2c_address = 0x5C if not testing: from smbus2 import SMBus self.device_measurements = db_retrieve_table_daemon( DeviceMeasurements).filter( DeviceMeasurements.device_id == input_dev.unique_id) self.i2c_bus = input_dev.i2c_bus self.power_output_id = input_dev.power_output_id self.start_sensor() self.sensor = SMBus(self.i2c_bus) def get_measurement(self): """ Gets the humidity and temperature """ self.return_dict = measurements_dict.copy() temperature, humidity = self.read() if self.is_enabled(0): self.set_value(0, temperature) if self.is_enabled(1): self.set_value(1, humidity) if (self.is_enabled(2) and self.is_enabled(0) and self.is_enabled(1)): self.set_value( 2, calculate_dewpoint(self.get_value(0), self.get_value(1))) if (self.is_enabled(3) and self.is_enabled(0) and self.is_enabled(1)): self.set_value( 3, calculate_vapor_pressure_deficit(self.get_value(0), self.get_value(1))) return self.return_dict def read(self): try: self.sensor.write_i2c_block_data(self.i2c_address, 0x03, [0x00, 0x04]) except OSError as e: self.logger.error(e) time.sleep(0.02) blocks = self.sensor.read_i2c_block_data(self.i2c_address, 0, 6) humidity = ((blocks[2] << 8) + blocks[3]) / 10.0 temperature = ((blocks[4] << 8) + blocks[5]) / 10.0 return temperature, humidity def setup(self): try: self.sensor.write_i2c_block_data(self.i2c_address, 0x00, []) except OSError as e: self.logger.error(e) time.sleep(0.1)
class InputModule(AbstractInput): """ A sensor support class that monitors the MH-Z16's CO2 concentration """ def __init__(self, input_dev, testing=False): super(InputModule, self).__init__() self.logger = logging.getLogger("mycodo.inputs.mh_z16") if not testing: self.logger = logging.getLogger( "mycodo.mh_z16_{id}".format(id=input_dev.unique_id.split('-')[0])) self.interface = input_dev.interface self.uart_location = input_dev.uart_location if self.interface == 'UART': import serial # Check if device is valid self.serial_device = is_device(self.uart_location) if self.serial_device: try: self.ser = serial.Serial(self.serial_device, timeout=1) except serial.SerialException: self.logger.exception('Opening serial') else: self.logger.error( 'Could not open "{dev}". ' 'Check the device location is correct.'.format( dev=self.uart_location)) elif self.interface == 'I2C': from smbus2 import SMBus self.i2c_address = int(str(input_dev.i2c_location), 16) self.i2c_bus = input_dev.i2c_bus self.cmd_measure = [0xFF, 0x01, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63] self.IOCONTROL = 0X0E << 3 self.FCR = 0X02 << 3 self.LCR = 0X03 << 3 self.DLL = 0x00 << 3 self.DLH = 0X01 << 3 self.THR = 0X00 << 3 self.RHR = 0x00 << 3 self.TXLVL = 0X08 << 3 self.RXLVL = 0X09 << 3 self.i2c = SMBus(self.i2c_bus) self.begin() def get_measurement(self): """ Gets the MH-Z16's CO2 concentration in ppmv via UART""" return_dict = measurements_dict.copy() co2 = None if self.interface == 'UART': if not self.serial_device: # Don't measure if device isn't validated return None self.ser.flushInput() time.sleep(1) self.ser.write(bytearray([0xff, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79])) time.sleep(.01) resp = self.ser.read(9) if len(resp) != 0: high = resp[2] low = resp[3] co2 = (high * 256) + low elif self.interface == 'I2C': self.write_register(self.FCR, 0x07) self.send(self.cmd_measure) try: co2 = self.parse(self.receive()) except Exception: co2 = None return_dict[0]['value'] = co2 return return_dict def begin(self): try: self.write_register(self.IOCONTROL, 0x08) except IOError: pass self.write_register(self.FCR, 0x07) self.write_register(self.LCR, 0x83) self.write_register(self.DLL, 0x60) self.write_register(self.DLH, 0x00) self.write_register(self.LCR, 0x03) @staticmethod def parse(response): checksum = 0 if len(response) < 9: return None for i in range(0, 9): checksum += response[i] if response[0] == 0xFF: if response[1] == 0x9C: if checksum % 256 == 0xFF: return (response[2] << 24) + (response[3] << 16) + (response[4] << 8) + response[5] return None def read_register(self, reg_addr): time.sleep(0.01) return self.i2c.read_byte_data(self.i2c_address, reg_addr) def write_register(self, reg_addr, val): time.sleep(0.01) self.i2c.write_byte_data(self.i2c_address, reg_addr, val) def send(self, command): if self.read_register(self.TXLVL) >= len(command): self.i2c.write_i2c_block_data(self.i2c_address, self.THR, command) def receive(self): n = 9 buf = [] start = time.clock() while n > 0: rx_level = self.read_register(self.RXLVL) if rx_level > n: rx_level = n buf.extend(self.i2c.read_i2c_block_data(self.i2c_address, self.RHR, rx_level)) n = n - rx_level if time.clock() - start > 0.2: break return buf