hass-core/scripts/get_entities.py

141 lines
3.9 KiB
Python
Executable file

#! /usr/bin/python
"""
get_entities.py
Usage: get_entities.py [OPTION] ... [ATTRIBUTE] ...
Query the Home Assistant API for available entities then print them and any
desired attributes to the screen.
Options:
-h, --help display this text
--password=PASS use the supplied password
--ask-password prompt for password
-a, --address=ADDR use the supplied server address
-p, --port=PORT use the supplied server port
"""
import sys
import getpass
try:
from urllib2 import urlopen
PYTHON = 2
except ImportError:
from urllib.request import urlopen
PYTHON = 3
import json
def main(password, askpass, attrs, address, port):
""" fetch Home Assistant api json page and post process """
# ask for password
if askpass:
password = getpass.getpass('Home Assistant API Password: ')
# fetch API result
url = mk_url(address, port, password)
response = urlopen(url).read()
if PYTHON == 3:
response = response.decode('utf-8')
data = json.loads(response)
# parse data
output = {'entity_id': []}
output.update([(attr, []) for attr in attrs])
for item in data:
output['entity_id'].append(item['entity_id'])
for attr in attrs:
output[attr].append(item['attributes'].get(attr, ''))
# output data
print_table(output, 'entity_id')
def print_table(data, first_key):
""" format and print a table of data from a dictionary """
# get column lengths
lengths = {}
for key, value in data.items():
lengths[key] = max([len(str(val)) for val in value] + [len(key)])
# construct the column order
columns = sorted(list(data.keys()))
ind = columns.index(first_key)
columns.pop(ind)
columns = [first_key] + columns
# print header
for item in columns:
itemup = item.upper()
sys.stdout.write(itemup + ' ' * (lengths[item] - len(item) + 4))
sys.stdout.write('\n')
# print body
for ind in range(len(data[columns[0]])):
for item in columns:
val = str(data[item][ind])
sys.stdout.write(val + ' ' * (lengths[item] - len(val) + 4))
sys.stdout.write("\n")
def mk_url(address, port, password):
""" construct the url call for the api states page """
url = ''
if address.startswith('http://'):
url += address
else:
url += 'http://' + address
url += ':' + port + '/api/states?'
if password is not None:
url += 'api_password=' + password
return url
def parse(option, all_options):
""" either update the options or set it to be updated next time """
if len(option) > 1:
all_options[option[0]] = option[1]
return (all_options, None)
else:
return (all_options, option)
if __name__ == "__main__":
all_options = {'password': None, 'askpass': False, 'attrs': [],
'address': 'localhost', 'port': '8123'}
# parse arguments
next_key = None
for arg in sys.argv[1:]:
if next_key is None:
option = arg.split('=')
if option[0] in ['-h', '--help']:
print(__doc__)
sys.exit(0)
elif option[0] == '--password':
all_options['password'] = '='.join(option[1:])
elif option[0] == '--ask-password':
all_options['askpass'] = True
elif option[0] == '-a':
next_key = 'address'
elif option[0] == '--address':
all_options['address'] = '='.join(option[1:])
elif option[0] == '-p':
next_key = 'port'
elif option[0] == '--port':
all_options['port'] = '='.join(option[1])
else:
all_options['attrs'].append('='.join(option))
else:
all_options[next_key] = arg
next_key = None
main(**all_options)