@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/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, reading) {
11260
+ function planFaultChanges(open, reading2) {
11258
11261
  const byCode = new Map(open.map((r) => [r.code, r]));
11259
11262
  const want = [];
11260
- const offline = !reading.ok || reading.online === false;
11263
+ const offline = !reading2.ok || reading2.online === false;
11261
11264
  if (offline) {
11262
- const reason = reading.ok ? "" : String(reading.error ?? "").slice(0, 200);
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 = reading.ok && reading.fault?.code ? reading.fault : null;
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 num3 = (v, def, min, max) => {
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 = num3(env2.ROBOT_FAULT_SWEEP_SECONDS, 60, 10, 3600);
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: num3(env2.ROBOT_FAULT_SWEEP_CONCURRENCY, 4, 1, 16),
11313
- timeoutMs: num3(env2.ROBOT_FAULT_SWEEP_TIMEOUT_MS, 1e4, 1e3, 6e4),
11314
- offlineAlertMinutes: num3(env2.ROBOT_OFFLINE_ALERT_MINUTES, 10, 1, 1440)
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 updatedAt = (/* @__PURE__ */ new Date()).toISOString();
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 updatedAt = (/* @__PURE__ */ new Date()).toISOString();
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 = 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 = 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(num3, length) {
57288
- return num3.toString(16).padStart(length * 2, "0");
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 num3 = Math.floor(Math.random() * 65536);
57469
- return num3.toString().padStart(10, "0");
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 num3 = parseInt(prevCard, 10) + 1;
58712
+ let num4 = parseInt(prevCard, 10) + 1;
58710
58713
  while (availableCardNo.length < (unit.length > 0 ? unit.length : quantity)) {
58711
- if (num3 === parseInt(currentCard, 10)) {
58712
- num3++;
58714
+ if (num4 === parseInt(currentCard, 10)) {
58715
+ num4++;
58713
58716
  }
58714
- availableCardNo.push(num3);
58715
- num3++;
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 num3 = (k) => typeof b[k] === "number" && Number.isFinite(b[k]);
64435
- if (!num3("x") || !num3("y"))
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") && !num3("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 (!num3("theta"))
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 ounitechRobotFromHomeRow(row) {
64883
- const st = row.robotState ?? {};
64884
- const flag = finite(st.statusFlag) ? st.statusFlag : void 0;
64885
- const online = flag !== void 0 && flag !== 99;
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 = propertyNumber(row, "battery-percent") ?? (finite(st.battery) ? st.battery : null);
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 === void 0 ? "Unknown" : ROBOT_STATUS_NAMES[flag] ?? `Status ${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
- return {
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 && finite(st.x) && finite(st.y) ? { x: st.x, y: st.y, theta: finite(st.theta) ? st.theta : 0 } : null
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
- const robot = ounitechRobotFromHomeRow(row);
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
- status: finite(s.statusFlag) ? ROBOT_STATUS_NAMES[s.statusFlag] ?? null : null,
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 num = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
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 = num(states["1001"]?.batteryPercent);
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 = num(states["1001"]?.batteryPercent);
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: num(st["1001"]?.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 = num(net?.wifi?.signalStrength);
67239
+ const wifi = num2(net?.wifi?.signalStrength);
67124
67240
  if (wifi !== null)
67125
67241
  return say("Wi-Fi", wifi);
67126
- const cell = num(net?.cellular?.signalStrength);
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 = num(frame2?.width), h = num(frame2?.height), r = num(frame2?.resolution);
67131
- const wx = num(x), wy = num(y);
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 - (num(frame2?.originX) ?? 0)) / r;
67135
- const pyUp = (wy - (num(frame2?.originY) ?? 0)) / r;
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 && num(t?.worldX) !== null && num(t?.worldY) !== null
67281
+ (t) => Number(t?.targetPointType) === 10 && num2(t?.worldX) !== null && num2(t?.worldY) !== null
67166
67282
  );
67167
- return piles.length === 1 ? { worldX: num(piles[0].worldX), worldY: num(piles[0].worldY), yaw: piles[0].yaw } : null;
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: num(r?.duration),
67263
- distanceM: num(r?.mileage),
67264
- alarmCount: num(r?.alarmCount) ?? 0
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: num(d?.centerTemperature),
67275
- maxTempC: num(d?.maxTemperature)
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: num(data?.totalItems) ?? 0,
67282
- pages: num(data?.totalPages) ?? 0
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 : num(st["1001"]?.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 = num(loc?.worldX ?? loc?.x);
67532
- const ly = num(loc?.worldY ?? loc?.y);
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: (num(loc.yaw ?? loc.r) ?? 0) * Math.PI / 180 };
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: (num(pile.yaw) ?? 0) * Math.PI / 180 };
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 = num(where?.loc?.worldX);
67660
- const ly = num(where?.loc?.worldY);
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: num(pt?.worldX), y: num(pt?.worldY) };
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 num3 = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
68717
- const x = num3(frame2.x);
68718
- const y = num3(frame2.y);
68719
- const theta = num3(frame2.theta);
68720
- const statusFlag = num3(frame2.status);
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 reading;
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
- reading = { ok: true, online: state.online === true, fault: state.fault ?? null };
69250
- if (reading.fault)
69251
- Object.assign(reading.fault, { floorNo: state.floorNo ?? null });
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
- reading = { ok: false, error: error?.message ?? "no answer" };
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, reading);
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 = reading.ok && reading.fault?.code === f.code ? reading.fault : null;
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 num2 = (v, fallback = 0) => v !== null && v !== "" && Number.isFinite(Number(v)) ? Number(v) : fallback;
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(num2(v), 0, 100) : str60(v);
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: num2(v?.[0]),
70684
- y: num2(v?.[1]) * flip,
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: num2(f?.[0]), y: num2(f?.[1]) * flip, name: str60(f?.[2]) }));
70689
- const meas = edgeList(y.measurements).map((e) => [e.a, e.b, num2(e.p.distance)]);
70690
- return { name: str60(name), y, vertices, fiducials, meas, elevation: num2(y.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 && num2(e.p.alpha, 1) !== 1)
70765
- extra.alpha = clamp3(num2(e.p.alpha, 1), 0, 1);
70766
- if (e.p.texture_height !== void 0 && num2(e.p.texture_height, 2.5) !== 2.5)
70767
- extra.textureHeight = clamp3(num2(e.p.texture_height, 2.5), 0, 100);
70768
- if (e.p.texture_width !== void 0 && num2(e.p.texture_width, 1) !== 1)
70769
- extra.textureWidth = clamp3(num2(e.p.texture_width, 1), 0, 100);
70770
- if (e.p.texture_scale !== void 0 && num2(e.p.texture_scale, 1) !== 1)
70771
- extra.textureScale = clamp3(num2(e.p.texture_scale, 1), 0, 100);
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(num2(e.p.motion_degrees, 90), -360, 360);
70777
- const ratio = clamp3(num2(e.p.right_left_ratio, 1), 0, 10);
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
- ...num2(e.p.motion_direction, 1) < 0 ? { motionDirection: -1 } : {},
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(num2(e.p.graph_idx, 0));
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
- ...num2(e.p.speed_limit) > 0 ? { speedLimit: clamp3(num2(e.p.speed_limit), 0, 20) } : {},
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 = num2(e.p.distance);
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: num2(ly?.x), y: num2(ly?.y) * flip });
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(num2(d?.door_type, 2))] ?? "double_sliding",
70847
- x: r3(clamp3(num2(d?.x), -20, 20)),
70848
- y: r3(clamp3(num2(d?.y), -20, 20)),
70849
- widthM: r3(clamp3(num2(d?.width, 1), 0.3, 10)),
70850
- axisYawRad: clamp3(num2(d?.motion_axis_orientation), -10, 10)
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(num2(ly?.yaw), -10, 10),
70860
- widthM: r3(clamp3(num2(ly?.width, 2), 0.3, 20)),
70861
- depthM: r3(clamp3(num2(ly?.depth, 2), 0.3, 20)),
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(num2(v?.[0])), y: r3(num2(v?.[1])), ...p.name ? { name: str60(p.name) } : {}, ...Object.keys(params).length ? { params } : {} };
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
- ...num2(p.speed_limit) > 0 ? { speedLimit: clamp3(num2(p.speed_limit), 0, 20) } : {},
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,