Voting resources, early voting, and poll worker information - VOTE. ... Adafruit is open and shipping.
0

PyPortal data retieval gets stuck
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

PyPortal data retieval gets stuck

by majotito on Thu Oct 01, 2020 1:23 pm

I'm trying to build the Hurricane Tracker, and it seems to work the first time through OK, but leaving it run it gets stuck sometimes. I get "Retrieving data...", and the PyPortal status newopixel turns a yellow/green, and it stays there until the next time it goes to "Updating...", and then it might work OK. I tried reducing the UPDATE_RATE to 1, and that seemed to work every time. I don't want to ping nhc.noaa.gov unnecessarily, so how do I make this behave? I'm not even sure what's going wrong.
I tried using the timeout parameter, "storm_data = pyportal.fetch(timeout=1)" but this made no difference (is this in minutes or seconds??)
I now have the UPDATE_RATE set to 10 minutes and it still hangs every other retrieval attempt. It seems to be reliable enough to do this every other fetch. But, why? Again, why would a UPDATE_RATE of 1 minute work every time?
Also, weirdly, at startup, I get an odd message "ESP firmware: bytearray(b'1.2.2\x00')" Which may or may not be a clue??
Thanks for any help!

majotito
 
Posts: 22
Joined: Tue Jun 04, 2013 8:17 pm

Re: PyPortal data retieval gets stuck

by brubell on Fri Oct 02, 2020 11:08 am

Hi Majotito,

Could you please post the output of the REPL and the contents of the code.py file, surrounded by [code] tags?

brubell
 
Posts: 1061
Joined: Fri Jul 17, 2015 10:33 pm

Re: PyPortal data retieval gets stuck

by majotito on Fri Oct 02, 2020 12:43 pm

OK. I set the UPDATE_RATE to 10 minutes for this. Any more than 4 minutes and this happens. Note the "normal" line is "Retrieving data...Socket missing recv_into. Using more memory to be compatible", when if gets stuck, it has "Retrieving data..." and the status newpixel turns a greenish-yellow and sticks there until the next cycle.
The below was taken with the LED yellow-green and just stuck there.

---- - - - - REPL: -- -- - -
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
ESP firmware: bytearray(b'1.6.1\x00')
Connecting to AP starcat
Set background to /map.bmp
No SD card found: no SD card
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Twenty-Five @ 18.1,-84.7
Updating...
Retrieving data...Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Twenty-Five @ 18.1,-84.7
Updating...
Retrieving data...
-- - - ------ - -- - - - - - - - - - - - - -

Code below; my notes mostly have "MT" on them.
---------------------------------- - --
Code: Select all | TOGGLE FULL SIZE
import time
import math
import board
import displayio
import terminalio
from simpleio import map_range
import adafruit_imageload
from adafruit_pyportal import PyPortal
from adafruit_display_text.label import Label
from adafruit_display_shapes.line import Line

# --| User Config |---------------------------------------------------
UPDATE_RATE = 10  # minutes MT: was 60
MAX_STORMS = 8  # limit storms (MT: was 3; I think we'll have more storms)
NAME_COLOR = 0xFFFFFF  # label text color
NAME_BG_COLOR = 0x1f1f1f  # label background color MT: was 0x000000
ARROW_COLOR = 0x0000FF  # movement direction arrow color
ARROW_LENGTH = 15  # movement direction arrow length
LAT_RANGE = (45, 5)  # set to match map MT original map was (45, 5)
LON_RANGE = (-100, -40)  # set to match map. MT: original map was (-100, -40) , name is just map.bmp
# I made my own 45-55 & -100--40  map.bmp
# my other map uses (45, 5) and (-125, -65)  name of map is: map-45-5--125--65.bmp
# whole US uses (50, 0)  and (-132, -55)     Name of map: map-50-0--132_5--55wStates.bmp

NO_STORM_BRIGHT = .01 # Very dim.
YES_STORM_BRIGHT = 1  # bright
# -------------------------------------------- -------- ----------------

# setup pyportal
pyportal = PyPortal(
    url="https://www.nhc.noaa.gov/CurrentStorms.json",
    json_path=["activeStorms"],
    status_neopixel=board.NEOPIXEL,
    default_bg="/map.bmp",
)

# setup display group for storms
icons_bmp, icons_pal = adafruit_imageload.load(
    "/storm_icons.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette
)
for i, c in enumerate(icons_pal):
    if c == 0xFFFF00:
        icons_pal.make_transparent(i)
storm_icons = displayio.Group(max_size=MAX_STORMS)
pyportal.splash.append(storm_icons)
STORM_CLASS = ("TD", "TS", "HU")

# setup info label
info_update = Label(
    terminalio.FONT,
    text="1984-01-01T00:00:00.000Z--I'm waiting for data. . .",
    color=NAME_COLOR,
    background_color=NAME_BG_COLOR,
)
info_update.anchor_point = (0.0, 1.0)
info_update.anchored_position = (10, board.DISPLAY.height - 10)
pyportal.splash.append(info_update)

# these are need for lat/lon to screen x/y mapping
VIRTUAL_WIDTH = board.DISPLAY.width * 360 / (LON_RANGE[1] - LON_RANGE[0])
VIRTUAL_HEIGHT = board.DISPLAY.height * 360 / (LAT_RANGE[0] - LAT_RANGE[1])
Y_OFFSET = math.radians(LAT_RANGE[0])
Y_OFFSET = math.tan(math.pi / 4 + Y_OFFSET / 2)
Y_OFFSET = math.log(Y_OFFSET)
Y_OFFSET = (VIRTUAL_WIDTH * Y_OFFSET) / (2 * math.pi)
Y_OFFSET = VIRTUAL_HEIGHT / 2 - Y_OFFSET


