@signalk/nmea0183-signalk
Version:
A node.js/javascript parser for NMEA0183 sentences. Sentences are parsed to Signal K format.
248 lines • 8.22 kB
JavaScript
;
/**
* Copyright 2016 Signal K and Fabian Tollenaar <fabian@signalk.org>.
* Based on the work by Philip J Freeman
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const debug_1 = __importDefault(require("debug"));
const debug = (0, debug_1.default)('signalk-parser-nmea0183/DSC');
function isEmpty(mixed) {
return typeof mixed !== 'string' || mixed.trim() === '';
}
function parsePosition(line) {
/*
* Position Format:
*
* / Quadrant Id ("0" = NE, "1" = NW, "2" = SE, and "3" = SW
* |
* |/ Degrees Latitude
* ||
* || / Minutes Latitude
* || |
* || | / Degrees Longitude
* || | |
* || | | / Minutes Longitude
* || | | |
* 1YYyyXXXxx
*/
var lat = parseFloat(line.substring(1, 3));
var lat_min = parseFloat(line.substring(3, 5));
var lat_dec = lat + lat_min / 60;
var lon = parseFloat(line.substring(5, 8));
var lon_min = parseFloat(line.substring(8, 10));
var lon_dec = lon + lon_min / 60;
var quadrant = parseInt(line.substring(0, 1));
if (quadrant == 1 || quadrant == 3) {
lon_dec = lon_dec * -1;
}
if (quadrant == 2 || quadrant == 3) {
lat_dec = lat_dec * -1;
}
debug('lat: ' + lat_dec + ' ,lon: ' + lon_dec);
return { longitude: lon_dec, latitude: lat_dec };
}
const DSC = function (input, _session) {
const { sentence, parts, tags } = input;
var values = [];
const empty = parts.reduce((e, val) => {
if (isEmpty(val)) {
++e;
}
return e;
}, 0);
if (empty > 3) {
return null;
}
// for some reason, it seems the sender identification is mmsi+'0', so we
// strip the trailing zero to get a 9 digit mmsi
var mmsi = parts[1].substring(0, 9);
debug('mmsi: ' + mmsi);
var handled = false;
var get_position = false;
var distress = false;
var distress_nature = '';
switch (parts[2]) {
case '00': // routine category
switch (parts[3]) {
case '21': // ship position
handled = true;
get_position = true;
break;
//case '??': // other telecommands
}
break;
case '08': // * 108 = safety
break;
case '10': // * 110 = urgency
break;
case '12': // * 112 = distress
handled = true;
get_position = true;
distress = true;
switch (parts[3] // Nature of Distress
) {
case '00': // = Fire, explosion
distress_nature = 'fire';
break;
case '01': // = Flooding
distress_nature = 'flooding';
break;
case '02': // = Collision
distress_nature = 'collision';
break;
case '03': // = Grounding
distress_nature = 'grounding';
break;
case '04': // = Listing, in danger of capsize
distress_nature = 'listing';
break;
case '05': // = Sinking
distress_nature = 'sinking';
break;
case '06': // = Disabled and adrift
distress_nature = 'adrift';
break;
case '07': // = Undesignated distres
distress_nature = 'undesignated';
break;
case '08': // = Abandoning ship
distress_nature = 'abandon';
break;
case '09': // = Piracy/armed robbery attack
distress_nature = 'piracy';
break;
case '10': // = Man overboard
distress_nature = 'mob';
break;
case '12': // = EPRIB emission
distress_nature = 'epirb';
break;
default:
// unassigned symbol; take no action
distress_nature = 'unassigned';
}
}
/*values.push({
path: "",
value: {
mmsi: parts[1]!
}
})*/
if (get_position) {
var position = parsePosition(parts[5]);
values.push({
path: 'navigation.position',
value: {
latitude: position.latitude,
longitude: position.longitude
}
});
}
if (distress) {
values.push({
path: 'notifications.' + distress_nature,
value: {
message: 'DSC Distress Recieved! Nature of distress: ' + distress_nature
}
});
}
if (!handled) {
debug('DSC Message Not Handled: ' + sentence);
values.push({
path: 'notifications.dsc_parser',
value: {
message: 'DSC Message Not Handled: ' + sentence
}
});
}
if (values.length === 0) {
return null;
}
return {
updates: [
{
source: tags.source,
timestamp: tags.timestamp,
values: values
}
],
context: 'vessels.urn:mrn:imo:mmsi:' + mmsi
};
};
/*
* DSC Codec - Some DSC Capable VHF Radios output DSC Sentences
*
* This codec currently contains basic support for distress messages and
* position messages.
*
* NOTE: The position in the DSC sentence is only accurate to the minute,
* however, there is an extended sentence that provides further detail. The
* DSE Sentence (which can follow the DSC sentence) contains further position
* detail.
*
*
* Documentation for DSC Sentences:
*
* * http://continuouswave.com/whaler/reference/DSC_Datagrams.html
*
* Distress Alert Example:
* $CDDSC,12,3380400790,12,06,00,1423108312,2019,,,S,E*6A
* $CDDSE,1,1,A,3380400790,00,45894494*1B
*
* Distress Cancelation (unsupported):
* $CDDSC,12,3381581370,12,06,00,1423108312,0236,3381581370,,S,*20
*
* Example of Non-Distress Call:
* $CDDSC,20,3381581370,00,21,26,1423108312,1902,,,B,E*7B
*
*
*
* 0 1 2 3 4 5 6 9 10
* | | | | | | | | |
* $--DSC,XX,XXXXXXXXXX,XX,XX,XX,XXXXXXXXXX,XXXX,,,A,C*hh<CR><LF>
*
* Field Number:
* 0. Format Specifier (without first digit)
* 102 = selective call to a group of ships in particular geographic area
* 112 = distress alert call
* 114 = selective call to a group of ships having common interest
* 116 = all ships call
* 120 = selective call to particular individual station
* 123 = selective call to a particular individual using automatic service
*
* 1. Sender MMSI
* 2. Category Element (without first digit)
* 100 = Routine
* 108 = Safety
* 110 = Urgency
* 112 = Distress
*
* 3. variable based on Category
* 4. variable based on category
* 5. Sender Position
* 6. time in UTC
* 7. address of vessel in distress (if different than sending vessel?)
* 8. Unknown
* 9. Unknown (It may be a representation of a service command)
* 10. Expansion message follows
* E = true
* ' '= false
*
*/
exports.default = DSC;
//# sourceMappingURL=DSC.js.map