diff --git a/bumper/__init__.py b/bumper/__init__.py index 618f1ab..6e53947 100644 --- a/bumper/__init__.py +++ b/bumper/__init__.py @@ -5,6 +5,7 @@ from .mqttserver import MQTTServer from .mqttserver import MQTTHelperBot from .xmppserver import XMPPServer import asyncio +import json import time from datetime import datetime, timedelta import platform @@ -280,6 +281,299 @@ class VacBotDevice(object): "xmpp_connection": self.xmpp_connection, } + def toJSON(self): + return json.dumps(self, default=lambda o: o.__dict__, + sort_keys=False)#, indent=4) + +class GlobalVacBotDevice(VacBotDevice): #EcoVacs Home + UILogicId = "" + ota = True + updateInfo = { + "changeLog": "", + "needUpdate": False + } + icon = "" + deviceName = "" + + +#EcoVacs Home Product IOT Map - 2019-05-20 +#https://portal-ww.ecouser.net/api/pim/product/getProductIotMap +EcoVacsHomeProducts = [ + { + "classid": "dl8fht", + "product": { + "UILogicId": "D_600", + "_id": "5acb0fa87c295c0001876ecf", + "icon": "5acc32067c295c0001876eea", + "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5acc32067c295c0001876eea", + "materialNo": "702-0000-0170", + "name": "DEEBOT 600 Series", + "ota": False, + "supportType": { + "alexa": True, + "assistant": True, + "share": True, + "tmjl": False + } + } + }, + { + "classid": "02uwxm", + "product": { + "UILogicId": "D_OZMO_SLIM10", + "_id": "5ae1481e7ccd1a0001e1f69e", + "icon": "5b1dddc48bc45700014035a1", + "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b1dddc48bc45700014035a1", + "materialNo": "110-1715-0201", + "name": "DEEBOT OZMO Slim10 Series", + "ota": False, + "supportType": { + "alexa": True, + "assistant": True, + "share": True, + "tmjl": False + } + } + }, + { + "classid": "y79a7u", + "product": { + "UILogicId": "D_OZMO_900", + "_id": "5b04c0227ccd1a0001e1f6a8", + "icon": "5b04c0217ccd1a0001e1f6a7", + "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b04c0217ccd1a0001e1f6a7", + "materialNo": "110-1810-0101", + "name": "DEEBOT OZMO 900 Series", + "ota": True, + "supportType": { + "alexa": True, + "assistant": True, + "share": True, + "tmjl": False + } + } + }, + { + "classid": "jr3pqa", + "product": { + "UILogicId": "D_700", + "_id": "5b43077b8bc457000140363e", + "icon": "5b5ac4cc8d5a56000111e769", + "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b5ac4cc8d5a56000111e769", + "materialNo": "702-0000-0202", + "name": "DEEBOT 711", + "ota": True, + "supportType": { + "alexa": True, + "assistant": True, + "share": True, + "tmjl": False + } + } + }, + { + "classid": "uv242z", + "product": { + "UILogicId": "D_700", + "_id": "5b5149b4ac0b87000148c128", + "icon": "5b5ac4e45f21100001882bb9", + "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b5ac4e45f21100001882bb9", + "materialNo": "702-0000-0205", + "name": "DEEBOT 710", + "ota": True, + "supportType": { + "alexa": True, + "assistant": True, + "share": True, + "tmjl": False + } + } + }, + { + "classid": "ls1ok3", + "product": { + "UILogicId": "D_900", + "_id": "5b6561060506b100015c8868", + "icon": "5ba4a2cb6c2f120001c32839", + "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ba4a2cb6c2f120001c32839", + "materialNo": "110-1711-0201", + "name": "DEEBOT 900 Series", + "ota": True, + "supportType": { + "alexa": True, + "assistant": True, + "share": True, + "tmjl": False + } + } + }, + { + "classid": "eyi9jv", + "product": { + "UILogicId": "D_700", + "_id": "5b7b65f364e1680001a08b54", + "icon": "5b7b65f176f7f10001e9a0c2", + "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b7b65f176f7f10001e9a0c2", + "materialNo": "715", + "name": "DEEBOT 715", + "ota": True, + "supportType": { + "alexa": True, + "assistant": True, + "share": True, + "tmjl": False + } + } + }, + { + "classid": "4zfacv", + "product": { + "UILogicId": "DN_2G", + "_id": "5bf2596f23244a00013f2f13", + "icon": "5c778731280fda0001770ba0", + "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5c778731280fda0001770ba0", + "materialNo": "910", + "name": "DEEBOT 910", + "ota": True, + "supportType": { + "alexa": True, + "assistant": True, + "share": True, + "tmjl": False + } + } + }, + { + "classid": "vi829v", + "product": { + "UILogicId": "DX_5G", + "_id": "5c19a8f3a1e6ee0001782247", + "icon": "5c9c7995e9e9270001354ab4", + "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5c9c7995e9e9270001354ab4", + "materialNo": "920", + "name": "DEEBOT OZMO 920 Series", + "ota": True, + "supportType": { + "alexa": True, + "assistant": True, + "share": True, + "tmjl": False + } + } + }, + { + "classid": "gd4uut", + "product": { + "UILogicId": "DR_935G", + "_id": "5bc8189d68142800016a6937", + "icon": "5c7384767b93c700013f12e7", + "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5c7384767b93c700013f12e7", + "materialNo": "960", + "name": "DEEBOT OZMO 960", + "ota": True, + "supportType": { + "alexa": True, + "assistant": True, + "share": False, + "tmjl": False + } + } + }, + { + "classid": "9akc61", + "product": { + "UILogicId": "D_500", + "_id": "5c763f8263023c0001e7f855", + "icon": "5c932067280fda0001770d7f", + "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5c932067280fda0001770d7f", + "materialNo": "D505", + "name": "DEEBOT 505", + "ota": False, + "supportType": { + "alexa": True, + "assistant": True, + "share": True, + "tmjl": False + } + } + }, + { + "classid": "r8ead0", + "product": { + "UILogicId": "D_500", + "_id": "5c763f63280fda0001770b88", + "icon": "5c93204b63023c0001e7faa7", + "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5c93204b63023c0001e7faa7", + "materialNo": "D502", + "name": "DEEBOT 502", + "ota": False, + "supportType": { + "alexa": True, + "assistant": True, + "share": True, + "tmjl": False + } + } + }, + { + "classid": "emzppx", + "product": { + "UILogicId": "D_500", + "_id": "5c763f35280fda0001770b84", + "icon": "5c931fef280fda0001770d7e", + "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5c931fef280fda0001770d7e", + "materialNo": "D501", + "name": "DEEBOT 501", + "ota": False, + "supportType": { + "alexa": True, + "assistant": True, + "share": True, + "tmjl": False + } + } + }, + { + "classid": "vsc5ia", + "product": { + "UILogicId": "D_500", + "_id": "5c763eba280fda0001770b81", + "icon": "5c874326280fda0001770d2a", + "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5c874326280fda0001770d2a", + "materialNo": "D500", + "name": "DEEBOT 500", + "ota": False, + "supportType": { + "alexa": True, + "assistant": True, + "share": True, + "tmjl": False + } + } + }, + { + "classid": "aqdd5p", + "product": { + "UILogicId": "D_900", + "_id": "5cb7cfba179839000114d762", + "icon": "5cb7cfbab72c4d00010e5fc7", + "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5cb7cfbab72c4d00010e5fc7", + "materialNo": "110-1711-0001", + "name": "DEEBOT DE55", + "ota": True, + "supportType": { + "alexa": False, + "assistant": False, + "share": False, + "tmjl": False + } + } + } + ] + + + + class VacBotClient(object): def __init__(self, userid="", realm="", token=""): @@ -320,6 +614,21 @@ def check_authcode(uid, authcode): return False +def loginByItToken(authcode): + bumperlog.debug("Checking for authcode: {}".format(authcode)) + tokens = db_get().table("tokens") + tmpauth = tokens.get( + (Query().authcode == authcode) + #& ( # Match authcode + # (Query().userid == uid.replace("fuid_", "")) + # | (Query().userid == "fuid_{}".format(uid)) + #) # Userid with or without fuid_ + ) + if tmpauth: + return {"token":tmpauth["token"], "userid":tmpauth["userid"]} + + return {} + def check_token(uid, token): bumperlog.debug("Checking for token: {}".format(token)) @@ -373,6 +682,16 @@ def bot_get(did): return bots.get(Bot.did == did) +def bot_toEcoVacsHome_JSON(bot): #EcoVacs Home + for botprod in EcoVacsHomeProducts: + if botprod["classid"] == bot["class"]: + bot["UILogicId"] = botprod["product"]["UILogicId"] + bot["ota"] = botprod["product"]["ota"] + bot["icon"] = botprod["product"]["iconUrl"] + return json.dumps(bot, default=lambda o: o.__dict__, + sort_keys=False)#, indent=4) + + def bot_full_upsert(vacbot): bots = db_get().table("bots") Bot = Query() diff --git a/bumper/confserver.py b/bumper/confserver.py index a9aa00d..07c8590 100644 --- a/bumper/confserver.py +++ b/bumper/confserver.py @@ -10,6 +10,7 @@ from datetime import datetime, timedelta import asyncio from aiohttp import web import uuid +import xml.etree.ElementTree as ET class aiohttp_filter(logging.Filter): @@ -34,6 +35,21 @@ confserverlog = logging.getLogger("confserver") #logging.getLogger("asyncio").setLevel(logging.CRITICAL + 1) # Ignore this logger logging.getLogger("aiohttp.access").addFilter(aiohttp_filter()) +class EcoVacs_Login: + accessToken = "" + country = "" + email = "" + uid = "" + username = "" + + def toJSON(self): + return json.dumps(self, default=lambda o: o.__dict__, + sort_keys=False)#, indent=4) + +class EcoVacsHome_Login(EcoVacs_Login): + loginName = "" + mobile = "" + ucUid = "" class ConfServer: def __init__(self, address, usessl=False, helperbot=None): @@ -94,6 +110,10 @@ class ConfServer: "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin", self.handle_login, ), + web.get( #EcoVacs Home GetUserAccountInfo + "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getUserAccountInfo", + self.handle_getUserAccountInfo, + ), web.get( "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/logout", self.handle_logout, @@ -102,24 +122,72 @@ class ConfServer: "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getAuthCode", self.handle_getAuthCode, ), + web.get( #EcoVacs Home GetAuthCode + "/{apiversion}/{apptype}/auth/getAuthCode", + self.handle_getAuthCode + ), web.get( "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreement", self.handle_checkAgreement, ), + web.get( #EcoVacs Home CheckAgreement + "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreementBatch", + self.handle_checkAgreement, + ), web.get( "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkVersion", self.handle_checkVersion, ), + web.get( #EcoVacs Home CheckAPPVersion + "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkAPPVersion", + self.handle_checkAPPVersion, + ), + web.get( #EcoVacs Home Upload Device Info + "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/uploadDeviceInfo", + self.handle_uploadDeviceInfo, + ), + web.get( #EcoVacs Home GetAdByPositionType + "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/ad/getAdByPositionType", + self.handle_getAdByPositionType, + ), + web.get( #EcoVacs Home Get Boot Screen + "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/ad/getBootScreen", + self.handle_getBootScreen, + ), + web.get( #EcoVacs Home message hasUnreadMsg + "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/message/hasUnreadMsg", + self.handle_hasUnreadMessage, + ), + web.get( #EcoVacs Home neng message hasUnreadMsg + "/api/neng/message/hasUnreadMsg", + self.handle_neng_hasUnreadMessage, + ), + web.get( #EcoVacs Home message getMsgList + "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/message/getMsgList", + self.handle_getMsgList, + ), + web.get( #EcoVacs Home common getSystemReminder + "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getSystemReminder", + self.handle_getSystemReminder, + ), + web.get( #EcoVacs Home shop getCnWapShopConfig + "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/shop/getCnWapShopConfig", + self.handle_getCnWapShopConfig, + ), web.get( "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/campaign/homePageAlert", self.handle_homePageAlert, ), web.post("/api/users/user.do", self.handle_usersapi), web.get("/api/users/user.do", self.handle_usersapi), + web.post("/api/appsvr/app.do", self.handle_appsvr_api), #EcoVacs Home + web.get("/api/appsvr/app.do", self.handle_appsvr_api), #EcoVacs Home web.post( "/api/pim/product/getProductIotMap", self.handle_getProductIotMap ), + web.post("/api/lg/log.do", self.handle_lg_log), #EcoVacs Home web.post("/api/iot/devmanager.do", self.handle_devmanager_botcommand), + web.post("/api/dim/devmanager.do", self.handle_dim_devmanager), #EcoVacs Home web.post("/lookup.do", self.handle_lookup), ] ) @@ -173,6 +241,7 @@ class ConfServer: try: user_devid = request.match_info.get("devid", "") countrycode = request.match_info.get("country", "us") + apptype = request.match_info.get("apptype", "") confserverlog.info( "client with devid {} attempting login".format(user_devid) ) @@ -181,30 +250,45 @@ class ConfServer: not user_devid == "" ): # Performing basic "auth" using devid, super insecure user = bumper.user_by_deviceid(user_devid) - if "checkLogin" in request.path: + if "checkLogin" in request.path: self.check_token( - countrycode, user, request.query["accessToken"] + apptype, countrycode, user, request.query["accessToken"] ) - else: + else: + if "global_" in apptype: #EcoVacs Home + login_details = EcoVacsHome_Login() + login_details.ucUid = "fuid_{}".format(user["userid"]) + login_details.loginName = "fusername_{}".format(user["userid"]) + login_details.mobile = None + + else: + login_details = EcoVacs_Login() + # Deactivate old tokens and authcodes bumper.user_revoke_expired_tokens(user["userid"]) + login_details.accessToken = self.generate_token(user) + login_details.uid = "fuid_{}".format(user["userid"]) + login_details.username = "fusername_{}".format(user["userid"]) + login_details.country = countrycode + login_details.email = "null@null.com" + body = { "code": bumper.RETURN_API_SUCCESS, - "data": { - "accessToken": self.generate_token( - user - ), # generate a new token - "country": countrycode, - "email": "null@null.com", - "uid": "fuid_{}".format(user["userid"]), - "username": "fusername_{}".format(user["userid"]), - }, + "data": json.loads(login_details.toJSON()), + #{ + # "accessToken": self.generate_token(tmpuser), # Generate a token + # "country": countrycode, + # "email": "null@null.com", + # "uid": "fuid_{}".format(tmpuser["userid"]), + # "username": "fusername_{}".format(tmpuser["userid"]), + #}, "msg": "操作成功", "time": bumper.get_milli_time( datetime.utcnow().timestamp() ), } + return web.json_response(body) body = { @@ -218,23 +302,81 @@ class ConfServer: else: return web.json_response( - self._auth_any(user_devid, countrycode, request) + self._auth_any(user_devid, apptype, countrycode, request) ) except Exception as e: confserverlog.exception("{}".format(e)) - def check_token(self, countrycode, user, token): - if bumper.check_token(user["userid"], token): + def handle_getUserAccountInfo(self, request): + try: + user_devid = request.match_info.get("devid", "") + countrycode = request.match_info.get("country", "us") + apptype = request.match_info.get("apptype", "") + user = bumper.user_by_deviceid(user_devid) + + if "global_" in apptype: #EcoVacs Home + login_details = EcoVacsHome_Login() + login_details.ucUid = "fuid_{}".format(user["userid"]) + login_details.loginName = "fusername_{}".format(user["userid"]) + login_details.mobile = None + else: + login_details = EcoVacs_Login() + + login_details.uid = "fuid_{}".format(user["userid"]) + login_details.username = "fusername_{}".format(user["userid"]) + login_details.country = countrycode + login_details.email = "null@null.com" + body = { "code": bumper.RETURN_API_SUCCESS, - "data": { - "accessToken": token, - "country": countrycode, - "email": "null@null.com", - "uid": "fuid_{}".format(user["userid"]), - "username": "fusername_{}".format(user["userid"]), - }, + "data": + { + "email": login_details.email, + "hasMobile": "N", + "hasPassword": "Y", + "uid": login_details.uid, + "userName": login_details.username, + "obfuscatedMobile": None, + "mobile": None, + "loginName": login_details.loginName + }, + "msg": "操作成功", + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), + } + return web.json_response(body) + + except Exception as e: + confserverlog.exception("{}".format(e)) + + + def check_token(self, apptype, countrycode, user, token): + if bumper.check_token(user["userid"], token): + + if "global_" in apptype: #EcoVacs Home + login_details = EcoVacsHome_Login() + login_details.ucUid = "fuid_{}".format(user["userid"]) + login_details.loginName = "fusername_{}".format(user["userid"]) + login_details.mobile = None + else: + login_details = EcoVacs_Login() + + login_details.accessToken = token + login_details.uid = "fuid_{}".format(user["userid"]) + login_details.username = "fusername_{}".format(user["userid"]) + login_details.country = countrycode + login_details.email = "null@null.com" + + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": json.loads(login_details.toJSON()), + #{ + # "accessToken": self.generate_token(tmpuser), # Generate a token + # "country": countrycode, + # "email": "null@null.com", + # "uid": "fuid_{}".format(tmpuser["userid"]), + # "username": "fusername_{}".format(tmpuser["userid"]), + #}, "msg": "操作成功", "time": bumper.get_milli_time(datetime.utcnow().timestamp()), } @@ -259,7 +401,7 @@ class ConfServer: bumper.user_add_authcode(user["userid"], token, tmpauthcode) return tmpauthcode - def _auth_any(self, devid, country, request): + def _auth_any(self, devid, apptype, country, request): try: user_devid = devid countrycode = country @@ -268,10 +410,36 @@ class ConfServer: if user: # Default to user 0 tmpuser = user + if "global_" in apptype: #EcoVacs Home + login_details = EcoVacsHome_Login() + login_details.ucUid = "fuid_{}".format(tmpuser["userid"]) + login_details.loginName = "fusername_{}".format(tmpuser["userid"]) + login_details.mobile = None + else: + login_details = EcoVacs_Login() + + login_details.accessToken = self.generate_token(tmpuser) + login_details.uid = "fuid_{}".format(tmpuser["userid"]) + login_details.username = "fusername_{}".format(tmpuser["userid"]) + login_details.country = countrycode + login_details.email = "null@null.com" bumper.user_add_device(tmpuser["userid"], user_devid) else: bumper.user_add("tmpuser") # Add a new user tmpuser = bumper.user_get("tmpuser") + if "global_" in apptype: #EcoVacs Home + login_details = EcoVacsHome_Login() + login_details.ucUid = "fuid_{}".format(tmpuser["userid"]) + login_details.loginName = "fusername_{}".format(tmpuser["userid"]) + login_details.mobile = None + else: + login_details = EcoVacs_Login() + + login_details.accessToken = self.generate_token(tmpuser) + login_details.uid = "fuid_{}".format(tmpuser["userid"]) + login_details.username = "fusername_{}".format(tmpuser["userid"]) + login_details.country = countrycode + login_details.email = "null@null.com" bumper.user_add_device(tmpuser["userid"], user_devid) for bot in bots: # Add all bots to the user @@ -279,7 +447,7 @@ class ConfServer: if "checkLogin" in request.path: # If request was to check a token do so checkToken = self.check_token( - countrycode, tmpuser, request.query["accessToken"] + apptype, countrycode, tmpuser, request.query["accessToken"] ) isGood = json.loads(checkToken.text) if isGood["code"] == "0000": @@ -287,16 +455,18 @@ class ConfServer: # Deactivate old tokens and authcodes bumper.user_revoke_expired_tokens(tmpuser["userid"]) + body = { "code": bumper.RETURN_API_SUCCESS, - "data": { - "accessToken": self.generate_token(tmpuser), # Generate a token - "country": countrycode, - "email": "null@null.com", - "uid": "fuid_{}".format(tmpuser["userid"]), - "username": "fusername_{}".format(tmpuser["userid"]), - }, + "data": json.loads(login_details.toJSON()), + #{ + # "accessToken": self.generate_token(tmpuser), # Generate a token + # "country": countrycode, + # "email": "null@null.com", + # "uid": "fuid_{}".format(tmpuser["userid"]), + # "username": "fusername_{}".format(tmpuser["userid"]), + #}, "msg": "操作成功", "time": bumper.get_milli_time(datetime.utcnow().timestamp()), } @@ -332,14 +502,19 @@ class ConfServer: async def handle_getAuthCode(self, request): try: + apptype = request.match_info.get("apptype", "") + user_devid = request.match_info.get("devid", "") #Ecovacs + if user_devid == "": + user_devid = request.query["deviceId"] #Ecovacs Home - user_devid = request.match_info.get("devid", "") if not user_devid == "": user = bumper.user_by_deviceid(user_devid) + token = "" if user: - token = bumper.user_get_token( - user["userid"], request.query["accessToken"] - ) + if "accessToken" in request.query: + token = bumper.user_get_token( + user["userid"], request.query["accessToken"] + ) if token: authcode = "" if not "authcode" in token: @@ -350,18 +525,31 @@ class ConfServer: ) else: authcode = token["authcode"] - - body = { + if "global" in apptype: + body = { "code": bumper.RETURN_API_SUCCESS, "data": { "authCode": authcode, "ecovacsUid": request.query["uid"], }, "msg": "操作成功", + "success": True, "time": bumper.get_milli_time( datetime.utcnow().timestamp() ), } + else: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": { + "authCode": authcode, + "ecovacsUid": request.query["uid"], + }, + "msg": "操作成功", + "time": bumper.get_milli_time( + datetime.utcnow().timestamp() + ), + } return web.json_response(body) body = { @@ -398,17 +586,206 @@ class ConfServer: except Exception as e: confserverlog.exception("{}".format(e)) - async def handle_checkAgreement(self, request): + async def handle_checkAPPVersion(self, request): #EcoVacs Home try: body = { "code": bumper.RETURN_API_SUCCESS, - "data": [], + "data": { + "c": None, + "downPageUrl": None, + "img": None, + "nextAlertTime": None, + "r": 0, + "t": None, + "u": None, + "ut": 0, + "v": None, + }, "msg": "操作成功", + "success": True, "time": bumper.get_milli_time(datetime.utcnow().timestamp()), } return web.json_response(body) + except Exception as e: + confserverlog.exception("{}".format(e)) + + async def handle_uploadDeviceInfo(self, request): #EcoVacs Home + try: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": None, + "msg": "操作成功", + "success": True, + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + confserverlog.exception("{}".format(e)) + + async def handle_getAdByPositionType(self, request): #EcoVacs Home + try: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": None, + "msg": "操作成功", + "success": True, + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + confserverlog.exception("{}".format(e)) + + async def handle_getBootScreen(self, request): #EcoVacs Home + try: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": None, + "msg": "操作成功", + "success": True, + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + confserverlog.exception("{}".format(e)) + + async def handle_hasUnreadMessage(self, request): #EcoVacs Home + try: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": "N", + "msg": "操作成功", + "success": True, + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + confserverlog.exception("{}".format(e)) + + + async def handle_neng_hasUnreadMessage(self, request): #EcoVacs Home + try: + body = { + "code": 0, + "data": { + "hasUnRead": True + }, + } + + return web.json_response(body) + + except Exception as e: + confserverlog.exception("{}".format(e)) + + + async def handle_getMsgList(self, request): #EcoVacs Home + try: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": { + "hasNextPage": 0, + "items": [] + }, + "msg": "操作成功", + "success": True, + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + confserverlog.exception("{}".format(e)) + + async def handle_getCnWapShopConfig(self, request): #EcoVacs Home + try: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": { + "myShopShowFlag": "N", + "myShopUrl": "", + "shopIndexShowFlag": "N", + "shopIndexUrl": "" + }, + "msg": "操作成功", + "success": True, + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + confserverlog.exception("{}".format(e)) + + async def handle_getSystemReminder(self, request): #EcoVacs Home + try: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": + { + "iosGradeTime": { + "iodGradeFlag": "N" + }, + "openNotification": { + "openNotificationContent": None, + "openNotificationFlag": "N", + "openNotificationTitle": None + } + }, + "msg": "操作成功", + "success": True, + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + confserverlog.exception("{}".format(e)) + + async def handle_checkAgreement(self, request): + try: + apptype = request.match_info.get("apptype", "") + if "global_" in apptype: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": [ + { + "force": "N", + "id": "20180804040641_7d746faf18b8cb22a50d145598fe4c90", + "type": "USER", + "url": "https://bumper.ecovacs.com/content/agreement?id=20180804040641_7d746faf18b8cb22a50d145598fe4c90&language=EN", #"https://gl-us-wap.ecovacs.com/content/agreement?id=20180804040641_7d746faf18b8cb22a50d145598fe4c90&language=EN + "version": "1.01" + }, + { + "force": "N", + "id": "20180804040245_4e7c56dfb7ebd3b81b1f2747d0859fac", + "type": "PRIVACY", + "url": "https://bumper.ecovacs.com/content/agreement?id=20180804040245_4e7c56dfb7ebd3b81b1f2747d0859fac&language=EN", #"https://gl-us-wap.ecovacs.com/content/agreement?id=20180804040245_4e7c56dfb7ebd3b81b1f2747d0859fac&language=EN" + "version": "1.01" + } + ], + "msg": "操作成功", + "success": True, + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), + } + else: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": [], + "msg": "操作成功", + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + except Exception as e: confserverlog.exception("{}".format(e)) @@ -438,6 +815,7 @@ class ConfServer: confserverlog.exception("{}".format(e)) async def handle_getProductIotMap(self, request): + user_devid = request.match_info.get("devid", "") try: body = { "code": bumper.RETURN_API_SUCCESS, @@ -540,14 +918,28 @@ class ConfServer: body = {"result": "ok", "ip": "47.88.66.164", "port": 8005} elif todo == "loginByItToken": - if bumper.check_authcode(postbody["userId"], postbody["token"]): - body = { - "resource": postbody["resource"], - "result": "ok", - "todo": "result", - "token": postbody["token"], - "userId": postbody["userId"], - } + if "userId" in postbody: + if bumper.check_authcode(postbody["userId"], postbody["token"]): + body = { + "resource": postbody["resource"], + "result": "ok", + "todo": "result", + "token": postbody["token"], + "userId": postbody["userId"], + } + else: #EcoVacs Home LoginByITToken + loginToken = bumper.loginByItToken(postbody["token"]) + if not loginToken == {}: + body = { + "resource": postbody["resource"], + "result": "ok", + "todo": "result", + "token": loginToken["token"], + "userId": loginToken["userid"], + } + else: + body = {"result": "fail", "todo": "result"} + elif todo == "GetDeviceList": body = { @@ -581,6 +973,51 @@ class ConfServer: body = {"result": "fail", "todo": "result"} return web.json_response(body) + + + async def handle_appsvr_api(self, request): + if not request.method == "GET": # Skip GET for now + try: + + body = {} + postbody = {} + if request.content_type == "application/x-www-form-urlencoded": + postbody = await request.post() + + else: + postbody = json.loads(await request.text()) + + todo = postbody["todo"] + + if todo == "GetGlobalDeviceList": #EcoVacs Home + bots = bumper.db_get().table("bots").all() + botlist = [] + for bot in bots: + if bot["class"] != "": + b = bumper.bot_toEcoVacsHome_JSON(bot) + botlist.append(json.loads(b)) + + body = { + "code": 0, + "devices": botlist, + "ret": "ok", + "todo": "result", + } + + confserverlog.debug( + "\r\n POST: {} \r\n Response: {}".format(postbody, body) + ) + + return web.json_response(body) + + except Exception as e: + confserverlog.exception("{}".format(e)) + + # Return fail for GET + body = {"result": "fail", "todo": "result"} + return web.json_response(body) + + async def handle_lookup(self, request): try: @@ -622,14 +1059,96 @@ class ConfServer: except Exception as e: confserverlog.exception("{}".format(e)) + + async def handle_lg_log(self, request): #EcoVacs Home + try: + json_body = json.loads(await request.text()) + + randomid = "".join(random.sample(string.ascii_letters, 6)) + did = json_body["did"] + + botdetails = bumper.bot_get(did) + if botdetails: + if not "cmdName" in json_body: + if "td" in json_body: + json_body["cmdName"] = json_body["td"] + #json_body["td"] = "q" + + if not "toId" in json_body: + json_body["toId"] = did + + if not "toType" in json_body: + json_body["toType"] = botdetails["class"] + + if not "toRes" in json_body: + json_body["toRes"] = botdetails["resource"] + + if not "payloadType" in json_body: + json_body["payloadType"] = "x" + + if not "payload" in json_body: + json_body["payload"] = "" + if json_body["td"] == "GetCleanLogs": + json_body["td"] = "q" + json_body["payload"] = '' #" + + + if did != "": + confserverlog.debug("BotCommand: {}".format(json_body)) + bot = bumper.bot_get(did) + if bot["company"] == "eco-ng" and bot["mqtt_connection"] == True: + body = "" + retcmd = await self.helperbot.send_command(json_body, randomid) + logs = [] + logsroot = ET.fromstring(retcmd["resp"]) + if logsroot.attrib["ret"] == "ok": + cleanlogs = logsroot.getchildren() + for l in cleanlogs: + logs.append(l.attrib) + + body = { + "ret": "ok", + #"logs": logs, #TODO: Doesn't parse correctly, new protocol & server side processing + "logs": [] + } + + else: + body = { + "ret": "ok", + "logs": [], + } + + confserverlog.debug( + "\r\n POST: {} \r\n Response: {}".format(json_body, body) + ) + + return web.json_response(body) + else: + # No response, send error back + confserverlog.error( + "No bots with DID: {} connected to MQTT".format( + json_body["toId"] + ) + ) + body = {"id": randomid, "errno": bumper.ERR_COMMON, "ret": "fail"} + return web.json_response(body) + + + except Exception as e: + confserverlog.exception("{}".format(e)) + async def handle_devmanager_botcommand(self, request): try: json_body = json.loads(await request.text()) - confserverlog.debug("BotCommand: {}".format(json_body)) + randomid = "".join(random.sample(string.ascii_letters, 6)) + did = "" + if "toId" in json_body: # Its a command + did = json_body["toId"] - if "toId" in json_body: # Its a command - bot = bumper.bot_get(json_body["toId"]) + if did != "": + confserverlog.debug("BotCommand: {}".format(json_body)) + bot = bumper.bot_get(did) if bot["company"] == "eco-ng" and bot["mqtt_connection"] == True: retcmd = await self.helperbot.send_command(json_body, randomid) body = retcmd @@ -646,15 +1165,63 @@ class ConfServer: ) body = {"id": randomid, "errno": bumper.ERR_COMMON, "ret": "fail"} return web.json_response(body) + else: if "td" in json_body: # Seen when doing initial wifi config if json_body["td"] == "PollSCResult": body = {"ret": "ok"} return web.json_response(body) + + if json_body["td"] == "HasUnreadMsg": #EcoVacs Home + body = {"ret":"ok","unRead":False} + return web.json_response(body) except Exception as e: confserverlog.exception("{}".format(e)) + + async def handle_dim_devmanager(self, request): + try: + json_body = json.loads(await request.text()) + + randomid = "".join(random.sample(string.ascii_letters, 6)) + did = "" + if "toId" in json_body: # Its a command + did = json_body["toId"] + + if did != "": + confserverlog.debug("BotCommand: {}".format(json_body)) + bot = bumper.bot_get(did) + if bot["company"] == "eco-ng" and bot["mqtt_connection"] == True: + retcmd = await self.helperbot.send_command(json_body, randomid) + body = retcmd + confserverlog.debug( + "\r\n POST: {} \r\n Response: {}".format(json_body, body) + ) + return web.json_response(body) + else: + # No response, send error back + confserverlog.error( + "No bots with DID: {} connected to MQTT".format( + json_body["toId"] + ) + ) + body = {"id": randomid, "errno": bumper.ERR_COMMON, "ret": "fail"} + return web.json_response(body) + + else: + if "td" in json_body: # Seen when doing initial wifi config + if json_body["td"] == "PollSCResult": + body = {"ret": "ok"} + return web.json_response(body) + + if json_body["td"] == "HasUnreadMsg": #EcoVacs Home + body = {"ret":"ok","unRead":False} + return web.json_response(body) + + except Exception as e: + confserverlog.exception("{}".format(e)) + def disconnect(self): try: confserverlog.info("shutting down")