def delete(ctx, names): """Delete an area. NAMES - one or more area names or id to delete """ ctx.auto_output("data") excode = 0 for name in names: area = api.find_area(ctx, name) if not area: _LOGGING.error("Could not find area with id or name: %s", name) excode = 1 else: result = api.delete_area(ctx, area['area_id']) ctx.echo( helper.format_output( ctx, [result], columns=ctx.columns if ctx.columns else const.COLUMNS_DEFAULT, ) ) if excode != 0: sys.exit(excode)
def delete(ctx, names): """Delete an area. NAMES - one or more area names or id to delete """ ctx.auto_output("data") excode = 0 for name in names: area = api.find_area(ctx, name) if not area: _LOGGING.error("Could not find area with id or name: %s", name) excode = 1 else: result = api.delete_area(ctx, area['area_id']) ctx.echo( helper.format_output( ctx, [result], columns=ctx.columns if ctx.columns else const.COLUMNS_DEFAULT, )) if excode != 0: sys.exit(excode)
def listcmd(ctx: Configuration, entityfilter: str): """List all entities from Home Assistant.""" ctx.auto_output("table") entities = api.get_entities(ctx) result = [] # type: List[Dict] if entityfilter == ".*": result = entities else: entityfilterre = re.compile(entityfilter) # type: Pattern for entity in entities: if entityfilterre.search(entity['entity_id']): result.append(entity) cols = [ ('ENTITY_ID', 'entity_id'), ('NAME', 'name'), ('DEVICE_ID', 'device_id'), ('PLATFORM', 'platform'), ('CONFIG_ENTRY_ID', 'config_entry_id'), ('DISABLED_BY', 'disabled_by'), ] ctx.echo( helper.format_output(ctx, result, columns=ctx.columns if ctx.columns else cols))
def listcmd(ctx: Configuration, devicefilter: str): """List all devices from Home Assistant.""" ctx.auto_output("table") devices = api.get_devices(ctx) result = [] # type: List[Dict] if devicefilter == ".*": result = devices else: devicefilterre = re.compile(devicefilter) # type: Pattern for device in devices: if devicefilterre.search(device['name']): result.append(device) cols = [ ('ID', 'id'), ('NAME', 'name'), ('MODEL', 'model'), ('MANUFACTURER', 'manufacturer'), ('AREA', 'area_id'), ] ctx.echo( helper.format_output( ctx, result, columns=ctx.columns if ctx.columns else cols ) )
def listcmd(ctx: Configuration, entityfilter: str): """List all entities from Home Assistant.""" ctx.auto_output("table") entities = api.get_entities(ctx) result = [] # type: List[Dict] if entityfilter == ".*": result = entities else: entityfilterre = re.compile(entityfilter) # type: Pattern for entity in entities: if entityfilterre.search(entity['entity_id']): result.append(entity) cols = [ ('ENTITY_ID', 'entity_id'), ('NAME', 'name'), ('DEVICE_ID', 'device_id'), ('PLATFORM', 'platform'), ('CONFIG_ENTRY_ID', 'config_entry_id'), ('DISABLED_BY', 'disabled_by'), ] ctx.echo( helper.format_output( ctx, result, columns=ctx.columns if ctx.columns else cols ) )
def _msghandler(msg: Dict) -> None: if msg['type'] == 'event': ctx.echo( format_output( ctx, msg['event'], columns=ctx.columns if ctx.columns else cols, ))
def release(ctx: Configuration): """Get the release of Home Assistant.""" click.echo( format_output( ctx, [api.get_config(ctx)['version']], columns=ctx.columns if ctx.columns else [('VERSION', '$')], ))
def whitelist_dirs(ctx: Configuration): """Get the whitelisted directories from Home Assistant.""" click.echo( format_output( ctx, api.get_config(ctx)['whitelist_external_dirs'], columns=ctx.columns if ctx.columns else [('DIRECTORY', '$')], ))
def components(ctx: Configuration): """Get loaded components from Home Assistant.""" click.echo( format_output( ctx, api.get_config(ctx)['components'], columns=ctx.columns if ctx.columns else [('COMPONENT', '$')], ))
def full(ctx: Configuration): """Get full details on the configuration from Home Assistant.""" click.echo( format_output( ctx, [api.get_config(ctx)], columns=ctx.columns if ctx.columns else COLUMNS_DETAILS, ))
def get(ctx: Configuration, entity): """Get/read entity state from Home Assistant.""" ctx.auto_output("table") state = api.get_state(ctx, entity) if state: ctx.echo(helper.format_output(ctx, [state], const.COLUMNS_ENTITIES)) else: _LOGGING.error("Entity with id: '%s' not found.", entity)
def _msghandler(msg: Dict) -> None: if msg['type'] == 'event': ctx.echo( format_output( ctx, msg['event'], columns=ctx.columns if ctx.columns else cols, ) )
def _report(ctx: Configuration, result: List[Dict[str, Any]], action: str): ctx.echo( helper.format_output( ctx, result, columns=ctx.columns if ctx.columns else const.COLUMNS_ENTITIES, )) if ctx.verbose: ctx.echo("%s entities reported to be %s", len(result), action)
def _report(ctx: Configuration, result: List[Dict[str, Any]], action: str): ctx.echo( helper.format_output( ctx, result, columns=ctx.columns if ctx.columns else const.COLUMNS_ENTITIES, ) ) if ctx.verbose: ctx.echo("%s entities reported to be %s", len(result), action)
def _msghandler(msg: Dict) -> None: if msg['type'] == 'event': ctx.echo( format_output( ctx, msg['event'], columns=ctx.columns if ctx.columns else cols, )) elif msg['type'] == 'auth_invalid': raise HomeAssistantCliError(msg.get('message'))
def health(ctx: Configuration): """Get system health from Home Assistant.""" info = api.get_health(ctx) ctx.echo( format_output( ctx, [info], columns=ctx.columns if ctx.columns else const.COLUMNS_DEFAULT, ))
def history(ctx: Configuration, entities: List, since: str, end: str): """Get state history from Home Assistant, all or per entity. You can use `--since` and `--end` to narrow or expand the time period. Both options accepts a full timestamp i.e. `2016-02-06T22:15:00+00:00` or a relative expression i.e. `3m` for three minutes, `5d` for 5 days. Even `3 minutes` or `5 days` will work. See https://dateparser.readthedocs.io/en/latest/#features for examples. """ import dateparser ctx.auto_output("table") settings = { 'DATE_ORDER': 'DMY', 'TIMEZONE': 'UTC', 'RETURN_AS_TIMEZONE_AWARE': True, } start_time = dateparser.parse(since, settings=settings) end_time = dateparser.parse(end, settings=settings) delta = end_time - start_time if ctx.verbose: click.echo( 'Querying from {}:{} to {}:{} a span of {}'.format( since, start_time.isoformat(), end, end_time.isoformat(), delta ) ) data = api.get_history(ctx, list(entities), start_time, end_time) result = [] # type: List[Dict[str, Any]] entitycount = 0 for item in data: result.extend(item) # type: ignore entitycount = entitycount + 1 click.echo( helper.format_output( ctx, result, columns=ctx.columns if ctx.columns else const.COLUMNS_ENTITIES, ) ) if ctx.verbose: click.echo( 'History with {} rows from {} entities found.'.format( len(result), entitycount ) )
def history(ctx: Configuration, entities: List, since: str, end: str): """Get history from Home Assistant, all or per entity. You can use `--since` and `--end` to narrow or expand the time period. Both options accepts a full timestamp i.e. `2016-02-06T22:15:00+00:00` or a relative expression i.e. `3m` for three minutes, `5d` for 5 days. Even `3 minutes` or `5 days` will work. See https://dateparser.readthedocs.io/en/latest/#features for examples. """ import dateparser ctx.auto_output("table") settings = { 'DATE_ORDER': 'DMY', 'TIMEZONE': 'UTC', 'RETURN_AS_TIMEZONE_AWARE': True, } start_time = dateparser.parse(since, settings=settings) end_time = dateparser.parse(end, settings=settings) delta = end_time - start_time if ctx.verbose: click.echo( 'Querying from {}:{} to {}:{} a span of {}'.format( since, start_time.isoformat(), end, end_time.isoformat(), delta ) ) data = api.get_history(ctx, list(entities), start_time, end_time) result = [] # type: List[Dict[str, Any]] entitycount = 0 for item in data: result.extend(item) # type: ignore entitycount = entitycount + 1 click.echo( helper.format_output( ctx, result, columns=ctx.columns if ctx.columns else const.COLUMNS_ENTITIES, ) ) if ctx.verbose: click.echo( 'History with {} rows from {} entities found.'.format( len(result), entitycount ) )
def health(ctx: Configuration): """Get system health from Home Assistant.""" info = api.get_health(ctx) ctx.echo( format_output( ctx, [info], columns=ctx.columns if ctx.columns else const.COLUMNS_DEFAULT, ) )
def state(ctx, entities): """toggle state from Home Assistant""" for entity in entities: import json data = {"entity_id": entity} click.echo("Toggling {}".format(entity)) response = req_raw(ctx, "post", "services/homeassistant/toggle", json.dumps(data)) if response.ok: result = response.json() click.echo(format_output(ctx, response.json())) click.echo("{} entities reported to be toggled".format( len(result)))
def list_cmd(ctx: Configuration, servicefilter): """Get list of services.""" ctx.auto_output('table') services = api.get_services(ctx) result = [] # type: List[Dict[Any,Any]] if servicefilter == ".*": result = services else: result = services servicefilterre = reg.compile(servicefilter) # type: Pattern domains = [] for domain in services: domain_name = domain['domain'] domaindata = {} servicesdict = domain['services'] servicedata = {} for service in servicesdict: if servicefilterre.search( "{}.{}".format(domain_name, service) ): servicedata[service] = servicesdict[service] if servicedata: domaindata["services"] = servicedata domaindata["domain"] = domain_name domains.append(domaindata) result = domains flattenresult = [] # type: List[Dict[str,Any]] for domain in result: for service in domain['services']: item = {} item['domain'] = domain['domain'] item['service'] = service item = {**item, **domain['services'][service]} flattenresult.append(item) cols = [ ('DOMAIN', 'domain'), ('SERVICE', 'service'), ('DESCRIPTION', 'description'), ] ctx.echo( format_output( ctx, flattenresult, columns=ctx.columns if ctx.columns else cols ) )
def list_cmd(ctx: Configuration, servicefilter): """Get list of services.""" ctx.auto_output('table') services = api.get_services(ctx) result = [] # type: List[Dict[Any,Any]] if servicefilter == ".*": result = services else: result = services servicefilterre = reg.compile(servicefilter) # type: Pattern domains = [] for domain in services: domain_name = domain['domain'] domaindata = {} servicesdict = domain['services'] servicedata = {} for service in servicesdict: if servicefilterre.search( "{}.{}".format(domain_name, service) ): servicedata[service] = servicesdict[service] if servicedata: domaindata["services"] = servicedata domaindata["domain"] = domain_name domains.append(domaindata) result = domains flattenresult = [] # type: List[Dict[str,Any]] for domain in result: for service in domain['services']: item = {} item['domain'] = domain['domain'] item['service'] = service item = {**item, **domain['services'][service]} flattenresult.append(item) cols = [ ('DOMAIN', 'domain'), ('SERVICE', 'service'), ('DESCRIPTION', 'description'), ] ctx.echo( format_output( ctx, flattenresult, columns=ctx.columns if ctx.columns else cols ) )
def get(ctx: Configuration, entity): """Get/read entity state from Home Assistant.""" ctx.auto_output("table") state = api.get_state(ctx, entity) if state: ctx.echo( helper.format_output( ctx, [state], columns=ctx.columns if ctx.columns else const.COLUMNS_ENTITIES, ) ) else: _LOGGING.error("Entity with id: '%s' not found.", entity)
def cli(ctx: Configuration): """Get basic info from Home Assistant.""" ctx.auto_output("table") cols = [ ("BASE_URL", "base_url"), ("LOCATION", "location_name"), ("REQUIRES_API_PASSWORD", "requires_api_password"), ("VERSION", "version"), ] ctx.echo( format_output( ctx, [api.get_info(ctx)], columns=ctx.columns if ctx.columns else cols, ))
def create(ctx, names): """Create an area. NAMES - one or more area names to create """ ctx.auto_output("data") for name in names: result = api.create_area(ctx, name) ctx.echo( helper.format_output( ctx, [result], columns=ctx.columns if ctx.columns else const.COLUMNS_DEFAULT, ))
def _report(ctx, cmd, method, response) -> None: response.raise_for_status() if response.ok: try: ctx.echo(format_output(ctx, response.json())) except json_.decoder.JSONDecodeError: _LOGGING.debug("Response could not be parsed as json.") ctx.echo(response.text) else: _LOGGING.warning( "%s: <No output returned from %s %s>", response.status_code, cmd, method, )
def create(ctx, names): """Create an area. NAMES - one or more area names to create """ ctx.auto_output("data") for name in names: result = api.create_area(ctx, name) ctx.echo( helper.format_output( ctx, [result], columns=ctx.columns if ctx.columns else const.COLUMNS_DEFAULT, ) )
def _report(ctx, cmd, method, response) -> None: response.raise_for_status() if response.ok: try: ctx.echo(format_output(ctx, response.json())) except json_.decoder.JSONDecodeError: _LOGGING.debug("Response could not be parsed as JSON") ctx.echo(response.text) else: _LOGGING.warning( "%s: <No output returned from %s %s>", response.status_code, cmd, method, )
def rename(ctx, oldname, newname): """Rename an area.""" ctx.auto_output("data") area = api.find_area(ctx, oldname) if not area: _LOGGING.error("Could not find area with id or name: %s", oldname) sys.exit(1) result = api.rename_area(ctx, area['area_id'], newname) ctx.echo( helper.format_output( ctx, [result], columns=ctx.columns if ctx.columns else const.COLUMNS_DEFAULT, ))
def cli(ctx: Configuration, raw): """Discovery for the local network.""" from netdisco.discovery import NetworkDiscovery click.echo("Running discovery on network (might take a while)...") netdiscovery = NetworkDiscovery() netdiscovery.scan() for device in netdiscovery.discover(): info = netdiscovery.get_info(device) click.echo("{}:\n{}".format(device, format_output(ctx, info))) if raw: click.echo("Raw data:") netdiscovery.print_raw_data() netdiscovery.stop()
def rename(ctx, oldname, newname): """Rename an area.""" ctx.auto_output("data") area = api.find_area(ctx, oldname) if not area: _LOGGING.error("Could not find area with id or name: %s", oldname) sys.exit(1) result = api.rename_area(ctx, area['area_id'], newname) ctx.echo( helper.format_output( ctx, [result], columns=ctx.columns if ctx.columns else const.COLUMNS_DEFAULT, ) )
def call(ctx: Configuration, service, arguments): """Call a service.""" ctx.auto_output('data') _LOGGING.debug("service call <start>") parts = service.split(".") if len(parts) != 2: _LOGGING.error("Service name not following <domain>.<service> format.") sys.exit(1) _LOGGING.debug("Convert arguments %s to dict", arguments) data = to_attributes(arguments) _LOGGING.debug("service call_service") result = api.call_service(ctx, parts[0], parts[1], data) _LOGGING.debug("Formatting ouput") ctx.echo(format_output(ctx, result))
def call(ctx: Configuration, service, arguments): """Call a service.""" ctx.auto_output('data') _LOGGING.debug("service call <start>") parts = service.split(".") if len(parts) != 2: _LOGGING.error("Service name not following <domain>.<service> format") sys.exit(1) _LOGGING.debug("Convert arguments %s to dict", arguments) data = to_attributes(arguments) _LOGGING.debug("service call_service") result = api.call_service(ctx, parts[0], parts[1], data) _LOGGING.debug("Formatting output") ctx.echo(format_output(ctx, result))
def websocket(ctx: Configuration, wstype, json): # noqa: D301 """Send a websocket request against /api/websocket. WSTYPE is name of websocket methods. \b --json is dictionary to pass in addition to the type. Example: --json='{ "area_id":"2c8bf93c8082492f99c989896962f207" }' """ if json: data = json_.loads(json) else: data = {} frame = {'type': wstype} frame = {**frame, **data} # merging data into frame response = cast(List[Dict[str, Any]], api.wsapi(ctx, frame)) ctx.echo(format_output(ctx, response))
def listcmd(ctx, entityfilter): """List all state from Home Assistant.""" ctx.auto_output("table") states = api.get_states(ctx) result = [] # type: List[Dict] if entityfilter == ".*": result = states else: entityfilterre = re.compile(entityfilter) # type: Pattern for entity in states: if entityfilterre.search(entity['entity_id']): result.append(entity) ctx.echo( helper.format_output( ctx, result, columns=ctx.columns if ctx.columns else const.COLUMNS_ENTITIES, ))
def rename(ctx, oldid, newid, name): """Rename a entity.""" ctx.auto_output("data") if not newid and not name: _LOGGING.error("Need to at least specify either a new id or new name") sys.exit(1) entity = api.get_entity(ctx, oldid) if not entity: _LOGGING.error("Could not find entity with ID: %s", oldid) sys.exit(1) result = api.rename_entity(ctx, oldid, newid, name) ctx.echo( helper.format_output( ctx, [result], columns=ctx.columns if ctx.columns else const.COLUMNS_DEFAULT, ))
def listcmd(ctx, entityfilter): """List all state from Home Assistant.""" ctx.auto_output("table") states = api.get_states(ctx) result = [] # type: List[Dict] if entityfilter == ".*": result = states else: entityfilterre = re.compile(entityfilter) # type: Pattern for entity in states: if entityfilterre.search(entity['entity_id']): result.append(entity) ctx.echo( helper.format_output( ctx, result, columns=ctx.columns if ctx.columns else const.COLUMNS_ENTITIES, ) )
def listcmd(ctx: Configuration, areafilter: str): """List all areas from Home Assistant.""" ctx.auto_output("table") areas = api.get_areas(ctx) result = [] # type: List[Dict] if areafilter == ".*": result = areas else: areafilterre = re.compile(areafilter) # type: Pattern for device in areas: if areafilterre.search(device['name']): result.append(device) cols = [('ID', 'area_id'), ('NAME', 'name')] ctx.echo( helper.format_output(ctx, result, columns=ctx.columns if ctx.columns else cols))
def rename(ctx, oldid, newid, name): """Rename a entity.""" ctx.auto_output("data") if not newid and not name: _LOGGING.error("Need to at least specify either a new id or new name") sys.exit(1) entity = api.get_entity(ctx, oldid) if not entity: _LOGGING.error("Could not find entity with id: %s", oldid) sys.exit(1) result = api.rename_entity(ctx, oldid, newid, name) ctx.echo( helper.format_output( ctx, [result], columns=ctx.columns if ctx.columns else const.COLUMNS_DEFAULT, ) )
def listcmd(ctx: Configuration, areafilter: str): """List all areas from Home Assistant.""" ctx.auto_output("table") areas = api.get_areas(ctx) result = [] # type: List[Dict] if areafilter == ".*": result = areas else: areafilterre = re.compile(areafilter) # type: Pattern for device in areas: if areafilterre.search(device['name']): result.append(device) cols = [('ID', 'area_id'), ('NAME', 'name')] ctx.echo( helper.format_output( ctx, result, columns=ctx.columns if ctx.columns else cols ) )
def cli(ctx): """Get basic info from Home Assistant using /api/discovery_info.""" click.echo(format_output(ctx, req(ctx, "get", "discovery_info")))
def get(ctx, method): """do a GET against api/<method>""" click.echo(format_output(ctx, req(ctx, "get", method)))
def post(ctx, method, json): """do a POST against api/<method>""" click.echo(format_output(ctx, req(ctx, "post", method, json)))