From 6b8f80981f791bdd0e1f35ea6fd40d04d5f01924 Mon Sep 17 00:00:00 2001 From: Christian Gagneraud Date: Tue, 5 Jun 2012 14:12:10 +0100 Subject: [AIS] Do scaling/offset operations only in json dump splint and check pass. --- driver_ais.c | 30 +++++--------------- gps.h | 56 ++++++++++++++++++++++++++----------- gpsd_json.c | 60 ++++++++++++++++++++-------------------- gpsdecode.c | 2 +- jsongen.py.in | 12 ++++---- test/sample.aivdm.chk | 6 ++-- test/synthetic-ais.json | 4 +-- www/AIVDM.txt | 73 ++++++++++++++++++++++++------------------------- 8 files changed, 125 insertions(+), 118 deletions(-) diff --git a/driver_ais.c b/driver_ais.c index 992063a3..385a448c 100644 --- a/driver_ais.c +++ b/driver_ais.c @@ -26,15 +26,6 @@ * Parse the data from the device */ -#define DAC1FID11_AIRTEMP_OFFSET 600 -#define DAC1FID11_DEWPOINT_OFFSET 200 -#define DAC1FID11_PRESSURE_OFFSET -800 -#define DAC1FID11_LEVEL_OFFSET 100 -#define DAC1FID11_WATERTEMP_OFFSET 100 - -#define DAC1FID31_PRESSURE_OFFSET -799 -#define DAC1FID31_LEVEL_OFFSET 1000 - static void from_sixbit(char *bitvec, uint start, int count, char *to) { /*@ +type @*/ @@ -408,17 +399,13 @@ bool ais_binary_decode(struct ais_t *ais, ais->type8.dac1fid11.wgust = UBITS(128, 7); ais->type8.dac1fid11.wdir = UBITS(135, 9); ais->type8.dac1fid11.wgustdir = UBITS(144, 9); - ais->type8.dac1fid11.airtemp = UBITS(153, 11) - - DAC1FID11_AIRTEMP_OFFSET; + ais->type8.dac1fid11.airtemp = UBITS(153, 11); ais->type8.dac1fid11.humidity = UBITS(164, 7); - ais->type8.dac1fid11.dewpoint = UBITS(171, 10) - - DAC1FID11_DEWPOINT_OFFSET; - ais->type8.dac1fid11.pressure = UBITS(181, 9) - - DAC1FID11_PRESSURE_OFFSET; + ais->type8.dac1fid11.dewpoint = UBITS(171, 10); + ais->type8.dac1fid11.pressure = UBITS(181, 9); ais->type8.dac1fid11.pressuretend = UBITS(190, 2); ais->type8.dac1fid11.visibility = UBITS(192, 8); - ais->type8.dac1fid11.waterlevel = UBITS(200, 9) - - DAC1FID11_LEVEL_OFFSET; + ais->type8.dac1fid11.waterlevel = UBITS(200, 9); ais->type8.dac1fid11.leveltrend = UBITS(209, 2); ais->type8.dac1fid11.cspeed = UBITS(211, 8); ais->type8.dac1fid11.cdir = UBITS(219, 9); @@ -435,8 +422,7 @@ bool ais_binary_decode(struct ais_t *ais, ais->type8.dac1fid11.swellperiod = UBITS(303, 6); ais->type8.dac1fid11.swelldir = UBITS(309, 9); ais->type8.dac1fid11.seastate = UBITS(318, 4); - ais->type8.dac1fid11.watertemp = UBITS(322, 10) - - DAC1FID11_WATERTEMP_OFFSET; + ais->type8.dac1fid11.watertemp = UBITS(322, 10); ais->type8.dac1fid11.preciptype = UBITS(332, 3); ais->type8.dac1fid11.salinity = UBITS(335, 9); ais->type8.dac1fid11.ice = UBITS(344, 2); @@ -554,13 +540,11 @@ bool ais_binary_decode(struct ais_t *ais, ais->type8.dac1fid31.airtemp = SBITS(154, 11); ais->type8.dac1fid31.humidity = UBITS(165, 7); ais->type8.dac1fid31.dewpoint = SBITS(172, 10); - ais->type8.dac1fid31.pressure = UBITS(182, 9) - - DAC1FID31_PRESSURE_OFFSET; + ais->type8.dac1fid31.pressure = UBITS(182, 9); ais->type8.dac1fid31.pressuretend = UBITS(191, 2); ais->type8.dac1fid31.visgreater = UBITS(193, 1); ais->type8.dac1fid31.visibility = UBITS(194, 7); - ais->type8.dac1fid31.waterlevel = UBITS(201, 12) - - DAC1FID31_LEVEL_OFFSET; + ais->type8.dac1fid31.waterlevel = UBITS(201, 12); ais->type8.dac1fid31.leveltrend = UBITS(213, 2); ais->type8.dac1fid31.cspeed = UBITS(215, 8); ais->type8.dac1fid31.cdir = UBITS(223, 9); diff --git a/gps.h b/gps.h index 09439ff3..966a2fee 100644 --- a/gps.h +++ b/gps.h @@ -1124,9 +1124,9 @@ struct ais_t struct { #define DAC1FID11_LATLON_SCALE 1000 int lon; /* longitude in minutes * .001 */ -#define DAC1FID11_LON_NOT_AVAILABLE 0x1FFFFFF - int lat; /* longitude in minutes * .001 */ -#define DAC1FID11_LAT_NOT_AVAILABLE 0xFFFFFF +#define DAC1FID11_LON_NOT_AVAILABLE 0xFFFFFF + int lat; /* latitude in minutes * .001 */ +#define DAC1FID11_LAT_NOT_AVAILABLE 0x7FFFFF unsigned int day; /* UTC day */ unsigned int hour; /* UTC hour */ unsigned int minute; /* UTC minute */ @@ -1136,24 +1136,33 @@ struct ais_t unsigned int wdir; /* wind direction */ unsigned int wgustdir; /* wind gust direction */ #define DAC1FID11_WDIR_NOT_AVAILABLE 511 - int airtemp; /* temperature, units 0.1C */ -#define DAC1FID11_AIRTEMP_NOT_AVAILABLE 1447 + unsigned int airtemp; /* temperature, units 0.1C */ +#define DAC1FID11_AIRTEMP_NOT_AVAILABLE 2047 +#define DAC1FID11_AIRTEMP_OFFSET 600 +#define DAC1FID11_AIRTEMP_SCALE 10.0 unsigned int humidity; /* relative humidity, % */ #define DAC1FID11_HUMIDITY_NOT_AVAILABLE 127 - int dewpoint; /* dew point, units 0.1C */ -#define DAC1FID11_DEWPOINT_NOT_AVAILABLE 823 + unsigned int dewpoint; /* dew point, units 0.1C */ +#define DAC1FID11_DEWPOINT_NOT_AVAILABLE 1023 +#define DAC1FID11_DEWPOINT_OFFSET 200 +#define DAC1FID11_DEWPOINT_SCALE 10.0 unsigned int pressure; /* air pressure, hpa */ -#define DAC1FID11_PRESSURE_NOT_AVAILABLE 1311 +#define DAC1FID11_PRESSURE_NOT_AVAILABLE 511 +#define DAC1FID11_PRESSURE_OFFSET -800 unsigned int pressuretend; /* tendency */ #define DAC1FID11_PRESSURETREND_NOT_AVAILABLE 3 unsigned int visibility; /* units 0.1 nautical miles */ #define DAC1FID11_VISIBILITY_NOT_AVAILABLE 255 - int waterlevel; /* decimeters */ -#define DAC1FID11_WATERLEVEL_NOT_AVAILABLE 411 +#define DAC1FID11_VISIBILITY_SCALE 10.0 + unsigned int waterlevel; /* decimeters */ +#define DAC1FID11_WATERLEVEL_NOT_AVAILABLE 511 +#define DAC1FID11_WATERLEVEL_OFFSET 100 +#define DAC1FID11_WATERLEVEL_SCALE 10.0 unsigned int leveltrend; /* water level trend code */ -#define DAC1FID11_LEVELTREND_NOT_AVAILABLE 3 +#define DAC1FID11_WATERLEVELTREND_NOT_AVAILABLE 3 unsigned int cspeed; /* surface current speed in deciknots */ #define DAC1FID11_CSPEED_NOT_AVAILABLE 255 +#define DAC1FID11_CSPEED_SCALE 10.0 unsigned int cdir; /* surface current dir., degrees */ #define DAC1FID11_CDIR_NOT_AVAILABLE 511 unsigned int cspeed2; /* current speed in deciknots */ @@ -1165,6 +1174,7 @@ struct ais_t unsigned int cdepth3; /* measurement depth, m */ unsigned int waveheight; /* in decimeters */ #define DAC1FID11_WAVEHEIGHT_NOT_AVAILABLE 255 +#define DAC1FID11_WAVEHEIGHT_SCALE 10.0 unsigned int waveperiod; /* in seconds */ #define DAC1FID11_WAVEPERIOD_NOT_AVAILABLE 63 unsigned int wavedir; /* direction in degrees */ @@ -1174,12 +1184,15 @@ struct ais_t unsigned int swelldir; /* direction in degrees */ unsigned int seastate; /* Beaufort scale, 0-12 */ #define DAC1FID11_SEASTATE_NOT_AVAILABLE 15 - int watertemp; /* units 0.1deg Celsius */ -#define DAC1FID11_WATERTEMP_NOT_AVAILABLE 923 + unsigned int watertemp; /* units 0.1deg Celsius */ +#define DAC1FID11_WATERTEMP_NOT_AVAILABLE 1023 +#define DAC1FID11_WATERTEMP_OFFSET 100 +#define DAC1FID11_WATERTEMP_SCALE 10.0 unsigned int preciptype; /* 0-7, enumerated */ #define DAC1FID11_PRECIPTYPE_NOT_AVAILABLE 7 unsigned int salinity; /* units of 0.1ppt */ #define DAC1FID11_SALINITY_NOT_AVAILABLE 511 +#define DAC1FID11_SALINITY_SCALE 10.0 unsigned int ice; /* is there sea ice? */ #define DAC1FID11_ICE_NOT_AVAILABLE 3 } dac1fid11; @@ -1270,34 +1283,43 @@ struct ais_t #define DAC1FID31_DIR_NOT_AVAILABLE 360 int airtemp; /* temperature, units 0.1C */ #define DAC1FID31_AIRTEMP_NOT_AVAILABLE -1024 +#define DAC1FID31_AIRTEMP_SCALE 10.0 unsigned int humidity; /* relative humidity, % */ #define DAC1FID31_HUMIDITY_NOT_AVAILABLE 101 int dewpoint; /* dew point, units 0.1C */ #define DAC1FID31_DEWPOINT_NOT_AVAILABLE 501 +#define DAC1FID31_DEWPOINT_SCALE 10.0 unsigned int pressure; /* air pressure, hpa */ #define DAC1FID31_PRESSURE_NOT_AVAILABLE 511 #define DAC1FID31_PRESSURE_HIGH 402 +#define DAC1FID31_PRESSURE_OFFSET -799 unsigned int pressuretend; /* tendency */ #define DAC1FID31_PRESSURETEND_NOT_AVAILABLE 3 bool visgreater; /* visibility greater than */ unsigned int visibility; /* units 0.1 nautical miles */ #define DAC1FID31_VISIBILITY_NOT_AVAILABLE 127 - int waterlevel; /* decimeters or cm */ +#define DAC1FID31_VISIBILITY_SCALE 10.0 + int waterlevel; /* cm */ #define DAC1FID31_WATERLEVEL_NOT_AVAILABLE 4001 +#define DAC1FID31_WATERLEVEL_OFFSET 1000 +#define DAC1FID31_WATERLEVEL_SCALE 100.0 unsigned int leveltrend; /* water level trend code */ -#define DAC1FID31_LEVELTREND_NOT_AVAILABLE 3 +#define DAC1FID31_WATERLEVELTREND_NOT_AVAILABLE 3 unsigned int cspeed; /* current speed in deciknots */ #define DAC1FID31_CSPEED_NOT_AVAILABLE 255 +#define DAC1FID31_CSPEED_SCALE 10.0 unsigned int cdir; /* current dir., degrees */ unsigned int cspeed2; /* current speed in deciknots */ unsigned int cdir2; /* current dir., degrees */ unsigned int cdepth2; /* measurement depth, 0.1m */ #define DAC1FID31_CDEPTH_NOT_AVAILABLE 301 +#define DAC1FID31_CDEPTH_SCALE 10.0 unsigned int cspeed3; /* current speed in deciknots */ unsigned int cdir3; /* current dir., degrees */ unsigned int cdepth3; /* measurement depth, 0.1m */ unsigned int waveheight; /* in decimeters */ #define DAC1FID31_HEIGHT_NOT_AVAILABLE 31 +#define DAC1FID31_HEIGHT_SCALE 10.0 unsigned int waveperiod; /* in seconds */ #define DAC1FID31_PERIOD_NOT_AVAILABLE 63 unsigned int wavedir; /* direction in degrees */ @@ -1308,10 +1330,12 @@ struct ais_t #define DAC1FID31_SEASTATE_NOT_AVAILABLE 15 int watertemp; /* units 0.1deg Celsius */ #define DAC1FID31_WATERTEMP_NOT_AVAILABLE 601 +#define DAC1FID31_WATERTEMP_SCALE 10.0 unsigned int preciptype; /* 0-7, enumerated */ #define DAC1FID31_PRECIPTYPE_NOT_AVAILABLE 7 - unsigned int salinity; /* units of 0.1% */ + unsigned int salinity; /* units of 0.1 permil (ca. PSU) */ #define DAC1FID31_SALINITY_NOT_AVAILABLE 510 +#define DAC1FID31_SALINITY_SCALE 10.0 unsigned int ice; /* is there sea ice? */ #define DAC1FID31_ICE_NOT_AVAILABLE 3 } dac1fid31; diff --git a/gpsd_json.c b/gpsd_json.c index cdbc13a2..c5a00849 100644 --- a/gpsd_json.c +++ b/gpsd_json.c @@ -2118,7 +2118,7 @@ void json_aivdm_dump(const struct ais_t *ais, if (ais->type8.dac == 1) { const char *trends[] = { "steady", - "increasing" + "increasing", "decreasing", "N/A", }; @@ -2169,13 +2169,13 @@ void json_aivdm_dump(const struct ais_t *ais, (void)snprintf(buf + strlen(buf), buflen - strlen(buf), "\"airtemp\":%.1f,\"dewpoint\":%.1f," "\"pressure\":%u,\"pressuretend\":\"%s\",", - ais->type8.dac1fid11.airtemp * 0.1, - ais->type8.dac1fid11.dewpoint * 0.1, - ais->type8.dac1fid11.pressure, + (ais->type8.dac1fid11.airtemp - DAC1FID11_AIRTEMP_OFFSET) / DAC1FID11_AIRTEMP_SCALE, + (ais->type8.dac1fid11.dewpoint - DAC1FID11_DEWPOINT_OFFSET) / DAC1FID11_DEWPOINT_SCALE, + ais->type8.dac1fid11.pressure - DAC1FID11_PRESSURE_OFFSET, trends[ais->type8.dac1fid11.pressuretend]); else (void)snprintf(buf + strlen(buf), buflen - strlen(buf), - "\"airtemp\":%d,\"dewpoint\":%d," + "\"airtemp\":%u,\"dewpoint\":%u," "\"pressure\":%u,\"pressuretend\":%u,", ais->type8.dac1fid11.airtemp, ais->type8.dac1fid11.dewpoint, @@ -2185,19 +2185,19 @@ void json_aivdm_dump(const struct ais_t *ais, if (scaled) (void)snprintf(buf + strlen(buf), buflen - strlen(buf), "\"visibility\":%.1f,", - ais->type8.dac1fid11.visibility * 0.1); + ais->type8.dac1fid11.visibility / DAC1FID11_VISIBILITY_SCALE); else (void)snprintf(buf + strlen(buf), buflen - strlen(buf), "\"visibility\":%u,", ais->type8.dac1fid11.visibility); if (!scaled) (void)snprintf(buf + strlen(buf), buflen - strlen(buf), - "\"waterlevel\":%d,", + "\"waterlevel\":%u,", ais->type8.dac1fid11.waterlevel); else (void)snprintf(buf + strlen(buf), buflen - strlen(buf), "\"waterlevel\":%.1f,", - ais->type8.dac1fid11.waterlevel * 0.1); + (ais->type8.dac1fid11.waterlevel - DAC1FID11_WATERLEVEL_OFFSET) / DAC1FID11_WATERLEVEL_SCALE); if (scaled) { (void)snprintf(buf + strlen(buf), buflen - strlen(buf), @@ -2208,26 +2208,26 @@ void json_aivdm_dump(const struct ais_t *ais, "\"waveheight\":%.1f,\"waveperiod\":%u,\"wavedir\":%u," "\"swellheight\":%.1f,\"swellperiod\":%u,\"swelldir\":%u," "\"seastate\":%u,\"watertemp\":%.1f," - "\"preciptype\":%s,\"salinity\":%.1f,\"ice\":%s", + "\"preciptype\":\"%s\",\"salinity\":%.1f,\"ice\":\"%s\"", trends[ais->type8.dac1fid11.leveltrend], - ais->type8.dac1fid11.cspeed * 0.1, + ais->type8.dac1fid11.cspeed / DAC1FID11_CSPEED_SCALE, ais->type8.dac1fid11.cdir, - ais->type8.dac1fid11.cspeed2 * 0.1, + ais->type8.dac1fid11.cspeed2 / DAC1FID11_CSPEED_SCALE, ais->type8.dac1fid11.cdir2, ais->type8.dac1fid11.cdepth2, - ais->type8.dac1fid11.cspeed3 * 0.1, + ais->type8.dac1fid11.cspeed3 / DAC1FID11_CSPEED_SCALE, ais->type8.dac1fid11.cdir3, ais->type8.dac1fid11.cdepth3, - ais->type8.dac1fid11.waveheight * 0.1, + ais->type8.dac1fid11.waveheight / DAC1FID11_WAVEHEIGHT_SCALE, ais->type8.dac1fid11.waveperiod, ais->type8.dac1fid11.wavedir, - ais->type8.dac1fid11.swellheight * 0.1, + ais->type8.dac1fid11.swellheight / DAC1FID11_WAVEHEIGHT_SCALE, ais->type8.dac1fid11.swellperiod, ais->type8.dac1fid11.swelldir, ais->type8.dac1fid11.seastate, - ais->type8.dac1fid11.watertemp * 0.1, + (ais->type8.dac1fid11.watertemp - DAC1FID11_WATERTEMP_OFFSET) / DAC1FID11_WATERTEMP_SCALE, preciptypes[ais->type8.dac1fid11.preciptype], - ais->type8.dac1fid11.salinity * 0.1, + ais->type8.dac1fid11.salinity / DAC1FID11_SALINITY_SCALE, ice[ais->type8.dac1fid11.ice]); } else (void)snprintf(buf + strlen(buf), buflen - strlen(buf), @@ -2237,7 +2237,7 @@ void json_aivdm_dump(const struct ais_t *ais, "\"cspeed3\":%u,\"cdir3\":%u,\"cdepth3\":%u," "\"waveheight\":%u,\"waveperiod\":%u,\"wavedir\":%u," "\"swellheight\":%u,\"swellperiod\":%u,\"swelldir\":%u," - "\"seastate\":%u,\"watertemp\":%d," + "\"seastate\":%u,\"watertemp\":%u," "\"preciptype\":%u,\"salinity\":%u,\"ice\":%u", ais->type8.dac1fid11.leveltrend, ais->type8.dac1fid11.cspeed, @@ -2451,12 +2451,12 @@ void json_aivdm_dump(const struct ais_t *ais, ais->type8.dac1fid31.humidity); if (scaled) (void)snprintf(buf + strlen(buf), buflen - strlen(buf), - "\"airtemp\":%1f,\"dewpoint\":%1f," + "\"airtemp\":%.1f,\"dewpoint\":%.1f," "\"pressure\":%u,\"pressuretend\":\"%s\"," "\"visgreater\":%s,", - ais->type8.dac1fid31.airtemp * 0.1, - ais->type8.dac1fid31.dewpoint * 0.1, - ais->type8.dac1fid31.pressure, + ais->type8.dac1fid31.airtemp / DAC1FID31_AIRTEMP_SCALE, + ais->type8.dac1fid31.dewpoint / DAC1FID31_DEWPOINT_SCALE, + ais->type8.dac1fid31.pressure - DAC1FID31_PRESSURE_OFFSET, trends[ais->type8.dac1fid31.pressuretend], JSON_BOOL(ais->type8.dac1fid31.visgreater)); else @@ -2473,7 +2473,7 @@ void json_aivdm_dump(const struct ais_t *ais, if (scaled) (void)snprintf(buf + strlen(buf), buflen - strlen(buf), "\"visibility\":%.1f,", - ais->type8.dac1fid31.visibility * 0.1); + ais->type8.dac1fid31.visibility / DAC1FID31_VISIBILITY_SCALE); else (void)snprintf(buf + strlen(buf), buflen - strlen(buf), "\"visibility\":%u,", @@ -2485,7 +2485,7 @@ void json_aivdm_dump(const struct ais_t *ais, else (void)snprintf(buf + strlen(buf), buflen - strlen(buf), "\"waterlevel\":%.1f,", - ais->type8.dac1fid31.waterlevel * 0.01); + (ais->type8.dac1fid31.waterlevel - DAC1FID31_WATERLEVEL_OFFSET) / DAC1FID31_WATERLEVEL_SCALE); if (scaled) { (void)snprintf(buf + strlen(buf), buflen - strlen(buf), @@ -2498,24 +2498,24 @@ void json_aivdm_dump(const struct ais_t *ais, "\"seastate\":%u,\"watertemp\":%.1f," "\"preciptype\":\"%s\",\"salinity\":%.1f,\"ice\":\"%s\"", trends[ais->type8.dac1fid31.leveltrend], - ais->type8.dac1fid31.cspeed * 0.1, + ais->type8.dac1fid31.cspeed / DAC1FID31_CSPEED_SCALE, ais->type8.dac1fid31.cdir, - ais->type8.dac1fid31.cspeed2 * 0.1, + ais->type8.dac1fid31.cspeed2 / DAC1FID31_CSPEED_SCALE, ais->type8.dac1fid31.cdir2, ais->type8.dac1fid31.cdepth2, - ais->type8.dac1fid31.cspeed3 * 0.1, + ais->type8.dac1fid31.cspeed3 / DAC1FID31_CSPEED_SCALE, ais->type8.dac1fid31.cdir3, ais->type8.dac1fid31.cdepth3, - ais->type8.dac1fid31.waveheight * 0.1, + ais->type8.dac1fid31.waveheight / DAC1FID31_HEIGHT_SCALE, ais->type8.dac1fid31.waveperiod, ais->type8.dac1fid31.wavedir, - ais->type8.dac1fid31.swellheight * 0.1, + ais->type8.dac1fid31.swellheight / DAC1FID31_HEIGHT_SCALE, ais->type8.dac1fid31.swellperiod, ais->type8.dac1fid31.swelldir, ais->type8.dac1fid31.seastate, - ais->type8.dac1fid31.watertemp * 0.1, + ais->type8.dac1fid31.watertemp / DAC1FID31_WATERTEMP_SCALE, preciptypes[ais->type8.dac1fid31.preciptype], - ais->type8.dac1fid31.salinity * 0.1, + ais->type8.dac1fid31.salinity / DAC1FID31_SALINITY_SCALE, ice[ais->type8.dac1fid31.ice]); } else (void)snprintf(buf + strlen(buf), buflen - strlen(buf), diff --git a/gpsdecode.c b/gpsdecode.c index 0198a66c..3ade9b8c 100644 --- a/gpsdecode.c +++ b/gpsdecode.c @@ -155,7 +155,7 @@ static void aivdm_csv_dump(struct ais_t *ais, char *buf, size_t buflen) switch(ais->type8.fid) { case 11: /* IMO236 - Met/Hydro message */ (void)snprintf(buf + strlen(buf), buflen - strlen(buf), - "|%d|%d|%02uT%02u:%02uZ|%u|%u|%u|%u|%d|%u|%d|%u|%u|%u|%d|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%d|%u|%u|%u", + "|%d|%d|%02uT%02u:%02uZ|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u", ais->type8.dac1fid11.lon, ais->type8.dac1fid11.lat, ais->type8.dac1fid11.day, diff --git a/jsongen.py.in b/jsongen.py.in index 7c85b3c5..cf785291 100644 --- a/jsongen.py.in +++ b/jsongen.py.in @@ -305,14 +305,14 @@ ais_specs = ( ('wgust', 'uinteger', 'DAC1FID11_WSPEED_NOT_AVAILABLE'), ('wdir', 'uinteger', 'DAC1FID11_WDIR_NOT_AVAILABLE'), ('wgustdir', 'uinteger', 'DAC1FID11_WDIR_NOT_AVAILABLE'), - ('airtemp', 'integer', 'DAC1FID11_AIRTEMP_NOT_AVAILABLE'), + ('airtemp', 'uinteger', 'DAC1FID11_AIRTEMP_NOT_AVAILABLE'), ('humidity', 'uinteger', 'DAC1FID11_HUMIDITY_NOT_AVAILABLE'), - ('dewpoint', 'integer', 'DAC1FID11_DEWPOINT_NOT_AVAILABLE'), + ('dewpoint', 'uinteger', 'DAC1FID11_DEWPOINT_NOT_AVAILABLE'), ('pressure', 'uinteger', 'DAC1FID11_PRESSURE_NOT_AVAILABLE'), ('pressuretend', 'uinteger', 'DAC1FID11_PRESSURETREND_NOT_AVAILABLE'), ('visibility', 'uinteger', 'DAC1FID11_VISIBILITY_NOT_AVAILABLE'), - ('waterlevel', 'integer', 'DAC1FID11_WATERLEVEL_NOT_AVAILABLE'), - ('leveltrend', 'uinteger', 'DAC1FID11_LEVELTREND_NOT_AVAILABLE'), + ('waterlevel', 'uinteger', 'DAC1FID11_WATERLEVEL_NOT_AVAILABLE'), + ('leveltrend', 'uinteger', 'DAC1FID11_WATERLEVELTREND_NOT_AVAILABLE'), ('cspeed', 'uinteger', 'DAC1FID11_CSPEED_NOT_AVAILABLE'), ('cdir', 'uinteger', 'DAC1FID11_CDIR_NOT_AVAILABLE'), ('cspeed2', 'uinteger', 'DAC1FID11_CSPEED_NOT_AVAILABLE'), @@ -328,7 +328,7 @@ ais_specs = ( ('swellperiod', 'uinteger', 'DAC1FID11_WAVEPERIOD_NOT_AVAILABLE'), ('swelldir', 'uinteger', 'DAC1FID11_WAVEDIR_NOT_AVAILABLE'), ('seastate', 'uinteger', 'DAC1FID11_SEASTATE_NOT_AVAILABLE'), - ('watertemp', 'integer', 'DAC1FID11_WATERTEMP_NOT_AVAILABLE'), + ('watertemp', 'uinteger', 'DAC1FID11_WATERTEMP_NOT_AVAILABLE'), ('preciptype', 'uinteger', 'DAC1FID11_PRECIPTYPE_NOT_AVAILABLE'), ('salinity', 'uinteger', 'DAC1FID11_SALINITY_NOT_AVAILABLE'), ('ice', 'uinteger', 'DAC1FID11_ICE_NOT_AVAILABLE'), @@ -455,7 +455,7 @@ ais_specs = ( ('visgreater', 'boolean', 'false'), ('visibility', 'uinteger', 'DAC1FID31_VISIBILITY_NOT_AVAILABLE'), ('waterlevel', 'uinteger', 'DAC1FID31_WATERLEVEL_NOT_AVAILABLE'), - ('leveltrend', 'uinteger', 'DAC1FID31_LEVELTREND_NOT_AVAILABLE'), + ('leveltrend', 'uinteger', 'DAC1FID31_WATERLEVELTREND_NOT_AVAILABLE'), ('cspeed', 'uinteger', 'DAC1FID31_CSPEED_NOT_AVAILABLE'), ('cdir', 'uinteger', 'DAC1FID31_DIR_NOT_AVAILABLE'), ('cspeed2', 'uinteger', 'DAC1FID31_CSPEED_NOT_AVAILABLE'), diff --git a/test/sample.aivdm.chk b/test/sample.aivdm.chk index 6b6adfd8..3b698060 100644 --- a/test/sample.aivdm.chk +++ b/test/sample.aivdm.chk @@ -12,9 +12,9 @@ 7|2|537411077|43101326|717096664|76161024|0 8|0|366999712|366|56|256:3a53dbb7be4a773137f87d7b0445f040dea05d93f593783194ae9b9d9dbe05fb 8|0|999999999|366|56|256:eb0d4f917a035b2dfca3d4739381735c18ebbe754936f66850037dcacd9538b8 -8|0|992509977|1|11|-368039|3197693|18T17:15Z|3|6|12|15|142|50|123|1024|2|153|-84|1|103|256|104|257|10|126|203|20|42|35|25|23|48|124|3|123|6|53|0 -8|0|992509977|1|11|-368037|3197689|18T17:45Z|127|127|511|511|1447|127|823|1311|3|255|411|3|255|511|255|511|31|255|511|31|255|63|511|255|63|511|15|923|7|511|3 -8|0|992509977|1|31|-368044|3197696|29T23:24Z|127|127|360|360|-1024|101|501|1310|3|127|3001|3|255|360|255|360|31|255|360|31|255|63|360|255|63|360|13|501|7|510|3 +8|0|992509977|1|11|-368039|3197693|18T17:15Z|3|6|12|15|742|50|323|224|2|153|16|1|103|256|104|257|10|126|203|20|42|35|25|23|48|124|3|223|6|53|0 +8|0|992509977|1|11|-368037|3197689|18T17:45Z|127|127|511|511|2047|127|1023|511|3|255|511|3|255|511|255|511|31|255|511|31|255|63|511|255|63|511|15|1023|7|511|3 +8|0|992509977|1|31|-368044|3197696|29T23:24Z|127|127|360|360|-1024|101|501|511|3|127|4001|3|255|360|255|360|31|255|360|31|255|63|360|255|63|360|13|501|7|510|3 9|0|111265591|15|0|0|7128960|34667073|0|28|0x0|0|0|0x6015 10|0|366814480|366832740 10|0|440882000|366972000 diff --git a/test/synthetic-ais.json b/test/synthetic-ais.json index 3622a2a6..32edcd29 100644 --- a/test/synthetic-ais.json +++ b/test/synthetic-ais.json @@ -19,8 +19,8 @@ {"class":"AIS","type":7,"repeat":2,"mmsi":537411077,"scaled":false,"mmsi1":43101326,"mmsi2":717096664,"mmsi3":76161024,"mmsi4":0} {"class":"AIS","type":8,"repeat":0,"mmsi":366999712,"scaled":false,"dac":366,"fid":22,"data":"256:3a53dbb7be4a773137f87d7b0445f040dea05d93f593783194ae9b9d9dbe05fb"} {"class":"AIS","type":8,"repeat":0,"mmsi":366999655,"scaled":false,"dac":366,"fid":22,"data":"256:631d1d6b32f735f03494870d9e13addaf3f373435347ab94628f1498868051c3"} -{"class":"AIS","type":8,"repeat":0,"mmsi":992509977,"scaled":false,"dac":1,"fid":11,"lat":3197693,"lon":-368039,"timestamp":"18T17:15Z","wspeed":3,"wgust":6,"wdir":12,"wgustdir":15,"humidity":50,"airtemp":142,"dewpoint":123,"pressure":1024,"pressuretend":2,"visibility":153,"waterlevel":-84,"leveltrend":1,"cspeed":103,"cdir":256,"cspeed2":104,"cdir2":257,"cdepth2":10,"cspeed3":126,"cdir3":203,"cdepth3":20,"waveheight":42,"waveperiod":35,"wavedir":25,"swellheight":23,"swellperiod":48,"swelldir":124,"seastate":3,"watertemp":123,"preciptype":6,"salinity":53,"ice":0} -{"class":"AIS","type":8,"repeat":0,"mmsi":992509977,"scaled":false,"dac":1,"fid":11,"lat":3197689,"lon":-368037,"timestamp":"18T17:45Z","wspeed":127,"wgust":127,"wdir":511,"wgustdir":511,"humidity":127,"airtemp":1447,"dewpoint":823,"pressure":1311,"pressuretend":3,"visibility":255,"waterlevel":411,"leveltrend":3,"cspeed":255,"cdir":511,"cspeed2":255,"cdir2":511,"cdepth2":31,"cspeed3":255,"cdir3":511,"cdepth3":31,"waveheight":255,"waveperiod":63,"wavedir":511,"swellheight":255,"swellperiod":63,"swelldir":511,"seastate":15,"watertemp":923,"preciptype":7,"salinity":511,"ice":3} +{"class":"AIS","device":"stdin","type":8,"repeat":0,"mmsi":992509977,"scaled":false,"dac":1,"fid":11,"lat":3197689,"lon":-368037,"timestamp":"18T17:45Z","wspeed":127,"wgust":127,"wdir":511,"wgustdir":511,"humidity":127,"airtemp":2047,"dewpoint":1023,"pressure":511,"pressuretend":3,"visibility":255,"waterlevel":511,"leveltrend":3,"cspeed":255,"cdir":511,"cspeed2":255,"cdir2":511,"cdepth2":31,"cspeed3":255,"cdir3":511,"cdepth3":31,"waveheight":255,"waveperiod":63,"wavedir":511,"swellheight":255,"swellperiod":63,"swelldir":511,"seastate":15,"watertemp":1023,"preciptype":7,"salinity":511,"ice":3} +{"class":"AIS","device":"stdin","type":8,"repeat":0,"mmsi":992509977,"scaled":false,"dac":1,"fid":31,"lat":3197696,"lon":-368044,"accuracy":false,"timestamp":"29T23:24Z","wspeed":127,"wgust":127,"wdir":360,"wgustdir":360,"humidity":101,"airtemp":-1024,"dewpoint":501,"pressure":511,"pressuretend":3,"visgreater":false,"visibility":127,"waterlevel":4001,"leveltrend":3,"cspeed":255,"cdir":360,"cspeed2":255,"cdir2":360,"cdepth2":31,"cspeed3":255,"cdir3":360,"cdepth3":31,"waveheight":255,"waveperiod":63,"wavedir":360,"swellheight":255,"swellperiod":63,"swelldir":360,"seastate":13,"watertemp":501,"preciptype":7,"salinity":510,"ice":3} {"class":"AIS","device":"stdin","type":8,"repeat":0,"mmsi":992509977,"scaled":false,"dac":1,"fid":31,"lat":3197696,"lon":-368044,"accuracy":false,"timestamp":"29T23:24Z","wspeed":127,"wgust":127,"wdir":360,"wgustdir":360,"humidity":101,"airtemp":-1024,"dewpoint":501,"pressure":1311,"pressuretend":3,"visgreater":false,"visibility":127,"waterlevel":3001,"leveltrend":3,"cspeed":255,"cdir":360,"cspeed2":255,"cdir2":360,"cdepth2":31,"cspeed3":255,"cdir3":360,"cdepth3":31,"waveheight":255,"waveperiod":63,"wavedir":360,"swellheight":255,"swellperiod":63,"swelldir":360,"seastate":13,"watertemp":501,"preciptype":7,"salinity":510,"ice":3} {"class":"AIS","type":9,"repeat":0,"mmsi":111265591,"scaled":false,"alt":15,"speed":0,"accuracy":false,"lon":7128960,"lat":34667073,"course":0,"second":28,"regional":0,"dte":0,"raim":false,"radio":24597} {"class":"AIS","type":10,"repeat":0,"mmsi":366814480,"scaled":false,"dest_mmsi":366832740} diff --git a/www/AIVDM.txt b/www/AIVDM.txt index a58b7322..9bf9b54b 100644 --- a/www/AIVDM.txt +++ b/www/AIVDM.txt @@ -1871,100 +1871,99 @@ broadcast of this message of 12 minutes. |40-49 | 10 |DAC |dac |u|DAC = 001 |50-55 | 6 |FID |fid |u|FID = 11 |56-79 | 24 |Latitude |lat |I3|Unit = minutes * 0.001, - 91000 = N/A (default), + 0x7FFFFF = N/A (default), E positive, W negative. |80-104 | 25 |Longitude |lon |I3|Unit = minutes * 0.001, - 181000 = N/A (default), + 0xFFFFFF = N/A (default), N positive, S negative. -|105-109 | 5 |Day (UTC) |day |u|1-31, 0=N/A (default) -|110-114 | 5 |Hour (UTC) |hour |u|0-23, >=24=N/A (default) -|115-120 | 6 |Minute (UTC) |minute |u|0-59, >=60=N/A (default) +|105-109 | 5 |Day (UTC) |day |u|1-31, 31=N/A (default) +|110-114 | 5 |Hour (UTC) |hour |u|0-23, 31=N/A (default) +|115-120 | 6 |Minute (UTC) |minute |u|0-59, 63=N/A (default) |121-127 | 7 |Average Wind Speed |wspeed |u|10-min avg wind speed, knots, 127 = N/A (default). |128-134 | 7 |Gust Speed |wgust |u|10-min max wind speed, knots, 127 = N/A (default). |135-143 | 9 |Wind Direction |wdir |u|0-359, degrees fom true north - >=360 = N/A (default) + 511 = N/A (default) |144-152 | 9 |Wind Gust Direction|wgustdir |u|0-359, degrees fom true north - >=360 = N/A (default) + 511 = N/A (default) |153-163 | 11 |Air Temperature |temperature |u|Dry bulb temp: 0.1 deg C -60.0 to +60.0, - -1024 = N/A (default), - else -60deg after scaling. + 2047 = N/A (default), |164-170 | 7 |Relative Humidity |humidity |u|0-100%, units of 1%, 127 = N/A (default). |171-180 | 10 |Dew Point |dewpoint |u|-20.0 to +50.0: 0.1 deg C, 1023 = N/A (default), - else -20.0deg after scaling. |181-189 | 9 |Air Pressure |pressure |u|800-1200hPa: units 1hPa, - 402 = pressure >= 1201 hPa, - 403 - N/A (default). - else add 400 to value. + 511 = N/A (default). |190-191 | 2 |Pressure Tendency |pressuretend|e|0 = steady, 1 = decreasing, 2 = increasing, 3 - N/A (default). |192-199 | 8 |Horiz. Visibility |visibility |U1|0-25.0, units of 0.1nm - >= 250 = N/A (default) + 255 = N/A (default) |200-208 | 9 |Water Level |waterlevel |U1|-10.0 to +30.0 in 0.1m, - 1923 = N/A (default). - else -10m after scaling. + 511 = N/A (default). |209-210 | 2 |Water Level Trend |leveltrend |e|0 = steady, 1 = decreasing, 2 = increasing, 3 - N/A (default). |211-218 | 8 |Surface Current Speed |cspeed |U1|0.0-25.0 knots: units 0.1 knot |219-227 | 9 |Surface Current Direction |cdir |u|0-359: deg from true north, - >=360 = N/A (default) + 511 = N/A (default) |228-235 | 8 |Current Speed #2 |cspeed2 |U1|0.0-25.0 in units of 0.1 knot, - >=251 = N/A (default). + 255 = N/A (default). |236-244 | 9 |Current Direction #2 |cdir2 |u|0-359: deg. fom true north, - >=360 = N/A (default) + 511 = N/A (default) |245-249 | 5 |Measurement Depth #2 |cdepth2 |U1|0-30m down: units 0.1m, 31 = N/A (default). |250-257 | 8 |Current Speed #3 |cspeed3 |U1|0.0-25.0: units of 0.1 knot, - >=251 = N/A (default). + 255 = N/A (default). |258-266 | 9 |Current Direction #3 |cdir3 |u|0-359: degrees fom true north, - >=360 = N/A (default). + 511 = N/A (default). |267-271 | 5 |Measurement Depth #3 |cdepth3 |U1|0-30m down: units 0.1m, 31 = N/A (default). |272-279 | 8 |Wave height |waveheight|U1|0-25m: units of 0.1m, - >=251 = N/A (default). + 255 = N/A (default). |280-285 | 6 |Wave period |waveperiod|u|Seconds 0-60: - >= 61 = N/A (default). + 63 = N/A (default). |286-294 | 9 |Wave direction |wavedir |u|0-359: deg. fom true north, - >=360 = N/A (default). + 511 = N/A (default). |295-302 | 8 |Swell height |swellheight|U1|0-25m: units of 0.1m - >=251 = N/A (default). + 255 = N/A (default). |303-308 | 6 |Swell period |swellperiod|u|Seconds 0-60: - >= 61 = N/A (default). + 63 = N/A (default). |309-317 | 9 |Swell direction |swelldir |u|0-359: deg. fom true north, - >=360 = N/A (default). + 511 = N/A (default). |318-321 | 4 |Sea state |seastate |e|See "Beaufort Scale" |322-331 | 10 |Water Temperature |watertemp |U1|-10.0 to 50.0: units 0.1 C, - >=601 = N/A (default). - else -10.0m after scaling. + 1023 = N/A (default). |332-334 | 3 |Precipitation |preciptype |e|See "Precipitation Types" |335-343 | 9 |Salinity |salinity |U1|0.0-50.0%: units 0.1%, - >=500 = N/A (default) -|344-345 | 2 |Ice |ice |b|Yes/No + 511 = N/A (default) +|344-345 | 2 |Ice |ice |e| 0 = No + 1 = Yes + 2 = (reserved for future use) + 3 = not available = default |346-351 | 6 |Spare | |x|Not used |============================================================================== <> says "If there is no data available, default value to be transmitted is the highest available binary value for that particular -data field." and no defaults are explicitly specified. However, the -replacement FID=31 message has default values which do not obey this -rule. It would be good practice for a decoder to treat any -out-of-bounds value as N/A; the N/A formulas in the table above -reflect this. +data field.", the above table reflects that. +The day, hour and minute have to be considered not available when all +three are set to their individual "N/A" value. +For the latitude and the longitude, the highest positive value is used, +as the highest available binary value for a signed integer is -1, which +would forbid the -0.001/-0.001 position. +The replacement FID=31 message has different default values that remove any ambiguities. <> gives the length of this message as 352, but lists only 336 payload bits. Water level is deviation from local chart datum and includes tide. -The waveheight field is labeled as "Significant" in <>, +The waveheight field is labeled as "Significant" in <>, for whatever that means. The seastate field has a note in <> reading "(manual input?)"? -- cgit v1.2.1