예제 #1
0
파일: api.py 프로젝트: natabat/hassiq
    def post(self, request, domain, service):
        """Call a service.

        Returns a list of changed states.
        """
        hass = request.app['hass']
        body = yield from request.text()
        data = json.loads(body) if body else None
        json_response = []

        restrict = request.query.get('restrict')

        with AsyncTrackStates(hass) as changed_states:
            yield from hass.services.async_call(domain, service, data, True)

        if restrict:
            restrict = restrict.split(',')
            for entity in changed_states:
                if restrict and entity.domain not in restrict and entity.entity_id not in restrict:
                    continue

                json_response.append(entity)
        else:
            json_response = changed_states

        return self.json(json_response)
예제 #2
0
    async def _controlDevice(self, action, payload):
        applianceDic = payload['appliance']
        entity_id = decrypt_device_id(applianceDic['applianceId'])
        domain = entity_id[:entity_id.find('.')]
        data = {"entity_id": entity_id}
        if domain in self._TRANSLATIONS.keys():
            translation = self._TRANSLATIONS[domain][action]
            if callable(translation):
                domain, service, content = translation(
                    self._hass.states.get(entity_id), payload)
                data.update(content)
            else:
                service = translation
        else:
            service = self._getControlService(action)

        _LOGGER.debug('_controlDevice():service:%s.%s, service_data:%s',
                      domain, service, data)
        with AsyncTrackStates(self._hass) as changed_states:
            result = await self._hass.services.async_call(
                domain, service, data, True, CONTEXT_AIHOME)

        if result:
            state = self._hass.states.get(entity_id)
            properties, actions = self._guessPropertyAndAction(
                entity_id, state.attributes, state.state)
            return {'attributes': [properties]}
        else:
            return self._errorResult('IOT_DEVICE_OFFLINE')
예제 #3
0
    async def _controlDevice(self, cmnd, payload):
        entity_id = decrypt_device_id(payload['deviceId'])
        domain = entity_id[:entity_id.find('.')]
        data = {"entity_id": entity_id}
        domain_list = [domain]
        data_list = [data]
        service_list = ['']
        if domain in self._TRANSLATIONS.keys():
            translation = self._TRANSLATIONS[domain][cmnd]
            if callable(translation):
                domain_list, service_list, data_list = translation(
                    self._hass.states.get(entity_id), payload)
                _LOGGER.debug('domain_list: %s', domain_list)
                _LOGGER.debug('service_list: %s', service_list)
                _LOGGER.debug('data_list: %s', data_list)
                for i, d in enumerate(data_list):
                    if 'entity_id' not in d and domain_list[
                            i] not in DOMAIN_SERVICE_WITHOUT_ENTITY_ID:
                        d.update(data)
            else:
                service_list[0] = translation
        else:
            service_list[0] = self._getControlService(cmnd)

        for i in range(len(domain_list)):
            _LOGGER.debug('domain: %s, servcie: %s, data: %s', domain_list[i],
                          service_list[i], data_list[i])
            with AsyncTrackStates(self._hass) as changed_states:
                result = await self._hass.services.async_call(
                    domain_list[i], service_list[i], data_list[i], True)
            if not result:
                return self._errorResult('IOT_DEVICE_OFFLINE')

        return {}
예제 #4
0
async def controlDevice(name, payload):
    entity_id = payload['deviceId']
    service = getControlService(name)
    domain = entity_id[:entity_id.find('.')]
    data = {"entity_id": entity_id }
    if domain == 'cover':
        service = 'close_cover' if service == 'turn_off' else 'open_cover'

    with AsyncTrackStates(_hass) as changed_states:
        result = await _hass.services.async_call(domain, service, data, True)

    return {} if result else errorResult('IOT_DEVICE_OFFLINE')
예제 #5
0
    def post(self, request, domain, service):
        """Call a service.

        Returns a list of changed states.
        """
        body = yield from request.text()
        data = json.loads(body) if body else None

        with AsyncTrackStates(self.hass) as changed_states:
            yield from self.hass.services.async_call(domain, service, data,
                                                     True)

        return self.json(changed_states)
