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