UPS Dying

My lastman project worked, got a bunch of SMS messages when the UPS for my stack of switches died.

I looked at when I purchased this UPS, July 2021, so yeah 4 years, need to be replaced.

I got quality batteries, this is a very important stack.

Another thing I got done was listing devices and entities via python. Yesterday I got it working with curl/bash. Here is my code for python

#!/usr/bin/python3
"""
hassquery.py
Simple Python Script that uses websockets API to query devices in home assistant
By Larry Apolonio
Date : 2025-05-13
"""
import argparse
import asyncio
import json
import websockets

# === CONFIGURATION ===
HA_WS_URL = "ws://homeassistant.local:8123/api/websocket"
ACCESS_TOKEN = "TOKENGOESHERE" # Replace with your token

# === PARSE ARGUMENTS ===
parser = argparse.ArgumentParser(description="List Home Assistant devices by integration.")
parser.add_argument(
"-i", "--integration",
type=str,
default="all",
help="Integration to filter by (e.g. zha, tplink, mqtt, hue). Use 'all' to list everything."
)
args = parser.parse_args()
filter_integration = args.integration.lower()

async def list_devices_by_integration():
"""
list_devices_by_integration
Actual function to list devices
"""
async with websockets.connect(HA_WS_URL, max_size=10 * 1024 * 1024) as ws:
# Step 1: Authenticate
await ws.recv()
await ws.send(json.dumps({"type": "auth", "access_token": ACCESS_TOKEN}))
auth_response = json.loads(await ws.recv())
if auth_response.get("type") != "auth_ok":
print("Authentication failed.")
return
print(f"Authenticated. Listing devices for integration: '{filter_integration}'\n")

# Step 2: Get device registry
await ws.send(json.dumps({"id": 1, "type": "config/device_registry/list"}))
while True:
msg = json.loads(await ws.recv())
if msg.get("id") == 1 and msg.get("type") == "result":
devices = msg.get("result", [])
break

# Step 3: Get entity registry
await ws.send(json.dumps({"id": 2, "type": "config/entity_registry/list"}))
while True:
msg = json.loads(await ws.recv())
if msg.get("id") == 2 and msg.get("type") == "result":
entities = msg.get("result", [])
break

# Step 4: Build entity map
entity_map = {}
for ent in entities:
device_id = ent.get("device_id")
if device_id not in entity_map:
entity_map[device_id] = []
entity_map[device_id].append(ent)

# Step 5: Filter and print
matched_count = 0
for device in devices:
device_id = device.get("id")
related_entities = entity_map.get(device_id, [])
platforms = {e.get("platform", "").lower() for e in related_entities}

if filter_integration != "all" and filter_integration not in platforms:
continue

matched_count += 1
name = device.get("name_by_user") or device.get("name") or "Unnamed"
manufacturer = device.get("manufacturer", "Unknown")
model = device.get("model", "Unknown")
identifiers = device.get("identifiers", [])
area = device.get("area_id", "N/A")

print(f"Name : {name}")
print(f"Manufacturer : {manufacturer}")
print(f"Model : {model}")
print(f"Area : {area}")
print(f"Identifiers : {identifiers}")
print(f"Platforms : {', '.join(sorted(platforms)) or 'N/A'}")
print("Entities :")
for ent in related_entities:
print(f" - {ent['entity_id']} ({ent['platform']})")
print("-" * 60)

print(f"\nTotal devices found: {matched_count}")

if __name__ == '__main__':
asyncio.run(list_devices_by_integration())

Weight: 347.8

This entry was posted in Coding, New Toys, Technical, Training, Weigh In. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.