Adding the new rewrite
This commit is contained in:
1 parent
4aca9f08d1
commit
9b48b01d1d
62 files changed
+4510
-1406
No files matched your search
+22
-7
@@ -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:
|
||||
|
||||
Reference in new issue
Block a user