def update_display():
    # get latest storm data
    try:
        storm_data = pyportal.fetch(timeout=1) # MT added timeout parameter. stock is 10, but 10 what?
    except RuntimeError:
        return
    print("Number of storms:", len(storm_data))

    # clear out existing icons (MT: I moved this to AFTER new data is attempted to be fetched)
    while len(storm_icons):
        _ = storm_icons.pop()

    # parse the storm data
    for storm in storm_data:
        # don't exceed max
        if len(storm_icons) >= MAX_STORMS:
            continue
        # get lat/lon
        lat = storm["latitudeNumeric"]
        lon = storm["longitudeNumeric"]
        # check if on map
        if (
            not LAT_RANGE[0] >= lat >= LAT_RANGE[1]
            or not LON_RANGE[0] <= lon <= LON_RANGE[1]
        ):
            continue
        # OK, let's make a group for all the graphics
        storm_gfx = displayio.Group(max_size=3)  # icon + label + arrow
        # convert to sreen coords
        x = int(map_range(lon, LON_RANGE[0], LON_RANGE[1], 0, board.DISPLAY.width - 1))
        y = math.radians(lat)
        y = math.tan(math.pi / 4 + y / 2)
        y = math.log(y)
        y = (VIRTUAL_WIDTH * y) / (2 * math.pi)
        y = VIRTUAL_HEIGHT / 2 - y
        y = int(y - Y_OFFSET)
        # icon type
        if storm["classification"] in STORM_CLASS:
            storm_type = STORM_CLASS.index(storm["classification"])
        else:
            storm_type = 0
        # create storm icon
        icon = displayio.TileGrid(
            icons_bmp,
            pixel_shader=icons_pal,
            width=1,
            height=1,
            tile_width=16,
            tile_height=16,
            default_tile=storm_type,
            x=x - 8,
            y=y - 8,
        )
        # add storm icon
        storm_gfx.append(icon)
        # add a label
        name = Label(
            terminalio.FONT,
            text=storm["name"],
            color=NAME_COLOR,
            background_color=NAME_BG_COLOR,
        )
        name.anchor_point = (0.0, 1.0)
        name.anchored_position = (x + 8, y - 8)
        storm_gfx.append(name)
        # add direction arrow
        angle = math.radians(storm["movementDir"])
        xd = x + int(ARROW_LENGTH * math.sin(angle))
        yd = y - int(ARROW_LENGTH * math.cos(angle))
        arrow = Line(x, y, xd, yd, color=ARROW_COLOR)
        storm_gfx.append(arrow)
        # add the storm graphics
        storm_icons.append(storm_gfx)
        # update time
        # info_update.text = storm["lastUpdate"] #MT: I moved this out of the if-storm section.
        #if storm, turn up the screen brightness
        board.DISPLAY.brightness = YES_STORM_BRIGHT  #MT bright when a storm is present
        # debug
        print(
            "{} @ {},{}".format(
                storm["name"], storm["latitudeNumeric"], storm["longitudeNumeric"]
            )
        )

    # update time- MT copied this line here, originally this only updated if there was a storm in the area
    info_update.text = storm["lastUpdate"]

    # no storms? at least say something
    if not len(storm_icons):
        print("No storms in map area.")
        board.DISPLAY.brightness = NO_STORM_BRIGHT  #MT no storm, dim the screen
        storm_icons.append(
            Label(
                terminalio.FONT,
                scale=4,
                x=30,
                y=100,
                text=" NO STORMS \n IN AREA",
                color=NAME_COLOR,
                background_color=NAME_BG_COLOR,
            )
        )


# --------------------------------------------------------------------
# M A I N
# --------------------------------------------------------------------
update_display()
last_update = time.monotonic()
while True:
    now = time.monotonic()
    if now - last_update > UPDATE_RATE * 60:
        print("Updating...")
        update_display()
        last_update = now


majotito
 
Posts: 22
Joined: Tue Jun 04, 2013 8:17 pm

Re: PyPortal data retieval gets stuck

by majotito on Fri Oct 02, 2020 12:43 pm

Oh and I did update the ESP32 to 1.6.1, if that matters.

majotito
 
Posts: 22
Joined: Tue Jun 04, 2013 8:17 pm

Re: PyPortal data retieval gets stuck

by majotito on Fri Oct 09, 2020 9:37 am

Hi--

Any thoughts on this? I'm not sure if it is, but maybe this is this related to the issues below?:

https://forums.adafruit.com/viewtopic.php?f=56&t=170049
or
https://forums.adafruit.com/viewtopic.php?f=60&t=169654

What else can I try? Should I try CircuitPython 6.0.0 beta?

I'm not sure what the clue is that this works every other time, or that it works if I have it check every 4 minutes or quicker. I put a PRINT statement in to see how fast it popped out of the .fetch routine, and it was very quick. I still don't know what the problem is but at least I see that it fails quickly. Is there a statement I can put in to find out the error? Or should I just add some code so that if this does not get good data back it just tries again with another call to the "update_display()" routine?

Does this have anything to do with the "Socket missing recv_into. Using more memory to be compatible" message?

Thanks.

code.py:
Code: Select all | TOGGLE FULL SIZE
import time
import math
import board
import displayio
import terminalio
from simpleio import map_range
import adafruit_imageload
from adafruit_pyportal import PyPortal
from adafruit_display_text.label import Label
from adafruit_display_shapes.line import Line

