コード例 #1
0
ファイル: climate.py プロジェクト: luoban/xiaomi_miot_raw
async def async_setup_platform(hass,
                               config,
                               async_add_devices,
                               discovery_info=None):
    """Set up the sensor from config."""

    if DATA_KEY not in hass.data:
        hass.data[DATA_KEY] = {}

    host = config.get(CONF_HOST)
    token = config.get(CONF_TOKEN)
    mapping = config.get(CONF_MAPPING)
    params = config.get(CONF_CONTROL_PARAMS)

    mappingnew = {}

    main_mi_type = None
    this_mi_type = []

    for t in MAP[TYPE]:
        if mapping.get(t):
            this_mi_type.append(t)
        if 'main' in (params.get(t) or ""):
            main_mi_type = t

    if main_mi_type or type(params) == OrderedDict:
        for k, v in mapping.items():
            for kk, vv in v.items():
                mappingnew[f"{k[:10]}_{kk}"] = vv

        _LOGGER.info("Initializing %s with host %s (token %s...)",
                     config.get(CONF_NAME), host, token[:5])
        if type(params) == OrderedDict:
            miio_device = MiotDevice(ip=host, token=token, mapping=mapping)
        else:
            miio_device = MiotDevice(ip=host, token=token, mapping=mappingnew)
        try:
            if host == DUMMY_IP and token == DUMMY_TOKEN:
                raise DeviceException
            device_info = miio_device.info()
            model = device_info.model
            _LOGGER.info(
                "%s %s %s detected",
                model,
                device_info.firmware_version,
                device_info.hardware_version,
            )

        except DeviceException as de:
            if not config.get(CONF_CLOUD):
                _LOGGER.warn(de)
                raise PlatformNotReady
            else:
                if not (di := config.get('cloud_device_info')):
                    _LOGGER.error(
                        f"未能获取到设备信息,请删除 {config.get(CONF_NAME)} 重新配置。")
                    raise PlatformNotReady
                else:
                    device_info = dev_info(di['model'], di['mac'],
                                           di['fw_version'], "")
コード例 #2
0
ファイル: humidifier.py プロジェクト: zjmhlxp/xiaomi_miot_raw
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
    """Set up the sensor from config."""

    if DATA_KEY not in hass.data:
        hass.data[DATA_KEY] = {}

    host = config.get(CONF_HOST)
    token = config.get(CONF_TOKEN)
    mapping = config.get(CONF_MAPPING)

    _LOGGER.info("Initializing %s with host %s (token %s...)",
                 config.get(CONF_NAME), host, token[:5])

    try:
        # miio_device = Device(host, token)
        miio_device = MiotDevice(ip=host, token=token, mapping=mapping)

        device_info = miio_device.info()
        model = device_info.model
        _LOGGER.info(
            "%s %s %s detected",
            model,
            device_info.firmware_version,
            device_info.hardware_version,
        )

        device = MiotHumidifier(miio_device, config, device_info, hass)
    except DeviceException:
        raise PlatformNotReady

    hass.data[DATA_KEY][host] = device
    async_add_devices([device], update_before_add=True)
コード例 #3
0
ファイル: cover.py プロジェクト: xllxll/xiaomi_miot_raw
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
    """Set up the sensor from config."""

    if DATA_KEY not in hass.data:
        hass.data[DATA_KEY] = {}

    host = config.get(CONF_HOST)
    token = config.get(CONF_TOKEN)
    mapping = config.get(CONF_MAPPING)
    params = config.get(CONF_CONTROL_PARAMS)

    mappingnew = {}

    main_mi_type = None
    this_mi_type = []

    for t in MAP[TYPE]:
        if params.get(t):
            this_mi_type.append(t)
        if 'main' in (params.get(t) or ""):
            main_mi_type = t

    if main_mi_type or type(params) == OrderedDict:
        for k, v in mapping.items():
            for kk, vv in v.items():
                mappingnew[f"{k[:10]}_{kk}"] = vv

        _LOGGER.info("Initializing %s with host %s (token %s...)",
                     config.get(CONF_NAME), host, token[:5])

        try:
            if type(params) == OrderedDict:
                miio_device = MiotDevice(ip=host, token=token, mapping=mapping)
            else:
                miio_device = MiotDevice(ip=host,
                                         token=token,
                                         mapping=mappingnew)
            device_info = miio_device.info()
            model = device_info.model
            _LOGGER.info(
                "%s %s %s detected",
                model,
                device_info.firmware_version,
                device_info.hardware_version,
            )

            device = MiotCover(miio_device, config, device_info, hass,
                               main_mi_type)
        except DeviceException as de:
            _LOGGER.warn(de)
            raise PlatformNotReady

        _LOGGER.info(f"{main_mi_type} is the main device of {host}.")
        hass.data[DOMAIN]['miot_main_entity'][host] = device
        hass.data[DOMAIN]['entities'][device.unique_id] = device
        async_add_devices([device], update_before_add=True)
    else:
        _LOGGER.error(f"cover只能作为主设备!请检查{config.get(CONF_NAME)}配置")
