Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web Workflow: no circuitpython.local (Pico W, 9.0.1) #9124

Closed
studiostephe opened this issue Mar 31, 2024 · 10 comments
Closed

Web Workflow: no circuitpython.local (Pico W, 9.0.1) #9124

studiostephe opened this issue Mar 31, 2024 · 10 comments
Assignees
Labels
Milestone

Comments

@studiostephe
Copy link

studiostephe commented Mar 31, 2024

CircuitPython version

Adafruit CircuitPython 9.0.1 on 2024-03-27; Raspberry Pi Pico W with rp2040

Code/REPL

#code.py (provided by anecdata in the discord)
import time
import os
import wifi
import ipaddress
import socketpool
import mdns

MDNSFINDTIMEOUT = 5

ssid = os.getenv('WIFI_SSID')
password = os.getenv('WIFI_PASSWORD')

pool = socketpool.SocketPool(wifi.radio)

def connect():
    # to connect in case CP8 web workflow hasn't already, or to reconnect if disconnexted
    if not wifi.radio.connected:
        print (f"Connecting to wifi AP... ", end="")
        wifi.radio.connect(ssid, password)
        print (f"{wifi.radio.ipv4_address}")

print(f"Starting mDNS server...\n")
m = mdns.Server(wifi.radio)

while True:
    connect()
    print(f"Finding mDNS hosts from {wifi.radio.ipv4_address}...\n")

    try:
        host = "circuitpython.local"
        print(f"{host}")
        # ESP mDNS TTL seems to be 2 minutes
        # no difference in result with wrong port
        print(f"{ipaddress.ip_address(pool.getaddrinfo(host, 80)[0][4][0])}")
        print()
    except OSError as e:
        print(f"OSError: {e}")

    for service in m.find(service_type="_circuitpython", protocol="_tcp", timeout=MDNSFINDTIMEOUT):
        print(f"{service.service_type} {service.protocol}")
        print(f"{service.instance_name}")
        localname = ".".join((service.hostname, "local"))
        print(f"{localname}:{service.port}")
        print(f"{service.ipv4_address}:{service.port}")
        print()
    time.sleep(10)


#and my settings.toml file contains:
CIRCUITPY_WIFI_SSID = "MyNetwork"
CIRCUITPY_WIFI_PASSWORD = "mypassword"
CIRCUITPY_WEB_API_PASSWORD= "jk"

Behavior

code.py output:
Starting mDNS server...

Finding mDNS hosts from 10.0.1.55...

circuitpython.local
socket_resolve_host() returned -2
OSError: (-2, 'Name or service not known')

Description

The Pico W joins the network without issue, and can be accessed via IP or individual hostname (cpy-xxxxxx.local), but not via circuitpython.local

Access via circuitpython.local is important for when the device's REPL is not physically accessible via USB (device installed somewhere deep), and the IP is not known or knowable in advance (not my network)

Additional information

No response

@anecdata
Copy link
Member

I've seen similar behavior on raspberrypi. Often, the browser tries to load but does not return with the page. The mdns server shows up in mdns.Server .find (done from a separate espressif device), but loading in a browser is problematic. In rare cases it will load in the browser (though I haven't been able to do that today), but in many of those the web workflow page will come up with all fields empty. Even accessing web workflow using the IP address sometimes shows similar behaviors, but it will succeed more often.

@tannewt tannewt added network rp2040 Raspberry Pi RP2040 labels Apr 1, 2024
@tannewt tannewt added this to the 9.x.x milestone Apr 1, 2024
@tannewt
Copy link
Member

tannewt commented Apr 1, 2024

I think this is because you are initializing the mdns.Server yourself. Right now, circuitpython.local is only added if the workflow starts the server: https://github.com/adafruit/circuitpython/blob/main/ports/raspberrypi/common-hal/mdns/Server.c#L70-L76

@anecdata
Copy link
Member

anecdata commented Apr 1, 2024

CIRCUITPY_WEB_API_PASSWORD= "jk"

I think this is the web workflow case. My understanding is that mdns.Server(wifi.radio) in code accesses what's essentially the web workflow mdns.Server Singleton?