예제 #6
0
async def handleState(entity_id, state, action):
    cover = entity_id.startswith('cover') or entity_id == 'group.all_covers'
    domain = 'cover' if cover else 'homeassistant'
    #domain = entity_id[:entity_id.find('.')]
    if action == '打开':
        service = 'open_cover' if cover else 'turn_on'
    elif action == '关闭':
        service = 'close_cover' if cover else 'turn_off'
    else:
        return '为' + (STATE_NAMES[state] if state in STATE_NAMES else state)

    data = {'entity_id': entity_id}
    with AsyncTrackStates(_hass) as changed_states:
        result = await _hass.services.async_call(domain, service, data, True)

    return action + ("成功" if result else "不成功")
예제 #7
0
파일: api.py 프로젝트: zzhmy/home-assistant
    def post(self, request, domain, service):
        """Call a service.

        Returns a list of changed states.
        """
        hass = request.app['hass']
        body = yield from request.text()
        try:
            data = json.loads(body) if body else None
        except ValueError:
            return self.json_message('Data should be valid JSON',
                                     HTTP_BAD_REQUEST)

        with AsyncTrackStates(hass) as changed_states:
            yield from hass.services.async_call(domain, service, data, True)

        return self.json(changed_states)
예제 #8
0
async def controlDevice(action, payload):
    entity_id = payload['deviceId']
    domain = entity_id[:entity_id.find('.')]
    data = {"entity_id": entity_id }
    if domain in TRANSLATIONS.keys():
        translation = TRANSLATIONS[domain][action]
        if callable(translation):
            service, content = translation(_hass.states.get(entity_id), payload)
            data.update(content)
        else:
            service = translation
    else:
        service = getControlService(action)

    with AsyncTrackStates(_hass) as changed_states:
        result = await _hass.services.async_call(domain, service, data, True)

    return {} if result else errorResult('IOT_DEVICE_OFFLINE')
예제 #9
0
파일: helper.py 프로젝트: telemansoft/havcs
    async def process_control_command(self, command) -> tuple:
        device_id = self._prase_command(command, 'device_id')
        entity_id = self._decrypt_device_id(device_id)
        if entity_id is None:
            return self._errorResult('DEVICE_IS_NOT_EXIST'), None
        action = self._prase_command(command, 'action')
        domain = entity_id[:entity_id.find('.')]
        data = {"entity_id": entity_id}
        domain_list = [domain]
        data_list = [data]
        service_list = ['']
        if domain in self._service_map_p2h.keys():
            translation = self._service_map_p2h[domain][action]
            if callable(translation):
                attributes = self._hass.data[INTEGRATION]['devices'].get(
                    entity_id)
                state = self._hass.states.get(entity_id)
                domain_list, service_list, data_list = translation(
                    state, attributes, self._prase_command(command, 'payload'))
                _LOGGER.debug('domain_list: %s', domain_list)
                _LOGGER.debug('service_list: %s', service_list)
                _LOGGER.debug('data_list: %s', data_list)
                for i, d in enumerate(data_list):
                    if 'entity_id' not in d and domain_list[
                            i] not in DOMAIN_SERVICE_WITHOUT_ENTITY_ID:
                        d.update(data)
            else:
                service_list[0] = translation
        else:
            service_list[0] = self._prase_action_p2h(action)

        for i in range(len(domain_list)):
            _LOGGER.debug('domain: %s, servcie: %s, data: %s', domain_list[i],
                          service_list[i], data_list[i])
            with AsyncTrackStates(self._hass) as changed_states:
                result = await self._hass.services.async_call(
                    domain_list[i], service_list[i], data_list[i], True)
                _LOGGER.debug('changed_states: %s', changed_states)
            if not result:
                return self._errorResult('IOT_DEVICE_OFFLINE'), None
        device_properties = self.vcdm.get(entity_id).get('properties')
        properties = self._control_process_propertites(device_properties,
                                                       action)
        return None, properties
