update WebSocket server
This commit is contained in:
		
							
								
								
									
										150
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										150
									
								
								main.py
									
									
									
									
									
								
							@@ -2,149 +2,131 @@ import _thread
 | 
				
			|||||||
import ubinascii
 | 
					import ubinascii
 | 
				
			||||||
import uwebsockets
 | 
					import uwebsockets
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# WebSocket connection
 | 
					# Extract a unique name for the robot from the device MAC address
 | 
				
			||||||
conn = None
 | 
					mac = ubinascii.hexlify(wlan.config("mac")[-3:]).decode("ascii")
 | 
				
			||||||
# blockly highlihgt WebSocket connection
 | 
					 | 
				
			||||||
conn_highlight = None
 | 
					 | 
				
			||||||
# to remember WiFi disconnects
 | 
					 | 
				
			||||||
has_wifi_connection = False
 | 
					 | 
				
			||||||
# extract a unique name for the robot from the device MAC address
 | 
					 | 
				
			||||||
name = "sumo-%s" % ubinascii.hexlify(wlan.config("mac")[-3:]).decode("ascii")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# remote server
 | 
					# Remote server
 | 
				
			||||||
url = "ws://iot.koodur.com:80/p2p/" + name + "/browser/"
 | 
					url = "ws://ws.achex.ca:4010"
 | 
				
			||||||
url_highlight = "ws://iot.koodur.com:80/p2p/" + name + "-highlight/browser/"
 | 
					# Local server
 | 
				
			||||||
 | 
					 | 
				
			||||||
# local server
 | 
					 | 
				
			||||||
#url = "ws://10.42.0.1:80/p2p/" + name + "/browser/"
 | 
					#url = "ws://10.42.0.1:80/p2p/" + name + "/browser/"
 | 
				
			||||||
#url_highlight = "ws://10.42.0.1:80/p2p/" + name + "-highlight/browser/"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# code to execute
 | 
					# Code to execute
 | 
				
			||||||
ast = ""
 | 
					ast = ""
 | 
				
			||||||
# scope, info to be sent to the client
 | 
					# Scope, info to be sent to the client
 | 
				
			||||||
scope = dict()
 | 
					scope = dict()
 | 
				
			||||||
# SumoRobot object
 | 
					 | 
				
			||||||
