@7365admin1/core 3.131.0 → 3.132.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 +58 -13
- package/dist/index.js +250 -129
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +247 -129
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/ounitech-api-2025-10.test.mjs +148 -4
package/dist/index.js
CHANGED
|
@@ -250,6 +250,7 @@ __export(src_exports, {
|
|
|
250
250
|
OUNITECH_BRAND: () => OUNITECH_BRAND,
|
|
251
251
|
OUNITECH_BRAND_DEFINITION: () => OUNITECH_BRAND_DEFINITION,
|
|
252
252
|
OUNITECH_CAPABILITIES: () => OUNITECH_CAPABILITIES,
|
|
253
|
+
OUNITECH_FRESH_MS: () => OUNITECH_FRESH_MS,
|
|
253
254
|
OUNITECH_PENDING_COMMANDS: () => OUNITECH_PENDING_COMMANDS,
|
|
254
255
|
OUNITECH_REGION_BASE_URLS: () => OUNITECH_REGION_BASE_URLS,
|
|
255
256
|
OUNITECH_TIMESTAMP_FORMAT: () => OUNITECH_TIMESTAMP_FORMAT,
|
|
@@ -616,7 +617,9 @@ __export(src_exports, {
|
|
|
616
617
|
orgQualifiesForOwnerRepair: () => orgQualifiesForOwnerRepair,
|
|
617
618
|
orgRoleSets: () => orgRoleSets,
|
|
618
619
|
orgSchema: () => orgSchema,
|
|
620
|
+
ounitechCleaning: () => ounitechCleaning,
|
|
619
621
|
ounitechFault: () => ounitechFault,
|
|
622
|
+
ounitechJobWords: () => ounitechJobWords,
|
|
620
623
|
ounitechRobotFromHomeRow: () => ounitechRobotFromHomeRow,
|
|
621
624
|
overnight_parking_requests_namespace_collection: () => overnight_parking_requests_namespace_collection,
|
|
622
625
|
padbotAccountKey: () => padbotAccountKey,
|
|
@@ -11254,15 +11257,15 @@ function robotConnectionText(robotName, online, minutes) {
|
|
|
11254
11257
|
}
|
|
11255
11258
|
var OFFLINE_FAULT_CODE = "OFFLINE";
|
|
11256
11259
|
var SAME_OCCURRENCE_MS = 1e3;
|
|
11257
|
-
function planFaultChanges(open,
|
|
11260
|
+
function planFaultChanges(open, reading2) {
|
|
11258
11261
|
const byCode = new Map(open.map((r) => [r.code, r]));
|
|
11259
11262
|
const want = [];
|
|
11260
|
-
const offline = !
|
|
11263
|
+
const offline = !reading2.ok || reading2.online === false;
|
|
11261
11264
|
if (offline) {
|
|
11262
|
-
const reason =
|
|
11265
|
+
const reason = reading2.ok ? "" : String(reading2.error ?? "").slice(0, 200);
|
|
11263
11266
|
want.push({ code: OFFLINE_FAULT_CODE, message: reason ? `Not reporting: ${reason}` : "Not reporting" });
|
|
11264
11267
|
}
|
|
11265
|
-
const fault =
|
|
11268
|
+
const fault = reading2.ok && reading2.fault?.code ? reading2.fault : null;
|
|
11266
11269
|
if (fault)
|
|
11267
11270
|
want.push({ code: fault.code, message: fault.message || fault.code, since: fault.since });
|
|
11268
11271
|
const clear = [];
|
|
@@ -11294,12 +11297,12 @@ function planFaultChanges(open, reading) {
|
|
|
11294
11297
|
return { open: toOpen, clear, refresh };
|
|
11295
11298
|
}
|
|
11296
11299
|
function robotFaultSweepConfig(env2 = process.env) {
|
|
11297
|
-
const
|
|
11300
|
+
const num4 = (v, def, min, max) => {
|
|
11298
11301
|
const n = Math.floor(Number(v));
|
|
11299
11302
|
return Number.isFinite(n) && String(v ?? "").trim() !== "" ? Math.min(max, Math.max(min, n)) : def;
|
|
11300
11303
|
};
|
|
11301
11304
|
const enabled = String(env2.ROBOT_FAULT_SWEEP ?? "on").trim().toLowerCase() !== "off";
|
|
11302
|
-
const asked =
|
|
11305
|
+
const asked = num4(env2.ROBOT_FAULT_SWEEP_SECONDS, 60, 10, 3600);
|
|
11303
11306
|
const pick = (steps, v) => steps.filter((d) => d <= v).pop() ?? steps[0];
|
|
11304
11307
|
const subMinute = asked < 60;
|
|
11305
11308
|
const step = subMinute ? pick([10, 12, 15, 20, 30], asked) : pick([1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60], Math.floor(asked / 60));
|
|
@@ -11309,9 +11312,9 @@ function robotFaultSweepConfig(env2 = process.env) {
|
|
|
11309
11312
|
enabled,
|
|
11310
11313
|
seconds,
|
|
11311
11314
|
cron: cron2,
|
|
11312
|
-
concurrency:
|
|
11313
|
-
timeoutMs:
|
|
11314
|
-
offlineAlertMinutes:
|
|
11315
|
+
concurrency: num4(env2.ROBOT_FAULT_SWEEP_CONCURRENCY, 4, 1, 16),
|
|
11316
|
+
timeoutMs: num4(env2.ROBOT_FAULT_SWEEP_TIMEOUT_MS, 1e4, 1e3, 6e4),
|
|
11317
|
+
offlineAlertMinutes: num4(env2.ROBOT_OFFLINE_ALERT_MINUTES, 10, 1, 1440)
|
|
11315
11318
|
};
|
|
11316
11319
|
}
|
|
11317
11320
|
function withTimeout(promise, ms2, label2 = "Timed out") {
|
|
@@ -27119,7 +27122,7 @@ function usePersonRepo() {
|
|
|
27119
27122
|
}
|
|
27120
27123
|
async function pushVehicleById(id, plate, session) {
|
|
27121
27124
|
const { plateNumber, recNo } = plate;
|
|
27122
|
-
const
|
|
27125
|
+
const updatedAt2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
27123
27126
|
const _id = (0, import_node_server_utils64.toObjectId)(id);
|
|
27124
27127
|
try {
|
|
27125
27128
|
const updateExisting = await collection.updateOne(
|
|
@@ -27130,7 +27133,7 @@ function usePersonRepo() {
|
|
|
27130
27133
|
{
|
|
27131
27134
|
$set: {
|
|
27132
27135
|
"plates.$.recNo": recNo,
|
|
27133
|
-
updatedAt
|
|
27136
|
+
updatedAt: updatedAt2
|
|
27134
27137
|
}
|
|
27135
27138
|
},
|
|
27136
27139
|
{ session }
|
|
@@ -27146,7 +27149,7 @@ function usePersonRepo() {
|
|
|
27146
27149
|
}
|
|
27147
27150
|
},
|
|
27148
27151
|
$set: {
|
|
27149
|
-
updatedAt
|
|
27152
|
+
updatedAt: updatedAt2
|
|
27150
27153
|
}
|
|
27151
27154
|
},
|
|
27152
27155
|
{ session }
|
|
@@ -27157,7 +27160,7 @@ function usePersonRepo() {
|
|
|
27157
27160
|
}
|
|
27158
27161
|
}
|
|
27159
27162
|
async function pullVehicleByRecNo(recNo, scope, session) {
|
|
27160
|
-
const
|
|
27163
|
+
const updatedAt2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
27161
27164
|
const owner = scope?.peopleId ? (0, import_node_server_utils64.toObjectId)(scope.peopleId) : null;
|
|
27162
27165
|
const site = scope?.site ? (0, import_node_server_utils64.toObjectId)(scope.site) : null;
|
|
27163
27166
|
if (!owner && !site) {
|
|
@@ -27196,7 +27199,7 @@ function usePersonRepo() {
|
|
|
27196
27199
|
plates: match
|
|
27197
27200
|
},
|
|
27198
27201
|
$set: {
|
|
27199
|
-
updatedAt
|
|
27202
|
+
updatedAt: updatedAt2
|
|
27200
27203
|
}
|
|
27201
27204
|
},
|
|
27202
27205
|
{ session }
|
|
@@ -48418,7 +48421,7 @@ var MKeyLog = class {
|
|
|
48418
48421
|
organization = "",
|
|
48419
48422
|
serviceProvider = "",
|
|
48420
48423
|
createdAt = /* @__PURE__ */ new Date(),
|
|
48421
|
-
updatedAt = /* @__PURE__ */ new Date(),
|
|
48424
|
+
updatedAt: updatedAt2 = /* @__PURE__ */ new Date(),
|
|
48422
48425
|
template,
|
|
48423
48426
|
status = "Available",
|
|
48424
48427
|
updatedBy = "",
|
|
@@ -48439,7 +48442,7 @@ var MKeyLog = class {
|
|
|
48439
48442
|
this.organization = organization;
|
|
48440
48443
|
this.serviceProvider = serviceProvider;
|
|
48441
48444
|
this.createdAt = createdAt;
|
|
48442
|
-
this.updatedAt =
|
|
48445
|
+
this.updatedAt = updatedAt2;
|
|
48443
48446
|
this.template = template;
|
|
48444
48447
|
this.status = status;
|
|
48445
48448
|
this.updatedBy = updatedBy;
|
|
@@ -57078,7 +57081,7 @@ var MAccessCard = class {
|
|
|
57078
57081
|
isLiftCard,
|
|
57079
57082
|
liftAccessLevel,
|
|
57080
57083
|
createdAt,
|
|
57081
|
-
updatedAt,
|
|
57084
|
+
updatedAt: updatedAt2,
|
|
57082
57085
|
assignedUnit,
|
|
57083
57086
|
userType,
|
|
57084
57087
|
doorName,
|
|
@@ -57105,7 +57108,7 @@ var MAccessCard = class {
|
|
|
57105
57108
|
this.isLiftCard = isLiftCard;
|
|
57106
57109
|
this.liftAccessLevel = liftAccessLevel;
|
|
57107
57110
|
this.createdAt = createdAt;
|
|
57108
|
-
this.updatedAt =
|
|
57111
|
+
this.updatedAt = updatedAt2;
|
|
57109
57112
|
this.assignedUnit = assignedUnit;
|
|
57110
57113
|
this.userType = userType;
|
|
57111
57114
|
this.doorName = doorName;
|
|
@@ -57284,8 +57287,8 @@ function encryptPayload(payloadHex) {
|
|
|
57284
57287
|
);
|
|
57285
57288
|
return encrypted.toString("base64");
|
|
57286
57289
|
}
|
|
57287
|
-
function toHex(
|
|
57288
|
-
return
|
|
57290
|
+
function toHex(num4, length) {
|
|
57291
|
+
return num4.toString(16).padStart(length * 2, "0");
|
|
57289
57292
|
}
|
|
57290
57293
|
function buildPayload(cardNumber, validityMinutes) {
|
|
57291
57294
|
const randomHex = import_crypto5.default.randomBytes(2).toString("hex");
|
|
@@ -57465,8 +57468,8 @@ function UseAccessManagementRepo() {
|
|
|
57465
57468
|
}
|
|
57466
57469
|
}
|
|
57467
57470
|
function generateCardNo() {
|
|
57468
|
-
const
|
|
57469
|
-
return
|
|
57471
|
+
const num4 = Math.floor(Math.random() * 65536);
|
|
57472
|
+
return num4.toString().padStart(10, "0");
|
|
57470
57473
|
}
|
|
57471
57474
|
async function createQrData({
|
|
57472
57475
|
cardNumber,
|
|
@@ -58706,13 +58709,13 @@ function UseAccessManagementRepo() {
|
|
|
58706
58709
|
const prevCard = res && res?.[1]?.cardNo || "-1";
|
|
58707
58710
|
const currentCard = res && res?.[0]?.cardNo || "0";
|
|
58708
58711
|
let availableCardNo = [];
|
|
58709
|
-
let
|
|
58712
|
+
let num4 = parseInt(prevCard, 10) + 1;
|
|
58710
58713
|
while (availableCardNo.length < (unit.length > 0 ? unit.length : quantity)) {
|
|
58711
|
-
if (
|
|
58712
|
-
|
|
58714
|
+
if (num4 === parseInt(currentCard, 10)) {
|
|
58715
|
+
num4++;
|
|
58713
58716
|
}
|
|
58714
|
-
availableCardNo.push(
|
|
58715
|
-
|
|
58717
|
+
availableCardNo.push(num4);
|
|
58718
|
+
num4++;
|
|
58716
58719
|
}
|
|
58717
58720
|
const cardNumbers = availableCardNo.map(
|
|
58718
58721
|
(no2) => no2.toString().padStart(10, "0")
|
|
@@ -63949,7 +63952,9 @@ var ROBOT_CAPABILITIES = [
|
|
|
63949
63952
|
*/
|
|
63950
63953
|
"manualDrive",
|
|
63951
63954
|
/** A heat camera: alarm and patrol photos carry a thermal picture and temperatures. Reporting only. */
|
|
63952
|
-
"thermalCamera"
|
|
63955
|
+
"thermalCamera",
|
|
63956
|
+
/** A scrubber's clean/dirty water levels and whether its tanks and covers are fitted. Reporting only. */
|
|
63957
|
+
"waterTanks"
|
|
63953
63958
|
];
|
|
63954
63959
|
var TIER_REQUIREMENTS = {
|
|
63955
63960
|
"full-control": [
|
|
@@ -64431,13 +64436,13 @@ function parseRobotCommand(body) {
|
|
|
64431
64436
|
if (has2(k))
|
|
64432
64437
|
return { ok: false, message: `${k} is not valid for a ${kind} command.` };
|
|
64433
64438
|
}
|
|
64434
|
-
const
|
|
64435
|
-
if (!
|
|
64439
|
+
const num4 = (k) => typeof b[k] === "number" && Number.isFinite(b[k]);
|
|
64440
|
+
if (!num4("x") || !num4("y"))
|
|
64436
64441
|
return { ok: false, message: `${kind} needs x and y (metres).` };
|
|
64437
64442
|
if (kind === "navigate") {
|
|
64438
64443
|
if (has2("floorNo"))
|
|
64439
64444
|
return { ok: false, message: "floorNo is not valid for a navigate command." };
|
|
64440
|
-
if (has2("theta") && !
|
|
64445
|
+
if (has2("theta") && !num4("theta"))
|
|
64441
64446
|
return { ok: false, message: "theta must be a number (radians)." };
|
|
64442
64447
|
return {
|
|
64443
64448
|
ok: true,
|
|
@@ -64449,7 +64454,7 @@ function parseRobotCommand(body) {
|
|
|
64449
64454
|
}
|
|
64450
64455
|
};
|
|
64451
64456
|
}
|
|
64452
|
-
if (!
|
|
64457
|
+
if (!num4("theta"))
|
|
64453
64458
|
return { ok: false, message: "relocalize needs theta (radians)." };
|
|
64454
64459
|
if (!Number.isInteger(b.floorNo))
|
|
64455
64460
|
return { ok: false, message: "relocalize needs an integer floorNo." };
|
|
@@ -64849,6 +64854,8 @@ var OUNITECH_CAPABILITIES = {
|
|
|
64849
64854
|
battery: true,
|
|
64850
64855
|
// The chapter-6 robot list: `floorNo` (the robot's floor).
|
|
64851
64856
|
floorReporting: true,
|
|
64857
|
+
// robotState readings: clean-water / dirty-water (%), top-cover / tank / dust-box fitted.
|
|
64858
|
+
waterTanks: true,
|
|
64852
64859
|
// FALSE on purpose - each one is a question for the vendor.
|
|
64853
64860
|
navigateToPoint: false,
|
|
64854
64861
|
// app: "Move to Target Point"; API: robot-control actionNo not documented
|
|
@@ -64873,23 +64880,114 @@ var OUNITECH_CAPABILITIES = {
|
|
|
64873
64880
|
var OUNITECH_PENDING_COMMANDS = ["pause", "resume", "cancel"].map(
|
|
64874
64881
|
(kind) => ({ kind, reason: "awaiting Ounitech's robot-control action numbers" })
|
|
64875
64882
|
);
|
|
64876
|
-
function propertyNumber(row, key) {
|
|
64877
|
-
const p = row.robotState?.properties?.find((x) => x?.key === key);
|
|
64878
|
-
const n = p?.value != null && String(p.value).trim() !== "" ? Number(p.value) : NaN;
|
|
64879
|
-
return Number.isFinite(n) ? n : null;
|
|
64880
|
-
}
|
|
64881
64883
|
var finite = (v) => typeof v === "number" && Number.isFinite(v);
|
|
64882
|
-
function
|
|
64883
|
-
|
|
64884
|
-
|
|
64885
|
-
|
|
64884
|
+
function num(v) {
|
|
64885
|
+
if (finite(v))
|
|
64886
|
+
return v;
|
|
64887
|
+
if (typeof v === "string" && v.trim() !== "") {
|
|
64888
|
+
const n = Number(v);
|
|
64889
|
+
return Number.isFinite(n) ? n : void 0;
|
|
64890
|
+
}
|
|
64891
|
+
return void 0;
|
|
64892
|
+
}
|
|
64893
|
+
function reading(st, key) {
|
|
64894
|
+
const v = st.properties?.find((x) => x?.key === key)?.value;
|
|
64895
|
+
return v == null || String(v).trim() === "" ? void 0 : String(v).trim();
|
|
64896
|
+
}
|
|
64897
|
+
var OUNITECH_FRESH_MS = 3 * 6e4;
|
|
64898
|
+
var STATUS_CODE_BY_READING = {
|
|
64899
|
+
\u5F85\u673A: 1,
|
|
64900
|
+
\u7A7A\u95F2: 1,
|
|
64901
|
+
\u6E05\u626B\u4E2D: 2,
|
|
64902
|
+
\u5DE5\u4F5C\u4E2D: 2,
|
|
64903
|
+
\u6682\u505C: 3,
|
|
64904
|
+
\u6682\u505C\u4E2D: 3,
|
|
64905
|
+
\u5EFA\u56FE\u4E2D: 4,
|
|
64906
|
+
\u56DE\u5145\u4E2D: 6,
|
|
64907
|
+
\u8FD4\u56DE\u5145\u7535: 6,
|
|
64908
|
+
\u6545\u969C: 7,
|
|
64909
|
+
\u5F02\u5E38: 7,
|
|
64910
|
+
\u5145\u7535\u4E2D: 8,
|
|
64911
|
+
\u65AD\u70B9\u5145\u7535\u4E2D: 16,
|
|
64912
|
+
\u5DF2\u5145\u6EE1: 9,
|
|
64913
|
+
\u5145\u6EE1: 9,
|
|
64914
|
+
\u6025\u505C: 11,
|
|
64915
|
+
\u5173\u673A: 14,
|
|
64916
|
+
\u79BB\u7EBF: 99
|
|
64917
|
+
};
|
|
64918
|
+
var JOB_WORDS = {
|
|
64919
|
+
\u5DF2\u7ED3\u675F: "job finished",
|
|
64920
|
+
\u5DF2\u5B8C\u6210: "job finished",
|
|
64921
|
+
\u5B8C\u6210: "job finished",
|
|
64922
|
+
\u6E05\u626B\u4E2D: "job in progress",
|
|
64923
|
+
\u8FDB\u884C\u4E2D: "job in progress",
|
|
64924
|
+
\u6682\u505C: "job paused",
|
|
64925
|
+
\u6682\u505C\u4E2D: "job paused",
|
|
64926
|
+
\u672A\u5F00\u59CB: "no job started",
|
|
64927
|
+
\u5DF2\u53D6\u6D88: "job cancelled",
|
|
64928
|
+
\u53D6\u6D88: "job cancelled"
|
|
64929
|
+
};
|
|
64930
|
+
function ounitechJobWords(st) {
|
|
64931
|
+
const v = reading(st, "job");
|
|
64932
|
+
return v ? JOB_WORDS[v] ?? null : null;
|
|
64933
|
+
}
|
|
64934
|
+
var levelOf = (pct) => pct < 25 ? "low" : pct >= 75 ? "high" : "medium";
|
|
64935
|
+
var LEVEL_WORDS = { \u4F4E: "low", \u4E2D: "medium", \u9AD8: "high" };
|
|
64936
|
+
var PARTS = [
|
|
64937
|
+
["top-cover", "top cover"],
|
|
64938
|
+
["clean-water-tank", "clean-water tank"],
|
|
64939
|
+
["waste-water-tank", "dirty-water tank"],
|
|
64940
|
+
["dust-box", "dust box"]
|
|
64941
|
+
];
|
|
64942
|
+
function ounitechCleaning(st, working, taskPercent) {
|
|
64943
|
+
const water = (pctKey, levelKey) => {
|
|
64944
|
+
const pct2 = num(reading(st, pctKey));
|
|
64945
|
+
if (pct2 !== void 0 && pct2 >= 0 && pct2 <= 100)
|
|
64946
|
+
return { level: levelOf(pct2), percent: Math.round(pct2) };
|
|
64947
|
+
const word = LEVEL_WORDS[reading(st, levelKey) ?? ""];
|
|
64948
|
+
return word ? { level: word, percent: null } : null;
|
|
64949
|
+
};
|
|
64950
|
+
const cleanWater = water("clean-water", "clean-water-level");
|
|
64951
|
+
const dirtyWater = water("dirty-water", "dirty-water-level");
|
|
64952
|
+
const parts = PARTS.flatMap(([key, part]) => {
|
|
64953
|
+
const v = reading(st, key)?.toLowerCase();
|
|
64954
|
+
return v === "true" || v === "1" ? [{ part, ok: true }] : v === "false" || v === "0" ? [{ part, ok: false }] : [];
|
|
64955
|
+
});
|
|
64956
|
+
const area = (k) => {
|
|
64957
|
+
const n = num(reading(st, k));
|
|
64958
|
+
return n !== void 0 && n > 0 ? Math.round(n * 10) / 10 : null;
|
|
64959
|
+
};
|
|
64960
|
+
const pct = num(reading(st, "acc-percent")) ?? (finite(taskPercent) ? taskPercent : void 0);
|
|
64961
|
+
const job = working ? { percent: pct !== void 0 && pct >= 0 && pct <= 100 ? Math.round(pct) : null, areaDone: area("acc-area"), areaPlanned: area("count-area") } : null;
|
|
64962
|
+
const hasJob = !!job && (job.percent !== null || job.areaDone !== null);
|
|
64963
|
+
if (!cleanWater && !dirtyWater && !parts.length && !hasJob)
|
|
64964
|
+
return null;
|
|
64965
|
+
return { cleanWater, dirtyWater, parts, job: hasJob ? job : null };
|
|
64966
|
+
}
|
|
64967
|
+
function updatedAt(v) {
|
|
64968
|
+
const n = num(v);
|
|
64969
|
+
if (n !== void 0)
|
|
64970
|
+
return n < 1e12 ? n * 1e3 : n;
|
|
64971
|
+
const t = typeof v === "string" ? Date.parse(v) : NaN;
|
|
64972
|
+
return Number.isFinite(t) ? t : null;
|
|
64973
|
+
}
|
|
64974
|
+
function ounitechRobotFromHomeRow(row, live2, now = Date.now()) {
|
|
64975
|
+
const listed = row.robotState ?? {};
|
|
64976
|
+
const st = live2 ? { ...listed, ...live2, properties: live2.properties?.length ? live2.properties : listed.properties } : listed;
|
|
64977
|
+
const statusReading = reading(st, "status");
|
|
64978
|
+
const flag = num(st.statusFlag) ?? (statusReading ? STATUS_CODE_BY_READING[statusReading] : void 0);
|
|
64979
|
+
const at2 = updatedAt(st.updateOn);
|
|
64980
|
+
const fresh = at2 !== null && now - at2 <= OUNITECH_FRESH_MS;
|
|
64981
|
+
const online = flag !== 99 && (flag !== void 0 || fresh);
|
|
64886
64982
|
const mode = online ? robotMode(flag) : "UNAVAILABLE";
|
|
64887
|
-
const pct =
|
|
64983
|
+
const pct = num(reading(st, "battery-percent")) ?? num(st.battery) ?? null;
|
|
64888
64984
|
const task = row.taskState;
|
|
64889
64985
|
const jobPct = task && String(task.statusFlag) === "1" && finite(task.accPercent) ? Math.round(task.accPercent) : null;
|
|
64890
|
-
const words = flag
|
|
64986
|
+
const words = flag !== void 0 ? ROBOT_STATUS_NAMES[flag] ?? `Status ${flag}` : online ? "Online - status not reported" : "Unknown";
|
|
64891
64987
|
const model = String(row.modelCode || row.modelName || "").trim().slice(0, 40);
|
|
64892
|
-
|
|
64988
|
+
const x = num(st.x);
|
|
64989
|
+
const y = num(st.y);
|
|
64990
|
+
const robot = {
|
|
64893
64991
|
robotSn: row.robotSn,
|
|
64894
64992
|
name: row.aliasName || row.robotName,
|
|
64895
64993
|
...model ? { model } : {},
|
|
@@ -64899,8 +64997,19 @@ function ounitechRobotFromHomeRow(row) {
|
|
|
64899
64997
|
batteryPercent: online && pct !== null && pct >= 0 && pct <= 100 ? Math.round(pct) : null,
|
|
64900
64998
|
floorNo: Number.isInteger(row.floorNo) ? row.floorNo : null,
|
|
64901
64999
|
floorKnown: Number.isInteger(row.floorNo),
|
|
64902
|
-
position: online &&
|
|
65000
|
+
position: online && x !== void 0 && y !== void 0 ? { x, y, theta: num(st.theta) ?? 0 } : null
|
|
64903
65001
|
};
|
|
65002
|
+
if (online) {
|
|
65003
|
+
robot.cleaning = ounitechCleaning(st, mode === "WORKING", task && String(task.statusFlag) === "1" ? task.accPercent : null);
|
|
65004
|
+
}
|
|
65005
|
+
if (online && (flag === 7 || Array.isArray(st.rtFaultList) && st.rtFaultList.length)) {
|
|
65006
|
+
robot.fault = ounitechFault(st.rtFaultList);
|
|
65007
|
+
}
|
|
65008
|
+
return robot;
|
|
65009
|
+
}
|
|
65010
|
+
function needsLiveState(row) {
|
|
65011
|
+
const f = num(row.robotState?.statusFlag);
|
|
65012
|
+
return finite(row.robotId) && (f === void 0 || f === 99 || f === 7);
|
|
64904
65013
|
}
|
|
64905
65014
|
function ounitechFault(list) {
|
|
64906
65015
|
const f = Array.isArray(list) ? list[0] : null;
|
|
@@ -64917,6 +65026,9 @@ function ounitechFault(list) {
|
|
|
64917
65026
|
var robotTime = (d) => robotCloudTimestamp(d, "yyyy-MM-dd HH:mm:ss", "Asia/Shanghai");
|
|
64918
65027
|
function createOunitechAdapter(credentials, options) {
|
|
64919
65028
|
const cloud = useRobotCloudService(credentials, options);
|
|
65029
|
+
async function liveFor(row) {
|
|
65030
|
+
return needsLiveState(row) ? cloud.getRobotState(row.robotId).catch(() => null) : null;
|
|
65031
|
+
}
|
|
64920
65032
|
async function rowFor(robotSn) {
|
|
64921
65033
|
return (await cloud.getHomeRobots()).find((r) => r.robotSn === robotSn) ?? null;
|
|
64922
65034
|
}
|
|
@@ -64925,7 +65037,7 @@ function createOunitechAdapter(credentials, options) {
|
|
|
64925
65037
|
displayName: "Ounitech (Q3-G / Q3-W)",
|
|
64926
65038
|
capabilities: OUNITECH_CAPABILITIES,
|
|
64927
65039
|
async listRobots() {
|
|
64928
|
-
return (await cloud.getHomeRobots()).map(ounitechRobotFromHomeRow);
|
|
65040
|
+
return Promise.all((await cloud.getHomeRobots()).map(async (row) => ounitechRobotFromHomeRow(row, await liveFor(row))));
|
|
64929
65041
|
},
|
|
64930
65042
|
async getRobot(robotSn) {
|
|
64931
65043
|
const row = await rowFor(robotSn);
|
|
@@ -64941,12 +65053,7 @@ function createOunitechAdapter(credentials, options) {
|
|
|
64941
65053
|
position: null
|
|
64942
65054
|
};
|
|
64943
65055
|
}
|
|
64944
|
-
|
|
64945
|
-
if (row.robotState?.statusFlag === 7 && finite(row.robotId)) {
|
|
64946
|
-
const state = await cloud.getRobotState(row.robotId).catch(() => null);
|
|
64947
|
-
robot.fault = ounitechFault(state?.rtFaultList);
|
|
64948
|
-
}
|
|
64949
|
-
return robot;
|
|
65056
|
+
return ounitechRobotFromHomeRow(row, await liveFor(row));
|
|
64950
65057
|
},
|
|
64951
65058
|
async sendCommand(robotSn, command) {
|
|
64952
65059
|
const options2 = {
|
|
@@ -65061,10 +65168,19 @@ function createOunitechAdapter(credentials, options) {
|
|
|
65061
65168
|
const window = { timeFrom: robotTime(from), timeTo: robotTime(to) };
|
|
65062
65169
|
await run("live state (get-robot-state-v2.0)", ROBOT_CLOUD_PATHS.robotState, { robotId }, async () => {
|
|
65063
65170
|
const s = await cloud.getRobotState(robotId);
|
|
65171
|
+
const r = ounitechRobotFromHomeRow(row, s);
|
|
65172
|
+
const level2 = (...keys) => keys.map((k) => num(reading(s, k))).find((n) => n !== void 0) ?? null;
|
|
65173
|
+
const at2 = updatedAt(s.updateOn);
|
|
65064
65174
|
return {
|
|
65175
|
+
online: r.online,
|
|
65176
|
+
status: r.statusName,
|
|
65177
|
+
job: ounitechJobWords(s),
|
|
65178
|
+
battery: r.batteryPercent,
|
|
65179
|
+
cleanWater: level2("clean-water", "clean-percent"),
|
|
65180
|
+
dirtyWater: level2("dirty-water", "dirty-percent"),
|
|
65181
|
+
fault: r.fault ?? null,
|
|
65065
65182
|
statusFlag: s.statusFlag,
|
|
65066
|
-
|
|
65067
|
-
updateOn: s.updateOn ? new Date(s.updateOn).toISOString() : null,
|
|
65183
|
+
updateOn: at2 !== null ? new Date(at2).toISOString() : null,
|
|
65068
65184
|
x: s.x,
|
|
65069
65185
|
y: s.y,
|
|
65070
65186
|
theta: s.theta,
|
|
@@ -66996,7 +67112,7 @@ function statesByType(entry) {
|
|
|
66996
67112
|
}
|
|
66997
67113
|
var PADBOT_ONLINE_WINDOW_MS = 12e4;
|
|
66998
67114
|
var ms = (t) => typeof t === "string" ? Date.parse(t) : NaN;
|
|
66999
|
-
var
|
|
67115
|
+
var num2 = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
67000
67116
|
function padbotMode(states, now = Date.now()) {
|
|
67001
67117
|
const hb = ms(states["1000"]?.updatedAt);
|
|
67002
67118
|
const online = Number.isFinite(hb) && now - hb <= PADBOT_ONLINE_WINDOW_MS;
|
|
@@ -67004,7 +67120,7 @@ function padbotMode(states, now = Date.now()) {
|
|
|
67004
67120
|
return { online: false, mode: "UNAVAILABLE", statusName: "Not reporting to PadBot" };
|
|
67005
67121
|
const nav = states["1003"] ?? {};
|
|
67006
67122
|
const work = states["1010"] ?? {};
|
|
67007
|
-
const battery =
|
|
67123
|
+
const battery = num2(states["1001"]?.batteryPercent);
|
|
67008
67124
|
const charging = states["1002"]?.chargingState === 1;
|
|
67009
67125
|
const type = Number(nav.actionType) || 0;
|
|
67010
67126
|
const st = Number(nav.actionState) || 0;
|
|
@@ -67041,7 +67157,7 @@ function padbotCommandBlock(states, kind, now = Date.now()) {
|
|
|
67041
67157
|
return "The robot is not reporting to PadBot, so it cannot take a command. Check it is switched on and connected.";
|
|
67042
67158
|
if (states["1006"]?.emergencyStopState === 1)
|
|
67043
67159
|
return "The robot's emergency stop button is pressed. Release the red button on the robot, then try again.";
|
|
67044
|
-
const battery =
|
|
67160
|
+
const battery = num2(states["1001"]?.batteryPercent);
|
|
67045
67161
|
if (kind !== "return" && battery !== null && battery < 10)
|
|
67046
67162
|
return `The battery is at ${battery}%. PadBot robots do not start jobs under 10%; send it to charge first.`;
|
|
67047
67163
|
if (kind === "return" && [1, 2].includes(states["1002"]?.chargingState))
|
|
@@ -67063,7 +67179,7 @@ function padbotReadiness(states, now = Date.now()) {
|
|
|
67063
67179
|
heartbeatAt: st["1000"]?.updatedAt ?? null,
|
|
67064
67180
|
emergencyStopPressed: es.emergencyStopState === 1,
|
|
67065
67181
|
wheelLockState: es.wheelLockState ?? null,
|
|
67066
|
-
batteryPercent:
|
|
67182
|
+
batteryPercent: num2(st["1001"]?.batteryPercent),
|
|
67067
67183
|
chargingState: charging ?? null,
|
|
67068
67184
|
map: { id: st["1007"]?.mapId ?? null, name: st["1007"]?.mapDisplayName ?? null, floor: st["1007"]?.floor ?? null },
|
|
67069
67185
|
navigation: { actionType: nav.actionType ?? null, actionState: nav.actionState ?? null, message: nav.message ?? null, updatedAt: nav.updatedAt ?? null },
|
|
@@ -67120,19 +67236,19 @@ function padbotMotion(m, now) {
|
|
|
67120
67236
|
}
|
|
67121
67237
|
function networkText(net) {
|
|
67122
67238
|
const say = (label2, v) => v < 0 ? ` \xB7 ${label2} ${v} dBm` : ` \xB7 ${label2} signal ${v}`;
|
|
67123
|
-
const wifi =
|
|
67239
|
+
const wifi = num2(net?.wifi?.signalStrength);
|
|
67124
67240
|
if (wifi !== null)
|
|
67125
67241
|
return say("Wi-Fi", wifi);
|
|
67126
|
-
const cell =
|
|
67242
|
+
const cell = num2(net?.cellular?.signalStrength);
|
|
67127
67243
|
return cell !== null ? say("Mobile", cell) : "";
|
|
67128
67244
|
}
|
|
67129
67245
|
function padbotPlanShare(frame2, x, y) {
|
|
67130
|
-
const w =
|
|
67131
|
-
const wx =
|
|
67246
|
+
const w = num2(frame2?.width), h = num2(frame2?.height), r = num2(frame2?.resolution);
|
|
67247
|
+
const wx = num2(x), wy = num2(y);
|
|
67132
67248
|
if (!w || !h || !r || r <= 0 || wx === null || wy === null)
|
|
67133
67249
|
return null;
|
|
67134
|
-
const px = (wx - (
|
|
67135
|
-
const pyUp = (wy - (
|
|
67250
|
+
const px = (wx - (num2(frame2?.originX) ?? 0)) / r;
|
|
67251
|
+
const pyUp = (wy - (num2(frame2?.originY) ?? 0)) / r;
|
|
67136
67252
|
const sx = px / w * 100, sy = 100 - pyUp / h * 100;
|
|
67137
67253
|
if (sx < 0 || sx > 100 || sy < 0 || sy > 100)
|
|
67138
67254
|
return null;
|
|
@@ -67162,9 +67278,9 @@ function padbotCurrentMap(maps, ids2, floor) {
|
|
|
67162
67278
|
}
|
|
67163
67279
|
function padbotChargingPoint(map) {
|
|
67164
67280
|
const piles = (Array.isArray(map?.targetPoints) ? map.targetPoints : []).filter(
|
|
67165
|
-
(t) => Number(t?.targetPointType) === 10 &&
|
|
67281
|
+
(t) => Number(t?.targetPointType) === 10 && num2(t?.worldX) !== null && num2(t?.worldY) !== null
|
|
67166
67282
|
);
|
|
67167
|
-
return piles.length === 1 ? { worldX:
|
|
67283
|
+
return piles.length === 1 ? { worldX: num2(piles[0].worldX), worldY: num2(piles[0].worldY), yaw: piles[0].yaw } : null;
|
|
67168
67284
|
}
|
|
67169
67285
|
var PADBOT_OTHER_MAP_TEXT = "The robot must be on this map first.";
|
|
67170
67286
|
function padbotAlarmFault(alarm) {
|
|
@@ -67259,9 +67375,9 @@ function padbotPatrolRecord(r) {
|
|
|
67259
67375
|
result: PATROL_RESULT[r?.completionState] ?? "unknown",
|
|
67260
67376
|
startedAt: r?.startedAt ?? null,
|
|
67261
67377
|
endedAt: r?.endedAt ?? null,
|
|
67262
|
-
durationS:
|
|
67263
|
-
distanceM:
|
|
67264
|
-
alarmCount:
|
|
67378
|
+
durationS: num2(r?.duration),
|
|
67379
|
+
distanceM: num2(r?.mileage),
|
|
67380
|
+
alarmCount: num2(r?.alarmCount) ?? 0
|
|
67265
67381
|
};
|
|
67266
67382
|
}
|
|
67267
67383
|
function padbotCheckpointVisit(d) {
|
|
@@ -67271,15 +67387,15 @@ function padbotCheckpointVisit(d) {
|
|
|
67271
67387
|
skipped: d?.skipped === true,
|
|
67272
67388
|
imageUrl: d?.visibleLightImageUrl ?? null,
|
|
67273
67389
|
thermalImageUrl: d?.thermalImageUrl ?? null,
|
|
67274
|
-
centerTempC:
|
|
67275
|
-
maxTempC:
|
|
67390
|
+
centerTempC: num2(d?.centerTemperature),
|
|
67391
|
+
maxTempC: num2(d?.maxTemperature)
|
|
67276
67392
|
};
|
|
67277
67393
|
}
|
|
67278
67394
|
var asList = (d) => Array.isArray(d) ? d : Array.isArray(d?.items) ? d.items : Array.isArray(d?.list) ? d.list : Array.isArray(d?.records) ? d.records : [];
|
|
67279
67395
|
var page = (data, map) => ({
|
|
67280
67396
|
items: (Array.isArray(data?.items) ? data.items : []).map(map),
|
|
67281
|
-
total:
|
|
67282
|
-
pages:
|
|
67397
|
+
total: num2(data?.totalItems) ?? 0,
|
|
67398
|
+
pages: num2(data?.totalPages) ?? 0
|
|
67283
67399
|
});
|
|
67284
67400
|
function createPadbotClient(credentials, options = {}) {
|
|
67285
67401
|
const baseUrl = (options.baseUrl ?? padbotBaseUrl()).replace(/\/+$/, "");
|
|
@@ -67501,7 +67617,7 @@ function createPadbotAdapter(credentials, options = {}) {
|
|
|
67501
67617
|
const { online, mode, statusName } = padbotMode(st, now());
|
|
67502
67618
|
const floor = st["1007"]?.floor;
|
|
67503
67619
|
const restBatteryAt = ms(st["1001"]?.updatedAt);
|
|
67504
|
-
const battery = heard?.batteryPercent !== void 0 && (!Number.isFinite(restBatteryAt) || (heard.batteryAt ?? 0) > restBatteryAt) ? heard.batteryPercent :
|
|
67620
|
+
const battery = heard?.batteryPercent !== void 0 && (!Number.isFinite(restBatteryAt) || (heard.batteryAt ?? 0) > restBatteryAt) ? heard.batteryPercent : num2(st["1001"]?.batteryPercent);
|
|
67505
67621
|
const failed = lastFailure.get(`${account}:${robotSn}`);
|
|
67506
67622
|
const showFailure = online && failed && now() - failed.at < PADBOT_FAILURE_SHOW_MS && /^(Standing by|Charging)/.test(statusName);
|
|
67507
67623
|
const robot = {
|
|
@@ -67528,15 +67644,15 @@ function createPadbotAdapter(credentials, options = {}) {
|
|
|
67528
67644
|
return robot;
|
|
67529
67645
|
const [loc, openA] = await Promise.all([locRead, alarmRead]);
|
|
67530
67646
|
const alarm = robot.fault ? null : openA;
|
|
67531
|
-
const lx =
|
|
67532
|
-
const ly =
|
|
67647
|
+
const lx = num2(loc?.worldX ?? loc?.x);
|
|
67648
|
+
const ly = num2(loc?.worldY ?? loc?.y);
|
|
67533
67649
|
if (typeof loc?.mapId === "string" && loc.mapId)
|
|
67534
67650
|
robot.mapId = loc.mapId;
|
|
67535
67651
|
const map = await maps(robotSn).then((all) => padbotCurrentMap(all, [robot.mapId, st["1007"]?.mapId], robot.floorNo)).catch(() => null);
|
|
67536
67652
|
if (map)
|
|
67537
67653
|
robot.mapId = map.mapId;
|
|
67538
67654
|
if (lx !== null && ly !== null) {
|
|
67539
|
-
robot.position = { x: lx, y: ly, theta: (
|
|
67655
|
+
robot.position = { x: lx, y: ly, theta: (num2(loc.yaw ?? loc.r) ?? 0) * Math.PI / 180 };
|
|
67540
67656
|
robot.planPosition = padbotPlanShare(map, lx, ly);
|
|
67541
67657
|
}
|
|
67542
67658
|
const mo = motions.get(`${account}:${robotSn}`);
|
|
@@ -67556,7 +67672,7 @@ function createPadbotAdapter(credentials, options = {}) {
|
|
|
67556
67672
|
const onCharger = [1, 2].includes(st["1002"]?.chargingState);
|
|
67557
67673
|
const pile = onCharger && !robot.position ? padbotChargingPoint(map) : null;
|
|
67558
67674
|
if (pile) {
|
|
67559
|
-
robot.position = { x: pile.worldX, y: pile.worldY, theta: (
|
|
67675
|
+
robot.position = { x: pile.worldX, y: pile.worldY, theta: (num2(pile.yaw) ?? 0) * Math.PI / 180 };
|
|
67560
67676
|
robot.planPosition = padbotPlanShare(map, pile.worldX, pile.worldY);
|
|
67561
67677
|
if (!going || going.done)
|
|
67562
67678
|
robot.statusName = `${robot.statusName} \xB7 At charger`;
|
|
@@ -67656,12 +67772,12 @@ function createPadbotAdapter(credentials, options = {}) {
|
|
|
67656
67772
|
throw new import_node_server_utils164.BadRequestError(block);
|
|
67657
67773
|
lastFailure.delete(`${account}:${robotSn}`);
|
|
67658
67774
|
const heard = padbotLive(account, robotSn)?.pose;
|
|
67659
|
-
const lx =
|
|
67660
|
-
const ly =
|
|
67775
|
+
const lx = num2(where?.loc?.worldX);
|
|
67776
|
+
const ly = num2(where?.loc?.worldY);
|
|
67661
67777
|
let target = null;
|
|
67662
67778
|
if (command.kind === "go-to-point") {
|
|
67663
67779
|
const pt = (where?.all ?? []).flatMap((m) => Array.isArray(m?.targetPoints) ? m.targetPoints : []).find((t) => t?.targetPointId === command.targetPointId);
|
|
67664
|
-
target = { name: String(pt?.name || "the chosen point"), x:
|
|
67780
|
+
target = { name: String(pt?.name || "the chosen point"), x: num2(pt?.worldX), y: num2(pt?.worldY) };
|
|
67665
67781
|
}
|
|
67666
67782
|
motion = {
|
|
67667
67783
|
kind: command.kind,
|
|
@@ -67880,6 +67996,7 @@ function fleetStateItem(id, s, lastSeenAt) {
|
|
|
67880
67996
|
fault: s.fault,
|
|
67881
67997
|
capabilities: s.capabilities,
|
|
67882
67998
|
profile: s.profile,
|
|
67999
|
+
cleaning: s.cleaning ?? null,
|
|
67883
68000
|
lastSeenAt: lastSeenAt ? new Date(lastSeenAt) : null
|
|
67884
68001
|
};
|
|
67885
68002
|
}
|
|
@@ -68008,7 +68125,8 @@ function useRobotFleetService(deps) {
|
|
|
68008
68125
|
planPosition: found.planPosition ?? null,
|
|
68009
68126
|
fault,
|
|
68010
68127
|
capabilities: manifest.capabilities,
|
|
68011
|
-
profile: manifest.profile
|
|
68128
|
+
profile: manifest.profile,
|
|
68129
|
+
cleaning: manifest.capabilities.waterTanks === true && found.online ? found.cleaning ?? null : null
|
|
68012
68130
|
};
|
|
68013
68131
|
}
|
|
68014
68132
|
async function getMaps(robot) {
|
|
@@ -68713,11 +68831,11 @@ function decodeTrackingFrame(data) {
|
|
|
68713
68831
|
if (!parsed || typeof parsed !== "object")
|
|
68714
68832
|
return null;
|
|
68715
68833
|
const frame2 = parsed;
|
|
68716
|
-
const
|
|
68717
|
-
const x =
|
|
68718
|
-
const y =
|
|
68719
|
-
const theta =
|
|
68720
|
-
const statusFlag =
|
|
68834
|
+
const num4 = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
68835
|
+
const x = num4(frame2.x);
|
|
68836
|
+
const y = num4(frame2.y);
|
|
68837
|
+
const theta = num4(frame2.theta);
|
|
68838
|
+
const statusFlag = num4(frame2.status);
|
|
68721
68839
|
if (x === null || y === null || theta === null || statusFlag === null) {
|
|
68722
68840
|
return null;
|
|
68723
68841
|
}
|
|
@@ -69241,22 +69359,22 @@ function useRobotFaultSweep(deps) {
|
|
|
69241
69359
|
if (!robot)
|
|
69242
69360
|
return;
|
|
69243
69361
|
out.robots++;
|
|
69244
|
-
let
|
|
69362
|
+
let reading2;
|
|
69245
69363
|
try {
|
|
69246
69364
|
const state = deps?.readState ? await deps.readState(robot) : await readRobotState(robot, { timeoutMs: cfg.timeoutMs });
|
|
69247
69365
|
if (deps?.readState)
|
|
69248
69366
|
rememberRobotState(robot, state);
|
|
69249
|
-
|
|
69250
|
-
if (
|
|
69251
|
-
Object.assign(
|
|
69367
|
+
reading2 = { ok: true, online: state.online === true, fault: state.fault ?? null };
|
|
69368
|
+
if (reading2.fault)
|
|
69369
|
+
Object.assign(reading2.fault, { floorNo: state.floorNo ?? null });
|
|
69252
69370
|
} catch (error) {
|
|
69253
69371
|
if (deps?.readState)
|
|
69254
69372
|
rememberRobotState(robot, null);
|
|
69255
|
-
|
|
69373
|
+
reading2 = { ok: false, error: error?.message ?? "no answer" };
|
|
69256
69374
|
}
|
|
69257
69375
|
const records = byRobot2.get(String(robot._id)) ?? [];
|
|
69258
69376
|
const offlineRec = records.find((r) => r.code === OFFLINE_FAULT_CODE);
|
|
69259
|
-
const plan = planFaultChanges(records,
|
|
69377
|
+
const plan = planFaultChanges(records, reading2);
|
|
69260
69378
|
for (const id of plan.clear) {
|
|
69261
69379
|
await repo.clearFault(id);
|
|
69262
69380
|
out.cleared++;
|
|
@@ -69269,7 +69387,7 @@ function useRobotFaultSweep(deps) {
|
|
|
69269
69387
|
out.alerts++;
|
|
69270
69388
|
}
|
|
69271
69389
|
for (const f of plan.open) {
|
|
69272
|
-
const detail =
|
|
69390
|
+
const detail = reading2.ok && reading2.fault?.code === f.code ? reading2.fault : null;
|
|
69273
69391
|
const r = await openFaultRecord(robot, detail ? { ...detail, ...f } : f, { notify: true, notifyFn: deps?.notifyFn });
|
|
69274
69392
|
if (r.opened)
|
|
69275
69393
|
out.opened++;
|
|
@@ -70587,7 +70705,7 @@ function measurementScale(vertices, meas) {
|
|
|
70587
70705
|
return est.length ? est.reduce((n, v) => n + v, 0) / est.length : null;
|
|
70588
70706
|
}
|
|
70589
70707
|
var pval = (p) => Array.isArray(p) ? p[1] : p;
|
|
70590
|
-
var
|
|
70708
|
+
var num3 = (v, fallback = 0) => v !== null && v !== "" && Number.isFinite(Number(v)) ? Number(v) : fallback;
|
|
70591
70709
|
var str60 = (v) => String(v ?? "").slice(0, 60);
|
|
70592
70710
|
function decodeParams(raw) {
|
|
70593
70711
|
const out = {};
|
|
@@ -70607,7 +70725,7 @@ function fileVertexParams(raw) {
|
|
|
70607
70725
|
const v = raw[k];
|
|
70608
70726
|
if (v === void 0 || v === null)
|
|
70609
70727
|
continue;
|
|
70610
|
-
out[k] = k.startsWith("is_") ? Boolean(v) : k === "merge_radius" ? clamp3(
|
|
70728
|
+
out[k] = k.startsWith("is_") ? Boolean(v) : k === "merge_radius" ? clamp3(num3(v), 0, 100) : str60(v);
|
|
70611
70729
|
}
|
|
70612
70730
|
return out;
|
|
70613
70731
|
}
|
|
@@ -70680,14 +70798,14 @@ function fromBuildingYaml(doc) {
|
|
|
70680
70798
|
const raw = names.map((name) => {
|
|
70681
70799
|
const y = doc.levels[name] ?? {};
|
|
70682
70800
|
const vertices = (Array.isArray(y.vertices) ? y.vertices : []).map((v) => ({
|
|
70683
|
-
x:
|
|
70684
|
-
y:
|
|
70801
|
+
x: num3(v?.[0]),
|
|
70802
|
+
y: num3(v?.[1]) * flip,
|
|
70685
70803
|
name: str60(v?.[3]),
|
|
70686
70804
|
params: fileVertexParams(decodeParams(v?.[4]))
|
|
70687
70805
|
}));
|
|
70688
|
-
const fiducials = (Array.isArray(y.fiducials) ? y.fiducials : []).map((f) => ({ x:
|
|
70689
|
-
const meas = edgeList(y.measurements).map((e) => [e.a, e.b,
|
|
70690
|
-
return { name: str60(name), y, vertices, fiducials, meas, elevation:
|
|
70806
|
+
const fiducials = (Array.isArray(y.fiducials) ? y.fiducials : []).map((f) => ({ x: num3(f?.[0]), y: num3(f?.[1]) * flip, name: str60(f?.[2]) }));
|
|
70807
|
+
const meas = edgeList(y.measurements).map((e) => [e.a, e.b, num3(e.p.distance)]);
|
|
70808
|
+
return { name: str60(name), y, vertices, fiducials, meas, elevation: num3(y.elevation) };
|
|
70691
70809
|
});
|
|
70692
70810
|
const refName = raw.some((l) => l.name === doc.reference_level_name) ? String(doc.reference_level_name) : raw[0].name;
|
|
70693
70811
|
const ref = raw.find((l) => l.name === refName);
|
|
@@ -70761,20 +70879,20 @@ function fromBuildingYaml(doc) {
|
|
|
70761
70879
|
const extra = {};
|
|
70762
70880
|
if (e.p.texture_name !== void 0 && e.p.texture_name !== "default")
|
|
70763
70881
|
extra.textureName = str60(e.p.texture_name);
|
|
70764
|
-
if (e.p.alpha !== void 0 &&
|
|
70765
|
-
extra.alpha = clamp3(
|
|
70766
|
-
if (e.p.texture_height !== void 0 &&
|
|
70767
|
-
extra.textureHeight = clamp3(
|
|
70768
|
-
if (e.p.texture_width !== void 0 &&
|
|
70769
|
-
extra.textureWidth = clamp3(
|
|
70770
|
-
if (e.p.texture_scale !== void 0 &&
|
|
70771
|
-
extra.textureScale = clamp3(
|
|
70882
|
+
if (e.p.alpha !== void 0 && num3(e.p.alpha, 1) !== 1)
|
|
70883
|
+
extra.alpha = clamp3(num3(e.p.alpha, 1), 0, 1);
|
|
70884
|
+
if (e.p.texture_height !== void 0 && num3(e.p.texture_height, 2.5) !== 2.5)
|
|
70885
|
+
extra.textureHeight = clamp3(num3(e.p.texture_height, 2.5), 0, 100);
|
|
70886
|
+
if (e.p.texture_width !== void 0 && num3(e.p.texture_width, 1) !== 1)
|
|
70887
|
+
extra.textureWidth = clamp3(num3(e.p.texture_width, 1), 0, 100);
|
|
70888
|
+
if (e.p.texture_scale !== void 0 && num3(e.p.texture_scale, 1) !== 1)
|
|
70889
|
+
extra.textureScale = clamp3(num3(e.p.texture_scale, 1), 0, 100);
|
|
70772
70890
|
level2.walls.push({ v1: ids2[e.a], v2: ids2[e.b], ...extra });
|
|
70773
70891
|
}
|
|
70774
70892
|
for (const e of edgeList(lv.y.doors).filter(ok)) {
|
|
70775
70893
|
const type = String(e.p.type ?? "hinged");
|
|
70776
|
-
const degrees = clamp3(
|
|
70777
|
-
const ratio = clamp3(
|
|
70894
|
+
const degrees = clamp3(num3(e.p.motion_degrees, 90), -360, 360);
|
|
70895
|
+
const ratio = clamp3(num3(e.p.right_left_ratio, 1), 0, 10);
|
|
70778
70896
|
const plugin = str60(e.p.plugin ?? "normal");
|
|
70779
70897
|
level2.doors.push({
|
|
70780
70898
|
name: str60(e.p.name ?? "").trim() || `door_${level2.doors.length + 1}`,
|
|
@@ -70783,13 +70901,13 @@ function fromBuildingYaml(doc) {
|
|
|
70783
70901
|
type: ["hinged", "double_hinged", "sliding", "double_sliding"].includes(type) ? type : "hinged",
|
|
70784
70902
|
...e.p.motion_axis === "end" ? { motionAxis: "end" } : {},
|
|
70785
70903
|
...degrees !== 90 ? { motionDegrees: degrees } : {},
|
|
70786
|
-
...
|
|
70904
|
+
...num3(e.p.motion_direction, 1) < 0 ? { motionDirection: -1 } : {},
|
|
70787
70905
|
...ratio !== 1 ? { rightLeftRatio: ratio } : {},
|
|
70788
70906
|
...plugin !== "normal" ? { plugin } : {}
|
|
70789
70907
|
});
|
|
70790
70908
|
}
|
|
70791
70909
|
for (const e of edgeList(lv.y.lanes).filter(ok)) {
|
|
70792
|
-
const gi = Math.round(
|
|
70910
|
+
const gi = Math.round(num3(e.p.graph_idx, 0));
|
|
70793
70911
|
if (gi < 0 || gi > 8) {
|
|
70794
70912
|
warnings.push(`Floor ${lv.name}: a lane on graph ${gi} was skipped (graphs 0-8 only).`);
|
|
70795
70913
|
continue;
|
|
@@ -70802,14 +70920,14 @@ function fromBuildingYaml(doc) {
|
|
|
70802
70920
|
graphIdx: gi,
|
|
70803
70921
|
bidirectional: e.p.bidirectional === true,
|
|
70804
70922
|
...orientation ? { orientation } : {},
|
|
70805
|
-
...
|
|
70923
|
+
...num3(e.p.speed_limit) > 0 ? { speedLimit: clamp3(num3(e.p.speed_limit), 0, 20) } : {},
|
|
70806
70924
|
...e.p.mutex ? { mutex: str60(e.p.mutex) } : {},
|
|
70807
70925
|
...e.p.demo_mock_floor_name ? { demoMockFloorName: str60(e.p.demo_mock_floor_name) } : {},
|
|
70808
70926
|
...e.p.demo_mock_lift_name ? { demoMockLiftName: str60(e.p.demo_mock_lift_name) } : {}
|
|
70809
70927
|
});
|
|
70810
70928
|
}
|
|
70811
70929
|
for (const e of edgeList(lv.y.measurements).filter(ok)) {
|
|
70812
|
-
const d =
|
|
70930
|
+
const d = num3(e.p.distance);
|
|
70813
70931
|
if (d >= 0.01)
|
|
70814
70932
|
level2.measurements.push({ v1: ids2[e.a], v2: ids2[e.b], distanceM: Math.min(d, 1e4) });
|
|
70815
70933
|
}
|
|
@@ -70840,14 +70958,14 @@ function fromBuildingYaml(doc) {
|
|
|
70840
70958
|
if (ly?.reference_floor_name && !levelNames.has(ly.reference_floor_name)) {
|
|
70841
70959
|
warnings.push(`Lift ${str60(liftName)}: its reference floor "${str60(ly.reference_floor_name)}" is not in the file; ${refName} was used.`);
|
|
70842
70960
|
}
|
|
70843
|
-
const c = applyXform(xf(refFloor), { x:
|
|
70961
|
+
const c = applyXform(xf(refFloor), { x: num3(ly?.x), y: num3(ly?.y) * flip });
|
|
70844
70962
|
const doors = Object.entries(ly?.doors ?? {}).slice(0, 8).map(([dn, d]) => ({
|
|
70845
70963
|
name: str60(dn),
|
|
70846
|
-
type: MSG_LIFT_DOOR_TYPE[Math.round(
|
|
70847
|
-
x: r3(clamp3(
|
|
70848
|
-
y: r3(clamp3(
|
|
70849
|
-
widthM: r3(clamp3(
|
|
70850
|
-
axisYawRad: clamp3(
|
|
70964
|
+
type: MSG_LIFT_DOOR_TYPE[Math.round(num3(d?.door_type, 2))] ?? "double_sliding",
|
|
70965
|
+
x: r3(clamp3(num3(d?.x), -20, 20)),
|
|
70966
|
+
y: r3(clamp3(num3(d?.y), -20, 20)),
|
|
70967
|
+
widthM: r3(clamp3(num3(d?.width, 1), 0.3, 10)),
|
|
70968
|
+
axisYawRad: clamp3(num3(d?.motion_axis_orientation), -10, 10)
|
|
70851
70969
|
}));
|
|
70852
70970
|
const doorNames = new Set(doors.map((d) => d.name));
|
|
70853
70971
|
const levelDoors = Object.entries(ly?.level_doors ?? {}).filter(([level2]) => levelNames.has(level2)).map(([level2, list]) => ({ level: level2, doors: (Array.isArray(list) ? list : []).map(str60).filter((d) => doorNames.has(d)) }));
|
|
@@ -70856,9 +70974,9 @@ function fromBuildingYaml(doc) {
|
|
|
70856
70974
|
name: str60(liftName),
|
|
70857
70975
|
x: r3(c.x),
|
|
70858
70976
|
y: r3(c.y),
|
|
70859
|
-
yawRad: clamp3(
|
|
70860
|
-
widthM: r3(clamp3(
|
|
70861
|
-
depthM: r3(clamp3(
|
|
70977
|
+
yawRad: clamp3(num3(ly?.yaw), -10, 10),
|
|
70978
|
+
widthM: r3(clamp3(num3(ly?.width, 2), 0.3, 20)),
|
|
70979
|
+
depthM: r3(clamp3(num3(ly?.depth, 2), 0.3, 20)),
|
|
70862
70980
|
referenceFloor: refFloor,
|
|
70863
70981
|
...floorName(ly?.initial_floor_name) ? { initialFloor: floorName(ly.initial_floor_name) } : {},
|
|
70864
70982
|
...floorName(ly?.lowest_floor) ? { lowestFloor: floorName(ly.lowest_floor) } : {},
|
|
@@ -70912,7 +71030,7 @@ function fromNavGraph(doc, graphIdx) {
|
|
|
70912
71030
|
level2.vertices = verts.map((v, k) => {
|
|
70913
71031
|
const p = v?.[2] && typeof v[2] === "object" ? v[2] : {};
|
|
70914
71032
|
const params = fileVertexParams(p);
|
|
70915
|
-
return { id: `v${k + 1}`, x: r3(
|
|
71033
|
+
return { id: `v${k + 1}`, x: r3(num3(v?.[0])), y: r3(num3(v?.[1])), ...p.name ? { name: str60(p.name) } : {}, ...Object.keys(params).length ? { params } : {} };
|
|
70916
71034
|
});
|
|
70917
71035
|
if (Array.isArray(ly?.lanes) && ly.lanes.length > 1e4)
|
|
70918
71036
|
throw new RmfImportError(`Floor ${str60(name)} has more than 10000 one-way lanes - more than a building map can hold.`);
|
|
@@ -70952,7 +71070,7 @@ function fromNavGraph(doc, graphIdx) {
|
|
|
70952
71070
|
graphIdx,
|
|
70953
71071
|
bidirectional,
|
|
70954
71072
|
...o === "forward" || o === "backward" ? { orientation: o } : {},
|
|
70955
|
-
...
|
|
71073
|
+
...num3(p.speed_limit) > 0 ? { speedLimit: clamp3(num3(p.speed_limit), 0, 20) } : {},
|
|
70956
71074
|
...p.mutex ? { mutex: str60(p.mutex) } : {},
|
|
70957
71075
|
...p.demo_mock_floor_name ? { demoMockFloorName: str60(p.demo_mock_floor_name) } : {},
|
|
70958
71076
|
...p.demo_mock_lift_name ? { demoMockLiftName: str60(p.demo_mock_lift_name) } : {}
|
|
@@ -83171,7 +83289,7 @@ function useAccessManagementController() {
|
|
|
83171
83289
|
liftName,
|
|
83172
83290
|
unit = [],
|
|
83173
83291
|
createdAt,
|
|
83174
|
-
updatedAt,
|
|
83292
|
+
updatedAt: updatedAt2,
|
|
83175
83293
|
startDate,
|
|
83176
83294
|
endDate,
|
|
83177
83295
|
isWinsland
|
|
@@ -83207,7 +83325,7 @@ function useAccessManagementController() {
|
|
|
83207
83325
|
startDate,
|
|
83208
83326
|
endDate,
|
|
83209
83327
|
createdAt,
|
|
83210
|
-
updatedAt,
|
|
83328
|
+
updatedAt: updatedAt2,
|
|
83211
83329
|
isWinsland
|
|
83212
83330
|
});
|
|
83213
83331
|
if (error) {
|
|
@@ -83229,7 +83347,7 @@ function useAccessManagementController() {
|
|
|
83229
83347
|
startDate,
|
|
83230
83348
|
endDate,
|
|
83231
83349
|
createdAt,
|
|
83232
|
-
updatedAt,
|
|
83350
|
+
updatedAt: updatedAt2,
|
|
83233
83351
|
isWinsland
|
|
83234
83352
|
});
|
|
83235
83353
|
return res.status(201).json({
|
|
@@ -106932,6 +107050,7 @@ function usePersonalEmergencyChainController() {
|
|
|
106932
107050
|
OUNITECH_BRAND,
|
|
106933
107051
|
OUNITECH_BRAND_DEFINITION,
|
|
106934
107052
|
OUNITECH_CAPABILITIES,
|
|
107053
|
+
OUNITECH_FRESH_MS,
|
|
106935
107054
|
OUNITECH_PENDING_COMMANDS,
|
|
106936
107055
|
OUNITECH_REGION_BASE_URLS,
|
|
106937
107056
|
OUNITECH_TIMESTAMP_FORMAT,
|
|
@@ -107298,7 +107417,9 @@ function usePersonalEmergencyChainController() {
|
|
|
107298
107417
|
orgQualifiesForOwnerRepair,
|
|
107299
107418
|
orgRoleSets,
|
|
107300
107419
|
orgSchema,
|
|
107420
|
+
ounitechCleaning,
|
|
107301
107421
|
ounitechFault,
|
|
107422
|
+
ounitechJobWords,
|
|
107302
107423
|
ounitechRobotFromHomeRow,
|
|
107303
107424
|
overnight_parking_requests_namespace_collection,
|
|
107304
107425
|
padbotAccountKey,
|