Initial Support

Initial Support for EcoVacs Home app.
- Login and most commands/controls work
This commit is contained in:
Brian Martin 2019-05-20 09:01:27 -04:00
parent d5449961f3
commit 734d1cee79
2 changed files with 805 additions and 47 deletions

View file

@ -6,6 +6,7 @@ from .mqttserver import MQTTHelperBot
from .xmppserver import XMPPServer from .xmppserver import XMPPServer
import asyncio import asyncio
import contextvars import contextvars
import json
import time import time
from datetime import datetime, timedelta from datetime import datetime, timedelta
import platform import platform
@ -249,6 +250,299 @@ class VacBotDevice(object):
"xmpp_connection": self.xmpp_connection, "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): class VacBotClient(object):
def __init__(self, userid="", realm="", token=""): def __init__(self, userid="", realm="", token=""):
@ -289,6 +583,21 @@ def check_authcode(uid, authcode):
return False 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): def check_token(uid, token):
bumperlog.debug("Checking for token: {}".format(token)) bumperlog.debug("Checking for token: {}".format(token))
@ -342,6 +651,16 @@ def bot_get(did):
return bots.get(Bot.did == 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): def bot_full_upsert(vacbot):
bots = db_get().table("bots") bots = db_get().table("bots")
Bot = Query() Bot = Query()

View file

