diff --git a/src/libais/ais.h b/src/libais/ais.h index 4619db19..9b3bc20e 100644 --- a/src/libais/ais.h +++ b/src/libais/ais.h @@ -850,6 +850,23 @@ class Ais6_1_40 : public Ais6 { }; ostream& operator<< (ostream &o, const Ais6_1_40 &msg); +// Number of persons on board. ITU 1371-1 +class Ais6_235_10 : public Ais6 { + public: + float ana_int; + float ana_ext1; + float ana_ext2; + int racon; + int light; + bool health; + int stat_ext; + bool off_pos; + int spare2; + + Ais6_235_10(const char *nmea_payload, const size_t pad); +}; +ostream& operator<< (ostream &o, const Ais6_235_10 &msg); + ////////////////////////////////////////////////////////////////////// // 7 and 13 are ACKs for msg 6 and 12 diff --git a/src/libais/ais6.cpp b/src/libais/ais6.cpp index bd4c245e..672e5564 100644 --- a/src/libais/ais6.cpp +++ b/src/libais/ais6.cpp @@ -561,4 +561,37 @@ Ais6_1_40::Ais6_1_40(const char *nmea_payload, const size_t pad) status = AIS_OK; } +// This message provides AtoN (Aid to navigation) monitoring data for the General Lighthouse Authorities (GLA) +Ais6_235_10::Ais6_235_10(const char *nmea_payload, const size_t pad) + : Ais6(nmea_payload, pad), ana_int(0.0), ana_ext1(0.0), ana_ext2(0.0), racon(0), light(0), health(0), stat_ext(0), off_pos(0), spare2(0) { + assert(dac == 235); + assert(fi == 10); + + if (num_bits != 136) { + status = AIS_ERR_BAD_BIT_COUNT; + return; + } + + AisBitset bs; + const AIS_STATUS r = bits.ParseNmeaPayload(nmea_payload, pad); + if (r != AIS_OK) { + status = r; + return; + } + + bits.SeekTo(88); + ana_int = bits.ToUnsignedInt(88, 10) / 20.; + ana_ext1 = bits.ToUnsignedInt(98, 10) / 20.; + ana_ext2 = bits.ToUnsignedInt(108, 10) / 20.; + racon = bits.ToUnsignedInt(118, 2); + light = bits.ToUnsignedInt(120, 2); + health = static_cast(bits[122]); + stat_ext = bits.ToUnsignedInt(123, 8); + off_pos = static_cast(bits[131]); + spare2 = bits.ToUnsignedInt(132, 4); + + assert(bits.GetRemaining() == 0); + status = AIS_OK; +} + } // namespace libais diff --git a/src/libais/ais_py.cpp b/src/libais/ais_py.cpp index a0fcce67..c21db147 100644 --- a/src/libais/ais_py.cpp +++ b/src/libais/ais_py.cpp @@ -36,7 +36,7 @@ enum AIS_FI { AIS_FI_6_200_21_RIS_VTS_ETA = 21, AIS_FI_6_200_22_RIS_VTS_RTA = 22, AIS_FI_6_200_55_RIS_VTS_SAR = 55, - + AIS_FI_6_235_10_ATON_MONITORING_DATA = 10, AIS_FI_8_1_0_TEXT = 0, AIS_FI_8_1_11_MET_HYDRO = 11, AIS_FI_8_1_13_FAIRWAY_CLOSED = 13, @@ -698,6 +698,30 @@ ais6_1_40_append_pydict(const char *nmea_payload, PyObject *dict, return AIS_OK; } +AIS_STATUS +ais6_235_10_append_pydict(const char *nmea_payload, PyObject *dict, + const size_t pad) { + assert(nmea_payload); + assert(dict); + assert(pad < 6); + Ais6_235_10 msg(nmea_payload, pad); + if (msg.had_error()) { + return msg.get_error(); + } + + DictSafeSetItem(dict, "ana_int", msg.ana_int); + DictSafeSetItem(dict, "ana_ext1", msg.ana_ext1); + DictSafeSetItem(dict, "ana_ext2", msg.ana_ext2); + DictSafeSetItem(dict, "racon", msg.racon); + DictSafeSetItem(dict, "light", msg.light); + DictSafeSetItem(dict, "health", msg.health); + DictSafeSetItem(dict, "stat_ext", msg.stat_ext); + DictSafeSetItem(dict, "off_pos", msg.off_pos); + DictSafeSetItem(dict, "spare2", msg.spare2); + + return AIS_OK; +} + PyObject* ais6_to_pydict(const char *nmea_payload, const size_t pad) { assert(nmea_payload); @@ -770,10 +794,19 @@ ais6_to_pydict(const char *nmea_payload, const size_t pad) { DictSafeSetItem(dict, "not_parsed", true); } break; - + case AIS_DAC_235_UNITED_KINGDOM_OF_GREAT_BRITAIN_AND_NORTHERN_IRELAND: // IMO. + switch (msg.fi) { + case AIS_FI_6_235_10_ATON_MONITORING_DATA: // IALA-A126. + status = ais6_235_10_append_pydict(nmea_payload, dict, pad); + break; default: // TODO(schwehr): Raise an exception? DictSafeSetItem(dict, "not_parsed", true); + } + break; + default: + // TODO(schwehr): Raise an exception? + DictSafeSetItem(dict, "not_parsed", true); } if (status != AIS_OK) { diff --git a/src/libais/decode_body.cpp b/src/libais/decode_body.cpp index 0e6a1c9d..ad7e4502 100644 --- a/src/libais/decode_body.cpp +++ b/src/libais/decode_body.cpp @@ -66,6 +66,13 @@ unique_ptr CreateAisMsg6(const string &body, const int fill_bits) { } // FI not handled. break; + case libais::AIS_DAC_235_UNITED_KINGDOM_OF_GREAT_BRITAIN_AND_NORTHERN_IRELAND: + switch (msg.fi) { + case 10: + return MakeUnique(body.c_str(), fill_bits); + } + // FI not handled. + break; } return nullptr; } diff --git a/test/test_data.py b/test/test_data.py index 30f06a7a..9e0f2cf6 100644 --- a/test/test_data.py +++ b/test/test_data.py @@ -673,4 +673,25 @@ 'y': -2.5533333333333332} }, + { + 'nmea': [ '!AIVDM,1,1,4,B,6>jR0600V:C0>da4P106P00,2*02' ], + 'result': {'id': 6, + 'repeat_indicator': 0, + 'mmsi': 992509976, + 'seq': 0, + 'mmsi_dest': 2500912, + 'retransmit': True, + 'spare': 0, + 'dac': 235, + 'fi': 10, + 'ana_int': 13.699999809265137, + 'ana_ext1': 0.05000000074505806, + 'ana_ext2': 0.05000000074505806, + 'racon': 2, + 'light': 2, + 'health': False, + 'stat_ext': 0, + 'off_pos': False, + 'spare2': 0} + }, ]