diff --git a/bumper/__init__.py b/bumper/__init__.py
index 04080fa..fae5aad 100644
--- a/bumper/__init__.py
+++ b/bumper/__init__.py
@@ -66,7 +66,7 @@ sys.path.append(os.path.join(data_dir, "plugins"))
discovered_plugins = {
name: importlib.import_module(name)
for finder, name, ispkg in pkgutil.iter_modules()
- if name.startswith('bumper_')
+ if name.startswith("bumper_")
}
shutting_down = False
@@ -104,9 +104,9 @@ async def start():
return
if not (
- os.path.exists(ca_cert)
- and os.path.exists(server_cert)
- and os.path.exists(server_key)
+ os.path.exists(ca_cert)
+ and os.path.exists(server_cert)
+ and os.path.exists(server_key)
):
bumperlog.fatal("Certificate(s) don't exist at paths specified")
return
@@ -143,9 +143,15 @@ async def start():
# Start web servers
conf_server.confserver_app()
asyncio.create_task(
- conf_server.start_site(conf_server.app, address=bumper_listen, port=conf1_listen_port, usessl=True))
+ conf_server.start_site(
+ conf_server.app, address=bumper_listen, port=conf1_listen_port, usessl=True
+ )
+ )
asyncio.create_task(
- conf_server.start_site(conf_server.app, address=bumper_listen, port=conf2_listen_port, usessl=False))
+ conf_server.start_site(
+ conf_server.app, address=bumper_listen, port=conf2_listen_port, usessl=False
+ )
+ )
# Start maintenance
while not shutting_down:
@@ -200,18 +206,17 @@ def main(argv=None):
try:
if not (
- os.path.exists(ca_cert)
- and os.path.exists(server_cert)
- and os.path.exists(server_key)
+ os.path.exists(ca_cert)
+ and os.path.exists(server_cert)
+ and os.path.exists(server_key)
):
msg = "No certs found! Please generate them (More infos in the docs)"
bumperlog.fatal(msg)
sys.exit(msg)
- if not (
- os.path.exists(os.path.join(data_dir, "passwd"))
- ):
- with open(os.path.join(data_dir, "passwd"), 'w'): pass
+ if not (os.path.exists(os.path.join(data_dir, "passwd"))):
+ with open(os.path.join(data_dir, "passwd"), "w"):
+ pass
parser = argparse.ArgumentParser()
parser.add_argument(
diff --git a/bumper/__main__.py b/bumper/__main__.py
index 7434132..d2c45b2 100644
--- a/bumper/__main__.py
+++ b/bumper/__main__.py
@@ -1,4 +1,4 @@
import bumper
if __name__ == "__main__":
- bumper.main()
\ No newline at end of file
+ bumper.main()
diff --git a/bumper/confserver.py b/bumper/confserver.py
index 8dd4918..e8fb066 100644
--- a/bumper/confserver.py
+++ b/bumper/confserver.py
@@ -13,6 +13,7 @@ from bumper import plugins
from bumper.models import *
from .util import get_logger
+
class aiohttp_filter(logging.Filter):
def filter(self, record):
if (
@@ -21,10 +22,7 @@ class aiohttp_filter(logging.Filter):
record.levelno = 10
record.levelname = "DEBUG"
- if (
- record.levelno == 10
- and get_logger("confserver").getEffectiveLevel() == 10
- ):
+ if record.levelno == 10 and get_logger("confserver").getEffectiveLevel() == 10:
return True
else:
return False
@@ -50,60 +48,75 @@ class ConfServer:
return int(round(timetoconvert * 1000))
def confserver_app(self):
- self.app = web.Application(loop=asyncio.get_event_loop(), middlewares=[
- self.log_all_requests,
- ])
- aiohttp_jinja2.setup(self.app, loader=jinja2.FileSystemLoader(os.path.join(bumper.bumper_dir,"bumper","web","templates")))
+ self.app = web.Application(
+ loop=asyncio.get_event_loop(),
+ middlewares=[
+ self.log_all_requests,
+ ],
+ )
+ aiohttp_jinja2.setup(
+ self.app,
+ loader=jinja2.FileSystemLoader(
+ os.path.join(bumper.bumper_dir, "bumper", "web", "templates")
+ ),
+ )
self.app.add_routes(
[
web.get("", self.handle_base, name="base"),
- web.get("/bot/remove/{did}", self.handle_RemoveBot, name='remove-bot'),
- web.get("/client/remove/{resource}", self.handle_RemoveClient, name='remove-client'),
- web.get("/restart_{service}", self.handle_RestartService, name='restart-service'),
+ web.get("/bot/remove/{did}", self.handle_RemoveBot, name="remove-bot"),
+ web.get(
+ "/client/remove/{resource}",
+ self.handle_RemoveClient,
+ name="remove-client",
+ ),
+ web.get(
+ "/restart_{service}",
+ self.handle_RestartService,
+ name="restart-service",
+ ),
web.post("/lookup.do", self.handle_lookup),
web.post("/newauth.do", self.handle_newauth),
]
)
# common api paths
- api_v1 = {"prefix": "/v1/", "app": web.Application()} # for /v1/
- api_v2 = {"prefix": "/v2/", "app": web.Application()} # for /v2/
- portal_api = {"prefix": "/api/", "app": web.Application()} # for /api/
- upload_api = {"prefix": "/upload/", "app": web.Application()} # for /upload/
-
+ api_v1 = {"prefix": "/v1/", "app": web.Application()} # for /v1/
+ api_v2 = {"prefix": "/v2/", "app": web.Application()} # for /v2/
+ portal_api = {"prefix": "/api/", "app": web.Application()} # for /api/
+ upload_api = {"prefix": "/upload/", "app": web.Application()} # for /upload/
+
apis = {
"api_v1": api_v1,
"api_v2": api_v2,
"portal_api": portal_api,
"upload_api": upload_api,
-
}
-
+
# Load plugins
for plug in bumper.discovered_plugins:
- if isinstance(bumper.discovered_plugins[plug].plugin, bumper.plugins.ConfServerApp):
- plugin = bumper.discovered_plugins[plug].plugin
- if plugin.plugin_type == "sub_api": # app or sub_api
+ if isinstance(
+ bumper.discovered_plugins[plug].plugin, bumper.plugins.ConfServerApp
+ ):
+ plugin = bumper.discovered_plugins[plug].plugin
+ if plugin.plugin_type == "sub_api": # app or sub_api
if plugin.sub_api in apis:
if plugin.routes:
logging.debug(f"Adding confserver sub_api ({plugin.name})")
apis[plugin.sub_api]["app"].add_routes(plugin.routes)
-
+
elif plugin.plugin_type == "app":
if plugin.path_prefix and plugin.app:
logging.debug(f"Adding confserver plugin ({plugin.name})")
- self.app.add_subapp(plugin.path_prefix, plugin.app)
-
- for api in apis:
+ self.app.add_subapp(plugin.path_prefix, plugin.app)
+
+ for api in apis:
self.app.add_subapp(apis[api]["prefix"], apis[api]["app"])
- #for resource in self.app.router.resources():
+ # for resource in self.app.router.resources():
# print(resource)
-
-
- async def start_site(self, app, address='localhost', port=8080, usessl=False):
+ async def start_site(self, app, address="localhost", port=8080, usessl=False):
runner = web.AppRunner(app)
self.runners.append(runner)
await runner.setup()
@@ -118,9 +131,7 @@ class ConfServer:
)
else:
- site = web.TCPSite(
- runner, host=address, port=port
- )
+ site = web.TCPSite(runner, host=address, port=port)
await site.start()
@@ -178,12 +189,14 @@ class ConfServer:
mq_sessions = []
for sess in mqttserver._sessions:
tmpsess = []
- tmpsess.append({
- "username": mqttserver._sessions[sess][0].username,
- "client_id": mqttserver._sessions[sess][0].client_id,
- "state": mqttserver._sessions[sess][0].transitions.state,
- })
-
+ tmpsess.append(
+ {
+ "username": mqttserver._sessions[sess][0].username,
+ "client_id": mqttserver._sessions[sess][0].client_id,
+ "state": mqttserver._sessions[sess][0].transitions.state,
+ }
+ )
+
mq_sessions.append(tmpsess)
all = {
"bots": bots,
@@ -198,10 +211,10 @@ class ConfServer:
]
},
],
- "xmpp_server": xmppserver
- }
- resp = aiohttp_jinja2.render_template('home.jinja2', request, context=all)
- #return web.json_response(all)
+ "xmpp_server": xmppserver,
+ }
+ resp = aiohttp_jinja2.render_template("home.jinja2", request, context=all)
+ # return web.json_response(all)
return resp
except Exception as e:
@@ -233,7 +246,7 @@ class ConfServer:
except Exception as e:
confserverlog.error(f"Request body not json: {e} - {e.doc}")
postbody = e.doc
-
+
else:
postbody = await request.post()
@@ -252,7 +265,7 @@ class ConfServer:
to_log["response"]["body"] = f"{json.loads(response.body)}"
confserverlog.debug(json.dumps(to_log))
-
+
return response
except web.HTTPNotFound as notfound:
@@ -263,7 +276,7 @@ class ConfServer:
except Exception as e:
confserverlog.exception(f"{e}")
confserverlog.error(json.dumps(to_log))
- return e
+ return e
else:
return await handler(request)
@@ -274,24 +287,26 @@ class ConfServer:
asyncio.create_task(bumper.mqtt_helperbot.start_helper_bot())
async def restart_MQTT(self):
-
- if not (bumper.mqtt_server.broker.transitions.state == "stopped" or bumper.mqtt_server.broker.transitions.state == "not_started"):
+
+ if not (
+ bumper.mqtt_server.broker.transitions.state == "stopped"
+ or bumper.mqtt_server.broker.transitions.state == "not_started"
+ ):
# close session writers - this was required so bots would reconnect properly after restarting
- for sess in list(bumper.mqtt_server.broker._sessions):
+ for sess in list(bumper.mqtt_server.broker._sessions):
sessobj = bumper.mqtt_server.broker._sessions[sess][1]
if sessobj.session.transitions.state == "connected":
await sessobj.writer.close()
- #await bumper.mqtt_server.broker.shutdown()
+ # await bumper.mqtt_server.broker.shutdown()
aloop = asyncio.get_event_loop()
aloop.call_later(
- 0.1, lambda: asyncio.create_task(bumper.mqtt_server.broker.shutdown())
+ 0.1, lambda: asyncio.create_task(bumper.mqtt_server.broker.shutdown())
) # In .1 seconds shutdown broker
-
aloop = asyncio.get_event_loop()
aloop.call_later(
- 1.5, lambda: asyncio.create_task(bumper.mqtt_server.broker_coro())
+ 1.5, lambda: asyncio.create_task(bumper.mqtt_server.broker_coro())
) # In 1.5 seconds start broker
async def restart_XMPP(self):
@@ -310,7 +325,7 @@ class ConfServer:
aloop.call_later(
5, lambda: asyncio.create_task(self.restart_Helper())
) # In 5 seconds restart Helperbot
-
+
return web.json_response({"status": "complete"})
elif service == "XMPPServer":
await self.restart_XMPP()
@@ -333,29 +348,27 @@ class ConfServer:
except Exception as e:
confserverlog.exception(f"{e}")
- pass
+ pass
async def handle_RemoveClient(self, request):
- try:
+ try:
resource = request.match_info.get("resource", "")
bumper.client_remove(resource)
if bumper.client_get(resource):
- return web.json_response({"status": "failed to remove client"})
+ return web.json_response({"status": "failed to remove client"})
else:
- return web.json_response({"status": "successfully removed client"})
+ return web.json_response({"status": "successfully removed client"})
except Exception as e:
confserverlog.exception(f"{e}")
- pass
+ pass
async def handle_login(self, request):
try:
user_devid = request.match_info.get("devid", "")
countrycode = request.match_info.get("country", "us")
apptype = request.match_info.get("apptype", "")
- confserverlog.info(
- f"client with devid {user_devid} attempting login"
- )
+ confserverlog.info(f"client with devid {user_devid} attempting login")
if bumper.use_auth:
if (
not user_devid == ""
@@ -476,11 +489,7 @@ class ConfServer:
confserverlog.debug(postbody)
- body = {
- "authCode": postbody["itToken"],
- "result": "ok",
- "todo": "result"
- }
+ body = {"authCode": postbody["itToken"], "result": "ok", "todo": "result"}
return web.json_response(body)
@@ -500,13 +509,15 @@ class ConfServer:
pass
def get_milli_time(self, timetoconvert):
- return int(round(timetoconvert * 1000))
+ return int(round(timetoconvert * 1000))
class ConfServer_AuthHandler:
def __init__(self):
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
pass
-
+
def generate_token(self, user):
try:
tmpaccesstoken = uuid.uuid4().hex
@@ -523,80 +534,80 @@ class ConfServer:
return tmpauthcode
except Exception as e:
- confserverlog.exception(f"{e}")
-
+ confserverlog.exception(f"{e}")
async def login(self, request):
- try:
- user_devid = request.match_info.get("devid", "")
- countrycode = request.match_info.get("country", "us")
- apptype = request.match_info.get("apptype", "")
- confserverlog.info(
- f"client with devid {user_devid} attempting login"
- )
- if bumper.use_auth:
- if (
- not user_devid == ""
- ): # Performing basic "auth" using devid, super insecure
- user = bumper.user_by_deviceid(user_devid)
- if "checkLogin" in request.path:
- self.check_token(
- apptype, countrycode, user, request.query["accessToken"]
+ try:
+ user_devid = request.match_info.get("devid", "")
+ countrycode = request.match_info.get("country", "us")
+ apptype = request.match_info.get("apptype", "")
+ confserverlog.info(f"client with devid {user_devid} attempting login")
+ if bumper.use_auth:
+ if (
+ not user_devid == ""
+ ): # Performing basic "auth" using devid, super insecure
+ user = bumper.user_by_deviceid(user_devid)
+ if "checkLogin" in request.path:
+ self.check_token(
+ apptype, countrycode, user, request.query["accessToken"]
+ )
+ 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:
- 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
+ login_details = EcoVacs_Login()
- else:
- login_details = EcoVacs_Login()
+ # Deactivate old tokens and authcodes
+ bumper.user_revoke_expired_tokens(user["userid"])
- # 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"
- 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": API_ERRORS[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": self.get_milli_time(
+ datetime.utcnow().timestamp()
+ ),
+ }
- body = {
- "code": API_ERRORS[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": self.get_milli_time(datetime.utcnow().timestamp()),
- }
+ return web.json_response(body)
- return web.json_response(body)
+ body = {
+ "code": bumper.ERR_USER_NOT_ACTIVATED,
+ "data": None,
+ "msg": "当前密码错误",
+ "time": self.get_milli_time(datetime.utcnow().timestamp()),
+ }
- body = {
- "code": bumper.ERR_USER_NOT_ACTIVATED,
- "data": None,
- "msg": "当前密码错误",
- "time": self.get_milli_time(datetime.utcnow().timestamp()),
- }
+ return web.json_response(body)
- return web.json_response(body)
-
- else:
- return web.json_response(
- self._auth_any(user_devid, apptype, countrycode, request)
- )
-
- except Exception as e:
- confserverlog.exception(f"{e}")
+ else:
+ return web.json_response(
+ self._auth_any(user_devid, apptype, countrycode, request)
+ )
+ except Exception as e:
+ confserverlog.exception(f"{e}")
async def get_AuthCode(self, request):
try:
@@ -660,7 +671,7 @@ class ConfServer:
return web.json_response(body)
except Exception as e:
- confserverlog.exception(f"{e}")
+ confserverlog.exception(f"{e}")
def check_token(self, apptype, countrycode, user, token):
try:
@@ -705,7 +716,7 @@ class ConfServer:
return web.json_response(body)
except Exception as e:
- confserverlog.exception(f"{e}")
+ confserverlog.exception(f"{e}")
def _auth_any(self, devid, apptype, country, request):
try:
@@ -719,7 +730,9 @@ class ConfServer:
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.loginName = "fusername_{}".format(
+ tmpuser["userid"]
+ )
login_details.mobile = None
else:
login_details = EcoVacs_Login()
@@ -736,7 +749,9 @@ class ConfServer:
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.loginName = "fusername_{}".format(
+ tmpuser["userid"]
+ )
login_details.mobile = None
else:
login_details = EcoVacs_Login()
@@ -754,7 +769,9 @@ class ConfServer:
else:
confserverlog.error(f"No DID for bot: {bot}")
- 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(
apptype, countrycode, tmpuser, request.query["accessToken"]
)
@@ -782,8 +799,7 @@ class ConfServer:
return body
except Exception as e:
- confserverlog.exception(f"{e}")
-
+ confserverlog.exception(f"{e}")
def getUserAccountInfo(self, request):
try:
@@ -851,7 +867,7 @@ class ConfServer:
return web.json_response(body)
except Exception as e:
- confserverlog.exception(f"{e}")
+ confserverlog.exception(f"{e}")
async def logout(self, request):
try:
@@ -859,7 +875,9 @@ class ConfServer:
if not user_devid == "":
user = bumper.user_by_deviceid(user_devid)
if user:
- if bumper.check_token(user["userid"], request.query["accessToken"]):
+ if bumper.check_token(
+ user["userid"], request.query["accessToken"]
+ ):
# Deactivate old tokens and authcodes
bumper.user_revoke_token(
user["userid"], request.query["accessToken"]
@@ -875,4 +893,4 @@ class ConfServer:
return web.json_response(body)
except Exception as e:
- confserverlog.exception(f"{e}")
\ No newline at end of file
+ confserverlog.exception(f"{e}")
diff --git a/bumper/db.py b/bumper/db.py
index 075ada1..09e99ef 100644
--- a/bumper/db.py
+++ b/bumper/db.py
@@ -8,7 +8,13 @@ from tinydb import TinyDB, Query
import bumper
from .util import get_logger
-from bumper.models import VacBotClient, VacBotDevice, BumperUser, EcoVacsHomeProducts, OAuth
+from bumper.models import (
+ VacBotClient,
+ VacBotDevice,
+ BumperUser,
+ EcoVacsHomeProducts,
+ OAuth,
+)
bumperlog = get_logger("bumper")
@@ -265,8 +271,8 @@ def check_authcode(uid, authcode):
tmpauth = tokens.get(
(Query().authcode == authcode)
& ( # Match authcode
- (Query().userid == uid.replace("fuid_", ""))
- | (Query().userid == f"fuid_{uid}")
+ (Query().userid == uid.replace("fuid_", ""))
+ | (Query().userid == f"fuid_{uid}")
) # Userid with or without fuid_
)
if tmpauth:
@@ -279,7 +285,8 @@ def loginByItToken(authcode):
bumperlog.debug(f"Checking for authcode: {authcode}")
tokens = db_get().table("tokens")
tmpauth = tokens.get(
- Query().authcode == authcode
+ Query().authcode
+ == authcode
# & ( # Match authcode
# (Query().userid == uid.replace("fuid_", ""))
# | (Query().userid == "fuid_{}".format(uid))
@@ -297,8 +304,8 @@ def check_token(uid, token):
tmpauth = tokens.get(
(Query().token == token)
& ( # Match token
- (Query().userid == uid.replace("fuid_", ""))
- | (Query().userid == f"fuid_{uid}")
+ (Query().userid == uid.replace("fuid_", ""))
+ | (Query().userid == f"fuid_{uid}")
) # Userid with or without fuid_
)
if tmpauth:
@@ -326,11 +333,9 @@ def bot_add(sn, did, devclass, resource, company):
bot = bot_get(did)
if not bot: # Not existing bot in database
if (
- not devclass == "" or "@" not in sn or "tmp" not in sn
+ not devclass == "" or "@" not in sn or "tmp" not in sn
): # try to prevent bad additions to the bot list
- bumperlog.info(
- f"Adding new bot with SN: {newbot.name} DID: {newbot.did}"
- )
+ bumperlog.info(f"Adding new bot with SN: {newbot.name} DID: {newbot.did}")
bot_full_upsert(newbot.asdict())
@@ -357,7 +362,11 @@ def bot_toEcoVacsHome_JSON(bot): # EcoVacs Home
bot["pip"] = botprod["product"]["_id"]
bot["deviceName"] = botprod["product"]["name"]
bot["materialNo"] = botprod["product"]["materialNo"]
- bot["product_category"] = "DEEBOT" if botprod["product"]["name"].startswith("DEEBOT") else "UNKNOWN"
+ bot["product_category"] = (
+ "DEEBOT"
+ if botprod["product"]["name"].startswith("DEEBOT")
+ else "UNKNOWN"
+ )
# bot["updateInfo"] = {
# "changeLog": "",
# "needUpdate": False
diff --git a/bumper/models.py b/bumper/models.py
index 0a3c533..2a79321 100644
--- a/bumper/models.py
+++ b/bumper/models.py
@@ -8,7 +8,7 @@ import bumper
class VacBotDevice:
def __init__(
- self, did="", vac_bot_device_class="", resource="", name="", nick="", company=""
+ self, did="", vac_bot_device_class="", resource="", name="", nick="", company=""
):
self.vac_bot_device_class = vac_bot_device_class
self.company = company
@@ -101,7 +101,9 @@ class OAuth:
oauth = OAuth()
oauth.userId = userId
oauth.access_token = uuid.uuid4().hex
- oauth.expire_at = f"{datetime.utcnow() + timedelta(days=bumper.oauth_validity_days)}"
+ oauth.expire_at = (
+ f"{datetime.utcnow() + timedelta(days=bumper.oauth_validity_days)}"
+ )
oauth.refresh_token = uuid.uuid4().hex
return oauth
@@ -110,8 +112,11 @@ class OAuth:
def toResponse(self):
data = self.__dict__
- data["expire_at"] = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time(
- datetime.fromisoformat(self.expire_at).timestamp())
+ data[
+ "expire_at"
+ ] = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time(
+ datetime.fromisoformat(self.expire_at).timestamp()
+ )
return data
@@ -132,10 +137,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": False,
- "alexa": False
+ "alexa": False,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d2d996c4d60de0001eaf2b5"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d2d996c4d60de0001eaf2b5",
+ },
},
{
"classid": "vsc5ia",
@@ -151,10 +156,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5c874326280fda0001770d2a"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5c874326280fda0001770d2a",
+ },
},
{
"classid": "zi1uwd",
@@ -170,10 +175,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5da834a8d66cd10001f58265"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5da834a8d66cd10001f58265",
+ },
},
{
"classid": "12baap",
@@ -189,10 +194,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606425981269020008a9627b"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606425981269020008a9627b",
+ },
},
{
"classid": "02uwxm",
@@ -208,10 +213,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b1dddc48bc45700014035a1"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b1dddc48bc45700014035a1",
+ },
},
{
"classid": "eyi9jv",
@@ -227,10 +232,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b7b65f176f7f10001e9a0c2"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b7b65f176f7f10001e9a0c2",
+ },
},
{
"classid": "9rft3c",
@@ -246,10 +251,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": False,
- "alexa": False
+ "alexa": False,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/6062795ad18cbd0008e2fce8"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/6062795ad18cbd0008e2fce8",
+ },
},
{
"classid": "141",
@@ -265,10 +270,10 @@ EcoVacsHomeProducts = [
"share": False,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c2aa64d60de0001eaf1f6"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c2aa64d60de0001eaf1f6",
+ },
},
{
"classid": "fqxoiu",
@@ -284,10 +289,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/605b059217c95b0008ff20d4"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/605b059217c95b0008ff20d4",
+ },
},
{
"classid": "u6eqoa",
@@ -303,10 +308,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606425a11269020008a9627d"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606425a11269020008a9627d",
+ },
},
{
"classid": "dl8fht",
@@ -322,10 +327,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5acc32067c295c0001876eea"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5acc32067c295c0001876eea",
+ },
},
{
"classid": "yna5xi",
@@ -341,10 +346,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606278df4a84d700082b39f1"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606278df4a84d700082b39f1",
+ },
},
{
"classid": "123",
@@ -360,10 +365,10 @@ EcoVacsHomeProducts = [
"share": False,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c150dba13eb00013feaae"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c150dba13eb00013feaae",
+ },
},
{
"classid": "140",
@@ -379,10 +384,10 @@ EcoVacsHomeProducts = [
"share": False,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c152f4d60de0001eaf1f4"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c152f4d60de0001eaf1f4",
+ },
},
{
"classid": "q1v5dn",
@@ -398,10 +403,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": False,
- "alexa": False
+ "alexa": False,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d83375f6b6a570001569e26"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d83375f6b6a570001569e26",
+ },
},
{
"classid": "16wdph",
@@ -417,10 +422,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d280ce3350e7a0001e84c95"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d280ce3350e7a0001e84c95",
+ },
},
{
"classid": "rvo6ev",
@@ -436,10 +441,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606426feb0a931000860fad5"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606426feb0a931000860fad5",
+ },
},
{
"classid": "09m4bu",
@@ -455,10 +460,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ef31b8cee3c1200075b6f67"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ef31b8cee3c1200075b6f67",
+ },
},
{
"classid": "y2qy3m",
@@ -474,10 +479,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606425784a84d700082b39f6"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606425784a84d700082b39f6",
+ },
},
{
"classid": "0xyhhr",
@@ -493,10 +498,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d117d4f0ac6ad00012b792d"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d117d4f0ac6ad00012b792d",
+ },
},
{
"classid": "ipzjy0",
@@ -512,10 +517,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606426c64a84d700082b39fa"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606426c64a84d700082b39fa",
+ },
},
{
"classid": "hsgwhi",
@@ -531,10 +536,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": False,
- "alexa": False
+ "alexa": False,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5e731a4a06f6de700464c69d"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5e731a4a06f6de700464c69d",
+ },
},
{
"classid": "h18jkh",
@@ -550,10 +555,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5e8e8d146482551d72530e47"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5e8e8d146482551d72530e47",
+ },
},
{
"classid": "126",
@@ -569,10 +574,10 @@ EcoVacsHomeProducts = [
"share": False,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ca32ab2e9e9270001354b3d"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ca32ab2e9e9270001354b3d",
+ },
},
{
"classid": "x5d34r",
@@ -588,10 +593,10 @@ EcoVacsHomeProducts = [
"share": False,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/605053e7fc527c00087fda1e"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/605053e7fc527c00087fda1e",
+ },
},
{
"classid": "ls1ok3",
@@ -607,10 +612,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ba4a2cb6c2f120001c32839"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ba4a2cb6c2f120001c32839",
+ },
},
{
"classid": "y79a7u",
@@ -626,10 +631,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b04c0217ccd1a0001e1f6a7"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b04c0217ccd1a0001e1f6a7",
+ },
},
{
"classid": "vi829v",
@@ -645,10 +650,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606278d3fc527c00087fdb08"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606278d3fc527c00087fdb08",
+ },
},
{
"classid": "55aiho",
@@ -664,10 +669,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/605be27250928b0007c13264"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/605be27250928b0007c13264",
+ },
},
{
"classid": "gd4uut",
@@ -683,10 +688,10 @@ EcoVacsHomeProducts = [
"share": False,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5e8da019032edd9008c66bf0"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5e8da019032edd9008c66bf0",
+ },
},
{
"classid": "130",
@@ -702,10 +707,10 @@ EcoVacsHomeProducts = [
"share": False,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d4b7640de51dd0001fee131"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d4b7640de51dd0001fee131",
+ },
},
{
"classid": "2pv572",
@@ -721,10 +726,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d1474632a6bd50001b5b6f3"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d1474632a6bd50001b5b6f3",
+ },
},
{
"classid": "xb83mv",
@@ -740,10 +745,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d3fe649de51dd0001fee0de"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d3fe649de51dd0001fee0de",
+ },
},
{
"classid": "ar5bjb",
@@ -759,10 +764,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5e58a2df36e8f39e318f031d"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5e58a2df36e8f39e318f031d",
+ },
},
{
"classid": "7j1tu6",
@@ -778,10 +783,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/6064260545505e0008e5cb49"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/6064260545505e0008e5cb49",
+ },
},
{
"classid": "ts2ofl",
@@ -797,10 +802,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606425dfd18cbd0008e2fcf3"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606425dfd18cbd0008e2fcf3",
+ },
},
{
"classid": "125",
@@ -816,10 +821,10 @@ EcoVacsHomeProducts = [
"share": False,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c14414d60de0001eaf1f2"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c14414d60de0001eaf1f2",
+ },
},
{
"classid": "jh3ry2",
@@ -835,10 +840,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": False,
- "alexa": False
+ "alexa": False,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/6049b34d1269020008a95aef"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/6049b34d1269020008a95aef",
+ },
},
{
"classid": "wlqdkp",
@@ -854,10 +859,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/6064263ad18cbd0008e2fcf4"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/6064263ad18cbd0008e2fcf4",
+ },
},
{
"classid": "c0lwyn",
@@ -873,10 +878,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606425ab4a84d700082b39f7"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606425ab4a84d700082b39f7",
+ },
},
{
"classid": "emzppx",
@@ -892,10 +897,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5c931fef280fda0001770d7e"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5c931fef280fda0001770d7e",
+ },
},
{
"classid": "115",
@@ -911,10 +916,10 @@ EcoVacsHomeProducts = [
"share": False,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5cf711aeb0acfc000179ff8a"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5cf711aeb0acfc000179ff8a",
+ },
},
{
"classid": "jr3pqa",
@@ -930,10 +935,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b5ac4cc8d5a56000111e769"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b5ac4cc8d5a56000111e769",
+ },
},
{
"classid": "142",
@@ -949,10 +954,10 @@ EcoVacsHomeProducts = [
"share": False,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ca1ca79e9e9270001354b2d"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ca1ca79e9e9270001354b2d",
+ },
},
{
"classid": "aqdd5p",
@@ -968,10 +973,10 @@ EcoVacsHomeProducts = [
"share": False,
"tmjl": False,
"assistant": False,
- "alexa": False
+ "alexa": False,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5cb7cfbab72c4d00010e5fc7"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5cb7cfbab72c4d00010e5fc7",
+ },
},
{
"classid": "152",
@@ -987,10 +992,10 @@ EcoVacsHomeProducts = [
"share": False,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d4b7628de51dd0001fee12f"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d4b7628de51dd0001fee12f",
+ },
},
{
"classid": "d0cnel",
@@ -1006,10 +1011,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d157f9f77a3a60001051f69"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d157f9f77a3a60001051f69",
+ },
},
{
"classid": "u4h1uk",
@@ -1025,10 +1030,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606425bed18cbd0008e2fcf2"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606425bed18cbd0008e2fcf2",
+ },
},
{
"classid": "3ab24g",
@@ -1044,10 +1049,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ef31b80f5dcdf000767cf4d"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ef31b80f5dcdf000767cf4d",
+ },
},
{
"classid": "9akc61",
@@ -1063,10 +1068,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5c932067280fda0001770d7f"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5c932067280fda0001770d7f",
+ },
},
{
"classid": "159",
@@ -1082,10 +1087,10 @@ EcoVacsHomeProducts = [
"share": False,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d4b7606de51dd0001fee12d"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d4b7606de51dd0001fee12d",
+ },
},
{
"classid": "b742vd",
@@ -1101,10 +1106,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5e8e93a7032edd3f5ec66d4a"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5e8e93a7032edd3f5ec66d4a",
+ },
},
{
"classid": "uv242z",
@@ -1120,10 +1125,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b5ac4e45f21100001882bb9"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b5ac4e45f21100001882bb9",
+ },
},
{
"classid": "155",
@@ -1139,10 +1144,10 @@ EcoVacsHomeProducts = [
"share": False,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5cd4ca505b032200015a455d"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5cd4ca505b032200015a455d",
+ },
},
{
"classid": "1qdu4z",
@@ -1158,10 +1163,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": False,
- "alexa": False
+ "alexa": False,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5e71c7df298f0d9cabfef86f"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5e71c7df298f0d9cabfef86f",
+ },
},
{
"classid": "4zfacv",
@@ -1177,10 +1182,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5c778731280fda0001770ba0"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5c778731280fda0001770ba0",
+ },
},
{
"classid": "nq9yhl",
@@ -1196,10 +1201,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606426ebb0a931000860fad4"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606426ebb0a931000860fad4",
+ },
},
{
"classid": "m7lqzi",
@@ -1215,10 +1220,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": False,
- "alexa": False
+ "alexa": False,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c63a5ba13eb00013feab7"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c63a5ba13eb00013feab7",
+ },
},
{
"classid": "r8ead0",
@@ -1234,10 +1239,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5c93204b63023c0001e7faa7"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5c93204b63023c0001e7faa7",
+ },
},
{
"classid": "jjccwk",
@@ -1253,10 +1258,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d3aa309ba13eb00013feb69"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5d3aa309ba13eb00013feb69",
+ },
},
{
"classid": "129",
@@ -1272,10 +1277,10 @@ EcoVacsHomeProducts = [
"share": False,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ca31df112851900016858c0"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ca31df112851900016858c0",
+ },
},
{
"classid": "165",
@@ -1291,10 +1296,10 @@ EcoVacsHomeProducts = [
"share": False,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ca32a1012851900016858c6"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ca32a1012851900016858c6",
+ },
},
{
"classid": "jffnlf",
@@ -1310,10 +1315,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": False,
- "alexa": False
+ "alexa": False,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5e53207a26be71596c4b55cd"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5e53207a26be71596c4b55cd",
+ },
},
{
"classid": "d4v1pm",
@@ -1329,10 +1334,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606426254a84d700082b39f9"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606426254a84d700082b39f9",
+ },
},
{
"classid": "34vhpm",
@@ -1348,10 +1353,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/605050031269020008a95af9"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/605050031269020008a95af9",
+ },
},
{
"classid": "tpnwyu",
@@ -1367,10 +1372,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/6050503e1269020008a95afa"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/6050503e1269020008a95afa",
+ },
},
{
"classid": "wgxm70",
@@ -1386,10 +1391,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5edf2bbedb28cc00062f8bd7"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5edf2bbedb28cc00062f8bd7",
+ },
},
{
"classid": "1zqysa",
@@ -1405,10 +1410,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/6064258d1269020008a9627a"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/6064258d1269020008a9627a",
+ },
},
{
"classid": "chmi0g",
@@ -1424,10 +1429,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606425821269020008a96279"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/606425821269020008a96279",
+ },
},
{
"classid": "p5nx9u",
@@ -1443,10 +1448,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5f59e774c0f03a0008ee72e0"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5f59e774c0f03a0008ee72e0",
+ },
},
{
"classid": "n6cwdb",
@@ -1462,10 +1467,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/60627a92fc527c00087fdb0a"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/60627a92fc527c00087fdb0a",
+ },
},
{
"classid": "lhbd50",
@@ -1481,10 +1486,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/603f51243b03f50007b6c2ca"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/603f51243b03f50007b6c2ca",
+ },
},
{
"classid": "ucn2xe",
@@ -1500,10 +1505,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/603f510e3b03f50007b6c2c9"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/603f510e3b03f50007b6c2c9",
+ },
},
{
"classid": "0bdtzz",
@@ -1519,10 +1524,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5fa105bbd16a99000667eb52"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5fa105bbd16a99000667eb52",
+ },
},
{
"classid": "r5zxjr",
@@ -1538,10 +1543,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/60627c09b0a931000860facd"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/60627c09b0a931000860facd",
+ },
},
{
"classid": "r5y7re",
@@ -1557,10 +1562,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/60627a9cb0a931000860fac7"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/60627a9cb0a931000860fac7",
+ },
},
{
"classid": "snxbvc",
@@ -1576,10 +1581,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/60627bbfb0a931000860fac9"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/60627bbfb0a931000860fac9",
+ },
},
{
"classid": "7bryc5",
@@ -1595,10 +1600,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5fb474d4d16a99000667edd9"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5fb474d4d16a99000667edd9",
+ },
},
{
"classid": "b2jqs4",
@@ -1614,10 +1619,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5feaeb27d4cb3a0006679047"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5feaeb27d4cb3a0006679047",
+ },
},
{
"classid": "yu362x",
@@ -1633,10 +1638,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/60627bde50928b0007c13273"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/60627bde50928b0007c13273",
+ },
},
{
"classid": "ifbw08",
@@ -1652,10 +1657,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5feaeb47d4cb3a0006679048"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5feaeb47d4cb3a0006679048",
+ },
},
{
"classid": "85as7h",
@@ -1671,10 +1676,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5feaeb585f437d0008e0e00c"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5feaeb585f437d0008e0e00c",
+ },
},
{
"classid": "ty84oi",
@@ -1690,10 +1695,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/60627bcafc527c00087fdb0c"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/60627bcafc527c00087fdb0c",
+ },
},
{
"classid": "36xnxf",
@@ -1709,10 +1714,10 @@ EcoVacsHomeProducts = [
"share": True,
"tmjl": False,
"assistant": True,
- "alexa": True
+ "alexa": True,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/60627bd517c95b0008ff20ec"
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/60627bd517c95b0008ff20ec",
+ },
},
{
"classid": "2pj946",
@@ -1728,11 +1733,11 @@ EcoVacsHomeProducts = [
"share": False,
"tmjl": False,
"assistant": False,
- "alexa": False
+ "alexa": False,
},
- "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/6049b3631269020008a95af0"
- }
- }
+ "iconUrl": "https://portal-ww.ecouser.net/api/pim/file/get/6049b3631269020008a95af0",
+ },
+ },
]
RETURN_API_SUCCESS = "0000"
diff --git a/bumper/mqttserver.py b/bumper/mqttserver.py
index f850ffc..8b9a90f 100644
--- a/bumper/mqttserver.py
+++ b/bumper/mqttserver.py
@@ -22,7 +22,6 @@ boterrorlog = get_logger("boterror")
class CommandDto:
-
def __init__(self, payload_type: str) -> None:
self._payload_type = payload_type
self._event = asyncio.Event()
@@ -44,8 +43,9 @@ class MQTTHelperBot:
Client = None
def __init__(self, host: str, port: int, timeout: float = 60):
- self._commands: MutableMapping[str, CommandDto] = TTLCache(maxsize=timeout * 60,
- ttl=timeout*1.1)
+ self._commands: MutableMapping[str, CommandDto] = TTLCache(
+ maxsize=timeout * 60, ttl=timeout * 1.1
+ )
self._host = host
self._port = port
self.client_id = "helperbot@bumper/helperbot"
@@ -56,16 +56,20 @@ class MQTTHelperBot:
return self._commands
@property
- def timeout(self)->float:
+ def timeout(self) -> float:
return self._timeout
async def start_helper_bot(self):
try:
if self.Client is None:
- self.Client = MQTTClient(client_id=self.client_id,
- config={"check_hostname": False, "reconnect_retries": 20})
+ self.Client = MQTTClient(
+ client_id=self.client_id,
+ config={"check_hostname": False, "reconnect_retries": 20},
+ )
- await self.Client.connect(f"mqtts://{self._host}:{self._port}/", cafile=bumper.ca_cert)
+ await self.Client.connect(
+ f"mqtts://{self._host}:{self._port}/", cafile=bumper.ca_cert
+ )
await self.Client.subscribe(
[
("iot/p2p/+/+/+/+/helperbot/bumper/helperbot/+/+/+", QOS_0),
@@ -78,12 +82,10 @@ class MQTTHelperBot:
async def _wait_for_resp(self, command_dto: CommandDto, request_id: str):
try:
- payload = await asyncio.wait_for(command_dto.wait_for_response(), timeout=self.timeout)
- return {
- "id": request_id,
- "ret": "ok",
- "resp": payload
- }
+ payload = await asyncio.wait_for(
+ command_dto.wait_for_response(), timeout=self.timeout
+ )
+ return {"id": request_id, "ret": "ok", "resp": payload}
except asyncio.TimeoutError:
helperbotlog.debug("wait_for_resp timeout reached")
except asyncio.CancelledError as e:
@@ -143,9 +145,7 @@ class MQTTServer:
self._port = port
# Default config opts
- passwd_file = os.path.join(
- os.path.join(bumper.data_dir, "passwd")
- )
+ passwd_file = os.path.join(os.path.join(bumper.data_dir, "passwd"))
# For file auth, set user:hash in passwd file see
# (https://hbmqtt.readthedocs.io/en/latest/references/hbmqtt.html#configuration-example)
@@ -156,7 +156,9 @@ class MQTTServer:
passwd_file = kwargs["password_file"]
elif key == "allow_anonymous":
- allow_anon = kwargs["allow_anonymous"] # Set to True to allow anonymous authentication
+ allow_anon = kwargs[
+ "allow_anonymous"
+ ] # Set to True to allow anonymous authentication
# The below adds a plugin to the hbmqtt.broker.plugins without having to futz with setup.py
distribution = pkg_resources.Distribution("hbmqtt.broker.plugins")
@@ -181,7 +183,9 @@ class MQTTServer:
"auth": {
"allow-anonymous": allow_anon,
"password-file": passwd_file,
- "plugins": ["bumper"], # Bumper plugin provides auth and handling of bots/clients connecting
+ "plugins": [
+ "bumper"
+ ], # Bumper plugin provides auth and handling of bots/clients connecting
},
"topic-check": {"enabled": False},
}
@@ -235,7 +239,7 @@ class BumperMQTTServer_Plugin:
if "@" in client_id:
didsplit = str(client_id).split("@")
if not ( # if ecouser or bumper aren't in details it is a bot
- "ecouser" in didsplit[1] or "bumper" in didsplit[1]
+ "ecouser" in didsplit[1] or "bumper" in didsplit[1]
):
tmpbotdetail = str(didsplit[1]).split("/")
bumper.bot_add(
@@ -245,8 +249,10 @@ class BumperMQTTServer_Plugin:
tmpbotdetail[1],
"eco-ng",
)
- mqttserverlog.info(f"Bumper Authentication Success - Bot - SN: {username} - DID: {didsplit[0]}"
- f" - Class: {tmpbotdetail[0]}")
+ mqttserverlog.info(
+ f"Bumper Authentication Success - Bot - SN: {username} - DID: {didsplit[0]}"
+ f" - Class: {tmpbotdetail[0]}"
+ )
authenticated = True
else:
tmpclientdetail = str(didsplit[1]).split("/")
@@ -255,27 +261,40 @@ class BumperMQTTServer_Plugin:
resource = tmpclientdetail[1]
if userid == "helperbot":
- mqttserverlog.info(f"Bumper Authentication Success - Helperbot: {client_id}")
+ mqttserverlog.info(
+ f"Bumper Authentication Success - Helperbot: {client_id}"
+ )
authenticated = True
- elif bumper.check_authcode(didsplit[0], password) or not bumper.use_auth:
+ elif (
+ bumper.check_authcode(didsplit[0], password)
+ or not bumper.use_auth
+ ):
bumper.client_add(userid, realm, resource)
- mqttserverlog.info(f"Bumper Authentication Success - Client - Username: {username} - "
- f"ClientID: {client_id}")
+ mqttserverlog.info(
+ f"Bumper Authentication Success - Client - Username: {username} - "
+ f"ClientID: {client_id}"
+ )
authenticated = True
- # Check for File Auth
- if username and not authenticated: # If there is a username and it isn't already authenticated
+ # Check for File Auth
+ if (
+ username and not authenticated
+ ): # If there is a username and it isn't already authenticated
hash = self._users.get(username, None)
if hash: # If there is a matching entry in passwd, check hash
authenticated = pwd_context.verify(password, hash)
if authenticated:
mqttserverlog.info(
- f"File Authentication Success - Username: {username} - ClientID: {client_id}")
+ f"File Authentication Success - Username: {username} - ClientID: {client_id}"
+ )
else:
- mqttserverlog.info(f"File Authentication Failed - Username: {username} - ClientID: {client_id}")
+ mqttserverlog.info(
+ f"File Authentication Failed - Username: {username} - ClientID: {client_id}"
+ )
else:
mqttserverlog.info(
- f"File Authentication Failed - No Entry for Username: {username} - ClientID: {client_id}")
+ f"File Authentication Failed - No Entry for Username: {username} - ClientID: {client_id}"
+ )
except Exception as e:
mqttserverlog.exception(
@@ -285,28 +304,39 @@ class BumperMQTTServer_Plugin:
# Check for allow anonymous
allow_anonymous = self.auth_config.get("allow-anonymous", True)
- if allow_anonymous and not authenticated: # If anonymous auth is allowed and it isn't already authenticated
+ if (
+ allow_anonymous and not authenticated
+ ): # If anonymous auth is allowed and it isn't already authenticated
authenticated = True
self.context.logger.debug(
- f"Anonymous Authentication Success: config allows anonymous - Username: {username}")
- mqttserverlog.info(f"Anonymous Authentication Success: config allows anonymous - Username: {username}")
+ f"Anonymous Authentication Success: config allows anonymous - Username: {username}"
+ )
+ mqttserverlog.info(
+ f"Anonymous Authentication Success: config allows anonymous - Username: {username}"
+ )
return authenticated
def _read_password_file(self):
- password_file = self.auth_config.get('password-file', None)
+ password_file = self.auth_config.get("password-file", None)
if password_file:
try:
with open(password_file) as f:
- self.context.logger.debug(f"Reading user database from {password_file}")
+ self.context.logger.debug(
+ f"Reading user database from {password_file}"
+ )
for l in f:
line = l.strip()
- if not line.startswith('#'): # Allow comments in files
+ if not line.startswith("#"): # Allow comments in files
(username, pwd_hash) = line.split(sep=":", maxsplit=3)
if username:
self._users[username] = pwd_hash
- self.context.logger.debug(f"user: {username} - hash: {pwd_hash}")
- self.context.logger.debug(f"{(len(self._users))} user(s) read from file {password_file}")
+ self.context.logger.debug(
+ f"user: {username} - hash: {pwd_hash}"
+ )
+ self.context.logger.debug(
+ f"{(len(self._users))} user(s) read from file {password_file}"
+ )
except FileNotFoundError:
self.context.logger.warning(f"Password file {password_file} not found")
@@ -332,20 +362,32 @@ class BumperMQTTServer_Plugin:
data_decoded = str(message.data.decode("utf-8"))
if topic_split[6] == "helperbot":
# Response to command
- helperbotlog.debug(f"Received Response - Topic: {topic} - Message: {data_decoded}")
+ helperbotlog.debug(
+ f"Received Response - Topic: {topic} - Message: {data_decoded}"
+ )
if topic_split[10] in bumper.mqtt_helperbot.commands:
- bumper.mqtt_helperbot.commands[topic_split[10]].add_response(data_decoded)
+ bumper.mqtt_helperbot.commands[topic_split[10]].add_response(
+ data_decoded
+ )
elif topic_split[3] == "helperbot":
# Helperbot sending command
- helperbotlog.debug(f"Send Command - Topic: {topic} - Message: {data_decoded}")
+ helperbotlog.debug(
+ f"Send Command - Topic: {topic} - Message: {data_decoded}"
+ )
elif topic_split[1] == "atr":
# Broadcast message received on atr
if topic_split[2] == "errors":
- boterrorlog.error(f"Received Error - Topic: {topic} - Message: {data_decoded}")
+ boterrorlog.error(
+ f"Received Error - Topic: {topic} - Message: {data_decoded}"
+ )
else:
- helperbotlog.debug(f"Received Broadcast - Topic: {topic} - Message: {data_decoded}")
+ helperbotlog.debug(
+ f"Received Broadcast - Topic: {topic} - Message: {data_decoded}"
+ )
else:
- helperbotlog.debug(f"Received Message - Topic: {topic} - Message: {data_decoded}")
+ helperbotlog.debug(
+ f"Received Message - Topic: {topic} - Message: {data_decoded}"
+ )
async def on_broker_client_disconnected(self, client_id):
self._set_client_connected(client_id, False)
diff --git a/bumper/plugins.py b/bumper/plugins.py
index d1cbc9b..e3934f3 100644
--- a/bumper/plugins.py
+++ b/bumper/plugins.py
@@ -2,12 +2,11 @@
import asyncio
from aiohttp import web
-class ConfServerApp():
+
+class ConfServerApp:
name = None
plugin_type = None
path_prefix = None
app = None
sub_api = None
routes = None
-
-
diff --git a/bumper/plugins/bumper_confserver_portal_appsvr.py b/bumper/plugins/bumper_confserver_portal_appsvr.py
index b2ee984..60dbb85 100644
--- a/bumper/plugins/bumper_confserver_portal_appsvr.py
+++ b/bumper/plugins/bumper_confserver_portal_appsvr.py
@@ -8,152 +8,167 @@ from bumper.models import *
class portal_api_appsvr(plugins.ConfServerApp):
-
def __init__(self):
self.name = "portal_api_appsvr"
self.plugin_type = "sub_api"
self.sub_api = "portal_api"
self.routes = [
- web.route("*", "/appsvr/app.do", self.handle_appsvr_app, name="portal_api_appsvr_app"),
- web.route("*", "/appsvr/service/list", self.handle_appsvr_service_list, name="portal_api_appsvr_service_list"),
- web.route("*", "/appsvr/oauth_callback", self.handle_appsvr_oauth_callback, name="portal_api_appsvr_oauth_callback"),
+ web.route(
+ "*",
+ "/appsvr/app.do",
+ self.handle_appsvr_app,
+ name="portal_api_appsvr_app",
+ ),
+ web.route(
+ "*",
+ "/appsvr/service/list",
+ self.handle_appsvr_service_list,
+ name="portal_api_appsvr_service_list",
+ ),
+ web.route(
+ "*",
+ "/appsvr/oauth_callback",
+ self.handle_appsvr_oauth_callback,
+ name="portal_api_appsvr_oauth_callback",
+ ),
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
async def handle_appsvr_app(self, request):
- if not request.method == "GET": # Skip GET for now
- try:
+ 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()
+ body = {}
+ postbody = {}
+ if request.content_type == "application/x-www-form-urlencoded":
+ postbody = await request.post()
- else:
- postbody = json.loads(await request.text())
+ else:
+ postbody = json.loads(await request.text())
- todo = postbody["todo"]
+ 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)
- if (
- not b is None
- ): # Happens if the bot isn't on the EcoVacs Home list
- botlist.append(json.loads(b))
+ 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)
+ if (
+ not b is None
+ ): # Happens if the bot isn't on the EcoVacs Home list
+ botlist.append(json.loads(b))
- body = {
- "code": 0,
- "devices": botlist,
- "ret": "ok",
- "todo": "result",
- }
+ body = {
+ "code": 0,
+ "devices": botlist,
+ "ret": "ok",
+ "todo": "result",
+ }
- return web.json_response(body)
+ return web.json_response(body)
- #elif todo == "GetShareDeviceList":
- # example response
- # {
- # "code": 0,
- # "devices": [
- # {
- # "deviceName": "DEEBOT 900 Series (Cleaner Cleaner)",
- # "did": "did",
- # "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ba4a2cb6c2f120001c32839",
- # "mid": "ls1ok3",
- # "ownUsers": {
- # "isMe": true,
- # "nickname": "user@gmail.com",
- # "user": "cg****"
- # },
- # "resource": "wC3g",
- # "share": true,
- # "shareUsers": []
- # }
- # ],
- # "ret": "ok",
- # "todo": "result"
- # }
+ # elif todo == "GetShareDeviceList":
+ # example response
+ # {
+ # "code": 0,
+ # "devices": [
+ # {
+ # "deviceName": "DEEBOT 900 Series (Cleaner Cleaner)",
+ # "did": "did",
+ # "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ba4a2cb6c2f120001c32839",
+ # "mid": "ls1ok3",
+ # "ownUsers": {
+ # "isMe": true,
+ # "nickname": "user@gmail.com",
+ # "user": "cg****"
+ # },
+ # "resource": "wC3g",
+ # "share": true,
+ # "shareUsers": []
+ # }
+ # ],
+ # "ret": "ok",
+ # "todo": "result"
+ # }
- # if shared shareUsers
- # "shareUsers": [
- # {
- # "isMe": false,
- # "nickname": "user@gmail.com",
- # "status": "sharing",
- # "user": "eafg****"
- # }
- # ]
+ # if shared shareUsers
+ # "shareUsers": [
+ # {
+ # "isMe": false,
+ # "nickname": "user@gmail.com",
+ # "status": "sharing",
+ # "user": "eafg****"
+ # }
+ # ]
- #elif todo == "ShareDevice":
- # example post
- # {
- # "todo": "ShareDevice",
- # "accountType": "EMAIL",
- # "auth": {
- # "realm": "ecouser.net",
- # "resource": "res",
- # "token": "token***",
- # "userid": "cg***",
- # "with": "users"
- # },
- # "country": "US",
- # "did": "did",
- # "resource": "wC3g",
- # "username": "email to share to"
- # }
+ # elif todo == "ShareDevice":
+ # example post
+ # {
+ # "todo": "ShareDevice",
+ # "accountType": "EMAIL",
+ # "auth": {
+ # "realm": "ecouser.net",
+ # "resource": "res",
+ # "token": "token***",
+ # "userid": "cg***",
+ # "with": "users"
+ # },
+ # "country": "US",
+ # "did": "did",
+ # "resource": "wC3g",
+ # "username": "email to share to"
+ # }
- #fail response (no user)
- # {
- # "todo": "result",
- # "code": -3,
- # "errno": -3,
- # "ret": "fail"
- # }
+ # fail response (no user)
+ # {
+ # "todo": "result",
+ # "code": -3,
+ # "errno": -3,
+ # "ret": "fail"
+ # }
- #success response
- #{"ret":"ok","code":0,"todo":"result"}
+ # success response
+ # {"ret":"ok","code":0,"todo":"result"}
- #elif todo == "ShareUnRegisterDevice":
- # example post
- # {
- # "todo": "ShareUnRegisterDevice",
- # "account": "email to share to",
- # "auth": {
- # "realm": "ecouser.net",
- # "resource": "res",
- # "token": "toke",
- # "userid": "userid",
- # "with": "users"
- # },
- # "country": "US",
- # "did": "did",
- # "lang": "EN",
- # "mid": "ls1ok3"
- # }
- # example response
- # {
- # "todo": "result",
- # "code": 0,
- # "data": {
- # "mailContent": "
",
- # "mailTitle": "I'm sharing my DEEBOT and you're invited!"
- # },
- # "ret": "ok"
- # }
+ # elif todo == "ShareUnRegisterDevice":
+ # example post
+ # {
+ # "todo": "ShareUnRegisterDevice",
+ # "account": "email to share to",
+ # "auth": {
+ # "realm": "ecouser.net",
+ # "resource": "res",
+ # "token": "toke",
+ # "userid": "userid",
+ # "with": "users"
+ # },
+ # "country": "US",
+ # "did": "did",
+ # "lang": "EN",
+ # "mid": "ls1ok3"
+ # }
+ # example response
+ # {
+ # "todo": "result",
+ # "code": 0,
+ # "data": {
+ # "mailContent": "",
+ # "mailTitle": "I'm sharing my DEEBOT and you're invited!"
+ # },
+ # "ret": "ok"
+ # }
+ except Exception as e:
+ logging.exception(f"{e}")
- except Exception as e:
- logging.exception(f"{e}")
-
- # Return fail for GET
- body = {"result": "fail", "todo": "result"}
- return web.json_response(body)
+ # Return fail for GET
+ body = {"result": "fail", "todo": "result"}
+ return web.json_response(body)
async def handle_appsvr_service_list(self, request):
try:
@@ -176,15 +191,10 @@ class portal_api_appsvr(plugins.ConfServerApp):
"magw": "api-app.ecouser.net",
"msgcloud": "msg-eu.ecouser.net:5223",
"ngiotLb": "jmq-ngiot-eu.ecouser.net",
- "rop": "api-rop.ecouser.net"
+ "rop": "api-rop.ecouser.net",
}
- body = {
- "code": 0,
- "data": data,
- "ret": "ok",
- "todo": "result"
- }
+ body = {"code": 0, "data": data, "ret": "ok", "todo": "result"}
return web.json_response(body)
@@ -199,7 +209,7 @@ class portal_api_appsvr(plugins.ConfServerApp):
"code": 0,
"data": oauth.toResponse(),
"ret": "ok",
- "todo": "result"
+ "todo": "result",
}
return web.json_response(body)
diff --git a/bumper/plugins/bumper_confserver_portal_dim.py b/bumper/plugins/bumper_confserver_portal_dim.py
index fd71d74..9f4aa29 100644
--- a/bumper/plugins/bumper_confserver_portal_dim.py
+++ b/bumper/plugins/bumper_confserver_portal_dim.py
@@ -12,19 +12,23 @@ import random
class portal_api_dim(plugins.ConfServerApp):
-
def __init__(self):
self.name = "portal_api_dimr"
- self.plugin_type = "sub_api"
+ self.plugin_type = "sub_api"
self.sub_api = "portal_api"
-
+
self.routes = [
-
- web.route("*", "/dim/devmanager.do", self.handle_dim_devmanager, name="portal_api_dim_devmanager"),
-
+ web.route(
+ "*",
+ "/dim/devmanager.do",
+ self.handle_dim_devmanager,
+ name="portal_api_dim_devmanager",
+ ),
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
async def handle_dim_devmanager(self, request): # Used in EcoVacs Home App
try:
@@ -66,11 +70,11 @@ class portal_api_dim(plugins.ConfServerApp):
return web.json_response(body)
if json_body["td"] == "ReceiveShareDevice": # EcoVacs Home
- body = {"ret":"ok"}
- return web.json_response(body)
+ body = {"ret": "ok"}
+ return web.json_response(body)
except Exception as e:
- logging.exception(f"{e}")
+ logging.exception(f"{e}")
+
plugin = portal_api_dim()
-
diff --git a/bumper/plugins/bumper_confserver_portal_ecms.py b/bumper/plugins/bumper_confserver_portal_ecms.py
index 152456d..ead6976 100644
--- a/bumper/plugins/bumper_confserver_portal_ecms.py
+++ b/bumper/plugins/bumper_confserver_portal_ecms.py
@@ -8,26 +8,27 @@ from bumper.models import *
class portal_api_ecms(plugins.ConfServerApp):
-
def __init__(self):
self.name = "portal_api_ecms"
self.plugin_type = "sub_api"
self.sub_api = "portal_api"
self.routes = [
- web.route("*", "/ecms/app/ad/res", self.handle_ad_res, name="portal_api_ecms_ad_res"),
+ web.route(
+ "*",
+ "/ecms/app/ad/res",
+ self.handle_ad_res,
+ name="portal_api_ecms_ad_res",
+ ),
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
async def handle_ad_res(self, request):
try:
- body = {
- "code": 0,
- "data": [],
- "message": "success",
- "success": True
- }
+ body = {"code": 0, "data": [], "message": "success", "success": True}
return web.json_response(body)
diff --git a/bumper/plugins/bumper_confserver_portal_iot.py b/bumper/plugins/bumper_confserver_portal_iot.py
index f9721df..85c4e61 100644
--- a/bumper/plugins/bumper_confserver_portal_iot.py
+++ b/bumper/plugins/bumper_confserver_portal_iot.py
@@ -10,21 +10,26 @@ from datetime import datetime, timedelta
import string
import random
-class portal_api_iot(plugins.ConfServerApp):
+class portal_api_iot(plugins.ConfServerApp):
def __init__(self):
self.name = "portal_api_iot"
- self.plugin_type = "sub_api"
+ self.plugin_type = "sub_api"
self.sub_api = "portal_api"
-
- self.routes = [
-
- web.route("*", "/iot/devmanager.do", self.handle_devmanager_botcommand, name="portal_api_iot_devmanager"),
+ self.routes = [
+ web.route(
+ "*",
+ "/iot/devmanager.do",
+ self.handle_devmanager_botcommand,
+ name="portal_api_iot_devmanager",
+ ),
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
-
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
+
async def handle_devmanager_botcommand(self, request):
try:
json_body = json.loads(await request.text())
@@ -70,12 +75,11 @@ class portal_api_iot(plugins.ConfServerApp):
return web.json_response(body)
if json_body["td"] == "PreWifiConfig": # EcoVacs Home
- body = {"ret":"ok"}
+ body = {"ret": "ok"}
return web.json_response(body)
-
except Exception as e:
logging.exception(f"{e}")
-plugin = portal_api_iot()
+plugin = portal_api_iot()
diff --git a/bumper/plugins/bumper_confserver_portal_lg.py b/bumper/plugins/bumper_confserver_portal_lg.py
index 015e7a0..85afac5 100644
--- a/bumper/plugins/bumper_confserver_portal_lg.py
+++ b/bumper/plugins/bumper_confserver_portal_lg.py
@@ -11,19 +11,18 @@ from bumper.models import *
class portal_api_lg(plugins.ConfServerApp):
-
def __init__(self):
self.name = "portal_api_lg"
self.plugin_type = "sub_api"
self.sub_api = "portal_api"
self.routes = [
-
web.route("*", "/lg/log.do", self.handle_lg_log, name="portal_api_lg_log"),
-
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
async def handle_lg_log(self, request): # EcoVacs Home
randomid = "".join(random.sample(string.ascii_letters, 6))
@@ -72,10 +71,10 @@ class portal_api_lg(plugins.ConfServerApp):
cleanlogs = logsroot.getchildren()
for l in cleanlogs:
cleanlog = {
- "ts": l.attrib['s'],
- "area": l.attrib['a'],
- "last": l.attrib['l'],
- "cleanType": l.attrib['t'],
+ "ts": l.attrib["s"],
+ "area": l.attrib["a"],
+ "last": l.attrib["l"],
+ "cleanType": l.attrib["t"],
# imageUrl allows for providing images of cleanings, something to look into later
# "imageUrl": "https://localhost:8007",
}
diff --git a/bumper/plugins/bumper_confserver_portal_neng.py b/bumper/plugins/bumper_confserver_portal_neng.py
index d4938de..a591006 100644
--- a/bumper/plugins/bumper_confserver_portal_neng.py
+++ b/bumper/plugins/bumper_confserver_portal_neng.py
@@ -10,21 +10,35 @@ from datetime import datetime, timedelta
class portal_api_neng(plugins.ConfServerApp):
-
def __init__(self):
self.name = "portal_api_neng"
- self.plugin_type = "sub_api"
+ self.plugin_type = "sub_api"
self.sub_api = "portal_api"
-
- self.routes = [
-
- web.route("*", "/neng/message/hasUnreadMsg", self.handle_neng_hasUnreadMessage, name="portal_api_neng_hasUnreadMessage"),
- web.route("*", "/neng/message/getShareMsgs", self.handle_neng_getShareMsgs, name="portal_api_neng_getShareMsgs"),
- web.route("*", "/neng/message/getlist", self.handle_neng_getlist, name="portal_api_neng_getlist"),
+ self.routes = [
+ web.route(
+ "*",
+ "/neng/message/hasUnreadMsg",
+ self.handle_neng_hasUnreadMessage,
+ name="portal_api_neng_hasUnreadMessage",
+ ),
+ web.route(
+ "*",
+ "/neng/message/getShareMsgs",
+ self.handle_neng_getShareMsgs,
+ name="portal_api_neng_getShareMsgs",
+ ),
+ web.route(
+ "*",
+ "/neng/message/getlist",
+ self.handle_neng_getlist,
+ name="portal_api_neng_getlist",
+ ),
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
async def handle_neng_hasUnreadMessage(self, request): # EcoVacs Home
try:
@@ -37,7 +51,7 @@ class portal_api_neng(plugins.ConfServerApp):
async def handle_neng_getShareMsgs(self, request): # EcoVacs Home
try:
- body = {"code":0,"data":{"hasNext":False,"msgs":[]}}
+ body = {"code": 0, "data": {"hasNext": False, "msgs": []}}
# share msg response
# {
@@ -65,33 +79,33 @@ class portal_api_neng(plugins.ConfServerApp):
return web.json_response(body)
except Exception as e:
- logging.exception(f"{e}")
+ logging.exception(f"{e}")
async def handle_neng_getlist(self, request): # EcoVacs Home
try:
- body = {"code":0,"data":{"hasNext":False,"msgs":[]}}
+ body = {"code": 0, "data": {"hasNext": False, "msgs": []}}
- #Sample Message
- # {
- # "id": "5da0ac9d636aec5107627ac4",
- # "ts": 1570811036877,
- # "did": "bot did",
- # "cid": "ls1ok3",
- # "name": "DEEBOT 900 Series",
- # "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ba4a2cb6c2f120001c32839",
- # "eventTypeId": "5aab824bb62ce30001f9a702",
- # "title": "DEEBOT is off the floor.",
- # "body": "DEEBOT is off the floor. Please put it back.",
- # "read": false,
- # "UILogicId": "D_900",
- # "type": "web",
- # "url": "https://portal-ww.ecouser.net/api/pim/eventdetail.html?id=5ba21e44aed83800015b9ca8" # Off the floor instructions
- # }
+ # Sample Message
+ # {
+ # "id": "5da0ac9d636aec5107627ac4",
+ # "ts": 1570811036877,
+ # "did": "bot did",
+ # "cid": "ls1ok3",
+ # "name": "DEEBOT 900 Series",
+ # "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ba4a2cb6c2f120001c32839",
+ # "eventTypeId": "5aab824bb62ce30001f9a702",
+ # "title": "DEEBOT is off the floor.",
+ # "body": "DEEBOT is off the floor. Please put it back.",
+ # "read": false,
+ # "UILogicId": "D_900",
+ # "type": "web",
+ # "url": "https://portal-ww.ecouser.net/api/pim/eventdetail.html?id=5ba21e44aed83800015b9ca8" # Off the floor instructions
+ # }
return web.json_response(body)
except Exception as e:
- logging.exception(f"{e}")
-
-plugin = portal_api_neng()
+ logging.exception(f"{e}")
+
+plugin = portal_api_neng()
diff --git a/bumper/plugins/bumper_confserver_portal_pim.py b/bumper/plugins/bumper_confserver_portal_pim.py
index 701a3d3..287d727 100644
--- a/bumper/plugins/bumper_confserver_portal_pim.py
+++ b/bumper/plugins/bumper_confserver_portal_pim.py
@@ -9,22 +9,53 @@ from bumper.models import *
class portal_api_pim(plugins.ConfServerApp):
-
def __init__(self):
self.name = "portal_api_pim"
self.plugin_type = "sub_api"
self.sub_api = "portal_api"
self.routes = [
- web.route("*", "/pim/product/getProductIotMap", self.handle_getProductIotMap, name="portal_api_pim_getProductIotMap"),
- web.route("*", "/pim/file/get/{id}", self.handle_pimFile, name="portal_api_pim_file"),
- web.route("*", "/pim/product/getConfignetAll", self.handle_getConfignetAll, name="portal_api_pim_getConfignetAll"),
- web.route("*", "/pim/product/getConfigGroups", self.handle_getConfigGroups, name="portal_api_pim_getConfigGroups"),
- web.route("*", "/pim/dictionary/getErrDetail", self.handle_getErrDetail, name="portal_api_pim_getErrDetail"),
- web.route("*", "/pim/product/software/config/batch", self.handle_product_config_batch, name="portal_api_pim_product_config_batch"),
+ web.route(
+ "*",
+ "/pim/product/getProductIotMap",
+ self.handle_getProductIotMap,
+ name="portal_api_pim_getProductIotMap",
+ ),
+ web.route(
+ "*",
+ "/pim/file/get/{id}",
+ self.handle_pimFile,
+ name="portal_api_pim_file",
+ ),
+ web.route(
+ "*",
+ "/pim/product/getConfignetAll",
+ self.handle_getConfignetAll,
+ name="portal_api_pim_getConfignetAll",
+ ),
+ web.route(
+ "*",
+ "/pim/product/getConfigGroups",
+ self.handle_getConfigGroups,
+ name="portal_api_pim_getConfigGroups",
+ ),
+ web.route(
+ "*",
+ "/pim/dictionary/getErrDetail",
+ self.handle_getErrDetail,
+ name="portal_api_pim_getErrDetail",
+ ),
+ web.route(
+ "*",
+ "/pim/product/software/config/batch",
+ self.handle_product_config_batch,
+ name="portal_api_pim_product_config_batch",
+ ),
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
async def handle_getProductIotMap(self, request):
try:
@@ -41,7 +72,11 @@ class portal_api_pim(plugins.ConfServerApp):
try:
fileID = request.match_info.get("id", "")
- return web.FileResponse(os.path.join(bumper.bumper_dir, "bumper", "web", "images", "robotvac_image.jpg"))
+ return web.FileResponse(
+ os.path.join(
+ bumper.bumper_dir, "bumper", "web", "images", "robotvac_image.jpg"
+ )
+ )
except Exception as e:
logging.exception(f"{e}")
@@ -67,7 +102,7 @@ class portal_api_pim(plugins.ConfServerApp):
body = {
"code": -1,
"data": [],
- "msg": "This errcode's detail is not exists"
+ "msg": "This errcode's detail is not exists",
}
return web.json_response(body)
@@ -86,16 +121,9 @@ class portal_api_pim(plugins.ConfServerApp):
# not found in productConfigBatch
# some devices don't have any product configuration
- data.append({
- "cfg": {},
- "pid": pid
- })
+ data.append({"cfg": {}, "pid": pid})
- body = {
- "code": 200,
- "data": data,
- "message": "success"
- }
+ body = {"code": 200, "data": data, "message": "success"}
return web.json_response(body)
except Exception as e:
@@ -105,2607 +133,2278 @@ class portal_api_pim(plugins.ConfServerApp):
plugin = portal_api_pim()
confignetAllResponse = {
- "code": 0,
- "data": [
- {
- "groupId": "5ae147f27ccd1a0001e1f69c",
- "sort": 60,
- "groupName": "DEEBOT OZMO Slim10 Series",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1715-0201",
- "mid": "02uwxm",
- "ota": False,
- "supportVer": {
- "Android": "1.0.0",
- "IOS": "1.0.0"
- },
- "smartTypes": [],
- "steps": [
+ "code": 0,
+ "data": [
{
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
+ "groupId": "5ae147f27ccd1a0001e1f69c",
+ "sort": 60,
+ "groupName": "DEEBOT OZMO Slim10 Series",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1715-0201",
+ "mid": "02uwxm",
+ "ota": False,
+ "supportVer": {"Android": "1.0.0", "IOS": "1.0.0"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5b1dddc48bc45700014035a1",
},
{
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5b1dddc48bc45700014035a1"
+ "groupId": "5ca32b5de9e9270001354b3f",
+ "sort": 80,
+ "groupName": "DEEBOT OZMO 601",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1629-0203",
+ "mid": "159",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d4b7606de51dd0001fee12d",
+ },
+ {
+ "groupId": "5ca32b5de9e9270001354b3f",
+ "sort": 80,
+ "groupName": "DEEBOT",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1629-0203",
+ "mid": "159",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d4b7628de51dd0001fee12f",
+ },
+ {
+ "groupId": "5ca32b5de9e9270001354b3f",
+ "sort": 80,
+ "groupName": "DEEBOT OZMO 610 Series",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1629-0203",
+ "mid": "159",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d4b7640de51dd0001fee131",
+ },
+ {
+ "groupId": "5cae9662e9e9270001354b55",
+ "sort": 150,
+ "groupName": "DEEBOT M80 Pro",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1638-0102",
+ "mid": "125",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c14414d60de0001eaf1f2",
+ },
+ {
+ "groupId": "5bbedcd922d57f00018c13b6",
+ "sort": 30,
+ "groupName": "DEEBOT OZMO/PRO 930 Series",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "HK_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1803-0101",
+ "mid": "115",
+ "ota": False,
+ "supportVer": {"Android": "1.1.8", "IOS": "1.1.8"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5cf711aeb0acfc000179ff8a",
+ },
+ {
+ "groupId": "5b6560760506b100015c8867",
+ "sort": 130,
+ "groupName": "DEEBOT 900 Series",
+ "isPopular": False,
+ "belongApp": ["ecoglobal", "ecodeebot"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1711-0201",
+ "mid": "ls1ok3",
+ "ota": False,
+ "supportVer": {"Android": "1.0.7", "IOS": "1.0.7"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ba4a2cb6c2f120001c32839",
+ },
+ {
+ "groupId": "5b6560760506b100015c8867",
+ "sort": 130,
+ "groupName": "DEEBOT 910",
+ "isPopular": False,
+ "belongApp": ["ecoglobal", "ecodeebot"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1711-0201",
+ "mid": "ls1ok3",
+ "ota": False,
+ "supportVer": {"Android": "1.0.7", "IOS": "1.0.7"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5c778731280fda0001770ba0",
+ },
+ {
+ "groupId": "5cae9793e9e9270001354b57",
+ "sort": 160,
+ "groupName": "DEEBOT M81 Pro",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1638-0101",
+ "mid": "141",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c2aa64d60de0001eaf1f6",
+ },
+ {
+ "groupId": "5c19a835a1e6ee0001782245",
+ "sort": 20,
+ "groupName": "DEEBOT OZMO 920 Series",
+ "isPopular": True,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 1,
+ "materialNo": "110-1819-0101",
+ "mid": "vi829v",
+ "ota": False,
+ "supportVer": {"Android": "1.1.5", "IOS": "1.1.5"},
+ "smartTypes": ["MQ_AP"],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
+ "retryText": "",
+ "confirmText": "I've heard the sound",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5c9c7995e9e9270001354ab4",
+ },
+ {
+ "groupId": "5bc8187422d57f00018c13ba",
+ "sort": 50,
+ "groupName": "DEEBOT OZMO 960",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1803-0101",
+ "mid": "gd4uut",
+ "ota": False,
+ "supportVer": {"Android": "1.1.5", "IOS": "1.1.5"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5c7384767b93c700013f12e7",
+ },
+ {
+ "groupId": "5b04bf1d7ccd1a0001e1f6a6",
+ "sort": 10,
+ "groupName": "DEEBOT OZMO 900 Series",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1810-0101",
+ "mid": "y79a7u",
+ "ota": False,
+ "supportVer": {"Android": "1.0.0", "IOS": "1.0.0"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5b04c0217ccd1a0001e1f6a7",
+ },
+ {
+ "groupId": "5b04bf1d7ccd1a0001e1f6a6",
+ "sort": 10,
+ "groupName": "DEEBOT OZMO 905",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1810-0101",
+ "mid": "y79a7u",
+ "ota": False,
+ "supportVer": {"Android": "1.0.0", "IOS": "1.0.0"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d1474632a6bd50001b5b6f3",
+ },
+ {
+ "groupId": "5c763de8280fda0001770b7f",
+ "sort": 100,
+ "groupName": "DEEBOT 500",
+ "isPopular": True,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "702-0000-0163",
+ "mid": "vsc5ia",
+ "ota": False,
+ "supportVer": {"Android": "1.1.5", "IOS": "1.1.5"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5df9d6b7c783810001d3d06b",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5dfc34d15d21490001700e14",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5c874326280fda0001770d2a",
+ },
+ {
+ "groupId": "5c763de8280fda0001770b7f",
+ "sort": 100,
+ "groupName": "DEEBOT 501",
+ "isPopular": True,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "702-0000-0163",
+ "mid": "vsc5ia",
+ "ota": False,
+ "supportVer": {"Android": "1.1.5", "IOS": "1.1.5"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5df9d6b7c783810001d3d06b",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5dfc34d15d21490001700e14",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5c931fef280fda0001770d7e",
+ },
+ {
+ "groupId": "5c763de8280fda0001770b7f",
+ "sort": 100,
+ "groupName": "DEEBOT 502",
+ "isPopular": True,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "702-0000-0163",
+ "mid": "vsc5ia",
+ "ota": False,
+ "supportVer": {"Android": "1.1.5", "IOS": "1.1.5"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5df9d6b7c783810001d3d06b",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5dfc34d15d21490001700e14",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5c93204b63023c0001e7faa7",
+ },
+ {
+ "groupId": "5c763de8280fda0001770b7f",
+ "sort": 100,
+ "groupName": "DEEBOT 505",
+ "isPopular": True,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "702-0000-0163",
+ "mid": "vsc5ia",
+ "ota": False,
+ "supportVer": {"Android": "1.1.5", "IOS": "1.1.5"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5df9d6b7c783810001d3d06b",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5dfc34d15d21490001700e14",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5c932067280fda0001770d7f",
+ },
+ {
+ "groupId": "5cae9aa5e9e9270001354b5d",
+ "sort": 230,
+ "groupName": "DEEBOT Slim2 Series",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1639-0102",
+ "mid": "123",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c150dba13eb00013feaae",
+ },
+ {
+ "groupId": "5cae9aa5e9e9270001354b5d",
+ "sort": 230,
+ "groupName": "DEEBOT Slim Neo",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1639-0102",
+ "mid": "123",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c152f4d60de0001eaf1f4",
+ },
+ {
+ "groupId": "5c19a8a0ddfc1f0001ede8e0",
+ "sort": 40,
+ "groupName": "DEEBOT OZMO 950 Series",
+ "isPopular": True,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 1,
+ "materialNo": "110-1820-0101",
+ "mid": "yna5xi",
+ "ota": False,
+ "supportVer": {"Android": "1.1.5", "IOS": "1.1.5"},
+ "smartTypes": ["MQ_AP"],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
+ "retryText": "",
+ "confirmText": "I've heard the sound",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5caafd7e1285190001685965",
+ },
+ {
+ "groupId": "5ca4711412851900016858cb",
+ "sort": 70,
+ "groupName": "DEEBOT OZMO 700",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 1,
+ "materialNo": "110-1825-0201",
+ "mid": "0xyhhr",
+ "ota": False,
+ "supportVer": {"Android": "1.1.5", "IOS": "1.1.5"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
+ "retryText": "",
+ "confirmText": "I've heard the sound",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d117d4f0ac6ad00012b792d",
+ },
+ {
+ "groupId": "5ca4711412851900016858cb",
+ "sort": 70,
+ "groupName": "DEEBOT OZMO 750",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 1,
+ "materialNo": "110-1825-0201",
+ "mid": "0xyhhr",
+ "ota": False,
+ "supportVer": {"Android": "1.1.5", "IOS": "1.1.5"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
+ "retryText": "",
+ "confirmText": "I've heard the sound",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d3aa309ba13eb00013feb69",
+ },
+ {
+ "groupId": "5acb0f2e7c295c0001876eb4",
+ "sort": 110,
+ "groupName": "DEEBOT 600 Series",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "702-0000-0170",
+ "mid": "dl8fht",
+ "ota": False,
+ "supportVer": {"Android": "1.0.0", "IOS": "1.0.0"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8e36591fd5d0001892541",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b8cd75f76f7f10001e9a0de",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5acc32067c295c0001876eea",
+ },
+ {
+ "groupId": "5acb0f2e7c295c0001876eb4",
+ "sort": 110,
+ "groupName": "DEEBOT 661",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "702-0000-0170",
+ "mid": "dl8fht",
+ "ota": False,
+ "supportVer": {"Android": "1.0.0", "IOS": "1.0.0"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8e36591fd5d0001892541",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b8cd75f76f7f10001e9a0de",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d280ce3350e7a0001e84c95",
+ },
+ {
+ "groupId": "5ca31ce8e9e9270001354b33",
+ "sort": 170,
+ "groupName": "DEEBOT M86",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1628-0101",
+ "mid": "129",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ca31df112851900016858c0",
+ },
+ {
+ "groupId": "5d2460f244af360001383992",
+ "sort": 9,
+ "groupName": "DEEBOT U3",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "939393939393",
+ "mid": "xb83mv",
+ "ota": False,
+ "supportVer": {"Android": "1.1.8", "IOS": "1.1.8"},
+ "smartTypes": ["MQ_AP"],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
+ "retryText": "",
+ "confirmText": "I've heard the sound",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d3fe649de51dd0001fee0de",
+ },
+ {
+ "groupId": "5d2460f244af360001383992",
+ "sort": 9,
+ "groupName": "DEEBOT U3 LINE FRIENDS",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "939393939393",
+ "mid": "xb83mv",
+ "ota": False,
+ "supportVer": {"Android": "1.1.8", "IOS": "1.1.8"},
+ "smartTypes": ["MQ_AP"],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
+ "retryText": "",
+ "confirmText": "I've heard the sound",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5da834a8d66cd10001f58265",
+ },
+ {
+ "groupId": "5ca1c9a3e9e9270001354b2b",
+ "sort": 240,
+ "groupName": "DEEBOT Mini2",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1640-0101",
+ "mid": "142",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ca1ca79e9e9270001354b2d",
+ },
+ {
+ "groupId": "5ca31e8212851900016858c2",
+ "sort": 140,
+ "groupName": "DEEBOT N79",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "702-0000-0136",
+ "mid": "126",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ca32ab2e9e9270001354b3d",
+ },
+ {
+ "groupId": "5ca31e8212851900016858c2",
+ "sort": 140,
+ "groupName": "DEEBOT N79S/SE",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "702-0000-0136",
+ "mid": "126",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5cd4ca505b032200015a455d",
+ },
+ {
+ "groupId": "5ca31e8212851900016858c2",
+ "sort": 140,
+ "groupName": "DEEBOT N79T/W",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "702-0000-0136",
+ "mid": "126",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ca32a1012851900016858c6",
+ },
+ {
+ "groupId": "5ae197be7ccd1a0001e1f6a1",
+ "sort": 120,
+ "groupName": "DEEBOT 711",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "702-0000-0205",
+ "mid": "uv242z",
+ "ota": False,
+ "supportVer": {"Android": "1.0.5", "IOS": "1.0.5"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b7fc85976f7f10001e9a0d0",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8e5d5d85b4d0001776484",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5b5ac4cc8d5a56000111e769",
+ },
+ {
+ "groupId": "5ae197be7ccd1a0001e1f6a1",
+ "sort": 120,
+ "groupName": "DEEBOT 710",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "702-0000-0205",
+ "mid": "uv242z",
+ "ota": False,
+ "supportVer": {"Android": "1.0.5", "IOS": "1.0.5"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b7fc85976f7f10001e9a0d0",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8e5d5d85b4d0001776484",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5b5ac4e45f21100001882bb9",
+ },
+ {
+ "groupId": "5ae197be7ccd1a0001e1f6a1",
+ "sort": 120,
+ "groupName": "DEEBOT 715",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "702-0000-0205",
+ "mid": "uv242z",
+ "ota": False,
+ "supportVer": {"Android": "1.0.5", "IOS": "1.0.5"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b7fc85976f7f10001e9a0d0",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8e5d5d85b4d0001776484",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5b7b65f176f7f10001e9a0c2",
+ },
+ {
+ "groupId": "5ae197be7ccd1a0001e1f6a1",
+ "sort": 120,
+ "groupName": "DEEBOT 711s",
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "702-0000-0205",
+ "mid": "uv242z",
+ "ota": False,
+ "supportVer": {"Android": "1.0.5", "IOS": "1.0.5"},
+ "smartTypes": [],
+ "steps": [
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b7fc85976f7f10001e9a0d0",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8e5d5d85b4d0001776484",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d157f9f77a3a60001051f69",
+ },
+ ],
+ "msg": "success",
+ "configFAQ": {
+ "wifiFAQUrl": "https://portal-ww.ecouser.net/api/pim/wififaq.html?lang=en&defaultLang=en",
+ "notFoundAPUrl": "https://portal-ww.ecouser.net/api/pim/findWifi.html?lang=en&defaultLang=en",
+ "configFailedUrl": "https://portal-ww.ecouser.net/api/pim/configfail.html?lang=en&defaultLang=en",
+ "contactUS": "helper",
},
- {
- "groupId": "5ca32b5de9e9270001354b3f",
- "sort": 80,
- "groupName": "DEEBOT OZMO 601",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1629-0203",
- "mid": "159",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d4b7606de51dd0001fee12d"
- },
- {
- "groupId": "5ca32b5de9e9270001354b3f",
- "sort": 80,
- "groupName": "DEEBOT",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1629-0203",
- "mid": "159",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d4b7628de51dd0001fee12f"
- },
- {
- "groupId": "5ca32b5de9e9270001354b3f",
- "sort": 80,
- "groupName": "DEEBOT OZMO 610 Series",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1629-0203",
- "mid": "159",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d4b7640de51dd0001fee131"
- },
- {
- "groupId": "5cae9662e9e9270001354b55",
- "sort": 150,
- "groupName": "DEEBOT M80 Pro",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1638-0102",
- "mid": "125",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c14414d60de0001eaf1f2"
- },
- {
- "groupId": "5bbedcd922d57f00018c13b6",
- "sort": 30,
- "groupName": "DEEBOT OZMO/PRO 930 Series",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "HK_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1803-0101",
- "mid": "115",
- "ota": False,
- "supportVer": {
- "Android": "1.1.8",
- "IOS": "1.1.8"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5cf711aeb0acfc000179ff8a"
- },
- {
- "groupId": "5b6560760506b100015c8867",
- "sort": 130,
- "groupName": "DEEBOT 900 Series",
- "isPopular": False,
- "belongApp": [
- "ecoglobal",
- "ecodeebot"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1711-0201",
- "mid": "ls1ok3",
- "ota": False,
- "supportVer": {
- "Android": "1.0.7",
- "IOS": "1.0.7"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ba4a2cb6c2f120001c32839"
- },
- {
- "groupId": "5b6560760506b100015c8867",
- "sort": 130,
- "groupName": "DEEBOT 910",
- "isPopular": False,
- "belongApp": [
- "ecoglobal",
- "ecodeebot"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1711-0201",
- "mid": "ls1ok3",
- "ota": False,
- "supportVer": {
- "Android": "1.0.7",
- "IOS": "1.0.7"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5c778731280fda0001770ba0"
- },
- {
- "groupId": "5cae9793e9e9270001354b57",
- "sort": 160,
- "groupName": "DEEBOT M81 Pro",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1638-0101",
- "mid": "141",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c2aa64d60de0001eaf1f6"
- },
- {
- "groupId": "5c19a835a1e6ee0001782245",
- "sort": 20,
- "groupName": "DEEBOT OZMO 920 Series",
- "isPopular": True,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 1,
- "materialNo": "110-1819-0101",
- "mid": "vi829v",
- "ota": False,
- "supportVer": {
- "Android": "1.1.5",
- "IOS": "1.1.5"
- },
- "smartTypes": [
- "MQ_AP"
- ],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
- "retryText": "",
- "confirmText": "I've heard the sound",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5c9c7995e9e9270001354ab4"
- },
- {
- "groupId": "5bc8187422d57f00018c13ba",
- "sort": 50,
- "groupName": "DEEBOT OZMO 960",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1803-0101",
- "mid": "gd4uut",
- "ota": False,
- "supportVer": {
- "Android": "1.1.5",
- "IOS": "1.1.5"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5c7384767b93c700013f12e7"
- },
- {
- "groupId": "5b04bf1d7ccd1a0001e1f6a6",
- "sort": 10,
- "groupName": "DEEBOT OZMO 900 Series",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1810-0101",
- "mid": "y79a7u",
- "ota": False,
- "supportVer": {
- "Android": "1.0.0",
- "IOS": "1.0.0"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5b04c0217ccd1a0001e1f6a7"
- },
- {
- "groupId": "5b04bf1d7ccd1a0001e1f6a6",
- "sort": 10,
- "groupName": "DEEBOT OZMO 905",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1810-0101",
- "mid": "y79a7u",
- "ota": False,
- "supportVer": {
- "Android": "1.0.0",
- "IOS": "1.0.0"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d1474632a6bd50001b5b6f3"
- },
- {
- "groupId": "5c763de8280fda0001770b7f",
- "sort": 100,
- "groupName": "DEEBOT 500",
- "isPopular": True,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "702-0000-0163",
- "mid": "vsc5ia",
- "ota": False,
- "supportVer": {
- "Android": "1.1.5",
- "IOS": "1.1.5"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5df9d6b7c783810001d3d06b",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5dfc34d15d21490001700e14",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5c874326280fda0001770d2a"
- },
- {
- "groupId": "5c763de8280fda0001770b7f",
- "sort": 100,
- "groupName": "DEEBOT 501",
- "isPopular": True,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "702-0000-0163",
- "mid": "vsc5ia",
- "ota": False,
- "supportVer": {
- "Android": "1.1.5",
- "IOS": "1.1.5"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5df9d6b7c783810001d3d06b",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5dfc34d15d21490001700e14",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5c931fef280fda0001770d7e"
- },
- {
- "groupId": "5c763de8280fda0001770b7f",
- "sort": 100,
- "groupName": "DEEBOT 502",
- "isPopular": True,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "702-0000-0163",
- "mid": "vsc5ia",
- "ota": False,
- "supportVer": {
- "Android": "1.1.5",
- "IOS": "1.1.5"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5df9d6b7c783810001d3d06b",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5dfc34d15d21490001700e14",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5c93204b63023c0001e7faa7"
- },
- {
- "groupId": "5c763de8280fda0001770b7f",
- "sort": 100,
- "groupName": "DEEBOT 505",
- "isPopular": True,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "702-0000-0163",
- "mid": "vsc5ia",
- "ota": False,
- "supportVer": {
- "Android": "1.1.5",
- "IOS": "1.1.5"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5df9d6b7c783810001d3d06b",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5dfc34d15d21490001700e14",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5c932067280fda0001770d7f"
- },
- {
- "groupId": "5cae9aa5e9e9270001354b5d",
- "sort": 230,
- "groupName": "DEEBOT Slim2 Series",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1639-0102",
- "mid": "123",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c150dba13eb00013feaae"
- },
- {
- "groupId": "5cae9aa5e9e9270001354b5d",
- "sort": 230,
- "groupName": "DEEBOT Slim Neo",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1639-0102",
- "mid": "123",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c152f4d60de0001eaf1f4"
- },
- {
- "groupId": "5c19a8a0ddfc1f0001ede8e0",
- "sort": 40,
- "groupName": "DEEBOT OZMO 950 Series",
- "isPopular": True,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 1,
- "materialNo": "110-1820-0101",
- "mid": "yna5xi",
- "ota": False,
- "supportVer": {
- "Android": "1.1.5",
- "IOS": "1.1.5"
- },
- "smartTypes": [
- "MQ_AP"
- ],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
- "retryText": "",
- "confirmText": "I've heard the sound",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5caafd7e1285190001685965"
- },
- {
- "groupId": "5ca4711412851900016858cb",
- "sort": 70,
- "groupName": "DEEBOT OZMO 700",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 1,
- "materialNo": "110-1825-0201",
- "mid": "0xyhhr",
- "ota": False,
- "supportVer": {
- "Android": "1.1.5",
- "IOS": "1.1.5"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
- "retryText": "",
- "confirmText": "I've heard the sound",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d117d4f0ac6ad00012b792d"
- },
- {
- "groupId": "5ca4711412851900016858cb",
- "sort": 70,
- "groupName": "DEEBOT OZMO 750",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 1,
- "materialNo": "110-1825-0201",
- "mid": "0xyhhr",
- "ota": False,
- "supportVer": {
- "Android": "1.1.5",
- "IOS": "1.1.5"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
- "retryText": "",
- "confirmText": "I've heard the sound",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d3aa309ba13eb00013feb69"
- },
- {
- "groupId": "5acb0f2e7c295c0001876eb4",
- "sort": 110,
- "groupName": "DEEBOT 600 Series",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "702-0000-0170",
- "mid": "dl8fht",
- "ota": False,
- "supportVer": {
- "Android": "1.0.0",
- "IOS": "1.0.0"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8e36591fd5d0001892541",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b8cd75f76f7f10001e9a0de",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5acc32067c295c0001876eea"
- },
- {
- "groupId": "5acb0f2e7c295c0001876eb4",
- "sort": 110,
- "groupName": "DEEBOT 661",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "702-0000-0170",
- "mid": "dl8fht",
- "ota": False,
- "supportVer": {
- "Android": "1.0.0",
- "IOS": "1.0.0"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8e36591fd5d0001892541",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b8cd75f76f7f10001e9a0de",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d280ce3350e7a0001e84c95"
- },
- {
- "groupId": "5ca31ce8e9e9270001354b33",
- "sort": 170,
- "groupName": "DEEBOT M86",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1628-0101",
- "mid": "129",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ca31df112851900016858c0"
- },
- {
- "groupId": "5d2460f244af360001383992",
- "sort": 9,
- "groupName": "DEEBOT U3",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "939393939393",
- "mid": "xb83mv",
- "ota": False,
- "supportVer": {
- "Android": "1.1.8",
- "IOS": "1.1.8"
- },
- "smartTypes": [
- "MQ_AP"
- ],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
- "retryText": "",
- "confirmText": "I've heard the sound",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d3fe649de51dd0001fee0de"
- },
- {
- "groupId": "5d2460f244af360001383992",
- "sort": 9,
- "groupName": "DEEBOT U3 LINE FRIENDS",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "939393939393",
- "mid": "xb83mv",
- "ota": False,
- "supportVer": {
- "Android": "1.1.8",
- "IOS": "1.1.8"
- },
- "smartTypes": [
- "MQ_AP"
- ],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
- "retryText": "",
- "confirmText": "I've heard the sound",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5da834a8d66cd10001f58265"
- },
- {
- "groupId": "5ca1c9a3e9e9270001354b2b",
- "sort": 240,
- "groupName": "DEEBOT Mini2",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1640-0101",
- "mid": "142",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ca1ca79e9e9270001354b2d"
- },
- {
- "groupId": "5ca31e8212851900016858c2",
- "sort": 140,
- "groupName": "DEEBOT N79",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "702-0000-0136",
- "mid": "126",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ca32ab2e9e9270001354b3d"
- },
- {
- "groupId": "5ca31e8212851900016858c2",
- "sort": 140,
- "groupName": "DEEBOT N79S/SE",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "702-0000-0136",
- "mid": "126",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5cd4ca505b032200015a455d"
- },
- {
- "groupId": "5ca31e8212851900016858c2",
- "sort": 140,
- "groupName": "DEEBOT N79T/W",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "702-0000-0136",
- "mid": "126",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ca32a1012851900016858c6"
- },
- {
- "groupId": "5ae197be7ccd1a0001e1f6a1",
- "sort": 120,
- "groupName": "DEEBOT 711",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "702-0000-0205",
- "mid": "uv242z",
- "ota": False,
- "supportVer": {
- "Android": "1.0.5",
- "IOS": "1.0.5"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b7fc85976f7f10001e9a0d0",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8e5d5d85b4d0001776484",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5b5ac4cc8d5a56000111e769"
- },
- {
- "groupId": "5ae197be7ccd1a0001e1f6a1",
- "sort": 120,
- "groupName": "DEEBOT 710",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "702-0000-0205",
- "mid": "uv242z",
- "ota": False,
- "supportVer": {
- "Android": "1.0.5",
- "IOS": "1.0.5"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b7fc85976f7f10001e9a0d0",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8e5d5d85b4d0001776484",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5b5ac4e45f21100001882bb9"
- },
- {
- "groupId": "5ae197be7ccd1a0001e1f6a1",
- "sort": 120,
- "groupName": "DEEBOT 715",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "702-0000-0205",
- "mid": "uv242z",
- "ota": False,
- "supportVer": {
- "Android": "1.0.5",
- "IOS": "1.0.5"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b7fc85976f7f10001e9a0d0",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8e5d5d85b4d0001776484",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5b7b65f176f7f10001e9a0c2"
- },
- {
- "groupId": "5ae197be7ccd1a0001e1f6a1",
- "sort": 120,
- "groupName": "DEEBOT 711s",
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "702-0000-0205",
- "mid": "uv242z",
- "ota": False,
- "supportVer": {
- "Android": "1.0.5",
- "IOS": "1.0.5"
- },
- "smartTypes": [],
- "steps": [
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b7fc85976f7f10001e9a0d0",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8e5d5d85b4d0001776484",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d157f9f77a3a60001051f69"
- }
- ],
- "msg": "success",
- "configFAQ": {
- "wifiFAQUrl": "https://portal-ww.ecouser.net/api/pim/wififaq.html?lang=en&defaultLang=en",
- "notFoundAPUrl": "https://portal-ww.ecouser.net/api/pim/findWifi.html?lang=en&defaultLang=en",
- "configFailedUrl": "https://portal-ww.ecouser.net/api/pim/configfail.html?lang=en&defaultLang=en",
- "contactUS": "helper"
- }
}
configGroupsResponse = {
- "code": 0,
- "data": [
- {
- "sort": 1,
- "id": "5c19a743e916ba00019a4e32",
- "name": "DEEBOT OZMO",
- "robots": [
+ "code": 0,
+ "data": [
{
- "groupId": "5d2460f244af360001383992",
- "category": "",
- "groupName": "DEEBOT U3",
- "sort": 9,
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "939393939393",
- "mid": "xb83mv",
- "ota": False,
- "supportVer": {
- "Android": "1.1.8",
- "IOS": "1.1.8"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
- "retryText": "",
- "confirmText": "I've heard the sound",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d3fe66cea1a2e0001d2f243",
- "products": [
- "5d246180350e7a0001e84bea",
- "5d78f4e878d8b60001e23edc"
- ],
- "smartTypes": [
- "MQ_AP",
- "MQ_AP"
- ],
- "seriesId": "5c19a743e916ba00019a4e32"
+ "sort": 1,
+ "id": "5c19a743e916ba00019a4e32",
+ "name": "DEEBOT OZMO",
+ "robots": [
+ {
+ "groupId": "5d2460f244af360001383992",
+ "category": "",
+ "groupName": "DEEBOT U3",
+ "sort": 9,
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "939393939393",
+ "mid": "xb83mv",
+ "ota": False,
+ "supportVer": {"Android": "1.1.8", "IOS": "1.1.8"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
+ "retryText": "",
+ "confirmText": "I've heard the sound",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d3fe66cea1a2e0001d2f243",
+ "products": [
+ "5d246180350e7a0001e84bea",
+ "5d78f4e878d8b60001e23edc",
+ ],
+ "smartTypes": ["MQ_AP", "MQ_AP"],
+ "seriesId": "5c19a743e916ba00019a4e32",
+ },
+ {
+ "groupId": "5b04bf1d7ccd1a0001e1f6a6",
+ "category": "",
+ "groupName": "DEEBOT OZMO 900 Series",
+ "sort": 10,
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1810-0101",
+ "mid": "y79a7u",
+ "ota": False,
+ "supportVer": {"Android": "1.0.0", "IOS": "1.0.0"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d1472a62a6bd50001b5b6f2",
+ "products": [
+ "5b04c0227ccd1a0001e1f6a8",
+ "5d1474630ac6ad00012b7940",
+ ],
+ "smartTypes": [],
+ "seriesId": "5c19a743e916ba00019a4e32",
+ },
+ {
+ "groupId": "5c19a835a1e6ee0001782245",
+ "category": "",
+ "groupName": "DEEBOT OZMO 920 Series",
+ "sort": 20,
+ "isPopular": True,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 1,
+ "materialNo": "110-1819-0101",
+ "mid": "vi829v",
+ "ota": False,
+ "supportVer": {"Android": "1.1.5", "IOS": "1.1.5"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
+ "retryText": "",
+ "confirmText": "I've heard the sound",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5c9c79c1e9e9270001354ab5",
+ "products": ["5c19a8f3a1e6ee0001782247"],
+ "smartTypes": ["MQ_AP"],
+ "seriesId": "5c19a743e916ba00019a4e32",
+ },
+ {
+ "groupId": "5bbedcd922d57f00018c13b6",
+ "category": "",
+ "groupName": "DEEBOT OZMO/PRO 930 Series",
+ "sort": 30,
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "HK_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1803-0101",
+ "mid": "115",
+ "ota": False,
+ "supportVer": {"Android": "1.1.8", "IOS": "1.1.8"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5cf66652b0acfc000179ff83",
+ "products": [
+ "5bbedd2822d57f00018c13b7",
+ "5cd4dd385b032200015a4561",
+ ],
+ "smartTypes": [],
+ "seriesId": "5c19a743e916ba00019a4e32",
+ },
+ {
+ "groupId": "5c19a8a0ddfc1f0001ede8e0",
+ "category": "",
+ "groupName": "DEEBOT OZMO 950 Series",
+ "sort": 40,
+ "isPopular": True,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 1,
+ "materialNo": "110-1820-0101",
+ "mid": "yna5xi",
+ "ota": False,
+ "supportVer": {"Android": "1.1.5", "IOS": "1.1.5"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
+ "retryText": "",
+ "confirmText": "I've heard the sound",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5caafd981285190001685966",
+ "products": ["5c19a91ca1e6ee000178224a"],
+ "smartTypes": ["MQ_AP"],
+ "seriesId": "5c19a743e916ba00019a4e32",
+ },
+ {
+ "groupId": "5bc8187422d57f00018c13ba",
+ "category": "",
+ "groupName": "DEEBOT OZMO 960 Series",
+ "sort": 50,
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1803-0101",
+ "mid": "gd4uut",
+ "ota": False,
+ "supportVer": {"Android": "1.1.5", "IOS": "1.1.5"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d0899b00ac6ad00012b78f7",
+ "products": ["5bc8189d68142800016a6937"],
+ "smartTypes": [],
+ "seriesId": "5c19a743e916ba00019a4e32",
+ },
+ {
+ "groupId": "5ae147f27ccd1a0001e1f69c",
+ "category": "",
+ "groupName": "DEEBOT OZMO Slim10 Series",
+ "sort": 60,
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1715-0201",
+ "mid": "02uwxm",
+ "ota": False,
+ "supportVer": {"Android": "1.0.0", "IOS": "1.0.0"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5b5ebc34822f0b00013a2e1a",
+ "products": ["5ae1481e7ccd1a0001e1f69e"],
+ "smartTypes": [],
+ "seriesId": "5c19a743e916ba00019a4e32",
+ },
+ {
+ "groupId": "5ca4711412851900016858cb",
+ "category": "",
+ "groupName": "DEEBOT OZMO 700 Series",
+ "sort": 70,
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 1,
+ "materialNo": "110-1825-0201",
+ "mid": "0xyhhr",
+ "ota": False,
+ "supportVer": {"Android": "1.1.5", "IOS": "1.1.5"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
+ "retryText": "",
+ "confirmText": "I've heard the sound",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d117d680ac6ad00012b792e",
+ "products": [
+ "5ca4716312851900016858cd",
+ "5ce7870cd85b4d0001775db9",
+ ],
+ "smartTypes": [],
+ "seriesId": "5c19a743e916ba00019a4e32",
+ },
+ {
+ "groupId": "5ca32b5de9e9270001354b3f",
+ "category": "",
+ "groupName": "DEEBOT OZMO 600 Series",
+ "sort": 80,
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1629-0203",
+ "mid": "159",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d4b75a8ea1a2e0001d2f28e",
+ "products": [
+ "5ca32bc2e9e9270001354b41",
+ "5cbd97b961526a00019799bd",
+ "5cae98d01285190001685974",
+ ],
+ "smartTypes": [],
+ "seriesId": "5c19a743e916ba00019a4e32",
+ },
+ ],
},
{
- "groupId": "5b04bf1d7ccd1a0001e1f6a6",
- "category": "",
- "groupName": "DEEBOT OZMO 900 Series",
- "sort": 10,
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1810-0101",
- "mid": "y79a7u",
- "ota": False,
- "supportVer": {
- "Android": "1.0.0",
- "IOS": "1.0.0"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d1472a62a6bd50001b5b6f2",
- "products": [
- "5b04c0227ccd1a0001e1f6a8",
- "5d1474630ac6ad00012b7940"
- ],
- "smartTypes": [],
- "seriesId": "5c19a743e916ba00019a4e32"
+ "sort": 2,
+ "id": "5c2599b6a1e6ee0001782328",
+ "name": "DEEBOT",
+ "robots": [
+ {
+ "groupId": "5c763de8280fda0001770b7f",
+ "category": "",
+ "groupName": "DEEBOT 500 Series",
+ "sort": 100,
+ "isPopular": True,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "702-0000-0163",
+ "mid": "vsc5ia",
+ "ota": False,
+ "supportVer": {"Android": "1.1.5", "IOS": "1.1.5"},
+ "steps": [
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5df9d6b7c783810001d3d06b",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5dfc34d15d21490001700e14",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5cf6668bda73e90001dc3b98",
+ "products": [
+ "5c763eba280fda0001770b81",
+ "5c763f35280fda0001770b84",
+ "5c763f63280fda0001770b88",
+ "5c763f8263023c0001e7f855",
+ ],
+ "smartTypes": [],
+ "seriesId": "5c2599b6a1e6ee0001782328",
+ },
+ {
+ "groupId": "5acb0f2e7c295c0001876eb4",
+ "category": "",
+ "groupName": "DEEBOT 600 Series",
+ "sort": 110,
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "702-0000-0170",
+ "mid": "dl8fht",
+ "ota": False,
+ "supportVer": {"Android": "1.0.0", "IOS": "1.0.0"},
+ "steps": [
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8e36591fd5d0001892541",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b8cd75f76f7f10001e9a0de",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5cf6669ab0acfc000179ff85",
+ "products": [
+ "5acb0fa87c295c0001876ecf",
+ "5d280ce344af3600013839ab",
+ ],
+ "smartTypes": [],
+ "seriesId": "5c2599b6a1e6ee0001782328",
+ },
+ {
+ "groupId": "5ae197be7ccd1a0001e1f6a1",
+ "category": "",
+ "groupName": "DEEBOT 700 Series",
+ "sort": 120,
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "702-0000-0205",
+ "mid": "uv242z",
+ "ota": False,
+ "supportVer": {"Android": "1.0.5", "IOS": "1.0.5"},
+ "steps": [
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b7fc85976f7f10001e9a0d0",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "image",
+ "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8e5d5d85b4d0001776484",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5b5ec2b1822f0b00013a2e1c",
+ "products": [
+ "5b43077b8bc457000140363e",
+ "5b5149b4ac0b87000148c128",
+ "5b7b65f364e1680001a08b54",
+ "5ceba1c6d85b4d0001776986",
+ ],
+ "smartTypes": [],
+ "seriesId": "5c2599b6a1e6ee0001782328",
+ },
+ {
+ "groupId": "5b6560760506b100015c8867",
+ "category": "",
+ "groupName": "DEEBOT 900 Series",
+ "sort": 130,
+ "isPopular": False,
+ "belongApp": ["ecoglobal", "ecodeebot"],
+ "smartType": "MQ_AP",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1711-0201",
+ "mid": "ls1ok3",
+ "ota": False,
+ "supportVer": {"Android": "1.0.7", "IOS": "1.0.7"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d1472b70ac6ad00012b793f",
+ "products": [
+ "5b6561060506b100015c8868",
+ "5bf2596f23244a00013f2f13",
+ ],
+ "smartTypes": [],
+ "seriesId": "5c2599b6a1e6ee0001782328",
+ },
+ {
+ "groupId": "5ca31e8212851900016858c2",
+ "category": "",
+ "groupName": "DEEBOT N79 Series",
+ "sort": 140,
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "702-0000-0136",
+ "mid": "126",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5cf666bdda73e90001dc3b9a",
+ "products": [
+ "5ca32ab212851900016858c7",
+ "5cce893813afb7000195d6af",
+ "5ca32a11e9e9270001354b39",
+ ],
+ "smartTypes": [],
+ "seriesId": "5c2599b6a1e6ee0001782328",
+ },
+ {
+ "groupId": "5cae9662e9e9270001354b55",
+ "category": "",
+ "groupName": "DEEBOT M80 Pro",
+ "sort": 150,
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1638-0102",
+ "mid": "125",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c1000ba13eb00013feaa4",
+ "products": ["5cae9703128519000168596a"],
+ "smartTypes": [],
+ "seriesId": "5c2599b6a1e6ee0001782328",
+ },
+ {
+ "groupId": "5cae9793e9e9270001354b57",
+ "category": "",
+ "groupName": "DEEBOT M81 Pro",
+ "sort": 160,
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1638-0101",
+ "mid": "141",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c10224d60de0001eaf1ea",
+ "products": ["5cae97c9128519000168596f"],
+ "smartTypes": [],
+ "seriesId": "5c2599b6a1e6ee0001782328",
+ },
+ {
+ "groupId": "5ca31ce8e9e9270001354b33",
+ "category": "",
+ "groupName": "DEEBOT M86",
+ "sort": 170,
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1628-0101",
+ "mid": "129",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5cf66704da73e90001dc3b9b",
+ "products": ["5ca31df1e9e9270001354b35"],
+ "smartTypes": [],
+ "seriesId": "5c2599b6a1e6ee0001782328",
+ },
+ {
+ "groupId": "5cd4df825b032200015a4567",
+ "category": "",
+ "groupName": "DEEBOT M87",
+ "sort": 180,
+ "isPopular": False,
+ "belongApp": ["ecodeebot"],
+ "smartType": "SCM0",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1517-1001",
+ "mid": "121",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8ea21d85b4d0001776489",
+ "products": [],
+ "smartTypes": [],
+ "seriesId": "5c2599b6a1e6ee0001782328",
+ },
+ {
+ "groupId": "5cd4dfc9f542e00001dc2df8",
+ "category": "",
+ "groupName": "DEEBOT M88",
+ "sort": 190,
+ "isPopular": False,
+ "belongApp": ["ecodeebot"],
+ "smartType": "SCM0",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1517-0701",
+ "mid": "107",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8eaa5d85b4d000177648a",
+ "products": [],
+ "smartTypes": [],
+ "seriesId": "5c2599b6a1e6ee0001782328",
+ },
+ {
+ "groupId": "5cd4e077f542e00001dc2dfb",
+ "category": "",
+ "groupName": "DEEBOT R95",
+ "sort": 200,
+ "isPopular": False,
+ "belongApp": ["ecodeebot"],
+ "smartType": "SCM0",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1412-0001",
+ "mid": "113",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8eb7091fd5d000189254a",
+ "products": [],
+ "smartTypes": [],
+ "seriesId": "5c2599b6a1e6ee0001782328",
+ },
+ {
+ "groupId": "5cd4e0b25b032200015a4569",
+ "category": "",
+ "groupName": "DEEBOT R96",
+ "sort": 210,
+ "isPopular": False,
+ "belongApp": ["ecodeebot"],
+ "smartType": "SCM0",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1510-0501",
+ "mid": "118",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8ebd791fd5d000189254b",
+ "products": [],
+ "smartTypes": [],
+ "seriesId": "5c2599b6a1e6ee0001782328",
+ },
+ {
+ "groupId": "5cd4e0e15b032200015a456c",
+ "category": "",
+ "groupName": "DEEBOT R98",
+ "sort": 220,
+ "isPopular": False,
+ "belongApp": ["ecodeebot"],
+ "smartType": "SCM0",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1510-0601",
+ "mid": "117",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8ec13d85b4d000177648b",
+ "products": [],
+ "smartTypes": [],
+ "seriesId": "5c2599b6a1e6ee0001782328",
+ },
+ {
+ "groupId": "5cae9aa5e9e9270001354b5d",
+ "category": "",
+ "groupName": "DEEBOT Slim Series",
+ "sort": 230,
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1639-0102",
+ "mid": "123",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c11fa4d60de0001eaf1ef",
+ "products": [
+ "5cae9b201285190001685977",
+ "5cd43b4cf542e00001dc2dec",
+ ],
+ "smartTypes": [],
+ "seriesId": "5c2599b6a1e6ee0001782328",
+ },
+ {
+ "groupId": "5ca1c9a3e9e9270001354b2b",
+ "category": "",
+ "groupName": "DEEBOT Mini2",
+ "sort": 240,
+ "isPopular": False,
+ "belongApp": ["ecoglobal"],
+ "smartType": "SPA",
+ "failCount": 0,
+ "checkTips": 0,
+ "materialNo": "110-1640-0101",
+ "mid": "142",
+ "ota": False,
+ "supportVer": {"Android": "1.1.7", "IOS": "1.1.7"},
+ "steps": [
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ {
+ "guideImageType": "",
+ "guideImageUrl": "",
+ "title": "",
+ "guideText": "",
+ "retryText": "",
+ "confirmText": "",
+ "btnText": "",
+ },
+ ],
+ "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ca1c901e9e9270001354b2a",
+ "products": ["5ca1ca7a12851900016858bd"],
+ "smartTypes": [],
+ "seriesId": "5c2599b6a1e6ee0001782328",
+ },
+ ],
},
- {
- "groupId": "5c19a835a1e6ee0001782245",
- "category": "",
- "groupName": "DEEBOT OZMO 920 Series",
- "sort": 20,
- "isPopular": True,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 1,
- "materialNo": "110-1819-0101",
- "mid": "vi829v",
- "ota": False,
- "supportVer": {
- "Android": "1.1.5",
- "IOS": "1.1.5"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
- "retryText": "",
- "confirmText": "I've heard the sound",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5c9c79c1e9e9270001354ab5",
- "products": [
- "5c19a8f3a1e6ee0001782247"
- ],
- "smartTypes": [
- "MQ_AP"
- ],
- "seriesId": "5c19a743e916ba00019a4e32"
- },
- {
- "groupId": "5bbedcd922d57f00018c13b6",
- "category": "",
- "groupName": "DEEBOT OZMO/PRO 930 Series",
- "sort": 30,
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "HK_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1803-0101",
- "mid": "115",
- "ota": False,
- "supportVer": {
- "Android": "1.1.8",
- "IOS": "1.1.8"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5cf66652b0acfc000179ff83",
- "products": [
- "5bbedd2822d57f00018c13b7",
- "5cd4dd385b032200015a4561"
- ],
- "smartTypes": [],
- "seriesId": "5c19a743e916ba00019a4e32"
- },
- {
- "groupId": "5c19a8a0ddfc1f0001ede8e0",
- "category": "",
- "groupName": "DEEBOT OZMO 950 Series",
- "sort": 40,
- "isPopular": True,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 1,
- "materialNo": "110-1820-0101",
- "mid": "yna5xi",
- "ota": False,
- "supportVer": {
- "Android": "1.1.5",
- "IOS": "1.1.5"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
- "retryText": "",
- "confirmText": "I've heard the sound",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5caafd981285190001685966",
- "products": [
- "5c19a91ca1e6ee000178224a"
- ],
- "smartTypes": [
- "MQ_AP"
- ],
- "seriesId": "5c19a743e916ba00019a4e32"
- },
- {
- "groupId": "5bc8187422d57f00018c13ba",
- "category": "",
- "groupName": "DEEBOT OZMO 960 Series",
- "sort": 50,
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1803-0101",
- "mid": "gd4uut",
- "ota": False,
- "supportVer": {
- "Android": "1.1.5",
- "IOS": "1.1.5"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d0899b00ac6ad00012b78f7",
- "products": [
- "5bc8189d68142800016a6937"
- ],
- "smartTypes": [],
- "seriesId": "5c19a743e916ba00019a4e32"
- },
- {
- "groupId": "5ae147f27ccd1a0001e1f69c",
- "category": "",
- "groupName": "DEEBOT OZMO Slim10 Series",
- "sort": 60,
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1715-0201",
- "mid": "02uwxm",
- "ota": False,
- "supportVer": {
- "Android": "1.0.0",
- "IOS": "1.0.0"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5b5ebc34822f0b00013a2e1a",
- "products": [
- "5ae1481e7ccd1a0001e1f69e"
- ],
- "smartTypes": [],
- "seriesId": "5c19a743e916ba00019a4e32"
- },
- {
- "groupId": "5ca4711412851900016858cb",
- "category": "",
- "groupName": "DEEBOT OZMO 700 Series",
- "sort": 70,
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 1,
- "materialNo": "110-1825-0201",
- "mid": "0xyhhr",
- "ota": False,
- "supportVer": {
- "Android": "1.1.5",
- "IOS": "1.1.5"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "Briefly press the RESET button for 1 second and then release. You will hear that DEEBOT is ready for network setup.",
- "retryText": "",
- "confirmText": "I've heard the sound",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d117d680ac6ad00012b792e",
- "products": [
- "5ca4716312851900016858cd",
- "5ce7870cd85b4d0001775db9"
- ],
- "smartTypes": [],
- "seriesId": "5c19a743e916ba00019a4e32"
- },
- {
- "groupId": "5ca32b5de9e9270001354b3f",
- "category": "",
- "groupName": "DEEBOT OZMO 600 Series",
- "sort": 80,
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1629-0203",
- "mid": "159",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d4b75a8ea1a2e0001d2f28e",
- "products": [
- "5ca32bc2e9e9270001354b41",
- "5cbd97b961526a00019799bd",
- "5cae98d01285190001685974"
- ],
- "smartTypes": [],
- "seriesId": "5c19a743e916ba00019a4e32"
- }
- ]
+ ],
+ "msg": "success",
+ "configFAQ": {
+ "wifiFAQUrl": "https://portal-ww.ecouser.net/api/pim/wififaq.html?lang=en&defaultLang=en",
+ "notFoundAPUrl": "https://portal-ww.ecouser.net/api/pim/findWifi.html?lang=en&defaultLang=en",
+ "configFailedUrl": "https://portal-ww.ecouser.net/api/pim/configfail.html?lang=en&defaultLang=en",
+ "contactUS": "helper",
},
- {
- "sort": 2,
- "id": "5c2599b6a1e6ee0001782328",
- "name": "DEEBOT",
- "robots": [
- {
- "groupId": "5c763de8280fda0001770b7f",
- "category": "",
- "groupName": "DEEBOT 500 Series",
- "sort": 100,
- "isPopular": True,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "702-0000-0163",
- "mid": "vsc5ia",
- "ota": False,
- "supportVer": {
- "Android": "1.1.5",
- "IOS": "1.1.5"
- },
- "steps": [
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5df9d6b7c783810001d3d06b",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5dfc34d15d21490001700e14",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5cf6668bda73e90001dc3b98",
- "products": [
- "5c763eba280fda0001770b81",
- "5c763f35280fda0001770b84",
- "5c763f63280fda0001770b88",
- "5c763f8263023c0001e7f855"
- ],
- "smartTypes": [],
- "seriesId": "5c2599b6a1e6ee0001782328"
- },
- {
- "groupId": "5acb0f2e7c295c0001876eb4",
- "category": "",
- "groupName": "DEEBOT 600 Series",
- "sort": 110,
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "702-0000-0170",
- "mid": "dl8fht",
- "ota": False,
- "supportVer": {
- "Android": "1.0.0",
- "IOS": "1.0.0"
- },
- "steps": [
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8e36591fd5d0001892541",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b8cd75f76f7f10001e9a0de",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5cf6669ab0acfc000179ff85",
- "products": [
- "5acb0fa87c295c0001876ecf",
- "5d280ce344af3600013839ab"
- ],
- "smartTypes": [],
- "seriesId": "5c2599b6a1e6ee0001782328"
- },
- {
- "groupId": "5ae197be7ccd1a0001e1f6a1",
- "category": "",
- "groupName": "DEEBOT 700 Series",
- "sort": 120,
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "702-0000-0205",
- "mid": "uv242z",
- "ota": False,
- "supportVer": {
- "Android": "1.0.5",
- "IOS": "1.0.5"
- },
- "steps": [
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5b7fc85976f7f10001e9a0d0",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "image",
- "guideImageUrl": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8e5d5d85b4d0001776484",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5b5ec2b1822f0b00013a2e1c",
- "products": [
- "5b43077b8bc457000140363e",
- "5b5149b4ac0b87000148c128",
- "5b7b65f364e1680001a08b54",
- "5ceba1c6d85b4d0001776986"
- ],
- "smartTypes": [],
- "seriesId": "5c2599b6a1e6ee0001782328"
- },
- {
- "groupId": "5b6560760506b100015c8867",
- "category": "",
- "groupName": "DEEBOT 900 Series",
- "sort": 130,
- "isPopular": False,
- "belongApp": [
- "ecoglobal",
- "ecodeebot"
- ],
- "smartType": "MQ_AP",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1711-0201",
- "mid": "ls1ok3",
- "ota": False,
- "supportVer": {
- "Android": "1.0.7",
- "IOS": "1.0.7"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d1472b70ac6ad00012b793f",
- "products": [
- "5b6561060506b100015c8868",
- "5bf2596f23244a00013f2f13"
- ],
- "smartTypes": [],
- "seriesId": "5c2599b6a1e6ee0001782328"
- },
- {
- "groupId": "5ca31e8212851900016858c2",
- "category": "",
- "groupName": "DEEBOT N79 Series",
- "sort": 140,
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "702-0000-0136",
- "mid": "126",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5cf666bdda73e90001dc3b9a",
- "products": [
- "5ca32ab212851900016858c7",
- "5cce893813afb7000195d6af",
- "5ca32a11e9e9270001354b39"
- ],
- "smartTypes": [],
- "seriesId": "5c2599b6a1e6ee0001782328"
- },
- {
- "groupId": "5cae9662e9e9270001354b55",
- "category": "",
- "groupName": "DEEBOT M80 Pro",
- "sort": 150,
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1638-0102",
- "mid": "125",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c1000ba13eb00013feaa4",
- "products": [
- "5cae9703128519000168596a"
- ],
- "smartTypes": [],
- "seriesId": "5c2599b6a1e6ee0001782328"
- },
- {
- "groupId": "5cae9793e9e9270001354b57",
- "category": "",
- "groupName": "DEEBOT M81 Pro",
- "sort": 160,
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1638-0101",
- "mid": "141",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c10224d60de0001eaf1ea",
- "products": [
- "5cae97c9128519000168596f"
- ],
- "smartTypes": [],
- "seriesId": "5c2599b6a1e6ee0001782328"
- },
- {
- "groupId": "5ca31ce8e9e9270001354b33",
- "category": "",
- "groupName": "DEEBOT M86",
- "sort": 170,
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1628-0101",
- "mid": "129",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5cf66704da73e90001dc3b9b",
- "products": [
- "5ca31df1e9e9270001354b35"
- ],
- "smartTypes": [],
- "seriesId": "5c2599b6a1e6ee0001782328"
- },
- {
- "groupId": "5cd4df825b032200015a4567",
- "category": "",
- "groupName": "DEEBOT M87",
- "sort": 180,
- "isPopular": False,
- "belongApp": [
- "ecodeebot"
- ],
- "smartType": "SCM0",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1517-1001",
- "mid": "121",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8ea21d85b4d0001776489",
- "products": [],
- "smartTypes": [],
- "seriesId": "5c2599b6a1e6ee0001782328"
- },
- {
- "groupId": "5cd4dfc9f542e00001dc2df8",
- "category": "",
- "groupName": "DEEBOT M88",
- "sort": 190,
- "isPopular": False,
- "belongApp": [
- "ecodeebot"
- ],
- "smartType": "SCM0",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1517-0701",
- "mid": "107",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8eaa5d85b4d000177648a",
- "products": [],
- "smartTypes": [],
- "seriesId": "5c2599b6a1e6ee0001782328"
- },
- {
- "groupId": "5cd4e077f542e00001dc2dfb",
- "category": "",
- "groupName": "DEEBOT R95",
- "sort": 200,
- "isPopular": False,
- "belongApp": [
- "ecodeebot"
- ],
- "smartType": "SCM0",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1412-0001",
- "mid": "113",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8eb7091fd5d000189254a",
- "products": [],
- "smartTypes": [],
- "seriesId": "5c2599b6a1e6ee0001782328"
- },
- {
- "groupId": "5cd4e0b25b032200015a4569",
- "category": "",
- "groupName": "DEEBOT R96",
- "sort": 210,
- "isPopular": False,
- "belongApp": [
- "ecodeebot"
- ],
- "smartType": "SCM0",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1510-0501",
- "mid": "118",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8ebd791fd5d000189254b",
- "products": [],
- "smartTypes": [],
- "seriesId": "5c2599b6a1e6ee0001782328"
- },
- {
- "groupId": "5cd4e0e15b032200015a456c",
- "category": "",
- "groupName": "DEEBOT R98",
- "sort": 220,
- "isPopular": False,
- "belongApp": [
- "ecodeebot"
- ],
- "smartType": "SCM0",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1510-0601",
- "mid": "117",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ce8ec13d85b4d000177648b",
- "products": [],
- "smartTypes": [],
- "seriesId": "5c2599b6a1e6ee0001782328"
- },
- {
- "groupId": "5cae9aa5e9e9270001354b5d",
- "category": "",
- "groupName": "DEEBOT Slim Series",
- "sort": 230,
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1639-0102",
- "mid": "123",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5d2c11fa4d60de0001eaf1ef",
- "products": [
- "5cae9b201285190001685977",
- "5cd43b4cf542e00001dc2dec"
- ],
- "smartTypes": [],
- "seriesId": "5c2599b6a1e6ee0001782328"
- },
- {
- "groupId": "5ca1c9a3e9e9270001354b2b",
- "category": "",
- "groupName": "DEEBOT Mini2",
- "sort": 240,
- "isPopular": False,
- "belongApp": [
- "ecoglobal"
- ],
- "smartType": "SPA",
- "failCount": 0,
- "checkTips": 0,
- "materialNo": "110-1640-0101",
- "mid": "142",
- "ota": False,
- "supportVer": {
- "Android": "1.1.7",
- "IOS": "1.1.7"
- },
- "steps": [
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- },
- {
- "guideImageType": "",
- "guideImageUrl": "",
- "title": "",
- "guideText": "",
- "retryText": "",
- "confirmText": "",
- "btnText": ""
- }
- ],
- "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ca1c901e9e9270001354b2a",
- "products": [
- "5ca1ca7a12851900016858bd"
- ],
- "smartTypes": [],
- "seriesId": "5c2599b6a1e6ee0001782328"
- }
- ]
- }
- ],
- "msg": "success",
- "configFAQ": {
- "wifiFAQUrl": "https://portal-ww.ecouser.net/api/pim/wififaq.html?lang=en&defaultLang=en",
- "notFoundAPUrl": "https://portal-ww.ecouser.net/api/pim/findWifi.html?lang=en&defaultLang=en",
- "configFailedUrl": "https://portal-ww.ecouser.net/api/pim/configfail.html?lang=en&defaultLang=en",
- "contactUS": "helper"
- }
}
productConfigBatch = [
@@ -2717,9 +2416,9 @@ productConfigBatch = [
"video": False,
"battery": True,
"clean": True,
- "charge": True
+ "charge": True,
}
- }
+ },
},
{
"pid": "5e8e8d8a032edd8457c66bfb",
@@ -2729,9 +2428,9 @@ productConfigBatch = [
"video": False,
"battery": True,
"clean": True,
- "charge": True
+ "charge": True,
}
- }
+ },
},
{
"pid": "5c19a91ca1e6ee000178224a",
@@ -2741,9 +2440,9 @@ productConfigBatch = [
"video": False,
"battery": True,
"clean": True,
- "charge": True
+ "charge": True,
}
- }
+ },
},
{
"pid": "5e8e8d2a032edd3c03c66bf7",
@@ -2753,9 +2452,9 @@ productConfigBatch = [
"video": False,
"battery": True,
"clean": True,
- "charge": True
+ "charge": True,
}
- }
+ },
},
{
"pid": "5de0d86ed88546000195239a",
@@ -2765,9 +2464,9 @@ productConfigBatch = [
"video": True,
"battery": True,
"clean": True,
- "charge": True
+ "charge": True,
}
- }
+ },
},
{
"pid": "5c19a8f3a1e6ee0001782247",
@@ -2777,9 +2476,9 @@ productConfigBatch = [
"video": False,
"battery": True,
"clean": True,
- "charge": True
+ "charge": True,
}
- }
+ },
},
{
"pid": "5e698a6306f6de52c264c61b",
@@ -2789,9 +2488,9 @@ productConfigBatch = [
"video": False,
"battery": True,
"clean": True,
- "charge": True
+ "charge": True,
}
- }
+ },
},
{
"pid": "5e699a4106f6de83ea64c620",
@@ -2801,9 +2500,9 @@ productConfigBatch = [
"video": False,
"battery": True,
"clean": True,
- "charge": True
+ "charge": True,
}
- }
+ },
},
{
"pid": "5edd998afdd6a30008da039b",
@@ -2813,9 +2512,9 @@ productConfigBatch = [
"video": True,
"battery": True,
"clean": True,
- "charge": True
+ "charge": True,
}
- }
+ },
},
{
"pid": "5edd9a4075f2fc000636086c",
@@ -2825,9 +2524,9 @@ productConfigBatch = [
"video": True,
"battery": True,
"clean": True,
- "charge": True
+ "charge": True,
}
- }
+ },
},
{
"pid": "5ed5e4d3a719ea460ec3216c",
@@ -2837,9 +2536,9 @@ productConfigBatch = [
"video": False,
"battery": True,
"clean": True,
- "charge": True
+ "charge": True,
}
- }
+ },
},
{
"pid": "5f88195e6cf8de0008ed7c11",
@@ -2849,9 +2548,9 @@ productConfigBatch = [
"video": False,
"battery": True,
"clean": True,
- "charge": True
+ "charge": True,
}
- }
+ },
},
{
"pid": "5f8819156cf8de0008ed7c0d",
@@ -2861,9 +2560,9 @@ productConfigBatch = [
"video": False,
"battery": True,
"clean": True,
- "charge": True
+ "charge": True,
}
- }
+ },
},
{
"pid": "5fa105c6d16a99000667eb54",
@@ -2873,8 +2572,8 @@ productConfigBatch = [
"video": False,
"battery": True,
"clean": True,
- "charge": True
+ "charge": True,
}
- }
- }
+ },
+ },
]
diff --git a/bumper/plugins/bumper_confserver_portal_rapp.py b/bumper/plugins/bumper_confserver_portal_rapp.py
index 1cd8627..44ca250 100644
--- a/bumper/plugins/bumper_confserver_portal_rapp.py
+++ b/bumper/plugins/bumper_confserver_portal_rapp.py
@@ -6,29 +6,27 @@ from bumper import plugins
class api_rapp(plugins.ConfServerApp):
-
def __init__(self):
self.name = "api_rapp"
self.plugin_type = "sub_api"
self.sub_api = "portal_api"
self.routes = [
- web.route("*", "/rapp/sds/user/data/map/get", self.handle_map_get, name="api_rapp"),
+ web.route(
+ "*", "/rapp/sds/user/data/map/get", self.handle_map_get, name="api_rapp"
+ ),
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
async def handle_map_get(self, request):
try:
body = {
"code": 0,
- "data": {
- "data": {
- "name": "My Home"
- },
- "tag": None
- },
- "message": "success"
+ "data": {"data": {"name": "My Home"}, "tag": None},
+ "message": "success",
}
return web.json_response(body)
@@ -36,4 +34,5 @@ class api_rapp(plugins.ConfServerApp):
except Exception as e:
logging.exception(f"{e}")
+
plugin = api_rapp()
diff --git a/bumper/plugins/bumper_confserver_portal_users.py b/bumper/plugins/bumper_confserver_portal_users.py
index 254fdbf..3c20182 100644
--- a/bumper/plugins/bumper_confserver_portal_users.py
+++ b/bumper/plugins/bumper_confserver_portal_users.py
@@ -10,20 +10,24 @@ from datetime import datetime, timedelta
class portal_api_users(plugins.ConfServerApp):
-
def __init__(self):
self.name = "portal_api_users"
- self.plugin_type = "sub_api"
+ self.plugin_type = "sub_api"
self.sub_api = "portal_api"
-
+
self.routes = [
-
- web.route("*", "/users/user.do", self.handle_usersapi, name="portal_api_users_user"),
-
+ web.route(
+ "*",
+ "/users/user.do",
+ self.handle_usersapi,
+ name="portal_api_users_user",
+ ),
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
-
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
+
async def handle_usersapi(self, request):
if not request.method == "GET": # Skip GET for now
try:
@@ -116,5 +120,5 @@ class portal_api_users(plugins.ConfServerApp):
body = {"result": "fail", "todo": "result"}
return web.json_response(body)
-plugin = portal_api_users()
+plugin = portal_api_users()
diff --git a/bumper/plugins/bumper_confserver_upload_global.py b/bumper/plugins/bumper_confserver_upload_global.py
index 8f6fa11..ed7447e 100644
--- a/bumper/plugins/bumper_confserver_upload_global.py
+++ b/bumper/plugins/bumper_confserver_upload_global.py
@@ -9,32 +9,38 @@ from bumper import plugins
from datetime import datetime, timedelta
import os
-class upload_global(plugins.ConfServerApp):
+class upload_global(plugins.ConfServerApp):
def __init__(self):
self.name = "upload_global"
- self.plugin_type = "sub_api"
+ self.plugin_type = "sub_api"
self.sub_api = "upload_api"
-
- self.routes = [
-
- web.route("*", "/global/{year}/{month}/{day}/{fileid}", self.handle_upload_global_file, name="upload_global_getFile"),
+ self.routes = [
+ web.route(
+ "*",
+ "/global/{year}/{month}/{day}/{fileid}",
+ self.handle_upload_global_file,
+ name="upload_global_getFile",
+ ),
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
-
-
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
async def handle_upload_global_file(self, request):
try:
fileID = request.match_info.get("id", "")
- return web.FileResponse(os.path.join(bumper.bumper_dir,"bumper","web","images","robotvac_image.jpg"))
-
- except Exception as e:
- logging.exception(f"{e}")
+ return web.FileResponse(
+ os.path.join(
+ bumper.bumper_dir, "bumper", "web", "images", "robotvac_image.jpg"
+ )
+ )
+
+ except Exception as e:
+ logging.exception(f"{e}")
+
-
-
plugin = upload_global()
diff --git a/bumper/plugins/bumper_confserver_v1_global_auth.py b/bumper/plugins/bumper_confserver_v1_global_auth.py
index bbceb70..ffb94b5 100644
--- a/bumper/plugins/bumper_confserver_v1_global_auth.py
+++ b/bumper/plugins/bumper_confserver_v1_global_auth.py
@@ -10,19 +10,24 @@ from datetime import datetime, timedelta
class v1_global_auth(plugins.ConfServerApp):
-
def __init__(self):
self.name = "v1_global_auth"
self.plugin_type = "sub_api"
self.sub_api = "api_v1"
-
+
authhandler = bumper.ConfServer.ConfServer_AuthHandler()
self.routes = [
- web.route("*", "/global/auth/getAuthCode", authhandler.get_AuthCode, name="v1_global_auth_getAuthCode"),
+ web.route(
+ "*",
+ "/global/auth/getAuthCode",
+ authhandler.get_AuthCode,
+ name="v1_global_auth_getAuthCode",
+ ),
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
plugin = v1_global_auth()
-
diff --git a/bumper/plugins/bumper_confserver_v1_private_ad.py b/bumper/plugins/bumper_confserver_v1_private_ad.py
index 530057c..000d85b 100644
--- a/bumper/plugins/bumper_confserver_v1_private_ad.py
+++ b/bumper/plugins/bumper_confserver_v1_private_ad.py
@@ -10,20 +10,30 @@ from datetime import datetime, timedelta
class v1_private_ad(plugins.ConfServerApp):
-
def __init__(self):
self.name = "v1_private_ad"
- self.plugin_type = "sub_api"
+ self.plugin_type = "sub_api"
self.sub_api = "api_v1"
-
- self.routes = [
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/ad/getAdByPositionType", self.handle_getAdByPositionType, name="v1_ad_getAdByPositionType"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/ad/getBootScreen", self.handle_getBootScreen, name="v1_ad_getBootScreen"),
+ self.routes = [
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/ad/getAdByPositionType",
+ self.handle_getAdByPositionType,
+ name="v1_ad_getAdByPositionType",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/ad/getBootScreen",
+ self.handle_getBootScreen,
+ name="v1_ad_getBootScreen",
+ ),
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
-
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
+
async def handle_getAdByPositionType(self, request): # EcoVacs Home
try:
body = {
@@ -54,5 +64,5 @@ class v1_private_ad(plugins.ConfServerApp):
except Exception as e:
logging.exception(f"{e}")
-plugin = v1_private_ad()
+plugin = v1_private_ad()
diff --git a/bumper/plugins/bumper_confserver_v1_private_campaign.py b/bumper/plugins/bumper_confserver_v1_private_campaign.py
index c388e25..da097a3 100644
--- a/bumper/plugins/bumper_confserver_v1_private_campaign.py
+++ b/bumper/plugins/bumper_confserver_v1_private_campaign.py
@@ -10,20 +10,24 @@ from datetime import datetime, timedelta
class v1_private_campaign(plugins.ConfServerApp):
-
def __init__(self):
self.name = "v1_private_campaign"
- self.plugin_type = "sub_api"
+ self.plugin_type = "sub_api"
self.sub_api = "api_v1"
-
+
self.routes = [
-
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/campaign/homePageAlert", self.handle_homePageAlert, name="v1_campaign_homePageAlert"),
-
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/campaign/homePageAlert",
+ self.handle_homePageAlert,
+ name="v1_campaign_homePageAlert",
+ ),
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
-
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
+
async def handle_homePageAlert(self, request):
try:
nextAlert = self.get_milli_time(
@@ -47,8 +51,7 @@ class v1_private_campaign(plugins.ConfServerApp):
return web.json_response(body)
except Exception as e:
- logging.exception(f"{e}")
-
+ logging.exception(f"{e}")
+
plugin = v1_private_campaign()
-
diff --git a/bumper/plugins/bumper_confserver_v1_private_common.py b/bumper/plugins/bumper_confserver_v1_private_common.py
index ec2010d..9727828 100644
--- a/bumper/plugins/bumper_confserver_v1_private_common.py
+++ b/bumper/plugins/bumper_confserver_v1_private_common.py
@@ -8,25 +8,65 @@ from bumper.models import *
class v1_private_common(plugins.ConfServerApp):
-
def __init__(self):
self.name = "v1_private_common"
self.plugin_type = "sub_api"
self.sub_api = "api_v1"
self.routes = [
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkAPPVersion", self.handle_checkAPPVersion, name="v1_common_checkAppVersion"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkVersion", self.handle_checkVersion, name="v1_common_checkVersion"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/uploadDeviceInfo", self.handle_uploadDeviceInfo, name="v1_common_uploadDeviceInfo"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getSystemReminder", self.handle_getSystemReminder, name="v1_common_getSystemReminder"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getConfig",self.handle_getConfig, name="v1_common_getConfig"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getAreas",self.handle_getAreas, name="v1_common_getAreas"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getAgreementURLBatch", self.handle_getAgreementURLBatch, name="v1_common_getAgreementURLBatch"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getTimestamp", self.handle_getTimestamp, name="v1_common_getTimestamp"),
-
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkAPPVersion",
+ self.handle_checkAPPVersion,
+ name="v1_common_checkAppVersion",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkVersion",
+ self.handle_checkVersion,
+ name="v1_common_checkVersion",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/uploadDeviceInfo",
+ self.handle_uploadDeviceInfo,
+ name="v1_common_uploadDeviceInfo",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getSystemReminder",
+ self.handle_getSystemReminder,
+ name="v1_common_getSystemReminder",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getConfig",
+ self.handle_getConfig,
+ name="v1_common_getConfig",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getAreas",
+ self.handle_getAreas,
+ name="v1_common_getAreas",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getAgreementURLBatch",
+ self.handle_getAgreementURLBatch,
+ name="v1_common_getAgreementURLBatch",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getTimestamp",
+ self.handle_getTimestamp,
+ name="v1_common_getTimestamp",
+ ),
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
async def handle_checkVersion(self, request):
try:
@@ -115,11 +155,8 @@ class v1_private_common(plugins.ConfServerApp):
async def handle_getConfig(self, request):
try:
data = []
- for key in request.query["keys"].split(','):
- data.append({
- "key": key,
- "value": "Y"
- })
+ for key in request.query["keys"].split(","):
+ data.append({"key": key, "value": "Y"})
body = {
"code": bumper.RETURN_API_SUCCESS,
@@ -160,7 +197,7 @@ class v1_private_common(plugins.ConfServerApp):
"id": "20180804040641_7d746faf18b8cb22a50d145598fe4c90",
"type": "USER",
"url": "https://gl-eu-wap.ecovacs.com/content/agreement?id=20180804040641_7d746faf18b8cb22a50d145598fe4c90&language=EN",
- "version": "1.03"
+ "version": "1.03",
},
{
"acceptTime": None,
@@ -168,8 +205,8 @@ class v1_private_common(plugins.ConfServerApp):
"id": "20180804040245_4e7c56dfb7ebd3b81b1f2747d0859fac",
"type": "PRIVACY",
"url": "https://gl-eu-wap.ecovacs.com/content/agreement?id=20180804040245_4e7c56dfb7ebd3b81b1f2747d0859fac&language=EN",
- "version": "1.03"
- }
+ "version": "1.03",
+ },
],
"msg": "操作成功",
"success": True,
@@ -186,9 +223,7 @@ class v1_private_common(plugins.ConfServerApp):
time = self.get_milli_time(datetime.utcnow().timestamp())
body = {
"code": bumper.RETURN_API_SUCCESS,
- "data": {
- "timestamp": time
- },
+ "data": {"timestamp": time},
"msg": "操作成功",
"success": True,
"time": time,
@@ -202,261 +237,442 @@ class v1_private_common(plugins.ConfServerApp):
plugin = v1_private_common()
-AREA_LIST = {"currentVersion": 231,
- "areaList": [{"areaKey": "JP", "chsName": "日本", "enName": "Japan", "pyFirst": "R"},
- {"areaKey": "MY", "chsName": "马来西亚", "enName": "Malaysia", "pyFirst": "M"},
- {"areaKey": "DE", "chsName": "德国", "enName": "Germany", "pyFirst": "D"},
- {"areaKey": "LI", "chsName": "列支敦斯登", "enName": "Liechtenstein", "pyFirst": "L"},
- {"areaKey": "AT", "chsName": "奥地利", "enName": "Austria", "pyFirst": "A"},
- {"areaKey": "TW", "chsName": "台湾", "enName": "Taiwan", "pyFirst": "T"},
- {"areaKey": "FR", "chsName": "法国", "enName": "France", "pyFirst": "F"},
- {"areaKey": "CN", "chsName": "中国大陆", "enName": "China Mainland", "pyFirst": "Z"},
- {"areaKey": "SG", "chsName": "新加坡", "enName": "Singapore", "pyFirst": "X"},
- {"areaKey": "RE", "chsName": "留尼汪岛", "enName": "Reunion Island", "pyFirst": "L"},
- {"areaKey": "EH", "chsName": "西撒哈拉", "enName": "Western Sahara", "pyFirst": "X"},
- {"areaKey": "WF", "chsName": "瓦利斯群岛和富图纳群岛", "enName": "Wallis and Futuna Islands",
- "pyFirst": "W"},
- {"areaKey": "KP", "chsName": "朝鲜", "enName": "North Korea", "pyFirst": "C"},
- {"areaKey": "ZW", "chsName": "津巴布韦", "enName": "Zimbabwe", "pyFirst": "J"},
- {"areaKey": "VI", "chsName": "美属维尔京群岛", "enName": "United States Virgin Islands",
- "pyFirst": "M"},
- {"areaKey": "PF", "chsName": "法属玻里尼西亚", "enName": "French Polynesia",
- "pyFirst": "F"},
- {"areaKey": "DJ", "chsName": "吉布提", "enName": "Djibouti", "pyFirst": "J"},
- {"areaKey": "KZ", "chsName": "哈萨克斯坦", "enName": "Kazakhstan", "pyFirst": "H"},
- {"areaKey": "TV", "chsName": "图瓦卢", "enName": "Tuvalu", "pyFirst": "T"},
- {"areaKey": "VU", "chsName": "瓦努阿图", "enName": "Vanuatu", "pyFirst": "W"},
- {"areaKey": "IN", "chsName": "印度", "enName": "India", "pyFirst": "Y"},
- {"areaKey": "CM", "chsName": "喀麦隆", "enName": "Cameroon", "pyFirst": "K"},
- {"areaKey": "LK", "chsName": "斯里兰卡", "enName": "Sri Lanka", "pyFirst": "S"},
- {"areaKey": "CC", "chsName": "科科斯群岛", "enName": "Cocos Islands", "pyFirst": "K"},
- {"areaKey": "KY", "chsName": "开曼群岛", "enName": "Cayman Islands", "pyFirst": "K"},
- {"areaKey": "QA", "chsName": "卡塔尔", "enName": "Qatar", "pyFirst": "K"},
- {"areaKey": "AZ", "chsName": "阿塞拜疆", "enName": "Azerbaijan", "pyFirst": "A"},
- {"areaKey": "HN", "chsName": "洪都拉斯", "enName": "Honduras", "pyFirst": "H"},
- {"areaKey": "AW", "chsName": "阿鲁巴岛", "enName": "Aruba", "pyFirst": "A"},
- {"areaKey": "KH", "chsName": "柬埔寨", "enName": "Cambodia", "pyFirst": "J"},
- {"areaKey": "CO", "chsName": "哥伦比亚", "enName": "Colombia", "pyFirst": "G"},
- {"areaKey": "IR", "chsName": "伊朗", "enName": "Iran", "pyFirst": "Y"},
- {"areaKey": "ZA", "chsName": "南非", "enName": "South Africa", "pyFirst": "N"},
- {"areaKey": "UY", "chsName": "乌拉圭", "enName": "Uruguay", "pyFirst": "W"},
- {"areaKey": "GU", "chsName": "关岛", "enName": "Guam", "pyFirst": "G"},
- {"areaKey": "GH", "chsName": "加纳", "enName": "Ghana", "pyFirst": "J"},
- {"areaKey": "GN", "chsName": "几内亚", "enName": "Guynea", "pyFirst": "J"},
- {"areaKey": "MH", "chsName": "马绍尔群岛", "enName": "Marshall Islands",
- "pyFirst": "M"},
- {"areaKey": "SE", "chsName": "瑞典", "enName": "Sweden", "pyFirst": "R"},
- {"areaKey": "SB", "chsName": "所罗门群岛", "enName": "Solomon Islands",
- "pyFirst": "S"},
- {"areaKey": "NE", "chsName": "尼日尔", "enName": "Niger", "pyFirst": "N"},
- {"areaKey": "HT", "chsName": "海地", "enName": "Haiti", "pyFirst": "H"},
- {"areaKey": "PL", "chsName": "波兰", "enName": "Poland", "pyFirst": "B"},
- {"areaKey": "DO", "chsName": "多米尼加共和国", "enName": "Dominican Republic",
- "pyFirst": "D"},
- {"areaKey": "PS", "chsName": "巴勒斯坦", "enName": "Palestine", "pyFirst": "B"},
- {"areaKey": "KW", "chsName": "科威特", "enName": "Kuwait", "pyFirst": "K"},
- {"areaKey": "UZ", "chsName": "乌兹别克斯坦", "enName": "Republic of Uzbekistan",
- "pyFirst": "W"},
- {"areaKey": "GD", "chsName": "格林纳达", "enName": "Grenada", "pyFirst": "G"},
- {"areaKey": "KG", "chsName": "吉尔吉斯斯坦", "enName": "Kyrgyzstan", "pyFirst": "J"},
- {"areaKey": "JO", "chsName": "约旦", "enName": "Jordan", "pyFirst": "Y"},
- {"areaKey": "IL", "chsName": "以色列", "enName": "Israel", "pyFirst": "Y"},
- {"areaKey": "UK", "chsName": "英国", "enName": "United Kingdom", "pyFirst": "Y"},
- {"areaKey": "MW", "chsName": "马拉维", "enName": "Malawi", "pyFirst": "M"},
- {"areaKey": "MC", "chsName": "摩纳哥", "enName": "Monaco", "pyFirst": "M"},
- {"areaKey": "IC", "chsName": "加那利群岛", "enName": "Canary Islands", "pyFirst": "J"},
- {"areaKey": "JM", "chsName": "牙买加", "enName": "Jamaica", "pyFirst": "Y"},
- {"areaKey": "MP", "chsName": "北马里亚纳群岛", "enName": "The Northern Mariana Islands",
- "pyFirst": "B"},
- {"areaKey": "BH", "chsName": "巴林岛", "enName": "Bahrain", "pyFirst": "B"},
- {"areaKey": "MK", "chsName": "马其顿", "enName": "Macedonia", "pyFirst": "M"},
- {"areaKey": "ET", "chsName": "埃塞俄比亚", "enName": "Ethiopia", "pyFirst": "A"},
- {"areaKey": "CL", "chsName": "智利", "enName": "Chile", "pyFirst": "Z"},
- {"areaKey": "GP", "chsName": "瓜德罗普岛", "enName": "Guadeloupe", "pyFirst": "G"},
- {"areaKey": "FK", "chsName": "福克兰群岛", "enName": "Falkland Islands",
- "pyFirst": "F"},
- {"areaKey": "GL", "chsName": "格陵兰", "enName": "Greenland", "pyFirst": "G"},
- {"areaKey": "BF", "chsName": "布基纳法索", "enName": "Burkina Faso", "pyFirst": "B"},
- {"areaKey": "GI", "chsName": "直布罗陀", "enName": "Gibraltar", "pyFirst": "Z"},
- {"areaKey": "MV", "chsName": "马尔代夫", "enName": "Maldives", "pyFirst": "M"},
- {"areaKey": "CU", "chsName": "古巴", "enName": "Cuba", "pyFirst": "G"},
- {"areaKey": "LS", "chsName": "莱索托", "enName": "Lesotho", "pyFirst": "L"},
- {"areaKey": "MA", "chsName": "摩洛哥", "enName": "Morocco", "pyFirst": "M"},
- {"areaKey": "AL", "chsName": "阿尔巴尼亚", "enName": "Albania", "pyFirst": "A"},
- {"areaKey": "AF", "chsName": "阿富汗", "enName": "Afghanistan", "pyFirst": "A"},
- {"areaKey": "CA", "chsName": "加拿大", "enName": "Canada", "pyFirst": "J"},
- {"areaKey": "BB", "chsName": "巴巴多斯", "enName": "Barbados", "pyFirst": "B"},
- {"areaKey": "LC", "chsName": "圣卢西亚岛", "enName": "Saint Lucia", "pyFirst": "S"},
- {"areaKey": "PN", "chsName": "皮特克恩岛", "enName": "Pitcairn Island",
- "pyFirst": "P"},
- {"areaKey": "LV", "chsName": "拉脱维亚", "enName": "Latvia", "pyFirst": "L"},
- {"areaKey": "NO", "chsName": "挪威", "enName": "Norway", "pyFirst": "N"},
- {"areaKey": "BE", "chsName": "比利时", "enName": "Belgium", "pyFirst": "B"},
- {"areaKey": "VE", "chsName": "委内瑞拉", "enName": "Venezuela", "pyFirst": "W"},
- {"areaKey": "MQ", "chsName": "马提尼克", "enName": "Martinique", "pyFirst": "M"},
- {"areaKey": "GY", "chsName": "圭亚那", "enName": "Guyana", "pyFirst": "G"},
- {"areaKey": "AM", "chsName": "亚美尼亚", "enName": "Armenia", "pyFirst": "Y"},
- {"areaKey": "EC", "chsName": "厄瓜多尔", "enName": "Ecuador", "pyFirst": "E"},
- {"areaKey": "CV", "chsName": "佛得角", "enName": "Cape Verde", "pyFirst": "F"},
- {"areaKey": "NZ", "chsName": "新西兰", "enName": "New Zealand", "pyFirst": "X"},
- {"areaKey": "RO", "chsName": "罗马尼亚", "enName": "Romania", "pyFirst": "L"},
- {"areaKey": "DM", "chsName": "多米尼加", "enName": "Dominica", "pyFirst": "D"},
- {"areaKey": "TZ", "chsName": "坦桑尼亚", "enName": "Tanzania", "pyFirst": "T"},
- {"areaKey": "BD", "chsName": "孟加拉国", "enName": "Bangladesh", "pyFirst": "M"},
- {"areaKey": "TD", "chsName": "乍得", "enName": "Chad", "pyFirst": "Z"},
- {"areaKey": "LT", "chsName": "立陶宛", "enName": "Lithuania", "pyFirst": "L"},
- {"areaKey": "TJ", "chsName": "塔吉克斯坦", "enName": "Tajikistan", "pyFirst": "T"},
- {"areaKey": "TK", "chsName": "托克劳", "enName": "Tokelau", "pyFirst": "T"},
- {"areaKey": "BS", "chsName": "巴哈马群岛", "enName": "Bahamas", "pyFirst": "B"},
- {"areaKey": "MM", "chsName": "缅甸", "enName": "Myanmar", "pyFirst": "M"},
- {"areaKey": "BI", "chsName": "布隆迪", "enName": "Burundi", "pyFirst": "B"},
- {"areaKey": "PY", "chsName": "巴拉圭", "enName": "Paraguay", "pyFirst": "B"},
- {"areaKey": "SK", "chsName": "斯洛伐克", "enName": "Slovakia", "pyFirst": "S"},
- {"areaKey": "FI", "chsName": "芬兰", "enName": "Finland", "pyFirst": "F"},
- {"areaKey": "GA", "chsName": "加蓬", "enName": "Gabon", "pyFirst": "J"},
- {"areaKey": "DZ", "chsName": "阿尔及利亚", "enName": "Algeria", "pyFirst": "A"},
- {"areaKey": "FO", "chsName": "法罗群岛", "enName": "Faroe Islands", "pyFirst": "F"},
- {"areaKey": "ZM", "chsName": "赞比亚", "enName": "Zambia", "pyFirst": "Z"},
- {"areaKey": "NU", "chsName": "纽埃", "enName": "Niue", "pyFirst": "N"},
- {"areaKey": "ER", "chsName": "厄立特里亚国", "enName": "Eritrea", "pyFirst": "E"},
- {"areaKey": "HK", "chsName": "香港", "enName": "Hong Kong", "pyFirst": "X"},
- {"areaKey": "IT", "chsName": "意大利", "enName": "Italy", "pyFirst": "Y"},
- {"areaKey": "MS", "chsName": "蒙特色拉特岛", "enName": "Montserrat", "pyFirst": "M"},
- {"areaKey": "EE", "chsName": "爱沙尼亚", "enName": "Estonia", "pyFirst": "A"},
- {"areaKey": "WS", "chsName": "萨摩亚", "enName": "Samoa", "pyFirst": "S"},
- {"areaKey": "TG", "chsName": "多哥", "enName": "Togo", "pyFirst": "D"},
- {"areaKey": "ML", "chsName": "马里", "enName": "Mali", "pyFirst": "M"},
- {"areaKey": "GF", "chsName": "法属圭亚那", "enName": "French Guyana", "pyFirst": "F"},
- {"areaKey": "KM", "chsName": "科摩罗", "enName": "Comoros", "pyFirst": "K"},
- {"areaKey": "ID", "chsName": "印度尼西亚", "enName": "Indonesia", "pyFirst": "Y"},
- {"areaKey": "KE", "chsName": "肯尼亚", "enName": "Kenya", "pyFirst": "K"},
- {"areaKey": "EG", "chsName": "埃及", "enName": "Egypt", "pyFirst": "A"},
- {"areaKey": "NF", "chsName": "诺福克岛", "enName": "Norfolk Island", "pyFirst": "N"},
- {"areaKey": "RS", "chsName": "塞尔维亚", "enName": "Serbia", "pyFirst": "S"},
- {"areaKey": "TR", "chsName": "土耳其", "enName": "Turkey", "pyFirst": "T"},
- {"areaKey": "DK", "chsName": "丹麦", "enName": "Denmark", "pyFirst": "D"},
- {"areaKey": "AD", "chsName": "安道尔", "enName": "Andorra", "pyFirst": "A"},
- {"areaKey": "LR", "chsName": "利比里亚", "enName": "Liberia", "pyFirst": "L"},
- {"areaKey": "AE", "chsName": "阿拉伯联合酋长国", "enName": "United Arab Emirates",
- "pyFirst": "A"},
- {"areaKey": "CH", "chsName": "瑞士", "enName": "Switzerland", "pyFirst": "R"},
- {"areaKey": "AU", "chsName": "澳大利亚", "enName": "Australia", "pyFirst": "A"},
- {"areaKey": "TP", "chsName": "东帝汶", "enName": "East Timor", "pyFirst": "D"},
- {"areaKey": "LY", "chsName": "利比亚", "enName": "Libya", "pyFirst": "L"},
- {"areaKey": "RW", "chsName": "卢旺达", "enName": "Rwanda", "pyFirst": "L"},
- {"areaKey": "SA", "chsName": "沙特阿拉伯", "enName": "Saudi Arabia", "pyFirst": "S"},
- {"areaKey": "AR", "chsName": "阿根廷", "enName": "Argentina", "pyFirst": "A"},
- {"areaKey": "GM", "chsName": "冈比亚", "enName": "Gambia", "pyFirst": "G"},
- {"areaKey": "BY", "chsName": "白俄罗斯", "enName": "Belarus", "pyFirst": "B"},
- {"areaKey": "SL", "chsName": "塞拉利昂", "enName": "Sierra Leone", "pyFirst": "S"},
- {"areaKey": "TM", "chsName": "土库曼斯坦", "enName": "Turkmenistan", "pyFirst": "T"},
- {"areaKey": "AG", "chsName": "安提瓜和巴布达", "enName": "Antigua and Barbuda",
- "pyFirst": "A"},
- {"areaKey": "MR", "chsName": "毛里塔尼亚", "enName": "Mauritania", "pyFirst": "M"},
- {"areaKey": "PT", "chsName": "葡萄牙", "enName": "Portugal", "pyFirst": "P"},
- {"areaKey": "BW", "chsName": "博茨瓦纳", "enName": "Botswana", "pyFirst": "B"},
- {"areaKey": "GT", "chsName": "危地马拉", "enName": "Guatemala", "pyFirst": "W"},
- {"areaKey": "BT", "chsName": "不丹", "enName": "Bhutan", "pyFirst": "B"},
- {"areaKey": "AI", "chsName": "安圭拉岛", "enName": "Anguilla", "pyFirst": "A"},
- {"areaKey": "OM", "chsName": "阿曼", "enName": "Oman", "pyFirst": "A"},
- {"areaKey": "KI", "chsName": "基里巴斯", "enName": "Kiribati", "pyFirst": "J"},
- {"areaKey": "UA", "chsName": "乌克兰", "enName": "Ukraine", "pyFirst": "W"},
- {"areaKey": "YE", "chsName": "也门", "enName": "Yemen", "pyFirst": "Y"},
- {"areaKey": "DR", "chsName": "刚果民主共和国",
- "enName": "Democratic Republic of the Congo", "pyFirst": "G"},
- {"areaKey": "MD", "chsName": "摩尔多瓦", "enName": "Moldova", "pyFirst": "M"},
- {"areaKey": "GW", "chsName": "几内亚比绍", "enName": "Guinea-Bissau", "pyFirst": "J"},
- {"areaKey": "CG", "chsName": "刚果布共和国", "enName": "Congo Brazzaville",
- "pyFirst": "G"},
- {"areaKey": "SN", "chsName": "塞内加尔", "enName": "Senegal", "pyFirst": "S"},
- {"areaKey": "BA", "chsName": "波黑", "enName": "Bosnia Hercegovina",
- "pyFirst": "B"},
- {"areaKey": "MO", "chsName": "澳门", "enName": "Macao", "pyFirst": "A"},
- {"areaKey": "KN", "chsName": "圣基茨和尼维斯", "enName": "Saint Kitts and Nevis",
- "pyFirst": "S"},
- {"areaKey": "TO", "chsName": "汤加", "enName": "Tonga", "pyFirst": "T"},
- {"areaKey": "NG", "chsName": "尼日利亚", "enName": "Nigeria", "pyFirst": "N"},
- {"areaKey": "TT", "chsName": "特立尼达和多巴哥", "enName": "Trinidad and Tobago",
- "pyFirst": "T"},
- {"areaKey": "CF", "chsName": "中非共和国", "enName": "Central African Republic",
- "pyFirst": "Z"},
- {"areaKey": "PE", "chsName": "秘鲁", "enName": "Peru", "pyFirst": "M"},
- {"areaKey": "PG", "chsName": "巴布亚新几内亚", "enName": "Papua New Guinea",
- "pyFirst": "B"},
- {"areaKey": "CX", "chsName": "圣延岛", "enName": "Christmas Island", "pyFirst": "S"},
- {"areaKey": "AN", "chsName": "安的列斯", "enName": "Netherlands Antilles",
- "pyFirst": "A"},
- {"areaKey": "BO", "chsName": "玻利维亚", "enName": "Bolivia", "pyFirst": "B"},
- {"areaKey": "IQ", "chsName": "伊拉克", "enName": "Iraq", "pyFirst": "Y"},
- {"areaKey": "NP", "chsName": "尼泊尔", "enName": "Nepal", "pyFirst": "N"},
- {"areaKey": "BJ", "chsName": "贝宁", "enName": "Benin", "pyFirst": "B"},
- {"areaKey": "VN", "chsName": "越南", "enName": "Vietnam", "pyFirst": "Y"},
- {"areaKey": "NI", "chsName": "尼加拉瓜", "enName": "Nicaragua", "pyFirst": "N"},
- {"areaKey": "PW", "chsName": "帕劳群岛", "enName": "Palau", "pyFirst": "P"},
- {"areaKey": "SO", "chsName": "索马里", "enName": "Somalia", "pyFirst": "S"},
- {"areaKey": "SM", "chsName": "圣马力诺", "enName": "San Marino", "pyFirst": "S"},
- {"areaKey": "NR", "chsName": "瑙鲁", "enName": "Nauru", "pyFirst": "N"},
- {"areaKey": "BN", "chsName": "文莱", "enName": "Brunei Darussalam", "pyFirst": "W"},
- {"areaKey": "MZ", "chsName": "莫桑比克", "enName": "Mozambique", "pyFirst": "M"},
- {"areaKey": "GR", "chsName": "希腊", "enName": "Greece", "pyFirst": "X"},
- {"areaKey": "TN", "chsName": "突尼斯", "enName": "Tunisia", "pyFirst": "T"},
- {"areaKey": "RU", "chsName": "俄罗斯", "enName": "Russian Federation",
- "pyFirst": "E"},
- {"areaKey": "MG", "chsName": "马达加斯加岛", "enName": "Madagascar", "pyFirst": "M"},
- {"areaKey": "NA", "chsName": "纳米比亚", "enName": "Namibia", "pyFirst": "N"},
- {"areaKey": "CQ", "chsName": "赤道几内亚", "enName": "Equatorial Guinea",
- "pyFirst": "C"},
- {"areaKey": "SR", "chsName": "苏里南", "enName": "Suriname", "pyFirst": "S"},
- {"areaKey": "MU", "chsName": "毛里求斯", "enName": "Mauritius", "pyFirst": "M"},
- {"areaKey": "LA", "chsName": "老挝", "enName": "Laos", "pyFirst": "L"},
- {"areaKey": "US", "chsName": "美国", "enName": "United States", "pyFirst": "M"},
- {"areaKey": "ST", "chsName": "圣多美与普林希比共和国", "enName": "Sao Tome and Principe",
- "pyFirst": "S"},
- {"areaKey": "BM", "chsName": "百慕大群岛", "enName": "Bermuda", "pyFirst": "B"},
- {"areaKey": "LU", "chsName": "卢森堡", "enName": "Luxembourg", "pyFirst": "L"},
- {"areaKey": "CR", "chsName": "哥斯达黎加", "enName": "Costa Rica", "pyFirst": "G"},
- {"areaKey": "KR", "chsName": "韩国", "enName": "South Korea", "pyFirst": "H"},
- {"areaKey": "CZ", "chsName": "捷克", "enName": "Czech Republic", "pyFirst": "J"},
- {"areaKey": "MX", "chsName": "墨西哥", "enName": "Mexico", "pyFirst": "M"},
- {"areaKey": "SH", "chsName": "圣赫勒拿岛", "enName": "St Helena", "pyFirst": "S"},
- {"areaKey": "AO", "chsName": "安哥拉", "enName": "Angola", "pyFirst": "A"},
- {"areaKey": "MN", "chsName": "蒙古", "enName": "Mongolia", "pyFirst": "M"},
- {"areaKey": "VC", "chsName": "圣文森特和格林纳丁斯",
- "enName": "Saint Vincent and the Grenadines", "pyFirst": "S"},
- {"areaKey": "PH", "chsName": "菲律宾", "enName": "Philippines", "pyFirst": "F"},
- {"areaKey": "SC", "chsName": "塞舌尔", "enName": "Seychelles", "pyFirst": "S"},
- {"areaKey": "CK", "chsName": "库克群岛", "enName": "Cook Islands", "pyFirst": "K"},
- {"areaKey": "PK", "chsName": "巴基斯坦", "enName": "Pakistan", "pyFirst": "B"},
- {"areaKey": "HR", "chsName": "克罗地亚", "enName": "Croatia", "pyFirst": "K"},
- {"areaKey": "TH", "chsName": "泰国", "enName": "Thailand", "pyFirst": "T"},
- {"areaKey": "SI", "chsName": "斯洛文尼亚", "enName": "Slovenia", "pyFirst": "S"},
- {"areaKey": "VG", "chsName": "英属维尔京群岛", "enName": "British Virgin Islands",
- "pyFirst": "Y"},
- {"areaKey": "SY", "chsName": "阿拉伯叙利亚共和国", "enName": "Syrian Arab Republic",
- "pyFirst": "A"},
- {"areaKey": "CY", "chsName": "塞浦路斯", "enName": "Cyprus", "pyFirst": "S"},
- {"areaKey": "BR", "chsName": "巴西", "enName": "Brazil", "pyFirst": "B"},
- {"areaKey": "LB", "chsName": "黎巴嫩", "enName": "Lebanon", "pyFirst": "L"},
- {"areaKey": "IS", "chsName": "冰岛", "enName": "Iceland", "pyFirst": "B"},
- {"areaKey": "PA", "chsName": "巴拿马", "enName": "Panama", "pyFirst": "B"},
- {"areaKey": "FM", "chsName": "密克罗尼西亚", "enName": "Micronesia", "pyFirst": "M"},
- {"areaKey": "VA", "chsName": "梵蒂冈", "enName": "Vatican City State",
- "pyFirst": "F"},
- {"areaKey": "NC", "chsName": "新喀里多尼亚", "enName": "New Caledonia", "pyFirst": "X"},
- {"areaKey": "MT", "chsName": "马尔他", "enName": "Malta", "pyFirst": "M"},
- {"areaKey": "BG", "chsName": "保加利亚", "enName": "Bulgaria", "pyFirst": "B"},
- {"areaKey": "ES", "chsName": "西班牙", "enName": "Spain", "pyFirst": "X"},
- {"areaKey": "CI", "chsName": "象牙海岸", "enName": "Ivory Coast", "pyFirst": "X"},
- {"areaKey": "IE", "chsName": "爱尔兰", "enName": "Ireland", "pyFirst": "A"},
- {"areaKey": "BZ", "chsName": "伯利兹城", "enName": "Belize", "pyFirst": "B"},
- {"areaKey": "SZ", "chsName": "斯威士兰", "enName": "Swaziland", "pyFirst": "S"},
- {"areaKey": "SV", "chsName": "萨尔瓦多", "enName": "EI Salvador", "pyFirst": "S"},
- {"areaKey": "GE", "chsName": "格鲁吉亚", "enName": "Georgia", "pyFirst": "G"},
- {"areaKey": "SD", "chsName": "苏丹", "enName": "Sudan", "pyFirst": "S"},
- {"areaKey": "PR", "chsName": "波多黎各", "enName": "Puerto Rico", "pyFirst": "B"},
- {"areaKey": "FJ", "chsName": "斐济", "enName": "Fiji", "pyFirst": "F"},
- {"areaKey": "NL", "chsName": "荷兰", "enName": "Netherlands", "pyFirst": "H"},
- {"areaKey": "UG", "chsName": "乌干达", "enName": "Uganda", "pyFirst": "W"},
- {"areaKey": "HU", "chsName": "匈牙利", "enName": "Hungary", "pyFirst": "X"},
- {"areaKey": "TC", "chsName": "特克斯和凯科斯群岛", "enName": "Turks and Caicos Islands",
- "pyFirst": "T"}]}
+AREA_LIST = {
+ "currentVersion": 231,
+ "areaList": [
+ {"areaKey": "JP", "chsName": "日本", "enName": "Japan", "pyFirst": "R"},
+ {"areaKey": "MY", "chsName": "马来西亚", "enName": "Malaysia", "pyFirst": "M"},
+ {"areaKey": "DE", "chsName": "德国", "enName": "Germany", "pyFirst": "D"},
+ {
+ "areaKey": "LI",
+ "chsName": "列支敦斯登",
+ "enName": "Liechtenstein",
+ "pyFirst": "L",
+ },
+ {"areaKey": "AT", "chsName": "奥地利", "enName": "Austria", "pyFirst": "A"},
+ {"areaKey": "TW", "chsName": "台湾", "enName": "Taiwan", "pyFirst": "T"},
+ {"areaKey": "FR", "chsName": "法国", "enName": "France", "pyFirst": "F"},
+ {
+ "areaKey": "CN",
+ "chsName": "中国大陆",
+ "enName": "China Mainland",
+ "pyFirst": "Z",
+ },
+ {"areaKey": "SG", "chsName": "新加坡", "enName": "Singapore", "pyFirst": "X"},
+ {
+ "areaKey": "RE",
+ "chsName": "留尼汪岛",
+ "enName": "Reunion Island",
+ "pyFirst": "L",
+ },
+ {
+ "areaKey": "EH",
+ "chsName": "西撒哈拉",
+ "enName": "Western Sahara",
+ "pyFirst": "X",
+ },
+ {
+ "areaKey": "WF",
+ "chsName": "瓦利斯群岛和富图纳群岛",
+ "enName": "Wallis and Futuna Islands",
+ "pyFirst": "W",
+ },
+ {"areaKey": "KP", "chsName": "朝鲜", "enName": "North Korea", "pyFirst": "C"},
+ {"areaKey": "ZW", "chsName": "津巴布韦", "enName": "Zimbabwe", "pyFirst": "J"},
+ {
+ "areaKey": "VI",
+ "chsName": "美属维尔京群岛",
+ "enName": "United States Virgin Islands",
+ "pyFirst": "M",
+ },
+ {
+ "areaKey": "PF",
+ "chsName": "法属玻里尼西亚",
+ "enName": "French Polynesia",
+ "pyFirst": "F",
+ },
+ {"areaKey": "DJ", "chsName": "吉布提", "enName": "Djibouti", "pyFirst": "J"},
+ {"areaKey": "KZ", "chsName": "哈萨克斯坦", "enName": "Kazakhstan", "pyFirst": "H"},
+ {"areaKey": "TV", "chsName": "图瓦卢", "enName": "Tuvalu", "pyFirst": "T"},
+ {"areaKey": "VU", "chsName": "瓦努阿图", "enName": "Vanuatu", "pyFirst": "W"},
+ {"areaKey": "IN", "chsName": "印度", "enName": "India", "pyFirst": "Y"},
+ {"areaKey": "CM", "chsName": "喀麦隆", "enName": "Cameroon", "pyFirst": "K"},
+ {"areaKey": "LK", "chsName": "斯里兰卡", "enName": "Sri Lanka", "pyFirst": "S"},
+ {
+ "areaKey": "CC",
+ "chsName": "科科斯群岛",
+ "enName": "Cocos Islands",
+ "pyFirst": "K",
+ },
+ {
+ "areaKey": "KY",
+ "chsName": "开曼群岛",
+ "enName": "Cayman Islands",
+ "pyFirst": "K",
+ },
+ {"areaKey": "QA", "chsName": "卡塔尔", "enName": "Qatar", "pyFirst": "K"},
+ {"areaKey": "AZ", "chsName": "阿塞拜疆", "enName": "Azerbaijan", "pyFirst": "A"},
+ {"areaKey": "HN", "chsName": "洪都拉斯", "enName": "Honduras", "pyFirst": "H"},
+ {"areaKey": "AW", "chsName": "阿鲁巴岛", "enName": "Aruba", "pyFirst": "A"},
+ {"areaKey": "KH", "chsName": "柬埔寨", "enName": "Cambodia", "pyFirst": "J"},
+ {"areaKey": "CO", "chsName": "哥伦比亚", "enName": "Colombia", "pyFirst": "G"},
+ {"areaKey": "IR", "chsName": "伊朗", "enName": "Iran", "pyFirst": "Y"},
+ {"areaKey": "ZA", "chsName": "南非", "enName": "South Africa", "pyFirst": "N"},
+ {"areaKey": "UY", "chsName": "乌拉圭", "enName": "Uruguay", "pyFirst": "W"},
+ {"areaKey": "GU", "chsName": "关岛", "enName": "Guam", "pyFirst": "G"},
+ {"areaKey": "GH", "chsName": "加纳", "enName": "Ghana", "pyFirst": "J"},
+ {"areaKey": "GN", "chsName": "几内亚", "enName": "Guynea", "pyFirst": "J"},
+ {
+ "areaKey": "MH",
+ "chsName": "马绍尔群岛",
+ "enName": "Marshall Islands",
+ "pyFirst": "M",
+ },
+ {"areaKey": "SE", "chsName": "瑞典", "enName": "Sweden", "pyFirst": "R"},
+ {
+ "areaKey": "SB",
+ "chsName": "所罗门群岛",
+ "enName": "Solomon Islands",
+ "pyFirst": "S",
+ },
+ {"areaKey": "NE", "chsName": "尼日尔", "enName": "Niger", "pyFirst": "N"},
+ {"areaKey": "HT", "chsName": "海地", "enName": "Haiti", "pyFirst": "H"},
+ {"areaKey": "PL", "chsName": "波兰", "enName": "Poland", "pyFirst": "B"},
+ {
+ "areaKey": "DO",
+ "chsName": "多米尼加共和国",
+ "enName": "Dominican Republic",
+ "pyFirst": "D",
+ },
+ {"areaKey": "PS", "chsName": "巴勒斯坦", "enName": "Palestine", "pyFirst": "B"},
+ {"areaKey": "KW", "chsName": "科威特", "enName": "Kuwait", "pyFirst": "K"},
+ {
+ "areaKey": "UZ",
+ "chsName": "乌兹别克斯坦",
+ "enName": "Republic of Uzbekistan",
+ "pyFirst": "W",
+ },
+ {"areaKey": "GD", "chsName": "格林纳达", "enName": "Grenada", "pyFirst": "G"},
+ {"areaKey": "KG", "chsName": "吉尔吉斯斯坦", "enName": "Kyrgyzstan", "pyFirst": "J"},
+ {"areaKey": "JO", "chsName": "约旦", "enName": "Jordan", "pyFirst": "Y"},
+ {"areaKey": "IL", "chsName": "以色列", "enName": "Israel", "pyFirst": "Y"},
+ {"areaKey": "UK", "chsName": "英国", "enName": "United Kingdom", "pyFirst": "Y"},
+ {"areaKey": "MW", "chsName": "马拉维", "enName": "Malawi", "pyFirst": "M"},
+ {"areaKey": "MC", "chsName": "摩纳哥", "enName": "Monaco", "pyFirst": "M"},
+ {
+ "areaKey": "IC",
+ "chsName": "加那利群岛",
+ "enName": "Canary Islands",
+ "pyFirst": "J",
+ },
+ {"areaKey": "JM", "chsName": "牙买加", "enName": "Jamaica", "pyFirst": "Y"},
+ {
+ "areaKey": "MP",
+ "chsName": "北马里亚纳群岛",
+ "enName": "The Northern Mariana Islands",
+ "pyFirst": "B",
+ },
+ {"areaKey": "BH", "chsName": "巴林岛", "enName": "Bahrain", "pyFirst": "B"},
+ {"areaKey": "MK", "chsName": "马其顿", "enName": "Macedonia", "pyFirst": "M"},
+ {"areaKey": "ET", "chsName": "埃塞俄比亚", "enName": "Ethiopia", "pyFirst": "A"},
+ {"areaKey": "CL", "chsName": "智利", "enName": "Chile", "pyFirst": "Z"},
+ {"areaKey": "GP", "chsName": "瓜德罗普岛", "enName": "Guadeloupe", "pyFirst": "G"},
+ {
+ "areaKey": "FK",
+ "chsName": "福克兰群岛",
+ "enName": "Falkland Islands",
+ "pyFirst": "F",
+ },
+ {"areaKey": "GL", "chsName": "格陵兰", "enName": "Greenland", "pyFirst": "G"},
+ {"areaKey": "BF", "chsName": "布基纳法索", "enName": "Burkina Faso", "pyFirst": "B"},
+ {"areaKey": "GI", "chsName": "直布罗陀", "enName": "Gibraltar", "pyFirst": "Z"},
+ {"areaKey": "MV", "chsName": "马尔代夫", "enName": "Maldives", "pyFirst": "M"},
+ {"areaKey": "CU", "chsName": "古巴", "enName": "Cuba", "pyFirst": "G"},
+ {"areaKey": "LS", "chsName": "莱索托", "enName": "Lesotho", "pyFirst": "L"},
+ {"areaKey": "MA", "chsName": "摩洛哥", "enName": "Morocco", "pyFirst": "M"},
+ {"areaKey": "AL", "chsName": "阿尔巴尼亚", "enName": "Albania", "pyFirst": "A"},
+ {"areaKey": "AF", "chsName": "阿富汗", "enName": "Afghanistan", "pyFirst": "A"},
+ {"areaKey": "CA", "chsName": "加拿大", "enName": "Canada", "pyFirst": "J"},
+ {"areaKey": "BB", "chsName": "巴巴多斯", "enName": "Barbados", "pyFirst": "B"},
+ {"areaKey": "LC", "chsName": "圣卢西亚岛", "enName": "Saint Lucia", "pyFirst": "S"},
+ {
+ "areaKey": "PN",
+ "chsName": "皮特克恩岛",
+ "enName": "Pitcairn Island",
+ "pyFirst": "P",
+ },
+ {"areaKey": "LV", "chsName": "拉脱维亚", "enName": "Latvia", "pyFirst": "L"},
+ {"areaKey": "NO", "chsName": "挪威", "enName": "Norway", "pyFirst": "N"},
+ {"areaKey": "BE", "chsName": "比利时", "enName": "Belgium", "pyFirst": "B"},
+ {"areaKey": "VE", "chsName": "委内瑞拉", "enName": "Venezuela", "pyFirst": "W"},
+ {"areaKey": "MQ", "chsName": "马提尼克", "enName": "Martinique", "pyFirst": "M"},
+ {"areaKey": "GY", "chsName": "圭亚那", "enName": "Guyana", "pyFirst": "G"},
+ {"areaKey": "AM", "chsName": "亚美尼亚", "enName": "Armenia", "pyFirst": "Y"},
+ {"areaKey": "EC", "chsName": "厄瓜多尔", "enName": "Ecuador", "pyFirst": "E"},
+ {"areaKey": "CV", "chsName": "佛得角", "enName": "Cape Verde", "pyFirst": "F"},
+ {"areaKey": "NZ", "chsName": "新西兰", "enName": "New Zealand", "pyFirst": "X"},
+ {"areaKey": "RO", "chsName": "罗马尼亚", "enName": "Romania", "pyFirst": "L"},
+ {"areaKey": "DM", "chsName": "多米尼加", "enName": "Dominica", "pyFirst": "D"},
+ {"areaKey": "TZ", "chsName": "坦桑尼亚", "enName": "Tanzania", "pyFirst": "T"},
+ {"areaKey": "BD", "chsName": "孟加拉国", "enName": "Bangladesh", "pyFirst": "M"},
+ {"areaKey": "TD", "chsName": "乍得", "enName": "Chad", "pyFirst": "Z"},
+ {"areaKey": "LT", "chsName": "立陶宛", "enName": "Lithuania", "pyFirst": "L"},
+ {"areaKey": "TJ", "chsName": "塔吉克斯坦", "enName": "Tajikistan", "pyFirst": "T"},
+ {"areaKey": "TK", "chsName": "托克劳", "enName": "Tokelau", "pyFirst": "T"},
+ {"areaKey": "BS", "chsName": "巴哈马群岛", "enName": "Bahamas", "pyFirst": "B"},
+ {"areaKey": "MM", "chsName": "缅甸", "enName": "Myanmar", "pyFirst": "M"},
+ {"areaKey": "BI", "chsName": "布隆迪", "enName": "Burundi", "pyFirst": "B"},
+ {"areaKey": "PY", "chsName": "巴拉圭", "enName": "Paraguay", "pyFirst": "B"},
+ {"areaKey": "SK", "chsName": "斯洛伐克", "enName": "Slovakia", "pyFirst": "S"},
+ {"areaKey": "FI", "chsName": "芬兰", "enName": "Finland", "pyFirst": "F"},
+ {"areaKey": "GA", "chsName": "加蓬", "enName": "Gabon", "pyFirst": "J"},
+ {"areaKey": "DZ", "chsName": "阿尔及利亚", "enName": "Algeria", "pyFirst": "A"},
+ {"areaKey": "FO", "chsName": "法罗群岛", "enName": "Faroe Islands", "pyFirst": "F"},
+ {"areaKey": "ZM", "chsName": "赞比亚", "enName": "Zambia", "pyFirst": "Z"},
+ {"areaKey": "NU", "chsName": "纽埃", "enName": "Niue", "pyFirst": "N"},
+ {"areaKey": "ER", "chsName": "厄立特里亚国", "enName": "Eritrea", "pyFirst": "E"},
+ {"areaKey": "HK", "chsName": "香港", "enName": "Hong Kong", "pyFirst": "X"},
+ {"areaKey": "IT", "chsName": "意大利", "enName": "Italy", "pyFirst": "Y"},
+ {"areaKey": "MS", "chsName": "蒙特色拉特岛", "enName": "Montserrat", "pyFirst": "M"},
+ {"areaKey": "EE", "chsName": "爱沙尼亚", "enName": "Estonia", "pyFirst": "A"},
+ {"areaKey": "WS", "chsName": "萨摩亚", "enName": "Samoa", "pyFirst": "S"},
+ {"areaKey": "TG", "chsName": "多哥", "enName": "Togo", "pyFirst": "D"},
+ {"areaKey": "ML", "chsName": "马里", "enName": "Mali", "pyFirst": "M"},
+ {
+ "areaKey": "GF",
+ "chsName": "法属圭亚那",
+ "enName": "French Guyana",
+ "pyFirst": "F",
+ },
+ {"areaKey": "KM", "chsName": "科摩罗", "enName": "Comoros", "pyFirst": "K"},
+ {"areaKey": "ID", "chsName": "印度尼西亚", "enName": "Indonesia", "pyFirst": "Y"},
+ {"areaKey": "KE", "chsName": "肯尼亚", "enName": "Kenya", "pyFirst": "K"},
+ {"areaKey": "EG", "chsName": "埃及", "enName": "Egypt", "pyFirst": "A"},
+ {
+ "areaKey": "NF",
+ "chsName": "诺福克岛",
+ "enName": "Norfolk Island",
+ "pyFirst": "N",
+ },
+ {"areaKey": "RS", "chsName": "塞尔维亚", "enName": "Serbia", "pyFirst": "S"},
+ {"areaKey": "TR", "chsName": "土耳其", "enName": "Turkey", "pyFirst": "T"},
+ {"areaKey": "DK", "chsName": "丹麦", "enName": "Denmark", "pyFirst": "D"},
+ {"areaKey": "AD", "chsName": "安道尔", "enName": "Andorra", "pyFirst": "A"},
+ {"areaKey": "LR", "chsName": "利比里亚", "enName": "Liberia", "pyFirst": "L"},
+ {
+ "areaKey": "AE",
+ "chsName": "阿拉伯联合酋长国",
+ "enName": "United Arab Emirates",
+ "pyFirst": "A",
+ },
+ {"areaKey": "CH", "chsName": "瑞士", "enName": "Switzerland", "pyFirst": "R"},
+ {"areaKey": "AU", "chsName": "澳大利亚", "enName": "Australia", "pyFirst": "A"},
+ {"areaKey": "TP", "chsName": "东帝汶", "enName": "East Timor", "pyFirst": "D"},
+ {"areaKey": "LY", "chsName": "利比亚", "enName": "Libya", "pyFirst": "L"},
+ {"areaKey": "RW", "chsName": "卢旺达", "enName": "Rwanda", "pyFirst": "L"},
+ {"areaKey": "SA", "chsName": "沙特阿拉伯", "enName": "Saudi Arabia", "pyFirst": "S"},
+ {"areaKey": "AR", "chsName": "阿根廷", "enName": "Argentina", "pyFirst": "A"},
+ {"areaKey": "GM", "chsName": "冈比亚", "enName": "Gambia", "pyFirst": "G"},
+ {"areaKey": "BY", "chsName": "白俄罗斯", "enName": "Belarus", "pyFirst": "B"},
+ {"areaKey": "SL", "chsName": "塞拉利昂", "enName": "Sierra Leone", "pyFirst": "S"},
+ {"areaKey": "TM", "chsName": "土库曼斯坦", "enName": "Turkmenistan", "pyFirst": "T"},
+ {
+ "areaKey": "AG",
+ "chsName": "安提瓜和巴布达",
+ "enName": "Antigua and Barbuda",
+ "pyFirst": "A",
+ },
+ {"areaKey": "MR", "chsName": "毛里塔尼亚", "enName": "Mauritania", "pyFirst": "M"},
+ {"areaKey": "PT", "chsName": "葡萄牙", "enName": "Portugal", "pyFirst": "P"},
+ {"areaKey": "BW", "chsName": "博茨瓦纳", "enName": "Botswana", "pyFirst": "B"},
+ {"areaKey": "GT", "chsName": "危地马拉", "enName": "Guatemala", "pyFirst": "W"},
+ {"areaKey": "BT", "chsName": "不丹", "enName": "Bhutan", "pyFirst": "B"},
+ {"areaKey": "AI", "chsName": "安圭拉岛", "enName": "Anguilla", "pyFirst": "A"},
+ {"areaKey": "OM", "chsName": "阿曼", "enName": "Oman", "pyFirst": "A"},
+ {"areaKey": "KI", "chsName": "基里巴斯", "enName": "Kiribati", "pyFirst": "J"},
+ {"areaKey": "UA", "chsName": "乌克兰", "enName": "Ukraine", "pyFirst": "W"},
+ {"areaKey": "YE", "chsName": "也门", "enName": "Yemen", "pyFirst": "Y"},
+ {
+ "areaKey": "DR",
+ "chsName": "刚果民主共和国",
+ "enName": "Democratic Republic of the Congo",
+ "pyFirst": "G",
+ },
+ {"areaKey": "MD", "chsName": "摩尔多瓦", "enName": "Moldova", "pyFirst": "M"},
+ {
+ "areaKey": "GW",
+ "chsName": "几内亚比绍",
+ "enName": "Guinea-Bissau",
+ "pyFirst": "J",
+ },
+ {
+ "areaKey": "CG",
+ "chsName": "刚果布共和国",
+ "enName": "Congo Brazzaville",
+ "pyFirst": "G",
+ },
+ {"areaKey": "SN", "chsName": "塞内加尔", "enName": "Senegal", "pyFirst": "S"},
+ {
+ "areaKey": "BA",
+ "chsName": "波黑",
+ "enName": "Bosnia Hercegovina",
+ "pyFirst": "B",
+ },
+ {"areaKey": "MO", "chsName": "澳门", "enName": "Macao", "pyFirst": "A"},
+ {
+ "areaKey": "KN",
+ "chsName": "圣基茨和尼维斯",
+ "enName": "Saint Kitts and Nevis",
+ "pyFirst": "S",
+ },
+ {"areaKey": "TO", "chsName": "汤加", "enName": "Tonga", "pyFirst": "T"},
+ {"areaKey": "NG", "chsName": "尼日利亚", "enName": "Nigeria", "pyFirst": "N"},
+ {
+ "areaKey": "TT",
+ "chsName": "特立尼达和多巴哥",
+ "enName": "Trinidad and Tobago",
+ "pyFirst": "T",
+ },
+ {
+ "areaKey": "CF",
+ "chsName": "中非共和国",
+ "enName": "Central African Republic",
+ "pyFirst": "Z",
+ },
+ {"areaKey": "PE", "chsName": "秘鲁", "enName": "Peru", "pyFirst": "M"},
+ {
+ "areaKey": "PG",
+ "chsName": "巴布亚新几内亚",
+ "enName": "Papua New Guinea",
+ "pyFirst": "B",
+ },
+ {
+ "areaKey": "CX",
+ "chsName": "圣延岛",
+ "enName": "Christmas Island",
+ "pyFirst": "S",
+ },
+ {
+ "areaKey": "AN",
+ "chsName": "安的列斯",
+ "enName": "Netherlands Antilles",
+ "pyFirst": "A",
+ },
+ {"areaKey": "BO", "chsName": "玻利维亚", "enName": "Bolivia", "pyFirst": "B"},
+ {"areaKey": "IQ", "chsName": "伊拉克", "enName": "Iraq", "pyFirst": "Y"},
+ {"areaKey": "NP", "chsName": "尼泊尔", "enName": "Nepal", "pyFirst": "N"},
+ {"areaKey": "BJ", "chsName": "贝宁", "enName": "Benin", "pyFirst": "B"},
+ {"areaKey": "VN", "chsName": "越南", "enName": "Vietnam", "pyFirst": "Y"},
+ {"areaKey": "NI", "chsName": "尼加拉瓜", "enName": "Nicaragua", "pyFirst": "N"},
+ {"areaKey": "PW", "chsName": "帕劳群岛", "enName": "Palau", "pyFirst": "P"},
+ {"areaKey": "SO", "chsName": "索马里", "enName": "Somalia", "pyFirst": "S"},
+ {"areaKey": "SM", "chsName": "圣马力诺", "enName": "San Marino", "pyFirst": "S"},
+ {"areaKey": "NR", "chsName": "瑙鲁", "enName": "Nauru", "pyFirst": "N"},
+ {
+ "areaKey": "BN",
+ "chsName": "文莱",
+ "enName": "Brunei Darussalam",
+ "pyFirst": "W",
+ },
+ {"areaKey": "MZ", "chsName": "莫桑比克", "enName": "Mozambique", "pyFirst": "M"},
+ {"areaKey": "GR", "chsName": "希腊", "enName": "Greece", "pyFirst": "X"},
+ {"areaKey": "TN", "chsName": "突尼斯", "enName": "Tunisia", "pyFirst": "T"},
+ {
+ "areaKey": "RU",
+ "chsName": "俄罗斯",
+ "enName": "Russian Federation",
+ "pyFirst": "E",
+ },
+ {"areaKey": "MG", "chsName": "马达加斯加岛", "enName": "Madagascar", "pyFirst": "M"},
+ {"areaKey": "NA", "chsName": "纳米比亚", "enName": "Namibia", "pyFirst": "N"},
+ {
+ "areaKey": "CQ",
+ "chsName": "赤道几内亚",
+ "enName": "Equatorial Guinea",
+ "pyFirst": "C",
+ },
+ {"areaKey": "SR", "chsName": "苏里南", "enName": "Suriname", "pyFirst": "S"},
+ {"areaKey": "MU", "chsName": "毛里求斯", "enName": "Mauritius", "pyFirst": "M"},
+ {"areaKey": "LA", "chsName": "老挝", "enName": "Laos", "pyFirst": "L"},
+ {"areaKey": "US", "chsName": "美国", "enName": "United States", "pyFirst": "M"},
+ {
+ "areaKey": "ST",
+ "chsName": "圣多美与普林希比共和国",
+ "enName": "Sao Tome and Principe",
+ "pyFirst": "S",
+ },
+ {"areaKey": "BM", "chsName": "百慕大群岛", "enName": "Bermuda", "pyFirst": "B"},
+ {"areaKey": "LU", "chsName": "卢森堡", "enName": "Luxembourg", "pyFirst": "L"},
+ {"areaKey": "CR", "chsName": "哥斯达黎加", "enName": "Costa Rica", "pyFirst": "G"},
+ {"areaKey": "KR", "chsName": "韩国", "enName": "South Korea", "pyFirst": "H"},
+ {"areaKey": "CZ", "chsName": "捷克", "enName": "Czech Republic", "pyFirst": "J"},
+ {"areaKey": "MX", "chsName": "墨西哥", "enName": "Mexico", "pyFirst": "M"},
+ {"areaKey": "SH", "chsName": "圣赫勒拿岛", "enName": "St Helena", "pyFirst": "S"},
+ {"areaKey": "AO", "chsName": "安哥拉", "enName": "Angola", "pyFirst": "A"},
+ {"areaKey": "MN", "chsName": "蒙古", "enName": "Mongolia", "pyFirst": "M"},
+ {
+ "areaKey": "VC",
+ "chsName": "圣文森特和格林纳丁斯",
+ "enName": "Saint Vincent and the Grenadines",
+ "pyFirst": "S",
+ },
+ {"areaKey": "PH", "chsName": "菲律宾", "enName": "Philippines", "pyFirst": "F"},
+ {"areaKey": "SC", "chsName": "塞舌尔", "enName": "Seychelles", "pyFirst": "S"},
+ {"areaKey": "CK", "chsName": "库克群岛", "enName": "Cook Islands", "pyFirst": "K"},
+ {"areaKey": "PK", "chsName": "巴基斯坦", "enName": "Pakistan", "pyFirst": "B"},
+ {"areaKey": "HR", "chsName": "克罗地亚", "enName": "Croatia", "pyFirst": "K"},
+ {"areaKey": "TH", "chsName": "泰国", "enName": "Thailand", "pyFirst": "T"},
+ {"areaKey": "SI", "chsName": "斯洛文尼亚", "enName": "Slovenia", "pyFirst": "S"},
+ {
+ "areaKey": "VG",
+ "chsName": "英属维尔京群岛",
+ "enName": "British Virgin Islands",
+ "pyFirst": "Y",
+ },
+ {
+ "areaKey": "SY",
+ "chsName": "阿拉伯叙利亚共和国",
+ "enName": "Syrian Arab Republic",
+ "pyFirst": "A",
+ },
+ {"areaKey": "CY", "chsName": "塞浦路斯", "enName": "Cyprus", "pyFirst": "S"},
+ {"areaKey": "BR", "chsName": "巴西", "enName": "Brazil", "pyFirst": "B"},
+ {"areaKey": "LB", "chsName": "黎巴嫩", "enName": "Lebanon", "pyFirst": "L"},
+ {"areaKey": "IS", "chsName": "冰岛", "enName": "Iceland", "pyFirst": "B"},
+ {"areaKey": "PA", "chsName": "巴拿马", "enName": "Panama", "pyFirst": "B"},
+ {"areaKey": "FM", "chsName": "密克罗尼西亚", "enName": "Micronesia", "pyFirst": "M"},
+ {
+ "areaKey": "VA",
+ "chsName": "梵蒂冈",
+ "enName": "Vatican City State",
+ "pyFirst": "F",
+ },
+ {
+ "areaKey": "NC",
+ "chsName": "新喀里多尼亚",
+ "enName": "New Caledonia",
+ "pyFirst": "X",
+ },
+ {"areaKey": "MT", "chsName": "马尔他", "enName": "Malta", "pyFirst": "M"},
+ {"areaKey": "BG", "chsName": "保加利亚", "enName": "Bulgaria", "pyFirst": "B"},
+ {"areaKey": "ES", "chsName": "西班牙", "enName": "Spain", "pyFirst": "X"},
+ {"areaKey": "CI", "chsName": "象牙海岸", "enName": "Ivory Coast", "pyFirst": "X"},
+ {"areaKey": "IE", "chsName": "爱尔兰", "enName": "Ireland", "pyFirst": "A"},
+ {"areaKey": "BZ", "chsName": "伯利兹城", "enName": "Belize", "pyFirst": "B"},
+ {"areaKey": "SZ", "chsName": "斯威士兰", "enName": "Swaziland", "pyFirst": "S"},
+ {"areaKey": "SV", "chsName": "萨尔瓦多", "enName": "EI Salvador", "pyFirst": "S"},
+ {"areaKey": "GE", "chsName": "格鲁吉亚", "enName": "Georgia", "pyFirst": "G"},
+ {"areaKey": "SD", "chsName": "苏丹", "enName": "Sudan", "pyFirst": "S"},
+ {"areaKey": "PR", "chsName": "波多黎各", "enName": "Puerto Rico", "pyFirst": "B"},
+ {"areaKey": "FJ", "chsName": "斐济", "enName": "Fiji", "pyFirst": "F"},
+ {"areaKey": "NL", "chsName": "荷兰", "enName": "Netherlands", "pyFirst": "H"},
+ {"areaKey": "UG", "chsName": "乌干达", "enName": "Uganda", "pyFirst": "W"},
+ {"areaKey": "HU", "chsName": "匈牙利", "enName": "Hungary", "pyFirst": "X"},
+ {
+ "areaKey": "TC",
+ "chsName": "特克斯和凯科斯群岛",
+ "enName": "Turks and Caicos Islands",
+ "pyFirst": "T",
+ },
+ ],
+}
diff --git a/bumper/plugins/bumper_confserver_v1_private_message.py b/bumper/plugins/bumper_confserver_v1_private_message.py
index 596ad67..796a7f7 100644
--- a/bumper/plugins/bumper_confserver_v1_private_message.py
+++ b/bumper/plugins/bumper_confserver_v1_private_message.py
@@ -10,21 +10,30 @@ from datetime import datetime, timedelta
class v1_private_message(plugins.ConfServerApp):
-
def __init__(self):
self.name = "v1_private_message"
- self.plugin_type = "sub_api"
+ self.plugin_type = "sub_api"
self.sub_api = "api_v1"
-
+
self.routes = [
-
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/message/hasUnreadMsg", self.handle_hasUnreadMessage, name="v1_message_hasUnreadMsg"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/message/getMsgList", self.handle_getMsgList, name="v1_message_getMsgList"),
-
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/message/hasUnreadMsg",
+ self.handle_hasUnreadMessage,
+ name="v1_message_hasUnreadMsg",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/message/getMsgList",
+ self.handle_getMsgList,
+ name="v1_message_getMsgList",
+ ),
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
-
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
+
async def handle_hasUnreadMessage(self, request): # EcoVacs Home
try:
body = {
@@ -53,7 +62,7 @@ class v1_private_message(plugins.ConfServerApp):
return web.json_response(body)
except Exception as e:
- logging.exception(f"{e}")
+ logging.exception(f"{e}")
+
plugin = v1_private_message()
-
diff --git a/bumper/plugins/bumper_confserver_v1_private_shop.py b/bumper/plugins/bumper_confserver_v1_private_shop.py
index 4697b8c..855570a 100644
--- a/bumper/plugins/bumper_confserver_v1_private_shop.py
+++ b/bumper/plugins/bumper_confserver_v1_private_shop.py
@@ -10,20 +10,24 @@ from datetime import datetime, timedelta
class v1_private_shop(plugins.ConfServerApp):
-
def __init__(self):
self.name = "v1_private_shop"
- self.plugin_type = "sub_api"
+ self.plugin_type = "sub_api"
self.sub_api = "api_v1"
-
- self.routes = [
-
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/shop/getCnWapShopConfig", self.handle_getCnWapShopConfig, name="v1_shop_getCnWapShopConfig"),
+ self.routes = [
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/shop/getCnWapShopConfig",
+ self.handle_getCnWapShopConfig,
+ name="v1_shop_getCnWapShopConfig",
+ ),
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
-
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
+
async def handle_getCnWapShopConfig(self, request): # EcoVacs Home
try:
body = {
@@ -42,7 +46,7 @@ class v1_private_shop(plugins.ConfServerApp):
return web.json_response(body)
except Exception as e:
- logging.exception(f"{e}")
+ logging.exception(f"{e}")
+
plugin = v1_private_shop()
-
diff --git a/bumper/plugins/bumper_confserver_v1_private_user.py b/bumper/plugins/bumper_confserver_v1_private_user.py
index 8787d5b..a69bb4e 100644
--- a/bumper/plugins/bumper_confserver_v1_private_user.py
+++ b/bumper/plugins/bumper_confserver_v1_private_user.py
@@ -10,34 +10,89 @@ from datetime import datetime, timedelta
class v1_private_user(plugins.ConfServerApp):
-
def __init__(self):
self.name = "v1_private_user"
- self.plugin_type = "sub_api"
+ self.plugin_type = "sub_api"
self.sub_api = "api_v1"
authhandler = bumper.ConfServer.ConfServer_AuthHandler()
self.routes = [
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/login", authhandler.login, name="v1_user_login"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin", authhandler.login, name="v1_user_checkLogin"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getAuthCode", authhandler.get_AuthCode, name="v1_user_getAuthCode"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/logout", authhandler.logout, name="v1_user_logout"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreement", self.handle_checkAgreement,name="v1_user_checkAgreement"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreementBatch", self.handle_checkAgreement,name="v1_user_checkAgreementBatch"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getUserAccountInfo", authhandler.getUserAccountInfo,name="v1_user_getUserAccountInfo"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getUserMenuInfo", self.handle_getUserMenuInfo,name="v1_user_getUserMenuInfo"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/changeArea", self.handle_changeArea, name="v1_user_changeArea"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/queryChangeArea", self.handle_changeArea, name="v1_user_queryChangeArea"),
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/acceptAgreementBatch", self.handle_acceptAgreementBatch, name="v1_user_acceptAgreementBatch"),
- # Direct register from app:
- # /{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/directRegister
- #Register by email
- # /registerByEmail
-
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/login",
+ authhandler.login,
+ name="v1_user_login",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin",
+ authhandler.login,
+ name="v1_user_checkLogin",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getAuthCode",
+ authhandler.get_AuthCode,
+ name="v1_user_getAuthCode",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/logout",
+ authhandler.logout,
+ name="v1_user_logout",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreement",
+ self.handle_checkAgreement,
+ name="v1_user_checkAgreement",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreementBatch",
+ self.handle_checkAgreement,
+ name="v1_user_checkAgreementBatch",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getUserAccountInfo",
+ authhandler.getUserAccountInfo,
+ name="v1_user_getUserAccountInfo",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getUserMenuInfo",
+ self.handle_getUserMenuInfo,
+ name="v1_user_getUserMenuInfo",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/changeArea",
+ self.handle_changeArea,
+ name="v1_user_changeArea",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/queryChangeArea",
+ self.handle_changeArea,
+ name="v1_user_queryChangeArea",
+ ),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/acceptAgreementBatch",
+ self.handle_acceptAgreementBatch,
+ name="v1_user_acceptAgreementBatch",
+ ),
+ # Direct register from app:
+ # /{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/directRegister
+ # Register by email
+ # /registerByEmail
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
async def handle_checkAgreement(self, request):
try:
@@ -76,84 +131,82 @@ class v1_private_user(plugins.ConfServerApp):
return web.json_response(body)
except Exception as e:
- logging.exception(f"{e}")
+ logging.exception(f"{e}")
async def handle_getUserMenuInfo(self, request):
try:
apptype = request.match_info.get("apptype", "")
body = {
- "code": "0000",
- "data": [
- {
+ "code": "0000",
+ "data": [
+ {
"menuItems": [
{
- "clickAction": 1,
- "clickUri": "https://ecovacs.zendesk.com/hc/en-us",
- "menuIconUrl": "https://gl-us-pub.ecovacs.com/upload/global/2019/12/16/2019121603180741b73907046e742b80e8fe4a90fe2498.png",
- "menuId": "20191216031849_4d744630f7ad2f5208a4b8051be61d10",
- "menuName": "Help & Feedback",
- "paramsJson": ""
+ "clickAction": 1,
+ "clickUri": "https://ecovacs.zendesk.com/hc/en-us",
+ "menuIconUrl": "https://gl-us-pub.ecovacs.com/upload/global/2019/12/16/2019121603180741b73907046e742b80e8fe4a90fe2498.png",
+ "menuId": "20191216031849_4d744630f7ad2f5208a4b8051be61d10",
+ "menuName": "Help & Feedback",
+ "paramsJson": "",
}
],
- "menuPositionKey": "A_FIRST"
- },
- {
+ "menuPositionKey": "A_FIRST",
+ },
+ {
"menuItems": [
{
- "clickAction": 3,
- "clickUri": "robotShare",
- "menuIconUrl": "https://gl-us-pub.ecovacs.com/upload/global/2019/12/16/2019121603284185e632ec6c5da10bd82119d7047a1f9e.png",
- "menuId": "20191216032853_5fac4cc9cbd0e166dfa951485d1d8cc4",
- "menuName": "Share Robot",
- "paramsJson": ""
+ "clickAction": 3,
+ "clickUri": "robotShare",
+ "menuIconUrl": "https://gl-us-pub.ecovacs.com/upload/global/2019/12/16/2019121603284185e632ec6c5da10bd82119d7047a1f9e.png",
+ "menuId": "20191216032853_5fac4cc9cbd0e166dfa951485d1d8cc4",
+ "menuName": "Share Robot",
+ "paramsJson": "",
}
],
- "menuPositionKey": "B_SECOND"
- },
- {
+ "menuPositionKey": "B_SECOND",
+ },
+ {
"menuItems": [
{
- "clickAction": 3,
- "clickUri": "config",
- "menuIconUrl": "https://gl-us-pub.ecovacs.com/upload/global/2019/12/16/201912160325324068da4e4a09b8c3973db162e84784d5.png",
- "menuId": "20191216032545_ebea0fbb4cb02d9c2fec5bdf3371bc2d",
- "menuName": "Settings",
- "paramsJson": ""
+ "clickAction": 3,
+ "clickUri": "config",
+ "menuIconUrl": "https://gl-us-pub.ecovacs.com/upload/global/2019/12/16/201912160325324068da4e4a09b8c3973db162e84784d5.png",
+ "menuId": "20191216032545_ebea0fbb4cb02d9c2fec5bdf3371bc2d",
+ "menuName": "Settings",
+ "paramsJson": "",
}
],
- "menuPositionKey": "C_THIRD"
- },
- {
+ "menuPositionKey": "C_THIRD",
+ },
+ {
"menuItems": [
{
- "clickAction": 1,
- "clickUri": "https://bumper.ecovacs.com/",
- "menuIconUrl": "https://gl-us-pub.ecovacs.com/upload/global/2019/12/16/201912160325324068da4e4a09b8c3973db162e84784d5.png",
- "menuId": "20191216032545_ebea0fbb4cb02d9c2fec5bdf3371bc2c",
- "menuName": "Bumper Status",
- "paramsJson": ""
+ "clickAction": 1,
+ "clickUri": "https://bumper.ecovacs.com/",
+ "menuIconUrl": "https://gl-us-pub.ecovacs.com/upload/global/2019/12/16/201912160325324068da4e4a09b8c3973db162e84784d5.png",
+ "menuId": "20191216032545_ebea0fbb4cb02d9c2fec5bdf3371bc2c",
+ "menuName": "Bumper Status",
+ "paramsJson": "",
}
],
- "menuPositionKey": "D_FOURTH"
- }
- ],
- "msg": "操作成功",
- "success": True,
- "time": self.get_milli_time(datetime.utcnow().timestamp())
- }
+ "menuPositionKey": "D_FOURTH",
+ },
+ ],
+ "msg": "操作成功",
+ "success": True,
+ "time": self.get_milli_time(datetime.utcnow().timestamp()),
+ }
return web.json_response(body)
except Exception as e:
- logging.exception(f"{e}")
+ logging.exception(f"{e}")
async def handle_changeArea(self, request):
try:
body = {
"code": bumper.RETURN_API_SUCCESS,
- "data": {
- "isNeedReLogin": "N"
- },
+ "data": {"isNeedReLogin": "N"},
"msg": "操作成功",
"success": True,
"time": self.get_milli_time(datetime.utcnow().timestamp()),
@@ -179,5 +232,5 @@ class v1_private_user(plugins.ConfServerApp):
except Exception as e:
logging.exception(f"{e}")
-plugin = v1_private_user()
+plugin = v1_private_user()
diff --git a/bumper/plugins/bumper_confserver_v1_private_userSetting.py b/bumper/plugins/bumper_confserver_v1_private_userSetting.py
index 9822545..2e78594 100644
--- a/bumper/plugins/bumper_confserver_v1_private_userSetting.py
+++ b/bumper/plugins/bumper_confserver_v1_private_userSetting.py
@@ -7,18 +7,24 @@ from datetime import datetime
class v1_private_userSetting(plugins.ConfServerApp):
-
def __init__(self):
self.name = "v1_private_userSetting"
- self.plugin_type = "sub_api"
+ self.plugin_type = "sub_api"
self.sub_api = "api_v1"
self.routes = [
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/userSetting/getSuggestionSetting", self.handle_getSuggestionSetting,name="v1_userSetting_getSuggestionSetting"),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/userSetting/getSuggestionSetting",
+ self.handle_getSuggestionSetting,
+ name="v1_userSetting_getSuggestionSetting",
+ ),
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
async def handle_getSuggestionSetting(self, request):
try:
@@ -31,19 +37,19 @@ class v1_private_userSetting(plugins.ConfServerApp):
{
"name": "Aktionen/Angebote/Ereignisse",
"settingKey": "MARKETING",
- "val": "Y"
+ "val": "Y",
},
{
"name": "Benutzerbefragung",
"settingKey": "QUESTIONNAIRE",
- "val": "Y"
+ "val": "Y",
},
{
"name": "Produkt-Upgrade/Hilfe für Benutzer",
"settingKey": "INTRODUCTION",
- "val": "Y"
- }
- ]
+ "val": "Y",
+ },
+ ],
},
"msg": "操作成功",
"time": self.get_milli_time(datetime.utcnow().timestamp()),
@@ -52,7 +58,7 @@ class v1_private_userSetting(plugins.ConfServerApp):
return web.json_response(body)
except Exception as e:
- logging.exception(f"{e}")
+ logging.exception(f"{e}")
plugin = v1_private_userSetting()
diff --git a/bumper/plugins/bumper_confserver_v2_private_user.py b/bumper/plugins/bumper_confserver_v2_private_user.py
index 5a3c7a3..981fb03 100644
--- a/bumper/plugins/bumper_confserver_v2_private_user.py
+++ b/bumper/plugins/bumper_confserver_v2_private_user.py
@@ -10,20 +10,25 @@ from datetime import datetime, timedelta
class v2_private_user(plugins.ConfServerApp):
-
def __init__(self):
self.name = "v2_private_user"
- self.plugin_type = "sub_api"
+ self.plugin_type = "sub_api"
self.sub_api = "api_v2"
authhandler = bumper.ConfServer.ConfServer_AuthHandler()
self.routes = [
- web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin", authhandler.login, name="v2_user_checkLogin"),
+ web.route(
+ "*",
+ "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin",
+ authhandler.login,
+ name="v2_user_checkLogin",
+ ),
]
- self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
-
+ self.get_milli_time = (
+ bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
+ )
+
plugin = v2_private_user()
-
diff --git a/bumper/util.py b/bumper/util.py
index a2aabcf..ce1359b 100644
--- a/bumper/util.py
+++ b/bumper/util.py
@@ -22,7 +22,9 @@ def get_logger(name: str, rotate: RotatingFileHandler = None) -> logging.Logger:
if not log_to_stdout:
if not rotate:
- rotate = RotatingFileHandler(f"logs/{name}.log", maxBytes=5000000, backupCount=5)
+ rotate = RotatingFileHandler(
+ f"logs/{name}.log", maxBytes=5000000, backupCount=5
+ )
rotate.setFormatter(logformat)
logger.addHandler(rotate)
else:
@@ -31,8 +33,12 @@ def get_logger(name: str, rotate: RotatingFileHandler = None) -> logging.Logger:
__loggers[name] = logger
if name == "mqttserver":
- get_logger("transitions", rotate).setLevel(logging.CRITICAL + 1) # Ignore this logger
- get_logger("passlib", rotate).setLevel(logging.CRITICAL + 1) # Ignore this logger
+ get_logger("transitions", rotate).setLevel(
+ logging.CRITICAL + 1
+ ) # Ignore this logger
+ get_logger("passlib", rotate).setLevel(
+ logging.CRITICAL + 1
+ ) # Ignore this logger
get_logger("hbmqtt.broker", rotate)
get_logger("hbmqtt.mqtt.protocol", rotate)
get_logger("hbmqtt.client", rotate)
diff --git a/bumper/xmppserver.py b/bumper/xmppserver.py
index 802320a..fbced1a 100644
--- a/bumper/xmppserver.py
+++ b/bumper/xmppserver.py
@@ -70,9 +70,7 @@ class XMPPServer_Protocol(asyncio.Protocol):
def connection_made(self, transport):
if self.aclient: # Existing client... upgrading to TLS
- xmppserverlog.debug(
- f"Upgraded connection for {self.aclient.address}"
- )
+ xmppserverlog.debug(f"Upgraded connection for {self.aclient.address}")
self.aclient.transport = transport
else:
aclient = XMPPAsyncClient(transport)
@@ -254,9 +252,7 @@ class XMPPAsyncClient:
if client.type == self.BOT:
if client.uid.lower() in ctl_to.lower():
- xmppserverlog.debug(
- f"Sending ctl to bot: {rxmlstring}"
- )
+ xmppserverlog.debug(f"Sending ctl to bot: {rxmlstring}")
client.send(rxmlstring)
except Exception as e:
@@ -310,17 +306,21 @@ class XMPPAsyncClient:
if not "from" in xml.attrib:
xml.attrib["from"] = f"{self.bumper_jid}"
if "errno" in data:
- xmppserverlog.error(f"Error from bot - {data}")
+ xmppserverlog.error(f"Error from bot - {data}")
if (
"errno='103'" in data
): # No permissions, usually if bot was last on Ecovac network, Bumper will try to add fuid user as owner
if self.type == self.BOT:
- xmppserverlog.info("Bot reported user has no permissions, Bumper will attempt to add user to bot. This is typical if bot was last on Ecovacs Network.")
+ xmppserverlog.info(
+ "Bot reported user has no permissions, Bumper will attempt to add user to bot. This is typical if bot was last on Ecovacs Network."
+ )
xquery = xml.getchildren()
ctl = xquery[0].getchildren()
if "error" in ctl[0].attrib:
ctlerr = ctl[0].attrib["error"]
- adminuser = ctlerr.replace("permission denied, please contact ", "")
+ adminuser = ctlerr.replace(
+ "permission denied, please contact ", ""
+ )
adminuser = adminuser.replace(" ", "")
elif "admin" in ctl[0].attrib:
adminuser = ctl[0].attrib["admin"]
@@ -473,9 +473,7 @@ class XMPPAsyncClient:
async def _handle_starttls(self, data):
try:
if self.TLSUpgraded == False:
- self.TLSUpgraded = (
- True
- ) # Set TLSUpgraded true to prevent further attempts to upgrade connection
+ self.TLSUpgraded = True # Set TLSUpgraded true to prevent further attempts to upgrade connection
xmppserverlog.debug(
"Upgrading connection with STARTTLS for {}:{}".format(
self.address[0], self.address[1]
@@ -662,9 +660,7 @@ class XMPPAsyncClient:
)
# Send dummy return
- self.send(
- f' dummy '
- )
+ self.send(f' dummy ')
elif xml.get("type") == "unavailable":
xmppserverlog.debug(
"client presence unavailable (DISCONNECT) - {} ".format(
@@ -681,9 +677,7 @@ class XMPPAsyncClient:
)
)
# Send dummy return
- self.send(
- f' dummy '
- )
+ self.send(f' dummy ')
def _parse_data(self, data):
@@ -768,9 +762,7 @@ class XMPPAsyncClient:
self._handle_connect(newdata.encode("utf-8"))
else:
if not (newdata == "" or newdata == " "):
- xmppserverlog.error(
- f"xml parse error - {newdata} - {e}"
- )
+ xmppserverlog.error(f"xml parse error - {newdata} - {e}")
elif "not well-formed (invalid token)" in e.msg:
# If a lone - client is signalling end of session/disconnect
@@ -782,15 +774,11 @@ class XMPPAsyncClient:
else:
if "" in newdata:
- xmppserverlog.error(
- f"xml parse error - {newdata} - {e}"
- )
+ xmppserverlog.error(f"xml parse error - {newdata} - {e}")
else:
self.send("") # Close stream
self._set_state("DISCONNECT")
diff --git a/tests/const.py b/tests/const.py
index f2a229f..143d88a 100644
--- a/tests/const.py
+++ b/tests/const.py
@@ -1,2 +1,2 @@
-HOST= "127.0.0.1"
+HOST = "127.0.0.1"
MQTT_PORT = 8883
diff --git a/tests/test_confserver.py b/tests/test_confserver.py
index 058e40a..9673618 100644
--- a/tests/test_confserver.py
+++ b/tests/test_confserver.py
@@ -42,29 +42,39 @@ async def test_confserver_ssl():
conf_server.confserver_app()
asyncio.create_task(conf_server.start_server())
+
async def test_confserver_exceptions():
with LogCapture() as l:
- conf_server = bumper.ConfServer((HOST, 8007), usessl=True)
- conf_server.confserver_app()
- conf_server.site = web.TCPSite
+ conf_server = bumper.ConfServer((HOST, 8007), usessl=True)
+ conf_server.confserver_app()
+ conf_server.site = web.TCPSite
- #bind permission
- conf_server.site.start = mock.Mock(side_effect=OSError(1, "error while attempting to bind on address ('127.0.0.1', 8007): permission denied"))
- await conf_server.start_server()
+ # bind permission
+ conf_server.site.start = mock.Mock(
+ side_effect=OSError(
+ 1,
+ "error while attempting to bind on address ('127.0.0.1', 8007): permission denied",
+ )
+ )
+ await conf_server.start_server()
- #asyncio Cancel
- conf_server.site = web.TCPSite
- conf_server.site.start = mock.Mock(side_effect=asyncio.CancelledError)
- await conf_server.start_server()
+ # asyncio Cancel
+ conf_server.site = web.TCPSite
+ conf_server.site.start = mock.Mock(side_effect=asyncio.CancelledError)
+ await conf_server.start_server()
+
+ # general exception
+ conf_server.site = web.TCPSite
+ conf_server.site.start = mock.Mock(side_effect=Exception(1, "general"))
+ await conf_server.start_server()
- #general exception
- conf_server.site = web.TCPSite
- conf_server.site.start = mock.Mock(side_effect=Exception(1, "general"))
- await conf_server.start_server()
-
l.check_present(
- ("confserver", "ERROR", "error while attempting to bind on address ('127.0.0.1', 8007): permission denied")
+ (
+ "confserver",
+ "ERROR",
+ "error while attempting to bind on address ('127.0.0.1', 8007): permission denied",
+ )
)
@@ -89,7 +99,7 @@ def test_get_milli_time():
async def test_base(aiohttp_client):
remove_existing_db()
bumper.db = "tests/tmp.db" # Set db location for testing
-
+
# Start MQTT
mqtt_server = bumper.MQTTServer(HOST, MQTT_PORT, password_file="tests/passwd")
bumper.mqtt_server = mqtt_server
@@ -100,7 +110,7 @@ async def test_base(aiohttp_client):
xmpp_server = bumper.XMPPServer(xmpp_address)
bumper.xmpp_server = xmpp_server
await xmpp_server.start_async_server()
-
+
# Start Helperbot
mqtt_helperbot = bumper.MQTTHelperBot(HOST, MQTT_PORT)
bumper.mqtt_helperbot = mqtt_helperbot
@@ -108,7 +118,7 @@ async def test_base(aiohttp_client):
client = await aiohttp_client(create_app)
resp = await client.get("/")
- assert resp.status == 200
+ assert resp.status == 200
mqtt_helperbot.Client.disconnect()
@@ -120,7 +130,7 @@ async def test_base(aiohttp_client):
async def test_restartService(aiohttp_client):
remove_existing_db()
bumper.db = "tests/tmp.db" # Set db location for testing
-
+
# Start MQTT
mqtt_server = bumper.MQTTServer(HOST, MQTT_PORT, password_file="tests/passwd")
bumper.mqtt_server = mqtt_server
@@ -131,37 +141,39 @@ async def test_restartService(aiohttp_client):
xmpp_server = bumper.XMPPServer(xmpp_address)
bumper.xmpp_server = xmpp_server
await xmpp_server.start_async_server()
-
+
# Start Helperbot
mqtt_helperbot = bumper.MQTTHelperBot(HOST, MQTT_PORT)
bumper.mqtt_helperbot = mqtt_helperbot
await mqtt_helperbot.start_helper_bot()
client = await aiohttp_client(create_app)
-
+
resp = await client.get("/restart_Helperbot")
- assert resp.status == 200
+ assert resp.status == 200
resp = await client.get("/restart_MQTTServer")
- assert resp.status == 200
+ assert resp.status == 200
resp = await client.get("/restart_XMPPServer")
- assert resp.status == 200
+ assert resp.status == 200
mqtt_helperbot.Client.disconnect()
await mqtt_server.broker.shutdown()
xmpp_server.disconnect()
+
async def test_RemoveBot(aiohttp_client):
client = await aiohttp_client(create_app)
resp = await client.get("/bot/remove/test_did")
- assert resp.status == 200
+ assert resp.status == 200
+
async def test_RemoveClient(aiohttp_client):
client = await aiohttp_client(create_app)
resp = await client.get("/client/remove/test_resource")
- assert resp.status == 200
+ assert resp.status == 200
async def test_login(aiohttp_client):
@@ -180,7 +192,7 @@ async def test_login(aiohttp_client):
assert "username" in jsonresp["data"]
remove_existing_db()
- bumper.db = "tests/tmp.db" # Set db location for testing
+ bumper.db = "tests/tmp.db" # Set db location for testing
# Test global_e without user
resp = await client.get("/v1/private/us/en/dev_1234/global_e/1/0/0/user/login")
@@ -216,11 +228,11 @@ async def test_login(aiohttp_client):
# Add a bot to db that doesn't have a did
newbot = {
- "class": "dev_1234",
- "company": "com_123",
- #"did": self.did,
- "name": "sn_1234",
- "resource": "res_1234",
+ "class": "dev_1234",
+ "company": "com_123",
+ # "did": self.did,
+ "name": "sn_1234",
+ "resource": "res_1234",
}
bumper.bot_full_upsert(newbot)
@@ -592,11 +604,10 @@ async def test_getProductIotMap(aiohttp_client):
jsonresp = json.loads(text)
assert jsonresp["code"] == bumper.RETURN_API_SUCCESS
-
# Test getPimFile
resp = await client.get("/api/pim/file/get/123")
assert resp.status == 200
-
+
async def test_getUsersAPI(aiohttp_client):
remove_existing_db()
@@ -1006,6 +1017,3 @@ async def test_dim_devmanager(aiohttp_client):
text = await resp.text()
test_resp = json.loads(text)
assert test_resp["ret"] == "fail"
-
-
-
diff --git a/tests/test_init.py b/tests/test_init.py
index d84848f..e8e18a5 100644
--- a/tests/test_init.py
+++ b/tests/test_init.py
@@ -59,4 +59,3 @@ async def test_start_stop_debug():
("bumper", "INFO", "Shutting down"), ("bumper", "INFO", "Shutdown complete")
)
assert b.shutting_down == True
-
diff --git a/tests/test_mqttserver.py b/tests/test_mqttserver.py
index aebbd8d..87eab72 100644
--- a/tests/test_mqttserver.py
+++ b/tests/test_mqttserver.py
@@ -14,6 +14,7 @@ import time
from tests.const import HOST, MQTT_PORT
+
async def test_helperbot_message():
mqtt_server = bumper.MQTTServer(HOST, MQTT_PORT, password_file="tests/passwd")
await mqtt_server.broker_coro()
@@ -51,13 +52,11 @@ async def test_helperbot_message():
mqtt_helperbot.Client._connected_state._value == True
) # Check helperbot is connected
msg_payload = "{}"
- msg_topic_name = (
- "iot/p2p/GetWKVer/helperbot/bumper/helperbot/bot_serial/ls1ok3/wC3g/q/iCmuqp/j"
- )
+ msg_topic_name = "iot/p2p/GetWKVer/helperbot/bumper/helperbot/bot_serial/ls1ok3/wC3g/q/iCmuqp/j"
await mqtt_helperbot.Client.publish(
msg_topic_name, msg_payload.encode(), hbmqtt.client.QOS_0
)
-
+
await asyncio.wait_for(mqtt_helperbot.Client.deliver_message(), timeout=0.1)
l.check_present(
@@ -77,9 +76,7 @@ async def test_helperbot_message():
mqtt_helperbot.Client._connected_state._value == True
) # Check helperbot is connected
msg_payload = '{"ret":"ok","ver":"0.13.5"}'
- msg_topic_name = (
- "iot/p2p/GetWKVer/bot_serial/ls1ok3/wC3g/helperbot/bumper/helperbot/p/iCmuqp/j"
- )
+ msg_topic_name = "iot/p2p/GetWKVer/bot_serial/ls1ok3/wC3g/helperbot/bumper/helperbot/p/iCmuqp/j"
await mqtt_helperbot.Client.publish(
msg_topic_name, msg_payload.encode(), hbmqtt.client.QOS_0
)
@@ -103,16 +100,13 @@ async def test_helperbot_message():
mqtt_helperbot.Client._connected_state._value == True
) # Check helperbot is connected
msg_payload = "test"
- msg_topic_name = (
- "iot/p2p/GetWKVer/bot_serial/ls1ok3/wC3g/TESTBAD/bumper/helperbot/p/iCmuqp/j"
- )
+ msg_topic_name = "iot/p2p/GetWKVer/bot_serial/ls1ok3/wC3g/TESTBAD/bumper/helperbot/p/iCmuqp/j"
await mqtt_helperbot.Client.publish(
msg_topic_name, msg_payload.encode(), hbmqtt.client.QOS_0
)
await asyncio.wait_for(mqtt_helperbot.Client.deliver_message(), timeout=0.1)
-
l.check_present(
(
"helperbot",
@@ -134,7 +128,7 @@ async def test_helperbot_message():
await mqtt_helperbot.Client.publish(
msg_topic_name, msg_payload.encode(), hbmqtt.client.QOS_0
)
-
+
await asyncio.wait_for(mqtt_helperbot.Client.deliver_message(), timeout=0.1)
l.check_present(
@@ -156,7 +150,7 @@ async def test_helperbot_expire_message():
timeout = 0.1
# Test broadcast message
- mqtt_helperbot = bumper.MQTTHelperBot(HOST, MQTT_PORT,timeout)
+ mqtt_helperbot = bumper.MQTTHelperBot(HOST, MQTT_PORT, timeout)
bumper.mqtt_helperbot = mqtt_helperbot
await mqtt_helperbot.start_helper_bot()
assert (
@@ -167,14 +161,13 @@ async def test_helperbot_expire_message():
expire_msg_topic_name = "iot/p2p/GetWKVer/bot_serial/ls1ok3/wC3g/helperbot/bumper/helperbot/p/testgood/j"
currenttime = time.time()
request_id = "ABC"
- data = {
- "time": currenttime,
- "topic": expire_msg_topic_name,
- "payload": expire_msg_payload,
- }
+ data = {
+ "time": currenttime,
+ "topic": expire_msg_topic_name,
+ "payload": expire_msg_payload,
+ }
-
- mqtt_helperbot.commands[request_id]= data
+ mqtt_helperbot.commands[request_id] = data
assert mqtt_helperbot.commands[request_id] == data
@@ -185,13 +178,12 @@ async def test_helperbot_expire_message():
msg_topic_name, msg_payload.encode(), hbmqtt.client.QOS_0
) # Send another message to force get_msg
- await asyncio.sleep(timeout*2)
+ await asyncio.sleep(timeout * 2)
assert mqtt_helperbot.commands.get(request_id, None) == None
await mqtt_helperbot.Client.disconnect()
await mqtt_server.broker.shutdown()
-
async def test_helperbot_sendcommand():
@@ -233,9 +225,7 @@ async def test_helperbot_sendcommand():
# Send response beforehand
msg_payload = '{"ret":"ok","ver":"0.13.5"}'
- msg_topic_name = (
- "iot/p2p/GetWKVer/bot_serial/ls1ok3/wC3g/helperbot/bumper/helperbot/p/testgood/j"
- )
+ msg_topic_name = "iot/p2p/GetWKVer/bot_serial/ls1ok3/wC3g/helperbot/bumper/helperbot/p/testgood/j"
await mqtt_helperbot.Client.publish(
msg_topic_name, msg_payload.encode(), hbmqtt.client.QOS_0
)
@@ -247,7 +237,7 @@ async def test_helperbot_sendcommand():
"ret": "ok",
}
- #mqtt_helperbot.Client.disconnect()
+ # mqtt_helperbot.Client.disconnect()
# Test GetLifeSpan (xml command)
cmdjson = {
@@ -269,9 +259,7 @@ async def test_helperbot_sendcommand():
# Send response beforehand
msg_payload = ""
- msg_topic_name = (
- "iot/p2p/GetLifeSpan/bot_serial/ls1ok3/wC3g/helperbot/bumper/helperbot/p/testx/q"
- )
+ msg_topic_name = "iot/p2p/GetLifeSpan/bot_serial/ls1ok3/wC3g/helperbot/bumper/helperbot/p/testx/q"
await mqtt_helperbot.Client.publish(
msg_topic_name, msg_payload.encode(), hbmqtt.client.QOS_0
)
@@ -289,12 +277,7 @@ async def test_helperbot_sendcommand():
"payloadType": "j",
"toRes": "wC3g",
"payload": {
- "header": {
- "pri": 1,
- "ts": "1569380075887",
- "tzm": -240,
- "ver": "0.0.50"
- }
+ "header": {"pri": 1, "ts": "1569380075887", "tzm": -240, "ver": "0.0.50"}
},
"td": "q",
"toId": "bot_serial",
@@ -310,7 +293,7 @@ async def test_helperbot_sendcommand():
# Send response beforehand
msg_payload = '{"body":{"code":0,"data":{"area":0,"cid":"111","start":"1569378657","time":6,"type":"auto"},"msg":"ok"},"header":{"fwVer":"1.6.4","hwVer":"0.1.1","pri":1,"ts":"1569380074036","tzm":480,"ver":"0.0.1"}}'
-
+
msg_topic_name = (
"iot/p2p/getStats/bot_serial/ls1ok3/wC3g/helperbot/bumper/helperbot/p/testj/j"
)
@@ -322,14 +305,33 @@ async def test_helperbot_sendcommand():
assert commandresult == {
"id": "testj",
- "resp": {'body':{'code':0,'data':{'area':0,'cid':'111','start':'1569378657','time':6,'type':'auto'},'msg':'ok'},'header':{'fwVer':'1.6.4','hwVer':'0.1.1','pri':1,'ts':'1569380074036','tzm':480,'ver':'0.0.1'}},
+ "resp": {
+ "body": {
+ "code": 0,
+ "data": {
+ "area": 0,
+ "cid": "111",
+ "start": "1569378657",
+ "time": 6,
+ "type": "auto",
+ },
+ "msg": "ok",
+ },
+ "header": {
+ "fwVer": "1.6.4",
+ "hwVer": "0.1.1",
+ "pri": 1,
+ "ts": "1569380074036",
+ "tzm": 480,
+ "ver": "0.0.1",
+ },
+ },
"ret": "ok",
}
mqtt_helperbot.Client.disconnect()
await mqtt_server.broker.shutdown()
-
async def test_mqttserver():
@@ -338,9 +340,10 @@ async def test_mqttserver():
bumper.db = "tests/tmp.db" # Set db location for testing
+ mqtt_server = bumper.MQTTServer(
+ HOST, MQTT_PORT, password_file="tests/passwd", allow_anonymous=True
+ )
- mqtt_server = bumper.MQTTServer(HOST, MQTT_PORT, password_file="tests/passwd", allow_anonymous=True)
-
await mqtt_server.broker_coro()
# Test helperbot connect
@@ -387,13 +390,19 @@ async def test_mqttserver():
test_client.client_id = "test-file-auth"
# await test_client.start_helper_bot()
test_client.Client = hbmqtt.client.MQTTClient(
- client_id=test_client.client_id, config={"check_hostname": False, "auto_reconnect": False, "reconnect_retries": 1}
+ client_id=test_client.client_id,
+ config={
+ "check_hostname": False,
+ "auto_reconnect": False,
+ "reconnect_retries": 1,
+ },
)
# good user/pass
await test_client.Client.connect(
f"mqtts://test-client:abc123!@{HOST}:{MQTT_PORT}/",
- cafile=bumper.ca_cert, cleansession=True
+ cafile=bumper.ca_cert,
+ cleansession=True,
)
assert (
@@ -403,42 +412,57 @@ async def test_mqttserver():
assert (
test_client.Client._connected_state._value == False
) # Check client is disconnected
-
+
# bad password
with LogCapture() as l:
-
+
await test_client.Client.connect(
f"mqtts://test-client:notvalid!@{HOST}:{MQTT_PORT}/",
- cafile=bumper.ca_cert, cleansession=True
+ cafile=bumper.ca_cert,
+ cleansession=True,
)
l.check_present(
- ("mqttserver", "INFO", "File Authentication Failed - Username: test-client - ClientID: test-file-auth"),
- order_matters=False
- )
- # no username in file
+ (
+ "mqttserver",
+ "INFO",
+ "File Authentication Failed - Username: test-client - ClientID: test-file-auth",
+ ),
+ order_matters=False,
+ )
+ # no username in file
await test_client.Client.connect(
f"mqtts://test-client-noexist:notvalid!@{HOST}:{MQTT_PORT}/",
- cafile=bumper.ca_cert, cleansession=True
+ cafile=bumper.ca_cert,
+ cleansession=True,
)
-
l.check_present(
- ("mqttserver", "INFO", 'File Authentication Failed - No Entry for Username: test-client-noexist - ClientID: test-file-auth'),
- order_matters=False
+ (
+ "mqttserver",
+ "INFO",
+ "File Authentication Failed - No Entry for Username: test-client-noexist - ClientID: test-file-auth",
+ ),
+ order_matters=False,
)
-
+
await mqtt_server.broker.shutdown()
-
+
async def test_nofileauth_mqttserver():
with LogCapture() as l:
- mqtt_server = bumper.MQTTServer(HOST, MQTT_PORT, password_file="tests/passwd-notfound")
+ mqtt_server = bumper.MQTTServer(
+ HOST, MQTT_PORT, password_file="tests/passwd-notfound"
+ )
await mqtt_server.broker_coro()
- await mqtt_server.broker.shutdown()
+ await mqtt_server.broker.shutdown()
l.check_present(
- ("hbmqtt.broker.plugins.bumper", "WARNING", 'Password file tests/passwd-notfound not found'),
- order_matters=False
+ (
+ "hbmqtt.broker.plugins.bumper",
+ "WARNING",
+ "Password file tests/passwd-notfound not found",
+ ),
+ order_matters=False,
)
diff --git a/tests/test_xmppserver.py b/tests/test_xmppserver.py
index 776cd0d..cc5521c 100644
--- a/tests/test_xmppserver.py
+++ b/tests/test_xmppserver.py
@@ -513,7 +513,9 @@ async def test_client_send_iq(*args, **kwargs):
bumper.xmppserver.XMPPServer.clients.append(xmppclient2)
# Roster IQ - Only seen from Android app so far
- test_data = b''
+ test_data = (
+ b''
+ )
xmppclient._parse_data(test_data)
assert (
@@ -594,4 +596,3 @@ async def test_client_send_iq(*args, **kwargs):
# Reset mock calls
mock_send.reset_mock()
-