homeassistant 升级导致xiaomi_miot_raw插件一直报错“小米账号登录信息失效”问题

2023-05-03 更新

自动更新的代码已经提交到项目github的pull request了,见 请求api返回小米账号登录信息失效时,自动重新登陆

=============================================================================
好像在集成里更新小米账号密码成功以后,新的api token,没有同步更新到每个设备,可以手工改配置更新
配置文件在
/usr/share/hassio/homeassistant/.storage/core.config_entries
这个是ha给插件提供的统一配置存储,里面有xiaomi_miot_raw插件的配置,很容易找到有中文的名称。其中有账号密码,还有api使用的user_id,ssecurity,service_token,然后每个设备下面的update_from_cloud段也有这三个,要将设备下面的user_id,ssecurity,service_token改成与账号密码下面一致。重启即可。
注意账号密码下面叫service_token,设备下面的叫serviceToken,不要直接全贴过来替换。替换后面的值。

      {
        "entry_id": "",
        "version": 1,
        "domain": "xiaomi_miot_raw",
        "title": "138******11",
        "data": {
          "action": "xiaomi_account",
          "username": "******",
          "password": "******",
          "server_location": "cn",
          "user_id": ******,
          "ssecurity": "******",
          "service_token": "******"
        },
      {
        "entry_id": "e6a2bac3cad5396dc3282e4c122585e2",
        "version": 1,
        "domain": "xiaomi_miot_raw",
        "title": "植物监测仪",
        "data": {
          "ett_id_migrated": true,
          "name": "植物监测仪",
          "cloud_write": true,
          "update_from_cloud": {
            "did": "blt.3.18m276lqke400",
            "userId": ******,
            "serviceToken": "******",
            "ssecurity": "******",
            "server_location": "cn"
          },

      },

为啥没有同步到设备,有能力的同学可以看源码
好像是两个路径,设备初始化读取配置在basic_dev_class
https://github.com/ha0y/xiaomi_miot_raw/blob/d1b70a6b49f74b6cb57f1c89b4a0325fbda937b0/custom_components/xiaomi_miot_raw/basic_dev_class.py
云api的调用,以及密码更新在
https://github.com/ha0y/xiaomi_miot_raw/blob/08a27578c3adf67c3a6d1dfe8c34fb0d1d7e5a04/custom_components/xiaomi_miot_raw/deps/xiaomi_cloud_new.py

这里面还有两个timeout=5 ,五秒超时,如果调用api总报错,可以尝试改大一点。

改源码,在界面更新小米账号密码时,同步更新设备的token

/usr/share/hassio/homeassistant/custom_components/xiaomi_miot_raw/config_flow.py

    async def async_step_update_xiaomi_account(self, user_input=None, error=None, hint=""): # 登录小米账号
        if user_input:
            user_input['username'] = self._all_config.get('username')
            if 'username' in user_input:
                session = aiohttp_client.async_create_clientsession(self.hass)
                cloud = MiCloud(session)
                resp = await cloud.login(user_input['username'],
                                    user_input['password'])
                if resp == (0, None):
                    self._all_config.update(user_input)
                    self._all_config.update(cloud.auth)

                    #让新 token 实时生效
                    for item in self.hass.data[DOMAIN]['cloud_instance_list']:
                      mc = item['cloud_instance']
                      mc.login_by_credientals(
                        cloud.auth["user_id"],
                        cloud.auth['service_token'],
                        cloud.auth['ssecurity']
                      )

                    if self.hass.config_entries.async_entries(DOMAIN):  #更新每个设备的token
                      _LOGGER.info("Found existing config entries")
                      for entry in self.hass.config_entries.async_entries(DOMAIN):
                        if (
                          entry.data.get("update_from_cloud")
                        ):
                          _LOGGER.info("Updating existing entry")
                          update_from_cloud=entry.data.get("update_from_cloud")
                          update_from_cloud_new={
                             "did": update_from_cloud["did"],
                             "userId": update_from_cloud["userId"],
                             "serviceToken": cloud.auth['service_token'],
                             "ssecurity": cloud.auth['ssecurity'],
                             "server_location": update_from_cloud["server_location"]
                          }
                          entry_data_new=dict(entry.data)
                          entry_data_new.update({"update_from_cloud":update_from_cloud_new})
                          entry_id = entry.entry_id
                          self.hass.data[DOMAIN]['configs'][entry_id] = entry_data_new
                          self.hass.config_entries.async_update_entry(  #保存新token到文件
                            entry,
                            data=entry_data_new,
                         )

                    self._steps.pop(0)
                    return await self._steps[0]

python dict.update 报错 mappingproxy python object has no attribute 'update' copy

解决的方法是创建一个新的dict对象,再update
entry_data_new=dict(entry.data)

Python类的dict无法更新
https://fingerchou.com/2018/05/17/python-class-dict-cannot-update/

Python数据类型之“集合(Sets)与映射(Mapping)”
https://www.cnblogs.com/yyds/p/6123917.html

Why is a class dict a mappingproxy?
https://stackoverflow.com/questions/32720492/why-is-a-class-dict-a-mappingproxy

创建一个home assistant组件的基本步骤

Checklist for creating a component
https://developers.home-assistant.io/docs/creating_component_code_review

3.您可以利用 hass.data[DOMAIN] 与您的平台共享数据。

创建组件的完整文档
https://developers.home-assistant.io/docs/creating_component_index/

其他参考

Homeassistant智能家居实战篇
https://www.hachina.io/

20230503

https://developers.home-assistant.io/docs/config_entries_config_flow_handler
https://developers.home-assistant.io/docs/config_entries_options_flow_handler?_highlight=async_step_init#flow-handler
https://www.hachina.io/26.%E5%A6%82%E4%BD%95%E5%BC%80%E5%8F%91%E9%9B%86%E6%88%90(Integration)/%E5%9C%A8%E5%89%8D%E7%AB%AF%E6%B7%BB%E5%8A%A0%E9%9B%86%E6%88%90/
基于涂鸦 Home Assistant 插件开发智能设备驱动教程
https://developer.tuya.com/cn/demo/devhomeassistantplugin

© 2022 - 2023, 新之助meow. 原创文章转载请注明: 转载自http://www.xinmeow.com

0.00 avg. rating (0% score) - 0 votes
点赞