Files
2026-06-23 15:30:55 +02:00

122 lines
2.8 KiB
Python

#!/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())