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