From 53109dd17fa20e223b5b165806f0a3ead6925b2b Mon Sep 17 00:00:00 2001 From: Mi! Date: Fri, 11 Mar 2022 15:13:04 +0100 Subject: [PATCH 1/2] Remove pytz dependency --- bme280/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bme280/__init__.py b/bme280/__init__.py index 2518192..8a05de7 100644 --- a/bme280/__init__.py +++ b/bme280/__init__.py @@ -35,7 +35,6 @@ from bme280.reader import reader import bme280.const as oversampling -import pytz # Oversampling modes oversampling.x1 = 1 @@ -78,7 +77,7 @@ def __init__(self, raw_readings, compensation_params): self._comp = compensation_params self.id = uuid.uuid4() self.uncompensated = raw_readings - self.timestamp = datetime.datetime.utcnow().replace(tzinfo=pytz.UTC) + self.timestamp = datetime.datetime.now(datetime.timezone.utc) self.temperature = self.__tfine(raw_readings.temperature) / 5120.0 self.humidity = self.__calc_humidity(raw_readings.humidity, raw_readings.temperature) From 3d2e1d12c91a8c264966cfe7e9934aa48aee7bec Mon Sep 17 00:00:00 2001 From: Marius Isken Date: Fri, 11 Mar 2022 15:59:57 +0100 Subject: [PATCH 2/2] Updating data models bringing to Python 3.5+ --- .gitignore | 3 + bme280/__init__.py | 239 ++++++++++++++++++++++++++----------------- bme280/const.py | 49 --------- bme280/reader.py | 21 ++-- setup.py | 46 +++++---- tests/test_bme280.py | 116 +++++++++++---------- tests/test_const.py | 33 ------ tests/test_reader.py | 10 +- 8 files changed, 252 insertions(+), 265 deletions(-) delete mode 100644 bme280/const.py delete mode 100644 tests/test_const.py diff --git a/.gitignore b/.gitignore index 3f54b97..19a165e 100644 --- a/.gitignore +++ b/.gitignore @@ -91,5 +91,8 @@ ENV/ .ropeproject *~ +# VS Code +.vscode/ + # OSX .DS_Store diff --git a/bme280/__init__.py b/bme280/__init__.py index 8a05de7..700cef1 100644 --- a/bme280/__init__.py +++ b/bme280/__init__.py @@ -27,40 +27,75 @@ Raspberry Pi BME280 Driver. """ -__version__ = "0.2.4" + +from __future__ import annotations +from dataclasses import dataclass import datetime import time import uuid +from enum import IntEnum +from functools import lru_cache + +from bme280.reader import Reader -from bme280.reader import reader -import bme280.const as oversampling +__version__ = "0.2.4" -# Oversampling modes -oversampling.x1 = 1 -oversampling.x2 = 2 -oversampling.x4 = 3 -oversampling.x8 = 4 -oversampling.x16 = 5 -DEFAULT_PORT = 0x76 +class Oversampling(IntEnum): + x1 = 1 + x2 = 2 + x4 = 3 + x8 = 4 + x16 = 5 -class uncompensated_readings(object): +DEFAULT_PORT = 0x76 - def __init__(self, block): + +@dataclass +class CompensationParams: + dig_T1: int + dig_T2: int + dig_T3: int + dig_P1: int + dig_P2: int + dig_P3: int + dig_P4: int + dig_P5: int + dig_P6: int + dig_P7: int + dig_P8: int + dig_P9: int + dig_H1: int + dig_H2: int + dig_H3: int + dig_H4: int + dig_H5: int + dig_H6: int + + +class UncompensatedReadings: + def __init__(self, block: tuple | list) -> None: self._block = block self.pressure = (block[0] << 16 | block[1] << 8 | block[2]) >> 4 self.temperature = (block[3] << 16 | block[4] << 8 | block[5]) >> 4 self.humidity = block[6] << 8 | block[7] - def __repr__(self): - return "uncompensated_reading(temp=0x{0:08X}, pressure=0x{1:08X}, humidity=0x{2:08X}, block={3})".format( - self.temperature, self.pressure, self.humidity, - ":".join("{0:02X}".format(c) for c in self._block)) + def __repr__(self) -> str: + return ( + "uncompensated_reading(temp=0x{0:08X}, " + "pressure=0x{1:08X}, " + "humidity=0x{2:08X}, block={3})" + ).format( + self.temperature, + self.pressure, + self.humidity, + ":".join("{0:02X}".format(c) for c in self._block), + ) -class compensated_readings(object): +class CompensatedReadings: """ Compensation formulas translated from Appendix A (8.1) of BME280 datasheet: @@ -73,34 +108,53 @@ class compensated_readings(object): * Humidity in %rH as as double. Output value of "46.332" represents 46.332 %rH """ - def __init__(self, raw_readings, compensation_params): + + def __init__( + self, + raw_readings: UncompensatedReadings, + compensation_params: CompensationParams, + ) -> None: self._comp = compensation_params self.id = uuid.uuid4() self.uncompensated = raw_readings self.timestamp = datetime.datetime.now(datetime.timezone.utc) - self.temperature = self.__tfine(raw_readings.temperature) / 5120.0 - self.humidity = self.__calc_humidity(raw_readings.humidity, - raw_readings.temperature) - self.pressure = self.__calc_pressure(raw_readings.pressure, - raw_readings.temperature) / 100.0 - - def __tfine(self, t): + self.temperature = self._tfine(raw_readings.temperature) / 5120.0 + self.humidity = self._calc_humidity( + raw_readings.humidity, raw_readings.temperature + ) + self.pressure = ( + self._calc_pressure(raw_readings.pressure, raw_readings.temperature) / 100.0 + ) + + def _tfine(self, t: float) -> float: v1 = (t / 16384.0 - self._comp.dig_T1 / 1024.0) * self._comp.dig_T2 v2 = ((t / 131072.0 - self._comp.dig_T1 / 8192.0) ** 2) * self._comp.dig_T3 return v1 + v2 - def __calc_humidity(self, h, t): - res = self.__tfine(t) - 76800.0 - res = (h - (self._comp.dig_H4 * 64.0 + self._comp.dig_H5 / 16384.0 * res)) * (self._comp.dig_H2 / 65536.0 * (1.0 + self._comp.dig_H6 / 67108864.0 * res * (1.0 + self._comp.dig_H3 / 67108864.0 * res))) + def _calc_humidity(self, h: float, t: float) -> float: + res = self._tfine(t) - 76800.0 + res = (h - (self._comp.dig_H4 * 64.0 + self._comp.dig_H5 / 16384.0 * res)) * ( + self._comp.dig_H2 + / 65536.0 + * ( + 1.0 + + self._comp.dig_H6 + / 67108864.0 + * res + * (1.0 + self._comp.dig_H3 / 67108864.0 * res) + ) + ) res = res * (1.0 - (self._comp.dig_H1 * res / 524288.0)) return max(0.0, min(res, 100.0)) - def __calc_pressure(self, p, t): - v1 = self.__tfine(t) / 2.0 - 64000.0 + def _calc_pressure(self, p: float, t: float) -> float: + v1 = self._tfine(t) / 2.0 - 64000.0 v2 = v1 * v1 * self._comp.dig_P6 / 32768.0 v2 = v2 + v1 * self._comp.dig_P5 * 2.0 v2 = v2 / 4.0 + self._comp.dig_P4 * 65536.0 - v1 = (self._comp.dig_P3 * v1 * v1 / 524288.0 + self._comp.dig_P2 * v1) / 524288.0 + v1 = ( + self._comp.dig_P3 * v1 * v1 / 524288.0 + self._comp.dig_P2 * v1 + ) / 524288.0 v1 = (1.0 + v1 / 32768.0) * self._comp.dig_P1 # Prevent divide by zero @@ -114,29 +168,20 @@ def __calc_pressure(self, p, t): res = res + (v1 + v2 + self._comp.dig_P7) / 16.0 return res - def __repr__(self): - return "compensated_reading(id={0}, timestamp={1:%Y-%m-%d %H:%M:%S.%f%Z}, temp={2:0.3f} °C, pressure={3:0.2f} hPa, humidity={4:0.2f} % rH)".format( - self.id, self.timestamp, self.temperature, self.pressure, self.humidity) - - -class params(dict): - __getattr__ = dict.__getitem__ - __setattr__ = dict.__setitem__ - __delattr__ = dict.__delitem__ + def __repr__(self) -> str: + return ( + f"compensated_reading(id={self.id}), " + f"timestamp={self.timestamp}, " + f"temp={self.temperature:.3f} °C, " + f"pressure={self.pressure:.2f} hPa, " + f"humidity={self.humidity:.2f} % rH)" + ) -class memoize: - def __init__(self, f): - self.f = f - self.memo = {} - - def __call__(self, *args): - if args not in self.memo: - self.memo[args] = self.f(*args) - return self.memo[args] - - -def load_calibration_params(bus, address=DEFAULT_PORT): +@lru_cache +def load_calibration_params( + bus: int, address: int = DEFAULT_PORT +) -> CompensationParams: """ The BME280 output consists of the ADC output values. However, each sensing element behaves differently. Therefore, the actual pressure and temperature @@ -146,52 +191,54 @@ def load_calibration_params(bus, address=DEFAULT_PORT): formula to perform temperature readout in degC, humidity in % and pressure in hPA. """ - read = reader(bus, address) - compensation_params = params() - - # Temperature trimming params - compensation_params.dig_T1 = read.unsigned_short(0x88) - compensation_params.dig_T2 = read.signed_short(0x8A) - compensation_params.dig_T3 = read.signed_short(0x8C) - - # Pressure trimming params - compensation_params.dig_P1 = read.unsigned_short(0x8E) - compensation_params.dig_P2 = read.signed_short(0x90) - compensation_params.dig_P3 = read.signed_short(0x92) - compensation_params.dig_P4 = read.signed_short(0x94) - compensation_params.dig_P5 = read.signed_short(0x96) - compensation_params.dig_P6 = read.signed_short(0x98) - compensation_params.dig_P7 = read.signed_short(0x9A) - compensation_params.dig_P8 = read.signed_short(0x9C) - compensation_params.dig_P9 = read.signed_short(0x9E) - - # Humidity trimming params - compensation_params.dig_H1 = read.unsigned_byte(0xA1) - compensation_params.dig_H2 = read.signed_short(0xE1) - compensation_params.dig_H3 = read.signed_byte(0xE3) + read = Reader(bus, address) e4 = read.signed_byte(0xE4) e5 = read.signed_byte(0xE5) e6 = read.signed_byte(0xE6) - compensation_params.dig_H4 = e4 << 4 | e5 & 0x0F - compensation_params.dig_H5 = ((e5 >> 4) & 0x0F) | (e6 << 4) - compensation_params.dig_H6 = read.signed_byte(0xE7) - - return compensation_params - - -__cache_calibration_params = memoize(load_calibration_params) - - -def __calc_delay(t_oversampling, h_oversampling, p_oversampling): + # Temperature trimming params + return CompensationParams( + dig_T1=read.unsigned_short(0x88), + dig_T2=read.signed_short(0x8A), + dig_T3=read.signed_short(0x8C), + # Pressure trimming params + dig_P1=read.unsigned_short(0x8E), + dig_P2=read.signed_short(0x90), + dig_P3=read.signed_short(0x92), + dig_P4=read.signed_short(0x94), + dig_P5=read.signed_short(0x96), + dig_P6=read.signed_short(0x98), + dig_P7=read.signed_short(0x9A), + dig_P8=read.signed_short(0x9C), + dig_P9=read.signed_short(0x9E), + # Humidity trimming params + dig_H1=read.unsigned_byte(0xA1), + dig_H2=read.signed_short(0xE1), + dig_H3=read.signed_byte(0xE3), + dig_H4=e4 << 4 | e5 & 0x0F, + dig_H5=((e5 >> 4) & 0x0F) | (e6 << 4), + dig_H6=read.signed_byte(0xE7), + ) + + +def _calc_delay( + t_oversampling: Oversampling, + h_oversampling: Oversampling, + p_oversampling: Oversampling, +) -> float: t_delay = 0.000575 + 0.0023 * (1 << t_oversampling) h_delay = 0.000575 + 0.0023 * (1 << h_oversampling) p_delay = 0.001250 + 0.0023 * (1 << p_oversampling) return t_delay + h_delay + p_delay -def sample(bus, address=DEFAULT_PORT, compensation_params=None, sampling=oversampling.x1): +def sample( + bus, + address: int = DEFAULT_PORT, + compensation_params: CompensationParams | None = None, + sampling: Oversampling = Oversampling.x1, +) -> CompensatedReadings: """ Primes the sensor for reading (defaut: x1 oversampling), pauses for a set amount of time so that the reading stabilizes, and then returns a @@ -203,18 +250,20 @@ def sample(bus, address=DEFAULT_PORT, compensation_params=None, sampling=oversam * pressure (in hPa) """ if compensation_params is None: - compensation_params = __cache_calibration_params(bus, address) + compensation_params = load_calibration_params(bus, address) mode = 1 # forced - t_oversampling = sampling or oversampling.x1 - h_oversampling = sampling or oversampling.x1 - p_oversampling = sampling or oversampling.x1 + t_oversampling = sampling + h_oversampling = sampling + p_oversampling = sampling bus.write_byte_data(address, 0xF2, h_oversampling) # ctrl_hum - bus.write_byte_data(address, 0xF4, t_oversampling << 5 | p_oversampling << 2 | mode) # ctrl - delay = __calc_delay(t_oversampling, h_oversampling, p_oversampling) + bus.write_byte_data( + address, 0xF4, t_oversampling << 5 | p_oversampling << 2 | mode + ) # ctrl + delay = _calc_delay(t_oversampling, h_oversampling, p_oversampling) time.sleep(delay) block = bus.read_i2c_block_data(address, 0xF7, 8) - raw_data = uncompensated_readings(block) - return compensated_readings(raw_data, compensation_params) + raw_data = UncompensatedReadings(block) + return CompensatedReadings(raw_data, compensation_params) diff --git a/bme280/const.py b/bme280/const.py deleted file mode 100644 index 187f566..0000000 --- a/bme280/const.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# The MIT License (MIT) -# -# Copyright (c) 2016 Richard Hull -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - - -class _const: - - # Attribution: - # Python Cookbook, By Alex Martelli, Anna Ravenscroft, David Ascher - - class ConstError(TypeError): - pass - - def __setattr__(self, name, value): - if name in self.__dict__: - raise self.ConstError("Can't rebind const(%s)" % name) - self.__dict__[name] = value - - def __delattr__(self, name): - raise self.ConstError("Can't unbind const(%s)" % name) - - def __str__(self): - return str(self.__dict__) - - -import sys - -sys.modules[__name__] = _const() diff --git a/bme280/reader.py b/bme280/reader.py index 2b56ec9..fbb00b2 100644 --- a/bme280/reader.py +++ b/bme280/reader.py @@ -26,26 +26,29 @@ # bus is an instance of SMBus # default is little endian +from __future__ import annotations -class reader(object): + +class Reader: """ Wraps a I2C SMBus instance to provide methods for reading signed/unsigned bytes and 16-bit words """ - def __init__(self, bus, address): + + def __init__(self, bus, address: int) -> None: self._bus = bus self._address = address - def unsigned_short(self, register): - return self._bus.read_word_data(self._address, register) & 0xffff + def unsigned_short(self, register: int) -> int: + return self._bus.read_word_data(self._address, register) & 0xFFFF - def signed_short(self, register): + def signed_short(self, register: int) -> int: word = self.unsigned_short(register) return word if word < 0x8000 else word - 0x10000 - def unsigned_byte(self, register): - return self._bus.read_byte_data(self._address, register) & 0xff + def unsigned_byte(self, register: int) -> int: + return self._bus.read_byte_data(self._address, register) & 0xFF - def signed_byte(self, register): - byte = self.unsigned_byte(register) & 0xff + def signed_byte(self, register: int) -> int: + byte = self.unsigned_byte(register) & 0xFF return byte if byte < 0x80 else byte - 0x100 diff --git a/setup.py b/setup.py index 98fd64b..7a1b585 100644 --- a/setup.py +++ b/setup.py @@ -7,22 +7,19 @@ here = os.path.dirname(__file__) -README = open(os.path.join(here, 'README.rst')).read() +README = open(os.path.join(here, "README.rst")).read() def _read_version(): - with open(os.path.join(here, 'bme280', '__init__.py')) as code: + with open(os.path.join(here, "bme280", "__init__.py")) as code: contents = code.read() match = re.search(r'__version__\s*=\s*["\'](.*?)["\']', contents) return match.group(1) -needs_pytest = {'pytest', 'test', 'ptr'}.intersection(sys.argv) -pytest_runner = ['pytest-runner'] if needs_pytest else [] -test_deps = [ - 'pytest>=3.1', - 'pytest-cov' -] +needs_pytest = {"pytest", "test", "ptr"}.intersection(sys.argv) +pytest_runner = ["pytest-runner"] if needs_pytest else [] +test_deps = ["pytest>=3.1", "pytest-cov"] version = _read_version() @@ -34,23 +31,30 @@ def _read_version(): description="A library to drive a Bosch BME280 temperature, humidity, pressure sensor over I2C", long_description=README, license="MIT", - keywords=["raspberry pi", "orange pi", "banana pi", "rpi", "bosch", "BME280", "i2c", "temperature", "humidity", "pressure"], + keywords=[ + "raspberry pi", + "orange pi", + "banana pi", + "rpi", + "bosch", + "BME280", + "i2c", + "temperature", + "humidity", + "pressure", + "environment sensor", + ], url="https://github.com/rm-hull/bme280", download_url="https://github.com/rm-hull/bme280/tarball/" + version, - packages=['bme280'], - install_requires=["pytz", "smbus2"], + packages=["bme280"], + install_requires=["smbus2"], setup_requires=pytest_runner, tests_require=test_deps, python_requires=">=3.6, <4", extras_require={ - 'docs': [ - 'sphinx>=1.5.1' - ], - 'qa': [ - 'rstcheck', - 'flake8' - ], - 'test': test_deps + "docs": ["sphinx>=1.5.1"], + "qa": ["rstcheck", "flake8"], + "test": test_deps, }, classifiers=[ "License :: OSI Approved :: MIT License", @@ -64,6 +68,6 @@ def _read_version(): "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10" - ] + "Programming Language :: Python :: 3.10", + ], ) diff --git a/tests/test_bme280.py b/tests/test_bme280.py index 18b5b5e..2b00a3f 100644 --- a/tests/test_bme280.py +++ b/tests/test_bme280.py @@ -3,31 +3,31 @@ # See LICENSE.rst for details. from unittest.mock import Mock, MagicMock -from datetime import datetime +from datetime import datetime, timezone import bme280 -import pytz smbus = Mock(unsafe=True) -compensation_params = bme280.params() -compensation_params.dig_H1 = 0 -compensation_params.dig_H2 = 1 -compensation_params.dig_H3 = 4 -compensation_params.dig_H4 = 3 -compensation_params.dig_H5 = 5 -compensation_params.dig_H6 = 6 -compensation_params.dig_P1 = 10 -compensation_params.dig_P2 = 11 -compensation_params.dig_P3 = 12 -compensation_params.dig_P4 = 13 -compensation_params.dig_P5 = 14 -compensation_params.dig_P6 = 15 -compensation_params.dig_P7 = 16 -compensation_params.dig_P8 = 17 -compensation_params.dig_P9 = 18 -compensation_params.dig_T1 = 20 -compensation_params.dig_T2 = 21 -compensation_params.dig_T3 = 22 +compensation_params = bme280.CompensationParams( + dig_H1=0, + dig_H2=1, + dig_H3=4, + dig_H4=3, + dig_H5=5, + dig_H6=6, + dig_P1=10, + dig_P2=11, + dig_P3=12, + dig_P4=13, + dig_P5=14, + dig_P6=15, + dig_P7=16, + dig_P8=17, + dig_P9=18, + dig_T1=20, + dig_T2=21, + dig_T3=22, +) def setup_function(function): @@ -38,34 +38,35 @@ def test_load_calibration_params(): smbus.read_word_data = MagicMock(side_effect=list(range(400))) smbus.read_byte_data = MagicMock(side_effect=list(range(400))) calibration_params = bme280.load_calibration_params(bus=smbus, address=0x77) - assert calibration_params == { - 'dig_H1': 0, - 'dig_H2': 12, - 'dig_H3': 1, - 'dig_H4': 35, - 'dig_H5': 64, - 'dig_H6': 5, - 'dig_P1': 3, - 'dig_P2': 4, - 'dig_P3': 5, - 'dig_P4': 6, - 'dig_P5': 7, - 'dig_P6': 8, - 'dig_P7': 9, - 'dig_P8': 10, - 'dig_P9': 11, - 'dig_T1': 0, - 'dig_T2': 1, - 'dig_T3': 2 - } + assert calibration_params == bme280.CompensationParams( + dig_H1=0, + dig_H2=12, + dig_H3=1, + dig_H4=35, + dig_H5=64, + dig_H6=5, + dig_P1=3, + dig_P2=4, + dig_P3=5, + dig_P4=6, + dig_P5=7, + dig_P6=8, + dig_P7=9, + dig_P8=10, + dig_P9=11, + dig_T1=0, + dig_T2=1, + dig_T3=2, + ) def test_sample_with_params(): smbus.write_byte_data = MagicMock() smbus.read_i2c_block_data = MagicMock(return_value=list(range(8))) - data = bme280.sample(bus=smbus, address=0x76, - compensation_params=compensation_params) + data = bme280.sample( + bus=smbus, address=0x76, compensation_params=compensation_params + ) assert data.pressure == 8801790.518824806 assert data.temperature == 0.0030482932925224304 @@ -88,23 +89,32 @@ def test_sample_without_params(): def test_uncompensated_readings_repr(): block = [1, 1, 2, 3, 5, 8, 13, 21] - reading = bme280.uncompensated_readings(block) - assert repr(reading) == "uncompensated_reading(temp=0x00003050, pressure=0x00001010, humidity=0x00000D15, block=01:01:02:03:05:08:0D:15)" + reading = bme280.UncompensatedReadings(block) + assert ( + repr(reading) + == "uncompensated_reading(temp=0x00003050, pressure=0x00001010, humidity=0x00000D15, block=01:01:02:03:05:08:0D:15)" + ) def test_compensated_readings_repr(): block = [1, 1, 2, 3, 5, 8, 13, 21] - raw = bme280.uncompensated_readings(block) - reading = bme280.compensated_readings(raw, compensation_params) + raw = bme280.UncompensatedReadings(block) + reading = bme280.CompensatedReadings(raw, compensation_params) reading.id = "55fea298-5a5d-4873-a46d-b631c8748100" - reading.timestamp = datetime(2018, 3, 18, 19, 26, 14, 206233, tzinfo=pytz.UTC) - assert repr(reading) == "compensated_reading(id=55fea298-5a5d-4873-a46d-b631c8748100, timestamp=2018-03-18 19:26:14.206233UTC, temp=0.003 °C, pressure=8758647.58 hPa, humidity=0.05 % rH)" + reading.timestamp = datetime(2018, 3, 18, 19, 26, 14, 206233, tzinfo=timezone.utc) + assert ( + repr(reading) + == "compensated_reading(id=55fea298-5a5d-4873-a46d-b631c8748100), timestamp=2018-03-18 19:26:14.206233+00:00, temp=0.003 °C, pressure=8758647.58 hPa, humidity=0.05 % rH)" + ) def test_compensated_readings_repr_zero_millis(): block = [1, 1, 2, 3, 5, 8, 13, 21] - raw = bme280.uncompensated_readings(block) - reading = bme280.compensated_readings(raw, compensation_params) + raw = bme280.UncompensatedReadings(block) + reading = bme280.CompensatedReadings(raw, compensation_params) reading.id = "55fea298-5a5d-4873-a46d-b631c8748100" - reading.timestamp = datetime(2018, 3, 18, 19, 26, 14, tzinfo=pytz.UTC) - assert repr(reading) == "compensated_reading(id=55fea298-5a5d-4873-a46d-b631c8748100, timestamp=2018-03-18 19:26:14.000000UTC, temp=0.003 °C, pressure=8758647.58 hPa, humidity=0.05 % rH)" + reading.timestamp = datetime(2018, 3, 18, 19, 26, 14, tzinfo=timezone.utc) + assert ( + repr(reading) + == "compensated_reading(id=55fea298-5a5d-4873-a46d-b631c8748100), timestamp=2018-03-18 19:26:14+00:00, temp=0.003 °C, pressure=8758647.58 hPa, humidity=0.05 % rH)" + ) diff --git a/tests/test_const.py b/tests/test_const.py deleted file mode 100644 index 918093c..0000000 --- a/tests/test_const.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2018-2021 Richard Hull -# See LICENSE.rst for details. - -import bme280.const as c -from bme280.const import ConstError -import pytest - -c.const1 = "goodbye" -c.const2 = "cruel" -c.const3 = "world" - - -def test_simple_assignment(): - assert c.const1 == "goodbye" - - -def test_to_string(): - assert "'const1': 'goodbye'" in str(c) - assert "'const2': 'cruel'" in str(c) - assert "'const3': 'world'" in str(c) - - -def test_rebind_throws_error(): - with pytest.raises(ConstError) as excinfo: - del c.const1 - assert "Can't unbind const(const1)" in str(excinfo.value) - - -def test_unbind_throws_error(): - with pytest.raises(ConstError) as excinfo: - c.const1 = "hello" - assert "Can't rebind const(const1)" in str(excinfo.value) diff --git a/tests/test_reader.py b/tests/test_reader.py index 3627208..b67f8f8 100644 --- a/tests/test_reader.py +++ b/tests/test_reader.py @@ -3,7 +3,7 @@ # See LICENSE.rst for details. from unittest.mock import Mock, MagicMock -from bme280.reader import reader +from bme280.reader import Reader smbus = Mock(unsafe=True) @@ -14,27 +14,27 @@ def setup_function(function): def test_unsigned_short(): smbus.read_word_data = MagicMock(return_value=0xDEADBEEF) - read = reader(bus=smbus, address=0x76) + read = Reader(bus=smbus, address=0x76) assert read.unsigned_short(register=0x19A) == 0xBEEF smbus.read_word_data.assert_called_with(0x76, 0x19A) def test_signed_short(): smbus.read_word_data = MagicMock(return_value=0xCAFEBABE) - read = reader(bus=smbus, address=0x76) + read = Reader(bus=smbus, address=0x76) assert read.signed_short(register=0x19A) == 0xBABE - 0x10000 smbus.read_word_data.assert_called_with(0x76, 0x19A) def test_unsigned_byte(): smbus.read_byte_data = MagicMock(return_value=0xEE) - read = reader(bus=smbus, address=0x76) + read = Reader(bus=smbus, address=0x76) assert read.unsigned_byte(register=0x19A) == 0xEE smbus.read_byte_data.assert_called_with(0x76, 0x19A) def test_signed_byte(): smbus.read_byte_data = MagicMock(return_value=0xEE) - read = reader(bus=smbus, address=0x76) + read = Reader(bus=smbus, address=0x76) assert read.signed_byte(register=0x19A) == 0xEE - 0x100 smbus.read_byte_data.assert_called_with(0x76, 0x19A)