# --| User Config |---------------------------------------------------
UPDATE_RATE = 10  # minutes MT: was 60
MAX_STORMS = 8  # limit storms (MT: was 3; I think we'll have more storms)
NAME_COLOR = 0xFFFFFF  # label text color
NAME_BG_COLOR = 0x1f1f1f  # label background color MT: was 0x000000
ARROW_COLOR = 0x0000FF  # movement direction arrow color
ARROW_LENGTH = 15  # movement direction arrow length
LAT_RANGE = (45, 5)  # set to match map MT original map was (45, 5)
LON_RANGE = (-100, -40)  # set to match map. MT: original map was (-100, -40) , name is just map.bmp
# I made my own 45-55 & -100--40  map.bmp
# my other map uses (45, 5) and (-125, -65)  name of map is: map-45-5--125--65.bmp
# whole US uses (50, 0)  and (-132, -55)     Name of map: map-50-0--132_5--55wStates.bmp

NO_STORM_BRIGHT = .01 # Very dim.
YES_STORM_BRIGHT = 1  # bright
# -------------------------------------------- -------- ----------------

# setup pyportal
pyportal = PyPortal(
    url="https://www.nhc.noaa.gov/CurrentStorms.json",
    json_path=["activeStorms"],
    status_neopixel=board.NEOPIXEL,
    default_bg="/map.bmp",
)

# setup display group for storms
icons_bmp, icons_pal = adafruit_imageload.load(
    "/storm_icons.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette
)
for i, c in enumerate(icons_pal):
    if c == 0xFFFF00:
        icons_pal.make_transparent(i)
storm_icons = displayio.Group(max_size=MAX_STORMS)
pyportal.splash.append(storm_icons)
STORM_CLASS = ("TD", "TS", "HU")

# setup info label
info_update = Label(
    terminalio.FONT,
    text="1984-01-01T00:00:00.000Z--I'm waiting for data. . .",
    color=NAME_COLOR,
    background_color=NAME_BG_COLOR,
)
info_update.anchor_point = (0.0, 1.0)
info_update.anchored_position = (10, board.DISPLAY.height - 10)
pyportal.splash.append(info_update)

# these are need for lat/lon to screen x/y mapping
VIRTUAL_WIDTH = board.DISPLAY.width * 360 / (LON_RANGE[1] - LON_RANGE[0])
VIRTUAL_HEIGHT = board.DISPLAY.height * 360 / (LAT_RANGE[0] - LAT_RANGE[1])
Y_OFFSET = math.radians(LAT_RANGE[0])
Y_OFFSET = math.tan(math.pi / 4 + Y_OFFSET / 2)
Y_OFFSET = math.log(Y_OFFSET)
Y_OFFSET = (VIRTUAL_WIDTH * Y_OFFSET) / (2 * math.pi)
Y_OFFSET = VIRTUAL_HEIGHT / 2 - Y_OFFSET


def update_display():
    # get latest storm data
    try:
        storm_data = pyportal.fetch(timeout=1) # MT added timeout parameter. stock is 10, but 10 what?
    except RuntimeError:
        print("I'M STUCK")
        return
    print("Number of storms:", len(storm_data))

    # clear out existing icons (MT: I moved this to after new data is attempted to be fetched)
    while len(storm_icons):
        _ = storm_icons.pop()

    # parse the storm data
    for storm in storm_data:
        # don't exceed max
        if len(storm_icons) >= MAX_STORMS:
            continue
        # get lat/lon
        lat = storm["latitudeNumeric"]
        lon = storm["longitudeNumeric"]
        # check if on map
        if (
            not LAT_RANGE[0] >= lat >= LAT_RANGE[1]
            or not LON_RANGE[0] <= lon <= LON_RANGE[1]
        ):
            continue
        # OK, let's make a group for all the graphics
        storm_gfx = displayio.Group(max_size=3)  # icon + label + arrow
        # convert to sreen coords
        x = int(map_range(lon, LON_RANGE[0], LON_RANGE[1], 0, board.DISPLAY.width - 1))
        y = math.radians(lat)
        y = math.tan(math.pi / 4 + y / 2)
        y = math.log(y)
        y = (VIRTUAL_WIDTH * y) / (2 * math.pi)
        y = VIRTUAL_HEIGHT / 2 - y
        y = int(y - Y_OFFSET)
        # icon type
        if storm["classification"] in STORM_CLASS:
            storm_type = STORM_CLASS.index(storm["classification"])
        else:
            storm_type = 0
        # create storm icon
        icon = displayio.TileGrid(
            icons_bmp,
            pixel_shader=icons_pal,
            width=1,
            height=1,
            tile_width=16,
            tile_height=16,
            default_tile=storm_type,
            x=x - 8,
            y=y - 8,
        )
        # add storm icon
        storm_gfx.append(icon)
        # add a label
        name = Label(
            terminalio.FONT,
            text=storm["name"],
            color=NAME_COLOR,
            background_color=NAME_BG_COLOR,
        )
        name.anchor_point = (0.0, 1.0)
        name.anchored_position = (x + 8, y - 8)
        storm_gfx.append(name)
        # add direction arrow
        angle = math.radians(storm["movementDir"])
        xd = x + int(ARROW_LENGTH * math.sin(angle))
        yd = y - int(ARROW_LENGTH * math.cos(angle))
        arrow = Line(x, y, xd, yd, color=ARROW_COLOR)
        storm_gfx.append(arrow)
        # add the storm graphics
        storm_icons.append(storm_gfx)
        # update time
        # info_update.text = storm["lastUpdate"] #MT: I moved this out of the if-storm section.
        #if storm, turn up the screen brightness
        board.DISPLAY.brightness = YES_STORM_BRIGHT  #MT bright when a storm is present
        # debug
        print(
            "{} @ {},{}".format(
                storm["name"], storm["latitudeNumeric"], storm["longitudeNumeric"]
            )
        )

    # update time- MT copied this line here
    info_update.text = storm["lastUpdate"]

    # no storms? at least say something
    if not len(storm_icons):
        print("No storms in map area.")
        board.DISPLAY.brightness = NO_STORM_BRIGHT   #MT no storm, dim the screen
        storm_icons.append(
            Label(
                terminalio.FONT,
                scale=4,
                x=30,
                y=100,
                text=" NO STORMS \n IN AREA",
                color=NAME_COLOR,
                background_color=NAME_BG_COLOR,
            )
        )


