from __future__ import annotations import asyncio import math import random import struct import time from utils.logger import get_logger logger = get_logger(__name__) class TestDataGenerator: def __init__(self, listener): self._listener = listener self._task: asyncio.Task | None = None @property def running(self) -> bool: return self._task is not None and not self._task.done() def start(self): if self.running: return loop = asyncio.get_event_loop() self._task = loop.create_task(self._loop()) logger.info("Test data generator started") def stop(self): if self._task and not self._task.done(): self._task.cancel() self._task = None logger.info("Test data generator stopped") async def _loop(self): phase = 0.0 gear = 1 gear_timer = 0 while True: try: await asyncio.sleep(1.0 / 30.0) phase += 0.06 gear_timer += 1 if gear_timer > 55: gear_timer = 0 gear = (gear % 6) + 1 max_rpm = 8000.0 rpm = max_rpm * (0.12 + 0.58 * abs(math.sin(phase))) speed_mps = rpm / max_rpm * 89.0 + random.uniform(-1, 1) throttle = max(0.0, min(1.0, 0.1 + 0.7 * abs(math.sin(phase + 0.5)))) brake = max(0.0, min(1.0, random.uniform(0, 0.35) if random.random() > 0.78 else 0)) steering = math.sin(phase * 0.25) * 0.45 fuel = max(0.0, 1.0 - phase * 0.007) best_lap = 92.0 + random.uniform(-0.8, 0.8) last_lap = best_lap + random.uniform(0.3, 2.0) lap_time = last_lap * random.uniform(0.15, 0.80) boost = random.uniform(0.2, 1.5) hp = rpm / max_rpm * 420.0 torque = rpm / max_rpm * 520.0 buf = self._build_packet(max_rpm, rpm, speed_mps, hp, torque, boost, fuel, best_lap, last_lap, lap_time, int(phase) % 15, throttle, brake, gear, steering) self._listener._handle_packet(buf, ("127.0.0.1", 0)) except asyncio.CancelledError: break except Exception as e: logger.error("Test data error: %s", e) await asyncio.sleep(1.0) @staticmethod def _build_packet(max_rpm, rpm, speed_mps, hp, torque, boost, fuel, best_lap, last_lap, lap_time, lap_num, throttle, brake, gear, steering): buf = bytearray(324) struct.pack_into(" TestDataGenerator: global _test_generator if _test_generator is None: _test_generator = TestDataGenerator(listener) elif listener is not None: _test_generator._listener = listener return _test_generator