Draggable nodes and periodic (hourly) announce

This commit is contained in:
Jack Kingsman
2026-01-22 22:39:34 -08:00
parent 775b128851
commit b3c26507f4
9 changed files with 141 additions and 26 deletions
+20
View File
@@ -161,6 +161,26 @@ if is_polling_paused():
print("Polling is currently paused")
```
### Periodic Advertisement
The server automatically sends an advertisement every hour to announce presence on the mesh.
This helps maintain visibility to other nodes and refreshes routing information.
- Started automatically on radio connection
- Interval: 1 hour (3600 seconds)
- Uses flood mode for maximum reach
```python
from app.radio_sync import start_periodic_advert, stop_periodic_advert, send_advertisement
# Start/stop periodic advertising
start_periodic_advert() # Started automatically in lifespan
await stop_periodic_advert()
# Manual advertisement
await send_advertisement() # Returns True on success
```
## Database Schema
```sql
+6
View File
@@ -14,8 +14,10 @@ from app.radio import radio_manager
from app.radio_sync import (
drain_pending_messages,
start_message_polling,
start_periodic_advert,
start_periodic_sync,
stop_message_polling,
stop_periodic_advert,
stop_periodic_sync,
sync_and_offload_all,
sync_radio_time,
@@ -69,6 +71,9 @@ async def lifespan(app: FastAPI):
advert_result = await radio_manager.meshcore.commands.send_advert(flood=True)
logger.info("Advertisement sent: %s", advert_result.type)
# Start periodic advertisement (every hour)
start_periodic_advert()
await radio_manager.meshcore.start_auto_message_fetching()
logger.info("Auto message fetching started")
@@ -90,6 +95,7 @@ async def lifespan(app: FastAPI):
logger.info("Shutting down")
await radio_manager.stop_connection_monitor()
await stop_message_polling()
await stop_periodic_advert()
await stop_periodic_sync()
if radio_manager.meshcore:
await radio_manager.meshcore.stop_auto_message_fetching()
+69
View File
@@ -29,6 +29,12 @@ _message_poll_task: asyncio.Task | None = None
# Message poll interval in seconds
MESSAGE_POLL_INTERVAL = 5
# Periodic advertisement task handle
_advert_task: asyncio.Task | None = None
# Advertisement interval in seconds (1 hour)
ADVERT_INTERVAL = 3600
# Counter to pause polling during repeater operations (supports nested pauses)
_polling_pause_count: int = 0
@@ -329,6 +335,69 @@ async def stop_message_polling():
logger.info("Stopped periodic message polling")
async def send_advertisement() -> bool:
"""Send an advertisement to announce presence on the mesh.
Returns True if successful, False otherwise.
"""
if not radio_manager.is_connected or radio_manager.meshcore is None:
logger.debug("Cannot send advertisement: radio not connected")
return False
try:
result = await radio_manager.meshcore.commands.send_advert(flood=True)
if result.type == EventType.OK:
logger.info("Periodic advertisement sent successfully")
return True
else:
logger.warning("Failed to send advertisement: %s", result.payload)
return False
except Exception as e:
logger.warning("Error sending advertisement: %s", e)
return False
async def _periodic_advert_loop():
"""Background task that periodically sends advertisements."""
while True:
try:
await asyncio.sleep(ADVERT_INTERVAL)
if radio_manager.is_connected:
await send_advertisement()
except asyncio.CancelledError:
logger.info("Periodic advertisement task cancelled")
break
except Exception as e:
logger.error("Error in periodic advertisement loop: %s", e)
def start_periodic_advert():
"""Start the periodic advertisement background task."""
global _advert_task
if _advert_task is None or _advert_task.done():
_advert_task = asyncio.create_task(_periodic_advert_loop())
logger.info(
"Started periodic advertisement (interval: %ds / %d min)",
ADVERT_INTERVAL,
ADVERT_INTERVAL // 60,
)
async def stop_periodic_advert():
"""Stop the periodic advertisement background task."""
global _advert_task
if _advert_task and not _advert_task.done():
_advert_task.cancel()
try:
await _advert_task
except asyncio.CancelledError:
pass
_advert_task = None
logger.info("Stopped periodic advertisement")
async def sync_radio_time() -> bool:
"""Sync the radio's clock with the system time.