@7365admin1/core 3.133.1 → 3.135.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.d.ts +124 -6
- package/dist/index.js +377 -32
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +368 -32
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/e2e/member-site-access.e2e.test.mjs +91 -2
- package/test/e2e/robot-vendor-errors.e2e.test.mjs +3 -2
- package/test/ounitech-api-2025-10.test.mjs +140 -2
- package/test/robot-vendor-errors.test.mjs +7 -0
package/dist/index.mjs
CHANGED
|
@@ -4286,7 +4286,7 @@ function useMemberRepo() {
|
|
|
4286
4286
|
throw error;
|
|
4287
4287
|
}
|
|
4288
4288
|
}
|
|
4289
|
-
async function updateRoleById(_id, role) {
|
|
4289
|
+
async function updateRoleById(_id, role, createdBy) {
|
|
4290
4290
|
try {
|
|
4291
4291
|
_id = new ObjectId14(_id);
|
|
4292
4292
|
} catch (error) {
|
|
@@ -4302,6 +4302,9 @@ function useMemberRepo() {
|
|
|
4302
4302
|
role,
|
|
4303
4303
|
updatedAt: /* @__PURE__ */ new Date()
|
|
4304
4304
|
};
|
|
4305
|
+
if (createdBy && ObjectId14.isValid(String(createdBy))) {
|
|
4306
|
+
updateValue.createdBy = new ObjectId14(String(createdBy));
|
|
4307
|
+
}
|
|
4305
4308
|
const res = await collection.updateOne({ _id }, { $set: updateValue });
|
|
4306
4309
|
if (res.modifiedCount === 0) {
|
|
4307
4310
|
throw new InternalServerError6("Unable to update feedback status.");
|
|
@@ -8833,11 +8836,27 @@ async function siteInvitedPins(db2, userId, memberships) {
|
|
|
8833
8836
|
const keys = /* @__PURE__ */ new Set();
|
|
8834
8837
|
if (!pinned.length || !ObjectId26.isValid(userId))
|
|
8835
8838
|
return keys;
|
|
8839
|
+
const both3 = (ids2) => [...new Set(ids2.map(String))].flatMap((v) => [v, new ObjectId26(v)]);
|
|
8840
|
+
const wanted = new Set(pinned.map((m) => pinKey(m.org, m.siteId)));
|
|
8841
|
+
const placed = await db2.collection("members").find(
|
|
8842
|
+
{
|
|
8843
|
+
user: new ObjectId26(userId),
|
|
8844
|
+
status: { $ne: "deleted" },
|
|
8845
|
+
org: { $in: both3(pinned.map((m) => m.org)) },
|
|
8846
|
+
siteId: { $in: both3(pinned.map((m) => m.siteId)) },
|
|
8847
|
+
createdBy: { $type: "objectId", $ne: new ObjectId26(userId) }
|
|
8848
|
+
},
|
|
8849
|
+
{ projection: { org: 1, siteId: 1 } }
|
|
8850
|
+
).toArray();
|
|
8851
|
+
for (const row of placed) {
|
|
8852
|
+
const key = pinKey(row.org, row.siteId);
|
|
8853
|
+
if (wanted.has(key))
|
|
8854
|
+
keys.add(key);
|
|
8855
|
+
}
|
|
8836
8856
|
const user = await db2.collection("users").findOne({ _id: new ObjectId26(userId) }, { projection: { email: 1 } });
|
|
8837
8857
|
const email = String(user?.email ?? "").trim();
|
|
8838
8858
|
if (!email)
|
|
8839
8859
|
return keys;
|
|
8840
|
-
const both3 = (ids2) => [...new Set(ids2.map(String))].flatMap((v) => [v, new ObjectId26(v)]);
|
|
8841
8860
|
const invites = await db2.collection("verifications").find(
|
|
8842
8861
|
{
|
|
8843
8862
|
email,
|
|
@@ -8853,7 +8872,6 @@ async function siteInvitedPins(db2, userId, memberships) {
|
|
|
8853
8872
|
collation: { locale: "en", strength: 2 }
|
|
8854
8873
|
}
|
|
8855
8874
|
).toArray();
|
|
8856
|
-
const wanted = new Set(pinned.map((m) => pinKey(m.org, m.siteId)));
|
|
8857
8875
|
for (const invite of invites) {
|
|
8858
8876
|
const key = pinKey(invite.metadata?.org, invite.metadata?.siteId);
|
|
8859
8877
|
if (wanted.has(key))
|
|
@@ -24813,7 +24831,8 @@ function useRoleRepo() {
|
|
|
24813
24831
|
sort = {},
|
|
24814
24832
|
type = "",
|
|
24815
24833
|
org = "",
|
|
24816
|
-
site = ""
|
|
24834
|
+
site = "",
|
|
24835
|
+
scope = ""
|
|
24817
24836
|
}) {
|
|
24818
24837
|
page2 = page2 > 0 ? page2 - 1 : 0;
|
|
24819
24838
|
if (org && typeof org === "string" && org.length === 24) {
|
|
@@ -24835,6 +24854,9 @@ function useRoleRepo() {
|
|
|
24835
24854
|
if (site) {
|
|
24836
24855
|
query2.$or = [{ site }, { site: "" }, { site: null }];
|
|
24837
24856
|
cacheOptions.site = site.toString();
|
|
24857
|
+
} else if (scope === "organisation") {
|
|
24858
|
+
query2.site = { $in: ["", null] };
|
|
24859
|
+
cacheOptions.scope = scope;
|
|
24838
24860
|
}
|
|
24839
24861
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
24840
24862
|
cacheOptions.sort = JSON.stringify(sort);
|
|
@@ -27290,7 +27312,9 @@ function useRoleController() {
|
|
|
27290
27312
|
limit: Joi28.number().integer().min(1).max(100).allow("", null).default(10),
|
|
27291
27313
|
type: Joi28.string().optional().allow("", null),
|
|
27292
27314
|
org: Joi28.string().hex().optional().allow("", null),
|
|
27293
|
-
site: Joi28.string().hex().optional().allow("", null)
|
|
27315
|
+
site: Joi28.string().hex().optional().allow("", null),
|
|
27316
|
+
// "organisation": only the roles with no site (Organization app, service roles made once)
|
|
27317
|
+
scope: Joi28.string().valid("organisation").optional().allow("", null)
|
|
27294
27318
|
});
|
|
27295
27319
|
const query2 = { ...req.query };
|
|
27296
27320
|
const { error } = validation.validate(query2);
|
|
@@ -27305,18 +27329,19 @@ function useRoleController() {
|
|
|
27305
27329
|
const type = req.query.type ?? "";
|
|
27306
27330
|
const org = req.query.org ?? "";
|
|
27307
27331
|
const site = req.query.site ?? "";
|
|
27332
|
+
const scope = req.query.scope ?? "";
|
|
27308
27333
|
try {
|
|
27309
27334
|
if (org) {
|
|
27310
27335
|
await requireOrgReach(req, org);
|
|
27311
27336
|
}
|
|
27312
|
-
let data = await _getRoles({ search, page: page2, limit, type, org, site });
|
|
27313
|
-
const listIsWholeOrg = org && !search && !site && page2 === 1;
|
|
27337
|
+
let data = await _getRoles({ search, page: page2, limit, type, org, site, scope });
|
|
27338
|
+
const listIsWholeOrg = org && !search && !site && !scope && page2 === 1;
|
|
27314
27339
|
const listed = data?.items;
|
|
27315
27340
|
if (listIsWholeOrg && listed?.length === 0) {
|
|
27316
27341
|
const seeded = await healDefaultRoles(org).catch(() => 0);
|
|
27317
27342
|
if (seeded > 0) {
|
|
27318
27343
|
try {
|
|
27319
|
-
data = await _getRoles({ search, page: page2, limit, type, org, site });
|
|
27344
|
+
data = await _getRoles({ search, page: page2, limit, type, org, site, scope });
|
|
27320
27345
|
} catch (error2) {
|
|
27321
27346
|
logger42.log({ level: "error", message: error2.message });
|
|
27322
27347
|
}
|
|
@@ -27768,7 +27793,8 @@ function useMemberService() {
|
|
|
27768
27793
|
}
|
|
27769
27794
|
}
|
|
27770
27795
|
}
|
|
27771
|
-
|
|
27796
|
+
const placedBy = member.siteId && !newRole?.site && callerId5 && ObjectId60.isValid(callerId5) && String(member.user ?? "") !== callerId5 ? callerId5 : void 0;
|
|
27797
|
+
await _updateRoleById(id, role, placedBy);
|
|
27772
27798
|
return { message: "Member role updated successfully." };
|
|
27773
27799
|
}
|
|
27774
27800
|
async function updateSiteById(id, siteId, siteName) {
|
|
@@ -27816,6 +27842,7 @@ function useMemberService() {
|
|
|
27816
27842
|
import { BadRequestError as BadRequestError56, UnauthorizedError as UnauthorizedError7, useAtlas as useAtlas44 } from "@7365admin1/node-server-utils";
|
|
27817
27843
|
import { ObjectId as ObjectId61 } from "mongodb";
|
|
27818
27844
|
var EXCLUDED_TYPES = ["resident", PLATFORM_STAFF_MEMBER_TYPE];
|
|
27845
|
+
var ORG_ROLE_EXCLUDED = [...EXCLUDED_TYPES, "organization"];
|
|
27819
27846
|
var both = (id) => [id, new ObjectId61(id)];
|
|
27820
27847
|
function useMemberSiteAccessService() {
|
|
27821
27848
|
const { add, updateMemberStatus, updateRoleById } = useMemberRepo();
|
|
@@ -27855,10 +27882,13 @@ function useMemberSiteAccessService() {
|
|
|
27855
27882
|
const roles = await db2().collection("roles").find({
|
|
27856
27883
|
$or: [
|
|
27857
27884
|
{ _id: { $in: roleIds.map((r) => new ObjectId61(r)) } },
|
|
27858
|
-
{ org: { $in: both(org) }, site: { $in: [...sites.keys()].flatMap(both) }, status: "active" }
|
|
27885
|
+
{ org: { $in: both(org) }, site: { $in: [...sites.keys()].flatMap(both) }, status: "active" },
|
|
27886
|
+
// organisation-level service roles (no site; never the org-console type)
|
|
27887
|
+
{ org: { $in: both(org) }, site: { $in: ["", null] }, status: "active", type: { $nin: ORG_ROLE_EXCLUDED } }
|
|
27859
27888
|
]
|
|
27860
27889
|
}).project({ name: 1, type: 1, site: 1, org: 1, status: 1 }).toArray();
|
|
27861
27890
|
const byId = new Map(roles.map((r) => [String(r._id), r]));
|
|
27891
|
+
const orgRoles = roles.filter((r) => !String(r.site ?? "") && String(r.org ?? "") === org && r.status === "active" && !ORG_ROLE_EXCLUDED.includes(r.type)).map((r) => ({ _id: String(r._id), name: r.name ?? "", type: r.type ?? "", scope: "organisation" })).sort((a, b) => a.name.localeCompare(b.name));
|
|
27862
27892
|
const view = (m) => ({
|
|
27863
27893
|
_id: String(m._id),
|
|
27864
27894
|
role: String(m.role ?? ""),
|
|
@@ -27872,7 +27902,7 @@ function useMemberSiteAccessService() {
|
|
|
27872
27902
|
...s,
|
|
27873
27903
|
membership: here[0] ?? null,
|
|
27874
27904
|
memberships: here,
|
|
27875
|
-
roles: roles.filter((r) => String(r.site ?? "") === s.site && String(r.org ?? "") === org && r.status === "active" && !EXCLUDED_TYPES.includes(r.type)).map((r) => ({ _id: String(r._id), name: r.name ?? "", type: r.type ?? "" }))
|
|
27905
|
+
roles: roles.filter((r) => String(r.site ?? "") === s.site && String(r.org ?? "") === org && r.status === "active" && !EXCLUDED_TYPES.includes(r.type)).map((r) => ({ _id: String(r._id), name: r.name ?? "", type: r.type ?? "", scope: "site" })).concat(orgRoles)
|
|
27876
27906
|
};
|
|
27877
27907
|
}).sort((a, b) => a.name.localeCompare(b.name));
|
|
27878
27908
|
const orgWide = members.filter((m) => !String(m.siteId ?? "")).map(view);
|
|
@@ -27898,7 +27928,7 @@ function useMemberSiteAccessService() {
|
|
|
27898
27928
|
throw new BadRequestError56("A site is listed twice.");
|
|
27899
27929
|
seen2.add(choice.site);
|
|
27900
27930
|
if (!row.roles.some((r) => r._id === choice.role)) {
|
|
27901
|
-
throw new BadRequestError56(`Choose a role created for ${row.name || "that site"}.`);
|
|
27931
|
+
throw new BadRequestError56(`Choose a role created for ${row.name || "that site"}, or one of the organisation's service roles.`);
|
|
27902
27932
|
}
|
|
27903
27933
|
}
|
|
27904
27934
|
const userDoc = await db2().collection("users").findOne({ _id: new ObjectId61(user) }, { projection: { email: 1, name: 1 } });
|
|
@@ -27912,10 +27942,11 @@ function useMemberSiteAccessService() {
|
|
|
27912
27942
|
const choice = sites.find((c) => c.site === row.site);
|
|
27913
27943
|
const role = choice ? row.roles.find((r) => r._id === choice.role) : null;
|
|
27914
27944
|
const keep = role ? row.memberships.find((m) => m.type === role.type) : void 0;
|
|
27915
|
-
if (role && keep && keep.role !== role._id) {
|
|
27945
|
+
if (role && keep && (keep.role !== role._id || role.scope === "organisation")) {
|
|
27916
27946
|
reroles.push(async () => {
|
|
27917
|
-
await updateRoleById(keep._id, role._id);
|
|
27918
|
-
|
|
27947
|
+
await updateRoleById(keep._id, role._id, actor);
|
|
27948
|
+
if (keep.role !== role._id)
|
|
27949
|
+
applied.changed.push(row.site);
|
|
27919
27950
|
});
|
|
27920
27951
|
} else if (role && !keep) {
|
|
27921
27952
|
adds.push(async () => {
|
|
@@ -27924,7 +27955,7 @@ function useMemberSiteAccessService() {
|
|
|
27924
27955
|
{ projection: { _id: 1 } }
|
|
27925
27956
|
);
|
|
27926
27957
|
if (old) {
|
|
27927
|
-
await updateRoleById(old._id, role._id);
|
|
27958
|
+
await updateRoleById(old._id, role._id, actor);
|
|
27928
27959
|
await updateMemberStatus(old._id, { status: suspended ? "suspended" : "active" });
|
|
27929
27960
|
} else {
|
|
27930
27961
|
await add({
|
|
@@ -27938,6 +27969,8 @@ function useMemberSiteAccessService() {
|
|
|
27938
27969
|
siteId: row.site,
|
|
27939
27970
|
siteName: row.name,
|
|
27940
27971
|
dateInvited: (/* @__PURE__ */ new Date()).toISOString(),
|
|
27972
|
+
// "placed at this site by the editor": confines an organisation role to it (siteInvitedPins)
|
|
27973
|
+
createdBy: actor,
|
|
27941
27974
|
...suspended ? { status: "suspended" } : {}
|
|
27942
27975
|
});
|
|
27943
27976
|
}
|
|
@@ -63571,6 +63604,17 @@ var ROBOT_CLOUD_PATHS = {
|
|
|
63571
63604
|
workHours: "/portal/workhours/get-work-hours",
|
|
63572
63605
|
haltPlans: "/portal/halt-plan/get",
|
|
63573
63606
|
stationState: "/portal/detailstate/get-station-detail-state",
|
|
63607
|
+
// Read-only map layers and logs (2026-09-30: every read in the document is used).
|
|
63608
|
+
wallList: "/portal/maps/get-wall-list",
|
|
63609
|
+
safeZoneList: "/portal/maps/get-safezone-list",
|
|
63610
|
+
slowZoneList: "/portal/maps/get-slowzone-list",
|
|
63611
|
+
obstacleLayer: "/portal/obstacles/get-obstacle-layer",
|
|
63612
|
+
teachTrack: "/portal/teach/get-teach-track",
|
|
63613
|
+
mapVersions: "/portal/maps/get-map-version-list",
|
|
63614
|
+
floorMapHistory: "/portal/maps/v2405/get-floor-maplist",
|
|
63615
|
+
robotLog: "/portal/report/get-robot-log-list",
|
|
63616
|
+
userLog: "/portal/userlog/get-user-logs",
|
|
63617
|
+
cleaningSetting: "/portal/setting/get-cleaning-setting",
|
|
63574
63618
|
mapList: "/portal/maps/get-map-list",
|
|
63575
63619
|
fileUrl: "/portal/maps/get-file-url",
|
|
63576
63620
|
tracking: "/portal/robots/tracking",
|
|
@@ -63871,7 +63915,17 @@ var STEP_NAMES = {
|
|
|
63871
63915
|
[ROBOT_CLOUD_PATHS.haltPlans]: "the power schedule",
|
|
63872
63916
|
[ROBOT_CLOUD_PATHS.stationState]: "the base station state",
|
|
63873
63917
|
[ROBOT_CLOUD_PATHS.alertList]: "the alert history",
|
|
63874
|
-
[ROBOT_CLOUD_PATHS.liftList]: "the lift list"
|
|
63918
|
+
[ROBOT_CLOUD_PATHS.liftList]: "the lift list",
|
|
63919
|
+
[ROBOT_CLOUD_PATHS.wallList]: "the virtual walls",
|
|
63920
|
+
[ROBOT_CLOUD_PATHS.safeZoneList]: "the safe zones",
|
|
63921
|
+
[ROBOT_CLOUD_PATHS.slowZoneList]: "the slow zones",
|
|
63922
|
+
[ROBOT_CLOUD_PATHS.obstacleLayer]: "the obstacle layer",
|
|
63923
|
+
[ROBOT_CLOUD_PATHS.teachTrack]: "the taught route",
|
|
63924
|
+
[ROBOT_CLOUD_PATHS.mapVersions]: "the map versions",
|
|
63925
|
+
[ROBOT_CLOUD_PATHS.floorMapHistory]: "the floor's map history",
|
|
63926
|
+
[ROBOT_CLOUD_PATHS.robotLog]: "the robot status log",
|
|
63927
|
+
[ROBOT_CLOUD_PATHS.userLog]: "the app action log",
|
|
63928
|
+
[ROBOT_CLOUD_PATHS.cleaningSetting]: "the robot settings"
|
|
63875
63929
|
};
|
|
63876
63930
|
var robotCloudStepName = (path5) => STEP_NAMES[path5] ?? path5;
|
|
63877
63931
|
var SUCCESS_CODES = /* @__PURE__ */ new Set(["0", "200"]);
|
|
@@ -64091,6 +64145,40 @@ function useRobotCloudService(credentials, options = {}) {
|
|
|
64091
64145
|
);
|
|
64092
64146
|
return data.state ?? null;
|
|
64093
64147
|
}
|
|
64148
|
+
async function getMapShapes(kind, mapId) {
|
|
64149
|
+
const [path5, list] = kind === "walls" ? [ROBOT_CLOUD_PATHS.wallList, "wallList"] : kind === "safe" ? [ROBOT_CLOUD_PATHS.safeZoneList, "safeZoneList"] : [ROBOT_CLOUD_PATHS.slowZoneList, "slowZoneList"];
|
|
64150
|
+
const data = await post(path5, { mapId }, list);
|
|
64151
|
+
return Array.isArray(data[list]) ? data[list] : [];
|
|
64152
|
+
}
|
|
64153
|
+
async function getObstacleLayer(robotId) {
|
|
64154
|
+
return post(ROBOT_CLOUD_PATHS.obstacleLayer, { robotId, version: 0 });
|
|
64155
|
+
}
|
|
64156
|
+
async function getTeachTrack(robotId, offset) {
|
|
64157
|
+
return post(ROBOT_CLOUD_PATHS.teachTrack, { robotId, offset }, "trackList");
|
|
64158
|
+
}
|
|
64159
|
+
async function getMapVersions(mapId) {
|
|
64160
|
+
return post(ROBOT_CLOUD_PATHS.mapVersions, { mapId }, "versionList");
|
|
64161
|
+
}
|
|
64162
|
+
async function getFloorMapHistory(sceneId, floorNo2) {
|
|
64163
|
+
return post(ROBOT_CLOUD_PATHS.floorMapHistory, { sceneId, floorNo: floorNo2 }, "mapList");
|
|
64164
|
+
}
|
|
64165
|
+
async function getRobotLog(robotId, sceneId, timeFrom, timeTo) {
|
|
64166
|
+
return post(
|
|
64167
|
+
ROBOT_CLOUD_PATHS.robotLog,
|
|
64168
|
+
{ robotId: String(robotId), sceneId: String(sceneId), timeFrom, timeTo, key: "", pageNo: 1, pageSize: 50 },
|
|
64169
|
+
"logList"
|
|
64170
|
+
);
|
|
64171
|
+
}
|
|
64172
|
+
async function getUserLogs(robotId, startTime, endTime) {
|
|
64173
|
+
return post(
|
|
64174
|
+
ROBOT_CLOUD_PATHS.userLog,
|
|
64175
|
+
{ robotId, pageNo: 1, pageSize: 50, startTime, endTime, keyword: "" },
|
|
64176
|
+
"actionList"
|
|
64177
|
+
);
|
|
64178
|
+
}
|
|
64179
|
+
async function getCleaningSetting(robotId) {
|
|
64180
|
+
return post(ROBOT_CLOUD_PATHS.cleaningSetting, { robotId });
|
|
64181
|
+
}
|
|
64094
64182
|
async function getMaps(robotSn) {
|
|
64095
64183
|
const data = await post(
|
|
64096
64184
|
ROBOT_CLOUD_PATHS.mapList,
|
|
@@ -64176,6 +64264,14 @@ function useRobotCloudService(credentials, options = {}) {
|
|
|
64176
64264
|
getHaltPlans,
|
|
64177
64265
|
getStationState,
|
|
64178
64266
|
getLiftList,
|
|
64267
|
+
getMapShapes,
|
|
64268
|
+
getObstacleLayer,
|
|
64269
|
+
getTeachTrack,
|
|
64270
|
+
getMapVersions,
|
|
64271
|
+
getFloorMapHistory,
|
|
64272
|
+
getRobotLog,
|
|
64273
|
+
getUserLogs,
|
|
64274
|
+
getCleaningSetting,
|
|
64179
64275
|
getMaps,
|
|
64180
64276
|
getFileUrls,
|
|
64181
64277
|
getPlans,
|
|
@@ -64370,22 +64466,48 @@ function ounitechFault(list) {
|
|
|
64370
64466
|
return { code: "error", message: String(list[0]).slice(0, 200) };
|
|
64371
64467
|
return { code: "error", message: "The robot reports an error" };
|
|
64372
64468
|
}
|
|
64373
|
-
function ounitechMapShare(map, x, y) {
|
|
64469
|
+
function ounitechMapShare(map, x, y, clamp4 = false) {
|
|
64374
64470
|
const w = map?.width, h = map?.height, r = map?.resolution;
|
|
64375
64471
|
const wx = num(x), wy = num(y);
|
|
64376
64472
|
if (!finite(w) || !finite(h) || !finite(r) || w <= 0 || h <= 0 || r <= 0 || wx === void 0 || wy === void 0)
|
|
64377
64473
|
return null;
|
|
64378
|
-
|
|
64379
|
-
|
|
64474
|
+
let sx = (wx - (num(map?.originX) ?? 0)) / r / w * 100;
|
|
64475
|
+
let sy = 100 - (wy - (num(map?.originY) ?? 0)) / r / h * 100;
|
|
64476
|
+
if (clamp4)
|
|
64477
|
+
sx = Math.min(100, Math.max(0, sx)), sy = Math.min(100, Math.max(0, sy));
|
|
64380
64478
|
if (sx < 0 || sx > 100 || sy < 0 || sy > 100)
|
|
64381
64479
|
return null;
|
|
64382
64480
|
return { x: Math.round(sx * 100) / 100, y: Math.round(sy * 100) / 100 };
|
|
64383
64481
|
}
|
|
64384
|
-
|
|
64482
|
+
var SHAPE_WORDS = { wall: "Virtual wall", safe: "Safe zone", slow: "Slow zone" };
|
|
64483
|
+
function ounitechShapes(map, kind, list) {
|
|
64484
|
+
return (Array.isArray(list) ? list : []).flatMap((z5, i) => {
|
|
64485
|
+
const points = (Array.isArray(z5?.pointList) ? z5.pointList : []).flatMap((p) => {
|
|
64486
|
+
const at2 = Array.isArray(p) ? ounitechMapShare(map, p[0], p[1], true) : null;
|
|
64487
|
+
return at2 ? [at2] : [];
|
|
64488
|
+
});
|
|
64489
|
+
const name = String(z5?.wallName ?? z5?.zoneName ?? "").trim();
|
|
64490
|
+
return points.length >= 2 ? [{ kind, name: name || `${SHAPE_WORDS[kind]} ${i + 1}`, points }] : [];
|
|
64491
|
+
});
|
|
64492
|
+
}
|
|
64493
|
+
function ounitechTrack(map, list) {
|
|
64494
|
+
const on = (Array.isArray(list) ? list : []).filter((p) => p && (p.mapid == null || String(p.mapid) === map?.mapId));
|
|
64495
|
+
const step = Math.max(1, Math.ceil(on.length / 500));
|
|
64496
|
+
return on.filter((_, i) => i % step === 0).flatMap((p) => {
|
|
64497
|
+
const at2 = ounitechMapShare(map, p.x, p.y, true);
|
|
64498
|
+
return at2 ? [at2] : [];
|
|
64499
|
+
});
|
|
64500
|
+
}
|
|
64501
|
+
function ounitechMapView(m, imageUrl, partitionImageUrl, size, shapes = {}) {
|
|
64385
64502
|
const floorNo2 = Number.isInteger(m.floorNo) ? m.floorNo : null;
|
|
64386
64503
|
const width = size?.width ?? null;
|
|
64387
64504
|
const height = size?.height ?? null;
|
|
64388
64505
|
const frame2 = { width, height, resolution: m.resolution, originX: m.originX, originY: m.originY };
|
|
64506
|
+
const zones = [
|
|
64507
|
+
...ounitechShapes(frame2, "wall", Array.isArray(shapes.walls) && shapes.walls.length ? shapes.walls : m.wallList),
|
|
64508
|
+
...ounitechShapes(frame2, "safe", shapes.safe),
|
|
64509
|
+
...ounitechShapes(frame2, "slow", shapes.slow)
|
|
64510
|
+
];
|
|
64389
64511
|
const areas = (Array.isArray(m.areaList) ? m.areaList : []).filter((a) => typeof a?.areaName === "string" && a.areaName.trim()).map((a) => {
|
|
64390
64512
|
const px = num(a.x), py = num(a.y);
|
|
64391
64513
|
const at2 = width && height && px !== void 0 && py !== void 0 && (px > 0 || py > 0) && px <= width && py <= height ? { x: Math.round(px / width * 1e4) / 100, y: Math.round(py / height * 1e4) / 100 } : null;
|
|
@@ -64415,7 +64537,11 @@ function ounitechMapView(m, imageUrl, partitionImageUrl, size) {
|
|
|
64415
64537
|
positionApproximate: true,
|
|
64416
64538
|
// The raw areas, kept for older screens.
|
|
64417
64539
|
areaList: areas.map(({ at: _at, ...a }) => a),
|
|
64418
|
-
areas: areas.map((a) => ({ name: a.areaName, at: a.at }))
|
|
64540
|
+
areas: areas.map((a) => ({ name: a.areaName, at: a.at })),
|
|
64541
|
+
/** Virtual walls (the robot never crosses), safe zones and slow zones, drawn on the map. */
|
|
64542
|
+
zones,
|
|
64543
|
+
/** The route the robot was taught (get-teach-track), set per robot by getMaps. */
|
|
64544
|
+
taughtRoute: []
|
|
64419
64545
|
};
|
|
64420
64546
|
}
|
|
64421
64547
|
function ounitechCurrentMap(maps, taskMapId, floorNo2) {
|
|
@@ -64642,10 +64768,115 @@ function ounitechPowerPlan(p) {
|
|
|
64642
64768
|
enabled: p.enableFlag !== false
|
|
64643
64769
|
};
|
|
64644
64770
|
}
|
|
64771
|
+
function ounitechStatusLog(l, tz = 480) {
|
|
64772
|
+
const code = num(l.typeFlag);
|
|
64773
|
+
const words = code !== void 0 ? ROBOT_STATUS_NAMES[code] : void 0;
|
|
64774
|
+
return {
|
|
64775
|
+
at: ounitechTime(l.timeFrom, tz),
|
|
64776
|
+
status: words ? code === 15 || code === 16 ? `${words} (mid-job)` : words : String(l.typeName ?? "").trim() || `Status ${l.typeFlag ?? "?"}`
|
|
64777
|
+
};
|
|
64778
|
+
}
|
|
64779
|
+
var ACTION_WORDS = {
|
|
64780
|
+
\u539F\u5730\u505C\u6B62: "Stopped in place",
|
|
64781
|
+
\u4E0B\u53D1\u6E05\u6D01: "Started a cleaning job",
|
|
64782
|
+
\u793A\u6559\u8DEF\u5F84\u63A7\u5236: "Controlled a taught route",
|
|
64783
|
+
\u6682\u505C: "Paused",
|
|
64784
|
+
\u7EE7\u7EED: "Resumed",
|
|
64785
|
+
\u56DE\u5145: "Sent back to charge",
|
|
64786
|
+
\u7ED3\u675F\u6E05\u6D01: "Ended the cleaning job",
|
|
64787
|
+
\u5F00\u673A: "Switched on",
|
|
64788
|
+
\u5173\u673A: "Switched off"
|
|
64789
|
+
};
|
|
64790
|
+
function ounitechAppAction(a, tz = 480) {
|
|
64791
|
+
const raw = String(a.actionName ?? "").trim();
|
|
64792
|
+
return {
|
|
64793
|
+
at: ounitechTime(a.createTime, tz),
|
|
64794
|
+
action: ACTION_WORDS[raw] ?? (raw ? /[㐀-鿿]/.test(raw) ? `App action: ${raw}` : raw : "App action"),
|
|
64795
|
+
by: String(a.userName ?? "").trim() || null
|
|
64796
|
+
};
|
|
64797
|
+
}
|
|
64798
|
+
function ounitechMapVersion(v, tz = 480) {
|
|
64799
|
+
return { version: num(v.versionNo) ?? null, latest: v.latestFlag === true, createdAt: ounitechTime(v.createTime, tz) };
|
|
64800
|
+
}
|
|
64801
|
+
function ounitechFloorMapHistory(m, tz = 480) {
|
|
64802
|
+
const area = num(m.totalArea);
|
|
64803
|
+
return {
|
|
64804
|
+
name: String(m.mapName ?? "").trim() || `Map ${m.mapId ?? ""}`.trim(),
|
|
64805
|
+
areaM2: area !== void 0 ? Math.round(area * 10) / 10 : null,
|
|
64806
|
+
latest: m.latestFlag === true,
|
|
64807
|
+
inUse: m.enableFlag === true,
|
|
64808
|
+
createdAt: ounitechTime(m.createTime, tz),
|
|
64809
|
+
updatedAt: ounitechTime(m.updateTime, tz)
|
|
64810
|
+
};
|
|
64811
|
+
}
|
|
64812
|
+
var SETTINGS = {
|
|
64813
|
+
soundLevel: { group: "Sound", label: "Sound level", unit: "%" },
|
|
64814
|
+
enableWorkSound: { group: "Sound", label: "Sounds while working" },
|
|
64815
|
+
clean_speed_mode: { group: "Cleaning", label: "Cleaning speed" },
|
|
64816
|
+
fanLevel: { group: "Cleaning", label: "Suction level" },
|
|
64817
|
+
waterGear: { group: "Cleaning", label: "Water level" },
|
|
64818
|
+
planningWidth: { group: "Cleaning", label: "Cleaning path width" },
|
|
64819
|
+
alongWallFlag: { group: "Cleaning", label: "Edge cleaning" },
|
|
64820
|
+
alongWallDistance: { group: "Cleaning", label: "Edge distance" },
|
|
64821
|
+
enablePlanFlag: { group: "Cleaning", label: "Schedules switched on" },
|
|
64822
|
+
slowZoneSpeed: { group: "Cleaning", label: "Speed in slow zones", unit: "m/s" },
|
|
64823
|
+
minCleanBatteryPerc: { group: "Battery", label: "Lowest battery to start cleaning", unit: "%" },
|
|
64824
|
+
normalCleanBatteryPerc: { group: "Battery", label: "Normal cleaning battery", unit: "%" },
|
|
64825
|
+
backChargeThreshold: { group: "Battery", label: "Return-to-charge battery level", unit: "%" },
|
|
64826
|
+
chargeCompIntervalDay: { group: "Battery", label: "Full charge every", unit: "days" },
|
|
64827
|
+
obsAvoidSens: { group: "Safety", label: "Obstacle avoidance sensitivity" },
|
|
64828
|
+
obsDetectionHeight: { group: "Safety", label: "Obstacle detection height" },
|
|
64829
|
+
enableCliffDetect: { group: "Safety", label: "Cliff (drop) detection" },
|
|
64830
|
+
ultrasonicSwitch: { group: "Safety", label: "Ultrasonic sensors" },
|
|
64831
|
+
panicButtonMode: { group: "Safety", label: "Emergency button mode" },
|
|
64832
|
+
autoUpdateMap: { group: "Maps", label: "Update the map automatically" },
|
|
64833
|
+
autoUpdateVirtualWall: { group: "Maps", label: "Update virtual walls automatically" },
|
|
64834
|
+
autoUpdateZoneMap: { group: "Maps", label: "Update the area map automatically" },
|
|
64835
|
+
stationAutoDrain: { group: "Base station", label: "Station drains automatically" },
|
|
64836
|
+
language: { group: "Robot", label: "Robot language" },
|
|
64837
|
+
timeZone: { group: "Robot", label: "Robot time zone" }
|
|
64838
|
+
};
|
|
64839
|
+
var SECRET_SETTING = /wifi|pwd|password|secret|token/i;
|
|
64840
|
+
var LANG_WORDS = { zh: "Chinese", en: "English" };
|
|
64841
|
+
function ounitechSettings(s) {
|
|
64842
|
+
const out = [];
|
|
64843
|
+
for (const [key, v] of Object.entries(s ?? {})) {
|
|
64844
|
+
if (key === "ok" || key === "msg" || SECRET_SETTING.test(key) || v == null || typeof v === "object")
|
|
64845
|
+
continue;
|
|
64846
|
+
const raw = String(v).trim();
|
|
64847
|
+
if (raw === "")
|
|
64848
|
+
continue;
|
|
64849
|
+
const d = SETTINGS[key] ?? { group: "Other settings", label: key };
|
|
64850
|
+
let value;
|
|
64851
|
+
if (typeof v === "boolean")
|
|
64852
|
+
value = v ? "On" : "Off";
|
|
64853
|
+
else if (key === "language")
|
|
64854
|
+
value = LANG_WORDS[raw] ?? raw;
|
|
64855
|
+
else if (key === "timeZone" && num(raw) !== void 0)
|
|
64856
|
+
value = `UTC${num(raw) >= 0 ? "+" : ""}${raw}`;
|
|
64857
|
+
else
|
|
64858
|
+
value = d.unit ? `${raw} ${d.unit}` : raw;
|
|
64859
|
+
out.push({ key, group: d.group, label: d.label, value, attention: false });
|
|
64860
|
+
}
|
|
64861
|
+
const order = ["Cleaning", "Battery", "Safety", "Maps", "Sound", "Base station", "Robot", "Other settings"];
|
|
64862
|
+
return out.sort((a, b) => order.indexOf(a.group) - order.indexOf(b.group));
|
|
64863
|
+
}
|
|
64864
|
+
function ounitechObstacleImage(o) {
|
|
64865
|
+
const b64 = typeof o?.image === "string" ? o.image.replace(/^data:image\/\w+;base64,/, "").trim() : "";
|
|
64866
|
+
if (!b64 || !/^[A-Za-z0-9+/=\s]+$/.test(b64.slice(0, 200)))
|
|
64867
|
+
return null;
|
|
64868
|
+
if (b64.length > 15e5)
|
|
64869
|
+
return { version: num(o?.version) ?? null, image: null, tooLarge: true };
|
|
64870
|
+
const type = b64.startsWith("/9j/") ? "jpeg" : "png";
|
|
64871
|
+
return { version: num(o?.version) ?? null, image: `data:image/${type};base64,${b64}`, tooLarge: false };
|
|
64872
|
+
}
|
|
64645
64873
|
var MAP_TTL_MS = 10 * 6e4;
|
|
64646
64874
|
var RECORDS_TTL_MS = 2 * 6e4;
|
|
64647
64875
|
var mapCache = /* @__PURE__ */ new Map();
|
|
64648
64876
|
var recordsCache = /* @__PURE__ */ new Map();
|
|
64877
|
+
var SLOW_TTL_MS = 10 * 6e4;
|
|
64878
|
+
var slowCache = /* @__PURE__ */ new Map();
|
|
64879
|
+
var trackCache = /* @__PURE__ */ new Map();
|
|
64649
64880
|
function cached2(cache3, field, key, ttl, load) {
|
|
64650
64881
|
const hit = cache3.get(key);
|
|
64651
64882
|
if (hit && Date.now() - hit.at < ttl)
|
|
@@ -64658,6 +64889,8 @@ function cached2(cache3, field, key, ttl, load) {
|
|
|
64658
64889
|
function clearOunitechCaches() {
|
|
64659
64890
|
mapCache.clear();
|
|
64660
64891
|
recordsCache.clear();
|
|
64892
|
+
slowCache.clear();
|
|
64893
|
+
trackCache.clear();
|
|
64661
64894
|
}
|
|
64662
64895
|
var robotTime = (d) => robotCloudTimestamp(d, "yyyy-MM-dd HH:mm:ss", "Asia/Shanghai");
|
|
64663
64896
|
function createOunitechAdapter(credentials, options) {
|
|
@@ -64671,12 +64904,15 @@ function createOunitechAdapter(credentials, options) {
|
|
|
64671
64904
|
const keys = list.flatMap((m) => [m.backgroundFileKey, m.partitionFileKey]).filter((k) => typeof k === "string" && !!k);
|
|
64672
64905
|
const files = keys.length ? await cloud.previewFiles(keys).catch(() => []) : [];
|
|
64673
64906
|
const url2 = (k) => files.find((f) => f.fileKey === k)?.url || null;
|
|
64674
|
-
|
|
64675
|
-
|
|
64676
|
-
|
|
64677
|
-
|
|
64678
|
-
|
|
64679
|
-
|
|
64907
|
+
const views = [];
|
|
64908
|
+
for (const m of list) {
|
|
64909
|
+
const imageUrl = url2(m.backgroundFileKey);
|
|
64910
|
+
const id = num(m.mapId);
|
|
64911
|
+
const layer = (kind) => id !== void 0 ? cloud.getMapShapes(kind, id).catch(() => []) : Promise.resolve([]);
|
|
64912
|
+
const shapes = { walls: await layer("walls"), safe: await layer("safe"), slow: await layer("slow") };
|
|
64913
|
+
views.push(ounitechMapView(m, imageUrl, url2(m.partitionFileKey), imageUrl ? await fetchPngSize(imageUrl) : null, shapes));
|
|
64914
|
+
}
|
|
64915
|
+
return views;
|
|
64680
64916
|
});
|
|
64681
64917
|
}
|
|
64682
64918
|
async function placed(row, robot) {
|
|
@@ -64690,6 +64926,40 @@ function createOunitechAdapter(credentials, options) {
|
|
|
64690
64926
|
robot.planPosition = robot.position ? ounitechMapShare(map, robot.position.x, robot.position.y) : null;
|
|
64691
64927
|
return robot;
|
|
64692
64928
|
}
|
|
64929
|
+
async function slowRecords(robotSn) {
|
|
64930
|
+
const row = await rowFor(robotSn);
|
|
64931
|
+
if (!row || !finite(row.robotId))
|
|
64932
|
+
return {};
|
|
64933
|
+
const robotId = row.robotId;
|
|
64934
|
+
const tz = finite(row.timezone) ? row.timezone : 480;
|
|
64935
|
+
const now = /* @__PURE__ */ new Date();
|
|
64936
|
+
const since = (days) => robotTime(new Date(now.getTime() - days * 864e5));
|
|
64937
|
+
const part = async (read2) => {
|
|
64938
|
+
try {
|
|
64939
|
+
return { items: await read2() };
|
|
64940
|
+
} catch (e) {
|
|
64941
|
+
return { items: [], error: String(e?.message ?? e).slice(0, 300) };
|
|
64942
|
+
}
|
|
64943
|
+
};
|
|
64944
|
+
const maps = finite(row.sceneId) ? await floorMaps(row.sceneId).catch(() => []) : [];
|
|
64945
|
+
const map = ounitechCurrentMap(maps, row.taskState?.mapId, Number.isInteger(row.floorNo) ? row.floorNo : null);
|
|
64946
|
+
const mapId = map ? num(map.mapId) : void 0;
|
|
64947
|
+
const floorNo2 = map?.floorNo ?? (Number.isInteger(row.floorNo) ? row.floorNo : null);
|
|
64948
|
+
const sceneId = finite(row.sceneId) ? row.sceneId : null;
|
|
64949
|
+
const statusLog = sceneId !== null ? await part(async () => ((await cloud.getRobotLog(robotId, sceneId, since(7), robotTime(now))).logList ?? []).map((l) => ounitechStatusLog(l, tz))) : { items: [] };
|
|
64950
|
+
const appActions = await part(async () => ((await cloud.getUserLogs(robotId, since(30), robotTime(now))).actionList ?? []).map((a) => ounitechAppAction(a, tz)));
|
|
64951
|
+
const settings = await part(async () => ounitechSettings(await cloud.getCleaningSetting(robotId)));
|
|
64952
|
+
const obstacles = await part(async () => {
|
|
64953
|
+
const o = ounitechObstacleImage(await cloud.getObstacleLayer(robotId));
|
|
64954
|
+
return o ? [o] : [];
|
|
64955
|
+
});
|
|
64956
|
+
const mapVersions = mapId !== void 0 ? await part(async () => ((await cloud.getMapVersions(mapId)).versionList ?? []).map((v) => ounitechMapVersion(v, tz))) : { items: [] };
|
|
64957
|
+
const mapHistory = sceneId !== null && floorNo2 !== null ? await part(async () => ((await cloud.getFloorMapHistory(sceneId, floorNo2)).mapList ?? []).map((m) => ounitechFloorMapHistory(m, tz))) : { items: [] };
|
|
64958
|
+
const mapLayers = {
|
|
64959
|
+
items: map ? [{ map: map.mapDisplayName || null, zones: map.zones.map((z5) => ({ kind: z5.kind, name: z5.name })) }] : []
|
|
64960
|
+
};
|
|
64961
|
+
return { statusLog, appActions, settings, obstacles, mapVersions, mapHistory, mapLayers };
|
|
64962
|
+
}
|
|
64693
64963
|
async function rowFor(robotSn) {
|
|
64694
64964
|
return (await cloud.getHomeRobots()).find((r) => r.robotSn === robotSn) ?? null;
|
|
64695
64965
|
}
|
|
@@ -64753,7 +65023,18 @@ function createOunitechAdapter(credentials, options) {
|
|
|
64753
65023
|
const row = await rowFor(robotSn);
|
|
64754
65024
|
if (!row || !finite(row.sceneId))
|
|
64755
65025
|
return [];
|
|
64756
|
-
|
|
65026
|
+
const maps = await floorMaps(row.sceneId);
|
|
65027
|
+
const robotId = row.robotId;
|
|
65028
|
+
if (!finite(robotId))
|
|
65029
|
+
return maps;
|
|
65030
|
+
const track = await cached2(
|
|
65031
|
+
trackCache,
|
|
65032
|
+
"value",
|
|
65033
|
+
`${options?.baseUrl ?? ""}|${credentials.appid}|${robotId}`,
|
|
65034
|
+
SLOW_TTL_MS,
|
|
65035
|
+
async () => (await cloud.getTeachTrack(robotId, robotTime(new Date(Date.now() - 365 * 864e5)))).trackList ?? []
|
|
65036
|
+
).catch(() => []);
|
|
65037
|
+
return maps.map((m) => ({ ...m, taughtRoute: ounitechTrack(m, track) }));
|
|
64757
65038
|
},
|
|
64758
65039
|
async getMapImages(_robotSn, fileKeys) {
|
|
64759
65040
|
return cloud.previewFiles(fileKeys);
|
|
@@ -64779,7 +65060,7 @@ function createOunitechAdapter(credentials, options) {
|
|
|
64779
65060
|
* after another (gentler on the rate limit); each part carries its own error.
|
|
64780
65061
|
*/
|
|
64781
65062
|
async getRecords(robotSn) {
|
|
64782
|
-
|
|
65063
|
+
const fast = cached2(recordsCache, "value", `${options?.baseUrl ?? ""}|${credentials.appid}|${robotSn}`, RECORDS_TTL_MS, async () => {
|
|
64783
65064
|
const row = await rowFor(robotSn);
|
|
64784
65065
|
if (!row || !finite(row.robotId))
|
|
64785
65066
|
return { supported: true, error: `Serial ${robotSn} is not on this Ounitech account.` };
|
|
@@ -64822,6 +65103,8 @@ function createOunitechAdapter(credentials, options) {
|
|
|
64822
65103
|
});
|
|
64823
65104
|
return { supported: true, readAt: now.toISOString(), tasks, alerts, consumables, power, lifts, readings, station };
|
|
64824
65105
|
});
|
|
65106
|
+
const slow = await cached2(slowCache, "value", `${options?.baseUrl ?? ""}|${credentials.appid}|${robotSn}`, SLOW_TTL_MS, () => slowRecords(robotSn));
|
|
65107
|
+
return { ...slow, ...await fast };
|
|
64825
65108
|
},
|
|
64826
65109
|
/**
|
|
64827
65110
|
* Staff Diagnose: every other read-only chapter-6 call, with the vendor's
|
|
@@ -64853,8 +65136,8 @@ function createOunitechAdapter(credentials, options) {
|
|
|
64853
65136
|
return { count: list.length, robots: list.slice(0, 3).map((r) => ({ robotSn: r.robotSn, statusName: r.statusName })) };
|
|
64854
65137
|
});
|
|
64855
65138
|
await run("serial-based map list (chapter 2)", ROBOT_CLOUD_PATHS.mapList, { robotSn }, async () => {
|
|
64856
|
-
const
|
|
64857
|
-
return { count:
|
|
65139
|
+
const maps2 = await cloud.getMaps(robotSn);
|
|
65140
|
+
return { count: maps2.length, floors: maps2.map((m) => m.floorNo) };
|
|
64858
65141
|
});
|
|
64859
65142
|
const row = await rowFor(robotSn).catch(() => null);
|
|
64860
65143
|
if (!row || !finite(row.robotId)) {
|
|
@@ -64906,6 +65189,50 @@ function createOunitechAdapter(credentials, options) {
|
|
|
64906
65189
|
return (r.liftlist ?? []).map((l) => ({ liftno: l.liftno, liftname: l.liftname, floorno: l.floorno, onlineflag: l.onlineflag, enableflag: l.enableflag }));
|
|
64907
65190
|
});
|
|
64908
65191
|
}
|
|
65192
|
+
const maps = finite(row.sceneId) ? await floorMaps(row.sceneId).catch(() => []) : [];
|
|
65193
|
+
const map = ounitechCurrentMap(maps, row.taskState?.mapId, Number.isInteger(row.floorNo) ? row.floorNo : null);
|
|
65194
|
+
const mapId = map ? num(map.mapId) : void 0;
|
|
65195
|
+
if (mapId !== void 0) {
|
|
65196
|
+
await run("virtual walls (get-wall-list)", ROBOT_CLOUD_PATHS.wallList, { mapId }, async () => cut(await cloud.getMapShapes("walls", mapId)));
|
|
65197
|
+
await run("safe zones (get-safezone-list)", ROBOT_CLOUD_PATHS.safeZoneList, { mapId }, async () => cut(await cloud.getMapShapes("safe", mapId)));
|
|
65198
|
+
await run("slow zones (get-slowzone-list)", ROBOT_CLOUD_PATHS.slowZoneList, { mapId }, async () => cut(await cloud.getMapShapes("slow", mapId)));
|
|
65199
|
+
await run("map versions (get-map-version-list)", ROBOT_CLOUD_PATHS.mapVersions, { mapId }, async () => cut((await cloud.getMapVersions(mapId)).versionList ?? []));
|
|
65200
|
+
}
|
|
65201
|
+
if (finite(row.sceneId) && map?.floorNo != null) {
|
|
65202
|
+
const sceneId = row.sceneId;
|
|
65203
|
+
const floorNo2 = map.floorNo;
|
|
65204
|
+
await run(
|
|
65205
|
+
"floor map history (v2405/get-floor-maplist)",
|
|
65206
|
+
ROBOT_CLOUD_PATHS.floorMapHistory,
|
|
65207
|
+
{ sceneId, floorNo: floorNo2 },
|
|
65208
|
+
async () => cut((await cloud.getFloorMapHistory(sceneId, floorNo2)).mapList ?? [])
|
|
65209
|
+
);
|
|
65210
|
+
}
|
|
65211
|
+
await run("obstacle layer (get-obstacle-layer)", ROBOT_CLOUD_PATHS.obstacleLayer, { robotId, version: 0 }, async () => {
|
|
65212
|
+
const o = await cloud.getObstacleLayer(robotId);
|
|
65213
|
+
return { version: o.version ?? null, imageChars: typeof o.image === "string" ? o.image.length : 0 };
|
|
65214
|
+
});
|
|
65215
|
+
await run("taught route (get-teach-track)", ROBOT_CLOUD_PATHS.teachTrack, { robotId, offset: window.timeFrom }, async () => {
|
|
65216
|
+
const r = await cloud.getTeachTrack(robotId, window.timeFrom);
|
|
65217
|
+
return { points: r.trackList?.length ?? 0, since: r.since ?? null, first: cut(r.trackList ?? []) };
|
|
65218
|
+
});
|
|
65219
|
+
if (finite(row.sceneId)) {
|
|
65220
|
+
const sceneId = row.sceneId;
|
|
65221
|
+
await run("robot status log, last 7 days (get-robot-log-list)", ROBOT_CLOUD_PATHS.robotLog, { robotId, sceneId, ...window }, async () => {
|
|
65222
|
+
const r = await cloud.getRobotLog(robotId, sceneId, window.timeFrom, window.timeTo);
|
|
65223
|
+
return { total: r.total ?? r.logList?.length ?? 0, latest: cut(r.logList ?? []) };
|
|
65224
|
+
});
|
|
65225
|
+
}
|
|
65226
|
+
await run("app action log, last 7 days (get-user-logs)", ROBOT_CLOUD_PATHS.userLog, { robotId, startTime: window.timeFrom, endTime: window.timeTo }, async () => {
|
|
65227
|
+
const r = await cloud.getUserLogs(robotId, window.timeFrom, window.timeTo);
|
|
65228
|
+
return { total: r.total ?? r.actionList?.length ?? 0, latest: cut((r.actionList ?? []).map(({ userPhone: _p, ...a }) => a)) };
|
|
65229
|
+
});
|
|
65230
|
+
await run(
|
|
65231
|
+
"robot settings (get-cleaning-setting)",
|
|
65232
|
+
ROBOT_CLOUD_PATHS.cleaningSetting,
|
|
65233
|
+
{ robotId },
|
|
65234
|
+
async () => Object.fromEntries(Object.entries(await cloud.getCleaningSetting(robotId)).filter(([k]) => !SECRET_SETTING.test(k) && k !== "ok" && k !== "msg"))
|
|
65235
|
+
);
|
|
64909
65236
|
steps.push({
|
|
64910
65237
|
step: "current job (robot list taskState)",
|
|
64911
65238
|
path: ROBOT_CLOUD_PATHS.homeRobotList,
|
|
@@ -107329,6 +107656,7 @@ export {
|
|
|
107329
107656
|
ROBOT_TYPES,
|
|
107330
107657
|
RobotCloudError,
|
|
107331
107658
|
RobotCredentialsError,
|
|
107659
|
+
SECRET_SETTING,
|
|
107332
107660
|
SELF_SERVICE_RESEND_COOLDOWN_MS,
|
|
107333
107661
|
SELF_SIGNUP_PLATFORM,
|
|
107334
107662
|
SELF_SIGNUP_STATUS,
|
|
@@ -107625,18 +107953,26 @@ export {
|
|
|
107625
107953
|
orgRoleSets,
|
|
107626
107954
|
orgSchema,
|
|
107627
107955
|
ounitechAlertRecord,
|
|
107956
|
+
ounitechAppAction,
|
|
107628
107957
|
ounitechCleaning,
|
|
107629
107958
|
ounitechConsumable,
|
|
107630
107959
|
ounitechCurrentMap,
|
|
107631
107960
|
ounitechFault,
|
|
107961
|
+
ounitechFloorMapHistory,
|
|
107632
107962
|
ounitechJobWords,
|
|
107633
107963
|
ounitechMapShare,
|
|
107964
|
+
ounitechMapVersion,
|
|
107634
107965
|
ounitechMapView,
|
|
107966
|
+
ounitechObstacleImage,
|
|
107635
107967
|
ounitechPowerPlan,
|
|
107636
107968
|
ounitechReadings,
|
|
107637
107969
|
ounitechRobotFromHomeRow,
|
|
107970
|
+
ounitechSettings,
|
|
107971
|
+
ounitechShapes,
|
|
107972
|
+
ounitechStatusLog,
|
|
107638
107973
|
ounitechTaskRecord,
|
|
107639
107974
|
ounitechTime,
|
|
107975
|
+
ounitechTrack,
|
|
107640
107976
|
overnight_parking_requests_namespace_collection,
|
|
107641
107977
|
padbotAccountKey,
|
|
107642
107978
|
padbotAlarmFault,
|