Files
IrSender2/capture_ir.py
T
2026-08-23 18:22:18 +00:00

173 lines
5.3 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 im gewünschten Format
- Fügt optional einen neuen Command in die Config ein
"""
import subprocess
import json
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 / "config.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
m = re.match(r"^(pulse|space|timeout)\s+(\d+)$", line, re.IGNORECASE)
if not m:
continue
kind, duration = m.group(1).lower(), int(m.group(2))
if kind == "timeout":
signals.append({"type": "space", "duration": duration})
print(f" space {duration} (timeout → Signalende)")
print("\nTimeout erkannt Signal aufgenommen.")
break
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:
- Jedes { "type": "...", "duration": N } steht in EINER Zeile
- Kein Zeilenumbruch zwischen type und duration
"""
lines = []
lines.append('{')
lines.append(f' "carrier": {CARRIER},')
lines.append(f' "repeat": {REPEAT},')
lines.append(' "signal": [')
for i, s in enumerate(signals):
comma = "," if i < len(signals) - 1 else ""
# Wichtig: alles in einer Zeile
lines.append(f' {{ "type": "{s["type"]}", "duration": {s["duration"]} }}{comma}')
lines.append(' ]')
lines.append('}')
content = "\n".join(lines) + "\n"
with open(filename, "w", encoding="utf-8") as f:
f.write(content)
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")
signals = capture_mode2()
if not signals:
print("Keine Daten empfangen. Abbruch.")
sys.exit(1)
print(f"\n{len(signals)} Einträge aufgenommen.")
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)
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()