#!/usr/bin/env python3 """Rebuild customer hydrogen evidence through existing local backend tunnels. Only the dedicated projection table is written; existing mileage is untouched. Credentials remain in memory. --write publishes complete daily scans. """ import argparse import datetime import importlib.util import os from pathlib import Path import re import subprocess import tempfile ROOT = Path(__file__).resolve().parents[1] def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('--date-from', required=True) parser.add_argument('--date-to', required=True) parser.add_argument('--vins', default='') parser.add_argument('--write', action='store_true') parser.add_argument('--limit', type=int, default=0) parser.add_argument('--ssh-target', default='root@115.29.187.205') args = parser.parse_args() start, end = (datetime.date.fromisoformat(x) for x in (args.date_from, args.date_to)) if start > end or (end-start).days > 365: parser.error('date range must contain 1–366 days') if args.write and args.limit: parser.error('a limited scan cannot publish daily results') spec = importlib.util.spec_from_file_location('oneos_backend', ROOT/'scripts/oneos-backend.py') backend = importlib.util.module_from_spec(spec) spec.loader.exec_module(backend) values = backend.production_config(args.ssh_target) env = {k: os.environ[k] for k in ('PATH', 'HOME', 'TMPDIR') if k in os.environ} env.update({'MYSQL_DSN': re.sub(r'@tcp\([^)]+\)', '@tcp(127.0.0.1:20430)', values['MYSQL_DSN'], count=1), 'TDENGINE_DSN': re.sub(r'@ws\([^)]+\)', '@ws(127.0.0.1:20441)', values['TDENGINE_DSN'], count=1), 'TDENGINE_DATABASE': values['TDENGINE_DATABASE'], 'TDENGINE_DRIVER': values.get('TDENGINE_DRIVER', 'taosWS'), 'BACKFILL_ENV_FILES': '/dev/null', 'BACKFILL_HYDROGEN_ONLY': 'true', 'BACKFILL_DRY_RUN': 'false' if args.write else 'true', 'BACKFILL_LIMIT': str(args.limit), 'BACKFILL_PROTOCOLS': 'GB32960,YUTONG_MQTT', 'BACKFILL_VINS': args.vins, 'BACKFILL_PROGRESS_EVERY': '10000'}) with tempfile.TemporaryDirectory(prefix='customer-hydrogen-') as run: binary = str(Path(run)/'backfill') subprocess.run(['go', 'build', '-o', binary, './cmd/stats-backfill'], cwd=ROOT.parent/'go/vehicle-gateway', check=True) day = start while day <= end: env.update({'BACKFILL_DATE_FROM': day.isoformat(), 'BACKFILL_DATE_TO': day.isoformat()}) subprocess.run([binary], env=env, check=True) day += datetime.timedelta(days=1) if __name__ == '__main__': main()