예제 #10
0
    async def _controlDevice(self, cmnd, payload):
        entity_id = decrypt_device_id(payload['deviceId'])
        domain = entity_id[:entity_id.find('.')]
        data = {"entity_id": entity_id }
        if domain in self._TRANSLATIONS.keys():
            translation = self._TRANSLATIONS[domain][cmnd]
            if callable(translation):
                domain, service, content = translation(self._hass.states.get(entity_id), payload)
                data.update(content)
            else:
                service = translation
        else:
            service = self._getControlService(cmnd)

        _LOGGER.info(self._hass.states.get(entity_id).attributes)
        with AsyncTrackStates(self._hass) as changed_states:
            result = await self._hass.services.async_call(domain, service, data, True)

        return {"result": "SUCCESS"} if result else self._errorResult('IOT_DEVICE_OFFLINE')
예제 #11
0
    async def post(self, request, domain, service):
        """Call a service.

        Returns a list of changed states.
        """
        hass = request.app['hass']
        body = await request.text()
        try:
            data = json.loads(body) if body else None
        except ValueError:
            return self.json_message("Data should be valid JSON.",
                                     HTTP_BAD_REQUEST)

        with AsyncTrackStates(hass) as changed_states:
            try:
                await hass.services.async_call(domain, service, data, True,
                                               self.context(request))
            except (vol.Invalid, ServiceNotFound):
                raise HTTPBadRequest()

        return self.json(changed_states)
예제 #12
0
async def zhiState(hass, entity_id, state, query):
    domain = entity_id[:entity_id.find('.')]
    is_cover = domain == 'cover'  # or entity_id == 'group.all_covers'
    can_action = not domain in [
        'sensor', 'binary_sensor', 'device_tracker', 'person']
    if can_action and '开' in query:
        service = 'open_cover' if is_cover else 'turn_on'
        action = '打开'
    elif can_action and '关' in query:
        service = 'close_cover' if is_cover else 'turn_off'
        action = '关闭'
    elif domain == 'automation':  # and not '查' in query
        service = 'trigger'
        action = '触发'
    else:
        return '为' + (STATE_NAMES[state] if state in STATE_NAMES else state)

    data = {'entity_id': entity_id}
    with AsyncTrackStates(hass) as changed_states:
        result = await hass.services.async_call(domain, service, data, True)

    return action + ("成功" if result else "不成功")
예제 #13
0
async def hassService(domain, service, data):
    if _hass:
        with AsyncTrackStates(_hass) as changed_states:
            return await _hass.services.async_call(domain, service, data, True)

    return hassRest('services/' + domain + '/' + service, data)