# --------------------------------------------------------------------
# M A I N
# --------------------------------------------------------------------
update_display()
last_update = time.monotonic()
while True:
    now = time.monotonic()
    if now - last_update > UPDATE_RATE * 60:
        print("Updating...")
        update_display()
        last_update = now


REPL
Code: Select all | TOGGLE FULL SIZE
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
ESP firmware: bytearray(b'1.6.1\x00')
Connecting to AP starcat
Set background to  /map.bmp
No SD card found: no SD card
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 27.5,-93.8
Updating...
Retrieving data...I'M STUCK
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 27.5,-93.8

majotito
 
Posts: 22
Joined: Tue Jun 04, 2013 8:17 pm

Re: PyPortal data retieval gets stuck

by brubell on Fri Oct 09, 2020 4:49 pm

The PyPortal library was updated and released today - could you try updating the library version and trying again?

brubell
 
Posts: 1061
Joined: Fri Jul 17, 2015 10:33 pm

Re: PyPortal data retieval gets stuck

by majotito on Fri Oct 09, 2020 7:35 pm

Hi. I altered the code a little to print out the RuntimeError. This error showed before and after I updated the library. I don't see any change in the problem.

code
Code: Select all | TOGGLE FULL SIZE
import time
import math
import board
import displayio
import terminalio
from simpleio import map_range
import adafruit_imageload
from adafruit_pyportal import PyPortal
from adafruit_display_text.label import Label
from adafruit_display_shapes.line import Line

# --| User Config |---------------------------------------------------
UPDATE_RATE = 10  # minutes MT: was 60
MAX_STORMS = 8  # limit storms (MT: was 3; I think we'll have more storms)
NAME_COLOR = 0xFFFFFF  # label text color
NAME_BG_COLOR = 0x1f1f1f  # label background color MT: was 0x000000
ARROW_COLOR = 0x0000FF  # movement direction arrow color
ARROW_LENGTH = 15  # movement direction arrow length
LAT_RANGE = (45, 5)  # set to match map MT original map was (45, 5)
LON_RANGE = (-100, -40)  # set to match map. MT: original map was (-100, -40) , name is just map.bmp
# I made my own 45-55 & -100--40  map.bmp
# my other map uses (45, 5) and (-125, -65)  name of map is: map-45-5--125--65.bmp
# whole US uses (50, 0)  and (-132, -55)     Name of map: map-50-0--132_5--55wStates.bmp

NO_STORM_BRIGHT = .01 # Very dim.
YES_STORM_BRIGHT = 1  # bright
# -------------------------------------------- -------- ----------------

# setup pyportal
pyportal = PyPortal(
    url="https://www.nhc.noaa.gov/CurrentStorms.json",
    json_path=["activeStorms"],
    status_neopixel=board.NEOPIXEL,
    default_bg="/map.bmp",
)

# setup display group for storms
icons_bmp, icons_pal = adafruit_imageload.load(
    "/storm_icons.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette
)
for i, c in enumerate(icons_pal):
    if c == 0xFFFF00:
        icons_pal.make_transparent(i)
storm_icons = displayio.Group(max_size=MAX_STORMS)
pyportal.splash.append(storm_icons)
STORM_CLASS = ("TD", "TS", "HU")

# setup info label
info_update = Label(
    terminalio.FONT,
    text="1984-01-01T00:00:00.000Z--I'm waiting for data. . .",
    color=NAME_COLOR,
    background_color=NAME_BG_COLOR,
)
info_update.anchor_point = (0.0, 1.0)
info_update.anchored_position = (10, board.DISPLAY.height - 10)
pyportal.splash.append(info_update)

# these are need for lat/lon to screen x/y mapping
VIRTUAL_WIDTH = board.DISPLAY.width * 360 / (LON_RANGE[1] - LON_RANGE[0])
VIRTUAL_HEIGHT = board.DISPLAY.height * 360 / (LAT_RANGE[0] - LAT_RANGE[1])
Y_OFFSET = math.radians(LAT_RANGE[0])
Y_OFFSET = math.tan(math.pi / 4 + Y_OFFSET / 2)
Y_OFFSET = math.log(Y_OFFSET)
Y_OFFSET = (VIRTUAL_WIDTH * Y_OFFSET) / (2 * math.pi)
Y_OFFSET = VIRTUAL_HEIGHT / 2 - Y_OFFSET


