Integrate debugger into controller
This commit is contained in:
parent
7d5076a9f4
commit
b048e11b04
2 changed files with 33 additions and 71 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
from distutils.log import debug
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from flask import Flask, jsonify, send_file
|
from flask import Flask, jsonify, send_file
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
@ -55,6 +56,14 @@ class SharedSerialToWeb:
|
||||||
last_state_update: datetime = None
|
last_state_update: datetime = None
|
||||||
registered_modules: dict[ModuleAddress, PuzzleState] = field(default_factory=dict)
|
registered_modules: dict[ModuleAddress, PuzzleState] = field(default_factory=dict)
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DebugShared:
|
||||||
|
messages: deque
|
||||||
|
last_message_index: int
|
||||||
|
|
||||||
|
# Keep this the same as max_messages on the client!
|
||||||
|
max_message_cache = 200
|
||||||
|
debug_shared = DebugShared(deque(maxlen=max_message_cache), -1)
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
@ -65,7 +74,7 @@ web_to_serial = SharedWebToSerial()
|
||||||
serial_to_web = SharedSerialToWeb()
|
serial_to_web = SharedSerialToWeb()
|
||||||
|
|
||||||
|
|
||||||
def parse_can_line(ser) -> Message:
|
def parse_can_line(ser, debug_shared) -> Message:
|
||||||
if not ser.in_waiting:
|
if not ser.in_waiting:
|
||||||
return None
|
return None
|
||||||
line = ser.read(12)
|
line = ser.read(12)
|
||||||
|
@ -75,11 +84,15 @@ def parse_can_line(ser) -> Message:
|
||||||
sender = (int(line[0]) << 8) + int(line[1])
|
sender = (int(line[0]) << 8) + int(line[1])
|
||||||
size = int(line[2])
|
size = int(line[2])
|
||||||
message = line[3:3+size]
|
message = line[3:3+size]
|
||||||
return Message(message, sender, datetime.now())
|
obj = Message(message, sender, datetime.now())
|
||||||
|
debug_shared.messages.append(obj)
|
||||||
|
debug_shared.last_message_index += 1
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def send_message(ser, msg) -> None:
|
def send_message(ser, msg, debug_shared) -> None:
|
||||||
|
debug_shared.messages.append(msg)
|
||||||
|
debug_shared.last_message_index += 1
|
||||||
# we send the payload padded with null-bytes, but these don't actually get sent
|
# we send the payload padded with null-bytes, but these don't actually get sent
|
||||||
packed = struct.pack('>HB8s', msg.module_address().as_binary(), len(msg.payload), msg.payload)
|
packed = struct.pack('>HB8s', msg.module_address().as_binary(), len(msg.payload), msg.payload)
|
||||||
ser.write(packed + b'\n')
|
ser.write(packed + b'\n')
|
||||||
|
@ -90,7 +103,7 @@ def calculate_puzzle_modules_left(serial_to_web) -> int:
|
||||||
def calculate_strikes(serial_to_web) -> int:
|
def calculate_strikes(serial_to_web) -> int:
|
||||||
return sum(state.strike_amount for state in serial_to_web.registered_modules.values())
|
return sum(state.strike_amount for state in serial_to_web.registered_modules.values())
|
||||||
|
|
||||||
def serial_controller(serialport, web_to_serial, serial_to_web):
|
def serial_controller(serialport, web_to_serial, serial_to_web, debug_shared):
|
||||||
with serial.Serial(serialport, 115200, timeout=0.05) as ser:
|
with serial.Serial(serialport, 115200, timeout=0.05) as ser:
|
||||||
serial_to_web.gamestate = Gamestate.INACTIVE
|
serial_to_web.gamestate = Gamestate.INACTIVE
|
||||||
# TODO send message here to get all modules to stop talking and reset
|
# TODO send message here to get all modules to stop talking and reset
|
||||||
|
@ -103,7 +116,7 @@ def serial_controller(serialport, web_to_serial, serial_to_web):
|
||||||
serial_to_web.info_round_start = datetime.now()
|
serial_to_web.info_round_start = datetime.now()
|
||||||
serial_to_web.registered_modules = {}
|
serial_to_web.registered_modules = {}
|
||||||
elif serial_to_web.gamestate == Gamestate.INFO:
|
elif serial_to_web.gamestate == Gamestate.INFO:
|
||||||
parse_can_line(ser) # throw away, TODO keep this and display it
|
parse_can_line(ser, debug_shared) # throw away, TODO keep this and display it
|
||||||
if datetime.now() - serial_to_web.info_round_start > INFO_ROUND_DURATION:
|
if datetime.now() - serial_to_web.info_round_start > INFO_ROUND_DURATION:
|
||||||
serial_to_web.gamestate = Gamestate.DISCOVER
|
serial_to_web.gamestate = Gamestate.DISCOVER
|
||||||
send_message(ser, Message.create_controller_hello())
|
send_message(ser, Message.create_controller_hello())
|
||||||
|
@ -114,7 +127,7 @@ def serial_controller(serialport, web_to_serial, serial_to_web):
|
||||||
serial_to_web.last_state_update = datetime.now()
|
serial_to_web.last_state_update = datetime.now()
|
||||||
serial_to_web.gamestate = Gamestate.GAME
|
serial_to_web.gamestate = Gamestate.GAME
|
||||||
send_message(ser, Message.create_controller_gamestart(web_to_serial.game_duration, 0, web_to_serial.max_allowed_strikes, len(serial_to_web.registered_modules)))
|
send_message(ser, Message.create_controller_gamestart(web_to_serial.game_duration, 0, web_to_serial.max_allowed_strikes, len(serial_to_web.registered_modules)))
|
||||||
msg = parse_can_line(ser)
|
msg = parse_can_line(ser, debug_shared)
|
||||||
if msg is None:
|
if msg is None:
|
||||||
continue
|
continue
|
||||||
puzzle_address = msg.get_puzzle_register()
|
puzzle_address = msg.get_puzzle_register()
|
||||||
|
@ -128,7 +141,7 @@ def serial_controller(serialport, web_to_serial, serial_to_web):
|
||||||
|
|
||||||
elif serial_to_web.gamestate == Gamestate.GAME:
|
elif serial_to_web.gamestate == Gamestate.GAME:
|
||||||
# React to puzzle strike / solve
|
# React to puzzle strike / solve
|
||||||
msg = parse_can_line(ser)
|
msg = parse_can_line(ser, debug_shared)
|
||||||
if msg is None:
|
if msg is None:
|
||||||
pass
|
pass
|
||||||
elif (strike_details := msg.get_puzzle_strike_details()):
|
elif (strike_details := msg.get_puzzle_strike_details()):
|
||||||
|
@ -206,16 +219,28 @@ def restart():
|
||||||
return 'OK'
|
return 'OK'
|
||||||
return 'Wrong gamestage'
|
return 'Wrong gamestage'
|
||||||
|
|
||||||
|
@app.route('/<last_received>/api.json')
|
||||||
|
def api(last_received):
|
||||||
|
last_received = int(last_received)
|
||||||
|
if last_received < debug_shared.last_message_index - len(debug_shared.messages):
|
||||||
|
return jsonify({"server_id": server_id, "newest_msg": debug_shared.last_message_index, "messages": list(debug_shared.messages)})
|
||||||
|
else:
|
||||||
|
return jsonify({"server_id": server_id, "newest_msg": debug_shared.last_message_index, "messages": list(debug_shared.messages)[len(debug_shared.messages) - (debug_shared.last_message_index - last_received):]})
|
||||||
|
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index():
|
def index():
|
||||||
return send_file('static/controller.html')
|
return send_file('static/controller.html')
|
||||||
|
|
||||||
|
@app.route('/debugger')
|
||||||
|
def debugger():
|
||||||
|
return send_file('static/debugger.html')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
if len(sys.argv) != 2:
|
if len(sys.argv) != 2:
|
||||||
print("Usage: python3 controller.py [serial port]")
|
print("Usage: python3 controller.py [serial port]")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
if sys.argv[1] != 'mock':
|
if sys.argv[1] != 'mock':
|
||||||
thread = Thread(target=serial_controller, args=(sys.argv[1], web_to_serial, serial_to_web))
|
thread = Thread(target=serial_controller, args=(sys.argv[1], web_to_serial, serial_to_web, debug_shared))
|
||||||
thread.start()
|
thread.start()
|
||||||
app.run(debug=False, host='0.0.0.0', port=8080)
|
app.run(debug=False, host='0.0.0.0', port=8080)
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
from threading import Thread
|
|
||||||
from flask import Flask, jsonify, send_file
|
|
||||||
from time import sleep
|
|
||||||
from dataclasses import dataclass
|
|
||||||
from datetime import datetime
|
|
||||||
import serial
|
|
||||||
import uuid
|
|
||||||
from collections import deque
|
|
||||||
import sys
|
|
||||||
from obus import Message
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
|
||||||
|
|
||||||
server_id = uuid.uuid4()
|
|
||||||
print("Server ID: ", server_id)
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class SharedData:
|
|
||||||
messages: deque
|
|
||||||
last_message_index: int
|
|
||||||
|
|
||||||
# Keep this the same as max_messages on the client!
|
|
||||||
max_message_cache = 200
|
|
||||||
shared_data = SharedData(deque(maxlen=max_message_cache), -1)
|
|
||||||
|
|
||||||
|
|
||||||
def serial_reader(serialport, shared_data):
|
|
||||||
with serial.Serial(serialport, 115200, timeout=0.05) as ser:
|
|
||||||
while True:
|
|
||||||
line = ser.read(12)
|
|
||||||
if not line:
|
|
||||||
continue
|
|
||||||
print(line)
|
|
||||||
if len(line) == 12:
|
|
||||||
if line == b'BEGIN START\n' or line[0] > 0b111:
|
|
||||||
continue
|
|
||||||
sender = (int(line[0]) << 8) + int(line[1])
|
|
||||||
size = int(line[2])
|
|
||||||
message = line[3:3+size]
|
|
||||||
received = Message(message, sender, datetime.now())
|
|
||||||
shared_data.messages.append(received.serialize())
|
|
||||||
shared_data.last_message_index += 1
|
|
||||||
print(shared_data.last_message_index)
|
|
||||||
|
|
||||||
@app.route('/')
|
|
||||||
def index():
|
|
||||||
return send_file('static/debugger.html')
|
|
||||||
|
|
||||||
@app.route('/<last_received>/api.json')
|
|
||||||
def api(last_received):
|
|
||||||
last_received = int(last_received)
|
|
||||||
if last_received < shared_data.last_message_index - len(shared_data.messages):
|
|
||||||
return jsonify({"server_id": server_id, "newest_msg": shared_data.last_message_index, "messages": list(shared_data.messages)})
|
|
||||||
else:
|
|
||||||
return jsonify({"server_id": server_id, "newest_msg": shared_data.last_message_index, "messages": list(shared_data.messages)[len(shared_data.messages) - (shared_data.last_message_index - last_received):]})
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
if len(sys.argv) != 2:
|
|
||||||
print("Usage: python3 debugserver.py [serial port]")
|
|
||||||
sys.exit()
|
|
||||||
thread = Thread(target=serial_reader, args=(sys.argv[1], shared_data, ))
|
|
||||||
thread.start()
|
|
||||||
app.run(debug=False, host='0.0.0.0')
|
|
Loading…
Reference in a new issue