diff --git a/adafruit_pyportal.py b/adafruit_pyportal.py index cccab99..fbdb159 100644 --- a/adafruit_pyportal.py +++ b/adafruit_pyportal.py @@ -180,6 +180,42 @@ def __init__(self, *, url=None, json_path=None, regexp_path=None, except OSError: self._uselocal = False + if self._debug: + print("Init display") + self.splash = displayio.Group(max_size=5) + + if self._debug: + print("Init background") + self._bg_group = displayio.Group(max_size=1) + self._bg_file = None + self._default_bg = default_bg + self.splash.append(self._bg_group) + + # show thank you and bootup file if available + for bootscreen in ("/thankyou.bmp", "/pyportal_startup.bmp"): + try: + os.stat(bootscreen) + board.DISPLAY.show(self.splash) + for i in range(100, -1, -1): # dim down + self.set_backlight(i/100) + time.sleep(0.005) + self.set_background(bootscreen) + board.DISPLAY.wait_for_frame() + for i in range(100): # dim up + self.set_backlight(i/100) + time.sleep(0.005) + time.sleep(2) + except OSError: + pass # they removed it, skip! + + self._speaker_enable = DigitalInOut(board.SPEAKER_ENABLE) + self._speaker_enable.switch_to_output(False) + self.audio = audioio.AudioOut(board.AUDIO_OUT) + try: + self.play_file("pyportal_startup.wav") + except OSError: + pass # they deleted the file, no biggie! + # Make ESP32 connection if self._debug: print("Init ESP32") @@ -207,6 +243,9 @@ def __init__(self, *, url=None, json_path=None, regexp_path=None, requests.set_interface(self._esp) self._connect_esp() + # set the default background + self.set_background(self._default_bg) + if self._debug: print("Init SD Card") sd_cs = DigitalInOut(board.SD_CS) @@ -218,27 +257,6 @@ def __init__(self, *, url=None, json_path=None, regexp_path=None, except OSError as error: print("No SD card found:", error) - self._speaker_enable = DigitalInOut(board.SPEAKER_ENABLE) - self._speaker_enable.switch_to_output(False) - self.audio = audioio.AudioOut(board.AUDIO_OUT) - - try: - self.play_file("pyportal_startup.wav") - except OSError: - pass # they deleted the file, no biggie! - - if self._debug: - print("Init display") - self.splash = displayio.Group(max_size=5) - board.DISPLAY.show(self.splash) - - if self._debug: - print("Init background") - self._bg_group = displayio.Group(max_size=1) - self._bg_file = None - self._default_bg = default_bg - self.set_background(self._default_bg) - self.splash.append(self._bg_group) self._qr_group = None @@ -318,7 +336,7 @@ def __init__(self, *, url=None, json_path=None, regexp_path=None, gc.collect() - def set_background(self, file_or_color): + def set_background(self, file_or_color, position=None): """The background image to a bitmap file. :param file_or_color: The filename of the chosen background image, or a hex color. @@ -328,6 +346,9 @@ def set_background(self, file_or_color): while self._bg_group: self._bg_group.pop() + if not position: + position = (0, 0) # default in top corner + if not file_or_color: return # we're done, no background desired if self._bg_file: @@ -337,7 +358,7 @@ def set_background(self, file_or_color): background = displayio.OnDiskBitmap(self._bg_file) self._bg_sprite = displayio.TileGrid(background, pixel_shader=displayio.ColorConverter(), - position=(0, 0)) + position=position) elif isinstance(file_or_color, int): # Make a background color fill color_bitmap = displayio.Bitmap(320, 240, 1) @@ -570,12 +591,13 @@ def _connect_esp(self): # secrets dictionary must contain 'ssid' and 'password' at a minimum print("Connecting to AP", secrets['ssid']) if secrets['ssid'] == 'CHANGE ME' or secrets['ssid'] == 'CHANGE ME': - print("*"*45) - print("Please update the 'secrets.py' file on your") - print("CIRCUITPY drive to include your local access") - print("point SSID name in 'ssid' and SSID password") - print("in 'password'. Then save to reload!") - print("*"*45) + change_me = "\n"+"*"*45 + change_me += "\nPlease update the 'secrets.py' file on your\n" + change_me += "CIRCUITPY drive to include your local WiFi\n" + change_me += "access point SSID name in 'ssid' and SSID\n" + change_me += "password in 'password'. Then save to reload!\n" + change_me += "*"*45 + raise OSError(change_me) self.neo_status((100, 0, 0)) # red = not connected try: self._esp.connect(secrets) @@ -688,7 +710,7 @@ def fetch(self): except OSError as error: print(error) raise OSError("""\n\nNo writable filesystem found for saving datastream. Insert an SD card or set internal filesystem to be unsafe by setting 'disable_concurrent_write_protection' in the mount options in boot.py""") # pylint: disable=line-too-long - self.set_background(filename) + self.set_background(filename, self._image_position) except ValueError as error: print("Error displaying cached image. " + error.args[0]) self.set_background(self._default_bg) @@ -717,7 +739,8 @@ def fetch(self): if self._text_wrap[i]: if self._debug: print("Wrapping text") - string = '\n'.join(PyPortal.wrap_nicely(string, self._text_wrap[i])) + lines = PyPortal.wrap_nicely(string, self._text_wrap[i]) + string = '\n'.join(lines) self.set_text(string, index=i) if len(values) == 1: return values[0] @@ -807,6 +830,7 @@ def wrap_nicely(string, max_chars): :param int max_chars: The maximum number of characters on a line before wrapping. """ + string = string.replace('\n', '').replace('\r', '') # strip confusing newlines words = string.split(' ') the_lines = [] the_line = "" @@ -818,4 +842,6 @@ def wrap_nicely(string, max_chars): the_line = ''+w if the_line: # last line remaining the_lines.append(the_line) + # remove first space from first line: + the_lines[0] = the_lines[0][1:] return the_lines