예제 #14
0
    async def process_control_command(self, command) -> tuple:
        device_id = self._prase_command(command, 'device_id')
        device_id = self._decrypt_device_id(device_id)
        device = self.vcdm.get(device_id)
        if device_id is None or device is None:
            return self._errorResult('DEVICE_IS_NOT_EXIST'), None
        entity_ids = device.entity_id
        action = self._prase_command(command, 'action')
        _LOGGER.debug(
            "[%s] control target info: device_id = %s, name = %s , entity_ids = %s, action = %s",
            LOGGER_NAME, device.device_id, device.name, entity_ids, action)

        success_task = []

        # 优先使用配置的自定义action,处理逻辑:直接调用自定义service方法
        ha_action = self._prase_action_p2h(action)
        if device.custom_actions.get(ha_action):
            domain_list = [
                cmnd[0] for cmnd in device.custom_actions[ha_action]
            ]
            service_list = [
                cmnd[1] for cmnd in device.custom_actions[ha_action]
            ]
            data_list = [
                eval(cmnd[2]) for cmnd in device.custom_actions[ha_action]
            ]
            _LOGGER.debug("[%s] prepared domain_list: %s", LOGGER_NAME,
                          domain_list)
            _LOGGER.debug("[%s] prepared service_list: %s", LOGGER_NAME,
                          service_list)
            _LOGGER.debug("[%s] prepared data_list: %s", LOGGER_NAME,
                          data_list)
            for i in range(len(domain_list)):
                _LOGGER.debug("[%s] %s : domain = %s, servcie = %s, data = %s",
                              LOGGER_NAME, i, domain_list[i], service_list[i],
                              data_list[i])
                with AsyncTrackStates(self._hass) as changed_states:
                    try:
                        result = await self._hass.services.async_call(
                            domain_list[i], service_list[i], data_list[i],
                            True)
                    except (vol.Invalid, ServiceNotFound):
                        _LOGGER.error("[%s] %s : failed to call service\n%s",
                                      LOGGER_NAME, i, traceback.format_exc())
                    else:
                        if result:
                            _LOGGER.debug("[%s] %s : success to call service",
                                          LOGGER_NAME, i)
                            success_task.append({
                                i: [
                                    domain_list[i], service_list[i],
                                    data_list[i]
                                ]
                            })
                        else:
                            _LOGGER.debug("[%s] %s : failed to call service",
                                          LOGGER_NAME, i)
                _LOGGER.debug("[%s] %s : changed_states = %s", LOGGER_NAME, i,
                              changed_states)
        # 自动处理action,处理逻辑:对device的所有entity,执行action对应的service方法
        else:
            for entity_id in entity_ids:
                domain = entity_id[:entity_id.find('.')]
                data = {"entity_id": entity_id}
                domain_list = [domain]
                data_list = [data]
                service_list = ['']

                if action in self._service_map_p2h.get(domain, []):
                    translation = self._service_map_p2h[domain][action]
                    if callable(translation):
                        state = self._hass.states.get(entity_id)
                        domain_list, service_list, data_list = translation(
                            state, device.raw_attributes,
                            self._prase_command(command, 'payload'))
                        _LOGGER.debug("[%s] prepared domain_list: %s",
                                      LOGGER_NAME, domain_list)
                        _LOGGER.debug("[%s] prepared service_list: %s",
                                      LOGGER_NAME, service_list)
                        _LOGGER.debug("[%s] prepared data_list: %s",
                                      LOGGER_NAME, data_list)
                        for i, d in enumerate(data_list):
                            if 'entity_id' not in d and (
                                    domain_list[i]
                                    in DOMAIN_SERVICE_WITH_ENTITY_ID or
                                (domain_list[i]
                                 not in DOMAIN_SERVICE_WITHOUT_ENTITY_ID and
                                 entity_id.startswith(domain_list[i] + '.'))):
                                d.update(data)
                    else:
                        service_list[0] = translation
                else:
                    service_list[0] = self._prase_action_p2h(action)

                _LOGGER.debug("[%s] ---excute tasks of %s: start", LOGGER_NAME,
                              entity_id)
                for i in range(len(domain_list)):
                    _LOGGER.debug(
                        "[%s] %s @task_%s: domain = %s, servcie = %s, data = %s",
                        LOGGER_NAME, entity_id, i, domain_list[i],
                        service_list[i], data_list[i])
                    with AsyncTrackStates(self._hass) as changed_states:
                        try:
                            result = await self._hass.services.async_call(
                                domain_list[i], service_list[i], data_list[i],
                                True)
                        except (vol.Invalid, ServiceNotFound):
                            _LOGGER.error(
                                "[%s] %s @task_%s: failed to call service\n%s",
                                LOGGER_NAME, entity_id, i,
                                traceback.format_exc())
                        else:
                            if result:
                                _LOGGER.debug(
                                    "[%s] %s @task_%s: success to call service, new state = %s",
                                    LOGGER_NAME, entity_id, i,
                                    self._hass.states.get(entity_id))
                                success_task.append({
                                    entity_id: [
                                        domain_list[i], service_list[i],
                                        data_list[i]
                                    ]
                                })
                            else:
                                _LOGGER.debug(
                                    "[%s] %s @task_%s: failed to call service",
                                    LOGGER_NAME, entity_id, i)
                    _LOGGER.debug("[%s] %s @task_%s: changed_states = %s",
                                  LOGGER_NAME, entity_id, i, changed_states)
                _LOGGER.debug("[%s] ---excute tasks of %s: end", LOGGER_NAME,
                              entity_id)
        if not success_task:
            _LOGGER.debug(
                "[%s] fail to control device, return 'IOT_DEVICE_OFFLINE' message.",
                LOGGER_NAME)
            return self._errorResult('IOT_DEVICE_OFFLINE'), None
        # wait 1s for updating state of entity
        await asyncio.sleep(1)
        device_properties = self.vcdm.get(device_id).properties
        properties = self._control_process_propertites(device_properties,
                                                       action)
        return None, properties
