node-red-contrib-tak-registration 0.2.1 → 0.2.2

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.
@@ -1,37 +1,49 @@
1
1
  {
2
- "name": "axios",
3
- "version": "0.25.0",
4
- "description": "Promise based HTTP client for the browser and node.js",
5
- "main": "index.js",
6
- "types": "index.d.ts",
7
- "scripts": {
8
- "test": "grunt test && dtslint",
9
- "start": "node ./sandbox/server.js",
10
- "build": "NODE_ENV=production grunt build",
11
- "preversion": "grunt version && npm test",
12
- "version": "npm run build && git add -A dist && git add CHANGELOG.md bower.json package.json",
13
- "postversion": "git push && git push --tags",
14
- "examples": "node ./examples/server.js",
15
- "coveralls": "cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
16
- "fix": "eslint --fix lib/**/*.js"
2
+ "_from": "axios@0.26.1",
3
+ "_id": "axios@0.26.1",
4
+ "_inBundle": false,
5
+ "_integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
6
+ "_location": "/axios",
7
+ "_phantomChildren": {},
8
+ "_requested": {
9
+ "type": "version",
10
+ "registry": true,
11
+ "raw": "axios@0.26.1",
12
+ "name": "axios",
13
+ "escapedName": "axios",
14
+ "rawSpec": "0.26.1",
15
+ "saveSpec": null,
16
+ "fetchSpec": "0.26.1"
17
17
  },
18
- "repository": {
19
- "type": "git",
20
- "url": "https://github.com/axios/axios.git"
21
- },
22
- "keywords": [
23
- "xhr",
24
- "http",
25
- "ajax",
26
- "promise",
27
- "node"
18
+ "_requiredBy": [
19
+ "#USER",
20
+ "/"
28
21
  ],
29
- "author": "Matt Zabriskie",
30
- "license": "MIT",
22
+ "_resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
23
+ "_shasum": "1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9",
24
+ "_spec": "axios@0.26.1",
25
+ "_where": "/Users/conway/Projects/TAKreg",
26
+ "author": {
27
+ "name": "Matt Zabriskie"
28
+ },
29
+ "browser": {
30
+ "./lib/adapters/http.js": "./lib/adapters/xhr.js"
31
+ },
31
32
  "bugs": {
32
33
  "url": "https://github.com/axios/axios/issues"
33
34
  },
34
- "homepage": "https://axios-http.com",
35
+ "bundleDependencies": false,
36
+ "bundlesize": [
37
+ {
38
+ "path": "./dist/axios.min.js",
39
+ "threshold": "5kB"
40
+ }
41
+ ],
42
+ "dependencies": {
43
+ "follow-redirects": "^1.14.8"
44
+ },
45
+ "deprecated": false,
46
+ "description": "Promise based HTTP client for the browser and node.js",
35
47
  "devDependencies": {
36
48
  "abortcontroller-polyfill": "^1.5.0",
37
49
  "coveralls": "^3.0.0",
@@ -68,19 +80,35 @@
68
80
  "webpack": "^4.44.2",
69
81
  "webpack-dev-server": "^3.11.0"
70
82
  },
71
- "browser": {
72
- "./lib/adapters/http.js": "./lib/adapters/xhr.js"
73
- },
83
+ "homepage": "https://axios-http.com",
74
84
  "jsdelivr": "dist/axios.min.js",
75
- "unpkg": "dist/axios.min.js",
76
- "typings": "./index.d.ts",
77
- "dependencies": {
78
- "follow-redirects": "^1.14.7"
85
+ "keywords": [
86
+ "xhr",
87
+ "http",
88
+ "ajax",
89
+ "promise",
90
+ "node"
91
+ ],
92
+ "license": "MIT",
93
+ "main": "index.js",
94
+ "name": "axios",
95
+ "repository": {
96
+ "type": "git",
97
+ "url": "git+https://github.com/axios/axios.git"
79
98
  },
80
- "bundlesize": [
81
- {
82
- "path": "./dist/axios.min.js",
83
- "threshold": "5kB"
84
- }
85
- ]
99
+ "scripts": {
100
+ "build": "NODE_ENV=production grunt build",
101
+ "coveralls": "cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
102
+ "examples": "node ./examples/server.js",
103
+ "fix": "eslint --fix lib/**/*.js",
104
+ "postversion": "git push && git push --tags",
105
+ "preversion": "grunt version && npm test",
106
+ "start": "node ./sandbox/server.js",
107
+ "test": "grunt test && dtslint",
108
+ "version": "npm run build && git add -A dist && git add CHANGELOG.md bower.json package.json"
109
+ },
110
+ "types": "index.d.ts",
111
+ "typings": "./index.d.ts",
112
+ "unpkg": "dist/axios.min.js",
113
+ "version": "0.26.1"
86
114
  }
@@ -336,96 +336,101 @@ RedirectableRequest.prototype._processResponse = function (response) {
336
336
  // the user agent MAY automatically redirect its request to the URI
337
337
  // referenced by the Location field value,
338
338
  // even if the specific status code is not understood.
339
+
340
+ // If the response is not a redirect; return it as-is
339
341
  var location = response.headers.location;
340
- if (location && this._options.followRedirects !== false &&
341
- statusCode >= 300 && statusCode < 400) {
342
- // Abort the current request
343
- abortRequest(this._currentRequest);
344
- // Discard the remainder of the response to avoid waiting for data
345
- response.destroy();
346
-
347
- // RFC7231§6.4: A client SHOULD detect and intervene
348
- // in cyclical redirections (i.e., "infinite" redirection loops).
349
- if (++this._redirectCount > this._options.maxRedirects) {
350
- this.emit("error", new TooManyRedirectsError());
351
- return;
352
- }
342
+ if (!location || this._options.followRedirects === false ||
343
+ statusCode < 300 || statusCode >= 400) {
344
+ response.responseUrl = this._currentUrl;
345
+ response.redirects = this._redirects;
346
+ this.emit("response", response);
353
347
 
354
- // RFC7231§6.4: Automatic redirection needs to done with
355
- // care for methods not known to be safe, []
356
- // RFC7231§6.4.2–3: For historical reasons, a user agent MAY change
357
- // the request method from POST to GET for the subsequent request.
358
- if ((statusCode === 301 || statusCode === 302) && this._options.method === "POST" ||
359
- // RFC7231§6.4.4: The 303 (See Other) status code indicates that
360
- // the server is redirecting the user agent to a different resource […]
361
- // A user agent can perform a retrieval request targeting that URI
362
- // (a GET or HEAD request if using HTTP) […]
363
- (statusCode === 303) && !/^(?:GET|HEAD)$/.test(this._options.method)) {
364
- this._options.method = "GET";
365
- // Drop a possible entity and headers related to it
366
- this._requestBodyBuffers = [];
367
- removeMatchingHeaders(/^content-/i, this._options.headers);
368
- }
348
+ // Clean up
349
+ this._requestBodyBuffers = [];
350
+ return;
351
+ }
369
352
 
370
- // Drop the Host header, as the redirect might lead to a different host
371
- var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers);
353
+ // The response is a redirect, so abort the current request
354
+ abortRequest(this._currentRequest);
355
+ // Discard the remainder of the response to avoid waiting for data
356
+ response.destroy();
372
357
 
373
- // If the redirect is relative, carry over the host of the last request
374
- var currentUrlParts = url.parse(this._currentUrl);
375
- var currentHost = currentHostHeader || currentUrlParts.host;
376
- var currentUrl = /^\w+:/.test(location) ? this._currentUrl :
377
- url.format(Object.assign(currentUrlParts, { host: currentHost }));
358
+ // RFC7231§6.4: A client SHOULD detect and intervene
359
+ // in cyclical redirections (i.e., "infinite" redirection loops).
360
+ if (++this._redirectCount > this._options.maxRedirects) {
361
+ this.emit("error", new TooManyRedirectsError());
362
+ return;
363
+ }
378
364
 
379
- // Determine the URL of the redirection
380
- var redirectUrl;
381
- try {
382
- redirectUrl = url.resolve(currentUrl, location);
383
- }
384
- catch (cause) {
385
- this.emit("error", new RedirectionError(cause));
386
- return;
387
- }
365
+ // RFC7231§6.4: Automatic redirection needs to done with
366
+ // care for methods not known to be safe, […]
367
+ // RFC7231§6.4.2–3: For historical reasons, a user agent MAY change
368
+ // the request method from POST to GET for the subsequent request.
369
+ if ((statusCode === 301 || statusCode === 302) && this._options.method === "POST" ||
370
+ // RFC7231§6.4.4: The 303 (See Other) status code indicates that
371
+ // the server is redirecting the user agent to a different resource […]
372
+ // A user agent can perform a retrieval request targeting that URI
373
+ // (a GET or HEAD request if using HTTP) […]
374
+ (statusCode === 303) && !/^(?:GET|HEAD)$/.test(this._options.method)) {
375
+ this._options.method = "GET";
376
+ // Drop a possible entity and headers related to it
377
+ this._requestBodyBuffers = [];
378
+ removeMatchingHeaders(/^content-/i, this._options.headers);
379
+ }
388
380
 
389
- // Create the redirected request
390
- debug("redirecting to", redirectUrl);
391
- this._isRedirect = true;
392
- var redirectUrlParts = url.parse(redirectUrl);
393
- Object.assign(this._options, redirectUrlParts);
381
+ // Drop the Host header, as the redirect might lead to a different host
382
+ var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers);
394
383
 
395
- // Drop the confidential headers when redirecting to another domain
396
- if (!(redirectUrlParts.host === currentHost || isSubdomainOf(redirectUrlParts.host, currentHost))) {
397
- removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers);
398
- }
384
+ // If the redirect is relative, carry over the host of the last request
385
+ var currentUrlParts = url.parse(this._currentUrl);
386
+ var currentHost = currentHostHeader || currentUrlParts.host;
387
+ var currentUrl = /^\w+:/.test(location) ? this._currentUrl :
388
+ url.format(Object.assign(currentUrlParts, { host: currentHost }));
399
389
 
400
- // Evaluate the beforeRedirect callback
401
- if (typeof this._options.beforeRedirect === "function") {
402
- var responseDetails = { headers: response.headers };
403
- try {
404
- this._options.beforeRedirect.call(null, this._options, responseDetails);
405
- }
406
- catch (err) {
407
- this.emit("error", err);
408
- return;
409
- }
410
- this._sanitizeOptions(this._options);
411
- }
390
+ // Determine the URL of the redirection
391
+ var redirectUrl;
392
+ try {
393
+ redirectUrl = url.resolve(currentUrl, location);
394
+ }
395
+ catch (cause) {
396
+ this.emit("error", new RedirectionError(cause));
397
+ return;
398
+ }
399
+
400
+ // Create the redirected request
401
+ debug("redirecting to", redirectUrl);
402
+ this._isRedirect = true;
403
+ var redirectUrlParts = url.parse(redirectUrl);
404
+ Object.assign(this._options, redirectUrlParts);
405
+
406
+ // Drop confidential headers when redirecting to a less secure protocol
407
+ // or to a different domain that is not a superdomain
408
+ if (redirectUrlParts.protocol !== currentUrlParts.protocol &&
409
+ redirectUrlParts.protocol !== "https:" ||
410
+ redirectUrlParts.host !== currentHost &&
411
+ !isSubdomain(redirectUrlParts.host, currentHost)) {
412
+ removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers);
413
+ }
412
414
 
413
- // Perform the redirected request
415
+ // Evaluate the beforeRedirect callback
416
+ if (typeof this._options.beforeRedirect === "function") {
417
+ var responseDetails = { headers: response.headers };
414
418
  try {
415
- this._performRequest();
419
+ this._options.beforeRedirect.call(null, this._options, responseDetails);
416
420
  }
417
- catch (cause) {
418
- this.emit("error", new RedirectionError(cause));
421
+ catch (err) {
422
+ this.emit("error", err);
423
+ return;
419
424
  }
425
+ this._sanitizeOptions(this._options);
420
426
  }
421
- else {
422
- // The response is not a redirect; return it as-is
423
- response.responseUrl = this._currentUrl;
424
- response.redirects = this._redirects;
425
- this.emit("response", response);
426
427
 
427
- // Clean up
428
- this._requestBodyBuffers = [];
428
+ // Perform the redirected request
429
+ try {
430
+ this._performRequest();
431
+ }
432
+ catch (cause) {
433
+ this.emit("error", new RedirectionError(cause));
429
434
  }
430
435
  };
431
436
 
@@ -559,7 +564,7 @@ function abortRequest(request) {
559
564
  request.abort();
560
565
  }
561
566
 
562
- function isSubdomainOf(subdomain, domain) {
567
+ function isSubdomain(subdomain, domain) {
563
568
  const dot = subdomain.length - domain.length - 1;
564
569
  return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain);
565
570
  }
@@ -1,27 +1,27 @@
1
1
  {
2
- "_from": "follow-redirects@^1.14.4",
3
- "_id": "follow-redirects@1.14.7",
2
+ "_from": "follow-redirects@^1.14.8",
3
+ "_id": "follow-redirects@1.14.9",
4
4
  "_inBundle": false,
5
- "_integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==",
6
- "_location": "/node-red-contrib-takfiles/follow-redirects",
5
+ "_integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==",
6
+ "_location": "/follow-redirects",
7
7
  "_phantomChildren": {},
8
8
  "_requested": {
9
9
  "type": "range",
10
10
  "registry": true,
11
- "raw": "follow-redirects@^1.14.4",
11
+ "raw": "follow-redirects@^1.14.8",
12
12
  "name": "follow-redirects",
13
13
  "escapedName": "follow-redirects",
14
- "rawSpec": "^1.14.4",
14
+ "rawSpec": "^1.14.8",
15
15
  "saveSpec": null,
16
- "fetchSpec": "^1.14.4"
16
+ "fetchSpec": "^1.14.8"
17
17
  },
18
18
  "_requiredBy": [
19
- "/node-red-contrib-takfiles/axios"
19
+ "/axios"
20
20
  ],
21
- "_resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
22
- "_shasum": "2004c02eb9436eee9a21446a6477debf17e81685",
23
- "_spec": "follow-redirects@^1.14.4",
24
- "_where": "/Users/conway/Projects/DCJNodes/takfile/node_modules/axios",
21
+ "_resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
22
+ "_shasum": "dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7",
23
+ "_spec": "follow-redirects@^1.14.8",
24
+ "_where": "/Users/conway/Projects/TAKreg/node_modules/axios",
25
25
  "author": {
26
26
  "name": "Ruben Verborgh",
27
27
  "email": "ruben@verborgh.org",
@@ -91,5 +91,5 @@
91
91
  "mocha": "nyc mocha",
92
92
  "test": "npm run lint && npm run mocha"
93
93
  },
94
- "version": "1.14.7"
94
+ "version": "1.14.9"
95
95
  }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
- "name" : "node-red-contrib-tak-registration",
3
- "version" : "0.2.1",
4
- "description" : "A Node-RED node to register to TAK and to help wrap files as datapackages to send to TAK",
5
- "dependencies" : {
2
+ "name": "node-red-contrib-tak-registration",
3
+ "version": "0.2.2",
4
+ "description": "A Node-RED node to register to TAK and to help wrap files as datapackages to send to TAK",
5
+ "dependencies": {
6
6
  "adm-zip": "^0.5.9",
7
- "axios": "^0.25.0",
7
+ "axios": "^0.26.1",
8
8
  "form-data": "^4.0.0",
9
9
  "uuid": "^8.3.2"
10
10
  },
@@ -14,19 +14,26 @@
14
14
  "form-data",
15
15
  "uuid"
16
16
  ],
17
- "repository" : {
18
- "type":"git",
19
- "url":"https://github.com/dceejay/takreg/tree/master/"
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/dceejay/takreg/tree/master/"
20
20
  },
21
21
  "license": "Apache-2.0",
22
- "keywords": [ "TAK" ],
23
- "node-red" : {
24
- "nodes" : {
25
- "takfiles": "tak-registration.js"
22
+ "keywords": [
23
+ "TAK",
24
+ "node-red"
25
+ ],
26
+ "node-red": {
27
+ "version": ">=2.0.0",
28
+ "nodes": {
29
+ "tak registration": "tak-registration.js"
26
30
  }
27
31
  },
28
32
  "author": {
29
33
  "name": "Dave Conway-Jones",
30
34
  "email": "dceejay@gmail.com"
35
+ },
36
+ "engines": {
37
+ "node": ">=12"
31
38
  }
32
39
  }
@@ -64,6 +64,9 @@
64
64
  <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
65
65
  <input type="text" id="node-input-name">
66
66
  </div>
67
+ <div class="form-tips" id="pin-tip"><b>Note</b>: This node MUST be used in conjunction with a TCP request node,
68
+ configured to point to your TAK server tcp address and port (usually 8087 or 8089), set to return strings,
69
+ <i>keep connection open</i> mode, and split on "&lt;/event&gt;"</div>
67
70
  </script>
68
71
  <style>
69
72
  .inject-time-count {
@@ -122,8 +125,8 @@
122
125
  <script type="text/html" data-help-name="tak registration">
123
126
  <p>Registers a TAK gateway node and sets up a heartbeat.</p>
124
127
  <p>Works in conjunction with a TCP request node, set to point to the TAK server tcp address and port
125
- (usually 8087 or 8089), set to return strings, <i>keep connection open</i> mode, and split on <code>&lt;event/&gt;</code>.</p>
126
- <p>If the `msg.payload` is an XML string it will be passed directly though.</p>
128
+ (usually 8087 or 8089), set to return strings, <i>keep connection open</i> mode, and split on <code>&lt;/event&gt;</code>.</p>
129
+ <p>If the <code>msg.payload</code> is an XML string it will be passed directly though.</p>
127
130
 
128
131
  <h3>Sending data packages...</h3>
129
132
  <dl class="message-properties">
@@ -136,25 +139,23 @@
136
139
  <dd>each object must contain at least a <b>filename</b> (string) and <b>content</b> a buffer of the file/data.
137
140
  eg <code>[{filename:"foo.kml", content: &lt;buffer of the file&gt;}]</code></dd>
138
141
  </dl>
139
-
140
142
  <h3>Sending marker position...</h3>
141
143
  <dl class="message-properties">
142
144
  <dt>payload <span class="property-type">object</span></dt>
143
- <dd>a "standard" <b>node-red worldmap</b> format msg.payload containing `name, lat, lon, type or SIDC,
144
- (alt), (speed), (bearing), (layer)`, where type is the CoT type eg a-f-g-u or the SIDC is
145
- the standard mil 2525C code, eg SFGPU. The layer will get turned int a hastag which can then
146
- be selected on/off in the TAK app.</dd>
145
+ <dd>a "standard" <b>node-red worldmap</b> format msg.payload containing `name, lat, lon, SIDC or cottype or aistype,
146
+ (alt), (speed), (bearing), (layer)`, where SIDC is the standard mil 2525C code, eg SFGPU, or cottype is the
147
+ CoT type, eg a-f-g-u, or aistype is the AIS type code, eg 80 for a tanker. The layer will get turned into a hashtag
148
+ which can then be selected on/off in the TAK app layers control.</dd>
147
149
  </dl>
148
150
 
149
151
  <h3>Updating gateway position...</h3>
150
152
  <dl class="message-properties">
151
153
  <dt>payload <span class="property-type">string | object</span></dt>
152
- <dd>Either an NMEA string starting `$GPGGA` or an object containing `lat` and `lon` and
153
- optional `alt` properties (but no name property).</dd>
154
+ <dd>Either an NMEA string starting `$GPGGA`, for example from a locally attached serial GPS, or an object
155
+ containing `lat` and `lon` and optional `alt` properties (but no name property).</dd>
154
156
  </dl>
155
-
156
157
  <h3>Details</h3>
157
158
  <p>This should work almost directly with messages received from an email-in node for example -
158
159
  but you will need to add the recipients in the sendTo property and may need to filter out
159
160
  unwanted messages first.</p>
160
- </script>
161
+ </script>
@@ -57,10 +57,10 @@ module.exports = function(RED) {
57
57
  setTimeout(sendIt, 2500);
58
58
 
59
59
  node.on("input",function(msg) {
60
- if (msg.heartbeat) { // Register gateway and do the heartbeats √<takv device="${os.hostname()}" platform="${os.type()}" />
60
+ if (msg.heartbeat) { // Register gateway and do the heartbeats
61
61
  var template = `<event version="2.0" uid="${node.uuid}" type="${msg.type}" how="h-e" time="${msg.time}" start="${msg.time}" stale="${msg.etime}"><point lat="${msg.lat}" lon="${msg.lon}" hae="${msg.alt}" ce="9999999" le="9999999"/><detail><takv device="${os.hostname()}" os="${os.platform()}" platform="NRedTAK" version="${ver}"/><contact endpoint="*:-1:stcp" callsign="${msg.callsign}"/><uid Droid="${msg.callsign}"/><__group name="${msg.group}" role="${msg.role}"/><status battery="99"/></detail></event>`;
62
62
  node.send({payload:template});
63
- node.status({fill:"green", shape:"dot", text: node.repeat/1000+"s - "+node.callsign});
63
+ node.status({fill:"green", shape:"dot", text:node.repeat/1000+"s - "+node.callsign});
64
64
  return;
65
65
  }
66
66
  // If there are attachments handle them first.
@@ -170,17 +170,22 @@ module.exports = function(RED) {
170
170
  }
171
171
  }
172
172
  }
173
- // Handle a generic worldmap marker style as a normal marker -
173
+ // Handle a generic worldmap marker style as a normal marker
174
174
  else if (typeof msg.payload === "object" && msg.payload.hasOwnProperty("name") && msg.payload.hasOwnProperty("lat") && msg.payload.hasOwnProperty("lon")) {
175
175
  var d = new Date();
176
176
  var st = d.toISOString();
177
177
  var ttl = ((msg.payload.ttl || 0) * 1000) || 60000;
178
178
  var et = Date.now() + ttl;
179
179
  et = (new Date(et)).toISOString();
180
- var tag ="#Worldmap";
181
- if (msg.payload.layer) { tag = "#" + msg.payload.layer }
182
- var type = msg.payload.type || "a-u-g-u";
183
- if (!msg.payload.type && msg.payload.SIDC) {
180
+ var tag = msg.payload.remarks || "";
181
+ if (msg.payload.tag) { tag += " " + msg.payload.tag }
182
+ if (msg.payload.layer) { tag += " #" + msg.payload.layer }
183
+ else { tag += " #Worldmap"; }
184
+ var type = msg.payload.cottype || "a-u-g-u";
185
+ if (!msg.payload.cottype && !msg.payload.SIDC && msg.payload.aistype) {
186
+ msg.payload.SIDC = ais2sidc(msg.payload.aistype);
187
+ }
188
+ if (!msg.payload.cottype && msg.payload.SIDC) {
184
189
  var s = msg.payload.SIDC.split('-')[0].toLowerCase();
185
190
  if (s.startsWith('s')) {
186
191
  type = s.split('').join('-').replace('s-','a-').replace('-p-','-');
@@ -199,13 +204,14 @@ module.exports = function(RED) {
199
204
  msg.payload = msg.payload.replace(/>\s+</g, "><");
200
205
  node.send(msg);
201
206
  }
207
+ // Just has lat, lon (and alt) but no name - assume it's our local position we're updating
202
208
  else if (typeof msg.payload === "object" && !msg.payload.hasOwnProperty("name") && msg.payload.hasOwnProperty("lat") && msg.payload.hasOwnProperty("lon")) {
203
- // just has lat, lon (and alt) but no name - assume it's us we're updating
204
209
  node.lat = msg.payload.lat;
205
210
  node.lon = msg.payload.lon;
206
211
  if (msg.payload.hasOwnProperty("alt")) { node.alt = parseInt(msg.payload.alt); }
207
212
  }
208
- else { // Drop anything we don't handle yet.
213
+ // Drop anything we don't handle yet.
214
+ else {
209
215
  node.log("Dropped: "+JSON.stringify(msg.payload));
210
216
  }
211
217
  });
@@ -219,5 +225,50 @@ module.exports = function(RED) {
219
225
  });
220
226
  }
221
227
 
222
- RED.nodes.registerType("tak registration",TakRegistrationNode);
223
- };
228
+ var aisToSidc1 = {
229
+ 4: "SFSPXA------",
230
+ 5: "SFSPXM------",
231
+ 6: "SFSPXMP-----",
232
+ 7: "SFSPXMC-----",
233
+ 8: "SFSPXMO-----",
234
+ 9: "SFSPXM------"
235
+ }
236
+
237
+ var aisToSidc2 = {
238
+ 30: "SFSPXF------",
239
+ 31: "SFSPXMTO----",
240
+ 32: "SFSPXMTO--NS",
241
+ 33: "SFSPXFDR----",
242
+ 34: "SFUPND------",
243
+ 35: "SFSP--------",
244
+ 36: "SFSPXR------",
245
+ 37: "SFSPXA------",
246
+ 40: "SFSPXA------", //-
247
+ 50: "SFSPXM------", //-
248
+ 52: "SFSPXMTU----",
249
+ 53: "SFSPNS------",
250
+ 55: "SFSPXL------",
251
+ 58: "SFSPNM------",
252
+ 60: "SFSPXMP-----", //-
253
+ 70: "SFSPXMC-----", //-
254
+ 71: "SFSPXMH-----",
255
+ 72: "SFSPXMH-----",
256
+ 73: "SFSPXMH-----",
257
+ 74: "SFSPXMH-----",
258
+ 80: "SFSPXMO-----", //-
259
+ 90: "SFSPXM------", //-
260
+ }
261
+
262
+ var ais2sidc = function (aisType) {
263
+ //aisType = Number(aisType);
264
+ if (aisType >= 100) { return "GNMPOHTH----"; }
265
+ aisType = aisToSidc2[aisType];
266
+ if (aisType && isNaN(aisType)) { return aisType; }
267
+ aisType = parseInt(aisType / 10);
268
+ aisType = aisToSidc1[aisType];
269
+ if (aisType && isNaN(aisType)) { return aisType; }
270
+ return "SFSPXM------";
271
+ }
272
+
273
+ RED.nodes.registerType("tak registration", TakRegistrationNode);
274
+ };