my python server is reachable from a browser but not from a pi pico client... this is my python server: server.py:
from http.server import BaseHTTPRequestHandler, HTTPServer
import time
import httphandler
import itemtype
HOST = "localhost"
PORT = 60001
class AirServer (httphandler.HttpHandler):
AIR_TIME = 10 #* 60
AIR_EARLY_START_HOUR = 9
AIR_EARLY_END_HOUR = 16
AIR_LATE_START_HOUR = 17 #19
AIR_LATE_END_HOUR = 22
MAX_HUMIDITY = 60
request = None
def delegate(self, command, params):
if command.startswith("q"):
command = "query"
for param in params:
if param.startswith("j"):
self.logJson = True
elif param.startswith("v"):
self.logVerbose = True
elif param.startswith("a"):
self.logAlertsOnly = True
self.logStart(refresh=(command=="query" and "r" in params))
if command != "query":
if command.startswith("i"):
command = "item"
elif command.startswith("s"):
command = "suppressalerts"
else:
self.logAlert("Unknown command: {}".format(command))
return
self.logCommand("Request: {}".format(self.path))
if command == "query":
self.delegateQuery(params)
if command == "suppressalerts":
self.delegateSuppressAlerts(params)
elif command == "item":
self.delegateItem(params)
self.logFinish()
def delegateQuery(self, params):
for param in params:
if param.startswith("j"):
self.logJson = True
elif param.startswith("v"):
self.logVerbose = True
elif param.startswith("a"):
self.logAlertsOnly = True
for id in AirServer.items.keys():
item = AirServer.items.get(id)
self.logHighlight(str(item))
self.checkItem(item)
if self.logVerbose:
self.logSize = "small"
for sample in item.samples:
self.log("\t{}".format(str(sample)))
self.logSize = "medium"
"""if not self.logJson:
for id in AirServer.items.keys():
item = AirServer.items.get(id)
self.logSize = "small"
self.logLink("{}:{}/s/{}".format(AirServer.hostname, AirServer.port, id), "Suppress alerts for {}".format(id))
self.logSize = "medium"
for s in ("frueh", "spaet"):
self.logSize = "small"
self.logLink("{}:{}/s/{}".format(AirServer.hostname, AirServer.port, s), "Suppress alerts for {}".format(s))
self.logSize = "medium"""
def delegateSuppressAlerts(self, params):
serverItem = AirServer.items.get("server")
suppress = serverItem.getCurrent("suppress")
if suppress is None:
suppress = ""
l = suppress.split("~")
if params:
l.extend(params)
l_ = []
for s in l:
if len(s) > 0:
l_.append(s)
if l_:
serverItem.addSample(["suppress", "~".join(l_)])
def checkItem(self, item):
if str(item.getCurrent("air")) == "1":
# early air
# late air
# max air time
openTimes = []
t = None
lastOpen = "0"
for sample in item.samples:
if sample.getCurrent("open") != lastOpen:
lastOpen = sample.getCurrent("open")
if lastOpen == "1":
t = sample.time
elif lastOpen == "0":
openTimes.append((t, sample.time - t))
if lastOpen == "1":
dt = time.time() - t
if dt > self.AIR_TIME:
self.logAlert("{} {} offen fuer {}, muss geschlossen werden!".format(itemtype.fmtT(t), item.id, itemtype.fmtRT(dt), item.id))
openTimes.append((t, dt))
foundEarly = False
foundLate = False
for openTime in openTimes:
if openTime[1] >= AirServer.AIR_TIME:
self.logHighlight("\t{} Lueftung fuer {}".format(itemtype.fmtT(openTime[0]), itemtype.fmtRT(openTime[1])))
hour = time.localtime(openTime[0]).tm_hour
if hour >= self.AIR_EARLY_START_HOUR and hour < self.AIR_EARLY_END_HOUR:
foundEarly = True
if hour >= self.AIR_LATE_START_HOUR and hour < self.AIR_LATE_END_HOUR:
foundLate = True
else:
self.log("\t{} offen fuer {}".format(itemtype.fmtT(openTime[0]), itemtype.fmtRT(openTime[1])))
hour = time.localtime().tm_hour
if lastOpen != "1":
if not foundEarly and hour >= self.AIR_EARLY_START_HOUR and hour < self.AIR_EARLY_END_HOUR:
self.logAlert("{} {} Noch keine fruehe Lueftung!".format(itemtype.fmtNow(), item.id))
if not foundLate and hour >= self.AIR_LATE_START_HOUR and hour < self.AIR_LATE_END_HOUR:
self.logAlert("{} {} Noch keine spaete Lueftung!".format(itemtype.fmtNow(), item.id))
humidity = item.getCurrent("humidity")
if humidity is not None:
humidity = int(humidity)
if humidity > self.MAX_HUMIDITY:
self.logAlert("{} {} Zu hohe Luftfeuchtigkeit, {}%!".format(itemtype.fmtNow(), item.id, humidity))
def delegateItem(self, params):
def usage():
self.logAlert("Syntax error, usage: /item/id/key1/value1/key2/value2/...")
if len(params) < 1:
usage()
return
id = str(params[0])
pairs = params[1:]
if len(pairs) % 2 != 0:
usage()
return
item = AirServer.items.get(id)
if item.addSample(pairs):
self.log(str(item))
else:
self.logAlert("Malformed sample")
if __name__ == "__main__":
AirServer.start_(AirServer, hostname=HOST, port=PORT)
using this http handler: httphandler.py:
from http.server import BaseHTTPRequestHandler, HTTPServer
import itemtype
class HttpHandler (BaseHTTPRequestHandler):
items = None
DEFAULT_LOG_COLOR = "#bbb"
ALERT_LOG_COLOR = "#f88"
REFRESH_RATE = 2 #10
logJson = None
logVerbose = None
logAlertsOnly = None
logColor = None
logSize = None
logAlerts = None
def header(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
def do_HEAD(self):
self.header()
def do_GET(self):
print("do_GET(): ")
self.header()
self.logInit()
self.parse(self.path)
def do_POST(self):
print("do_POST(): ")
self.header()
self.logInit()
self.parse(self.path)
def parse(self, path):
parts = path.split("/")
if len(parts) < 2:
return
command = parts[1]
params = parts[2:]
self.delegate(command, params)
def delegate(self, command, params):
pass
def logInit(self):
self.logJson = False
self.logVerbose = False
self.logAlertsOnly = False
self.logColor = self.DEFAULT_LOG_COLOR
self.logSize = "medium"
self.logAlerts = []
def logStart(self, refresh=False):
if self.logJson:
self.wfile.write(bytes("[\n", "utf-8"))
else:
if refresh:
self.wfile.write(bytes("<html>\n<head><title>AirServer</title><meta http-equiv=\"refresh\" content=\"{}\"></head>\n".format(self.REFRESH_RATE), "utf-8"))
else:
self.wfile.write(bytes("<html>\n<head><title>AirServer</title></head>\n", "utf-8"))
self.wfile.write(bytes("<body style=\"font-family:'Lucida Console','Courier New',monospace;font-size:{};background-color:#234;color:{};\">\n".format(self.logSize, self.logColor), "utf-8"))
def log(self, s):
if self.logAlertsOnly and self.logColor != self.ALERT_LOG_COLOR:
return
if self.logJson:
self.wfile.write(bytes("\t\"{}\",\n".format(s), "utf-8"))
else:
s = s.replace("\n", "<br/>\n").replace("\t", " ")
self.wfile.write(bytes("<div style=\"font-size:{};color:{};\">{}</div>\n".format(self.logSize, self.logColor, s), "utf-8"))
def logAlert(self, s):
suppress = HttpHandler.items.get("server").getCurrent("suppress")
if suppress is not None:
suppress = suppress.split("~")
for token in suppress:
if token.lower() in s.lower():
return
self.logColor = self.ALERT_LOG_COLOR
self.logAlerts.append(s)
self.log(s)
self.logColor = self.DEFAULT_LOG_COLOR
def logHighlight(self, s):
self.logColor = "#fff"
self.log(s)
self.logColor = self.DEFAULT_LOG_COLOR
def logCommand(self, s):
self.logColor = "#8f8"
self.log(s)
self.logColor = self.DEFAULT_LOG_COLOR
def logLink(self, link, text):
self.log("<a href=\"{}\" style=\"color:#484\">{}</a>".format(link, text))
def logFinish(self):
if self.logJson:
self.wfile.write(bytes("\t\"terminated\"\n]\n", "utf-8"))
else:
self.logCommand("Terminated")
self.wfile.write(bytes("</body>\n</html>\n", "utf-8"))
@staticmethod
def start(ServerClass, hostname="localhost", port=60001):
print("Start server...")
server = HTTPServer((hostname, port), ServerClass)
HttpServer.hostname = hostname
HttpServer.port = port
print("Server started http://%s:%s" % (hostname, port))
try:
server.serve_forever()
except KeyboardInterrupt:
pass
server.server_close()
print("Server stopped")
@staticmethod
def start_(ServerClass, hostname="localhost", port=60001):
with HTTPServer((hostname, port), ServerClass) as server:
print("Server started http://%s:%s" % (hostname, port))
server.serve_forever()
if HttpHandler.items is None:
print("Init data...")
HttpHandler.items = itemtype.Items()
serverItem = HttpHandler.items.get("server")
serverItem.addSample(["type", "server", "event", "start"])
this is my pi pico client:
import utime
import urequests
from led import Led
from wlan import Wlan
SSID = "M7"
PASSWORD = "blah"
HOST = "127.0.0.1"
PORT = 60001
led = Led("LED", value=0)
wlan = Wlan(SSID, PASSWORD)
wlan.connect()
if wlan.isConnected():
led.on()
print("connected")
u = "http://{}:{}".format(HOST, PORT)
print(u)
r = urequests.get(url=u)
print(r.text)
wlan.disconnect()
led.off()
print("disconnected")
wlan.py:
import network
import utime
class Wlan (object):
NUM_CHECK_FOR_CONNECT= 64
CHECK_CONNECT_DELAY = 0.2
CHECK_DISCONNECT_DELAY = CHECK_CONNECT_DELAY
ssid = None
password = None
country = None
wlan = None
def __init__(self, ssid, password, country="DE"):
self.ssid = ssid
self.password = password
self.country = country
def isConnected(self):
return not (not self.wlan.isconnected() and self.wlan.status() >= 0) #todo
def isDisconnected(self):
return not self.wlan.isconnected()
def connect(self):
self.wlan = network.WLAN(network.STA_IF)
self.wlan.active(True)
self.wlan.connect(self.ssid, self.password)
for i in range(self.NUM_CHECK_FOR_CONNECT):
if self.isConnected():
break
utime.sleep(self.CHECK_CONNECT_DELAY)
return self.isConnected()
def disconnect(self):
self.wlan.disconnect()
while not self.isDisconnected():
utime.sleep(self.CHECK_DISCONNECT_DELAY)
return True
if __name__ == "__main__":
import machine
led = machine.Pin("LED")
led.off()
wlan = Wlan("M7", "blah")
print("connect...")
wlan.connect()
if wlan.isConnected():
led.on()
print("connected")
wlan.disconnect()
led.off()
print("disconnected")
else:
print("failure")
i tried to reach the server via a browser and got a response. when i try to reach it via the pi pico i get
Traceback (most recent call last):
File "<stdin>", line 23, in <module>
File "urequests.py", line 180, in get
File "urequests.py", line 91, in request
OSError: [Errno 113] EHOSTUNREACH
the connection to wlan does work. i also tried it with firewall off...
Change HOST = "localhost"
to HOST = "0.0.0.0"
in server.py - it should make the server available in the home network, whereas HOST = "localhost"
only makes it available on the same machine. Then get the server's ip in the network (on Linux it can be done with ip addr
or any other similar command). Try using this ip as HOST
in the client code
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.