mirror of
https://github.com/pimoroni/grow-python
synced 2025-10-25 15:19:23 +00:00
Initial commit
This commit is contained in:
4
library/.coveragerc
Normal file
4
library/.coveragerc
Normal file
@@ -0,0 +1,4 @@
|
||||
[run]
|
||||
source = enviroplus
|
||||
omit =
|
||||
.tox/*
|
||||
16
library/CHANGELOG.txt
Normal file
16
library/CHANGELOG.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
0.0.3
|
||||
-----
|
||||
|
||||
* Fix "self.noise_floor" bug in get_noise_profile
|
||||
|
||||
0.0.2
|
||||
-----
|
||||
|
||||
* Add support for extra ADC channel in Gas
|
||||
* Handle breaking change in new ltr559 library
|
||||
* Add Noise functionality
|
||||
|
||||
0.0.1
|
||||
-----
|
||||
|
||||
* Initial Release
|
||||
21
library/LICENSE.txt
Normal file
21
library/LICENSE.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Pimoroni Ltd.
|
||||
|
||||
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.
|
||||
5
library/MANIFEST.in
Normal file
5
library/MANIFEST.in
Normal file
@@ -0,0 +1,5 @@
|
||||
include CHANGELOG.txt
|
||||
include LICENSE.txt
|
||||
include README.rst
|
||||
include setup.py
|
||||
recursive-include enviroplus *.py
|
||||
93
library/README.rst
Normal file
93
library/README.rst
Normal file
@@ -0,0 +1,93 @@
|
||||
Enviro+
|
||||
=======
|
||||
|
||||
Designed for environmental monitoring, Enviro+ lets you measure air
|
||||
quality (pollutant gases and particulates), temperature, pressure,
|
||||
humidity, light, and noise level. Learn more -
|
||||
https://shop.pimoroni.com/products/enviro-plus
|
||||
|
||||
|Build Status| |Coverage Status| |PyPi Package| |Python Versions|
|
||||
|
||||
Installing
|
||||
==========
|
||||
|
||||
You're best using the "One-line" install method if you want all of the
|
||||
UART serial configuration for the PMS5003 particulate matter sensor to
|
||||
run automatically.
|
||||
|
||||
One-line (Installs from GitHub)
|
||||
-------------------------------
|
||||
|
||||
::
|
||||
|
||||
curl -sSL https://get.pimoroni.com/enviroplus | bash
|
||||
|
||||
**Note** report issues with one-line installer here:
|
||||
https://github.com/pimoroni/get
|
||||
|
||||
Or... Install and configure dependencies from GitHub:
|
||||
-----------------------------------------------------
|
||||
|
||||
- ``git clone https://github.com/pimoroni/enviroplus-python``
|
||||
- ``cd enviroplus-python``
|
||||
- ``sudo ./install.sh``
|
||||
|
||||
**Note** Raspbian Lite users may first need to install git:
|
||||
``sudo apt install git``
|
||||
|
||||
Or... Install from PyPi and configure manually:
|
||||
-----------------------------------------------
|
||||
|
||||
- Run ``sudo pip install enviroplus``
|
||||
|
||||
**Note** this wont perform any of the required configuration changes on
|
||||
your Pi, you may additionally need to:
|
||||
|
||||
- Enable i2c: ``raspi-config nonint do_i2c 0``
|
||||
- Enable SPI: ``raspi-config nonint do_spi 0``
|
||||
|
||||
And if you're using a PMS5003 sensor you will need to:
|
||||
|
||||
- Enable serial:
|
||||
``raspi-config nonint set_config_var enable_uart 1 /boot/config.txt``
|
||||
- Disable serial terminal: ``sudo raspi-config nonint do_serial 1``
|
||||
- Add ``dtoverlay=pi3-miniuart-bt`` to your ``/boot/config.txt``
|
||||
|
||||
And install additional dependencies:
|
||||
|
||||
::
|
||||
|
||||
sudo apt install python-numpy python-smbus python-pil python-setuptools
|
||||
|
||||
Help & Support
|
||||
--------------
|
||||
|
||||
- GPIO Pinout - https://pinout.xyz/pinout/enviro\_plus
|
||||
- Support forums - http://forums.pimoroni.com/c/support
|
||||
- Discord - https://discord.gg/hr93ByC
|
||||
|
||||
.. |Build Status| image:: https://travis-ci.com/pimoroni/enviroplus-python.svg?branch=master
|
||||
:target: https://travis-ci.com/pimoroni/enviroplus-python
|
||||
.. |Coverage Status| image:: https://coveralls.io/repos/github/pimoroni/enviroplus-python/badge.svg?branch=master
|
||||
:target: https://coveralls.io/github/pimoroni/enviroplus-python?branch=master
|
||||
.. |PyPi Package| image:: https://img.shields.io/pypi/v/enviroplus.svg
|
||||
:target: https://pypi.python.org/pypi/enviroplus
|
||||
.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/enviroplus.svg
|
||||
:target: https://pypi.python.org/pypi/enviroplus
|
||||
|
||||
0.0.3
|
||||
-----
|
||||
|
||||
* Fix "self.noise_floor" bug in get_noise_profile
|
||||
|
||||
0.0.2
|
||||
-----
|
||||
|
||||
* Add support for extra ADC channel in Gas
|
||||
* Handle breaking change in new ltr559 library
|
||||
* Add Noise functionality
|
||||
|
||||
0.0.1
|
||||
-----
|
||||
|
||||
* Initial Release
|
||||
1
library/grow/__init__.py
Normal file
1
library/grow/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
__version__ = '0.0.3'
|
||||
140
library/grow/gas.py
Normal file
140
library/grow/gas.py
Normal file
@@ -0,0 +1,140 @@
|
||||
"""Read the MICS6814 via an ads1015 ADC"""
|
||||
|
||||
import time
|
||||
import atexit
|
||||
import ads1015
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
MICS6814_HEATER_PIN = 24
|
||||
MICS6814_GAIN = 6.144
|
||||
|
||||
ads1015.I2C_ADDRESS_DEFAULT = ads1015.I2C_ADDRESS_ALTERNATE
|
||||
_is_setup = False
|
||||
_adc_enabled = False
|
||||
_adc_gain = 6.148
|
||||
|
||||
|
||||
class Mics6814Reading(object):
|
||||
__slots__ = 'oxidising', 'reducing', 'nh3', 'adc'
|
||||
|
||||
def __init__(self, ox, red, nh3, adc=None):
|
||||
self.oxidising = ox
|
||||
self.reducing = red
|
||||
self.nh3 = nh3
|
||||
self.adc = adc
|
||||
|
||||
def __repr__(self):
|
||||
fmt = """Oxidising: {ox:05.02f} Ohms
|
||||
Reducing: {red:05.02f} Ohms
|
||||
NH3: {nh3:05.02f} Ohms"""
|
||||
if self.adc is not None:
|
||||
fmt += """
|
||||
ADC: {adc:05.02f} Volts
|
||||
"""
|
||||
return fmt.format(
|
||||
ox=self.oxidising,
|
||||
red=self.reducing,
|
||||
nh3=self.nh3,
|
||||
adc=self.adc)
|
||||
|
||||
__str__ = __repr__
|
||||
|
||||
|
||||
def setup():
|
||||
global adc, _is_setup
|
||||
if _is_setup:
|
||||
return
|
||||
_is_setup = True
|
||||
|
||||
adc = ads1015.ADS1015(i2c_addr=0x49)
|
||||
adc.set_mode('single')
|
||||
adc.set_programmable_gain(MICS6814_GAIN)
|
||||
adc.set_sample_rate(1600)
|
||||
|
||||
GPIO.setwarnings(False)
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
GPIO.setup(MICS6814_HEATER_PIN, GPIO.OUT)
|
||||
GPIO.output(MICS6814_HEATER_PIN, 1)
|
||||
atexit.register(cleanup)
|
||||
|
||||
|
||||
def enable_adc(value=True):
|
||||
"""Enable reading from the additional ADC pin."""
|
||||
global _adc_enabled
|
||||
_adc_enabled = value
|
||||
|
||||
|
||||
def set_adc_gain(value):
|
||||
"""Set gain value for the additional ADC pin."""
|
||||
global _adc_gain
|
||||
_adc_gain = value
|
||||
|
||||
|
||||
def cleanup():
|
||||
GPIO.output(MICS6814_HEATER_PIN, 0)
|
||||
|
||||
|
||||
def read_all():
|
||||
"""Return gas resistence for oxidising, reducing and NH3"""
|
||||
setup()
|
||||
ox = adc.get_voltage('in0/gnd')
|
||||
red = adc.get_voltage('in1/gnd')
|
||||
nh3 = adc.get_voltage('in2/gnd')
|
||||
|
||||
try:
|
||||
ox = (ox * 56000) / (3.3 - ox)
|
||||
except ZeroDivisionError:
|
||||
ox = 0
|
||||
|
||||
try:
|
||||
red = (red * 56000) / (3.3 - red)
|
||||
except ZeroDivisionError:
|
||||
red = 0
|
||||
|
||||
try:
|
||||
nh3 = (nh3 * 56000) / (3.3 - nh3)
|
||||
except ZeroDivisionError:
|
||||
nh3 = 0
|
||||
|
||||
analog = None
|
||||
|
||||
if _adc_enabled:
|
||||
if _adc_gain == MICS6814_GAIN:
|
||||
analog = adc.get_voltage('ref/gnd')
|
||||
else:
|
||||
adc.set_programmable_gain(_adc_gain)
|
||||
time.sleep(0.05)
|
||||
analog = adc.get_voltage('ref/gnd')
|
||||
adc.set_programmable_gain(MICS6814_GAIN)
|
||||
|
||||
return Mics6814Reading(ox, red, nh3, analog)
|
||||
|
||||
|
||||
def read_oxidising():
|
||||
"""Return gas resistance for oxidising gases.
|
||||
|
||||
Eg chlorine, nitrous oxide
|
||||
"""
|
||||
setup()
|
||||
return read_all().oxidising
|
||||
|
||||
|
||||
def read_reducing():
|
||||
"""Return gas resistance for reducing gases.
|
||||
|
||||
Eg hydrogen, carbon monoxide
|
||||
"""
|
||||
setup()
|
||||
return read_all().reducing
|
||||
|
||||
|
||||
def read_nh3():
|
||||
"""Return gas resistance for nh3/ammonia"""
|
||||
setup()
|
||||
return read_all().nh3
|
||||
|
||||
|
||||
def read_adc():
|
||||
"""Return spare ADC channel value"""
|
||||
setup()
|
||||
return read_all().adc
|
||||
90
library/grow/noise.py
Normal file
90
library/grow/noise.py
Normal file
@@ -0,0 +1,90 @@
|
||||
import sounddevice
|
||||
import numpy
|
||||
|
||||
|
||||
class Noise():
|
||||
def __init__(self,
|
||||
sample_rate=16000,
|
||||
duration=0.5):
|
||||
"""Noise measurement.
|
||||
|
||||
:param sample_rate: Sample rate in Hz
|
||||
:param duraton: Duration, in seconds, of noise sample capture
|
||||
|
||||
"""
|
||||
|
||||
self.duration = duration
|
||||
self.sample_rate = sample_rate
|
||||
|
||||
def get_amplitudes_at_frequency_ranges(self, ranges):
|
||||
"""Return the mean amplitude of frequencies in the given ranges.
|
||||
|
||||
:param ranges: List of ranges including a start and end range
|
||||
|
||||
"""
|
||||
recording = self._record()
|
||||
magnitude = numpy.abs(numpy.fft.rfft(recording[:, 0], n=self.sample_rate))
|
||||
result = []
|
||||
for r in ranges:
|
||||
start, end = r
|
||||
result.append(numpy.mean(magnitude[start:end]))
|
||||
return result
|
||||
|
||||
def get_amplitude_at_frequency_range(self, start, end):
|
||||
"""Return the mean amplitude of frequencies in the specified range.
|
||||
|
||||
:param start: Start frequency (in Hz)
|
||||
:param end: End frequency (in Hz)
|
||||
|
||||
"""
|
||||
n = self.sample_rate // 2
|
||||
if start > n or end > n:
|
||||
raise ValueError("Maxmimum frequency is {}".format(n))
|
||||
|
||||
recording = self._record()
|
||||
magnitude = numpy.abs(numpy.fft.rfft(recording[:, 0], n=self.sample_rate))
|
||||
return numpy.mean(magnitude[start:end])
|
||||
|
||||
def get_noise_profile(self,
|
||||
noise_floor=100,
|
||||
low=0.12,
|
||||
mid=0.36,
|
||||
high=None):
|
||||
"""Returns a noise charateristic profile.
|
||||
|
||||
Bins all frequencies into 3 weighted groups expressed as a percentage of the total frequency range.
|
||||
|
||||
:param noise_floor: "High-pass" frequency, exclude frequencies below this value
|
||||
:param low: Percentage of frequency ranges to count in the low bin (as a float, 0.5 = 50%)
|
||||
:param mid: Percentage of frequency ranges to count in the mid bin (as a float, 0.5 = 50%)
|
||||
:param high: Optional percentage for high bin, effectively creates a "Low-pass" if total percentage is less than 100%
|
||||
|
||||
"""
|
||||
|
||||
if high is None:
|
||||
high = 1.0 - low - mid
|
||||
|
||||
recording = self._record()
|
||||
magnitude = numpy.abs(numpy.fft.rfft(recording[:, 0], n=self.sample_rate))
|
||||
|
||||
sample_count = (self.sample_rate // 2) - noise_floor
|
||||
|
||||
mid_start = noise_floor + int(sample_count * low)
|
||||
high_start = mid_start + int(sample_count * mid)
|
||||
noise_ceiling = high_start + int(sample_count * high)
|
||||
|
||||
amp_low = numpy.mean(magnitude[noise_floor:mid_start])
|
||||
amp_mid = numpy.mean(magnitude[mid_start:high_start])
|
||||
amp_high = numpy.mean(magnitude[high_start:noise_ceiling])
|
||||
amp_total = (amp_low + amp_mid + amp_high) / 3.0
|
||||
|
||||
return amp_low, amp_mid, amp_high, amp_total
|
||||
|
||||
def _record(self):
|
||||
return sounddevice.rec(
|
||||
int(self.duration * self.sample_rate),
|
||||
samplerate=self.sample_rate,
|
||||
blocking=True,
|
||||
channels=1,
|
||||
dtype='float64'
|
||||
)
|
||||
79
library/setup.cfg
Normal file
79
library/setup.cfg
Normal file
@@ -0,0 +1,79 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
[metadata]
|
||||
name = enviroplus
|
||||
version = 0.0.3
|
||||
author = Philip Howard
|
||||
author_email = phil@pimoroni.com
|
||||
description = Enviro pHAT Plus environmental monitoring add-on for Raspberry Pi
|
||||
long_description = file: README.rst
|
||||
keywords = Raspberry Pi
|
||||
url = https://www.pimoroni.com
|
||||
project_urls =
|
||||
GitHub=https://www.github.com/pimoroni/enviroplus-python
|
||||
license = MIT
|
||||
# This includes the license file(s) in the wheel.
|
||||
# https://wheel.readthedocs.io/en/stable/user_guide.html#including-license-files-in-the-generated-wheel-file
|
||||
license_files = LICENSE.txt
|
||||
classifiers =
|
||||
Development Status :: 4 - Beta
|
||||
Operating System :: POSIX :: Linux
|
||||
License :: OSI Approved :: MIT License
|
||||
Intended Audience :: Developers
|
||||
Programming Language :: Python :: 2.7
|
||||
Programming Language :: Python :: 3
|
||||
Topic :: Software Development
|
||||
Topic :: Software Development :: Libraries
|
||||
Topic :: System :: Hardware
|
||||
|
||||
[options]
|
||||
packages = enviroplus
|
||||
install_requires =
|
||||
pimoroni-bme280
|
||||
pms5003
|
||||
ltr559
|
||||
st7735
|
||||
ads1015
|
||||
fonts
|
||||
font-roboto
|
||||
astral
|
||||
pytz
|
||||
sounddevice
|
||||
|
||||
[flake8]
|
||||
exclude =
|
||||
.tox,
|
||||
.eggs,
|
||||
.git,
|
||||
__pycache__,
|
||||
build,
|
||||
dist
|
||||
ignore =
|
||||
E501
|
||||
|
||||
[pimoroni]
|
||||
py2deps =
|
||||
python-pip
|
||||
python-numpy
|
||||
python-smbus
|
||||
python-pil
|
||||
python-spidev
|
||||
python-rpi.gpio
|
||||
libportaudio2
|
||||
py3deps =
|
||||
python3-pip
|
||||
python3-numpy
|
||||
python3-smbus
|
||||
python3-pil
|
||||
python3-spidev
|
||||
python3-rpi.gpio
|
||||
libportaudio2
|
||||
configtxt =
|
||||
dtoverlay=pi3-miniuart-bt
|
||||
dtoverlay=adau7002-simple
|
||||
commands =
|
||||
printf "Setting up i2c and SPI..\n"
|
||||
raspi-config nonint do_spi 0
|
||||
raspi-config nonint do_i2c 0
|
||||
printf "Setting up serial for PMS5003..\n"
|
||||
raspi-config nonint do_serial 1 # Disable serial terminal over /dev/ttyAMA0
|
||||
raspi-config nonint set_config_var enable_uart 1 $CONFIG # Enable serial port
|
||||
33
library/setup.py
Normal file
33
library/setup.py
Normal file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2016 Pimoroni
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
from setuptools import setup, __version__
|
||||
from pkg_resources import parse_version
|
||||
|
||||
minimum_version = parse_version('30.4.0')
|
||||
|
||||
if parse_version(__version__) < minimum_version:
|
||||
raise RuntimeError("Package setuptools must be at least version {}".format(minimum_version))
|
||||
|
||||
setup()
|
||||
90
library/tests/conftest.py
Normal file
90
library/tests/conftest.py
Normal file
@@ -0,0 +1,90 @@
|
||||
"""Test configuration.
|
||||
These allow the mocking of various Python modules
|
||||
that might otherwise have runtime side-effects.
|
||||
"""
|
||||
import sys
|
||||
import mock
|
||||
import pytest
|
||||
from i2cdevice import MockSMBus
|
||||
|
||||
|
||||
class SMBusFakeDevice(MockSMBus):
|
||||
def __init__(self, i2c_bus):
|
||||
MockSMBus.__init__(self, i2c_bus)
|
||||
self.regs[0x00:0x01] = 0x0f, 0x00
|
||||
|
||||
|
||||
@pytest.fixture(scope='function', autouse=True)
|
||||
def cleanup():
|
||||
yield None
|
||||
try:
|
||||
del sys.modules['enviroplus']
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
del sys.modules['enviroplus.noise']
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
del sys.modules['enviroplus.gas']
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
|
||||
@pytest.fixture(scope='function', autouse=False)
|
||||
def GPIO():
|
||||
"""Mock RPi.GPIO module."""
|
||||
GPIO = mock.MagicMock()
|
||||
# Fudge for Python < 37 (possibly earlier)
|
||||
sys.modules['RPi'] = mock.Mock()
|
||||
sys.modules['RPi'].GPIO = GPIO
|
||||
sys.modules['RPi.GPIO'] = GPIO
|
||||
yield GPIO
|
||||
del sys.modules['RPi']
|
||||
del sys.modules['RPi.GPIO']
|
||||
|
||||
|
||||
@pytest.fixture(scope='function', autouse=False)
|
||||
def spidev():
|
||||
"""Mock spidev module."""
|
||||
spidev = mock.MagicMock()
|
||||
sys.modules['spidev'] = spidev
|
||||
yield spidev
|
||||
del sys.modules['spidev']
|
||||
|
||||
|
||||
@pytest.fixture(scope='function', autouse=False)
|
||||
def smbus():
|
||||
"""Mock smbus module."""
|
||||
smbus = mock.MagicMock()
|
||||
smbus.SMBus = SMBusFakeDevice
|
||||
sys.modules['smbus'] = smbus
|
||||
yield smbus
|
||||
del sys.modules['smbus']
|
||||
|
||||
|
||||
@pytest.fixture(scope='function', autouse=False)
|
||||
def atexit():
|
||||
"""Mock atexit module."""
|
||||
atexit = mock.MagicMock()
|
||||
sys.modules['atexit'] = atexit
|
||||
yield atexit
|
||||
del sys.modules['atexit']
|
||||
|
||||
|
||||
@pytest.fixture(scope='function', autouse=False)
|
||||
def sounddevice():
|
||||
"""Mock sounddevice module."""
|
||||
sounddevice = mock.MagicMock()
|
||||
sys.modules['sounddevice'] = sounddevice
|
||||
yield sounddevice
|
||||
del sys.modules['sounddevice']
|
||||
|
||||
|
||||
@pytest.fixture(scope='function', autouse=False)
|
||||
def numpy():
|
||||
"""Mock numpy module."""
|
||||
numpy = mock.MagicMock()
|
||||
sys.modules['numpy'] = numpy
|
||||
yield numpy
|
||||
del sys.modules['numpy']
|
||||
48
library/tests/test_noise.py
Normal file
48
library/tests/test_noise.py
Normal file
@@ -0,0 +1,48 @@
|
||||
import pytest
|
||||
|
||||
|
||||
def test_noise_setup(sounddevice, numpy):
|
||||
from enviroplus.noise import Noise
|
||||
|
||||
noise = Noise(sample_rate=16000, duration=0.1)
|
||||
del noise
|
||||
|
||||
|
||||
def test_noise_get_amplitudes_at_frequency_ranges(sounddevice, numpy):
|
||||
from enviroplus.noise import Noise
|
||||
|
||||
noise = Noise(sample_rate=16000, duration=0.1)
|
||||
noise.get_amplitudes_at_frequency_ranges([
|
||||
(100, 500),
|
||||
(501, 1000)
|
||||
])
|
||||
|
||||
sounddevice.rec.assert_called_with(0.1 * 16000, samplerate=16000, blocking=True, channels=1, dtype='float64')
|
||||
|
||||
|
||||
def test_noise_get_noise_profile(sounddevice, numpy):
|
||||
from enviroplus.noise import Noise
|
||||
|
||||
numpy.mean.return_value = 10.0
|
||||
|
||||
noise = Noise(sample_rate=16000, duration=0.1)
|
||||
amp_low, amp_mid, amp_high, amp_total = noise.get_noise_profile(
|
||||
noise_floor=100,
|
||||
low=0.12,
|
||||
mid=0.36,
|
||||
high=None)
|
||||
|
||||
sounddevice.rec.assert_called_with(0.1 * 16000, samplerate=16000, blocking=True, channels=1, dtype='float64')
|
||||
|
||||
assert amp_total == 10.0
|
||||
|
||||
|
||||
def test_get_amplitude_at_frequency_range(sounddevice, numpy):
|
||||
from enviroplus.noise import Noise
|
||||
|
||||
noise = Noise(sample_rate=16000, duration=0.1)
|
||||
|
||||
noise.get_amplitude_at_frequency_range(0, 8000)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
noise.get_amplitude_at_frequency_range(0, 16000)
|
||||
66
library/tests/test_setup.py
Normal file
66
library/tests/test_setup.py
Normal file
@@ -0,0 +1,66 @@
|
||||
def test_gas_setup(GPIO, smbus):
|
||||
from enviroplus import gas
|
||||
gas._is_setup = False
|
||||
gas.setup()
|
||||
gas.setup()
|
||||
|
||||
|
||||
def test_gas_read_all(GPIO, smbus):
|
||||
from enviroplus import gas
|
||||
gas._is_setup = False
|
||||
result = gas.read_all()
|
||||
|
||||
assert type(result.oxidising) == float
|
||||
assert int(result.oxidising) == 16641
|
||||
|
||||
assert type(result.reducing) == float
|
||||
assert int(result.reducing) == 16727
|
||||
|
||||
assert type(result.nh3) == float
|
||||
assert int(result.nh3) == 16813
|
||||
|
||||
assert "Oxidising" in str(result)
|
||||
|
||||
|
||||
def test_gas_read_each(GPIO, smbus):
|
||||
from enviroplus import gas
|
||||
gas._is_setup = False
|
||||
|
||||
assert int(gas.read_oxidising()) == 16641
|
||||
assert int(gas.read_reducing()) == 16727
|
||||
assert int(gas.read_nh3()) == 16813
|
||||
|
||||
|
||||
def test_gas_read_adc(GPIO, smbus):
|
||||
from enviroplus import gas
|
||||
gas._is_setup = False
|
||||
|
||||
gas.enable_adc(True)
|
||||
gas.set_adc_gain(2.048)
|
||||
assert gas.read_adc() == 0.255
|
||||
|
||||
|
||||
def test_gas_read_adc_default_gain(GPIO, smbus):
|
||||
from enviroplus import gas
|
||||
gas._is_setup = False
|
||||
|
||||
gas.enable_adc(True)
|
||||
gas.set_adc_gain(gas.MICS6814_GAIN)
|
||||
assert gas.read_adc() == 0.765
|
||||
|
||||
|
||||
def test_gas_read_adc_str(GPIO, smbus):
|
||||
from enviroplus import gas
|
||||
gas._is_setup = False
|
||||
|
||||
gas.enable_adc(True)
|
||||
gas.set_adc_gain(2.048)
|
||||
assert 'ADC' in str(gas.read_all())
|
||||
|
||||
|
||||
def test_gas_cleanup(GPIO, smbus):
|
||||
from enviroplus import gas
|
||||
|
||||
gas.cleanup()
|
||||
|
||||
GPIO.output.assert_called_with(gas.MICS6814_HEATER_PIN, 0)
|
||||
24
library/tox.ini
Normal file
24
library/tox.ini
Normal file
@@ -0,0 +1,24 @@
|
||||
[tox]
|
||||
envlist = py{27,35},qa
|
||||
skip_missing_interpreters = True
|
||||
|
||||
[testenv]
|
||||
commands =
|
||||
python setup.py install
|
||||
coverage run -m py.test -v -r wsx
|
||||
coverage report
|
||||
deps =
|
||||
mock
|
||||
pytest>=3.1
|
||||
pytest-cov
|
||||
|
||||
[testenv:qa]
|
||||
commands =
|
||||
check-manifest --ignore tox.ini,tests*,.coveragerc
|
||||
python setup.py check -m -r -s
|
||||
flake8 --ignore E501
|
||||
rstcheck README.rst
|
||||
deps =
|
||||
check-manifest
|
||||
flake8
|
||||
rstcheck
|
||||
Reference in New Issue
Block a user