import json from http.server import BaseHTTPRequestHandler, HTTPServer import threading import requests import io import asyncore jsonserver_hostname = "localhost" jsonserver_port = 8800 #refserver_hostname = "192.168.68.150" #refserver_port = 26700 refserver_hostname = "192.168.190.78" refserver_port = 4001 vMixAPI_address = 'http://localhost:8088/API/' vMixAPI_TimerInputID = 'TIMER' vMixAPI_TimerTextField = 'Clock .Text' vMixAPI_Timer24InputID = 'TIMER' vMixAPI_Timer24TextField = 'Title Text.Text' vMixAPI_ColorPlace = '#C7A2E399' vMixAPI_ColorNone = "#00000000" game_filename = 'game.json' homeplayers_filename = 'homeplayers.json' guestplayers_filename = 'guestplayers.json' Game = { 'type': '', 'home_name': '', 'guest_name': '' } GameHandFutsal = { 'timer': '', 'home_fouls': '', 'guest_fouls': '', 'home_points': '', 'guest_points': '', 'period': '', 'home_penalties': '', 'guest_penalties': '', 'home_timeouts': '', 'guest_timeouts': '', 'horn': '', 'timer_status': '', 'home_penalty1_player': '', 'home_penalty2_player': '', 'home_penalty3_player': '', 'home_penalty1_timer': '', 'home_penalty2_timer': '', 'home_penalty3_timer': '', 'guest_penalty1_player': '', 'guest_penalty2_player': '', 'guest_penalty3_player': '', 'guest_penalty1_timer': '', 'guest_penalty2_timer': '', 'guest_penalty3_timer': '' } GameBasketball = { 'ball_pos':'', 'timer':'', 'home_points':'', 'guest_points':'', 'period':'', 'home_fouls':'', 'guest_fouls':'', 'home_timeouts':'', 'guest_timeouts':'', 'horn':'', 'timer_status':'', 'timeout_timer':'', 'timer24':'', 'horn24':'', 'timer24_status':'', 'timer24_display':'', } HomePlayers = [{ 'number': '', 'name': '', 'points': '', 'fouls': '' } for i in range(0, 16)] GuestPlayers = [{ 'number': '', 'name': '', 'points': '', 'fouls': '' } for i in range(0, 16)] def TimerSet(time): #requests.get('{api_address}?Function=SetText&Input={input}&SelectedName={field}&Value={value}'.format(api_address=vMixAPI_address, input=vMixAPI_TimerInputID, field=vMixAPI_TimerTextField, value=time)) pass def Timer24Set(time): #requests.get('{api_address}?Function=SetText&Input={input}&SelectedName={field}&Value={value}'.format(api_address=vMixAPI_address, input=vMixAPI_TimerInputID, field=vMixAPI_TimerTextField, value=time)) pass def dc(v): if isinstance(v, int): return bytes([v]).decode() else: return bytes(v).decode() def pn_ball_pos(v): return 'home' if v == 0x31 else ('guset' if v == 0x32 else '') def pn_timer(v): return dc(v[0:2]) + ':' + dc(v[2:4]) def pn_points(v): return dc(v.strip()) def pn_period(v): return dc(v) if v != 0x30 else 'O' def pn_teamfouls(v): return dc(v) if v != 0x52 else 'red' def pn_timeouts(v): return dc(v) def pn_horn(v): return 1 if v == 0x31 else 0 def pn_startstop(v): return 1 if v == 0x30 else 0 def pn_timertimeout(v): return dc(v[0]) + ':' + dc(v[1:3]) def pn_timer24(v): return dc(v) if 0x30 <= v[1] and v[1] <= 0x39 else dc(v[0]) + '.' + dc(v[1] - 0x10) def pn_display24(v): return 1 if v != 0x30 else 0 def pn_playernumber(v): return dc(v) def pn_playerfouls(v): return dc(v) def pn_penalties(v): return dc(v) def pn_name(v): return v.decode('utf-16') def parce(pkg): global GameHandFutsal, GameBasketball, HomePlayers, GuestPlayers if len(pkg) < 54: print('Error: pkg too short') return if pkg[0] != 0xf8 or pkg[53] != 0x0d: print('Error: Frame uncorrect') return sport_code = pkg[1] if sport_code == 0x33 or sport_code == 0x37 or sport_code == 0x38: GameBasketball.update({ 'timer': pn_timer(pkg[4:8]), 'horn': pn_horn(pkg[19]), 'timer_status': pn_startstop(pkg[20]), 'timer24': pn_timer24(pkg[48:50]), 'horn24': pn_horn(pkg[50]), 'timer24_status': pn_startstop(pkg[51]), 'timer24_display': pn_display24(pkg[52]) }) if GameBasketball['timer24_display'] == 0: GameBasketball['timer24'] = ' ' if sport_code == 0x33: # BASKETBALL with individual fouls Game['type'] = 'Basketball' GameBasketball.update({ 'ball_pos': pn_ball_pos(pkg[3]), 'home_points': pn_points(pkg[8:11]), 'guest_points': pn_points(pkg[11:14]), 'period': pn_period(pkg[14]), 'home_fouls': pn_teamfouls(pkg[15]), 'guest_fouls': pn_teamfouls(pkg[16]), 'home_timeouts': pn_timeouts(pkg[17]), 'guest_timeouts': pn_timeouts(pkg[18]), 'timeout_timer': pn_timertimeout(bytes([pkg[21]]) + pkg[46:48]), }) for i in range(0, 12): HomePlayers[i]['fouls'] = pn_playerfouls(pkg[22 + i]) for i in range(0, 12): GuestPlayers[i]['fouls'] = pn_playerfouls(pkg[34 + i]) TimerSet(GameBasketball['timer']) Timer24Set(GameBasketball['timer24']) elif sport_code == 0x35: # HANDBALL/FUTSAL Game['type'] = 'HandFutsal' GameHandFutsal.update({ 'timer': pn_timer(pkg[4:8]), 'home_fouls': pn_teamfouls(pkg[8]), 'home_points': pn_points(pkg[9:11]), 'guest_fouls': pn_teamfouls(pkg[11]), 'guest_points': pn_points(pkg[12:14]), 'period': pn_period(pkg[14]), 'home_penalties': pn_penalties(pkg[15]), 'guest_penalties': pn_penalties(pkg[16]), 'home_timeouts': pn_timeouts(pkg[17]), 'guest_timeouts': pn_timeouts(pkg[18]), 'horn': pn_horn(pkg[19]), 'timer_status': pn_startstop(pkg[20]), 'home_penalty1_player': pn_playernumber(pkg[22:24]), 'home_penalty2_player': pn_playernumber(pkg[27:29]), 'home_penalty3_player': pn_playernumber(pkg[32:34]), 'home_penalty1_timer': pn_playerfouls(pkg[24:27]), 'home_penalty2_timer': pn_playerfouls(pkg[29:32]), 'home_penalty3_timer': pn_playerfouls(pkg[34:37]), 'guest_penalty1_player': pn_playernumber(pkg[37:39]), 'guest_penalty2_player': pn_playernumber(pkg[42:44]), 'guest_penalty3_player': pn_playernumber(pkg[47:49]), 'guest_penalty1_timer': pn_playerfouls(pkg[39:42]), 'guest_penalty2_timer': pn_playerfouls(pkg[44:47]), 'guest_penalty3_timer': pn_playerfouls(pkg[49:52]) }) elif sport_code == 0x36: # VOLLEYBALL pass elif sport_code == 0x37: # Individual points - GUEST BASKET/HAND/HOCKEY/FUTSAL for i in range(0, 13): GuestPlayers[i]['points'] = pn_points(pkg[22 + 2*i : 24 + 2*i]) for i in range(13, 16): GuestPlayers[i]['points'] = pn_points(pkg[11 + 2*i : 13 + 2*i]) print(GuestPlayers) elif sport_code == 0x38: # Individual points - HOME BASKET/HAND/HOCKEY/FUTSAL for i in range(0, 13): HomePlayers[i]['points'] = pn_points(pkg[22 + 2*i : 24 + 2*i]) for i in range(13, 16): HomePlayers[i]['points'] = pn_points(pkg[11 + 2*i : 13 + 2*i]) elif sport_code == 0x39: # TENNIS pass elif sport_code == 0x3A: # TABLE TENNIS pass elif sport_code == 0x3C: # HANDBALL with individual penalties pass elif sport_code == 0x62: # GUEST NAME if pkg[2] == 0x20: Game['guest_name'] = pn_name(pkg[6:48]) with open(game_filename, 'w', encoding='utf-8') as f: json.dump(Game, f, ensure_ascii=False, indent=4) else: GuestPlayers[int(pkg[2])]['number'] = pn_playernumber(pkg[51:53]) GuestPlayers[int(pkg[2])]['name'] = pn_name(pkg[3:23]) with open(guestplayers_filename, 'w', encoding='utf-8') as f: json.dump(GuestPlayers, f, ensure_ascii=False, indent=4) elif sport_code == 0x77: # HOME NAME if pkg[2] == 0x20: Game['home_name'] = pn_name(pkg[6:48]) with open(game_filename, 'w', encoding='utf-8') as f: json.dump(Game, f, ensure_ascii=False, indent=4) else: HomePlayers[int(pkg[2])]['number'] = pn_playernumber(pkg[51:53]) HomePlayers[int(pkg[2])]['name'] = pn_name(pkg[3:23]) with open(homeplayers_filename, 'w', encoding='utf-8') as f: json.dump(HomePlayers, f, ensure_ascii=False, indent=4) elif sport_code == 0x4D: # MESSAGE GameHandFutsal.update({ 'timer': pn_timer(pkg[4:8]), 'horn': pn_horn(pkg[19]), 'timer_status': pn_startstop(pkg[20]), 'timer24': pn_timer24(pkg[48:50]), 'horn24': pn_horn(pkg[50]), 'timer24_status': pn_startstop(pkg[51]), 'timer24_display': pn_display24(pkg[52]) }) elif sport_code == 0x41 or sport_code == 0x043: # MESSAGE CONFIGURATION GameHandFutsal.update({ 'timer': pn_timer(pkg[4:8]), 'horn': pn_horn(pkg[19]), 'timer_status': pn_startstop(pkg[20]), 'timer24': pn_timer24(pkg[48:50]), 'horn24': pn_horn(pkg[50]), 'timer24_status': pn_startstop(pkg[51]), 'timer24_display': pn_display24(pkg[52]) }) else: print('Error: Unknown sport code {}'.format(sport_code)) class REFClient(asyncore.dispatcher): buff = [] def __init__(self, host, port): asyncore.dispatcher.__init__(self) self.create_socket() self.connect( (host, port) ) def handle_connect(self): pass #print('Connect to referee system is established') def handle_close(self): self.close() def handle_read(self): buff = self.recv(8192) if len(buff) == 54: parce(buff) class JSONServer(BaseHTTPRequestHandler): def do_GET(self): if self.path == '/Game': self.send_response(200) self.send_header("Content-type", "application/json") self.end_headers() self.wfile.write(bytes(json.dumps([GameBasketball]), "utf-8")) elif self.path == '/GameBasketball': self.send_response(200) self.send_header("Content-type", "application/json") self.end_headers() self.wfile.write(bytes(json.dumps([GameBasketball]), "utf-8")) elif self.path == '/GameHandFutsal': self.send_response(200) self.send_header("Content-type", "application/json") self.end_headers() self.wfile.write(bytes(json.dumps([GameHandFutsal]), "utf-8")) #GameHandFutsal #self.wfile.write(bytes(json.dumps([GameHandFutsal]), "utf-8")) elif self.path == '/HomePlayers': self.send_response(200) self.send_header("Content-type", "application/json") self.end_headers() self.wfile.write(bytes(json.dumps(HomePlayers), "utf-8")) elif self.path == '/GuestPlayers': self.send_response(200) self.send_header("Content-type", "application/json") self.end_headers() self.wfile.write(bytes(json.dumps(GuestPlayers), "utf-8")) elif self.path == '/refresh': self.send_response(200) self.send_header("Content-type", "application/json") self.end_headers() self.wfile.write(bytes('[{"refresh":"ok"}]', "utf-8")) with io.open('C:/Users/aksma/YandexDisk/workspace/_hd1/_gfx/multisport_452/data.bin', 'rb') as f: parce(f.read()) else: self.send_response(200) self.send_header("Content-type", "application/json") self.end_headers() self.wfile.write(bytes('[{"error":"bad path"}]', "utf-8")) if __name__ == "__main__": try: with open(game_filename) as f: Game = json.load(f) with open(homeplayers_filename) as f: HomePlayers = json.load(f) with open(guestplayers_filename) as f: GuestPlayers = json.load(f) except: pass webServer = HTTPServer((jsonserver_hostname, jsonserver_port), JSONServer) print("Server started http://%s:%s" % (jsonserver_hostname, jsonserver_port)) client = REFClient(refserver_hostname, refserver_port) thread = threading.Thread(target=asyncore.loop, args=()) thread.start() print('Connect to referee system is established') try: webServer.serve_forever() except KeyboardInterrupt: pass webServer.server_close() print("Server stopped.")