@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.mjs
CHANGED
|
@@ -10204,15 +10204,15 @@ function robotConnectionText(robotName, online, minutes) {
|
|
|
10204
10204
|
}
|
|
10205
10205
|
var OFFLINE_FAULT_CODE = "OFFLINE";
|
|
10206
10206
|
var SAME_OCCURRENCE_MS = 1e3;
|
|
10207
|
-
function planFaultChanges(open,
|
|
10207
|
+
function planFaultChanges(open, reading2) {
|
|
10208
10208
|
const byCode = new Map(open.map((r) => [r.code, r]));
|
|
10209
10209
|
const want = [];
|
|
10210
|
-
const offline = !
|
|
10210
|
+
const offline = !reading2.ok || reading2.online === false;
|
|
10211
10211
|
if (offline) {
|
|
10212
|
-
const reason =
|
|
10212
|
+
const reason = reading2.ok ? "" : String(reading2.error ?? "").slice(0, 200);
|
|
10213
10213
|
want.push({ code: OFFLINE_FAULT_CODE, message: reason ? `Not reporting: ${reason}` : "Not reporting" });
|
|
10214
10214
|
}
|
|
10215
|
-
const fault =
|
|
10215
|
+
const fault = reading2.ok && reading2.fault?.code ? reading2.fault : null;
|
|
10216
10216
|
if (fault)
|
|
10217
10217
|
want.push({ code: fault.code, message: fault.message || fault.code, since: fault.since });
|
|
10218
10218
|
const clear = [];
|
|
@@ -10244,12 +10244,12 @@ function planFaultChanges(open, reading) {
|
|
|
10244
10244
|
return { open: toOpen, clear, refresh };
|
|
10245
10245
|
}
|
|
10246
10246
|
function robotFaultSweepConfig(env2 = process.env) {
|
|
10247
|
-
const
|
|
10247
|
+
const num4 = (v, def, min, max) => {
|
|
10248
10248
|
const n = Math.floor(Number(v));
|
|
10249
10249
|
return Number.isFinite(n) && String(v ?? "").trim() !== "" ? Math.min(max, Math.max(min, n)) : def;
|
|
10250
10250
|
};
|
|
10251
10251
|
const enabled = String(env2.ROBOT_FAULT_SWEEP ?? "on").trim().toLowerCase() !== "off";
|
|
10252
|
-
const asked =
|
|
10252
|
+
const asked = num4(env2.ROBOT_FAULT_SWEEP_SECONDS, 60, 10, 3600);
|
|
10253
10253
|
const pick = (steps, v) => steps.filter((d) => d <= v).pop() ?? steps[0];
|
|
10254
10254
|
const subMinute = asked < 60;
|
|
10255
10255
|
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));
|
|
@@ -10259,9 +10259,9 @@ function robotFaultSweepConfig(env2 = process.env) {
|
|
|
10259
10259
|
enabled,
|
|
10260
10260
|
seconds,
|
|
10261
10261
|
cron: cron2,
|
|
10262
|
-
concurrency:
|
|
10263
|
-
timeoutMs:
|
|
10264
|
-
offlineAlertMinutes:
|
|
10262
|
+
concurrency: num4(env2.ROBOT_FAULT_SWEEP_CONCURRENCY, 4, 1, 16),
|
|
10263
|
+
timeoutMs: num4(env2.ROBOT_FAULT_SWEEP_TIMEOUT_MS, 1e4, 1e3, 6e4),
|
|
10264
|
+
offlineAlertMinutes: num4(env2.ROBOT_OFFLINE_ALERT_MINUTES, 10, 1, 1440)
|
|
10265
10265
|
};
|
|
10266
10266
|
}
|
|
10267
10267
|
function withTimeout(promise, ms2, label2 = "Timed out") {
|
|
@@ -26173,7 +26173,7 @@ function usePersonRepo() {
|
|
|
26173
26173
|
}
|
|
26174
26174
|
async function pushVehicleById(id, plate, session) {
|
|
26175
26175
|
const { plateNumber, recNo } = plate;
|
|
26176
|
-
const
|
|
26176
|
+
const updatedAt2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
26177
26177
|
const _id = toObjectId9(id);
|
|
26178
26178
|
try {
|
|
26179
26179
|
const updateExisting = await collection.updateOne(
|
|
@@ -26184,7 +26184,7 @@ function usePersonRepo() {
|
|
|
26184
26184
|
{
|
|
26185
26185
|
$set: {
|
|
26186
26186
|
"plates.$.recNo": recNo,
|
|
26187
|
-
updatedAt
|
|
26187
|
+
updatedAt: updatedAt2
|
|
26188
26188
|
}
|
|
26189
26189
|
},
|
|
26190
26190
|
{ session }
|
|
@@ -26200,7 +26200,7 @@ function usePersonRepo() {
|
|
|
26200
26200
|
}
|
|
26201
26201
|
},
|
|
26202
26202
|
$set: {
|
|
26203
|
-
updatedAt
|
|
26203
|
+
updatedAt: updatedAt2
|
|
26204
26204
|
}
|
|
26205
26205
|
},
|
|
26206
26206
|
{ session }
|
|
@@ -26211,7 +26211,7 @@ function usePersonRepo() {
|
|
|
26211
26211
|
}
|
|
26212
26212
|
}
|
|
26213
26213
|
async function pullVehicleByRecNo(recNo, scope, session) {
|
|
26214
|
-
const
|
|
26214
|
+
const updatedAt2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
26215
26215
|
const owner = scope?.peopleId ? toObjectId9(scope.peopleId) : null;
|
|
26216
26216
|
const site = scope?.site ? toObjectId9(scope.site) : null;
|
|
26217
26217
|
if (!owner && !site) {
|
|
@@ -26250,7 +26250,7 @@ function usePersonRepo() {
|
|
|
26250
26250
|
plates: match
|
|
26251
26251
|
},
|
|
26252
26252
|
$set: {
|
|
26253
|
-
updatedAt
|
|
26253
|
+
updatedAt: updatedAt2
|
|
26254
26254
|
}
|
|
26255
26255
|
},
|
|
26256
26256
|
{ session }
|
|
@@ -47708,7 +47708,7 @@ var MKeyLog = class {
|
|
|
47708
47708
|
organization = "",
|
|
47709
47709
|
serviceProvider = "",
|
|
47710
47710
|
createdAt = /* @__PURE__ */ new Date(),
|
|
47711
|
-
updatedAt = /* @__PURE__ */ new Date(),
|
|
47711
|
+
updatedAt: updatedAt2 = /* @__PURE__ */ new Date(),
|
|
47712
47712
|
template,
|
|
47713
47713
|
status = "Available",
|
|
47714
47714
|
updatedBy = "",
|
|
@@ -47729,7 +47729,7 @@ var MKeyLog = class {
|
|
|
47729
47729
|
this.organization = organization;
|
|
47730
47730
|
this.serviceProvider = serviceProvider;
|
|
47731
47731
|
this.createdAt = createdAt;
|
|
47732
|
-
this.updatedAt =
|
|
47732
|
+
this.updatedAt = updatedAt2;
|
|
47733
47733
|
this.template = template;
|
|
47734
47734
|
this.status = status;
|
|
47735
47735
|
this.updatedBy = updatedBy;
|
|
@@ -56384,7 +56384,7 @@ var MAccessCard = class {
|
|
|
56384
56384
|
isLiftCard,
|
|
56385
56385
|
liftAccessLevel,
|
|
56386
56386
|
createdAt,
|
|
56387
|
-
updatedAt,
|
|
56387
|
+
updatedAt: updatedAt2,
|
|
56388
56388
|
assignedUnit,
|
|
56389
56389
|
userType,
|
|
56390
56390
|
doorName,
|
|
@@ -56411,7 +56411,7 @@ var MAccessCard = class {
|
|
|
56411
56411
|
this.isLiftCard = isLiftCard;
|
|
56412
56412
|
this.liftAccessLevel = liftAccessLevel;
|
|
56413
56413
|
this.createdAt = createdAt;
|
|
56414
|
-
this.updatedAt =
|
|
56414
|
+
this.updatedAt = updatedAt2;
|
|
56415
56415
|
this.assignedUnit = assignedUnit;
|
|
56416
56416
|
this.userType = userType;
|
|
56417
56417
|
this.doorName = doorName;
|
|
@@ -56590,8 +56590,8 @@ function encryptPayload(payloadHex) {
|
|
|
56590
56590
|
);
|
|
56591
56591
|
return encrypted.toString("base64");
|
|
56592
56592
|
}
|
|
56593
|
-
function toHex(
|
|
56594
|
-
return
|
|
56593
|
+
function toHex(num4, length) {
|
|
56594
|
+
return num4.toString(16).padStart(length * 2, "0");
|
|
56595
56595
|
}
|
|
56596
56596
|
function buildPayload(cardNumber, validityMinutes) {
|
|
56597
56597
|
const randomHex = crypto7.randomBytes(2).toString("hex");
|
|
@@ -56771,8 +56771,8 @@ function UseAccessManagementRepo() {
|
|
|
56771
56771
|
}
|
|
56772
56772
|
}
|
|
56773
56773
|
function generateCardNo() {
|
|
56774
|
-
const
|
|
56775
|
-
return
|
|
56774
|
+
const num4 = Math.floor(Math.random() * 65536);
|
|
56775
|
+
return num4.toString().padStart(10, "0");
|
|
56776
56776
|
}
|
|
56777
56777
|
async function createQrData({
|
|
56778
56778
|
cardNumber,
|
|
@@ -58012,13 +58012,13 @@ function UseAccessManagementRepo() {
|
|
|
58012
58012
|
const prevCard = res && res?.[1]?.cardNo || "-1";
|
|
58013
58013
|
const currentCard = res && res?.[0]?.cardNo || "0";
|
|
58014
58014
|
let availableCardNo = [];
|
|
58015
|
-
let
|
|
58015
|
+
let num4 = parseInt(prevCard, 10) + 1;
|
|
58016
58016
|
while (availableCardNo.length < (unit.length > 0 ? unit.length : quantity)) {
|
|
58017
|
-
if (
|
|
58018
|
-
|
|
58017
|
+
if (num4 === parseInt(currentCard, 10)) {
|
|
58018
|
+
num4++;
|
|
58019
58019
|
}
|
|
58020
|
-
availableCardNo.push(
|
|
58021
|
-
|
|
58020
|
+
availableCardNo.push(num4);
|
|
58021
|
+
num4++;
|
|
58022
58022
|
}
|
|
58023
58023
|
const cardNumbers = availableCardNo.map(
|
|
58024
58024
|
(no2) => no2.toString().padStart(10, "0")
|
|
@@ -63272,7 +63272,9 @@ var ROBOT_CAPABILITIES = [
|
|
|
63272
63272
|
*/
|
|
63273
63273
|
"manualDrive",
|
|
63274
63274
|
/** A heat camera: alarm and patrol photos carry a thermal picture and temperatures. Reporting only. */
|
|
63275
|
-
"thermalCamera"
|
|
63275
|
+
"thermalCamera",
|
|
63276
|
+
/** A scrubber's clean/dirty water levels and whether its tanks and covers are fitted. Reporting only. */
|
|
63277
|
+
"waterTanks"
|
|
63276
63278
|
];
|
|
63277
63279
|
var TIER_REQUIREMENTS = {
|
|
63278
63280
|
"full-control": [
|
|
@@ -63754,13 +63756,13 @@ function parseRobotCommand(body) {
|
|
|
63754
63756
|
if (has2(k))
|
|
63755
63757
|
return { ok: false, message: `${k} is not valid for a ${kind} command.` };
|
|
63756
63758
|
}
|
|
63757
|
-
const
|
|
63758
|
-
if (!
|
|
63759
|
+
const num4 = (k) => typeof b[k] === "number" && Number.isFinite(b[k]);
|
|
63760
|
+
if (!num4("x") || !num4("y"))
|
|
63759
63761
|
return { ok: false, message: `${kind} needs x and y (metres).` };
|
|
63760
63762
|
if (kind === "navigate") {
|
|
63761
63763
|
if (has2("floorNo"))
|
|
63762
63764
|
return { ok: false, message: "floorNo is not valid for a navigate command." };
|
|
63763
|
-
if (has2("theta") && !
|
|
63765
|
+
if (has2("theta") && !num4("theta"))
|
|
63764
63766
|
return { ok: false, message: "theta must be a number (radians)." };
|
|
63765
63767
|
return {
|
|
63766
63768
|
ok: true,
|
|
@@ -63772,7 +63774,7 @@ function parseRobotCommand(body) {
|
|
|
63772
63774
|
}
|
|
63773
63775
|
};
|
|
63774
63776
|
}
|
|
63775
|
-
if (!
|
|
63777
|
+
if (!num4("theta"))
|
|
63776
63778
|
return { ok: false, message: "relocalize needs theta (radians)." };
|
|
63777
63779
|
if (!Number.isInteger(b.floorNo))
|
|
63778
63780
|
return { ok: false, message: "relocalize needs an integer floorNo." };
|
|
@@ -64172,6 +64174,8 @@ var OUNITECH_CAPABILITIES = {
|
|
|
64172
64174
|
battery: true,
|
|
64173
64175
|
// The chapter-6 robot list: `floorNo` (the robot's floor).
|
|
64174
64176
|
floorReporting: true,
|
|
64177
|
+
// robotState readings: clean-water / dirty-water (%), top-cover / tank / dust-box fitted.
|
|
64178
|
+
waterTanks: true,
|
|
64175
64179
|
// FALSE on purpose - each one is a question for the vendor.
|
|
64176
64180
|
navigateToPoint: false,
|
|
64177
64181
|
// app: "Move to Target Point"; API: robot-control actionNo not documented
|
|
@@ -64196,23 +64200,114 @@ var OUNITECH_CAPABILITIES = {
|
|
|
64196
64200
|
var OUNITECH_PENDING_COMMANDS = ["pause", "resume", "cancel"].map(
|
|
64197
64201
|
(kind) => ({ kind, reason: "awaiting Ounitech's robot-control action numbers" })
|
|
64198
64202
|
);
|
|
64199
|
-
function propertyNumber(row, key) {
|
|
64200
|
-
const p = row.robotState?.properties?.find((x) => x?.key === key);
|
|
64201
|
-
const n = p?.value != null && String(p.value).trim() !== "" ? Number(p.value) : NaN;
|
|
64202
|
-
return Number.isFinite(n) ? n : null;
|
|
64203
|
-
}
|
|
64204
64203
|
var finite = (v) => typeof v === "number" && Number.isFinite(v);
|
|
64205
|
-
function
|
|
64206
|
-
|
|
64207
|
-
|
|
64208
|
-
|
|
64204
|
+
function num(v) {
|
|
64205
|
+
if (finite(v))
|
|
64206
|
+
return v;
|
|
64207
|
+
if (typeof v === "string" && v.trim() !== "") {
|
|
64208
|
+
const n = Number(v);
|
|
64209
|
+
return Number.isFinite(n) ? n : void 0;
|
|
64210
|
+
}
|
|
64211
|
+
return void 0;
|
|
64212
|
+
}
|
|
64213
|
+
function reading(st, key) {
|
|
64214
|
+
const v = st.properties?.find((x) => x?.key === key)?.value;
|
|
64215
|
+
return v == null || String(v).trim() === "" ? void 0 : String(v).trim();
|
|
64216
|
+
}
|
|
64217
|
+
var OUNITECH_FRESH_MS = 3 * 6e4;
|
|
64218
|
+
var STATUS_CODE_BY_READING = {
|
|
64219
|
+
\u5F85\u673A: 1,
|
|
64220
|
+
\u7A7A\u95F2: 1,
|
|
64221
|
+
\u6E05\u626B\u4E2D: 2,
|
|
64222
|
+
\u5DE5\u4F5C\u4E2D: 2,
|
|
64223
|
+
\u6682\u505C: 3,
|
|
64224
|
+
\u6682\u505C\u4E2D: 3,
|
|
64225
|
+
\u5EFA\u56FE\u4E2D: 4,
|
|
64226
|
+
\u56DE\u5145\u4E2D: 6,
|
|
64227
|
+
\u8FD4\u56DE\u5145\u7535: 6,
|
|
64228
|
+
\u6545\u969C: 7,
|
|
64229
|
+
\u5F02\u5E38: 7,
|
|
64230
|
+
\u5145\u7535\u4E2D: 8,
|
|
64231
|
+
\u65AD\u70B9\u5145\u7535\u4E2D: 16,
|
|
64232
|
+
\u5DF2\u5145\u6EE1: 9,
|
|
64233
|
+
\u5145\u6EE1: 9,
|
|
64234
|
+
\u6025\u505C: 11,
|
|
64235
|
+
\u5173\u673A: 14,
|
|
64236
|
+
\u79BB\u7EBF: 99
|
|
64237
|
+
};
|
|
64238
|
+
var JOB_WORDS = {
|
|
64239
|
+
\u5DF2\u7ED3\u675F: "job finished",
|
|
64240
|
+
\u5DF2\u5B8C\u6210: "job finished",
|
|
64241
|
+
\u5B8C\u6210: "job finished",
|
|
64242
|
+
\u6E05\u626B\u4E2D: "job in progress",
|
|
64243
|
+
\u8FDB\u884C\u4E2D: "job in progress",
|
|
64244
|
+
\u6682\u505C: "job paused",
|
|
64245
|
+
\u6682\u505C\u4E2D: "job paused",
|
|
64246
|
+
\u672A\u5F00\u59CB: "no job started",
|
|
64247
|
+
\u5DF2\u53D6\u6D88: "job cancelled",
|
|
64248
|
+
\u53D6\u6D88: "job cancelled"
|
|
64249
|
+
};
|
|
64250
|
+
function ounitechJobWords(st) {
|
|
64251
|
+
const v = reading(st, "job");
|
|
64252
|
+
return v ? JOB_WORDS[v] ?? null : null;
|
|
64253
|
+
}
|
|
64254
|
+
var levelOf = (pct) => pct < 25 ? "low" : pct >= 75 ? "high" : "medium";
|
|
64255
|
+
var LEVEL_WORDS = { \u4F4E: "low", \u4E2D: "medium", \u9AD8: "high" };
|
|
64256
|
+
var PARTS = [
|
|
64257
|
+
["top-cover", "top cover"],
|
|
64258
|
+
["clean-water-tank", "clean-water tank"],
|
|
64259
|
+
["waste-water-tank", "dirty-water tank"],
|
|
64260
|
+
["dust-box", "dust box"]
|
|
64261
|
+
];
|
|
64262
|
+
function ounitechCleaning(st, working, taskPercent) {
|
|
64263
|
+
const water = (pctKey, levelKey) => {
|
|
64264
|
+
const pct2 = num(reading(st, pctKey));
|
|
64265
|
+
if (pct2 !== void 0 && pct2 >= 0 && pct2 <= 100)
|
|
64266
|
+
return { level: levelOf(pct2), percent: Math.round(pct2) };
|
|
64267
|
+
const word = LEVEL_WORDS[reading(st, levelKey) ?? ""];
|
|
64268
|
+
return word ? { level: word, percent: null } : null;
|
|
64269
|
+
};
|
|
64270
|
+
const cleanWater = water("clean-water", "clean-water-level");
|
|
64271
|
+
const dirtyWater = water("dirty-water", "dirty-water-level");
|
|
64272
|
+
const parts = PARTS.flatMap(([key, part]) => {
|
|
64273
|
+
const v = reading(st, key)?.toLowerCase();
|
|
64274
|
+
return v === "true" || v === "1" ? [{ part, ok: true }] : v === "false" || v === "0" ? [{ part, ok: false }] : [];
|
|
64275
|
+
});
|
|
64276
|
+
const area = (k) => {
|
|
64277
|
+
const n = num(reading(st, k));
|
|
64278
|
+
return n !== void 0 && n > 0 ? Math.round(n * 10) / 10 : null;
|
|
64279
|
+
};
|
|
64280
|
+
const pct = num(reading(st, "acc-percent")) ?? (finite(taskPercent) ? taskPercent : void 0);
|
|
64281
|
+
const job = working ? { percent: pct !== void 0 && pct >= 0 && pct <= 100 ? Math.round(pct) : null, areaDone: area("acc-area"), areaPlanned: area("count-area") } : null;
|
|
64282
|
+
const hasJob = !!job && (job.percent !== null || job.areaDone !== null);
|
|
64283
|
+
if (!cleanWater && !dirtyWater && !parts.length && !hasJob)
|
|
64284
|
+
return null;
|
|
64285
|
+
return { cleanWater, dirtyWater, parts, job: hasJob ? job : null };
|
|
64286
|
+
}
|
|
64287
|
+
function updatedAt(v) {
|
|
64288
|
+
const n = num(v);
|
|
64289
|
+
if (n !== void 0)
|
|
64290
|
+
return n < 1e12 ? n * 1e3 : n;
|
|
64291
|
+
const t = typeof v === "string" ? Date.parse(v) : NaN;
|
|
64292
|
+
return Number.isFinite(t) ? t : null;
|
|
64293
|
+
}
|
|
64294
|
+
function ounitechRobotFromHomeRow(row, live2, now = Date.now()) {
|
|
64295
|
+
const listed = row.robotState ?? {};
|
|
64296
|
+
const st = live2 ? { ...listed, ...live2, properties: live2.properties?.length ? live2.properties : listed.properties } : listed;
|
|
64297
|
+
const statusReading = reading(st, "status");
|
|
64298
|
+
const flag = num(st.statusFlag) ?? (statusReading ? STATUS_CODE_BY_READING[statusReading] : void 0);
|
|
64299
|
+
const at2 = updatedAt(st.updateOn);
|
|
64300
|
+
const fresh = at2 !== null && now - at2 <= OUNITECH_FRESH_MS;
|
|
64301
|
+
const online = flag !== 99 && (flag !== void 0 || fresh);
|
|
64209
64302
|
const mode = online ? robotMode(flag) : "UNAVAILABLE";
|
|
64210
|
-
const pct =
|
|
64303
|
+
const pct = num(reading(st, "battery-percent")) ?? num(st.battery) ?? null;
|
|
64211
64304
|
const task = row.taskState;
|
|
64212
64305
|
const jobPct = task && String(task.statusFlag) === "1" && finite(task.accPercent) ? Math.round(task.accPercent) : null;
|
|
64213
|
-
const words = flag
|
|
64306
|
+
const words = flag !== void 0 ? ROBOT_STATUS_NAMES[flag] ?? `Status ${flag}` : online ? "Online - status not reported" : "Unknown";
|
|
64214
64307
|
const model = String(row.modelCode || row.modelName || "").trim().slice(0, 40);
|
|
64215
|
-
|
|
64308
|
+
const x = num(st.x);
|
|
64309
|
+
const y = num(st.y);
|
|
64310
|
+
const robot = {
|
|
64216
64311
|
robotSn: row.robotSn,
|
|
64217
64312
|
name: row.aliasName || row.robotName,
|
|
64218
64313
|
...model ? { model } : {},
|
|
@@ -64222,8 +64317,19 @@ function ounitechRobotFromHomeRow(row) {
|
|
|
64222
64317
|
batteryPercent: online && pct !== null && pct >= 0 && pct <= 100 ? Math.round(pct) : null,
|
|
64223
64318
|
floorNo: Number.isInteger(row.floorNo) ? row.floorNo : null,
|
|
64224
64319
|
floorKnown: Number.isInteger(row.floorNo),
|
|
64225
|
-
position: online &&
|
|
64320
|
+
position: online && x !== void 0 && y !== void 0 ? { x, y, theta: num(st.theta) ?? 0 } : null
|
|
64226
64321
|
};
|
|
64322
|
+
if (online) {
|
|
64323
|
+
robot.cleaning = ounitechCleaning(st, mode === "WORKING", task && String(task.statusFlag) === "1" ? task.accPercent : null);
|
|
64324
|
+
}
|
|
64325
|
+
if (online && (flag === 7 || Array.isArray(st.rtFaultList) && st.rtFaultList.length)) {
|
|
64326
|
+
robot.fault = ounitechFault(st.rtFaultList);
|
|
64327
|
+
}
|
|
64328
|
+
return robot;
|
|
64329
|
+
}
|
|
64330
|
+
function needsLiveState(row) {
|
|
64331
|
+
const f = num(row.robotState?.statusFlag);
|
|
64332
|
+
return finite(row.robotId) && (f === void 0 || f === 99 || f === 7);
|
|
64227
64333
|
}
|
|
64228
64334
|
function ounitechFault(list) {
|
|
64229
64335
|
const f = Array.isArray(list) ? list[0] : null;
|
|
@@ -64240,6 +64346,9 @@ function ounitechFault(list) {
|
|
|
64240
64346
|
var robotTime = (d) => robotCloudTimestamp(d, "yyyy-MM-dd HH:mm:ss", "Asia/Shanghai");
|
|
64241
64347
|
function createOunitechAdapter(credentials, options) {
|
|
64242
64348
|
const cloud = useRobotCloudService(credentials, options);
|
|
64349
|
+
async function liveFor(row) {
|
|
64350
|
+
return needsLiveState(row) ? cloud.getRobotState(row.robotId).catch(() => null) : null;
|
|
64351
|
+
}
|
|
64243
64352
|
async function rowFor(robotSn) {
|
|
64244
64353
|
return (await cloud.getHomeRobots()).find((r) => r.robotSn === robotSn) ?? null;
|
|
64245
64354
|
}
|
|
@@ -64248,7 +64357,7 @@ function createOunitechAdapter(credentials, options) {
|
|
|
64248
64357
|
displayName: "Ounitech (Q3-G / Q3-W)",
|
|
64249
64358
|
capabilities: OUNITECH_CAPABILITIES,
|
|
64250
64359
|
async listRobots() {
|
|
64251
|
-
return (await cloud.getHomeRobots()).map(ounitechRobotFromHomeRow);
|
|
64360
|
+
return Promise.all((await cloud.getHomeRobots()).map(async (row) => ounitechRobotFromHomeRow(row, await liveFor(row))));
|
|
64252
64361
|
},
|
|
64253
64362
|
async getRobot(robotSn) {
|
|
64254
64363
|
const row = await rowFor(robotSn);
|
|
@@ -64264,12 +64373,7 @@ function createOunitechAdapter(credentials, options) {
|
|
|
64264
64373
|
position: null
|
|
64265
64374
|
};
|
|
64266
64375
|
}
|
|
64267
|
-
|
|
64268
|
-
if (row.robotState?.statusFlag === 7 && finite(row.robotId)) {
|
|
64269
|
-
const state = await cloud.getRobotState(row.robotId).catch(() => null);
|
|
64270
|
-
robot.fault = ounitechFault(state?.rtFaultList);
|
|
64271
|
-
}
|
|
64272
|
-
return robot;
|
|
64376
|
+
return ounitechRobotFromHomeRow(row, await liveFor(row));
|
|
64273
64377
|
},
|
|
64274
64378
|
async sendCommand(robotSn, command) {
|
|
64275
64379
|
const options2 = {
|
|
@@ -64384,10 +64488,19 @@ function createOunitechAdapter(credentials, options) {
|
|
|
64384
64488
|
const window = { timeFrom: robotTime(from), timeTo: robotTime(to) };
|
|
64385
64489
|
await run("live state (get-robot-state-v2.0)", ROBOT_CLOUD_PATHS.robotState, { robotId }, async () => {
|
|
64386
64490
|
const s = await cloud.getRobotState(robotId);
|
|
64491
|
+
const r = ounitechRobotFromHomeRow(row, s);
|
|
64492
|
+
const level2 = (...keys) => keys.map((k) => num(reading(s, k))).find((n) => n !== void 0) ?? null;
|
|
64493
|
+
const at2 = updatedAt(s.updateOn);
|
|
64387
64494
|
return {
|
|
64495
|
+
online: r.online,
|
|
64496
|
+
status: r.statusName,
|
|
64497
|
+
job: ounitechJobWords(s),
|
|
64498
|
+
battery: r.batteryPercent,
|
|
64499
|
+
cleanWater: level2("clean-water", "clean-percent"),
|
|
64500
|
+
dirtyWater: level2("dirty-water", "dirty-percent"),
|
|
64501
|
+
fault: r.fault ?? null,
|
|
64388
64502
|
statusFlag: s.statusFlag,
|
|
64389
|
-
|
|
64390
|
-
updateOn: s.updateOn ? new Date(s.updateOn).toISOString() : null,
|
|
64503
|
+
updateOn: at2 !== null ? new Date(at2).toISOString() : null,
|
|
64391
64504
|
x: s.x,
|
|
64392
64505
|
y: s.y,
|
|
64393
64506
|
theta: s.theta,
|
|
@@ -66319,7 +66432,7 @@ function statesByType(entry) {
|
|
|
66319
66432
|
}
|
|
66320
66433
|
var PADBOT_ONLINE_WINDOW_MS = 12e4;
|
|
66321
66434
|
var ms = (t) => typeof t === "string" ? Date.parse(t) : NaN;
|
|
66322
|
-
var
|
|
66435
|
+
var num2 = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
66323
66436
|
function padbotMode(states, now = Date.now()) {
|
|
66324
66437
|
const hb = ms(states["1000"]?.updatedAt);
|
|
66325
66438
|
const online = Number.isFinite(hb) && now - hb <= PADBOT_ONLINE_WINDOW_MS;
|
|
@@ -66327,7 +66440,7 @@ function padbotMode(states, now = Date.now()) {
|
|
|
66327
66440
|
return { online: false, mode: "UNAVAILABLE", statusName: "Not reporting to PadBot" };
|
|
66328
66441
|
const nav = states["1003"] ?? {};
|
|
66329
66442
|
const work = states["1010"] ?? {};
|
|
66330
|
-
const battery =
|
|
66443
|
+
const battery = num2(states["1001"]?.batteryPercent);
|
|
66331
66444
|
const charging = states["1002"]?.chargingState === 1;
|
|
66332
66445
|
const type = Number(nav.actionType) || 0;
|
|
66333
66446
|
const st = Number(nav.actionState) || 0;
|
|
@@ -66364,7 +66477,7 @@ function padbotCommandBlock(states, kind, now = Date.now()) {
|
|
|
66364
66477
|
return "The robot is not reporting to PadBot, so it cannot take a command. Check it is switched on and connected.";
|
|
66365
66478
|
if (states["1006"]?.emergencyStopState === 1)
|
|
66366
66479
|
return "The robot's emergency stop button is pressed. Release the red button on the robot, then try again.";
|
|
66367
|
-
const battery =
|
|
66480
|
+
const battery = num2(states["1001"]?.batteryPercent);
|
|
66368
66481
|
if (kind !== "return" && battery !== null && battery < 10)
|
|
66369
66482
|
return `The battery is at ${battery}%. PadBot robots do not start jobs under 10%; send it to charge first.`;
|
|
66370
66483
|
if (kind === "return" && [1, 2].includes(states["1002"]?.chargingState))
|
|
@@ -66386,7 +66499,7 @@ function padbotReadiness(states, now = Date.now()) {
|
|
|
66386
66499
|
heartbeatAt: st["1000"]?.updatedAt ?? null,
|
|
66387
66500
|
emergencyStopPressed: es.emergencyStopState === 1,
|
|
66388
66501
|
wheelLockState: es.wheelLockState ?? null,
|
|
66389
|
-
batteryPercent:
|
|
66502
|
+
batteryPercent: num2(st["1001"]?.batteryPercent),
|
|
66390
66503
|
chargingState: charging ?? null,
|
|
66391
66504
|
map: { id: st["1007"]?.mapId ?? null, name: st["1007"]?.mapDisplayName ?? null, floor: st["1007"]?.floor ?? null },
|
|
66392
66505
|
navigation: { actionType: nav.actionType ?? null, actionState: nav.actionState ?? null, message: nav.message ?? null, updatedAt: nav.updatedAt ?? null },
|
|
@@ -66443,19 +66556,19 @@ function padbotMotion(m, now) {
|
|
|
66443
66556
|
}
|
|
66444
66557
|
function networkText(net) {
|
|
66445
66558
|
const say = (label2, v) => v < 0 ? ` \xB7 ${label2} ${v} dBm` : ` \xB7 ${label2} signal ${v}`;
|
|
66446
|
-
const wifi =
|
|
66559
|
+
const wifi = num2(net?.wifi?.signalStrength);
|
|
66447
66560
|
if (wifi !== null)
|
|
66448
66561
|
return say("Wi-Fi", wifi);
|
|
66449
|
-
const cell =
|
|
66562
|
+
const cell = num2(net?.cellular?.signalStrength);
|
|
66450
66563
|
return cell !== null ? say("Mobile", cell) : "";
|
|
66451
66564
|
}
|
|
66452
66565
|
function padbotPlanShare(frame2, x, y) {
|
|
66453
|
-
const w =
|
|
66454
|
-
const wx =
|
|
66566
|
+
const w = num2(frame2?.width), h = num2(frame2?.height), r = num2(frame2?.resolution);
|
|
66567
|
+
const wx = num2(x), wy = num2(y);
|
|
66455
66568
|
if (!w || !h || !r || r <= 0 || wx === null || wy === null)
|
|
66456
66569
|
return null;
|
|
66457
|
-
const px = (wx - (
|
|
66458
|
-
const pyUp = (wy - (
|
|
66570
|
+
const px = (wx - (num2(frame2?.originX) ?? 0)) / r;
|
|
66571
|
+
const pyUp = (wy - (num2(frame2?.originY) ?? 0)) / r;
|
|
66459
66572
|
const sx = px / w * 100, sy = 100 - pyUp / h * 100;
|
|
66460
66573
|
if (sx < 0 || sx > 100 || sy < 0 || sy > 100)
|
|
66461
66574
|
return null;
|
|
@@ -66485,9 +66598,9 @@ function padbotCurrentMap(maps, ids2, floor) {
|
|
|
66485
66598
|
}
|
|
66486
66599
|
function padbotChargingPoint(map) {
|
|
66487
66600
|
const piles = (Array.isArray(map?.targetPoints) ? map.targetPoints : []).filter(
|
|
66488
|
-
(t) => Number(t?.targetPointType) === 10 &&
|
|
66601
|
+
(t) => Number(t?.targetPointType) === 10 && num2(t?.worldX) !== null && num2(t?.worldY) !== null
|
|
66489
66602
|
);
|
|
66490
|
-
return piles.length === 1 ? { worldX:
|
|
66603
|
+
return piles.length === 1 ? { worldX: num2(piles[0].worldX), worldY: num2(piles[0].worldY), yaw: piles[0].yaw } : null;
|
|
66491
66604
|
}
|
|
66492
66605
|
var PADBOT_OTHER_MAP_TEXT = "The robot must be on this map first.";
|
|
66493
66606
|
function padbotAlarmFault(alarm) {
|
|
@@ -66582,9 +66695,9 @@ function padbotPatrolRecord(r) {
|
|
|
66582
66695
|
result: PATROL_RESULT[r?.completionState] ?? "unknown",
|
|
66583
66696
|
startedAt: r?.startedAt ?? null,
|
|
66584
66697
|
endedAt: r?.endedAt ?? null,
|
|
66585
|
-
durationS:
|
|
66586
|
-
distanceM:
|
|
66587
|
-
alarmCount:
|
|
66698
|
+
durationS: num2(r?.duration),
|
|
66699
|
+
distanceM: num2(r?.mileage),
|
|
66700
|
+
alarmCount: num2(r?.alarmCount) ?? 0
|
|
66588
66701
|
};
|
|
66589
66702
|
}
|
|
66590
66703
|
function padbotCheckpointVisit(d) {
|
|
@@ -66594,15 +66707,15 @@ function padbotCheckpointVisit(d) {
|
|
|
66594
66707
|
skipped: d?.skipped === true,
|
|
66595
66708
|
imageUrl: d?.visibleLightImageUrl ?? null,
|
|
66596
66709
|
thermalImageUrl: d?.thermalImageUrl ?? null,
|
|
66597
|
-
centerTempC:
|
|
66598
|
-
maxTempC:
|
|
66710
|
+
centerTempC: num2(d?.centerTemperature),
|
|
66711
|
+
maxTempC: num2(d?.maxTemperature)
|
|
66599
66712
|
};
|
|
66600
66713
|
}
|
|
66601
66714
|
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 : [];
|
|
66602
66715
|
var page = (data, map) => ({
|
|
66603
66716
|
items: (Array.isArray(data?.items) ? data.items : []).map(map),
|
|
66604
|
-
total:
|
|
66605
|
-
pages:
|
|
66717
|
+
total: num2(data?.totalItems) ?? 0,
|
|
66718
|
+
pages: num2(data?.totalPages) ?? 0
|
|
66606
66719
|
});
|
|
66607
66720
|
function createPadbotClient(credentials, options = {}) {
|
|
66608
66721
|
const baseUrl = (options.baseUrl ?? padbotBaseUrl()).replace(/\/+$/, "");
|
|
@@ -66824,7 +66937,7 @@ function createPadbotAdapter(credentials, options = {}) {
|
|
|
66824
66937
|
const { online, mode, statusName } = padbotMode(st, now());
|
|
66825
66938
|
const floor = st["1007"]?.floor;
|
|
66826
66939
|
const restBatteryAt = ms(st["1001"]?.updatedAt);
|
|
66827
|
-
const battery = heard?.batteryPercent !== void 0 && (!Number.isFinite(restBatteryAt) || (heard.batteryAt ?? 0) > restBatteryAt) ? heard.batteryPercent :
|
|
66940
|
+
const battery = heard?.batteryPercent !== void 0 && (!Number.isFinite(restBatteryAt) || (heard.batteryAt ?? 0) > restBatteryAt) ? heard.batteryPercent : num2(st["1001"]?.batteryPercent);
|
|
66828
66941
|
const failed = lastFailure.get(`${account}:${robotSn}`);
|
|
66829
66942
|
const showFailure = online && failed && now() - failed.at < PADBOT_FAILURE_SHOW_MS && /^(Standing by|Charging)/.test(statusName);
|
|
66830
66943
|
const robot = {
|
|
@@ -66851,15 +66964,15 @@ function createPadbotAdapter(credentials, options = {}) {
|
|
|
66851
66964
|
return robot;
|
|
66852
66965
|
const [loc, openA] = await Promise.all([locRead, alarmRead]);
|
|
66853
66966
|
const alarm = robot.fault ? null : openA;
|
|
66854
|
-
const lx =
|
|
66855
|
-
const ly =
|
|
66967
|
+
const lx = num2(loc?.worldX ?? loc?.x);
|
|
66968
|
+
const ly = num2(loc?.worldY ?? loc?.y);
|
|
66856
66969
|
if (typeof loc?.mapId === "string" && loc.mapId)
|
|
66857
66970
|
robot.mapId = loc.mapId;
|
|
66858
66971
|
const map = await maps(robotSn).then((all) => padbotCurrentMap(all, [robot.mapId, st["1007"]?.mapId], robot.floorNo)).catch(() => null);
|
|
66859
66972
|
if (map)
|
|
66860
66973
|
robot.mapId = map.mapId;
|
|
66861
66974
|
if (lx !== null && ly !== null) {
|
|
66862
|
-
robot.position = { x: lx, y: ly, theta: (
|
|
66975
|
+
robot.position = { x: lx, y: ly, theta: (num2(loc.yaw ?? loc.r) ?? 0) * Math.PI / 180 };
|
|
66863
66976
|
robot.planPosition = padbotPlanShare(map, lx, ly);
|
|
66864
66977
|
}
|
|
66865
66978
|
const mo = motions.get(`${account}:${robotSn}`);
|
|
@@ -66879,7 +66992,7 @@ function createPadbotAdapter(credentials, options = {}) {
|
|
|
66879
66992
|
const onCharger = [1, 2].includes(st["1002"]?.chargingState);
|
|
66880
66993
|
const pile = onCharger && !robot.position ? padbotChargingPoint(map) : null;
|
|
66881
66994
|
if (pile) {
|
|
66882
|
-
robot.position = { x: pile.worldX, y: pile.worldY, theta: (
|
|
66995
|
+
robot.position = { x: pile.worldX, y: pile.worldY, theta: (num2(pile.yaw) ?? 0) * Math.PI / 180 };
|
|
66883
66996
|
robot.planPosition = padbotPlanShare(map, pile.worldX, pile.worldY);
|
|
66884
66997
|
if (!going || going.done)
|
|
66885
66998
|
robot.statusName = `${robot.statusName} \xB7 At charger`;
|
|
@@ -66979,12 +67092,12 @@ function createPadbotAdapter(credentials, options = {}) {
|
|
|
66979
67092
|
throw new BadRequestError137(block);
|
|
66980
67093
|
lastFailure.delete(`${account}:${robotSn}`);
|
|
66981
67094
|
const heard = padbotLive(account, robotSn)?.pose;
|
|
66982
|
-
const lx =
|
|
66983
|
-
const ly =
|
|
67095
|
+
const lx = num2(where?.loc?.worldX);
|
|
67096
|
+
const ly = num2(where?.loc?.worldY);
|
|
66984
67097
|
let target = null;
|
|
66985
67098
|
if (command.kind === "go-to-point") {
|
|
66986
67099
|
const pt = (where?.all ?? []).flatMap((m) => Array.isArray(m?.targetPoints) ? m.targetPoints : []).find((t) => t?.targetPointId === command.targetPointId);
|
|
66987
|
-
target = { name: String(pt?.name || "the chosen point"), x:
|
|
67100
|
+
target = { name: String(pt?.name || "the chosen point"), x: num2(pt?.worldX), y: num2(pt?.worldY) };
|
|
66988
67101
|
}
|
|
66989
67102
|
motion = {
|
|
66990
67103
|
kind: command.kind,
|
|
@@ -67203,6 +67316,7 @@ function fleetStateItem(id, s, lastSeenAt) {
|
|
|
67203
67316
|
fault: s.fault,
|
|
67204
67317
|
capabilities: s.capabilities,
|
|
67205
67318
|
profile: s.profile,
|
|
67319
|
+
cleaning: s.cleaning ?? null,
|
|
67206
67320
|
lastSeenAt: lastSeenAt ? new Date(lastSeenAt) : null
|
|
67207
67321
|
};
|
|
67208
67322
|
}
|
|
@@ -67331,7 +67445,8 @@ function useRobotFleetService(deps) {
|
|
|
67331
67445
|
planPosition: found.planPosition ?? null,
|
|
67332
67446
|
fault,
|
|
67333
67447
|
capabilities: manifest.capabilities,
|
|
67334
|
-
profile: manifest.profile
|
|
67448
|
+
profile: manifest.profile,
|
|
67449
|
+
cleaning: manifest.capabilities.waterTanks === true && found.online ? found.cleaning ?? null : null
|
|
67335
67450
|
};
|
|
67336
67451
|
}
|
|
67337
67452
|
async function getMaps(robot) {
|
|
@@ -68036,11 +68151,11 @@ function decodeTrackingFrame(data) {
|
|
|
68036
68151
|
if (!parsed || typeof parsed !== "object")
|
|
68037
68152
|
return null;
|
|
68038
68153
|
const frame2 = parsed;
|
|
68039
|
-
const
|
|
68040
|
-
const x =
|
|
68041
|
-
const y =
|
|
68042
|
-
const theta =
|
|
68043
|
-
const statusFlag =
|
|
68154
|
+
const num4 = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
68155
|
+
const x = num4(frame2.x);
|
|
68156
|
+
const y = num4(frame2.y);
|
|
68157
|
+
const theta = num4(frame2.theta);
|
|
68158
|
+
const statusFlag = num4(frame2.status);
|
|
68044
68159
|
if (x === null || y === null || theta === null || statusFlag === null) {
|
|
68045
68160
|
return null;
|
|
68046
68161
|
}
|
|
@@ -68564,22 +68679,22 @@ function useRobotFaultSweep(deps) {
|
|
|
68564
68679
|
if (!robot)
|
|
68565
68680
|
return;
|
|
68566
68681
|
out.robots++;
|
|
68567
|
-
let
|
|
68682
|
+
let reading2;
|
|
68568
68683
|
try {
|
|
68569
68684
|
const state = deps?.readState ? await deps.readState(robot) : await readRobotState(robot, { timeoutMs: cfg.timeoutMs });
|
|
68570
68685
|
if (deps?.readState)
|
|
68571
68686
|
rememberRobotState(robot, state);
|
|
68572
|
-
|
|
68573
|
-
if (
|
|
68574
|
-
Object.assign(
|
|
68687
|
+
reading2 = { ok: true, online: state.online === true, fault: state.fault ?? null };
|
|
68688
|
+
if (reading2.fault)
|
|
68689
|
+
Object.assign(reading2.fault, { floorNo: state.floorNo ?? null });
|
|
68575
68690
|
} catch (error) {
|
|
68576
68691
|
if (deps?.readState)
|
|
68577
68692
|
rememberRobotState(robot, null);
|
|
68578
|
-
|
|
68693
|
+
reading2 = { ok: false, error: error?.message ?? "no answer" };
|
|
68579
68694
|
}
|
|
68580
68695
|
const records = byRobot2.get(String(robot._id)) ?? [];
|
|
68581
68696
|
const offlineRec = records.find((r) => r.code === OFFLINE_FAULT_CODE);
|
|
68582
|
-
const plan = planFaultChanges(records,
|
|
68697
|
+
const plan = planFaultChanges(records, reading2);
|
|
68583
68698
|
for (const id of plan.clear) {
|
|
68584
68699
|
await repo.clearFault(id);
|
|
68585
68700
|
out.cleared++;
|
|
@@ -68592,7 +68707,7 @@ function useRobotFaultSweep(deps) {
|
|
|
68592
68707
|
out.alerts++;
|
|
68593
68708
|
}
|
|
68594
68709
|
for (const f of plan.open) {
|
|
68595
|
-
const detail =
|
|
68710
|
+
const detail = reading2.ok && reading2.fault?.code === f.code ? reading2.fault : null;
|
|
68596
68711
|
const r = await openFaultRecord(robot, detail ? { ...detail, ...f } : f, { notify: true, notifyFn: deps?.notifyFn });
|
|
68597
68712
|
if (r.opened)
|
|
68598
68713
|
out.opened++;
|
|
@@ -69910,7 +70025,7 @@ function measurementScale(vertices, meas) {
|
|
|
69910
70025
|
return est.length ? est.reduce((n, v) => n + v, 0) / est.length : null;
|
|
69911
70026
|
}
|
|
69912
70027
|
var pval = (p) => Array.isArray(p) ? p[1] : p;
|
|
69913
|
-
var
|
|
70028
|
+
var num3 = (v, fallback = 0) => v !== null && v !== "" && Number.isFinite(Number(v)) ? Number(v) : fallback;
|
|
69914
70029
|
var str60 = (v) => String(v ?? "").slice(0, 60);
|
|
69915
70030
|
function decodeParams(raw) {
|
|
69916
70031
|
const out = {};
|
|
@@ -69930,7 +70045,7 @@ function fileVertexParams(raw) {
|
|
|
69930
70045
|
const v = raw[k];
|
|
69931
70046
|
if (v === void 0 || v === null)
|
|
69932
70047
|
continue;
|
|
69933
|
-
out[k] = k.startsWith("is_") ? Boolean(v) : k === "merge_radius" ? clamp3(
|
|
70048
|
+
out[k] = k.startsWith("is_") ? Boolean(v) : k === "merge_radius" ? clamp3(num3(v), 0, 100) : str60(v);
|
|
69934
70049
|
}
|
|
69935
70050
|
return out;
|
|
69936
70051
|
}
|
|
@@ -70003,14 +70118,14 @@ function fromBuildingYaml(doc) {
|
|
|
70003
70118
|
const raw = names.map((name) => {
|
|
70004
70119
|
const y = doc.levels[name] ?? {};
|
|
70005
70120
|
const vertices = (Array.isArray(y.vertices) ? y.vertices : []).map((v) => ({
|
|
70006
|
-
x:
|
|
70007
|
-
y:
|
|
70121
|
+
x: num3(v?.[0]),
|
|
70122
|
+
y: num3(v?.[1]) * flip,
|
|
70008
70123
|
name: str60(v?.[3]),
|
|
70009
70124
|
params: fileVertexParams(decodeParams(v?.[4]))
|
|
70010
70125
|
}));
|
|
70011
|
-
const fiducials = (Array.isArray(y.fiducials) ? y.fiducials : []).map((f) => ({ x:
|
|
70012
|
-
const meas = edgeList(y.measurements).map((e) => [e.a, e.b,
|
|
70013
|
-
return { name: str60(name), y, vertices, fiducials, meas, elevation:
|
|
70126
|
+
const fiducials = (Array.isArray(y.fiducials) ? y.fiducials : []).map((f) => ({ x: num3(f?.[0]), y: num3(f?.[1]) * flip, name: str60(f?.[2]) }));
|
|
70127
|
+
const meas = edgeList(y.measurements).map((e) => [e.a, e.b, num3(e.p.distance)]);
|
|
70128
|
+
return { name: str60(name), y, vertices, fiducials, meas, elevation: num3(y.elevation) };
|
|
70014
70129
|
});
|
|
70015
70130
|
const refName = raw.some((l) => l.name === doc.reference_level_name) ? String(doc.reference_level_name) : raw[0].name;
|
|
70016
70131
|
const ref = raw.find((l) => l.name === refName);
|
|
@@ -70084,20 +70199,20 @@ function fromBuildingYaml(doc) {
|
|
|
70084
70199
|
const extra = {};
|
|
70085
70200
|
if (e.p.texture_name !== void 0 && e.p.texture_name !== "default")
|
|
70086
70201
|
extra.textureName = str60(e.p.texture_name);
|
|
70087
|
-
if (e.p.alpha !== void 0 &&
|
|
70088
|
-
extra.alpha = clamp3(
|
|
70089
|
-
if (e.p.texture_height !== void 0 &&
|
|
70090
|
-
extra.textureHeight = clamp3(
|
|
70091
|
-
if (e.p.texture_width !== void 0 &&
|
|
70092
|
-
extra.textureWidth = clamp3(
|
|
70093
|
-
if (e.p.texture_scale !== void 0 &&
|
|
70094
|
-
extra.textureScale = clamp3(
|
|
70202
|
+
if (e.p.alpha !== void 0 && num3(e.p.alpha, 1) !== 1)
|
|
70203
|
+
extra.alpha = clamp3(num3(e.p.alpha, 1), 0, 1);
|
|
70204
|
+
if (e.p.texture_height !== void 0 && num3(e.p.texture_height, 2.5) !== 2.5)
|
|
70205
|
+
extra.textureHeight = clamp3(num3(e.p.texture_height, 2.5), 0, 100);
|
|
70206
|
+
if (e.p.texture_width !== void 0 && num3(e.p.texture_width, 1) !== 1)
|
|
70207
|
+
extra.textureWidth = clamp3(num3(e.p.texture_width, 1), 0, 100);
|
|
70208
|
+
if (e.p.texture_scale !== void 0 && num3(e.p.texture_scale, 1) !== 1)
|
|
70209
|
+
extra.textureScale = clamp3(num3(e.p.texture_scale, 1), 0, 100);
|
|
70095
70210
|
level2.walls.push({ v1: ids2[e.a], v2: ids2[e.b], ...extra });
|
|
70096
70211
|
}
|
|
70097
70212
|
for (const e of edgeList(lv.y.doors).filter(ok)) {
|
|
70098
70213
|
const type = String(e.p.type ?? "hinged");
|
|
70099
|
-
const degrees = clamp3(
|
|
70100
|
-
const ratio = clamp3(
|
|
70214
|
+
const degrees = clamp3(num3(e.p.motion_degrees, 90), -360, 360);
|
|
70215
|
+
const ratio = clamp3(num3(e.p.right_left_ratio, 1), 0, 10);
|
|
70101
70216
|
const plugin = str60(e.p.plugin ?? "normal");
|
|
70102
70217
|
level2.doors.push({
|
|
70103
70218
|
name: str60(e.p.name ?? "").trim() || `door_${level2.doors.length + 1}`,
|
|
@@ -70106,13 +70221,13 @@ function fromBuildingYaml(doc) {
|
|
|
70106
70221
|
type: ["hinged", "double_hinged", "sliding", "double_sliding"].includes(type) ? type : "hinged",
|
|
70107
70222
|
...e.p.motion_axis === "end" ? { motionAxis: "end" } : {},
|
|
70108
70223
|
...degrees !== 90 ? { motionDegrees: degrees } : {},
|
|
70109
|
-
...
|
|
70224
|
+
...num3(e.p.motion_direction, 1) < 0 ? { motionDirection: -1 } : {},
|
|
70110
70225
|
...ratio !== 1 ? { rightLeftRatio: ratio } : {},
|
|
70111
70226
|
...plugin !== "normal" ? { plugin } : {}
|
|
70112
70227
|
});
|
|
70113
70228
|
}
|
|
70114
70229
|
for (const e of edgeList(lv.y.lanes).filter(ok)) {
|
|
70115
|
-
const gi = Math.round(
|
|
70230
|
+
const gi = Math.round(num3(e.p.graph_idx, 0));
|
|
70116
70231
|
if (gi < 0 || gi > 8) {
|
|
70117
70232
|
warnings.push(`Floor ${lv.name}: a lane on graph ${gi} was skipped (graphs 0-8 only).`);
|
|
70118
70233
|
continue;
|
|
@@ -70125,14 +70240,14 @@ function fromBuildingYaml(doc) {
|
|
|
70125
70240
|
graphIdx: gi,
|
|
70126
70241
|
bidirectional: e.p.bidirectional === true,
|
|
70127
70242
|
...orientation ? { orientation } : {},
|
|
70128
|
-
...
|
|
70243
|
+
...num3(e.p.speed_limit) > 0 ? { speedLimit: clamp3(num3(e.p.speed_limit), 0, 20) } : {},
|
|
70129
70244
|
...e.p.mutex ? { mutex: str60(e.p.mutex) } : {},
|
|
70130
70245
|
...e.p.demo_mock_floor_name ? { demoMockFloorName: str60(e.p.demo_mock_floor_name) } : {},
|
|
70131
70246
|
...e.p.demo_mock_lift_name ? { demoMockLiftName: str60(e.p.demo_mock_lift_name) } : {}
|
|
70132
70247
|
});
|
|
70133
70248
|
}
|
|
70134
70249
|
for (const e of edgeList(lv.y.measurements).filter(ok)) {
|
|
70135
|
-
const d =
|
|
70250
|
+
const d = num3(e.p.distance);
|
|
70136
70251
|
if (d >= 0.01)
|
|
70137
70252
|
level2.measurements.push({ v1: ids2[e.a], v2: ids2[e.b], distanceM: Math.min(d, 1e4) });
|
|
70138
70253
|
}
|
|
@@ -70163,14 +70278,14 @@ function fromBuildingYaml(doc) {
|
|
|
70163
70278
|
if (ly?.reference_floor_name && !levelNames.has(ly.reference_floor_name)) {
|
|
70164
70279
|
warnings.push(`Lift ${str60(liftName)}: its reference floor "${str60(ly.reference_floor_name)}" is not in the file; ${refName} was used.`);
|
|
70165
70280
|
}
|
|
70166
|
-
const c = applyXform(xf(refFloor), { x:
|
|
70281
|
+
const c = applyXform(xf(refFloor), { x: num3(ly?.x), y: num3(ly?.y) * flip });
|
|
70167
70282
|
const doors = Object.entries(ly?.doors ?? {}).slice(0, 8).map(([dn, d]) => ({
|
|
70168
70283
|
name: str60(dn),
|
|
70169
|
-
type: MSG_LIFT_DOOR_TYPE[Math.round(
|
|
70170
|
-
x: r3(clamp3(
|
|
70171
|
-
y: r3(clamp3(
|
|
70172
|
-
widthM: r3(clamp3(
|
|
70173
|
-
axisYawRad: clamp3(
|
|
70284
|
+
type: MSG_LIFT_DOOR_TYPE[Math.round(num3(d?.door_type, 2))] ?? "double_sliding",
|
|
70285
|
+
x: r3(clamp3(num3(d?.x), -20, 20)),
|
|
70286
|
+
y: r3(clamp3(num3(d?.y), -20, 20)),
|
|
70287
|
+
widthM: r3(clamp3(num3(d?.width, 1), 0.3, 10)),
|
|
70288
|
+
axisYawRad: clamp3(num3(d?.motion_axis_orientation), -10, 10)
|
|
70174
70289
|
}));
|
|
70175
70290
|
const doorNames = new Set(doors.map((d) => d.name));
|
|
70176
70291
|
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)) }));
|
|
@@ -70179,9 +70294,9 @@ function fromBuildingYaml(doc) {
|
|
|
70179
70294
|
name: str60(liftName),
|
|
70180
70295
|
x: r3(c.x),
|
|
70181
70296
|
y: r3(c.y),
|
|
70182
|
-
yawRad: clamp3(
|
|
70183
|
-
widthM: r3(clamp3(
|
|
70184
|
-
depthM: r3(clamp3(
|
|
70297
|
+
yawRad: clamp3(num3(ly?.yaw), -10, 10),
|
|
70298
|
+
widthM: r3(clamp3(num3(ly?.width, 2), 0.3, 20)),
|
|
70299
|
+
depthM: r3(clamp3(num3(ly?.depth, 2), 0.3, 20)),
|
|
70185
70300
|
referenceFloor: refFloor,
|
|
70186
70301
|
...floorName(ly?.initial_floor_name) ? { initialFloor: floorName(ly.initial_floor_name) } : {},
|
|
70187
70302
|
...floorName(ly?.lowest_floor) ? { lowestFloor: floorName(ly.lowest_floor) } : {},
|
|
@@ -70235,7 +70350,7 @@ function fromNavGraph(doc, graphIdx) {
|
|
|
70235
70350
|
level2.vertices = verts.map((v, k) => {
|
|
70236
70351
|
const p = v?.[2] && typeof v[2] === "object" ? v[2] : {};
|
|
70237
70352
|
const params = fileVertexParams(p);
|
|
70238
|
-
return { id: `v${k + 1}`, x: r3(
|
|
70353
|
+
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 } : {} };
|
|
70239
70354
|
});
|
|
70240
70355
|
if (Array.isArray(ly?.lanes) && ly.lanes.length > 1e4)
|
|
70241
70356
|
throw new RmfImportError(`Floor ${str60(name)} has more than 10000 one-way lanes - more than a building map can hold.`);
|
|
@@ -70275,7 +70390,7 @@ function fromNavGraph(doc, graphIdx) {
|
|
|
70275
70390
|
graphIdx,
|
|
70276
70391
|
bidirectional,
|
|
70277
70392
|
...o === "forward" || o === "backward" ? { orientation: o } : {},
|
|
70278
|
-
...
|
|
70393
|
+
...num3(p.speed_limit) > 0 ? { speedLimit: clamp3(num3(p.speed_limit), 0, 20) } : {},
|
|
70279
70394
|
...p.mutex ? { mutex: str60(p.mutex) } : {},
|
|
70280
70395
|
...p.demo_mock_floor_name ? { demoMockFloorName: str60(p.demo_mock_floor_name) } : {},
|
|
70281
70396
|
...p.demo_mock_lift_name ? { demoMockLiftName: str60(p.demo_mock_lift_name) } : {}
|
|
@@ -82668,7 +82783,7 @@ function useAccessManagementController() {
|
|
|
82668
82783
|
liftName,
|
|
82669
82784
|
unit = [],
|
|
82670
82785
|
createdAt,
|
|
82671
|
-
updatedAt,
|
|
82786
|
+
updatedAt: updatedAt2,
|
|
82672
82787
|
startDate,
|
|
82673
82788
|
endDate,
|
|
82674
82789
|
isWinsland
|
|
@@ -82704,7 +82819,7 @@ function useAccessManagementController() {
|
|
|
82704
82819
|
startDate,
|
|
82705
82820
|
endDate,
|
|
82706
82821
|
createdAt,
|
|
82707
|
-
updatedAt,
|
|
82822
|
+
updatedAt: updatedAt2,
|
|
82708
82823
|
isWinsland
|
|
82709
82824
|
});
|
|
82710
82825
|
if (error) {
|
|
@@ -82726,7 +82841,7 @@ function useAccessManagementController() {
|
|
|
82726
82841
|
startDate,
|
|
82727
82842
|
endDate,
|
|
82728
82843
|
createdAt,
|
|
82729
|
-
updatedAt,
|
|
82844
|
+
updatedAt: updatedAt2,
|
|
82730
82845
|
isWinsland
|
|
82731
82846
|
});
|
|
82732
82847
|
return res.status(201).json({
|
|
@@ -106743,6 +106858,7 @@ export {
|
|
|
106743
106858
|
OUNITECH_BRAND,
|
|
106744
106859
|
OUNITECH_BRAND_DEFINITION,
|
|
106745
106860
|
OUNITECH_CAPABILITIES,
|
|
106861
|
+
OUNITECH_FRESH_MS,
|
|
106746
106862
|
OUNITECH_PENDING_COMMANDS,
|
|
106747
106863
|
OUNITECH_REGION_BASE_URLS,
|
|
106748
106864
|
OUNITECH_TIMESTAMP_FORMAT,
|
|
@@ -107109,7 +107225,9 @@ export {
|
|
|
107109
107225
|
orgQualifiesForOwnerRepair,
|
|
107110
107226
|
orgRoleSets,
|
|
107111
107227
|
orgSchema,
|
|
107228
|
+
ounitechCleaning,
|
|
107112
107229
|
ounitechFault,
|
|
107230
|
+
ounitechJobWords,
|
|
107113
107231
|
ounitechRobotFromHomeRow,
|
|
107114
107232
|
overnight_parking_requests_namespace_collection,
|
|
107115
107233
|
padbotAccountKey,
|