Skip to content

Commit 103895f

Browse files
Mark JessopMark Jessop
authored andcommitted
Added initial XDATA parser, with OIF411 support
1 parent 49bb7ac commit 103895f

File tree

2 files changed

+126
-0
lines changed

2 files changed

+126
-0
lines changed

build.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ java -jar "../tools/yuicompressor-2.4.8.jar" --type=js --disable-optimizations -
2525
java -jar "../tools/yuicompressor-2.4.8.jar" --type=js --disable-optimizations --nomunge tracker.js >> mobile.js
2626
java -jar "../tools/yuicompressor-2.4.8.jar" --type=js --disable-optimizations --nomunge app.js >> mobile.js
2727
java -jar "../tools/yuicompressor-2.4.8.jar" --type=js --disable-optimizations --nomunge colour-map.js >> mobile.js
28+
java -jar "../tools/yuicompressor-2.4.8.jar" --type=js --disable-optimizations --nomunge xdata.js >> mobile.js
2829

2930
#compile plot lib and config
3031
java -jar "../tools/yuicompressor-2.4.8.jar" --type=js --disable-optimizations --nomunge _jquery.flot.js >> init_plot.js

js/xdata.js

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/* SondeHub XDATA Parser Library
2+
*
3+
* Author: Mark Jessop
4+
*/
5+
6+
function parseOIF411(xdata){
7+
// Attempt to parse an XDATA string from an OIF411 Ozone Sounder
8+
// Returns an object with parameters to be added to the sondes telemetry.
9+
//
10+
// References:
11+
// https://www.vaisala.com/sites/default/files/documents/Ozone%20Sounding%20with%20Vaisala%20Radiosonde%20RS41%20User%27s%20Guide%20M211486EN-C.pdf
12+
//
13+
// Sample data: 0501036402B958B07500 (length = 20 characters)
14+
// More sample data: 0501R20234850000006EI (length = 21 characters)
15+
16+
// Cast to string if not already
17+
xdata = String(xdata);
18+
19+
// Run some checks over the input
20+
if(xdata.length < 20){
21+
// Invalid OIF411 dataset
22+
return {};
23+
}
24+
25+
if(xdata.substr(0,2) !== '05'){
26+
// Not an OIF411 (shouldn't get here)
27+
return {};
28+
}
29+
_output = {'xdata_instrument': 'OIF411'};
30+
31+
// Instrument number is common to all XDATA types.
32+
_output['oif411_instrument_number'] = parseInt(xdata.substr(2,2),16);
33+
34+
35+
if(xdata.length == 21){
36+
// ID Data (Table 19)
37+
// Serial number
38+
_output['oif411_serial'] = xdata.substr(4,8);
39+
40+
// Diagnostics word.
41+
_diagnostics_word = xdata.substr(12,4);
42+
if(_diagnostics_word == '0000'){
43+
_output['oif411_diagnostics'] = "All OK";
44+
}else if(_diagnostics_word == '0004'){
45+
_output['oif411_diagnostics'] = 'Ozone pump temperature below −5 °C.';
46+
}else if(_diagnostics_word == '0400'){
47+
_output['oif411_diagnostics'] = 'Ozone pump battery voltage (+VBatt) is not connected to OIF411';
48+
}else if (_diagnostics_word == '0404'){
49+
_output['oif411_diagnostics'] = 'Ozone pump temp low, and +VBatt not connected.';
50+
}else {
51+
_output['oif411_diagnostics'] = 'Unknown State: ' + _diagnostics_word;
52+
}
53+
54+
// Version number
55+
_output['oif411_version'] = (parseInt(xdata.substr(16,4),16)/100).toFixed(2);
56+
57+
return _output
58+
} else if (xdata.length == 20){
59+
// Measurement Data (Table 18)
60+
// Ozone pump temperature - signed int16
61+
_ozone_pump_temp = parseInt(xdata.substr(4,4),16);
62+
if ((_ozone_pump_temp & 0x8000) > 0) {
63+
_ozone_pump_temp = _ozone_pump_temp - 0x10000;
64+
}
65+
_output['oif411_ozone_pump_temp'] = _ozone_pump_temp*0.01; // Degrees C
66+
67+
// Ozone Pump Current
68+
_output['oif411_ozone_current_uA'] = parseInt(xdata.substr(8,5),16)*0.0001; // micro-Amps
69+
70+
// Battery Voltage
71+
_output['oif411_ozone_battery_v'] = parseInt(xdata.substr(13,2),16)*0.1; // Volts
72+
73+
// Ozone Pump Current
74+
_output['oif411_ozone_pump_curr_mA'] = parseInt(xdata.substr(15,3),16); // mA
75+
76+
// External Voltage
77+
_output['oif411_ext_voltage'] = parseInt(xdata.substr(18,2),16)*0.1; // Volts
78+
79+
80+
return _output
81+
82+
} else {
83+
return {}
84+
}
85+
}
86+
87+
function parseXDATA(data){
88+
// Accept an XDATA string, or multiple XDATA entries, delimited by '#'
89+
// Attempt to parse each one, and return an object
90+
// Test datasets:
91+
// "0501034F02C978A06300"
92+
// "0501R20234850000006EI"
93+
// "0501034F02CA08B06700#800261FCA6F80012F6F40A75"
94+
// "800262358C080012FE6C0A70#0501035902BA08908400"
95+
96+
// Split apart any contatenated xdata.
97+
if(data.includes('#')){
98+
data_split = data.split('#');
99+
} else {
100+
data_split = [data];
101+
}
102+
103+
_output = {};
104+
for(xdata_i = 0; xdata_i < data_split.length; xdata_i++){
105+
_current_xdata = data_split[xdata_i];
106+
107+
// Get Instrument ID
108+
_instrument = _current_xdata.substr(0,2);
109+
110+
if(_instrument === '05'){
111+
// OIF411
112+
_xdata_temp = parseOIF411(_current_xdata);
113+
_output = Object.assign(_output,_xdata_temp);
114+
} else if (_instrument === '80'){
115+
// Unknown!
116+
//console.log("Saw unknown XDATA instrument 0x80.")
117+
} else {
118+
// Unknown!
119+
120+
}
121+
}
122+
123+
return _output
124+
125+
}

0 commit comments

Comments
 (0)