collect: add --dry flag to run push server without WeConnect
When --dry is set, WeConnect login and data collection are skipped. The push server still starts and serves preloaded 24 h history to connecting clients — useful for GUI testing without a live vehicle. Credentials are not required in dry-run mode. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+48
-33
@@ -71,15 +71,20 @@ def run(args: argparse.Namespace) -> None:
|
|||||||
log.error("Unknown domain(s): %s. Available: %s", unknown, list(ALL_DOMAINS))
|
log.error("Unknown domain(s): %s. Available: %s", unknown, list(ALL_DOMAINS))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
log.info("Connecting to WeConnect…")
|
if args.dry:
|
||||||
wc = we_connect.connect(args.username, args.password)
|
log.info("Dry-run mode — skipping WeConnect login")
|
||||||
|
wc = None
|
||||||
|
vehicle = None
|
||||||
|
vin = args.vin or "UNKNOWN"
|
||||||
|
else:
|
||||||
|
log.info("Connecting to WeConnect…")
|
||||||
|
wc = we_connect.connect(args.username, args.password)
|
||||||
|
vehicle, err = we_connect.select_vehicle(wc, args.vin)
|
||||||
|
if err:
|
||||||
|
log.error(err)
|
||||||
|
sys.exit(1)
|
||||||
|
vin = vehicle.vin.value
|
||||||
|
|
||||||
vehicle, err = we_connect.select_vehicle(wc, args.vin)
|
|
||||||
if err:
|
|
||||||
log.error(err)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
vin = vehicle.vin.value
|
|
||||||
log.info("Vehicle: %s", vin)
|
log.info("Vehicle: %s", vin)
|
||||||
|
|
||||||
logs_dir = Path(args.log_dir)
|
logs_dir = Path(args.log_dir)
|
||||||
@@ -94,34 +99,39 @@ def run(args: argparse.Namespace) -> None:
|
|||||||
current_day = datetime.now(timezone.utc).date()
|
current_day = datetime.now(timezone.utc).date()
|
||||||
store = load_store(out, vin, args.interval)
|
store = load_store(out, vin, args.interval)
|
||||||
push_store_ref["current"] = store
|
push_store_ref["current"] = store
|
||||||
log.info(
|
|
||||||
"Collecting [%s] every %ds → %s (Ctrl-C to stop)",
|
if args.dry:
|
||||||
", ".join(domains),
|
log.info("Push server running on %s:%d — no live collection (Ctrl-C to stop)", args.host, args.port)
|
||||||
args.interval,
|
else:
|
||||||
out,
|
log.info(
|
||||||
)
|
"Collecting [%s] every %ds → %s (Ctrl-C to stop)",
|
||||||
|
", ".join(domains),
|
||||||
|
args.interval,
|
||||||
|
out,
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
today = datetime.now(timezone.utc).date()
|
if not args.dry:
|
||||||
if today != current_day:
|
today = datetime.now(timezone.utc).date()
|
||||||
out = auto_out_path(logs_dir, vin)
|
if today != current_day:
|
||||||
store = load_store(out, vin, args.interval)
|
out = auto_out_path(logs_dir, vin)
|
||||||
push_store_ref["current"] = store
|
store = load_store(out, vin, args.interval)
|
||||||
current_day = today
|
push_store_ref["current"] = store
|
||||||
log.info("Midnight UTC rotation → %s", out)
|
current_day = today
|
||||||
|
log.info("Midnight UTC rotation → %s", out)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
wc.update()
|
wc.update()
|
||||||
snapshot = collect_snapshot(vehicle, domains)
|
snapshot = collect_snapshot(vehicle, domains)
|
||||||
store["records"].append(snapshot)
|
store["records"].append(snapshot)
|
||||||
save_store(out, store, args.max_records)
|
save_store(out, store, args.max_records)
|
||||||
network.broadcast(snapshot, push_clients, push_lock)
|
network.broadcast(snapshot, push_clients, push_lock)
|
||||||
log.info("Record #%d saved at %s", len(store["records"]), snapshot["ts"])
|
log.info("Record #%d saved at %s", len(store["records"]), snapshot["ts"])
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
except Exception:
|
except Exception:
|
||||||
log.exception("Collection failed — will retry at next interval")
|
log.exception("Collection failed — will retry at next interval")
|
||||||
|
|
||||||
time.sleep(args.interval)
|
time.sleep(args.interval)
|
||||||
|
|
||||||
@@ -174,6 +184,11 @@ def main() -> None:
|
|||||||
help="Keep only the last N records per file (default: unlimited)",
|
help="Keep only the last N records per file (default: unlimited)",
|
||||||
)
|
)
|
||||||
p.add_argument("-v", "--verbose", action="store_true", help="Enable debug logging")
|
p.add_argument("-v", "--verbose", action="store_true", help="Enable debug logging")
|
||||||
|
p.add_argument(
|
||||||
|
"--dry",
|
||||||
|
action="store_true",
|
||||||
|
help="Skip WeConnect login and data collection; run push server only (for GUI testing)",
|
||||||
|
)
|
||||||
p.add_argument(
|
p.add_argument(
|
||||||
"--list-domains",
|
"--list-domains",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
@@ -217,7 +232,7 @@ def main() -> None:
|
|||||||
args.port = int(creds_data.get("port", 9999))
|
args.port = int(creds_data.get("port", 9999))
|
||||||
args.log_dir = creds_data.get("log_dir", "./logs")
|
args.log_dir = creds_data.get("log_dir", "./logs")
|
||||||
|
|
||||||
if not args.username or not args.password:
|
if not args.dry and (not args.username or not args.password):
|
||||||
p.error(
|
p.error(
|
||||||
"Username and password are required. "
|
"Username and password are required. "
|
||||||
"Provide them in the credentials file or via -u/-p / WC_USER / WC_PASS."
|
"Provide them in the credentials file or via -u/-p / WC_USER / WC_PASS."
|
||||||
|
|||||||
Reference in New Issue
Block a user