コード例 #4
0
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
    """Set up the fan from config."""

    if DATA_KEY not in hass.data:
        hass.data[DATA_KEY] = {}

    host = config.get(CONF_HOST)
    token = config.get(CONF_TOKEN)
    mapping = config.get(CONF_MAPPING)
    params = config.get(CONF_CONTROL_PARAMS)

    mappingnew = {}

    main_mi_type = None
    this_mi_type = []

    for t in MAP[TYPE]:
        if params.get(t):
            this_mi_type.append(t)
        if 'main' in (params.get(t) or ""):
            main_mi_type = t

    if main_mi_type or type(params) == OrderedDict:
        for k, v in mapping.items():
            for kk, vv in v.items():
                mappingnew[f"{k[:10]}_{kk}"] = vv

        _LOGGER.info("Initializing %s with host %s (token %s...)",
                     config.get(CONF_NAME), host, token[:5])

        try:
            if type(params) == OrderedDict:
                miio_device = MiotDevice(ip=host, token=token, mapping=mapping)
            else:
                miio_device = MiotDevice(ip=host,
                                         token=token,
                                         mapping=mappingnew)
            device_info = dev_info("aaa", "bbb", "ccc", "ddd")
            device = MiotMediaPlayer(miio_device, config, device_info, hass,
                                     main_mi_type)
        except DeviceException as de:
            _LOGGER.warn(de)
            raise PlatformNotReady

        hass.data[DATA_KEY][host] = device
        async_add_devices([device], update_before_add=True)
    else:
        _LOGGER.error("media player只能作为主设备!")
        pass
コード例 #5
0
    def __init__(self, config):
        name = config[CONF_NAME]
        host = config[CONF_HOST]
        token = config[CONF_TOKEN]
        model = config.get(CONF_MODEL)
        _LOGGER.info('Initializing with host %s (token %s...)', host,
                     token[:5])

        if model in ['yeelink.light.fancl1', 'YLFD02YL']:
            self.mapping.update({
                'scenes': {
                    'siid': 4,
                    'piid': 3
                },
            })

        self._device = MiotDevice(self.mapping, host, token)
        super().__init__(name, self._device)

        self._supported_features = SUPPORT_BRIGHTNESS | SUPPORT_COLOR_TEMP
        self._state_attrs.update({'entity_class': self.__class__.__name__})
        self._brightness = None
        self._color_temp = None
        self._delay_off = None
        self._scenes = LIGHT_SCENES
コード例 #6
0
 def __init__(self, name, host, token, model):
     if model == BABAI_CURTAIN_BB82MJ or model == LUMI_CURTAIN_HAGL05:
         self._action_pause = 0
         self._action_open = 1
         self._action_close = 2
     if model == SYNIOT_CURTAIN_SYC1:
         self._action_open = 0
         self._action_close = 1
         self._action_pause = 2
     else:
         self._action_pause = 1
         self._action_open = 2
         self._action_close = 0
     self._model = model
     self._name = name
     self._current_position = 0
     self._target_position = 0
     self._action = 0
     self.miotDevice = MiotDevice(ip=host,
                                  token=token,
                                  mapping=MIOT_MAPPING[self._model])
     _LOGGER.info("Init miot device: {}, {}".format(self._name,
                                                    self.miotDevice))
コード例 #7
0
 def __init__(self, name, host, token, model):
     self._name = name
     self._current_position = 0
     self._target_position = 0
     self._action = 0
     if model:
         self._model = model
         self._mapping = MIOT_MAPPING[model]
     else:
         self._mapping = {
             ATTR_MOTOR_CONTROL: {"siid": 0, "piid": 0},
             ATTR_CURRENT_POSITION: {"siid": 0, "piid": 0},
             ATTR_TARGET_POSITION: {"siid": 0, "piid": 0},
             ATTR_PAUSE: 0,
             ATTR_OPEN: 0,
             ATTR_CLOSE: 0,
         }
     # init device
     self.miotDevice = MiotDevice(ip=host, token=token)
     _LOGGER.info("Init miot device: {}, {}".format(self._name, self.miotDevice))
     # if model not config get model from miot device info
     if not model:
         self._model = self.miotDevice.info().model
         self._mapping = get_mapping(self._model, self._mapping)
コード例 #8
0
ファイル: sensor.py プロジェクト: zjmhlxp/xiaomi_miot_raw
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
    """Set up the sensor from config."""
    if DATA_KEY not in hass.data:
        hass.data[DATA_KEY] = {}

    host = config.get(CONF_HOST)
    token = config.get(CONF_TOKEN)
    mapping = config.get(CONF_MAPPING)

    _LOGGER.info("Initializing %s with host %s (token %s...)", config.get(CONF_NAME), host, token[:5])


    try:
        miio_device = MiotDevice(ip=host, token=token, mapping=mapping)
        device_info = miio_device.info()
        model = device_info.model
        _LOGGER.info(
            "%s %s %s detected",
            model,
            device_info.firmware_version,
            device_info.hardware_version,
        )

        device = MiotSensor(miio_device, config, device_info)
        devices = [device]
        # for item in config['mapping']:
        #     devices.append(MiotSubSensor(device, item))
    except DeviceException as de:
        _LOGGER.warn(de)

        raise PlatformNotReady


    hass.data[DATA_KEY][host] = device
    # async_add_devices([device], update_before_add=True)
    async_add_devices(devices, update_before_add=True)