sumorobot = None
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
def step():
 | 
					def step():
 | 
				
			||||||
    global scope
 | 
					    global scope
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while True:
 | 
					    while True:
 | 
				
			||||||
        # execute to see LED feedback for sensors
 | 
					        # Execute to see LED feedback for sensors
 | 
				
			||||||
        sumorobot.is_opponent()
 | 
					        sumorobot.is_opponent()
 | 
				
			||||||
        sumorobot.is_line(LEFT)
 | 
					        sumorobot.is_line(LEFT)
 | 
				
			||||||
        sumorobot.is_line(RIGHT)
 | 
					        sumorobot.is_line(RIGHT)
 | 
				
			||||||
        # update scope
 | 
					        # Update scope
 | 
				
			||||||
        scope = dict(
 | 
					        scope = dict(
 | 
				
			||||||
 | 
					            to = "browser-%s@00000514" % mac,
 | 
				
			||||||
            line_left = sumorobot.get_line(LEFT),
 | 
					            line_left = sumorobot.get_line(LEFT),
 | 
				
			||||||
            line_right = sumorobot.get_line(RIGHT),
 | 
					            line_right = sumorobot.get_line(RIGHT),
 | 
				
			||||||
            opponent = sumorobot.get_opponent_distance(),
 | 
					            opponent = sumorobot.get_opponent_distance(),
 | 
				
			||||||
            battery_voltage = sumorobot.get_battery_voltage(),
 | 
					            battery_voltage = sumorobot.get_battery_voltage(),
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        # execute code
 | 
					        # Execute code
 | 
				
			||||||
        exec(ast)
 | 
					        exec(ast)
 | 
				
			||||||
        # when robot was stopped
 | 
					        # When robot was stopped
 | 
				
			||||||
        if sumorobot.terminate:
 | 
					        if sumorobot.terminate:
 | 
				
			||||||
            # disable forceful termination of delays in code
 | 
					            # Disable forceful termination of delays in code
 | 
				
			||||||
            sumorobot.terminate = False
 | 
					            sumorobot.terminate = False
 | 
				
			||||||
            # stop the robot
 | 
					            # Stop the robot
 | 
				
			||||||
            sumorobot.move(STOP)
 | 
					            sumorobot.move(STOP)
 | 
				
			||||||
        # leave time to process WebSocket commands
 | 
					        # Leave time to process WebSocket commands
 | 
				
			||||||
        sleep_ms(50)
 | 
					        sleep_ms(50)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def ws_handler():
 | 
					def ws_handler():
 | 
				
			||||||
    global ast
 | 
					    global ast
 | 
				
			||||||
    global conn
 | 
					 | 
				
			||||||
    global has_wifi_connection
 | 
					    global has_wifi_connection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while True:
 | 
					    while True:
 | 
				
			||||||
        # when WiFi is connected
 | 
					        # When WiFi has just been reconnected
 | 
				
			||||||
        if wlan.isconnected():
 | 
					        if wlan.isconnected() and not has_wifi_connection:
 | 
				
			||||||
            # when WiFi has just been reconnected
 | 
					            #conn = uwebsockets.connect(url)
 | 
				
			||||||
            if not has_wifi_connection:
 | 
					            sumorobot.set_led(STATUS, True)
 | 
				
			||||||
                conn = uwebsockets.connect(url)
 | 
					            has_wifi_connection = True
 | 
				
			||||||
                sumorobot.set_led(STATUS, True)
 | 
					        # When WiFi has just been disconnected
 | 
				
			||||||
                has_wifi_connection = True
 | 
					        elif not wlan.isconnected() and has_wifi_connection:
 | 
				
			||||||
        else: # when WiFi is not connected
 | 
					            sumorobot.set_led(STATUS, False)
 | 
				
			||||||
            # when WiFi has just been disconnected
 | 
					            has_wifi_connection = False
 | 
				
			||||||
            if has_wifi_connection:
 | 
					        elif not wlan.isconnected():
 | 
				
			||||||
                sumorobot.set_led(STATUS, False)
 | 
					            # Continue to wait for a WiFi connection
 | 
				
			||||||
                has_wifi_connection = False
 | 
					 | 
				
			||||||
            # continue to wait for a WiFi connection
 | 
					 | 
				
			||||||
            continue
 | 
					            continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try: # try to read from the WebSocket
 | 
					        try: # Try to read from the WebSocket
 | 
				
			||||||
            fin, opcode, data = conn.read_frame()
 | 
					            data = conn.recv()
 | 
				
			||||||
        except: # socket timeout, no data received
 | 
					        except: # Socket timeout, no data received
 | 
				
			||||||
            # continue to reconnect to WiFi
 | 
					            # Continue to try to read data
 | 
				
			||||||
            continue
 | 
					            continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if data == b"forward":
 | 
					        # When an empty frame was received
 | 
				
			||||||
            #print("Going forward")
 | 
					        if not data:
 | 
				
			||||||
 | 
					            # Continue to receive data
 | 
				
			||||||
 | 
					            continue
 | 
				
			||||||
 | 
					        elif b'forward' in data:
 | 
				
			||||||
            ast = ""
 | 
					            ast = ""
 | 
				
			||||||
            sumorobot.move(FORWARD)
 | 
					            sumorobot.move(FORWARD)
 | 
				
			||||||
        elif data == b"backward":
 | 
					        elif b'backward' in data:
 | 
				
			||||||
            #print("Going backward")
 | 
					 | 
				
			||||||
            ast = ""
 | 
					            ast = ""
 | 
				
			||||||
            sumorobot.move(BACKWARD)
 | 
					            sumorobot.move(BACKWARD)
 | 
				
			||||||
        elif data == b"right":
 | 
					        elif b'right' in data:
 | 
				
			||||||
            #print("Going right")
 | 
					 | 
				
			||||||
            ast = ""
 | 
					            ast = ""
 | 
				
			||||||
            sumorobot.move(RIGHT)
 | 
					            sumorobot.move(RIGHT)
 | 
				
			||||||
        elif data == b"left":
 | 
					        elif b'left' in data:
 | 
				
			||||||
            #print("Going left")
 | 
					 | 
				
			||||||
            ast = ""
 | 
					            ast = ""
 | 
				
			||||||
            sumorobot.move(LEFT)
 | 
					            sumorobot.move(LEFT)
 | 
				
			||||||
        elif data == b"kick":
 | 
					        elif b'ping' in data:
 | 
				
			||||||
            conn.send(repr(scope))
 | 
					            conn.send(repr(scope).replace("'", '"'))
 | 
				
			||||||
        elif data == b"ping":
 | 
					        elif b'code' in data:
 | 
				
			||||||
            conn.send(repr(scope))
 | 
					            data = ujson.loads(data)
 | 
				
			||||||
        elif data.startswith("start:"):
 | 
					            data['val'] = data['val'].replace(";;", "\n")
 | 
				
			||||||
            #print("Got code:", data[6:])
 | 
					            print("code:", data['val'])
 | 
				
			||||||
            ast = compile(data[6:], "snippet", "exec")
 | 
					            ast = compile(data['val'], "snippet", "exec")
 | 
				
			||||||
        elif data == b"stop":
 | 
					        elif b'stop' in data:
 | 
				
			||||||
            ast = ""
 | 
					            ast = ""
 | 
				
			||||||
            sumorobot.move(STOP)
 | 
					            sumorobot.move(STOP)
 | 
				
			||||||
            # for terminating delays in code
 | 
					            # for terminating delays in code
 | 
				
			||||||
            sumorobot.terminate = True
 | 
					            sumorobot.terminate = True
 | 
				
			||||||
            #print("Got stop")
 | 
					        elif b'calibrate_line' in data:
 | 
				
			||||||
        elif data == b"calibrate_line":
 | 
					 | 
				
			||||||
            sumorobot.calibrate_line()
 | 
					            sumorobot.calibrate_line()
 | 
				
			||||||
            #print("Got calibrate")
 | 
					        elif b'Gone' in data:
 | 
				
			||||||
        elif b"Gone" in data:
 | 
					            print("server said 410 Gone, attempting to reconnect...")
 | 
				
			||||||
            #print("Server said 410 Gone, attempting to reconnect...")
 | 
					            #conn = uwebsockets.connect(url)
 | 
				
			||||||
            conn = uwebsockets.connect(url)
 | 
					 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            pass
 | 
					            print("unknown cmd:", data)
 | 
				
			||||||
            #print("unknown command:", data)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# wait for WiFi to get connected
 | 
					# Wait for WiFi to get connected
 | 
				
			||||||
while not wlan.isconnected():
 | 
					while not wlan.isconnected():
 | 
				
			||||||
    sleep_ms(100)
 | 
					    sleep_ms(100)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# connect to the websocket
 | 
					# Connect to the websocket
 | 
				
			||||||
#print("Connecting to:", url)
 | 
					 | 
				
			||||||
conn = uwebsockets.connect(url)
 | 
					conn = uwebsockets.connect(url)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# set X seconds timeout for socket reads
 | 
					# Set X seconds timeout for socket reads
 | 
				
			||||||
conn.settimeout(1)
 | 
					conn.settimeout(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# send a ping to the robot
 | 
					# Send a ping to the robot
 | 
				
			||||||
#print("Sending ping")
 | 
					conn.send('{"setID": "sumo-%s@00000514", "passwd": "salakala"}' % mac)
 | 
				
			||||||
conn.send("{'ping': true}")
 | 
					# Receive session and auth ok frames
 | 
				
			||||||
conn.send("{'ip': '" + wlan.ifconfig()[0] + "'}")
 | 
					conn.recv()
 | 
				
			||||||
 | 
					conn.recv()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# connect to the blockly highlight websocket
 | 
					# Stop bootup blinking
 | 
				
			||||||
conn_highlight = uwebsockets.connect(url_highlight)
 | 
					timer.deinit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# initialize SumoRobot object
 | 
					# WiFi is connected
 | 
				
			||||||
sumorobot = Sumorobot(conn_highlight.send)
 | 
					has_wifi_connection = True
 | 
				
			||||||
 | 
					# Indicate that the WebSocket is connected
 | 
				
			||||||
# indicate that the WebSocket is connected
 | 
					 | 
				
			||||||
sumorobot.set_led(STATUS, True)
 | 
					sumorobot.set_led(STATUS, True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#print("Starting WebSocket and code loop")
 | 
					# Start the code processing thread
 | 
				
			||||||
# start the code processing thread
 | 
					 | 
				
			||||||
_thread.start_new_thread(step, ())
 | 
					_thread.start_new_thread(step, ())
 | 
				
			||||||
# start the Websocket processing thread
 | 
					# Start the Websocket processing thread
 | 
				
			||||||
_thread.start_new_thread(ws_handler, ())
 | 
					_thread.start_new_thread(ws_handler, ())
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user