Skip to content

Commit 2cfed37

Browse files
committed
Port to new libraries. Fixup examples and tests.
1 parent 342cf4e commit 2cfed37

24 files changed

+312
-302
lines changed

enviroplus/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '0.0.6'
1+
__version__ = "0.0.6"

enviroplus/gas.py

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,29 @@
44
import time
55

66
import ads1015
7-
import RPi.GPIO as GPIO
7+
import gpiod
8+
import gpiodevice
9+
from gpiod.line import Direction, Value
810

9-
MICS6814_HEATER_PIN = 24
1011
MICS6814_GAIN = 6.144
1112

13+
OUTH = gpiod.LineSettings(direction=Direction.OUTPUT, output_value=Value.ACTIVE)
14+
PLATFORMS = {
15+
"Radxa ROCK 5B": {"heater": ("PIN_18", OUTH)},
16+
"Raspberry Pi 5": {"heater": ("PIN18", OUTH)},
17+
"Raspberry Pi 4": {"heater": ("GPIO24", OUTH)}
18+
}
19+
1220
ads1015.I2C_ADDRESS_DEFAULT = ads1015.I2C_ADDRESS_ALTERNATE
1321
_is_setup = False
1422
_is_available = False
1523
_adc_enabled = False
1624
_adc_gain = 6.148
25+
_heater = None
1726

1827

1928
class Mics6814Reading(object):
20-
__slots__ = 'oxidising', 'reducing', 'nh3', 'adc'
29+
__slots__ = "oxidising", "reducing", "nh3", "adc"
2130

2231
def __init__(self, ox, red, nh3, adc=None):
2332
self.oxidising = ox
@@ -26,24 +35,20 @@ def __init__(self, ox, red, nh3, adc=None):
2635
self.adc = adc
2736