コード例 #9
0
    def __init__(self, config):
        name = config[CONF_NAME]
        host = config[CONF_HOST]
        token = config[CONF_TOKEN]
        model = config.get(CONF_MODEL)
        _LOGGER.info('Initializing with host %s (token %s...)', host,
                     token[:5])

        if model in ['yeelink.light.fancl2', 'YLFD001']:
            # http://miot-spec.org/miot-spec-v2/instance?type=urn:miot-spec-v2:device:light:0000A001:yeelink-fancl2:1
            self.mapping.update({
                'dalayoff': {
                    'siid': 3,
                    'piid': 11
                },
            })

        self._device = MiotDevice(self.mapping, host, token)
        super().__init__(name, self._device)
        self._unique_id = f'{self._miio_info.model}-{self._miio_info.mac_address}-fan'
        self._supported_features = SUPPORT_SET_SPEED
        self._state_attrs.update({'entity_class': self.__class__.__name__})
コード例 #10
0
ファイル: sensor.py プロジェクト: iChenlife/xiaomi_miot_raw
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
    """Set up the sensor from config."""
    if DATA_KEY not in hass.data:
        hass.data[DATA_KEY] = {}

    host = config.get(CONF_HOST)
    token = config.get(CONF_TOKEN)
    mapping = config.get(CONF_MAPPING)
    params = config.get(CONF_CONTROL_PARAMS)
    if params is None: params = OrderedDict()

    mappingnew = {}

    main_mi_type = None
    other_mi_type = []

    #sensor的添加逻辑和其他实体不一样。他会把每个属性都作为实体。其他设备会作为attr

    for t in MAP[TYPE]:
        if params.get(t):
            other_mi_type.append(t)
        if 'main' in (params.get(t) or ""):
            main_mi_type = t

    try:
        other_mi_type.remove(main_mi_type)
    except:
        pass

    if main_mi_type or type(params) == OrderedDict:
        for k,v in mapping.items():
            for kk,vv in v.items():
                mappingnew[f"{k[:10]}_{kk}"] = vv

        _LOGGER.info("Initializing %s with host %s (token %s...)", config.get(CONF_NAME), host, token[:5])


        try:
            if type(params) == OrderedDict:
                miio_device = MiotDevice(ip=host, token=token, mapping=mapping)
            else:
                miio_device = MiotDevice(ip=host, token=token, mapping=mappingnew)
            device_info = miio_device.info()
            model = device_info.model
            _LOGGER.info(
                "%s %s %s detected",
                model,
                device_info.firmware_version,
                device_info.hardware_version,
            )

            device = MiotSensor(miio_device, config, device_info, hass, main_mi_type)
            devices = [device]
            # for item in config['mapping']:
            #     devices.append(MiotSubSensor(device, item))
        except DeviceException as de:
            _LOGGER.warn(de)

            raise PlatformNotReady

        _LOGGER.info(f"{main_mi_type} is the main device of {host}.")
        hass.data[DOMAIN]['miot_main_entity'][host] = device
        hass.data[DOMAIN]['entities'][device.unique_id] = device
        async_add_devices(devices, update_before_add=True)
    if other_mi_type:

        parent_device = None
        try:
            parent_device = hass.data[DOMAIN]['miot_main_entity'][host]
        except KeyError:
            _LOGGER.warning(f"{host} 的主设备尚未就绪,子设备 {TYPE} 等待主设备加载完毕后才会加载")
            raise PlatformNotReady

        # _LOGGER.error( parent_device.device_state_attributes)

        for k,v in mapping.items():
            if k in MAP[TYPE]:
                for kk,vv in v.items():
                    mappingnew[f"{k[:10]}_{kk}"] = vv

        devices = []
        for k in mappingnew.keys():
            devices.append(MiotSubSensor(parent_device, mappingnew, params, other_mi_type[0],{'sensor_property': k}))

        # device = MiotSubSensor(parent_device, "switch_switch_status")
        async_add_devices(devices, update_before_add=True)