@ -35,6 +35,21 @@ confserverlog = logging.getLogger("confserver")
logging.getLogger("asyncio").setLevel(logging.CRITICAL + 1) # Ignore this logger logging.getLogger("asyncio").setLevel(logging.CRITICAL + 1) # Ignore this logger
logging.getLogger("aiohttp.access").addFilter(aiohttp_filter()) 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: class ConfServer:
def __init__(self, address, usessl=False, helperbot=None): def __init__(self, address, usessl=False, helperbot=None):
@ -95,6 +110,10 @@ class ConfServer:
"/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin", "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin",
self.handle_login, self.handle_login,
), ),
web.get( #EcoVacs Home GetUserAccountInfo
"/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getUserAccountInfo",
self.handle_getUserAccountInfo,
),
web.get( web.get(
"/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/logout", "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/logout",
self.handle_logout, self.handle_logout,
@ -103,24 +122,71 @@ class ConfServer:
"/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getAuthCode", "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getAuthCode",
self.handle_getAuthCode, self.handle_getAuthCode,
), ),
web.get( #EcoVacs Home GetAuthCode
"/{apiversion}/{apptype}/auth/getAuthCode",
self.handle_getAuthCode
),
web.get( web.get(
"/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreement", "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreement",
self.handle_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( web.get(
"/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkVersion", "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkVersion",
self.handle_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( web.get(
"/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/campaign/homePageAlert", "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/campaign/homePageAlert",
self.handle_homePageAlert, self.handle_homePageAlert,
), ),
web.post("/api/users/user.do", self.handle_usersapi), web.post("/api/users/user.do", self.handle_usersapi),
web.get("/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( web.post(
"/api/pim/product/getProductIotMap", self.handle_getProductIotMap "/api/pim/product/getProductIotMap", self.handle_getProductIotMap
), ),
web.post("/api/iot/devmanager.do", self.handle_devmanager_botcommand), web.post("/api/iot/devmanager.do", self.handle_devmanager_botcommand),
web.post("/api/dim/devmanager.do", self.handle_devmanager_botcommand), #EcoVacs Home
web.post("/lookup.do", self.handle_lookup), web.post("/lookup.do", self.handle_lookup),
] ]
) )
@ -174,6 +240,7 @@ class ConfServer:
try: try:
user_devid = request.match_info.get("devid", "") user_devid = request.match_info.get("devid", "")
countrycode = request.match_info.get("country", "us") countrycode = request.match_info.get("country", "us")
apptype = request.match_info.get("apptype", "")
confserverlog.info( confserverlog.info(
"client with devid {} attempting login".format(user_devid) "client with devid {} attempting login".format(user_devid)
) )
@ -184,28 +251,43 @@ class ConfServer:
user = bumper.user_by_deviceid(user_devid) user = bumper.user_by_deviceid(user_devid)
if "checkLogin" in request.path: if "checkLogin" in request.path:
self.check_token( 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 # Deactivate old tokens and authcodes
bumper.user_revoke_expired_tokens(user["userid"]) 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 = { body = {
"code": bumper.RETURN_API_SUCCESS, "code": bumper.RETURN_API_SUCCESS,
"data": { "data": json.loads(login_details.toJSON()),
"accessToken": self.generate_token( #{
user # "accessToken": self.generate_token(tmpuser), # Generate a token
), # generate a new token # "country": countrycode,
"country": countrycode, # "email": "null@null.com",
"email": "null@null.com", # "uid": "fuid_{}".format(tmpuser["userid"]),
"uid": "fuid_{}".format(user["userid"]), # "username": "fusername_{}".format(tmpuser["userid"]),
"username": "fusername_{}".format(user["userid"]), #},
},
"msg": "操作成功", "msg": "操作成功",
"time": bumper.get_milli_time( "time": bumper.get_milli_time(
datetime.utcnow().timestamp() datetime.utcnow().timestamp()
), ),
} }
return web.json_response(body) return web.json_response(body)
body = { body = {
@ -219,23 +301,81 @@ class ConfServer:
else: else:
return web.json_response( return web.json_response(
self._auth_any(user_devid, countrycode, request) self._auth_any(user_devid, apptype, countrycode, request)
) )
except Exception as e: except Exception as e:
confserverlog.exception("{}".format(e)) confserverlog.exception("{}".format(e))
def check_token(self, countrycode, user, token): def handle_getUserAccountInfo(self, request):
if bumper.check_token(user["userid"], token): 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 = { body = {
"code": bumper.RETURN_API_SUCCESS, "code": bumper.RETURN_API_SUCCESS,
"data": { "data":
"accessToken": token, {
"country": countrycode, "email": login_details.email,
"email": "null@null.com", "hasMobile": "N",
"uid": "fuid_{}".format(user["userid"]), "hasPassword": "Y",
"username": "fusername_{}".format(user["userid"]), "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": "操作成功", "msg": "操作成功",
"time": bumper.get_milli_time(datetime.utcnow().timestamp()), "time": bumper.get_milli_time(datetime.utcnow().timestamp()),
} }
@ -260,7 +400,7 @@ class ConfServer:
bumper.user_add_authcode(user["userid"], token, tmpauthcode) bumper.user_add_authcode(user["userid"], token, tmpauthcode)
return tmpauthcode return tmpauthcode
def _auth_any(self, devid, country, request): def _auth_any(self, devid, apptype, country, request):
try: try:
user_devid = devid user_devid = devid
countrycode = country countrycode = country
@ -269,10 +409,36 @@ class ConfServer:
if user: # Default to user 0 if user: # Default to user 0
tmpuser = user 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) bumper.user_add_device(tmpuser["userid"], user_devid)
else: else:
bumper.user_add("tmpuser") # Add a new user bumper.user_add("tmpuser") # Add a new user
tmpuser = bumper.user_get("tmpuser") 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) bumper.user_add_device(tmpuser["userid"], user_devid)
for bot in bots: # Add all bots to the user for bot in bots: # Add all bots to the user
@ -280,7 +446,7 @@ class ConfServer:
if "checkLogin" in request.path: # If request was to check a token do so if "checkLogin" in request.path: # If request was to check a token do so
checkToken = self.check_token( checkToken = self.check_token(
countrycode, tmpuser, request.query["accessToken"] apptype, countrycode, tmpuser, request.query["accessToken"]
) )
isGood = json.loads(checkToken.text) isGood = json.loads(checkToken.text)
if isGood["code"] == "0000": if isGood["code"] == "0000":
@ -289,15 +455,17 @@ class ConfServer:
# Deactivate old tokens and authcodes # Deactivate old tokens and authcodes
bumper.user_revoke_expired_tokens(tmpuser["userid"]) bumper.user_revoke_expired_tokens(tmpuser["userid"])
body = { body = {
"code": bumper.RETURN_API_SUCCESS, "code": bumper.RETURN_API_SUCCESS,
"data": { "data": json.loads(login_details.toJSON()),
"accessToken": self.generate_token(tmpuser), # Generate a token #{
"country": countrycode, # "accessToken": self.generate_token(tmpuser), # Generate a token
"email": "null@null.com", # "country": countrycode,
"uid": "fuid_{}".format(tmpuser["userid"]), # "email": "null@null.com",
"username": "fusername_{}".format(tmpuser["userid"]), # "uid": "fuid_{}".format(tmpuser["userid"]),
}, # "username": "fusername_{}".format(tmpuser["userid"]),
#},
"msg": "操作成功", "msg": "操作成功",
"time": bumper.get_milli_time(datetime.utcnow().timestamp()), "time": bumper.get_milli_time(datetime.utcnow().timestamp()),
} }
@ -333,14 +501,19 @@ class ConfServer:
async def handle_getAuthCode(self, request): async def handle_getAuthCode(self, request):
try: 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 == "": if not user_devid == "":
user = bumper.user_by_deviceid(user_devid) user = bumper.user_by_deviceid(user_devid)
token = ""
if user: if user:
token = bumper.user_get_token( if "accessToken" in request.query:
user["userid"], request.query["accessToken"] token = bumper.user_get_token(
) user["userid"], request.query["accessToken"]
)
if token: if token:
authcode = "" authcode = ""
if not "authcode" in token: if not "authcode" in token:
@ -351,18 +524,31 @@ class ConfServer:
) )
else: else:
authcode = token["authcode"] authcode = token["authcode"]
if "global" in apptype:
body = { body = {
"code": bumper.RETURN_API_SUCCESS, "code": bumper.RETURN_API_SUCCESS,
"data": { "data": {
"authCode": authcode, "authCode": authcode,
"ecovacsUid": request.query["uid"], "ecovacsUid": request.query["uid"],
}, },
"msg": "操作成功", "msg": "操作成功",
"success": True,
"time": bumper.get_milli_time( "time": bumper.get_milli_time(
datetime.utcnow().timestamp() 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) return web.json_response(body)
body = { body = {
@ -399,12 +585,23 @@ class ConfServer:
except Exception as e: except Exception as e:
confserverlog.exception("{}".format(e)) confserverlog.exception("{}".format(e))
async def handle_checkAgreement(self, request): async def handle_checkAPPVersion(self, request): #EcoVacs Home
try: try:
body = { body = {
"code": bumper.RETURN_API_SUCCESS, "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": "操作成功", "msg": "操作成功",
"success": True,
"time": bumper.get_milli_time(datetime.utcnow().timestamp()), "time": bumper.get_milli_time(datetime.utcnow().timestamp()),
} }
@ -413,6 +610,184 @@ class ConfServer:
except Exception as e: except Exception as e:
confserverlog.exception("{}".format(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))
async def handle_homePageAlert(self, request): async def handle_homePageAlert(self, request):
try: try:
nextAlert = bumper.get_milli_time( nextAlert = bumper.get_milli_time(
@ -439,6 +814,7 @@ class ConfServer:
confserverlog.exception("{}".format(e)) confserverlog.exception("{}".format(e))
async def handle_getProductIotMap(self, request): async def handle_getProductIotMap(self, request):
user_devid = request.match_info.get("devid", "")
try: try:
body = { body = {
"code": bumper.RETURN_API_SUCCESS, "code": bumper.RETURN_API_SUCCESS,
@ -541,14 +917,28 @@ class ConfServer:
body = {"result": "ok", "ip": "47.88.66.164", "port": 8005} body = {"result": "ok", "ip": "47.88.66.164", "port": 8005}
elif todo == "loginByItToken": elif todo == "loginByItToken":
if bumper.check_authcode(postbody["userId"], postbody["token"]): if "userId" in postbody:
body = { if bumper.check_authcode(postbody["userId"], postbody["token"]):
"resource": postbody["resource"], body = {
"result": "ok", "resource": postbody["resource"],
"todo": "result", "result": "ok",
"token": postbody["token"], "todo": "result",
"userId": postbody["userId"], "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": elif todo == "GetDeviceList":
body = { body = {
@ -582,6 +972,51 @@ class ConfServer:
body = {"result": "fail", "todo": "result"} body = {"result": "fail", "todo": "result"}
return web.json_response(body) 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): async def handle_lookup(self, request):
try: try:
@ -653,6 +1088,10 @@ class ConfServer:
body = {"ret": "ok"} body = {"ret": "ok"}
return web.json_response(body) 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: except Exception as e:
confserverlog.exception("{}".format(e)) confserverlog.exception("{}".format(e))