def update_display():
    # get latest storm data
    try:
        storm_data = pyportal.fetch(timeout=1) # MT added timeout parameter. stock is 10 __.
    except (RuntimeError) as ERROR:
        print("There was a RuntimeError:" ,ERROR)
        return
    print("Number of storms:", len(storm_data))

    # clear out existing icons (MT: I moved this to after new data is attempted to be fetched, in case of error)
    while len(storm_icons):
        _ = storm_icons.pop()

    # parse the storm data
    for storm in storm_data:
        # don't exceed max
        if len(storm_icons) >= MAX_STORMS:
            continue
        # get lat/lon
        lat = storm["latitudeNumeric"]
        lon = storm["longitudeNumeric"]
        # check if on map
        if (
            not LAT_RANGE[0] >= lat >= LAT_RANGE[1]
            or not LON_RANGE[0] <= lon <= LON_RANGE[1]
        ):
            continue
        # OK, let's make a group for all the graphics
        storm_gfx = displayio.Group(max_size=3)  # icon + label + arrow
        # convert to sreen coords
        x = int(map_range(lon, LON_RANGE[0], LON_RANGE[1], 0, board.DISPLAY.width - 1))
        y = math.radians(lat)
        y = math.tan(math.pi / 4 + y / 2)
        y = math.log(y)
        y = (VIRTUAL_WIDTH * y) / (2 * math.pi)
        y = VIRTUAL_HEIGHT / 2 - y
        y = int(y - Y_OFFSET)
        # icon type
        if storm["classification"] in STORM_CLASS:
            storm_type = STORM_CLASS.index(storm["classification"])
        else:
            storm_type = 0
        # create storm icon
        icon = displayio.TileGrid(
            icons_bmp,
            pixel_shader=icons_pal,
            width=1,
            height=1,
            tile_width=16,
            tile_height=16,
            default_tile=storm_type,
            x=x - 8,
            y=y - 8,
        )
        # add storm icon
        storm_gfx.append(icon)
        # add a label
        name = Label(
            terminalio.FONT,
            text=storm["name"],
            color=NAME_COLOR,
            background_color=NAME_BG_COLOR,
        )
        name.anchor_point = (0.0, 1.0)
        name.anchored_position = (x + 8, y - 8)
        storm_gfx.append(name)
        # add direction arrow
        angle = math.radians(storm["movementDir"])
        xd = x + int(ARROW_LENGTH * math.sin(angle))
        yd = y - int(ARROW_LENGTH * math.cos(angle))
        arrow = Line(x, y, xd, yd, color=ARROW_COLOR)
        storm_gfx.append(arrow)
        # add the storm graphics
        storm_icons.append(storm_gfx)
        # update time
        # info_update.text = storm["lastUpdate"] #MT: I moved this out of the if-storm section.
        #if storm, turn up the screen brightness
        board.DISPLAY.brightness = YES_STORM_BRIGHT  #MT bright when a storm is present
        # debug
        print(
            "{} @ {},{}".format(
                storm["name"], storm["latitudeNumeric"], storm["longitudeNumeric"]
            )
        )

    # update time- MT copied this line here, originally this only updated if there was a storm in this area.
    info_update.text = storm["lastUpdate"]

    # no storms? at least say something
    if not len(storm_icons):
        print("No storms in map area.")
        board.DISPLAY.brightness = NO_STORM_BRIGHT   #MT no storm, dim the screen
        storm_icons.append(
            Label(
                terminalio.FONT,
                scale=4,
                x=30,
                y=100,
                text=" NO STORMS \n IN AREA",
                color=NAME_COLOR,
                background_color=NAME_BG_COLOR,
            )
        )


# --------------------------------------------------------------------
# M A I N
# --------------------------------------------------------------------
update_display()
last_update = time.monotonic()
while True:
    now = time.monotonic()
    if now - last_update > UPDATE_RATE * 60:
        print("Updating...")
        update_display()
        last_update = now


From the REPL:
Code: Select all | TOGGLE FULL SIZE
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
ESP firmware: bytearray(b'1.6.1\x00')
Connecting to AP starcat
Set background to  /map.bmp
No SD card found: no SD card
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 29.5,-93.1
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 29.5,-93.1
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 29.5,-93.1
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 29.8,-93.1
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)

majotito
 
Posts: 22
Joined: Tue Jun 04, 2013 8:17 pm

Re: PyPortal data retieval gets stuck

by majotito on Sat Oct 10, 2020 7:39 am

A follow-up from last night. I let it run and the same errors kept showing. Then the status neopixel turned red and apparently it lost connection to the wifi. It tried to reconnect all night. This morning I pressed the reset button and it booted up and connected just fine so I don't know what the problem was. Here is the first section of the REPL. After this point it repeats the reconnection attempt for many lines that I did not include here. I'm not sure what happened at the gap; it appears to have rebooted at that point somehow.

Code: Select all | TOGGLE FULL SIZE
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
ESP firmware: bytearray(b'1.6.1\x00')
Connecting to AP starcat
Set background to  /map.bmp
No SD card found: no SD card
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 29.1,-93.4
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 29.1,-93.4
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 29.1,-93.4
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 29.3,-93.2
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 29.3,-93.2
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 29.3,-93.2
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 29.5,-93.1
soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Traceback (most recent call last):
  File "code.py", line 6, in <module>
ImportError: no module named 'simpleio'



