8913cef932c24dda27d91e6cfe62527dcfcc0a9e
[EVA-2020-02-2.git] / examples / all-in-one-enviro-mini-bk.py
1 #!/usr/bin/env python3
2
3 import time
4 import colorsys
5 import os
6 import sys
7 import ST7735
8 import schedule # https://pypi.org/project/schedule/ via https://stackoverflow.com/a/16786600
9 import datetime # http://stackoverflow.com/questions/2150739/ddg#28147286
10 try:
11 # Transitional fix for breaking change in LTR559
12 from ltr559 import LTR559
13 ltr559 = LTR559()
14 except ImportError:
15 import ltr559
16
17 from bme280 import BME280
18 from enviroplus import gas
19 from subprocess import PIPE, Popen
20 from PIL import Image
21 from PIL import ImageDraw
22 from PIL import ImageFont
23 from fonts.ttf import RobotoMedium as UserFont
24 import logging
25 import numpy as np
26
27 logging.basicConfig(
28 format='%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s',
29 level=logging.INFO,
30 datefmt='%Y-%m-%d %H:%M:%S')
31
32 logging.info("""all-in-one.py - Displays readings from all of Enviro plus' sensors
33 Press Ctrl+C to exit!
34 """)
35
36 # Script Constants
37 varLenBufferTTL = int((2*24*60*60)*10**9) # time-to-live in nanoseconds
38
39 # BME280 temperature/pressure/humidity sensor
40 bme280 = BME280()
41
42 # Create ST7735 LCD display class
43 st7735 = ST7735.ST7735(
44 port=0,
45 cs=1,
46 dc=9,
47 backlight=12,
48 rotation=270,
49 #rotation=90, # flip upside down wrt enviro+ default orientation
50 spi_speed_hz=10000000
51 )
52
53 # Initialize display
54 st7735.begin()
55
56 WIDTH = st7735.width
57 HEIGHT = st7735.height
58
59 # Set up canvas and font
60 img = Image.new('RGB', (WIDTH, HEIGHT), color=(0, 0, 0))
61 draw = ImageDraw.Draw(img)
62 path = os.path.dirname(os.path.realpath(__file__))
63 font_size = 20
64 font = ImageFont.truetype(UserFont, font_size)
65 font2_size = 15
66 font2 = ImageFont.truetype(UserFont, font2_size)
67
68 message = ""
69
70 # The position of the top bar
71 top_pos = 25
72
73
74 # Displays data and text on the 0.96" LCD
75 def display_text(variable, data, unit):
76 # Maintain length of list
77 values[variable] = values[variable][1:] + [data]
78 # Scale the values for the variable between 0 and 1
79 vmin = min(values[variable])
80 vmax = max(values[variable])
81 colours = [(v - vmin + 1) / (vmax - vmin + 1) for v in values[variable]]
82 # Format the variable name and value
83 message = "{}: {:.1f} {}".format(variable[:4], data, unit)
84 logging.info(message)
85 draw.rectangle((0, 0, WIDTH, HEIGHT), (255, 255, 255))
86 for i in range(len(colours)):
87 # Convert the values to colours from red to blue
88 colour = (1.0 - colours[i]) * 0.6
89 r, g, b = [int(x * 255.0) for x in colorsys.hsv_to_rgb(colour, 1.0, 1.0)]
90 # Draw a 1-pixel wide rectangle of colour
91 draw.rectangle((i, top_pos, i + 1, HEIGHT), (r, g, b))
92 # Draw a line graph in black
93 line_y = HEIGHT - (top_pos + (colours[i] * (HEIGHT - top_pos))) + top_pos
94 draw.rectangle((i, line_y, i + 1, line_y + 1), (0, 0, 0))
95 # Write the text at the top in black
96 draw.text((0, 0), message, font=font, fill=(0, 0, 0))
97 st7735.display(img)
98
99 # Displays data and text on the 0.96" LCD
100 def display_text2(variable, data, unit, values):
101 # Scale the values for the variable between 0 and 1
102 print('DEBUG:len(values[' + str(variable) + ']):' + str(len(values[variable])))
103 #print('DEBUG:values[' + str(variable) + ']:' + str(values[variable]))
104 vmin = min(values[variable])
105 vmax = max(values[variable])
106 colours = [(v - vmin + 1) / (vmax - vmin + 1) for v in values[variable]]
107 # Format the variable name and value
108 message = "{}: {:.1f} {}".format(variable[:4], data, unit)
109 #message = "{}: {:.1f} {}".format(variable[:4], values[variable][-1], unit)
110 logging.info(message)
111 draw.rectangle((0, 0, WIDTH, HEIGHT), (255, 255, 255))
112 for i in range(len(colours)):
113 # Convert the values to colours from red to blue
114 colour = (1.0 - colours[i]) * 0.6
115 r, g, b = [int(x * 255.0) for x in colorsys.hsv_to_rgb(colour, 1.0, 1.0)]
116 # Draw a 1-pixel wide rectangle of colour
117 draw.rectangle((i, top_pos, i + 1, HEIGHT), (r, g, b))
118 # Draw a line graph in black
119 line_y = HEIGHT - (top_pos + (colours[i] * (HEIGHT - top_pos))) + top_pos
120 draw.rectangle((i, line_y, i + 1, line_y + 1), (0, 0, 0))
121 # Write the text at the top in black
122 draw.text((0, 0), message, font=font, fill=(0, 0, 0))
123 # Write text (test)
124 maxMsg = "MAX:{:.1f}".format(vmax)
125 durMsg = "HR:{:.1f}".format(span_time_h)
126 minMsg = "MIN:{:.1f}".format(vmin)
127 maxMsg_y = int( ((HEIGHT - top_pos)/(HEIGHT))*(HEIGHT*(1/4)) + top_pos - (font2_size/2) )
128 durMsg_y = int( ((HEIGHT - top_pos)/(HEIGHT))*(HEIGHT*(2/4)) + top_pos - (font2_size/2) )
129 minMsg_y = int( ((HEIGHT - top_pos)/(HEIGHT))*(HEIGHT*(3/4)) + top_pos - (font2_size/2) )
130 maxMsg_x = int( WIDTH*(3/100) )
131 durMsg_x = int( WIDTH*(3/100) )
132 minMsg_x = int( WIDTH*(3/100) )
133 draw.text((maxMsg_x, maxMsg_y), maxMsg, font=font2, fill=(0, 0, 0))
134 draw.text((durMsg_x, durMsg_y), durMsg, font=font2, fill=(0, 0, 0))
135 draw.text((minMsg_x, minMsg_y), minMsg, font=font2, fill=(0, 0, 0))
136 st7735.display(img)
137
138
139 # Get the temperature of the CPU for compensation
140 def get_cpu_temperature():
141 process = Popen(['vcgencmd', 'measure_temp'], stdout=PIPE, universal_newlines=True)
142 output, _error = process.communicate()
143 return float(output[output.index('=') + 1:output.rindex("'")])
144
145 def rel_to_abs(T,P,RH):
146 """Returns absolute humidity given relative humidity.
147
148 Inputs:
149 --------
150 T : float
151 Absolute temperature in units Kelvin (K).
152 P : float
153 Total pressure in units Pascals (Pa).
154 RH : float
155 Relative humidity in units percent (%).
156
157 Output:
158 --------
159 absolute_humidity : float
160 Absolute humidity in units [kg water vapor / kg dry air].
161
162 References:
163 --------
164 1. Sonntag, D. "Advancements in the field of hygrometry". 1994. https://doi.org/10.1127/metz/3/1994/51
165 2. Green, D. "Perry's Chemical Engineers' Handbook" (8th Edition). Page "12-4". McGraw-Hill Professional Publishing. 2007.
166
167 Version: 0.0.1
168 Author: Steven Baltakatei Sandoval
169 License: GPLv3+
170 """
171
172 import math;
173
174 # Check input types
175 T = float(T);
176 P = float(P);
177 RH = float(RH);
178
179 #debug
180 # print('DEBUG:Input Temperature (K) :' + str(T));
181 # print('DEBUG:Input Pressure (Pa) :' + str(P));
182 # print('DEBUG:Input Rel. Humidity (%) :' + str(RH));
183
184 # Set constants and initial conversions
185 epsilon = 0.62198 # (molar mass of water vapor) / (molar mass of dry air)
186 t = T - 273.15; # Celsius from Kelvin
187 P_hpa = P / 100; # hectoPascals (hPa) from Pascals (Pa)
188
189 # Calculate e_w(T), saturation vapor pressure of water in a pure phase, in Pascals
190 ln_e_w = -6096*T**-1 + 21.2409642 - 2.711193*10**-2*T + 1.673952*10**-5*T**2 + 2.433502*math.log(T); # Sonntag-1994 eq 7; e_w in Pascals
191 e_w = math.exp(ln_e_w);
192 e_w_hpa = e_w / 100; # also save e_w in hectoPascals (hPa)
193 # print('DEBUG:ln_e_w:' + str(ln_e_w)); # debug
194 # print('DEBUG:e_w:' + str(e_w)); # debug
195
196 # Calculate f_w(P,T), enhancement factor for water
197 f_w = 1 + (10**-4*e_w_hpa)/(273 + t)*(((38 + 173*math.exp(-t/43))*(1 - (e_w_hpa / P_hpa))) + ((6.39 + 4.28*math.exp(-t / 107))*((P_hpa / e_w_hpa) - 1))); # Sonntag-1994 eq 22.
198 # print('DEBUG:f_w:' + str(f_w)); # debug
199
200 # Calculate e_prime_w(P,T), saturation vapor pressure of water in air-water mixture, in Pascals
201 e_prime_w = f_w * e_w; # Sonntag-1994 eq 18
202 # print('DEBUG:e_prime_w:' + str(e_prime_w)); # debug
203
204 # Calculate e_prime, vapor pressure of water in air, in Pascals
205 e_prime = (RH / 100) * e_prime_w;
206 # print('DEBUG:e_prime:' + str(e_prime)); # debug
207
208 # Calculate r, the absolute humidity, in [kg water vapor / kg dry air]
209 r = (epsilon * e_prime) / (P - e_prime);
210 # print('DEBUG:r:' + str(r)); # debug
211
212 return float(r);
213
214
215 # Tuning factor for compensation. Decrease this number to adjust the
216 # temperature down, and increase to adjust up
217 factor = 2.25
218
219 cpu_temps = [get_cpu_temperature()] * 5
220
221 delay = 0.5 # Debounce the proximity tap
222 mode = 0 # The starting mode
223 last_page = 0
224 light = 1
225
226 # Create a values dict to store the data
227 variables = ["temperature",
228 "pressure",
229 "humidity",
230 "humidity_abs",
231 "light"]
232 values = {} # Initialize values dictionary
233 for v in variables:
234 values[v] = [1] * WIDTH # Init a WIDTH-length list as value for each string in variables
235
236 # Create a varLenBuffer dict to store recent data
237 varLenBuffer = {}
238 for v in variables:
239 varLenBuffer[v] = [] # Init an empty list for each string in variables
240
241 # Create a varLenBufferFlt dict to store recent data as floats only
242 varLenBufferFlt = {}
243 for v in variables:
244 varLenBufferFlt[v] = [] # Init an empty list for each string in variables
245
246 # Create a fixLenBuffer dict to store data for displaying
247 fixLenBuffer = {}
248 for v in variables:
249 fixLenBuffer[v] = [] # Init an empty list for each string in variables
250
251 pollDelay = 5.0
252
253 def pollSensors():
254 # Desc: Update variables containing latest sensor tuples
255 # Output: (time [ns], unit, float)
256 # now_temp_tuple (°C)
257 # now_pressure_tuple (hPa)
258 # now_humidity_tuple (%)
259 # now_humidity_abs_tuple (g water vapor / kg dry air)
260 # now_illuminance_tuple (lux)
261 # Depends: time, bme280, ltr559, get_cpu_temperature(), rel_to_abs()
262
263 # Tell function to modify these global variables
264 global now_temp_tuple
265 global now_pressure_tuple
266 global now_humidity_tuple
267 global now_humidity_abs_tuple
268 global now_illuminance_tuple
269 # Initialize
270 cpu_temps = []
271 poll_time_ns_start = time.time_ns() # Get time reading (unix spoech, nanoseconds)
272 # Get temperature reading
273 cpu_temp = get_cpu_temperature() # get °C from CPU
274 # Smooth out with some averaging to decrease jitter
275 cpu_temps = cpu_temps[1:] + [cpu_temp]
276 avg_cpu_temp = sum(cpu_temps) / float(len(cpu_temps))
277 raw_temp = bme280.get_temperature() # get °C from BME280 sensor
278 now_temp = raw_temp - ((avg_cpu_temp - raw_temp) / factor)
279 now_temp_tuple = (time.time_ns(), '°C', now_temp)
280 # Get pressure reading
281 now_time_ns = time.time_ns() # Get time reading (unix epoch, nanoseconds)
282 now_pressure = bme280.get_pressure() # get hPa from BME280 sensor
283 now_pressure_tuple = (time.time_ns(), 'hPa', now_pressure)
284 # Get relative humidity reading
285 now_humidity = bme280.get_humidity() # get % relative humidity from BME280 sensor
286 now_humidity_tuple = (time.time_ns(), '%', now_humidity)
287 # Calculate absolute humidity reading
288 raw_temp_k = 273.15 + raw_temp; # convert sensor temp from degC to K
289 now_pressure_pa = now_pressure * 100; # convert sensor pressure from hPa to Pa
290 now_humidity_abs = rel_to_abs(raw_temp_k,now_pressure_pa,now_humidity); # calc abs humidity
291 now_humidity_abs_tuple = (time.time_ns(), 'g/kg', now_humidity_abs);
292 # Get light reading
293 proximity = ltr559.get_proximity() # get proximity reading
294 if proximity < 10:
295 now_illuminance = ltr559.get_lux() # get lux reading from LTR-559 sensor if nothing is nearby
296 now_illuminance_tuple = (time.time_ns(), 'lux', now_illuminance)
297 poll_time_ns_end = time.time_ns()
298 #print('DEBUG:poll time (s):' + str((poll_time_ns_end - poll_time_ns_start)/1000000000))
299
300
301 def dateIso8601Str():
302 nowUTC = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).isoformat()
303 return str(nowUTC)
304
305 def medianSubset(listIn: list = [], listOutLen: int = 0) -> list:
306 # Input: int: listOutLen: quantity of elements in output list
307 # list: listIn: input list consisting of integers or floats
308 # Output: list: ints/floats of specified size
309 # Ref/Attrib: PEP 3107 typing https://stackoverflow.com/a/21384492
310 # Version: 0.1.0
311 #print('DEBUG:listOutLen:' + str(listOutLen))
312 #print('DEBUG:listIn:' + str(listIn))
313
314 # Exit for invalid input
315 if not isinstance(listOutLen, int):
316 raise ValueError('ERROR:Not a valid int:' + str(listOutLen))
317 else:
318 if not listOutLen > 0:
319 raise ValueError('ERROR:Invalid value:' + str(listOutLen))
320 if not isinstance(listIn, list):
321 raise ValueError('ERROR:Not a valid list:' + str(listOutLen))
322 if not all([( (isinstance(x,int)) or (isinstance(x,float)) ) for x in listIn]):
323 raise ValueError('ERROR:Input list contains something besides integers or floating point numbers.')
324
325 # Initialize listOut
326 listOut = [None] * listOutLen
327 #print('DEBUG:listOut:' + str(listOut))
328
329 # Calc listIn length
330 listInLen = len(listIn)
331 #print('DEBUG:listInLen:' + str(listInLen))
332
333 # Calc subset length float
334 subsetLenFloat = ( (max([listInLen,listOutLen]) - 1) /min([listInLen,listOutLen]))
335 subsetIndRatio = ( (listInLen)/(listOutLen) )
336 #print('DEBUG:subsetLenFloat: %.5f' % subsetLenFloat)
337 #print('DEBUG:subsetLenFloat2: %.5f' % subsetIndRatio)
338
339 # Iterate for each element in listOut
340 for i_out in range(listOutLen):
341 #print('DEBUG:i_out:' + str(i_out))
342 ## Decide to expand or reduce listIn to produce listOut
343 if listInLen > listOutLen:
344 ### reduce listIn to listOut
345 #print('DEBUG:listOutLen:' + str(listOutLen))
346 #print('DEBUG:listInLen:' + str(listInLen))
347 if i_out == 0:
348 #### Initialize subsetIndLo in first loop
349 subsetIndLo = int(0)
350 #print('DEBUG:subsetIndLo:' + str(subsetIndLo))
351 #print('DEBUG:i_out:' + str(i_out))
352 #### Calc indices of i_out'th subset of listIn
353 subsetIndHi = (listInLen - 1) * (i_out + 1) // listOutLen
354 subsetLen = subsetIndHi - subsetIndLo + 1
355 #print('DEBUG:subsetIndLo:' + str(subsetIndLo))
356 #print('DEBUG:subsetIndHi:' + str(subsetIndHi))
357 #print('DEBUG:subsetLen:' + str(subsetLen))
358 #### Extract subset from listIn using indices inclusively
359 subset = listIn[ int(subsetIndLo) : int(subsetIndHi)+1 ]
360 #print('DEBUG:subset:' + str(subset))
361 #### Calculate median for subset
362 subsetMedian = np.median(subset)
363 #print('DEBUG:subset median:' + str(subsetMedian))
364 #### Set listOut element
365 listOut[i_out] = subsetMedian
366 #### Housekeeping
367 ##### Update subsetIndLo for next loop
368 subsetIndLo = subsetIndHi + 1
369 #print('DEBUG:Updated subsetIndLo:' + str(subsetIndLo))
370 elif listOutLen > listInLen:
371 ### Expand listIn to listOut
372 #print('DEBUG:listOutLen:' + str(listOutLen))
373 #print('DEBUG:listInLen:' + str(listInLen))
374 #### Identify index list of lists mapping listIn to ListOut
375 expandIndex = int(i_out / subsetLenFloat)
376 expandIndex = min([expandIndex,(listInLen - 1)])
377 #print('DEBUG:expandIndex:' + str(expandIndex))
378 listOut[i_out] = listIn[expandIndex]
379 #print('DEBUG:listOut[i_out]:' + str(listOut[i_out]))
380 elif listOutLen == listInLen:
381 listOut = listIn
382 #print('DEBUG:end for loop===========')
383 return listOut
384
385 def updateBuffer():
386 global now_temp_tuple
387 global now_pressure_tuple
388 global now_humidity_tuple
389 global now_humidity_abs_tuple
390 global now_illuminance_tuple
391 global varLenBuffer
392 global fixLenBuffer
393 global fixLenBufferFlt
394 global span_time_h
395 #print('DEBUG:This is the updateBuffer() function.')
396 #print('DEBUG:===========================================================')
397 #print('DEBUG:===========================================================')
398 # Capture new sensor tuples
399 pollSensors()
400 #print('DEBUG:now_temp_tuple:' + str(now_temp_tuple))
401 #print('DEBUG:now_pressure_tuple:' + str(now_pressure_tuple))
402 #print('DEBUG:now_humidity_tuple:' + str(now_humidity_tuple))
403 #print('DEBUG:now_humidity_abs_tuple:' + str(now_humidity_abs_tuple))
404 #print('DEBUG:now_illuminance_tuple:' + str(now_illuminance_tuple))
405
406 # Append new sensor tuples to varying-length buffer
407 ## Temperature
408 varLenBuffer[variables[0]].append(now_temp_tuple)
409 ## Pressure
410 varLenBuffer[variables[1]].append(now_pressure_tuple)
411 ## Relative Humidity
412 varLenBuffer[variables[2]].append(now_humidity_tuple)
413 ## Absolute Humidity
414 varLenBuffer[variables[3]].append(now_humidity_abs_tuple)
415 ## Illuminance
416 varLenBuffer[variables[4]].append(now_illuminance_tuple)
417 #print('DEBUG:varLenBuffer:' + str(varLenBuffer))
418
419 # Trim outdated sensor tuples from varying-length buffer
420 ## iterate through each tuple list and remove old tuples
421 varLenBufferTemp = []
422 for v in variables:
423 #varLenBufferTemp = varLenBuffer[v].copy()
424 now_time_ns = time.time_ns() # get ns timestamp of now
425 thn_time_ns = varLenBuffer[v][0][0] # get ns timestamp of earliest tuple
426 dif_time_ns = now_time_ns - thn_time_ns # calc nanosecond difference
427 #print('DEBUG:varLenBufferTTL:' + str(varLenBufferTTL))
428 #print('DEBUG:now:' + str(now_time_ns))
429 #print('DEBUG:thn:' + str(thn_time_ns))
430 #print('DEBUG:dif:' + str(dif_time_ns))
431 #print('DEBUG:dif(s):' + str(dif_time_ns / 1000000000))
432 if dif_time_ns > varLenBufferTTL:
433 varLenBuffer[v].pop(0) # discard earliest tuple if age > varLenBufferTTL
434 print('DEBUG:Len of varLenBuffer[' + str(v) + ']:' + str(len(varLenBuffer[v])))
435 #print('DEBUG:*******************************************')
436 #print('DEBUG:varLenBuffer[variables[' + str(v) + ']]:' + str(varLenBuffer[v]))
437 #print('DEBUG:*******************************************')
438
439 # Calculate buffer time span in hours
440 ## Get earliest timestamp (use temperature tuples)
441 first_time_ns = varLenBuffer[variables[0]][0][0]
442 last_time_ns = varLenBuffer[variables[0]][-1][0]
443 span_time_ns = int(last_time_ns - first_time_ns)
444 span_time_h = float(span_time_ns / (10**9*60*60)) # nanoseconds to hours
445
446 # Convert tuple buffer into float buffer
447 for v in variables:
448 varLenBufferFlt[v].clear() # clear old float list
449 #print('DEBUG:v:' + str(v))
450 for t in varLenBuffer[v]:
451 #print('DEBUG:t:' + str(t))
452 #print('DEBUG:t[2]:' + str(t[2]))
453 #print('DEBUG:------------------------------------------')
454 #print('DEBUG:varLenBufferFlt[' + str(v) + ']:' + str(varLenBufferFlt[v]))
455 #print('DEBUG:------------------------------------------')
456 if isinstance(t[2], float):
457 varLenBufferFlt[v].append(float(t[2])) # build new float list
458 else:
459 varLenBufferFlt[v].append(float(-273)) # add obvious zero otherwise
460 #print('DEBUG:varLenBufferFlt[' + str(v) + ']:' + str(varLenBufferFlt[v]))
461
462 # Compress/expand buffer to fixed-length buffer
463 for v in variables:
464 #print('DEBUG:varLenBufferFlt[0]:' + str(varLenBufferFlt[variables[0]]))
465 fixLenBuffer[v] = medianSubset(varLenBufferFlt[v], WIDTH)
466 print('DEBUG:Len of fixLenBuffer[' + str(v) + ']:' + str(len(fixLenBuffer[v])))
467 #print('DEBUG:fixLenBuffer[' + str(v) + ']:' + str(fixLenBuffer[v]))
468
469
470 # The main loop
471 try:
472 # Schedule tasks
473 # schedule.every(1).second.do(updateBuffer)
474 schedule.every().minute.at(":00").do(updateBuffer)
475 # schedule.every().minute.at(":05").do(updateBuffer)
476 # schedule.every().minute.at(":10").do(updateBuffer)
477 # schedule.every().minute.at(":15").do(updateBuffer)
478 # schedule.every().minute.at(":20").do(updateBuffer)
479 # schedule.every().minute.at(":25").do(updateBuffer)
480 # schedule.every().minute.at(":30").do(updateBuffer)
481 # schedule.every().minute.at(":35").do(updateBuffer)
482 # schedule.every().minute.at(":40").do(updateBuffer)
483 # schedule.every().minute.at(":45").do(updateBuffer)
484 # schedule.every().minute.at(":50").do(updateBuffer)
485 # schedule.every().minute.at(":55").do(updateBuffer)
486 pollSensors() # initial run to start up sensors
487 time.sleep(1) # pause to give sensors time to initialize
488 updateBuffer() # initial run
489
490 while True:
491 proximity = ltr559.get_proximity()
492
493 # If the proximity crosses the threshold, toggle the display mode
494 if proximity > 1500 and time.time() - last_page > delay:
495 mode += 1
496 mode %= len(variables)
497 last_page = time.time()
498
499 # Run scheduled tasks
500 schedule.run_pending()
501
502 # One display mode for each variable
503 if mode == 0:
504 # variable = "temperature"
505 ## run function to display latest temp values in variables[mode] list
506 unit = "°C"
507 cpu_temp = get_cpu_temperature()
508 # Smooth out with some averaging to decrease jitter
509 cpu_temps = cpu_temps[1:] + [cpu_temp]
510 avg_cpu_temp = sum(cpu_temps) / float(len(cpu_temps))
511 raw_temp = bme280.get_temperature()
512 data = raw_temp - ((avg_cpu_temp - raw_temp) / factor)
513 #display_text(variables[mode], data, unit)
514 display_text2(variables[mode],data,unit,fixLenBuffer)
515
516 if mode == 1:
517 # variable = "pressure"
518 unit = "hPa"
519 data = bme280.get_pressure()
520 #display_text(variables[mode], data, unit)
521 display_text2(variables[mode],data,unit,fixLenBuffer)
522
523 if mode == 2:
524 # variable = "humidity"
525 unit = "%"
526 data = bme280.get_humidity()
527 #display_text(variables[mode], data, unit)
528 display_text2(variables[mode],data,unit,fixLenBuffer)
529
530 if mode == 3:
531 # variable = "humidity_abs"
532 unit = "g/kg"
533 raw_temp = bme280.get_temperature() # get °C from BME280 sensor
534 raw_temp_k = 273.15 + raw_temp; # convert sensor temp from degC to K
535 now_pressure = bme280.get_pressure() # get hPa from BME280 sensor
536 now_pressure_pa = now_pressure * 100; # convert sensor pressure from hPa to Pa
537 now_humidity = bme280.get_humidity() # get % relative humidity from BME280 sensor
538 data = rel_to_abs(raw_temp_k,now_pressure_pa,now_humidity); # calc abs humidity
539 display_text2(variables[mode],data,unit,fixLenBuffer)
540
541 if mode == 4:
542 # variable = "light"
543 unit = "Lux"
544 if proximity < 10:
545 data = ltr559.get_lux()
546 else:
547 data = 1
548 #display_text(variables[mode], data, unit)
549 display_text2(variables[mode],data,unit,fixLenBuffer)
550
551
552
553 # Exit cleanly
554 except KeyboardInterrupt:
555 sys.exit(0)