77
77
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PyPortal.git"
78
78
79
79
# pylint: disable=line-too-long
80
- IMAGE_CONVERTER_SERVICE = "https://res.cloudinary.com/schmarty/image/fetch/w_320,h_240,c_fill,f_bmp/"
81
- #IMAGE_CONVERTER_SERVICE = "http://ec2-107-23-37-170.compute-1.amazonaws.com/rx/ofmt_bmp,rz_320x240/"
80
+ # you'll need to pass in an io username, width, height, format (bit depth), io key, and then url!
81
+ IMAGE_CONVERTER_SERVICE = "https://io.adafruit.com/api/v2/%s/integrations/image-formatter?x-aio-key=%s&width=%d&height=%d&output=BMP%d&url=%s"
82
+
82
83
TIME_SERVICE_IPADDR = "http://worldtimeapi.org/api/ip"
83
84
TIME_SERVICE_LOCATION = "http://worldtimeapi.org/api/timezone/"
84
85
LOCALFILE = "local.txt"
@@ -119,6 +120,7 @@ class PyPortal:
119
120
:param text_wrap: Whether or not to wrap text (for long text data chunks). Defaults to
120
121
``False``, no wrapping.
121
122
:param text_maxlen: The max length of the text for text wrapping. Defaults to 0.
123
+ :param text_transform: A function that will be called on the text before display
122
124
:param image_json_path: The JSON traversal path for a background image to display. Defaults to
123
125
``None``.
124
126
:param image_resize: What size to resize the image we got from the json_path, make this a tuple
@@ -140,7 +142,7 @@ class PyPortal:
140
142
def __init__ (self , * , url = None , json_path = None , regexp_path = None ,
141
143
default_bg = 0x000000 , status_neopixel = None ,
142
144
text_font = None , text_position = None , text_color = 0x808080 ,
143
- text_wrap = False , text_maxlen = 0 ,
145
+ text_wrap = False , text_maxlen = 0 , text_transform = None ,
144
146
image_json_path = None , image_resize = None , image_position = None ,
145
147
caption_text = None , caption_font = None , caption_position = None ,
146
148
caption_color = 0x808080 ,
@@ -181,17 +183,11 @@ def __init__(self, *, url=None, json_path=None, regexp_path=None,
181
183
# Make ESP32 connection
182
184
if self ._debug :
183
185
print ("Init ESP32" )
184
- # pylint: disable=no-member
185
- esp32_cs = DigitalInOut (microcontroller .pin .PB14 )
186
- esp32_ready = DigitalInOut (microcontroller .pin .PB16 )
187
- esp32_gpio0 = DigitalInOut (microcontroller .pin .PB15 )
188
- esp32_reset = DigitalInOut (microcontroller .pin .PB17 )
189
- #esp32_ready = DigitalInOut(board.ESP_BUSY)
190
- #esp32_gpio0 = DigitalInOut(board.ESP_GPIO0)
191
- #esp32_reset = DigitalInOut(board.ESP_RESET)
192
- #esp32_cs = DigitalInOut(board.ESP_CS)
186
+ esp32_ready = DigitalInOut (board .ESP_BUSY )
187
+ esp32_gpio0 = DigitalInOut (board .ESP_GPIO0 )
188
+ esp32_reset = DigitalInOut (board .ESP_RESET )
189
+ esp32_cs = DigitalInOut (board .ESP_CS )
193
190
spi = busio .SPI (board .SCK , board .MOSI , board .MISO )
194
- # pylint: enable=no-member
195
191
196
192
if not self ._uselocal :
197
193
self ._esp = adafruit_esp32spi .ESP_SPIcontrol (spi , esp32_cs , esp32_ready ,
@@ -222,6 +218,10 @@ def __init__(self, *, url=None, json_path=None, regexp_path=None,
222
218
except OSError as error :
223
219
print ("No SD card found:" , error )
224
220
221
+ self ._speaker_enable = DigitalInOut (board .SPEAKER_ENABLE )
222
+ self ._speaker_enable .switch_to_output (False )
223
+ self .audio = audioio .AudioOut (board .AUDIO_OUT )
224
+
225
225
try :
226
226
self .play_file ("pyportal_startup.wav" )
227
227
except OSError :
@@ -256,17 +256,21 @@ def __init__(self, *, url=None, json_path=None, regexp_path=None,
256
256
text_wrap = [0 ] * num
257
257
if not text_maxlen :
258
258
text_maxlen = [0 ] * num
259
+ if not text_transform :
260
+ text_transform = [None ] * num
259
261
else :
260
262
num = 1
261
263
text_position = (text_position ,)
262
264
text_color = (text_color ,)
263
265
text_wrap = (text_wrap ,)
264
266
text_maxlen = (text_maxlen ,)
267
+ text_transform = (text_transform ,)
265
268
self ._text = [None ] * num
266
269
self ._text_color = [None ] * num
267
270
self ._text_position = [None ] * num
268
271
self ._text_wrap = [None ] * num
269
272
self ._text_maxlen = [None ] * num
273
+ self ._text_transform = [None ] * num
270
274
self ._text_font = bitmap_font .load_font (text_font )
271
275
if self ._debug :
272
276
print ("Loading font glyphs" )
@@ -282,6 +286,7 @@ def __init__(self, *, url=None, json_path=None, regexp_path=None,
282
286
self ._text_position [i ] = text_position [i ]
283
287
self ._text_wrap [i ] = text_wrap [i ]
284
288
self ._text_maxlen [i ] = text_maxlen [i ]
289
+ self ._text_transform [i ] = text_transform [i ]
285
290
else :
286
291
self ._text_font = None
287
292
self ._text = None
@@ -453,21 +458,23 @@ def neo_status(self, value):
453
458
if self .neopix :
454
459
self .neopix .fill (value )
455
460
456
- @staticmethod
457
- def play_file (file_name ):
461
+ def play_file (self , file_name , wait_to_finish = True ):
458
462
"""Play a wav file.
459
463
460
464
:param str file_name: The name of the wav file to play on the speaker.
461
465
462
466
"""
463
- #self._speaker_enable.value = True
464
- with open (file_name , "rb" ) as file :
465
- with audioio .AudioOut (board .AUDIO_OUT ) as audio :
466
- with audioio .WaveFile (file ) as wavefile :
467
- audio .play (wavefile )
468
- while audio .playing :
469
- pass
470
- #self._speaker_enable.value = False
467
+ board .DISPLAY .wait_for_frame ()
468
+ wavfile = open (file_name , "rb" )
469
+ wavedata = audioio .WaveFile (wavfile )
470
+ self ._speaker_enable .value = True
471
+ self .audio .play (wavedata )
472
+ if not wait_to_finish :
473
+ return
474
+ while self .audio .playing :
475
+ pass
476
+ wavfile .close ()
477
+ self ._speaker_enable .value = False
471
478
472
479
@staticmethod
473
480
def _json_traverse (json , path ):
@@ -487,8 +494,7 @@ def get_local_time(self, location=None):
487
494
# pylint: enable=line-too-long
488
495
self ._connect_esp ()
489
496
api_url = None
490
- if secrets ['timezone' ]:
491
- location = secrets ['timezone' ]
497
+ location = secrets .get ('timezone' , location )
492
498
if location :
493
499
print ("Getting time for timezone" , location )
494
500
api_url = TIME_SERVICE_LOCATION + location
@@ -624,7 +630,11 @@ def fetch(self):
624
630
# extract desired text/values from json
625
631
if self ._json_path :
626
632
for path in self ._json_path :
627
- values .append (PyPortal ._json_traverse (json_out , path ))
633
+ try :
634
+ values .append (PyPortal ._json_traverse (json_out , path ))
635
+ except KeyError :
636
+ print (json_out )
637
+ raise
628
638
elif self ._regexp_path :
629
639
for regexp in self ._regexp_path :
630
640
values .append (re .search (regexp , r .text ).group (1 ))
@@ -644,9 +654,17 @@ def fetch(self):
644
654
gc .collect ()
645
655
646
656
if image_url :
657
+ try :
658
+ aio_username = secrets ['aio_username' ]
659
+ aio_key = secrets ['aio_key' ]
660
+ except KeyError :
661
+ raise KeyError ("\n \n Our image converter service require a login/password to rate-limit. Please register for a freeadafruit.io account and place the user/key in your secrets file under 'aio_username' and 'aio_key'" )# pylint: disable=line-too-long
647
662
try :
648
663
print ("original URL:" , image_url )
649
- image_url = IMAGE_CONVERTER_SERVICE + image_url
664
+ image_url = IMAGE_CONVERTER_SERVICE % (aio_username , aio_key ,
665
+ self ._image_resize [0 ],
666
+ self ._image_resize [1 ],
667
+ 16 , image_url )
650
668
print ("convert URL:" , image_url )
651
669
# convert image to bitmap and cache
652
670
#print("**not actually wgetting**")
@@ -676,10 +694,14 @@ def fetch(self):
676
694
if self ._text :
677
695
for i in range (len (self ._text )):
678
696
string = None
679
- try :
680
- string = "{:,d}" .format (int (values [i ]))
681
- except (TypeError , ValueError ):
682
- string = values [i ] # ok its a string
697
+ if self ._text_transform [i ]:
698
+ func = self ._text_transform [i ]
699
+ string = func (values [i ])
700
+ else :
701
+ try :
702
+ string = "{:,d}" .format (int (values [i ]))
703
+ except (TypeError , ValueError ):
704
+ string = values [i ] # ok its a string
683
705
if self ._debug :
684
706
print ("Drawing text" , string )
685
707
if self ._text_wrap [i ]:
0 commit comments