Esempio n. 1
0
 async def async_step_user(self, user_input=None):
     errors = {}
     if user_input is not None:
         if user_input.get(CONF_HOST):
             self.host = user_input[CONF_HOST]
         token = user_input.get(CONF_TOKEN)
         device = MiioDevice(self.host, token)
         try:
             info = device.info()
         except DeviceException:
             info = None
             errors['base'] = 'cannot_connect'
         _LOGGER.debug('Xiaomi Miot async_step_user %s', {
             'user_input': user_input,
             'info': info,
             'errors': errors,
         })
         if info is not None:
             unique_id = format_mac(info.mac_address)
             await self.async_set_unique_id(unique_id)
             self._abort_if_unique_id_configured()
             if not user_input.get(CONF_MODEL):
                 user_input[CONF_MODEL] = str(info.model or '')
             user_input['miio_info'] = dict(info.raw or {})
             return self.async_create_entry(
                 title=user_input.get(CONF_NAME),
                 data=user_input,
             )
     return self.async_show_form(
         step_id='user',
         data_schema=MIIO_CONFIG_SCHEMA,
         errors=errors,
     )
async def check_miio_device(hass, user_input, errors):
    host = user_input.get(CONF_HOST)
    token = user_input.get(CONF_TOKEN)
    try:
        device = MiioDevice(host, token)
        info = await hass.async_add_executor_job(device.info)
    except DeviceException:
        info = None
        errors['base'] = 'cannot_connect'
    _LOGGER.debug('Miio Yeelink config flow: %s', {
        'user_input': user_input,
        'miio_info': info,
        'errors': errors,
    })
    if info is not None:
        if not user_input.get(CONF_MODEL):
            user_input[CONF_MODEL] = str(info.model or '')
        user_input['miio_info'] = dict(info.raw or {})
    return user_input
Esempio n. 3
0
async def check_miio_device(hass, user_input, errors):
    host = user_input.get(CONF_HOST)
    token = user_input.get(CONF_TOKEN)
    try:
        device = MiioDevice(host, token)
        info = await hass.async_add_executor_job(device.info)
    except DeviceException:
        info = None
        errors['base'] = 'cannot_connect'
    _LOGGER.debug('Xiaomi Miot config flow: %s', {
        'user_input': user_input,
        'miio_info': info,
        'errors': errors,
    })
    if info is not None:
        if not user_input.get(CONF_MODEL):
            user_input[CONF_MODEL] = str(info.model or '')
        user_input['miio_info'] = dict(info.raw or {})
        miot_type = await MiotSpec.async_get_model_type(hass, user_input.get(CONF_MODEL))
        user_input['miot_type'] = miot_type
        user_input['unique_did'] = format_mac(info.mac_address)
    return user_input
Esempio n. 4
0
async def check_miio_device(hass, user_input, errors):
    host = user_input.get(CONF_HOST)
    token = user_input.get(CONF_TOKEN)
    try:
        device = MiioDevice(host, token)
        info = await hass.async_add_executor_job(device.info)
    except DeviceException:
        device = None
        info = None
        errors['base'] = 'cannot_connect'
    _LOGGER.debug('Xiaomi Miot config flow: %s', {
        'user_input': user_input,
        'miio_info': info,
        'errors': errors,
    })
    model = ''
    if info is not None:
        if not user_input.get(CONF_MODEL):
            model = str(info.model or '')
            user_input[CONF_MODEL] = model
        user_input['miio_info'] = dict(info.raw or {})
        miot_type = await MiotSpec.async_get_model_type(hass, model)
        if not miot_type:
            miot_type = await MiotSpec.async_get_model_type(hass,
                                                            model,
                                                            use_remote=True)
        user_input['miot_type'] = miot_type
        user_input['unique_did'] = format_mac(info.mac_address)
        if miot_type and device:
            try:
                pms = [
                    {
                        'did': 'miot',
                        'siid': 2,
                        'piid': 1
                    },
                    {
                        'did': 'miot',
                        'siid': 2,
                        'piid': 2
                    },
                    {
                        'did': 'miot',
                        'siid': 3,
                        'piid': 1
                    },
                ]
                results = device.get_properties(
                    pms, property_getter='get_properties') or []
                for prop in results:
                    if not isinstance(prop, dict):
                        continue
                    if prop.get('code') == 0:
                        # Collect supported models in LAN
                        await async_analytics_track_event(
                            hass,
                            'miot',
                            'local',
                            model,
                            firmware=info.firmware_version,
                            results=results,
                        )
                        break
            except DeviceException:
                pass
    return user_input
