Add support for Kuma push monitoring with retry logic
This commit is contained in:
65
listen.py
65
listen.py
@@ -29,6 +29,8 @@ ESP_API_KEY = os.getenv("ESP_API_KEY", "")
|
||||
KUMA_URL = os.getenv("KUMA_URL")
|
||||
KUMA_KEY = os.getenv("KUMA_KEY")
|
||||
POLL_INTERVAL = int(os.getenv("POLL_INTERVAL", "30"))
|
||||
KUMA_PUSH_URL = os.getenv("KUMA_PUSH_URL")
|
||||
KUMA_PUSH_INTERVAL = int(os.getenv("KUMA_PUSH_INTERVAL", "60"))
|
||||
|
||||
|
||||
class UptimeKumaMonitor:
|
||||
@@ -271,6 +273,51 @@ class ESP32Controller:
|
||||
logger.info("Disconnected from ESP32")
|
||||
|
||||
|
||||
async def push_to_kuma(session: aiohttp.ClientSession, url: str):
|
||||
"""Send a GET request to the Kuma push URL with retry logic"""
|
||||
try:
|
||||
# First attempt
|
||||
async with session.get(url, timeout=aiohttp.ClientTimeout(total=10)) as resp:
|
||||
logger.info(f"Kuma push: status {resp.status}")
|
||||
return
|
||||
except Exception as e:
|
||||
logger.warning(f"Kuma push failed: {e} (retrying in 15s)")
|
||||
await asyncio.sleep(15)
|
||||
|
||||
try:
|
||||
# Retry attempt
|
||||
async with session.get(url, timeout=aiohttp.ClientTimeout(total=10)) as resp:
|
||||
logger.info(f"Kuma push retry succeeded: status {resp.status}")
|
||||
except Exception as retry_e:
|
||||
logger.error(f"Kuma push retry failed: {retry_e}")
|
||||
|
||||
|
||||
async def kuma_push_monitor(
|
||||
url: str, interval: int, session: Optional[aiohttp.ClientSession] = None
|
||||
):
|
||||
"""Periodically send GET requests to the Kuma push URL.
|
||||
|
||||
If a session is provided, it will be reused and not closed here.
|
||||
If no session is provided, this function will create one and ensure it is
|
||||
properly closed, even if the task is cancelled.
|
||||
"""
|
||||
own_session = False
|
||||
if session is None:
|
||||
session = aiohttp.ClientSession()
|
||||
own_session = True
|
||||
|
||||
try:
|
||||
while True:
|
||||
await push_to_kuma(session, url)
|
||||
await asyncio.sleep(interval)
|
||||
except asyncio.CancelledError:
|
||||
# Ensure proper cleanup on cancellation before propagating
|
||||
raise
|
||||
finally:
|
||||
if own_session and not session.closed:
|
||||
await session.close()
|
||||
|
||||
|
||||
async def main():
|
||||
"""Main monitoring loop"""
|
||||
|
||||
@@ -285,12 +332,13 @@ async def main():
|
||||
|
||||
if not KUMA_KEY:
|
||||
logger.error("KUMA_KEY not set in environment")
|
||||
logger.error("Get your API key from Uptime Kuma: Settings → API Keys")
|
||||
sys.exit(1)
|
||||
|
||||
# Initialize ESP32 controller
|
||||
esp = ESP32Controller(ESP_IP, ESP_API_KEY)
|
||||
|
||||
# Initialize ESP32 controller
|
||||
esp = ESP32Controller(ESP_IP, ESP_API_KEY)
|
||||
# Connect to ESP32
|
||||
logger.info(f"Connecting to ESP32 at {ESP_IP}...")
|
||||
if not await esp.connect():
|
||||
@@ -300,6 +348,14 @@ async def main():
|
||||
|
||||
logger.info(f"Starting monitoring loop (interval: {POLL_INTERVAL}s)")
|
||||
|
||||
# Start Kuma push monitor if configured
|
||||
push_task = None
|
||||
if KUMA_PUSH_URL:
|
||||
push_task = asyncio.create_task(kuma_push_monitor(KUMA_PUSH_URL, KUMA_PUSH_INTERVAL))
|
||||
logger.info(f"Kuma push monitor started (URL: {KUMA_PUSH_URL}, Interval: {KUMA_PUSH_INTERVAL}s)")
|
||||
else:
|
||||
logger.info("Kuma push monitor not configured")
|
||||
|
||||
try:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
# Wait for esp to be fully connected
|
||||
@@ -327,6 +383,13 @@ async def main():
|
||||
except Exception as e:
|
||||
logger.error(f"Unexpected error: {e}")
|
||||
finally:
|
||||
# Cancel push monitor task if running
|
||||
if push_task and not push_task.done():
|
||||
push_task.cancel()
|
||||
try:
|
||||
await push_task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
await esp.disconnect()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user