예제 #15
0
    async def process_control_command(self, command) -> tuple:
        device_id = self._prase_command(command, 'device_id')
        device_id = self._decrypt_device_id(device_id)
        device = self.vcdm.get(device_id)
        if device_id is None or device is None:
            return self._errorResult('DEVICE_IS_NOT_EXIST'), None
        entity_ids = device.entity_id
        action = self._prase_command(command, 'action')
        success_task = []
        for entity_id in entity_ids:
            domain = entity_id[:entity_id.find('.')]
            data = {"entity_id": entity_id}
            domain_list = [domain]
            data_list = [data]
            service_list = ['']

            if domain in self._service_map_p2h.keys():
                translation = self._service_map_p2h[domain][action]
                if callable(translation):
                    state = self._hass.states.get(entity_id)
                    domain_list, service_list, data_list = translation(
                        state, device.raw_attributes,
                        self._prase_command(command, 'payload'))
                    _LOGGER.debug("[%s] domain_list: %s", LOGGER_NAME,
                                  domain_list)
                    _LOGGER.debug("[%s] service_list: %s", LOGGER_NAME,
                                  service_list)
                    _LOGGER.debug("[%s] data_list: %s", LOGGER_NAME, data_list)
                    for i, d in enumerate(data_list):
                        if 'entity_id' not in d and domain_list[
                                i] not in DOMAIN_SERVICE_WITHOUT_ENTITY_ID and entity_id.startswith(
                                    domain_list[i] + '.'):
                            d.update(data)
                else:
                    service_list[0] = translation
            else:
                service_list[0] = self._prase_action_p2h(action)

            for i in range(len(domain_list)):
                _LOGGER.debug(
                    "[%s] %s @task_%s: domain = %s, servcie = %s, data = %s",
                    LOGGER_NAME, entity_id, i, domain_list[i], service_list[i],
                    data_list[i])
                with AsyncTrackStates(self._hass) as changed_states:
                    try:
                        result = await self._hass.services.async_call(
                            domain_list[i], service_list[i], data_list[i],
                            True)
                    except (vol.Invalid, ServiceNotFound):
                        _LOGGER.error(
                            "[%s] %s @task_%s: failed to call service\n%s",
                            LOGGER_NAME, entity_id, i, traceback.format_exc())
                    else:
                        if result:
                            _LOGGER.debug(
                                "[%s] %s @task_%s: success to call service, new state = %s",
                                LOGGER_NAME, entity_id, i,
                                self._hass.states.get(entity_id))
                            success_task.append({
                                entity_id: [
                                    domain_list[i], service_list[i],
                                    data_list[i]
                                ]
                            })
                        else:
                            _LOGGER.debug(
                                "[%s] %s @task_%s: failed to call service",
                                LOGGER_NAME, entity_id, i)
                _LOGGER.debug("[%s] %s @task_%s: changed_states = %s",
                              LOGGER_NAME, entity_id, i, changed_states)
        if not success_task:
            return self._errorResult('IOT_DEVICE_OFFLINE'), None
        # wait 1s for updating state of entity
        await asyncio.sleep(1)
        device_properties = self.vcdm.get(device_id).properties
        properties = self._control_process_propertites(device_properties,
                                                       action)
        return None, properties