]>
zdv2.bktei.com Git - EVA-2020-02-2.git/blob - examples/combined.py
   9     # Transitional fix for breaking change in LTR559 
  10     from ltr559 
import LTR559
 
  15 from bme280 
import BME280
 
  16 from pms5003 
import PMS5003
, ReadTimeoutError 
as pmsReadTimeoutError
 
  17 from enviroplus 
import gas
 
  18 from subprocess 
import PIPE
, Popen
 
  20 from PIL 
import ImageDraw
 
  21 from PIL 
import ImageFont
 
  25     format
='%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s', 
  27     datefmt
='%Y-%m-%d %H:%M:%S') 
  29 logging
.info("""all-in-one.py - Displays readings from all of Enviro plus' sensors 
  35 # BME280 temperature/pressure/humidity sensor 
  38 # PMS5003 particulate sensor 
  41 # Create ST7735 LCD display class 
  42 st7735 
= ST7735
.ST7735( 
  55 HEIGHT 
= st7735
.height
 
  57 # Set up canvas and font 
  58 img 
= Image
.new('RGB', (WIDTH
, HEIGHT
), color
=(0, 0, 0)) 
  59 draw 
= ImageDraw
.Draw(img
) 
  60 path 
= os
.path
.dirname(os
.path
.realpath(__file__
)) 
  61 font 
= ImageFont
.truetype(path 
+ "/fonts/Asap/Asap-Bold.ttf", 20) 
  62 smallfont 
= ImageFont
.truetype(path 
+ "/fonts/Asap/Asap-Bold.ttf", 10) 
  68 # The position of the top bar 
  71 # Create a values dict to store the data 
  72 variables 
= ["temperature", 
  94 # Define your own warning limits 
  95 # The limits definition follows the order of the variables array 
  96 # Example limits explanation for temperature: 
  98 # [-273.15 .. 4] -> Dangerously Low 
 100 # (18 .. 28]     -> Normal 
 102 # (35 .. MAX]    -> Dangerously High 
 103 # DISCLAIMER: The limits provided here are just examples and come 
 104 # with NO WARRANTY. The authors of this example code claim 
 105 # NO RESPONSIBILITY if reliance on the following values or this 
 106 # code in general leads to ANY DAMAGES or DEATH. 
 107 limits 
= [[4,18,28,35], 
 108           [250,650,1013.25,1015], 
 110           [-1,-1,30000,100000], 
 118 # RGB palette for values on the combined screen 
 119 palette 
= [(0,0,255),           # Dangerously Low 
 123            (255,0,0)]           # Dangerously High 
 128 # Displays data and text on the 0.96" LCD 
 129 def display_text(variable
, data
, unit
): 
 130     # Maintain length of list 
 131     values
[variable
] = values
[variable
][1:] + [data
] 
 132     # Scale the values for the variable between 0 and 1 
 133     colours 
= [(v 
- min(values
[variable
]) + 1) / (max(values
[variable
]) 
 134                - min(values
[variable
]) + 1) for v 
in values
[variable
]] 
 135     # Format the variable name and value 
 136     message 
= "{}: {:.1f} {}".format(variable
[:4], data
, unit
) 
 137     logging
.info(message
) 
 138     draw
.rectangle((0, 0, WIDTH
, HEIGHT
), (255, 255, 255)) 
 139     for i 
in range(len(colours
)): 
 140         # Convert the values to colours from red to blue 
 141         colour 
= (1.0 - colours
[i
]) * 0.6 
 142         r
, g
, b 
= [int(x 
* 255.0) for x 
in colorsys
.hsv_to_rgb(colour
, 
 144         # Draw a 1-pixel wide rectangle of colour 
 145         draw
.rectangle((i
, top_pos
, i
+1, HEIGHT
), (r
, g
, b
)) 
 146         # Draw a line graph in black 
 147         line_y 
= HEIGHT 
- (top_pos 
+ (colours
[i
] * (HEIGHT 
- top_pos
)))\
 
 149         draw
.rectangle((i
, line_y
, i
+1, line_y
+1), (0, 0, 0)) 
 150     # Write the text at the top in black 
 151     draw
.text((0, 0), message
, font
=font
, fill
=(0, 0, 0)) 
 154 # Saves the data to be used in the graphs later and prints to the log 
 155 def save_data(idx
, data
): 
 156     variable 
= variables
[idx
] 
 157     # Maintain length of list 
 158     values
[variable
] = values
[variable
][1:] + [data
] 
 160     message 
= "{}: {:.1f} {}".format(variable
[:4], data
, unit
) 
 161     logging
.info(message
) 
 164 # Displays all the text on the 0.96" LCD 
 165 def display_everything(): 
 166     draw
.rectangle((0, 0, WIDTH
, HEIGHT
), (0, 0, 0)) 
 168     row_count 
= (len(variables
)/column_count
) 
 169     for i 
in xrange(len(variables
)): 
 170         variable 
= variables
[i
] 
 171         data_value 
= values
[variable
][-1] 
 173         x 
= x_offset 
+ ((WIDTH
/column_count
) * (i 
/ row_count
)) 
 174         y 
= y_offset 
+ ((HEIGHT
/row_count
) * (i 
% row_count
)) 
 175         message 
= "{}: {:.1f} {}".format(variable
[:4], data_value
, unit
) 
 178         for j 
in xrange(len(lim
)): 
 179             if data_value 
> lim
[j
]: 
 181         draw
.text((x
, y
), message
, font
=smallfont
, fill
=rgb
) 
 186 # Get the temperature of the CPU for compensation 
 187 def get_cpu_temperature(): 
 188     process 
= Popen(['vcgencmd', 'measure_temp'], stdout
=PIPE
, universal_newlines
=True) 
 189     output
, _error 
= process
.communicate() 
 190     return float(output
[output
.index('=') + 1:output
.rindex("'")]) 
 193 # Tuning factor for compensation. Decrease this number to adjust the 
 194 # temperature down, and increase to adjust up 
 197 cpu_temps 
= [get_cpu_temperature()] * 5 
 199 delay 
= 0.5  # Debounce the proximity tap 
 200 mode 
= 10    # The starting mode 
 205     values
[v
] = [1] * WIDTH
 
 210         proximity 
= ltr559
.get_proximity() 
 212         # If the proximity crosses the threshold, toggle the mode 
 213         if proximity 
> 1500 and time
.time() - last_page 
> delay
: 
 215             mode 
%= (len(variables
)+1) 
 216             last_page 
= time
.time() 
 218         # One mode for each variable 
 220             # variable = "temperature" 
 222             cpu_temp 
= get_cpu_temperature() 
 223             # Smooth out with some averaging to decrease jitter 
 224             cpu_temps 
= cpu_temps
[1:] + [cpu_temp
] 
 225             avg_cpu_temp 
= sum(cpu_temps
) / float(len(cpu_temps
)) 
 226             raw_temp 
= bme280
.get_temperature() 
 227             data 
= raw_temp 
- ((avg_cpu_temp 
- raw_temp
) / factor
) 
 228             display_text(variables
[mode
], data
, unit
) 
 231             # variable = "pressure" 
 233             data 
= bme280
.get_pressure() 
 234             display_text(variables
[mode
], data
, unit
) 
 237             # variable = "humidity" 
 239             data 
= bme280
.get_humidity() 
 240             display_text(variables
[mode
], data
, unit
) 
 246                 data 
= ltr559
.get_lux() 
 249             display_text(variables
[mode
], data
, unit
) 
 252             # variable = "oxidised" 
 254             data 
= gas
.read_all() 
 255             data 
= data
.oxidising 
/ 1000 
 256             display_text(variables
[mode
], data
, unit
) 
 259             # variable = "reduced" 
 261             data 
= gas
.read_all() 
 262             data 
= data
.reducing 
/ 1000 
 263             display_text(variables
[mode
], data
, unit
) 
 268             data 
= gas
.read_all() 
 269             data 
= data
.nh3 
/ 1000 
 270             display_text(variables
[mode
], data
, unit
) 
 276                 data 
= pms5003
.read() 
 277             except pmsReadTimeoutError
: 
 278                 logging
.warn("Failed to read PMS5003") 
 280                 data 
= float(data
.pm_ug_per_m3(1.0)) 
 281                 display_text(variables
[mode
], data
, unit
) 
 287                 data 
= pms5003
.read() 
 288             except pmsReadTimeoutError
: 
 289                 logging
.warn("Failed to read PMS5003") 
 291                 data 
= float(data
.pm_ug_per_m3(2.5)) 
 292                 display_text(variables
[mode
], data
, unit
) 
 298                 data 
= pms5003
.read() 
 299             except pmsReadTimeoutError
: 
 300                 logging
.warn("Failed to read PMS5003") 
 302                 data 
= float(data
.pm_ug_per_m3(10)) 
 303                 display_text(variables
[mode
], data
, unit
) 
 305             # Everything on one screen 
 306             cpu_temp 
= get_cpu_temperature() 
 307             # Smooth out with some averaging to decrease jitter 
 308             cpu_temps 
= cpu_temps
[1:] + [cpu_temp
] 
 309             avg_cpu_temp 
= sum(cpu_temps
) / float(len(cpu_temps
)) 
 310             raw_temp 
= bme280
.get_temperature() 
 311             raw_data 
= raw_temp 
- ((avg_cpu_temp 
- raw_temp
) / factor
) 
 312             save_data(0, raw_data
) 
 314             raw_data 
= bme280
.get_pressure() 
 315             save_data(1, raw_data
) 
 317             raw_data 
= bme280
.get_humidity() 
 318             save_data(2, raw_data
) 
 320                 raw_data 
= ltr559
.get_lux() 
 323             save_data(3, raw_data
) 
 325             gas_data 
= gas
.read_all() 
 326             save_data(4, gas_data
.oxidising 
/ 1000) 
 327             save_data(5, gas_data
.reducing 
/ 1000) 
 328             save_data(6, gas_data
.nh3 
/ 1000) 
 332                 pms_data 
= pms5003
.read() 
 333             except pmsReadTimeoutError
: 
 334                 logging
.warn("Failed to read PMS5003") 
 336                 save_data(7, float(pms_data
.pm_ug_per_m3(1.0))) 
 337                 save_data(8, float(pms_data
.pm_ug_per_m3(2.5))) 
 338                 save_data(9, float(pms_data
.pm_ug_per_m3(10))) 
 344 except KeyboardInterrupt: