unetjs 1.0.0 → 2.0.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/cjs/unet.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /* unet.js v1.0.0 2021-07-07T04:11:04.914Z */
1
+ /* unet.js v2.0.0 2022-05-18T02:36:38.084Z */
2
2
 
3
3
  'use strict';
4
4
 
@@ -13,18 +13,16 @@ function _interopNamespace(e) {
13
13
  var d = Object.getOwnPropertyDescriptor(e, k);
14
14
  Object.defineProperty(n, k, d.get ? d : {
15
15
  enumerable: true,
16
- get: function () {
17
- return e[k];
18
- }
16
+ get: function () { return e[k]; }
19
17
  });
20
18
  }
21
19
  });
22
20
  }
23
- n['default'] = e;
21
+ n["default"] = e;
24
22
  return Object.freeze(n);
25
23
  }
26
24
 
27
- /* fjage.js v1.9.1-rc5 2021-07-07T04:07:53.061Z */
25
+ /* fjage.js v1.9.1-rc6 */
28
26
 
29
27
  /* global window self */
30
28
 
@@ -1295,6 +1293,8 @@ let UnetServices = {
1295
1293
  'TRANSPORT': 'org.arl.unet.Services.TRANSPORT',
1296
1294
  'REMOTE': 'org.arl.unet.Services.REMOTE',
1297
1295
  'STATE_MANAGER': 'org.arl.unet.Services.STATE_MANAGER',
1296
+ 'DEVICE_INFO': 'org.arl.unet.Services.DEVICE_INFO',
1297
+ 'DOA': 'org.arl.unet.Services.DOA'
1298
1298
  };
1299
1299
 
1300
1300
  Object.assign(Services, UnetServices);
@@ -1323,100 +1323,361 @@ let Protocol = {
1323
1323
  */
1324
1324
  let UnetMessages = {
1325
1325
  // unet
1326
- 'TestReportNtf' : MessageClass('org.arl.unet.TestReportNtf'),
1327
- 'AbnormalTerminationNtf' : MessageClass('org.arl.unet.AbnormalTerminationNtf'),
1328
- 'CapabilityListRsp' : MessageClass('org.arl.unet.CapabilityListRsp'),
1329
- 'CapabilityReq' : MessageClass('org.arl.unet.CapabilityReq'),
1330
- 'ClearReq' : MessageClass('org.arl.unet.ClearReq'),
1331
- 'DatagramCancelReq' : MessageClass('org.arl.unet.DatagramCancelReq'),
1332
- 'DatagramDeliveryNtf' : MessageClass('org.arl.unet.DatagramDeliveryNtf'),
1333
- 'DatagramFailureNtf' : MessageClass('org.arl.unet.DatagramFailureNtf'),
1334
- 'DatagramNtf' : MessageClass('org.arl.unet.DatagramNtf'),
1335
- 'DatagramProgressNtf' : MessageClass('org.arl.unet.DatagramProgressNtf'),
1336
- 'DatagramReq' : MessageClass('org.arl.unet.DatagramReq'),
1337
- 'ParamChangeNtf' : MessageClass('org.arl.unet.ParamChangeNtf'),
1338
- 'RefuseRsp' : MessageClass('org.arl.unet.RefuseRsp'),
1339
- 'FailureNtf' : MessageClass('org.arl.unet.FailureNtf'),
1326
+ 'TestReportNtf' : MessageClass('org.arl.unet.TestReportNtf'),
1327
+ 'AbnormalTerminationNtf' : MessageClass('org.arl.unet.AbnormalTerminationNtf'),
1328
+ 'CapabilityListRsp' : MessageClass('org.arl.unet.CapabilityListRsp'),
1329
+ 'CapabilityReq' : MessageClass('org.arl.unet.CapabilityReq'),
1330
+ 'ClearReq' : MessageClass('org.arl.unet.ClearReq'),
1331
+ 'DatagramCancelReq' : MessageClass('org.arl.unet.DatagramCancelReq'),
1332
+ 'DatagramDeliveryNtf' : MessageClass('org.arl.unet.DatagramDeliveryNtf'),
1333
+ 'DatagramFailureNtf' : MessageClass('org.arl.unet.DatagramFailureNtf'),
1334
+ 'DatagramNtf' : MessageClass('org.arl.unet.DatagramNtf'),
1335
+ 'DatagramProgressNtf' : MessageClass('org.arl.unet.DatagramProgressNtf'),
1336
+ 'DatagramReq' : MessageClass('org.arl.unet.DatagramReq'),
1337
+ 'ParamChangeNtf' : MessageClass('org.arl.unet.ParamChangeNtf'),
1338
+ 'RefuseRsp' : MessageClass('org.arl.unet.RefuseRsp'),
1339
+ 'FailureNtf' : MessageClass('org.arl.unet.FailureNtf'),
1340
1340
 
1341
1341
  // net
1342
- 'DatagramTraceReq' : MessageClass('org.arl.unet.net.DatagramTraceReq'),
1343
- 'RouteDiscoveryReq' : MessageClass('org.arl.unet.net.RouteDiscoveryReq'),
1344
- 'RouteTraceReq' : MessageClass('org.arl.unet.net.RouteTraceReq'),
1345
- 'RouteDiscoveryNtf' : MessageClass('org.arl.unet.net.RouteDiscoveryNtf'),
1346
- 'RouteTraceNtf' : MessageClass('org.arl.unet.net.RouteTraceNtf'),
1342
+ 'DatagramTraceReq' : MessageClass('org.arl.unet.net.DatagramTraceReq'),
1343
+ 'RouteDiscoveryReq' : MessageClass('org.arl.unet.net.RouteDiscoveryReq'),
1344
+ 'RouteTraceReq' : MessageClass('org.arl.unet.net.RouteTraceReq'),
1345
+ 'RouteDiscoveryNtf' : MessageClass('org.arl.unet.net.RouteDiscoveryNtf'),
1346
+ 'RouteTraceNtf' : MessageClass('org.arl.unet.net.RouteTraceNtf'),
1347
1347
 
1348
1348
  // phy
1349
- 'FecDecodeReq' : MessageClass('org.arl.unet.phy.FecDecodeReq'),
1350
- 'RxJanusFrameNtf' : MessageClass('org.arl.unet.phy.RxJanusFrameNtf'),
1351
- 'TxJanusFrameReq' : MessageClass('org.arl.unet.phy.TxJanusFrameReq'),
1352
- 'BadFrameNtf' : MessageClass('org.arl.unet.phy.BadFrameNtf'),
1349
+ 'FecDecodeReq' : MessageClass('org.arl.unet.phy.FecDecodeReq'),
1350
+ 'RxJanusFrameNtf' : MessageClass('org.arl.unet.phy.RxJanusFrameNtf'),
1351
+ 'TxJanusFrameReq' : MessageClass('org.arl.unet.phy.TxJanusFrameReq'),
1352
+ 'BadFrameNtf' : MessageClass('org.arl.unet.phy.BadFrameNtf'),
1353
1353
  'BadRangeNtf' : MessageClass('org.arl.unet.phy.BadRangeNtf'),
1354
- 'ClearSyncReq' : MessageClass('org.arl.unet.phy.ClearSyncReq'),
1355
- 'CollisionNtf' : MessageClass('org.arl.unet.phy.CollisionNtf'),
1356
- 'RxFrameNtf' : MessageClass('org.arl.unet.phy.RxFrameNtf', DatagramNtf$1),
1357
- 'RxFrameStartNtf' : MessageClass('org.arl.unet.phy.RxFrameStartNtf'),
1358
- 'SyncInfoReq' : MessageClass('org.arl.unet.phy.SyncInfoReq'),
1359
- 'SyncInfoRsp' : MessageClass('org.arl.unet.phy.SyncInfoRsp'),
1360
- 'TxFrameNtf' : MessageClass('org.arl.unet.phy.TxFrameNtf'),
1361
- 'TxFrameReq' : MessageClass('org.arl.unet.phy.TxFrameReq', DatagramReq$1),
1362
- 'TxFrameStartNtf' : MessageClass('org.arl.unet.phy.TxFrameStartNtf'),
1363
- 'TxRawFrameReq' : MessageClass('org.arl.unet.phy.TxRawFrameReq'),
1354
+ 'ClearSyncReq' : MessageClass('org.arl.unet.phy.ClearSyncReq'),
1355
+ 'CollisionNtf' : MessageClass('org.arl.unet.phy.CollisionNtf'),
1356
+ 'RxFrameNtf' : MessageClass('org.arl.unet.phy.RxFrameNtf', DatagramNtf$1),
1357
+ 'RxFrameStartNtf' : MessageClass('org.arl.unet.phy.RxFrameStartNtf'),
1358
+ 'SyncInfoReq' : MessageClass('org.arl.unet.phy.SyncInfoReq'),
1359
+ 'SyncInfoRsp' : MessageClass('org.arl.unet.phy.SyncInfoRsp'),
1360
+ 'TxFrameNtf' : MessageClass('org.arl.unet.phy.TxFrameNtf'),
1361
+ 'TxFrameReq' : MessageClass('org.arl.unet.phy.TxFrameReq', DatagramReq$1),
1362
+ 'TxFrameStartNtf' : MessageClass('org.arl.unet.phy.TxFrameStartNtf'),
1363
+ 'TxRawFrameReq' : MessageClass('org.arl.unet.phy.TxRawFrameReq'),
1364
1364
 
1365
1365
  // addr
1366
- 'AddressAllocReq' : MessageClass('org.arl.unet.addr.AddressAllocReq'),
1367
- 'AddressAllocRsp' : MessageClass('org.arl.unet.addr.AddressAllocRsp'),
1368
- 'AddressResolutionReq' : MessageClass('org.arl.unet.addr.AddressResolutionReq'),
1369
- 'AddressResolutionRsp' : MessageClass('org.arl.unet.addr.AddressResolutionRsp'),
1366
+ 'AddressAllocReq' : MessageClass('org.arl.unet.addr.AddressAllocReq'),
1367
+ 'AddressAllocRsp' : MessageClass('org.arl.unet.addr.AddressAllocRsp'),
1368
+ 'AddressResolutionReq' : MessageClass('org.arl.unet.addr.AddressResolutionReq'),
1369
+ 'AddressResolutionRsp' : MessageClass('org.arl.unet.addr.AddressResolutionRsp'),
1370
1370
 
1371
1371
  // bb
1372
- 'BasebandSignal' : MessageClass('org.arl.unet.bb.BasebandSignal'),
1373
- 'RecordBasebandSignalReq' : MessageClass('org.arl.unet.bb.RecordBasebandSignalReq'),
1374
- 'RxBasebandSignalNtf' : MessageClass('org.arl.unet.bb.RxBasebandSignalNtf', BasebandSignal),
1375
- 'TxBasebandSignalReq' : MessageClass('org.arl.unet.bb.TxBasebandSignalReq', BasebandSignal),
1372
+ 'BasebandSignal' : MessageClass('org.arl.unet.bb.BasebandSignal'),
1373
+ 'RecordBasebandSignalReq' : MessageClass('org.arl.unet.bb.RecordBasebandSignalReq'),
1374
+ 'RxBasebandSignalNtf' : MessageClass('org.arl.unet.bb.RxBasebandSignalNtf', BasebandSignal),
1375
+ 'TxBasebandSignalReq' : MessageClass('org.arl.unet.bb.TxBasebandSignalReq', BasebandSignal),
1376
1376
 
1377
1377
  // link
1378
- 'LinkStatusNtf' : MessageClass('org.arl.unet.link.LinkStatusNtf'),
1378
+ 'LinkStatusNtf' : MessageClass('org.arl.unet.link.LinkStatusNtf'),
1379
1379
 
1380
1380
  // localization
1381
- 'RangeNtf' : MessageClass('org.arl.unet.localization.RangeNtf'),
1382
- 'RangeReq' : MessageClass('org.arl.unet.localization.RangeReq'),
1383
- 'BeaconReq' : MessageClass('org.arl.unet.localization.BeaconReq'),
1384
- 'RespondReq' : MessageClass('org.arl.unet.localization.RespondReq'),
1385
- 'InterrogationNtf' : MessageClass('org.arl.unet.localization.InterrogationNtf'),
1381
+ 'RangeNtf' : MessageClass('org.arl.unet.localization.RangeNtf'),
1382
+ 'RangeReq' : MessageClass('org.arl.unet.localization.RangeReq'),
1383
+ 'BeaconReq' : MessageClass('org.arl.unet.localization.BeaconReq'),
1384
+ 'RespondReq' : MessageClass('org.arl.unet.localization.RespondReq'),
1385
+ 'InterrogationNtf' : MessageClass('org.arl.unet.localization.InterrogationNtf'),
1386
1386
 
1387
1387
 
1388
1388
  // mac
1389
- 'ReservationAcceptReq' : MessageClass('org.arl.unet.mac.ReservationAcceptReq'),
1390
- 'ReservationCancelReq' : MessageClass('org.arl.unet.mac.ReservationCancelReq'),
1391
- 'ReservationReq' : MessageClass('org.arl.unet.mac.ReservationReq'),
1392
- 'ReservationRsp' : MessageClass('org.arl.unet.mac.ReservationRsp'),
1393
- 'ReservationStatusNtf' : MessageClass('org.arl.unet.mac.ReservationStatusNtf'),
1394
- 'RxAckNtf' : MessageClass('org.arl.unet.mac.RxAckNtf'),
1395
- 'TxAckReq' : MessageClass('org.arl.unet.mac.TxAckReq'),
1389
+ 'ReservationAcceptReq' : MessageClass('org.arl.unet.mac.ReservationAcceptReq'),
1390
+ 'ReservationCancelReq' : MessageClass('org.arl.unet.mac.ReservationCancelReq'),
1391
+ 'ReservationReq' : MessageClass('org.arl.unet.mac.ReservationReq'),
1392
+ 'ReservationRsp' : MessageClass('org.arl.unet.mac.ReservationRsp'),
1393
+ 'ReservationStatusNtf' : MessageClass('org.arl.unet.mac.ReservationStatusNtf'),
1394
+ 'RxAckNtf' : MessageClass('org.arl.unet.mac.RxAckNtf'),
1395
+ 'TxAckReq' : MessageClass('org.arl.unet.mac.TxAckReq'),
1396
1396
 
1397
1397
 
1398
1398
  // remote
1399
- 'RemoteExecReq' : MessageClass('org.arl.unet.remote.RemoteExecReq'),
1400
- 'RemoteFailureNtf' : MessageClass('org.arl.unet.remote.RemoteFailureNtf'),
1401
- 'RemoteFileGetReq' : MessageClass('org.arl.unet.remote.RemoteFileGetReq'),
1402
- 'RemoteFileNtf' : MessageClass('org.arl.unet.remote.RemoteFileNtf'),
1403
- 'RemoteFilePutReq' : MessageClass('org.arl.unet.remote.RemoteFilePutReq'),
1404
- 'RemoteSuccessNtf' : MessageClass('org.arl.unet.remote.RemoteSuccessNtf'),
1405
- 'RemoteTextNtf' : MessageClass('org.arl.unet.remote.RemoteTextNtf'),
1406
- 'RemoteTextReq' : MessageClass('org.arl.unet.remote.RemoteTextReq'),
1399
+ 'RemoteExecReq' : MessageClass('org.arl.unet.remote.RemoteExecReq'),
1400
+ 'RemoteFailureNtf' : MessageClass('org.arl.unet.remote.RemoteFailureNtf'),
1401
+ 'RemoteFileGetReq' : MessageClass('org.arl.unet.remote.RemoteFileGetReq'),
1402
+ 'RemoteFileNtf' : MessageClass('org.arl.unet.remote.RemoteFileNtf'),
1403
+ 'RemoteFilePutReq' : MessageClass('org.arl.unet.remote.RemoteFilePutReq'),
1404
+ 'RemoteSuccessNtf' : MessageClass('org.arl.unet.remote.RemoteSuccessNtf'),
1405
+ 'RemoteTextNtf' : MessageClass('org.arl.unet.remote.RemoteTextNtf'),
1406
+ 'RemoteTextReq' : MessageClass('org.arl.unet.remote.RemoteTextReq'),
1407
1407
 
1408
1408
  // scheduler
1409
- 'AddScheduledSleepReq' : MessageClass('org.arl.unet.scheduler.AddScheduledSleepReq'),
1410
- 'GetSleepScheduleReq' : MessageClass('org.arl.unet.scheduler.GetSleepScheduleReq'),
1411
- 'RemoveScheduledSleepReq' : MessageClass('org.arl.unet.scheduler.RemoveScheduledSleepReq'),
1412
- 'SleepScheduleRsp' : MessageClass('org.arl.unet.scheduler.SleepScheduleRsp'),
1413
- 'WakeFromSleepNtf' : MessageClass('org.arl.unet.scheduler.WakeFromSleepNtf'),
1409
+ 'AddScheduledSleepReq' : MessageClass('org.arl.unet.scheduler.AddScheduledSleepReq'),
1410
+ 'GetSleepScheduleReq' : MessageClass('org.arl.unet.scheduler.GetSleepScheduleReq'),
1411
+ 'RemoveScheduledSleepReq' : MessageClass('org.arl.unet.scheduler.RemoveScheduledSleepReq'),
1412
+ 'SleepScheduleRsp' : MessageClass('org.arl.unet.scheduler.SleepScheduleRsp'),
1413
+ 'WakeFromSleepNtf' : MessageClass('org.arl.unet.scheduler.WakeFromSleepNtf'),
1414
1414
 
1415
1415
  // state
1416
- 'ClearStateReq' : MessageClass('org.arl.unet.state.ClearStateReq'),
1416
+ 'ClearStateReq' : MessageClass('org.arl.unet.state.ClearStateReq'),
1417
1417
  'SaveStateReq' : MessageClass('org.arl.unet.state.SaveStateReq')
1418
1418
  };
1419
1419
 
1420
+ /**
1421
+ * Convert coordinates from a local coordinates to GPS coordinate
1422
+ * @param {Array} origin - Local coordinate system's origin as `[latitude, longitude]`
1423
+ * @param {Number} x - X coordinate of the local coordinate to be converted
1424
+ * @param {Number} y - Y coordinate of the local coordinate to be converted
1425
+ * @returns {Array} - GPS coordinates (in decimal degrees) as `[latitude, longitude]`
1426
+ */
1427
+
1428
+ function toGps(origin, x, y) {
1429
+ let coords = [] ;
1430
+ let [xScale,yScale] = _initConv(origin[0]);
1431
+ coords[1] = x/xScale + origin[1];
1432
+ coords[0] = y/yScale + origin[0];
1433
+ return coords;
1434
+ }
1435
+
1436
+ /**
1437
+ * Convert coordinates from a GPS coordinates to local coordinate
1438
+ * @param {Array} origin - Local coordinate system's origin as `[latitude, longitude]`
1439
+ * @param {Number} lat - Latitude of the GPS coordinate to be converted
1440
+ * @param {Number} lon - Longitude of the GPS coordinate to be converted
1441
+ * @returns {Array} - GPS coordinates (in decimal degrees) as `[latitude, longitude]`
1442
+ */
1443
+ function toLocal(origin, lat, lon) {
1444
+ let pos = [];
1445
+ let [xScale,yScale] = _initConv(origin[0]);
1446
+ pos[0] = (lon-origin[1]) * xScale;
1447
+ pos[1] = (lat-origin[0]) * yScale;
1448
+ return pos;
1449
+ }
1450
+
1451
+ function _initConv(lat){
1452
+ let rlat = lat * Math.PI/180;
1453
+ let yScale = 111132.92 - 559.82*Math.cos(2*rlat) + 1.175*Math.cos(4*rlat) - 0.0023*Math.cos(6*rlat);
1454
+ let xScale = 111412.84*Math.cos(rlat) - 93.5*Math.cos(3*rlat) + 0.118*Math.cos(5*rlat);
1455
+ return [xScale, yScale];
1456
+ }
1457
+
1458
+ /**
1459
+ * A message which requests the transmission of the datagram from the Unet
1460
+ *
1461
+ * @typedef {Message} DatagramReq
1462
+ * @property {number[]} data - data as an Array of bytes
1463
+ * @property {number} from - from/source node address
1464
+ * @property {number} to - to/destination node address
1465
+ * @property {number} protocol - protocol number to be used to send this Datagram
1466
+ * @property {boolean} reliability - true if Datagram should be reliable, false if unreliable
1467
+ * @property {number} ttl - time-to-live for the datagram. Time-to-live is advisory, and an agent may choose it ignore it
1468
+ */
1469
+
1470
+ /**
1471
+ * Notification of received datagram message received by the Unet node.
1472
+ *
1473
+ * @typedef {Message} DatagramNtf
1474
+ * @property {number[]} data - data as an Array of bytes
1475
+ * @property {number} from - from/source node address
1476
+ * @property {number} to - to/destination node address
1477
+ * @property {number} protocol - protocol number to be used to send this Datagram
1478
+ * @property {number} ttl - time-to-live for the datagram. Time-to-live is advisory, and an agent may choose it ignore it
1479
+ */
1480
+
1481
+ /**
1482
+ * An identifier for an agent or a topic.
1483
+ * @external AgentID
1484
+ * @see {@link https://org-arl.github.io/fjage/jsdoc/|fjåge.js Documentation}
1485
+ */
1486
+
1487
+ /**
1488
+ * Services supported by fjage agents.
1489
+ * @external Services
1490
+ * @see {@link https://org-arl.github.io/fjage/jsdoc/|fjåge.js Documentation}
1491
+ */
1492
+
1493
+ /**
1494
+ * An action represented by a message.
1495
+ * @external Performative
1496
+ * @see {@link https://org-arl.github.io/fjage/jsdoc/|fjåge.js Documentation}
1497
+ */
1498
+
1499
+ /**
1500
+ * Function to creates a unqualified message class based on a fully qualified name.
1501
+ * @external MessageClass
1502
+ * @see {@link https://org-arl.github.io/fjage/jsdoc/|fjåge.js Documentation}
1503
+ */
1504
+
1505
+ /**
1506
+ * A caching CachingAgentID which caches Agent parameters locally.
1507
+ *
1508
+ * @class
1509
+ * @extends AgentID
1510
+ * @param {string | AgentID} name - name of the agent or an AgentID to copy
1511
+ * @param {boolean} topic - name of topic
1512
+ * @param {Gateway} owner - Gateway owner for this AgentID
1513
+ * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
1514
+ *
1515
+ */
1516
+ class CachingAgentID extends AgentID {
1517
+
1518
+ constructor(name, topic, owner, greedy=true) {
1519
+ if (name instanceof AgentID) {
1520
+ super(name.getName(), name.topic, name.owner);
1521
+ } else {
1522
+ super(name, topic, owner);
1523
+ }
1524
+ this.greedy = greedy;
1525
+ this.cache = {};
1526
+ }
1527
+
1528
+ /**
1529
+ * Sets parameter(s) on the Agent referred to by this AgentID, and caches the parameter(s).
1530
+ *
1531
+ * @param {(string|string[])} params - parameters name(s) to be set
1532
+ * @param {(Object|Object[])} values - parameters value(s) to be set
1533
+ * @param {number} [index=-1] - index of parameter(s) to be set
1534
+ * @param {number} [timeout=5000] - timeout for the response
1535
+ * @returns {Promise<(Object|Object[])>} - a promise which returns the new value(s) of the parameters
1536
+ */
1537
+ async set(params, values, index=-1, timeout=5000) {
1538
+ let s = await super.set(params, values, index, timeout);
1539
+ this._updateCache(params, s, index);
1540
+ }
1541
+
1542
+ /**
1543
+ * Gets parameter(s) on the Agent referred to by this AgentID, getting them from the cache if possible.
1544
+ *
1545
+ * @param {(string|string[])} params - parameters name(s) to be fetched
1546
+ * @param {number} [index=-1] - index of parameter(s) to be fetched
1547
+ * @param {number} [timeout=5000] - timeout for the response
1548
+ * @param {number} [maxage=5000] - maximum age of the cached result to retreive
1549
+ * @returns {Promise<(Object|Object[])>} - a promise which returns the value(s) of the parameters
1550
+ */
1551
+ async get(params, index=-1, timeout=5000, maxage=5000) {
1552
+ if (this._isCached(params, index, maxage)) return this._getCache(params, index);
1553
+ if (this.greedy && !(Array.isArray(params) && params.includes('name')) && params != 'name') {
1554
+ let rsp = await super.get(null, index, timeout);
1555
+ this._updateCache(null, rsp, index);
1556
+ if (Array.isArray(params)) {
1557
+ return params.map(p => {
1558
+ let f = Object.keys(rsp).find(rv => this._toNamed(rv) === p);
1559
+ return f ? rsp[f] : null;
1560
+ });
1561
+ } else {
1562
+ let f = Object.keys(rsp).find(rv => this._toNamed(rv) === params);
1563
+ return f ? rsp[f] : null;
1564
+ }
1565
+ } else {
1566
+ let r = await super.get(params, index, timeout);
1567
+ this._updateCache(params, r, index);
1568
+ return r;
1569
+ }
1570
+ }
1571
+
1572
+ _updateCache(params, vals, index) {
1573
+ if (vals == null || Array.isArray(vals) && vals.every(v => v == null)) return;
1574
+ if (params == null) {
1575
+ params = Object.keys(vals);
1576
+ vals = Object.values(vals);
1577
+ } else if (!Array.isArray(params)) params = [params];
1578
+ if (!Array.isArray(vals)) vals = [vals];
1579
+ params = params.map(this._toNamed);
1580
+ if (this.cache[index.toString()] === undefined) this.cache[index.toString()] = {};
1581
+ let c = this.cache[index.toString()];
1582
+ for (let i = 0; i < params.length; i++) {
1583
+ if (c[params[i]] === undefined) c[params[i]] = {};
1584
+ c[params[i]].value = vals[i];
1585
+ c[params[i]].ctime = Date.now();
1586
+ }
1587
+ }
1588
+
1589
+ _isCached(params, index, maxage) {
1590
+ if (maxage <= 0) return false;
1591
+ if (params == null) return false;
1592
+ let c = this.cache[index.toString()];
1593
+ if (!c) {
1594
+ return false;
1595
+ }
1596
+ if (!Array.isArray(params)) params = [params];
1597
+ const rv = params.every(p => {
1598
+ p = this._toNamed(p);
1599
+ return (p in c) && (Date.now() - c[p].ctime <= maxage);
1600
+ });
1601
+ return rv;
1602
+ }
1603
+
1604
+ _getCache(params, index) {
1605
+ let c = this.cache[index.toString()];
1606
+ if (!c) return null;
1607
+ if (!Array.isArray(params)){
1608
+ if (params in c) return c[params].value;
1609
+ return null;
1610
+ }else {
1611
+ return params.map(p => p in c ? c[p].value : null);
1612
+ }
1613
+ }
1614
+
1615
+ _toNamed(param) {
1616
+ const idx = param.lastIndexOf('.');
1617
+ if (idx < 0) return param;
1618
+ else return param.slice(idx+1);
1619
+ }
1620
+
1621
+ }
1622
+
1623
+
1624
+ class CachingGateway extends Gateway{
1625
+
1626
+ /**
1627
+ * Get an AgentID for a given agent name.
1628
+ *
1629
+ * @param {string} name - name of agent
1630
+ * @param {Boolean} [caching=true] - if the AgentID should cache parameters
1631
+ * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
1632
+ * @returns {AgentID|CachingAgentID} - AgentID for the given name
1633
+ */
1634
+ agent(name, caching=true, greedy=true) {
1635
+ const aid = super.agent(name);
1636
+ return caching ? new CachingAgentID(aid, null, null, greedy) : aid;
1637
+ }
1638
+
1639
+ /**
1640
+ * Returns an object representing the named topic.
1641
+ *
1642
+ * @param {string|AgentID} topic - name of the topic or AgentID
1643
+ * @param {string} topic2 - name of the topic if the topic param is an AgentID
1644
+ * @param {Boolean} [caching=true] - if the AgentID should cache parameters
1645
+ * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
1646
+ * @returns {AgentID|CachingAgentID} - object representing the topic
1647
+ */
1648
+ topic(topic, topic2, caching=true, greedy=true) {
1649
+ const aid = super.topic(topic, topic2);
1650
+ return caching ? new CachingAgentID(aid, null, null, greedy) : aid;
1651
+ }
1652
+
1653
+ /**
1654
+ * Finds an agent that provides a named service. If multiple agents are registered
1655
+ * to provide a given service, any of the agents' id may be returned.
1656
+ *
1657
+ * @param {string} service - the named service of interest
1658
+ * @param {Boolean} [caching=true] - if the AgentID should cache parameters
1659
+ * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
1660
+ * @returns {Promise<?AgentID|CachingAgentID>} - a promise which returns an agent id for an agent that provides the service when resolved
1661
+ */
1662
+ async agentForService(service, caching=true, greedy=true) {
1663
+ const aid = await super.agentForService(service);
1664
+ return caching ? new CachingAgentID(aid, null, null, greedy) : aid;
1665
+ }
1666
+
1667
+ /**
1668
+ * Finds all agents that provides a named service.
1669
+ *
1670
+ * @param {string} service - the named service of interest
1671
+ * @param {Boolean} [caching=true] - if the AgentID should cache parameters
1672
+ * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
1673
+ * @returns {Promise<?AgentID|CachingAgentID[]>} - a promise which returns an array of all agent ids that provides the service when resolved
1674
+ */
1675
+ async agentsForService(service, caching=true, greedy=true) {
1676
+ const aids = await super.agentsForService(service);
1677
+ return caching ? aids.map(a => new CachingAgentID(a, null, null, greedy)) : aids;
1678
+ }
1679
+ }
1680
+
1420
1681
  const REQUEST_TIMEOUT = 1000;
1421
1682
 
1422
1683
  const AddressResolutionReq = UnetMessages.AddressResolutionReq;
@@ -1425,26 +1686,26 @@ const DatagramNtf = UnetMessages.DatagramNtf;
1425
1686
  const RxFrameNtf = UnetMessages.RxFrameNtf;
1426
1687
 
1427
1688
  /**
1428
- * Creates a new UnetSocket to connect to a running Unet instance. This constructor returns a
1429
- * {@link Promise} instead of the constructed UnetSocket object. Use `await` or `.then()` to get
1430
- * a reference to the UnetSocket object. Based on if this is run in a Browser or Node.js,
1689
+ * Creates a new UnetSocket to connect to a running Unet instance. This constructor returns a
1690
+ * {@link Promise} instead of the constructed UnetSocket object. Use `await` or `.then()` to get
1691
+ * a reference to the UnetSocket object. Based on if this is run in a Browser or Node.js,
1431
1692
  * it will internally connect over WebSockets or TCP respectively.
1432
1693
  *
1433
- *
1694
+ *
1434
1695
  * @class UnetSocket
1435
1696
  * @param {string} [hostname] - hostname/ip address of the master container to connect to
1436
1697
  * @param {number} [port] - port number of the master container to connect to
1437
1698
  * @param {string} [path=''] - path of the master container to connect to (for WebSockets)
1438
1699
  * @returns {Promise<UnetSocket>} - Promise which resolves to the UnetSocket object being constructed
1439
- *
1700
+ *
1440
1701
  * @example
1441
1702
  * let socket = await new UnetSocket('localhost', 8081, '/ws/');
1442
1703
  */
1443
1704
  class UnetSocket {
1444
1705
 
1445
- constructor(hostname, port, path='') {
1706
+ constructor(hostname, port, path='') {
1446
1707
  return (async () => {
1447
- this.gw = new Gateway({
1708
+ this.gw = new CachingGateway({
1448
1709
  hostname : hostname,
1449
1710
  port : port,
1450
1711
  path : path
@@ -1473,13 +1734,13 @@ class UnetSocket {
1473
1734
  * Checks if a socket is closed.
1474
1735
  * @returns {boolean} - true if closed, false if open
1475
1736
  */
1476
- isClosed() {
1737
+ isClosed() {
1477
1738
  return this.gw == null;
1478
1739
  }
1479
1740
 
1480
1741
  /**
1481
1742
  * Binds a socket to listen to a specific protocol datagrams.
1482
- * Protocol numbers between Protocol.DATA+1 to Protocol.USER-1 are reserved protocols
1743
+ * Protocol numbers between Protocol.DATA+1 to Protocol.USER-1 are reserved protocols
1483
1744
  * and cannot be bound. Unbound sockets listen to all unreserved
1484
1745
  * @param {Protocol} protocol - protocol number to listen for
1485
1746
  * @returns {boolean} - true on success, false on failure
@@ -1491,9 +1752,9 @@ class UnetSocket {
1491
1752
  }
1492
1753
  return false;
1493
1754
  }
1494
-
1755
+
1495
1756
  /**
1496
- * Unbinds a socket so that it listens to all unreserved protocols.
1757
+ * Unbinds a socket so that it listens to all unreserved protocols.
1497
1758
  * Protocol numbers between Protocol.DATA+1 to Protocol.USER-1 are considered reserved.
1498
1759
  * @returns {void}
1499
1760
  */
@@ -1506,13 +1767,13 @@ class UnetSocket {
1506
1767
  isBound() { return this.localProtocol >= 0;}
1507
1768
 
1508
1769
  /**
1509
- * Sets the default destination address and destination protocol number for datagrams sent
1510
- * using this socket. The defaults can be overridden for specific send() calls.
1511
- * The default protcol number when a socket is opened is Protcol.DATA.
1512
- * The default node address is undefined.
1513
- * Protocol numbers between Protocol.DATA+1 to Protocol.USER-1 are considered reserved,
1770
+ * Sets the default destination address and destination protocol number for datagrams sent
1771
+ * using this socket. The defaults can be overridden for specific send() calls.
1772
+ * The default protcol number when a socket is opened is Protcol.DATA.
1773
+ * The default node address is undefined.
1774
+ * Protocol numbers between Protocol.DATA+1 to Protocol.USER-1 are considered reserved,
1514
1775
  * and cannot be used for sending datagrams using the socket.
1515
- *
1776
+ *
1516
1777
  * @param {number} to - default destination node address
1517
1778
  * @param {Protocol} protocol - default protocol number
1518
1779
  * @returns {boolean} - true on success, false on failure
@@ -1527,11 +1788,11 @@ class UnetSocket {
1527
1788
  }
1528
1789
 
1529
1790
  /**
1530
- * Resets the default destination address to undefined, and the default protocol number
1791
+ * Resets the default destination address to undefined, and the default protocol number
1531
1792
  * to Protocol.DATA.
1532
1793
  * @returns {void}
1533
1794
  */
1534
- disconnect() {
1795
+ disconnect() {
1535
1796
  this.remoteAddress = -1;
1536
1797
  this.remoteProtocol = 0;
1537
1798
  }
@@ -1546,7 +1807,7 @@ class UnetSocket {
1546
1807
  * Gets the local node address of the Unet node connected to.
1547
1808
  * @returns {Promise<int>} - local node address, or -1 on error
1548
1809
  */
1549
- async getLocalAddress() {
1810
+ async getLocalAddress() {
1550
1811
  if (this.gw == null) return -1;
1551
1812
  const nodeinfo = await this.gw.agentForService(Services.NODE_INFO);
1552
1813
  if (nodeinfo == null) return -1;
@@ -1573,14 +1834,14 @@ class UnetSocket {
1573
1834
  getRemoteProtocol() { return this.remoteProtocol; }
1574
1835
 
1575
1836
  /**
1576
- * Sets the timeout for datagram reception. A timeout of 0 means the
1577
- * {@link UnetSocket#receive|receive method} will check any appropriate
1837
+ * Sets the timeout for datagram reception. A timeout of 0 means the
1838
+ * {@link UnetSocket#receive|receive method} will check any appropriate
1578
1839
  * Datagram has already been received (and is cached) else return immediately.
1579
- *
1840
+ *
1580
1841
  * @param {number} ms - timeout in milliseconds
1581
1842
  * @returns {void}
1582
1843
  */
1583
- setTimeout(ms) {
1844
+ setTimeout(ms) {
1584
1845
  if (ms < 0) ms = 0;
1585
1846
  this.timeout = ms;
1586
1847
  }
@@ -1629,12 +1890,12 @@ class UnetSocket {
1629
1890
  }
1630
1891
 
1631
1892
  /**
1632
- * Receives a datagram sent to the local node and the bound protocol number. If the socket is unbound,
1893
+ * Receives a datagram sent to the local node and the bound protocol number. If the socket is unbound,
1633
1894
  * then datagrams with all unreserved protocols are received. Any broadcast datagrams are also received.
1634
- *
1895
+ *
1635
1896
  * @returns {Promise<?DatagramNtf>} - datagram received by the socket
1636
1897
  */
1637
- async receive() {
1898
+ async receive() {
1638
1899
  if (this.gw == null) return null;
1639
1900
  return await this.gw.receive(msg => {
1640
1901
  if (msg.__clazz__ != DatagramNtf.__clazz__ && msg.__clazz__ != RxFrameNtf.__clazz__ ) return false;
@@ -1655,31 +1916,34 @@ class UnetSocket {
1655
1916
  /**
1656
1917
  * Gets an AgentID providing a specified service for low-level access to UnetStack
1657
1918
  * @param {string} svc - the named service of interest
1919
+ * @param {Boolean} caching - if the AgentID should cache parameters
1658
1920
  * @returns {Promise<?AgentID>} - a promise which returns an {@link AgentID} that provides the service when resolved
1659
1921
  */
1660
- async agentForService(svc) {
1922
+ async agentForService(svc, caching=true) {
1661
1923
  if (this.gw == null) return null;
1662
- return await this.gw.agentForService(svc);
1924
+ return await this.gw.agentForService(svc, caching);
1663
1925
  }
1664
1926
 
1665
1927
  /**
1666
- *
1928
+ *
1667
1929
  * @param {string} svc - the named service of interest
1930
+ * @param {Boolean} caching - if the AgentID should cache parameters
1668
1931
  * @returns {Promise<AgentID[]>} - a promise which returns an array of {@link AgentID|AgentIDs} that provides the service when resolved
1669
1932
  */
1670
- async agentsForService(svc) {
1933
+ async agentsForService(svc, caching=true) {
1671
1934
  if (this.gw == null) return null;
1672
- return await this.gw.agentsForService(svc);
1935
+ return await this.gw.agentsForService(svc, caching``);
1673
1936
  }
1674
1937
 
1675
1938
  /**
1676
1939
  * Gets a named AgentID for low-level access to UnetStack.
1677
1940
  * @param {string} name - name of agent
1941
+ * @param {Boolean} caching - if the AgentID should cache parameters
1678
1942
  * @returns {AgentID} - AgentID for the given name
1679
1943
  */
1680
- agent(name) {
1944
+ agent(name, caching=true) {
1681
1945
  if (this.gw == null) return null;
1682
- return this.gw.agent(name);
1946
+ return this.gw.agent(name, caching);
1683
1947
  }
1684
1948
 
1685
1949
  /**
@@ -1687,7 +1951,7 @@ class UnetSocket {
1687
1951
  * @param {string} nodeName - name of the node to resolve
1688
1952
  * @returns {Promise<?number>} - address of the node, or null if unable to resolve
1689
1953
  */
1690
- async host(nodeName) {
1954
+ async host(nodeName) {
1691
1955
  const arp = await this.agentForService(Services.ADDRESS_RESOLUTION);
1692
1956
  if (arp == null) return null;
1693
1957
  const req = new AddressResolutionReq(nodeName);
@@ -1700,7 +1964,8 @@ class UnetSocket {
1700
1964
  }
1701
1965
 
1702
1966
  exports.AgentID = AgentID;
1703
- exports.Gateway = Gateway;
1967
+ exports.CachingAgentID = CachingAgentID;
1968
+ exports.Gateway = CachingGateway;
1704
1969
  exports.Message = Message;
1705
1970
  exports.MessageClass = MessageClass;
1706
1971
  exports.Performative = Performative;
@@ -1708,3 +1973,5 @@ exports.Protocol = Protocol;
1708
1973
  exports.Services = Services;
1709
1974
  exports.UnetMessages = UnetMessages;
1710
1975
  exports.UnetSocket = UnetSocket;
1976
+ exports.toGps = toGps;
1977
+ exports.toLocal = toLocal;