放个虫子;加了手动输入 link 和 key 的交互;可导出CSV文件方便查看;
import requests
import json
import csv
from datetime import datetime
template = """
{
"devices": [
{%- for entity_id in states | map(attribute='entity_id') | list -%}
{
"device": "{{ state_attr(entity_id, 'friendly_name') if state_attr(entity_id, 'friendly_name') else states[entity_id].name }}",
"domain": "{{ entity_id.split('.')[0] }}",
"entity_id": "{{ entity_id }}",
"area": "{{ area_name(entity_id) if area_name(entity_id) else '未指定' }}"
}{%- if not loop.last -%},{%- endif -%}
{%- endfor -%}
]
}
"""
def get_ha_url():
while True:
url = input("请输入Home Assistant的URL (例如: http://192.168.31.223:8123): ").strip()
# 验证URL格式
if url.startswith(('http://', 'https://')):
# 移除URL末尾的斜杠
return url.rstrip('/')
else:
print("错误: URL必须以 'http://' 或 'https://' 开头")
def get_token():
while True:
token = input("请输入Long-Lived Access Token: ").strip()
if token:
return token
else:
print("错误: Token不能为空")
def get_device_info(ha_url, token):
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
}
try:
response = requests.post(
f"{ha_url}/api/template",
headers=headers,
json={"template": template}
)
response.raise_for_status()
result = json.loads(response.text)
return result['devices']
except requests.exceptions.ConnectionError:
print("连接错误: 无法连接到Home Assistant,请检查URL是否正确")
except requests.exceptions.HTTPError as e:
if e.response.status_code == 401:
print("认证错误: Token无效或已过期")
else:
print(f"HTTP错误: {e}")
except Exception as e:
print(f"错误: {e}")
return None
def save_to_csv(devices, filename):
fieldnames = ['Device', 'Domain', 'Entity ID', 'Area']
try:
with open(filename, 'w', newline='', encoding='utf-8') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for device in devices:
writer.writerow({
'Device': device['device'],
'Domain': device['domain'],
'Entity ID': device['entity_id'],
'Area': device['area']
})
print(f"CSV文件已保存: {filename}")
except Exception as e:
print(f"保存CSV文件时出错: {e}")
def main():
# 获取Home Assistant URL和Token
ha_url = get_ha_url()
token = get_token()
# 获取设备信息
devices = get_device_info(ha_url, token)
if devices:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"ha_devices_{timestamp}.csv"
# 调整列宽
device_width = 50
domain_width = 30
entity_id_width = 50
area_width = 30
# 计算总宽度用于分隔线
total_width = device_width + domain_width + entity_id_width + area_width
print("\n设备信息:")
print("-" * total_width)
print(f"{'Device':<{device_width}}{'Domain':<{domain_width}}{'Entity ID':<{entity_id_width}}{'Area':<{area_width}}")
print("-" * total_width)
for device in devices:
# 截断过长的字符串以防止错位
device_name = device['device'][:device_width-3] + '...' if len(device['device']) > device_width else device['device']
domain = device['domain'][:domain_width-3] + '...' if len(device['domain']) > domain_width else device['domain']
entity_id = device['entity_id'][:entity_id_width-3] + '...' if len(device['entity_id']) > entity_id_width else device['entity_id']
area = device['area'][:area_width-3] + '...' if len(device['area']) > area_width else device['area']
print(f"{device_name:<{device_width}}{domain:<{domain_width}}{entity_id:<{entity_id_width}}{area:<{area_width}}")
print("-" * total_width)
save_to_csv(devices, filename)
if __name__ == "__main__":
main()
ha_device_export.zip
(2.21 KB, 下载次数: 1)
|