first commit
This commit is contained in:
117
timer GPT 1.py
Normal file
117
timer GPT 1.py
Normal file
@@ -0,0 +1,117 @@
|
||||
# serial_to_vmix.py
|
||||
# pip install pyserial requests
|
||||
|
||||
import time
|
||||
import argparse
|
||||
import socket
|
||||
import urllib.parse
|
||||
import requests
|
||||
import serial
|
||||
from serial.serialutil import SerialException
|
||||
|
||||
# ---------------------------
|
||||
# 1) ВАША функция отправки в vMix
|
||||
# Замените содержимое по своему желанию.
|
||||
# ---------------------------
|
||||
def parse(data: str):
|
||||
"""
|
||||
Пользовательская обработка/отправка данных в vMix.
|
||||
Здесь просто печатаем; замените на вашу логику.
|
||||
"""
|
||||
print(f"[parse] {data}")
|
||||
|
||||
# ---- ПРИМЕРЫ реализации parse (раскомментируйте нужное) ----
|
||||
# Пример A: отправка через vMix HTTP API (SetText в определённый input/title)
|
||||
# def parse(data: str):
|
||||
# vmix_host = "http://127.0.0.1:8088" # адрес vMix Web Controller
|
||||
# function = "SetText"
|
||||
# input_id = "1" # замените на ваш Input (номер/имя/строка GUID)
|
||||
# selected_title = None # если нужно указать конкретный Title layer: "TitleName.xaml"
|
||||
# field = None # если нужно указать конкретное текстовое поле в титре
|
||||
#
|
||||
# params = {
|
||||
# "Function": function,
|
||||
# "Input": input_id,
|
||||
# "Value": data
|
||||
# }
|
||||
# if selected_title:
|
||||
# params["SelectedName"] = selected_title
|
||||
# if field:
|
||||
# params["SelectedIndex"] = field
|
||||
#
|
||||
# # важно: корректно кодируем Value
|
||||
# url = f"{vmix_host}/api?{urllib.parse.urlencode(params, doseq=True, safe='')}"
|
||||
# try:
|
||||
# r = requests.get(url, timeout=2)
|
||||
# r.raise_for_status()
|
||||
# except requests.RequestException as e:
|
||||
# print(f"[parse][HTTP] ошибка запроса к vMix: {e}")
|
||||
|
||||
# Пример B: отправка одной строки в vMix TCP (порт 8099) — например, выполнить функцию
|
||||
# def parse(data: str):
|
||||
# vmix_tcp_host = "127.0.0.1"
|
||||
# vmix_tcp_port = 8099
|
||||
# # пример: выполнить SetText
|
||||
# cmd = f"FUNCTION SetText Input=1 Value=\"{data}\"\r\n"
|
||||
# try:
|
||||
# with socket.create_connection((vmix_tcp_host, vmix_tcp_port), timeout=2) as s:
|
||||
# s.sendall(cmd.encode("utf-8"))
|
||||
# except OSError as e:
|
||||
# print(f"[parse][TCP] ошибка сокета к vMix: {e}")
|
||||
|
||||
# ---------------------------
|
||||
# 2) Чтение из COM-порта и вызов parse
|
||||
# ---------------------------
|
||||
def read_loop(port: str, baud: int, newline: str, strip_whitespace: bool):
|
||||
# мапинг для окончания строк в pyserial
|
||||
eol = {"CRLF": b"\r\n", "LF": b"\n", "CR": b"\r"}.get(newline.upper(), b"\n")
|
||||
|
||||
while True:
|
||||
try:
|
||||
with serial.Serial(port, baudrate=baud, timeout=1) as ser:
|
||||
print(f"[serial] открыт {ser.port} @ {baud} бод. Ожидаю данные...")
|
||||
buffer = bytearray()
|
||||
while True:
|
||||
chunk = ser.read(1024)
|
||||
if not chunk:
|
||||
continue
|
||||
buffer.extend(chunk)
|
||||
# разбираем по разделителю строк
|
||||
while True:
|
||||
idx = buffer.find(eol)
|
||||
if idx == -1:
|
||||
break
|
||||
line = buffer[:idx]
|
||||
del buffer[:idx + len(eol)]
|
||||
try:
|
||||
text = line.decode("utf-8", errors="replace")
|
||||
except Exception:
|
||||
text = line.decode("latin-1", errors="replace")
|
||||
if strip_whitespace:
|
||||
text = text.strip()
|
||||
if text != "":
|
||||
parse(text)
|
||||
except SerialException as e:
|
||||
print(f"[serial] не удалось открыть/читать {port}: {e}. Повтор через 3 сек...")
|
||||
time.sleep(3)
|
||||
except KeyboardInterrupt:
|
||||
print("\n[serial] остановлено пользователем.")
|
||||
break
|
||||
except Exception as e:
|
||||
print(f"[serial] непредвиденная ошибка: {e}. Повтор через 3 сек...")
|
||||
time.sleep(3)
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description="Чтение COM и отправка в vMix через parse()")
|
||||
ap.add_argument("--port", required=True, help="COM-порт, напр. COM3 (Windows) или /dev/ttyUSB0 (Linux)")
|
||||
ap.add_argument("--baud", type=int, default=19200, help="Скорость, по умолчанию 9600")
|
||||
ap.add_argument("--newline", choices=["LF", "CRLF", "CR"], default="CR",
|
||||
help="Разделитель строк, по умолчанию LF")
|
||||
ap.add_argument("--no-strip", action="store_true",
|
||||
help="Не обрезать пробелы по краям (по умолчанию обрезаем)")
|
||||
args = ap.parse_args()
|
||||
|
||||
read_loop(args.port, args.baud, args.newline, strip_whitespace=not args.no_strip)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user