Esempio n. 5
0
    async def async_step_localinfo(self, user_input=None):  # 2. 手动接入,本地通信信息
        """Handle a flow initialized by the user."""
        errors = {}

        # Check if already configured
        # await self.async_set_unique_id(DOMAIN)
        # self._abort_if_unique_id_configured()

        if user_input is not None:

            self._name = user_input[CONF_NAME]
            self._host = user_input[CONF_HOST]
            if user_input[CONF_TOKEN] == '0':
                user_input[CONF_TOKEN] = '0' * 32
            self._token = user_input[CONF_TOKEN]
            self._input2 = {**self._input2, **user_input}

            device = MiioDevice(self._host, self._token)
            try:
                self._info = device.info()
            except DeviceException:
                errors['base'] = 'cannot_connect'
            # except ValueError:
            #     errors['base'] = 'value_error'

            if self._info is not None:
                unique_id = format_mac(self._info.mac_address)
                # await self.async_set_unique_id(unique_id)
                for entry in self._async_current_entries():
                    if entry.unique_id == unique_id:
                        persistent_notification.async_create(
                            self.hass, f"您新添加的设备: **{self._name}** ,\n"
                            f"其 MAC 地址与现有的某个设备相同。\n"
                            f"只是通知,不会造成任何影响。", "设备可能重复")
                        break

                self._abort_if_unique_id_configured()
                d = self._info.raw
                self._model = d['model']
                device_info = (f"Model: {d['model']}\n"
                               f"Firmware: {d['fw_ver']}\n"
                               f"MAC: {d['mac']}\n")

                self._info = await guess_mp_from_model(self.hass, self._model)

                if self._info and self._info.get('mapping') != "{}":
                    device_info += "\n已经自动发现配置参数。\n如无特殊需要,无需修改下列内容。\n"
                    devtype_default = self._info.get('device_type')

                    mp = self._info.get('mapping')
                    prm = self._info.get('params')
                    mapping_default = mp
                    params_default = prm
                else:
                    device_info += f"很抱歉,未能自动发现配置参数。但这不代表您的设备不受支持。\n您可以[手工编写配置](https://github.com/ha0y/xiaomi_miot_raw/#文件配置法),或者将型号 **{self._model}** 报告给作者。"
                    devtype_default = ['switch']
                    mapping_default = '{"switch":{"switch_status":{"siid":2,"piid":1}}}'
                    params_default = '{"switch":{"switch_status":{"power_on":true,"power_off":false}}}'

                if not self._non_interactive:
                    return self.async_show_form(
                        step_id="devinfo",
                        data_schema=vol.Schema(
                            {
                                vol.Required('devtype',
                                             default=devtype_default):
                                cv.multi_select(SUPPORTED_DOMAINS),
                                vol.Required(CONF_MAPPING,
                                             default=mapping_default):
                                str,
                                vol.Required(CONF_CONTROL_PARAMS,
                                             default=params_default):
                                str,
                                vol.Optional('cloud_read'):
                                bool,
                                vol.Optional('cloud_write'):
                                bool,
                            }),
                        description_placeholders={"device_info": device_info},
                        errors=errors,
                    )
                else:
                    return await self.async_step_devinfo({
                        'devtype': devtype_default,
                        CONF_MAPPING: mapping_default,
                        CONF_CONTROL_PARAMS: params_default,
                        'cloud_read': True,
                        'cloud_write': True,
                    })
            else:
                return await self.async_step_xiaoai(
                    {CONF_MODEL: self._model} if self._model else None)

        return self.async_show_form(
            step_id="localinfo",
            data_schema=vol.Schema({
                vol.Required(CONF_NAME):
                str,
                vol.Required(CONF_HOST, default='192.168.'):
                str,
                vol.Required(CONF_TOKEN):
                str,
            }),
            # description_placeholders={"device_info": "device_info"},
            errors=errors,
        )
    async def async_step_user(self, user_input=None):
        """Handle a flow initialized by the user."""
        errors = {}

        # Check if already configured
        # await self.async_set_unique_id(DOMAIN)
        # self._abort_if_unique_id_configured()

        if user_input is not None:

            self._name = user_input[CONF_NAME]
            self._host = user_input[CONF_HOST]
            self._token = user_input[CONF_TOKEN]
            # self._mapping = user_input[CONF_MAPPING]
            # self._params = user_input[CONF_CONTROL_PARAMS]

            device = MiioDevice(self._host, self._token)
            try:
                self._info = device.info()
            except DeviceException:
                # print("DeviceException!!!!!!")
                errors['base'] = 'cannot_connect'
            # except ValueError:
            #     errors['base'] = 'value_error'

            if self._info is not None:
                unique_id = format_mac(self._info.mac_address)
                # await self.async_set_unique_id(unique_id)
                for entry in self._async_current_entries():
                    if entry.unique_id == unique_id:
                        persistent_notification.async_create(
                            self.hass, f"您新添加的设备: **{self._name}** ,\n"
                            f"其 MAC 地址与现有的某个设备相同。\n"
                            f"只是通知,不会造成任何影响。", "设备可能重复")
                        break

                self._abort_if_unique_id_configured()
                d = self._info.raw
                self._model = d['model']
                device_info = (f"Model: {d['model']}\n"
                               f"Firmware: {d['fw_ver']}\n"
                               f"MAC: {d['mac']}\n")

                # self._info = self.get_devconfg_by_model(self._model)

                self._info = await async_get_mp_from_net(self.hass, self._model) \
                    or await guess_mp_from_model(self.hass, self._model)

                if self._info:
                    device_info += "\n已经自动发现配置参数。\n如无特殊需要,无需修改下列内容。\n"
                    devtype_default = self._info.get('device_type')
                    mapping_default = self._info.get('mapping')
                    params_default = self._info.get('params')
                else:
                    device_info += "请手动进行配置。\n"
                    devtype_default = ''
                    mapping_default = '{"switch_status":{"siid":2,"piid":1}}'
                    params_default = '{"switch_status":{"power_on":true,"power_off":false}}'

                self._input2 = user_input
                return self.async_show_form(
                    step_id="devinfo",
                    data_schema=vol.Schema({
                        vol.Required('devtype', default=devtype_default):
                        vol.In(SUPPORTED_DOMAINS),
                        vol.Required(CONF_MAPPING, default=mapping_default):
                        str,
                        vol.Required(CONF_CONTROL_PARAMS,
                                     default=params_default):
                        str,
                        vol.Optional('cloud_read'):
                        bool,
                        vol.Optional('cloud_write'):
                        bool,
                    }),
                    description_placeholders={"device_info": device_info},
                    errors=errors,
                )

        return self.async_show_form(
            step_id="user",
            data_schema=vol.Schema({
                vol.Required(CONF_NAME):
                str,
                vol.Required(CONF_HOST, default='192.168.'):
                str,
                vol.Required(CONF_TOKEN):
                str,
                # vol.Required(CONF_MAPPING, default='{"switch_status":{"siid":2,"piid":1}}'): str,
                # vol.Required(CONF_CONTROL_PARAMS, default='{"switch_status":{"power_on":true,"power_off":false}}'): str,
            }),
            # description_placeholders={"device_info": "device_info"},
            errors=errors,
        )