diff --git a/scripts/get_entities.py b/scripts/get_entities.py new file mode 100755 index 0000000000000000000000000000000000000000..e2a5ff50c1ade45a14832c487f063d726fdb54ca --- /dev/null +++ b/scripts/get_entities.py @@ -0,0 +1,141 @@ +#! /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)