88c3475e18ca76abf592a4e09edc1ab811f89ef0
[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_gkg_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_gkg_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 kg/kg abs humidity
291 now_humidity_abs_gkg = now_humidity_abs * 1000;
292 now_humidity_abs_gkg_tuple = (time.time_ns(), 'g/kg', now_humidity_abs_gkg);
293 # Get light reading
294 proximity = ltr559.get_proximity() # get proximity reading
295 if proximity < 10:
296 now_illuminance = ltr559.get_lux() # get lux reading from LTR-559 sensor if nothing is nearby
297 now_illuminance_tuple = (time.time_ns(), 'lux', now_illuminance)
298 poll_time_ns_end = time.time_ns()
299 #print('DEBUG:poll time (s):' + str((poll_time_ns_end - poll_time_ns_start)/1000000000))
300
301
302 def dateIso8601Str():
303 nowUTC = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).isoformat()
304 return str(nowUTC)
305
306 def medianSubset(listIn: list = [], listOutLen: int = 0) -> list:
307 # Input: int: listOutLen: quantity of elements in output list
308 # list: listIn: input list consisting of integers or floats
309 # Output: list: ints/floats of specified size
310 # Ref/Attrib: PEP 3107 typing https://stackoverflow.com/a/21384492
311 # Version: 0.1.0
312 #print('DEBUG:listOutLen:' + str(listOutLen))
313 #print('DEBUG:listIn:' + str(listIn))
314
315 # Exit for invalid input
316 if not isinstance(listOutLen, int):
317 raise ValueError('ERROR:Not a valid int:' + str(listOutLen))
318 else:
319 if not listOutLen > 0:
320 raise ValueError('ERROR:Invalid value:' + str(listOutLen))
321 if not isinstance(listIn, list):
322 raise ValueError('ERROR:Not a valid list:' + str(listOutLen))
323 if not all([( (isinstance(x,int)) or (isinstance(x,float)) ) for x in listIn]):
324 raise ValueError('ERROR:Input list contains something besides integers or floating point numbers.')
325
326 # Initialize listOut
327 listOut = [None] * listOutLen
328 #print('DEBUG:listOut:' + str(listOut))
329
330 # Calc listIn length
331 listInLen = len(listIn)
332 #print('DEBUG:listInLen:' + str(listInLen))
333
334 # Calc subset length float
335 subsetLenFloat = ( (max([listInLen,listOutLen]) - 1) /min([listInLen,listOutLen]))
336 subsetIndRatio = ( (listInLen)/(listOutLen) )
337 #print('DEBUG:subsetLenFloat: %.5f' % subsetLenFloat)
338 #print('DEBUG:subsetLenFloat2: %.5f' % subsetIndRatio)
339
340 # Iterate for each element in listOut
341 for i_out in range(listOutLen):
342 #print('DEBUG:i_out:' + str(i_out))
343 ## Decide to expand or reduce listIn to produce listOut
344 if listInLen > listOutLen:
345 ### reduce listIn to listOut
346 #print('DEBUG:listOutLen:' + str(listOutLen))
347 #print('DEBUG:listInLen:' + str(listInLen))
348 if i_out == 0:
349 #### Initialize subsetIndLo in first loop
350 subsetIndLo = int(0)
351 #print('DEBUG:subsetIndLo:' + str(subsetIndLo))
352 #print('DEBUG:i_out:' + str(i_out))
353 #### Calc indices of i_out'th subset of listIn
354 subsetIndHi = (listInLen - 1) * (i_out + 1) // listOutLen
355 subsetLen = subsetIndHi - subsetIndLo + 1
356 #print('DEBUG:subsetIndLo:' + str(subsetIndLo))
357 #print('DEBUG:subsetIndHi:' + str(subsetIndHi))
358 #print('DEBUG:subsetLen:' + str(subsetLen))
359 #### Extract subset from listIn using indices inclusively
360 subset = listIn[ int(subsetIndLo) : int(subsetIndHi)+1 ]
361 #print('DEBUG:subset:' + str(subset))
362 #### Calculate median for subset
363 subsetMedian = np.median(subset)
364 #print('DEBUG:subset median:' + str(subsetMedian))
365 #### Set listOut element
366 listOut[i_out] = subsetMedian
367 #### Housekeeping
368 ##### Update subsetIndLo for next loop
369 subsetIndLo = subsetIndHi + 1
370 #print('DEBUG:Updated subsetIndLo:' + str(subsetIndLo))
371 elif listOutLen > listInLen:
372 ### Expand listIn to listOut
373 #print('DEBUG:listOutLen:' + str(listOutLen))
374 #print('DEBUG:listInLen:' + str(listInLen))
375 #### Identify index list of lists mapping listIn to ListOut
376 expandIndex = int(i_out / subsetLenFloat)
377 expandIndex = min([expandIndex,(listInLen - 1)])
378 #print('DEBUG:expandIndex:' + str(expandIndex))
379 listOut[i_out] = listIn[expandIndex]
380 #print('DEBUG:listOut[i_out]:' + str(listOut[i_out]))
381 elif listOutLen == listInLen:
382 listOut = listIn
383 #print('DEBUG:end for loop===========')
384 return listOut
385
386 def updateBuffer():
387 global now_temp_tuple
388 global now_pressure_tuple
389 global now_humidity_tuple
390 global now_humidity_abs_gkg_tuple
391 global now_illuminance_tuple
392 global varLenBuffer
393 global fixLenBuffer
394 global fixLenBufferFlt
395 global span_time_h
396 #print('DEBUG:This is the updateBuffer() function.')
397 #print('DEBUG:===========================================================')
398 #print('DEBUG:===========================================================')
399 # Capture new sensor tuples
400 pollSensors()
401 #print('DEBUG:now_temp_tuple:' + str(now_temp_tuple))
402 #print('DEBUG:now_pressure_tuple:' + str(now_pressure_tuple))
403 #print('DEBUG:now_humidity_tuple:' + str(now_humidity_tuple))
404 #print('DEBUG:now_humidity_abs_gkg_tuple:' + str(now_humidity_abs_gkg_tuple))
405 #print('DEBUG:now_illuminance_tuple:' + str(now_illuminance_tuple))
406
407 # Append new sensor tuples to varying-length buffer
408 ## Temperature
409 varLenBuffer[variables[0]].append(now_temp_tuple)
410 ## Pressure
411 varLenBuffer[variables[1]].append(now_pressure_tuple)
412 ## Relative Humidity
413 varLenBuffer[variables[2]].append(now_humidity_tuple)
414 ## Absolute Humidity
415 varLenBuffer[variables[3]].append(now_humidity_abs_gkg_tuple)
416 ## Illuminance
417 varLenBuffer[variables[4]].append(now_illuminance_tuple)
418 #print('DEBUG:varLenBuffer:' + str(varLenBuffer))
419
420 # Trim outdated sensor tuples from varying-length buffer
421 ## iterate through each tuple list and remove old tuples
422 varLenBufferTemp = []
423 for v in variables:
424 #varLenBufferTemp = varLenBuffer[v].copy()
425 now_time_ns = time.time_ns() # get ns timestamp of now
426 thn_time_ns = varLenBuffer[v][0][0] # get ns timestamp of earliest tuple
427 dif_time_ns = now_time_ns - thn_time_ns # calc nanosecond difference
428 #print('DEBUG:varLenBufferTTL:' + str(varLenBufferTTL))
429 #print('DEBUG:now:' + str(now_time_ns))
430 #print('DEBUG:thn:' + str(thn_time_ns))
431 #print('DEBUG:dif:' + str(dif_time_ns))
432 #print('DEBUG:dif(s):' + str(dif_time_ns / 1000000000))
433 if dif_time_ns > varLenBufferTTL:
434 varLenBuffer[v].pop(0) # discard earliest tuple if age > varLenBufferTTL
435 print('DEBUG:Len of varLenBuffer[' + str(v) + ']:' + str(len(varLenBuffer[v])))
436 #print('DEBUG:*******************************************')
437 #print('DEBUG:varLenBuffer[variables[' + str(v) + ']]:' + str(varLenBuffer[v]))
438 #print('DEBUG:*******************************************')
439
440 # Calculate buffer time span in hours
441 ## Get earliest timestamp (use temperature tuples)
442 first_time_ns = varLenBuffer[variables[0]][0][0]
443 last_time_ns = varLenBuffer[variables[0]][-1][0]
444 span_time_ns = int(last_time_ns - first_time_ns)
445 span_time_h = float(span_time_ns / (10**9*60*60)) # nanoseconds to hours
446
447 # Convert tuple buffer into float buffer
448 for v in variables:
449 varLenBufferFlt[v].clear() # clear old float list
450 #print('DEBUG:v:' + str(v))
451 for t in varLenBuffer[v]:
452 #print('DEBUG:t:' + str(t))
453 #print('DEBUG:t[2]:' + str(t[2]))
454 #print('DEBUG:------------------------------------------')
455 #print('DEBUG:varLenBufferFlt[' + str(v) + ']:' + str(varLenBufferFlt[v]))
456 #print('DEBUG:------------------------------------------')
457 if isinstance(t[2], float):
458 varLenBufferFlt[v].append(float(t[2])) # build new float list
459 else:
460 varLenBufferFlt[v].append(float(-273)) # add obvious zero otherwise
461 #print('DEBUG:varLenBufferFlt[' + str(v) + ']:' + str(varLenBufferFlt[v]))
462
463 # Compress/expand buffer to fixed-length buffer
464 for v in variables:
465 #print('DEBUG:varLenBufferFlt[0]:' + str(varLenBufferFlt[variables[0]]))
466 fixLenBuffer[v] = medianSubset(varLenBufferFlt[v], WIDTH)
467 print('DEBUG:Len of fixLenBuffer[' + str(v) + ']:' + str(len(fixLenBuffer[v])))
468 #print('DEBUG:fixLenBuffer[' + str(v) + ']:' + str(fixLenBuffer[v]))
469
470
471 # The main loop
472 try:
473 # Schedule tasks
474 # schedule.every(1).second.do(updateBuffer)
475 schedule.every().minute.at(":00").do(updateBuffer)
476 # schedule.every().minute.at(":05").do(updateBuffer)
477 # schedule.every().minute.at(":10").do(updateBuffer)
478 # schedule.every().minute.at(":15").do(updateBuffer)
479 # schedule.every().minute.at(":20").do(updateBuffer)
480 # schedule.every().minute.at(":25").do(updateBuffer)
481 # schedule.every().minute.at(":30").do(updateBuffer)
482 # schedule.every().minute.at(":35").do(updateBuffer)
483 # schedule.every().minute.at(":40").do(updateBuffer)
484 # schedule.every().minute.at(":45").do(updateBuffer)
485 # schedule.every().minute.at(":50").do(updateBuffer)
486 # schedule.every().minute.at(":55").do(updateBuffer)
487 pollSensors() # initial run to start up sensors
488 time.sleep(1) # pause to give sensors time to initialize
489 updateBuffer() # initial run
490
491 while True:
492 proximity = ltr559.get_proximity()
493
494 # If the proximity crosses the threshold, toggle the display mode
495 if proximity > 1500 and time.time() - last_page > delay:
496 mode += 1
497 mode %= len(variables)
498 last_page = time.time()
499
500 # Run scheduled tasks
501 schedule.run_pending()
502
503 # One display mode for each variable
504 if mode == 0:
505 # variable = "temperature"
506 ## run function to display latest temp values in variables[mode] list
507 unit = "°C"
508 cpu_temp = get_cpu_temperature()
509 # Smooth out with some averaging to decrease jitter
510 cpu_temps = cpu_temps[1:] + [cpu_temp]
511 avg_cpu_temp = sum(cpu_temps) / float(len(cpu_temps))
512 raw_temp = bme280.get_temperature()
513 data = raw_temp - ((avg_cpu_temp - raw_temp) / factor)
514 #display_text(variables[mode], data, unit)
515 display_text2(variables[mode],data,unit,fixLenBuffer)
516
517 if mode == 1:
518 # variable = "pressure"
519 unit = "hPa"
520 data = bme280.get_pressure()
521 #display_text(variables[mode], data, unit)
522 display_text2(variables[mode],data,unit,fixLenBuffer)
523
524 if mode == 2:
525 # variable = "humidity"
526 unit = "%"
527 data = bme280.get_humidity()
528 #display_text(variables[mode], data, unit)
529 display_text2(variables[mode],data,unit,fixLenBuffer)
530
531 if mode == 3:
532 # variable = "humidity_abs"
533 unit = "g/kg"
534 raw_temp = bme280.get_temperature() # get °C from BME280 sensor
535 raw_temp_k = 273.15 + raw_temp; # convert sensor temp from degC to K
536 now_pressure = bme280.get_pressure() # get hPa from BME280 sensor
537 now_pressure_pa = now_pressure * 100; # convert sensor pressure from hPa to Pa
538 now_humidity = bme280.get_humidity() # get % relative humidity from BME280 sensor
539 now_humidity_abs = rel_to_abs(raw_temp_k,now_pressure_pa,now_humidity); # calc [kg water / kg dry air] abs humidity
540 now_humidity_abs_gkg = now_humidity_abs * 1000; # convert kg/kg to g/kg abs humidity
541 data = now_humidity_abs_gkg;
542 # print('DEBUG:raw_temp:' + str(raw_temp));
543 # print('DEBUG:raw_temp_k:' + str(raw_temp_k));
544 # print('DEBUG:now_pressure:' + str(now_pressure));
545 # print('DEBUG:now_pressure_pa:' + str(now_pressure_pa));
546 # print('DEBUG:now_humidity:' + str(now_humidity));
547 # print('DEBUG:now_humidity_abs_gkg:' + str(data));
548 display_text2(variables[mode],data,unit,fixLenBuffer)
549
550 if mode == 4:
551 # variable = "light"
552 unit = "Lux"
553 if proximity < 10:
554 data = ltr559.get_lux()
555 else:
556 data = 1
557 #display_text(variables[mode], data, unit)
558 display_text2(variables[mode],data,unit,fixLenBuffer)
559
560
561
562 # Exit cleanly
563 except KeyboardInterrupt:
564 sys.exit(0)