Esempio n. 1
0
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
        )
    )
Esempio n. 2
0
def edit(ctx: Configuration, entity, newstate, attributes, merge, json):
    """Edit entity state from Home Assistant."""
    ctx.auto_output('data')
    new_state = newstate
    if json:
        _LOGGING.debug(
            "JSON found overriding/creating new state for entity %s", entity)
        wanted_state = json_.loads(json)
    elif new_state or attributes:
        wanted_state = {}
        existing_state = api.get_state(ctx, entity)

        if existing_state:
            ctx.echo("Existing state found for %s", entity)
            if merge:
                wanted_state = existing_state
        else:
            ctx.echo("No existing state found for '%s'", entity)

        if attributes:
            attributes_dict = helper.to_attributes(attributes)

            new_attr = wanted_state.get('attributes', {})
            new_attr.update(attributes_dict)
            # This is not honoring merge!
            wanted_state['attributes'] = new_attr

        if newstate:
            wanted_state['state'] = newstate
        else:
            if not existing_state:
                raise ValueError("No new or existing state provided.")
            wanted_state['state'] = existing_state['state']

    else:
        existing = api.get_state(ctx, entity)
        if existing:
            existing_raw = helper.raw_format_output(ctx.output, existing,
                                                    ctx.yaml())
        else:
            existing_raw = helper.raw_format_output(ctx.output, {}, ctx.yaml())

        new = click.edit(existing_raw, extension='.{}'.format(ctx.output))

        if new is not None:
            ctx.echo("Updating '%s'", entity)
            if ctx.output == 'yaml':
                wanted_state = ctx.yamlload(new)
            if ctx.output == 'json':
                wanted_state = json_.loads(new)

            api.set_state(ctx, entity, wanted_state)
        else:
            ctx.echo("No edits/changes returned from editor.")
            return

    _LOGGING.debug("wanted: %s", str(wanted_state))
    result = api.set_state(ctx, entity, wanted_state)
    ctx.echo("Entity %s updated successfully", entity)
    _LOGGING.debug("Updated to: %s", result)
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
        )
    )
Esempio n. 4
0
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))
Esempio n. 5
0
def assign(
    ctx: Configuration,
    area_id_or_name,
    names: List[str],
    match: Optional[str] = None,
):
    """Update area on one or more devices.

    NAMES - one or more name or id (Optional)
    """
    ctx.auto_output("data")

    devices = api.get_devices(ctx)

    result = []  # type: List[Dict]

    area = api.find_area(ctx, area_id_or_name)
    if not area:
        _LOGGING.error("Could not find area with id or name: %s",
                       area_id_or_name)
        sys.exit(1)

    if match:
        if match == ".*":
            result = devices
        else:
            devicefilterre = re.compile(match)  # type: Pattern

            for device in devices:
                if devicefilterre.search(device['name']):
                    result.append(device)

    for id_or_name in names:
        device = next(
            (x for x in devices if x['id'] == id_or_name),
            None  # type: ignore
        )
        if not device:
            device = next(
                (x for x in devices if x['name'] == id_or_name),
                None,  # type: ignore
            )
        if not device:
            _LOGGING.error("Could not find device with id or name: %s",
                           id_or_name)
            sys.exit(1)
        result.append(device)

    for device in result:
        output = api.assign_area(ctx, device['id'], area['area_id'])
        if output['success']:
            ctx.echo("Successfully assigned '{}' to '{}'".format(
                area['name'], device['name']))
        else:
            _LOGGING.error("Failed to assign '%s' to '%s'", area['name'],
                           device['name'])

            ctx.echo(str(output))
Esempio n. 6
0
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)
Esempio n. 7
0
def delete(ctx: Configuration, entity):
    """Delete entity state from Home Assistant."""
    ctx.auto_output("table")
    deleted = api.remove_state(ctx, entity)

    if deleted:
        ctx.echo("State for entity %s deleted.", entity)
    else:
        ctx.echo("Entity %s not found.", entity)
Esempio n. 8
0
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)
Esempio n. 9
0
def delete(ctx: Configuration, entity):
    """Delete entity state from Home Assistant."""
    ctx.auto_output("table")
    deleted = api.remove_state(ctx, entity)

    if deleted:
        ctx.echo("State for entity %s deleted.", entity)
    else:
        ctx.echo("Entity %s not found.", entity)
Esempio n. 10
0
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,
        ))