コード例 #11
0
async def async_setup_platform(hass,
                               config,
                               async_add_devices,
                               discovery_info=None):
    """Set up the fan from config."""

    if DATA_KEY not in hass.data:
        hass.data[DATA_KEY] = {}

    host = config.get(CONF_HOST)
    token = config.get(CONF_TOKEN)
    mapping = config.get(CONF_MAPPING)
    params = config.get(CONF_CONTROL_PARAMS)

    mappingnew = {}

    main_mi_type = None
    other_mi_type = []

    for t in MAP[TYPE]:
        if mapping.get(t):
            other_mi_type.append(t)
        if 'main' in (params.get(t) or ""):
            main_mi_type = t

    try:
        other_mi_type.remove(main_mi_type)
    except:
        pass

    if main_mi_type or type(params) == OrderedDict:
        for k, v in mapping.items():
            for kk, vv in v.items():
                mappingnew[f"{k[:10]}_{kk}"] = vv

        _LOGGER.info("Initializing %s with host %s (token %s...)",
                     config.get(CONF_NAME), host, token[:5])
        if type(params) == OrderedDict:
            miio_device = MiotDevice(ip=host, token=token, mapping=mapping)
        else:
            miio_device = MiotDevice(ip=host, token=token, mapping=mappingnew)
        try:
            if host == DUMMY_IP and token == DUMMY_TOKEN:
                raise DeviceException
            device_info = miio_device.info()
            model = device_info.model
            _LOGGER.info(
                "%s %s %s detected",
                model,
                device_info.firmware_version,
                device_info.hardware_version,
            )

        except DeviceException as de:
            if not config.get(CONF_CLOUD):
                _LOGGER.warn(de)
                raise PlatformNotReady
            else:
                try:
                    devinfo = await get_dev_info(hass,
                                                 config.get(CONF_CLOUD)['did'])
                    device_info = dev_info(devinfo['result'][1]['value'],
                                           token,
                                           devinfo['result'][3]['value'], "")
                except Exception as ex:
                    _LOGGER.error(
                        f"Failed to get device info for {config.get(CONF_NAME)}"
                    )
                    device_info = dev_info(host, token, "", "")
        device = MiotFan(miio_device, config, device_info, hass, main_mi_type)

        _LOGGER.info(f"{main_mi_type} is the main device of {host}.")
        hass.data[DOMAIN]['miot_main_entity'][host] = device
        hass.data[DOMAIN]['entities'][device.unique_id] = device
        async_add_devices([device], update_before_add=True)
    if other_mi_type:
        retry_time = 1
        while True:
            if parent_device := hass.data[DOMAIN]['miot_main_entity'].get(
                    host):
                break
            else:
                retry_time *= 2
                if retry_time > 120:
                    _LOGGER.error(
                        f"The main device of {config.get(CONF_NAME)}({host}) is still not ready after 120 seconds!"
                    )
                    raise PlatformNotReady
                else:
                    _LOGGER.debug(
                        f"The main device of {config.get(CONF_NAME)}({host}) is still not ready after {retry_time - 1} seconds."
                    )
                    await asyncio.sleep(retry_time)

        for k, v in mapping.items():
            if k in MAP[TYPE]:
                for kk, vv in v.items():
                    mappingnew[f"{k[:10]}_{kk}"] = vv

        devices = []

        for item in other_mi_type:
            if item == 'a_l':
                devices.append(
                    MiotActionList(parent_device, mapping.get(item), item))
            else:
                devices.append(
                    MiotSubFan(parent_device, mapping.get(item),
                               params.get(item), item))
        async_add_devices(devices, update_before_add=True)
コード例 #12
0
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
    """Set up the fan from config."""

    if DATA_KEY not in hass.data:
        hass.data[DATA_KEY] = {}

    host = config.get(CONF_HOST)
    token = config.get(CONF_TOKEN)
    mapping = config.get(CONF_MAPPING)
    params = config.get(CONF_CONTROL_PARAMS)

    mappingnew = {}

    main_mi_type = None
    other_mi_type = []

    for t in MAP[TYPE]:
        if mapping.get(t):
            other_mi_type.append(t)
        if 'main' in (mapping.get(t) or ""):
            main_mi_type = t

    try:
        other_mi_type.remove(main_mi_type)
    except:
        pass

    if main_mi_type or type(params) == OrderedDict:
        for k, v in mapping.items():
            for kk, vv in v.items():
                mappingnew[f"{k[:10]}_{kk}"] = vv

        _LOGGER.info("Initializing %s with host %s (token %s...)",
                     config.get(CONF_NAME), host, token[:5])

        try:
            if type(params) == OrderedDict:
                miio_device = MiotDevice(ip=host, token=token, mapping=mapping)
            else:
                miio_device = MiotDevice(ip=host,
                                         token=token,
                                         mapping=mappingnew)
            device_info = miio_device.info()
            model = device_info.model
            _LOGGER.info(
                "%s %s %s detected",
                model,
                device_info.firmware_version,
                device_info.hardware_version,
            )

            device = MiotFan(miio_device, config, device_info, hass,
                             main_mi_type)
        except DeviceException as de:
            _LOGGER.warn(de)
            raise PlatformNotReady

        _LOGGER.info(f"{main_mi_type} is the main device of {host}.")
        hass.data[DOMAIN]['miot_main_entity'][host] = device
        hass.data[DOMAIN]['entities'][device.unique_id] = device
        async_add_devices([device], update_before_add=True)
    if other_mi_type:

        parent_device = None
        try:
            parent_device = hass.data[DOMAIN]['miot_main_entity'][host]
        except KeyError:
            _LOGGER.warning(f"{host} 的主设备尚未就绪,子设备 {TYPE} 等待主设备加载完毕后才会加载")
            raise PlatformNotReady

        for k, v in mapping.items():
            if k in MAP[TYPE]:
                for kk, vv in v.items():
                    mappingnew[f"{k[:10]}_{kk}"] = vv

        devices = []

        for item in other_mi_type:
            if item == 'a_l':
                devices.append(
                    MiotActionList(parent_device, mapping.get(item), item))
            else:
                devices.append(
                    MiotSubLight(parent_device, mapping.get(item),
                                 params.get(item), item))
        async_add_devices(devices, update_before_add=True)
コード例 #13
0
    async def async_step_devinfo(self, user_input=None):
        errors = {}
        hint = ""
        if user_input is not None:
            self._devtype = user_input['devtype']
            self._input2['devtype'] = self._devtype
            self._input2[CONF_MAPPING] = user_input[CONF_MAPPING]
            self._input2[CONF_CONTROL_PARAMS] = user_input[CONF_CONTROL_PARAMS]
            # self._input2['cloud_read'] = user_input['cloud_read']
            self._input2['cloud_write'] = user_input.get('cloud_write')

            # v = await validate_devinfo(self.hass, self._input2)
            v = [[], []]
            if v == [[], []]:

                try:
                    # print(result)
                    if not user_input.get('cloud_read') and not user_input.get(
                            'cloud_write'):
                        device = MiotDevice(
                            ip=self._input2[CONF_HOST],
                            token=self._input2[CONF_TOKEN],
                            mapping=list(
                                json.loads(
                                    self._input2[CONF_MAPPING]).values())[0])
                        result = device.get_properties_for_mapping()
                        return self.async_create_entry(
                            title=self._input2[CONF_NAME],
                            data=self._input2,
                        )
                    else:
                        if cloud := self.hass.data[DOMAIN].get(
                                'cloud_instance'):
                            did = None
                            for dev in self.hass.data[DOMAIN][
                                    'micloud_devices']:
                                if dev.get(
                                        'localip') == self._input2[CONF_HOST]:
                                    did = dev['did']
                            if did:
                                self._input2['update_from_cloud'] = {
                                    'did': did,
                                    'userId': cloud.auth['user_id'],
                                    'serviceToken':
                                    cloud.auth['service_token'],
                                    'ssecurity': cloud.auth['ssecurity'],
                                }
                                return self.async_create_entry(
                                    title=self._input2[CONF_NAME],
                                    data=self._input2,
                                )
                            else:
                                return self.async_show_form(
                                    step_id="cloudinfo",
                                    data_schema=vol.Schema({
                                        vol.Required('did'):
                                        str,
                                        vol.Required('userId',
                                                     default=cloud.auth['user_id']):
                                        str,
                                        vol.Required('serviceToken',
                                                     default=cloud.auth['service_token']):
                                        str,
                                        vol.Required('ssecurity',
                                                     default=cloud.auth['ssecurity']):
                                        str,
                                    }),
                                    description_placeholders={
                                        "device_info": "没找到 did,请手动填一下"
                                    },
                                    errors=errors,
                                )
                        else:
                            return self.async_show_form(
                                step_id="cloudinfo",
                                data_schema=vol.Schema({
                                    vol.Required('did'):
                                    str,
                                    vol.Required('userId'):
                                    str,
                                    vol.Required('serviceToken'):
                                    str,
                                    vol.Required('ssecurity'):
                                    str,
                                }),
                                # description_placeholders={"device_info": hint},
                                errors=errors,
                            )
コード例 #14
0
async def async_setup_platform(hass,
                               config,
                               async_add_devices,
                               discovery_info=None):
    """Set up the fan from config."""

    if DATA_KEY not in hass.data:
        hass.data[DATA_KEY] = {}

    host = config.get(CONF_HOST)
    token = config.get(CONF_TOKEN)
    mapping = config.get(CONF_MAPPING)
    params = config.get(CONF_CONTROL_PARAMS)

    mappingnew = {}

    main_mi_type = None
    other_mi_type = []

    for t in MAP[TYPE]:
        if mapping.get(t):
            other_mi_type.append(t)
        if 'main' in (params.get(t) or ""):
            main_mi_type = t

    try:
        other_mi_type.remove(main_mi_type)
    except:
        pass

    if main_mi_type or type(params) == OrderedDict:
        for k, v in mapping.items():
            for kk, vv in v.items():
                mappingnew[f"{k[:10]}_{kk}"] = vv

        if 'a_l' not in mapping.keys():
            persistent_notification.async_create(
                hass, f"为了支持更多种类小爱,配置参数有变动,\n"
                f"请删除您的 **{config.get(CONF_NAME)}** 重新配置。谢谢\n", "Xiaomi MIoT")

        _LOGGER.info("Initializing %s with host %s (token %s...)",
                     config.get(CONF_NAME), host, token[:5])

        try:
            if type(params) == OrderedDict:
                miio_device = MiotDevice(ip=host, token=token, mapping=mapping)
            else:
                miio_device = MiotDevice(ip=host,
                                         token=token,
                                         mapping=mappingnew)
            device_info = dev_info(host, token, "", "")
            device = MiotMediaPlayer(miio_device, config, device_info, hass,
                                     main_mi_type)
        except DeviceException as de:
            _LOGGER.warn(de)
            raise PlatformNotReady

        _LOGGER.info(f"{main_mi_type} is the main device of {host}.")
        hass.data[DOMAIN]['miot_main_entity'][host] = device
        hass.data[DOMAIN]['entities'][device.unique_id] = device
        async_add_devices([device], update_before_add=True)

        @asyncio.coroutine
        def async_service_handler(service):
            """Map services to methods on XiaomiMiioDevice."""
            method = SERVICE_TO_METHOD.get(service.service)
            params = {
                key: value
                for key, value in service.data.items() if key != ATTR_ENTITY_ID
            }
            entity_ids = service.data.get(ATTR_ENTITY_ID)
            if entity_ids:
                devices = [
                    device
                    for device in hass.data[DOMAIN]['entities'].values()
                    if device.entity_id in entity_ids
                ]
            else:
                # devices = hass.data[DOMAIN]['entities'].values()
                _LOGGER.error("No entity_id specified.")

            update_tasks = []
            for device in devices:
                yield from getattr(device, method["method"])(**params)
                update_tasks.append(device.async_update_ha_state(True))

            if update_tasks:
                yield from asyncio.wait(update_tasks, loop=hass.loop)

        for service in SERVICE_TO_METHOD:
            schema = SERVICE_TO_METHOD[service].get("schema", SERVICE_SCHEMA)
            hass.services.async_register(DOMAIN,
                                         service,
                                         async_service_handler,
                                         schema=schema)

    else:
        _LOGGER.error("media player只能作为主设备!")
        pass
コード例 #15
0
class MijiaCurtain(CoverEntity):
    def __init__(self, name, host, token, model):
        self._name = name
        self._current_position = 0
        self._target_position = 0
        self._action = 0
        if model:
            self._model = model
            self._mapping = MIOT_MAPPING[model]
        else:
            self._mapping = {
                ATTR_MOTOR_CONTROL: {"siid": 0, "piid": 0},
                ATTR_CURRENT_POSITION: {"siid": 0, "piid": 0},
                ATTR_TARGET_POSITION: {"siid": 0, "piid": 0},
                ATTR_PAUSE: 0,
                ATTR_OPEN: 0,
                ATTR_CLOSE: 0,
            }
        # init device
        self.miotDevice = MiotDevice(ip=host, token=token)
        _LOGGER.info("Init miot device: {}, {}".format(self._name, self.miotDevice))
        # if model not config get model from miot device info
        if not model:
            self._model = self.miotDevice.info().model
            self._mapping = get_mapping(self._model, self._mapping)

    @property
    def supported_features(self):
        return SUPPORT_OPEN | SUPPORT_CLOSE | SUPPORT_STOP | SUPPORT_SET_POSITION

    @property
    def name(self):
        return self._name

    @property
    def device_class(self) -> Optional[str]:
        return DEVICE_CLASS_CURTAIN

    @property
    def state(self):
        if self.is_opening:
            return STATE_OPENING
        if self.is_closing:
            return STATE_CLOSING
        closed = self.is_closed
        if closed is None:
            return None
        return STATE_CLOSED if closed else STATE_OPEN

    @property
    def state_attributes(self):
        data = {
            'current_position': self._current_position,
            'target_position': self._target_position,
            CONF_MODEL: self._model,
        }
        return data

    def update(self):
        self.update_current_position()
        self.update_target_position()
        self.update_action()
        _LOGGER.debug('update_state {} data: {}'.format(self._name, self.state_attributes))

    def update_current_position(self):
        position = self.get_property(ATTR_CURRENT_POSITION)
        if position is None:
            return
        if 0 < position < 5:
            position = 0
        if 95 < position < 100:
            position = 100
        self._current_position = position

    def update_target_position(self):
        self._target_position = self.get_property(ATTR_TARGET_POSITION)

    def update_action(self):
        if ATTR_LUMI in self._model:
            self._action = self.get_property(ATTR_STATUS)
        else:
            self._action = self.get_property(ATTR_MOTOR_CONTROL)

    @property
    def is_opening(self):
        if ATTR_LUMI in self._model:
            return self._action == self._mapping[ATTR_OPENING]
        else:
            return self._action == self._mapping[ATTR_OPEN]

    @property
    def is_closing(self):
        if ATTR_LUMI in self._model:
            return self._action == self._mapping[ATTR_CLOSING]
        else:
            return self._action == self._mapping[ATTR_CLOSE]

    @property
    def is_closed(self):
        return self._current_position == 0

    @property
    def is_opened(self):
        return self._current_position == 100

    @property
    def current_cover_position(self):
        return self._current_position

    def open_cover(self, **kwargs) -> None:
        self.set_property(ATTR_MOTOR_CONTROL, self._mapping[ATTR_OPEN])

    def close_cover(self, **kwargs):
        self.set_property(ATTR_MOTOR_CONTROL, self._mapping[ATTR_CLOSE])

    def toggle(self, **kwargs) -> None:
        if self.is_closed:
            self.open_cover(**kwargs)
        else:
            self.close_cover(**kwargs)

    def stop_cover(self, **kwargs):
        self.set_property(ATTR_MOTOR_CONTROL, self._mapping[ATTR_PAUSE])

    def set_cover_position(self, **kwargs):
        self.set_property(ATTR_TARGET_POSITION, kwargs['position'])

    def set_property(self, property_key, value):
        siid = self._mapping[property_key]['siid']
        piid = self._mapping[property_key]['piid']
        self.miotDevice.set_property_by(siid, piid, value)

    def get_property(self, property_key):
        value = None
        try:
            siid = self._mapping[property_key]['siid']
            piid = self._mapping[property_key]['piid']
            results = self.miotDevice.get_property_by(siid, piid)
            for result in results:
                if result["code"] == 0 and result["siid"] == siid and  result['piid'] == piid:
                    value = result["value"]
        except Exception:
            _LOGGER.error("Get property {} exception".format(property_key), exc_info=True)
        _LOGGER.debug("{}, {} is: {}".format(self._name, property_key, value))
        return value
コード例 #16
0
    async def async_step_devinfo(self, user_input=None):
        errors = {}
        hint = ""
        if user_input is not None:
            self._devtype = user_input['devtype']
            self._input2['devtype'] = self._devtype
            self._input2[CONF_MAPPING] = user_input[CONF_MAPPING]
            self._input2[CONF_CONTROL_PARAMS] = user_input[CONF_CONTROL_PARAMS]
            # self._input2['cloud_read'] = user_input['cloud_read']
            self._input2['cloud_write'] = user_input.get('cloud_write')

            v = await validate_devinfo(self.hass, self._input2)
            if v == [[], []]:

                try:
                    # print(result)
                    if not user_input.get('cloud_read') and not user_input.get(
                            'cloud_write'):
                        device = MiotDevice(ip=self._input2[CONF_HOST],
                                            token=self._input2[CONF_TOKEN],
                                            mapping=json.loads(
                                                self._input2[CONF_MAPPING]))
                        result = device.get_properties_for_mapping()
                        return self.async_create_entry(
                            title=self._input2[CONF_NAME],
                            data=self._input2,
                        )
                    else:
                        return self.async_show_form(
                            step_id="cloudinfo",
                            data_schema=vol.Schema({
                                vol.Required('did'):
                                str,
                                vol.Required('userId'):
                                str,
                                vol.Required('serviceToken'):
                                str,
                                vol.Required('ssecurity'):
                                str,
                            }),
                            # description_placeholders={"device_info": hint},
                            errors=errors,
                        )
                except DeviceException as ex:
                    errors["base"] = "no_local_access"
                    hint = f"错误信息: {ex}"
                except Exception as exe:
                    hint = f"错误信息: {exe}"
            else:
                errors["base"] = "bad_params"

                hint = ""
                if v[0]:
                    hint += "\nmapping 缺少必须配置的项目:"
                    for item in v[0]:
                        hint += (item + ', ')
                if v[1]:
                    hint += "\nparams 缺少必须配置的项目:"
                    for item in v[1]:
                        hint += (item + ', ')

            # if info:
        return self.async_show_form(
            step_id="devinfo",
            data_schema=vol.Schema({
                vol.Required('devtype', default=user_input['devtype']):
                vol.In(SUPPORTED_DOMAINS),
                vol.Required(CONF_MAPPING, default=user_input[CONF_MAPPING]):
                str,
                vol.Required(CONF_CONTROL_PARAMS,
                             default=user_input[CONF_CONTROL_PARAMS]):
                str,
                vol.Optional('cloud_read'):
                bool,
                vol.Optional('cloud_write'):
                bool,
            }),
            description_placeholders={"device_info": hint},
            errors=errors,
        )
コード例 #17
0
#!/usr/bin/env python3

from miio.miot_device import MiotDevice

device = MiotDevice(
{
    'power': {'siid': 2, 'piid': 1}, 
    'power2': {'siid': 5, 'piid': 10}, 
    'power3': {'siid': 2, 'piid': 3}, 
    'power4': {'siid': 2, 'piid': 4}, 
    'power5': {'siid': 2, 'piid': 5}, 
    'power6': {'siid': 2, 'piid': 6}, 
    'power7': {'siid': 2, 'piid': 7}, 
    'power8': {'siid': 2, 'piid': 8}, 
    'power9': {'siid': 2, 'piid': 10}, 
    'powerA': {'siid': 2, 'piid': 11}, 
    'powerB': {'siid': 5, 'piid': 2}, 
    'powerC': {'siid': 6, 'piid': 1}, 
    'powerD': {'siid': 5, 'piid': 4}, 
    'powerE': {'siid': 5, 'piid': 5},
}, '192.168.1.28', '6dd1ec1c895a61d1b994b4a6242efe56')

print('%s' % device.get_properties_for_mapping())
コード例 #18
0
class DooyaCurtain(CoverEntity):
    def __init__(self, name, host, token, model):
        if model == BABAI_CURTAIN_BB82MJ or model == LUMI_CURTAIN_HAGL05:
            self._action_pause = 0
            self._action_open = 1
            self._action_close = 2
        if model == SYNIOT_CURTAIN_SYC1:
            self._action_open = 0
            self._action_close = 1
            self._action_pause = 2
        else:
            self._action_pause = 1
            self._action_open = 2
            self._action_close = 0
        self._model = model
        self._name = name
        self._current_position = 0
        self._target_position = 0
        self._action = 0
        self.miotDevice = MiotDevice(ip=host,
                                     token=token,
                                     mapping=MIOT_MAPPING[self._model])
        _LOGGER.info("Init miot device: {}, {}".format(self._name,
                                                       self.miotDevice))

    @property
    def supported_features(self):
        return SUPPORT_OPEN | SUPPORT_CLOSE | SUPPORT_STOP | SUPPORT_SET_POSITION

    @property
    def name(self):
        return self._name

    @property
    def device_class(self) -> Optional[str]:
        return DEVICE_CLASS_CURTAIN

    @property
    def state(self):
        if self.is_opening:
            return STATE_OPENING
        if self.is_closing:
            return STATE_CLOSING
        closed = self.is_closed
        if closed is None:
            return None
        return STATE_CLOSED if closed else STATE_OPEN

    @property
    def state_attributes(self):
        data = {
            'current_position': self._current_position,
            'target_position': self._target_position,
            'action': self._action,
        }
        return data

    def update(self):
        self.update_current_position()
        self.update_target_position()
        self.update_action()
        _LOGGER.debug('update_state {} data: {}'.format(
            self._name, self.state_attributes))

    def update_current_position(self):
        position = self.get_property('current_position')
        if position is None:
            return
        if position:
            if 95 < position < 100:
                position = 100
            if 0 < position < 5:
                position = 0
            self._current_position = position

    def update_target_position(self):
        self._target_position = self.get_property('target_position')

    def update_action(self):
        self._action = self.get_property('motor_control')

    @property
    def is_opening(self):
        self.update_action()
        return self._action == self._action_open

    @property
    def is_closing(self):
        self.update_action()
        return self._action == self._action_close

    @property
    def is_closed(self):
        self.update_current_position()
        return self._current_position == 0

    @property
    def is_opened(self):
        self.update_current_position()
        return self._current_position == 100

    @property
    def current_cover_position(self):
        self.update_current_position()
        return self._current_position

    def open_cover(self, **kwargs) -> None:
        self.miotDevice.set_property("motor_control", self._action_open)

    def close_cover(self, **kwargs):
        self.miotDevice.set_property("motor_control", self._action_close)

    def toggle(self, **kwargs) -> None:
        if self.is_closed:
            self.open_cover(**kwargs)
        else:
            self.close_cover(**kwargs)

    def stop_cover(self, **kwargs):
        self.miotDevice.set_property("motor_control", self._action_pause)

    def set_cover_position(self, **kwargs):
        self.miotDevice.set_property("target_position", kwargs['position'])

    def get_property(self, property_key):
        properties = [{
            "did": property_key,
            **MIOT_MAPPING[self._model][property_key]
        }]
        value = None
        try:
            results = self.miotDevice.get_properties(
                properties,
                property_getter="get_properties",
                max_properties=15)
            for prop in results:
                if prop["code"] == 0 and prop["did"] == property_key:
                    value = prop["value"]
        except Exception:
            _LOGGER.error("Get property {} exception".format(property_key),
                          exc_info=True)
        _LOGGER.debug("{}, {} is: {}".format(self._name, property_key, value))
        return value
コード例 #19
0
    async def async_step_devinfo(self, user_input=None):
        errors = {}
        hint = ""
        if user_input is not None:
            self._devtype = user_input['devtype']
            self._input2['devtype'] = self._devtype
            self._input2[CONF_MAPPING] = user_input[CONF_MAPPING]
            self._input2[CONF_CONTROL_PARAMS] = user_input[CONF_CONTROL_PARAMS]
            self._input2['cloud_write'] = user_input.get('cloud_write')

            try:
                # print(result)
                if not user_input.get('cloud_read') and not user_input.get(
                        'cloud_write'):
                    device = MiotDevice(
                        ip=self._input2[CONF_HOST],
                        token=self._input2[CONF_TOKEN],
                        mapping=list(
                            json.loads(
                                self._input2[CONF_MAPPING]).values())[0])
                    result = device.get_properties_for_mapping()
                    return self.async_create_entry(
                        title=self._input2[CONF_NAME],
                        data=self._input2,
                    )
                else:
                    for item in self.hass.data[DOMAIN]['cloud_instance_list']:
                        if item['username']:
                            cloud = item['cloud_instance']
                    if cloud:
                        if not self._did:
                            for dev in self.hass.data[DOMAIN][
                                    'micloud_devices']:
                                if dev.get(
                                        'localip') == self._input2[CONF_HOST]:
                                    self._did = dev['did']
                        if self._did:
                            self._input2['update_from_cloud'] = {
                                'did': self._did,
                                'userId': cloud.auth['user_id'],
                                'serviceToken': cloud.auth['service_token'],
                                'ssecurity': cloud.auth['ssecurity'],
                            }
                            if s := cloud.svr:
                                self._input2['update_from_cloud'][
                                    'server_location'] = s
                            if self._cloud_device:
                                self._input2['cloud_device_info'] = {
                                    'name':
                                    self._cloud_device.get('name'),
                                    'mac':
                                    self._cloud_device.get('mac'),
                                    'did':
                                    self._cloud_device.get('did'),
                                    'model':
                                    self._cloud_device.get('model'),
                                    'fw_version':
                                    self._cloud_device['extra'].get(
                                        'fw_version'),
                                }
                            else:
                                # 3rd party device and Manually added device doesn't have one
                                self._input2['cloud_device_info'] = {
                                    'name': self._input2[CONF_NAME],
                                    'mac': "",
                                    'did': self._did,
                                    'model': self._input2[CONF_MODEL],
                                    'fw_version': "",
                                }
                            return self.async_create_entry(
                                title=self._input2[CONF_NAME],
                                data=self._input2,
                            )
                        else:
                            return self.async_show_form(
                                step_id="cloudinfo",
                                data_schema=vol.Schema({
                                    vol.Required('did'):
                                    str,
                                    vol.Required('userId',
                                                 default=cloud.auth['user_id']):
                                    str,
                                    vol.Required('serviceToken',
                                                 default=cloud.auth['service_token']):
                                    str,
                                    vol.Required('ssecurity',
                                                 default=cloud.auth['ssecurity']):
                                    str,
                                }),
                                description_placeholders={
                                    "device_info": "没找到 did,请手动填一下"
                                },
                                errors=errors,
                            )
                    else:
                        return self.async_show_form(
                            step_id="cloudinfo",
                            data_schema=vol.Schema({
                                vol.Required('did'):
                                str,
                                vol.Required('userId'):
                                str,
                                vol.Required('serviceToken'):
                                str,
                                vol.Required('ssecurity'):
                                str,
                            }),
                            # description_placeholders={"device_info": hint},
                            errors=errors,
                        )