Press any key to enter the REPL. Use CTRL-D to reload.soft reboot

Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 29.8,-93.1
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 29.8,-93.1
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 30.0,-93.0
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 30.0,-93.0
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
There was a RuntimeError: Unable to read HTTP response.
Updating...
Retrieving data...There was a RuntimeError: Expected 01 but got 00
Updating...
Retrieving data...There was a RuntimeError: Expected 01 but got 00
Updating...
Connecting to AP starcat
Could not connect to internet Error response to command
Retrying in 3 seconds...
Connecting to AP starcat
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 2
Delta @ 30.2,-92.9
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
There was a RuntimeError: Unable to read HTTP response.
Updating...
Retrieving data...There was a RuntimeError: Expected 01 but got 00
Updating...
Retrieving data...There was a RuntimeError: Expected 01 but got 00
Updating...
Connecting to AP starcat
Could not connect to internet Error response to command
Retrying in 3 seconds...
Connecting to AP starcat
Retrieving data...Socket missing recv_into. Using more memory to be compatible
There was a RuntimeError: Unable to read HTTP response.
Updating...
Retrieving data...There was a RuntimeError: Expected 01 but got 00
Updating...
Retrieving data...There was a RuntimeError: Expected 01 but got 00
Updating...
Connecting to AP starcat
Could not connect to internet Error response to command
Retrying in 3 seconds...
Connecting to AP starcat
Retrieving data...Socket missing recv_into. Using more memory to be compatible
There was a RuntimeError: Unable to read HTTP response.
Updating...
Retrieving data...There was a RuntimeError: Expected 01 but got 00
Updating...
Retrieving data...There was a RuntimeError: Expected 01 but got 00
Updating...
Connecting to AP starcat
Could not connect to internet ('Failed to connect to ssid', b'starcat')
Retrying in 3 seconds...
Connecting to AP starcat
Could not connect to internet ('Failed to connect to ssid', b'starcat')
Retrying in 3 seconds...
Connecting to AP starcat
Could not connect to internet ('Failed to connect to ssid', b'starcat')
Retrying in 3 seconds...
Connecting to AP starcat
Could not connect to internet ('Failed to connect to ssid', b'starcat')
Retrying in 3 seconds...
Connecting to AP starcat
Could not connect to internet ('Failed to connect to ssid', b'starcat')
Retrying in 3 seconds...
Connecting to AP starcat
Could not connect to internet ('Failed to connect to ssid', b'starcat')
Retrying in 3 seconds...
Connecting to AP starcat
Could not connect to internet ('Failed to connect to ssid', b'starcat')
Retrying in 3 seconds...
Connecting to AP starcat
Could not connect to internet ('Failed to connect to ssid', b'starcat')
Retrying in 3 seconds...
Connecting to AP starcat
Could not connect to internet Timed out waiting for SPI char
Retrying in 3 seconds...
Connecting to AP starcat
Could not connect to internet ('Failed to connect to ssid', b'starcat')
Retrying in 3 seconds...
Connecting to AP starcat
Could not connect to internet ('Failed to connect to ssid', b'starcat')
Retrying in 3 seconds...
Connecting to AP starcat
Could not connect to internet ('Failed to connect to ssid', b'starcat')
Retrying in 3 seconds...
Connecting to AP starcat
Could not connect to internet ('Failed to connect to ssid', b'starcat')
Retrying in 3 seconds...
Connecting to AP starcat
Could not connect to internet ('Failed to connect to ssid', b'starcat')
Retrying in 3 seconds...
Connecting to AP starcat
Could not connect to internet ('Failed to connect to ssid', b'starcat')
Retrying in 3 seconds...
Connecting to AP starcat
Could not connect to internet ('Failed to connect to ssid', b'starcat')
Retrying in 3 seconds...

majotito
 
Posts: 22
Joined: Tue Jun 04, 2013 8:17 pm

Re: PyPortal data retieval gets stuck

by majotito on Mon Oct 12, 2020 1:28 pm

Hi-- Another follow-up.

I had this disconnected for a day and turned it back on. Apparently there are no storms now, and now this throws an error. I guess if there are no storms, storm["lastUpdate"] is never initialized. I had to add in a "try" function to get around this. Somehow, this worked before, but maybe there was one storm but none in the target area? Can we set a dummy placeholder or otherwise set the "lastUpdate" variable maybe based on the last time this was checked? I did move the "info_update.text = storm["lastUpdate"]" to outside the "for storm in storm_data:" section so it showed in any case, because that made more sense than leaving the first dummy text display "1984-01-01T00:00:00.000Z" showing.

Also, I'm still getting the every-other-time "Failed to send 3 bytes (sent 0)" error pretty consistently, which is perplexing and annoying since I don't know what's wrong.

Is there anything else I can try? Does this fetch error happen in other builds or just mine?

code:
Code: Select all | TOGGLE FULL SIZE
import time
import math
import board
import displayio
import terminalio
from simpleio import map_range
import adafruit_imageload
from adafruit_pyportal import PyPortal
from adafruit_display_text.label import Label
from adafruit_display_shapes.line import Line

# --| User Config |---------------------------------------------------
UPDATE_RATE = 10  # minutes MT: was 60
MAX_STORMS = 8  # limit storms (MT: was 3; I think we'll have more storms)
NAME_COLOR = 0xFFFFFF  # label text color
NAME_BG_COLOR = 0x1f1f1f  # label background color MT: was 0x000000
ARROW_COLOR = 0x0000FF  # movement direction arrow color
ARROW_LENGTH = 15  # movement direction arrow length
LAT_RANGE = (45, 5)  # set to match map MT original map was (45, 5)
LON_RANGE = (-100, -40)  # set to match map. MT: original map was (-100, -40) , name is just map.bmp
# I made my own 45-55 & -100--40  map.bmp
# my other map uses (45, 5) and (-125, -65)  name of map is: map-45-5--125--65.bmp
# whole US uses (50, 0)  and (-132, -55)     Name of map: map-50-0--132_5--55wStates.bmp

NO_STORM_BRIGHT = .01 # Very dim.
YES_STORM_BRIGHT = 1  # bright
# -------------------------------------------- -------- ----------------
# Will this fix the error "File "code.py", line 155, in update_display / NameError: local variable referenced before assignment"
# storm["lastUpdate"] = "NOTHING"
# _______---- NO IT DIDN"T

# setup pyportal
pyportal = PyPortal(
    url="https://www.nhc.noaa.gov/CurrentStorms.json",
    json_path=["activeStorms"],
    status_neopixel=board.NEOPIXEL,
    default_bg="/map.bmp",
)

# setup display group for storms
icons_bmp, icons_pal = adafruit_imageload.load(
    "/storm_icons.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette
)
for i, c in enumerate(icons_pal):
    if c == 0xFFFF00:
        icons_pal.make_transparent(i)
storm_icons = displayio.Group(max_size=MAX_STORMS)
pyportal.splash.append(storm_icons)
STORM_CLASS = ("TD", "TS", "HU")

# setup info label
info_update = Label(
    terminalio.FONT,
    text="1984-01-01T00:00:00.000Z--I'm waiting for data. . .",
    color=NAME_COLOR,
    background_color=NAME_BG_COLOR,
)
info_update.anchor_point = (0.0, 1.0)
info_update.anchored_position = (10, board.DISPLAY.height - 10)
pyportal.splash.append(info_update)

