fix: refresh mc.contacts from device on dirty flag to update stale names

Contact names stayed stale indefinitely because mc.contacts (in-memory
dict) was only populated at startup. When a remote node renamed itself,
the device firmware updated its contact list but the app never re-read it.

Now ensure_contacts(follow=True) is called when contacts_dirty is set:
- In _on_advertisement(): refresh before name lookup (incremental via lastmod)
- In get_contacts_with_last_seen(): refresh + DB sync before serving API data

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
MarekWo
2026-04-09 12:29:45 +02:00
parent bbfca38d34
commit 8f8bd30747
2 changed files with 22 additions and 3 deletions
+8 -1
View File
@@ -778,7 +778,7 @@ class DeviceManager:
ADVERTISEMENT payload only contains {'public_key': '...'}.
Full contact details (name, type, lat/lon) must be looked up
from mc.contacts which is synced at startup.
from mc.contacts which is refreshed from device when dirty.
If the contact is unknown (new auto-add by firmware), refresh contacts.
"""
try:
@@ -788,6 +788,13 @@ class DeviceManager:
if not pubkey:
return
# Refresh contacts from device if dirty (e.g., contact renamed).
# The meshcore library sets contacts_dirty=True on every advert,
# but with auto_update_contacts=False we must refresh manually.
# Uses incremental fetch (lastmod) so only changed contacts are read.
if self.mc.contacts_dirty:
await self.mc.ensure_contacts(follow=True)
# Look up full contact details from meshcore's contact list
contact = (self.mc.contacts or {}).get(pubkey, {})
name = contact.get('adv_name', contact.get('name', ''))
+14 -2
View File
@@ -158,10 +158,22 @@ def _parse_last_advert(value) -> int:
def get_contacts_with_last_seen() -> Tuple[bool, Dict[str, Dict], str]:
"""Get contacts actually on the device firmware (from mc.contacts)."""
"""Get contacts actually on the device firmware (from mc.contacts).
Refreshes from device if contacts_dirty flag is set (e.g., after
receiving adverts that may carry updated names/paths).
"""
try:
dm = _get_dm()
if not dm.mc or not dm.mc.contacts:
if not dm.mc:
return True, {}, ""
# Refresh contacts from device if dirty (name changes, path updates, etc.)
if dm.mc.contacts_dirty:
dm.execute(dm.mc.ensure_contacts(follow=True))
dm._sync_contacts_to_db()
if not dm.mc.contacts:
return True, {}, ""
contacts_dict = {}
for pk, contact in dm.mc.contacts.items():