77
77
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PyPortal.git"
78
78
79
79
# pylint: disable=line-too-long
80
- IMAGE_CONVERTER_SERVICE = "http ://res.cloudinary.com/schmarty/image/fetch/w_320,h_240,c_fill,f_bmp/"
80
+ IMAGE_CONVERTER_SERVICE = "https ://res.cloudinary.com/schmarty/image/fetch/w_320,h_240,c_fill,f_bmp/"
81
81
#IMAGE_CONVERTER_SERVICE = "http://ec2-107-23-37-170.compute-1.amazonaws.com/rx/ofmt_bmp,rz_320x240/"
82
82
TIME_SERVICE_IPADDR = "http://worldtimeapi.org/api/ip"
83
83
TIME_SERVICE_LOCATION = "http://worldtimeapi.org/api/timezone/"
@@ -107,7 +107,8 @@ class PyPortal:
107
107
:param regexp_path: The list of regexp strings to get data out (use a single regexp group). Can
108
108
be list of regexps for multiple data points. Defaults to ``None`` to not
109
109
use regexp.
110
- :param default_bg: The path to your default background image file. Defaults to ``None``.
110
+ :param default_bg: The path to your default background image file or a hex color.
111
+ Defaults to 0x000000.
111
112
:param status_neopixel: The pin for the status NeoPixel. Use ``board.NEOPIXEL`` for the on-board
112
113
NeoPixel. Defaults to ``None``, no status LED
113
114
:param str text_font: The path to your font file for your data text display.
@@ -137,7 +138,7 @@ class PyPortal:
137
138
"""
138
139
# pylint: disable=too-many-instance-attributes, too-many-locals, too-many-branches, too-many-statements
139
140
def __init__ (self , * , url = None , json_path = None , regexp_path = None ,
140
- default_bg = None , status_neopixel = None ,
141
+ default_bg = 0x000000 , status_neopixel = None ,
141
142
text_font = None , text_position = None , text_color = 0x808080 ,
142
143
text_wrap = False , text_maxlen = 0 ,
143
144
image_json_path = None , image_resize = None , image_position = None ,
@@ -208,6 +209,7 @@ def __init__(self, *, url=None, json_path=None, regexp_path=None,
208
209
raise RuntimeError ("Was not able to find ESP32" )
209
210
210
211
requests .set_interface (self ._esp )
212
+ self ._connect_esp ()
211
213
212
214
if self ._debug :
213
215
print ("Init SD Card" )
@@ -220,6 +222,11 @@ def __init__(self, *, url=None, json_path=None, regexp_path=None,
220
222
except OSError as error :
221
223
print ("No SD card found:" , error )
222
224
225
+ try :
226
+ self .play_file ("pyportal_startup.wav" )
227
+ except OSError :
228
+ pass # they deleted the file, no biggie!
229
+
223
230
if self ._debug :
224
231
print ("Init display" )
225
232
self .splash = displayio .Group (max_size = 5 )
@@ -303,34 +310,39 @@ def __init__(self, *, url=None, json_path=None, regexp_path=None,
303
310
# pylint: enable=no-member
304
311
305
312
self .set_backlight (1.0 ) # turn on backlight
313
+
306
314
gc .collect ()
307
315
308
- def set_background (self , filename ):
316
+ def set_background (self , file_or_color ):
309
317
"""The background image to a bitmap file.
310
318
311
- :param filename : The name of the chosen background image file .
319
+ :param file_or_color : The filename of the chosen background image, or a hex color .
312
320
313
321
"""
314
- print ("Set background to " , filename )
315
- try :
322
+ print ("Set background to " , file_or_color )
323
+ while self . _bg_group :
316
324
self ._bg_group .pop ()
317
- except IndexError :
318
- pass # s'ok, we'll fix to test once we can
319
325
320
- if not filename :
326
+ if not file_or_color :
321
327
return # we're done, no background desired
322
328
if self ._bg_file :
323
329
self ._bg_file .close ()
324
- self . _bg_file = open ( filename , "rb" )
325
- background = displayio . OnDiskBitmap ( self ._bg_file )
326
- try :
330
+ if isinstance ( file_or_color , str ): # its a filenme:
331
+ self ._bg_file = open ( file_or_color , "rb" )
332
+ background = displayio . OnDiskBitmap ( self . _bg_file )
327
333
self ._bg_sprite = displayio .TileGrid (background ,
328
334
pixel_shader = displayio .ColorConverter (),
329
335
position = (0 , 0 ))
330
- except AttributeError :
331
- self ._bg_sprite = displayio .Sprite (background , pixel_shader = displayio .ColorConverter (),
332
- position = (0 , 0 ))
333
-
336
+ elif isinstance (file_or_color , int ):
337
+ # Make a background color fill
338
+ color_bitmap = displayio .Bitmap (320 , 240 , 1 )
339
+ color_palette = displayio .Palette (1 )
340
+ color_palette [0 ] = file_or_color
341
+ self ._bg_sprite = displayio .TileGrid (color_bitmap ,
342
+ pixel_shader = color_palette ,
343
+ position = (0 , 0 ))
344
+ else :
345
+ raise RuntimeError ("Unknown type of background" )
334
346
self ._bg_group .append (self ._bg_sprite )
335
347
board .DISPLAY .refresh_soon ()
336
348
gc .collect ()
@@ -449,8 +461,8 @@ def play_file(file_name):
449
461
450
462
"""
451
463
#self._speaker_enable.value = True
452
- with audioio . AudioOut ( board . AUDIO_OUT ) as audio :
453
- with open ( file_name , "rb" ) as file :
464
+ with open ( file_name , "rb" ) as file :
465
+ with audioio . AudioOut ( board . AUDIO_OUT ) as audio :
454
466
with audioio .WaveFile (file ) as wavefile :
455
467
audio .play (wavefile )
456
468
while audio .playing :
@@ -475,17 +487,24 @@ def get_local_time(self, location=None):
475
487
# pylint: enable=line-too-long
476
488
self ._connect_esp ()
477
489
api_url = None
478
- if not location :
479
- api_url = TIME_SERVICE_IPADDR
480
- else :
490
+ if secrets ['timezone' ]:
491
+ location = secrets ['timezone' ]
492
+ if location :
493
+ print ("Getting time for timezone" , location )
481
494
api_url = TIME_SERVICE_LOCATION + location
482
- response = requests .get (api_url )
483
- time_json = response .json ()
484
- current_time = time_json ['datetime' ]
485
- year_day = time_json ['day_of_year' ]
486
- week_day = time_json ['day_of_week' ]
487
- is_dst = time_json ['dst' ]
495
+ else : # we'll try to figure it out from the IP address
496
+ print ("Getting time from IP address" )
497
+ api_url = TIME_SERVICE_IPADDR
488
498
499
+ try :
500
+ response = requests .get (api_url )
501
+ time_json = response .json ()
502
+ current_time = time_json ['datetime' ]
503
+ year_day = time_json ['day_of_year' ]
504
+ week_day = time_json ['day_of_week' ]
505
+ is_dst = time_json ['dst' ]
506
+ except KeyError :
507
+ raise KeyError ("Was unable to lookup the time, try setting secrets['timezone'] according to http://worldtimeapi.org/timezones" ) # pylint: disable=line-too-long
489
508
the_date , the_time = current_time .split ('T' )
490
509
year , month , mday = [int (x ) for x in the_date .split ('-' )]
491
510
the_time = the_time .split ('.' )[0 ]
@@ -542,12 +561,22 @@ def wget(self, url, filename, *, chunk_size=12000):
542
561
def _connect_esp (self ):
543
562
self .neo_status ((0 , 0 , 100 ))
544
563
while not self ._esp .is_connected :
545
- if self ._debug :
546
- print ("Connecting to AP" )
547
564
# secrets dictionary must contain 'ssid' and 'password' at a minimum
565
+ print ("Connecting to AP" , secrets ['ssid' ])
566
+ if secrets ['ssid' ] == 'CHANGE ME' or secrets ['ssid' ] == 'CHANGE ME' :
567
+ print ("*" * 45 )
568
+ print ("Please update the 'secrets.py' file on your" )
569
+ print ("CIRCUITPY drive to include your local access" )
570
+ print ("point SSID name in 'ssid' and SSID password" )
571
+ print ("in 'password'. Then save to reload!" )
572
+ print ("*" * 45 )
548
573
self .neo_status ((100 , 0 , 0 )) # red = not connected
549
- self ._esp .connect (secrets )
550
-
574
+ try :
575
+ self ._esp .connect (secrets )
576
+ except RuntimeError as error :
577
+ print ("Cound not connect to internet" , error )
578
+ print ("Retrying in 3 seconds..." )
579
+ time .sleep (3 )
551
580
def fetch (self ):
552
581
"""Fetch data from the url we initialized with, perfom any parsing,
553
582
and display text or graphics. This function does pretty much everything"""
@@ -719,7 +748,8 @@ def show_QR(self, qr_data, qr_size=128, position=None): # pylint: disable=inval
719
748
720
749
for b in range (BLOCK_SIZE ):
721
750
# load this line of data in, as many time as block size
722
- qr_bitmap ._load_row (Y_OFFSET + y * BLOCK_SIZE + b , line ) # pylint: disable=protected-access
751
+ for i , byte in enumerate (line ):
752
+ qr_bitmap [Y_OFFSET + y * BLOCK_SIZE + b + i ] = byte
723
753
# pylint: enable=invalid-name
724
754
725
755
# display the bitmap using our palette
0 commit comments