From 08bb25779184abad95792ef3a37015f03320ccf0 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Sat, 11 Jul 2026 22:18:42 +0200 Subject: [PATCH] =?UTF-8?q?fix(bridge):=20Ortsname=20rechtzeitig=20da=20?= =?UTF-8?q?=E2=80=94=20Geocode=20vor=20Pr=C3=A4fix-Bau=20awaiten?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Der Reverse-Geocode lief nur async im Hintergrund — die ERSTE Nachricht an einem Ort (v.a. direkt nach Bridge-Neustart, Cache leer) wurde gebaut BEVOR der Name fertig war → Präfix ohne Ort → local suchte Wetter mit rohen Koordinaten und fand nichts. Neu: _ensure_place_name() awaitet den (laufenden oder frisch gestarteten) Geocode kurz mit Timeout, bevor der Standort-Präfix gebaut wird. Gecacht → nur die erste Nachricht an einem neuen Ort zahlt ~0,5s, danach instant. Timeout/Fehler → Fallback auf reine Koordinaten (kein Hänger). Co-Authored-By: Claude Opus 4.8 --- bridge/aria_bridge.py | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/bridge/aria_bridge.py b/bridge/aria_bridge.py index 1879533..6a319af 100644 --- a/bridge/aria_bridge.py +++ b/bridge/aria_bridge.py @@ -1252,9 +1252,29 @@ class ARIABridge: self._geocoded_key = key self._last_place_name = "" try: - asyncio.create_task(self._do_reverse_geocode(lat, lon, key)) + self._geocode_task = asyncio.create_task(self._do_reverse_geocode(lat, lon, key)) except Exception: - pass + self._geocode_task = None + + async def _ensure_place_name(self, lat, lon) -> None: + """Stellt (blockierend, mit Timeout) sicher, dass der Ortsname fuer die + aktuelle Position da ist — fuer die ERSTE Nachricht an einem neuen Ort, + wo der Hintergrund-Geocode noch laeuft. Gecacht → danach instant.""" + try: + lat, lon = float(lat), float(lon) + key = (round(lat, 3), round(lon, 3)) + except Exception: + return + if key == getattr(self, "_geocoded_key", None) and getattr(self, "_last_place_name", ""): + return # schon aufgeloest + if key != getattr(self, "_geocoded_key", None): + self._maybe_reverse_geocode(lat, lon) # startet Task + task = getattr(self, "_geocode_task", None) + if task is not None and not task.done(): + try: + await asyncio.wait_for(asyncio.shield(task), timeout=6) + except Exception: + pass # Timeout/Fehler → Praefix faellt auf reine Koordinaten zurueck async def _do_reverse_geocode(self, lat: float, lon: float, key) -> None: """Nominatim-Reverse-Geocode (keyless, gratis). Baut einen moeglichst @@ -2283,6 +2303,9 @@ class ARIABridge: logger.info("[rvs] App-Chat (mit Anhaengen) project=%s: '%s'", str(payload.get("projectId") or "") or "(main)", text[:80]) else: + _lg = location or getattr(self, "_last_location", None) + if isinstance(_lg, dict) and _lg.get("lat") is not None: + await self._ensure_place_name(_lg.get("lat"), _lg.get("lon") or _lg.get("lng")) core_text = self._build_core_text(text, interrupted, location) logger.info("[rvs] App-Chat%s%s: '%s'", " [BARGE-IN]" if interrupted else "", @@ -3380,6 +3403,9 @@ class ARIABridge: logger.warning("[rvs] STT-Text konnte nicht an RVS gesendet werden: %s", e) # Dann an Brain — der blockt synchron bis ARIA fertig ist. + _lg = location or getattr(self, "_last_location", None) + if isinstance(_lg, dict) and _lg.get("lat") is not None: + await self._ensure_place_name(_lg.get("lat"), _lg.get("lon") or _lg.get("lng")) core_text = self._build_core_text(text, interrupted, location) await self.send_to_core(core_text, source="app-voice" + (" [barge-in]" if interrupted else ""),