Files
auto-charger/collector/sim_charge.py
T
admin ca708b5dda docs: Test-Abschnitt reparieren + sim_charge.py aufnehmen
- README: leerer Code-Block im Abschnitt "Test ohne Auto" ersetzt durch
  sim_charge.py-Beispiele und die mosquitto_pub-Sequenz.
- collector/sim_charge.py: Test-Skript zum Simulieren einer Ladung über MQTT.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 13:13:41 +02:00

93 lines
3.1 KiB
Python
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
"""Simuliert eine go-e-Wallbox-Ladung über MQTT, um den Collector zu testen.
Sendet nacheinander:
car=2 (Start) -> wh -> cdi -> car=4 (Ende)
Broker/User/Topic werden wie beim Collector aus der .env gelesen.
Beispiele:
.venv/bin/python collector/sim_charge.py # 5230 Wh, 3600 s
.venv/bin/python collector/sim_charge.py --wh 8000 --duration 5400
.venv/bin/python collector/sim_charge.py --end idle # mit car=1 beenden
.venv/bin/python collector/sim_charge.py --no-finish # Session offen lassen
"""
import argparse
import json
import os
import sys
import time
import paho.mqtt.client as mqtt
from dotenv import load_dotenv
load_dotenv()
MQTT_HOST = os.environ.get("MQTT_HOST", "localhost")
MQTT_PORT = int(os.environ.get("MQTT_PORT", "1883"))
MQTT_USER = os.environ.get("MQTT_USER") or None
MQTT_PASS = os.environ.get("MQTT_PASS") or None
TOPIC_BASE = os.environ.get("MQTT_TOPIC_BASE", "go-eCharger/310014").rstrip("/")
def parse_args() -> argparse.Namespace:
p = argparse.ArgumentParser(description="Test-Ladung über MQTT simulieren")
p.add_argument("--wh", type=float, default=5230.5, help="geladene Energie in Wh")
p.add_argument("--duration", type=int, default=3600, help="Ladedauer in Sekunden")
p.add_argument("--end", choices=["complete", "idle"], default="complete",
help="Abschluss über car=4 (complete) oder car=1 (idle)")
p.add_argument("--no-finish", action="store_true",
help="Session nicht abschließen (kein car=1/4 senden)")
p.add_argument("--delay", type=float, default=0.7,
help="Pause zwischen den Nachrichten in Sekunden")
return p.parse_args()
def main() -> int:
args = parse_args()
client = mqtt.Client(
callback_api_version=mqtt.CallbackAPIVersion.VERSION2,
client_id="auto-charger-sim",
)
if MQTT_USER:
client.username_pw_set(MQTT_USER, MQTT_PASS)
print(f"Verbinde zu {MQTT_HOST}:{MQTT_PORT} (Topic-Basis {TOPIC_BASE}) ...")
try:
client.connect(MQTT_HOST, MQTT_PORT, keepalive=60)
except OSError as exc:
print(f"FEHLER: Verbindung zum Broker fehlgeschlagen: {exc}")
return 1
client.loop_start()
end_car = 4 if args.end == "complete" else 1
steps: list[tuple[str, str]] = [
("car", "2"),
("wh", f"{args.wh}"),
("cdi", json.dumps({"type": 1, "value": args.duration * 1000})),
]
if not args.no_finish:
steps.append(("car", str(end_car)))
for key, payload in steps:
topic = f"{TOPIC_BASE}/{key}"
info = client.publish(topic, payload, qos=1)
info.wait_for_publish(timeout=5)
print(f" -> {topic} = {payload}")
time.sleep(args.delay)
client.loop_stop()
client.disconnect()
print("Fertig. Erwartete Collector-Ausgabe: 'Ladung gestartet ...' "
"und 'Ladung gespeichert: %.0f Wh, %d s'." % (args.wh, args.duration))
return 0
if __name__ == "__main__":
try:
sys.exit(main())
except KeyboardInterrupt:
sys.exit(0)