Files
2026-10-22 10:52:58 -05:00

55 lines
2.2 KiB
Python

"""Local and authenticated presentation of the shared drive-state owner."""
import threading
import time
from .resolver import Mode
LABELS = {Mode.AUTO: 'Auto', Mode.OFFROAD: 'Offroad', Mode.ONROAD: 'Onroad'}
CYCLE = (Mode.OFFROAD, Mode.ONROAD, Mode.AUTO)
class DriveStateControl:
def __init__(self, owner, physical, *, effective=None, clock=time.monotonic):
self.owner, self.physical, self.effective, self.clock = owner, physical, effective or physical.effective, clock
self.cached = None
self.lock = threading.Lock()
def snapshot(self):
with self.lock:
now = self.clock()
if self.cached is None or not 0 <= now - self.cached[0] < 0.5:
state = self.owner.snapshot()
status = getattr(self.physical, 'status', None)
admission = status() if callable(status) else {'allowed': self.physical.allowed(), 'reason': None}
self.cached = now, state, bool(admission['allowed']), admission['reason']
state = self.cached[1]
actual = self.effective()
return {'mode': state.mode.value, 'revision': state.revision, 'available': state.available,
'effective': 'onroad' if actual is True else 'offroad' if actual is False else None,
'overrideAllowed': self.cached[2], 'reason': self.cached[3]}
def change(self, mode, revision, authorized):
# Deliberate local requests may stop driving services while moving; Galaxy uses a separate Park-checked request.
result = self.owner.request(mode, expected_revision=revision, authorized=authorized,
override_allowed=lambda: True)
with self.lock:
self.cached = None
return result
def change_galaxy(self, mode, revision, authorized):
result = self.owner.request(mode, expected_revision=revision, authorized=authorized,
override_allowed=lambda: self.physical.status(require_park=True)['allowed'])
with self.lock:
self.cached = None
return result
@staticmethod
def next_mode(status):
mode = Mode(status['mode'])
return CYCLE[(CYCLE.index(mode) + 1) % len(CYCLE)]
def cycle(self, status, authorized):
return self.change(self.next_mode(status).value, status['revision'], authorized)