# these are need for lat/lon to screen x/y mapping
VIRTUAL_WIDTH = board.DISPLAY.width * 360 / (LON_RANGE[1] - LON_RANGE[0])
VIRTUAL_HEIGHT = board.DISPLAY.height * 360 / (LAT_RANGE[0] - LAT_RANGE[1])
Y_OFFSET = math.radians(LAT_RANGE[0])
Y_OFFSET = math.tan(math.pi / 4 + Y_OFFSET / 2)
Y_OFFSET = math.log(Y_OFFSET)
Y_OFFSET = (VIRTUAL_WIDTH * Y_OFFSET) / (2 * math.pi)
Y_OFFSET = VIRTUAL_HEIGHT / 2 - Y_OFFSET


def update_display():
    # get latest storm data
    try:
        storm_data = pyportal.fetch(timeout=1) # MT added timeout parameter. stock is 10 __.
    except (RuntimeError) as ERROR:
        print("There was a RuntimeError:" ,ERROR)
        return
    print("Number of storms:", len(storm_data))

    # clear out existing icons (MT: I moved this to after new data is attempted to be fetched, in case of error)
    while len(storm_icons):
        _ = storm_icons.pop()

    # parse the storm data
    for storm in storm_data:
        # don't exceed max
        if len(storm_icons) >= MAX_STORMS:
            continue
        # get lat/lon
        lat = storm["latitudeNumeric"]
        lon = storm["longitudeNumeric"]
        # check if on map
        if (
            not LAT_RANGE[0] >= lat >= LAT_RANGE[1]
            or not LON_RANGE[0] <= lon <= LON_RANGE[1]
        ):
            continue
        # OK, let's make a group for all the graphics
        storm_gfx = displayio.Group(max_size=3)  # icon + label + arrow
        # convert to sreen coords
        x = int(map_range(lon, LON_RANGE[0], LON_RANGE[1], 0, board.DISPLAY.width - 1))
        y = math.radians(lat)
        y = math.tan(math.pi / 4 + y / 2)
        y = math.log(y)
        y = (VIRTUAL_WIDTH * y) / (2 * math.pi)
        y = VIRTUAL_HEIGHT / 2 - y
        y = int(y - Y_OFFSET)
        # icon type
        if storm["classification"] in STORM_CLASS:
            storm_type = STORM_CLASS.index(storm["classification"])
        else:
            storm_type = 0
        # create storm icon
        icon = displayio.TileGrid(
            icons_bmp,
            pixel_shader=icons_pal,
            width=1,
            height=1,
            tile_width=16,
            tile_height=16,
            default_tile=storm_type,
            x=x - 8,
            y=y - 8,
        )
        # add storm icon
        storm_gfx.append(icon)
        # add a label
        name = Label(
            terminalio.FONT,
            text=storm["name"],
            color=NAME_COLOR,
            background_color=NAME_BG_COLOR,
        )
        name.anchor_point = (0.0, 1.0)
        name.anchored_position = (x + 8, y - 8)
        storm_gfx.append(name)
        # add direction arrow
        angle = math.radians(storm["movementDir"])
        xd = x + int(ARROW_LENGTH * math.sin(angle))
        yd = y - int(ARROW_LENGTH * math.cos(angle))
        arrow = Line(x, y, xd, yd, color=ARROW_COLOR)
        storm_gfx.append(arrow)
        # add the storm graphics
        storm_icons.append(storm_gfx)
        # update time
        # info_update.text = storm["lastUpdate"] #MT: I moved this out of the if-storm section.
        #if storm, turn up the screen brightness
        board.DISPLAY.brightness = YES_STORM_BRIGHT  #MT bright when a storm is present
        # debug
        print(
            "{} @ {},{}".format(
                storm["name"], storm["latitudeNumeric"], storm["longitudeNumeric"]
            )
        )

    # update time- MT copied this line here, originally this only updated if there was a storm in this area.
    # Then, an update to the library caused this to not work; had to add error handling when no storms were in area.
    # But, why no update time, even if no data?
    try:
        info_update.text = storm["lastUpdate"]
    except:
        print("no update")

    # no storms? at least say something
    if not len(storm_icons):
        print("No storms in map area.")
        board.DISPLAY.brightness = NO_STORM_BRIGHT   #MT no storm, dim the screen
        storm_icons.append(
            Label(
                terminalio.FONT,
                scale=4,
                x=30,
                y=100,
                text=" NO STORMS \n IN AREA",
                color=NAME_COLOR,
                background_color=NAME_BG_COLOR,
            )
        )


# --------------------------------------------------------------------
# M A I N
# --------------------------------------------------------------------
update_display()
last_update = time.monotonic()
while True:
    now = time.monotonic()
    if now - last_update > UPDATE_RATE * 60:
        print("Updating...")
        update_display()
        last_update = now


From REPL:
Code: Select all | TOGGLE FULL SIZE
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
ESP firmware: bytearray(b'1.6.1\x00')
Connecting to AP starcat
Set background to  /map.bmp
No SD card found: no SD card
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 0
no update
No storms in map area.
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 0
no update
No storms in map area.
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 0
no update
No storms in map area.
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 0
no update
No storms in map area.
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 0
no update
No storms in map area.
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 0
no update
No storms in map area.
Updating...
Retrieving data...There was a RuntimeError: Failed to send 3 bytes (sent 0)
Updating...
Retrieving data...Socket missing recv_into. Using more memory to be compatible
Reply is OK!
Number of storms: 0
no update
No storms in map area.

majotito
 
Posts: 22
Joined: Tue Jun 04, 2013 8:17 pm

Re: PyPortal data retieval gets stuck