Esempio n. 11
0
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)
Esempio n. 12
0
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,
        )
    )
Esempio n. 13
0
def core_update(ctx: Configuration):
    """Home Assistant core update."""
    response = _handle_raw(ctx, 'core/info')
    data = response['data']
    current_version = data['version']
    latest_version = data['version_latest']
    if StrictVersion(current_version) == StrictVersion(latest_version):
        ctx.echo("Already running the latest release")
    else:
        try:
            _handle(ctx, 'core/update', 'post')
        except (HomeAssistantCliError, HTTPError):
            pass
Esempio n. 14
0
def supervisor_update(ctx: Configuration):
    """Home Assistant supervisor update."""
    response = _handle_raw(ctx, 'supervisor/info')
    data = response['data']
    current_version = int(data['version'])
    latest_version = int(data['version_latest'])
    if current_version == latest_version:
        ctx.echo("Already running the latest release")
    else:
        try:
            _handle(ctx, 'supervisor/update', 'post')
        except (HomeAssistantCliError, HTTPError):
            pass
Esempio n. 15
0
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
        )
    )
Esempio n. 16
0
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
        )
    )
Esempio n. 17
0
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)
Esempio n. 18
0
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,
        ))
Esempio n. 19
0
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))
Esempio n. 20
0
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))
Esempio n. 21
0
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 cli(ctx: Configuration, template, datafile, local: bool) -> None:
    """Render templates on server or locally.

    TEMPLATE - jinja2 template file
    DATAFILE - yaml file with variables to pass to rendering
    """
    variables = {}  # type: Dict[str, Any]
    if datafile:
        variables = ctx.yamlload(datafile)

    templatestr = template.read()

    _LOGGING.debug("Rendering: %s Variables: %s", templatestr, variables)

    if local:
        output = render(template.name, variables, True)
    else:
        output = api.render_template(ctx, templatestr, variables)

    ctx.echo(output)
Esempio n. 23
0
def cli(ctx: Configuration, template, datafile, local: bool) -> None:
    """Render templates on server or locally.

    TEMPLATE - jinja2 template file
    DATAFILE - yaml file with variables to pass to rendering
    """
    variables = {}  # type: Dict[str, Any]
    if datafile:
        variables = yaml.load(datafile)

    templatestr = template.read()

    _LOGGING.debug("Rendering: %s Variables: %s", templatestr, variables)

    if local:
        output = render(template.name, variables, True)
    else:
        output = api.render_template(ctx, templatestr, variables)

    ctx.echo(output)
Esempio n. 24
0
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))
Esempio n. 25
0
def fire(ctx: Configuration, event, json):
    """Fire event in Home Assistant."""
    if json:
        click.echo("Fire {}".format(event))
        response = api.fire_event(ctx, event, json)
    else:
        existing = raw_format_output(ctx.output, [{}], ctx.yaml())
        new = click.edit(existing, extension='.{}'.format(ctx.output))

        if new:
            click.echo("Fire {}".format(event))
            if ctx.output == 'yaml':
                data = ctx.yamlload(new)
            else:
                data = json_.loads(new)

            response = api.fire_event(ctx, event, data)
        else:
            click.echo("No edits/changes.")
            return

    if response:
        ctx.echo(raw_format_output(ctx.output, [response], ctx.yaml()))
Esempio n. 26
0
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
        )
    )
Esempio n. 27
0
def fire(ctx: Configuration, event, json):
    """Fire event in Home Assistant."""
    if json:
        click.echo("Fire {}".format(event))
        response = api.fire_event(ctx, event, json)
    else:
        existing = raw_format_output(ctx.output, {})  # type: ignore
        new = click.edit(existing, extension='.{}'.format(ctx.output))

        if new:
            click.echo("Fire {}".format(event))
            if ctx.output == 'yaml':
                data = yaml.load(new)
            else:
                data = json_.loads(new)

            response = api.fire_event(ctx, event, data)
        else:
            click.echo("No edits/changes.")
            return

    if response:
        ctx.echo(raw_format_output(ctx.output, response))  # type: ignore
