mirror of
https://gitlab.com/wgp/dougal/software.git
synced 2025-12-06 13:07:08 +00:00
Implement SmartSource header parser
This commit is contained in:
@@ -1,10 +1,234 @@
|
||||
|
||||
const NavHeaderError = require('./error');
|
||||
|
||||
function detect (buffer) {
|
||||
return false;
|
||||
const s = buffer.indexOf("*SMSRC");
|
||||
return s != -1 ? s : false;
|
||||
}
|
||||
|
||||
function parse (buffer) {
|
||||
return; // undefined
|
||||
let offset = buffer.indexOf("*SMSRC");
|
||||
|
||||
if (offset == -1) {
|
||||
return; // undefined
|
||||
}
|
||||
|
||||
function ascii (length, start = offset) {
|
||||
// const start = offset;
|
||||
const end = start+length;
|
||||
offset = end;
|
||||
// const v = buffer.subarray(start, end).toString('ascii');
|
||||
// console.log("s, e", start, end, offset);
|
||||
// console.log("v = ", v);
|
||||
// return v;
|
||||
return buffer.subarray(start, end).toString('ascii');
|
||||
}
|
||||
|
||||
const header = {
|
||||
header: (buf, ctx) => {
|
||||
const header = ascii(6);
|
||||
if (header != "*SMSRC") {
|
||||
throw new NavHeaderError("Expected SmartSource marker not found at position " + s, buf);
|
||||
}
|
||||
},
|
||||
|
||||
blk_siz: (buf, ctx) => {
|
||||
return Number(ascii(4));
|
||||
},
|
||||
|
||||
line: (buf, ctx) => {
|
||||
return ascii(30).trim();
|
||||
},
|
||||
|
||||
shot: (buf, ctx) => {
|
||||
return Number(ascii(10));
|
||||
},
|
||||
|
||||
mask: (buf, ctx) => {
|
||||
return Number(ascii(2));
|
||||
},
|
||||
|
||||
trg_mode: (buf, ctx) => {
|
||||
const trg_mode = ascii(1);
|
||||
switch (trg_mode) {
|
||||
case "I":
|
||||
return "internal";
|
||||
case "E":
|
||||
return "external";
|
||||
default:
|
||||
throw new NavHeaderError("Unknown SmartSource trigger mode: " + trg_mode, buf);
|
||||
}
|
||||
},
|
||||
|
||||
time: (buf, ctx) => {
|
||||
const time = ascii(17);
|
||||
'20/08/30:05:45:58'
|
||||
return new Date(time.replace(/(\d{2})\/(\d{2})\/(\d{2}):(\d{2}):(\d{2}):(\d{2})/, "20$1-$2-$3T$4:$5:$6Z"));
|
||||
},
|
||||
|
||||
src_number: (buf, ctx) => {
|
||||
return Number(ascii(1));
|
||||
},
|
||||
|
||||
num_subarray: (buf, ctx) => {
|
||||
return Number(ascii(1));
|
||||
},
|
||||
|
||||
num_guns: (buf, ctx) => {
|
||||
return Number(ascii(2));
|
||||
},
|
||||
|
||||
num_active: (buf, ctx) => {
|
||||
return Number(ascii(2));
|
||||
},
|
||||
|
||||
num_delta: (buf, ctx) => {
|
||||
return Number(ascii(2));
|
||||
},
|
||||
|
||||
num_auto: (buf, ctx) => {
|
||||
return Number(ascii(2));
|
||||
},
|
||||
|
||||
num_nofire: (buf, ctx) => {
|
||||
return Number(ascii(2));
|
||||
},
|
||||
|
||||
spread: (buf, ctx) => {
|
||||
// Convert to ms
|
||||
return Number(ascii(4))/10;
|
||||
},
|
||||
|
||||
volume: (buf, ctx) => {
|
||||
return Number(ascii(6));
|
||||
},
|
||||
|
||||
avg_delta: (buf, ctx) => {
|
||||
return Number(ascii(5));
|
||||
},
|
||||
|
||||
std_delta: (buf, ctx) => {
|
||||
return Number(ascii(5));
|
||||
},
|
||||
|
||||
baroPress: (buf, ctx) => {
|
||||
// Converted to millibars
|
||||
return Number(ascii(6))/100;
|
||||
},
|
||||
|
||||
manifold: (buf, ctx) => {
|
||||
return Number(ascii(4)); // PSI
|
||||
},
|
||||
|
||||
spare: (buf, ctx) => {
|
||||
return ascii(88).trim();
|
||||
},
|
||||
};
|
||||
|
||||
const gun = {
|
||||
string: (buf, ctx) => {
|
||||
return Number(ascii(1));
|
||||
},
|
||||
|
||||
gun: (buf, ctx) => {
|
||||
return Number(ascii(2));
|
||||
},
|
||||
|
||||
source: (buf, ctx) => {
|
||||
return Number(ascii(1));
|
||||
},
|
||||
|
||||
mode: (buf, ctx) => {
|
||||
const v = ascii(1);
|
||||
switch (v) {
|
||||
case "A":
|
||||
case "M":
|
||||
case "O":
|
||||
case "D":
|
||||
return v;
|
||||
default:
|
||||
throw new NavHeaderError("Unrecognised SmartSource gun mode value: "+v, buf);
|
||||
}
|
||||
},
|
||||
|
||||
detect: (buf, ctx) => {
|
||||
const v = ascii(1);
|
||||
switch (v) {
|
||||
case "P":
|
||||
case "Z":
|
||||
case "L":
|
||||
return v;
|
||||
default:
|
||||
throw new NavHeaderError("Unrecognised SmartSource detect value: "+v, buf);
|
||||
}
|
||||
},
|
||||
|
||||
autofire: (buf, ctx) => {
|
||||
const v = ascii(1);
|
||||
switch (v) {
|
||||
case "N": return false;
|
||||
case "Y": return true;
|
||||
default:
|
||||
throw new NavHeaderError("Unrecognised SmartSource autofire value: "+v, buf);
|
||||
}
|
||||
},
|
||||
|
||||
spare: (buf, ctx) => {
|
||||
return ascii(1).trim();
|
||||
},
|
||||
|
||||
aimport: (buf, ctx) => {
|
||||
// Convert to ms
|
||||
return Number(ascii(6))/10;
|
||||
},
|
||||
|
||||
firetime: (buf, ctx) => {
|
||||
// Convert to ms
|
||||
return Number(ascii(6))/10;
|
||||
},
|
||||
|
||||
delay: (buf, ctx) => {
|
||||
// Convert to ms
|
||||
return Number(ascii(4))/10;
|
||||
},
|
||||
|
||||
depth: (buf, ctx) => {
|
||||
// Convert to metres
|
||||
return Number(ascii(4))/10;
|
||||
},
|
||||
|
||||
pressure: (buf, ctx) => {
|
||||
return Number(ascii(4));
|
||||
},
|
||||
|
||||
volume: (buf, ctx) => {
|
||||
return Number(ascii(4));
|
||||
},
|
||||
|
||||
filltime: (buf, ctx) => {
|
||||
return Number(ascii(4));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const smartsource = {};
|
||||
smartsource._type = "smartsource";
|
||||
smartsource._received = new Date();
|
||||
for (const key of Object.keys(header)) {
|
||||
smartsource[key] = header[key](buffer, smartsource);
|
||||
}
|
||||
|
||||
smartsource.guns = [];
|
||||
for (let n=0; n<smartsource.num_guns; n++) {
|
||||
const gunItem = {};
|
||||
for (const key of Object.keys(gun)) {
|
||||
gunItem[key] = gun[key](buffer, gunItem);
|
||||
}
|
||||
smartsource.guns.push(gunItem);
|
||||
}
|
||||
|
||||
return smartsource;
|
||||
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
Reference in New Issue
Block a user