Files
IrSender2/capture_ir.py
T
2026-08-23 20:16:17 +02:00

166 lines
5.1 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
IR Capture Script
- Führt mode2 --device /dev/lirc1 aus
- Wandelt pulse/space/timeout in mark/space JSON um
- Speichert die JSON-Datei
- Fügt optional einen neuen Command in die Config ein
"""
import subprocess
import json
import os
import sys
import re
from pathlib import Path
# === Anpassbare Pfade ===
DEVICE = "/dev/lirc1"
IR_SENDER_DIR = Path("/home/till/IrSender2")
CONFIG_FILE = IR_SENDER_DIR / "commands.json" # ggf. anpassen
IR_SEND_SCRIPT = IR_SENDER_DIR / "ir_send.py"
CARRIER = 38000
REPEAT = 1
def capture_mode2():
"""Startet mode2 und liest pulse/space/timeout-Daten."""
print(f"Starte mode2 auf {DEVICE} ...")
print("Drücke jetzt die Taste auf der Fernbedienung.")
print("Warte auf Signal (timeout = Ende). Mit Ctrl+C abbrechen.\n")
try:
proc = subprocess.Popen(
["mode2", "--device", DEVICE],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
bufsize=1
)
except FileNotFoundError:
print("Fehler: 'mode2' nicht gefunden. Ist LIRC installiert?")
sys.exit(1)
except PermissionError:
print(f"Fehler: Keine Berechtigung für {DEVICE}. Mit sudo ausführen?")
sys.exit(1)
signals = []
try:
for line in proc.stdout:
line = line.strip()
if not line:
continue
# mode2 Ausgabe: "pulse 1234", "space 5678" oder "timeout 21585"
m = re.match(r"^(pulse|space|timeout)\s+(\d+)$", line, re.IGNORECASE)
if not m:
# z.B. "Using device: ..." ignorieren
continue
kind, duration = m.group(1).lower(), int(m.group(2))
if kind == "timeout":
# timeout → abschließender space (wie in deinem Original-Beispiel)
signals.append({"type": "space", "duration": duration})
print(f" space {duration} (timeout → Signalende)")
print("\nTimeout erkannt Signal aufgenommen.")
break
# pulse → mark, space → space
typ = "mark" if kind == "pulse" else "space"
signals.append({"type": typ, "duration": duration})
print(f" {typ:5} {duration}")
except KeyboardInterrupt:
print("\nAbbruch durch Benutzer vorhandene Daten werden verwendet.")
finally:
proc.terminate()
try:
proc.wait(timeout=1)
except subprocess.TimeoutExpired:
proc.kill()
return signals
def save_json(signals, filename: Path):
"""Speichert das Signal im gewünschten Format."""
data = {
"carrier": CARRIER,
"repeat": REPEAT,
"signal": signals
}
with open(filename, "w", encoding="utf-8") as f:
json.dump(data, f, indent=2)
print(f"\nJSON gespeichert: {filename}")
def add_command_to_config(command_name: str, json_filename: str, web_title: str):
"""Fügt einen neuen Command in die Config-Datei ein."""
if not CONFIG_FILE.exists():
print(f"Warnung: Config-Datei {CONFIG_FILE} nicht gefunden Command wird nicht hinzugefügt.")
return
with open(CONFIG_FILE, "r", encoding="utf-8") as f:
config = json.load(f)
if "commands" not in config:
config["commands"] = {}
if command_name in config["commands"]:
print(f"Warnung: Command '{command_name}' existiert bereits wird überschrieben.")
config["commands"][command_name] = {
"description": f"Send IR command {json_filename}",
"web_title": web_title,
"web_enabled": True,
"timeout_seconds": 10,
"command": [
"python3",
str(IR_SEND_SCRIPT),
str(IR_SENDER_DIR / json_filename)
]
}
# Backup anlegen
backup = CONFIG_FILE.with_suffix(".json.bak")
CONFIG_FILE.rename(backup)
print(f"Backup der Config erstellt: {backup}")
with open(CONFIG_FILE, "w", encoding="utf-8") as f:
json.dump(config, f, indent=2, ensure_ascii=False)
print(f"Command '{command_name}' zur Config hinzugefügt.")
def main():
print("=== IR Capture → JSON + Config ===\n")
# 1. Signal aufnehmen
signals = capture_mode2()
if not signals:
print("Keine Daten empfangen. Abbruch.")
sys.exit(1)
print(f"\n{len(signals)} Einträge aufgenommen.")
# 2. Dateiname vom Benutzer erfragen
while True:
name = input("Dateiname (ohne .json, z.B. hektagonYellow): ").strip()
if name and re.match(r"^[a-zA-Z0-9_\-]+$", name):
break
print("Nur Buchstaben, Zahlen, _ und - erlaubt.")
json_path = IR_SENDER_DIR / f"{name}.json"
save_json(signals, json_path)
# 3. Optional Command in Config eintragen
add = input("\nSoll ein neuer Command in die Config eingetragen werden? [j/N]: ").strip().lower()
if add in ("j", "y", "ja", "yes"):
cmd_name = input(f"Command-Name (Standard: {name}): ").strip() or name
web_title = input(f"Web-Titel (Standard: {name}): ").strip() or name
add_command_to_config(cmd_name, f"{name}.json", web_title)
print("\nFertig!")
if __name__ == "__main__":
main()