2837
def __repr__(self):
29-
fmt = """Oxidising: {ox:05.02f} Ohms
30-
Reducing: {red:05.02f} Ohms
31-
NH3: {nh3:05.02f} Ohms"""
38+
fmt = f"""Oxidising: {self.oxidising:05.02f} Ohms
39+
Reducing: {self.reducing:05.02f} Ohms
40+
NH3: {self.nh3:05.02f} Ohms"""
3241
if self.adc is not None:
33-
fmt += """
34-
ADC: {adc:05.02f} Volts
42+
fmt += f"""
43+
ADC: {self.adc:05.02f} Volts
3544
"""
36-
return fmt.format(
37-
ox=self.oxidising,
38-
red=self.reducing,
39-
nh3=self.nh3,
40-
adc=self.adc)
45+
return fmt
4146

4247
__str__ = __repr__
4348

4449

4550
def setup():
46-
global adc, adc_type, _is_setup, _is_available
51+
global adc, adc_type, _is_setup, _is_available, _heater
4752
if _is_setup:
4853
return
4954
_is_setup = True
@@ -56,17 +61,15 @@ def setup():
5661
_is_available = False
5762
return
5863

59-
adc.set_mode('single')
64+
adc.set_mode("single")
6065
adc.set_programmable_gain(MICS6814_GAIN)
61-
if adc_type == 'ADS1115':
66+
if adc_type == "ADS1115":
6267
adc.set_sample_rate(128)
6368
else:
6469
adc.set_sample_rate(1600)
6570

66-
GPIO.setwarnings(False)
67-
GPIO.setmode(GPIO.BCM)
68-
GPIO.setup(MICS6814_HEATER_PIN, GPIO.OUT)
69-
GPIO.output(MICS6814_HEATER_PIN, 1)
71+
_heater = gpiodevice.get_pins_for_platform(PLATFORMS)[0]
72+
7073
atexit.register(cleanup)
7174

7275

@@ -88,7 +91,10 @@ def set_adc_gain(value):
8891

8992

9093
def cleanup():
91-
GPIO.output(MICS6814_HEATER_PIN, 0)
94+
if _heater is None:
95+
return
96+
lines, offset = _heater
97+
lines.set_value(offset, Value.INACTIVE)
9298

9399

94100
def read_all():
@@ -98,9 +104,9 @@ def read_all():
98104
if not _is_available:
99105
raise RuntimeError("Gas sensor not connected.")
100106

101-
ox = adc.get_voltage('in0/gnd')
102-
red = adc.get_voltage('in1/gnd')
103-
nh3 = adc.get_voltage('in2/gnd')
107+
ox = adc.get_voltage("in0/gnd")
108+
red = adc.get_voltage("in1/gnd")
109+
nh3 = adc.get_voltage("in2/gnd")
104110

105111
try:
106112
ox = (ox * 56000) / (3.3 - ox)
@@ -121,11 +127,11 @@ def read_all():
121127

122128
if _adc_enabled:
123129
if _adc_gain == MICS6814_GAIN:
124-
analog = adc.get_voltage('ref/gnd')
130+
analog = adc.get_voltage("ref/gnd")
125131
else:
126132
adc.set_programmable_gain(_adc_gain)
127133
time.sleep(0.05)
128-
analog = adc.get_voltage('ref/gnd')
134+
analog = adc.get_voltage("ref/gnd")
129135
adc.set_programmable_gain(MICS6814_GAIN)
130136

131137
return Mics6814Reading(ox, red, nh3, analog)

enviroplus/noise.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22
import sounddevice
33

44

5-
class Noise():
6-
def __init__(self,
7-
sample_rate=16000,
8-
duration=0.5):
5+
class Noise:
6+
def __init__(self, sample_rate=16000, duration=0.5):
97
"""Noise measurement.
108
119
:param sample_rate: Sample rate in Hz
@@ -39,17 +37,13 @@ def get_amplitude_at_frequency_range(self, start, end):
3937
"""
4038
n = self.sample_rate // 2
4139
if start > n or end > n:
42-
raise ValueError("Maximum frequency is {}".format(n))
40+
raise ValueError(f"Maximum frequency is {n}")
4341

4442
recording = self._record()
4543
magnitude = numpy.abs(numpy.fft.rfft(recording[:, 0], n=self.sample_rate))
4644
return numpy.mean(magnitude[start:end])
4745

48-
def get_noise_profile(self,
49-
noise_floor=100,
50-
low=0.12,
51-
mid=0.36,
52-
high=None):
46+
def get_noise_profile(self, noise_floor=100, low=0.12, mid=0.36, high=None):
5347
"""Returns a noise characteristic profile.
5448
5549
Bins all frequencies into 3 weighted groups expressed as a percentage of the total frequency range.
@@ -83,9 +77,9 @@ def get_noise_profile(self,
8377
def _record(self):
8478
return sounddevice.rec(
8579
int(self.duration * self.sample_rate),
86-
device='adau7002',
80+
device="adau7002",
8781
samplerate=self.sample_rate,
8882
blocking=True,
8983
channels=1,
90-
dtype='float64'
84+
dtype="float64"
9185
)

examples/adc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
from enviroplus import gas
77

88
logging.basicConfig(
9-
format='%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s',
9+
format="%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s",
1010
level=logging.INFO,
11-
datefmt='%Y-%m-%d %H:%M:%S')
11+
datefmt="%Y-%m-%d %H:%M:%S")
1212

1313
logging.info("""adc.py - Print readings from the MICS6814 Gas sensor.
1414

examples/all-in-one-enviro-mini.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import sys
66
import time
77

8-
import ST7735
8+
import st7735
99

1010
try:
1111
# Transitional fix for breaking change in LTR559
@@ -22,23 +22,23 @@
2222
from PIL import Image, ImageDraw, ImageFont
2323

2424
logging.basicConfig(
25-
format='%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s',
25+
format="%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s",
2626
level=logging.INFO,
27-
datefmt='%Y-%m-%d %H:%M:%S')
27+
datefmt="%Y-%m-%d %H:%M:%S")
2828

29-
logging.info("""all-in-one.py - Displays readings from all of Enviro plus' sensors
29+
logging.info("""all-in-one.py - Displays readings from all of Enviro plus" sensors
3030
Press Ctrl+C to exit!
3131
""")
3232

3333
# BME280 temperature/pressure/humidity sensor
3434
bme280 = BME280()
3535

3636
# Create ST7735 LCD display class
37-
st7735 = ST7735.ST7735(
37+
st7735 = st7735.ST7735(
3838
port=0,
3939
cs=1,
40-
dc=9,
41-
backlight=12,
40+
dc="PIN21", # "GPIO9" on a Raspberry Pi 4
41+
backlight="PIN32", # "GPIO12" on a Raspberry Pi 4
4242
rotation=270,
4343
spi_speed_hz=10000000
4444
)
@@ -50,7 +50,7 @@
5050
HEIGHT = st7735.height
5151

5252
# Set up canvas and font
53-
img = Image.new('RGB', (WIDTH, HEIGHT), color=(0, 0, 0))
53+
img = Image.new("RGB", (WIDTH, HEIGHT), color=(0, 0, 0))
5454
draw = ImageDraw.Draw(img)
5555
path = os.path.dirname(os.path.realpath(__file__))
5656
font_size = 20
@@ -71,7 +71,7 @@ def display_text(variable, data, unit):
7171
vmax = max(values[variable])
7272
colours = [(v - vmin + 1) / (vmax - vmin + 1) for v in values[variable]]
7373
# Format the variable name and value
74-
message = "{}: {:.1f} {}".format(variable[:4], data, unit)
74+
message = f"{variable[:4]}: {data:.1f} {unit}"
7575
logging.info(message)
7676
draw.rectangle((0, 0, WIDTH, HEIGHT), (255, 255, 255))
7777
for i in range(len(colours)):
@@ -90,9 +90,9 @@ def display_text(variable, data, unit):
9090

9191
# Get the temperature of the CPU for compensation
9292
def get_cpu_temperature():
93-
process = Popen(['vcgencmd', 'measure_temp'], stdout=PIPE, universal_newlines=True)
93+
process = Popen(["vcgencmd", "measure_temp"], stdout=PIPE, universal_newlines=True)
9494
output, _error = process.communicate()
95-
return float(output[output.index('=') + 1:output.rindex("'")])
95+
return float(output[output.index("=") + 1:output.rindex("'")])
9696

9797

9898
# Tuning factor for compensation. Decrease this number to adjust the
@@ -131,7 +131,7 @@ def get_cpu_temperature():
131131
# One mode for each variable
132132
if mode == 0:
133133
# variable = "temperature"
134-
unit = "C"
134+
unit = "°C"
135135
cpu_temp = get_cpu_temperature()
136136
# Smooth out with some averaging to decrease jitter
137137
cpu_temps = cpu_temps[1:] + [cpu_temp]

examples/all-in-one-no-pm.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import sys
66
import time
77

8-
import ST7735
8+
import st7735
99

1010
try:
1111
# Transitional fix for breaking change in LTR559
@@ -23,9 +23,9 @@
2323
from enviroplus import gas
2424

2525
logging.basicConfig(
26-
format='%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s',
26+
format="%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s",
2727
level=logging.INFO,
28-
datefmt='%Y-%m-%d %H:%M:%S')
28+
datefmt="%Y-%m-%d %H:%M:%S")
2929

3030
logging.info("""all-in-one.py - Displays readings from all of Enviro plus' sensors
3131
Press Ctrl+C to exit!
@@ -35,11 +35,11 @@
3535
bme280 = BME280()
3636

3737
# Create ST7735 LCD display class
38-
st7735 = ST7735.ST7735(
38+
st7735 = st7735.ST7735(
3939
port=0,
4040
cs=1,
41-
dc=9,
42-
backlight=12,
41+
dc="PIN21", # "GPIO9" on a Raspberry Pi 4
42+
backlight="PIN32", # "GPIO12" on a Raspberry Pi 4
4343
rotation=270,
4444
spi_speed_hz=10000000
4545
)
@@ -51,7 +51,7 @@
5151
HEIGHT = st7735.height
5252

5353
# Set up canvas and font
54-
img = Image.new('RGB', (WIDTH, HEIGHT), color=(0, 0, 0))
54+
img = Image.new("RGB", (WIDTH, HEIGHT), color=(0, 0, 0))
5555
draw = ImageDraw.Draw(img)
5656
path = os.path.dirname(os.path.realpath(__file__))
5757
font_size = 20
@@ -72,7 +72,7 @@ def display_text(variable, data, unit):
7272
vmax = max(values[variable])
7373
colours = [(v - vmin + 1) / (vmax - vmin + 1) for v in values[variable]]
7474
# Format the variable name and value
75-
message = "{}: {:.1f} {}".format(variable[:4], data, unit)
75+
message = f"{variable[:4]}: {data:.1f} {unit}"
7676
logging.info(message)
7777
draw.rectangle((0, 0, WIDTH, HEIGHT), (255, 255, 255))
7878
for i in range(len(colours)):
@@ -136,7 +136,7 @@ def get_cpu_temperature():
136136
# One mode for each variable
137137
if mode == 0:
138138
# variable = "temperature"
139-
unit = "C"
139+
unit = "°C"
140140
cpu_temp = get_cpu_temperature()
141141
# Smooth out with some averaging to decrease jitter
142142
cpu_temps = cpu_temps[1:] + [cpu_temp]

examples/all-in-one.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import sys
55
import time
66

7-
import ST7735
7+
import st7735
88

99
try:
1010
# Transitional fix for breaking change in LTR559
@@ -24,9 +24,9 @@
2424
from enviroplus import gas
2525

2626
logging.basicConfig(
27-
format='%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s',
27+
format="%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s",
2828
level=logging.INFO,
29-
datefmt='%Y-%m-%d %H:%M:%S')
29+
datefmt="%Y-%m-%d %H:%M:%S")
3030

3131
logging.info("""all-in-one.py - Displays readings from all of Enviro plus' sensors
3232
@@ -41,11 +41,11 @@
4141
pms5003 = PMS5003()
4242

4343
# Create ST7735 LCD display class
44-
st7735 = ST7735.ST7735(
44+
st7735 = st7735.ST7735(
4545
port=0,
4646
cs=1,
47-
dc=9,
48-
backlight=12,
47+
dc="PIN21", # "GPIO9" on a Raspberry Pi 4
48+
backlight="PIN32", # "GPIO12" on a Raspberry Pi 4
4949
rotation=270,
5050
spi_speed_hz=10000000
5151
)
@@ -57,7 +57,7 @@
5757
HEIGHT = st7735.height
5858

5959
# Set up canvas and font
60-
img = Image.new('RGB', (WIDTH, HEIGHT), color=(0, 0, 0))
60+
img = Image.new("RGB", (WIDTH, HEIGHT), color=(0, 0, 0))
6161
draw = ImageDraw.Draw(img)
6262
font_size = 20
6363
font = ImageFont.truetype(UserFont, font_size)
@@ -77,7 +77,7 @@ def display_text(variable, data, unit):
7777
vmax = max(values[variable])
7878
colours = [(v - vmin + 1) / (vmax - vmin + 1) for v in values[variable]]
7979
# Format the variable name and value
80-
message = "{}: {:.1f} {}".format(variable[:4], data, unit)
80+
message = f"{variable[:4]}: {data:.1f} {unit}"
8181
logging.info(message)
8282
draw.rectangle((0, 0, WIDTH, HEIGHT), (255, 255, 255))
8383
for i in range(len(colours)):
@@ -144,7 +144,7 @@ def get_cpu_temperature():
144144
# One mode for each variable
145145
if mode == 0:
146146
# variable = "temperature"
147-
unit = "C"
147+
unit = "°C"
148148
cpu_temp = get_cpu_temperature()
149149
# Smooth out with some averaging to decrease jitter
150150
cpu_temps = cpu_temps[1:] + [cpu_temp]

0 commit comments

Comments
 (0)