by brubell on Tue Oct 13, 2020 10:15 am

It seems requests.get is not working in Adafruit CircuitPython Requests 1.7.0 (https://github.com/adafruit/Adafruit_Ci ... /issues/41) and is being addressed. I'll update this thread when there's a fix.

For now - you can try downgrading to Adafruit CircuitPython Requests version 1.6.0

brubell
 
Posts: 1061
Joined: Fri Jul 17, 2015 10:33 pm

Re: PyPortal data retieval gets stuck

by haroldf on Tue Oct 13, 2020 4:58 pm

just my bad timing, I guess. I got my first adafruit product (pyportal titano) on 10/8... The first day experience was great -- I'm new to python on hw, and so I did basic displayio and os testing on the local file system, and checked that esp32spi_simpletest.py worked. THEN -- neither of the pyportal projects I tried (weather station, tides) worked -- resulting in 3 days banging the rocks together, making no progress.

Here are some constructive comments:
1. Considering that all the featured pyportal projects rely on fetch(), and according to the library source code, "This function does pretty much everything", it would be good if there was a version of "quotes" that actually used pyportal.fetch() instead of just setting the background BMP and doing a text-get.
2. Post a link to a resource that shows specifically where to get the older library(s), including enough identifying info to eliminate guesswork.

haroldf
 
Posts: 4
Joined: Sun Oct 11, 2020 12:20 pm

Re: PyPortal data retieval gets stuck

by majotito on Wed Oct 14, 2020 9:05 am

Hi—

Downgrading to 1.6.0 worked to resolve the error on every other request with delays of more than 4 minutes.

I have to agree with haroldf. I’m trying to learn about programming and find I need 4+ browser tabs open from a few different resources to try to get basic information about libraries and functions. And even then I still cannot find what I need to understand what is going on, what each parameter needs or returns, how it is broken, and if I can fix or modify it or find some other way to use it. I hope I am just missing some resource that ties it all together with all the details and I am having trouble finding it.

For everyone following this, I found the Adafruit CircuitPython Requests version 1.6.0 here:
https://github.com/adafruit/Adafruit_Ci ... /tag/1.6.0

majotito
 
Posts: 22
Joined: Tue Jun 04, 2013 8:17 pm

Re: PyPortal data retieval gets stuck

by haroldf on Thu Oct 15, 2020 1:37 am

thank you majotito, I found the lib where you said. For me it was not an immediate fix, and I'm going to do what I've learned -- start with a clean install... at this point, I've lost all track of versioning -- that's what frustration induces. This time, tho -- I'll use the lib you pointed to. Seriously, thank you again.

haroldf
 
Posts: 4
Joined: Sun Oct 11, 2020 12:20 pm

Re: PyPortal data retieval gets stuck

by majotito on Thu Oct 15, 2020 12:03 pm

You're welcome, haroldf.

I don't know if you do this, but, I'd suggest every time you make a few significant adjustments to your code, copy the entire contents of the CIRCUITPY to a new dated folder on your computer's hard drive. I have lost a few edits due to crashes or editing errors that I wish I had a backup of. Plus, if you ever need to repurpose the device and use it for another project or idea for a while, this lets you reload where you were last time. (I'm not sure if that's what you meant by "lost all track of versioning"?)

What errors do you get? Did you try my code from above? I <think> you should be able to copy and use that as "code.py" without having to adjust anything else. I'm using CircuitPython 5.3.1, if that matters. I haven't adjusted my code to go back to checking every 60 minutes yet, but I will when I get a few rounds of the different possible scenarios, i.e.: no storms, storms but none in map area, one storm in area, and more than 1 storm in area.

Another fun thing to do: Use this interactive map to set up how you like with colors and borders and such. Then, get a screenshot of the map area (45 to 5 latitude, -100 to -40 longitude). Make this into a 320x240 .bmp (I used fire alpaca but I'm sure other apps can do it), and rename as map.bmp and put into the CIRCUITPY drive.

https://mapmaker.nationalgeographic.org/

You can also use this to make a different or larger coverage area. I found the code works just fine if you make a map and adjust the LAT_RANGE = (45, 5) and LON_RANGE = (-100, -40) in the code to match the map coverage.

majotito
 
Posts: 22
Joined: Tue Jun 04, 2013 8:17 pm

Re: PyPortal data retieval gets stuck

by haroldf on Fri Oct 16, 2020 3:21 pm

majotito, that was all very good information. I tried your hurricane code this morning, I got errors, and they made things much clearer. Two errors showed me there was a library issue:
Code: Select all | TOGGLE FULL SIZE
  File "adafruit_display_text/label.py", line 64, in __init__
TypeError: extra keyword arguments given

and
Code: Select all | TOGGLE FULL SIZE
  File "code.py", line 75, in update_display
TypeError: unexpected keyword argument 'timeout'

Then it got interesting: I used the 6.0 library (because I forgot that you said you were using 5.3.1) and the error went away. But then, I tried to recreate the error (and confirm the issue) by reverting to 5.3.1... and there was no error. So, the issue was resolved, but I'm guessing problem was that the pyportal was shipped with old libraries -- I was surprised to find that it was shipped with
Code: Select all | TOGGLE FULL SIZE
Adafruit CircuitPython 5.0.0-beta.0 on 2019-11-19; Adafruit PyPortal Titano with samd51j20

I'll be doing a full rebuild and see if things change, and I'll update when I'm done.

Mapmaker link is definitely a good resource. I'm on the west coast, and so fires and Santa Ana winds are more relevant to me than hurricanes (more data, too.) Maybe that will be a good project -- but it will have to be back-burnered because I have a lot to learn about the pyportal code model.

haroldf
 
Posts: 4
Joined: Sun Oct 11, 2020 12:20 pm

Please be positive and constructive with your questions and comments.