adafruit / Adafruit_CircuitPython_ESP32SPI

ESP32 as wifi with SPI interface
MIT License
101 stars 74 forks source link

Request to local IP does not work #136

Closed Lnk2past closed 3 years ago

Lnk2past commented 3 years ago

All library versions are from the adafruit-circuitpython-bundle-6.x-mpy-20210612 bundle.


Not sure if this is the correct project to report this in.

I just set up a Feather nRF52840 Sense with an AirLift FeatherWing, and while all of the example code works (all of this works), I am having some issues trying to set up something a little more custom.

I am running into an issue sending a request to a local IP. I am running a flask server from a Raspberry Pi with a simple GET endpoint exposed. The endpoint works perfectly fine when hitting it with Postman, but when trying to hit it using adafruit_esp32spi, I receive an odd error. I tried digging into the source here as well as in adafruit_requests, but I couldn't figure anything out.

My simple flask server (ultimately running at http://127.0.0.1:5000 with the endpoint boop):

import json
from flask import Flask

app = Flask(__name__)

@app.route('/boop', methods=['GET'])
def boop():
    return json.dumps({'success':True}), 200, {'ContentType':'application/json'} 

if __name__ == '__main__':
    app.run(debug=True)

Code I am running on the Sense/Airlift:

# SPDX-FileCopyrightText: 2019 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
import board
import busio
from digitalio import DigitalInOut
import adafruit_requests as requests
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
from adafruit_esp32spi import adafruit_esp32spi

# Get wifi details and more from a secrets.py file
try:
    from secrets import secrets
except ImportError:
    print("WiFi secrets are kept in secrets.py, please add them there!")
    raise

print("ESP32 SPI webclient test")

LOCAL_URL = "http://127.0.0.1:5000/boop"

esp32_cs = DigitalInOut(board.D13)
esp32_ready = DigitalInOut(board.D11)
esp32_reset = DigitalInOut(board.D12)

spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)

socket.set_interface(esp)
requests.set_socket(socket, esp)

if esp.status == adafruit_esp32spi.WL_IDLE_STATUS:
    print("ESP32 found and in idle mode")
print("Firmware vers.", esp.firmware_version)
print("MAC addr:", [hex(i) for i in esp.MAC_address])

for ap in esp.scan_networks():
    print("\t%s\t\tRSSI: %d" % (str(ap["ssid"], "utf-8"), ap["rssi"]))

print("Connecting to AP...")
while not esp.is_connected:
    try:
        esp.connect_AP(secrets["ssid"], secrets["password"])
    except RuntimeError as e:
        print("could not connect to AP, retrying: ", e)
        continue
print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi)
print("My IP address is", esp.pretty_ip(esp.ip_address))

esp._debug = True

r = requests.get(LOCAL_URL)
print("-" * 40)
print(r.text)
print("-" * 40)
r.close()

print("Done!")

And here is the output when I run everything (networks redacted):

code.py output:
ESP32 SPI webclient test
ESP32 found and in idle mode
Firmware vers. bytearray(b'1.2.2\x00')
MAC addr: ['0x64', '0x8d', '0xb8', '0x57', '0xdd', '0xc4']
        Home          RSSI: -46
Connecting to AP...
Connected to Home     RSSI: -46
My IP address is 10.0.0.123
*** Get host by name
*** Get socket
Allocated socket #0
*** Socket connect mode 0
*** Open socket to bytearray(b'\x7f\x00\x00\x01') 5000 0
Traceback (most recent call last):
  File "code.py", line 52, in <module>
  File "adafruit_requests.py", line 684, in get
  File "adafruit_requests.py", line 562, in request
  File "adafruit_requests.py", line 454, in _get_socket
  File "adafruit_requests.py", line 448, in _get_socket
  File "adafruit_esp32spi/adafruit_esp32spi_socket.py", line 75, in connect
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 761, in socket_connect
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 663, in socket_open
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 325, in _send_command_get_response
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 308, in _wait_response_cmd
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 295, in _wait_response_cmd
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 277, in _check_data
RuntimeError: Expected 01 but got 00

Code done running.

Thanks in advance for any information, insight, or help!

FoamyGuy commented 3 years ago

127.0.0.1 is typically used as a local "loop-back" address and is only visible to the system it's running on. So if your Raspberry pi is running the flask server another software running on that same pi could successfully reach the web server at this address, but anything not running specifically on that raspberry pi would not be able to see that address you'll need to find the visible IP for the Raspberry pi and use that on the micro-controller / air-lift in order to successfully reach it.

You can try running the command ip addr on the raspberry pi and see if you can find which ip is visible to the rest of the network it tends to be something like 192.168.1.[something] in most default setups but depends entirely on the network infrastructure in use. Once you find the Pi's visible IP then you should be able to use that instead of 127.0.0.1 on the micro-controller / air-lift device to get a successful connection.

Lnk2past commented 3 years ago

Hi there, thanks for the reply!

I will give that a try when I get home, but I figured it would have been OK with 127.0.0.1 since I ran the flask server with the host set to 0.0.0.0 (I should have noted that in my original post). I am able to hit it with Postman from my PC (not the pi) (I should have noted this too lol).

I will at least try with the actual network address and will report back.

Lnk2past commented 3 years ago

I am still confused how my PC was able to hit the API at 127.0.0.1, especially since I was running my flask app incorrectly. Everything is working as expected now, thanks for getting me oriented in the right direction!