(Running the code above I don't think will show its own device, but running on a separate device should catch any MDNS _circuitpython._tcp.)

Maybe @studiostephe can chime in on their original observations from Discord. From my own observations, it can be difficult to connect to raspberrypi web workflow via circuitpython.local even if it does show up in an MDNS scan.

@anecdata
Copy link
Member

anecdata commented Apr 1, 2024

For example, I just set up a Pico W with no code.py, but web workflow and auto-connect set up in settings.toml. I've turned off web workflow on all other devices.
Adafruit CircuitPython 9.1.0-beta.0 on 2024-03-28; Raspberry Pi Pico W with rp2040

A separate MDNS scanner shows the Pico W:

  • ipaddress.ip_address(pool.getaddrinfo(circuitpython.local, 80)[0][4][0]) gives the proper IP address.
  • .find(service_type="_circuitpython", protocol="_tcp") gives the .hostname as the cpy-xxxxxx name.

Loading http://circuitpython.local in the browser never(?) returns.

Loading http://192.168.6.198 (or http://cpy-xxxxxx.local) often returns after some wait with:
Screenshot 2024-04-01 at 2 57 36 PM
Repeated reloads of the browser tab give the same thing. Sometimes after 30-60 seconds, the page will load properly, after an initial load or reload of the page.

espressif boards are much more consistent in their MDNS / web workflow behavior.

@studiostephe
Copy link
Author

My observations match anecdata's above: a blank code.py, Web Workflow has started because its accessible via cpy-xxxxxx, but circuitpython.local never loads

@tannewt
Copy link
Member

tannewt commented Apr 2, 2024

It is totally possible that MDNS on pico w isn't as reliable as ESP.

What OS are you running and what browser? (To know what is doing the mdns lookup for the browser.)

@studiostephe
Copy link
Author

This is Safari on MacOS

@anecdata
Copy link
Member

anecdata commented Apr 2, 2024

To remove the browser from the equation:
curl (macOS 14.4.1)...

Running web workflow on:
Adafruit CircuitPython 9.1.0-beta.0 on 2024-03-28; Raspberry Pi Pico W with rp2040

% curl -iL --compressed "http://192.168.6.198"
returns immediately:

HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Length: 644
Content-Type: text/html
# etc...

% curl -iL --compressed "http://cpy-redact.local"
returns after about 5 seconds:

HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Length: 644
Content-Type: text/html
# etc...

% curl -iL --compressed "http://circuitpython.local"
returns after about 5 seconds or so:

curl: (6) Could not resolve host: circuitpython.local

A separate ESP32-S3 scanning MDNS in CircuitPython (code above) continually shows:

circuitpython.local
192.168.6.198

_circuitpython _tcp
Raspberry Pi Pico W
cpy-redact.local:80
192.168.6.198:80

For comparison, later (to get past the 2-minute? MDNS cache) running web workflow on:
Adafruit CircuitPython 9.1.0-beta.0 on 2024-03-28; Adafruit QT Py ESP32-S3 4MB Flash 2MB PSRAM with ESP32S3
gives:

%  curl -iL --compressed "http://circuitpython.local"
HTTP/1.1 307 Temporary Redirect
Connection: close
Content-Length: 0
Location: http://cpy-yyyyyy.local/. # this is the ESP32-S3 responding
Access-Control-Allow-Credentials: true
Vary: Origin, Accept, Upgrade
Access-Control-Allow-Origin: *

HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Length: 644
Content-Type: text/html
# etc...

(the redirect comes after a couple of seconds, the final page comes after a couple more seconds)

@anecdata
Copy link
Member

anecdata commented Apr 3, 2024

(Some previous observations on MDNS / raspberrypi here.)

@eightycc
Copy link
Collaborator

@anecdata I've retested with Adafruit CircuitPython 9.2.5 on 2025-03-19; Raspberry Pi Pico W with rp2040.

With an empty code.py and a settings.toml:

CIRCUITPY_WIFI_SSID = "xxxxxxxxxx"
CIRCUITPY_WIFI_PASSWORD = "xxxxxxxxxx"
CIRCUITPY_WEB_API_PASSWORD= "jk"

I can access the web workflow through my browser (Firefox on Debian Bookworm) using either http://192.168.1.250 or http://circuitpython.local with no discernible delay.

curl -iL --compressed "http://circuitpython.local" promptly returns:

↪ curl -iL --compressed "http://circuitpython.local"
HTTP/1.1 307 Temporary Redirect
Connection: close
Content-Length: 0
Location: http://cpy-00d3a5.local/
Access-Control-Allow-Credentials: true
Vary: Origin, Accept, Upgrade
Access-Control-Allow-Origin: *

HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Length: 644
Content-Type: text/html

<!doctypehtml><title>CircuitPython</title><meta charset=UTF-8><meta content=width=device-width,initial-scale=1 name=viewport><link href=/style
(snip)

It appears that #10027 has resolved this issue. Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants