def yunmi_login(self): url = 'https://ms.viomi.com.cn//user-web/services/login/withPwd?account=' + self._phone_number + '&pwd=' + hashlib.md5( str(self._password).encode('utf-8')).hexdigest().upper() headers = { 'Accept': 'application/json', 'Accept-Encoding': 'br, gzip, deflate', 'User-Agent': 'WaterPurifier/2.1.6 (iPhone; iOS 12.2; Scale/3.00)' } try: res = requests.get(url, headers=headers) json_str = res.content.decode(encoding='utf-8') res_list = json.loads(json_str) self._refresh_token = res_list['mobBaseRes']['result']['token'] self._usercode = res_list['mobBaseRes']['result']['userBaseInfo'][ 'userCode'] self._userId = str( res_list['mobBaseRes']['result']['userViomiInfo']['userId']) tk_arr = self.yunmi_get_access_token(self._refresh_token, self._client_id) if tk_arr: self._access_token = tk_arr['access_token'] self._member_id = tk_arr['member_id'] ret = { 'refresh_token': self._refresh_token, 'user_id': self._user_id, 'access_token': self._access_token, 'member_id': self._member_id } with open(TOKEN_PATH, 'w') as f: f.write(json.dumps(ret)) return True except Exception as e: _LOGGER.error('login failed:' + e.__context__) return False
async def async_set_operation_mode(self, **kwargs): """Set new target operation mode.""" current_operation = kwargs.get(ATTR_OPERATION_MODE) if current_operation == STATE_APPOINTMENT: self._controller.yunmi_set_poweron() if self._controller.yunmi_set_appoint(8, 18) is True: self._curroperation = current_operation self.schedule_update_ha_state() return True elif current_operation == STATE_DAILYTEMPERATURE: self._controller.yunmi_set_poweron() if self._controller.yunmi_set_mode( HA_STATE_TO_YUNMI[current_operation]) is True: self._curroperation = current_operation self.schedule_update_ha_state() return True elif current_operation == STATE_QUICKBATH: self._controller.yunmi_set_poweron() if self._controller.yunmi_set_mode( HA_STATE_TO_YUNMI[current_operation]) is True: self._curroperation = current_operation self.schedule_update_ha_state() return True elif current_operation == STATE_OFF: if self._controller.yunmi_set_poweroff() is True: self._curroperation = current_operation self.schedule_update_ha_state() return True else: _LOGGER.error("set_operation_mode error") return False
async def async_turn_off(self): if self._controller._detail['washStatus'] == 0: return True elif self._controller._detail['washStatus'] == 1: self._controller.yunmi_set_poweroff() return True else: _LOGGER.error("async_turn_off error") return False
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): _LOGGER.info('setting up yunmi water heater') name = config.get('name') or DEFAULT_NAME phone_number = config.get('phone_number') password = config.get('password') client_id = config.get('client_id') _LOGGER.error( '============= yunmi water heater setup -> name: %s =============', name) yunmi_wh = YunmiWaterHeater(hass, name, phone_number, password, client_id) async_add_entities([yunmi_wh], update_before_add=True)
async def update(self): '''scan interval default to be 30s''' _LOGGER.error("Updating the sensor...") try: if self._access_token_exp_time is not None and int( round(time.time() * 1000)) >= self._access_token_exp_time: self.yunmi_login() if self._access_token is not None: self.yunmi_get_detail() self.yunmi_get_deviceid() else: self.yunmi_login() self.yunmi_get_detail() self.yunmi_get_deviceid() except Exception as e: _LOGGER.error("update fail" + e.__context__)
def yunmi_get_access_token(self, refresh_token, client_id): url = 'https://ms.viomi.com.cn/home/mi/getMiInfoByToken?token=' + refresh_token + '&clientId=' + client_id headers = { 'Accept-Encoding': 'br, gzip, deflate', 'User-Agent': 'WaterPurifier/2.1.6 (iPhone; iOS 12.2; Scale/3.00)' } try: res = requests.get(url, headers=headers) json_str = res.content.decode(encoding='utf-8') res_list = json.loads(json_str) self._access_token_exp_time = int(res_list['result']['expiresIn']) return { 'access_token': res_list['result']['token'], 'member_id': str(res_list['result']['mid']) } except Exception as e: _LOGGER.error('get access token failed:' + e.__context__) return False
def yunmi_get_detail(self): url = 'https://openapp.io.mi.com/openapp/device/rpc/' + str( self._did ) + '?data=%7B%22method%22:%22get_prop%22,%22did%22:%22' + str( self._did ) + '%22,%22id%22:%221%22,%22params%22:%5B%22washStatus%22,%22velocity%22,%22waterTemp%22,%22targetTemp%22,%22errStatus%22,%22hotWater%22,%22needClean%22,%22modeType%22,%22appointStart%22,%22appointEnd%22%5D%7D&clientId=' + self._client_id + '&accessToken=' + self._access_token headers = { 'Accept-Encoding': 'br, gzip, deflate', 'User-Agent': 'WaterPurifier/2.1.6 (iPhone; iOS 12.2; Scale/3.00)' } try: _LOGGER.info('258:' + url) res = requests.get(url, headers=headers) json_str = res.content.decode(encoding='utf-8') _LOGGER.info('260:' + json_str) res_list = json.loads(json_str) if res_list['code'] == 0: self._detail['washStatus'] = res_list['result'][0] self._detail['velocity'] = res_list['result'][1] self._detail['waterTemp'] = res_list['result'][2] self._detail['targetTemp'] = res_list['result'][3] self._detail['errStatus'] = res_list['result'][4] self._detail['hotWater'] = res_list['result'][5] self._detail['needClean'] = res_list['result'][6] self._detail['modeType'] = res_list['result'][7] self._detail['appointStart'] = res_list['result'][8] self._detail['appointEnd'] = res_list['result'][9] return True except Exception as e: _LOGGER.error('get detail failed:' + e.__context__) self._detail['washStatus'] = -99 self._detail['velocity'] = -99 self._detail['waterTemp'] = -99 self._detail['targetTemp'] = -99 self._detail['errStatus'] = -99 self._detail['hotWater'] = -99 self._detail['needClean'] = -99 self._detail['modeType'] = -99 self._detail['appointStart'] = -99 self._detail['appointEnd'] = -99 return False
def yunmi_set_poweroff(self): url = 'https://openapp.io.mi.com/openapp/device/rpc/' + str( self._did ) + '?data=%7B%22method%22:%22set_power%22,%22did%22:%22' + str( self._did ) + '%22,%22id%22:%221%22,%22params%22:%5B0%5D%7D&clientId=' + self._client_id + '&accessToken=' + self._access_token headers = { 'Accept-Encoding': 'br, gzip, deflate', 'User-Agent': 'WaterPurifier/2.1.6 (iPhone; iOS 12.2; Scale/3.00)' } try: res = requests.get(url, headers=headers) json_str = res.content.decode(encoding='utf-8') res_list = json.loads(json_str) if res_list['message'] == 'ok': return True except Exception as e: _LOGGER.error('yunmi_set_poweroff failed:' + e) return False
def yunmi_get_deviceid(self): url = 'https://openapp.io.mi.com/openapp/user/device_list?accessToken=' + self._access_token + '&clientId=' + self._client_id + '&locale=zh_CN' headers = { 'Accept-Encoding': 'br, gzip, deflate', 'User-Agent': 'WaterPurifier/2.1.6 (iPhone; iOS 12.2; Scale/3.00)' } try: res = requests.get(url, headers=headers) json_str = res.content.decode(encoding='utf-8') res_list = json.loads(json_str) if res_list['message'] == 'ok': self._did = res_list['result']['list'][0]['did'] self._isonline = res_list['result']['list'][0]['isOnline'] return True except Exception as e: _LOGGER.error('get deviceid failed:' + e) self._did = 0 self._isonline = 'error' return False
def __init__(self, name, phone_number, password, client_id): self._name = name self._client_id = client_id self._token = None self._phone_number = phone_number self._password = password self._access_token_exp_time = None self._detail = {} self._did = None self._isonline = None # _LOGGER.error('============= YunmiWaterHeaterController setup -> phone_number: %s =============', phone_number) try: with open(TOKEN_PATH) as f: token_arr = json.loads(f.read()) self._access_token = token_arr['access_token'] self._refresh_token = token_arr['refresh_token'] self._user_id = token_arr['user_id'] self._member_id = token_arr['member_id'] # _LOGGER.error('============= YunmiWaterHeaterController setup -> _access_token: %s =============', self._access_token) except: self._access_token = None self._refresh_token = None self._user_id = None self._member_id = None try: if self._access_token_exp_time is not None and int( round(time.time() * 1000)) >= self._access_token_exp_time: self.yunmi_login() if self._access_token is not None: self.yunmi_get_detail() self.yunmi_get_deviceid() else: self.yunmi_login() self.yunmi_get_detail() self.yunmi_get_deviceid() except Exception as e: _LOGGER.error("update fail" + e.__context__)