blob: abf71bae0d888163f4f5d87a34b6e9600371b780 [file] [log] [blame]
# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Drivers for shared functionality provided by the Environment Bonnet."""
import os
import platform
from luma.core.interface.serial import noop, spi
from luma.oled.device import ssd1306
def _get_path(sysfs_name):
search_path = '/sys/bus/iio/devices/'
try:
for fname in os.listdir(search_path):
with open(search_path + fname + '/name', 'r') as f:
if sysfs_name in f.read():
return search_path + fname
return ''
except FileNotFoundError:
return ''
def _read_sysfs(path, retries=2):
try:
with open(path, 'r') as f:
# Allow multiple attempts in case sensor times out.
for _ in range(retries):
try:
data = f.read()
if data:
return float(data)
except:
pass
return None
except FileNotFoundError:
return None
class EnviroBoard():
"""
An interface for all input and output modules on the Environmental Sensor Board.
"""
def __init__(self):
# Obtain the full sysfs path of the IIO devices.
self._hdc2010 = _get_path('hdc20x0')
self._bmp280 = _get_path('bmp280')
self._opt3002 = _get_path('opt3001')
self._tla2021 = _get_path('ads1015')
# Create SSD1306 OLED instance, with SPI as the interface.
if 'mendel' in platform.platform():
from .rpi_gpio_periphery import pGPIO
# Values for the Coral Dev Board (running Mendel Linux).
self._display = ssd1306(serial_interface=spi(gpio=pGPIO(), port=32766, device=0, gpio_DC=138, gpio_RST=140),
gpio=pGPIO(), height=32, rotate=2)
else:
# Default to RPi.GPIO in luma and defaults GPIO.
self._display = ssd1306(serial_interface=spi(),
gpio=noop(), height=32, rotate=2)
@property
def temperature(self):
"""
Gets the current temperature, in Celsius.
"""
temperature = _read_sysfs(self._hdc2010 + '/in_temp_input')
if temperature is not None:
return temperature
temperature = _read_sysfs(self._bmp280 + '/in_temp_input')
# BMP280 reports as mC.
if temperature is not None:
return temperature / 1000.0
return None
@property
def humidity(self):
"""
Gets the current relative humidity, in percentage.
"""
return _read_sysfs(self._hdc2010 + '/in_humidityrelative_input')
@property
def ambient_light(self):
"""
Gets the ambient light, in lux.
"""
return _read_sysfs(self._opt3002 + '/in_illuminance_input')
@property
def pressure(self):
"""
Gets the current atmospheric pressure, in kPa.
"""
return _read_sysfs(self._bmp280 + '/in_pressure_input')
@property
def grove_analog(self):
"""
Gets a raw value from a device connected to the board's analog Grove connector.
.. note::
ADC is set to +/- 6V range, independent of supply voltage (selected by jumper).
"""
return _read_sysfs(self._tla2021 + '/in_voltage0_raw')
@property
def display(self):
"""
Gets an instance of :class:`luma.core.device.device` representing the board's OLED display.
For example, you can write to the display using :class:`luma.core.render.canvas`
as follows::
enviro = EnviroBoard()
update_display(enviro.display, "Hello world")
def update_display(display, msg):
with canvas(display) as draw:
draw.text((0, 0), msg, fill='white')
"""
return self._display