#!/usr/bin/env python3 import json import sys import time import pigpio DEFAULT_GPIO = 12 def load_config(path: str) -> dict: with open(path, "r", encoding="utf-8") as f: data = json.load(f) if "signal" not in data or not isinstance(data["signal"], list): raise ValueError("JSON braucht ein 'signal'-Array.") return data def build_wave(pi: pigpio.pi, gpio: int, carrier_hz: int, signal: list[dict]) -> int: period_us = max(2, round(1_000_000 / carrier_hz)) on_us = max(1, period_us // 2) off_us = max(1, period_us - on_us) gpio_mask = 1 << gpio pulses = [] for item in signal: kind = str(item.get("type", "")).lower() duration = int(item.get("duration", 0)) if duration <= 0: continue if kind == "space": pulses.append(pigpio.pulse(0, 0, duration)) elif kind == "mark": full_cycles = duration // period_us remainder = duration % period_us for _ in range(full_cycles): pulses.append(pigpio.pulse(gpio_mask, 0, on_us)) pulses.append(pigpio.pulse(0, gpio_mask, off_us)) if remainder > 0: pulses.append(pigpio.pulse(gpio_mask, 0, remainder)) else: raise ValueError(f"Unbekannter type: {kind} (erlaubt: mark, space)") pi.wave_clear() pi.wave_add_generic(pulses) wid = pi.wave_create() return wid def send_wave(pi: pigpio.pi, wid: int, repeat: int) -> None: for i in range(repeat): pi.wave_send_once(wid) while pi.wave_tx_busy(): time.sleep(0.001) if i != repeat - 1: time.sleep(0.03) def main() -> int: if len(sys.argv) != 2: print("Usage: python3 ir_send.py signal.json") return 1 cfg = load_config(sys.argv[1]) gpio = int(cfg.get("gpio", DEFAULT_GPIO)) carrier = int(cfg.get("carrier", 38000)) repeat = int(cfg.get("repeat", 1)) if repeat < 1: repeat = 1 pi = pigpio.pi() if not pi.connected: print("Fehler: pigpiod läuft nicht.") return 1 wid = -1 try: pi.set_mode(gpio, pigpio.OUTPUT) pi.write(gpio, 0) wid = build_wave(pi, gpio, carrier, cfg["signal"]) if wid < 0: print("Fehler: wave_create fehlgeschlagen.") return 1 send_wave(pi, wid, repeat) print("IR-Signal gesendet.") return 0 finally: try: if wid >= 0: pi.wave_tx_stop() pi.wave_delete(wid) except Exception: pass try: pi.write(gpio, 0) except Exception: pass pi.wave_clear() pi.stop() if __name__ == "__main__": raise SystemExit(main())