Skip to content

feat(bme280): Add altitude computation and sea-level pressure#321

Merged
nedseb merged 2 commits intomainfrom
feat/bme280-altitude
Mar 30, 2026
Merged

feat(bme280): Add altitude computation and sea-level pressure#321
nedseb merged 2 commits intomainfrom
feat/bme280-altitude

Conversation

@nedseb
Copy link
Copy Markdown
Contributor

@nedseb nedseb commented Mar 29, 2026

Closes #315

Summary

  • sea_level_pressure attribute: initialized to 1013.25 hPa, user-adjustable for local conditions
  • altitude() method: estimates altitude in meters using the ICAO barometric formula 44330 * (1 - (P/P0)^0.1903) — same formula used by robert-hh, Adafruit, and Pimoroni
  • weather_station.py updated: uses sensor.altitude() instead of a local altitude_m() function; sea-level pressure configured via sensor.sea_level_pressure
  • README updated: new Altitude section in API reference, comparison table updated (Altitude and Sea-level pressure now ✅)
  • 4 new mock tests: default reference value, altitude with default/custom reference, altitude=0 when pressure matches reference

Test plan

  • 52 mock tests pass (make test-bme280)
  • Hardware validation

Copilot AI review requested due to automatic review settings March 29, 2026 19:18
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds altitude estimation to the BME280 driver via a configurable sea-level pressure reference, and updates docs/tests/examples accordingly.

Changes:

  • Introduces sea_level_pressure (default 1013.25 hPa) and an altitude() method on the driver.
  • Updates the weather_station.py example to use the driver’s altitude computation.
  • Extends README and mock scenario tests to cover altitude and the new reference pressure.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
lib/bme280/bme280/device.py Adds sea_level_pressure attribute and altitude() API.
lib/bme280/examples/weather_station.py Switches example altitude calculation to sensor.altitude().
lib/bme280/README.md Documents altitude usage and marks altitude/sea-level pressure supported in comparison table.
tests/scenarios/bme280.yaml Adds mock tests for default sea-level pressure and altitude computations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/bme280/examples/weather_station.py Outdated
Comment on lines +39 to +40
temperature, pressure, humidity = sensor.read()
alt = altitude_m(pressure)
alt = sensor.altitude()
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this example loop, sensor.read() returns a pressure value that gets logged/printed, but sensor.altitude() immediately reads pressure again internally. That means pressure and alt may come from different measurements (and adds extra I2C traffic). Consider computing altitude from the already-read pressure (e.g., an altitude_from_pressure(pressure_hpa) helper or allowing altitude(pressure_hpa=...)), so all fields in the same row are consistent.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in e920a67: weather_station.py now passes the already-read pressure to sensor.altitude(pressure_hpa=pressure), ensuring consistency between all fields in the same row.

Comment thread lib/bme280/bme280/device.py Outdated
Comment on lines +400 to +406
def altitude(self):
"""Return estimated altitude in meters from current pressure.

Uses the ICAO barometric formula with ``sea_level_pressure`` as
reference (default 1013.25 hPa, adjustable).
"""
p = self.pressure_hpa()
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

altitude() always calls pressure_hpa(), which forces an additional burst read (and may trigger a new measurement in sleep mode). This makes it hard to compute altitude from an already-fetched pressure value and can lead to inconsistent multi-field reads. Consider adding an optional pressure_hpa parameter (or a separate altitude_from_pressure() method) so callers can avoid redundant I2C reads and ensure consistent sampling.

Suggested change
def altitude(self):
"""Return estimated altitude in meters from current pressure.
Uses the ICAO barometric formula with ``sea_level_pressure`` as
reference (default 1013.25 hPa, adjustable).
"""
p = self.pressure_hpa()
def altitude(self, pressure_hpa=None):
"""Return estimated altitude in meters from current pressure.
Uses the ICAO barometric formula with ``sea_level_pressure`` as
reference (default 1013.25 hPa, adjustable).
If ``pressure_hpa`` is provided, it is used directly; otherwise a new
pressure reading is obtained via :meth:`pressure_hpa`.
"""
p = self.pressure_hpa() if pressure_hpa is None else pressure_hpa

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in e920a67: altitude() now accepts an optional pressure_hpa parameter. When provided, it skips the I2C read and uses the given value directly.

Comment thread lib/bme280/bme280/device.py Outdated
Comment on lines +406 to +407
p = self.pressure_hpa()
return 44330.0 * (1.0 - (p / self.sea_level_pressure) ** 0.1903)
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sea_level_pressure is user-adjustable and used as a divisor in altitude(). If it’s set to 0 or a negative value, altitude() will raise (or return nonsensical results). Add validation (e.g., require a positive float) and raise a clear ValueError when the value is invalid.

Suggested change
p = self.pressure_hpa()
return 44330.0 * (1.0 - (p / self.sea_level_pressure) ** 0.1903)
slp = getattr(self, "sea_level_pressure", None)
try:
if slp is None or slp <= 0:
raise ValueError(
"sea_level_pressure must be a positive float, got: {!r}".format(slp)
)
except TypeError:
raise ValueError(
"sea_level_pressure must be a positive float, got: {!r}".format(slp)
)
p = self.pressure_hpa()
return 44330.0 * (1.0 - (p / slp) ** 0.1903)

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not addressed: this is an internal attribute, not user input from an external boundary. The project convention is to only validate at system boundaries (user input, external APIs), not internal driver state. Adding defensive validation here would be inconsistent with the rest of the codebase.

Comment thread lib/bme280/bme280/device.py Outdated
def __init__(self, i2c, address=BME280_I2C_DEFAULT_ADDR):
self.i2c = i2c
self.address = address
self.sea_level_pressure = 1013.25
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new public attribute name sea_level_pressure doesn’t encode its units, while the rest of the public API does (e.g., pressure_hpa(), read() returns pressure_hpa). To avoid user confusion (Pa vs hPa), consider renaming to sea_level_pressure_hpa or providing a documented property with unit in its name.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in e920a67: renamed to sea_level_pressure_hpa for consistency with the rest of the API (pressure_hpa(), etc.).

@nedseb nedseb merged commit 43625d9 into main Mar 30, 2026
9 checks passed
@nedseb nedseb deleted the feat/bme280-altitude branch March 30, 2026 09:57
semantic-release-updater Bot pushed a commit that referenced this pull request Mar 30, 2026
# [0.8.0](v0.7.0...v0.8.0) (2026-03-30)

### Features

* **bme280:** Add altitude computation and sea-level pressure ([#321](#321)) ([43625d9](43625d9))
@semantic-release-updater
Copy link
Copy Markdown

🎉 This PR is included in version 0.8.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@nedseb nedseb restored the feat/bme280-altitude branch March 30, 2026 10:05
@nedseb nedseb deleted the feat/bme280-altitude branch March 30, 2026 10:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bme280: Add altitude computation and sea-level pressure reference.

2 participants