Esempio n. 28
0
def cli(ctx: Configuration, service: str, entity: str) -> None:
    """Show the location of the config or an entity on a map."""
    latitude = None
    longitude = None

    if entity:
        thing = entity
        data = api.get_state(ctx, entity)
        if data:
            attr = data.get('attributes', {})
            latitude = attr.get('latitude')
            longitude = attr.get('longitude')
            thing = attr.get('friendly_name', entity)
    else:
        thing = "configuration"
        response = api.get_config(ctx)
        if response:
            latitude = response.get('latitude')
            longitude = response.get('longitude')
            thing = response.get('location_name', thing)

    if latitude and longitude:
        urlpattern = SERVICE.get(service)
        import urllib.parse

        if urlpattern:
            url = urlpattern.format(latitude, longitude,
                                    urllib.parse.quote_plus(thing))
            ctx.echo("{} location is at {}, {}".format(thing, latitude,
                                                       longitude))
            webbrowser.open_new_tab(url)
        else:
            ctx.echo(
                "Could not find url pattern for service {}".format(service))
    else:
        ctx.echo("No exact location info found in {}".format(thing))
        sys.exit(2)
Esempio n. 29
0
def assign(
    ctx: Configuration,
    area_id_or_name,
    names: List[str],
    match: Optional[str] = None,
):
    """Update area on one or more devices.

    NAMES - one or more name or id (Optional)
    """
    ctx.auto_output("data")

    devices = api.get_devices(ctx)

    result = []  # type: List[Dict]

    area = api.find_area(ctx, area_id_or_name)
    if not area:
        _LOGGING.error(
            "Could not find area with id or name: %s", area_id_or_name
        )
        sys.exit(1)

    if match:
        if match == ".*":
            result = devices
        else:
            devicefilterre = re.compile(match)  # type: Pattern

            for device in devices:
                if devicefilterre.search(device['name']):
                    result.append(device)

    for id_or_name in names:
        device = next(  # type: ignore
            (x for x in devices if x['id'] == id_or_name), None
        )
        if not device:
            device = next(  # type: ignore
                (x for x in devices if x['name'] == id_or_name), None
            )
        if not device:
            _LOGGING.error(
                "Could not find device with id or name: %s", id_or_name
            )
            sys.exit(1)
        result.append(device)

    for device in result:
        output = api.assign_area(ctx, device['id'], area['area_id'])
        if output['success']:
            ctx.echo(
                "Successfully assigned '{}' to '{}'".format(
                    area['name'], device['name']
                )
            )
        else:
            _LOGGING.error(
                "Failed to assign '%s' to '%s'", area['name'], device['name']
            )

            ctx.echo(str(output))
Esempio n. 30
0
def edit(ctx: Configuration, entity, newstate, attributes, merge, json):
    """Edit entity state from Home Assistant."""
    ctx.auto_output('data')
    if json:
        _LOGGING.debug(
            "json found overriding/creating new state for entity %s", entity
        )
        wanted_state = json_.loads(json)
    elif newstate or attributes:
        wanted_state = {}
        existing_state = api.get_state(ctx, entity)

        if existing_state:
            ctx.echo("Existing state found for %s", entity)
            if merge:
                wanted_state = existing_state
        else:
            ctx.echo("No existing state found for '%s'", entity)

        if attributes:
            attributes_dict = helper.to_attributes(attributes)

            newattr = wanted_state.get('attributes', {})
            newattr.update(attributes_dict)
            # this is not hornoring merge!
            wanted_state['attributes'] = newattr

        if newstate:
            wanted_state['state'] = newstate
        else:
            if not existing_state:
                raise ValueError("No new or existing state provided.")
            wanted_state['state'] = existing_state['state']

    else:
        existing = api.get_state(ctx, entity)
        if existing:
            existingraw = helper.raw_format_output(
                ctx.output, [existing], ctx.yaml()
            )[0]
        else:
            existingraw = helper.raw_format_output(
                ctx.output, [{}], ctx.yaml()
            )[0]

        new = click.edit(existingraw, extension='.{}'.format(ctx.output))

        if new is not None:
            ctx.echo("Updating '%s'", entity)
            if ctx.output == 'yaml':
                wanted_state = ctx.yamlload(new)
            if ctx.output == 'json':
                wanted_state = json_.loads(new)

            api.set_state(ctx, entity, wanted_state)
        else:
            ctx.echo("No edits/changes returned from editor.")
            return

    _LOGGING.debug("wanted: %s", str(wanted_state))
    result = api.set_state(ctx, entity, wanted_state)
    ctx.echo("Entity %s updated succesfully", entity)
    _LOGGING.debug("Updated to: %s", result)