Files
Felix Zösch 9be64a0696 Add homeassistant skill in unpacked format
- Add complete homeassistant skill source to skills/ directory
- Includes all scripts, references, and automation templates
- Matches format of other skills in repository
2025-12-16 12:49:56 +01:00

96 lines
3.3 KiB
Python
Executable File

#!/usr/bin/env python3
"""
List all available Home Assistant services
This script queries Home Assistant and displays all available services organized by domain.
Usage:
# List all services
python3 list_services.py --url http://homeassistant.local:8123 --token YOUR_TOKEN
# List services for specific domain
python3 list_services.py --url http://homeassistant.local:8123 --token YOUR_TOKEN --domain light
# Output as JSON
python3 list_services.py --url http://homeassistant.local:8123 --token YOUR_TOKEN --format json
Environment variables:
HA_URL: Home Assistant URL
HA_TOKEN: Long-lived access token
"""
import argparse
import json
import os
import sys
import urllib.request
def get_services(url: str, token: str):
"""Get all services from Home Assistant."""
api_url = f"{url.rstrip('/')}/api/services"
headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
req = urllib.request.Request(api_url, headers=headers)
try:
with urllib.request.urlopen(req) as response:
return json.loads(response.read().decode('utf-8'))
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
def main():
parser = argparse.ArgumentParser(description='List Home Assistant services')
parser.add_argument('--url', help='Home Assistant URL',
default=os.getenv('HA_URL'))
parser.add_argument('--token', help='Long-lived access token',
default=os.getenv('HA_TOKEN'))
parser.add_argument('--domain', help='Filter by domain (e.g., light, switch)')
parser.add_argument('--format', choices=['tree', 'json', 'list'],
default='tree', help='Output format')
args = parser.parse_args()
if not args.url or not args.token:
print("Error: URL and token are required", file=sys.stderr)
sys.exit(1)
services = get_services(args.url, args.token)
# Filter by domain if specified
if args.domain:
services = {args.domain: services.get(args.domain, {})}
if args.format == 'json':
print(json.dumps(services, indent=2))
elif args.format == 'list':
for domain, domain_services in sorted(services.items()):
for service in sorted(domain_services.keys()):
print(f"{domain}.{service}")
else: # tree format
for domain, domain_services in sorted(services.items()):
print(f"\n{domain}:")
for service, details in sorted(domain_services.items()):
description = details.get('description', 'No description')
print(f"{service}")
if description and description != 'No description':
print(f" {description}")
# Show fields if available
if 'fields' in details and details['fields']:
print(f" Fields:")
for field_name, field_info in details['fields'].items():
field_desc = field_info.get('description', '')
print(f" - {field_name}: {field_desc}")
print(f"\nTotal: {sum(len(s) for s in services.values())} services across {len(services)} domains")
if __name__ == '__main__':
main()