Open ShorTie8 opened 1 year ago
How did you install the library?
Did you pip install bme280
instead of pip install pimoroni-bme280
?
Edit: okay, plot twist - I just ran into exactly this error on a ROCK 5B. It was fixed with pip install --upgrade pimoroni-bme280
, but that doesn't really explain why I got a corrupt package install in the first place.
sudo pip install pimoroni-bme280 is what I did
also ran the installer too...
Must be somehow getting an older version of the library, since there was a bug like this prior to v0.1.1 - https://github.com/pimoroni/bme280-python/commit/91071570e57bd0726a53f08b915090575c163e39
What do you see if you: pip freeze | grep bme280
And also:
cat /usr/local/lib/python3.9/dist-packages/bme280/__init__.py
pi@Grow4:~/bme280-python/examples $
pi@Grow4:~/bme280-python/examples $
pi@Grow4:~/bme280-python/examples $ pip freeze | grep bme280
bme280==0.6
pimoroni-bme280==0.1.1
RPi.bme280==0.2.4
pi@Grow4:~/bme280-python/examples $ cat /usr/local/lib/python3.9/dist-packages/bme280/__init__.py
#!/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.
"""
Raspberry Pi BME280 Driver.
"""
__version__ = "0.2.4"
import datetime
import time
import uuid
from bme280.reader import reader
import bme280.const as oversampling
import pytz
# Oversampling modes
oversampling.x1 = 1
oversampling.x2 = 2
oversampling.x4 = 3
oversampling.x8 = 4
oversampling.x16 = 5
DEFAULT_PORT = 0x76
class uncompensated_readings(object):
def __init__(self, block):
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))
class compensated_readings(object):
"""
Compensation formulas translated from Appendix A (8.1) of BME280 datasheet:
* Temperature in °C, double precision. Output value of "51.23"
equals 51.23 °C
* Pressure in hPa as double. Output value of "963.862" equals
963.862 hPa
* Humidity in %rH as as double. Output value of "46.332" represents
46.332 %rH
"""
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.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):
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)))
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
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 = (1.0 + v1 / 32768.0) * self._comp.dig_P1
# Prevent divide by zero
if v1 == 0:
return 0
res = 1048576.0 - p
res = ((res - v2 / 4096.0) * 6250.0) / v1
v1 = self._comp.dig_P9 * res * res / 2147483648.0
v2 = res * self._comp.dig_P8 / 32768.0
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__
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):
"""
The BME280 output consists of the ADC output values. However, each sensing
element behaves differently. Therefore, the actual pressure and temperature
must be calculated using a set of calibration parameters.
The calibration parameters are subsequently used to with some compensation
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)
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):
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):
"""
Primes the sensor for reading (defaut: x1 oversampling), pauses for a set
amount of time so that the reading stabilizes, and then returns a
compensated reading object with the following attributes:
* timestamp (Python's datetime object) when reading was taken.
* temperature, in degrees Celcius.
* humidity, in % relative humidity.
* pressure, in hPa.
"""
if compensation_params is None:
compensation_params = __cache_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
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)
time.sleep(delay)
block = bus.read_i2c_block_data(address, 0xF7, 8)
raw_data = uncompensated_readings(block)
return compensated_readings(raw_data, compensation_params)
Okay that bme280 library is not our bme280 library, I wonder if it's just shadowing ours or was installed by the installer accidentally.
Try:
pip uninstall bme280
pip install --upgrade pimoroni-bme280
pi@Grow4:~ $ pip uninstall bme280 pip install --upgrade pimoroni-bme280 Found existing installation: bme280 0.6 Uninstalling bme280-0.6: Would remove: /usr/local/bin/read_bme280 /usr/local/lib/python3.9/dist-packages/bme280-0.6.dist-info/ /usr/local/lib/python3.9/dist-packages/bme280/ Would not remove (might be manually added): /usr/local/lib/python3.9/dist-packages/bme280/const.py /usr/local/lib/python3.9/dist-packages/bme280/reader.py Proceed (y/n)? y ERROR: Exception: Traceback (most recent call last): File "/usr/lib/python3.9/shutil.py", line 806, in move os.rename(src, real_dst) PermissionError: [Errno 13] Permission denied: '/usr/local/bin/' -> '/tmp/pip-uninstall-9ouiakkc'
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File "/usr/lib/python3/dist-packages/pip/_internal/cli/base_command.py", line 223, in _main status = self.run(options, args) File "/usr/lib/python3/dist-packages/pip/_internal/commands/uninstall.py", line 89, in run uninstall_pathset = req.uninstall( File "/usr/lib/python3/dist-packages/pip/_internal/req/req_install.py", line 694, in uninstall uninstalled_pathset.remove(auto_confirm, verbose) File "/usr/lib/python3/dist-packages/pip/_internal/req/req_uninstall.py", line 403, in remove moved.stash(path) File "/usr/lib/python3/dist-packages/pip/_internal/req/req_uninstall.py", line 292, in stash renames(path, new_path) File "/usr/lib/python3/dist-packages/pip/_internal/utils/misc.py", line 355, in renames shutil.move(old, new) File "/usr/lib/python3.9/shutil.py", line 818, in move rmtree(src) File "/usr/lib/python3.9/shutil.py", line 718, in rmtree _rmtree_safe_fd(fd, path, onerror) File "/usr/lib/python3.9/shutil.py", line 675, in _rmtree_safe_fd onerror(os.unlink, fullname, sys.exc_info()) File "/usr/lib/python3.9/shutil.py", line 673, in _rmtree_safe_fd os.unlink(entry.name, dir_fd=topfd) PermissionError: [Errno 13] Permission denied: 'read_bme280' Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple Requirement already satisfied: pimoroni-bme280 in /usr/local/lib/python3.9/dist-packages (0.1.1) Collecting pimoroni-bme280 Downloading pimoroni_bme280-1.0.0-py3-none-any.whl (7.8 kB) Collecting i2cdevice>=1.0.0 Downloading https://www.piwheels.org/simple/i2cdevice/i2cdevice-1.0.0-py3-none-any.whl (10 kB) Requirement already satisfied: smbus2 in /usr/local/lib/python3.9/dist-packages (from i2cdevice>=1.0.0->pimoroni-bme280) (0.4.3) Installing collected packages: i2cdevice, pimoroni-bme280 Successfully installed i2cdevice-1.0.0 pimoroni-bme280-1.0.0 pi@Grow4:~ $
i've probably have install a few bme280 libraries playing
Ok, I know there are Turtles and then Me. Na, Been waiting on my pi5. So it's fresh everything. Like only history entries.
So, got me, still don't work
` pi@pi5:~ $ history 1 sudo apt update 2 sudo apt upgrade 3 sudo apt install python3-full 4 sudo apt install i2c-tools 5 sudo apt autoremove pi@pi5:~ $ i2cdetect -a 1 70: -- -- -- -- -- -- 76 -- -- -- -- -- -- -- -- --
locate bme280.py /usr/local/lib/python3.9/dist-packages/bme280/bme280.py root@Grow4:/home/pi# ls -l /usr/local/lib/python3.9/dist-packages/bme28* /usr/local/lib/python3.9/dist-packages/bme280: total 40 -rw-r--r-- 1 root root 1037 Oct 16 01:40 bme280_i2c.py -rw-r--r-- 1 root root 8393 Oct 16 01:40 bme280.py -rw-r--r-- 1 root root 1699 Nov 5 00:50 const.py -rw-r--r-- 1 root root 8357 Nov 5 00:50 init.py drwxr-xr-x 2 root root 4096 Nov 5 00:50 pycache -rw-r--r-- 1 root root 1971 Nov 5 00:50 reader.py
/usr/local/lib/python3.9/dist-packages/bme280-0.6.dist-info: total 32 -rw-r--r-- 1 root root 337 Oct 16 01:40 DESCRIPTION.rst -rw-r--r-- 1 root root 52 Oct 16 01:40 entry_points.txt -rw-r--r-- 1 root root 4 Oct 16 01:40 INSTALLER -rw-r--r-- 1 root root 1105 Oct 16 01:40 METADATA -rw-r--r-- 1 root root 1079 Oct 16 01:40 metadata.json -rw-r--r-- 1 root root 1184 Oct 16 01:40 RECORD -rw-r--r-- 1 root root 0 Oct 16 01:40 REQUESTED -rw-r--r-- 1 root root 7 Oct 16 01:40 top_level.txt -rw-r--r-- 1 root root 110 Oct 16 01:40 WHEEL
pi@pi5:~ $ python3 -m pip install pimoroni-bme280 error: externally-managed-environment
× This environment is externally managed ?-> To install Python packages system-wide, try apt install python3-xyz, where xyz is the package you are trying to install.
If you wish to install a non-Debian-packaged Python package,
create a virtual environment using python3 -m venv path/to/venv.
Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
sure you have python3-full installed.
For more information visit http://rptl.io/venv
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
`
You should now be working in a virtual environment. I've explained why in exhaustive detail here: https://github.com/pimoroni/boilerplate-python/pull/13
If it sounds like tedious nonsense to you, welcome to the last two months of my life.
In short, you'll need to:
sudo apt install python3-virtualenvwrapper virtualenvwrapper
source /usr/share/virtualenvwrapper/virtualenvwrapper.sh
mkvirtualenv your_project_name
Then install everything into that virtual environment with pip install
and to get back into the environment:
source /usr/share/virtualenvwrapper/virtualenvwrapper.sh
workon your_project_name
You can add source /usr/share/virtualenvwrapper/virtualenvwrapper.sh
to the bottom of ~/.bashrc
to avoid having to repeat that step every time.
Trying to run some examples, but not working real well
pi@Grow4:~/bme280-python/examples $ ls all-values.py dump-calibration.py relative-altitude.py temperature-forced-mode.py compensated-temperature.py local_altitude.py temperature-compare.py pi@Grow4:~/bme280-python/examples $ python compensated-temperature.py Traceback (most recent call last): File "/home/pi/bme280-python/examples/compensated-temperature.py", line 6, in <module> from bme280 import BME280 ImportError: cannot import name 'BME280' from 'bme280' (/usr/local/lib/python3.9/dist-packages/bme280/__init__.py) pi@Grow4:~/bme280-python/examples $ python dump-calibration.py Traceback (most recent call last): File "/home/pi/bme280-python/examples/dump-calibration.py", line 7, in <module> from bme280 import BME280 ImportError: cannot import name 'BME280' from 'bme280' (/usr/local/lib/python3.9/dist-packages/bme280/__init__.py) pi@Grow4:~/bme280-python/examples $ python relative-altitude.py Traceback (most recent call last): File "/home/pi/bme280-python/examples/relative-altitude.py", line 9, in <module> from bme280 import BME280 ImportError: cannot import name 'BME280' from 'bme280' (/usr/local/lib/python3.9/dist-packages/bme280/__init__.py) pi@Grow4:~/bme280-python/examples $
Jeff