first commit

This commit is contained in:
2025-11-05 18:29:49 +03:00
commit a80c03a27d
41 changed files with 7713 additions and 0 deletions

163
RPL/main.py Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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)

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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)