forked from home-assistant/core
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for Bosch BMP280 Sensor (home-assistant#30837)
* Implement support for Bosch BMP280 Sensor * Fixed linting errors * Fixed case of the requirement RPi.GPIO so it is ignored in requirements * Update homeassistant/components/bmp280/manifest.json Co-Authored-By: springstan <[email protected]> * Update homeassistant/components/bmp280/sensor.py Co-Authored-By: springstan <[email protected]> * Fix linting errors * Implemented changes suggested by code review * Fixed incomplete refactoring Co-authored-by: springstan <[email protected]>
- Loading branch information
1 parent
c21a2ea
commit df67ab9
Showing
6 changed files
with
174 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
"""The Bosch BMP280 sensor integration.""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"domain": "bmp280", | ||
"name": "Bosch BMP280 Environmental Sensor", | ||
"documentation": "https://www.home-assistant.io/integrations/bmp280", | ||
"dependencies": [], | ||
"codeowners": ["@belidzs"], | ||
"requirements": ["adafruit-circuitpython-bmp280==3.1.1", "RPi.GPIO==0.7.0"], | ||
"quality_scale": "silver" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
"""Platform for Bosch BMP280 Environmental Sensor integration.""" | ||
from datetime import timedelta | ||
import logging | ||
|
||
from adafruit_bmp280 import Adafruit_BMP280_I2C | ||
import board | ||
from busio import I2C | ||
import voluptuous as vol | ||
|
||
from homeassistant.components.sensor import ( | ||
DEVICE_CLASS_PRESSURE, | ||
DEVICE_CLASS_TEMPERATURE, | ||
PLATFORM_SCHEMA, | ||
) | ||
from homeassistant.const import CONF_NAME, PRESSURE_HPA, TEMP_CELSIUS | ||
from homeassistant.exceptions import PlatformNotReady | ||
import homeassistant.helpers.config_validation as cv | ||
from homeassistant.helpers.entity import Entity | ||
from homeassistant.util import Throttle | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
DEFAULT_NAME = "BMP280" | ||
DEFAULT_SCAN_INTERVAL = timedelta(seconds=15) | ||
|
||
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=3) | ||
|
||
MIN_I2C_ADDRESS = 0x76 | ||
MAX_I2C_ADDRESS = 0x77 | ||
|
||
CONF_I2C_ADDRESS = "i2c_address" | ||
|
||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( | ||
{ | ||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, | ||
vol.Required(CONF_I2C_ADDRESS): vol.All( | ||
vol.Coerce(int), vol.Range(min=MIN_I2C_ADDRESS, max=MAX_I2C_ADDRESS) | ||
), | ||
} | ||
) | ||
|
||
|
||
def setup_platform(hass, config, add_entities, discovery_info=None): | ||
"""Set up the sensor platform.""" | ||
try: | ||
# initializing I2C bus using the auto-detected pins | ||
i2c = I2C(board.SCL, board.SDA) | ||
# initializing the sensor | ||
bmp280 = Adafruit_BMP280_I2C(i2c, address=config[CONF_I2C_ADDRESS]) | ||
except ValueError as error: | ||
# this usually happens when the board is I2C capable, but the device can't be found at the configured address | ||
if str(error.args[0]).startswith("No I2C device at address"): | ||
_LOGGER.error( | ||
"%s. Hint: Check wiring and make sure that the SDO pin is tied to either ground (0x76) or VCC (0x77)!", | ||
error.args[0], | ||
) | ||
raise PlatformNotReady() | ||
raise error | ||
# use custom name if there's any | ||
name = config.get(CONF_NAME) | ||
# BMP280 has both temperature and pressure sensing capability | ||
add_entities( | ||
[Bmp280TemperatureSensor(bmp280, name), Bmp280PressureSensor(bmp280, name)] | ||
) | ||
|
||
|
||
class Bmp280Sensor(Entity): | ||
"""Base class for BMP280 entities.""" | ||
|
||
def __init__( | ||
self, | ||
bmp280: Adafruit_BMP280_I2C, | ||
name: str, | ||
unit_of_measurement: str, | ||
device_class: str, | ||
): | ||
"""Initialize the sensor.""" | ||
self._bmp280 = bmp280 | ||
self._name = name | ||
self._unit_of_measurement = unit_of_measurement | ||
self._device_class = device_class | ||
self._state = None | ||
self._errored = False | ||
|
||
@property | ||
def name(self): | ||
"""Return the name of the sensor.""" | ||
return self._name | ||
|
||
@property | ||
def state(self): | ||
"""Return the state of the sensor.""" | ||
return self._state | ||
|
||
@property | ||
def unit_of_measurement(self): | ||
"""Return the unit of measurement.""" | ||
return self._unit_of_measurement | ||
|
||
@property | ||
def device_class(self): | ||
"""Return the device class.""" | ||
return self._device_class | ||
|
||
@property | ||
def available(self) -> bool: | ||
"""Return if the device is currently available.""" | ||
return not self._errored | ||
|
||
|
||
class Bmp280TemperatureSensor(Bmp280Sensor): | ||
"""Representation of a Bosch BMP280 Temperature Sensor.""" | ||
|
||
def __init__(self, bmp280: Adafruit_BMP280_I2C, name: str): | ||
"""Initialize the entity.""" | ||
super().__init__( | ||
bmp280, f"{name} Temperature", TEMP_CELSIUS, DEVICE_CLASS_TEMPERATURE | ||
) | ||
|
||
@Throttle(MIN_TIME_BETWEEN_UPDATES) | ||
def update(self): | ||
"""Fetch new state data for the sensor.""" | ||
try: | ||
self._state = round(self._bmp280.temperature, 1) | ||
if self._errored: | ||
_LOGGER.warning("Communication restored with temperature sensor") | ||
self._errored = False | ||
except OSError: | ||
# this is thrown when a working sensor is unplugged between two updates | ||
_LOGGER.warning( | ||
"Unable to read temperature data due to a communication problem" | ||
) | ||
self._errored = True | ||
|
||
|
||
class Bmp280PressureSensor(Bmp280Sensor): | ||
"""Representation of a Bosch BMP280 Barometric Pressure Sensor.""" | ||
|
||
def __init__(self, bmp280: Adafruit_BMP280_I2C, name: str): | ||
"""Initialize the entity.""" | ||
super().__init__( | ||
bmp280, f"{name} Pressure", PRESSURE_HPA, DEVICE_CLASS_PRESSURE | ||
) | ||
|
||
@Throttle(MIN_TIME_BETWEEN_UPDATES) | ||
def update(self): | ||
"""Fetch new state data for the sensor.""" | ||
try: | ||
self._state = round(self._bmp280.pressure) | ||
if self._errored: | ||
_LOGGER.warning("Communication restored with pressure sensor") | ||
self._errored = False | ||
except OSError: | ||
# this is thrown when a working sensor is unplugged between two updates | ||
_LOGGER.warning( | ||
"Unable to read pressure data due to a communication problem" | ||
) | ||
self._errored = True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters