Merged cipy-improved-logging, omitted luftdaten.py for now
[EVA-2020-02-2.git] / examples / all-in-one-no-pm.py
CommitLineData
c96f1398
TF
1#!/usr/bin/env python
2
3import time
4import colorsys
5import os
6import sys
7import ST7735
8import ltr559
9
10from bme280 import BME280
11from enviroplus import gas
12from subprocess import PIPE, Popen
13from PIL import Image
14from PIL import ImageDraw
15from PIL import ImageFont
10b73e18 16import logging
c96f1398 17
10b73e18
CM
18logging.basicConfig(
19 format='%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s',
20 level=logging.INFO,
21 datefmt='%Y-%m-%d %H:%M:%S')
22
23logging.info("""all-in-one.py - Displays readings from all of Enviro plus' sensors
c96f1398
TF
24Press Ctrl+C to exit!
25""")
26
27# BME280 temperature/pressure/humidity sensor
28bme280 = BME280()
29
30# Create ST7735 LCD display class
31st7735 = ST7735.ST7735(
32 port=0,
33 cs=1,
34 dc=9,
35 backlight=12,
36 rotation=270,
37 spi_speed_hz=10000000
38)
39
40# Initialize display
41st7735.begin()
42
43WIDTH = st7735.width
44HEIGHT = st7735.height
45
46# Set up canvas and font
47img = Image.new('RGB', (WIDTH, HEIGHT), color=(0, 0, 0))
48draw = ImageDraw.Draw(img)
49path = os.path.dirname(os.path.realpath(__file__))
50font = ImageFont.truetype(path + "/fonts/Asap/Asap-Bold.ttf", 20)
51
52message = ""
53
54# The position of the top bar
55top_pos = 25
56
57
58# Displays data and text on the 0.96" LCD
59def display_text(variable, data, unit):
60 # Maintain length of list
61 values[variable] = values[variable][1:] + [data]
62 # Scale the values for the variable between 0 and 1
63 colours = [(v - min(values[variable]) + 1) / (max(values[variable])
64 - min(values[variable]) + 1) for v in values[variable]]
65 # Format the variable name and value
66 message = "{}: {:.1f} {}".format(variable[:4], data, unit)
10b73e18 67 logging.info(message)
c96f1398
TF
68 draw.rectangle((0, 0, WIDTH, HEIGHT), (255, 255, 255))
69 for i in range(len(colours)):
70 # Convert the values to colours from red to blue
71 colour = (1.0 - colours[i]) * 0.6
72 r, g, b = [int(x * 255.0) for x in colorsys.hsv_to_rgb(colour,
73 1.0, 1.0)]
74 # Draw a 1-pixel wide rectangle of colour
75 draw.rectangle((i, top_pos, i+1, HEIGHT), (r, g, b))
76 # Draw a line graph in black
77 line_y = HEIGHT - (top_pos + (colours[i] * (HEIGHT - top_pos)))\
78 + top_pos
79 draw.rectangle((i, line_y, i+1, line_y+1), (0, 0, 0))
80 # Write the text at the top in black
81 draw.text((0, 0), message, font=font, fill=(0, 0, 0))
82 st7735.display(img)
83
84
85# Get the temperature of the CPU for compensation
86def get_cpu_temperature():
e2d010e2 87 process = Popen(['vcgencmd', 'measure_temp'], stdout=PIPE, universal_newlines=True)
c96f1398
TF
88 output, _error = process.communicate()
89 return float(output[output.index('=') + 1:output.rindex("'")])
90
91
92# Tuning factor for compensation. Decrease this number to adjust the
93# temperature down, and increase to adjust up
94factor = 0.8
95
27156d25 96cpu_temps = [get_cpu_temperature()] * 5
c96f1398
TF
97
98delay = 0.5 # Debounce the proximity tap
99mode = 0 # The starting mode
100last_page = 0
101light = 1
102
103# Create a values dict to store the data
104variables = ["temperature",
105 "pressure",
106 "humidity",
107 "light",
108 "oxidised",
109 "reduced",
110 "nh3"]
111
112values = {}
113
114for v in variables:
115 values[v] = [1] * WIDTH
116
117# The main loop
118try:
119 while True:
120 proximity = ltr559.get_proximity()
121
122 # If the proximity crosses the threshold, toggle the mode
123 if proximity > 1500 and time.time() - last_page > delay:
124 mode += 1
125 mode %= len(variables)
126 last_page = time.time()
127
128 # One mode for each variable
129 if mode == 0:
69294f3c 130 # variable = "temperature"
c96f1398
TF
131 unit = "C"
132 cpu_temp = get_cpu_temperature()
133 # Smooth out with some averaging to decrease jitter
134 cpu_temps = cpu_temps[1:] + [cpu_temp]
135 avg_cpu_temp = sum(cpu_temps) / float(len(cpu_temps))
136 raw_temp = bme280.get_temperature()
137 data = raw_temp - ((avg_cpu_temp - raw_temp) / factor)
69294f3c 138 display_text(variables[mode], data, unit)
c96f1398
TF
139
140 if mode == 1:
69294f3c 141 # variable = "pressure"
c96f1398
TF
142 unit = "hPa"
143 data = bme280.get_pressure()
69294f3c 144 display_text(variables[mode], data, unit)
c96f1398
TF
145
146 if mode == 2:
69294f3c 147 # variable = "humidity"
c96f1398
TF
148 unit = "%"
149 data = bme280.get_humidity()
69294f3c 150 display_text(variables[mode], data, unit)
c96f1398
TF
151
152 if mode == 3:
69294f3c 153 # variable = "light"
c96f1398
TF
154 unit = "Lux"
155 if proximity < 10:
156 data = ltr559.get_lux()
157 else:
158 data = 1
69294f3c 159 display_text(variables[mode], data, unit)
c96f1398
TF
160
161 if mode == 4:
69294f3c 162 # variable = "oxidised"
c96f1398
TF
163 unit = "kO"
164 data = gas.read_all()
165 data = data.oxidising / 1000
69294f3c 166 display_text(variables[mode], data, unit)
c96f1398
TF
167
168 if mode == 5:
69294f3c 169 # variable = "reduced"
c96f1398
TF
170 unit = "kO"
171 data = gas.read_all()
172 data = data.reducing / 1000
69294f3c 173 display_text(variables[mode], data, unit)
c96f1398
TF
174
175 if mode == 6:
69294f3c 176 # variable = "nh3"
c96f1398
TF
177 unit = "kO"
178 data = gas.read_all()
179 data = data.nh3 / 1000
69294f3c 180 display_text(variables[mode], data, unit)
c96f1398
TF
181
182# Exit cleanly
183except KeyboardInterrupt:
184 sys.exit(0)