Reputation: 11
so i have been building a project for connecting my esp8266 to wifi using micropython but whenever i run the script it gives this error
>>> import main
trying to load wifi credentials from ./wifi.creds
./wifi.creds does not exist
starting captive portal
Waiting for access Point To turn on
#12 ets_task(4020f510, 29, 3fff9428, 10)
AP mode Configured: ('210.210.210.1', '255.255.255.0', '210.210.210.1', '210.210.210.1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "main.py", line 5, in <module>
File "captive_portal.py", line 37, in start
File "captive_portal.py", line 93, in captive_portal
File "captive_dns.py", line 55, in __init__
TypeError: function takes 4 positional arguments but 5 were given
so the script is supposed to print dns request made from my phone once it has connected to the AP created by the esp8266 board. but it keeps printing the error message . here is my are my scripts for the project
from captive_portal import CaptivePortal
portal = CaptivePortal()
portal.start()
captive_portal.py
import network
import uerrno
import uos as os
import utime as time
import gc
import uselect as select
from captive_dns import DNSServer
class CaptivePortal():
AP_IP = "210.210.210.1"
CRED_FILE = "./wifi.creds"
MAX_CONN_ATTEMPTS = 10
def __init__(self, essid = None):
self.local_ip = self.AP_IP
self.sta_if = network.WLAN(network.STA_IF)
self.ap_if = network.WLAN(network.AP_IF)
if essid is None:
essid = "FAKEAP"
self.essid = essid
self.dns_server = None
self.poller = select.poll()
self.ssid = None
self.password = None
def start(self):
#turn off station interface to force reconnect
self.sta_if.active(False)
if not self.try_connect_from_file():
self.captive_portal()
def connect_to_wifi(self):
print(
"Trying to connect using SSID '{:s}' with password {:s}".format(
self.ssid, self.password
)
)
#initiate the connection
self.sta_if.active(True)
self.sta_if.connect(self.ssid, self.password)
attempts = 0
while attempts < self.MAX_CONN_ATTEMPTS:
if not self.sta_if.isconnected():
print("connection in progress")
time.sleep(2)
attempts += 1
else:
print("connected to {:s}".format(self.ssid))
self.local_ip = self.sta_if.ifconfig()[0]
self.write_creds(self.ssid, self.password)
return True
print("Failed to connect to {:s} with {:s}. WLAN status={:d}".format(
self.ssid, self.password, self.sta_if.status()
))
#forget the credentials since they didnt work, and turn off station mode
self.ssid = self.password = None
self.sta_if.active(False)
return False
def write_creds(self, ssid, password):
open(self.CRED_FILE, 'wb').write(b','.join([ssid, password]))
print("wrote credentials to {:s}".format(self.CRED_FILE))
def start_access_point(self):
#sometimes need to turn off AP before it comes up properly
self.ap_if.active(False)
while not self.ap_if.active():
print("Waiting for access Point To turn on")
self.ap_if.active(True)
time.sleep(4)
#setup a DNS server to redirect all connected clients Traffic
self.ap_if.ifconfig((self.local_ip, "255.255.255.0", self.local_ip, self.local_ip))
self.ap_if.config(essid=self.essid, authmode=network.AUTH_OPEN)
print("AP mode Configured:", self.ap_if.ifconfig())
def captive_portal(self):
print("starting captive portal")
self.start_access_point()
if self.dns_server is None:
self.dns_server = DNSServer(self.poller, self.local_ip)
print("DNS Server has been Configured")
try:
while True:
gc.collect()
#check for socket events and handle them
for response in self.poller.ipoll(1000):
sock, events, *others = response
self.handle_dns(sock, events, others)
except KeyboardInterrupt:
print("Captive portal stopped")
self.cleanup()
def handle_dns(self, sock, event, others):
if sock is self.dns_server.sock:
#ignore UDP sockets hangup
if events == select.POLLHUP:
return True
self.dns_server.handle(sock, event, others)
return True
return False
def cleanup(self):
print("cleaning up")
if self.dns_server:
self.dns_server.stop(self.poller)
gc.collect()
def try_connect_from_file(self):
print("trying to load wifi credentials from {:s}".format(self.CRED_FILE))
try:
os.stat(self.CRED_FILE)
except OSError as e:
if e.args[0] == uerrno.ENOENT:
print("{:s} does not exist ".format(self.CRED_FILE))
return False
contents = open(self.CRED_FILE, 'rb').read().split(b',')
if len(contents) == 2:
self.ssid, self.password = contents
else:
print("Invalid Credentials Files:", contents)
return False
if not self.connect_to_wifi():
print("conect with wifi credentials failed, Starting Captive portal")
os.remove(self.CRED_FILE)
return False
return True
captive_dns.py
import usocket as socket
import gc
from server import Server
class DNSServer(Server):
def __init__(self, poller, ip_addr):
super().__init__(poller, 53, socket.SOCK_DGRAM, "DNS Server")
self.ip_addr = ip_addr
def handle(self, sock, event, others):
# server doesn't spawn other sockets, so only respond to its own socket
if sock is not self.sock:
return
# check the DNS question, and respond with an answer
try:
data, sender = sock.recvfrom(1024)
request = DNSQuery(data)
print("Sending {:s} -> {:s}".format(request.domain, self.ip_addr))
sock.sendto(request.answer(self.ip_addr), sender)
# help MicroPython with memory management
del request
gc.collect()
except Exception as e:
print("DNS server exception:", e)
server.py
import usocket as socket
import uselect as select
class Server:
def __init__(self, poller, sock_type, name):
self.name = name
# create socket with correct type : stream (TCP) or datagrams (UDP)
self.sock = socket.socket(socket.AF_INET, sock_type)
#register to get event update for this socket
self.poller = poller
self.poller.register(self.sock, select.POLLIN)
addr = socket.getaddrinfo("0.0.0.0", port) [0] [-1]
#allow new request while sending last response
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind(addr)
print(self.name , "listening on", addr)
def stop(self, poller):
poller.unregister(self.sock)
self.sock.close()
print(self.name, "stopped")
Upvotes: 0
Views: 711
Reputation: 143098
It seems that your Server
is missing a port
parameter in the third position of __init__
(which is later used in addr = socket.getaddrinfo("0.0.0.0", port) [0] [-1]
):
class Server:
def __init__(self, poller, port, sock_type, name):
Upvotes: 1