first commit
This commit is contained in:
163
RPL/main.py
Normal file
163
RPL/main.py
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
import socket
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
def send_data(value):
|
||||||
|
url = "http://127.0.0.1:8088/API/"
|
||||||
|
par = "SetText"
|
||||||
|
if 'проверка' in value:
|
||||||
|
input = 34
|
||||||
|
else:
|
||||||
|
input = 35
|
||||||
|
if "-" in value:
|
||||||
|
params = {
|
||||||
|
"Function": par,
|
||||||
|
"Input": input,
|
||||||
|
"SelectedName": "СТрока1.Text",
|
||||||
|
"Value": value.split("-")[0].strip(),
|
||||||
|
}
|
||||||
|
requests.get(url, params=params)
|
||||||
|
params = {
|
||||||
|
"Function": par,
|
||||||
|
"Input": input,
|
||||||
|
"SelectedName": "Строка2.Text",
|
||||||
|
"Value": value.split("-")[1].strip(),
|
||||||
|
}
|
||||||
|
requests.get(url, params=params)
|
||||||
|
|
||||||
|
|
||||||
|
VOR = "VOR3"
|
||||||
|
|
||||||
|
list_code = {
|
||||||
|
"101": "Приветствие",
|
||||||
|
"102": "Инфо",
|
||||||
|
"103": "Игра проходит без системы определения офсайдных линий",
|
||||||
|
"104": "Игра проходит без системы VAR",
|
||||||
|
"105": "Проверка",
|
||||||
|
"106": "проверка - Офсайд",
|
||||||
|
"107": "проверка - Возможно, офсайд",
|
||||||
|
"108": "проверка - Игра рукой",
|
||||||
|
"109": "проверка - Фол в атаке",
|
||||||
|
"110": "проверка - Симуляция",
|
||||||
|
"111": "Игра проходит с системой VAR",
|
||||||
|
"112": "Игра проходит с ограниченными техническими возможностями",
|
||||||
|
"113": "Объявление решения",
|
||||||
|
"114": "Неисправность системы объявления решений судьи",
|
||||||
|
"115": "Не используется система объявления решений судьи",
|
||||||
|
"116": "Решение подтверждено - офсайд",
|
||||||
|
"117": "Нет офсайда",
|
||||||
|
"118": "Возможно игра рукой в атаке",
|
||||||
|
"119": "проверка - Игра рукой в атаке",
|
||||||
|
"201": "проверка - Гол",
|
||||||
|
"202": "Решение подтверждено - гол",
|
||||||
|
"203": "Решение подтверждено - гол, нет офсайда",
|
||||||
|
"204": "Решение подтверждено - гол, нет фола",
|
||||||
|
"205": "Решение подтверждено - гол, нет игры рукой",
|
||||||
|
"206": "Решение подтверждено - гол, мяч в игре",
|
||||||
|
"207": "Решение подтверждено - гол, симуляция",
|
||||||
|
"208": "Решение подтверждено - гол, мяч пересек линию ворот",
|
||||||
|
"209": "Решение изменено - нет гола, офсайд",
|
||||||
|
"210": "Решение изменено - нет гола, фол",
|
||||||
|
"211": "Решение изменено - нет гола, игра рукой",
|
||||||
|
"212": "Решение изменено - нет гола, мяч не в игре",
|
||||||
|
"213": "Решение изменено - нет гола, мяч не пересек линию ворот",
|
||||||
|
"301": "проверка - Возможно, гол",
|
||||||
|
"302": "Решение подтверждено - нет гола",
|
||||||
|
"303": "Решение подтверждено - нет гола, офсайд",
|
||||||
|
"304": "Решение подтверждено - нет гола, фол",
|
||||||
|
"305": "Решение подтверждено - нет гола, игра рукой",
|
||||||
|
"306": "Решение подтверждено - нет гола, мяч не в игре",
|
||||||
|
"307": "Решение подтверждено - нет гола, мяч не пересек линию ворот",
|
||||||
|
"308": "Решение изменено - гол",
|
||||||
|
"309": "Решение изменено - гол, нет офсайда",
|
||||||
|
"310": "Решение изменено - гол, нет фола",
|
||||||
|
"311": "Решение изменено - гол, нет игры рукой",
|
||||||
|
"312": "Решение изменено - гол, мяч в игре",
|
||||||
|
"313": "Решение изменено - гол, симуляция",
|
||||||
|
"314": "Решение изменено - гол, мяч пересек линию ворот",
|
||||||
|
"401": "проверка - Пенальти",
|
||||||
|
"402": "Решение подтверждено - пенальти",
|
||||||
|
"403": "Решение подтверждено - пенальти, фол",
|
||||||
|
"404": "Решение подтверждено - пенальти, игра рукой",
|
||||||
|
"405": "Решение подтверждено - пенальти, фол в штрафной",
|
||||||
|
"406": "Решение подтверждено - пенальти, игра рукой в штрафной",
|
||||||
|
"407": "Решение изменено - нет пенальти, нет фола",
|
||||||
|
"408": "Решение изменено - нет пенальти, нет игры рукой",
|
||||||
|
"409": "Решение изменено - нет пенальти, фол за штрафной",
|
||||||
|
"410": "Решение изменено - нет пенальти, офсайд",
|
||||||
|
"411": "Решение изменено - нет пенальти, фол в атаке",
|
||||||
|
"412": "Решение изменено - нет пенальти, игра рукой в атаке",
|
||||||
|
"413": "Решение изменено - нет пенальти, мяч не в игре",
|
||||||
|
"414": "Решение изменено - нет пенальти, симуляция",
|
||||||
|
"501": "проверка - Возможно, пенальти",
|
||||||
|
"502": "Решение подтверждено - нет пенальти",
|
||||||
|
"503": "Решение подтверждено - нет пенальти, нет фола",
|
||||||
|
"504": "Решение подтверждено - нет пенальти, нет игры рукой",
|
||||||
|
"505": "Решение подтверждено - нет пенальти, фол за штрафной",
|
||||||
|
"506": "Решение подтверждено - нет пенальти, офсайд",
|
||||||
|
"507": "Решение подтверждено - нет пенальти, фол в атаке",
|
||||||
|
"508": "Решение подтверждено - нет пенальти, игра рукой в атаке",
|
||||||
|
"509": "Решение подтверждено - нет пенальти, мяч не в игре",
|
||||||
|
"510": "Решение подтверждено - нет пенальти, симуляция",
|
||||||
|
"511": "Решение изменено - пенальти",
|
||||||
|
"512": "Решение изменено - пенальти, фол",
|
||||||
|
"513": "Решение изменено - пенальти, игра рукой",
|
||||||
|
"514": "Решение изменено - пенальти, фол в штрафной",
|
||||||
|
"515": "Решение изменено - пенальти, игра рукой в штрафной",
|
||||||
|
"516": "Решение изменено – пенальти, нет симуляции",
|
||||||
|
"601": "проверка - Красная карточка",
|
||||||
|
"602": "Решение подтверждено - красная карточка",
|
||||||
|
"603": "Решение изменено - жёлтая карточка",
|
||||||
|
"604": "Решение изменено - нет карточки",
|
||||||
|
"701": "проверка - Возможно, красная карточка",
|
||||||
|
"702": "Решение подтверждено - нет красной карточки",
|
||||||
|
"703": "Решение изменено - красная карточка",
|
||||||
|
"704": "Решение изменено - жёлтая карточка",
|
||||||
|
"801": "проверка - Идентификация игрока",
|
||||||
|
"802": "Ошибочная идентификация игрока",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HOST = '127.0.0.1' # Принимаем соединения со всех интерфейсов
|
||||||
|
PORT = 60000 # Порт, который будем слушать
|
||||||
|
|
||||||
|
|
||||||
|
def start_tcp_server():
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
|
||||||
|
server_socket.bind((HOST, PORT))
|
||||||
|
server_socket.listen(5)
|
||||||
|
print(f"Сервер запущен на {HOST}:{PORT}")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
client_socket, addr = server_socket.accept()
|
||||||
|
with client_socket:
|
||||||
|
print(f"Клиент подключился: {addr}")
|
||||||
|
while True:
|
||||||
|
data = client_socket.recv(1024)
|
||||||
|
if not data:
|
||||||
|
break
|
||||||
|
|
||||||
|
try:
|
||||||
|
decoded = data.decode('utf-8')
|
||||||
|
print(f"Получено: {decoded}")
|
||||||
|
send_data(list_code[decoded.split("/")[2]])
|
||||||
|
|
||||||
|
# parts = decoded.split(", ")
|
||||||
|
# if len(parts) != 2:
|
||||||
|
# print("Неверный формат сообщения")
|
||||||
|
# continue
|
||||||
|
|
||||||
|
# sender, code = parts
|
||||||
|
# if sender == VOR and code in list_code:
|
||||||
|
# send_data(list_code[code])
|
||||||
|
# else:
|
||||||
|
# print("Неверный код или отправитель")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Ошибка обработки данных: {e}")
|
||||||
|
|
||||||
|
print(f"Отключение клиента: {addr}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
start_tcp_server()
|
||||||
11
data_sender.py
Normal file
11
data_sender.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
def send_data_to_ips(data, ip_list):
|
||||||
|
for ip in ip_list:
|
||||||
|
try:
|
||||||
|
url = f"{ip}/API/"
|
||||||
|
response = requests.post(url, json=data)
|
||||||
|
print(f"Data sent to {ip}: {response.status_code}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error sending data to {ip}: {e}")
|
||||||
405
divs/jsonserver.py
Normal file
405
divs/jsonserver.py
Normal file
@@ -0,0 +1,405 @@
|
|||||||
|
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.")
|
||||||
34
divs/tcp_monitor.py
Normal file
34
divs/tcp_monitor.py
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import asyncore
|
||||||
|
from textwrap import wrap
|
||||||
|
|
||||||
|
refserver_hostname = "79.172.5.168"
|
||||||
|
refserver_port = 4001
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
def handle_close(self):
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def handle_read(self):
|
||||||
|
hex = bytes.hex(self.recv(8192))
|
||||||
|
hex = wrap(hex, 2)
|
||||||
|
print(' '.join(hex))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
client = REFClient(refserver_hostname, refserver_port)
|
||||||
|
|
||||||
|
try:
|
||||||
|
asyncore.loop()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
|
||||||
|
print("Server stopped.")
|
||||||
123
old/timer_MBA.py
Normal file
123
old/timer_MBA.py
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
from socket import *
|
||||||
|
from datetime import datetime
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
|
||||||
|
HOST = "10.0.0.57" # local
|
||||||
|
PORT = 50002
|
||||||
|
ADDR = (HOST,PORT)
|
||||||
|
|
||||||
|
PATH = "D:\\timer.json"
|
||||||
|
|
||||||
|
|
||||||
|
def connect():
|
||||||
|
tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
tcp_socket.connect(ADDR)
|
||||||
|
data = "Hello, world"
|
||||||
|
data = str.encode(data)
|
||||||
|
tcp_socket.send(data)
|
||||||
|
data = bytes.decode(data)
|
||||||
|
data = tcp_socket.recv(1024)
|
||||||
|
# tcp_socket.close()
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def save_log(name, data):
|
||||||
|
current_time = datetime.now().strftime("%d-%m-%Y %H:%M:%S.%f")
|
||||||
|
message_with_time = f"[{current_time}] {data}"
|
||||||
|
with open(name, "a") as file:
|
||||||
|
file.write(message_with_time + "\n")
|
||||||
|
|
||||||
|
|
||||||
|
def formatted_data(data):
|
||||||
|
save_log("logs_mba.txt", data)
|
||||||
|
|
||||||
|
# data_converted = list(data)
|
||||||
|
# data_formatted = [
|
||||||
|
# str(hex_value // 16) + str(hex_value % 16) for hex_value in data_converted
|
||||||
|
# ]
|
||||||
|
# save_log("logs_mba_formatted.txt", data_formatted)
|
||||||
|
|
||||||
|
|
||||||
|
def parse(data_formatted):
|
||||||
|
# print(len(data_formatted))
|
||||||
|
# print(data_formatted)
|
||||||
|
with open(PATH, "r", encoding="utf-8") as f:
|
||||||
|
new_data = json.load(f)
|
||||||
|
new_data = new_data[0]
|
||||||
|
|
||||||
|
if len(data_formatted) > 30:
|
||||||
|
if data_formatted[17] == "010":
|
||||||
|
if data_formatted[-8] in ["01", "05"]:
|
||||||
|
timer_str = (
|
||||||
|
f"{int(data_formatted[-7])}:{data_formatted[-6]}"
|
||||||
|
if int(data_formatted[-7]) != 0
|
||||||
|
else f"{int(data_formatted[-6])}.{int(data_formatted[-5])}"
|
||||||
|
)
|
||||||
|
new_data["timeGFX"] = timer_str
|
||||||
|
new_data["minutesGFX"] = int(
|
||||||
|
data_formatted[-7]
|
||||||
|
) # [25] #data_formatted[17] = 010 - таймер data_formatted[-8] = 05 - овертайм, 06 - перерыв между основным временем и овертаймом, 01 - игровое время, 02 - перерыв между периодами
|
||||||
|
new_data["secondsGFX"] = data_formatted[-6] # [26]
|
||||||
|
else:
|
||||||
|
timer_str = f"{int(data_formatted[-7])}:{data_formatted[-6]}"
|
||||||
|
new_data["timeNotGame"] = timer_str
|
||||||
|
|
||||||
|
if len(data_formatted) == 58:
|
||||||
|
new_data[
|
||||||
|
"timeDel1"
|
||||||
|
] = f"{int(data_formatted[26])}:{data_formatted[27]}" # data_formatted[17] = 24 - удаление
|
||||||
|
new_data["timeDel2"] = f"{int(data_formatted[41])}:{data_formatted[42]}"
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
print(new_data)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
with socket(AF_INET, SOCK_STREAM) as s:
|
||||||
|
s.connect((HOST, PORT))
|
||||||
|
s.sendall(b"Hello, world")
|
||||||
|
data = s.recv(1024)
|
||||||
|
while True:
|
||||||
|
print(data)
|
||||||
|
data_new = formatted_data(data)
|
||||||
|
time.sleep(.1)
|
||||||
|
# parse(data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def read_logs():
|
||||||
|
import time
|
||||||
|
with open("test_logs_balashikha_new.txt", "r") as file:
|
||||||
|
for line in file:
|
||||||
|
parts = line.strip().split("] ")
|
||||||
|
if len(parts) == 2:
|
||||||
|
timestamp = parts[0][1:]
|
||||||
|
data = parts[1]
|
||||||
|
parse(eval(data))
|
||||||
|
if len(eval(data)) > 30 and eval(data)[-7] == "00":
|
||||||
|
time.sleep(.1)
|
||||||
|
else:
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
new_data = {
|
||||||
|
"timeGFX": "0:00",
|
||||||
|
"minutesGFX": "0",
|
||||||
|
"secondsGFX": "0",
|
||||||
|
"foul1": "0",
|
||||||
|
"foul2": "0",
|
||||||
|
"quarter": "0",
|
||||||
|
}
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
main()
|
||||||
|
# read_logs()
|
||||||
143
old/timer_MBA_2.py
Normal file
143
old/timer_MBA_2.py
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
import sys
|
||||||
|
import json
|
||||||
|
from socket import *
|
||||||
|
from datetime import datetime
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
host = "10.0.0.57"
|
||||||
|
port = 50002
|
||||||
|
ADDR = (host, port)
|
||||||
|
PATH = "D:\\timer_basketball.json"
|
||||||
|
|
||||||
|
|
||||||
|
def save_log(name, data):
|
||||||
|
current_time = datetime.now().strftime("%d-%m-%Y %H:%M:%S.%f")
|
||||||
|
message_with_time = f"[{current_time}] {data}"
|
||||||
|
with open(name, "a") as file:
|
||||||
|
file.write(message_with_time + "\n")
|
||||||
|
|
||||||
|
|
||||||
|
def parse(data):
|
||||||
|
data = data.split("/")
|
||||||
|
|
||||||
|
with open(PATH, "r", encoding="utf-8") as f:
|
||||||
|
new_data = json.load(f)
|
||||||
|
new_data = new_data[0]
|
||||||
|
path_pic = "D:\Графика\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\VTB_Fouls for scoreboard smaller"
|
||||||
|
if len(data) > 10:
|
||||||
|
if data[4] == "NPR":
|
||||||
|
new_data["quarter"] = data[5]
|
||||||
|
if data[17] == "HCP":
|
||||||
|
new_data["points1"] = data[18]
|
||||||
|
if data[20] == "GCP":
|
||||||
|
new_data["points2"] = data[21]
|
||||||
|
if data[29] == "HCF":
|
||||||
|
new_data["foul1"] = data[30]
|
||||||
|
new_data["foul_pic1"] = path_pic + f"\Home тАУ {int(data[30])} Foul.png"
|
||||||
|
if data[32] == "GCF":
|
||||||
|
new_data["foul2"] = data[33]
|
||||||
|
new_data["foul_pic2"] = path_pic + f"\Away тАУ {int(data[33])} Foul.png"
|
||||||
|
else:
|
||||||
|
if data[1] == "TGI":
|
||||||
|
if data[2] != "0":
|
||||||
|
seconds = data[3] if len(data[3]) != 1 else f"0{data[3]}"
|
||||||
|
new_data["timeGFX"] = f"{data[2]}:{seconds}"
|
||||||
|
else:
|
||||||
|
millisec = data[4]
|
||||||
|
if millisec == "#":
|
||||||
|
millisec = "0"
|
||||||
|
new_data["timeGFX"] = f"{data[3]}.{millisec}"
|
||||||
|
elif data[1] == "NPR":
|
||||||
|
new_data["quarter"] = data[2]
|
||||||
|
elif data[1] == "HCP":
|
||||||
|
new_data["points1"] = data[2]
|
||||||
|
elif data[1] == "GCP":
|
||||||
|
new_data["points2"] = data[2]
|
||||||
|
elif data[1] == "HCF":
|
||||||
|
new_data["foul1"] = data[2]
|
||||||
|
new_data["foul_pic1"] = path_pic + f"\Home тАУ {int(data[2])} Foul.png"
|
||||||
|
elif data[1] == "GCF":
|
||||||
|
new_data["foul2"] = data[2]
|
||||||
|
new_data["foul_pic2"] = path_pic + f"\Away тАУ {int(data[2])} Foul.png"
|
||||||
|
elif data[1] == "TAI":
|
||||||
|
if data[2] not in ["0", "-1"]:
|
||||||
|
new_data["time_attackGFX"] = str(int(data[2]))
|
||||||
|
if int(data[2]) <= 5:
|
||||||
|
new_data["time_attac_pic"] = ""
|
||||||
|
else:
|
||||||
|
new_data["time_attac_pic"] = "empty"
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
print(new_data)
|
||||||
|
if ":" in new_data["timeGFX"]:
|
||||||
|
time.sleep(.5)
|
||||||
|
else:
|
||||||
|
time.sleep(.1)
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def read_logs():
|
||||||
|
with open("logs_mba_1.txt", "r") as file:
|
||||||
|
for line in file:
|
||||||
|
parts = line.strip().split("] ")
|
||||||
|
if len(parts) == 2:
|
||||||
|
timestamp = parts[0][1:]
|
||||||
|
data = parts[1]
|
||||||
|
|
||||||
|
parse(data)
|
||||||
|
|
||||||
|
# if len(eval(data)) > 30 and eval(data)[-7] == "00":
|
||||||
|
# time.sleep(.1)
|
||||||
|
# else:
|
||||||
|
# time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
new_data = {
|
||||||
|
"timeGFX": "0:00",
|
||||||
|
"time_attackGFX": "",
|
||||||
|
"quarter": "0",
|
||||||
|
"points1": "0",
|
||||||
|
"points2": "0",
|
||||||
|
"foul1": "0",
|
||||||
|
"foul2": "0",
|
||||||
|
"foul_pic1": "",
|
||||||
|
"foul_pic2": "",
|
||||||
|
"time_attac_pic": "",
|
||||||
|
}
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
# tcp_socket.connect(ADDR)
|
||||||
|
|
||||||
|
# try:
|
||||||
|
# while True:
|
||||||
|
# data = str.encode("hello")
|
||||||
|
# tcp_socket.send(data)
|
||||||
|
# data = bytes.decode(data)
|
||||||
|
# data = tcp_socket.recv(1024)
|
||||||
|
# data = data.decode()
|
||||||
|
# save_log("logs_mba_1.txt", data)
|
||||||
|
# parse(data)
|
||||||
|
# except KeyboardInterrupt:
|
||||||
|
# tcp_socket.close()
|
||||||
|
# sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
read_logs()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
141
old/timer_Megasport_test.py
Normal file
141
old/timer_Megasport_test.py
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
import sys
|
||||||
|
import json
|
||||||
|
from socket import *
|
||||||
|
from datetime import datetime
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import binascii
|
||||||
|
|
||||||
|
HOST = "192.168.127.254"
|
||||||
|
PORT = 1993
|
||||||
|
PATH = (
|
||||||
|
r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\python\JSON\timer_basketball.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def hexspace(string, length):
|
||||||
|
return " ".join(string[i : i + length] for i in range(0, len(string), length))
|
||||||
|
|
||||||
|
|
||||||
|
def parse(line):
|
||||||
|
cdata = binascii.hexlify(line)
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
|
||||||
|
if len(edata.split()) == 33:
|
||||||
|
temp_data = edata.split()
|
||||||
|
temp_new = [int(t, 16) for t in temp_data]
|
||||||
|
minutes = temp_new[6]
|
||||||
|
seconds = temp_new[7]
|
||||||
|
milliseconds = temp_new[8]
|
||||||
|
timer_str = (
|
||||||
|
f"{minutes}:{seconds:02d}"
|
||||||
|
if minutes != 0
|
||||||
|
else f"{seconds:02d}.{milliseconds}"
|
||||||
|
)
|
||||||
|
active_temp = temp_new[
|
||||||
|
9
|
||||||
|
] # 133 - таймер идёт | 132 - таймер стоит | 128 - не игровое время стоит | 129 - не игровое время идёт
|
||||||
|
|
||||||
|
if temp_new[-2] != 0:
|
||||||
|
time_attack = (
|
||||||
|
temp_new[-4] if temp_new[-4] > 4 else f"{temp_new[-4]}.{temp_new[-3]}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
time_attack = "" # temp_new[-2] == 1 - таймер идёт | 2 - таймер стоит | 0 - таймер не отображён
|
||||||
|
|
||||||
|
# print(f"{str(temp_new):<120}__{timer_str:<7}__{time_attack:<3}__")
|
||||||
|
else:
|
||||||
|
temp_data = edata.split()
|
||||||
|
temp_new = [int(t, 16) for t in temp_data]
|
||||||
|
|
||||||
|
with open("timer_NN.csv", "a+") as file:
|
||||||
|
file.write(str(temp_new))
|
||||||
|
file.write("\n")
|
||||||
|
with open("timer_NN_2.csv", "a+") as file:
|
||||||
|
file.write(str(temp_data))
|
||||||
|
file.write("\n")
|
||||||
|
with open("timer_NN_3.csv", "a+") as file:
|
||||||
|
file.write(str(ddata))
|
||||||
|
file.write("\n")
|
||||||
|
|
||||||
|
# time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def read_logs():
|
||||||
|
with open("timer_NN_2023-12-20_18-17-29.log", "r") as file:
|
||||||
|
# with open("timer_NN_test.log", "r") as file:
|
||||||
|
temp_line = ""
|
||||||
|
for line in file:
|
||||||
|
parts = line.strip().split(" DEBUG ")
|
||||||
|
if len(parts) == 2:
|
||||||
|
timestamp = parts[0][1:]
|
||||||
|
data = eval(parts[1])
|
||||||
|
parse(data)
|
||||||
|
time.sllep(.1)
|
||||||
|
|
||||||
|
# if len(eval(data)) > 30 and eval(data)[-7] == "00":
|
||||||
|
# time.sleep(.1)
|
||||||
|
# else:
|
||||||
|
# time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# current_time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
# if not os.path.isdir("LOGS"):
|
||||||
|
# os.mkdir("LOGS")
|
||||||
|
|
||||||
|
# LogFileName = f"LOGS/timer_Chine_tcp_{current_time}.log"
|
||||||
|
# logging.basicConfig(
|
||||||
|
# level=logging.DEBUG,
|
||||||
|
# format="%(asctime)s %(levelname)s %(message)s",
|
||||||
|
# filename=LogFileName,
|
||||||
|
# filemode="w",
|
||||||
|
# )
|
||||||
|
# new_data = {
|
||||||
|
# "timeGFX": "0:00",
|
||||||
|
# "time_attackGFX": "",
|
||||||
|
# "quarter": "0",
|
||||||
|
# "points1": "0",
|
||||||
|
# "points2": "0",
|
||||||
|
# "foul1": "0",
|
||||||
|
# "foul2": "0",
|
||||||
|
# "foul_pic1": "",
|
||||||
|
# "foul_pic2": "",
|
||||||
|
# "time_attac_pic": "",
|
||||||
|
# }
|
||||||
|
# with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
# json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
|
||||||
|
try:
|
||||||
|
tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
tcp_socket.connect((HOST, PORT))
|
||||||
|
data = str.encode("hello")
|
||||||
|
tcp_socket.send(data)
|
||||||
|
data = bytes.decode(data)
|
||||||
|
while True:
|
||||||
|
data = tcp_socket.recv(1024)
|
||||||
|
# logging.debug(data)
|
||||||
|
cdata = binascii.hexlify(data)
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
print(edata)
|
||||||
|
# temp_data = edata.split()
|
||||||
|
# temp_new = [int(t, 16) for t in temp_data]
|
||||||
|
# timer = f"{temp_new[3]}:{temp_new[2]}"
|
||||||
|
# seconds = temp_new[5]
|
||||||
|
# milliseconds = str(temp_new[4])[0]
|
||||||
|
# print(f"data: {edata}", temp_new, timer, f"{seconds}.{milliseconds}")
|
||||||
|
# print(temp_new, timer, f"{seconds}.{milliseconds}")
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
tcp_socket.close()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
# read_logs()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(1)
|
||||||
82
old/timer_megasport.py
Normal file
82
old/timer_megasport.py
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
# import serial.tools.list_ports #pip install pyserial
|
||||||
|
|
||||||
|
import serial
|
||||||
|
from datetime import datetime
|
||||||
|
import json
|
||||||
|
|
||||||
|
# Configure the COM port
|
||||||
|
port = "COM8" # Replace with the appropriate COM port name
|
||||||
|
baudrate = 9600
|
||||||
|
# baudrate = 19200
|
||||||
|
PATH = "D:\\timer_basketball.json"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def save_log(name, data):
|
||||||
|
current_time = datetime.now().strftime("%d-%m-%Y %H:%M:%S.%f")
|
||||||
|
message_with_time = f"[{current_time}] {data}"
|
||||||
|
with open(name, "a") as file:
|
||||||
|
file.write(message_with_time + "\n")
|
||||||
|
|
||||||
|
|
||||||
|
def read_logs():
|
||||||
|
import time
|
||||||
|
|
||||||
|
with open("logs_megasport_formatted.txt", "r") as file:
|
||||||
|
for line in file:
|
||||||
|
parts = line.strip().split("] ")
|
||||||
|
if len(parts) == 2:
|
||||||
|
timestamp = parts[0][1:]
|
||||||
|
data = parts[1]
|
||||||
|
parse(eval(data))
|
||||||
|
|
||||||
|
input()
|
||||||
|
# if len(eval(data)) > 30 and eval(data)[-7] == "00":
|
||||||
|
# time.sleep(0.1)
|
||||||
|
# else:
|
||||||
|
# time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
def parse(data_formatted):
|
||||||
|
print(len(data_formatted))
|
||||||
|
if len(data_formatted) > 8:
|
||||||
|
print(data_formatted)
|
||||||
|
with open(PATH, "r", encoding="utf-8") as f:
|
||||||
|
new_data = json.load(f)
|
||||||
|
new_data = new_data[0]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
try:
|
||||||
|
# Open the COM port
|
||||||
|
ser = serial.Serial(port, baudrate=baudrate)
|
||||||
|
print("Serial connection established.")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
line = ser.readline()
|
||||||
|
line = list(line)
|
||||||
|
line = [str(hex_value // 16) + str(hex_value % 16) for hex_value in line]
|
||||||
|
save_log("logs_balashikha_formatted.txt", line)
|
||||||
|
print(line)
|
||||||
|
|
||||||
|
except serial.SerialException as se:
|
||||||
|
print("Serial port error:", str(se))
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
if ser.is_open:
|
||||||
|
ser.close()
|
||||||
|
print("Serial connection closed.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# new_data = {
|
||||||
|
# "timeGFX": "0:00",
|
||||||
|
# }
|
||||||
|
# with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
# json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
main()
|
||||||
|
# read_logs()
|
||||||
70
old/timer_megasport2.py
Normal file
70
old/timer_megasport2.py
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import serial
|
||||||
|
from serial import SerialException
|
||||||
|
import logging
|
||||||
|
import time
|
||||||
|
import binascii
|
||||||
|
|
||||||
|
SerialPort = "COM1"
|
||||||
|
BaudRate = 19200
|
||||||
|
PackageByTime = 0.1
|
||||||
|
PackageByLenght = 256
|
||||||
|
BufferMax = 2000
|
||||||
|
LogFileName = "megasport_new_4.log"
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG,
|
||||||
|
format='%(asctime)s %(levelname)s %(message)s',
|
||||||
|
filename=LogFileName,
|
||||||
|
filemode="w")
|
||||||
|
|
||||||
|
ser = serial.Serial()
|
||||||
|
ser.port = SerialPort
|
||||||
|
ser.baudrate = BaudRate
|
||||||
|
ser.bytesize = serial.EIGHTBITS
|
||||||
|
ser.parity = serial.PARITY_NONE
|
||||||
|
ser.stopbits = serial.STOPBITS_ONE
|
||||||
|
ser.timeout = PackageByTime
|
||||||
|
ser.xonxoff = False
|
||||||
|
ser.rtscts = False
|
||||||
|
ser.dsrdtr = False
|
||||||
|
ser.write_timeout = 2
|
||||||
|
|
||||||
|
start = b"\xe0\xe0\xe8\xe8\xe4\xe4\xf8"
|
||||||
|
finish = b"\r"
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
print("Initializing")
|
||||||
|
ser.close()
|
||||||
|
ser.open()
|
||||||
|
if ser.is_open:
|
||||||
|
try:
|
||||||
|
RequestCount = 0
|
||||||
|
print("Port Opening")
|
||||||
|
RetryCount = 0
|
||||||
|
remainder_hex = b""
|
||||||
|
while True:
|
||||||
|
response = ser.read(PackageByLenght)
|
||||||
|
print(response)
|
||||||
|
|
||||||
|
logging.debug(response)
|
||||||
|
if len(response) > 0:
|
||||||
|
|
||||||
|
StarterTime = time.time() * 1000
|
||||||
|
response_hex = response.replace(b" ", b"")
|
||||||
|
try:
|
||||||
|
int(response_hex,16)
|
||||||
|
except ValueError:
|
||||||
|
response_hex = binascii.hexlify(response)
|
||||||
|
response_hex = response_hex.upper()
|
||||||
|
|
||||||
|
response_hex = remainder_hex + response_hex
|
||||||
|
print(response_hex)
|
||||||
|
|
||||||
|
except Exception as e1:
|
||||||
|
logging.error("error communicating...: " + str(e1))
|
||||||
|
else:
|
||||||
|
print("Port Opening Failed... trying again in 5 seconds")
|
||||||
|
time.sleep(5)
|
||||||
|
ser.close()
|
||||||
|
except SerialException:
|
||||||
|
print("No port connected... trying again in 5 seconds")
|
||||||
|
time.sleep(5)
|
||||||
58
old/timer_megasport3.py
Normal file
58
old/timer_megasport3.py
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import serial
|
||||||
|
from serial import SerialException
|
||||||
|
import logging
|
||||||
|
import time
|
||||||
|
import binascii
|
||||||
|
|
||||||
|
SerialPort = "COM1"
|
||||||
|
BaudRate = 19200
|
||||||
|
PackageByTime = 0.1
|
||||||
|
PackageByLenght = 256
|
||||||
|
BufferMax = 2000
|
||||||
|
LogFileName = "megasport_new_4.log"
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG,
|
||||||
|
format='%(asctime)s %(levelname)s %(message)s',
|
||||||
|
filename=LogFileName,
|
||||||
|
filemode="w")
|
||||||
|
|
||||||
|
ser = serial.Serial()
|
||||||
|
ser.port = SerialPort
|
||||||
|
ser.baudrate = BaudRate
|
||||||
|
ser.bytesize = serial.EIGHTBITS
|
||||||
|
ser.parity = serial.PARITY_NONE
|
||||||
|
ser.stopbits = serial.STOPBITS_ONE
|
||||||
|
ser.timeout = PackageByTime
|
||||||
|
ser.xonxoff = False
|
||||||
|
ser.rtscts = False
|
||||||
|
ser.dsrdtr = False
|
||||||
|
ser.write_timeout = 2
|
||||||
|
|
||||||
|
# start = b"\xf8"
|
||||||
|
# finish = b"\r"
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
print("Initializing")
|
||||||
|
ser.close()
|
||||||
|
ser.open()
|
||||||
|
if ser.is_open:
|
||||||
|
try:
|
||||||
|
RequestCount = 0
|
||||||
|
print("Port Opening")
|
||||||
|
RetryCount = 0
|
||||||
|
remainder_hex = b""
|
||||||
|
while True:
|
||||||
|
response = ser.read(PackageByLenght)
|
||||||
|
print(response)
|
||||||
|
logging.debug(response)
|
||||||
|
|
||||||
|
|
||||||
|
except Exception as e1:
|
||||||
|
logging.error("error communicating...: " + str(e1))
|
||||||
|
else:
|
||||||
|
print("Port Opening Failed... trying again in 5 seconds")
|
||||||
|
time.sleep(5)
|
||||||
|
ser.close()
|
||||||
|
except SerialException:
|
||||||
|
print("No port connected... trying again in 5 seconds")
|
||||||
|
time.sleep(5)
|
||||||
261
old/timer_megasport5.py
Normal file
261
old/timer_megasport5.py
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
import serial
|
||||||
|
from serial import SerialException
|
||||||
|
import datetime
|
||||||
|
import binascii
|
||||||
|
import logging
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
# Configuration Data (later to be put in Panel2Net.conf)
|
||||||
|
# SerialPort: Name of RPi serial port receiving the panel data
|
||||||
|
# SerialPort = "COM1"
|
||||||
|
SerialPort = "COM2"
|
||||||
|
# BaudRate: Serial port speed (Baud, Default will be adjusted later)
|
||||||
|
BaudRate = 19200
|
||||||
|
# PackageByTime: Time Duration until a package is closed
|
||||||
|
# and sent off (seconds)
|
||||||
|
PackageByTime = 0.1
|
||||||
|
# PackageByLength* Length (in bytes) of data input
|
||||||
|
# until a package is closed and sent off
|
||||||
|
PackageByLength = 128
|
||||||
|
# PackageByLength = 256 попробовать нужно !!!!!!!!!!!!!!!!!!!!
|
||||||
|
# PackageByLength = 80
|
||||||
|
|
||||||
|
# MaxBuffer before flushing (in order to avoid buffer overflow)
|
||||||
|
BufferMax = 2000
|
||||||
|
|
||||||
|
|
||||||
|
# LogFileName: Name of LogFile
|
||||||
|
current_time = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
LogFileName = f"timer_megasport5_{current_time}.log"
|
||||||
|
# LogFileSize Maximum Size of LogFile (in Mbytes)
|
||||||
|
LogFileSize = 10
|
||||||
|
# LogLevel Minimum Severity Level to be logged (see severity in Logs)
|
||||||
|
LogLevel = "E"
|
||||||
|
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format="%(asctime)s %(levelname)s %(message)s",
|
||||||
|
filename=LogFileName,
|
||||||
|
filemode="w",
|
||||||
|
)
|
||||||
|
|
||||||
|
def hexspace(string, length):
|
||||||
|
return ' '.join(string[i:i+length] for i in range(0,len(string),length))
|
||||||
|
|
||||||
|
ser = serial.Serial()
|
||||||
|
ser.port = SerialPort
|
||||||
|
ser.baudrate = BaudRate
|
||||||
|
ser.bytesize = serial.EIGHTBITS
|
||||||
|
# number of bits per bytes
|
||||||
|
ser.parity = serial.PARITY_NONE
|
||||||
|
# set parity check: no parity
|
||||||
|
ser.stopbits = serial.STOPBITS_ONE
|
||||||
|
# number of stop bits
|
||||||
|
ser.timeout = PackageByTime
|
||||||
|
# non-block read
|
||||||
|
ser.xonxoff = False
|
||||||
|
# disable software flow control
|
||||||
|
ser.rtscts = False
|
||||||
|
# disable hardware (RTS/CTS) flow control
|
||||||
|
ser.dsrdtr = False
|
||||||
|
# disable hardware (DSR/DTR) flow control
|
||||||
|
ser.writeTimeout = 2
|
||||||
|
# timeout for write
|
||||||
|
|
||||||
|
PATH = (
|
||||||
|
r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\python\JSON\timer_basketball.json"
|
||||||
|
)
|
||||||
|
new_data = {
|
||||||
|
"timeGFX": "0.0",
|
||||||
|
"time_attackGFX": "",
|
||||||
|
"quarter": "0",
|
||||||
|
"points1": "0",
|
||||||
|
"points2": "0",
|
||||||
|
"foul1": "0",
|
||||||
|
"foul2": "0",
|
||||||
|
"foul_pic1": "",
|
||||||
|
"foul_pic2": "",
|
||||||
|
"time_attac_pic": "",
|
||||||
|
}
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
print("Initializing")
|
||||||
|
ser.close()
|
||||||
|
ser.open()
|
||||||
|
if ser.is_open:
|
||||||
|
try:
|
||||||
|
ser.reset_input_buffer()
|
||||||
|
# flush input buffer, discarding all its contents
|
||||||
|
ser.reset_output_buffer()
|
||||||
|
# flush output buffer, aborting current output
|
||||||
|
# and discard all that is in buffer
|
||||||
|
RequestCount = 0
|
||||||
|
print("Port Opening")
|
||||||
|
# Initialise RetryCounter
|
||||||
|
RetryCount = 0
|
||||||
|
# Initialise Variable to take remainder string
|
||||||
|
remainder_hex = b""
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# Read from Serial Interface
|
||||||
|
response = ser.read(PackageByLength)
|
||||||
|
# print(response)
|
||||||
|
if len(response) > 0:
|
||||||
|
# In case there is something coming down the serial path
|
||||||
|
logging.debug(response)
|
||||||
|
|
||||||
|
if response != b"":
|
||||||
|
data = response
|
||||||
|
# debug line
|
||||||
|
# f.write(data)
|
||||||
|
# f.write("\n")
|
||||||
|
|
||||||
|
cdata = binascii.hexlify(data)
|
||||||
|
ddata = cdata.decode('utf-8')
|
||||||
|
ddata = ddata.upper()
|
||||||
|
print (ddata)
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
print (edata)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# points1 = ""
|
||||||
|
# points2 = ""
|
||||||
|
# quarter = ""
|
||||||
|
# data_str = response.decode(
|
||||||
|
# "ascii", errors="ignore"
|
||||||
|
# ).replace("\r", "|")
|
||||||
|
# if len(data_str) == 53:
|
||||||
|
# pattern = r"^(3 0|7 |8 |69i553 |69i557 |69i558 |5:i553 )(.{4})"
|
||||||
|
# matches = re.findall(pattern, data_str)
|
||||||
|
# for match in matches:
|
||||||
|
# found_value = match[0]
|
||||||
|
# timer_str = match[1]
|
||||||
|
# if match[0] == "3 0":
|
||||||
|
# points1 = data_str[7:10].strip()
|
||||||
|
# points2 = data_str[10:13].strip()
|
||||||
|
# quarter = data_str[13:14].strip()
|
||||||
|
|
||||||
|
# # print(f"Следующие 4 символа: {timer_str}, Найдено: {found_value}, {data_str}_____")
|
||||||
|
# else:
|
||||||
|
# pattern = r"(\|3 0|\|7 |\|8 |\|69i553 |\|69i557 |\|69i558 |\|5:i553 )(.{4})"
|
||||||
|
# matches = re.findall(pattern, data_str)
|
||||||
|
# # print(data_str)
|
||||||
|
# for match in matches:
|
||||||
|
# found_value = match[0]
|
||||||
|
# timer_str = match[1]
|
||||||
|
# if match[0] == "3 0":
|
||||||
|
# points1 = data_str[7:10].strip()
|
||||||
|
# points2 = data_str[10:13].strip()
|
||||||
|
# quarter = data_str[13:14].strip()
|
||||||
|
|
||||||
|
# # print(f"Следующие 4 символа: {timer_str}, Найдено: {found_value}, {data_str}_____")
|
||||||
|
# pattern_attack = r"(.{5})\|"
|
||||||
|
# matches_attack = re.findall(pattern_attack, data_str)
|
||||||
|
# path_pic = r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators"
|
||||||
|
# try:
|
||||||
|
# if matches_attack[0][2:] == "030":
|
||||||
|
# time_attackGFX = ""
|
||||||
|
# time_attac_pic = path_pic + "\\24Sec_empty.png"
|
||||||
|
# else:
|
||||||
|
# hex_dict = {
|
||||||
|
# "I": 9,
|
||||||
|
# "H": 8,
|
||||||
|
# "G": 7,
|
||||||
|
# "F": 6,
|
||||||
|
# "E": 5,
|
||||||
|
# "D": 4,
|
||||||
|
# "C": 3,
|
||||||
|
# "B": 2,
|
||||||
|
# "A": 1,
|
||||||
|
# }
|
||||||
|
# time_attackGFX = matches_attack[0][:2]
|
||||||
|
# if time_attackGFX[-1] in [
|
||||||
|
# "A",
|
||||||
|
# "B",
|
||||||
|
# "C",
|
||||||
|
# "D",
|
||||||
|
# "E",
|
||||||
|
# "F",
|
||||||
|
# "G",
|
||||||
|
# "H",
|
||||||
|
# "I",
|
||||||
|
# ]:
|
||||||
|
# first_character = time_attackGFX[0]
|
||||||
|
# second_character = time_attackGFX[1]
|
||||||
|
# time_attackGFX = str(
|
||||||
|
# int(first_character, 16)
|
||||||
|
# + hex_dict.get(second_character, 0) / 10.0
|
||||||
|
# )
|
||||||
|
# time_attac_pic = path_pic + "\\24Sec_Red.png"
|
||||||
|
# else:
|
||||||
|
# time_attac_pic = path_pic + "\\24Sec_Orange.png"
|
||||||
|
# except IndexError:
|
||||||
|
# pass
|
||||||
|
|
||||||
|
# if timer_str[0] == " ":
|
||||||
|
# if timer_str == " 000":
|
||||||
|
# timer = "0.0"
|
||||||
|
# else:
|
||||||
|
# minites = timer_str[:2]
|
||||||
|
# seconds = timer_str[2:]
|
||||||
|
# timer = f"{int(minites)}:{seconds}".strip()
|
||||||
|
# elif timer_str[-1] == " ":
|
||||||
|
# seconds = timer_str[:2]
|
||||||
|
# milliseconds = timer_str[2:]
|
||||||
|
# timer = f"{int(seconds)}.{milliseconds}".strip()
|
||||||
|
# else:
|
||||||
|
# minites = timer_str[:2]
|
||||||
|
# seconds = timer_str[2:]
|
||||||
|
# timer = f"{int(minites)}:{seconds}".strip()
|
||||||
|
|
||||||
|
# print(
|
||||||
|
# f"Следующие 4 символа: {timer_str}, {timer}, {time_attackGFX}, Найдено: {found_value}, {data_str}_____"
|
||||||
|
# )
|
||||||
|
|
||||||
|
# with open(PATH, "r", encoding="utf-8") as f:
|
||||||
|
# new_data = json.load(f)
|
||||||
|
# new_data = new_data[0]
|
||||||
|
# new_data["timeGFX"] = timer
|
||||||
|
# new_data["time_attackGFX"] = time_attackGFX
|
||||||
|
# new_data["time_attac_pic"] = time_attac_pic
|
||||||
|
# if points1:
|
||||||
|
# new_data["points1"] = points1
|
||||||
|
# new_data["points2"] = points2
|
||||||
|
# new_data["quarter"] = quarter
|
||||||
|
# try:
|
||||||
|
# with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
# json.dump(
|
||||||
|
# [new_data], file, ensure_ascii=False, indent=4
|
||||||
|
# )
|
||||||
|
# except Exception:
|
||||||
|
# pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
# In case nothing is coming down the serial interface
|
||||||
|
print(
|
||||||
|
"\rWaiting for serial input...",
|
||||||
|
end=" ",
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# in case that the Serial Read or HTTP request fails
|
||||||
|
except Exception as e1:
|
||||||
|
print("error communicating...: " + str(e1))
|
||||||
|
logging.error("error communicating...: " + str(e1))
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("Port Opening Failed... trying again in 5 seconds")
|
||||||
|
time.sleep(0.1)
|
||||||
|
ser.close()
|
||||||
|
|
||||||
|
except SerialException:
|
||||||
|
print("No port connected... trying again in 5 seconds")
|
||||||
|
time.sleep(0.1)
|
||||||
25
old/timer_megasport_rider.py
Normal file
25
old/timer_megasport_rider.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
start = "\xf8"
|
||||||
|
finish = "\r"
|
||||||
|
|
||||||
|
with open('megasport_new_5.txt', 'r') as file:
|
||||||
|
new_lines = []
|
||||||
|
current_line = ""
|
||||||
|
capturing = False
|
||||||
|
|
||||||
|
for line in file:
|
||||||
|
if start in line:
|
||||||
|
capturing = True
|
||||||
|
current_line = line[line.index(start):]
|
||||||
|
elif capturing:
|
||||||
|
if finish in line:
|
||||||
|
finish_idx = line.index(finish)
|
||||||
|
current_line += line[:finish_idx + len(finish)]
|
||||||
|
new_lines.append(current_line)
|
||||||
|
current_line = ""
|
||||||
|
capturing = False
|
||||||
|
else:
|
||||||
|
current_line += line
|
||||||
|
|
||||||
|
with open('new_log.txt', 'w') as new_file:
|
||||||
|
for line in new_lines:
|
||||||
|
new_file.write(line + '\n')
|
||||||
363
timer COM copy.py
Normal file
363
timer COM copy.py
Normal file
@@ -0,0 +1,363 @@
|
|||||||
|
# vmix_serial_bridge.py
|
||||||
|
# pip install pyserial requests
|
||||||
|
|
||||||
|
import time
|
||||||
|
import argparse
|
||||||
|
import urllib.parse
|
||||||
|
import requests
|
||||||
|
import serial
|
||||||
|
from serial.serialutil import SerialException
|
||||||
|
from serial.tools import list_ports
|
||||||
|
import re
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from threading import Thread, Event
|
||||||
|
from queue import Queue, Empty
|
||||||
|
|
||||||
|
VMIX_HOST = "http://127.0.0.1:8088"
|
||||||
|
|
||||||
|
VMIX_TARGETS = {
|
||||||
|
"main_time": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": "TIMER.Text", "SelectedIndex": None},
|
||||||
|
"shot_clock": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": "24sec.Text", "SelectedIndex": None},
|
||||||
|
"quarter": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": "QUARTER.Text", "SelectedIndex": None},
|
||||||
|
"score_1": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": "SCORE1.Text", "SelectedIndex": None},
|
||||||
|
"score_2": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": "SCORE2.Text", "SelectedIndex": None},
|
||||||
|
"fouls_1": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": "FOULS1.Text", "SelectedIndex": None},
|
||||||
|
"fouls_2": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": "FOULS2.Text", "SelectedIndex": None},
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---------------- HTTP client ----------------
|
||||||
|
class VmixClient:
|
||||||
|
def __init__(self, host: str, timeout: float = 0.01, retries: int = 3, backoff: float = 0.3):
|
||||||
|
self.host = host.rstrip("/")
|
||||||
|
self.timeout = timeout
|
||||||
|
self.retries = retries
|
||||||
|
self.backoff = backoff
|
||||||
|
self.session = requests.Session()
|
||||||
|
self.session.headers.update({"Connection": "keep-alive"})
|
||||||
|
|
||||||
|
def call(self, function: str, input_id: str, value: str, selected_name=None, selected_index=None) -> bool:
|
||||||
|
params = {"Function": function, "Input": input_id, "Value": value}
|
||||||
|
if selected_name:
|
||||||
|
params["SelectedName"] = selected_name
|
||||||
|
if selected_index is not None:
|
||||||
|
params["SelectedIndex"] = selected_index
|
||||||
|
url = f"{self.host}/api?{urllib.parse.urlencode(params, doseq=True, safe='')}"
|
||||||
|
for attempt in range(1, self.retries + 2):
|
||||||
|
try:
|
||||||
|
r = self.session.get(url, timeout=self.timeout)
|
||||||
|
print(r.status_code())
|
||||||
|
r.raise_for_status()
|
||||||
|
return True
|
||||||
|
except requests.RequestException as e:
|
||||||
|
if attempt > self.retries:
|
||||||
|
print(f"[vMix] ERROR: {e} -> {url}")
|
||||||
|
return False
|
||||||
|
delay = self.backoff * attempt
|
||||||
|
print(f"[vMix] WARN attempt {attempt}: {e}. Retry in {delay:.2f}s")
|
||||||
|
time.sleep(delay)
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class VmixMessage:
|
||||||
|
field: str
|
||||||
|
value: str
|
||||||
|
|
||||||
|
class VmixSender:
|
||||||
|
def __init__(self, client: VmixClient, dedupe: bool = False, max_queue: int = 2000):
|
||||||
|
self.client = client
|
||||||
|
self.queue: Queue[VmixMessage] = Queue(maxsize=max_queue)
|
||||||
|
self.stop_event = Event()
|
||||||
|
self.thread = Thread(target=self._run, name="vmix-sender", daemon=True)
|
||||||
|
self.dedupe = dedupe
|
||||||
|
self._last_sent: dict[str, str | None] = {}
|
||||||
|
|
||||||
|
def start(self): self.thread.start()
|
||||||
|
def stop(self): self.stop_event.set(); self.thread.join(timeout=2)
|
||||||
|
|
||||||
|
# VmixSender
|
||||||
|
def send(self, field: str, value: str | None):
|
||||||
|
if value is None:
|
||||||
|
return
|
||||||
|
if field not in VMIX_TARGETS:
|
||||||
|
return
|
||||||
|
if self.dedupe and self._last_sent.get(field) == value:
|
||||||
|
return
|
||||||
|
if self.dedupe:
|
||||||
|
self._last_sent[field] = value
|
||||||
|
try:
|
||||||
|
self.queue.put_nowait(VmixMessage(field, str(value)))
|
||||||
|
except Exception:
|
||||||
|
try:
|
||||||
|
_ = self.queue.get_nowait(); self.queue.task_done()
|
||||||
|
except Empty:
|
||||||
|
pass
|
||||||
|
self.queue.put_nowait(VmixMessage(field, str(value)))
|
||||||
|
|
||||||
|
|
||||||
|
def _run(self):
|
||||||
|
while not self.stop_event.is_set():
|
||||||
|
try:
|
||||||
|
msg = self.queue.get(timeout=0.2)
|
||||||
|
except Empty:
|
||||||
|
continue
|
||||||
|
t = VMIX_TARGETS[msg.field]
|
||||||
|
ok = self.client.call(t["Function"], t["Input"], msg.value, t.get("SelectedName"), t.get("SelectedIndex"))
|
||||||
|
if ok: print(f"[vMix] {msg.field} <- {msg.value}")
|
||||||
|
self.queue.task_done()
|
||||||
|
|
||||||
|
# ---------------- Parser ----------------
|
||||||
|
def parse_time_5ch(chunk: str) -> str | None:
|
||||||
|
if len(chunk) != 5: return None
|
||||||
|
try:
|
||||||
|
if chunk[0:2] == "0 ":
|
||||||
|
return f"{int(chunk[1:3])}:{int(chunk[3:5]):02d}"
|
||||||
|
# elif len(chunk) == 5:
|
||||||
|
# return f"{int(chunk[1:3])}:{int(chunk[3:5]):02d}"
|
||||||
|
else:
|
||||||
|
return f"{int(chunk[1:3])}.{chunk[3]}"
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def format_shot_clock_from_tail_number(n: int) -> str | None:
|
||||||
|
if n < 0: return ""
|
||||||
|
tail = n % 100
|
||||||
|
if tail != 31: return "" # не обновлять
|
||||||
|
sec_tenths = n // 100
|
||||||
|
return str(sec_tenths // 10) if sec_tenths >= 50 else f"{sec_tenths / 10:.1f}"
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ParsedPacket:
|
||||||
|
main_time: str | None = None
|
||||||
|
score1: str | None = None
|
||||||
|
score2: str | None = None
|
||||||
|
quarter: str | None = None
|
||||||
|
shot_clock: str | None = None
|
||||||
|
|
||||||
|
def parse_line(line: str) -> ParsedPacket | None:
|
||||||
|
clean = line.strip().replace("<EFBFBD>", "")
|
||||||
|
print(clean)
|
||||||
|
# if not clean or len(clean) < 24: return None
|
||||||
|
try:
|
||||||
|
if clean[0] != "3": return None
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
main_time_raw = clean[2:7]
|
||||||
|
main_time = parse_time_5ch(main_time_raw)
|
||||||
|
# print(main_time)
|
||||||
|
|
||||||
|
score1 = clean[7:10].strip()
|
||||||
|
score2 = clean[10:13].strip()
|
||||||
|
|
||||||
|
quarter = None
|
||||||
|
m = re.search(r"\s([1-5])\s\s\d{6}\s", clean)
|
||||||
|
if m: quarter = m.group(1)
|
||||||
|
|
||||||
|
shot_clock = ""
|
||||||
|
tail = clean[-5:]
|
||||||
|
if tail.isdigit():
|
||||||
|
shot_clock = format_shot_clock_from_tail_number(int(tail))
|
||||||
|
return ParsedPacket(
|
||||||
|
main_time=main_time,
|
||||||
|
score1=score1 or None,
|
||||||
|
score2=score2 or None,
|
||||||
|
quarter=quarter,
|
||||||
|
shot_clock=shot_clock,
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---------------- Serial reader ----------------
|
||||||
|
EOLS = {"CR": b"\r", "LF": b"\n", "CRLF": b"\r\n"}
|
||||||
|
|
||||||
|
def sniff_eol(sample: bytes) -> bytes:
|
||||||
|
# простейшая эвристика
|
||||||
|
if b"\r\n" in sample: return EOLS["CRLF"]
|
||||||
|
if b"\r" in sample and b"\n" not in sample: return EOLS["CR"]
|
||||||
|
if b"\n" in sample: return EOLS["LF"]
|
||||||
|
return EOLS["CR"] # дефолт
|
||||||
|
|
||||||
|
class SerialReader:
|
||||||
|
def __init__(self, port: str, baud: int, newline: str, strip_ws: bool, sender: VmixSender,
|
||||||
|
send_quarter: bool, autoeol: bool, bytesize: int, parity: str, stopbits: float,
|
||||||
|
rtscts: bool, xonxoff: bool, dsrdtr: bool):
|
||||||
|
self.port = port
|
||||||
|
self.baud = baud
|
||||||
|
self.eol = EOLS.get(newline.upper(), b"\r")
|
||||||
|
self.strip_ws = strip_ws
|
||||||
|
self.sender = sender
|
||||||
|
self.send_quarter = send_quarter
|
||||||
|
self.autoeol = autoeol
|
||||||
|
self.bytesize = bytesize
|
||||||
|
self.parity = getattr(serial, f"PARITY_{parity.upper()}", serial.PARITY_NONE)
|
||||||
|
self.stopbits = {1: serial.STOPBITS_ONE, 1.5: serial.STOPBITS_ONE_POINT_FIVE, 2: serial.STOPBITS_TWO}[stopbits]
|
||||||
|
self.rtscts = rtscts
|
||||||
|
self.xonxoff = xonxoff
|
||||||
|
self.dsrdtr = dsrdtr
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
with serial.Serial(
|
||||||
|
self.port,
|
||||||
|
baudrate=self.baud,
|
||||||
|
timeout=0.01,
|
||||||
|
bytesize=self.bytesize,
|
||||||
|
parity=self.parity,
|
||||||
|
stopbits=self.stopbits,
|
||||||
|
rtscts=self.rtscts,
|
||||||
|
xonxoff=self.xonxoff,
|
||||||
|
dsrdtr=self.dsrdtr,
|
||||||
|
) as ser:
|
||||||
|
print(f"[serial] OPEN {ser.port} @ {self.baud} ({self.bytesize}{self._parity_name()}{self._stopbits_name()})")
|
||||||
|
# сбросим линии и буферы
|
||||||
|
try:
|
||||||
|
ser.setDTR(True); ser.setRTS(True)
|
||||||
|
except Exception: pass
|
||||||
|
ser.reset_input_buffer(); ser.reset_output_buffer()
|
||||||
|
|
||||||
|
buffer = bytearray()
|
||||||
|
last_feed = time.time()
|
||||||
|
# авто-детект EOL по первому куску
|
||||||
|
if self.autoeol:
|
||||||
|
chunk = ser.read(256)
|
||||||
|
if chunk:
|
||||||
|
self.eol = sniff_eol(chunk)
|
||||||
|
print(f"[serial] auto EOL = {self._eol_name(self.eol)}")
|
||||||
|
buffer.extend(chunk)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
chunk = ser.read(1024)
|
||||||
|
if chunk:
|
||||||
|
buffer.extend(chunk)
|
||||||
|
last_feed = time.time()
|
||||||
|
|
||||||
|
# разбор по EOL
|
||||||
|
progressed = False
|
||||||
|
while True:
|
||||||
|
idx = buffer.find(self.eol)
|
||||||
|
if idx == -1: break
|
||||||
|
line = buffer[:idx]
|
||||||
|
del buffer[: idx + len(self.eol)]
|
||||||
|
text = self._decode(line, self.strip_ws)
|
||||||
|
if text:
|
||||||
|
self._process(text)
|
||||||
|
progressed = True
|
||||||
|
|
||||||
|
# фолбэк: если долго не было EOL, попробуем отдать «как есть»
|
||||||
|
if not progressed and buffer and (time.time() - last_feed) > 0.5:
|
||||||
|
text = self._decode(buffer, self.strip_ws)
|
||||||
|
buffer.clear()
|
||||||
|
if text:
|
||||||
|
self._process(text)
|
||||||
|
|
||||||
|
except SerialException as e:
|
||||||
|
print(f"[serial] ERROR open/read {self.port}: {e}. Retry in 3s...")
|
||||||
|
time.sleep(3)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n[serial] Stopped by user.")
|
||||||
|
return
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[serial] UNEXPECTED: {e}. Retry in 3s...")
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
|
def _decode(self, raw: bytes, strip_ws: bool) -> str | None:
|
||||||
|
try:
|
||||||
|
text = raw.decode("utf-8", errors="replace")
|
||||||
|
except Exception:
|
||||||
|
text = raw.decode("latin-1", errors="replace")
|
||||||
|
if strip_ws: text = text.strip()
|
||||||
|
return text or None
|
||||||
|
|
||||||
|
def _process(self, text: str):
|
||||||
|
pkt = parse_line(text)
|
||||||
|
if not pkt:
|
||||||
|
print(f"[serial] RAW: {text!r}")
|
||||||
|
return
|
||||||
|
if pkt.main_time is not None: self.sender.send("main_time", pkt.main_time)
|
||||||
|
if pkt.score1 is not None: self.sender.send("score_1", pkt.score1)
|
||||||
|
if pkt.score2 is not None: self.sender.send("score_2", pkt.score2)
|
||||||
|
if self.send_quarter and pkt.quarter is not None:
|
||||||
|
self.sender.send("quarter", pkt.quarter)
|
||||||
|
if pkt.shot_clock is not None:
|
||||||
|
self.sender.send("shot_clock", pkt.shot_clock)
|
||||||
|
|
||||||
|
def _parity_name(self): return {"N":"N","E":"E","O":"O","M":"M","S":"S"}[self.parity]
|
||||||
|
def _stopbits_name(self): return {serial.STOPBITS_ONE:"1", serial.STOPBITS_ONE_POINT_FIVE:"1.5", serial.STOPBITS_TWO:"2"}[self.stopbits]
|
||||||
|
def _eol_name(self, e: bytes): return {b"\r":"CR", b"\n":"LF", b"\r\n":"CRLF"}.get(e, f"{e!r}")
|
||||||
|
|
||||||
|
# ---------------- Probe (sniffer) ----------------
|
||||||
|
def probe_port(port: str, baud: int, seconds: int, **kwargs):
|
||||||
|
print("[probe] Available ports:")
|
||||||
|
for p in list_ports.comports():
|
||||||
|
print(f" - {p.device}: {p.description}")
|
||||||
|
try:
|
||||||
|
with serial.Serial(port, baudrate=baud, timeout=0.01) as ser:
|
||||||
|
print(f"[probe] OPEN {ser.port} @ {baud}. Sniffing {seconds}s...")
|
||||||
|
ser.reset_input_buffer()
|
||||||
|
t0 = time.time()
|
||||||
|
total = 0
|
||||||
|
while time.time() - t0 < seconds:
|
||||||
|
b = ser.read(512)
|
||||||
|
if not b: continue
|
||||||
|
total += len(b)
|
||||||
|
print(f"[{len(b):03d} bytes] HEX: {b.hex(' ')}")
|
||||||
|
try:
|
||||||
|
txt = b.decode("utf-8")
|
||||||
|
except Exception:
|
||||||
|
txt = b.decode("latin-1", errors="replace")
|
||||||
|
print(f" TXT: {txt!r}")
|
||||||
|
print(f"[probe] Done. Total bytes: {total}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[probe] ERROR: {e}")
|
||||||
|
|
||||||
|
# ---------------- CLI ----------------
|
||||||
|
def main():
|
||||||
|
ap = argparse.ArgumentParser(description="COM -> vMix bridge with diagnostics")
|
||||||
|
ap.add_argument("--port", required=True, help="e.g. COM2 or /dev/ttyUSB0")
|
||||||
|
ap.add_argument("--baud", type=int, default=19200)
|
||||||
|
ap.add_argument("--newline", choices=["LF", "CRLF", "CR"], default="CR")
|
||||||
|
ap.add_argument("--autoeol", action="store_true", help="Auto-detect EOL from stream")
|
||||||
|
ap.add_argument("--no-strip", action="store_true")
|
||||||
|
ap.add_argument("--vmix-host", default=VMIX_HOST)
|
||||||
|
ap.add_argument("--timeout", type=float, default=0.01)
|
||||||
|
ap.add_argument("--retries", type=int, default=3)
|
||||||
|
ap.add_argument("--backoff", type=float, default=0.3)
|
||||||
|
ap.add_argument("--dedupe", action="store_true")
|
||||||
|
ap.add_argument("--send-quarter", action="store_true")
|
||||||
|
# serial low-level
|
||||||
|
ap.add_argument("--bytesize", type=int, choices=[5,6,7,8], default=8)
|
||||||
|
ap.add_argument("--parity", choices=["N","E","O","M","S"], default="N")
|
||||||
|
ap.add_argument("--stopbits", type=float, choices=[1,1.5,2], default=1)
|
||||||
|
ap.add_argument("--rtscts", action="store_true")
|
||||||
|
ap.add_argument("--xonxoff", action="store_true")
|
||||||
|
ap.add_argument("--dsrdtr", action="store_true")
|
||||||
|
# tools
|
||||||
|
ap.add_argument("--probe", type=int, metavar="SECONDS", help="Sniff raw bytes/text for N seconds and exit")
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
if args.probe:
|
||||||
|
probe_port(args.port, args.baud, args.probe)
|
||||||
|
return
|
||||||
|
|
||||||
|
client = VmixClient(host=args.vmix_host, timeout=args.timeout, retries=args.retries, backoff=args.backoff)
|
||||||
|
sender = VmixSender(client=client, dedupe=args.dedupe); sender.start()
|
||||||
|
|
||||||
|
reader = SerialReader(
|
||||||
|
port=args.port,
|
||||||
|
baud=args.baud,
|
||||||
|
newline=args.newline,
|
||||||
|
strip_ws=not args.no_strip,
|
||||||
|
sender=sender,
|
||||||
|
send_quarter=args.send_quarter,
|
||||||
|
autoeol=args.autoeol,
|
||||||
|
bytesize=args.bytesize,
|
||||||
|
parity=args.parity,
|
||||||
|
stopbits=args.stopbits,
|
||||||
|
rtscts=args.rtscts,
|
||||||
|
xonxoff=args.xonxoff,
|
||||||
|
dsrdtr=args.dsrdtr,
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
reader.run()
|
||||||
|
finally:
|
||||||
|
sender.stop()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
345
timer COM.py
Normal file
345
timer COM.py
Normal file
@@ -0,0 +1,345 @@
|
|||||||
|
# serial_to_vmix.py
|
||||||
|
# pip install pyserial requests
|
||||||
|
|
||||||
|
import time
|
||||||
|
import argparse
|
||||||
|
import socket
|
||||||
|
import urllib.parse
|
||||||
|
import requests
|
||||||
|
import serial
|
||||||
|
from serial.serialutil import SerialException
|
||||||
|
|
||||||
|
# ---------------------------
|
||||||
|
# 1) ВАША функция отправки в vMix
|
||||||
|
# Замените содержимое по своему желанию.
|
||||||
|
# ---------------------------
|
||||||
|
# --- ВСТАВЬТЕ ВАШ serial_to_vmix.py вместо заглушки parse() ---
|
||||||
|
|
||||||
|
import re
|
||||||
|
from dataclasses import dataclass, asdict
|
||||||
|
|
||||||
|
session = requests.Session()
|
||||||
|
session.headers.update({"Connection": "keep-alive"})
|
||||||
|
|
||||||
|
VMIX_HOST = "http://127.0.0.1:8088" # адрес vMix Web Controller
|
||||||
|
|
||||||
|
# куда писать поля в vMix — укажите свои Inputs/поля титров
|
||||||
|
# 1) В блоке VMIX_TARGETS добавьте цель для секундника:
|
||||||
|
VMIX_TARGETS = {
|
||||||
|
"main_time": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": "TIMER.Text", "SelectedIndex": None},
|
||||||
|
"shot_clock": {"Function": "SetText", "Input": "SCOREBUG","SelectedName": "24sec.Text", "SelectedIndex": None}, # ⬅️ ДОБАВЛЕНО
|
||||||
|
"quarter": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": None, "SelectedIndex": None},
|
||||||
|
"score_1": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": "SCORE1.Text", "SelectedIndex": None},
|
||||||
|
"score_2": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": "SCORE2.Text", "SelectedIndex": None},
|
||||||
|
"fouls_1": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": None, "SelectedIndex": None},
|
||||||
|
"fouls_2": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": None, "SelectedIndex": None},
|
||||||
|
}
|
||||||
|
|
||||||
|
def vmix_call(function: str, input_id: str, value: str, selected_name=None, selected_index=None, timeout=1.5):
|
||||||
|
params = {"Function": function, "Input": input_id, "Value": value}
|
||||||
|
if selected_name:
|
||||||
|
params["SelectedName"] = selected_name
|
||||||
|
if selected_index:
|
||||||
|
params["SelectedIndex"] = selected_index
|
||||||
|
url = f"{VMIX_HOST}/api?{urllib.parse.urlencode(params, doseq=True, safe='')}"
|
||||||
|
try:
|
||||||
|
r = session.get(url, timeout=timeout)
|
||||||
|
r.raise_for_status()
|
||||||
|
except requests.RequestException as e:
|
||||||
|
print(f"[vMix] HTTP ошибка: {e} -> {url}")
|
||||||
|
|
||||||
|
# 2) В State замените shot_clock (int) на текстовый shot_clock (str), чтобы иногда писать десятые:
|
||||||
|
@dataclass
|
||||||
|
class State:
|
||||||
|
main_time: str | None = None # "M:SS"
|
||||||
|
shot_clock: str | None = None # ⬅️ теперь строка: "21" или "4.9"
|
||||||
|
quarter: int | None = None
|
||||||
|
score_1: int | None = None
|
||||||
|
score_2: int | None = None
|
||||||
|
fouls_1: int | None = None
|
||||||
|
fouls_2: int | None = None
|
||||||
|
timeouts_1: int | None = None
|
||||||
|
timeouts_2: int | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class SmartBasketParser:
|
||||||
|
# строка «наша» если начинается с мусора и цифры 3, и содержит блок 0000
|
||||||
|
full_line_guard = re.compile(r'^\D*3\b')
|
||||||
|
re_numbers = re.compile(r"\d+")
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.state = State()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _mmss_to_str(n: int) -> str:
|
||||||
|
"""
|
||||||
|
Универсальный форматтер:
|
||||||
|
- < 100 -> 'ss:0'
|
||||||
|
- 3 цифры, s<=59 -> 'M:SS' (MMSS)
|
||||||
|
- 3 цифры, s>59 -> 'ss:ms' (SSd, где ms = десятые)
|
||||||
|
- 4 цифры -> 'M:SS' (MMSS)
|
||||||
|
"""
|
||||||
|
if n < 0:
|
||||||
|
return "0:00"
|
||||||
|
|
||||||
|
# только секунды
|
||||||
|
if n < 100:
|
||||||
|
ss = max(0, min(n, 59))
|
||||||
|
return f"{ss}:0"
|
||||||
|
|
||||||
|
# 3 цифры: либо M:SS, либо SS.d
|
||||||
|
if 100 <= n <= 999:
|
||||||
|
m = n // 100
|
||||||
|
s = n % 100
|
||||||
|
if s <= 59:
|
||||||
|
return f"{m}:{s:02d}" # 102 -> 1:02
|
||||||
|
else:
|
||||||
|
ss = n // 10 # 199 -> 19
|
||||||
|
d = n % 10 # 199 -> 9
|
||||||
|
return f"{ss}.{d}" # 199 -> 19:9
|
||||||
|
|
||||||
|
# 4 цифры: MMSS
|
||||||
|
if 1000 <= n <= 5959:
|
||||||
|
m, s = divmod(n, 100)
|
||||||
|
if s >= 60:
|
||||||
|
m += s // 60
|
||||||
|
s = s % 60
|
||||||
|
return f"{m}:{s:02d}"
|
||||||
|
|
||||||
|
# всё прочее не считаем временем
|
||||||
|
return "0:00"
|
||||||
|
|
||||||
|
def _pick_main_time(self, nums: list[int]) -> str | None:
|
||||||
|
"""
|
||||||
|
В 'полной' строке основное время идёт сразу после ведущей '3'.
|
||||||
|
Если следом '0' — берём через один.
|
||||||
|
Примеры:
|
||||||
|
[3, 0, 58, 35, 35, 2200, 1, ...] -> 58:0
|
||||||
|
[3, 199, 2, 13200, 1, ...] -> 19:9
|
||||||
|
[3, 102, 35, 35, 0000, 1, ...] -> 1:02
|
||||||
|
"""
|
||||||
|
if not nums:
|
||||||
|
return None
|
||||||
|
# nums[0] — это 3
|
||||||
|
idx = 1
|
||||||
|
if len(nums) > 1 and nums[1] == 0:
|
||||||
|
idx = 2
|
||||||
|
if idx < len(nums):
|
||||||
|
t = nums[idx]
|
||||||
|
# считаем временем только разумные токены: секунды/3-цифр. спец./MMSS
|
||||||
|
if (0 <= t <= 59) or (100 <= t <= 999) or (1000 <= t <= 5959):
|
||||||
|
return self._mmss_to_str(t)
|
||||||
|
|
||||||
|
# fallback (на всякий): ищем первый разумный токен до первого 4-значного блока
|
||||||
|
idx_flags = next((i for i, n in enumerate(nums) if len(str(n)) == 4), None)
|
||||||
|
search_upto = idx_flags if idx_flags is not None else len(nums)
|
||||||
|
for n in nums[:search_upto]:
|
||||||
|
if (0 <= n <= 59) or (100 <= n <= 999) or (1000 <= n <= 5959):
|
||||||
|
return self._mmss_to_str(n)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _format_main_time_compact(n: int) -> str:
|
||||||
|
"""
|
||||||
|
Компактный формат 'MMSSd' (например, 13200 -> 13:20.0).
|
||||||
|
m = n // 1000
|
||||||
|
s = (n // 10) % 100
|
||||||
|
d = n % 10 (десятые)
|
||||||
|
Вывод: если m>0 -> 'M:SS', если m==0 -> 'SS:d' (как вы просили '< 1 мин — ss:ms').
|
||||||
|
"""
|
||||||
|
if n < 0:
|
||||||
|
return "0:00"
|
||||||
|
m = n // 1000
|
||||||
|
s = (n // 10) % 100
|
||||||
|
d = n % 10
|
||||||
|
if s >= 60: # подстраховка
|
||||||
|
m += s // 60
|
||||||
|
s = s % 60
|
||||||
|
if m > 0:
|
||||||
|
return f"{m}:{s:02d}"
|
||||||
|
else:
|
||||||
|
return f"{s}:{d}"
|
||||||
|
|
||||||
|
def _format_shot_clock_from_tail_number(self, n: int) -> str | None:
|
||||||
|
"""
|
||||||
|
n — последнее число в строке (например, 21031).
|
||||||
|
Правило валидности: если последние две цифры == 31 — обновляем таймер,
|
||||||
|
если == 30 (или не 31) — не обновляем (возвращаем None).
|
||||||
|
Расчёт: отбрасываем две последние цифры -> n // 100 (секунды * 10).
|
||||||
|
>= 50 -> целые секунды ('21', '20', ...), иначе -> десятые ('4.9', ...).
|
||||||
|
"""
|
||||||
|
if n < 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
tail = n % 100
|
||||||
|
if tail != 31:
|
||||||
|
# 30 — специально игнорируем; всё, что не 31 — тоже игнорим
|
||||||
|
return None
|
||||||
|
|
||||||
|
sec_tenths = n // 100 # «секунды × 10»
|
||||||
|
if sec_tenths >= 50:
|
||||||
|
return str(sec_tenths // 10) # «21», «20», ...
|
||||||
|
else:
|
||||||
|
return f"{sec_tenths / 10:.1f}" # «4.9», «4.8», ..., «0.0»
|
||||||
|
|
||||||
|
|
||||||
|
def _pick_scores_flags_and_quarter(self, nums: list[int]):
|
||||||
|
"""
|
||||||
|
Ищем последовательность: ... s1 s2 F1F2T1T2 Q ...
|
||||||
|
СЧЁТ ОБНОВЛЯЕМ ТОЛЬКО если нашли 4-значный блок флагов (1000..9999).
|
||||||
|
Если флагов нет — возвращаем None для счёта/флагов/четверти,
|
||||||
|
чтобы не перезатирать корректные прошлые значения.
|
||||||
|
"""
|
||||||
|
score1 = score2 = fouls1 = fouls2 = to1 = to2 = quarter = None
|
||||||
|
|
||||||
|
# найдём первый 4-значный блок (флаги)
|
||||||
|
idx_flags = next((i for i, n in enumerate(nums) if 1000 <= n <= 9999), None)
|
||||||
|
if idx_flags is None:
|
||||||
|
# нет флагов -> ничего не обновляем
|
||||||
|
return score1, score2, fouls1, fouls2, to1, to2, quarter
|
||||||
|
|
||||||
|
# перед флагами должны стоять два счёта
|
||||||
|
if idx_flags >= 2:
|
||||||
|
s1, s2 = nums[idx_flags - 2], nums[idx_flags - 1]
|
||||||
|
if 0 <= s1 <= 300 and 0 <= s2 <= 300:
|
||||||
|
score1, score2 = s1, s2
|
||||||
|
|
||||||
|
# разбираем флаги F1F2T1T2
|
||||||
|
f = f"{nums[idx_flags]:04d}"
|
||||||
|
fouls1, fouls2, to1, to2 = map(int, f)
|
||||||
|
|
||||||
|
# четверть — число сразу после флагов (1..10)
|
||||||
|
if idx_flags + 1 < len(nums):
|
||||||
|
q = nums[idx_flags + 1]
|
||||||
|
if 1 <= q <= 10:
|
||||||
|
quarter = q
|
||||||
|
|
||||||
|
return score1, score2, fouls1, fouls2, to1, to2, quarter
|
||||||
|
|
||||||
|
# 4) В parse_line() после nums = [...] добавьте вычисление секундника:
|
||||||
|
def parse_line(self, line: str) -> State | None:
|
||||||
|
if not (self.full_line_guard.search(line) and "0000" in line):
|
||||||
|
return None
|
||||||
|
|
||||||
|
parts = self.re_numbers.findall(line)
|
||||||
|
if not parts:
|
||||||
|
return None
|
||||||
|
nums = [int(p) for p in parts]
|
||||||
|
|
||||||
|
main_time_str = self._pick_main_time(nums)
|
||||||
|
s1, s2, f1, f2, to1, to2, q = self._pick_scores_flags_and_quarter(nums)
|
||||||
|
|
||||||
|
# ⬇️ новый блок: секундник из последнего числа
|
||||||
|
# shot_clock_text = ""
|
||||||
|
# ⬇️ новый безопасный блок секундника
|
||||||
|
shot_clock_text = self.state.shot_clock # по умолчанию — предыдущее значение
|
||||||
|
if nums: # nums уже есть выше: nums = [int(p) for p in parts]
|
||||||
|
sc_new = self._format_shot_clock_from_tail_number(nums[-1])
|
||||||
|
if sc_new is not None:
|
||||||
|
shot_clock_text = sc_new
|
||||||
|
|
||||||
|
out = State(
|
||||||
|
main_time=main_time_str or self.state.main_time,
|
||||||
|
shot_clock=shot_clock_text,
|
||||||
|
score_1 = s1 if s1 is not None else self.state.score_1,
|
||||||
|
score_2 = s2 if s2 is not None else self.state.score_2,
|
||||||
|
fouls_1 = f1 if f1 is not None else self.state.fouls_1,
|
||||||
|
fouls_2 = f2 if f2 is not None else self.state.fouls_2,
|
||||||
|
timeouts_1 = to1 if to1 is not None else self.state.timeouts_1,
|
||||||
|
timeouts_2 = to2 if to2 is not None else self.state.timeouts_2,
|
||||||
|
quarter = q if q is not None else self.state.quarter,
|
||||||
|
)
|
||||||
|
return out
|
||||||
|
|
||||||
|
def update_and_push(self, new_state: State):
|
||||||
|
old = self.state
|
||||||
|
for k, v in asdict(new_state).items():
|
||||||
|
if getattr(old, k) != v and v is not None:
|
||||||
|
self._push_to_vmix(k, v)
|
||||||
|
self.state = new_state
|
||||||
|
|
||||||
|
# 5) В _push_to_vmix оставьте как есть — он уже приводит value к строке.
|
||||||
|
# Если хотите реально отправлять в vMix — раскомментируйте vmix_call:
|
||||||
|
|
||||||
|
def _push_to_vmix(self, key: str, value):
|
||||||
|
t = VMIX_TARGETS.get(key)
|
||||||
|
if not t:
|
||||||
|
return
|
||||||
|
# 👉 РАСКОММЕНТИРУЙТЕ для отправки в vMix
|
||||||
|
vmix_call(
|
||||||
|
function=t["Function"],
|
||||||
|
input_id=t["Input"],
|
||||||
|
value=str(value),
|
||||||
|
selected_name=t.get("SelectedName"),
|
||||||
|
selected_index=t.get("SelectedIndex"),
|
||||||
|
)
|
||||||
|
# print(f"[push] {key} = {value}")
|
||||||
|
|
||||||
|
_parser = SmartBasketParser()
|
||||||
|
|
||||||
|
def parse(data: str):
|
||||||
|
print(data)
|
||||||
|
st = _parser.parse_line(data)
|
||||||
|
if st:
|
||||||
|
_parser.update_and_push(st)
|
||||||
|
else:
|
||||||
|
# полезно видеть, что игнорируем — закомментируйте, если мешает
|
||||||
|
print("[parse] пропуск строки (не формат <20><><EFBFBD><EFBFBD><EFBFBD>3 + 0000)")
|
||||||
|
|
||||||
|
# ---------------------------
|
||||||
|
# 2) Чтение из COM-порта и вызов parse
|
||||||
|
# ---------------------------
|
||||||
|
def read_loop(port: str, baud: int, newline: str, strip_whitespace: bool):
|
||||||
|
# мапинг для окончания строк в pyserial
|
||||||
|
eol = {"CRLF": b"\r\n", "LF": b"\n", "CR": b"\r"}.get(newline.upper(), b"\n")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
with serial.Serial(port, baudrate=baud) as ser:
|
||||||
|
print(f"[serial] открыт {ser.port} @ {baud} бод. Ожидаю данные...")
|
||||||
|
buffer = bytearray()
|
||||||
|
while True:
|
||||||
|
chunk = ser.read(1024)
|
||||||
|
if not chunk:
|
||||||
|
continue
|
||||||
|
buffer.extend(chunk)
|
||||||
|
# разбираем по разделителю строк
|
||||||
|
while True:
|
||||||
|
idx = buffer.find(eol)
|
||||||
|
if idx == -1:
|
||||||
|
break
|
||||||
|
line = buffer[:idx]
|
||||||
|
del buffer[:idx + len(eol)]
|
||||||
|
try:
|
||||||
|
text = line.decode("utf-8", errors="replace")
|
||||||
|
except Exception:
|
||||||
|
text = line.decode("latin-1", errors="replace")
|
||||||
|
if strip_whitespace:
|
||||||
|
text = text.strip()
|
||||||
|
if text != "":
|
||||||
|
parse(text)
|
||||||
|
except SerialException as e:
|
||||||
|
print(f"[serial] не удалось открыть/читать {port}: {e}. Повтор через 3 сек...")
|
||||||
|
time.sleep(3)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n[serial] остановлено пользователем.")
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[serial] непредвиденная ошибка: {e}. Повтор через 3 сек...")
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
ap = argparse.ArgumentParser(description="Чтение COM и отправка в vMix через parse()")
|
||||||
|
ap.add_argument("--port", required=True, help="COM-порт, напр. COM3 (Windows) или /dev/ttyUSB0 (Linux)")
|
||||||
|
ap.add_argument("--baud", type=int, default=19200, help="Скорость, по умолчанию 19200")
|
||||||
|
ap.add_argument("--newline", choices=["LF", "CRLF", "CR"], default="CR",
|
||||||
|
help="Разделитель строк, по умолчанию LF")
|
||||||
|
ap.add_argument("--no-strip", action="store_true",
|
||||||
|
help="Не обрезать пробелы по краям (по умолчанию обрезаем)")
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
read_loop(args.port, args.baud, args.newline, strip_whitespace=not args.no_strip)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
486
timer COM3.py
Normal file
486
timer COM3.py
Normal file
@@ -0,0 +1,486 @@
|
|||||||
|
# vmix_serial_bridge_optimized.py
|
||||||
|
# pip install pyserial requests
|
||||||
|
|
||||||
|
"""
|
||||||
|
Оптимизированная версия COM -> vMix моста для максимально быстрой доставки
|
||||||
|
данных в vMix. Ключевые изменения:
|
||||||
|
- Немедленная обработка входящих байт: неблокирующее чтение с малой задержкой
|
||||||
|
(timeout) и мгновенная отправка строк при появлении EOL или коротком «простоя».
|
||||||
|
- Параметризуемые интервалы: --read-timeout, --idle-flush для тонкой настройки
|
||||||
|
задержки между получением и отправкой.
|
||||||
|
- Убраны лишние print'ы, добавлен флаг --verbose для отладки без штрафа к скорости.
|
||||||
|
- Дедупликация значений к vMix включаемая флагом (по умолчанию включена).
|
||||||
|
- Предкомпиляция регулярных выражений и мелкие микроптимизации парсера.
|
||||||
|
- Очередь отправки без блокировок и аккуратное «сбросить-старое-сообщение» поведение
|
||||||
|
на переполнении.
|
||||||
|
|
||||||
|
Совместима с прежней CLI, но добавлены новые опции:
|
||||||
|
--read-timeout (сек, по умолчанию 0.03)
|
||||||
|
--idle-flush (сек, по умолчанию 0.06)
|
||||||
|
--max-chunk (байт, по умолчанию 512)
|
||||||
|
--verbose (подробные логи)
|
||||||
|
|
||||||
|
Пример запуска:
|
||||||
|
python vmix_serial_bridge_optimized.py --port COM2 --baud 19200 --autoeol \
|
||||||
|
--send-quarter --dedupe --read-timeout 0.02 --idle-flush 0.05
|
||||||
|
"""
|
||||||
|
|
||||||
|
import time
|
||||||
|
import argparse
|
||||||
|
import urllib.parse
|
||||||
|
import requests
|
||||||
|
import serial
|
||||||
|
from serial.serialutil import SerialException
|
||||||
|
from serial.tools import list_ports
|
||||||
|
import re
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from threading import Thread, Event
|
||||||
|
from queue import Queue, Empty
|
||||||
|
from typing import Optional, Dict
|
||||||
|
|
||||||
|
VMIX_HOST = "http://127.0.0.1:8088"
|
||||||
|
|
||||||
|
VMIX_TARGETS = {
|
||||||
|
"main_time": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": "TIMER.Text", "SelectedIndex": None},
|
||||||
|
"shot_clock": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": "24sec.Text", "SelectedIndex": None},
|
||||||
|
"quarter": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": "QUARTER.Text", "SelectedIndex": None},
|
||||||
|
"score_1": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": "SCORE1.Text", "SelectedIndex": None},
|
||||||
|
"score_2": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": "SCORE2.Text", "SelectedIndex": None},
|
||||||
|
"fouls_1": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": "FOULS1.Text", "SelectedIndex": None},
|
||||||
|
"fouls_2": {"Function": "SetText", "Input": "SCOREBUG", "SelectedName": "FOULS2.Text", "SelectedIndex": None},
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---------------- HTTP client ----------------
|
||||||
|
class VmixClient:
|
||||||
|
def __init__(self, host: str, timeout: float = 0.01, retries: int = 2, backoff: float = 0.2):
|
||||||
|
self.host = host.rstrip("/")
|
||||||
|
self.timeout = timeout
|
||||||
|
self.retries = retries
|
||||||
|
self.backoff = backoff
|
||||||
|
self.session = requests.Session()
|
||||||
|
self.session.headers.update({"Connection": "keep-alive"})
|
||||||
|
|
||||||
|
def call(self, function: str, input_id: str, value: str, selected_name=None, selected_index=None) -> bool:
|
||||||
|
params = {"Function": function, "Input": input_id, "Value": value}
|
||||||
|
if selected_name:
|
||||||
|
params["SelectedName"] = selected_name
|
||||||
|
if selected_index is not None:
|
||||||
|
params["SelectedIndex"] = selected_index
|
||||||
|
url = f"{self.host}/api?{urllib.parse.urlencode(params, doseq=True, safe='')}"
|
||||||
|
for attempt in range(1, self.retries + 2):
|
||||||
|
try:
|
||||||
|
r = self.session.get(url, timeout=self.timeout)
|
||||||
|
r.raise_for_status()
|
||||||
|
return True
|
||||||
|
except requests.RequestException as e:
|
||||||
|
if attempt > self.retries:
|
||||||
|
return False
|
||||||
|
time.sleep(self.backoff * attempt)
|
||||||
|
return False
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class VmixMessage:
|
||||||
|
field: str
|
||||||
|
value: str
|
||||||
|
|
||||||
|
class VmixSender:
|
||||||
|
def __init__(self, client: VmixClient, dedupe: bool = True, max_queue: int = 4096, verbose: bool = False):
|
||||||
|
self.client = client
|
||||||
|
self.queue: Queue[VmixMessage] = Queue(maxsize=max_queue)
|
||||||
|
self.stop_event = Event()
|
||||||
|
self.thread = Thread(target=self._run, name="vmix-sender", daemon=True)
|
||||||
|
self.dedupe = dedupe
|
||||||
|
self._last_sent: Dict[str, Optional[str]] = {}
|
||||||
|
self.verbose = verbose
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
self.thread.start()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.stop_event.set()
|
||||||
|
self.thread.join(timeout=2)
|
||||||
|
|
||||||
|
def send(self, field: str, value: Optional[str]):
|
||||||
|
if value is None:
|
||||||
|
return
|
||||||
|
if field not in VMIX_TARGETS:
|
||||||
|
return
|
||||||
|
if self.dedupe and self._last_sent.get(field) == value:
|
||||||
|
return
|
||||||
|
if self.dedupe:
|
||||||
|
self._last_sent[field] = value
|
||||||
|
msg = VmixMessage(field, str(value))
|
||||||
|
try:
|
||||||
|
self.queue.put_nowait(msg)
|
||||||
|
except Exception:
|
||||||
|
# Сбрасываем самое старое сообщение, чтобы не накапливать задержку
|
||||||
|
try:
|
||||||
|
_ = self.queue.get_nowait()
|
||||||
|
self.queue.task_done()
|
||||||
|
except Empty:
|
||||||
|
pass
|
||||||
|
self.queue.put_nowait(msg)
|
||||||
|
|
||||||
|
def _run(self):
|
||||||
|
while not self.stop_event.is_set():
|
||||||
|
try:
|
||||||
|
msg = self.queue.get(timeout=0.01)
|
||||||
|
except Empty:
|
||||||
|
continue
|
||||||
|
t = VMIX_TARGETS[msg.field]
|
||||||
|
ok = self.client.call(t["Function"], t["Input"], msg.value, t.get("SelectedName"), t.get("SelectedIndex"))
|
||||||
|
if self.verbose:
|
||||||
|
if ok:
|
||||||
|
print(f"[vMix] {msg.field} <- {msg.value}")
|
||||||
|
else:
|
||||||
|
print(f"[vMix] ERROR send {msg.field} <- {msg.value}")
|
||||||
|
self.queue.task_done()
|
||||||
|
|
||||||
|
# ---------------- Parser ----------------
|
||||||
|
_QUARTER_RE = re.compile(r"\s([1-5])\s\s\d{6}\s")
|
||||||
|
|
||||||
|
def parse_time_5ch(chunk: str) -> Optional[str]:
|
||||||
|
if len(chunk) != 5:
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
if chunk[0:2] == "0 " or chunk[0:2] == " ":
|
||||||
|
print(f"{int(chunk[1:3])}:{int(chunk[3:5]):02d}")
|
||||||
|
return f"{int(chunk[1:3])}:{int(chunk[3:5]):02d}"
|
||||||
|
else:
|
||||||
|
return f"{int(chunk[1:3])}.{chunk[3]}"
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def format_shot_clock_from_tail_number(n: str) -> str:
|
||||||
|
tail = n[-2:]
|
||||||
|
if tail == "30":
|
||||||
|
return "" # не обновлять
|
||||||
|
num = n[:2]
|
||||||
|
word_to_int = "ABCDEFGHI@"
|
||||||
|
if n[1] in word_to_int:
|
||||||
|
return f"{num[0]}.{word_to_int.index(num[1])+1 if num[1] != '@' else '0'}"
|
||||||
|
else:
|
||||||
|
return num
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ParsedPacket:
|
||||||
|
main_time: Optional[str] = None
|
||||||
|
score1: Optional[str] = None
|
||||||
|
score2: Optional[str] = None
|
||||||
|
quarter: Optional[str] = None
|
||||||
|
shot_clock: Optional[str] = None
|
||||||
|
|
||||||
|
def parse_line(line: str, verbose: bool = False) -> Optional[ParsedPacket]:
|
||||||
|
clean = line.strip().replace("<EFBFBD>", "")
|
||||||
|
if len(clean) != 52:
|
||||||
|
clean = clean[-52:]
|
||||||
|
print(clean)
|
||||||
|
if not clean or clean[0] not in ["3", "7", "8"]:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# фиксированные позиции — всегда
|
||||||
|
main_time_raw = clean[2:7]
|
||||||
|
main_time = parse_time_5ch(main_time_raw)
|
||||||
|
|
||||||
|
# score1/score2 есть только если строка начинается с "3"
|
||||||
|
score1 = None
|
||||||
|
score2 = None
|
||||||
|
if clean and clean[0] == "3":
|
||||||
|
s1 = clean[7:10].strip()
|
||||||
|
s2 = clean[10:13].strip()
|
||||||
|
if s1:
|
||||||
|
score1 = s1
|
||||||
|
if s2:
|
||||||
|
score2 = s2
|
||||||
|
|
||||||
|
# четверть — всегда, если найдётся
|
||||||
|
quarter = None
|
||||||
|
m = _QUARTER_RE.search(clean)
|
||||||
|
if m:
|
||||||
|
quarter = m.group(1)
|
||||||
|
|
||||||
|
# шот-клок — всегда, если хвост — число
|
||||||
|
shot_clock = None
|
||||||
|
tail = clean[-5:]
|
||||||
|
shot_clock = format_shot_clock_from_tail_number(tail)
|
||||||
|
|
||||||
|
return ParsedPacket(
|
||||||
|
main_time=main_time,
|
||||||
|
score1=score1,
|
||||||
|
score2=score2,
|
||||||
|
quarter=quarter,
|
||||||
|
shot_clock=shot_clock,
|
||||||
|
)# ---------------- Serial reader ----------------
|
||||||
|
EOLS = {"CR": b"\r", "LF": b"\n", "CRLF": b"\r\n"}
|
||||||
|
|
||||||
|
|
||||||
|
def sniff_eol(sample: bytes) -> bytes:
|
||||||
|
if b"\r\n" in sample:
|
||||||
|
return EOLS["CRLF"]
|
||||||
|
if b"\r" in sample and b"\n" not in sample:
|
||||||
|
return EOLS["CR"]
|
||||||
|
if b"\n" in sample:
|
||||||
|
return EOLS["LF"]
|
||||||
|
return EOLS["CR"]
|
||||||
|
|
||||||
|
class SerialReader:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
port: str,
|
||||||
|
baud: int,
|
||||||
|
newline: str,
|
||||||
|
strip_ws: bool,
|
||||||
|
sender: VmixSender,
|
||||||
|
send_quarter: bool,
|
||||||
|
autoeol: bool,
|
||||||
|
bytesize: int,
|
||||||
|
parity: str,
|
||||||
|
stopbits: float,
|
||||||
|
rtscts: bool,
|
||||||
|
xonxoff: bool,
|
||||||
|
dsrdtr: bool,
|
||||||
|
read_timeout: float = 0.03,
|
||||||
|
idle_flush: float = 0.06,
|
||||||
|
max_chunk: int = 512,
|
||||||
|
verbose: bool = False,
|
||||||
|
):
|
||||||
|
self.port = port
|
||||||
|
self.baud = baud
|
||||||
|
self.eol = EOLS.get(newline.upper(), b"\r")
|
||||||
|
self.strip_ws = strip_ws
|
||||||
|
self.sender = sender
|
||||||
|
self.send_quarter = send_quarter
|
||||||
|
self.autoeol = autoeol
|
||||||
|
self.bytesize = bytesize
|
||||||
|
self.parity = getattr(serial, f"PARITY_{parity.upper()}", serial.PARITY_NONE)
|
||||||
|
self.stopbits = {1: serial.STOPBITS_ONE, 1.5: serial.STOPBITS_ONE_POINT_FIVE, 2: serial.STOPBITS_TWO}[stopbits]
|
||||||
|
self.rtscts = rtscts
|
||||||
|
self.xonxoff = xonxoff
|
||||||
|
self.dsrdtr = dsrdtr
|
||||||
|
self.read_timeout = max(0.0, float(read_timeout))
|
||||||
|
self.idle_flush = max(0.0, float(idle_flush))
|
||||||
|
self.max_chunk = max(1, int(max_chunk))
|
||||||
|
self.verbose = verbose
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
with serial.Serial(
|
||||||
|
self.port,
|
||||||
|
baudrate=self.baud,
|
||||||
|
timeout=self.read_timeout, # КЛЮЧЕВОЕ: неблокирующее чтение
|
||||||
|
write_timeout=0.01,
|
||||||
|
bytesize=self.bytesize,
|
||||||
|
parity=self.parity,
|
||||||
|
stopbits=self.stopbits,
|
||||||
|
rtscts=self.rtscts,
|
||||||
|
xonxoff=self.xonxoff,
|
||||||
|
dsrdtr=self.dsrdtr,
|
||||||
|
) as ser:
|
||||||
|
# if self.verbose:
|
||||||
|
# print(
|
||||||
|
# f"[serial] OPEN {ser.port} @ {self.baud} ({self.bytesize}{self._parity_name()}{self._stopbits_name()})"
|
||||||
|
# )
|
||||||
|
try:
|
||||||
|
ser.setDTR(True)
|
||||||
|
ser.setRTS(True)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
ser.reset_input_buffer()
|
||||||
|
ser.reset_output_buffer()
|
||||||
|
|
||||||
|
buffer = bytearray()
|
||||||
|
last_feed = time.time()
|
||||||
|
|
||||||
|
# Авто-детект EOL: быстрый сэмпл
|
||||||
|
if self.autoeol:
|
||||||
|
sample_t0 = time.time()
|
||||||
|
while time.time() - sample_t0 < 0.15: # ~150 мс
|
||||||
|
n = ser.in_waiting
|
||||||
|
if n:
|
||||||
|
chunk = ser.read(min(n, self.max_chunk))
|
||||||
|
if chunk:
|
||||||
|
buffer.extend(chunk)
|
||||||
|
if buffer:
|
||||||
|
self.eol = sniff_eol(buffer)
|
||||||
|
if self.verbose:
|
||||||
|
print(f"[serial] auto EOL = {self._eol_name(self.eol)}")
|
||||||
|
break
|
||||||
|
|
||||||
|
while True:
|
||||||
|
n = ser.in_waiting
|
||||||
|
if n:
|
||||||
|
chunk = ser.read(min(n, self.max_chunk))
|
||||||
|
else:
|
||||||
|
# читаем «минимум 1 байт», чтобы не спиниться
|
||||||
|
chunk = ser.read(1)
|
||||||
|
|
||||||
|
if chunk:
|
||||||
|
buffer.extend(chunk)
|
||||||
|
last_feed = time.time()
|
||||||
|
|
||||||
|
progressed = False
|
||||||
|
while True:
|
||||||
|
idx = buffer.find(self.eol)
|
||||||
|
if idx == -1:
|
||||||
|
break
|
||||||
|
line = buffer[:idx]
|
||||||
|
del buffer[: idx + len(self.eol)]
|
||||||
|
text = self._decode(line, self.strip_ws)
|
||||||
|
if text:
|
||||||
|
self._process(text)
|
||||||
|
progressed = True
|
||||||
|
|
||||||
|
# Если нет EOL и давно не приходили байты — отдаём накопленное
|
||||||
|
if not progressed and buffer and (time.time() - last_feed) >= self.idle_flush:
|
||||||
|
text = self._decode(buffer, self.strip_ws)
|
||||||
|
buffer.clear()
|
||||||
|
if text:
|
||||||
|
self._process(text)
|
||||||
|
|
||||||
|
except SerialException as e:
|
||||||
|
if self.verbose:
|
||||||
|
print(f"[serial] ERROR open/read {self.port}: {e}. Retry in 0.5s...")
|
||||||
|
time.sleep(0.5)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
if self.verbose:
|
||||||
|
print("\n[serial] Stopped by user.")
|
||||||
|
return
|
||||||
|
except Exception as e:
|
||||||
|
if self.verbose:
|
||||||
|
print(f"[serial] UNEXPECTED: {e}. Retry in 0.5s...")
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
def _decode(self, raw: bytes, strip_ws: bool) -> Optional[str]:
|
||||||
|
try:
|
||||||
|
text = raw.decode("utf-8", errors="replace")
|
||||||
|
except Exception:
|
||||||
|
text = raw.decode("latin-1", errors="replace")
|
||||||
|
if strip_ws:
|
||||||
|
text = text.strip()
|
||||||
|
return text or None
|
||||||
|
|
||||||
|
def _process(self, text: str):
|
||||||
|
pkt = parse_line(text, verbose=self.verbose)
|
||||||
|
if not pkt:
|
||||||
|
if self.verbose:
|
||||||
|
print(f"[serial] RAW: {text!r}")
|
||||||
|
return
|
||||||
|
if pkt.main_time is not None:
|
||||||
|
self.sender.send("main_time", pkt.main_time)
|
||||||
|
if pkt.score1 is not None:
|
||||||
|
self.sender.send("score_1", pkt.score1)
|
||||||
|
if pkt.score2 is not None:
|
||||||
|
self.sender.send("score_2", pkt.score2)
|
||||||
|
if self.send_quarter and pkt.quarter is not None:
|
||||||
|
self.sender.send("quarter", pkt.quarter)
|
||||||
|
if pkt.shot_clock is not None:
|
||||||
|
self.sender.send("shot_clock", pkt.shot_clock)
|
||||||
|
|
||||||
|
def _parity_name(self):
|
||||||
|
return {"N": "N", "E": "E", "O": "O", "M": "M", "S": "S"}[self.parity]
|
||||||
|
|
||||||
|
def _stopbits_name(self):
|
||||||
|
return {
|
||||||
|
serial.STOPBITS_ONE: "1",
|
||||||
|
serial.STOPBITS_ONE_POINT_FIVE: "1.5",
|
||||||
|
serial.STOPBITS_TWO: "2",
|
||||||
|
}[self.stopbits]
|
||||||
|
|
||||||
|
def _eol_name(self, e: bytes):
|
||||||
|
return {b"\r": "CR", b"\n": "LF", b"\r\n": "CRLF"}.get(e, f"{e!r}")
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Probe (sniffer) ----------------
|
||||||
|
|
||||||
|
def probe_port(port: str, baud: int, seconds: int, **kwargs):
|
||||||
|
print("[probe] Available ports:")
|
||||||
|
for p in list_ports.comports():
|
||||||
|
print(f" - {p.device}: {p.description}")
|
||||||
|
try:
|
||||||
|
with serial.Serial(port, baudrate=baud) as ser:
|
||||||
|
print(f"[probe] OPEN {ser.port} @ {baud}. Sniffing {seconds}s...")
|
||||||
|
ser.reset_input_buffer()
|
||||||
|
t0 = time.time()
|
||||||
|
total = 0
|
||||||
|
while time.time() - t0 < seconds:
|
||||||
|
b = ser.read(512)
|
||||||
|
if not b:
|
||||||
|
continue
|
||||||
|
total += len(b)
|
||||||
|
print(f"[{len(b):03d} bytes] HEX: {b.hex(' ')}")
|
||||||
|
try:
|
||||||
|
txt = b.decode("utf-8")
|
||||||
|
except Exception:
|
||||||
|
txt = b.decode("latin-1", errors="replace")
|
||||||
|
print(f" TXT: {txt!r}")
|
||||||
|
print(f"[probe] Done. Total bytes: {total}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[probe] ERROR: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- CLI ----------------
|
||||||
|
|
||||||
|
def main():
|
||||||
|
ap = argparse.ArgumentParser(description="COM -> vMix bridge (optimized)")
|
||||||
|
ap.add_argument("--port", required=True, help="e.g. COM2 or /dev/ttyUSB0")
|
||||||
|
ap.add_argument("--baud", type=int, default=19200)
|
||||||
|
ap.add_argument("--newline", choices=["LF", "CRLF", "CR"], default="CR")
|
||||||
|
ap.add_argument("--autoeol", action="store_true", help="Auto-detect EOL from stream")
|
||||||
|
ap.add_argument("--no-strip", action="store_true")
|
||||||
|
ap.add_argument("--vmix-host", default=VMIX_HOST)
|
||||||
|
ap.add_argument("--timeout", type=float, default=0.01)
|
||||||
|
ap.add_argument("--retries", type=int, default=2)
|
||||||
|
ap.add_argument("--backoff", type=float, default=0.2)
|
||||||
|
ap.add_argument("--dedupe", action="store_true", help="Deduplicate values before sending to vMix")
|
||||||
|
ap.add_argument("--send-quarter", action="store_true")
|
||||||
|
ap.add_argument("--read-timeout", type=float, default=0.03, help="Serial read timeout (s)")
|
||||||
|
ap.add_argument("--idle-flush", type=float, default=0.06, help="Flush partial line after idle (s)")
|
||||||
|
ap.add_argument("--max-chunk", type=int, default=512, help="Max bytes per read()")
|
||||||
|
ap.add_argument("--verbose", action="store_true")
|
||||||
|
# serial low-level
|
||||||
|
ap.add_argument("--bytesize", type=int, choices=[5, 6, 7, 8], default=8)
|
||||||
|
ap.add_argument("--parity", choices=["N", "E", "O", "M", "S"], default="N")
|
||||||
|
ap.add_argument("--stopbits", type=float, choices=[1, 1.5, 2], default=1)
|
||||||
|
ap.add_argument("--rtscts", action="store_true")
|
||||||
|
ap.add_argument("--xonxoff", action="store_true")
|
||||||
|
ap.add_argument("--dsrdtr", action="store_true")
|
||||||
|
# tools
|
||||||
|
ap.add_argument("--probe", type=int, metavar="SECONDS", help="Sniff raw bytes/text for N seconds and exit")
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
if args.probe:
|
||||||
|
probe_port(args.port, args.baud, args.probe)
|
||||||
|
return
|
||||||
|
|
||||||
|
client = VmixClient(host=args.vmix_host, timeout=args.timeout, retries=args.retries, backoff=args.backoff)
|
||||||
|
sender = VmixSender(client=client, dedupe=args.dedupe or True, verbose=args.verbose)
|
||||||
|
sender.start()
|
||||||
|
|
||||||
|
reader = SerialReader(
|
||||||
|
port=args.port,
|
||||||
|
baud=args.baud,
|
||||||
|
newline=args.newline,
|
||||||
|
strip_ws=not args.no_strip,
|
||||||
|
sender=sender,
|
||||||
|
send_quarter=args.send_quarter,
|
||||||
|
autoeol=args.autoeol,
|
||||||
|
bytesize=args.bytesize,
|
||||||
|
parity=args.parity,
|
||||||
|
stopbits=args.stopbits,
|
||||||
|
rtscts=args.rtscts,
|
||||||
|
xonxoff=args.xonxoff,
|
||||||
|
dsrdtr=args.dsrdtr,
|
||||||
|
read_timeout=args.read_timeout,
|
||||||
|
idle_flush=args.idle_flush,
|
||||||
|
max_chunk=args.max_chunk,
|
||||||
|
verbose=args.verbose,
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
reader.run()
|
||||||
|
finally:
|
||||||
|
sender.stop()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
117
timer GPT 1.py
Normal file
117
timer GPT 1.py
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
# serial_to_vmix.py
|
||||||
|
# pip install pyserial requests
|
||||||
|
|
||||||
|
import time
|
||||||
|
import argparse
|
||||||
|
import socket
|
||||||
|
import urllib.parse
|
||||||
|
import requests
|
||||||
|
import serial
|
||||||
|
from serial.serialutil import SerialException
|
||||||
|
|
||||||
|
# ---------------------------
|
||||||
|
# 1) ВАША функция отправки в vMix
|
||||||
|
# Замените содержимое по своему желанию.
|
||||||
|
# ---------------------------
|
||||||
|
def parse(data: str):
|
||||||
|
"""
|
||||||
|
Пользовательская обработка/отправка данных в vMix.
|
||||||
|
Здесь просто печатаем; замените на вашу логику.
|
||||||
|
"""
|
||||||
|
print(f"[parse] {data}")
|
||||||
|
|
||||||
|
# ---- ПРИМЕРЫ реализации parse (раскомментируйте нужное) ----
|
||||||
|
# Пример A: отправка через vMix HTTP API (SetText в определённый input/title)
|
||||||
|
# def parse(data: str):
|
||||||
|
# vmix_host = "http://127.0.0.1:8088" # адрес vMix Web Controller
|
||||||
|
# function = "SetText"
|
||||||
|
# input_id = "1" # замените на ваш Input (номер/имя/строка GUID)
|
||||||
|
# selected_title = None # если нужно указать конкретный Title layer: "TitleName.xaml"
|
||||||
|
# field = None # если нужно указать конкретное текстовое поле в титре
|
||||||
|
#
|
||||||
|
# params = {
|
||||||
|
# "Function": function,
|
||||||
|
# "Input": input_id,
|
||||||
|
# "Value": data
|
||||||
|
# }
|
||||||
|
# if selected_title:
|
||||||
|
# params["SelectedName"] = selected_title
|
||||||
|
# if field:
|
||||||
|
# params["SelectedIndex"] = field
|
||||||
|
#
|
||||||
|
# # важно: корректно кодируем Value
|
||||||
|
# url = f"{vmix_host}/api?{urllib.parse.urlencode(params, doseq=True, safe='')}"
|
||||||
|
# try:
|
||||||
|
# r = requests.get(url, timeout=2)
|
||||||
|
# r.raise_for_status()
|
||||||
|
# except requests.RequestException as e:
|
||||||
|
# print(f"[parse][HTTP] ошибка запроса к vMix: {e}")
|
||||||
|
|
||||||
|
# Пример B: отправка одной строки в vMix TCP (порт 8099) — например, выполнить функцию
|
||||||
|
# def parse(data: str):
|
||||||
|
# vmix_tcp_host = "127.0.0.1"
|
||||||
|
# vmix_tcp_port = 8099
|
||||||
|
# # пример: выполнить SetText
|
||||||
|
# cmd = f"FUNCTION SetText Input=1 Value=\"{data}\"\r\n"
|
||||||
|
# try:
|
||||||
|
# with socket.create_connection((vmix_tcp_host, vmix_tcp_port), timeout=2) as s:
|
||||||
|
# s.sendall(cmd.encode("utf-8"))
|
||||||
|
# except OSError as e:
|
||||||
|
# print(f"[parse][TCP] ошибка сокета к vMix: {e}")
|
||||||
|
|
||||||
|
# ---------------------------
|
||||||
|
# 2) Чтение из COM-порта и вызов parse
|
||||||
|
# ---------------------------
|
||||||
|
def read_loop(port: str, baud: int, newline: str, strip_whitespace: bool):
|
||||||
|
# мапинг для окончания строк в pyserial
|
||||||
|
eol = {"CRLF": b"\r\n", "LF": b"\n", "CR": b"\r"}.get(newline.upper(), b"\n")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
with serial.Serial(port, baudrate=baud, timeout=1) as ser:
|
||||||
|
print(f"[serial] открыт {ser.port} @ {baud} бод. Ожидаю данные...")
|
||||||
|
buffer = bytearray()
|
||||||
|
while True:
|
||||||
|
chunk = ser.read(1024)
|
||||||
|
if not chunk:
|
||||||
|
continue
|
||||||
|
buffer.extend(chunk)
|
||||||
|
# разбираем по разделителю строк
|
||||||
|
while True:
|
||||||
|
idx = buffer.find(eol)
|
||||||
|
if idx == -1:
|
||||||
|
break
|
||||||
|
line = buffer[:idx]
|
||||||
|
del buffer[:idx + len(eol)]
|
||||||
|
try:
|
||||||
|
text = line.decode("utf-8", errors="replace")
|
||||||
|
except Exception:
|
||||||
|
text = line.decode("latin-1", errors="replace")
|
||||||
|
if strip_whitespace:
|
||||||
|
text = text.strip()
|
||||||
|
if text != "":
|
||||||
|
parse(text)
|
||||||
|
except SerialException as e:
|
||||||
|
print(f"[serial] не удалось открыть/читать {port}: {e}. Повтор через 3 сек...")
|
||||||
|
time.sleep(3)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n[serial] остановлено пользователем.")
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[serial] непредвиденная ошибка: {e}. Повтор через 3 сек...")
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
ap = argparse.ArgumentParser(description="Чтение COM и отправка в vMix через parse()")
|
||||||
|
ap.add_argument("--port", required=True, help="COM-порт, напр. COM3 (Windows) или /dev/ttyUSB0 (Linux)")
|
||||||
|
ap.add_argument("--baud", type=int, default=19200, help="Скорость, по умолчанию 9600")
|
||||||
|
ap.add_argument("--newline", choices=["LF", "CRLF", "CR"], default="CR",
|
||||||
|
help="Разделитель строк, по умолчанию LF")
|
||||||
|
ap.add_argument("--no-strip", action="store_true",
|
||||||
|
help="Не обрезать пробелы по краям (по умолчанию обрезаем)")
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
read_loop(args.port, args.baud, args.newline, strip_whitespace=not args.no_strip)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
189
timer NATA Kazan.py
Normal file
189
timer NATA Kazan.py
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
import sys
|
||||||
|
import json
|
||||||
|
from socket import *
|
||||||
|
from datetime import datetime
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import binascii
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
HOST = "192.168.127.254"
|
||||||
|
PORT = 1993
|
||||||
|
PATH = (
|
||||||
|
r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\python\JSON\timer_basketball.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
session = requests.Session()
|
||||||
|
session.headers.update({"Connection": "keep-alive"})
|
||||||
|
|
||||||
|
|
||||||
|
def hexspace(string, length):
|
||||||
|
return " ".join(string[i : i + length] for i in range(0, len(string), length))
|
||||||
|
|
||||||
|
|
||||||
|
def send_data(name, value):
|
||||||
|
url = "http://127.0.0.1:8088/API/"
|
||||||
|
par = "SetText" if name.split(".")[1] == "Text" else "SetImage"
|
||||||
|
params = {
|
||||||
|
"Function": par,
|
||||||
|
"Input": 33,
|
||||||
|
"SelectedName": name,
|
||||||
|
"Value": value,
|
||||||
|
}
|
||||||
|
session.get(url, params=params)
|
||||||
|
|
||||||
|
def parse_new(line):
|
||||||
|
try:
|
||||||
|
with open(PATH, "r", encoding="utf-8") as f:
|
||||||
|
new_data = json.load(f)
|
||||||
|
except json.decoder.JSONDecodeError:
|
||||||
|
new_data = [
|
||||||
|
{
|
||||||
|
"timeGFX": "0:00",
|
||||||
|
"time_attackGFX": "",
|
||||||
|
"quarter": "0",
|
||||||
|
"points1": "0",
|
||||||
|
"points2": "0",
|
||||||
|
"foul1": "0",
|
||||||
|
"foul2": "0",
|
||||||
|
"foul_pic1": "",
|
||||||
|
"foul_pic2": "",
|
||||||
|
"time_attac_pic": "",
|
||||||
|
"timeout1": "0",
|
||||||
|
"timeout2": "0",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
cdata = binascii.hexlify(line)
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
temp = edata.split("FF 52")
|
||||||
|
# print(temp)
|
||||||
|
for i in temp:
|
||||||
|
if "7D 4A C0 0A" in i: #основной таймер
|
||||||
|
minutes = int(i.split()[-5], )
|
||||||
|
seconds = int(i.split()[-4], )
|
||||||
|
milliseconds = int(i.split()[-3], )
|
||||||
|
timer_str = (
|
||||||
|
f"{minutes}:{seconds:02d}" if minutes != 0 else f"{seconds}.{milliseconds}"
|
||||||
|
)
|
||||||
|
send_data("TIMER.Text", timer_str)
|
||||||
|
|
||||||
|
# print(i.split()[-7], i)
|
||||||
|
# if i.split()[-7] == "13" or i.split()[-7] == "10":
|
||||||
|
# new_data[0]["timeGFX"] = timer_str
|
||||||
|
elif "7D 4A C0 07" in i: #Счет
|
||||||
|
if i.split()[-7] == "06": #Счет первой команды
|
||||||
|
score1 = int(i.split()[-4], 16)
|
||||||
|
# new_data[0]["points1"] = score1
|
||||||
|
send_data("SCORE1.Text", score1)
|
||||||
|
elif i.split()[-7] == "07": #Счет второй команды
|
||||||
|
score2 = int(i.split()[-4], 16)
|
||||||
|
send_data("SCORE2.Text", score2)
|
||||||
|
# new_data[0]["points2"] = score2
|
||||||
|
else:
|
||||||
|
print("[СЧЁТ] == НЕПОНЯТНО")
|
||||||
|
elif "7D 4A C0 06" in i: #Информация
|
||||||
|
if i.split()[-6] == "09": #фолы первой команды
|
||||||
|
foul1 = int(i.split()[-3], 16)
|
||||||
|
# new_data[0]["foul1"] = foul1
|
||||||
|
send_data("fouls1.Source", f"D:\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\Away_{foul1}.png")
|
||||||
|
elif i.split()[-6] == "0A": #фолы второй команды
|
||||||
|
foul2 = int(i.split()[-3], 16)
|
||||||
|
send_data("fouls2.Source", f"D:\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\Away_{foul2}.png")
|
||||||
|
# new_data[0]["foul2"] = foul2
|
||||||
|
elif i.split()[-6] == "0E": #тайм-аут первой команды
|
||||||
|
time_out1 = int(i.split()[-3], 16)
|
||||||
|
# new_data[0]["timeout1"] = time_out1
|
||||||
|
elif i.split()[-6] == "0F": #тайм-аут второй команды
|
||||||
|
time_out2 = int(i.split()[-3], 16)
|
||||||
|
# new_data[0]["timeout2"] = time_out2
|
||||||
|
elif i.split()[-6] == "08": #четверть
|
||||||
|
quarter = int(i.split()[-3], 16)
|
||||||
|
# new_data[0]["quarter"] = quarter
|
||||||
|
|
||||||
|
elif "79 84 C0 0A" in i: #24 секунды
|
||||||
|
print(i)
|
||||||
|
seconds = int(i.split()[-4])
|
||||||
|
milliseconds = int(i.split()[-3])
|
||||||
|
if seconds < int(5):
|
||||||
|
time_attack = f"{seconds}.{milliseconds}"
|
||||||
|
timer_pic = "D:\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\24Sec_Red.png"
|
||||||
|
else:
|
||||||
|
time_attack = seconds
|
||||||
|
timer_pic = "D:\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\24Sec_Empty.png"
|
||||||
|
if time_attack == "0.0":
|
||||||
|
time_attack = ""
|
||||||
|
timer_pic = "D:\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\24Sec_Empty.png"
|
||||||
|
send_data("24sec.Text", time_attack)
|
||||||
|
# send_data("24SECBACKGROUND.Source", timer_pic)
|
||||||
|
|
||||||
|
# print(time_attack)
|
||||||
|
elif "89 4E C8 05" in i:
|
||||||
|
if i.split()[-3] == "05": #таймер 24 секунд выключен
|
||||||
|
time_attack = ""
|
||||||
|
timer_pic = "D:\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\24Sec_Empty.png"
|
||||||
|
send_data("24sec.Text", time_attack)
|
||||||
|
# send_data("24SECBACKGROUND.Source", timer_pic)
|
||||||
|
# data = {
|
||||||
|
# "TIMER.Text": timer_str,
|
||||||
|
# "ATTACK.Text": time_attack,
|
||||||
|
# "Score_Home.Text": score1,
|
||||||
|
# "Score_Away.Text": score2,
|
||||||
|
# "fouls1.Source": f"D:\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\Home_{foul1}.png",
|
||||||
|
# "fouls2.Source": f"D:\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\Away_{foul2}.png",
|
||||||
|
# "24SECBACKGROUND.Source": timer_pic,
|
||||||
|
# }
|
||||||
|
|
||||||
|
def read_logs():
|
||||||
|
with open(
|
||||||
|
r"C:\Users\soule\Downloads\Telegram Desktop\timer_Megasport_Nport_2024-03-05_20-00-17.log",
|
||||||
|
"r",
|
||||||
|
) as file:
|
||||||
|
for line in file:
|
||||||
|
parts = line.strip().split(" DEBUG ")
|
||||||
|
if len(parts) == 2:
|
||||||
|
timestamp = parts[0][1:]
|
||||||
|
data = eval(parts[1])
|
||||||
|
if b"\xf83" in data or b"\xf88" in data or b"\xf87" in data:
|
||||||
|
parse(data)
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
current_time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
if not os.path.isdir("LOGS"):
|
||||||
|
os.mkdir("LOGS")
|
||||||
|
|
||||||
|
LogFileName = f"LOGS/timer_Nata_Nport_{current_time}.log"
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format="%(asctime)s %(levelname)s %(message)s",
|
||||||
|
filename=LogFileName,
|
||||||
|
filemode="w",
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
tcp_socket.connect((HOST, PORT))
|
||||||
|
data = str.encode("hello")
|
||||||
|
tcp_socket.send(data)
|
||||||
|
data = bytes.decode(data)
|
||||||
|
while True:
|
||||||
|
data = tcp_socket.recv(1024)
|
||||||
|
parse_new(data)
|
||||||
|
logging.debug(data)
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
tcp_socket.close()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
# read_logs()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(1)
|
||||||
162
timer_KAZ.py
Normal file
162
timer_KAZ.py
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
import sys
|
||||||
|
import json
|
||||||
|
from socket import *
|
||||||
|
from datetime import datetime
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
# import logging
|
||||||
|
|
||||||
|
|
||||||
|
VERSION = "версия 2" # от 02.04.2024
|
||||||
|
|
||||||
|
host = "192.168.127.254"
|
||||||
|
port = 1993
|
||||||
|
ADDR = (host, port)
|
||||||
|
PATH = (
|
||||||
|
r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\python\JSON\timer_basketball.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def save_log(name, data):
|
||||||
|
current_time = datetime.now().strftime("%d-%m-%Y %H:%M:%S.%f")
|
||||||
|
message_with_time = f"[{current_time}] {data}"
|
||||||
|
if not os.path.isdir("LOGS"):
|
||||||
|
os.mkdir("LOGS")
|
||||||
|
with open(f"LOGS/{name}", "a") as file:
|
||||||
|
file.write(message_with_time + "\n")
|
||||||
|
|
||||||
|
|
||||||
|
def parse(data, score1, score2):
|
||||||
|
data = data.split("/")
|
||||||
|
|
||||||
|
with open(PATH, "r", encoding="utf-8") as f:
|
||||||
|
new_data = json.load(f)
|
||||||
|
new_data = new_data[0]
|
||||||
|
path_pic = r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators"
|
||||||
|
# print(data)
|
||||||
|
diff1, diff2 = 0, 0
|
||||||
|
try:
|
||||||
|
if len(data) > 10:
|
||||||
|
if data[4] == "NPR":
|
||||||
|
new_data["quarter"] = data[5]
|
||||||
|
if data[17] == "HCP":
|
||||||
|
new_data["points1"] = data[18]
|
||||||
|
if score1 != new_data["points1"]:
|
||||||
|
diff1 = int(new_data["points1"]) - int(score1)
|
||||||
|
score1 = new_data["points1"]
|
||||||
|
if data[20] == "GCP":
|
||||||
|
new_data["points2"] = data[21]
|
||||||
|
if score2 != new_data["points2"]:
|
||||||
|
diff2 = int(new_data["points2"]) - int(score2)
|
||||||
|
score2 = new_data["points2"]
|
||||||
|
if data[29] == "HCF":
|
||||||
|
new_data["foul1"] = data[30]
|
||||||
|
new_data["foul_pic1"] = path_pic + f"\\Home_{int(data[30])}.png"
|
||||||
|
if data[32] == "GCF":
|
||||||
|
new_data["foul2"] = data[33]
|
||||||
|
new_data["foul_pic2"] = path_pic + f"\\Away_{int(data[33])}.png"
|
||||||
|
else:
|
||||||
|
if data[1] == "TGI":
|
||||||
|
if data[2] != "0":
|
||||||
|
seconds = data[3] if len(data[3]) != 1 else f"0{data[3]}"
|
||||||
|
new_data["timeGFX"] = f"{data[2]}:{seconds}"
|
||||||
|
else:
|
||||||
|
millisec = data[4]
|
||||||
|
if not millisec.isdigit():
|
||||||
|
millisec = "0"
|
||||||
|
new_data["timeGFX"] = f"{data[3]}.{millisec}"
|
||||||
|
elif data[1] == "NPR":
|
||||||
|
new_data["quarter"] = data[2]
|
||||||
|
elif data[1] == "HCP":
|
||||||
|
new_data["points1"] = data[2]
|
||||||
|
if score1 != new_data["points1"]:
|
||||||
|
diff1 = int(new_data["points1"]) - int(score1)
|
||||||
|
score1 = new_data["points1"]
|
||||||
|
elif data[1] == "GCP":
|
||||||
|
new_data["points2"] = data[2]
|
||||||
|
if score2 != new_data["points2"]:
|
||||||
|
diff2 = int(new_data["points2"]) - int(score2)
|
||||||
|
score2 = new_data["points2"]
|
||||||
|
elif data[1] == "HCF":
|
||||||
|
new_data["foul1"] = data[2]
|
||||||
|
new_data["foul_pic1"] = path_pic + f"\\Home_{int(data[2])}.png"
|
||||||
|
if len(data) > 4 and data[4] == "GCF":
|
||||||
|
new_data["foul2"] = data[2]
|
||||||
|
new_data["foul_pic2"] = path_pic + f"\\Away_{int(data[2])}.png"
|
||||||
|
elif data[1] == "GCF":
|
||||||
|
new_data["foul2"] = data[2]
|
||||||
|
new_data["foul_pic2"] = path_pic + f"\\Away_{int(data[2])}.png"
|
||||||
|
elif data[1] == "TAI":
|
||||||
|
if data[2] not in ["0", "-1"]:
|
||||||
|
new_data["time_attackGFX"] = str(int(data[2]))
|
||||||
|
elif data[2] == "-1":
|
||||||
|
new_data["time_attackGFX"] = ""
|
||||||
|
new_data["time_attac_pic"] = path_pic + "\\24Sec_empty.png"
|
||||||
|
if 0 < int(data[2]) <= 5:
|
||||||
|
new_data["time_attac_pic"] = path_pic + "\\24Sec_Red.png"
|
||||||
|
else:
|
||||||
|
if int(data[2]) in [0, -1]:
|
||||||
|
new_data["time_attac_pic"] = path_pic + "\\24Sec_empty.png"
|
||||||
|
else:
|
||||||
|
new_data["time_attac_pic"] = path_pic + "\\24Sec_Orange.png"
|
||||||
|
|
||||||
|
print(f'{diff1}, {diff2}, {new_data["timeGFX"]:<5}, {new_data["time_attackGFX"]:<3}, {new_data["points1"]:<3}, {new_data["points2"]:<3}, {new_data["foul1"]:<2}, {new_data["foul2"]:<2}')
|
||||||
|
except Exception as ex:
|
||||||
|
print(ex)
|
||||||
|
try:
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
# if ":" in new_data["timeGFX"]:
|
||||||
|
# time.sleep(.5)
|
||||||
|
# else:
|
||||||
|
# time.sleep(.1)
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return score1, score2
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
current_time = datetime.now().strftime("%d-%m-%Y_%H-%M-%S")
|
||||||
|
|
||||||
|
new_data = {
|
||||||
|
"timeGFX": "0:00",
|
||||||
|
"time_attackGFX": "",
|
||||||
|
"quarter": "0",
|
||||||
|
"points1": "0",
|
||||||
|
"points2": "0",
|
||||||
|
"foul1": "0",
|
||||||
|
"foul2": "0",
|
||||||
|
"foul_pic1": "",
|
||||||
|
"foul_pic2": "",
|
||||||
|
"time_attac_pic": "",
|
||||||
|
}
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
|
||||||
|
tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
tcp_socket.connect(ADDR)
|
||||||
|
score1, score2 = 0, 0
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
data = str.encode("hello")
|
||||||
|
tcp_socket.send(data)
|
||||||
|
data = bytes.decode(data)
|
||||||
|
data = tcp_socket.recv(1024)
|
||||||
|
data = data.decode("utf-8", errors="ignore")
|
||||||
|
print(data)
|
||||||
|
|
||||||
|
save_log(f"logs_mba_{VERSION}_{current_time}.txt", data)
|
||||||
|
score1, score2 = parse(data, score1, score2)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
tcp_socket.close()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(1)
|
||||||
208
timer_MBA.py
Normal file
208
timer_MBA.py
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
import sys
|
||||||
|
import json
|
||||||
|
from socket import *
|
||||||
|
from datetime import datetime
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
# import logging
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
VERSION = "версия 2" # от 02.04.2024
|
||||||
|
|
||||||
|
host = "10.0.0.57"
|
||||||
|
port = 50002
|
||||||
|
ADDR = (host, port)
|
||||||
|
PATH = (
|
||||||
|
r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\python\JSON\timer_basketball.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
session = requests.Session()
|
||||||
|
session.headers.update({"Connection": "keep-alive"})
|
||||||
|
|
||||||
|
def save_log(name, data):
|
||||||
|
current_time = datetime.now().strftime("%d-%m-%Y %H:%M:%S.%f")
|
||||||
|
message_with_time = f"[{current_time}] {data}"
|
||||||
|
if not os.path.isdir("LOGS"):
|
||||||
|
os.mkdir("LOGS")
|
||||||
|
with open(f"LOGS/{name}", "a") as file:
|
||||||
|
file.write(message_with_time + "\n")
|
||||||
|
|
||||||
|
|
||||||
|
def send_data(name, value):
|
||||||
|
url = "http://127.0.0.1:8088/API/"
|
||||||
|
par = "SetText" if name.split(".")[1] == "Text" else "SetImage"
|
||||||
|
params = {
|
||||||
|
"Function": par,
|
||||||
|
"Input": 41,
|
||||||
|
# "Input": "SCOREBUG",
|
||||||
|
"SelectedName": name,
|
||||||
|
"Value": value,
|
||||||
|
}
|
||||||
|
session.get(url, params=params)
|
||||||
|
|
||||||
|
|
||||||
|
def parse(data, score1, score2):
|
||||||
|
data = data.split("/")
|
||||||
|
|
||||||
|
with open(PATH, "r", encoding="utf-8") as f:
|
||||||
|
new_data = json.load(f)
|
||||||
|
new_data = new_data[0]
|
||||||
|
path_pic = r"D:\графика\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ ФИНАЛ ЧЕТЫРЕХ\FOULS"
|
||||||
|
# print(data)
|
||||||
|
diff1, diff2 = 0, 0
|
||||||
|
if len(data) > 10:
|
||||||
|
if data[4] == "NPR":
|
||||||
|
new_data["quarter"] = data[5]
|
||||||
|
if data[17] == "HCP":
|
||||||
|
new_data["points1"] = data[18]
|
||||||
|
if score1 != new_data["points1"]:
|
||||||
|
diff1 = int(new_data["points1"]) - int(score1)
|
||||||
|
score1 = new_data["points1"]
|
||||||
|
if data[20] == "GCP":
|
||||||
|
new_data["points2"] = data[21]
|
||||||
|
if score2 != new_data["points2"]:
|
||||||
|
diff2 = int(new_data["points2"]) - int(score2)
|
||||||
|
score2 = new_data["points2"]
|
||||||
|
if data[29] == "HCF":
|
||||||
|
new_data["foul1"] = data[30]
|
||||||
|
new_data["foul_pic1"] = path_pic + f"\\FOULS_{int(data[30])}.png"
|
||||||
|
if data[32] == "GCF":
|
||||||
|
new_data["foul2"] = data[33]
|
||||||
|
new_data["foul_pic2"] = path_pic + f"\\FOULS_{int(data[33])}.png"
|
||||||
|
else:
|
||||||
|
if data[1] == "TGI":
|
||||||
|
if data[2] != "0":
|
||||||
|
seconds = data[3] if len(data[3]) != 1 else f"0{data[3]}"
|
||||||
|
new_data["timeGFX"] = f"{data[2]}:{seconds}"
|
||||||
|
else:
|
||||||
|
millisec = data[4]
|
||||||
|
if not millisec.isdigit():
|
||||||
|
millisec = "0"
|
||||||
|
new_data["timeGFX"] = f"{data[3]}.{millisec}"
|
||||||
|
elif data[1] == "NPR":
|
||||||
|
new_data["quarter"] = data[2]
|
||||||
|
elif data[1] == "HCP":
|
||||||
|
new_data["points1"] = data[2]
|
||||||
|
if score1 != new_data["points1"]:
|
||||||
|
diff1 = int(new_data["points1"]) - int(score1)
|
||||||
|
score1 = new_data["points1"]
|
||||||
|
elif data[1] == "GCP":
|
||||||
|
new_data["points2"] = data[2]
|
||||||
|
if score2 != new_data["points2"]:
|
||||||
|
diff2 = int(new_data["points2"]) - int(score2)
|
||||||
|
score2 = new_data["points2"]
|
||||||
|
elif data[1] == "HCF":
|
||||||
|
new_data["foul1"] = data[2]
|
||||||
|
new_data["foul_pic1"] = path_pic + f"\\FOULS_{int(data[2])}.png"
|
||||||
|
if len(data) > 4 and data[4] == "GCF":
|
||||||
|
new_data["foul2"] = data[2]
|
||||||
|
new_data["foul_pic2"] = path_pic + f"\\FOULS_{int(data[2])}.png"
|
||||||
|
elif data[1] == "GCF":
|
||||||
|
new_data["foul2"] = data[2]
|
||||||
|
new_data["foul_pic2"] = path_pic + f"\\FOULS_{int(data[2])}.png"
|
||||||
|
elif data[1] == "TAI":
|
||||||
|
if data[2] not in ["0", "-1"]:
|
||||||
|
new_data["time_attackGFX"] = str(int(data[2]))
|
||||||
|
elif data[2] == "-1":
|
||||||
|
new_data["time_attackGFX"] = ""
|
||||||
|
new_data["time_attac_pic"] = path_pic + "\\24Sec_empty.png"
|
||||||
|
if 0 < int(data[2]) <= 5:
|
||||||
|
new_data["time_attac_pic"] = path_pic + "\\24Sec_Red.png"
|
||||||
|
else:
|
||||||
|
if int(data[2]) in [0, -1]:
|
||||||
|
new_data["time_attac_pic"] = path_pic + "\\24Sec_empty.png"
|
||||||
|
else:
|
||||||
|
new_data["time_attac_pic"] = path_pic + "\\24Sec_Orange.png"
|
||||||
|
send_data("Timer.Text", new_data["timeGFX"])
|
||||||
|
send_data("Score_Team1.Text", new_data["points1"])
|
||||||
|
send_data("Score_Team2.Text", new_data["points2"])
|
||||||
|
send_data("Timer24sec.Text", new_data["time_attackGFX"])
|
||||||
|
send_data("FOULS_TEAM_A.Source", new_data["foul_pic1"])
|
||||||
|
send_data("FOULS_TEAM_B.Source", new_data["foul_pic2"])
|
||||||
|
|
||||||
|
print(f'{diff1}, {diff2}, {new_data["timeGFX"]:<5}, {new_data["time_attackGFX"]:<3}, {new_data["points1"]:<3}, {new_data["points2"]:<3}, {new_data["foul1"]:<2}, {new_data["foul2"]:<2}')
|
||||||
|
try:
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
# if ":" in new_data["timeGFX"]:
|
||||||
|
# time.sleep(.5)
|
||||||
|
# else:
|
||||||
|
# time.sleep(.1)
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return score1, score2
|
||||||
|
|
||||||
|
|
||||||
|
def read_logs():
|
||||||
|
score1, score2 = 0, 0
|
||||||
|
new_data = {
|
||||||
|
"timeGFX": "0:00",
|
||||||
|
"time_attackGFX": "",
|
||||||
|
"quarter": "0",
|
||||||
|
"points1": "0",
|
||||||
|
"points2": "0",
|
||||||
|
"foul1": "0",
|
||||||
|
"foul2": "0",
|
||||||
|
"foul_pic1": "",
|
||||||
|
"foul_pic2": "",
|
||||||
|
"time_attac_pic": "",
|
||||||
|
}
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
with open("D:\Графика\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\python\logs_mba_3.txt", "r") as file:
|
||||||
|
for line in file:
|
||||||
|
parts = line.strip().split("] ")
|
||||||
|
if len(parts) == 2:
|
||||||
|
timestamp = parts[0][1:]
|
||||||
|
data = parts[1]
|
||||||
|
score1, score2 = parse(data, score1, score2)
|
||||||
|
time.sleep(.1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
current_time = datetime.now().strftime("%d-%m-%Y_%H-%M-%S")
|
||||||
|
|
||||||
|
new_data = {
|
||||||
|
"timeGFX": "0:00",
|
||||||
|
"time_attackGFX": "",
|
||||||
|
"quarter": "0",
|
||||||
|
"points1": "0",
|
||||||
|
"points2": "0",
|
||||||
|
"foul1": "0",
|
||||||
|
"foul2": "0",
|
||||||
|
"foul_pic1": "",
|
||||||
|
"foul_pic2": "",
|
||||||
|
"time_attac_pic": "",
|
||||||
|
}
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
|
||||||
|
tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
tcp_socket.connect(ADDR)
|
||||||
|
score1, score2 = 0, 0
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
data = str.encode("hello")
|
||||||
|
tcp_socket.send(data)
|
||||||
|
data = bytes.decode(data)
|
||||||
|
data = tcp_socket.recv(1024)
|
||||||
|
data = data.decode("utf-8", errors="ignore")
|
||||||
|
print(data)
|
||||||
|
|
||||||
|
save_log(f"logs_mba_{VERSION}_{current_time}.txt", data)
|
||||||
|
score1, score2 = parse(data, score1, score2)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
tcp_socket.close()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
# read_logs()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(1)
|
||||||
171
timer_NN.py
Normal file
171
timer_NN.py
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
import sys
|
||||||
|
import json
|
||||||
|
from socket import *
|
||||||
|
from datetime import datetime
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import binascii
|
||||||
|
import requests
|
||||||
|
|
||||||
|
HOST = "192.168.0.7"
|
||||||
|
PORT = 40004
|
||||||
|
PATH = (
|
||||||
|
r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\python\JSON\timer_basketball.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
session = requests.Session()
|
||||||
|
session.headers.update({"Connection": "keep-alive"})
|
||||||
|
|
||||||
|
|
||||||
|
def hexspace(string, length):
|
||||||
|
return " ".join(string[i : i + length] for i in range(0, len(string), length))
|
||||||
|
|
||||||
|
|
||||||
|
def timer(line):
|
||||||
|
temp_new = [int(t, 16) for t in line.split()]
|
||||||
|
minutes = temp_new[4]
|
||||||
|
seconds = temp_new[5]
|
||||||
|
milliseconds = temp_new[6]
|
||||||
|
timer_str = (
|
||||||
|
f"{minutes}:{seconds:02d}" if minutes != 0 else f"{seconds}.{milliseconds}"
|
||||||
|
)
|
||||||
|
return timer_str
|
||||||
|
|
||||||
|
|
||||||
|
def attack_time(line):
|
||||||
|
temp_new = [int(t, 16) for t in line.split()]
|
||||||
|
path_pic = r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators"
|
||||||
|
if temp_new[7] != 2:
|
||||||
|
seconds = temp_new[5]
|
||||||
|
milliseconds = temp_new[6]
|
||||||
|
if int(seconds) > 4:
|
||||||
|
if int(milliseconds) >= 5:
|
||||||
|
seconds = int(seconds) + 1
|
||||||
|
else:
|
||||||
|
seconds = seconds
|
||||||
|
time_attack = seconds
|
||||||
|
else:
|
||||||
|
time_attack = f"{seconds}.{milliseconds}"
|
||||||
|
if time_attack == "0.0":
|
||||||
|
time_attack = ""
|
||||||
|
# time_attack = (
|
||||||
|
# temp_new[5]
|
||||||
|
# if temp_new[5] > 4
|
||||||
|
# else f"{temp_new[5]}.{temp_new[6]}"
|
||||||
|
# if f"{temp_new[5]}.{temp_new[6]}" != "0.0"
|
||||||
|
# else ""
|
||||||
|
# )
|
||||||
|
path_pic = path_pic + (
|
||||||
|
"\\24Sec_Orange.png"
|
||||||
|
if temp_new[5] > 4
|
||||||
|
else (
|
||||||
|
"\\24Sec_Red.png"
|
||||||
|
if f"{temp_new[5]}.{temp_new[6]}" != "0.0"
|
||||||
|
else "\\24Sec_empty.png"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
time_attack = "" # temp_new[-2] == 1 - таймер идёт | 2 - таймер стоит | 0 - таймер не отображён
|
||||||
|
path_pic = path_pic + "\\24Sec_empty.png"
|
||||||
|
return time_attack, path_pic
|
||||||
|
|
||||||
|
def send_data(name, value):
|
||||||
|
url = "http://127.0.0.1:8088/API/"
|
||||||
|
par = "SetText" if name.split(".")[1] == "Text" else "SetImage"
|
||||||
|
params = {
|
||||||
|
"Function": par,
|
||||||
|
# "Input": 41,
|
||||||
|
"Input": "SCOREBUG",
|
||||||
|
"SelectedName": name,
|
||||||
|
"Value": value,
|
||||||
|
}
|
||||||
|
session.get(url, params=params)
|
||||||
|
|
||||||
|
def parse(line):
|
||||||
|
cdata = binascii.hexlify(line)
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
|
||||||
|
temp_line = ""
|
||||||
|
line = ""
|
||||||
|
if len(edata.split()) in [2, 31, 32, 1]:
|
||||||
|
if temp_line == "":
|
||||||
|
temp_line = edata
|
||||||
|
else:
|
||||||
|
line = temp_line + edata
|
||||||
|
temp_line = ""
|
||||||
|
else:
|
||||||
|
line = edata
|
||||||
|
|
||||||
|
data = line.split("FE FF")
|
||||||
|
path_pic_foul = (
|
||||||
|
r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators"
|
||||||
|
)
|
||||||
|
diff1, diff2 = 0, 0
|
||||||
|
for d in data:
|
||||||
|
if d != "":
|
||||||
|
temp_d = d.strip()
|
||||||
|
if "08 01" in temp_d[:5] and str(temp_d.split()[-2])[0] == "8":
|
||||||
|
timer_str = timer(temp_d)
|
||||||
|
send_data("TIMER.Text", timer_str)
|
||||||
|
aaaaa = temp_d.split()[-2]
|
||||||
|
elif "08 03" in temp_d[:5]:
|
||||||
|
time_attack, path_pic = attack_time(temp_d)
|
||||||
|
send_data("24sec.Text", time_attack)
|
||||||
|
aaaa = temp_d.split()[-2], int(temp_d.split()[-2], 16)
|
||||||
|
elif "0D 1F" in temp_d[:5]:
|
||||||
|
send_data("SCORE1.Text", int(temp_d.split()[2], 16))
|
||||||
|
send_data("SCORE2.Text", int(temp_d.split()[3], 16))
|
||||||
|
|
||||||
|
|
||||||
|
def read_logs():
|
||||||
|
|
||||||
|
score1, score2 = 0, 0
|
||||||
|
with open("timer_NN_1.log", "r") as file:
|
||||||
|
# with open("timer_NN_test.log", "r") as file:
|
||||||
|
for line in file:
|
||||||
|
parts = line.strip().split(" DEBUG ")
|
||||||
|
if len(parts) == 2:
|
||||||
|
timestamp = parts[0][1:]
|
||||||
|
data = eval(parts[1])
|
||||||
|
parse(data)
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
current_time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
if not os.path.isdir("LOGS"):
|
||||||
|
os.mkdir("LOGS")
|
||||||
|
|
||||||
|
LogFileName = f"LOGS/timer_NN_{current_time}.log"
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format="%(asctime)s %(levelname)s %(message)s",
|
||||||
|
filename=LogFileName,
|
||||||
|
filemode="w",
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
tcp_socket.connect((HOST, PORT))
|
||||||
|
data = str.encode("hello")
|
||||||
|
tcp_socket.send(data)
|
||||||
|
data = bytes.decode(data)
|
||||||
|
while True:
|
||||||
|
data = tcp_socket.recv(1024)
|
||||||
|
print(data)
|
||||||
|
logging.debug(data)
|
||||||
|
parse(data)
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
tcp_socket.close()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
# read_logs()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(1)
|
||||||
159
timer_NN_backup.py
Normal file
159
timer_NN_backup.py
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
import sys
|
||||||
|
import json
|
||||||
|
from socket import *
|
||||||
|
from datetime import datetime
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import binascii
|
||||||
|
|
||||||
|
HOST = "192.168.0.7"
|
||||||
|
PORT = 40004
|
||||||
|
PATH = (
|
||||||
|
r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\python\JSON\timer_basketball.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def hexspace(string, length):
|
||||||
|
return " ".join(string[i : i + length] for i in range(0, len(string), length))
|
||||||
|
|
||||||
|
|
||||||
|
def parse(line):
|
||||||
|
with open(PATH, "r", encoding="utf-8") as f:
|
||||||
|
new_data = json.load(f)
|
||||||
|
cdata = binascii.hexlify(line)
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
path_pic = r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators"
|
||||||
|
|
||||||
|
if len(edata.split()) in [32, 33, 40]:
|
||||||
|
temp_data = edata.split()
|
||||||
|
temp_new = [int(t, 16) for t in temp_data]
|
||||||
|
minutes = temp_new[6]
|
||||||
|
seconds = temp_new[7]
|
||||||
|
milliseconds = temp_new[8]
|
||||||
|
timer_str = (
|
||||||
|
f"{minutes}:{seconds:02d}"
|
||||||
|
if minutes != 0
|
||||||
|
else f"{seconds}.{milliseconds}"
|
||||||
|
)
|
||||||
|
active_temp = temp_new[
|
||||||
|
9
|
||||||
|
] # 133 - таймер идёт | 132 - таймер стоит | 128 - не игровое время стоит | 129 - не игровое время идёт
|
||||||
|
|
||||||
|
if temp_new[31] not in [2]:
|
||||||
|
time_attack = (
|
||||||
|
temp_new[29] if temp_new[29] > 4 else f"{temp_new[29]}.{temp_new[30]}" if f"{temp_new[29]}.{temp_new[30]}" != "0.0" else ""
|
||||||
|
)
|
||||||
|
path_pic = path_pic + ("\\24Sec_Orange.png" if temp_new[29] > 4 else "\\24Sec_Red.png" if f"{temp_new[29]}.{temp_new[30]}" != "0.0" else "\\24Sec_empty.png")
|
||||||
|
else:
|
||||||
|
time_attack = "" # temp_new[-2] == 1 - таймер идёт | 2 - таймер стоит | 0 - таймер не отображён
|
||||||
|
path_pic = path_pic + "\\24Sec_empty.png"
|
||||||
|
|
||||||
|
# print(f"{str(temp_new):<120}__{timer_str:<7}__{time_attack:<3}__")
|
||||||
|
new_data[0]["timeGFX"] = timer_str
|
||||||
|
new_data[0]["time_attackGFX"] = time_attack
|
||||||
|
new_data[0]["time_attac_pic"] = path_pic
|
||||||
|
else:
|
||||||
|
temp_data = edata.split()
|
||||||
|
temp_new = [int(t, 16) for t in temp_data]
|
||||||
|
timer_str = "99:99"
|
||||||
|
time_attack = "99:99"
|
||||||
|
|
||||||
|
|
||||||
|
print(len(edata.split()), f"{str(edata):<120}__{timer_str:<7}__{time_attack:<3}__")
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump(new_data, file, ensure_ascii=False, indent=4)
|
||||||
|
# if ":" in new_data["timeGFX"]:
|
||||||
|
# time.sleep(.5)
|
||||||
|
# else:
|
||||||
|
# time.sleep(.1)
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# with open("timer_NN.csv", "a+") as file:
|
||||||
|
# file.write(str(temp_new))
|
||||||
|
# file.write("\n")
|
||||||
|
# with open("timer_NN_2.csv", "a+") as file:
|
||||||
|
# file.write(str(temp_data))
|
||||||
|
# file.write("\n")
|
||||||
|
# with open("timer_NN_3.csv", "a+") as file:
|
||||||
|
# file.write(str(ddata))
|
||||||
|
# file.write("\n")
|
||||||
|
|
||||||
|
# time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def read_logs():
|
||||||
|
with open("timer_NN_1.log", "r") as file:
|
||||||
|
# with open("timer_NN_test.log", "r") as file:
|
||||||
|
temp_line = ""
|
||||||
|
for line in file:
|
||||||
|
parts = line.strip().split(" DEBUG ")
|
||||||
|
if len(parts) == 2:
|
||||||
|
timestamp = parts[0][1:]
|
||||||
|
data = eval(parts[1])
|
||||||
|
parse(data)
|
||||||
|
time.sleep(.05)
|
||||||
|
|
||||||
|
# if len(eval(data)) > 30 and eval(data)[-7] == "00":
|
||||||
|
# time.sleep(.1)
|
||||||
|
# else:
|
||||||
|
# time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
current_time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
if not os.path.isdir("LOGS"):
|
||||||
|
os.mkdir("LOGS")
|
||||||
|
|
||||||
|
LogFileName = f"LOGS/timer_NN_{current_time}.log"
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format="%(asctime)s %(levelname)s %(message)s",
|
||||||
|
filename=LogFileName,
|
||||||
|
filemode="w",
|
||||||
|
)
|
||||||
|
new_data = {
|
||||||
|
"timeGFX": "0:00",
|
||||||
|
"time_attackGFX": "",
|
||||||
|
"quarter": "0",
|
||||||
|
"points1": "0",
|
||||||
|
"points2": "0",
|
||||||
|
"foul1": "0",
|
||||||
|
"foul2": "0",
|
||||||
|
"foul_pic1": "",
|
||||||
|
"foul_pic2": "",
|
||||||
|
"time_attac_pic": "",
|
||||||
|
}
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
|
||||||
|
try:
|
||||||
|
tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
tcp_socket.connect((HOST, PORT))
|
||||||
|
data = str.encode("hello")
|
||||||
|
tcp_socket.send(data)
|
||||||
|
data = bytes.decode(data)
|
||||||
|
while True:
|
||||||
|
data = tcp_socket.recv(1024)
|
||||||
|
print(data)
|
||||||
|
logging.debug(data)
|
||||||
|
parse(data)
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
tcp_socket.close()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
# main()
|
||||||
|
read_logs()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(1)
|
||||||
153
timer_NPORT_Deepron.py
Normal file
153
timer_NPORT_Deepron.py
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
import sys
|
||||||
|
from socket import *
|
||||||
|
from datetime import datetime
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
SETTING = "9600,RS-232"
|
||||||
|
HOST = "192.168.127.254"
|
||||||
|
PORT = 1993
|
||||||
|
URL = "http://127.0.0.1:8088/API/"
|
||||||
|
INPUT = ["ТАЙМЕР МУЖЧИНЫ", "ТАЙМЕР ЖЕНЩИНЫ"]
|
||||||
|
|
||||||
|
|
||||||
|
def send_data(data, name):
|
||||||
|
for i in INPUT:
|
||||||
|
params = {
|
||||||
|
"Function": "SetText",
|
||||||
|
"Input": i,
|
||||||
|
"SelectedName": f"{name}.Text",
|
||||||
|
"Value": data,
|
||||||
|
}
|
||||||
|
requests.get(URL, params=params)
|
||||||
|
|
||||||
|
|
||||||
|
def win(name):
|
||||||
|
params = {
|
||||||
|
"Function": "SetTextColour",
|
||||||
|
"Input": INPUT,
|
||||||
|
"SelectedName": f"{name}.Text",
|
||||||
|
"Value": "Green",
|
||||||
|
}
|
||||||
|
requests.get(URL, params=params)
|
||||||
|
|
||||||
|
|
||||||
|
def reset(name):
|
||||||
|
params = {
|
||||||
|
"Function": "SetTextColour",
|
||||||
|
"Input": INPUT,
|
||||||
|
"SelectedName": f"{name}.Text",
|
||||||
|
"Value": "white",
|
||||||
|
}
|
||||||
|
requests.get(URL, params=params)
|
||||||
|
|
||||||
|
|
||||||
|
def func_new(i, name, tag):
|
||||||
|
data = (
|
||||||
|
i.split(f"{tag}<")[1]
|
||||||
|
.replace("0'0", "")
|
||||||
|
.replace("0'", "")
|
||||||
|
.replace("10>", "")
|
||||||
|
.split()[0]
|
||||||
|
)
|
||||||
|
if "FALSE START" in i:
|
||||||
|
send_data("FS", name)
|
||||||
|
elif "OK NO FS" in i:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
send_data(data, name)
|
||||||
|
# if "WIN" in i:
|
||||||
|
# win(name)
|
||||||
|
|
||||||
|
|
||||||
|
def parse(line):
|
||||||
|
decode_line = line.decode("utf-8")
|
||||||
|
print(decode_line)
|
||||||
|
temp_list = decode_line.split("<E>")
|
||||||
|
name1, name2, name3, name4 = "Time1", "Time2", "Reaction1", "Reaction2"
|
||||||
|
for i in temp_list:
|
||||||
|
if i != "":
|
||||||
|
if "READY" in i:
|
||||||
|
send_data('0"000', name1)
|
||||||
|
send_data('0"000', name2)
|
||||||
|
send_data("", name3)
|
||||||
|
send_data("", name4)
|
||||||
|
# reset(name1)
|
||||||
|
# reset(name2)
|
||||||
|
|
||||||
|
if not any(char in i[7] for char in ["R", "G", "B", "C", "Y", "M", "A"]):
|
||||||
|
if "<ID01>" in i and not any(char in i for char in ["$", "@", "%"]):
|
||||||
|
func_new(i, name1, "<ID01>")
|
||||||
|
elif "<ID02>" in i and not any(char in i for char in ["$", "@", "%"]):
|
||||||
|
func_new(i, name2, "<ID02>")
|
||||||
|
elif "<ID03>" in i:
|
||||||
|
func_new(i, name3, "<ID03>")
|
||||||
|
elif "<ID04>" in i:
|
||||||
|
func_new(i, name4, "<ID04>")
|
||||||
|
|
||||||
|
|
||||||
|
def read_logs():
|
||||||
|
with open("C:\Code\LOGS\\timer_NPORT_tcp_2024-03-29_13-24-22.log", "r") as file:
|
||||||
|
timestamp_temp = ""
|
||||||
|
diff_time = 0
|
||||||
|
for line in file:
|
||||||
|
parts = line.strip().split(" DEBUG ")
|
||||||
|
if len(parts) == 2:
|
||||||
|
timestamp = parts[0]
|
||||||
|
if timestamp_temp == "":
|
||||||
|
timestamp_temp = timestamp
|
||||||
|
else:
|
||||||
|
time_format = "%Y-%m-%d %H:%M:%S,%f"
|
||||||
|
timestamp_datetime = datetime.strptime(timestamp, time_format)
|
||||||
|
timestamp_temp_datetime = datetime.strptime(
|
||||||
|
timestamp_temp, time_format
|
||||||
|
)
|
||||||
|
delta = timestamp_datetime - timestamp_temp_datetime
|
||||||
|
seconds = delta.total_seconds() # Convert timedelta to seconds
|
||||||
|
timestamp_temp = timestamp
|
||||||
|
time.sleep(abs(seconds - diff_time))
|
||||||
|
data = eval(parts[1])
|
||||||
|
start_time = time.time()
|
||||||
|
parse(data)
|
||||||
|
end_time = time.time()
|
||||||
|
diff_time = end_time - start_time
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
current_time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
if not os.path.isdir("LOGS"):
|
||||||
|
os.mkdir("LOGS")
|
||||||
|
|
||||||
|
LogFileName = f"LOGS/timer_NPORT_tcp_{current_time}.log"
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format="%(asctime)s %(levelname)s %(message)s",
|
||||||
|
filename=LogFileName,
|
||||||
|
filemode="w",
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
tcp_socket.connect((HOST, PORT))
|
||||||
|
data = str.encode("hello")
|
||||||
|
tcp_socket.send(data)
|
||||||
|
data = bytes.decode(data)
|
||||||
|
while True:
|
||||||
|
data = tcp_socket.recv(1024)
|
||||||
|
logging.debug(data)
|
||||||
|
parse(data)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
tcp_socket.close()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
# while True:
|
||||||
|
# read_logs()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(1)
|
||||||
128
timer_NPORT_коньки.py
Normal file
128
timer_NPORT_коньки.py
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
import sys
|
||||||
|
from socket import *
|
||||||
|
from datetime import datetime
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import binascii
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
HOST = "192.168.127.254"
|
||||||
|
PORT = 1993
|
||||||
|
PATH = (
|
||||||
|
r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\python\JSON\timer_basketball.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def hexspace(string, length):
|
||||||
|
return " ".join(string[i : i + length] for i in range(0, len(string), length))
|
||||||
|
|
||||||
|
|
||||||
|
def parse(line):
|
||||||
|
cdata = binascii.hexlify(line)
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
|
||||||
|
if len(edata.split()) == 33:
|
||||||
|
temp_data = edata.split()
|
||||||
|
temp_new = [int(t, 16) for t in temp_data]
|
||||||
|
minutes = temp_new[6]
|
||||||
|
seconds = temp_new[7]
|
||||||
|
milliseconds = temp_new[8]
|
||||||
|
timer_str = (
|
||||||
|
f"{minutes}:{seconds:02d}"
|
||||||
|
if minutes != 0
|
||||||
|
else f"{seconds:02d}.{milliseconds}"
|
||||||
|
)
|
||||||
|
active_temp = temp_new[
|
||||||
|
9
|
||||||
|
] # 133 - таймер идёт | 132 - таймер стоит | 128 - не игровое время стоит | 129 - не игровое время идёт
|
||||||
|
|
||||||
|
if temp_new[-2] != 0:
|
||||||
|
time_attack = (
|
||||||
|
temp_new[-4] if temp_new[-4] > 4 else f"{temp_new[-4]}.{temp_new[-3]}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
time_attack = "" # temp_new[-2] == 1 - таймер идёт | 2 - таймер стоит | 0 - таймер не отображён
|
||||||
|
|
||||||
|
# print(f"{str(temp_new):<120}__{timer_str:<7}__{time_attack:<3}__")
|
||||||
|
else:
|
||||||
|
temp_data = edata.split()
|
||||||
|
temp_new = [int(t, 16) for t in temp_data]
|
||||||
|
|
||||||
|
# time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def read_logs():
|
||||||
|
with open("timer_NN_2023-12-20_18-17-29.log", "r") as file:
|
||||||
|
# with open("timer_NN_test.log", "r") as file:
|
||||||
|
temp_line = ""
|
||||||
|
for line in file:
|
||||||
|
parts = line.strip().split(" DEBUG ")
|
||||||
|
if len(parts) == 2:
|
||||||
|
timestamp = parts[0][1:]
|
||||||
|
data = eval(parts[1])
|
||||||
|
parse(data)
|
||||||
|
time.sllep(0.1)
|
||||||
|
|
||||||
|
# if len(eval(data)) > 30 and eval(data)[-7] == "00":
|
||||||
|
# time.sleep(.1)
|
||||||
|
# else:
|
||||||
|
# time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_2(data):
|
||||||
|
data = data.decode()
|
||||||
|
print(data)
|
||||||
|
if "S04" in data:
|
||||||
|
temp = data.split("S04")[1]
|
||||||
|
print(f"{data:<50}", temp)
|
||||||
|
elif "S09" in data: #White
|
||||||
|
temp = data
|
||||||
|
elif "S00" in data: #Red
|
||||||
|
temp = data
|
||||||
|
|
||||||
|
def main():
|
||||||
|
current_time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
if not os.path.isdir("LOGS"):
|
||||||
|
os.mkdir("LOGS")
|
||||||
|
|
||||||
|
LogFileName = f"LOGS/timer_NPORT_zzz_{current_time}.log"
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format="%(asctime)s %(levelname)s %(message)s",
|
||||||
|
filename=LogFileName,
|
||||||
|
filemode="w",
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
tcp_socket.connect((HOST, PORT))
|
||||||
|
data = str.encode("hello")
|
||||||
|
tcp_socket.send(data)
|
||||||
|
data = bytes.decode(data)
|
||||||
|
temp = b""
|
||||||
|
line_new = b""
|
||||||
|
while True:
|
||||||
|
data = tcp_socket.recv(1024)
|
||||||
|
logging.debug(data)
|
||||||
|
print(data)
|
||||||
|
if b"\x03" in data:
|
||||||
|
temp += data
|
||||||
|
line_new = temp
|
||||||
|
temp = b""
|
||||||
|
else:
|
||||||
|
temp += data
|
||||||
|
|
||||||
|
parse_2(line_new)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
tcp_socket.close()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(1)
|
||||||
92
timer_app.py
Normal file
92
timer_app.py
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import socket
|
||||||
|
import tkinter as tk
|
||||||
|
import threading
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
def on_validate(P):
|
||||||
|
# Проверка на соответствие шаблону IP-адреса (допускаются промежуточные неполные значения)
|
||||||
|
pattern = (
|
||||||
|
r"^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){0,3}"
|
||||||
|
r"(25[0-5]|2[0-4]\d|[01]?\d\d?)?$"
|
||||||
|
)
|
||||||
|
return re.match(pattern, P) is not None
|
||||||
|
|
||||||
|
|
||||||
|
class ServerConnectionApp:
|
||||||
|
def __init__(self, root):
|
||||||
|
self.root = root
|
||||||
|
self.root.title("Server Connection App")
|
||||||
|
|
||||||
|
# GUI setup
|
||||||
|
self.setup_gui()
|
||||||
|
|
||||||
|
# Server connection
|
||||||
|
self.client_socket = None
|
||||||
|
|
||||||
|
def setup_gui(self):
|
||||||
|
self.ip_label = tk.Label(self.root, text="IP Address:")
|
||||||
|
self.ip_label.grid(row=0, column=0)
|
||||||
|
|
||||||
|
self.ip_entry = tk.Entry(self.root)
|
||||||
|
self.ip_entry.grid(row=0, column=1)
|
||||||
|
self.ip_entry.insert(0, "127.0.0.1") # Default IP address (localhost)
|
||||||
|
|
||||||
|
self.port_label = tk.Label(self.root, text="Port:")
|
||||||
|
self.port_label.grid(row=1, column=0)
|
||||||
|
|
||||||
|
self.port_entry = tk.Entry(self.root)
|
||||||
|
self.port_entry.grid(row=1, column=1)
|
||||||
|
self.port_entry.insert(0, "12345") # Default port
|
||||||
|
|
||||||
|
self.connect_button = tk.Button(self.root, text="Connect", command=self.initiate_connection)
|
||||||
|
self.connect_button.grid(row=2, column=0, columnspan=2)
|
||||||
|
|
||||||
|
self.status_label = tk.Label(self.root, text="")
|
||||||
|
self.status_label.grid(row=3, column=0, columnspan=2)
|
||||||
|
|
||||||
|
def initiate_connection(self):
|
||||||
|
ip = self.ip_entry.get()
|
||||||
|
port = int(self.port_entry.get())
|
||||||
|
|
||||||
|
# Create a thread to avoid blocking the GUI
|
||||||
|
connection_thread = threading.Thread(target=self.connect_to_server, args=(ip, port))
|
||||||
|
connection_thread.daemon = True
|
||||||
|
connection_thread.start()
|
||||||
|
|
||||||
|
def connect_to_server(self, ip, port):
|
||||||
|
try:
|
||||||
|
self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
self.client_socket.connect((ip, port))
|
||||||
|
self.status_label.config(text="Connected successfully.")
|
||||||
|
|
||||||
|
# Consume the data and print it to the console
|
||||||
|
self.listen_to_server()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.status_label.config(text=f"Connection failed: {e}")
|
||||||
|
|
||||||
|
def listen_to_server(self):
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
data = self.client_socket.recv(1024)
|
||||||
|
if data:
|
||||||
|
print("Received from server:", data.decode())
|
||||||
|
else:
|
||||||
|
# Connection is closed
|
||||||
|
print("Server has closed the connection.")
|
||||||
|
self.client_socket.close()
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error while listening to the server: {e}")
|
||||||
|
if self.client_socket:
|
||||||
|
self.client_socket.close()
|
||||||
|
|
||||||
|
# Create the Tkinter window
|
||||||
|
root = tk.Tk()
|
||||||
|
|
||||||
|
# Create an instance of the app
|
||||||
|
app = ServerConnectionApp(root)
|
||||||
|
|
||||||
|
# Start the Tkinter main event loop
|
||||||
|
root.mainloop()
|
||||||
326
timer_app2.py
Normal file
326
timer_app2.py
Normal file
@@ -0,0 +1,326 @@
|
|||||||
|
import tkinter as tk
|
||||||
|
from tkinter import filedialog, messagebox, ttk
|
||||||
|
import threading
|
||||||
|
import socket
|
||||||
|
import time
|
||||||
|
import binascii
|
||||||
|
|
||||||
|
def hexspace(data, n):
|
||||||
|
return " ".join([data[i:i + n] for i in range(0, len(data), n)])
|
||||||
|
|
||||||
|
def send_data(key, value):
|
||||||
|
print(f"Sending {key}: {value}")
|
||||||
|
|
||||||
|
|
||||||
|
class DataReceiver:
|
||||||
|
def __init__(self):
|
||||||
|
self.running = False
|
||||||
|
self.file_mode = False
|
||||||
|
self.file_path = None
|
||||||
|
|
||||||
|
def start_tcp(self, host, port, callback):
|
||||||
|
self.running = True
|
||||||
|
def run():
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
|
s.bind((host, port))
|
||||||
|
s.listen(1)
|
||||||
|
conn, addr = s.accept()
|
||||||
|
with conn:
|
||||||
|
while self.running:
|
||||||
|
data = conn.recv(1024)
|
||||||
|
if data:
|
||||||
|
callback(data.decode('utf-8'))
|
||||||
|
threading.Thread(target=run, daemon=True).start()
|
||||||
|
|
||||||
|
def start_file(self, callback):
|
||||||
|
self.running = True
|
||||||
|
def run():
|
||||||
|
if not self.file_path:
|
||||||
|
return
|
||||||
|
with open(self.file_path, 'r') as f:
|
||||||
|
while self.running:
|
||||||
|
line = f.readline()
|
||||||
|
if line:
|
||||||
|
callback(line.strip())
|
||||||
|
else:
|
||||||
|
time.sleep(0.5)
|
||||||
|
threading.Thread(target=run, daemon=True).start()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.running = False
|
||||||
|
|
||||||
|
class DataSender:
|
||||||
|
def __init__(self):
|
||||||
|
self.targets = []
|
||||||
|
|
||||||
|
def add_target(self, host, port):
|
||||||
|
self.targets.append((host, port))
|
||||||
|
|
||||||
|
|
||||||
|
# def send(self, data):
|
||||||
|
# for host, port in self.targets:
|
||||||
|
# try:
|
||||||
|
# with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
|
# s.connect((host, port))
|
||||||
|
# s.sendall(data.encode('utf-8'))
|
||||||
|
# except Exception as e:
|
||||||
|
# print(f"Error sending data to {host}:{port}: {e}")
|
||||||
|
|
||||||
|
class DataProcessor:
|
||||||
|
def process_protocol_a(self, data):
|
||||||
|
return data.upper()
|
||||||
|
|
||||||
|
def process_protocol_b(self, data):
|
||||||
|
return data[::-1]
|
||||||
|
|
||||||
|
def process_protocol_saratov(self, data):
|
||||||
|
if data == "\xff":
|
||||||
|
return
|
||||||
|
|
||||||
|
cdata = binascii.hexlify(data.encode("utf-8"))
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
temp = edata.split("FF 52")
|
||||||
|
results = []
|
||||||
|
for i in temp:
|
||||||
|
try:
|
||||||
|
minutes = int(i.split()[5], 16)
|
||||||
|
seconds = int(i.split()[6], 16)
|
||||||
|
timer_str = f"{minutes}:{seconds:02d}" if seconds < 60 else f"{minutes}.{seconds-128}"
|
||||||
|
|
||||||
|
seconds_24 = int(i.split()[7], 16)
|
||||||
|
timer_attack = ""
|
||||||
|
timer_pic = "D:\\Graphics\\Basketball\\24Sec_Orange.png"
|
||||||
|
if seconds_24 != 255:
|
||||||
|
if seconds_24 > 127:
|
||||||
|
seconds_24 -= 128
|
||||||
|
timer_attack = f"{seconds_24//10}.{seconds_24%10}"
|
||||||
|
timer_pic = "D:\\Graphics\\Basketball\\24Sec_Red.png"
|
||||||
|
else:
|
||||||
|
timer_attack = seconds_24
|
||||||
|
|
||||||
|
quarter = int(i.split()[14][1], 16)
|
||||||
|
timeout1 = int(i.split()[10], 16)
|
||||||
|
timeout2 = int(i.split()[11], 16)
|
||||||
|
score1 = int(i.split()[8], 16)
|
||||||
|
score2 = int(i.split()[9], 16)
|
||||||
|
foul1 = int(i.split()[12], 16)
|
||||||
|
foul2 = int(i.split()[13], 16)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"TIMER.Text": timer_str,
|
||||||
|
"ATTACK.Text": timer_attack,
|
||||||
|
"Score_Home.Text": score1,
|
||||||
|
"Score_Away.Text": score2,
|
||||||
|
"fouls1.Source": f"D:\\Graphics\\Basketball\\Home_{foul1}.png",
|
||||||
|
"fouls2.Source": f"D:\\Graphics\\Basketball\\Away_{foul2}.png",
|
||||||
|
"24SECBACKGROUND.Source": timer_pic,
|
||||||
|
}
|
||||||
|
for key, value in data.items():
|
||||||
|
send_data(key, value)
|
||||||
|
|
||||||
|
results.append(data)
|
||||||
|
except (IndexError, ValueError):
|
||||||
|
continue
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
class App:
|
||||||
|
def __init__(self, root):
|
||||||
|
self.receiver = DataReceiver()
|
||||||
|
self.sender = DataSender()
|
||||||
|
self.processor = DataProcessor()
|
||||||
|
|
||||||
|
self.protocol_var = tk.StringVar(value="Protocol A")
|
||||||
|
self.mode_var = tk.StringVar(value="Log File")
|
||||||
|
|
||||||
|
self.create_ui(root)
|
||||||
|
|
||||||
|
def display_data(self, data):
|
||||||
|
protocol = self.protocol_var.get()
|
||||||
|
if protocol == "Protocol A":
|
||||||
|
processed_data = self.processor.process_protocol_a(data)
|
||||||
|
elif protocol == "Protocol B":
|
||||||
|
processed_data = self.processor.process_protocol_b(data)
|
||||||
|
elif protocol == "Saratov":
|
||||||
|
processed_data = self.processor.process_protocol_saratov(data)
|
||||||
|
else:
|
||||||
|
processed_data = data
|
||||||
|
|
||||||
|
if processed_data:
|
||||||
|
self.update_send_status(True)
|
||||||
|
self.sender.send(str(processed_data))
|
||||||
|
self.update_send_status(False)
|
||||||
|
|
||||||
|
def create_ui(self, root):
|
||||||
|
root.title("Data Processing Application")
|
||||||
|
|
||||||
|
self.notebook = tk.ttk.Notebook(root)
|
||||||
|
self.notebook.pack(fill="both", expand=True)
|
||||||
|
|
||||||
|
self.settings_frame = tk.Frame(self.notebook)
|
||||||
|
self.game_frame = tk.Frame(self.notebook)
|
||||||
|
|
||||||
|
self.notebook.add(self.settings_frame, text="Settings")
|
||||||
|
self.notebook.add(self.game_frame, text="Game")
|
||||||
|
|
||||||
|
self.create_settings_ui(self.settings_frame)
|
||||||
|
self.create_game_ui(self.game_frame)
|
||||||
|
|
||||||
|
def create_settings_ui(self, frame):
|
||||||
|
# Frame for receiving data
|
||||||
|
frame_receive = tk.LabelFrame(frame, text="Receive Data")
|
||||||
|
frame_receive.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
|
tk.Label(frame_receive, text="Select Mode:").pack(side="left", padx=5, pady=5)
|
||||||
|
tk.OptionMenu(frame_receive, self.mode_var, "Log File", "TCP Connection", command=self.update_mode).pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.file_button = tk.Button(frame_receive, text="Select Log File", command=self.select_file)
|
||||||
|
|
||||||
|
self.tcp_frame = tk.Frame(frame_receive)
|
||||||
|
tk.Label(self.tcp_frame, text="IP:").pack(side="left")
|
||||||
|
self.tcp_ip_entry = tk.Entry(self.tcp_frame)
|
||||||
|
self.tcp_ip_entry.pack(side="left", padx=5)
|
||||||
|
tk.Label(self.tcp_frame, text="Port:").pack(side="left")
|
||||||
|
self.tcp_port_entry = tk.Entry(self.tcp_frame)
|
||||||
|
self.tcp_port_entry.pack(side="left", padx=5)
|
||||||
|
|
||||||
|
self.start_button = tk.Button(frame_receive, text="Start", command=self.start_receiving)
|
||||||
|
self.start_button.pack(side="left", padx=5, pady=5)
|
||||||
|
tk.Button(frame_receive, text="Stop", command=self.stop_receiving).pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
# Frame for processing data
|
||||||
|
frame_process = tk.LabelFrame(frame, text="Process Data")
|
||||||
|
frame_process.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
|
tk.Label(frame_process, text="Select Protocol:").pack(side="left", padx=5, pady=5)
|
||||||
|
tk.OptionMenu(frame_process, self.protocol_var, "Protocol A", "Protocol B", "Saratov").pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
# Frame for sending data
|
||||||
|
frame_send = tk.LabelFrame(frame, text="Send Data")
|
||||||
|
frame_send.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.target_count_var = tk.IntVar(value=1)
|
||||||
|
tk.Label(frame_send, text="Number of Targets:").pack(side="left", padx=5, pady=5)
|
||||||
|
tk.Spinbox(frame_send, from_=1, to=10, textvariable=self.target_count_var, command=self.update_targets).pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.targets_frame = tk.Frame(frame_send)
|
||||||
|
self.targets_frame.pack(fill="x", padx=5, pady=5)
|
||||||
|
self.target_entries = []
|
||||||
|
self.update_targets()
|
||||||
|
|
||||||
|
tk.Button(frame_send, text="Send Data", command=self.send_data).pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.update_mode(self.mode_var.get())
|
||||||
|
|
||||||
|
def create_game_ui(self, frame):
|
||||||
|
frame_status = tk.LabelFrame(frame, text="Status")
|
||||||
|
frame_status.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.data_receive_status = tk.Label(frame_status, text="Receiving Data: Not Active", fg="red")
|
||||||
|
self.data_receive_status.pack(pady=5)
|
||||||
|
|
||||||
|
self.data_send_status = tk.Label(frame_status, text="Sending Data: Not Active", fg="red")
|
||||||
|
self.data_send_status.pack(pady=5)
|
||||||
|
|
||||||
|
def update_mode(self, mode):
|
||||||
|
if mode == "Log File":
|
||||||
|
self.file_button.pack(side="left", padx=5, pady=5)
|
||||||
|
self.tcp_frame.pack_forget()
|
||||||
|
self.start_button.config(state="normal")
|
||||||
|
else:
|
||||||
|
self.file_button.pack_forget()
|
||||||
|
self.tcp_frame.pack(side="left", padx=5, pady=5)
|
||||||
|
self.start_button.config(state="normal")
|
||||||
|
|
||||||
|
def select_file(self):
|
||||||
|
self.receiver.file_path = filedialog.askopenfilename()
|
||||||
|
|
||||||
|
def start_receiving(self):
|
||||||
|
self.start_button.config(state="disabled")
|
||||||
|
mode = self.mode_var.get()
|
||||||
|
if mode == "Log File":
|
||||||
|
if self.receiver.file_path:
|
||||||
|
self.receiver.start_file(self.display_data)
|
||||||
|
self.update_receive_status(True)
|
||||||
|
else:
|
||||||
|
messagebox.showerror("Error", "No file selected.")
|
||||||
|
elif mode == "TCP Connection":
|
||||||
|
host = self.tcp_ip_entry.get()
|
||||||
|
port = self.tcp_port_entry.get()
|
||||||
|
if host and port.isdigit():
|
||||||
|
self.receiver.start_tcp(host, int(port), self.display_data)
|
||||||
|
self.update_receive_status(True)
|
||||||
|
else:
|
||||||
|
messagebox.showerror("Error", "Invalid IP or port.")
|
||||||
|
self.start_button.config(state="normal")
|
||||||
|
|
||||||
|
def stop_receiving(self):
|
||||||
|
self.receiver.stop()
|
||||||
|
self.start_button.config(state="normal")
|
||||||
|
self.update_receive_status(False)
|
||||||
|
|
||||||
|
def display_data(self, data):
|
||||||
|
protocol = self.protocol_var.get()
|
||||||
|
if protocol == "Protocol A":
|
||||||
|
processed_data = self.processor.process_protocol_a(data)
|
||||||
|
else:
|
||||||
|
processed_data = self.processor.process_protocol_b(data)
|
||||||
|
|
||||||
|
self.update_send_status(True)
|
||||||
|
self.sender.send(processed_data)
|
||||||
|
self.update_send_status(False)
|
||||||
|
|
||||||
|
def update_receive_status(self, active):
|
||||||
|
if active:
|
||||||
|
self.data_receive_status.config(text="Receiving Data: Active", fg="green")
|
||||||
|
else:
|
||||||
|
self.data_receive_status.config(text="Receiving Data: Not Active", fg="red")
|
||||||
|
|
||||||
|
def update_send_status(self, active):
|
||||||
|
if active:
|
||||||
|
self.data_send_status.config(text="Sending Data: Active", fg="green")
|
||||||
|
else:
|
||||||
|
self.data_send_status.config(text="Sending Data: Not Active", fg="red")
|
||||||
|
|
||||||
|
def update_targets(self):
|
||||||
|
for widget in self.targets_frame.winfo_children():
|
||||||
|
widget.destroy()
|
||||||
|
|
||||||
|
self.target_entries = []
|
||||||
|
for i in range(self.target_count_var.get()):
|
||||||
|
target_frame = tk.Frame(self.targets_frame)
|
||||||
|
target_frame.pack(fill="x", pady=2)
|
||||||
|
|
||||||
|
tk.Label(target_frame, text=f"Target {i+1} Host:").pack(side="left")
|
||||||
|
host_entry = tk.Entry(target_frame)
|
||||||
|
host_entry.pack(side="left", padx=5)
|
||||||
|
|
||||||
|
tk.Label(target_frame, text="Port:").pack(side="left")
|
||||||
|
port_entry = tk.Entry(target_frame)
|
||||||
|
port_entry.pack(side="left", padx=5)
|
||||||
|
|
||||||
|
self.target_entries.append((host_entry, port_entry))
|
||||||
|
|
||||||
|
def send_data(self):
|
||||||
|
data = "Sample data to send"
|
||||||
|
if not data:
|
||||||
|
messagebox.showerror("No Data", "No data to send.")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.sender.targets = []
|
||||||
|
for host_entry, port_entry in self.target_entries:
|
||||||
|
host = host_entry.get()
|
||||||
|
port = port_entry.get()
|
||||||
|
if host and port.isdigit():
|
||||||
|
self.sender.add_target(host, int(port))
|
||||||
|
|
||||||
|
self.update_send_status(True)
|
||||||
|
self.sender.send(data)
|
||||||
|
self.update_send_status(False)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
root = tk.Tk()
|
||||||
|
app = App(root)
|
||||||
|
root.mainloop()
|
||||||
369
timer_app2_temp.py
Normal file
369
timer_app2_temp.py
Normal file
@@ -0,0 +1,369 @@
|
|||||||
|
import tkinter as tk
|
||||||
|
from tkinter import filedialog, messagebox, ttk
|
||||||
|
import threading
|
||||||
|
import socket
|
||||||
|
import time
|
||||||
|
import binascii
|
||||||
|
import requests
|
||||||
|
import json # To handle structured data better
|
||||||
|
|
||||||
|
def hexspace(data, n):
|
||||||
|
return " ".join([data[i:i + n] for i in range(0, len(data), n)])
|
||||||
|
|
||||||
|
session = requests.Session()
|
||||||
|
session.headers.update({"Connection": "keep-alive"})
|
||||||
|
|
||||||
|
class DataReceiver:
|
||||||
|
def __init__(self):
|
||||||
|
self.running = False
|
||||||
|
self.file_mode = False
|
||||||
|
self.file_path = None
|
||||||
|
self.manual_mode = False
|
||||||
|
|
||||||
|
def start_tcp(self, host, port, callback):
|
||||||
|
self.running = True
|
||||||
|
def run():
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
|
s.bind((host, port))
|
||||||
|
s.listen(1)
|
||||||
|
conn, addr = s.accept()
|
||||||
|
with conn:
|
||||||
|
while self.running:
|
||||||
|
data = conn.recv(1024)
|
||||||
|
if data:
|
||||||
|
callback(data.decode('utf-8'))
|
||||||
|
threading.Thread(target=run, daemon=True).start()
|
||||||
|
|
||||||
|
def start_file(self, callback, timeout):
|
||||||
|
self.running = True
|
||||||
|
def run():
|
||||||
|
if not self.file_path:
|
||||||
|
return
|
||||||
|
with open(self.file_path, 'r') as f:
|
||||||
|
while self.running:
|
||||||
|
if self.manual_mode:
|
||||||
|
continue
|
||||||
|
line = f.readline()
|
||||||
|
if line:
|
||||||
|
try:
|
||||||
|
# Safely parse the data, assuming the data format is correct
|
||||||
|
callback(json.loads(line.strip().split(" DEBUG ")[1]))
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error parsing line: {e}")
|
||||||
|
time.sleep(timeout)
|
||||||
|
threading.Thread(target=run, daemon=True).start()
|
||||||
|
|
||||||
|
def read_next_line(self, callback):
|
||||||
|
if not self.file_path:
|
||||||
|
return
|
||||||
|
with open(self.file_path, 'r') as f:
|
||||||
|
line = f.readline()
|
||||||
|
if line:
|
||||||
|
try:
|
||||||
|
callback(json.loads(line.strip().split(" DEBUG ")[1]))
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error parsing line: {e}")
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.running = False
|
||||||
|
|
||||||
|
class DataSender:
|
||||||
|
def __init__(self):
|
||||||
|
self.targets = []
|
||||||
|
|
||||||
|
def add_target(self, host, port):
|
||||||
|
self.targets.append((host, port))
|
||||||
|
|
||||||
|
def send(self, data):
|
||||||
|
for host, port in self.targets:
|
||||||
|
try:
|
||||||
|
url = f"http://{host}:{port}/API/"
|
||||||
|
for k, v in data.items():
|
||||||
|
par = "SetText" if k.split(".")[1] == "Text" else "SetImage"
|
||||||
|
params = {
|
||||||
|
"Function": par,
|
||||||
|
"Input": 23,
|
||||||
|
"SelectedName": k,
|
||||||
|
"Value": v,
|
||||||
|
}
|
||||||
|
session.get(url, params=params)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error sending data to {host}:{port}: {e}")
|
||||||
|
|
||||||
|
class DataProcessor:
|
||||||
|
def process_protocol_a(self, data):
|
||||||
|
return data.upper()
|
||||||
|
|
||||||
|
def process_protocol_b(self, data):
|
||||||
|
return data[::-1]
|
||||||
|
|
||||||
|
def process_protocol_saratov(self, data):
|
||||||
|
if data == "\xff":
|
||||||
|
return None
|
||||||
|
|
||||||
|
cdata = binascii.hexlify(data.encode()) # Ensure data is properly encoded to bytes
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
temp = edata.split("FF 52")
|
||||||
|
processed_data = []
|
||||||
|
for i in temp:
|
||||||
|
try:
|
||||||
|
parts = i.split()
|
||||||
|
minutes = int(parts[5], 16)
|
||||||
|
seconds = int(parts[6], 16)
|
||||||
|
timer_str = f"{minutes}:{seconds:02d}" if seconds < 60 else f"{minutes}.{seconds - 128}"
|
||||||
|
|
||||||
|
seconds_24 = int(parts[7], 16)
|
||||||
|
timer_attack = ""
|
||||||
|
timer_pic = "D:/Графика/БАСКЕТБОЛ/ЕДИНАЯ ЛИГА ВТБ 2022-2023/Scorebug Indicators/24Sec_Orange.png"
|
||||||
|
if seconds_24 != 255:
|
||||||
|
if seconds_24 > 127:
|
||||||
|
seconds_24 -= 128
|
||||||
|
timer_attack = f"{seconds_24 // 10}.{seconds_24 % 10}"
|
||||||
|
timer_pic = "D:/Графика/БАСКЕТБОЛ/ЕДИНАЯ ЛИГА ВТБ 2022-2023/Scorebug Indicators/24Sec_Red.png"
|
||||||
|
else:
|
||||||
|
timer_attack = seconds_24
|
||||||
|
|
||||||
|
quarter = int(parts[14][1], 16)
|
||||||
|
timeout1 = int(parts[10], 16)
|
||||||
|
timeout2 = int(parts[11], 16)
|
||||||
|
score1 = int(parts[8], 16)
|
||||||
|
score2 = int(parts[9], 16)
|
||||||
|
foul1 = int(parts[12], 16)
|
||||||
|
foul2 = int(parts[13], 16)
|
||||||
|
|
||||||
|
data_dict = {
|
||||||
|
"TIMER.Text": timer_str,
|
||||||
|
"ATTACK.Text": timer_attack,
|
||||||
|
"Score_Home.Text": score1,
|
||||||
|
"Score_Away.Text": score2,
|
||||||
|
"fouls1.Source": f"D:/Графика/БАСКЕТБОЛ/ЕДИНАЯ ЛИГА ВТБ 2022-2023/Scorebug Indicators/Home_{foul1}.png",
|
||||||
|
"fouls2.Source": f"D:/Графика/БАСКЕТБОЛ/ЕДИНАЯ ЛИГА ВТБ 2022-2023/Scorebug Indicators/Away_{foul2}.png",
|
||||||
|
"24SECBACKGROUND.Source": timer_pic,
|
||||||
|
}
|
||||||
|
|
||||||
|
processed_data.append(data_dict)
|
||||||
|
except (IndexError, ValueError) as e:
|
||||||
|
print(f"Error processing data: {e}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
return processed_data
|
||||||
|
|
||||||
|
class App:
|
||||||
|
def __init__(self, root):
|
||||||
|
self.receiver = DataReceiver()
|
||||||
|
self.sender = DataSender()
|
||||||
|
self.processor = DataProcessor()
|
||||||
|
|
||||||
|
self.protocol_var = tk.StringVar(value="Protocol A")
|
||||||
|
self.mode_var = tk.StringVar(value="Log File")
|
||||||
|
self.read_mode_var = tk.StringVar(value="Automatic")
|
||||||
|
self.timeout_var = tk.DoubleVar(value=0.5)
|
||||||
|
|
||||||
|
self.create_ui(root)
|
||||||
|
|
||||||
|
def display_data(self, data):
|
||||||
|
protocol = self.protocol_var.get()
|
||||||
|
if protocol == "Protocol A":
|
||||||
|
processed_data = self.processor.process_protocol_a(data)
|
||||||
|
elif protocol == "Protocol B":
|
||||||
|
processed_data = self.processor.process_protocol_b(data)
|
||||||
|
elif protocol == "Saratov":
|
||||||
|
processed_data = self.processor.process_protocol_saratov(data)
|
||||||
|
else:
|
||||||
|
processed_data = data
|
||||||
|
|
||||||
|
if processed_data:
|
||||||
|
self.update_send_status(True)
|
||||||
|
self.sender.send(processed_data)
|
||||||
|
self.update_send_status(False)
|
||||||
|
|
||||||
|
self.log_text.insert(tk.END, f"{data}\n")
|
||||||
|
self.log_text.see(tk.END)
|
||||||
|
|
||||||
|
self.processed_data_text.insert(tk.END, f"{processed_data}\n")
|
||||||
|
self.processed_data_text.see(tk.END)
|
||||||
|
|
||||||
|
def create_ui(self, root):
|
||||||
|
root.title("Data Processing Application")
|
||||||
|
|
||||||
|
self.notebook = ttk.Notebook(root)
|
||||||
|
self.notebook.pack(fill="both", expand=True)
|
||||||
|
|
||||||
|
self.settings_frame = tk.Frame(self.notebook)
|
||||||
|
self.game_frame = tk.Frame(self.notebook)
|
||||||
|
|
||||||
|
self.notebook.add(self.settings_frame, text="Settings")
|
||||||
|
self.notebook.add(self.game_frame, text="Game")
|
||||||
|
|
||||||
|
self.create_settings_ui(self.settings_frame)
|
||||||
|
self.create_game_ui(self.game_frame)
|
||||||
|
|
||||||
|
def create_settings_ui(self, frame):
|
||||||
|
frame_receive = tk.LabelFrame(frame, text="Receive Data")
|
||||||
|
frame_receive.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
|
tk.Label(frame_receive, text="Select Mode:").pack(side="left", padx=5, pady=5)
|
||||||
|
tk.OptionMenu(frame_receive, self.mode_var, "Log File", "TCP Connection", command=self.update_mode).pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.file_button = tk.Button(frame_receive, text="Select Log File", command=self.select_file)
|
||||||
|
|
||||||
|
self.tcp_frame = tk.Frame(frame_receive)
|
||||||
|
tk.Label(self.tcp_frame, text="IP:").pack(side="left")
|
||||||
|
self.tcp_ip_entry = tk.Entry(self.tcp_frame)
|
||||||
|
self.tcp_ip_entry.pack(side="left", padx=5)
|
||||||
|
self.tcp_ip_entry.insert(0, "192.168.127.254") # Example default IP address
|
||||||
|
tk.Label(self.tcp_frame, text="Port:").pack(side="left")
|
||||||
|
self.tcp_port_entry = tk.Entry(self.tcp_frame)
|
||||||
|
self.tcp_port_entry.pack(side="left", padx=5)
|
||||||
|
self.tcp_port_entry.insert(0, 1993) # Example default port
|
||||||
|
|
||||||
|
self.read_mode_frame = tk.Frame(frame_receive)
|
||||||
|
tk.Label(self.read_mode_frame, text="Read Mode:").pack(side="left", padx=5, pady=5)
|
||||||
|
tk.OptionMenu(self.read_mode_frame, self.read_mode_var, "Automatic", "Manual", command=self.update_read_mode).pack(side="left", padx=5, pady=5)
|
||||||
|
tk.Label(self.read_mode_frame, text="Timeout (s):").pack(side="left", padx=5, pady=5)
|
||||||
|
self.timeout_entry = tk.Entry(self.read_mode_frame, textvariable=self.timeout_var)
|
||||||
|
self.timeout_entry.pack(side="left", padx=5)
|
||||||
|
self.manual_read_button = tk.Button(self.read_mode_frame, text="Read Next Line", command=self.read_next_line)
|
||||||
|
|
||||||
|
self.start_button = tk.Button(frame_receive, text="Start", command=self.start_receiving)
|
||||||
|
self.start_button.pack(side="left", padx=5, pady=5)
|
||||||
|
tk.Button(frame_receive, text="Stop", command=self.stop_receiving).pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
frame_process = tk.LabelFrame(frame, text="Process Data")
|
||||||
|
frame_process.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
|
tk.Label(frame_process, text="Select Protocol:").pack(side="left", padx=5, pady=5)
|
||||||
|
tk.OptionMenu(frame_process, self.protocol_var, "Protocol A", "Protocol B", "Saratov").pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
frame_send = tk.LabelFrame(frame, text="Send Data")
|
||||||
|
frame_send.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.target_count_var = tk.IntVar(value=1)
|
||||||
|
tk.Label(frame_send, text="Number of Targets:").pack(side="left", padx=5, pady=5)
|
||||||
|
tk.Spinbox(frame_send, from_=1, to=10, textvariable=self.target_count_var, command=self.update_targets).pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.targets_frame = tk.Frame(frame_send)
|
||||||
|
self.targets_frame.pack(fill="x", padx=5, pady=5)
|
||||||
|
self.target_entries = []
|
||||||
|
self.update_targets()
|
||||||
|
|
||||||
|
tk.Button(frame_send, text="Send Data", command=self.send_data).pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.update_mode(self.mode_var.get())
|
||||||
|
|
||||||
|
def create_game_ui(self, frame):
|
||||||
|
frame_status = tk.LabelFrame(frame, text="Status")
|
||||||
|
frame_status.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.data_receive_status = tk.Label(frame_status, text="Receiving Data: Not Active", fg="red")
|
||||||
|
self.data_receive_status.pack(pady=5)
|
||||||
|
|
||||||
|
self.data_send_status = tk.Label(frame_status, text="Sending Data: Not Active", fg="red")
|
||||||
|
self.data_send_status.pack(pady=5)
|
||||||
|
|
||||||
|
frame_log = tk.LabelFrame(frame, text="Log")
|
||||||
|
frame_log.pack(fill="both", expand=True, padx=5, pady=5)
|
||||||
|
|
||||||
|
self.log_text = tk.Text(frame_log, height=10, state="normal")
|
||||||
|
self.log_text.pack(fill="both", expand=True, padx=5, pady=5)
|
||||||
|
|
||||||
|
frame_processed = tk.LabelFrame(frame, text="Processed Data")
|
||||||
|
frame_processed.pack(fill="both", expand=True, padx=5, pady=5)
|
||||||
|
|
||||||
|
self.processed_data_text = tk.Text(frame_processed, height=10, state="normal")
|
||||||
|
self.processed_data_text.pack(fill="both", expand=True, padx=5, pady=5)
|
||||||
|
|
||||||
|
def update_mode(self, mode):
|
||||||
|
if mode == "Log File":
|
||||||
|
self.file_button.pack(side="left", padx=5, pady=5)
|
||||||
|
self.tcp_frame.pack_forget()
|
||||||
|
self.read_mode_frame.pack(fill="x", padx=5, pady=5)
|
||||||
|
self.start_button.config(state="normal")
|
||||||
|
else:
|
||||||
|
self.file_button.pack_forget()
|
||||||
|
self.read_mode_frame.pack_forget()
|
||||||
|
self.tcp_frame.pack(side="left", padx=5, pady=5)
|
||||||
|
self.start_button.config(state="normal")
|
||||||
|
|
||||||
|
def update_read_mode(self, mode):
|
||||||
|
if mode == "Automatic":
|
||||||
|
self.timeout_entry.config(state="normal")
|
||||||
|
self.manual_read_button.pack_forget()
|
||||||
|
self.receiver.manual_mode = False
|
||||||
|
else:
|
||||||
|
self.timeout_entry.config(state="disabled")
|
||||||
|
self.manual_read_button.pack(side="left", padx=5, pady=5)
|
||||||
|
self.receiver.manual_mode = True
|
||||||
|
|
||||||
|
def select_file(self):
|
||||||
|
self.receiver.file_path = filedialog.askopenfilename()
|
||||||
|
|
||||||
|
def start_receiving(self):
|
||||||
|
self.start_button.config(state="disabled")
|
||||||
|
mode = self.mode_var.get()
|
||||||
|
if mode == "Log File":
|
||||||
|
if self.receiver.file_path:
|
||||||
|
timeout = self.timeout_var.get() if self.read_mode_var.get() == "Automatic" else 0
|
||||||
|
self.receiver.start_file(self.display_data, timeout)
|
||||||
|
self.update_receive_status(True)
|
||||||
|
else:
|
||||||
|
messagebox.showerror("Error", "No file selected.")
|
||||||
|
elif mode == "TCP Connection":
|
||||||
|
host = self.tcp_ip_entry.get()
|
||||||
|
port = self.tcp_port_entry.get()
|
||||||
|
if host and port.isdigit():
|
||||||
|
self.receiver.start_tcp(host, int(port), self.display_data)
|
||||||
|
self.update_receive_status(True)
|
||||||
|
else:
|
||||||
|
messagebox.showerror("Error", "Invalid IP or port.")
|
||||||
|
self.start_button.config(state="normal")
|
||||||
|
|
||||||
|
def stop_receiving(self):
|
||||||
|
self.receiver.stop()
|
||||||
|
self.start_button.config(state="normal")
|
||||||
|
self.update_receive_status(False)
|
||||||
|
|
||||||
|
def read_next_line(self):
|
||||||
|
self.receiver.read_next_line(self.display_data)
|
||||||
|
|
||||||
|
def update_receive_status(self, active):
|
||||||
|
if active:
|
||||||
|
self.data_receive_status.config(text="Receiving Data: Active", fg="green")
|
||||||
|
else:
|
||||||
|
self.data_receive_status.config(text="Receiving Data: Not Active", fg="red")
|
||||||
|
|
||||||
|
def update_send_status(self, active):
|
||||||
|
if active:
|
||||||
|
self.data_send_status.config(text="Sending Data: Active", fg="green")
|
||||||
|
else:
|
||||||
|
self.data_send_status.config(text="Sending Data: Not Active", fg="red")
|
||||||
|
|
||||||
|
def update_targets(self):
|
||||||
|
for widget in self.targets_frame.winfo_children():
|
||||||
|
widget.destroy()
|
||||||
|
|
||||||
|
self.target_entries = []
|
||||||
|
for i in range(self.target_count_var.get()):
|
||||||
|
target_frame = tk.Frame(self.targets_frame)
|
||||||
|
target_frame.pack(fill="x", pady=2)
|
||||||
|
|
||||||
|
tk.Label(target_frame, text=f"Target {i+1}:").pack(side="left", padx=5, pady=5)
|
||||||
|
host_entry = tk.Entry(target_frame)
|
||||||
|
host_entry.pack(side="left", padx=5)
|
||||||
|
host_entry.insert(0, f"192.168.1.{i+1}")
|
||||||
|
self.target_entries.append(host_entry)
|
||||||
|
|
||||||
|
def send_data(self):
|
||||||
|
if not self.target_entries:
|
||||||
|
messagebox.showerror("Error", "No targets defined.")
|
||||||
|
return
|
||||||
|
|
||||||
|
targets = [(entry.get(), 8080) for entry in self.target_entries]
|
||||||
|
self.sender.targets = targets
|
||||||
|
self.sender.send({"data": "sample"})
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
root = tk.Tk()
|
||||||
|
app = App(root)
|
||||||
|
root.mainloop()
|
||||||
415
timer_app3.py
Normal file
415
timer_app3.py
Normal file
@@ -0,0 +1,415 @@
|
|||||||
|
import tkinter as tk
|
||||||
|
from tkinter import filedialog, messagebox, ttk
|
||||||
|
import threading
|
||||||
|
import socket
|
||||||
|
import time
|
||||||
|
import binascii
|
||||||
|
import requests
|
||||||
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
|
||||||
|
def hexspace(data, n):
|
||||||
|
return " ".join([data[i:i + n] for i in range(0, len(data), n)])
|
||||||
|
|
||||||
|
session = requests.Session()
|
||||||
|
session.headers.update({"Connection": "keep-alive"})
|
||||||
|
|
||||||
|
class DataReceiver:
|
||||||
|
def __init__(self):
|
||||||
|
self.running = False
|
||||||
|
self.file_mode = False
|
||||||
|
self.file_path = None
|
||||||
|
self.manual_mode = False
|
||||||
|
|
||||||
|
def start_tcp(self, host, port, callback):
|
||||||
|
self.running = True
|
||||||
|
def run():
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
|
s.bind((host, port))
|
||||||
|
s.listen(1)
|
||||||
|
conn, addr = s.accept()
|
||||||
|
with conn:
|
||||||
|
while self.running:
|
||||||
|
data = conn.recv(1024)
|
||||||
|
if data:
|
||||||
|
callback(data.decode('utf-8'))
|
||||||
|
threading.Thread(target=run, daemon=True).start()
|
||||||
|
|
||||||
|
def start_file(self, callback, timeout):
|
||||||
|
self.running = True
|
||||||
|
def run():
|
||||||
|
if not self.file_path:
|
||||||
|
return
|
||||||
|
with open(self.file_path, 'r') as f:
|
||||||
|
while self.running:
|
||||||
|
if self.manual_mode:
|
||||||
|
continue
|
||||||
|
line = f.readline()
|
||||||
|
if line:
|
||||||
|
callback(eval(line.strip().split(" DEBUG ")[1]))
|
||||||
|
time.sleep(timeout)
|
||||||
|
threading.Thread(target=run, daemon=True).start()
|
||||||
|
|
||||||
|
def read_next_line(self, callback):
|
||||||
|
if not self.file_path:
|
||||||
|
return
|
||||||
|
with open(self.file_path, 'r') as f:
|
||||||
|
line = f.readline()
|
||||||
|
if line:
|
||||||
|
callback(eval(line.strip().split(" DEBUG ")[1]))
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.running = False
|
||||||
|
|
||||||
|
class DataSender:
|
||||||
|
def __init__(self):
|
||||||
|
self.targets = []
|
||||||
|
self.session = requests.Session()
|
||||||
|
self.session.headers.update({"Connection": "keep-alive"})
|
||||||
|
|
||||||
|
def add_target(self, host, port):
|
||||||
|
self.targets.append((host, port))
|
||||||
|
|
||||||
|
|
||||||
|
def send(self, data):
|
||||||
|
"""Многопоточная отправка данных на все указанные цели."""
|
||||||
|
if not self.targets:
|
||||||
|
print("No targets available to send data.")
|
||||||
|
return
|
||||||
|
|
||||||
|
def send_to_target(target):
|
||||||
|
host, port = target
|
||||||
|
url = f"http://{host}:{port}/API/"
|
||||||
|
try:
|
||||||
|
for k, v in data.items():
|
||||||
|
par = "SetText" if k.split(".")[1] == "Text" else "SetImage"
|
||||||
|
params = {
|
||||||
|
"Function": par,
|
||||||
|
"Input": 51,
|
||||||
|
"SelectedName": k,
|
||||||
|
"Value": v,
|
||||||
|
}
|
||||||
|
response = self.session.get(url, params=params, timeout=5)
|
||||||
|
response.raise_for_status() # Проверяет, есть ли ошибки HTTP
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print(f"Error sending data to {host}:{port}: {e}")
|
||||||
|
|
||||||
|
# Используем ThreadPoolExecutor для многопоточной отправки
|
||||||
|
with ThreadPoolExecutor(max_workers=5) as executor: # max_workers можно настроить
|
||||||
|
executor.map(send_to_target, self.targets)
|
||||||
|
|
||||||
|
|
||||||
|
# def send(self, data):
|
||||||
|
# for host, port in self.targets:
|
||||||
|
# try:
|
||||||
|
# url = f"http://{host}:{port}/API/"
|
||||||
|
# print(data)
|
||||||
|
# for k,v in data.items():
|
||||||
|
# par = "SetText" if k.split(".")[1] == "Text" else "SetImage"
|
||||||
|
# params = {
|
||||||
|
# "Function": par,
|
||||||
|
# "Input": 51,
|
||||||
|
# "SelectedName": k,
|
||||||
|
# "Value": v,
|
||||||
|
# }
|
||||||
|
# session.get(url, params=params)
|
||||||
|
# except Exception as e:
|
||||||
|
# print(f"Error sending data to {host}:{port}: {e}")
|
||||||
|
|
||||||
|
# def send(self, data):
|
||||||
|
# for host, port in self.targets:
|
||||||
|
# try:
|
||||||
|
# with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
|
# s.connect((host, port))
|
||||||
|
# s.sendall(data.encode('utf-8'))
|
||||||
|
# except Exception as e:
|
||||||
|
# print(f"Error sending data to {host}:{port}: {e}")
|
||||||
|
|
||||||
|
class DataProcessor:
|
||||||
|
def process_protocol_a(self, data):
|
||||||
|
return data.upper()
|
||||||
|
|
||||||
|
def process_protocol_b(self, data):
|
||||||
|
return data[::-1]
|
||||||
|
|
||||||
|
def process_protocol_saratov(self, data):
|
||||||
|
if data == "\xff":
|
||||||
|
return
|
||||||
|
|
||||||
|
cdata = binascii.hexlify(data)
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
temp = edata.split("FF 52")
|
||||||
|
# results = []
|
||||||
|
for i in temp:
|
||||||
|
try:
|
||||||
|
minutes = int(i.split()[5], 16)
|
||||||
|
seconds = int(i.split()[6], 16)
|
||||||
|
timer_str = f"{minutes}:{seconds:02d}" if seconds < 60 else f"{minutes}.{seconds-128}"
|
||||||
|
|
||||||
|
seconds_24 = int(i.split()[7], 16)
|
||||||
|
timer_attack = ""
|
||||||
|
timer_pic = "D:\Графика\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators\\24Sec_Orange.png"
|
||||||
|
if seconds_24 != 255:
|
||||||
|
if seconds_24 > 127:
|
||||||
|
seconds_24 -= 128
|
||||||
|
timer_attack = f"{seconds_24//10}.{seconds_24%10}"
|
||||||
|
timer_pic = "D:\Графика\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators\\24Sec_Red.png"
|
||||||
|
else:
|
||||||
|
timer_attack = seconds_24
|
||||||
|
|
||||||
|
quarter = int(i.split()[14][1], 16)
|
||||||
|
timeout1 = int(i.split()[10], 16)
|
||||||
|
timeout2 = int(i.split()[11], 16)
|
||||||
|
score1 = int(i.split()[8], 16)
|
||||||
|
score2 = int(i.split()[9], 16)
|
||||||
|
foul1 = int(i.split()[12], 16)
|
||||||
|
foul2 = int(i.split()[13], 16)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"TIMER.Text": timer_str,
|
||||||
|
"ATTACK.Text": timer_attack,
|
||||||
|
"Score_Home.Text": score1,
|
||||||
|
"Score_Away.Text": score2,
|
||||||
|
"fouls1.Source": f"D:\Графика\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators\Home_{foul1}.png",
|
||||||
|
"fouls2.Source": f"D:\Графика\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators\Away_{foul2}.png",
|
||||||
|
"24SECBACKGROUND.Source": timer_pic,
|
||||||
|
}
|
||||||
|
|
||||||
|
# results.append(data)
|
||||||
|
except (IndexError, ValueError):
|
||||||
|
continue
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
class App:
|
||||||
|
def __init__(self, root):
|
||||||
|
self.receiver = DataReceiver()
|
||||||
|
self.sender = DataSender()
|
||||||
|
self.processor = DataProcessor()
|
||||||
|
|
||||||
|
self.protocol_var = tk.StringVar(value="Protocol A")
|
||||||
|
self.mode_var = tk.StringVar(value="Log File")
|
||||||
|
self.read_mode_var = tk.StringVar(value="Automatic")
|
||||||
|
self.timeout_var = tk.DoubleVar(value=0.5)
|
||||||
|
|
||||||
|
self.create_ui(root)
|
||||||
|
|
||||||
|
def display_data(self, data):
|
||||||
|
protocol = self.protocol_var.get()
|
||||||
|
if protocol == "Protocol A":
|
||||||
|
processed_data = self.processor.process_protocol_a(data)
|
||||||
|
elif protocol == "Protocol B":
|
||||||
|
processed_data = self.processor.process_protocol_b(data)
|
||||||
|
elif protocol == "Saratov":
|
||||||
|
processed_data = self.processor.process_protocol_saratov(data)
|
||||||
|
else:
|
||||||
|
processed_data = data
|
||||||
|
|
||||||
|
if processed_data:
|
||||||
|
self.update_send_status(True)
|
||||||
|
self.sender.send(processed_data)
|
||||||
|
self.update_send_status(False)
|
||||||
|
|
||||||
|
self.log_text.insert(tk.END, f"{data}\n")
|
||||||
|
self.log_text.see(tk.END)
|
||||||
|
|
||||||
|
self.processed_data_text.insert(tk.END, f"{processed_data}\n")
|
||||||
|
self.processed_data_text.see(tk.END)
|
||||||
|
|
||||||
|
def create_ui(self, root):
|
||||||
|
root.title("Data Processing Application")
|
||||||
|
|
||||||
|
self.notebook = ttk.Notebook(root)
|
||||||
|
self.notebook.pack(fill="both", expand=True)
|
||||||
|
|
||||||
|
self.settings_frame = tk.Frame(self.notebook)
|
||||||
|
self.game_frame = tk.Frame(self.notebook)
|
||||||
|
|
||||||
|
self.notebook.add(self.settings_frame, text="Settings")
|
||||||
|
self.notebook.add(self.game_frame, text="Game")
|
||||||
|
|
||||||
|
self.create_settings_ui(self.settings_frame)
|
||||||
|
self.create_game_ui(self.game_frame)
|
||||||
|
|
||||||
|
def create_settings_ui(self, frame):
|
||||||
|
frame_receive = tk.LabelFrame(frame, text="Receive Data")
|
||||||
|
frame_receive.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
|
tk.Label(frame_receive, text="Select Mode:").pack(side="left", padx=5, pady=5)
|
||||||
|
tk.OptionMenu(frame_receive, self.mode_var, "Log File", "TCP Connection", command=self.update_mode).pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.file_button = tk.Button(frame_receive, text="Select Log File", command=self.select_file)
|
||||||
|
|
||||||
|
self.tcp_frame = tk.Frame(frame_receive)
|
||||||
|
tk.Label(self.tcp_frame, text="IP:").pack(side="left")
|
||||||
|
self.tcp_ip_entry = tk.Entry(self.tcp_frame)
|
||||||
|
self.tcp_ip_entry.pack(side="left", padx=5)
|
||||||
|
self.tcp_ip_entry.insert(0, "192.168.127.254") # например, default IP адрес
|
||||||
|
tk.Label(self.tcp_frame, text="Port:").pack(side="left")
|
||||||
|
self.tcp_port_entry = tk.Entry(self.tcp_frame)
|
||||||
|
self.tcp_port_entry.pack(side="left", padx=5)
|
||||||
|
self.tcp_port_entry.insert(0, 1993) # например, default порт
|
||||||
|
|
||||||
|
self.read_mode_frame = tk.Frame(frame_receive)
|
||||||
|
tk.Label(self.read_mode_frame, text="Read Mode:").pack(side="left", padx=5, pady=5)
|
||||||
|
tk.OptionMenu(self.read_mode_frame, self.read_mode_var, "Automatic", "Manual", command=self.update_read_mode).pack(side="left", padx=5, pady=5)
|
||||||
|
tk.Label(self.read_mode_frame, text="Timeout (s):").pack(side="left", padx=5, pady=5)
|
||||||
|
self.timeout_entry = tk.Entry(self.read_mode_frame, textvariable=self.timeout_var)
|
||||||
|
self.timeout_entry.pack(side="left", padx=5)
|
||||||
|
self.manual_read_button = tk.Button(self.read_mode_frame, text="Read Next Line", command=self.read_next_line)
|
||||||
|
|
||||||
|
self.start_button = tk.Button(frame_receive, text="Start", command=self.start_receiving)
|
||||||
|
self.start_button.pack(side="left", padx=5, pady=5)
|
||||||
|
tk.Button(frame_receive, text="Stop", command=self.stop_receiving).pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
frame_process = tk.LabelFrame(frame, text="Process Data")
|
||||||
|
frame_process.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
|
tk.Label(frame_process, text="Select Protocol:").pack(side="left", padx=5, pady=5)
|
||||||
|
tk.OptionMenu(frame_process, self.protocol_var, "Protocol A", "Protocol B", "Saratov").pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
frame_send = tk.LabelFrame(frame, text="Send Data")
|
||||||
|
frame_send.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.target_count_var = tk.IntVar(value=1)
|
||||||
|
tk.Label(frame_send, text="Number of Targets:").pack(side="left", padx=5, pady=5)
|
||||||
|
tk.Spinbox(frame_send, from_=1, to=10, textvariable=self.target_count_var, command=self.update_targets).pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.targets_frame = tk.Frame(frame_send)
|
||||||
|
self.targets_frame.pack(fill="x", padx=5, pady=5)
|
||||||
|
self.target_entries = []
|
||||||
|
self.update_targets()
|
||||||
|
|
||||||
|
tk.Button(frame_send, text="Send Data", command=self.send_data).pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.update_mode(self.mode_var.get())
|
||||||
|
|
||||||
|
def create_game_ui(self, frame):
|
||||||
|
frame_status = tk.LabelFrame(frame, text="Status")
|
||||||
|
frame_status.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.data_receive_status = tk.Label(frame_status, text="Receiving Data: Not Active", fg="red")
|
||||||
|
self.data_receive_status.pack(pady=5)
|
||||||
|
|
||||||
|
self.data_send_status = tk.Label(frame_status, text="Sending Data: Not Active", fg="red")
|
||||||
|
self.data_send_status.pack(pady=5)
|
||||||
|
|
||||||
|
frame_log = tk.LabelFrame(frame, text="Log")
|
||||||
|
frame_log.pack(fill="both", expand=True, padx=5, pady=5)
|
||||||
|
|
||||||
|
self.log_text = tk.Text(frame_log, height=10, state="normal")
|
||||||
|
self.log_text.pack(fill="both", expand=True, padx=5, pady=5)
|
||||||
|
|
||||||
|
frame_processed = tk.LabelFrame(frame, text="Processed Data")
|
||||||
|
frame_processed.pack(fill="both", expand=True, padx=5, pady=5)
|
||||||
|
|
||||||
|
self.processed_data_text = tk.Text(frame_processed, height=10, state="normal")
|
||||||
|
self.processed_data_text.pack(fill="both", expand=True, padx=5, pady=5)
|
||||||
|
|
||||||
|
def update_mode(self, mode):
|
||||||
|
if mode == "Log File":
|
||||||
|
self.file_button.pack(side="left", padx=5, pady=5)
|
||||||
|
self.tcp_frame.pack_forget()
|
||||||
|
self.read_mode_frame.pack(fill="x", padx=5, pady=5)
|
||||||
|
self.start_button.config(state="normal")
|
||||||
|
else:
|
||||||
|
self.file_button.pack_forget()
|
||||||
|
self.read_mode_frame.pack_forget()
|
||||||
|
self.tcp_frame.pack(side="left", padx=5, pady=5)
|
||||||
|
self.start_button.config(state="normal")
|
||||||
|
|
||||||
|
def update_read_mode(self, mode):
|
||||||
|
if mode == "Automatic":
|
||||||
|
self.timeout_entry.config(state="normal")
|
||||||
|
self.manual_read_button.pack_forget()
|
||||||
|
self.receiver.manual_mode = False
|
||||||
|
else:
|
||||||
|
self.timeout_entry.config(state="disabled")
|
||||||
|
self.manual_read_button.pack(side="left", padx=5, pady=5)
|
||||||
|
self.receiver.manual_mode = True
|
||||||
|
|
||||||
|
def select_file(self):
|
||||||
|
self.receiver.file_path = filedialog.askopenfilename()
|
||||||
|
|
||||||
|
def start_receiving(self):
|
||||||
|
self.start_button.config(state="disabled")
|
||||||
|
mode = self.mode_var.get()
|
||||||
|
if mode == "Log File":
|
||||||
|
if self.receiver.file_path:
|
||||||
|
timeout = self.timeout_var.get() if self.read_mode_var.get() == "Automatic" else 0
|
||||||
|
self.receiver.start_file(self.display_data, timeout)
|
||||||
|
self.update_receive_status(True)
|
||||||
|
else:
|
||||||
|
messagebox.showerror("Error", "No file selected.")
|
||||||
|
elif mode == "TCP Connection":
|
||||||
|
host = self.tcp_ip_entry.get()
|
||||||
|
port = self.tcp_port_entry.get()
|
||||||
|
if host and port.isdigit():
|
||||||
|
self.receiver.start_tcp(host, int(port), self.display_data)
|
||||||
|
self.update_receive_status(True)
|
||||||
|
else:
|
||||||
|
messagebox.showerror("Error", "Invalid IP or port.")
|
||||||
|
self.start_button.config(state="normal")
|
||||||
|
|
||||||
|
def stop_receiving(self):
|
||||||
|
self.receiver.stop()
|
||||||
|
self.start_button.config(state="normal")
|
||||||
|
self.update_receive_status(False)
|
||||||
|
|
||||||
|
def read_next_line(self):
|
||||||
|
self.receiver.read_next_line(self.display_data)
|
||||||
|
|
||||||
|
def update_receive_status(self, active):
|
||||||
|
if active:
|
||||||
|
self.data_receive_status.config(text="Receiving Data: Active", fg="green")
|
||||||
|
else:
|
||||||
|
self.data_receive_status.config(text="Receiving Data: Not Active", fg="red")
|
||||||
|
|
||||||
|
def update_send_status(self, active):
|
||||||
|
if active:
|
||||||
|
self.data_send_status.config(text="Sending Data: Active", fg="green")
|
||||||
|
else:
|
||||||
|
self.data_send_status.config(text="Sending Data: Not Active", fg="red")
|
||||||
|
|
||||||
|
def update_targets(self):
|
||||||
|
for widget in self.targets_frame.winfo_children():
|
||||||
|
widget.destroy()
|
||||||
|
|
||||||
|
self.target_entries = []
|
||||||
|
for i in range(self.target_count_var.get()):
|
||||||
|
target_frame = tk.Frame(self.targets_frame)
|
||||||
|
target_frame.pack(fill="x", pady=2)
|
||||||
|
|
||||||
|
tk.Label(target_frame, text=f"Target {i+1} Host:").pack(side="left")
|
||||||
|
host_entry = tk.Entry(target_frame)
|
||||||
|
host_entry.pack(side="left", padx=5)
|
||||||
|
host_entry.insert(0, "127.0.0.1")
|
||||||
|
|
||||||
|
tk.Label(target_frame, text="Port:").pack(side="left")
|
||||||
|
port_entry = tk.Entry(target_frame)
|
||||||
|
port_entry.pack(side="left", padx=5)
|
||||||
|
port_entry.insert(0, 8088)
|
||||||
|
|
||||||
|
self.target_entries.append((host_entry, port_entry))
|
||||||
|
|
||||||
|
def send_data(self):
|
||||||
|
data = "Sample data to send"
|
||||||
|
if not data:
|
||||||
|
messagebox.showerror("No Data", "No data to send.")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.sender.targets = []
|
||||||
|
for host_entry, port_entry in self.target_entries:
|
||||||
|
host = host_entry.get()
|
||||||
|
port = port_entry.get()
|
||||||
|
if host and port.isdigit():
|
||||||
|
self.sender.add_target(host, int(port))
|
||||||
|
|
||||||
|
self.update_send_status(True)
|
||||||
|
self.sender.send(data)
|
||||||
|
self.update_send_status(False)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
root = tk.Tk()
|
||||||
|
app = App(root)
|
||||||
|
root.mainloop()
|
||||||
620
timer_app4.py
Normal file
620
timer_app4.py
Normal file
@@ -0,0 +1,620 @@
|
|||||||
|
import tkinter as tk
|
||||||
|
from tkinter import filedialog, messagebox, ttk
|
||||||
|
import threading
|
||||||
|
import socket
|
||||||
|
import time
|
||||||
|
import binascii
|
||||||
|
import requests
|
||||||
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
|
||||||
|
|
||||||
|
def hexspace(data, n):
|
||||||
|
return " ".join([data[i : i + n] for i in range(0, len(data), n)])
|
||||||
|
|
||||||
|
|
||||||
|
class DataReceiver:
|
||||||
|
def __init__(self):
|
||||||
|
self.running = False
|
||||||
|
self.file_mode = False
|
||||||
|
self.file_path = None
|
||||||
|
self.manual_mode = False
|
||||||
|
|
||||||
|
def start_tcp(self, host, port, callback):
|
||||||
|
self.running = True
|
||||||
|
|
||||||
|
def run():
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
|
try:
|
||||||
|
# Подключаемся к серверу
|
||||||
|
s.connect((host, port))
|
||||||
|
|
||||||
|
# Отправляем строку "hello" в виде байтов
|
||||||
|
s.sendall("hello".encode("utf-8"))
|
||||||
|
|
||||||
|
# Основной цикл для получения данных
|
||||||
|
while self.running:
|
||||||
|
try:
|
||||||
|
# Получаем данные от сервера (максимум 1024 байта)
|
||||||
|
data = s.recv(1024)
|
||||||
|
|
||||||
|
if data:
|
||||||
|
try:
|
||||||
|
# Преобразуем байты в строку UTF-8
|
||||||
|
decoded_data = data
|
||||||
|
# Вызываем callback с декодированными данными
|
||||||
|
callback(decoded_data)
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
print(f"Ошибка декодирования данных: {data}")
|
||||||
|
callback(data.decode("latin1", errors="replace"))
|
||||||
|
else:
|
||||||
|
# Если data пустое, соединение закрылось
|
||||||
|
print("Сервер закрыл соединение.")
|
||||||
|
break
|
||||||
|
except (socket.error, OSError) as e:
|
||||||
|
print(f"Ошибка приёма данных: {e}")
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Ошибка подключения: {e}")
|
||||||
|
finally:
|
||||||
|
print("Соединение закрыто.")
|
||||||
|
self.running = False
|
||||||
|
|
||||||
|
threading.Thread(target=run, daemon=True).start()
|
||||||
|
|
||||||
|
def start_file(self, callback, timeout):
|
||||||
|
self.running = True
|
||||||
|
|
||||||
|
def run():
|
||||||
|
if not self.file_path:
|
||||||
|
return
|
||||||
|
with open(self.file_path, "r") as f:
|
||||||
|
while self.running:
|
||||||
|
if self.manual_mode:
|
||||||
|
continue
|
||||||
|
line = f.readline()
|
||||||
|
if line:
|
||||||
|
callback(eval(line.strip().split(" DEBUG ")[1]))
|
||||||
|
time.sleep(timeout)
|
||||||
|
|
||||||
|
threading.Thread(target=run, daemon=True).start()
|
||||||
|
|
||||||
|
def read_next_line(self, callback):
|
||||||
|
if not self.file_path:
|
||||||
|
return
|
||||||
|
with open(self.file_path, "r") as f:
|
||||||
|
line = f.readline()
|
||||||
|
if line:
|
||||||
|
callback(eval(line.strip().split(" DEBUG ")[1]))
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.running = False
|
||||||
|
|
||||||
|
|
||||||
|
class DataSender:
|
||||||
|
def __init__(self):
|
||||||
|
self.targets = []
|
||||||
|
self.session = requests.Session()
|
||||||
|
self.session.headers.update({"Connection": "keep-alive"})
|
||||||
|
|
||||||
|
def add_target(self, host, port):
|
||||||
|
self.targets.append((host, port))
|
||||||
|
|
||||||
|
def send(self, data):
|
||||||
|
"""Многопоточная отправка данных на все указанные цели."""
|
||||||
|
if not self.targets:
|
||||||
|
print("No targets available to send data.")
|
||||||
|
return
|
||||||
|
|
||||||
|
def send_to_target(target):
|
||||||
|
host, port = target
|
||||||
|
url = f"http://{host}:{port}/API/"
|
||||||
|
# url = f"http://{host}:{port}/"
|
||||||
|
try:
|
||||||
|
for k, v in data.items():
|
||||||
|
par = "SetText" if k.split(".")[1] == "Text" else "SetImage"
|
||||||
|
params = {
|
||||||
|
"Function": par,
|
||||||
|
"Input": 51,
|
||||||
|
"SelectedName": k,
|
||||||
|
"Value": v,
|
||||||
|
}
|
||||||
|
|
||||||
|
# params = {
|
||||||
|
# "action": "set_text",
|
||||||
|
# "layer": f"SCORE STRIPE FLAGS INTRO\Data\{k}",
|
||||||
|
# "value": str(v),
|
||||||
|
# "channel": "live1",
|
||||||
|
# }
|
||||||
|
|
||||||
|
# params = {
|
||||||
|
# "action": "set_data_source_query_parameter",
|
||||||
|
# "data_source": "timer_data",
|
||||||
|
# "parameter": k,
|
||||||
|
# "value": v,
|
||||||
|
# }
|
||||||
|
# params = { "action" : "set_data_source_query_parameter", "data_source" : "XML/JSON Source 11", "parameter" : "TIMER", "value" : "London" }
|
||||||
|
# print(url, params)
|
||||||
|
response = self.session.get(url, params=params, timeout=5)
|
||||||
|
# response = self.session.post(url, params=params)
|
||||||
|
# print(response.headers)
|
||||||
|
response.raise_for_status() # Проверяет, есть ли ошибки HTTP
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print(f"Error sending data to {host}:{port}: {e}")
|
||||||
|
|
||||||
|
# Используем ThreadPoolExecutor для многопоточной отправки
|
||||||
|
with ThreadPoolExecutor(
|
||||||
|
max_workers=5
|
||||||
|
) as executor: # max_workers можно настроить
|
||||||
|
executor.map(send_to_target, self.targets)
|
||||||
|
|
||||||
|
def check_vmix_connections(self):
|
||||||
|
"""Проверяем соединения для всех целей и обновляем индикаторы."""
|
||||||
|
for index, (host_entry, port_entry) in enumerate(self.target_entries):
|
||||||
|
host = host_entry.get()
|
||||||
|
port = port_entry.get()
|
||||||
|
|
||||||
|
if not port.isdigit():
|
||||||
|
continue # Пропускаем некорректные порты
|
||||||
|
|
||||||
|
connected = self.sender.check_vmix_connection(host, int(port))
|
||||||
|
self.update_connection_indicator(index, connected)
|
||||||
|
|
||||||
|
def update_connection_indicator(self, index, connected):
|
||||||
|
"""Обновляем цвет индикатора для определенной цели."""
|
||||||
|
color = "green" if connected else "red"
|
||||||
|
self.connection_indicators[index].itemconfig("indicator", fill=color)
|
||||||
|
|
||||||
|
def check_vmix_connection(self, host, port):
|
||||||
|
url = f"http://{host}:{port}/API/"
|
||||||
|
# url = f"http://{host}:{port}"
|
||||||
|
try:
|
||||||
|
response = self.session.get(url, timeout=2) # Таймаут в секундах
|
||||||
|
return response.status_code == 200
|
||||||
|
except requests.exceptions.RequestException:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class DataProcessor:
|
||||||
|
def process_protocol_a(self, data):
|
||||||
|
return data.upper()
|
||||||
|
|
||||||
|
def process_protocol_b(self, data):
|
||||||
|
return data[::-1]
|
||||||
|
|
||||||
|
def process_chine(self, data):
|
||||||
|
cdata = binascii.hexlify(data)
|
||||||
|
ddata = cdata.decode("utf-8", errors="replace").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
temp_data = edata.split()
|
||||||
|
temp_new = [int(t, 16) for t in temp_data]
|
||||||
|
# print(temp_new)
|
||||||
|
timer = f"{temp_new[3]}:{temp_new[2]}"
|
||||||
|
seconds = temp_new[5]
|
||||||
|
milliseconds = str(temp_new[4])[0]
|
||||||
|
if int(seconds) > 4:
|
||||||
|
temp = float(f"{seconds}.{milliseconds}")
|
||||||
|
if int(milliseconds) >= 5:
|
||||||
|
seconds = int(seconds) + 1
|
||||||
|
else:
|
||||||
|
seconds = seconds
|
||||||
|
timer_attack = seconds
|
||||||
|
timer_color = "#59358A"
|
||||||
|
else:
|
||||||
|
timer_attack = f"{seconds}.{milliseconds}"
|
||||||
|
timer_color = "#FF6A13"
|
||||||
|
if temp_new[0] in [16, 24]:
|
||||||
|
timer_attack = ""
|
||||||
|
timer_color = "#000000"
|
||||||
|
data = {
|
||||||
|
"12sec.Text": timer_attack,
|
||||||
|
"12SecBackground.Fill.Color": timer_color,
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
|
||||||
|
def process_protocol_saratov(self, data):
|
||||||
|
if data == "\xff":
|
||||||
|
return
|
||||||
|
|
||||||
|
cdata = binascii.hexlify(data)
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
temp = edata.split("FF 52")
|
||||||
|
for i in temp:
|
||||||
|
try:
|
||||||
|
minutes = int(i.split()[5], 16)
|
||||||
|
seconds = int(i.split()[6], 16)
|
||||||
|
timer_str = (
|
||||||
|
f"{minutes}:{seconds:02d}"
|
||||||
|
if seconds < 60
|
||||||
|
else f"{minutes}.{seconds-128}"
|
||||||
|
)
|
||||||
|
|
||||||
|
seconds_24 = int(i.split()[7], 16)
|
||||||
|
timer_attack = ""
|
||||||
|
timer_pic = "D:\Графика\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators\\24Sec_Orange.png"
|
||||||
|
if seconds_24 != 255:
|
||||||
|
if seconds_24 > 127:
|
||||||
|
seconds_24 -= 128
|
||||||
|
timer_attack = f"{seconds_24//10}.{seconds_24%10}"
|
||||||
|
timer_pic = "D:\Графика\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators\\24Sec_Red.png"
|
||||||
|
else:
|
||||||
|
timer_attack = seconds_24
|
||||||
|
|
||||||
|
quarter = int(i.split()[14][1], 16)
|
||||||
|
timeout1 = int(i.split()[10], 16)
|
||||||
|
timeout2 = int(i.split()[11], 16)
|
||||||
|
score1 = int(i.split()[8], 16)
|
||||||
|
score2 = int(i.split()[9], 16)
|
||||||
|
foul1 = int(i.split()[12], 16)
|
||||||
|
foul2 = int(i.split()[13], 16)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"TIMER.Text": timer_str,
|
||||||
|
"ATTACK.Text": timer_attack,
|
||||||
|
"Score_Home.Text": score1,
|
||||||
|
"Score_Away.Text": score2,
|
||||||
|
"fouls1.Source": f"D:\Графика\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators\Home_{foul1}.png",
|
||||||
|
"fouls2.Source": f"D:\Графика\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators\Away_{foul2}.png",
|
||||||
|
"24SECBACKGROUND.Source": timer_pic,
|
||||||
|
}
|
||||||
|
# data = {
|
||||||
|
# "Timer": timer_str,
|
||||||
|
# # "Attack": timer_attack,
|
||||||
|
# # "Score1": score1,
|
||||||
|
# # "Score2": score2,
|
||||||
|
# # "fouls1.Source": f"D:\Графика\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators\Home_{foul1}.png",
|
||||||
|
# # "fouls2.Source": f"D:\Графика\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators\Away_{foul2}.png",
|
||||||
|
# # "24SECBACKGROUND.Source": timer_pic,
|
||||||
|
# }
|
||||||
|
|
||||||
|
except (IndexError, ValueError):
|
||||||
|
continue
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class App:
|
||||||
|
def __init__(self, root):
|
||||||
|
self.receiver = DataReceiver()
|
||||||
|
self.sender = DataSender()
|
||||||
|
self.processor = DataProcessor()
|
||||||
|
|
||||||
|
self.protocol_var = tk.StringVar(value="Protocol A")
|
||||||
|
self.mode_var = tk.StringVar(value="Log File")
|
||||||
|
self.read_mode_var = tk.StringVar(value="Automatic")
|
||||||
|
self.timeout_var = tk.DoubleVar(value=0.5)
|
||||||
|
|
||||||
|
self.create_ui(root)
|
||||||
|
self.start_vmix_connection_check()
|
||||||
|
|
||||||
|
def display_data(self, data):
|
||||||
|
protocol = self.protocol_var.get()
|
||||||
|
if protocol == "Protocol A":
|
||||||
|
processed_data = self.processor.process_protocol_a(data)
|
||||||
|
elif protocol == "Protocol B":
|
||||||
|
processed_data = self.processor.process_protocol_b(data)
|
||||||
|
elif protocol == "Saratov":
|
||||||
|
processed_data = self.processor.process_protocol_saratov(data)
|
||||||
|
elif protocol == "Chine":
|
||||||
|
processed_data = self.processor.process_chine(data)
|
||||||
|
else:
|
||||||
|
processed_data = data
|
||||||
|
|
||||||
|
if processed_data:
|
||||||
|
self.update_send_status(True)
|
||||||
|
self.sender.send(processed_data)
|
||||||
|
self.update_send_status(False)
|
||||||
|
|
||||||
|
self.log_text.insert(tk.END, f"{data}\n")
|
||||||
|
self.log_text.see(tk.END)
|
||||||
|
|
||||||
|
self.processed_data_text.insert(tk.END, f"{processed_data}\n")
|
||||||
|
self.processed_data_text.see(tk.END)
|
||||||
|
|
||||||
|
def create_ui(self, root):
|
||||||
|
root.title("Data Processing Application")
|
||||||
|
|
||||||
|
self.notebook = ttk.Notebook(root)
|
||||||
|
self.notebook.pack(fill="both", expand=True)
|
||||||
|
|
||||||
|
self.settings_frame = tk.Frame(self.notebook)
|
||||||
|
self.game_frame = tk.Frame(self.notebook)
|
||||||
|
|
||||||
|
self.notebook.add(self.settings_frame, text="Settings")
|
||||||
|
self.notebook.add(self.game_frame, text="Game")
|
||||||
|
|
||||||
|
self.create_settings_ui(self.settings_frame)
|
||||||
|
self.create_game_ui(self.game_frame)
|
||||||
|
|
||||||
|
def create_settings_ui(self, frame):
|
||||||
|
frame_receive = tk.LabelFrame(frame, text="Receive Data")
|
||||||
|
frame_receive.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
|
tk.Label(frame_receive, text="Select Mode:").pack(side="left", padx=5, pady=5)
|
||||||
|
tk.OptionMenu(
|
||||||
|
frame_receive,
|
||||||
|
self.mode_var,
|
||||||
|
"Log File",
|
||||||
|
"TCP Connection",
|
||||||
|
command=self.update_mode,
|
||||||
|
).pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.file_button = tk.Button(
|
||||||
|
frame_receive, text="Select Log File", command=self.select_file
|
||||||
|
)
|
||||||
|
|
||||||
|
self.tcp_frame = tk.Frame(frame_receive)
|
||||||
|
tk.Label(self.tcp_frame, text="IP:").pack(side="left")
|
||||||
|
self.tcp_ip_entry = tk.Entry(self.tcp_frame)
|
||||||
|
self.tcp_ip_entry.pack(side="left", padx=5)
|
||||||
|
self.tcp_ip_entry.insert(0, "192.168.127.254") # например, default IP адрес
|
||||||
|
tk.Label(self.tcp_frame, text="Port:").pack(side="left")
|
||||||
|
self.tcp_port_entry = tk.Entry(self.tcp_frame)
|
||||||
|
self.tcp_port_entry.pack(side="left", padx=5)
|
||||||
|
self.tcp_port_entry.insert(0, 1993) # например, default порт
|
||||||
|
|
||||||
|
self.read_mode_frame = tk.Frame(frame_receive)
|
||||||
|
tk.Label(self.read_mode_frame, text="Read Mode:").pack(
|
||||||
|
side="left", padx=5, pady=5
|
||||||
|
)
|
||||||
|
tk.OptionMenu(
|
||||||
|
self.read_mode_frame,
|
||||||
|
self.read_mode_var,
|
||||||
|
"Automatic",
|
||||||
|
"Manual",
|
||||||
|
command=self.update_read_mode,
|
||||||
|
).pack(side="left", padx=5, pady=5)
|
||||||
|
tk.Label(self.read_mode_frame, text="Timeout (s):").pack(
|
||||||
|
side="left", padx=5, pady=5
|
||||||
|
)
|
||||||
|
self.timeout_entry = tk.Entry(
|
||||||
|
self.read_mode_frame, textvariable=self.timeout_var
|
||||||
|
)
|
||||||
|
self.timeout_entry.pack(side="left", padx=5)
|
||||||
|
self.manual_read_button = tk.Button(
|
||||||
|
self.read_mode_frame, text="Read Next Line", command=self.read_next_line
|
||||||
|
)
|
||||||
|
|
||||||
|
self.start_button = tk.Button(
|
||||||
|
frame_receive, text="Start", command=self.start_receiving
|
||||||
|
)
|
||||||
|
self.start_button.pack(side="left", padx=5, pady=5)
|
||||||
|
tk.Button(frame_receive, text="Stop", command=self.stop_receiving).pack(
|
||||||
|
side="left", padx=5, pady=5
|
||||||
|
)
|
||||||
|
|
||||||
|
frame_process = tk.LabelFrame(frame, text="Process Data")
|
||||||
|
frame_process.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
|
tk.Label(frame_process, text="Select Protocol:").pack(
|
||||||
|
side="left", padx=5, pady=5
|
||||||
|
)
|
||||||
|
tk.OptionMenu(
|
||||||
|
frame_process,
|
||||||
|
self.protocol_var,
|
||||||
|
"Protocol A",
|
||||||
|
"Protocol B",
|
||||||
|
"Saratov",
|
||||||
|
"Chine",
|
||||||
|
).pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
frame_send = tk.LabelFrame(frame, text="Send Data")
|
||||||
|
frame_send.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.target_count_var = tk.IntVar(value=1)
|
||||||
|
tk.Label(frame_send, text="Number of Targets:").pack(
|
||||||
|
side="left", padx=5, pady=5
|
||||||
|
)
|
||||||
|
tk.Spinbox(
|
||||||
|
frame_send,
|
||||||
|
from_=1,
|
||||||
|
to=10,
|
||||||
|
textvariable=self.target_count_var,
|
||||||
|
command=self.update_targets,
|
||||||
|
).pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
self.targets_frame = tk.Frame(frame_send)
|
||||||
|
self.targets_frame.pack(fill="x", padx=5, pady=5)
|
||||||
|
self.target_entries = []
|
||||||
|
self.update_targets()
|
||||||
|
|
||||||
|
tk.Button(frame_send, text="Send Data", command=self.send_data).pack(
|
||||||
|
side="left", padx=5, pady=5
|
||||||
|
)
|
||||||
|
|
||||||
|
self.update_mode(self.mode_var.get())
|
||||||
|
|
||||||
|
def create_game_ui(self, frame):
|
||||||
|
frame_status = tk.LabelFrame(frame, text="Status")
|
||||||
|
frame_status.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
|
# Canvas indicators
|
||||||
|
self.receive_status_canvas = tk.Canvas(frame_status, width=20, height=20)
|
||||||
|
self.receive_status_canvas.create_oval(
|
||||||
|
2, 2, 18, 18, fill="red", tags="indicator"
|
||||||
|
)
|
||||||
|
self.receive_status_canvas.pack(side="left", padx=10, pady=5)
|
||||||
|
tk.Label(frame_status, text="Receiving Data").pack(side="left")
|
||||||
|
|
||||||
|
self.send_status_canvas = tk.Canvas(frame_status, width=20, height=20)
|
||||||
|
self.send_status_canvas.create_oval(2, 2, 18, 18, fill="red", tags="indicator")
|
||||||
|
self.send_status_canvas.pack(side="left", padx=10, pady=5)
|
||||||
|
tk.Label(frame_status, text="Sending Data").pack(side="left")
|
||||||
|
|
||||||
|
frame_log = tk.LabelFrame(frame, text="Log")
|
||||||
|
frame_log.pack(fill="both", expand=True, padx=5, pady=5)
|
||||||
|
|
||||||
|
self.log_text = tk.Text(frame_log, height=10, state="normal")
|
||||||
|
self.log_text.pack(fill="both", expand=True, padx=5, pady=5)
|
||||||
|
|
||||||
|
frame_processed = tk.LabelFrame(frame, text="Processed Data")
|
||||||
|
frame_processed.pack(fill="both", expand=True, padx=5, pady=5)
|
||||||
|
|
||||||
|
self.processed_data_text = tk.Text(frame_processed, height=10, state="normal")
|
||||||
|
self.processed_data_text.pack(fill="both", expand=True, padx=5, pady=5)
|
||||||
|
|
||||||
|
# self.vmix_status_indicator = tk.Canvas(frame_status, width=20, height=20)
|
||||||
|
# self.vmix_status_indicator.pack(side="left", padx=5, pady=5)
|
||||||
|
# self.update_vmix_indicator(False)
|
||||||
|
|
||||||
|
# tk.Label(frame_status, text="vMix Connection").pack(side="left", padx=5, pady=5)
|
||||||
|
|
||||||
|
# def update_vmix_indicator(self, connected):
|
||||||
|
# self.vmix_status_indicator.delete("all")
|
||||||
|
# color = "green" if connected else "red"
|
||||||
|
# self.vmix_status_indicator.create_oval(2, 2, 18, 18, fill=color)
|
||||||
|
|
||||||
|
# def check_vmix_connection(self):
|
||||||
|
# if not self.target_entries:
|
||||||
|
# return False
|
||||||
|
|
||||||
|
# host_entry, port_entry = self.target_entries[0] # Проверяем первую цель
|
||||||
|
# host = host_entry.get()
|
||||||
|
# port = port_entry.get()
|
||||||
|
# if not port.isdigit():
|
||||||
|
# return False
|
||||||
|
|
||||||
|
# connected = self.sender.check_vmix_connection(host, int(port))
|
||||||
|
# self.update_vmix_indicator(connected)
|
||||||
|
# return connected
|
||||||
|
|
||||||
|
def check_vmix_connections(self):
|
||||||
|
for index, (host_entry, port_entry) in enumerate(self.target_entries):
|
||||||
|
host = host_entry.get()
|
||||||
|
port = port_entry.get()
|
||||||
|
|
||||||
|
if not port.isdigit():
|
||||||
|
continue # Пропускаем некорректные порты
|
||||||
|
|
||||||
|
connected = self.sender.check_vmix_connection(host, int(port))
|
||||||
|
self.update_connection_indicator(index, connected)
|
||||||
|
|
||||||
|
def update_connection_indicator(self, index, connected):
|
||||||
|
color = "green" if connected else "red"
|
||||||
|
self.connection_indicators[index].itemconfig("indicator", fill=color)
|
||||||
|
|
||||||
|
def start_vmix_connection_check(self):
|
||||||
|
"""Периодически проверяем соединения."""
|
||||||
|
|
||||||
|
def check_loop():
|
||||||
|
while True:
|
||||||
|
self.check_vmix_connections()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
threading.Thread(target=check_loop, daemon=True).start()
|
||||||
|
|
||||||
|
def update_mode(self, mode):
|
||||||
|
if mode == "Log File":
|
||||||
|
self.file_button.pack(side="left", padx=5, pady=5)
|
||||||
|
self.tcp_frame.pack_forget()
|
||||||
|
self.read_mode_frame.pack(fill="x", padx=5, pady=5)
|
||||||
|
self.start_button.config(state="normal")
|
||||||
|
else:
|
||||||
|
self.file_button.pack_forget()
|
||||||
|
self.read_mode_frame.pack_forget()
|
||||||
|
self.tcp_frame.pack(side="left", padx=5, pady=5)
|
||||||
|
self.start_button.config(state="normal")
|
||||||
|
|
||||||
|
def update_read_mode(self, mode):
|
||||||
|
if mode == "Automatic":
|
||||||
|
self.timeout_entry.config(state="normal")
|
||||||
|
self.manual_read_button.pack_forget()
|
||||||
|
self.receiver.manual_mode = False
|
||||||
|
else:
|
||||||
|
self.timeout_entry.config(state="disabled")
|
||||||
|
self.manual_read_button.pack(side="left", padx=5, pady=5)
|
||||||
|
self.receiver.manual_mode = True
|
||||||
|
|
||||||
|
def select_file(self):
|
||||||
|
self.receiver.file_path = filedialog.askopenfilename()
|
||||||
|
|
||||||
|
def start_receiving(self):
|
||||||
|
self.start_button.config(state="disabled")
|
||||||
|
mode = self.mode_var.get()
|
||||||
|
if mode == "Log File":
|
||||||
|
if self.receiver.file_path:
|
||||||
|
timeout = (
|
||||||
|
self.timeout_var.get()
|
||||||
|
if self.read_mode_var.get() == "Automatic"
|
||||||
|
else 0
|
||||||
|
)
|
||||||
|
self.receiver.start_file(self.display_data, timeout)
|
||||||
|
self.update_receive_status(True)
|
||||||
|
else:
|
||||||
|
messagebox.showerror("Error", "No file selected.")
|
||||||
|
elif mode == "TCP Connection":
|
||||||
|
host = self.tcp_ip_entry.get()
|
||||||
|
port = self.tcp_port_entry.get()
|
||||||
|
if host and port.isdigit():
|
||||||
|
self.receiver.start_tcp(host, int(port), self.display_data)
|
||||||
|
self.update_receive_status(True)
|
||||||
|
else:
|
||||||
|
messagebox.showerror("Error", "Invalid IP or port.")
|
||||||
|
self.start_button.config(state="normal")
|
||||||
|
|
||||||
|
def stop_receiving(self):
|
||||||
|
self.receiver.stop()
|
||||||
|
self.start_button.config(state="normal")
|
||||||
|
self.update_receive_status(False)
|
||||||
|
|
||||||
|
def read_next_line(self):
|
||||||
|
self.receiver.read_next_line(self.display_data)
|
||||||
|
|
||||||
|
def update_receive_status(self, active):
|
||||||
|
color = "green" if active else "red"
|
||||||
|
self.receive_status_canvas.itemconfig("indicator", fill=color)
|
||||||
|
|
||||||
|
def update_send_status(self, active):
|
||||||
|
color = "green" if active else "red"
|
||||||
|
self.send_status_canvas.itemconfig("indicator", fill=color)
|
||||||
|
|
||||||
|
def update_targets(self):
|
||||||
|
for widget in self.targets_frame.winfo_children():
|
||||||
|
widget.destroy()
|
||||||
|
|
||||||
|
self.target_entries = []
|
||||||
|
self.connection_indicators = [] # Храним индикаторы состояния
|
||||||
|
|
||||||
|
for i in range(self.target_count_var.get()):
|
||||||
|
target_frame = tk.Frame(self.targets_frame)
|
||||||
|
target_frame.pack(fill="x", pady=2)
|
||||||
|
|
||||||
|
tk.Label(target_frame, text=f"Target {i+1} Host:").pack(side="left")
|
||||||
|
host_entry = tk.Entry(target_frame)
|
||||||
|
host_entry.pack(side="left", padx=5)
|
||||||
|
host_entry.insert(0, "127.0.0.1")
|
||||||
|
|
||||||
|
tk.Label(target_frame, text="Port:").pack(side="left")
|
||||||
|
port_entry = tk.Entry(target_frame)
|
||||||
|
port_entry.pack(side="left", padx=5)
|
||||||
|
port_entry.insert(0, 8088)
|
||||||
|
|
||||||
|
indicator = tk.Canvas(target_frame, width=20, height=20)
|
||||||
|
indicator.create_oval(2, 2, 18, 18, fill="red", tags="indicator")
|
||||||
|
indicator.pack(side="left", padx=5)
|
||||||
|
|
||||||
|
self.target_entries.append((host_entry, port_entry))
|
||||||
|
self.connection_indicators.append(indicator)
|
||||||
|
|
||||||
|
def send_data(self):
|
||||||
|
data = "Sample data to send"
|
||||||
|
if not data:
|
||||||
|
messagebox.showerror("No Data", "No data to send.")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.sender.targets = []
|
||||||
|
for host_entry, port_entry in self.target_entries:
|
||||||
|
host = host_entry.get()
|
||||||
|
port = port_entry.get()
|
||||||
|
if host and port.isdigit():
|
||||||
|
self.sender.add_target(host, int(port))
|
||||||
|
|
||||||
|
# self.update_send_status(True)
|
||||||
|
self.sender.send(data)
|
||||||
|
# self.update_send_status(False)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
root = tk.Tk()
|
||||||
|
app = App(root)
|
||||||
|
root.mainloop()
|
||||||
155
timer_china_tcp.py
Normal file
155
timer_china_tcp.py
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
import sys
|
||||||
|
from socket import *
|
||||||
|
from datetime import datetime
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import binascii
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
HOST = "192.168.127.254"
|
||||||
|
PORT = 1993
|
||||||
|
PATH = (
|
||||||
|
r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\python\JSON\timer_basketball.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def hexspace(string, length):
|
||||||
|
return " ".join(string[i : i + length] for i in range(0, len(string), length))
|
||||||
|
|
||||||
|
|
||||||
|
def parse(line):
|
||||||
|
cdata = binascii.hexlify(line)
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
|
||||||
|
if len(edata.split()) == 33:
|
||||||
|
temp_data = edata.split()
|
||||||
|
temp_new = [int(t, 16) for t in temp_data]
|
||||||
|
minutes = temp_new[6]
|
||||||
|
seconds = temp_new[7]
|
||||||
|
milliseconds = temp_new[8]
|
||||||
|
timer_str = (
|
||||||
|
f"{minutes}:{seconds:02d}"
|
||||||
|
if minutes != 0
|
||||||
|
else f"{seconds:02d}.{milliseconds}"
|
||||||
|
)
|
||||||
|
active_temp = temp_new[
|
||||||
|
9
|
||||||
|
] # 133 - таймер идёт | 132 - таймер стоит | 128 - не игровое время стоит | 129 - не игровое время идёт
|
||||||
|
|
||||||
|
if temp_new[-2] != 0:
|
||||||
|
time_attack = (
|
||||||
|
temp_new[-4] if temp_new[-4] > 4 else f"{temp_new[-4]}.{temp_new[-3]}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
time_attack = "" # temp_new[-2] == 1 - таймер идёт | 2 - таймер стоит | 0 - таймер не отображён
|
||||||
|
|
||||||
|
# print(f"{str(temp_new):<120}__{timer_str:<7}__{time_attack:<3}__")
|
||||||
|
else:
|
||||||
|
temp_data = edata.split()
|
||||||
|
temp_new = [int(t, 16) for t in temp_data]
|
||||||
|
|
||||||
|
# time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def read_logs():
|
||||||
|
with open("timer_NN_2023-12-20_18-17-29.log", "r") as file:
|
||||||
|
# with open("timer_NN_test.log", "r") as file:
|
||||||
|
temp_line = ""
|
||||||
|
for line in file:
|
||||||
|
parts = line.strip().split(" DEBUG ")
|
||||||
|
if len(parts) == 2:
|
||||||
|
timestamp = parts[0][1:]
|
||||||
|
data = eval(parts[1])
|
||||||
|
parse(data)
|
||||||
|
time.sllep(0.1)
|
||||||
|
|
||||||
|
# if len(eval(data)) > 30 and eval(data)[-7] == "00":
|
||||||
|
# time.sleep(.1)
|
||||||
|
# else:
|
||||||
|
# time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
current_time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
if not os.path.isdir("LOGS"):
|
||||||
|
os.mkdir("LOGS")
|
||||||
|
|
||||||
|
LogFileName = f"LOGS/timer_Chine_tcp_{current_time}.log"
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format="%(asctime)s %(levelname)s %(message)s",
|
||||||
|
filename=LogFileName,
|
||||||
|
filemode="w",
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
tcp_socket.connect((HOST, PORT))
|
||||||
|
data = str.encode("hello")
|
||||||
|
tcp_socket.send(data)
|
||||||
|
data = bytes.decode(data)
|
||||||
|
while True:
|
||||||
|
data = tcp_socket.recv(1024)
|
||||||
|
logging.debug(data)
|
||||||
|
cdata = binascii.hexlify(data)
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
temp_data = edata.split()
|
||||||
|
temp_new = [int(t, 16) for t in temp_data]
|
||||||
|
timer = f"{temp_new[3]}:{temp_new[2]}"
|
||||||
|
seconds = temp_new[5]
|
||||||
|
milliseconds = str(temp_new[4])[0]
|
||||||
|
if int(seconds) > 4:
|
||||||
|
temp = float(f"{seconds}.{milliseconds}")
|
||||||
|
if int(milliseconds) >= 5:
|
||||||
|
seconds = int(seconds) + 1
|
||||||
|
else:
|
||||||
|
seconds = seconds
|
||||||
|
timer_attack = seconds
|
||||||
|
timer_color = "#FF6EAB"
|
||||||
|
else:
|
||||||
|
timer_attack = f"{seconds}.{milliseconds}"
|
||||||
|
timer_color = "#561D93"
|
||||||
|
if temp_new[0] in [16, 24]:
|
||||||
|
timer_attack = ""
|
||||||
|
timer_color = "#000000"
|
||||||
|
url = "http://127.0.0.1:8088/API/"
|
||||||
|
params = {
|
||||||
|
"Function": "SetText",
|
||||||
|
"Input": 151,
|
||||||
|
"SelectedName": "12sec.Text",
|
||||||
|
"Value": timer_attack,
|
||||||
|
}
|
||||||
|
params1 = {
|
||||||
|
"Function": "SetColor",
|
||||||
|
"Input": 150,
|
||||||
|
"SelectedName": "12SecBackground.Fill.Color",
|
||||||
|
"Value": timer_color,
|
||||||
|
}
|
||||||
|
requests.get(url, params=params)
|
||||||
|
requests.get(url, params=params1)
|
||||||
|
print(
|
||||||
|
f"data: {edata}",
|
||||||
|
temp_new,
|
||||||
|
timer,
|
||||||
|
f"{seconds}.{milliseconds}, attack: {timer_attack}",
|
||||||
|
)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
tcp_socket.close()
|
||||||
|
sys.exit(1)
|
||||||
|
except Exception:
|
||||||
|
tcp_socket.close()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
# read_logs()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(1)
|
||||||
|
except Exception as ex:
|
||||||
|
print(ex)
|
||||||
119
timer_chine.py
Normal file
119
timer_chine.py
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
import serial
|
||||||
|
from serial import SerialException
|
||||||
|
import datetime
|
||||||
|
import binascii
|
||||||
|
import logging
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
# Configuration Data (later to be put in Panel2Net.conf)
|
||||||
|
# SerialPort: Name of RPi serial port receiving the panel data
|
||||||
|
# SerialPort = "COM1"
|
||||||
|
SerialPort = "COM1"
|
||||||
|
# BaudRate: Serial port speed (Baud, Default will be adjusted later)
|
||||||
|
BaudRate = 19200
|
||||||
|
# PackageByTime: Time Duration until a package is closed
|
||||||
|
# and sent off (seconds)
|
||||||
|
PackageByTime = 0.1
|
||||||
|
# PackageByLength* Length (in bytes) of data input
|
||||||
|
# until a package is closed and sent off
|
||||||
|
PackageByLength = 128
|
||||||
|
# PackageByLength = 256 #попробовать нужно !!!!!!!!!!!!!!!!!!!!
|
||||||
|
# PackageByLength = 256
|
||||||
|
|
||||||
|
# MaxBuffer before flushing (in order to avoid buffer overflow)
|
||||||
|
BufferMax = 2000
|
||||||
|
|
||||||
|
|
||||||
|
# LogFileName: Name of LogFile
|
||||||
|
current_time = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
LogFileName = f"timer_megasport5_{current_time}.log"
|
||||||
|
# LogFileSize Maximum Size of LogFile (in Mbytes)
|
||||||
|
LogFileSize = 10
|
||||||
|
# LogLevel Minimum Severity Level to be logged (see severity in Logs)
|
||||||
|
LogLevel = "E"
|
||||||
|
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format="%(asctime)s %(levelname)s %(message)s",
|
||||||
|
filename=LogFileName,
|
||||||
|
filemode="w",
|
||||||
|
)
|
||||||
|
|
||||||
|
def hexspace(string, length):
|
||||||
|
return ' '.join(string[i:i+length] for i in range(0,len(string),length))
|
||||||
|
|
||||||
|
ser = serial.Serial()
|
||||||
|
ser.port = SerialPort
|
||||||
|
ser.baudrate = BaudRate
|
||||||
|
ser.bytesize = serial.EIGHTBITS # number of bits per bytes
|
||||||
|
ser.parity = serial.PARITY_NONE # PARITY_NONE # set parity check: no parity
|
||||||
|
ser.stopbits = serial.STOPBITS_ONE # number of stop bits
|
||||||
|
ser.timeout = PackageByTime # non-block read
|
||||||
|
ser.xonxoff = False # disable software flow control
|
||||||
|
ser.rtscts = False # disable hardware (RTS/CTS) flow control
|
||||||
|
ser.dsrdtr = False # disable hardware (DSR/DTR) flow control
|
||||||
|
ser.writeTimeout = 0 # timeout for write
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
print("Initializing")
|
||||||
|
ser.close()
|
||||||
|
ser.open()
|
||||||
|
if ser.is_open:
|
||||||
|
try:
|
||||||
|
ser.reset_input_buffer()
|
||||||
|
# flush input buffer, discarding all its contents
|
||||||
|
ser.reset_output_buffer()
|
||||||
|
# flush output buffer, aborting current output
|
||||||
|
# and discard all that is in buffer
|
||||||
|
RequestCount = 0
|
||||||
|
print("Port Opening")
|
||||||
|
# Initialise RetryCounter
|
||||||
|
RetryCount = 0
|
||||||
|
# Initialise Variable to take remainder string
|
||||||
|
remainder_hex = b""
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# Read from Serial Interface
|
||||||
|
response = ser.read(PackageByLength)
|
||||||
|
# print(response)
|
||||||
|
if len(response) > 0:
|
||||||
|
# In case there is something coming down the serial path
|
||||||
|
logging.debug(response)
|
||||||
|
|
||||||
|
if response != b"":
|
||||||
|
cdata = binascii.hexlify(response)
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
temp_data = edata.split()
|
||||||
|
temp_new = [int(t, 16) for t in temp_data]
|
||||||
|
timer = f"{temp_new[3]}:{temp_new[2]}"
|
||||||
|
seconds = temp_new[5]
|
||||||
|
# milliseconds = str(temp_new[6])[0]
|
||||||
|
print(len(temp_new), edata, temp_new, timer, seconds)
|
||||||
|
|
||||||
|
|
||||||
|
else:
|
||||||
|
# In case nothing is coming down the serial interface
|
||||||
|
print(
|
||||||
|
"\rWaiting for serial input...",
|
||||||
|
end=" ",
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# in case that the Serial Read or HTTP request fails
|
||||||
|
except Exception as e1:
|
||||||
|
print("error communicating...: " + str(e1))
|
||||||
|
logging.error("error communicating...: " + str(e1))
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("Port Opening Failed... trying again in 5 seconds")
|
||||||
|
time.sleep(0.1)
|
||||||
|
ser.close()
|
||||||
|
|
||||||
|
except SerialException:
|
||||||
|
print("No port connected... trying again in 5 seconds")
|
||||||
|
time.sleep(0.1)
|
||||||
165
timer_chine_tcp.py
Normal file
165
timer_chine_tcp.py
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
import sys
|
||||||
|
from socket import *
|
||||||
|
from datetime import datetime
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import binascii
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
HOST = "192.168.127.254"
|
||||||
|
PORT = 1993
|
||||||
|
PATH = (
|
||||||
|
r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\python\JSON\timer_basketball.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def hexspace(string, length):
|
||||||
|
return " ".join(string[i : i + length] for i in range(0, len(string), length))
|
||||||
|
|
||||||
|
|
||||||
|
def parse(line):
|
||||||
|
cdata = binascii.hexlify(line)
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
|
||||||
|
if len(edata.split()) == 33:
|
||||||
|
temp_data = edata.split()
|
||||||
|
temp_new = [int(t, 16) for t in temp_data]
|
||||||
|
minutes = temp_new[6]
|
||||||
|
seconds = temp_new[7]
|
||||||
|
milliseconds = temp_new[8]
|
||||||
|
timer_str = (
|
||||||
|
f"{minutes}:{seconds:02d}"
|
||||||
|
if minutes != 0
|
||||||
|
else f"{seconds:02d}.{milliseconds}"
|
||||||
|
)
|
||||||
|
active_temp = temp_new[
|
||||||
|
9
|
||||||
|
] # 133 - таймер идёт | 132 - таймер стоит | 128 - не игровое время стоит | 129 - не игровое время идёт
|
||||||
|
|
||||||
|
if temp_new[-2] != 0:
|
||||||
|
time_attack = (
|
||||||
|
temp_new[-4] if temp_new[-4] > 4 else f"{temp_new[-4]}.{temp_new[-3]}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
time_attack = "" # temp_new[-2] == 1 - таймер идёт | 2 - таймер стоит | 0 - таймер не отображён
|
||||||
|
|
||||||
|
# print(f"{str(temp_new):<120}__{timer_str:<7}__{time_attack:<3}__")
|
||||||
|
else:
|
||||||
|
temp_data = edata.split()
|
||||||
|
temp_new = [int(t, 16) for t in temp_data]
|
||||||
|
|
||||||
|
# time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def read_logs():
|
||||||
|
with open("timer_NN_2023-12-20_18-17-29.log", "r") as file:
|
||||||
|
# with open("timer_NN_test.log", "r") as file:
|
||||||
|
temp_line = ""
|
||||||
|
for line in file:
|
||||||
|
parts = line.strip().split(" DEBUG ")
|
||||||
|
if len(parts) == 2:
|
||||||
|
timestamp = parts[0][1:]
|
||||||
|
data = eval(parts[1])
|
||||||
|
parse(data)
|
||||||
|
time.sllep(0.1)
|
||||||
|
|
||||||
|
# if len(eval(data)) > 30 and eval(data)[-7] == "00":
|
||||||
|
# time.sleep(.1)
|
||||||
|
# else:
|
||||||
|
# time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
current_time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
if not os.path.isdir("LOGS"):
|
||||||
|
os.mkdir("LOGS")
|
||||||
|
|
||||||
|
LogFileName = f"LOGS/timer_Chine_tcp_{current_time}.log"
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format="%(asctime)s %(levelname)s %(message)s",
|
||||||
|
filename=LogFileName,
|
||||||
|
filemode="w",
|
||||||
|
)
|
||||||
|
# new_data = {
|
||||||
|
# "timeGFX": "0:00",
|
||||||
|
# "time_attackGFX": "",
|
||||||
|
# "quarter": "0",
|
||||||
|
# "points1": "0",
|
||||||
|
# "points2": "0",
|
||||||
|
# "foul1": "0",
|
||||||
|
# "foul2": "0",
|
||||||
|
# "foul_pic1": "",
|
||||||
|
# "foul_pic2": "",
|
||||||
|
# "time_attac_pic": "",
|
||||||
|
# }
|
||||||
|
# with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
# json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
|
||||||
|
try:
|
||||||
|
tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
tcp_socket.connect((HOST, PORT))
|
||||||
|
data = str.encode("hello")
|
||||||
|
tcp_socket.send(data)
|
||||||
|
data = bytes.decode(data)
|
||||||
|
while True:
|
||||||
|
data = tcp_socket.recv(1024)
|
||||||
|
logging.debug(data)
|
||||||
|
cdata = binascii.hexlify(data)
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
temp_data = edata.split()
|
||||||
|
temp_new = [int(t, 16) for t in temp_data]
|
||||||
|
# print(temp_new)
|
||||||
|
timer = f"{temp_new[3]}:{temp_new[2]}"
|
||||||
|
seconds = temp_new[5]
|
||||||
|
milliseconds = str(temp_new[4])[0]
|
||||||
|
if int(seconds) > 4:
|
||||||
|
temp = float(f"{seconds}.{milliseconds}")
|
||||||
|
if int(milliseconds) >= 5:
|
||||||
|
seconds = int(seconds) + 1
|
||||||
|
else:
|
||||||
|
seconds = seconds
|
||||||
|
timer_attack = seconds
|
||||||
|
timer_color = "#59358A"
|
||||||
|
else:
|
||||||
|
timer_attack = f"{seconds}.{milliseconds}"
|
||||||
|
timer_color = "#FF6A13"
|
||||||
|
if temp_new[0] in [16, 24]:
|
||||||
|
timer_attack = ""
|
||||||
|
timer_color = "#000000"
|
||||||
|
url = "http://127.0.0.1:8088/API/"
|
||||||
|
params = {
|
||||||
|
"Function": "SetText",
|
||||||
|
"Input": 221,
|
||||||
|
"SelectedName": "12sec.Text",
|
||||||
|
"Value": timer_attack,
|
||||||
|
}
|
||||||
|
params1 = {
|
||||||
|
"Function": "SetColor",
|
||||||
|
"Input": 221,
|
||||||
|
"SelectedName": "12SecBackground.Fill.Color",
|
||||||
|
"Value": timer_color,
|
||||||
|
}
|
||||||
|
requests.get(url, params=params)
|
||||||
|
requests.get(url, params=params1)
|
||||||
|
print(
|
||||||
|
f"data: {edata}",
|
||||||
|
temp_new,
|
||||||
|
timer,
|
||||||
|
f"{seconds}.{milliseconds}, attack: {timer_attack}",
|
||||||
|
)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
tcp_socket.close()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
# read_logs()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(1)
|
||||||
169
timer_exe.py
Normal file
169
timer_exe.py
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
import tkinter as tk
|
||||||
|
from tkinter import filedialog, ttk, messagebox
|
||||||
|
import threading
|
||||||
|
import serial
|
||||||
|
import socket
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
from data_sender import send_data_to_ips
|
||||||
|
|
||||||
|
|
||||||
|
class ConnectionApp:
|
||||||
|
def __init__(self, root):
|
||||||
|
self.root = root
|
||||||
|
self.root.title("Connection and Parser Application")
|
||||||
|
|
||||||
|
# Variables
|
||||||
|
self.connection_type = tk.StringVar(value="IP")
|
||||||
|
self.log_file_path = tk.StringVar(value="No file selected")
|
||||||
|
self.parser_type = tk.StringVar(value="Parser 1")
|
||||||
|
self.ip_address = tk.StringVar(value="127.0.0.1")
|
||||||
|
self.port = tk.IntVar(value=8080)
|
||||||
|
self.com_port = tk.StringVar(value="COM1")
|
||||||
|
self.baud_rate = tk.IntVar(value=9600)
|
||||||
|
self.data = ""
|
||||||
|
self.http_destinations = []
|
||||||
|
|
||||||
|
# Thread control
|
||||||
|
self.connection_thread = None
|
||||||
|
self.is_running = False
|
||||||
|
|
||||||
|
# UI
|
||||||
|
self.create_widgets()
|
||||||
|
|
||||||
|
def create_widgets(self):
|
||||||
|
# Connection Type Selection
|
||||||
|
tk.Label(self.root, text="Connection Type:").grid(row=0, column=0, pady=5, sticky="e")
|
||||||
|
connection_menu = ttk.Combobox(
|
||||||
|
self.root, textvariable=self.connection_type, values=["IP", "Log File", "COM"], state="readonly"
|
||||||
|
)
|
||||||
|
connection_menu.grid(row=0, column=1, pady=5, sticky="w")
|
||||||
|
|
||||||
|
# IP Settings
|
||||||
|
tk.Label(self.root, text="IP Address:").grid(row=1, column=0, pady=5, sticky="e")
|
||||||
|
tk.Entry(self.root, textvariable=self.ip_address).grid(row=1, column=1, pady=5, sticky="w")
|
||||||
|
|
||||||
|
tk.Label(self.root, text="Port:").grid(row=2, column=0, pady=5, sticky="e")
|
||||||
|
tk.Entry(self.root, textvariable=self.port).grid(row=2, column=1, pady=5, sticky="w")
|
||||||
|
|
||||||
|
# Log File Selection
|
||||||
|
tk.Label(self.root, text="Log File:").grid(row=3, column=0, pady=5, sticky="e")
|
||||||
|
tk.Button(self.root, text="Select File", command=self.select_log_file).grid(row=3, column=1, pady=5, sticky="w")
|
||||||
|
tk.Label(self.root, textvariable=self.log_file_path).grid(row=4, column=0, columnspan=2, sticky="w")
|
||||||
|
|
||||||
|
# COM Port Settings
|
||||||
|
tk.Label(self.root, text="COM Port:").grid(row=5, column=0, pady=5, sticky="e")
|
||||||
|
tk.Entry(self.root, textvariable=self.com_port).grid(row=5, column=1, pady=5, sticky="w")
|
||||||
|
|
||||||
|
tk.Label(self.root, text="Baud Rate:").grid(row=6, column=0, pady=5, sticky="e")
|
||||||
|
tk.Entry(self.root, textvariable=self.baud_rate).grid(row=6, column=1, pady=5, sticky="w")
|
||||||
|
|
||||||
|
# Parser Selection
|
||||||
|
tk.Label(self.root, text="Parser:").grid(row=7, column=0, pady=5, sticky="e")
|
||||||
|
parser_menu = ttk.Combobox(
|
||||||
|
self.root, textvariable=self.parser_type, values=["Parser 1", "Parser 2", "Parser 3"], state="readonly"
|
||||||
|
)
|
||||||
|
parser_menu.grid(row=7, column=1, pady=5, sticky="w")
|
||||||
|
|
||||||
|
# Control Buttons
|
||||||
|
tk.Button(self.root, text="Start", command=self.start_connection).grid(row=8, column=0, pady=10)
|
||||||
|
tk.Button(self.root, text="Stop", command=self.stop_connection).grid(row=8, column=1, pady=10)
|
||||||
|
|
||||||
|
# Destination Management
|
||||||
|
tk.Button(self.root, text="Add HTTP Destination", command=self.add_http_destination).grid(row=9, column=0, pady=10)
|
||||||
|
tk.Button(self.root, text="Show Destinations", command=self.show_destinations).grid(row=9, column=1, pady=10)
|
||||||
|
|
||||||
|
def select_log_file(self):
|
||||||
|
file_path = filedialog.askopenfilename(
|
||||||
|
title="Select Log File", filetypes=[("Log files", "*.log"), ("All files", "*.*")]
|
||||||
|
)
|
||||||
|
if file_path:
|
||||||
|
self.log_file_path.set(file_path)
|
||||||
|
|
||||||
|
def start_connection(self):
|
||||||
|
if self.connection_thread and self.connection_thread.is_alive():
|
||||||
|
messagebox.showinfo("Info", "Connection is already running.")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.is_running = True
|
||||||
|
connection_type = self.connection_type.get()
|
||||||
|
|
||||||
|
if connection_type == "IP":
|
||||||
|
self.connection_thread = threading.Thread(target=self.connect_via_ip, daemon=True)
|
||||||
|
elif connection_type == "Log File":
|
||||||
|
self.connection_thread = threading.Thread(target=self.read_log_file, daemon=True)
|
||||||
|
elif connection_type == "COM":
|
||||||
|
self.connection_thread = threading.Thread(target=self.connect_via_com, daemon=True)
|
||||||
|
else:
|
||||||
|
messagebox.showerror("Error", "Unknown connection type.")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.connection_thread.start()
|
||||||
|
|
||||||
|
def stop_connection(self):
|
||||||
|
self.is_running = False
|
||||||
|
if self.connection_thread and self.connection_thread.is_alive():
|
||||||
|
self.connection_thread.join()
|
||||||
|
messagebox.showinfo("Info", "Connection stopped.")
|
||||||
|
|
||||||
|
def connect_via_ip(self):
|
||||||
|
try:
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
|
s.connect((self.ip_address.get(), self.port.get()))
|
||||||
|
while self.is_running:
|
||||||
|
data = s.recv(1024).decode()
|
||||||
|
self.process_data(data)
|
||||||
|
except Exception as e:
|
||||||
|
messagebox.showerror("Error", f"IP connection error: {e}")
|
||||||
|
|
||||||
|
def read_log_file(self):
|
||||||
|
try:
|
||||||
|
with open(self.log_file_path.get(), "r") as file:
|
||||||
|
while self.is_running:
|
||||||
|
line = file.readline()
|
||||||
|
if not line:
|
||||||
|
time.sleep(0.1)
|
||||||
|
continue
|
||||||
|
self.process_data(line)
|
||||||
|
except Exception as e:
|
||||||
|
messagebox.showerror("Error", f"Log file error: {e}")
|
||||||
|
|
||||||
|
def connect_via_com(self):
|
||||||
|
try:
|
||||||
|
with serial.Serial(self.com_port.get(), self.baud_rate.get(), timeout=1) as ser:
|
||||||
|
while self.is_running:
|
||||||
|
data = ser.readline().decode()
|
||||||
|
self.process_data(data)
|
||||||
|
except Exception as e:
|
||||||
|
messagebox.showerror("Error", f"COM port error: {e}")
|
||||||
|
|
||||||
|
def process_data(self, data):
|
||||||
|
parser = self.get_parser(self.parser_type.get())
|
||||||
|
parsed_data = parser(data)
|
||||||
|
self.data = parsed_data
|
||||||
|
send_data_to_ips(parsed_data, self.http_destinations)
|
||||||
|
|
||||||
|
def get_parser(self, parser_name):
|
||||||
|
if parser_name == "Parser 1":
|
||||||
|
return lambda x: {"parsed": f"Parser 1 processed {x}"}
|
||||||
|
elif parser_name == "Parser 2":
|
||||||
|
return lambda x: {"parsed": f"Parser 2 processed {x}"}
|
||||||
|
elif parser_name == "Parser 3":
|
||||||
|
return lambda x: {"parsed": f"Parser 3 processed {x}"}
|
||||||
|
else:
|
||||||
|
return lambda x: {"error": "No valid parser selected"}
|
||||||
|
|
||||||
|
def add_http_destination(self):
|
||||||
|
ip = tk.simpledialog.askstring("Add HTTP Destination", "Enter IP (http://<ip>:port):")
|
||||||
|
if ip:
|
||||||
|
self.http_destinations.append(ip)
|
||||||
|
|
||||||
|
def show_destinations(self):
|
||||||
|
messagebox.showinfo("HTTP Destinations", "\n".join(self.http_destinations))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
root = tk.Tk()
|
||||||
|
app = ConnectionApp(root)
|
||||||
|
root.mainloop()
|
||||||
107
timer_hockey_balashikha.py
Normal file
107
timer_hockey_balashikha.py
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
import socket
|
||||||
|
from datetime import datetime
|
||||||
|
import json
|
||||||
|
|
||||||
|
HOST = "10.1.68.38" # local
|
||||||
|
PORT = 40001
|
||||||
|
PATH = "D:\\timer.json"
|
||||||
|
|
||||||
|
|
||||||
|
def connect():
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
|
s.connect((HOST, PORT))
|
||||||
|
s.sendall(b"Hello, world")
|
||||||
|
data = s.recv(1024)
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def save_log(name, data):
|
||||||
|
current_time = datetime.now().strftime("%d-%m-%Y %H:%M:%S.%f")
|
||||||
|
message_with_time = f"[{current_time}] {data}"
|
||||||
|
with open(name, "a") as file:
|
||||||
|
file.write(message_with_time + "\n")
|
||||||
|
|
||||||
|
|
||||||
|
def formatted_data(data):
|
||||||
|
save_log("logs_balashikha.txt", data)
|
||||||
|
|
||||||
|
data_converted = list(data)
|
||||||
|
data_formatted = [
|
||||||
|
str(hex_value // 16) + str(hex_value % 16) for hex_value in data_converted
|
||||||
|
]
|
||||||
|
save_log("logs_balashikha_formatted.txt", data_formatted)
|
||||||
|
|
||||||
|
|
||||||
|
def parse(data_formatted):
|
||||||
|
# print(len(data_formatted))
|
||||||
|
# print(data_formatted)
|
||||||
|
with open(PATH, "r", encoding="utf-8") as f:
|
||||||
|
new_data = json.load(f)
|
||||||
|
new_data = new_data[0]
|
||||||
|
|
||||||
|
if len(data_formatted) > 30:
|
||||||
|
if data_formatted[17] == "010":
|
||||||
|
if data_formatted[-8] in ["01", "05"]:
|
||||||
|
timer_str = (
|
||||||
|
f"{int(data_formatted[-7])}:{data_formatted[-6]}"
|
||||||
|
if int(data_formatted[-7]) != 0
|
||||||
|
else f"{int(data_formatted[-6])}.{int(data_formatted[-5])}"
|
||||||
|
)
|
||||||
|
new_data["timeGFX"] = timer_str
|
||||||
|
new_data["minutesGFX"] = int(
|
||||||
|
data_formatted[-7]
|
||||||
|
) # [25] #data_formatted[17] = 010 - таймер data_formatted[-8] = 05 - овертайм, 06 - перерыв между основным временем и овертаймом, 01 - игровое время, 02 - перерыв между периодами
|
||||||
|
new_data["secondsGFX"] = data_formatted[-6] # [26]
|
||||||
|
else:
|
||||||
|
timer_str = f"{int(data_formatted[-7])}:{data_formatted[-6]}"
|
||||||
|
new_data["timeNotGame"] = timer_str
|
||||||
|
|
||||||
|
if len(data_formatted) == 58:
|
||||||
|
new_data[
|
||||||
|
"timeDel1"
|
||||||
|
] = f"{int(data_formatted[26])}:{data_formatted[27]}" # data_formatted[17] = 24 - удаление
|
||||||
|
new_data["timeDel2"] = f"{int(data_formatted[41])}:{data_formatted[42]}"
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
print(new_data)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
while True:
|
||||||
|
data = connect()
|
||||||
|
data_new = formatted_data(data)
|
||||||
|
parse(data_new)
|
||||||
|
|
||||||
|
|
||||||
|
def read_logs():
|
||||||
|
import time
|
||||||
|
with open("test_logs_balashikha_new.txt", "r") as file:
|
||||||
|
for line in file:
|
||||||
|
parts = line.strip().split("] ")
|
||||||
|
if len(parts) == 2:
|
||||||
|
timestamp = parts[0][1:]
|
||||||
|
data = parts[1]
|
||||||
|
parse(eval(data))
|
||||||
|
if len(eval(data)) > 30 and eval(data)[-7] == "00":
|
||||||
|
time.sleep(.1)
|
||||||
|
else:
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
new_data = {
|
||||||
|
"timeGFX": "0:00",
|
||||||
|
"minutesGFX": "0",
|
||||||
|
"secondsGFX": "0",
|
||||||
|
"timeDel1": "0:00",
|
||||||
|
"timeDel2": "0:00",
|
||||||
|
"timeNotGame": "0:00",
|
||||||
|
}
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
# main()
|
||||||
|
read_logs()
|
||||||
203
timer_jet.py
Normal file
203
timer_jet.py
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
import sys
|
||||||
|
from socket import *
|
||||||
|
from datetime import datetime
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import binascii
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
HOST = "127.0.0.1"
|
||||||
|
PORT = 50000
|
||||||
|
PATH = (
|
||||||
|
r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\python\JSON\timer_basketball.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
import socket
|
||||||
|
|
||||||
|
sock = socket.socket()
|
||||||
|
sock.bind(('', PORT))
|
||||||
|
sock.listen(1)
|
||||||
|
conn, addr = sock.accept()
|
||||||
|
print ('connected:', addr)
|
||||||
|
|
||||||
|
def send_data_CW(name, value):
|
||||||
|
try:
|
||||||
|
with socket.socket(AF_INET, SOCK_STREAM) as tcp_socket:
|
||||||
|
tcp_socket.connect(('192.168.1.170', 5115))
|
||||||
|
data = f"{name}={value}\n".encode()
|
||||||
|
# print(f"Sending: {data}") # Отладка
|
||||||
|
tcp_socket.sendall(data)
|
||||||
|
# print("Data sent!") # Подтверждение отправки
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error sending TCP data: {e}")
|
||||||
|
|
||||||
|
def send_vmix(params):
|
||||||
|
try:
|
||||||
|
url = "http://192.168.1.240:8088/API/"
|
||||||
|
requests.get(url, params=params)
|
||||||
|
except Exception as ex:
|
||||||
|
print(ex)
|
||||||
|
|
||||||
|
def parse(line, score1, score2):
|
||||||
|
temp = line.split('#')
|
||||||
|
diff1, diff2 = None, None
|
||||||
|
t = temp[0]
|
||||||
|
# for t in temp:
|
||||||
|
if t not in [" ", ""]:
|
||||||
|
a = t.split('/')
|
||||||
|
print(a)
|
||||||
|
timer_str = f"{a[4]}:{a[5] if len(a[5]) != 1 else f'0{a[5]}'}" if a[4] != "0" else f"{a[5]}.{a[6]}"
|
||||||
|
timer_attack_str = a[2]
|
||||||
|
points1 = a[7]
|
||||||
|
points2 = a[8]
|
||||||
|
quarter = a[13]
|
||||||
|
if score1 != points1:
|
||||||
|
diff1 = int(points1) - int(score1)
|
||||||
|
score1 = points1
|
||||||
|
if score2 != points2:
|
||||||
|
score2 = points2
|
||||||
|
diff2 = int(points2) - int(score2)
|
||||||
|
|
||||||
|
fouls1 = a[9]
|
||||||
|
fouls2 = a[10]
|
||||||
|
path = r"D:\Графика\БАСКЕТБОЛ\FIBA"
|
||||||
|
if int(fouls1) > 4:
|
||||||
|
foul_pic1 = path + "\HOME-FOUL4.png"
|
||||||
|
else:
|
||||||
|
foul_pic1 = path + f"\HOME-FOUL{fouls1}.png"
|
||||||
|
if int(fouls2) > 4:
|
||||||
|
foul_pic2 = path + "\AWAY-FOUL4.png"
|
||||||
|
else:
|
||||||
|
foul_pic2 = path + f"\AWAY-FOUL{fouls2}.png"
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"TIMER": timer_str,
|
||||||
|
"ATTACK": timer_attack_str,
|
||||||
|
"Score_Home": score1,
|
||||||
|
"Score_Away": score2,
|
||||||
|
"fouls1": fouls1,
|
||||||
|
"fouls2": fouls2,
|
||||||
|
"quarter": quarter,
|
||||||
|
}
|
||||||
|
|
||||||
|
send_data_CW("TIMER", data["TIMER"])
|
||||||
|
send_data_CW("ATTACK", data["ATTACK"])
|
||||||
|
send_data_CW("Score_Home", data["Score_Home"])
|
||||||
|
send_data_CW("Score_Away", data["Score_Away"])
|
||||||
|
send_data_CW("fouls1", data["fouls1"])
|
||||||
|
send_data_CW("fouls2", data["fouls2"])
|
||||||
|
send_data_CW("quarter", data["quarter"])
|
||||||
|
|
||||||
|
params = {
|
||||||
|
"Function": "SetText",
|
||||||
|
"Input": 2,
|
||||||
|
"SelectedName": "ATTACK.Text",
|
||||||
|
"Value": data["ATTACK"],
|
||||||
|
# "SelectedName": "TIME.Text",
|
||||||
|
# "Value": timer_str,
|
||||||
|
}
|
||||||
|
send_vmix(params)
|
||||||
|
params = {
|
||||||
|
"Function": "SetText",
|
||||||
|
"Input": 2,
|
||||||
|
"SelectedName": "TIME.Text",
|
||||||
|
"Value": data["TIMER"],
|
||||||
|
}
|
||||||
|
send_vmix(params)
|
||||||
|
params = {
|
||||||
|
"Function": "SetText",
|
||||||
|
"Input": 2,
|
||||||
|
"SelectedName": "SCORE1.Text",
|
||||||
|
"Value": data["Score_Home"],
|
||||||
|
}
|
||||||
|
send_vmix(params)
|
||||||
|
params = {
|
||||||
|
"Function": "SetText",
|
||||||
|
"Input": 2,
|
||||||
|
"SelectedName": "SCORE2.Text",
|
||||||
|
"Value": data["Score_Away"],
|
||||||
|
}
|
||||||
|
send_vmix(params)
|
||||||
|
# params = {
|
||||||
|
# "Function": "SetText",
|
||||||
|
# "Input": 20,
|
||||||
|
# "SelectedName": "SCOREDIFF1.Text",
|
||||||
|
# "Value": f"+{diff1}",
|
||||||
|
# }
|
||||||
|
# requests.get(url, params=params)
|
||||||
|
# params = {
|
||||||
|
# "Function": "SetText",
|
||||||
|
# "Input": 20,
|
||||||
|
# "SelectedName": "SCOREDIFF2.Text",
|
||||||
|
# "Value": f"+{diff2}",
|
||||||
|
# }
|
||||||
|
# requests.get(url, params=params)
|
||||||
|
|
||||||
|
params = {
|
||||||
|
"Function": "SetImage",
|
||||||
|
"Input": 2,
|
||||||
|
"SelectedName": "FOULS_HOME.Source",
|
||||||
|
"Value": foul_pic1,
|
||||||
|
}
|
||||||
|
send_vmix(params)
|
||||||
|
params = {
|
||||||
|
"Function": "SetImage",
|
||||||
|
"Input": 2,
|
||||||
|
"SelectedName": "FOULS_AWAY.Source",
|
||||||
|
"Value": foul_pic2,
|
||||||
|
}
|
||||||
|
send_vmix(params)
|
||||||
|
print(timer_str, timer_attack_str, points1, points2,fouls1, fouls2, diff1, diff2, a)
|
||||||
|
return score1, score2
|
||||||
|
|
||||||
|
|
||||||
|
score1, score2 = 0, 0
|
||||||
|
while True:
|
||||||
|
data = conn.recv(1024)
|
||||||
|
line = data.decode("utf-8")
|
||||||
|
print(line)
|
||||||
|
if not data:
|
||||||
|
break
|
||||||
|
score1, score2 = parse(line, score1, score2)
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# def main():
|
||||||
|
# try:
|
||||||
|
# tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
# tcp_socket.connect((HOST, PORT))
|
||||||
|
# data = str.encode("hello")
|
||||||
|
# tcp_socket.send(data)
|
||||||
|
# data = bytes.decode(data)
|
||||||
|
# while True:
|
||||||
|
# data = tcp_socket.recv(1024)
|
||||||
|
# print(data)
|
||||||
|
# # url = "http://127.0.0.1:8088/API/"
|
||||||
|
# # params = {
|
||||||
|
# # "Function": "SetText",
|
||||||
|
# # "Input": 221,
|
||||||
|
# # "SelectedName": "12sec.Text",
|
||||||
|
# # "Value": timer_attack,
|
||||||
|
# # }
|
||||||
|
# # params1 = {
|
||||||
|
# # "Function": "SetColor",
|
||||||
|
# # "Input": 221,
|
||||||
|
# # "SelectedName": "12SecBackground.Fill.Color",
|
||||||
|
# # "Value": timer_color,
|
||||||
|
# # }
|
||||||
|
# # requests.get(url, params=params)
|
||||||
|
# except KeyboardInterrupt:
|
||||||
|
# tcp_socket.close()
|
||||||
|
# sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
# if __name__ == "__main__":
|
||||||
|
# main()
|
||||||
189
timer_nata_test (2).py
Normal file
189
timer_nata_test (2).py
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
import sys
|
||||||
|
import json
|
||||||
|
from socket import *
|
||||||
|
from datetime import datetime
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import binascii
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
HOST = "192.168.127.254"
|
||||||
|
PORT = 1993
|
||||||
|
PATH = (
|
||||||
|
r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\python\JSON\timer_basketball.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
session = requests.Session()
|
||||||
|
session.headers.update({"Connection": "keep-alive"})
|
||||||
|
|
||||||
|
|
||||||
|
def hexspace(string, length):
|
||||||
|
return " ".join(string[i : i + length] for i in range(0, len(string), length))
|
||||||
|
|
||||||
|
|
||||||
|
def send_data(name, value):
|
||||||
|
url = "http://127.0.0.1:8088/API/"
|
||||||
|
par = "SetText" if name.split(".")[1] == "Text" else "SetImage"
|
||||||
|
params = {
|
||||||
|
"Function": par,
|
||||||
|
"Input": 51,
|
||||||
|
"SelectedName": name,
|
||||||
|
"Value": value,
|
||||||
|
}
|
||||||
|
session.get(url, params=params)
|
||||||
|
|
||||||
|
def parse_new(line):
|
||||||
|
try:
|
||||||
|
with open(PATH, "r", encoding="utf-8") as f:
|
||||||
|
new_data = json.load(f)
|
||||||
|
except json.decoder.JSONDecodeError:
|
||||||
|
new_data = [
|
||||||
|
{
|
||||||
|
"timeGFX": "0:00",
|
||||||
|
"time_attackGFX": "",
|
||||||
|
"quarter": "0",
|
||||||
|
"points1": "0",
|
||||||
|
"points2": "0",
|
||||||
|
"foul1": "0",
|
||||||
|
"foul2": "0",
|
||||||
|
"foul_pic1": "",
|
||||||
|
"foul_pic2": "",
|
||||||
|
"time_attac_pic": "",
|
||||||
|
"timeout1": "0",
|
||||||
|
"timeout2": "0",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
cdata = binascii.hexlify(line)
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
temp = edata.split("FF 52")
|
||||||
|
print(line)
|
||||||
|
for i in temp:
|
||||||
|
if "7D 4A C0 0A" in i: #основной таймер
|
||||||
|
minutes = int(i.split()[-5], )
|
||||||
|
seconds = int(i.split()[-4], )
|
||||||
|
milliseconds = int(i.split()[-3], )
|
||||||
|
timer_str = (
|
||||||
|
f"{minutes}:{seconds:02d}" if minutes != 0 else f"{seconds}.{milliseconds}"
|
||||||
|
)
|
||||||
|
send_data("TIMER.Text", timer_str)
|
||||||
|
|
||||||
|
# print(i.split()[-7], i)
|
||||||
|
# if i.split()[-7] == "13" or i.split()[-7] == "10":
|
||||||
|
# new_data[0]["timeGFX"] = timer_str
|
||||||
|
elif "7D 4A C0 07" in i: #Счет
|
||||||
|
if i.split()[-7] == "06": #Счет первой команды
|
||||||
|
score1 = int(i.split()[-4], 16)
|
||||||
|
# new_data[0]["points1"] = score1
|
||||||
|
send_data("Score_Home.Text", score1)
|
||||||
|
elif i.split()[-7] == "07": #Счет второй команды
|
||||||
|
score2 = int(i.split()[-4], 16)
|
||||||
|
send_data("Score_Away.Text", score2)
|
||||||
|
# new_data[0]["points2"] = score2
|
||||||
|
else:
|
||||||
|
print("[СЧЁТ] == НЕПОНЯТНО")
|
||||||
|
elif "7D 4A C0 06" in i: #Информация
|
||||||
|
if i.split()[-6] == "09": #фолы первой команды
|
||||||
|
foul1 = int(i.split()[-3], 16)
|
||||||
|
# new_data[0]["foul1"] = foul1
|
||||||
|
send_data("fouls1.Source", f"D:\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\Home_{foul1}.png")
|
||||||
|
elif i.split()[-6] == "0A": #фолы второй команды
|
||||||
|
foul2 = int(i.split()[-3], 16)
|
||||||
|
send_data("fouls2.Source", f"D:\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\Away_{foul2}.png")
|
||||||
|
# new_data[0]["foul2"] = foul2
|
||||||
|
elif i.split()[-6] == "0E": #тайм-аут первой команды
|
||||||
|
time_out1 = int(i.split()[-3], 16)
|
||||||
|
# new_data[0]["timeout1"] = time_out1
|
||||||
|
elif i.split()[-6] == "0F": #тайм-аут второй команды
|
||||||
|
time_out2 = int(i.split()[-3], 16)
|
||||||
|
# new_data[0]["timeout2"] = time_out2
|
||||||
|
elif i.split()[-6] == "08": #четверть
|
||||||
|
quarter = int(i.split()[-3], 16)
|
||||||
|
# new_data[0]["quarter"] = quarter
|
||||||
|
|
||||||
|
elif "79 84 C0 0A" in i: #24 секунды
|
||||||
|
# print(i)
|
||||||
|
seconds = int(i.split()[-4])
|
||||||
|
milliseconds = int(i.split()[-3])
|
||||||
|
if seconds < int(5):
|
||||||
|
time_attack = f"{seconds}.{milliseconds}"
|
||||||
|
timer_pic = "D:\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\24Sec_Red.png"
|
||||||
|
else:
|
||||||
|
time_attack = seconds
|
||||||
|
timer_pic = "D:\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\24Sec_Empty.png"
|
||||||
|
if time_attack == "0.0":
|
||||||
|
time_attack = ""
|
||||||
|
timer_pic = "D:\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\24Sec_Empty.png"
|
||||||
|
send_data("ATTACK.Text", time_attack)
|
||||||
|
send_data("24SECBACKGROUND.Source", timer_pic)
|
||||||
|
|
||||||
|
# print(time_attack)
|
||||||
|
elif "89 4E C8 05" in i:
|
||||||
|
if i.split()[-3] == "05": #таймер 24 секунд выключен
|
||||||
|
time_attack = ""
|
||||||
|
timer_pic = "D:\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\24Sec_Empty.png"
|
||||||
|
send_data("ATTACK.Text", time_attack)
|
||||||
|
send_data("24SECBACKGROUND.Source", timer_pic)
|
||||||
|
# data = {
|
||||||
|
# "TIMER.Text": timer_str,
|
||||||
|
# "ATTACK.Text": time_attack,
|
||||||
|
# "Score_Home.Text": score1,
|
||||||
|
# "Score_Away.Text": score2,
|
||||||
|
# "fouls1.Source": f"D:\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\Home_{foul1}.png",
|
||||||
|
# "fouls2.Source": f"D:\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\Away_{foul2}.png",
|
||||||
|
# "24SECBACKGROUND.Source": timer_pic,
|
||||||
|
# }
|
||||||
|
|
||||||
|
# def read_logs():
|
||||||
|
# with open(
|
||||||
|
# r"C:\Users\soule\Downloads\Telegram Desktop\timer_Megasport_Nport_2024-03-05_20-00-17.log",
|
||||||
|
# "r",
|
||||||
|
# ) as file:
|
||||||
|
# for line in file:
|
||||||
|
# parts = line.strip().split(" DEBUG ")
|
||||||
|
# if len(parts) == 2:
|
||||||
|
# timestamp = parts[0][1:]
|
||||||
|
# data = eval(parts[1])
|
||||||
|
# if b"\xf83" in data or b"\xf88" in data or b"\xf87" in data:
|
||||||
|
# parse(data)
|
||||||
|
# time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
current_time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
if not os.path.isdir("LOGS"):
|
||||||
|
os.mkdir("LOGS")
|
||||||
|
|
||||||
|
LogFileName = f"LOGS/timer_Nata_Nport_{current_time}.log"
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format="%(asctime)s %(levelname)s %(message)s",
|
||||||
|
filename=LogFileName,
|
||||||
|
filemode="w",
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
tcp_socket.connect((HOST, PORT))
|
||||||
|
data = str.encode("hello")
|
||||||
|
tcp_socket.send(data)
|
||||||
|
data = bytes.decode(data)
|
||||||
|
while True:
|
||||||
|
data = tcp_socket.recv(1024)
|
||||||
|
logging.debug(data)
|
||||||
|
parse_new(data)
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
tcp_socket.close()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
# read_logs()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(1)
|
||||||
78
timer_playground copy.py
Normal file
78
timer_playground copy.py
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import requests
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
URL = "http://192.168.88.247:4700/TabloData/GetTabloData"
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
req = requests.get(URL)
|
||||||
|
new_json = {
|
||||||
|
"QUARTER": "",
|
||||||
|
"TIMER": "",
|
||||||
|
"TIMER_24": "",
|
||||||
|
"TEAM1": "",
|
||||||
|
"TEAM2": "",
|
||||||
|
"SCORE1": "",
|
||||||
|
"SCORE2": "",
|
||||||
|
"FOUL1": "",
|
||||||
|
"FOUL2": "",
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = req.json()
|
||||||
|
path_to_foul = "E:\TABLO\public_html obs — LETO 22 (09.10)"
|
||||||
|
if len(temp) > 3:
|
||||||
|
for i in temp:
|
||||||
|
if i["ID"] == "43":
|
||||||
|
new_json["TEAM1"] = i["VAL"]
|
||||||
|
elif i["ID"] == "44":
|
||||||
|
new_json["TEAM2"] = i["VAL"]
|
||||||
|
elif i["ID"] == "TIMER":
|
||||||
|
new_json["TIMER"] = i["VAL"].split(".")[0]
|
||||||
|
elif i["ID"] == "21":
|
||||||
|
new_json["SCORE1"] = i["VAL"]
|
||||||
|
elif i["ID"] == "22":
|
||||||
|
new_json["SCORE2"] = i["VAL"]
|
||||||
|
elif i["ID"] == "23":
|
||||||
|
foul1 = i["VAL"]
|
||||||
|
if int(foul1) > 5:
|
||||||
|
new_json["FOUL1"] = path_to_foul + "\\left" + "\\5.png"
|
||||||
|
else:
|
||||||
|
new_json["FOUL1"] = path_to_foul + "\\left" + f"\{i['VAL']}.png"
|
||||||
|
elif i["ID"] == "24":
|
||||||
|
foul2 = i["VAL"]
|
||||||
|
if int(foul2) > 5:
|
||||||
|
new_json["FOUL2"] = path_to_foul + "\\right" + "\\5.png"
|
||||||
|
else:
|
||||||
|
new_json["FOUL2"] = path_to_foul + "\\right" + f"\{i['VAL']}.png"
|
||||||
|
elif i["ID"] == "5":
|
||||||
|
val = ""
|
||||||
|
if i["VAL"] == "1":
|
||||||
|
val = "1ST"
|
||||||
|
elif i["VAL"] == "2":
|
||||||
|
val = "2ND"
|
||||||
|
elif i["VAL"] == "3":
|
||||||
|
val = "3RD"
|
||||||
|
elif i["VAL"] == "4":
|
||||||
|
val = "4TH"
|
||||||
|
else:
|
||||||
|
val = "OT" + str(int(i["VAL"]) - 4)
|
||||||
|
new_json["QUARTER"] = val
|
||||||
|
elif i["ID"] == "4":
|
||||||
|
new_json["TIMER_24"] = i["VAL"]
|
||||||
|
with open("E:\\TABLO\\timer_basketball.json", "w", encoding="utf-8") as file:
|
||||||
|
json.dump([new_json], file, ensure_ascii=False, indent=4)
|
||||||
|
print(new_json)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
time.sleep(0.1)
|
||||||
|
except Exception as ex:
|
||||||
|
print(ex)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
exit(1)
|
||||||
87
timer_playground.py
Normal file
87
timer_playground.py
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
import requests
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
URL = "http://192.168.1.80:4700/TabloData/GetTabloData"
|
||||||
|
# URL = "http://192.168.88.247:4700/TabloData/GetTabloData"
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
req = requests.get(URL)
|
||||||
|
new_json = {
|
||||||
|
"QUARTER": "",
|
||||||
|
"TIMER": "",
|
||||||
|
"TIMER_24": "",
|
||||||
|
"TEAM1": "",
|
||||||
|
"TEAM2": "",
|
||||||
|
"SCORE1": "",
|
||||||
|
"SCORE2": "",
|
||||||
|
"FOUL1": "",
|
||||||
|
"FOUL2": "",
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.status_code == 200:
|
||||||
|
temp = req.json()
|
||||||
|
path_to_foul = "E:\TABLO\public_html obs — LETO 22 (09.10)"
|
||||||
|
if len(temp) > 3:
|
||||||
|
for i in temp:
|
||||||
|
if i["ID"] == "43":
|
||||||
|
new_json["TEAM1"] = i["VAL"]
|
||||||
|
elif i["ID"] == "44":
|
||||||
|
new_json["TEAM2"] = i["VAL"]
|
||||||
|
elif i["ID"] == "TIMER":
|
||||||
|
new_json["TIMER"] = i["VAL"].split(".")[0]
|
||||||
|
elif i["ID"] == "21":
|
||||||
|
new_json["SCORE1"] = i["VAL"]
|
||||||
|
elif i["ID"] == "22":
|
||||||
|
new_json["SCORE2"] = i["VAL"]
|
||||||
|
elif i["ID"] == "23":
|
||||||
|
foul1 = i["VAL"]
|
||||||
|
if int(foul1) > 5:
|
||||||
|
new_json["FOUL1"] = path_to_foul + "\\left" + "\\5.png"
|
||||||
|
else:
|
||||||
|
new_json["FOUL1"] = path_to_foul + "\\left" + f"\{i['VAL']}.png"
|
||||||
|
elif i["ID"] == "24":
|
||||||
|
foul2 = i["VAL"]
|
||||||
|
if int(foul2) > 5:
|
||||||
|
new_json["FOUL2"] = path_to_foul + "\\right" + "\\5.png"
|
||||||
|
else:
|
||||||
|
new_json["FOUL2"] = (
|
||||||
|
path_to_foul + "\\right" + f"\{i['VAL']}.png"
|
||||||
|
)
|
||||||
|
elif i["ID"] == "5":
|
||||||
|
val = ""
|
||||||
|
if i["VAL"] == "1":
|
||||||
|
val = "1ST"
|
||||||
|
elif i["VAL"] == "2":
|
||||||
|
val = "2ND"
|
||||||
|
elif i["VAL"] == "3":
|
||||||
|
val = "3RD"
|
||||||
|
elif i["VAL"] == "4":
|
||||||
|
val = "4TH"
|
||||||
|
else:
|
||||||
|
val = "OT" + str(int(i["VAL"]) - 4)
|
||||||
|
new_json["QUARTER"] = val
|
||||||
|
elif i["ID"] == "4":
|
||||||
|
new_json["TIMER_24"] = i["VAL"]
|
||||||
|
with open(
|
||||||
|
"E:\\TABLO\\timer_basketball.json", "w", encoding="utf-8"
|
||||||
|
) as file:
|
||||||
|
json.dump([new_json], file, ensure_ascii=False, indent=4)
|
||||||
|
print(new_json)
|
||||||
|
else:
|
||||||
|
print(f"!!!!!Error!!!!!")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
time.sleep(0.1)
|
||||||
|
except Exception as ex:
|
||||||
|
print(ex)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
exit(1)
|
||||||
|
|
||||||
141
timer_saratov.py
Normal file
141
timer_saratov.py
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
import sys
|
||||||
|
import json
|
||||||
|
from socket import *
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import binascii
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
SETTING = "19200,None,8,1,None,Enable,RS-485(2 wire)"
|
||||||
|
HOST = "192.168.127.254"
|
||||||
|
PORT = 1993
|
||||||
|
|
||||||
|
|
||||||
|
def hexspace(string, length):
|
||||||
|
return " ".join(string[i : i + length] for i in range(0, len(string), length))
|
||||||
|
|
||||||
|
|
||||||
|
session = requests.Session()
|
||||||
|
session.headers.update({"Connection": "keep-alive"})
|
||||||
|
|
||||||
|
|
||||||
|
def send_data(name, value):
|
||||||
|
url = "http://127.0.0.1:8088/API/"
|
||||||
|
par = "SetText" if name.split(".")[1] == "Text" else "SetImage"
|
||||||
|
params = {
|
||||||
|
"Function": par,
|
||||||
|
"Input": "SCOREBUG",
|
||||||
|
"SelectedName": name,
|
||||||
|
"Value": value,
|
||||||
|
}
|
||||||
|
session.get(url, params=params)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_new(line):
|
||||||
|
if line == b"\xff":
|
||||||
|
return
|
||||||
|
|
||||||
|
cdata = binascii.hexlify(line)
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
temp = edata.split("FF 52")
|
||||||
|
for i in temp:
|
||||||
|
minutes = int(i.split()[5], 16)
|
||||||
|
seconds = int(i.split()[6], 16)
|
||||||
|
if seconds < 60:
|
||||||
|
timer_str = f"{minutes}:{seconds:02d}"
|
||||||
|
else:
|
||||||
|
timer_str = f"{minutes}.{seconds-128}"
|
||||||
|
seconds_24 = int(i.split()[7], 16)
|
||||||
|
timer_attack = ""
|
||||||
|
timer_pic = "D:\\YandexDisk\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\24Sec_Orange.png"
|
||||||
|
if seconds_24 == 255:
|
||||||
|
timer_attack = ""
|
||||||
|
else:
|
||||||
|
if seconds_24 > 127:
|
||||||
|
seconds_24 = seconds_24 - 128
|
||||||
|
timer_attack = f"{seconds_24//10}.{seconds_24%10}"
|
||||||
|
timer_pic = "D:\\YandexDisk\\Графика\\БАСКЕТБОЛ\\ЕДИНАЯ ЛИГА ВТБ 2022-2023\\Scorebug Indicators\\24Sec_Red.png"
|
||||||
|
else:
|
||||||
|
timer_attack = seconds_24
|
||||||
|
|
||||||
|
quarter = int(i.split()[14][1], 16)
|
||||||
|
timeout1 = int(i.split()[10], 16)
|
||||||
|
timeout2 = int(i.split()[11], 16)
|
||||||
|
score1 = int(i.split()[8], 16)
|
||||||
|
score2 = int(i.split()[9], 16)
|
||||||
|
foul1 = int(i.split()[12], 16)
|
||||||
|
foul2 = int(i.split()[13], 16)
|
||||||
|
data = {
|
||||||
|
"TIMER.Text": timer_str,
|
||||||
|
"24sec.Text": timer_attack,
|
||||||
|
"SCORE1.Text": score1,
|
||||||
|
"SCORE2.Text": score2,
|
||||||
|
}
|
||||||
|
send_data("TIMER.Text", data["TIMER.Text"])
|
||||||
|
send_data("24sec.Text", data["24sec.Text"])
|
||||||
|
send_data("SCORE1.Text", data["SCORE1.Text"])
|
||||||
|
send_data("SCORE2.Text", data["SCORE2.Text"])
|
||||||
|
# send_data("fouls1.Source", data["fouls1.Source"])
|
||||||
|
# send_data("fouls2.Source", data["fouls2.Source"])
|
||||||
|
# send_data("24SECBACKGROUND.Source", data["24SECBACKGROUND.Source"])
|
||||||
|
x = [int(x, 16) for x in i.split()]
|
||||||
|
print(f"{i}, timer: {timer_str}, attack: {timer_attack}, Q: {quarter}, {x}")
|
||||||
|
|
||||||
|
|
||||||
|
def read_logs():
|
||||||
|
with open(
|
||||||
|
r"C:\Code\timer\LOGS\timer_SARATOV_full.log",
|
||||||
|
"r",
|
||||||
|
) as file:
|
||||||
|
for line in file:
|
||||||
|
parts = line.strip().split(" DEBUG ")
|
||||||
|
if len(parts) == 2:
|
||||||
|
timestamp = parts[0]
|
||||||
|
data = eval(parts[1])
|
||||||
|
parse_new(data)
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if not os.path.isdir("LOGS"):
|
||||||
|
os.mkdir("LOGS")
|
||||||
|
|
||||||
|
LogFileName = f"LOGS/timer_SARATOV.log"
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format="%(asctime)s %(levelname)s %(message)s",
|
||||||
|
filename=LogFileName,
|
||||||
|
filemode="w",
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
tcp_socket.connect((HOST, PORT))
|
||||||
|
data = str.encode("hello")
|
||||||
|
tcp_socket.send(data)
|
||||||
|
data = bytes.decode(data)
|
||||||
|
while True:
|
||||||
|
data = tcp_socket.recv(1024)
|
||||||
|
print(data)
|
||||||
|
logging.debug(data)
|
||||||
|
try:
|
||||||
|
parse_new(data)
|
||||||
|
except Exception as ex:
|
||||||
|
print(f"\n{ex}\n")
|
||||||
|
except Exception as ex:
|
||||||
|
pass
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
tcp_socket.close()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
# read_logs()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(1)
|
||||||
160
timer_saratovCW.py
Normal file
160
timer_saratovCW.py
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
import sys
|
||||||
|
import json
|
||||||
|
from socket import *
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import binascii
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
HOST = "192.168.127.254"
|
||||||
|
PORT = 1993
|
||||||
|
|
||||||
|
def hexspace(string, length):
|
||||||
|
return " ".join(string[i : i + length] for i in range(0, len(string), length))
|
||||||
|
|
||||||
|
|
||||||
|
session = requests.Session()
|
||||||
|
session.headers.update({"Connection": "keep-alive"})
|
||||||
|
|
||||||
|
|
||||||
|
def send_data(name, value):
|
||||||
|
url = "http://127.0.0.1:8088/API/"
|
||||||
|
par = "SetText" if name.split(".")[1] == "Text" else "SetImage"
|
||||||
|
params = {
|
||||||
|
"Function": par,
|
||||||
|
"Input": 51,
|
||||||
|
"SelectedName": name,
|
||||||
|
"Value": value,
|
||||||
|
}
|
||||||
|
session.get(url, params=params)
|
||||||
|
|
||||||
|
|
||||||
|
def send_data_CW(name, value):
|
||||||
|
try:
|
||||||
|
with socket(AF_INET, SOCK_STREAM) as tcp_socket:
|
||||||
|
tcp_socket.connect(('localhost', 5115))
|
||||||
|
data = f"{name}={value}\n".encode()
|
||||||
|
# print(f"Sending: {data}") # Отладка
|
||||||
|
tcp_socket.sendall(data)
|
||||||
|
# print("Data sent!") # Подтверждение отправки
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error sending TCP data: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def parse_new(line):
|
||||||
|
if line == b"\xff":
|
||||||
|
return
|
||||||
|
|
||||||
|
cdata = binascii.hexlify(line)
|
||||||
|
ddata = cdata.decode("utf-8").upper()
|
||||||
|
edata = hexspace(ddata, 2)
|
||||||
|
temp = edata.split("FF 52")
|
||||||
|
for i in temp:
|
||||||
|
minutes = int(i.split()[5], 16)
|
||||||
|
seconds = int(i.split()[6], 16)
|
||||||
|
if seconds < 60:
|
||||||
|
timer_str = f"{minutes}:{seconds:02d}"
|
||||||
|
else:
|
||||||
|
timer_str = f"{minutes}.{seconds-128}"
|
||||||
|
seconds_24 = int(i.split()[7], 16)
|
||||||
|
timer_attack = ""
|
||||||
|
timer_pic = "D:\YandexDisk\Графика\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators\\24Sec_Orange.png"
|
||||||
|
if seconds_24 == 255:
|
||||||
|
timer_attack = ""
|
||||||
|
else:
|
||||||
|
if seconds_24 > 127:
|
||||||
|
seconds_24 = seconds_24 - 128
|
||||||
|
timer_attack = f"{seconds_24//10}.{seconds_24%10}"
|
||||||
|
timer_pic = "D:\YandexDisk\Графика\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators\\24Sec_Red.png"
|
||||||
|
else:
|
||||||
|
timer_attack = seconds_24
|
||||||
|
|
||||||
|
quarter = int(i.split()[14][1], 16)
|
||||||
|
timeout1 = int(i.split()[10], 16)
|
||||||
|
timeout2 = int(i.split()[11], 16)
|
||||||
|
score1 = int(i.split()[8], 16)
|
||||||
|
score2 = int(i.split()[9], 16)
|
||||||
|
foul1 = int(i.split()[12], 16)
|
||||||
|
foul2 = int(i.split()[13], 16)
|
||||||
|
data = {
|
||||||
|
"TIMER": timer_str,
|
||||||
|
"ATTACK": timer_attack,
|
||||||
|
"Score_Home": score1,
|
||||||
|
"Score_Away": score2,
|
||||||
|
"fouls1": foul1,
|
||||||
|
"fouls2": foul2,
|
||||||
|
"quarter": quarter,
|
||||||
|
}
|
||||||
|
# with open("D:\FIBA CW\\timer.json", "w", encoding="utf-8") as file:
|
||||||
|
# json.dump([data], file, ensure_ascii=False, indent=4)
|
||||||
|
send_data_CW("TIMER", data["TIMER"])
|
||||||
|
send_data_CW("ATTACK", data["ATTACK"])
|
||||||
|
send_data_CW("Score_Home", data["Score_Home"])
|
||||||
|
send_data_CW("Score_Away", data["Score_Away"])
|
||||||
|
send_data_CW("fouls1", data["fouls1"])
|
||||||
|
send_data_CW("fouls2", data["fouls2"])
|
||||||
|
send_data_CW("quarter", data["quarter"])
|
||||||
|
# send_data("Score_Home", data["Score_Home"])
|
||||||
|
# send_data("Score_Away", data["Score_Away"])
|
||||||
|
# send_data("fouls1", data["fouls1"])
|
||||||
|
# send_data("fouls2", data["fouls2"])
|
||||||
|
# send_data("24SECBACKGROUND.Source", data["24SECBACKGROUND.Source"])
|
||||||
|
# x = [int(x, 16) for x in i.split()]
|
||||||
|
print(f"{i}, {data}")
|
||||||
|
|
||||||
|
|
||||||
|
def read_logs():
|
||||||
|
with open(
|
||||||
|
r"C:\Code\timer\LOGS\timer_SARATOV copy 2.log",
|
||||||
|
"r",
|
||||||
|
) as file:
|
||||||
|
for line in file:
|
||||||
|
parts = line.strip().split(" DEBUG ")
|
||||||
|
if len(parts) == 2:
|
||||||
|
timestamp = parts[0]
|
||||||
|
data = eval(parts[1])
|
||||||
|
parse_new(data)
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if not os.path.isdir("LOGS"):
|
||||||
|
os.mkdir("LOGS")
|
||||||
|
|
||||||
|
LogFileName = f"LOGS/timer_SARATOV copy.log"
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format="%(asctime)s %(levelname)s %(message)s",
|
||||||
|
filename=LogFileName,
|
||||||
|
filemode="w",
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
tcp_socket.connect((HOST, PORT))
|
||||||
|
data = str.encode("hello")
|
||||||
|
tcp_socket.send(data)
|
||||||
|
data = bytes.decode(data)
|
||||||
|
while True:
|
||||||
|
data = tcp_socket.recv(1024)
|
||||||
|
print(data)
|
||||||
|
logging.debug(data)
|
||||||
|
try:
|
||||||
|
parse_new(data)
|
||||||
|
except Exception as ex:
|
||||||
|
print(f"\n{ex}\n")
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
tcp_socket.close()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
# main()
|
||||||
|
read_logs()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(1)
|
||||||
161
timer_stramatel copy.py
Normal file
161
timer_stramatel copy.py
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
import sys
|
||||||
|
import json
|
||||||
|
from socket import *
|
||||||
|
from datetime import datetime
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
|
SETTING = "19200,RS-485"
|
||||||
|
HOST = "192.168.127.254"
|
||||||
|
PORT = 1993
|
||||||
|
PATH = (
|
||||||
|
r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\python\JSON\timer_basketball.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def parse(line):
|
||||||
|
|
||||||
|
# if len(line) > 6:
|
||||||
|
try:
|
||||||
|
with open(PATH, "r", encoding="utf-8") as f:
|
||||||
|
new_data = json.load(f)
|
||||||
|
timer_bool = 0
|
||||||
|
if b"\xf87" in line:
|
||||||
|
temp_new = str(line.split(b"\xf87")[1])
|
||||||
|
elif b"\xf88" in line:
|
||||||
|
temp_new = str(line.split(b"\xf88")[1])
|
||||||
|
elif b"\xf83" in line:
|
||||||
|
temp_new = str(line.split(b"\xf83")[1])
|
||||||
|
timer_bool = 1
|
||||||
|
print(line)
|
||||||
|
timer_temp = temp_new[4:8]
|
||||||
|
# print(str(timer_temp) == '\\xf2')
|
||||||
|
if timer_temp != "\\xf2":
|
||||||
|
if timer_temp[-1] != " ":
|
||||||
|
minutes = int(timer_temp[:2])
|
||||||
|
seconds = timer_temp[2:]
|
||||||
|
timer_str = f"{minutes}:{seconds}"
|
||||||
|
else:
|
||||||
|
seconds = int(timer_temp[0:2])
|
||||||
|
milliseconds = int(timer_temp[2:])
|
||||||
|
timer_str = f"{seconds}.{milliseconds}"
|
||||||
|
if timer_bool == 1:
|
||||||
|
quarter = temp_new[14]
|
||||||
|
points1 = (temp_new[8:11]).strip()
|
||||||
|
points2 = (temp_new[11:14]).strip()
|
||||||
|
fouls1 = temp_new[15]
|
||||||
|
fouls2 = temp_new[16]
|
||||||
|
new_data[0]["points1"] = points1
|
||||||
|
new_data[0]["points2"] = points2
|
||||||
|
new_data[0]["foul1"] = fouls1
|
||||||
|
new_data[0]["foul2"] = fouls2
|
||||||
|
new_data[0]["quarter"] = quarter
|
||||||
|
|
||||||
|
path_pic = r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators"
|
||||||
|
attack_display = temp_new[51:53]
|
||||||
|
if attack_display == "30":
|
||||||
|
time_attack = ""
|
||||||
|
path_pic = path_pic + "\\24Sec_empty.png"
|
||||||
|
else:
|
||||||
|
word_to_int = "ABCDEFGHI@"
|
||||||
|
time_attack_temp = temp_new[48:50]
|
||||||
|
# print(time_attack_temp)
|
||||||
|
# print(word_to_int.index(time_attack_temp[1])+1 if time_attack_temp[1] != '@' else '0')
|
||||||
|
if time_attack_temp[1] in word_to_int:
|
||||||
|
time_attack = f"{time_attack_temp[0]}.{word_to_int.index(time_attack_temp[1])+1 if time_attack_temp[1] != '@' else '0'}"
|
||||||
|
path_pic = path_pic + "\\24Sec_Red.png"
|
||||||
|
else:
|
||||||
|
time_attack = (
|
||||||
|
int(time_attack_temp)
|
||||||
|
if time_attack_temp != " "
|
||||||
|
else time_attack_temp
|
||||||
|
)
|
||||||
|
path_pic = path_pic + "\\24Sec_Orange.png"
|
||||||
|
if time_attack == "0.0":
|
||||||
|
time_attack = ""
|
||||||
|
path_pic = path_pic + "\\24Sec_empty.png"
|
||||||
|
if timer_str == "0:00":
|
||||||
|
timer_str = "0.0"
|
||||||
|
|
||||||
|
new_data[0]["timeGFX"] = timer_str
|
||||||
|
new_data[0]["time_attackGFX"] = time_attack
|
||||||
|
new_data[0]["time_attac_pic"] = path_pic
|
||||||
|
|
||||||
|
print(new_data[0]["timeGFX"], new_data[0]["time_attackGFX"])
|
||||||
|
try:
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump(new_data, file, ensure_ascii=False, indent=4)
|
||||||
|
except Exception:
|
||||||
|
print(Exception)
|
||||||
|
pass
|
||||||
|
# logging.debug(new_data)
|
||||||
|
except Exception as ex:
|
||||||
|
print(ex)
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def read_logs():
|
||||||
|
with open(
|
||||||
|
r"C:\Users\soule\Downloads\Telegram Desktop\timer_Megasport_Nport_2024-03-05_20-00-17.log",
|
||||||
|
"r",
|
||||||
|
) as file:
|
||||||
|
for line in file:
|
||||||
|
parts = line.strip().split(" DEBUG ")
|
||||||
|
if len(parts) == 2:
|
||||||
|
timestamp = parts[0][1:]
|
||||||
|
data = eval(parts[1])
|
||||||
|
if b"\xf83" in data or b"\xf88" in data or b"\xf87" in data:
|
||||||
|
parse(data)
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
current_time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
if not os.path.isdir("LOGS"):
|
||||||
|
os.mkdir("LOGS")
|
||||||
|
|
||||||
|
LogFileName = f"LOGS/timer_Megasport_Nport_{current_time}.log"
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format="%(asctime)s %(levelname)s %(message)s",
|
||||||
|
filename=LogFileName,
|
||||||
|
filemode="w",
|
||||||
|
)
|
||||||
|
new_data = {
|
||||||
|
"timeGFX": "0.0",
|
||||||
|
"time_attackGFX": "",
|
||||||
|
"quarter": "0",
|
||||||
|
"points1": "0",
|
||||||
|
"points2": "0",
|
||||||
|
"foul1": "0",
|
||||||
|
"foul2": "0",
|
||||||
|
"foul_pic1": "",
|
||||||
|
"foul_pic2": "",
|
||||||
|
"time_attac_pic": "",
|
||||||
|
}
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
|
||||||
|
try:
|
||||||
|
tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
tcp_socket.connect((HOST, PORT))
|
||||||
|
data = str.encode("hello")
|
||||||
|
tcp_socket.send(data)
|
||||||
|
data = bytes.decode(data)
|
||||||
|
while True:
|
||||||
|
data = tcp_socket.recv(1024)
|
||||||
|
logging.debug(data)
|
||||||
|
# if b"\xf83" in data or b"\xf88" in data or b"\xf87" in data:
|
||||||
|
parse(data)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
tcp_socket.close()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
# read_logs()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(1)
|
||||||
160
timer_stramatel.py
Normal file
160
timer_stramatel.py
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
import sys
|
||||||
|
import json
|
||||||
|
from socket import *
|
||||||
|
from datetime import datetime
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
|
SETTING = "19200,RS-485"
|
||||||
|
HOST = "192.168.127.254"
|
||||||
|
PORT = 1993
|
||||||
|
PATH = (
|
||||||
|
r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\python\JSON\timer_basketball.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def parse(line):
|
||||||
|
if len(line) > 6:
|
||||||
|
try:
|
||||||
|
with open(PATH, "r", encoding="utf-8") as f:
|
||||||
|
new_data = json.load(f)
|
||||||
|
timer_bool = 0
|
||||||
|
if b"\xf87" in line:
|
||||||
|
temp_new = str(line.split(b"\xf87")[1])
|
||||||
|
elif b"\xf88" in line:
|
||||||
|
temp_new = str(line.split(b"\xf88")[1])
|
||||||
|
elif b"\xf83" in line:
|
||||||
|
temp_new = str(line.split(b"\xf83")[1])
|
||||||
|
timer_bool = 1
|
||||||
|
print(line)
|
||||||
|
timer_temp = temp_new[4:8]
|
||||||
|
# print(str(timer_temp) == '\\xf2')
|
||||||
|
if timer_temp != "\\xf2":
|
||||||
|
if timer_temp[-1] != " ":
|
||||||
|
minutes = int(timer_temp[:2])
|
||||||
|
seconds = timer_temp[2:]
|
||||||
|
timer_str = f"{minutes}:{seconds}"
|
||||||
|
else:
|
||||||
|
seconds = int(timer_temp[0:2])
|
||||||
|
milliseconds = int(timer_temp[2:])
|
||||||
|
timer_str = f"{seconds}.{milliseconds}"
|
||||||
|
if timer_bool == 1:
|
||||||
|
quarter = temp_new[14]
|
||||||
|
points1 = (temp_new[8:11]).strip()
|
||||||
|
points2 = (temp_new[11:14]).strip()
|
||||||
|
fouls1 = temp_new[15]
|
||||||
|
fouls2 = temp_new[16]
|
||||||
|
new_data[0]["points1"] = points1
|
||||||
|
new_data[0]["points2"] = points2
|
||||||
|
new_data[0]["foul1"] = fouls1
|
||||||
|
new_data[0]["foul2"] = fouls2
|
||||||
|
new_data[0]["quarter"] = quarter
|
||||||
|
|
||||||
|
path_pic = r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators"
|
||||||
|
attack_display = temp_new[51:53]
|
||||||
|
if attack_display == "30":
|
||||||
|
time_attack = ""
|
||||||
|
path_pic = path_pic + "\\24Sec_empty.png"
|
||||||
|
else:
|
||||||
|
word_to_int = "ABCDEFGHI@"
|
||||||
|
time_attack_temp = temp_new[48:50]
|
||||||
|
# print(time_attack_temp)
|
||||||
|
# print(word_to_int.index(time_attack_temp[1])+1 if time_attack_temp[1] != '@' else '0')
|
||||||
|
if time_attack_temp[1] in word_to_int:
|
||||||
|
time_attack = f"{time_attack_temp[0]}.{word_to_int.index(time_attack_temp[1])+1 if time_attack_temp[1] != '@' else '0'}"
|
||||||
|
path_pic = path_pic + "\\24Sec_Red.png"
|
||||||
|
else:
|
||||||
|
time_attack = (
|
||||||
|
int(time_attack_temp)
|
||||||
|
if time_attack_temp != " "
|
||||||
|
else time_attack_temp
|
||||||
|
)
|
||||||
|
path_pic = path_pic + "\\24Sec_Orange.png"
|
||||||
|
if time_attack == "0.0":
|
||||||
|
time_attack = ""
|
||||||
|
path_pic = path_pic + "\\24Sec_empty.png"
|
||||||
|
if timer_str == "0:00":
|
||||||
|
timer_str = "0.0"
|
||||||
|
|
||||||
|
new_data[0]["timeGFX"] = timer_str
|
||||||
|
new_data[0]["time_attackGFX"] = time_attack
|
||||||
|
new_data[0]["time_attac_pic"] = path_pic
|
||||||
|
|
||||||
|
print(new_data[0]["timeGFX"], new_data[0]["time_attackGFX"])
|
||||||
|
try:
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump(new_data, file, ensure_ascii=False, indent=4)
|
||||||
|
except Exception:
|
||||||
|
print(Exception)
|
||||||
|
pass
|
||||||
|
# logging.debug(new_data)
|
||||||
|
except Exception as ex:
|
||||||
|
print(ex)
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def read_logs():
|
||||||
|
with open(
|
||||||
|
r"C:\Users\soule\Downloads\Telegram Desktop\timer_Megasport_Nport_2024-03-05_20-00-17.log",
|
||||||
|
"r",
|
||||||
|
) as file:
|
||||||
|
for line in file:
|
||||||
|
parts = line.strip().split(" DEBUG ")
|
||||||
|
if len(parts) == 2:
|
||||||
|
timestamp = parts[0][1:]
|
||||||
|
data = eval(parts[1])
|
||||||
|
if b"\xf83" in data or b"\xf88" in data or b"\xf87" in data:
|
||||||
|
parse(data)
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
current_time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
if not os.path.isdir("LOGS"):
|
||||||
|
os.mkdir("LOGS")
|
||||||
|
|
||||||
|
LogFileName = f"LOGS/timer_Megasport_Nport_{current_time}.log"
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format="%(asctime)s %(levelname)s %(message)s",
|
||||||
|
filename=LogFileName,
|
||||||
|
filemode="w",
|
||||||
|
)
|
||||||
|
new_data = {
|
||||||
|
"timeGFX": "0.0",
|
||||||
|
"time_attackGFX": "",
|
||||||
|
"quarter": "0",
|
||||||
|
"points1": "0",
|
||||||
|
"points2": "0",
|
||||||
|
"foul1": "0",
|
||||||
|
"foul2": "0",
|
||||||
|
"foul_pic1": "",
|
||||||
|
"foul_pic2": "",
|
||||||
|
"time_attac_pic": "",
|
||||||
|
}
|
||||||
|
with open(PATH, "w", encoding="utf-8") as file:
|
||||||
|
json.dump([new_data], file, ensure_ascii=False, indent=4)
|
||||||
|
|
||||||
|
try:
|
||||||
|
tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||||
|
tcp_socket.connect((HOST, PORT))
|
||||||
|
data = str.encode("hello")
|
||||||
|
tcp_socket.send(data)
|
||||||
|
data = bytes.decode(data)
|
||||||
|
while True:
|
||||||
|
data = tcp_socket.recv(1024)
|
||||||
|
logging.debug(data)
|
||||||
|
if b"\xf83" in data or b"\xf88" in data or b"\xf87" in data:
|
||||||
|
parse(data)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
tcp_socket.close()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
# read_logs()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(1)
|
||||||
Reference in New Issue
Block a user