forked from TillRepo/IrSender
setup
This commit is contained in:
+121
@@ -0,0 +1,121 @@
|
||||
#!/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())
|
||||
Reference in New Issue
Block a user