Adding the new rewrite

This commit is contained in:
Ketan Patel committed 2026-04-04 13:53:57 -04:00
1 parent 4aca9f08d1
commit 9b48b01d1d
62 files changed
+4510 -1406

No files matched your search

+22 -7
View File
@@ -1,22 +1,24 @@
from __future__ import annotations
import asyncio
import shutil
import logging
from typing import Dict, Any
import shutil
from typing import Any
logger = logging.getLogger(__name__)
APCACCESS_BIN = shutil.which('apcaccess') or 'apcaccess'
APCACCESS_TIMEOUT_SECONDS = 10.0
class APCStatusError(Exception):
pass
async def fetch_status(host: str, port: int) -> Dict[str, Any]:
async def fetch_status(host: str, port: int) -> dict[str, Any]:
"""Invoke apcaccess CLI and parse key:value lines into a dict.
Raises APCStatusError if binary fails or returns no data.
Raises APCStatusError if binary fails, times out, or returns no data.
"""
proc = await asyncio.create_subprocess_exec(
APCACCESS_BIN,
@@ -25,14 +27,26 @@ async def fetch_status(host: str, port: int) -> Dict[str, Any]:
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await proc.communicate()
try:
stdout, stderr = await asyncio.wait_for(
proc.communicate(), timeout=APCACCESS_TIMEOUT_SECONDS
)
except TimeoutError:
try:
proc.kill()
await proc.wait()
except ProcessLookupError:
pass
raise APCStatusError(
f"apcaccess timed out after {APCACCESS_TIMEOUT_SECONDS}s for {host}:{port}"
)
if proc.returncode != 0:
err_txt = stderr.decode(errors="replace").strip()
raise APCStatusError(
f'apcaccess exit {proc.returncode}: {err_txt}'
)
text = stdout.decode(errors='replace')
data: Dict[str, Any] = {}
data: dict[str, Any] = {}
for line in text.splitlines():
if ':' not in line:
continue
@@ -40,7 +54,8 @@ async def fetch_status(host: str, port: int) -> Dict[str, Any]:
key = k.strip()
val = v.strip()
data[key] = val
# Normalize expected fields/aliases
if not data:
raise APCStatusError("apcaccess returned no data")
if 'UPSNAME' not in data and 'NAME' in data:
data['UPSNAME'] = data['NAME']
if 'MODEL' in data: