@robotical/webapp-types 3.18.13 → 3.19.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.
Files changed (31) hide show
  1. package/dist-types/src/application/ApplicationManager/ApplicationManager.d.ts +21 -10
  2. package/dist-types/src/application/ApplicationManager/ApplicationManager.js +297 -83
  3. package/dist-types/src/application/RAFTs/Cog/Cog.d.ts +2 -0
  4. package/dist-types/src/application/RAFTs/Cog/Cog.js +3 -0
  5. package/dist-types/src/application/RAFTs/Marty/Marty.js +7 -3
  6. package/dist-types/src/application/RAFTs/Marty/MartyWifiManager.d.ts +6 -18
  7. package/dist-types/src/application/RAFTs/Marty/MartyWifiManager.js +25 -274
  8. package/dist-types/src/application/RAFTs/RAFT.d.ts +8 -2
  9. package/dist-types/src/application/RAFTs/RAFT.js +23 -4
  10. package/dist-types/src/application/RAFTs/RaftWifiManager.d.ts +24 -0
  11. package/dist-types/src/application/RAFTs/RaftWifiManager.js +329 -0
  12. package/dist-types/src/application/communicators/WrapperCommunicator.js +7 -3
  13. package/dist-types/src/components/modals/VerificationModal/index.js +4 -1
  14. package/dist-types/src/components/modals/WifiConnectionModal/index.d.ts +6 -0
  15. package/dist-types/src/components/modals/WifiConnectionModal/index.js +41 -0
  16. package/dist-types/src/i18n.js +43 -3
  17. package/dist-types/src/store/ConnectionMethodPreference.d.ts +7 -0
  18. package/dist-types/src/store/ConnectionMethodPreference.js +44 -0
  19. package/dist-types/src/store/SelectedRaftContext.d.ts +3 -1
  20. package/dist-types/src/store/SelectedRaftContext.js +1 -1
  21. package/dist-types/src/types/raft.d.ts +23 -0
  22. package/dist-types/src/utils/helpers/wifi-configuration-subtitle-gen.d.ts +2 -1
  23. package/dist-types/src/utils/helpers/wifi-configuration-subtitle-gen.js +26 -22
  24. package/dist-types/src/utils/wifi-connection.d.ts +18 -0
  25. package/dist-types/src/utils/wifi-connection.js +97 -0
  26. package/dist-types/src/wrapper-app/WrapperAppManager.d.ts +3 -2
  27. package/dist-types/src/wrapper-app/WrapperAppManager.js +149 -45
  28. package/dist-types/src/wrapper-app/communicators/WebAppCommunicator.js +1 -1
  29. package/dist-types/src/wrapper-app/connectors/ConnectorFactory.d.ts +1 -0
  30. package/dist-types/src/wrapper-app/connectors/ConnectorFactory.js +15 -11
  31. package/package.json +1 -1
@@ -1,3 +1,14 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
1
12
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
13
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
14
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -36,7 +47,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
36
47
  };
37
48
  import { createElement } from "react";
38
49
  import modalState, { secondaryModalState } from "../../state-observables/modal/ModalState";
39
- import { RaftConnectionMethod, RaftTypeE } from "../../types/raft";
50
+ import { RaftConnectionMethod, RaftTypeE, } from "../../types/raft";
40
51
  import WebAppCommunicator from "../../wrapper-app/communicators/WebAppCommunicator";
41
52
  import RAFT from "../RAFTs/RAFT";
42
53
  import Marty from "../RAFTs/Marty/Marty";
@@ -56,10 +67,13 @@ import ConnectingLoadingSpinnerModal from "../../components/modals/ConnectingLoa
56
67
  import draggableModalState from "../../state-observables/modal/DraggableModalState";
57
68
  import SensorsDashboardModal from "../../components/modals/ SensorsDashboardModal";
58
69
  import LEDLightsOrQRVerificationModal from "../../components/modals/LEDLightsOrQRVerificationModal";
70
+ import WifiConnectionModal from "../../components/modals/WifiConnectionModal";
59
71
  import { CarouselNavigatorManager } from "../../utils/CarouselNavigatorManager";
60
72
  import i18n from "../../i18n";
61
73
  import InUnpluggedModalContent from "../../components/modals/InUnplugged";
62
74
  import { cogKeepAwakeManager, } from "../../features/cog-keep-awake";
75
+ import { normalizeWifiLocator } from "../../utils/wifi-connection";
76
+ import { ConnectionMethodPreference, getConnectionMethodPreference, } from "../../store/ConnectionMethodPreference";
63
77
  var SHOW_LOGS = true;
64
78
  var TAG = "ApplicationManager";
65
79
  var UNSUPPORTED_WEB_BLUETOOTH_BROWSER_MESSAGE = "This browser can't connect to Marty or Cog over Bluetooth. Please use Chrome or Edge, or use the iPad app.";
@@ -95,6 +109,7 @@ var ApplicationManager = /** @class */ (function () {
95
109
  this._connectAttemptSequence = 0;
96
110
  this._activeConnectAttemptId = null;
97
111
  this._disconnectPromises = new Map();
112
+ this._pendingWifiLocators = new Set();
98
113
  this.connectedRaftsContext = [];
99
114
  this.returnToMainApp = function () { };
100
115
  // Carousel navigators
@@ -254,6 +269,8 @@ var ApplicationManager = /** @class */ (function () {
254
269
  type: raft.type,
255
270
  name: name,
256
271
  isSelected: true,
272
+ connectionMethod: raft.connectionMethod,
273
+ connectionLocator: raft.connectionLocator,
257
274
  });
258
275
  return [2 /*return*/, true];
259
276
  }
@@ -296,82 +313,118 @@ var ApplicationManager = /** @class */ (function () {
296
313
  });
297
314
  };
298
315
  //======================//
299
- /* MARTY WIFI */
316
+ /* RAFT WIFI */
300
317
  //======================//
301
- ApplicationManager.prototype.pauseWifiConnectionMarty = function (raftId, pause) {
318
+ ApplicationManager.prototype.getWifiManager = function (raftId) {
319
+ var raft = this.connectedRafts[raftId];
320
+ if ((raft === null || raft === void 0 ? void 0 : raft.type) === RaftTypeE.MARTY) {
321
+ return raft.wifiManager;
322
+ }
323
+ if ((raft === null || raft === void 0 ? void 0 : raft.type) === RaftTypeE.COG) {
324
+ return raft.wifiManager;
325
+ }
326
+ Logger.warn(SHOW_LOGS, TAG, "RAFT with id ".concat(raftId, " does not support Wi-Fi provisioning"));
327
+ return undefined;
328
+ };
329
+ ApplicationManager.prototype.pauseWifiConnection = function (raftId, pause) {
330
+ var _a, _b;
302
331
  return __awaiter(this, void 0, void 0, function () {
303
- var raft;
304
- return __generator(this, function (_a) {
305
- raft = this.connectedRafts[raftId];
306
- if (raft && raft.type === RaftTypeE.MARTY) {
307
- return [2 /*return*/, raft.wifiManager.pauseWifiConnection(pause)];
308
- }
309
- Logger.warn(SHOW_LOGS, TAG, "RAFT with id: ".concat(raftId, " doesn't exist or is not a Marty"));
310
- return [2 /*return*/, false];
332
+ return __generator(this, function (_c) {
333
+ return [2 /*return*/, (_b = (_a = this.getWifiManager(raftId)) === null || _a === void 0 ? void 0 : _a.pauseWifiConnection(pause)) !== null && _b !== void 0 ? _b : false];
334
+ });
335
+ });
336
+ };
337
+ ApplicationManager.prototype.getCachedWifiStatus = function (raftId) {
338
+ var _a;
339
+ return (_a = this.getWifiManager(raftId)) === null || _a === void 0 ? void 0 : _a.getCachedWifiStatus();
340
+ };
341
+ ApplicationManager.prototype.wifiConnect = function (raftId, ssid, password) {
342
+ var _a, _b;
343
+ return __awaiter(this, void 0, void 0, function () {
344
+ return __generator(this, function (_c) {
345
+ return [2 /*return*/, (_b = (_a = this.getWifiManager(raftId)) === null || _a === void 0 ? void 0 : _a.wifiConnect(ssid, password)) !== null && _b !== void 0 ? _b : false];
346
+ });
347
+ });
348
+ };
349
+ ApplicationManager.prototype.wifiDisconnect = function (raftId) {
350
+ var _a, _b;
351
+ return __awaiter(this, void 0, void 0, function () {
352
+ return __generator(this, function (_c) {
353
+ return [2 /*return*/, (_b = (_a = this.getWifiManager(raftId)) === null || _a === void 0 ? void 0 : _a.wifiDisconnect()) !== null && _b !== void 0 ? _b : false];
354
+ });
355
+ });
356
+ };
357
+ ApplicationManager.prototype.getWiFiConnStatus = function (raftId) {
358
+ var _a, _b;
359
+ return __awaiter(this, void 0, void 0, function () {
360
+ return __generator(this, function (_c) {
361
+ return [2 /*return*/, (_b = (_a = this.getWifiManager(raftId)) === null || _a === void 0 ? void 0 : _a.getWiFiConnStatus()) !== null && _b !== void 0 ? _b : null];
362
+ });
363
+ });
364
+ };
365
+ ApplicationManager.prototype.getWifiScanResults = function (raftId) {
366
+ var _a, _b;
367
+ return __awaiter(this, void 0, void 0, function () {
368
+ return __generator(this, function (_c) {
369
+ return [2 /*return*/, (_b = (_a = this.getWifiManager(raftId)) === null || _a === void 0 ? void 0 : _a.getWifiScanResults()) !== null && _b !== void 0 ? _b : false];
311
370
  });
312
371
  });
313
372
  };
314
- ApplicationManager.prototype.getCachedWifiStatusMarty = function (martyId) {
315
- var raft = this.connectedRafts[martyId];
316
- if (raft && raft.type === RaftTypeE.MARTY) {
317
- return raft.wifiManager.getCachedWifiStatus();
373
+ // Marty-specific aliases remain part of the embedded-platform contract.
374
+ ApplicationManager.prototype.getMartyWifiManager = function (raftId) {
375
+ var raft = this.connectedRafts[raftId];
376
+ if ((raft === null || raft === void 0 ? void 0 : raft.type) === RaftTypeE.MARTY) {
377
+ return raft.wifiManager;
318
378
  }
319
- Logger.warn(SHOW_LOGS, TAG, "RAFT with id: ".concat(martyId, " doesn't exist or is not a Marty"));
379
+ Logger.warn(SHOW_LOGS, TAG, "RAFT with id ".concat(raftId, " is not a Marty"));
320
380
  return undefined;
321
381
  };
322
- ApplicationManager.prototype.wifiConnectMarty = function (martyId, ssid, password) {
382
+ ApplicationManager.prototype.pauseWifiConnectionMarty = function (raftId, pause) {
383
+ var _a, _b;
323
384
  return __awaiter(this, void 0, void 0, function () {
324
- var raft;
325
- return __generator(this, function (_a) {
326
- raft = this.connectedRafts[martyId];
327
- if (raft && raft.type === RaftTypeE.MARTY) {
328
- return [2 /*return*/, raft.wifiManager.wifiConnect(ssid, password)];
329
- }
330
- Logger.warn(SHOW_LOGS, TAG, "RAFT with id: ".concat(martyId, " doesn't exist or is not a Marty"));
331
- return [2 /*return*/, false];
385
+ return __generator(this, function (_c) {
386
+ return [2 /*return*/, (_b = (_a = this.getMartyWifiManager(raftId)) === null || _a === void 0 ? void 0 : _a.pauseWifiConnection(pause)) !== null && _b !== void 0 ? _b : false];
332
387
  });
333
388
  });
334
389
  };
335
- ApplicationManager.prototype.wifiDisconnectMarty = function (martyId) {
390
+ ApplicationManager.prototype.getCachedWifiStatusMarty = function (raftId) {
391
+ var _a;
392
+ return (_a = this.getMartyWifiManager(raftId)) === null || _a === void 0 ? void 0 : _a.getCachedWifiStatus();
393
+ };
394
+ ApplicationManager.prototype.wifiConnectMarty = function (raftId, ssid, password) {
395
+ var _a, _b;
336
396
  return __awaiter(this, void 0, void 0, function () {
337
- var raft;
338
- return __generator(this, function (_a) {
339
- raft = this.connectedRafts[martyId];
340
- if (raft && raft.type === RaftTypeE.MARTY) {
341
- return [2 /*return*/, raft.wifiManager.wifiDisconnect()];
342
- }
343
- Logger.warn(SHOW_LOGS, TAG, "RAFT with id: ".concat(martyId, " doesn't exist or is not a Marty"));
344
- return [2 /*return*/, false];
397
+ return __generator(this, function (_c) {
398
+ return [2 /*return*/, (_b = (_a = this.getMartyWifiManager(raftId)) === null || _a === void 0 ? void 0 : _a.wifiConnect(ssid, password)) !== null && _b !== void 0 ? _b : false];
345
399
  });
346
400
  });
347
401
  };
348
- ApplicationManager.prototype.getWiFiConnStatusMarty = function (martyId) {
402
+ ApplicationManager.prototype.wifiDisconnectMarty = function (raftId) {
403
+ var _a, _b;
349
404
  return __awaiter(this, void 0, void 0, function () {
350
- var raft;
351
- return __generator(this, function (_a) {
352
- raft = this.connectedRafts[martyId];
353
- if (raft && raft.type === RaftTypeE.MARTY) {
354
- return [2 /*return*/, raft.wifiManager.getWiFiConnStatus()];
355
- }
356
- return [2 /*return*/, null];
405
+ return __generator(this, function (_c) {
406
+ return [2 /*return*/, (_b = (_a = this.getMartyWifiManager(raftId)) === null || _a === void 0 ? void 0 : _a.wifiDisconnect()) !== null && _b !== void 0 ? _b : false];
357
407
  });
358
408
  });
359
409
  };
360
- ApplicationManager.prototype.getWifiScanResultsMarty = function (martyId) {
410
+ ApplicationManager.prototype.getWiFiConnStatusMarty = function (raftId) {
411
+ var _a, _b;
361
412
  return __awaiter(this, void 0, void 0, function () {
362
- var raft;
363
- return __generator(this, function (_a) {
364
- raft = this.connectedRafts[martyId];
365
- if (raft && raft.type === RaftTypeE.MARTY) {
366
- return [2 /*return*/, raft.wifiManager.getWifiScanResults()];
367
- }
368
- Logger.warn(SHOW_LOGS, TAG, "RAFT with id: ".concat(martyId, " doesn't exist or is not a Marty"));
369
- return [2 /*return*/, false];
413
+ return __generator(this, function (_c) {
414
+ return [2 /*return*/, (_b = (_a = this.getMartyWifiManager(raftId)) === null || _a === void 0 ? void 0 : _a.getWiFiConnStatus()) !== null && _b !== void 0 ? _b : null];
415
+ });
416
+ });
417
+ };
418
+ ApplicationManager.prototype.getWifiScanResultsMarty = function (raftId) {
419
+ var _a, _b;
420
+ return __awaiter(this, void 0, void 0, function () {
421
+ return __generator(this, function (_c) {
422
+ return [2 /*return*/, (_b = (_a = this.getMartyWifiManager(raftId)) === null || _a === void 0 ? void 0 : _a.getWifiScanResults()) !== null && _b !== void 0 ? _b : false];
370
423
  });
371
424
  });
372
425
  };
373
426
  //======================//
374
- /* END MARTY WIFI */
427
+ /* END RAFT WIFI */
375
428
  //======================//
376
429
  //======================//
377
430
  /* CALIBRATION MARTY */
@@ -503,32 +556,42 @@ var ApplicationManager = /** @class */ (function () {
503
556
  ApplicationManager.prototype.createNewMarty = function (id) {
504
557
  return new Marty(id);
505
558
  };
506
- ApplicationManager.prototype.connectGenericMarty = function (afterRaftConnectedCb) {
507
- return this.connectGeneric(afterRaftConnectedCb, [ConnManager.RICUUID], false);
559
+ ApplicationManager.prototype.connectGenericMarty = function (afterRaftConnectedCb, options) {
560
+ if (options === void 0) { options = {}; }
561
+ return this.connectGeneric(afterRaftConnectedCb, [ConnManager.RICUUID], false, __assign(__assign({}, options), { expectedRaftType: RaftTypeE.MARTY }));
508
562
  };
509
- ApplicationManager.prototype.connectGenericCog = function (afterRaftConnectedCb) {
510
- return this.connectGeneric(afterRaftConnectedCb, [ConnManager.COGUUID]);
563
+ ApplicationManager.prototype.connectGenericCog = function (afterRaftConnectedCb, options) {
564
+ if (options === void 0) { options = {}; }
565
+ return this.connectGeneric(afterRaftConnectedCb, [ConnManager.COGUUID], true, __assign(__assign({}, options), { expectedRaftType: RaftTypeE.COG }));
511
566
  };
512
567
  /**
513
568
  * Generic Connect method
514
569
  * This method is called from various environments (connection button, blocksjr, blocks etc.)
515
570
  * Known issue: connecting to a raft from within a platform won't add the newly connected raft to the connectedRafts hook
516
571
  */
517
- ApplicationManager.prototype.connectGeneric = function (afterRaftConnectedCb, uuids, shouldShowQrModal) {
572
+ ApplicationManager.prototype.connectGeneric = function (afterRaftConnectedCb, uuids, shouldShowQrModal, options) {
518
573
  var _this = this;
519
574
  if (shouldShowQrModal === void 0) { shouldShowQrModal = true; }
575
+ if (options === void 0) { options = {}; }
520
576
  if (this._connectPromise) {
521
577
  return this._connectPromise;
522
578
  }
523
579
  if (this._disconnectPromises.size > 0) {
524
- this.toaster.info(i18n.t("connection.wait_for_bluetooth_disconnect", {
525
- defaultValue: "Please wait for the current Bluetooth disconnect to finish.",
580
+ this.toaster.info(i18n.t("connection.wait_for_disconnect", {
581
+ defaultValue: "Please wait for the current device disconnect to finish.",
526
582
  }));
527
583
  return Promise.resolve();
528
584
  }
529
585
  var connectAttemptId = ++this._connectAttemptSequence;
530
586
  this._activeConnectAttemptId = connectAttemptId;
531
- var connectPromise = this._connectGeneric(afterRaftConnectedCb, uuids, shouldShowQrModal, connectAttemptId);
587
+ var inferredRaftType = !options.expectedRaftType && (uuids === null || uuids === void 0 ? void 0 : uuids.length) === 1
588
+ ? uuids[0] === ConnManager.RICUUID
589
+ ? RaftTypeE.MARTY
590
+ : uuids[0] === ConnManager.COGUUID
591
+ ? RaftTypeE.COG
592
+ : undefined
593
+ : undefined;
594
+ var connectPromise = this._connectGeneric(afterRaftConnectedCb, uuids, shouldShowQrModal, connectAttemptId, __assign(__assign({}, options), { expectedRaftType: options.expectedRaftType || inferredRaftType }));
532
595
  this._connectPromise = connectPromise;
533
596
  void connectPromise.then(function () { return _this._clearConnectPromise(connectPromise, connectAttemptId); }, function () { return _this._clearConnectPromise(connectPromise, connectAttemptId); });
534
597
  return connectPromise;
@@ -555,7 +618,7 @@ var ApplicationManager = /** @class */ (function () {
555
618
  if (this._isConnectAttemptActive(connectAttemptId)) {
556
619
  return "commit";
557
620
  }
558
- // A newer app attempt shares WrapperAppManager's in-flight Bluetooth
621
+ // A newer app attempt shares WrapperAppManager's in-flight connection
559
622
  // result. Let that current consumer commit it instead of tearing down the
560
623
  // transport underneath it. With no replacement consumer, Dismiss means
561
624
  // the late success must be fully released.
@@ -567,21 +630,138 @@ var ApplicationManager = /** @class */ (function () {
567
630
  onDismiss: function () { return _this._dismissConnectAttempt(connectAttemptId); },
568
631
  });
569
632
  };
570
- ApplicationManager.prototype._connectGeneric = function (afterRaftConnectedCb, uuids, shouldShowQrModal, connectAttemptId) {
633
+ ApplicationManager.prototype._resolveConnectOptions = function (options) {
571
634
  return __awaiter(this, void 0, void 0, function () {
572
- var verificationMethod, cancelVerificationResult, isQRVerification, e_1, newRaft, wasAdopted, e_2;
635
+ var method, expectedRaftType, bluetoothMethod, locator, modalLocator;
636
+ return __generator(this, function (_a) {
637
+ switch (_a.label) {
638
+ case 0:
639
+ method = options.method;
640
+ expectedRaftType = options.expectedRaftType;
641
+ bluetoothMethod = isPhoneApp()
642
+ ? RaftConnectionMethod.PHONE_BLE
643
+ : RaftConnectionMethod.WEB_BLE;
644
+ if (!method) {
645
+ method = expectedRaftType === RaftTypeE.MARTY &&
646
+ getConnectionMethodPreference() === ConnectionMethodPreference.WIFI
647
+ ? RaftConnectionMethod.WEB_SOCKET
648
+ : bluetoothMethod;
649
+ }
650
+ if (expectedRaftType === RaftTypeE.COG &&
651
+ method === RaftConnectionMethod.WEB_SOCKET) {
652
+ this.toaster.error(i18n.t("connection.cog_wifi_unsupported", {
653
+ defaultValue: "Cog does not support Wi-Fi. Connect using Bluetooth instead.",
654
+ }));
655
+ return [2 /*return*/, null];
656
+ }
657
+ if (method !== RaftConnectionMethod.WEB_SOCKET) {
658
+ // The caller chooses the transport family; the runtime owns the
659
+ // concrete Bluetooth implementation.
660
+ method = bluetoothMethod;
661
+ return [2 /*return*/, {
662
+ method: method,
663
+ locator: "",
664
+ expectedRaftType: expectedRaftType,
665
+ }];
666
+ }
667
+ if (!expectedRaftType) {
668
+ this.toaster.error(i18n.t("connection.wifi_robot_type_required", {
669
+ defaultValue: "Choose Marty or Cog before connecting over Wi-Fi.",
670
+ }));
671
+ return [2 /*return*/, null];
672
+ }
673
+ locator = options.locator;
674
+ if (!!locator) return [3 /*break*/, 2];
675
+ return [4 /*yield*/, modalState.setModal(createElement(WifiConnectionModal, { raftType: expectedRaftType }), i18n.t("connection.wifi_connection_title", {
676
+ defaultValue: "Connect over Wi-Fi",
677
+ }), getModalLogoForRaftType(expectedRaftType), true, false)];
678
+ case 1:
679
+ modalLocator = _a.sent();
680
+ if (!modalLocator) {
681
+ return [2 /*return*/, null];
682
+ }
683
+ locator = modalLocator;
684
+ _a.label = 2;
685
+ case 2:
686
+ if (!locator) {
687
+ return [2 /*return*/, null];
688
+ }
689
+ try {
690
+ return [2 /*return*/, {
691
+ method: method,
692
+ locator: normalizeWifiLocator(locator, expectedRaftType),
693
+ expectedRaftType: expectedRaftType,
694
+ }];
695
+ }
696
+ catch (error) {
697
+ this.toaster.error(error instanceof Error ? error.message : String(error));
698
+ return [2 /*return*/, null];
699
+ }
700
+ return [2 /*return*/];
701
+ }
702
+ });
703
+ });
704
+ };
705
+ ApplicationManager.prototype._connectGeneric = function (afterRaftConnectedCb, uuids, shouldShowQrModal, connectAttemptId, options) {
706
+ return __awaiter(this, void 0, void 0, function () {
707
+ var resolvedOptions, method, locator, isWifiConnection, tracksWifiLocator, alreadyConnected;
708
+ return __generator(this, function (_a) {
709
+ switch (_a.label) {
710
+ case 0: return [4 /*yield*/, this._resolveConnectOptions(options)];
711
+ case 1:
712
+ resolvedOptions = _a.sent();
713
+ if (!resolvedOptions || !this._isConnectAttemptActive(connectAttemptId)) {
714
+ return [2 /*return*/];
715
+ }
716
+ method = resolvedOptions.method, locator = resolvedOptions.locator;
717
+ isWifiConnection = method === RaftConnectionMethod.WEB_SOCKET;
718
+ tracksWifiLocator = isWifiConnection && !!locator;
719
+ if (tracksWifiLocator) {
720
+ alreadyConnected = Object.values(this.connectedRafts).some(function (raft) {
721
+ return raft.connectionMethod === RaftConnectionMethod.WEB_SOCKET &&
722
+ raft.connectionLocator === locator;
723
+ });
724
+ if (alreadyConnected || this._pendingWifiLocators.has(locator)) {
725
+ this.toaster.info(i18n.t("connection.wifi_already_connected", {
726
+ defaultValue: "This Wi-Fi device is already connected or connecting.",
727
+ }));
728
+ return [2 /*return*/];
729
+ }
730
+ this._pendingWifiLocators.add(locator);
731
+ }
732
+ _a.label = 2;
733
+ case 2:
734
+ _a.trys.push([2, , 4, 5]);
735
+ return [4 /*yield*/, this._connectWithResolvedOptions(afterRaftConnectedCb, uuids, shouldShowQrModal, connectAttemptId, resolvedOptions)];
736
+ case 3: return [2 /*return*/, _a.sent()];
737
+ case 4:
738
+ if (tracksWifiLocator) {
739
+ this._pendingWifiLocators.delete(locator);
740
+ }
741
+ return [7 /*endfinally*/];
742
+ case 5: return [2 /*return*/];
743
+ }
744
+ });
745
+ });
746
+ };
747
+ ApplicationManager.prototype._connectWithResolvedOptions = function (afterRaftConnectedCb, uuids, shouldShowQrModal, connectAttemptId, resolvedOptions) {
748
+ return __awaiter(this, void 0, void 0, function () {
749
+ var method, locator, expectedRaftType, isWifiConnection, isPhoneBluetoothConnection, verificationMethod, cancelVerificationResult, isQRVerification, e_1, newRaft, wasAdopted, e_2;
573
750
  var _this = this;
574
751
  return __generator(this, function (_a) {
575
752
  switch (_a.label) {
576
753
  case 0:
577
- if (!isPhoneApp() && !canUseWebBluetooth()) {
754
+ method = resolvedOptions.method, locator = resolvedOptions.locator, expectedRaftType = resolvedOptions.expectedRaftType;
755
+ isWifiConnection = method === RaftConnectionMethod.WEB_SOCKET;
756
+ isPhoneBluetoothConnection = method === RaftConnectionMethod.PHONE_BLE && isPhoneApp();
757
+ if (method === RaftConnectionMethod.WEB_BLE && !canUseWebBluetooth()) {
578
758
  this.toaster.error(i18n.t("connection.unsupported_web_bluetooth_browser", {
579
759
  defaultValue: UNSUPPORTED_WEB_BLUETOOTH_BROWSER_MESSAGE,
580
760
  }), { autoClose: false });
581
761
  return [2 /*return*/];
582
762
  }
583
763
  verificationMethod = { action: "led" };
584
- if (!shouldShowQrModal) return [3 /*break*/, 2];
764
+ if (!(shouldShowQrModal && !isWifiConnection)) return [3 /*break*/, 2];
585
765
  cancelVerificationResult = { action: "cancel" };
586
766
  return [4 /*yield*/, modalState.setModal(createElement(LEDLightsOrQRVerificationModal, {
587
767
  targetRaftType: RaftTypeE.COG,
@@ -596,7 +776,10 @@ var ApplicationManager = /** @class */ (function () {
596
776
  return [2 /*return*/];
597
777
  }
598
778
  if (verificationMethod.action === "switch-to-marty") {
599
- return [2 /*return*/, this._connectGeneric(afterRaftConnectedCb, [ConnManager.RICUUID], false, connectAttemptId)];
779
+ return [2 /*return*/, this._connectGeneric(afterRaftConnectedCb, [ConnManager.RICUUID], false, connectAttemptId, {
780
+ method: method,
781
+ expectedRaftType: RaftTypeE.MARTY,
782
+ })];
600
783
  }
601
784
  isQRVerification = false;
602
785
  if (verificationMethod.action === "qr") {
@@ -608,7 +791,7 @@ var ApplicationManager = /** @class */ (function () {
608
791
  uuids = [ConnManager.COGUUID, ConnManager.RICUUID];
609
792
  }
610
793
  }
611
- if (!isPhoneApp()) return [3 /*break*/, 10];
794
+ if (!isPhoneBluetoothConnection) return [3 /*break*/, 10];
612
795
  this.lastUUIDsUsed = uuids; // Store the last used UUIDs so when the user presses "Scan Again" in the phone app connection modal, we can use them to start discovery again
613
796
  _a.label = 3;
614
797
  case 3:
@@ -648,7 +831,7 @@ var ApplicationManager = /** @class */ (function () {
648
831
  _a.label = 11;
649
832
  case 11:
650
833
  _a.trys.push([11, 16, , 17]);
651
- return [4 /*yield*/, window.applicationManager.connectToRIC(RaftConnectionMethod.WEB_BLE, uuids, isQRVerification, function () { return _this._getConnectResultDisposition(connectAttemptId); })];
834
+ return [4 /*yield*/, window.applicationManager.connectToRIC(method, uuids, isQRVerification, function () { return _this._getConnectResultDisposition(connectAttemptId); }, locator, expectedRaftType)];
652
835
  case 12:
653
836
  newRaft = _a.sent();
654
837
  if (!this._isConnectAttemptActive(connectAttemptId)) {
@@ -670,6 +853,11 @@ var ApplicationManager = /** @class */ (function () {
670
853
  case 16:
671
854
  e_2 = _a.sent();
672
855
  Logger.error(SHOW_LOGS, TAG, "Failed to connect to new robot: ".concat(e_2));
856
+ if (isWifiConnection) {
857
+ this.toaster.error(i18n.t("connection.wifi_connect_failed", {
858
+ defaultValue: "Couldn't connect over Wi-Fi. Check the address, local-network permission, and that the device is online.",
859
+ }));
860
+ }
673
861
  return [3 /*break*/, 17];
674
862
  case 17:
675
863
  if (this._isConnectAttemptActive(connectAttemptId)) {
@@ -751,6 +939,8 @@ var ApplicationManager = /** @class */ (function () {
751
939
  default:
752
940
  throw new Error("Unknown RAFT type");
753
941
  }
942
+ raft.connectionMethod = method;
943
+ raft.connectionLocator = "";
754
944
  this.connectedRafts[raftId] = raft;
755
945
  if ((_c = selectResults.data) === null || _c === void 0 ? void 0 : _c.systemInfo) {
756
946
  raft.systemInfo = selectResults.data.systemInfo;
@@ -782,31 +972,43 @@ var ApplicationManager = /** @class */ (function () {
782
972
  });
783
973
  });
784
974
  };
785
- ApplicationManager.prototype.connectToRIC = function (method, uuids, withoutVerification, getResultDisposition) {
975
+ ApplicationManager.prototype.connectToRIC = function (method, uuids, withoutVerification, getResultDisposition, locator, expectedRaftType) {
786
976
  var _a, _b, _c, _d;
787
977
  if (getResultDisposition === void 0) { getResultDisposition = function () { return "commit"; }; }
978
+ if (locator === void 0) { locator = ""; }
788
979
  return __awaiter(this, void 0, void 0, function () {
789
980
  var wasConnectedObj, raftId, raftType, resultDisposition, raft;
790
981
  return __generator(this, function (_e) {
791
982
  switch (_e.label) {
792
- case 0: return [4 /*yield*/, RAFT.connect(method, uuids)];
983
+ case 0: return [4 /*yield*/, RAFT.connect(method, uuids, locator, expectedRaftType)];
793
984
  case 1:
794
985
  wasConnectedObj = _e.sent();
795
- if (!wasConnectedObj.success) return [3 /*break*/, 7];
986
+ if (!wasConnectedObj.success) return [3 /*break*/, 9];
796
987
  raftId = (_a = wasConnectedObj.data) === null || _a === void 0 ? void 0 : _a.raftId;
797
988
  raftType = (_b = wasConnectedObj.data) === null || _b === void 0 ? void 0 : _b.raftType;
798
989
  if (!raftId || !raftType) {
799
990
  throw new Error("RAFT ID or RAFT Type is missing: ".concat(raftId, " ").concat(raftType));
800
991
  }
801
- resultDisposition = getResultDisposition();
802
- if (!(resultDisposition !== "commit")) return [3 /*break*/, 4];
803
- if (!(resultDisposition === "release")) return [3 /*break*/, 3];
992
+ if (!(expectedRaftType && raftType !== expectedRaftType)) return [3 /*break*/, 3];
804
993
  return [4 /*yield*/, window.wrapperCommunicator.sendMessageAndWait(AppSentMessage.RAFT_DISCONNECT, { raftId: raftId })];
805
994
  case 2:
806
995
  _e.sent();
807
- _e.label = 3;
808
- case 3: return [2 /*return*/, null];
996
+ this.toaster.error(i18n.t("connection.wifi_wrong_robot_type", {
997
+ defaultValue: "The address belongs to a {{actualType}}, not a {{expectedType}}.",
998
+ actualType: raftType,
999
+ expectedType: expectedRaftType,
1000
+ }));
1001
+ return [2 /*return*/, null];
1002
+ case 3:
1003
+ resultDisposition = getResultDisposition();
1004
+ if (!(resultDisposition !== "commit")) return [3 /*break*/, 6];
1005
+ if (!(resultDisposition === "release")) return [3 /*break*/, 5];
1006
+ return [4 /*yield*/, window.wrapperCommunicator.sendMessageAndWait(AppSentMessage.RAFT_DISCONNECT, { raftId: raftId })];
809
1007
  case 4:
1008
+ _e.sent();
1009
+ _e.label = 5;
1010
+ case 5: return [2 /*return*/, null];
1011
+ case 6:
810
1012
  raft = void 0;
811
1013
  switch (raftType) {
812
1014
  case RaftTypeE.MARTY:
@@ -818,29 +1020,41 @@ var ApplicationManager = /** @class */ (function () {
818
1020
  default:
819
1021
  throw new Error("Unknown RAFT type");
820
1022
  }
1023
+ raft.connectionMethod = method;
1024
+ raft.connectionLocator = locator;
821
1025
  this.connectedRafts[raftId] = raft;
822
1026
  if ((_c = wasConnectedObj.data) === null || _c === void 0 ? void 0 : _c.systemInfo) {
823
1027
  raft.systemInfo = wasConnectedObj.data.systemInfo;
824
1028
  }
825
1029
  // get missed Connect event
826
1030
  publishMissedConnectionEvent(raftId);
827
- if (!!((_d = wasConnectedObj.data) === null || _d === void 0 ? void 0 : _d.systemInfo)) return [3 /*break*/, 6];
1031
+ if (!!((_d = wasConnectedObj.data) === null || _d === void 0 ? void 0 : _d.systemInfo)) return [3 /*break*/, 8];
828
1032
  return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 200); })];
829
- case 5:
1033
+ case 7:
830
1034
  _e.sent();
831
- _e.label = 6;
832
- case 6:
1035
+ _e.label = 8;
1036
+ case 8:
833
1037
  // start LED verification process
834
1038
  if (!withoutVerification) {
835
1039
  modalState.setModal(createElement(VerificationModal, { connectedRAFT_: raft }), i18n.t("connection.looking_for_raft", { raftType: raft.type }), false);
836
1040
  }
837
1041
  return [2 /*return*/, raft];
838
- case 7:
1042
+ case 9:
839
1043
  if (wasConnectedObj.reason === 'unplugged') {
840
1044
  modalState.setModal(createElement(InUnpluggedModalContent), i18n.t("calibration_screen.colour_calibration.unplugged_modal_title"));
841
1045
  }
842
- _e.label = 8;
843
- case 8: return [2 /*return*/, null];
1046
+ else if (wasConnectedObj.reason === "invalid_raft_type") {
1047
+ this.toaster.error(i18n.t("connection.wifi_wrong_robot_type_generic", {
1048
+ defaultValue: "The address belongs to a different kind of device.",
1049
+ }));
1050
+ }
1051
+ else if (method === RaftConnectionMethod.WEB_SOCKET) {
1052
+ this.toaster.error(i18n.t("connection.wifi_connect_failed", {
1053
+ defaultValue: "Couldn't connect over Wi-Fi. Check the address, local-network permission, and that the device is online.",
1054
+ }));
1055
+ }
1056
+ _e.label = 10;
1057
+ case 10: return [2 /*return*/, null];
844
1058
  }
845
1059
  });
846
1060
  });
@@ -6,9 +6,11 @@ import { SimplifiedCogStateInfo } from "@robotical/roboticaljs/dist/SystemTypeCo
6
6
  import { RaftConnEvent, RaftPublishEvent, RaftUpdateEvent } from "@robdobsn/raftjs";
7
7
  import { RaftInfoEvents } from "../../../types/events/raft-info";
8
8
  import PublishedDataAnalyser from "./PublishedDataAnalyser";
9
+ import { RaftWifiManager } from "../RaftWifiManager";
9
10
  export declare class Cog extends RAFT implements RICInterface {
10
11
  id: string;
11
12
  type: RaftTypeE;
13
+ wifiManager: RaftWifiManager;
12
14
  _ledLcdColours: RICLedLcdColours;
13
15
  raftStateInfo: SimplifiedCogStateInfo | null;
14
16
  publishedDataAnalyser: PublishedDataAnalyser;
@@ -54,12 +54,15 @@ import { RaftTypeE } from "../../../types/raft";
54
54
  import { RaftConnEvent, RaftPublishEvent } from "@robdobsn/raftjs";
55
55
  import { RaftInfoEvents } from "../../../types/events/raft-info";
56
56
  import PublishedDataAnalyser, { setButtonThresholdsUtil } from "./PublishedDataAnalyser";
57
+ import { RaftWifiManager } from "../RaftWifiManager";
57
58
  var Cog = /** @class */ (function (_super) {
58
59
  __extends(Cog, _super);
59
60
  function Cog(id) {
60
61
  var _this = _super.call(this, id) || this;
61
62
  _this.id = id;
62
63
  _this.type = RaftTypeE.COG;
64
+ // Wi-Fi provisioning uses the common NetMan API when supported by firmware.
65
+ _this.wifiManager = new RaftWifiManager(_this, "Cog");
63
66
  // Colours to use for LED patterns
64
67
  _this._ledLcdColours = [
65
68
  { led: "#202000", lcd: "#FFFF00" },
@@ -49,7 +49,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
49
49
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
50
50
  }
51
51
  };
52
- import { RaftTypeE } from "../../../types/raft";
52
+ import { RaftConnectionMethod, RaftTypeE } from "../../../types/raft";
53
53
  import RAFT from "../RAFT";
54
54
  import { RaftConnEvent, RaftPublishEvent } from "@robdobsn/raftjs";
55
55
  import { RaftInfoEvents } from "../../../types/events/raft-info";
@@ -74,7 +74,7 @@ var Marty = /** @class */ (function (_super) {
74
74
  // Marty System info
75
75
  _this.systemInfo = null;
76
76
  // Marty wifi manager
77
- _this.wifiManager = new MartyWifiManager(_this);
77
+ _this.wifiManager = new MartyWifiManager(_this, "Raft");
78
78
  // Addons Manager
79
79
  _this.addonsManager = new MartyAddonsManager(_this);
80
80
  // Calibration Manager
@@ -120,7 +120,11 @@ var Marty = /** @class */ (function (_super) {
120
120
  */
121
121
  Marty.prototype.getRSSI = function () {
122
122
  var _a;
123
- var newRssi = ((_a = this.raftStateInfo) === null || _a === void 0 ? void 0 : _a.robotStatus.robotStatus.bleRSSI) || -200;
123
+ var robotStatus = (_a = this.raftStateInfo) === null || _a === void 0 ? void 0 : _a.robotStatus.robotStatus;
124
+ var transportRssi = this.connectionMethod === RaftConnectionMethod.WEB_SOCKET
125
+ ? robotStatus === null || robotStatus === void 0 ? void 0 : robotStatus.wifiRSSI
126
+ : robotStatus === null || robotStatus === void 0 ? void 0 : robotStatus.bleRSSI;
127
+ var newRssi = transportRssi || -200;
124
128
  if (this.rssiValues.length >= this.MAX_RSSI_VALUES_N) {
125
129
  this.rssiValues.shift();
126
130
  }