diff --git a/tests/Dockerfile b/tests/Dockerfile index baec630..32e2be0 100644 --- a/tests/Dockerfile +++ b/tests/Dockerfile @@ -5,4 +5,3 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get -q update && apt-get -qy upgrade && apt-get -qy install postgresql-client # Clean up APT when done. RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - diff --git a/tests/index.js b/tests/index.js new file mode 100644 index 0000000..74acf6d --- /dev/null +++ b/tests/index.js @@ -0,0 +1,822 @@ +'use strict'; +/* +* Unit test #1 +* Create 2 users and 2 associate vessel with metrics +* +* process.env.PGSAIL_API_URI = from inside the docker +* +* npm install supertest should mocha mochawesome moment +* alias mocha="./node_modules/mocha/bin/_mocha" +* mocha index.js --reporter mochawesome --reporter-options reportDir=/mnt/postgsail/,reportFilename=report_api.html +* +*/ + +const sleep = ms => new Promise(r => setTimeout(r, ms)); + +const supertest = require("supertest"); +// Deprecated +const should = require("should"); +//const chai = require("chai"); +//const should = chai.should(); +let request = null; +let user_jwt = null; +let vessel_jwt = null; +var moment = require('moment'); +const metrics_kapla = require('./metrics_sample_kapla.json'); +const metrics_aava = require('./metrics_sample_aava.json'); + +const fs = require('fs'); + + +// CNAMEs Array +[ + + { cname: process.env.PGSAIL_API_URI, name: "PostgSail unit test kapla", + signin: { email: 'demo+kapla@openplotter.cloud', pass: 'test', firstname:'First_kapla', lastname:'Last_kapla'}, + login: { email: 'demo+kapla@openplotter.cloud', pass: 'test'}, + vessel: { vessel_email: "demo+kapla@openplotter.cloud", vessel_mmsi: "test", vessel_name: "kapla"}, + preferences: { key: '{email_notifications}', value: false }, /* Disable email_notifications */ + vessel_metadata: { + name: "kapla", + mmsi: "123456789", + client_id: "vessels.urn:mrn:signalk:uuid:5b4f7543-7153-4840-b139-761310b242fd", + length: "12", + beam: "10", + height: "24", + ship_type: "36", + plugin_version: "0.0.1", + signalk_version: "signalk_version", + time: moment.utc().subtract(69, 'minutes').format() + /* To trigger monitor_offline quickly */ + }, + vessel_metrics: metrics_kapla, + user_tables: [ + { url: '/stays', res_body_length: 3}, + // not processed yet, { url: '/moorages', res_body_length: 2}, + { url: '/logbook', res_body_length: 2}, + { url: '/metadata', res_body_length: 1} + ], + user_views: [ + // not processed yet, { url: '/stays_view', res_body_length: 1}, + // not processed yet, { url: '/moorages_view', res_body_length: 1}, + { url: '/logs_view', res_body_length: 2}, + { url: '/log_view', res_body_length: 2}, + //{ url: '/stats_view', res_body_length: 1}, + { url: '/vessels_view', res_body_length: 1}, + ], + user_patchs: [ + { url: '/logbook?id=eq.1', + patch: { + name: "patch log name", + notes: "new log note" + }, + }, + { url: '/stays?id=eq.1', + patch: { + name: "patch stay name", + stay_code: 2, + notes: "new stay note" + }, + }, + /* not processed yet, { url: '/moorages?id=eq.1', + patch: { + name: "patch moorage name", + home_flag: true, + stay_code: 2, + notes: "new moorage note" + }, + } + */ + ], + user_fn: [ + { url: '/rpc/timelapse_fn', + payload: { + start_log: 1 + }, + res: { + obj_name: 'geojson' + } + }, + { url: '/rpc/export_logbook_geojson_fn', + payload: { + _id: 1 + }, + res: { + obj_name: 'geojson' + } + }, + { url: '/rpc/export_logbook_gpx_fn', + payload: { + _id: 1 + }, + res: { + obj_name: null + } + }, + { url: '/rpc/vessel_fn', + payload: null, + res: { + obj_name: 'vessel' + } + }, + { url: '/rpc/settings_fn', + payload: null, + res: { + obj_name: 'settings' + } + }, + { url: '/rpc/versions_fn', + payload: null, + res: { + obj_name: 'versions' + } + } + ], + otp_fn: [ + { url: '/rpc/generate_otp_fn', + payload: { email: 'demo+kapla@openplotter.cloud' }, + res: { + otp: 0 + } + }, + { url: '/rpc/email_fn', + payload: { token: null }, + res: { + obj_name: 'settings' + } + }, + { url: '/rpc/generate_otp_fn', + payload: { email: 'demo+kapla@openplotter.cloud' }, + res: { + otp: 0 + } + }, + { url: '/rpc/pushover_fn', + payload: { token: null, pushover_user_key: '1234567890azerty!'}, + res: { + obj_name: 'settings' + } + }, + { url: '/rpc/generate_otp_fn', + payload: { email: 'demo+kapla@openplotter.cloud' }, + res: { + otp: 0 + } + }, + { url: '/rpc/telegram_fn', + payload: { token: null, telegram_obj: {"chat": {"id": 1234567890, "type": "private", "title": null, "all_members_are_administrators": null}, "date": "NOW", "from": {"id": 1234567890, "is_bot": false, "first_name": "Kapla", "language_code": "en"}} }, + res: { + obj_name: 'settings' + } + } + ] + }, + { cname: process.env.PGSAIL_API_URI, name: "PostgSail unit test, aava", + signin: { email: 'demo+aava@openplotter.cloud', pass: 'test', firstname:'first_aava', lastname:'last_aava'}, + login: { email: 'demo+aava@openplotter.cloud', pass: 'test'}, + vessel: { vessel_email: "demo+aava@openplotter.cloud", vessel_mmsi: "787654321", vessel_name: "aava"}, + preferences: { key: '{email_notifications}', value: false }, /* Disable email_notifications */ + vessel_metadata: { + name: "aava", + mmsi: "787654321", + client_id: "vessels.urn:mrn:imo:mmsi:787654321", + length: "12", + beam: "10", + height: "24", + ship_type: "37", + plugin_version: "1.0.2", + signalk_version: "1.20.0", + time: moment().subtract(69, 'minutes').format() + }, + vessel_metrics: metrics_aava, + user_tables: [ + { url: '/stays', res_body_length: 2}, + // not processed yet, { url: '/moorages', res_body_length: 2}, + { url: '/logbook', res_body_length: 1}, + { url: '/metadata', res_body_length: 1} + ], + user_views: [ + // not processed yet, { url: '/stays_view', res_body_length: 1}, + // not processed yet, { url: '/moorages_view', res_body_length: 1}, + { url: '/logs_view', res_body_length: 1}, + { url: '/log_view', res_body_length: 1}, + //{ url: '/stats_view', res_body_length: 1}, + { url: '/vessels_view', res_body_length: 1}, + ], + user_patchs: [ + { url: '/logbook?id=eq.3', + patch: { + name: "patch log name", + notes: "new log note" + }, + }, + { url: '/stays?id=eq.4', + patch: { + name: "patch stay name", + stay_code: 2, + notes: "new stay note" + }, + }, + /* not processed yet, { url: '/moorages?id=eq.1', + patch: { + name: "patch moorage name", + home_flag: true, + stay_code: 2, + notes: "new moorage note" + }, + } + */ + ], + user_fn: [ + { url: '/rpc/timelapse_fn', + payload: { + start_log: 3 + }, + res: { + obj_name: 'geojson' + } + }, + { url: '/rpc/export_logbook_geojson_fn', + payload: { + _id: 3 + }, + res: { + obj_name: 'geojson' + } + }, + { url: '/rpc/export_logbook_gpx_fn', + payload: { + _id: 3 + }, + res: { + obj_name: null + } + }, + { url: '/rpc/vessel_fn', + payload: null, + res: { + obj_name: 'vessel' + } + }, + { url: '/rpc/settings_fn', + payload: null, + res: { + obj_name: 'settings' + } + } + ], + otp_fn: [ + { url: '/rpc/generate_otp_fn', + payload: { email: 'demo+aava@openplotter.cloud' }, + res: { + otp: 0 + } + }, + { url: '/rpc/email_fn', + payload: { token: null }, + res: { + obj_name: 'settings' + } + }, + { url: '/rpc/generate_otp_fn', + payload: { email: 'demo+aava@openplotter.cloud' }, + res: { + otp: 0 + } + }, + { url: '/rpc/pushover_fn', + payload: { token: null, pushover_user_key: '0987654321qwerty!'}, + res: { + obj_name: 'settings' + } + }, + { url: '/rpc/generate_otp_fn', + payload: { email: 'demo+aava@openplotter.cloud' }, + res: { + otp: 0 + } + }, + { url: '/rpc/telegram_fn', + payload: { token: null, telegram_obj: {"chat": {"id": 9876543210, "type": "private", "title": null, "all_members_are_administrators": null}, "date": "NOW", "from": {"id": 9876543210, "is_bot": false, "first_name": "Aava", "language_code": "en"}} }, + res: { + obj_name: 'settings' + } + }, + ] + } +].forEach( function(test){ + +//console.log(`${test.cname}`); +describe(`${test.name}`, function(){ +request = supertest.agent(test.cname); +request.set('User-Agent', 'PostgSail unit tests'); + + describe("OpenAPI description", function(){ + + it('/', function(done) { + request = supertest.agent(test.cname); + request + .get('/') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body.paths['/rpc/signup']); + should.exist(res.body.paths['/rpc/login']); + should.exist(res.body.paths['/rpc/reset']); + should.exist(res.body.paths['/rpc/recover']); + //should.exist(res.body.paths['/rpc/generate_otp_fn']); + should.exist(res.body.paths['/rpc/pushover_fn']); + should.exist(res.body.paths['/rpc/telegram_fn']); + should.exist(res.body.paths['/rpc/telegram']); + done(err); + }); + }); + + }); // OpenAPI description + + describe("Get JWT user_role", function(){ + + it('/rpc/signup return user_role jwt token', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post('/rpc/signup') + .send(test.signin) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body.token); + user_jwt = res.body.token; + should.exist(user_jwt); + done(err); + }); + }); + + it('/rpc/login return user_role jwt token', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post('/rpc/login') + .send(test.login) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body.token); + //res.body.token.should.match(user_jwt); + console.log(user_jwt); + should.exist(user_jwt); + done(err); + }); + }); + + }); // JWT user_role + + describe("OpenAPI with JWT user_role", function(){ + + it('/', function(done) { + request = supertest.agent(test.cname); + request + .get('/') + .set('Authorization', `Bearer ${user_jwt}`) + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + // Functions + should.exist(res.body.paths['/rpc/register_vessel']); + should.exist(res.body.paths['/rpc/update_user_preferences_fn']); + should.exist(res.body.paths['/rpc/settings_fn']); + should.exist(res.body.paths['/rpc/versions_fn']); + // Tables + should.exist(res.body.paths['/metadata']); + should.exist(res.body.paths['/metrics']); + should.exist(res.body.paths['/logbook']); + should.exist(res.body.paths['/stays']); + should.exist(res.body.paths['/moorages']); + // Views + should.exist(res.body.paths['/logs_view']); + should.exist(res.body.paths['/moorages_view']); + should.exist(res.body.paths['/stays_view']); + should.exist(res.body.paths['/vessels_view']); + //should.exist(res.body.paths['/stats_view']); + should.exist(res.body.paths['/monitoring_view']); + done(err); + }); + }); + + }); // OpenAPI JWT user_role + + describe("Set preferences email_notifications, JWT user_role", function(){ + + it('/rpc/update_user_preferences_fn return true', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post('/rpc/update_user_preferences_fn') + .send(test.preferences) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .set('Content-Type', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + //console.log(res.text); + should.exist(res.text); + res.text.should.match('true'); + done(err); + }); + }); + }); // JWT user_role + + describe("Get versions, JWT user_role", function(){ + + it('/rpc/versions_fn return json', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .get('/rpc/versions_fn') + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + //console.log(res.text); + should.exist(res.body.api_version); + should.exist(res.body.sys_version); + done(err); + }); + }); + }); // JWT user_role + + describe("Get JWT vessel_role from user_role", function(){ + + it('/rpc/register_vessel return vessel_role jwt token', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post('/rpc/register_vessel') + .send(test.vessel) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body.token); + vessel_jwt = res.body.token; + console.log(vessel_jwt); + should.exist(vessel_jwt); + // Save vessel JWT token for later use. + fs.writeFile(`vessel_jwt_${test.vessel.vessel_name}.txt`, vessel_jwt, (err) => { + // In case of a error throw err. + if (err) throw err; + }) + done(err); + }); + }); + }); // JWT user_role + + describe("OpenAPI with JWT vessel_role", function(){ + + it('/', function(done) { + request = supertest.agent(test.cname); + request + .get('/') + .set('Authorization', `Bearer ${vessel_jwt}`) + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body.paths['/metadata']); + should.exist(res.body.paths['/metrics']); + should.exist(res.body.paths['/logbook']); + should.exist(res.body.paths['/stays']); + should.exist(res.body.paths['/moorages']); + done(err); + }); + }); + + }); // OpenAPI JWT vessel_role + + describe("Get vessel details view, JWT user_role", function(){ + + it('/vessels_view return json', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .get('/vessels_view') + .set('Authorization', `Bearer ${user_jwt}`) + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + console.log(res.body); + //res.body.length.should.match(0); + res.body.length.should.match(1); + //res.body[0].last_contact.should.match('Never'); + should.equal(res.body[0].last_contact, null); + done(err); + }); + }); + }); // JWT user_role + + describe("Get vessel details function, JWT user_role", function(){ + // no metadata from vessel so error - unrecognized configuration parameter "vessel.client_id" + it('/rpc/vessel_fn return json', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .get('/rpc/vessel_fn') + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .set('Content-Type', 'application/json') + .end(function(err,res){ + console.log(res.body) + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body); + //body = res.body; + //console.log(res.text); + done(err); + }); + }); + }); // JWT user_role + + describe("Vessel POST metadata, JWT vessel_role", function(){ + + it('/metadata?on_conflict=vessel_id', function(done) { + request = supertest.agent(test.cname); + request + .post('/metadata?on_conflict=vessel_id') + .send(test.vessel_metadata) + .set('Authorization', `Bearer ${vessel_jwt}`) + .set('Accept', 'application/json') + .set('Content-Type', 'application/json') + .set('Prefer', 'return=headers-only,resolution=merge-duplicates') + .end(function(err,res){ + res.status.should.equal(201); + //console.log(res.header); + should.exist(res.header['server']); + res.header['server'].should.match(new RegExp('postgrest','g')); + done(err); + }); + }); + + }); // Vessel metadata JWT vessel_role + + describe("Vessel POST metrics, JWT vessel_role", function(){ + + let data = []; + //console.log(vessel_metrics['metrics'][0]); + let i; + for (i = 0; i < test.vessel_metrics['metrics'].length; i++) { + data[i] = test.vessel_metrics['metrics'][i]; + // Override time, -2h to allow to new data later without delay. + data[i]['time'] = moment.utc().subtract(2, 'hours').add(i, 'minutes').format(); + // Override client_id + data[i]['client_id'] = test.vessel_metadata.client_id; + } + // Force last entry to be back in time from previous, it should be ignore silently + data.at(-1).time = moment.utc(data.at(-2).time).subtract(1, 'minutes').format(); + //console.log(data[0]); + + it('/metrics?select=time', function(done) { + request = supertest.agent(test.cname); + request + .post('/metrics?select=time') + .send(data) + .set('Authorization', `Bearer ${vessel_jwt}`) + .set('Accept', 'application/json') + .set('Content-Type', 'application/json') + .set('Prefer', 'return=representation') + .end(function(err,res){ + //console.log(res.body); + res.status.should.equal(201); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body); + res.body.length.should.match(test.vessel_metrics['metrics'].length-1); + done(err); + }); + }); + + }); // Vessel POST metrics JWT vessel_role + +/* + describe("run_cron_jobs() JWT vessel_role", function(){ + + it('/rpc/run_cron_jobs', function(done) { + request = supertest.agent(test.cname); + request + .get('/rpc/run_cron_jobs') + .set('Authorization', `Bearer ${vessel_jwt}`) + .set('Accept', 'application/json') + .set('Content-Type', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + done(); + }); + }); + + }); // run_cron_jobs() JWT vessel_role +*/ + + describe("Table endpoint, JWT user_role", function(){ + + test.user_tables.forEach(function (subtest) { + it(`${subtest.url}`, function(done) { + try { + //console.log(`${subtest.url} ${subtest.res_body_length}`); + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .get(`${subtest.url}`) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body); + res.body.length.should.match(subtest.res_body_length); + done(err); + }); + } + catch (error) { + done(); + } + }); + }); + }); // Table endpoint + + describe("Views endpoint, JWT user_role", function(){ + + test.user_views.forEach(function (subtest) { + it(`${subtest.url}`, function(done) { + try { + //console.log(`${subtest.url} ${subtest.res_body_length}`); + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .get(`${subtest.url}`) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body); + res.body.length.should.match(subtest.res_body_length); + done(err); + }); + } + catch (error) { + done(); + } + }); + }); + }); // Views endpoint + + describe("Patch endpoint, JWT user_role", function(){ + + test.user_patchs.forEach(function (subtest) { + it(`${subtest.url}`, function(done) { + try { + //console.log(`${subtest.url} ${subtest.res_body_length}`); + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .patch(subtest.url) + .send(subtest.patch) + .set('Content-Type', 'application/json') + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(204); + should.exist(res.header['server']); + res.header['server'].should.match(new RegExp('postgrest','g')); + done(err); + }); + } + catch (error) { + done(); + } + }); + }); + }); // Patch endpoint + + describe("Function endpoint, JWT user_role", function(){ + + test.user_fn.forEach(function (subtest) { + it(`${subtest.url}`, function(done) { + try { + //console.log(`${subtest.url} ${subtest.res_body_length}`); + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post(subtest.url) + .send(subtest.payload) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + //should.exist(res.body); + done(err); + }); + } + catch (error) { + done(); + } + }); + }); + }); // Function endpoint + + /* + describe("Function OTP endpoint, JWT user_role", function(){ + + let otp = null; + test.otp_fn.forEach(function (subtest) { + otp = null; + it(`${subtest.url}`, function(done) { + try { + //console.log(`${subtest.url} ${subtest.res}`); + if (otp) { + subtest.payload.token = otp; + } + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post(subtest.url) + .send(subtest.payload) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + console.log(res.body); + should.exist(res.body); + if (subtest.url == '/rpc/generate_otp_fn') { + otp = res.body; + } else { + res.text.should.match('true'); + otp = null; + } + done(err); + }); + } + catch (error) { + done(); + } + }); + }); + }); // Function OTP endpoint + */ + +}); // OpenAPI description + +}); // CNAMEs Array diff --git a/tests/index2.js b/tests/index2.js new file mode 100644 index 0000000..27374b6 --- /dev/null +++ b/tests/index2.js @@ -0,0 +1,645 @@ +'use strict'; +/* +* Unit test #2, additional aava sample vessel metrics +* +* process.env.PGSAIL_API_URI = from inside the docker +* +* npm install supertest should mocha mochawesome moment +* alias mocha="./node_modules/mocha/bin/_mocha" +* mocha index.js --reporter mochawesome --reporter-options reportDir=/mnt/postgsail/,reportFilename=report_api.html +* +*/ + +const supertest = require("supertest"); +const should = require("should"); +let request = null; +let user_jwt = null; +let vessel_jwt = null; +var moment = require('moment'); +const metrics_simulator = require('./metrics_sample_simulator.json'); + +// CNAMEs Array +[ + { cname: process.env.PGSAIL_API_URI, name: "PostgSail unit test 2, aava", + signin: { email: 'demo+aava@openplotter.cloud', pass: 'test', firstname:'first_aava', lastname:'last_aava'}, + login: { email: 'demo+aava@openplotter.cloud', pass: 'test'}, + vessel: { vessel_email: "demo+aava@openplotter.cloud", vessel_mmsi: "787654321", vessel_name: "aava"}, + preferences: { key: '{email_notifications}', value: false }, /* Disable email_notifications */ + vessel_metadata: { + name: "aava", + mmsi: "787654321", + client_id: "vessels.urn:mrn:imo:mmsi:787654321", + length: "12", + beam: "10", + height: "24", + ship_type: "37", + plugin_version: "1.0.2", + signalk_version: "1.20.0", + time: moment().subtract(69, 'minutes').format() + }, + vessel_metrics: metrics_simulator, + user_tables: [ + { url: '/stays', res_body_length: 3}, + // not processed yet, { url: '/moorages', res_body_length: 2}, + { url: '/logbook', res_body_length: 2}, + { url: '/metadata', res_body_length: 1} + ], + user_views: [ + // not processed yet, { url: '/stays_view', res_body_length: 1}, + // not processed yet, { url: '/moorages_view', res_body_length: 1}, + { url: '/logs_view', res_body_length: 2}, + { url: '/log_view', res_body_length: 2}, + //{ url: '/stats_view', res_body_length: 1}, + { url: '/vessels_view', res_body_length: 1}, + ], + user_patchs: [ + { url: '/logbook?id=eq.4', + patch: { + name: "patch log name 2", + notes: "new log note 2" + }, + }, + { url: '/stays?id=eq.5', + patch: { + name: "patch stay name 2", + stay_code: 2, + notes: "new stay note 2" + }, + }, + /* not processed yet, { url: '/moorages?id=eq.1', + patch: { + name: "patch moorage name", + home_flag: true, + stay_code: 2, + notes: "new moorage note" + }, + } + */ + ], + user_fn: [ + { url: '/rpc/timelapse_fn', + payload: { + start_log: 4 + }, + res: { + obj_name: 'geojson' + } + }, + { url: '/rpc/export_logbook_geojson_fn', + payload: { + _id: 4 + }, + res: { + obj_name: 'geojson' + } + }, + { url: '/rpc/export_logbook_gpx_fn', + payload: { + _id: 4 + }, + res: { + obj_name: null + } + }, + { url: '/rpc/vessel_fn', + payload: null, + res: { + obj_name: 'vessel' + } + }, + { url: '/rpc/settings_fn', + payload: null, + res: { + obj_name: 'settings' + } + } + ], + others_fn: [ + { url: '/rpc/generate_otp_fn', + payload: { email: 'demo+aava@openplotter.cloud' }, + res: { + obj_name: 'settings' + } + }, + { url: '/rpc/pushover_fn', + // invalid key to avoid trigger notification + payload: { token: 'zxy', pushover_test_key: '987azerty#'}, + res: { + obj_name: 'settings' + } + }, + { url: '/rpc/update_user_preferences_fn', + //payload: { key: '{xyz}', value: '987azerty#'}, + // invalid key to avoid trigger notification + payload: { key: '{telegram_test}', value: '{"id": 987654321, "is_bot": false, "first_name": "aaVa", "language_code": "en"}' }, + res: { + obj_name: 'settings' + } + }, + { url: '/rpc/bot', + payload: { email: 'demo+aava@openplotter.cloud', chat_id: 987654321}, + res: { + obj_name: 'settings' + } + } + ] + } +].forEach( function(test){ + +//console.log(`${test.cname}`); +describe(`${test.name}`, function(){ +request = supertest.agent(test.cname); +request.set('User-Agent', 'PostgSail unit tests'); + + describe("OpenAPI description", function(){ + + it('/', function(done) { + request = supertest.agent(test.cname); + request + .get('/') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body.paths['/rpc/signup']); + should.exist(res.body.paths['/rpc/login']); + //should.exist(res.body.paths['/rpc/generate_otp_fn']); + should.exist(res.body.paths['/rpc/pushover_fn']); + should.exist(res.body.paths['/rpc/telegram_fn']); + //should.exist(res.body.paths['/rpc/bot']); + done(err); + }); + }); + + }); // OpenAPI description + + describe("Get JWT user_role", function(){ + + it('/rpc/signup return user_role jwt token', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post('/rpc/signup') + .send(test.signin) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body.token); + user_jwt = res.body.token; + should.exist(user_jwt); + done(err); + }); + }); + + it('/rpc/login return user_role jwt token', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post('/rpc/login') + .send(test.login) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body.token); + res.body.token.should.match(user_jwt); + console.log(user_jwt); + should.exist(user_jwt); + done(err); + }); + }); + + }); // JWT user_role + + describe("OpenAPI with JWT user_role", function(){ + + it('/', function(done) { + request = supertest.agent(test.cname); + request + .get('/') + .set('Authorization', `Bearer ${user_jwt}`) + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + // Function + should.exist(res.body.paths['/rpc/register_vessel']); + should.exist(res.body.paths['/rpc/update_user_preferences_fn']); + should.exist(res.body.paths['/rpc/settings_fn']); + should.exist(res.body.paths['/rpc/versions_fn']); + // Tables + should.exist(res.body.paths['/metadata']); + should.exist(res.body.paths['/metrics']); + should.exist(res.body.paths['/logbook']); + should.exist(res.body.paths['/stays']); + should.exist(res.body.paths['/moorages']); + // Views + should.exist(res.body.paths['/logs_view']); + should.exist(res.body.paths['/moorages_view']); + should.exist(res.body.paths['/stays_view']); + should.exist(res.body.paths['/vessels_view']); +// should.exist(res.body.paths['/stats_view']); + should.exist(res.body.paths['/monitoring_view']); + done(err); + }); + }); + + }); // OpenAPI JWT user_role + + describe("Set preferences email_notifications, JWT user_role", function(){ + + it('/rpc/update_user_preferences_fn return true', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post('/rpc/update_user_preferences_fn') + .send(test.preferences) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .set('Content-Type', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + //console.log(res.text); + should.exist(res.text); + res.text.should.match('true'); + done(err); + }); + }); + }); // JWT user_role + + describe("Get versions, JWT user_role", function(){ + + it('/rpc/versions_fn return json', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .get('/rpc/versions_fn') + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + //console.log(res.text); + should.exist(res.body.api_version); + should.exist(res.body.sys_version); + done(err); + }); + }); + }); // JWT user_role + + describe("Get JWT vessel_role from user_role", function(){ + + it('/rpc/register_vessel return vessel_role jwt token', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post('/rpc/register_vessel') + .send(test.vessel) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body.token); + vessel_jwt = res.body.token; + console.log(vessel_jwt); + should.exist(vessel_jwt); + done(err); + }); + }); + }); // JWT user_role + + describe("OpenAPI with JWT vessel_role", function(){ + + it('/', function(done) { + request = supertest.agent(test.cname); + request + .get('/') + .set('Authorization', `Bearer ${vessel_jwt}`) + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body.paths['/metadata']); + should.exist(res.body.paths['/metrics']); + should.exist(res.body.paths['/logbook']); + should.exist(res.body.paths['/stays']); + should.exist(res.body.paths['/moorages']); + done(err); + }); + }); + + }); // OpenAPI JWT vessel_role + + describe("Get vessel details view, JWT user_role", function(){ + + it('/vessels_view return json', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .get('/vessels_view') + .set('Authorization', `Bearer ${user_jwt}`) + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + console.log(res.body); + //res.body.length.should.match(0); + res.body.length.should.match(1); + //res.body[0].last_contact.should.match('Never'); + should.exist(res.body[0].last_contact); + done(err); + }); + }); + }); // JWT user_role + + describe("Get vessel details function, JWT user_role", function(){ + + it('/rpc/vessel_fn return json', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post('/rpc/vessel_fn') + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .set('Content-Type', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + //should.exist(res.body); + //body = res.body; + console.log(res.text); + done(err); + }); + }); + }); // JWT user_role + + describe("Vessel POST metadata, JWT vessel_role", function(){ + + it('/metadata', function(done) { + request = supertest.agent(test.cname); + request + .post('/metadata') + .send(test.vessel_metadata) + .set('Authorization', `Bearer ${vessel_jwt}`) + .set('Accept', 'application/json') + .set('Content-Type', 'application/json') + .set('Prefer', 'return=headers-only') + .end(function(err,res){ + res.status.should.equal(201); + //console.log(res.header); + should.exist(res.header['server']); + res.header['server'].should.match(new RegExp('postgrest','g')); + done(err); + }); + }); + + }); // Vessel metadata JWT vessel_role + + describe("Vessel POST metrics, JWT vessel_role", function(){ + + let data = []; + //console.log(vessel_metrics['metrics'][0]); + let i; + for (i = 0; i < test.vessel_metrics['metrics'].length; i++) { + data[i] = test.vessel_metrics['metrics'][i]; + // Override time, +1h because previous sample include 47 entry. + data[i]['time'] = moment().add(1, 'hour').add(i, 'minutes').format(); + // Override client_id + data[i]['client_id'] = test.vessel_metadata.client_id; + } + console.log(data[0]); + + it('/metrics?select=time', function(done) { + request = supertest.agent(test.cname); + request + .post('/metrics?select=time') + .send(data) + .set('Authorization', `Bearer ${vessel_jwt}`) + .set('Accept', 'application/json') + .set('Content-Type', 'application/json') + .set('Prefer', 'return=representation') + .end(function(err,res){ + //console.log(res.body); + res.status.should.equal(201); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body); + res.body.length.should.match(test.vessel_metrics['metrics'].length); + done(err); + }); + }); + + }); // Vessel POST metrics JWT vessel_role + +/* + describe("run_cron_jobs() JWT vessel_role", function(){ + + it('/rpc/run_cron_jobs', function(done) { + request = supertest.agent(test.cname); + request + .get('/rpc/run_cron_jobs') + .set('Authorization', `Bearer ${vessel_jwt}`) + .set('Accept', 'application/json') + .set('Content-Type', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + done(); + }); + }); + + }); // run_cron_jobs() JWT vessel_role +*/ + + describe("Table endpoint, JWT user_role", function(){ + + test.user_tables.forEach(function (subtest) { + it(`${subtest.url}`, function(done) { + try { + //console.log(`${subtest.url} ${subtest.res_body_length}`); + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .get(`${subtest.url}`) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body); + res.body.length.should.match(subtest.res_body_length); + done(err); + }); + } + catch (error) { + done(); + } + }); + }); + }); // Table endpoint + + describe("Views endpoint, JWT user_role", function(){ + + test.user_views.forEach(function (subtest) { + it(`${subtest.url}`, function(done) { + try { + //console.log(`${subtest.url} ${subtest.res_body_length}`); + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .get(`${subtest.url}`) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body); + res.body.length.should.match(subtest.res_body_length); + done(err); + }); + } + catch (error) { + done(); + } + }); + }); + }); // Views endpoint + + describe("Patch endpoint, JWT user_role", function(){ + + test.user_patchs.forEach(function (subtest) { + it(`${subtest.url}`, function(done) { + try { + //console.log(`${subtest.url} ${subtest.res_body_length}`); + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .patch(subtest.url) + .send(subtest.patch) + .set('Content-Type', 'application/json') + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(204); + should.exist(res.header['server']); + res.header['server'].should.match(new RegExp('postgrest','g')); + done(err); + }); + } + catch (error) { + done(); + } + }); + }); + }); // Patch endpoint + + describe("Function user_fn endpoint, JWT user_role", function(){ + + test.user_fn.forEach(function (subtest) { + it(`${subtest.url}`, function(done) { + try { + //console.log(`${subtest.url} ${subtest.res_body_length}`); + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post(subtest.url) + .send(subtest.payload) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + //should.exist(res.body); + done(err); + }); + } + catch (error) { + done(); + } + }); + }); + }); // Function endpoint + +/* + describe("Function others endpoint, JWT user_role", function(){ + + let otp = null; + test.others_fn.forEach(function (subtest) { + it(`${subtest.url}`, function(done) { + try { + //console.log(`${subtest.url} ${subtest.res_body_length}`); + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post(subtest.url) + .send(subtest.payload) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + //console.log(res.body); + should.exist(res.body); + if (subtest.url == '/rpc/generate_otp_fn') { + otp = res.body.text(); + } + done(err); + }); + } + catch (error) { + done(); + } + }); + }); + }); // Function endpoint +*/ + +}); // OpenAPI description + +}); // CNAMEs Array diff --git a/tests/index3.js b/tests/index3.js new file mode 100644 index 0000000..8cd752c --- /dev/null +++ b/tests/index3.js @@ -0,0 +1,802 @@ +'use strict'; +/* +* Unit test #3, check post cron results, moorages, stays and stats +* +* process.env.PGSAIL_API_URI = from inside the docker +* +* npm install supertest should mocha mochawesome moment +* alias mocha="./node_modules/mocha/bin/_mocha" +* mocha index.js --reporter mochawesome --reporter-options reportDir=/mnt/postgsail/,reportFilename=report_api.html +* +*/ + +const supertest = require("supertest"); +// Deprecated +const should = require("should"); +//const chai = require("chai"); +//const should = chai.should(); +let request = null; +let user_jwt = null; +let vessel_jwt = null; +var moment = require('moment'); + +// CNAMEs Array +[ + + { cname: process.env.PGSAIL_API_URI, name: "PostgSail unit test kapla", + signin: { email: 'demo+kapla@openplotter.cloud', pass: 'test', firstname:'First_kapla', lastname:'Last_kapla'}, + login: { email: 'demo+kapla@openplotter.cloud', pass: 'test'}, + vessel: { vessel_email: "demo+kapla@openplotter.cloud", vessel_mmsi: null, vessel_name: "kapla"}, + preferences: { key: '{email_notifications}', value: false }, /* Disable email_notifications */ + vessel_metadata: { + name: "kapla", + mmsi: "123456789", + client_id: "vessels.urn:mrn:imo:mmsi:123456789", + length: "12", + beam: "10", + height: "24", + ship_type: "36", + plugin_version: "0.0.1", + signalk_version: "1.12.0", + time: moment().subtract(69, 'minutes').format() + /* To trigger monitor_offline quickly */ + }, + user_tables: [ + { url: '/stays', res_body_length: 3}, + { url: '/moorages', res_body_length: 2}, + { url: '/logbook', res_body_length: 2}, + { url: '/metadata', res_body_length: 1} + ], + user_views: [ + { url: '/stays_view', res_body_length: 2}, + { url: '/moorages_view', res_body_length: 2}, + { url: '/logs_view', res_body_length: 2}, + { url: '/log_view', res_body_length: 2}, + //{ url: '/stats_view', res_body_length: 1}, + { url: '/vessels_view', res_body_length: 1}, + ], + user_patchs: [ + { url: '/logbook?id=eq.1', + patch: { + name: "patch log name 3", + notes: "new log note 3" + }, + }, + { url: '/stays?id=eq.1', + patch: { + name: "patch stay name 3", + stay_code: 2, + notes: "new stay note 3" + }, + }, + { url: '/moorages?id=eq.1', + patch: { + name: "patch moorage name 3", + home_flag: true, + stay_code: 2, + notes: "new moorage note 3" + }, + } + ], + user_fn: [ + { url: '/rpc/timelapse_fn', + payload: { + start_log: 2 + }, + res: { + obj_name: 'geojson' + } + }, + { url: '/rpc/export_logbook_geojson_fn', + payload: { + _id: 2 + }, + res: { + obj_name: 'geojson' + } + }, + { url: '/rpc/export_logbook_gpx_fn', + payload: { + _id: 2 + }, + res: { + obj_name: null + } + }, + { url: '/rpc/export_moorages_geojson_fn', + payload: {}, + res: { + obj_name: 'geojson' + } + }, + { url: '/rpc/export_moorages_gpx_fn', + payload: {}, + res: { + obj_name: null + } + }, + { url: '/rpc/find_log_from_moorage_fn', + payload: { + _id: 2 + }, + res: { + obj_name: 'geojson' + } + }, + { url: '/rpc/find_log_to_moorage_fn', + payload: { + _id: 2 + }, + res: { + obj_name: 'geojson' + } + }, + { url: '/rpc/vessel_fn', + payload: null, + res: { + obj_name: 'vessel' + } + }, + { url: '/rpc/settings_fn', + payload: null, + res: { + obj_name: 'settings' + } + }, + { url: '/rpc/versions_fn', + payload: null, + res: { + obj_name: 'versions' + } + }, + { url: '/rpc/stats_logs_fn', + payload: {}, + res: { + obj_name: 'stats' + } + }, + { url: '/rpc/stats_logs_fn', + payload: { + start_date: '2022-01-01', + end_date: '2022-06-12' + }, + res: { + obj_name: null + } + }, + ], + email_otp_fn: [ + { url: '/rpc/generate_otp_fn', + payload: { email: 'demo+kapla@openplotter.cloud' }, + res: { + otp: 0 + } + }, + { url: '/rpc/email_fn', + //payload: { token: 'abc', pushover_user_key: '123qwerty!'}, + // invalid key to avoid trigger notification + payload: { token: '123456' }, + res: { + obj_name: 'settings' + } + } + ], + pushover_fn: [ + { url: '/rpc/generate_otp_fn', + payload: { email: 'demo+kapla@openplotter.cloud' }, + res: { + otp: 0 + } + }, + { url: '/rpc/pushover_fn', + //payload: { token: 'abc', pushover_user_key: '123qwerty!'}, + // invalid key to avoid trigger notification + payload: { token: null, pushover_test_key: '123qwerty!'}, + res: { + obj_name: 'settings' + } + } + ], + telegram_fn: [ + { url: '/rpc/generate_otp_fn', + payload: { email: 'demo+kapla@openplotter.cloud' }, + res: { + otp: 0 + } + }, + { url: '/rpc/telegram_fn', + //payload: { key: '{abc}', value: {"a": "1", "b": 2, "c": true}}, + // invalid key to avoid trigger notification + payload: { token: null, telegram_test: '{"id": 123456789, "is_bot": false, "first_name": "kaplA", "language_code": "en"}' }, + res: { + obj_name: 'settings' + } + } + ] + }, + { cname: process.env.PGSAIL_API_URI, name: "PostgSail unit test, aava", + signin: {email: 'demo+aava@openplotter.cloud', pass: 'test', firstname:'first_aava', lastname:'last_aava'}, + login: {email: 'demo+aava@openplotter.cloud', pass: 'test'}, + vessel: {vessel_email: "demo+aava@openplotter.cloud", vessel_mmsi: null, vessel_name: "aava"}, + preferences: { key: '{email_notifications}', value: false }, /* Disable email_notifications */ + vessel_metadata: { + name: "aava", + mmsi: "787654321", + client_id: "vessels.urn:mrn:imo:mmsi:787654321", + length: "12", + beam: "10", + height: "24", + ship_type: "37", + plugin_version: "1.0.2", + signalk_version: "1.20.0", + time: moment().subtract(69, 'minutes').format() + }, + user_tables: [ + { url: '/stays', res_body_length: 3}, + { url: '/moorages', res_body_length: 2}, + { url: '/logbook', res_body_length: 2}, + { url: '/metadata', res_body_length: 1} + ], + user_views: [ + { url: '/stays_view', res_body_length: 2}, + { url: '/moorages_view', res_body_length: 2}, + { url: '/logs_view', res_body_length: 2}, + { url: '/log_view', res_body_length: 2}, + //{ url: '/stats_view', res_body_length: 1}, + { url: '/vessels_view', res_body_length: 1}, + ], + user_patchs: [ + { url: '/logbook?id=eq.4', + patch: { + name: "patch log name 4", + notes: "new log note 4" + }, + }, + { url: '/stays?id=eq.4', + patch: { + name: "patch stay name 4", + stay_code: 2, + notes: "new stay note 4" + }, + }, + { url: '/moorages?id=eq.4', + patch: { + name: "patch moorage name", + home_flag: true, + stay_code: 2, + notes: "new moorage note" + }, + } + ], + user_fn: [ + { url: '/rpc/timelapse_fn', + payload: { + start_log: 4 + }, + res: { + obj_name: 'geojson' + } + }, + { url: '/rpc/export_logbook_geojson_fn', + payload: { + _id: 4 + }, + res: { + obj_name: 'geojson' + } + }, + { url: '/rpc/export_logbook_gpx_fn', + payload: { + _id: 4 + }, + res: { + obj_name: null + } + }, + { url: '/rpc/export_moorages_geojson_fn', + payload: {}, + res: { + geojson: { type: 'FeatureCollection', features: [ [Object], [Object] ] } + } + }, + { url: '/rpc/export_moorages_gpx_fn', + payload: {}, + res: { + obj_name: null + } + }, + { url: '/rpc/find_log_from_moorage_fn', + payload: { + _id: 4 + }, + res: { geojson: { type: 'FeatureCollection', features: [ [Object] ] } } + }, + { url: '/rpc/find_log_to_moorage_fn', + payload: { + _id: 4 + }, + res: { geojson: { type: 'FeatureCollection', features: [ [Object] ] } } + }, + { url: '/rpc/vessel_fn', + payload: null, + res: { + vessel: { + beam: 10, + mmsi: 787654321, + name: 'aava', + height: 24, + length: 37, + alpha_2: null, + country: null, + geojson: { type: 'Feature', geometry: [Object], properties: [Object] }, + ship_type: 'Pleasure Craft', + created_at: '2023-08-17T16:32:13', + last_contact: '2023-08-17T15:23:14' + } + } + }, + { url: '/rpc/settings_fn', + payload: null, + res: { + settings: { + email: 'demo+aava@openplotter.cloud', + first: 'first_aava', + last: 'last_aava', + preferences: { badges: [Object], email_notifications: false }, + created_at: '2023-08-17T16:32:12.701788', + username: 'F Last_Aava', + has_vessel: true + } + } + }, + { url: '/rpc/stats_logs_fn', + payload: {}, + res: { // Compare keys only + stats: { + count: 2, + max_speed: 7.1, + max_distance: 8.2365, + max_duration: '01:11:00', + max_speed_id: 3, + sum_duration: '01:54:00', + max_wind_speed: 44.2, + max_distance_id: 3, + max_wind_speed_id: 4 + } + } + }, + { url: '/rpc/stats_logs_fn', + payload: { + start_date: '2022-01-01', + end_date: '2022-06-12' + }, + res: { stats: null } + }, + ], + others_fn: [ + { url: '/rpc/generate_otp_fn', + payload: { email: 'demo+aava@openplotter.cloud' }, + res: { + obj_name: 'settings' + } + }, + { url: '/rpc/pushover_fn', + // invalid key to avoid trigger notification + payload: { token: 'zxy', pushover_test_key: '987azerty#'}, + res: { + obj_name: 'settings' + } + }, + { url: '/rpc/update_user_preferences_fn', + //payload: { key: '{xyz}', value: '987azerty#'}, + // invalid key to avoid trigger notification + payload: { key: '{telegram_test}', value: '{"id": 987654321, "is_bot": false, "first_name": "aaVa", "language_code": "en"}' }, + res: { + obj_name: 'settings' + } + }, + { url: '/rpc/bot', + payload: { email: 'demo+aava@openplotter.cloud', chat_id: 987654321}, + res: { + obj_name: 'settings' + } + } + ] + } +].forEach( function(test){ + +//console.log(`${test.cname}`); +describe(`${test.name}`, function(){ +request = supertest.agent(test.cname); +request.set('User-Agent', 'PostgSail unit tests'); + + describe("OpenAPI description", function(){ + + it('/', function(done) { + request = supertest.agent(test.cname); + request + .get('/') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body.paths['/rpc/signup']); + should.exist(res.body.paths['/rpc/login']); + //should.exist(res.body.paths['/rpc/generate_otp_fn']); + should.exist(res.body.paths['/rpc/pushover_fn']); + should.exist(res.body.paths['/rpc/telegram_fn']); + //should.exist(res.body.paths['/rpc/bot']); + done(err); + }); + }); + + }); // OpenAPI description + + describe("Get JWT user_role", function(){ + + it('/rpc/signup return user_role jwt token', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post('/rpc/signup') + .send(test.signin) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body.token); + user_jwt = res.body.token; + should.exist(user_jwt); + done(err); + }); + }); + + it('/rpc/login return user_role jwt token', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post('/rpc/login') + .send(test.login) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body.token); + //res.body.token.should.match(user_jwt); + //console.log(user_jwt); + should.exist(user_jwt); + done(err); + }); + }); + + }); // JWT user_role + + describe("OpenAPI with JWT user_role", function(){ + + it('/', function(done) { + request = supertest.agent(test.cname); + request + .get('/') + .set('Authorization', `Bearer ${user_jwt}`) + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + // Function + should.exist(res.body.paths['/rpc/register_vessel']); + should.exist(res.body.paths['/rpc/update_user_preferences_fn']); + should.exist(res.body.paths['/rpc/settings_fn']); + should.exist(res.body.paths['/rpc/versions_fn']); + // Tables + should.exist(res.body.paths['/metadata']); + should.exist(res.body.paths['/metrics']); + should.exist(res.body.paths['/logbook']); + should.exist(res.body.paths['/stays']); + should.exist(res.body.paths['/moorages']); + // Views + should.exist(res.body.paths['/logs_view']); + should.exist(res.body.paths['/moorages_view']); + should.exist(res.body.paths['/stays_view']); + should.exist(res.body.paths['/vessels_view']); + //should.exist(res.body.paths['/stats_view']); + should.exist(res.body.paths['/monitoring_view']); + done(err); + }); + }); + + }); // OpenAPI JWT user_role + + describe("Set preferences email_notifications, JWT user_role", function(){ + + it('/rpc/update_user_preferences_fn return true', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post('/rpc/update_user_preferences_fn') + .send(test.preferences) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .set('Content-Type', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + //console.log(res.text); + should.exist(res.text); + res.text.should.match('true'); + done(err); + }); + }); + }); // JWT user_role + + describe("Get versions, JWT user_role", function(){ + + it('/rpc/versions_fn return json', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .get('/rpc/versions_fn') + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + //console.log(res.text); + should.exist(res.body.api_version); + should.exist(res.body.sys_version); + done(err); + }); + }); + }); // JWT user_role + + describe("Get JWT vessel_role from user_role", function(){ + + it('/rpc/register_vessel return vessel_role jwt token', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post('/rpc/register_vessel') + .send(test.vessel) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body.token); + vessel_jwt = res.body.token; + console.log(vessel_jwt); + should.exist(vessel_jwt); + done(err); + }); + }); + }); // JWT user_role + + describe("Get vessel details view, JWT user_role", function(){ + + it('/vessels_view return json', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .get('/vessels_view') + .set('Authorization', `Bearer ${user_jwt}`) + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + console.log(res.body); + //res.body.length.should.match(0); + res.body.length.should.match(1); + //res.body[0].last_contact.should.match('Never'); + should.exist(res.body[0].last_contact); + done(err); + }); + }); + }); // JWT user_role + + describe("Get vessel details function, JWT user_role", function(){ + + it('/rpc/vessel_fn return json', function(done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post('/rpc/vessel_fn') + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .set('Content-Type', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + //should.exist(res.body); + //body = res.body; + console.log(res.text); + done(err); + }); + }); + }); // JWT user_role + + describe("Table endpoint, JWT user_role", function(){ + + test.user_tables.forEach(function (subtest) { + it(`${subtest.url}`, function(done) { + try { + //console.log(`${subtest.url} ${subtest.res_body_length}`); + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .get(`${subtest.url}`) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + //console.log(res.body); + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body); + res.body.length.should.match(subtest.res_body_length); + done(err); + }); + } + catch (error) { + done(); + } + }); + }); + }); // Table endpoint + + describe("Views endpoint, JWT user_role", function(){ + + test.user_views.forEach(function (subtest) { + it(`${subtest.url}`, function(done) { + try { + //console.log(`${subtest.url} ${subtest.res_body_length}`); + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .get(`${subtest.url}`) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + //console.log(res.body); + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + should.exist(res.body); + res.body.length.should.match(subtest.res_body_length); + console.log(res.body); + done(err); + }); + } + catch (error) { + done(); + } + }); + }); + }); // Views endpoint + + describe("Patch endpoint, JWT user_role", function(){ + + test.user_patchs.forEach(function (subtest) { + it(`${subtest.url}`, function(done) { + try { + //console.log(`${subtest.url} ${subtest.res_body_length}`); + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .patch(subtest.url) + .send(subtest.patch) + .set('Content-Type', 'application/json') + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(204); + should.exist(res.header['server']); + res.header['server'].should.match(new RegExp('postgrest','g')); + console.log(res.body); + done(err); + }); + } + catch (error) { + done(); + } + }); + }); + }); // Patch endpoint + + describe("Function user_fn endpoint, JWT user_role", function(){ + + test.user_fn.forEach(function (subtest) { + it(`${subtest.url}`, function(done) { + try { + //console.log(`${subtest.url} ${subtest.res_body_length}`); + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post(subtest.url) + .send(subtest.payload) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + //should.exist(res.body); + console.log(res.body); + done(err); + }); + } + catch (error) { + done(); + } + }); + }); + }); // Function endpoint + +/* + describe("Function others endpoint, JWT user_role", function(){ + + let otp = null; + test.others_fn.forEach(function (subtest) { + it(`${subtest.url}`, function(done) { + try { + //console.log(`${subtest.url} ${subtest.res_body_length}`); + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post(subtest.url) + .send(subtest.payload) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + //console.log(res.body); + should.exist(res.body); + if (subtest.url == '/rpc/generate_otp_fn') { + otp = res.body.text(); + } + done(err); + }); + } + catch (error) { + done(); + } + }); + }); + }); // Function endpoint +*/ + +}); // OpenAPI description + +}); // CNAMEs Array diff --git a/tests/index4.js b/tests/index4.js new file mode 100644 index 0000000..e86d451 --- /dev/null +++ b/tests/index4.js @@ -0,0 +1,671 @@ +"use strict"; +/* + * Unit test #4 + * OTP for email, Pushover, Telegram + * + * process.env.PGSAIL_API_URI = from inside the docker + * + * npm install supertest should mocha mochawesome moment + * alias mocha="./node_modules/mocha/bin/_mocha" + * mocha index4.js --reporter mochawesome --reporter-options reportDir=/mnt/postgsail/,reportFilename=report_api.html + * + */ + +const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); + +const supertest = require("supertest"); +// Deprecated +const should = require("should"); +//const chai = require("chai"); +//const should = chai.should(); +let request = null; +let user_jwt = null; +var moment = require("moment"); + +// Users Array +[ + { + cname: process.env.PGSAIL_API_URI, + name: "PostgSail unit test kapla", + signin: { + email: "demo+kapla@openplotter.cloud", + pass: "test", + firstname: "First_kapla", + lastname: "Last_kapla", + }, + login: { email: "demo+kapla@openplotter.cloud", pass: "test" }, + preferences: { key: "{email_valid}", value: false }, + email_otp: [ + { + url: "/rpc/generate_otp_fn", + payload: { email: "demo+kapla@openplotter.cloud" }, + res: { + otp: 0, + }, + }, + { + url: "/rpc/email_fn", + payload: { token: null }, + res: { + obj_name: "settings", + }, + }, + ], + pushover_otp: [ + { + //url: '/rpc/generate_otp_fn', + url: "/rpc/pushover_subscribe_link_fn", + //payload: { email: 'demo+kapla@openplotter.cloud' }, + res: { + obj_name: "pushover_link", + }, + }, + { + url: "/rpc/pushover_fn", + payload: { token: null, pushover_user_key: "1234567890azerty!" }, + res: { + obj_name: "settings", + }, + }, + ], + telegram_otp: [ + { + url: "/rpc/update_user_preferences_fn", + payload: { key: "{email_notifications}", value: false }, + }, + { + url: "/rpc/update_user_preferences_fn", + payload: { key: "{phone_notifications}", value: false }, + }, + { + //url: '/rpc/generate_otp_fn', + url: "/rpc/telegram_otp_fn", + payload: { email: "demo+kapla@openplotter.cloud" }, + res: { + otp: 0, + }, + }, + { + url: "/rpc/telegram_fn", + payload: { + token: null, + telegram_obj: { + chat: { + id: 1234567890, + type: "private", + title: null, + all_members_are_administrators: null, + }, + date: "NOW", + from: { + id: 1234567890, + is_bot: false, + first_name: "Kapla", + language_code: "en", + }, + }, + }, + res: {}, + }, + ], + telegram: { payload: { user_id: 1234567890 } }, + telegram_fn: [{ url: "/rpc/vessel_fn" }, { url: "/monitoring_view" }], + badges: { + url: "/rpc/settings_fn", + payload: null, + res: { + obj_name: "settings", + }, + }, + monitoring: [ + { + url: "/monitoring_view", + payload: null, + res: {}, + }, + { + url: "/monitoring_view2", + payload: null, + res: {}, + }, + { + url: "/monitoring_view3", + payload: null, + res: {}, + }, + { + url: "/monitoring_voltage", + payload: null, + res: {}, + }, + { + url: "/monitoring_temperatures", + payload: null, + res: {}, + }, + { + url: "/monitoring_humidity", + payload: null, + res: {}, + }, + ], + eventlogs: { + url: "/eventlogs_view", + payload: null, + res: {}, + }, + }, + { + cname: process.env.PGSAIL_API_URI, + name: "PostgSail unit test, aava", + signin: { + email: "demo+aava@openplotter.cloud", + pass: "test", + firstname: "first_aava", + lastname: "last_aava", + }, + login: { email: "demo+aava@openplotter.cloud", pass: "test" }, + preferences: { key: "{email_valid}", value: false }, + email_otp: [ + { + url: "/rpc/generate_otp_fn", + payload: { email: "demo+aava@openplotter.cloud" }, + res: { + otp: 0, + }, + }, + { + url: "/rpc/email_fn", + payload: { token: null }, + res: { + obj_name: "settings", + }, + }, + ], + pushover_otp: [ + { + //url: '/rpc/generate_otp_fn', + url: "/rpc/pushover_subscribe_link_fn", + //payload: { email: 'demo+aava@openplotter.cloud' }, + res: { + obj_name: "pushover_link", + }, + }, + { + url: "/rpc/pushover_fn", + payload: { token: null, pushover_user_key: "0987654321qwerty!" }, + res: { + obj_name: "settings", + }, + }, + ], + telegram_otp: [ + { + url: "/rpc/update_user_preferences_fn", + payload: { key: "{email_notifications}", value: false }, + }, + { + url: "/rpc/update_user_preferences_fn", + payload: { key: "{phone_notifications}", value: false }, + }, + { + //url: '/rpc/generate_otp_fn', + url: "/rpc/telegram_otp_fn", + payload: { email: "demo+aava@openplotter.cloud" }, + res: { + otp: 0, + }, + }, + { + url: "/rpc/telegram_fn", + payload: { + token: null, + telegram_obj: { + chat: { + id: 9876543210, + type: "private", + title: null, + all_members_are_administrators: null, + }, + date: "NOW", + from: { + id: 9876543210, + is_bot: false, + first_name: "Aava", + language_code: "en", + }, + }, + }, + res: {}, + }, + ], + telegram: { payload: { user_id: 9876543210 } }, + telegram_fn: [{ url: "/rpc/vessel_fn" }, { url: "/monitoring_view" }], + badges: { + url: "/rpc/settings_fn", + payload: null, + res: { + obj_name: "settings", + }, + }, + monitoring: [ + { + url: "/monitoring_view", + payload: null, + res: {}, + }, + { + url: "/monitoring_view2", + payload: null, + res: {}, + }, + { + url: "/monitoring_view3", + payload: null, + res: {}, + }, + { + url: "/monitoring_voltage", + payload: null, + res: {}, + }, + { + url: "/monitoring_temperatures", + payload: null, + res: {}, + }, + { + url: "/monitoring_humidity", + payload: null, + res: {}, + }, + ], + eventlogs: { + url: "/eventlogs_view", + payload: null, + res: {}, + }, + }, +].forEach(function (test) { + //console.log(`${test.cname}`); + describe(`${test.name}`, function () { + request = supertest.agent(test.cname); + request.set("User-Agent", "PostgSail unit tests"); + + describe("Get JWT user_role", function () { + it("/rpc/signup return user_role jwt token", function (done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post("/rpc/signup") + .send(test.signin) + .set("Accept", "application/json") + .end(function (err, res) { + res.status.should.equal(200); + should.exist(res.header["content-type"]); + should.exist(res.header["server"]); + res.header["content-type"].should.match(new RegExp("json", "g")); + res.header["server"].should.match(new RegExp("postgrest", "g")); + should.exist(res.body.token); + user_jwt = res.body.token; + should.exist(user_jwt); + done(err); + }); + }); + + it("/rpc/login return user_role jwt token", function (done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post("/rpc/login") + .send(test.login) + .set("Accept", "application/json") + .end(function (err, res) { + res.status.should.equal(200); + should.exist(res.header["content-type"]); + should.exist(res.header["server"]); + res.header["content-type"].should.match(new RegExp("json", "g")); + res.header["server"].should.match(new RegExp("postgrest", "g")); + should.exist(res.body.token); + res.body.token.should.match(user_jwt); + console.log(user_jwt); + should.exist(user_jwt); + done(err); + }); + }); + }); // JWT user_role + + describe("Set preferences email_notifications, JWT user_role", function () { + it("/rpc/update_user_preferences_fn return true", function (done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post("/rpc/update_user_preferences_fn") + .send(test.preferences) + .set("Authorization", `Bearer ${user_jwt}`) + .set("Accept", "application/json") + .set("Content-Type", "application/json") + .end(function (err, res) { + res.status.should.equal(200); + should.exist(res.header["content-type"]); + should.exist(res.header["server"]); + res.header["content-type"].should.match(new RegExp("json", "g")); + res.header["server"].should.match(new RegExp("postgrest", "g")); + //console.log(res.text); + should.exist(res.text); + res.text.should.match("true"); + done(err); + }); + }); + }); // JWT user_role + + describe("Function email OTP endpoint, JWT user_role", function () { + let otp = null; + test.email_otp.forEach(function (subtest) { + it(`${subtest.url}`, function (done) { + try { + //console.log(`${subtest.url} ${subtest.payload}`); + if (otp) { + subtest.payload.token = otp; + } + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post(subtest.url) + .send(subtest.payload) + .set("Authorization", `Bearer ${user_jwt}`) + .set("Accept", "application/json") + .end(function (err, res) { + res.status.should.equal(200); + should.exist(res.header["content-type"]); + should.exist(res.header["server"]); + res.header["content-type"].should.match( + new RegExp("json", "g") + ); + res.header["server"].should.match(new RegExp("postgrest", "g")); + console.log(res.body); + should.exist(res.body); + if (subtest.url == "/rpc/generate_otp_fn") { + otp = res.body; + } else { + res.text.should.match("true"); + } + done(err); + }); + } catch (error) { + done(); + } + }); + }); + }); // email OTP endpoint + + describe("Function Pushover OTP endpoint, JWT user_role", function () { + let otp = null; + test.pushover_otp.forEach(function (subtest) { + it(`${subtest.url}`, function (done) { + try { + //console.log(`${subtest.url} ${subtest.payload}`); + if (otp) { + subtest.payload.token = otp; + } + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post(subtest.url) + .send(subtest.payload) + .set("Authorization", `Bearer ${user_jwt}`) + .set("Accept", "application/json") + .end(function (err, res) { + res.status.should.equal(200); + should.exist(res.header["content-type"]); + should.exist(res.header["server"]); + res.header["content-type"].should.match( + new RegExp("json", "g") + ); + res.header["server"].should.match(new RegExp("postgrest", "g")); + //console.log(res.body); + should.exist(res.body); + if (subtest.url == "/rpc/pushover_subscribe_link_fn") { + should.exist(res.body.pushover_link.link); + let rx = /3D(\d+)\&/g; + //console.log(rx.exec(res.body.pushover_link.link)[1]); + let arr = rx.exec(res.body.pushover_link.link); + //console.log(arr); + console.log(arr[1]); + otp = arr[1]; + } else { + res.text.should.match("true"); + } + done(err); + }); + } catch (error) { + done(); + } + }); + }); + }); // pushover OTP endpoint + + describe("Function Telegram OTP endpoint, JWT user_role", function () { + let otp = null; + test.telegram_otp.forEach(function (subtest) { + it(`${subtest.url}`, function (done) { + try { + console.log(`${subtest.url} ${subtest.payload.email} ${otp}`); + if (otp) { + subtest.payload.token = otp; + console.log(subtest.payload.telegram_obj.date); + subtest.payload.telegram_obj.date = moment.utc().format(); + } + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post(subtest.url) + .send(subtest.payload) + .set("Authorization", `Bearer ${user_jwt}`) + .set("Accept", "application/json") + .end(function (err, res) { + res.status.should.equal(200); + should.exist(res.header["content-type"]); + should.exist(res.header["server"]); + res.header["content-type"].should.match( + new RegExp("json", "g") + ); + res.header["server"].should.match(new RegExp("postgrest", "g")); + console.log(res.body); + should.exist(res.body); + if (subtest.url == "/rpc/telegram_otp_fn") { + console.log(res.body.otp_code); + otp = res.body.otp_code; + } else { + console.log(res.text); + res.text.should.match("true"); + otp = null; + } + done(err); + }); + } catch (error) { + done(); + } + }); + }); + }); // telegram OTP endpoint + + describe("telegram session, anonymous", function () { + it("/rpc/telegram return jwt token", function (done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post("/rpc/telegram") + .send(test.telegram.payload) + .set("Accept", "application/json") + .set("Content-Type", "application/json") + .end(function (err, res) { + res.status.should.equal(200); + should.exist(res.header["content-type"]); + should.exist(res.header["server"]); + res.header["content-type"].should.match(new RegExp("json", "g")); + res.header["server"].should.match(new RegExp("postgrest", "g")); + should.exist(res.body.token); + user_jwt = res.body.token; + console.log(res.body.token); + done(err); + }); + }); + }); // anonymous JWT + + describe("Telegram endpoint, JWT user_role", function () { + let otp = null; + test.telegram_fn.forEach(function (subtest) { + it(`${subtest.url}`, function (done) { + try { + //console.log(`${subtest.url} ${subtest.res_body_length}`); + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .get(subtest.url) + .set("Authorization", `Bearer ${user_jwt}`) + .set("Accept", "application/json") + .end(function (err, res) { + res.status.should.equal(200); + should.exist(res.header["content-type"]); + should.exist(res.header["server"]); + res.header["content-type"].should.match( + new RegExp("json", "g") + ); + res.header["server"].should.match(new RegExp("postgrest", "g")); + console.log(res.body); + should.exist(res.body); + done(err); + }); + } catch (error) { + done(); + } + }); + }); + }); // Function endpoint + + /* + describe("Function others endpoint, JWT user_role", function(){ + + let otp = null; + test.others_fn.forEach(function (subtest) { + it(`${subtest.url}`, function(done) { + try { + //console.log(`${subtest.url} ${subtest.res_body_length}`); + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post(subtest.url) + .send(subtest.payload) + .set('Authorization', `Bearer ${user_jwt}`) + .set('Accept', 'application/json') + .end(function(err,res){ + res.status.should.equal(200); + should.exist(res.header['content-type']); + should.exist(res.header['server']); + res.header['content-type'].should.match(new RegExp('json','g')); + res.header['server'].should.match(new RegExp('postgrest','g')); + //console.log(res.body); + should.exist(res.body); + if (subtest.url == '/rpc/generate_otp_fn') { + otp = res.body.text(); + } + done(err); + }); + } + catch (error) { + done(); + } + }); + }); + }); // Function endpoint +*/ + +describe("Badges, user jwt", function () { + it("/rpc/settings_fn return user settings", function (done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .post("/rpc/settings_fn") + .set("Authorization", `Bearer ${user_jwt}`) + .set("Accept", "application/json") + .end(function (err, res) { + res.status.should.equal(200); + should.exist(res.header["content-type"]); + should.exist(res.header["server"]); + res.header["content-type"].should.match(new RegExp("json", "g")); + res.header["server"].should.match(new RegExp("postgrest", "g")); + console.log(res.body); + should.exist(res.body.settings); + should.exist(res.body.settings.preferences.badges) + let badges = res.body.settings.preferences.badges; + //console.log(Object.keys(badges)); + Object.keys(badges).length.should.be.aboveOrEqual(3); + (badges).should.have.properties('Helmsman', 'Wake Maker', 'Stormtrooper'); + done(err); + }); + }); +}); // user JWT + +describe("Function monitoring endpoint, JWT user_role", function () { + let otp = null; + test.monitoring.forEach(function (subtest) { + it(`${subtest.url}`, function (done) { + try { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .get(subtest.url) + .set("Authorization", `Bearer ${user_jwt}`) + .set("Accept", "application/json") + .end(function (err, res) { + res.status.should.equal(200); + should.exist(res.header["content-type"]); + should.exist(res.header["server"]); + res.header["content-type"].should.match( + new RegExp("json", "g") + ); + res.header["server"].should.match(new RegExp("postgrest", "g")); + //console.log(res.body); + should.exist(res.body); + //let monitoring = res.body; + //console.log(monitoring); + // minimum set for static monitoring page + // no value for humidity monitoring + //monitoring.length.should.be.aboveOrEqual(21); + done(err); + }); + } catch (error) { + done(); + } + }); + }); +}); // Monitoring endpoint + +describe("Event Logs, user jwt", function () { + it("/eventlogs_view endpoint, list process_queue, JWT user_role", function (done) { + // Reset agent so we do not save cookies + request = supertest.agent(test.cname); + request + .get("/eventlogs_view") + .set("Authorization", `Bearer ${user_jwt}`) + .set("Accept", "application/json") + .end(function (err, res) { + res.status.should.equal(200); + should.exist(res.header["content-type"]); + should.exist(res.header["server"]); + res.header["content-type"].should.match(new RegExp("json", "g")); + res.header["server"].should.match(new RegExp("postgrest", "g")); + //console.log(res.body); + should.exist(res.body); + let event = res.body; + //console.log(event); + // minimum events log for kapla & aava 13 + 4 email_otp = 17 + event.length.should.be.aboveOrEqual(13); + done(err); + }); + }); +}); // user JWT + + }); // OpenAPI description +}); // Users Array diff --git a/tests/metrics_sample_aava.json b/tests/metrics_sample_aava.json new file mode 100644 index 0000000..1267ae7 --- /dev/null +++ b/tests/metrics_sample_aava.json @@ -0,0 +1,567 @@ +{ +"metrics": [ + { + "time" : "2022-07-31T11:28:13.331Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7231605, + "longitude" : 24.7358807, + "speedoverground" : 7.1, + "courseovergroundtrue" : 188.9, + "windspeedapparent" : 13.9, + "anglespeedapparent" : 56.0, + "status" : "moored", + "metrics" : {"navigation.log": 17441210, "navigation.trip.log": 80099, "navigation.headingTrue": 3.3179, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 36.219, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.48, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 19.6, "electrical.batteries.1.voltage": 13.38, "navigation.gnss.antennaAltitude": 2.21, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 36.22, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 89, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 9, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:29:13.340Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7213961, + "longitude" : 24.7349507, + "speedoverground" : 6.5, + "courseovergroundtrue" : 197.4, + "windspeedapparent" : 15.4, + "anglespeedapparent" : 43.0, + "status" : "moored", + "metrics" : {"navigation.log": 17441395, "navigation.trip.log": 80284, "navigation.headingTrue": 3.4924, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 32.289, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.34, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 231, "electrical.batteries.1.voltage": 14.45, "navigation.gnss.antennaAltitude": -0.04, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 32.29, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 57, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 4, "network.n2k.ngt-1.130356.ch1.bandwidth": 3, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 11, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:30:28.338Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7190763, + "longitude" : 24.733775, + "speedoverground" : 7.1, + "courseovergroundtrue" : 194.4, + "windspeedapparent" : 16.3, + "anglespeedapparent" : 41.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441580, "navigation.trip.log": 80544, "navigation.headingTrue": 3.4226, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 23.808999999999997, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.61, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 231.5, "electrical.batteries.1.voltage": 13.02, "navigation.gnss.antennaAltitude": 2.06, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 23.81, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 73, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 1, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 1, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:31:28.348Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7173052, + "longitude" : 24.7325741, + "speedoverground" : 6.5, + "courseovergroundtrue" : 198.8, + "windspeedapparent" : 15.8, + "anglespeedapparent" : 41.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441766, "navigation.trip.log": 80747, "navigation.headingTrue": 3.5972, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 20.948999999999998, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.47, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 192.4, "electrical.batteries.1.voltage": 14.56, "navigation.gnss.antennaAltitude": 0.21, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 20.95, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 64, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:32:28.364Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7156422, + "longitude" : 24.731211599999998, + "speedoverground" : 6.4, + "courseovergroundtrue" : 203.3, + "windspeedapparent" : 13.7, + "anglespeedapparent" : 58.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442136, "navigation.trip.log": 80951, "navigation.headingTrue": 3.5361, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 17.529, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 2.93, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 105.2, "electrical.batteries.1.voltage": 14.55, "navigation.gnss.antennaAltitude": 2.49, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 17.53, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 2, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 43, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 4, "network.n2k.ngt-1.130356.ch1.bandwidth": 3, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 11, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:33:28.377Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7139966, + "longitude" : 24.7299656, + "speedoverground" : 6.5, + "courseovergroundtrue" : 200.4, + "windspeedapparent" : 15.6, + "anglespeedapparent" : 44.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442321, "navigation.trip.log": 81136, "navigation.headingTrue": 3.571, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 13.999, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.21, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 70.4, "electrical.batteries.1.voltage": 14.56, "navigation.gnss.antennaAltitude": 2.69, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 14, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 34, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:34:28.396Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7124464, + "longitude" : 24.728924, + "speedoverground" : 5.8, + "courseovergroundtrue" : 197.8, + "windspeedapparent" : 12.2, + "anglespeedapparent" : 31.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442506, "navigation.trip.log": 81321, "navigation.headingTrue": 3.5535, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 13.999, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.07, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 43.9, "electrical.batteries.1.voltage": 14.54, "navigation.gnss.antennaAltitude": 2.11, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 14, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 66, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:35:28.413Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7106379, + "longitude" : 24.728088, + "speedoverground" : 6.7, + "courseovergroundtrue" : 187.8, + "windspeedapparent" : 13.7, + "anglespeedapparent" : 42.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442692, "navigation.trip.log": 81507, "navigation.headingTrue": 3.4313, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 14.029, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.21, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 36.1, "electrical.batteries.1.voltage": 14.56, "navigation.gnss.antennaAltitude": 2.78, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 14.03, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 69, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:36:28.424Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7087125, + "longitude" : 24.7276837, + "speedoverground" : 7.1, + "courseovergroundtrue" : 185.4, + "windspeedapparent" : 13.5, + "anglespeedapparent" : 51.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442877, "navigation.trip.log": 81692, "navigation.headingTrue": 3.3004, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 22.689, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.34, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 25.2, "electrical.batteries.1.voltage": 14.55, "navigation.gnss.antennaAltitude": 3.24, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 22.69, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 2, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 45, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:37:28.444Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7245499, + "longitude" : 24.736394999999998, + "speedoverground" : 6.7, + "courseovergroundtrue" : 196.5, + "windspeedapparent" : 14.1, + "anglespeedapparent" : 42.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441025, "navigation.trip.log": 79951, "navigation.headingTrue": 3.475, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 71.039, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.34, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 16.4, "electrical.batteries.1.voltage": 14.54, "navigation.gnss.antennaAltitude": 2.32, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 71.04, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 64, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:38:28.483Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7227198, + "longitude" : 24.735699, + "speedoverground" : 6.4, + "courseovergroundtrue" : 186.4, + "windspeedapparent" : 13.9, + "anglespeedapparent" : 44.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441210, "navigation.trip.log": 80136, "navigation.headingTrue": 3.4401, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 33.169000000000004, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.21, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 172, "electrical.batteries.1.voltage": 13.35, "navigation.gnss.antennaAltitude": 2.11, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 33.17, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 32, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 5, "network.n2k.ngt-1.130356.ch1.bandwidth": 3, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 6, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 13, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 1, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 1, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:39:28.509Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7209298, + "longitude" : 24.73472, + "speedoverground" : 6.8, + "courseovergroundtrue" : 190.7, + "windspeedapparent" : 15.4, + "anglespeedapparent" : 38.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441395, "navigation.trip.log": 80340, "navigation.headingTrue": 3.4663, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 30.738999999999997, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.47, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 211.6, "electrical.batteries.1.voltage": 14.54, "navigation.gnss.antennaAltitude": 0.76, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 30.74, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 2, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 52, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 9, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:40:28.539Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7190763, + "longitude" : 24.733774999999998, + "speedoverground" : 7.1, + "courseovergroundtrue" : 194.4, + "windspeedapparent" : 16.3, + "anglespeedapparent" : 41.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441580, "navigation.trip.log": 80544, "navigation.headingTrue": 3.4226, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 23.808999999999997, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.61, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 231.5, "electrical.batteries.1.voltage": 13.02, "navigation.gnss.antennaAltitude": 2.06, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 23.81, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 73, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 1, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 1, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:41:28.561Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7173052, + "longitude" : 24.7325741, + "speedoverground" : 6.5, + "courseovergroundtrue" : 198.8, + "windspeedapparent" : 15.8, + "anglespeedapparent" : 41.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441766, "navigation.trip.log": 80747, "navigation.headingTrue": 3.5972, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 20.948999999999998, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.47, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 192.4, "electrical.batteries.1.voltage": 14.56, "navigation.gnss.antennaAltitude": 0.39, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 20.95, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 64, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:42:28.569Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7156422, + "longitude" : 24.7312116, + "speedoverground" : 6.4, + "courseovergroundtrue" : 203.3, + "windspeedapparent" : 13.7, + "anglespeedapparent" : 58.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442136, "navigation.trip.log": 80951, "navigation.headingTrue": 3.5361, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 17.529, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 2.93, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 107.6, "electrical.batteries.1.voltage": 14.55, "navigation.gnss.antennaAltitude": 2.49, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 17.53, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 2, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 43, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 4, "network.n2k.ngt-1.130356.ch1.bandwidth": 3, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 11, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:43:28.603Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7139966, + "longitude" : 24.7299656, + "speedoverground" : 6.4, + "courseovergroundtrue" : 200.4, + "windspeedapparent" : 15.6, + "anglespeedapparent" : 44.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442321, "navigation.trip.log": 81136, "navigation.headingTrue": 3.571, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 13.999, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.21, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 70.4, "electrical.batteries.1.voltage": 14.56, "navigation.gnss.antennaAltitude": 2.69, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 14, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 34, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:44:28.629Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7124464, + "longitude" : 24.728924, + "speedoverground" : 5.7, + "courseovergroundtrue" : 197.6, + "windspeedapparent" : 12.2, + "anglespeedapparent" : 31.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442506, "navigation.trip.log": 81321, "navigation.headingTrue": 3.571, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 13.999, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.07, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 43.9, "electrical.batteries.1.voltage": 14.54, "navigation.gnss.antennaAltitude": 2.05, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 14, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 66, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:45:28.645Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7106379, + "longitude" : 24.728088, + "speedoverground" : 6.7, + "courseovergroundtrue" : 187.8, + "windspeedapparent" : 13.7, + "anglespeedapparent" : 42.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442692, "navigation.trip.log": 81507, "navigation.headingTrue": 3.4313, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 14.029, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.21, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 36.1, "electrical.batteries.1.voltage": 14.56, "navigation.gnss.antennaAltitude": 2.78, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 14.03, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 69, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:46:28.664Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7087125, + "longitude" : 24.7276837, + "speedoverground" : 7.0, + "courseovergroundtrue" : 185.4, + "windspeedapparent" : 13.5, + "anglespeedapparent" : 51.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442877, "navigation.trip.log": 81692, "navigation.headingTrue": 3.3004, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 22.689, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.34, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 25.2, "electrical.batteries.1.voltage": 14.55, "navigation.gnss.antennaAltitude": 3.24, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 22.69, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 2, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 45, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:47:28.696Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7245499, + "longitude" : 24.736394999999998, + "speedoverground" : 6.7, + "courseovergroundtrue" : 196.5, + "windspeedapparent" : 14.1, + "anglespeedapparent" : 42.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441025, "navigation.trip.log": 79951, "navigation.headingTrue": 3.475, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 71.039, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.34, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 16.4, "electrical.batteries.1.voltage": 14.54, "navigation.gnss.antennaAltitude": 2.32, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 71.04, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 64, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:48:28.712Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7226901, + "longitude" : 24.735683899999998, + "speedoverground" : 6.4, + "courseovergroundtrue" : 187.7, + "windspeedapparent" : 14.9, + "anglespeedapparent" : 44.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441210, "navigation.trip.log": 80136, "navigation.headingTrue": 3.4313, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 33.169000000000004, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.21, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 172, "electrical.batteries.1.voltage": 13.35, "navigation.gnss.antennaAltitude": 2.13, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 33.17, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 32, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 5, "network.n2k.ngt-1.130356.ch1.bandwidth": 3, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 6, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 13, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 1, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 1, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:49:28.726Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7209298, + "longitude" : 24.73472, + "speedoverground" : 6.8, + "courseovergroundtrue" : 190.7, + "windspeedapparent" : 15.4, + "anglespeedapparent" : 38.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441395, "navigation.trip.log": 80340, "navigation.headingTrue": 3.4663, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 30.738999999999997, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.47, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 211.6, "electrical.batteries.1.voltage": 14.54, "navigation.gnss.antennaAltitude": 0.76, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 30.74, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 2, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 52, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 9, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:50:28.743Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7190454, + "longitude" : 24.7337548, + "speedoverground" : 7.0, + "courseovergroundtrue" : 194.4, + "windspeedapparent" : 16.3, + "anglespeedapparent" : 41.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441580, "navigation.trip.log": 80544, "navigation.headingTrue": 3.4226, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 23.808999999999997, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.61, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 231.5, "electrical.batteries.1.voltage": 13.02, "navigation.gnss.antennaAltitude": 2.06, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 23.81, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 73, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 1, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 1, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:51:28.762Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7172775, + "longitude" : 24.7325491, + "speedoverground" : 6.5, + "courseovergroundtrue" : 198.3, + "windspeedapparent" : 13.9, + "anglespeedapparent" : 41.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441766, "navigation.trip.log": 80747, "navigation.headingTrue": 3.5797, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 20.948999999999998, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.47, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 192.4, "electrical.batteries.1.voltage": 14.56, "navigation.gnss.antennaAltitude": 0.39, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 20.95, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 64, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:52:28.783Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7156422, + "longitude" : 24.7312116, + "speedoverground" : 6.4, + "courseovergroundtrue" : 203.3, + "windspeedapparent" : 15.6, + "anglespeedapparent" : 58.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442136, "navigation.trip.log": 80951, "navigation.headingTrue": 3.5361, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 17.529, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 2.93, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 107.6, "electrical.batteries.1.voltage": 14.55, "navigation.gnss.antennaAltitude": 2.49, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 17.53, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 2, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 43, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 4, "network.n2k.ngt-1.130356.ch1.bandwidth": 3, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 11, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:53:28.800Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7139716, + "longitude" : 24.7299463, + "speedoverground" : 6.4, + "courseovergroundtrue" : 200.4, + "windspeedapparent" : 14.1, + "anglespeedapparent" : 44.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442321, "navigation.trip.log": 81136, "navigation.headingTrue": 3.571, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 13.999, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.21, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 70.4, "electrical.batteries.1.voltage": 14.56, "navigation.gnss.antennaAltitude": 2.69, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 14, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 34, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:54:28.819Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7124464, + "longitude" : 24.728924, + "speedoverground" : 5.7, + "courseovergroundtrue" : 197.6, + "windspeedapparent" : 15.9, + "anglespeedapparent" : 31.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442506, "navigation.trip.log": 81321, "navigation.headingTrue": 3.571, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 13.999, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.07, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 43.9, "electrical.batteries.1.voltage": 14.54, "navigation.gnss.antennaAltitude": 2.05, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 14, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 66, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:55:28.837Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7106379, + "longitude" : 24.728088, + "speedoverground" : 6.7, + "courseovergroundtrue" : 187.8, + "windspeedapparent" : 16.9, + "anglespeedapparent" : 42.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442692, "navigation.trip.log": 81507, "navigation.headingTrue": 3.4313, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 14.029, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.21, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 36.1, "electrical.batteries.1.voltage": 14.56, "navigation.gnss.antennaAltitude": 2.74, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 14.03, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 69, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:56:28.855Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7086808, + "longitude" : 24.7276789, + "speedoverground" : 7.0, + "courseovergroundtrue" : 185.4, + "windspeedapparent" : 13.5, + "anglespeedapparent" : 51.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442877, "navigation.trip.log": 81692, "navigation.headingTrue": 3.3004, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 22.689, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.34, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 25.2, "electrical.batteries.1.voltage": 14.55, "navigation.gnss.antennaAltitude": 3.24, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 22.69, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 2, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 45, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:57:28.876Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7245198, + "longitude" : 24.7363702, + "speedoverground" : 6.7, + "courseovergroundtrue" : 196.5, + "windspeedapparent" : 14.1, + "anglespeedapparent" : 42.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441025, "navigation.trip.log": 79951, "navigation.headingTrue": 3.475, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 71.039, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.34, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 16.4, "electrical.batteries.1.voltage": 14.54, "navigation.gnss.antennaAltitude": 2.32, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 71.04, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 64, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:58:28.899Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7226901, + "longitude" : 24.735683899999998, + "speedoverground" : 6.4, + "courseovergroundtrue" : 187.7, + "windspeedapparent" : 14.9, + "anglespeedapparent" : 44.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441210, "navigation.trip.log": 80136, "navigation.headingTrue": 3.4313, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 33.169000000000004, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.21, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 172, "electrical.batteries.1.voltage": 13.35, "navigation.gnss.antennaAltitude": 2.13, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 33.17, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 32, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 5, "network.n2k.ngt-1.130356.ch1.bandwidth": 3, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 6, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 13, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 1, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 1, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T11:59:28.928Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7208986, + "longitude" : 24.734705599999998, + "speedoverground" : 6.8, + "courseovergroundtrue" : 190.7, + "windspeedapparent" : 15.4, + "anglespeedapparent" : 38.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441395, "navigation.trip.log": 80358, "navigation.headingTrue": 3.5099, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 30.738999999999997, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.47, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 211.6, "electrical.batteries.1.voltage": 14.54, "navigation.gnss.antennaAltitude": 0.78, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 30.74, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 2, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 52, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 9, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T12:00:28.941Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7190454, + "longitude" : 24.7337548, + "speedoverground" : 7.0, + "courseovergroundtrue" : 194.4, + "windspeedapparent" : 17.0, + "anglespeedapparent" : 41.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441580, "navigation.trip.log": 80544, "navigation.headingTrue": 3.4226, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 23.808999999999997, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.61, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 231.5, "electrical.batteries.1.voltage": 13.02, "navigation.gnss.antennaAltitude": 2.06, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 23.81, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 73, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 1, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 1, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T12:01:28.966Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7172775, + "longitude" : 24.7325491, + "speedoverground" : 6.5, + "courseovergroundtrue" : 198.3, + "windspeedapparent" : 15.1, + "anglespeedapparent" : 41.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441766, "navigation.trip.log": 80747, "navigation.headingTrue": 3.5797, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 20.948999999999998, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.47, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 192.4, "electrical.batteries.1.voltage": 14.56, "navigation.gnss.antennaAltitude": 0.39, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 20.95, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 64, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T12:02:28.982Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7156162, + "longitude" : 24.731190599999998, + "speedoverground" : 6.4, + "courseovergroundtrue" : 203.1, + "windspeedapparent" : 15.6, + "anglespeedapparent" : 58.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442136, "navigation.trip.log": 80951, "navigation.headingTrue": 3.5273, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 17.529, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 2.93, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 107.6, "electrical.batteries.1.voltage": 14.55, "navigation.gnss.antennaAltitude": 2.6, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 17.53, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 2, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 43, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 4, "network.n2k.ngt-1.130356.ch1.bandwidth": 3, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 11, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T12:03:28.988Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7139716, + "longitude" : 24.7299463, + "speedoverground" : 6.4, + "courseovergroundtrue" : 200.4, + "windspeedapparent" : 14.1, + "anglespeedapparent" : 44.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442321, "navigation.trip.log": 81136, "navigation.headingTrue": 3.571, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 13.999, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.07, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 70.4, "electrical.batteries.1.voltage": 14.56, "navigation.gnss.antennaAltitude": 2.69, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 14, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 34, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T12:04:29.008Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7124174, + "longitude" : 24.7289112, + "speedoverground" : 5.7, + "courseovergroundtrue" : 197.6, + "windspeedapparent" : 15.9, + "anglespeedapparent" : 31.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442506, "navigation.trip.log": 81321, "navigation.headingTrue": 3.571, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 13.749, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.07, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 43.9, "electrical.batteries.1.voltage": 14.54, "navigation.gnss.antennaAltitude": 2.05, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 13.75, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 66, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T12:05:29.025Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7106066, + "longitude" : 24.7280837, + "speedoverground" : 6.7, + "courseovergroundtrue" : 191.2, + "windspeedapparent" : 16.9, + "anglespeedapparent" : 42.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442692, "navigation.trip.log": 81507, "navigation.headingTrue": 3.4313, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 13.539, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.34, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 36.1, "electrical.batteries.1.voltage": 14.56, "navigation.gnss.antennaAltitude": 2.74, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 13.54, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 69, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T12:06:29.043Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7086808, + "longitude" : 24.7276789, + "speedoverground" : 7.0, + "courseovergroundtrue" : 185.4, + "windspeedapparent" : 14.4, + "anglespeedapparent" : 51.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442877, "navigation.trip.log": 81710, "navigation.headingTrue": 3.3004, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 22.689, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.34, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 25.2, "electrical.batteries.1.voltage": 14.55, "navigation.gnss.antennaAltitude": 3.24, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 22.69, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 2, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 45, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T12:07:29.071Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7245198, + "longitude" : 24.7363702, + "speedoverground" : 6.7, + "courseovergroundtrue" : 196.5, + "windspeedapparent" : 14.1, + "anglespeedapparent" : 42.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441025, "navigation.trip.log": 79951, "navigation.headingTrue": 3.475, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 71.039, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.19, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 16.4, "electrical.batteries.1.voltage": 14.54, "navigation.gnss.antennaAltitude": 2.51, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 71.04, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 64, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T12:08:29.081Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7226901, + "longitude" : 24.7356839, + "speedoverground" : 6.4, + "courseovergroundtrue" : 187.7, + "windspeedapparent" : 14.9, + "anglespeedapparent" : 44.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441210, "navigation.trip.log": 80155, "navigation.headingTrue": 3.4313, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 33.719, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.09, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 172, "electrical.batteries.1.voltage": 13.35, "navigation.gnss.antennaAltitude": 2.13, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 33.72, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 72, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 3, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 6, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 13, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 1, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 1, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T12:09:29.094Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7208986, + "longitude" : 24.734705599999998, + "speedoverground" : 6.8, + "courseovergroundtrue" : 191.3, + "windspeedapparent" : 15.4, + "anglespeedapparent" : 38.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441395, "navigation.trip.log": 80358, "navigation.headingTrue": 3.5099, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 31.529, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.47, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 211.6, "electrical.batteries.1.voltage": 14.54, "navigation.gnss.antennaAltitude": 0.78, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 31.53, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 2, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 49, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 9, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T12:10:29.108Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7190454, + "longitude" : 24.7337548, + "speedoverground" : 7.0, + "courseovergroundtrue" : 194.4, + "windspeedapparent" : 17.0, + "anglespeedapparent" : 41.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441580, "navigation.trip.log": 80544, "navigation.headingTrue": 3.4226, "navigation.gnss.satellites": 11, "environment.depth.belowKeel": 25.398999999999997, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.47, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 231.5, "electrical.batteries.1.voltage": 13.02, "navigation.gnss.antennaAltitude": 1.8, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 25.4, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 57, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 1, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 1, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T12:11:29.120Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7172775, + "longitude" : 24.7325491, + "speedoverground" : 6.5, + "courseovergroundtrue" : 198.3, + "windspeedapparent" : 15.1, + "anglespeedapparent" : 41.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17441766, "navigation.trip.log": 80747, "navigation.headingTrue": 3.5797, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 20.948999999999998, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.34, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 192.4, "electrical.batteries.1.voltage": 14.56, "navigation.gnss.antennaAltitude": 0.39, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 20.95, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 81, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 4, "network.n2k.ngt-1.130356.ch1.bandwidth": 3, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T12:12:29.137Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7156162, + "longitude" : 24.731190599999998, + "speedoverground" : 6.4, + "courseovergroundtrue" : 203.1, + "windspeedapparent" : 15.6, + "anglespeedapparent" : 58.0, + "status" : "sailing", + "metrics" : {"navigation.log": 17442136, "navigation.trip.log": 80951, "navigation.headingTrue": 3.5273, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 17.529, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.21, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 107.6, "electrical.batteries.1.voltage": 14.55, "navigation.gnss.antennaAltitude": 2.6, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 17.53, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 2, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 55, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 3, "network.n2k.ngt-1.130356.ch1.bandwidth": 2, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 11, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T12:13:29.150Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7139716, + "longitude" : 24.729946299999998, + "speedoverground" : 6.4, + "courseovergroundtrue" : 200.7, + "windspeedapparent" : 14.1, + "anglespeedapparent" : 44.0, + "status" : "anchored", + "metrics" : {"navigation.log": 17442321, "navigation.trip.log": 81136, "navigation.headingTrue": 3.571, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 14.209000000000001, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.07, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 70.4, "electrical.batteries.1.voltage": 14.56, "navigation.gnss.antennaAltitude": 2.38, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 14.21, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 70, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 4, "network.n2k.ngt-1.130356.ch1.bandwidth": 3, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 4, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + }, + { + "time" : "2022-07-31T12:14:29.168Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:987654321", + "latitude" : 59.7124174, + "longitude" : 24.7289112, + "speedoverground" : 5.7, + "courseovergroundtrue" : 197.6, + "windspeedapparent" : 15.9, + "anglespeedapparent" : 31.0, + "status" : "anchored", + "metrics" : {"navigation.log": 17442506, "navigation.trip.log": 81321, "navigation.headingTrue": 3.571, "navigation.gnss.satellites": 10, "environment.depth.belowKeel": 13.749, "navigation.magneticVariation": 0.1414, "navigation.speedThroughWater": 3.07, "environment.water.temperature": 313.15, "electrical.batteries.1.current": 43.9, "electrical.batteries.1.voltage": 14.54, "navigation.gnss.antennaAltitude": 2.05, "network.n2k.ngt-1.130356.errorID": 0, "network.n2k.ngt-1.130356.modelID": 14, "environment.depth.belowTransducer": 13.75, "electrical.batteries.1.temperature": 299.82, "environment.depth.transducerToKeel": -0.001, "navigation.gnss.horizontalDilution": 0.8, "network.n2k.ngt-1.130356.ch1.rxLoad": 4, "network.n2k.ngt-1.130356.ch1.txLoad": 0, "network.n2k.ngt-1.130356.ch2.rxLoad": 0, "network.n2k.ngt-1.130356.ch2.txLoad": 40, "network.n2k.ngt-1.130356.ch1.deleted": 0, "network.n2k.ngt-1.130356.ch2.deleted": 0, "network.n2k.ngt-1.130356.ch2Bandwidth": 4, "network.n2k.ngt-1.130356.ch1.bandwidth": 3, "network.n2k.ngt-1.130356.ch1.rxDropped": 0, "network.n2k.ngt-1.130356.ch2.rxDropped": 0, "network.n2k.ngt-1.130356.ch1.rxFiltered": 0, "network.n2k.ngt-1.130356.ch2.rxFiltered": 0, "network.n2k.ngt-1.130356.ch1.rxBandwidth": 5, "network.n2k.ngt-1.130356.ch1.txBandwidth": 0, "network.n2k.ngt-1.130356.ch2.rxBandwidth": 0, "network.n2k.ngt-1.130356.ch2.txBandwidth": 10, "network.n2k.ngt-1.130356.uniChannelCount": 2, "network.n2k.ngt-1.130356.indiChannelCount": 2, "network.n2k.ngt-1.130356.ch1.BufferLoading": 0, "network.n2k.ngt-1.130356.ch2.bufferLoading": 0, "network.n2k.ngt-1.130356.ch1.PointerLoading": 0, "network.n2k.ngt-1.130356.ch2.pointerLoading": 0} + } +]} diff --git a/tests/metrics_sample_kapla.json b/tests/metrics_sample_kapla.json new file mode 100644 index 0000000..7b61bc7 --- /dev/null +++ b/tests/metrics_sample_kapla.json @@ -0,0 +1,615 @@ +{ +"metrics": [ + { + "time" : "2022-07-30T14:52:28.000Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 60.077666666666666, + "longitude" : 23.530866666666668, + "speedoverground" : 0.0, + "courseovergroundtrue" : 207.5, + "windspeedapparent" : 14.8, + "anglespeedapparent" : -12.0, + "status" : "moored", + "metrics" : {"environment.wind.speedTrue": 4.44, "navigation.speedThroughWater": 3.0918118943701245, "performance.velocityMadeGood": 2.9323340761912995, "environment.wind.angleTrueWater": -0.3665191430024964, "environment.depth.belowTransducer": 13.1, "navigation.courseOverGroundMagnetic": 3.620685534088946, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T14:53:28.000Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 60.077666666666666, + "longitude" : 23.530866666666668, + "speedoverground" : 5.7, + "courseovergroundtrue" : 207.5, + "windspeedapparent" : 14.8, + "anglespeedapparent" : -12.0, + "status" : "moored", + "metrics" : {"environment.wind.speedTrue": 4.44, "navigation.speedThroughWater": 3.0918118943701245, "performance.velocityMadeGood": 2.9323340761912995, "environment.wind.angleTrueWater": -0.3665191430024964, "environment.depth.belowTransducer": 13.1, "navigation.courseOverGroundMagnetic": 3.620685534088946, "navigation.courseRhumbline.crossTrackError": 0, "propulsion.main.runTime":1776241 } + }, + { + "time" : "2022-07-30T14:54:28.016Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 60.07065, + "longitude" : 23.52355, + "speedoverground" : 5.6, + "courseovergroundtrue" : 211.5, + "windspeedapparent" : 14.8, + "anglespeedapparent" : -7.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 4.52, "navigation.speedThroughWater": 3.0815230028747167, "performance.velocityMadeGood": 2.9683451964252274, "environment.wind.angleTrueWater": -0.20943951028714078, "environment.depth.belowTransducer": 13.58, "navigation.courseOverGroundMagnetic": 3.6910223029603775, "navigation.courseRhumbline.crossTrackError": 0, "propulsion.main.runTime":1776241 } + }, + { + "time" : "2022-07-30T14:55:28.021Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 60.0637, + "longitude" : 23.515866666666668, + "speedoverground" : 5.6, + "courseovergroundtrue" : 211.3, + "windspeedapparent" : 15.7, + "anglespeedapparent" : 0.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 4.99, "navigation.speedThroughWater": 3.0558007741361966, "performance.velocityMadeGood": 3.00950076240686, "environment.wind.angleTrueWater": 0, "environment.depth.belowTransducer": 16.75, "navigation.courseOverGroundMagnetic": 3.6878807103060707, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T14:56:28.033Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 60.05671666666667, + "longitude" : 23.507866666666665, + "speedoverground" : 5.9, + "courseovergroundtrue" : 211.1, + "windspeedapparent" : 19.8, + "anglespeedapparent" : -2.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 4.22, "navigation.speedThroughWater": 3.1895563635765014, "performance.velocityMadeGood": 3.1586896890902767, "environment.wind.angleTrueWater": -0.0174532925239284, "environment.depth.belowTransducer": 18.96, "navigation.courseOverGroundMagnetic": 3.683866453025567, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T14:57:28.049Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 60.04915, + "longitude" : 23.500533333333333, + "speedoverground" : 6.1, + "courseovergroundtrue" : 212.0, + "windspeedapparent" : 14.2, + "anglespeedapparent" : -5.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 2.9, "navigation.speedThroughWater": 3.2204230380627252, "performance.velocityMadeGood": 3.168978580585685, "environment.wind.angleTrueWater": -0.19198621776321237, "environment.depth.belowTransducer": 21.41, "navigation.courseOverGroundMagnetic": 3.6997489492223417, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T14:58:28.064Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 60.04163333333333, + "longitude" : 23.493, + "speedoverground" : 6.0, + "courseovergroundtrue" : 204.9, + "windspeedapparent" : 12.0, + "anglespeedapparent" : -26.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 1.93, "navigation.speedThroughWater": 3.2615786040443577, "performance.velocityMadeGood": 0.8025335366418294, "environment.wind.angleTrueWater": -1.30899693929463, "environment.depth.belowTransducer": 21.01, "navigation.courseOverGroundMagnetic": 3.5753069735267324, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T14:59:28.095Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 60.03398333333333, + "longitude" : 23.485466666666667, + "speedoverground" : 6.1, + "courseovergroundtrue" : 206.0, + "windspeedapparent" : 9.5, + "anglespeedapparent" : -23.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 2.29, "navigation.speedThroughWater": 3.2461452668012454, "performance.velocityMadeGood": 1.6668004222561073, "environment.wind.angleTrueWater": -0.9948376738639186, "environment.depth.belowTransducer": 27.74, "navigation.courseOverGroundMagnetic": 3.595203727004011, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:00:28.106Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 60.02621666666667, + "longitude" : 23.479033333333334, + "speedoverground" : 6.0, + "courseovergroundtrue" : 201.6, + "windspeedapparent" : 10.5, + "anglespeedapparent" : -8.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 2.21, "navigation.speedThroughWater": 3.2410008210535413, "performance.velocityMadeGood": 3.0660896656316043, "environment.wind.angleTrueWater": -0.38397243552642474, "environment.depth.belowTransducer": 31.18, "navigation.courseOverGroundMagnetic": 3.518409239898726, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:01:28.107Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 60.01835, + "longitude" : 23.47295, + "speedoverground" : 6.0, + "courseovergroundtrue" : 197.4, + "windspeedapparent" : 10.9, + "anglespeedapparent" : -13.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 2.07, "navigation.speedThroughWater": 3.2461452668012454, "performance.velocityMadeGood": 2.896322955957371, "environment.wind.angleTrueWater": -0.40142572805035315, "environment.depth.belowTransducer": 34.89, "navigation.courseOverGroundMagnetic": 3.445454477148705, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:02:28.118Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 60.01045, + "longitude" : 23.46745, + "speedoverground" : 6.0, + "courseovergroundtrue" : 201.6, + "windspeedapparent" : 12.8, + "anglespeedapparent" : -26.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 3.98, "navigation.speedThroughWater": 3.2101341465673174, "performance.velocityMadeGood": 2.263556128989775, "environment.wind.angleTrueWater": -0.8203047486246348, "environment.depth.belowTransducer": 23.33, "navigation.courseOverGroundMagnetic": 3.518060174048247, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:03:28.140Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 60.00351666666667, + "longitude" : 23.461033333333333, + "speedoverground" : 5.1, + "courseovergroundtrue" : 210.5, + "windspeedapparent" : 12.0, + "anglespeedapparent" : -8.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 2.34, "navigation.speedThroughWater": 2.69054512604921, "performance.velocityMadeGood": 2.5207784163749767, "environment.wind.angleTrueWater": -0.3665191430024964, "environment.depth.belowTransducer": 18.21, "navigation.courseOverGroundMagnetic": 3.673219944585971, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:04:28.159Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.99755, + "longitude" : 23.45415, + "speedoverground" : 4.8, + "courseovergroundtrue" : 215.7, + "windspeedapparent" : 14.4, + "anglespeedapparent" : 6.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 4.86, "navigation.speedThroughWater": 2.5670784281043133, "performance.velocityMadeGood": 2.546500645113497, "environment.wind.angleTrueWater": 0.20943951028714078, "environment.depth.belowTransducer": 8.97, "navigation.courseOverGroundMagnetic": 3.765198796187073, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:05:28.169Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.99235, + "longitude" : 23.445683333333335, + "speedoverground" : 4.7, + "courseovergroundtrue" : 225.9, + "windspeedapparent" : 16.1, + "anglespeedapparent" : -5.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 6.075590428038464, "navigation.speedThroughWater": 2.5053450791318648, "performance.velocityMadeGood": 2.4641895131502323, "environment.wind.angleTrueWater": -0.12217304766749879, "environment.depth.belowTransducer": 7.03, "navigation.courseOverGroundMagnetic": 3.9426987811554253, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:06:28.196Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.989266666666666, + "longitude" : 23.438766666666666, + "speedoverground" : 1.9, + "courseovergroundtrue" : 223.2, + "windspeedapparent" : 16.7, + "anglespeedapparent" : 3.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 7.61, "navigation.speedThroughWater": 1.0134558122976947, "performance.velocityMadeGood": 0.9825891378114705, "environment.wind.angleTrueWater": 0.052359877571785195, "environment.depth.belowTransducer": 5.78, "navigation.courseOverGroundMagnetic": 3.89522582549034, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:07:28.205Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.98786666666667, + "longitude" : 23.435116666666666, + "speedoverground" : 1.9, + "courseovergroundtrue" : 229.6, + "windspeedapparent" : 18.1, + "anglespeedapparent" : -5.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 8.02, "navigation.speedThroughWater": 1.0186002580453988, "performance.velocityMadeGood": 0.9620113548206545, "environment.wind.angleTrueWater": -0.19198621776321237, "environment.depth.belowTransducer": 5.33, "navigation.courseOverGroundMagnetic": 4.007799562269678, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:08:28.218Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.986333333333334, + "longitude" : 23.43165, + "speedoverground" : 1.4, + "courseovergroundtrue" : 204.7, + "windspeedapparent" : 14.8, + "anglespeedapparent" : 4.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 6.3, "navigation.speedThroughWater": 0.745944633417085, "performance.velocityMadeGood": 0.7408001876693809, "environment.wind.angleTrueWater": 0, "environment.depth.belowTransducer": 5.49, "navigation.courseOverGroundMagnetic": 3.5732125784238606, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:09:28.241Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.984833333333334, + "longitude" : 23.4292, + "speedoverground" : 1.3, + "courseovergroundtrue" : 225.8, + "windspeedapparent" : 13.4, + "anglespeedapparent" : -20.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 4.48, "navigation.speedThroughWater": 0.745944633417085, "performance.velocityMadeGood": 0.7613779706601971, "environment.wind.angleTrueWater": -0.40142572805035315, "environment.depth.belowTransducer": 7.8, "navigation.courseOverGroundMagnetic": 3.9414770506787504, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:10:28.257Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.9862, + "longitude" : 23.432566666666666, + "speedoverground" : 3.3, + "courseovergroundtrue" : 41.1, + "windspeedapparent" : 16.1, + "anglespeedapparent" : 175.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 9.93, "navigation.speedThroughWater": 1.6205004105267706, "performance.velocityMadeGood": -1.6153559647790667, "environment.wind.angleTrueWater": 3.071779484211398, "environment.depth.belowTransducer": 5.41, "navigation.courseOverGroundMagnetic": 0.7171557898082179, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:11:43.288Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.98726666666666, + "longitude" : 23.43375, + "speedoverground" : 1.7, + "courseovergroundtrue" : 228.8, + "windspeedapparent" : 15.7, + "anglespeedapparent" : 8.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 6.37, "navigation.speedThroughWater": 0.9825891378114705, "performance.velocityMadeGood": 0.8694113313619818, "environment.wind.angleTrueWater": 0.15707963271535558, "environment.depth.belowTransducer": 5.31, "navigation.courseOverGroundMagnetic": 3.9934878624000567, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:12:58.309Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.98615, + "longitude" : 23.431566666666665, + "speedoverground" : 1.0, + "courseovergroundtrue" : 223.5, + "windspeedapparent" : 22.1, + "anglespeedapparent" : -6.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 7.63, "navigation.speedThroughWater": 0.6687779472015245, "performance.velocityMadeGood": 0.61218904397678, "environment.wind.angleTrueWater": -0.12217304766749879, "environment.depth.belowTransducer": 5.71, "navigation.courseOverGroundMagnetic": 3.9011599449484757, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:13:58.309Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.98615, + "longitude" : 23.431566666666665, + "speedoverground" : 1.0, + "courseovergroundtrue" : 223.5, + "windspeedapparent" : 22.1, + "anglespeedapparent" : -6.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 7.63, "navigation.speedThroughWater": 0.6687779472015245, "performance.velocityMadeGood": 0.61218904397678, "environment.wind.angleTrueWater": -0.12217304766749879, "environment.depth.belowTransducer": 5.71, "navigation.courseOverGroundMagnetic": 3.9011599449484757, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:14:28.343Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.98565, + "longitude" : 23.4307, + "speedoverground" : 1.2, + "courseovergroundtrue" : 224.5, + "windspeedapparent" : 19.4, + "anglespeedapparent" : 2.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 5.83, "navigation.speedThroughWater": 0.7613779706601971, "performance.velocityMadeGood": 0.7150779589308607, "environment.wind.angleTrueWater": -0.29670597290678274, "environment.depth.belowTransducer": 6.44, "navigation.courseOverGroundMagnetic": 3.9177405728462076, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:15:28.366Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.98468333333334, + "longitude" : 23.429383333333334, + "speedoverground" : 6.1, + "courseovergroundtrue" : 219.9, + "windspeedapparent" : 13.2, + "anglespeedapparent" : 3.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 3.35, "navigation.speedThroughWater": 3.4622119882048152, "performance.velocityMadeGood": 3.32845639876451, "environment.wind.angleTrueWater": 0, "environment.depth.belowTransducer": 8.07, "navigation.courseOverGroundMagnetic": 3.837455427236137, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:16:28.373Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.978233333333336, + "longitude" : 23.42106666666667, + "speedoverground" : 5.3, + "courseovergroundtrue" : 216.7, + "windspeedapparent" : 15.3, + "anglespeedapparent" : -8.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 4.93, "navigation.speedThroughWater": 2.9632007506775238, "performance.velocityMadeGood": 2.772856258012474, "environment.wind.angleTrueWater": -0.20943951028714078, "environment.depth.belowTransducer": 5.16, "navigation.courseOverGroundMagnetic": 3.7824775557857624, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:17:28.386Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.977716666666666, + "longitude" : 23.431, + "speedoverground" : 2.1, + "courseovergroundtrue" : 151.9, + "windspeedapparent" : 12.8, + "anglespeedapparent" : 32.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 2.74, "navigation.speedThroughWater": 1.1214891729994796, "performance.velocityMadeGood": 0.2520778416374977, "environment.wind.angleTrueWater": 1.5533430346296275, "environment.depth.belowTransducer": 3.49, "navigation.courseOverGroundMagnetic": 2.6518532660856806, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:18:28.434Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.97688333333333, + "longitude" : 23.432133333333333, + "speedoverground" : 0.0, + "courseovergroundtrue" : 179.3, + "windspeedapparent" : 11.1, + "anglespeedapparent" : 88.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 3.1895563635765014, "navigation.speedThroughWater": 0, "performance.velocityMadeGood": 0, "environment.wind.angleTrueWater": 1.8151424224885533, "environment.depth.belowTransducer": 1.67, "navigation.courseOverGroundMagnetic": 3.1290262836898832, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:19:28.467Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.97688333333333, + "longitude" : 23.4321, + "speedoverground" : 0.0, + "courseovergroundtrue" : 241.0, + "windspeedapparent" : 4.3, + "anglespeedapparent" : 74.0, + "status" : "moored", + "metrics" : {"environment.wind.speedTrue": 0, "navigation.speedThroughWater": 0, "performance.velocityMadeGood": 0, "environment.wind.angleTrueWater": 0.7853981635767779, "environment.depth.belowTransducer": 1.65, "navigation.courseOverGroundMagnetic": 4.206068965341505, "navigation.courseRhumbline.crossTrackError": 0, "propulsion.main.runTime":1776251} + }, + { + "time" : "2022-07-30T15:20:28.467Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.97688333333333, + "longitude" : 23.4321, + "speedoverground" : 0.0, + "courseovergroundtrue" : 241.0, + "windspeedapparent" : 4.3, + "anglespeedapparent" : 74.0, + "status" : "moored", + "metrics" : {"environment.wind.speedTrue": 0, "navigation.speedThroughWater": 0, "performance.velocityMadeGood": 0, "environment.wind.angleTrueWater": 0.7853981635767779, "environment.depth.belowTransducer": 1.65, "navigation.courseOverGroundMagnetic": 4.206068965341505, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:21:28.467Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.97688333333333, + "longitude" : 23.4321, + "speedoverground" : 0.0, + "courseovergroundtrue" : 241.0, + "windspeedapparent" : 4.3, + "anglespeedapparent" : 74.0, + "status" : "moored", + "metrics" : {"environment.wind.speedTrue": 0, "navigation.speedThroughWater": 0, "performance.velocityMadeGood": 0, "environment.wind.angleTrueWater": 0.7853981635767779, "environment.depth.belowTransducer": 1.65, "navigation.courseOverGroundMagnetic": 4.206068965341505, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:22:28.479Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.9781, + "longitude" : 23.425533333333334, + "speedoverground" : 5.0, + "courseovergroundtrue" : 258.3, + "windspeedapparent" : 9.1, + "anglespeedapparent" : 11.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 2.24, "navigation.speedThroughWater": 2.577367319599721, "performance.velocityMadeGood": 2.3561561524484476, "environment.wind.angleTrueWater": 0.41887902057428156, "environment.depth.belowTransducer": 5.05, "navigation.courseOverGroundMagnetic": 4.507661860154987, "navigation.courseRhumbline.crossTrackError": 0, "propulsion.main.runTime": 1776251} + }, + { + "time" : "2022-07-30T15:23:28.492Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.9738, + "longitude" : 23.41165, + "speedoverground" : 6.2, + "courseovergroundtrue" : 228.0, + "windspeedapparent" : 11.8, + "anglespeedapparent" : 12.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 2.92, "navigation.speedThroughWater": 3.194700809324205, "performance.velocityMadeGood": 2.5207784163749767, "environment.wind.angleTrueWater": 0.8028514561007063, "environment.depth.belowTransducer": 5.44, "navigation.courseOverGroundMagnetic": 3.9854593478390496, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:24:28.498Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.967, + "longitude" : 23.40138333333333, + "speedoverground" : 6.1, + "courseovergroundtrue" : 197.7, + "windspeedapparent" : 10.9, + "anglespeedapparent" : 16.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 2.99, "navigation.speedThroughWater": 3.215278592315021, "performance.velocityMadeGood": 1.2964003284214165, "environment.wind.angleTrueWater": 1.274090354246773, "environment.depth.belowTransducer": 5.74, "navigation.courseOverGroundMagnetic": 3.4508649978311228, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:25:28.540Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.958866666666665, + "longitude" : 23.395816666666665, + "speedoverground" : 6.2, + "courseovergroundtrue" : 203.9, + "windspeedapparent" : 10.5, + "anglespeedapparent" : 38.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 3.44, "navigation.speedThroughWater": 3.215278592315021, "performance.velocityMadeGood": 1.512467049824986, "environment.wind.angleTrueWater": 1.2566370617228446, "environment.depth.belowTransducer": 7.13, "navigation.courseOverGroundMagnetic": 3.5587263456290006, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:26:28.572Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.9508, + "longitude" : 23.390166666666666, + "speedoverground" : 6.2, + "courseovergroundtrue" : 200.6, + "windspeedapparent" : 12.0, + "anglespeedapparent" : 63.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 4.12, "navigation.speedThroughWater": 3.2461452668012454, "performance.velocityMadeGood": -1.3787114603846813, "environment.wind.angleTrueWater": 1.884955592584267, "environment.depth.belowTransducer": 8.6, "navigation.courseOverGroundMagnetic": 3.5004323485990794, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:27:28.599Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.94275, + "longitude" : 23.38365, + "speedoverground" : 6.3, + "courseovergroundtrue" : 206.9, + "windspeedapparent" : 7.8, + "anglespeedapparent" : 22.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 2.13, "navigation.speedThroughWater": 3.2255674838104293, "performance.velocityMadeGood": -1.1317780644948876, "environment.wind.angleTrueWater": 1.9373154701560522, "environment.depth.belowTransducer": 12.98, "navigation.courseOverGroundMagnetic": 3.6112607561260246, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:28:28.606Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.93578333333333, + "longitude" : 23.37245, + "speedoverground" : 6.5, + "courseovergroundtrue" : 227.5, + "windspeedapparent" : 7.6, + "anglespeedapparent" : -10.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 1.12, "navigation.speedThroughWater": 3.2307119295581335, "performance.velocityMadeGood": -2.896322955957371, "environment.wind.angleTrueWater": -2.7750735113046154, "environment.depth.belowTransducer": 11.7, "navigation.courseOverGroundMagnetic": 3.9704495162684714, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:29:28.619Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.93076666666666, + "longitude" : 23.3572, + "speedoverground" : 6.3, + "courseovergroundtrue" : 232.5, + "windspeedapparent" : 6.8, + "anglespeedapparent" : 19.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 0.92, "navigation.speedThroughWater": 3.2307119295581335, "performance.velocityMadeGood": -1.960033829875237, "environment.wind.angleTrueWater": 2.2165681505389068, "environment.depth.belowTransducer": 14.23, "navigation.courseOverGroundMagnetic": 4.05858864351431, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:30:28.637Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.925133333333335, + "longitude" : 23.3448, + "speedoverground" : 5.9, + "courseovergroundtrue" : 228.4, + "windspeedapparent" : 7.2, + "anglespeedapparent" : 13.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 0.82, "navigation.speedThroughWater": 3.2358563753058376, "performance.velocityMadeGood": -2.1246560938017662, "environment.wind.angleTrueWater": 2.373647783254262, "environment.depth.belowTransducer": 14.29, "navigation.courseOverGroundMagnetic": 3.986855611240964, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:31:28.668Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.918933333333335, + "longitude" : 23.33415, + "speedoverground" : 6.0, + "courseovergroundtrue" : 211.6, + "windspeedapparent" : 6.4, + "anglespeedapparent" : -15.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 0.86, "navigation.speedThroughWater": 3.2255674838104293, "performance.velocityMadeGood": -0.38068898533009854, "environment.wind.angleTrueWater": -1.7278759598689115, "environment.depth.belowTransducer": 18.1, "navigation.courseOverGroundMagnetic": 3.6927676322127705, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:32:28.735Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.9114, + "longitude" : 23.32743333333333, + "speedoverground" : 6.2, + "courseovergroundtrue" : 175.6, + "windspeedapparent" : 6.4, + "anglespeedapparent" : -8.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 0.36, "navigation.speedThroughWater": 3.199845255071909, "performance.velocityMadeGood": -0.3189556363576501, "environment.wind.angleTrueWater": -1.6057029122014126, "environment.depth.belowTransducer": 10.95, "navigation.courseOverGroundMagnetic": 3.064972700127066, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:33:28.757Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.90315, + "longitude" : 23.329966666666667, + "speedoverground" : 6.1, + "courseovergroundtrue" : 144.0, + "windspeedapparent" : 5.8, + "anglespeedapparent" : -3.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 0.24, "navigation.speedThroughWater": 3.2049897008196133, "performance.velocityMadeGood": -2.4847672961410483, "environment.wind.angleTrueWater": -2.3911010757781903, "environment.depth.belowTransducer": 13.92, "navigation.courseOverGroundMagnetic": 2.512575991744732, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:34:28.787Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.89735, + "longitude" : 23.3428, + "speedoverground" : 6.3, + "courseovergroundtrue" : 129.8, + "windspeedapparent" : 5.2, + "anglespeedapparent" : -2.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 1, "navigation.speedThroughWater": 3.2307119295581335, "performance.velocityMadeGood": -3.1895563635765014, "environment.wind.angleTrueWater": -2.932153144019971, "environment.depth.belowTransducer": 11.32, "navigation.courseOverGroundMagnetic": 2.265960968381624, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:35:28.798Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.88953333333333, + "longitude" : 23.3492, + "speedoverground" : 6.5, + "courseovergroundtrue" : 162.5, + "windspeedapparent" : 7.2, + "anglespeedapparent" : -7.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 0.95, "navigation.speedThroughWater": 3.199845255071909, "performance.velocityMadeGood": -3.050656328388492, "environment.wind.angleTrueWater": -2.844886681400329, "environment.depth.belowTransducer": 10.04, "navigation.courseOverGroundMagnetic": 2.8354619034374076, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:36:28.812Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.88126666666667, + "longitude" : 23.345833333333335, + "speedoverground" : 6.1, + "courseovergroundtrue" : 196.5, + "windspeedapparent" : 8.7, + "anglespeedapparent" : -15.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 0.87, "navigation.speedThroughWater": 3.199845255071909, "performance.velocityMadeGood": -1.1832225219719277, "environment.wind.angleTrueWater": -1.972222055203909, "environment.depth.belowTransducer": 22.3, "navigation.courseOverGroundMagnetic": 3.429921046802409, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:37:28.835Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.87278333333333, + "longitude" : 23.344066666666667, + "speedoverground" : 6.2, + "courseovergroundtrue" : 160.5, + "windspeedapparent" : 7.8, + "anglespeedapparent" : -5.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 0.57, "navigation.speedThroughWater": 3.174123026333389, "performance.velocityMadeGood": 2.870600727218851, "environment.wind.angleTrueWater": -0.261799387858926, "environment.depth.belowTransducer": 24.73, "navigation.courseOverGroundMagnetic": 2.8016025159409867, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:38:28.838Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.866616666666665, + "longitude" : 23.355716666666666, + "speedoverground" : 6.1, + "courseovergroundtrue" : 131.4, + "windspeedapparent" : 35.8, + "anglespeedapparent" : 9.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 0.51, "navigation.speedThroughWater": 3.2255674838104293, "performance.velocityMadeGood": -1.347844785898457, "environment.wind.angleTrueWater": 1.7453292523928399, "environment.depth.belowTransducer": 9.85, "navigation.courseOverGroundMagnetic": 2.292489973017995, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:39:28.867Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.86, + "longitude" : 23.365766666666666, + "speedoverground" : 5.8, + "courseovergroundtrue" : 122.0, + "windspeedapparent" : 37.2, + "anglespeedapparent" : 10.0, + "status" : "sailing", + "metrics" : {"environment.wind.speedTrue": 0.63, "navigation.speedThroughWater": 3.2255674838104293, "performance.velocityMadeGood": -2.242978345998959, "environment.wind.angleTrueWater": 2.3038346131585485, "environment.depth.belowTransducer": 17.73, "navigation.courseOverGroundMagnetic": 2.129127154994025, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:40:28.867Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.86, + "longitude" : 23.365766666666666, + "speedoverground" : 4.5, + "courseovergroundtrue" : 122.0, + "windspeedapparent" : 7.2, + "anglespeedapparent" : 10.0, + "status" : "anchored", + "metrics" : {"environment.wind.speedTrue": 0.63, "navigation.speedThroughWater": 3.2255674838104293, "performance.velocityMadeGood": -2.242978345998959, "environment.wind.angleTrueWater": 2.3038346131585485, "environment.depth.belowTransducer": 17.73, "navigation.courseOverGroundMagnetic": 2.129127154994025, "navigation.courseRhumbline.crossTrackError": 0, "propulsion.main.runTime":1776262} + }, + { + "time" : "2022-07-30T15:41:28.867Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.86, + "longitude" : 23.365766666666666, + "speedoverground" : 0.0, + "courseovergroundtrue" : 122.0, + "windspeedapparent" : 7.2, + "anglespeedapparent" : 10.0, + "status" : "anchored", + "metrics" : {"environment.wind.speedTrue": 0.63, "navigation.speedThroughWater": 3.2255674838104293, "performance.velocityMadeGood": -2.242978345998959, "environment.wind.angleTrueWater": 2.3038346131585485, "environment.depth.belowTransducer": 17.73, "navigation.courseOverGroundMagnetic": 2.129127154994025, "navigation.courseRhumbline.crossTrackError": 0} + }, + { + "time" : "2022-07-30T15:41:28.867Z", + "client_id" : "vessels.urn:mrn:imo:mmsi:123456789", + "latitude" : 59.86, + "longitude" : 23.365766666666666, + "speedoverground" : 0.0, + "courseovergroundtrue" : 122.0, + "windspeedapparent" : 7.2, + "anglespeedapparent" : 10.0, + "status" : "anchored", + "metrics" : {"environment.wind.speedTrue": 0.63, "navigation.speedThroughWater": 3.2255674838104293, "performance.velocityMadeGood": -2.242978345998959, "environment.wind.angleTrueWater": 2.3038346131585485, "environment.depth.belowTransducer": 17.73, "navigation.courseOverGroundMagnetic": 2.129127154994025, "navigation.courseRhumbline.crossTrackError": 0} + } +]} diff --git a/tests/metrics_sample_simulator.json b/tests/metrics_sample_simulator.json new file mode 100644 index 0000000..8ac8b53 --- /dev/null +++ b/tests/metrics_sample_simulator.json @@ -0,0 +1,879 @@ +{ + "metrics": [ + { + "time" : "2022-12-13 20:39:04.562", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.3786471, + "longitude" : 2.277667383333333, + "speedoverground" : 4.1, + "courseovergroundtrue" : 17.4, + "windspeedapparent" : 8.1, + "anglespeedapparent" : -32.3, + "status" : "moored", + "metrics" : {"navigation.headingTrue": 0.3036872899163541, "environment.wind.speedTrue": 1.6, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.3036872899163541, "environment.depth.belowKeel": 9.3, "navigation.speedThroughWater": 2.109222756558654, "environment.water.temperature": 280.75, "environment.depth.belowSurface": 9.3, "environment.wind.directionTrue": 5.223770452411769, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 0, "propulsion.engine_2.revolutions": 0, "environment.depth.belowTransducer": 9.3, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 5.223770452411769, "navigation.gnss.horizontalDilution": 1.8, "navigation.courseOverGroundMagnetic": 0.3036872899163541, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670963929} + }, + { + "time" : "2022-12-13 20:40:04.568", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.37983186666666, + "longitude" : 2.2781615333333334, + "speedoverground" : 4.1, + "courseovergroundtrue" : 16.5, + "windspeedapparent" : 6.0, + "anglespeedapparent" : -25.2, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.28797932664481857, "environment.wind.speedTrue": 1.5, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.28797932664481857, "environment.depth.belowKeel": 11.8, "navigation.speedThroughWater": 2.109222756558654, "environment.water.temperature": 280.95, "environment.depth.belowSurface": 11.8, "environment.wind.directionTrue": 5.483824511018303, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 0, "propulsion.engine_2.revolutions": 0, "environment.depth.belowTransducer": 11.8, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 5.483824511018303, "navigation.gnss.horizontalDilution": 1.7, "navigation.courseOverGroundMagnetic": 0.28797932664481857, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670963985} + }, + { + "time" : "2022-12-13 20:41:04.592", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.380872266666664, + "longitude" : 2.2785093333333335, + "speedoverground" : 4.1, + "courseovergroundtrue" : 13.6, + "windspeedapparent" : 7.2, + "anglespeedapparent" : -34.7, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.2373647783254262, "environment.wind.speedTrue": 1.5, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.2373647783254262, "environment.depth.belowKeel": 10.7, "navigation.speedThroughWater": 2.109222756558654, "environment.water.temperature": 281.15, "environment.depth.belowSurface": 10.7, "environment.wind.directionTrue": 4.974188369319593, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 0, "propulsion.engine_2.revolutions": 0, "environment.depth.belowTransducer": 10.7, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 4.974188369319593, "navigation.gnss.horizontalDilution": 1.3, "navigation.courseOverGroundMagnetic": 0.2373647783254262, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670964045} + }, + { + "time" : "2022-12-13 20:42:04.609", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.38208281666667, + "longitude" : 2.2788272, + "speedoverground" : 4.2, + "courseovergroundtrue" : 10.7, + "windspeedapparent" : 10.0, + "anglespeedapparent" : -39.2, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.18675023000603386, "environment.wind.speedTrue": 2.6, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.18675023000603386, "environment.depth.belowKeel": 12.4, "navigation.speedThroughWater": 2.1606672140356946, "environment.water.temperature": 281.15, "environment.depth.belowSurface": 12.4, "environment.wind.directionTrue": 5.223770452411769, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10, "propulsion.engine_2.revolutions": 10, "environment.depth.belowTransducer": 12.4, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 5.223770452411769, "navigation.gnss.horizontalDilution": 1.6, "navigation.courseOverGroundMagnetic": 0.18675023000603386, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670964109} + }, + { + "time" : "2022-12-13 20:43:04.645", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.383208116666665, + "longitude" : 2.2791273833333334, + "speedoverground" : 4.1, + "courseovergroundtrue" : 11.2, + "windspeedapparent" : 6.5, + "anglespeedapparent" : -10.8, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.19547687626799803, "environment.wind.speedTrue": 1.2, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.19547687626799803, "environment.depth.belowKeel": 14.4, "navigation.speedThroughWater": 2.109222756558654, "environment.water.temperature": 280.95, "environment.depth.belowSurface": 14.4, "environment.wind.directionTrue": 5.967280713931119, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.403333333333334, "propulsion.engine_2.revolutions": 10.2, "environment.depth.belowTransducer": 14.4, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 5.967280713931119, "navigation.gnss.horizontalDilution": 1.7, "navigation.courseOverGroundMagnetic": 0.19547687626799803, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670964164} + }, + { + "time" : "2022-12-13 20:44:04.683", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.38424145, + "longitude" : 2.27946345, + "speedoverground" : 4.2, + "courseovergroundtrue" : 13.6, + "windspeedapparent" : 7.0, + "anglespeedapparent" : -12.7, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.2373647783254262, "environment.wind.speedTrue": 1.5, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.2373647783254262, "environment.depth.belowKeel": 11.8, "navigation.speedThroughWater": 2.1606672140356946, "environment.water.temperature": 280.95, "environment.depth.belowSurface": 11.8, "environment.wind.directionTrue": 5.967280713931119, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.403333333333334, "propulsion.engine_2.revolutions": 10, "environment.depth.belowTransducer": 11.8, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 5.967280713931119, "navigation.gnss.horizontalDilution": 1.3, "navigation.courseOverGroundMagnetic": 0.2373647783254262, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670964225} + }, + { + "time" : "2022-12-13 20:45:04.722", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.385386716666666, + "longitude" : 2.2798840166666667, + "speedoverground" : 4.2, + "courseovergroundtrue" : 15.8, + "windspeedapparent" : 5.2, + "anglespeedapparent" : -34.4, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.2757620218780687, "environment.wind.speedTrue": 1.2, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.2757620218780687, "environment.depth.belowKeel": 15.1, "navigation.speedThroughWater": 2.1606672140356946, "environment.water.temperature": 280.75, "environment.depth.belowSurface": 15.1, "environment.wind.directionTrue": 4.241150083314601, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.2, "propulsion.engine_2.revolutions": 11.04, "environment.depth.belowTransducer": 15.1, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 4.241150083314601, "navigation.gnss.horizontalDilution": 1.2, "navigation.courseOverGroundMagnetic": 0.2757620218780687, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670964290} + }, + { + "time" : "2022-12-13 20:46:04.743", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.38658911666667, + "longitude" : 2.2802688166666667, + "speedoverground" : 4.6, + "courseovergroundtrue" : 13.6, + "windspeedapparent" : 2.8, + "anglespeedapparent" : 166.2, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.2373647783254262, "environment.wind.speedTrue": 3.1, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.2373647783254262, "environment.depth.belowKeel": 10.7, "navigation.speedThroughWater": 2.3664450439438554, "environment.water.temperature": 280.54999999999995, "environment.depth.belowSurface": 10.7, "environment.wind.directionTrue": 3.323106896555967, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.2, "propulsion.engine_2.revolutions": 10.403333333333334, "environment.depth.belowTransducer": 10.7, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 3.323106896555967, "navigation.gnss.horizontalDilution": 1.5, "navigation.courseOverGroundMagnetic": 0.2373647783254262, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670964355} + }, + { + "time" : "2022-12-13 20:47:04.759", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.387908966666664, + "longitude" : 2.2806784166666665, + "speedoverground" : 4.6, + "courseovergroundtrue" : 13.6, + "windspeedapparent" : 8.2, + "anglespeedapparent" : 138.2, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.2373647783254262, "environment.wind.speedTrue": 4.4, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.2373647783254262, "environment.depth.belowKeel": 9.7, "navigation.speedThroughWater": 2.3664450439438554, "environment.water.temperature": 280.25, "environment.depth.belowSurface": 9.7, "environment.wind.directionTrue": 3.0141836188824342, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.04, "propulsion.engine_2.revolutions": 10.403333333333334, "environment.depth.belowTransducer": 9.7, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 3.0141836188824342, "navigation.gnss.horizontalDilution": 1.5, "navigation.courseOverGroundMagnetic": 0.2373647783254262, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670964414} + }, + { + "time" : "2022-12-13 20:48:04.770", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.389180233333335, + "longitude" : 2.28109, + "speedoverground" : 4.7, + "courseovergroundtrue" : 15.0, + "windspeedapparent" : 3.6, + "anglespeedapparent" : 60.8, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.261799387858926, "environment.wind.speedTrue": 2.1, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.261799387858926, "environment.depth.belowKeel": 8.8, "navigation.speedThroughWater": 2.417889501420896, "environment.water.temperature": 279.84999999999997, "environment.depth.belowSurface": 8.8, "environment.wind.directionTrue": 2.733185609247187, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.2, "propulsion.engine_2.revolutions": 10.2, "environment.depth.belowTransducer": 8.8, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 2.733185609247187, "navigation.gnss.horizontalDilution": 1.7, "navigation.courseOverGroundMagnetic": 0.261799387858926, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670964474} + }, + { + "time" : "2022-12-13 20:49:04.782", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.39048306666667, + "longitude" : 2.28150255, + "speedoverground" : 4.8, + "courseovergroundtrue" : 12.3, + "windspeedapparent" : 5.2, + "anglespeedapparent" : 27.3, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.21467549804431932, "environment.wind.speedTrue": 1.2, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.21467549804431932, "environment.depth.belowKeel": 7.3, "navigation.speedThroughWater": 2.4693339588979364, "environment.water.temperature": 280.04999999999995, "environment.depth.belowSurface": 7.3, "environment.wind.directionTrue": 1.8500490075364102, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.486666666666668, "propulsion.engine_2.revolutions": 10.611666666666668, "environment.depth.belowTransducer": 7.3, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 1.8500490075364102, "navigation.gnss.horizontalDilution": 2, "navigation.courseOverGroundMagnetic": 0.21467549804431932, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670964534} + }, + { + "time" : "2022-12-13 20:50:04.811", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.3917979, + "longitude" : 2.28186645, + "speedoverground" : 4.8, + "courseovergroundtrue" : 10.2, + "windspeedapparent" : 8.3, + "anglespeedapparent" : 35.3, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.17802358374406965, "environment.wind.speedTrue": 2.6, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.17802358374406965, "environment.depth.belowKeel": 4.9, "navigation.speedThroughWater": 2.4693339588979364, "environment.water.temperature": 280.54999999999995, "environment.depth.belowSurface": 4.9, "environment.wind.directionTrue": 1.380555438642736, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.04, "propulsion.engine_2.revolutions": 10, "environment.depth.belowTransducer": 4.9, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 1.380555438642736, "navigation.gnss.horizontalDilution": 2.3, "navigation.courseOverGroundMagnetic": 0.17802358374406965, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670964595} + }, + { + "time" : "2022-12-13 20:51:04.862", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.39308273333333, + "longitude" : 2.2821629833333335, + "speedoverground" : 5.0, + "courseovergroundtrue" : 10.2, + "windspeedapparent" : 8.6, + "anglespeedapparent" : 34.5, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.17802358374406965, "environment.wind.speedTrue": 2.6, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.17802358374406965, "environment.depth.belowKeel": 3.7, "navigation.speedThroughWater": 2.572222873852017, "environment.water.temperature": 280.65, "environment.depth.belowSurface": 3.7, "environment.wind.directionTrue": 1.380555438642736, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.486666666666668, "propulsion.engine_2.revolutions": 10.2, "environment.depth.belowTransducer": 3.7, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 1.380555438642736, "navigation.gnss.horizontalDilution": 2.3, "navigation.courseOverGroundMagnetic": 0.17802358374406965, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670964654} + }, + { + "time" : "2022-12-13 20:52:04.904", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.394408983333335, + "longitude" : 2.2825271833333334, + "speedoverground" : 4.8, + "courseovergroundtrue" : 11.2, + "windspeedapparent" : 9.5, + "anglespeedapparent" : 46.9, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.19547687626799803, "environment.wind.speedTrue": 3.7, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.19547687626799803, "environment.depth.belowKeel": 4.5, "navigation.speedThroughWater": 2.4693339588979364, "environment.water.temperature": 280.34999999999997, "environment.depth.belowSurface": 4.5, "environment.wind.directionTrue": 1.5219271080865564, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.611666666666668, "propulsion.engine_2.revolutions": 10.403333333333334, "environment.depth.belowTransducer": 4.5, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 1.5219271080865564, "navigation.gnss.horizontalDilution": 2.3, "navigation.courseOverGroundMagnetic": 0.19547687626799803, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670964714} + }, + { + "time" : "2022-12-13 20:53:04.922", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.39573106666667, + "longitude" : 2.2829267166666667, + "speedoverground" : 4.9, + "courseovergroundtrue" : 12.3, + "windspeedapparent" : 10.2, + "anglespeedapparent" : 42.4, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.21467549804431932, "environment.wind.speedTrue": 2.6, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.21467549804431932, "environment.depth.belowKeel": 4.5, "navigation.speedThroughWater": 2.5207784163749767, "environment.water.temperature": 280.65, "environment.depth.belowSurface": 4.5, "environment.wind.directionTrue": 1.679006740801912, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.04, "propulsion.engine_2.revolutions": 10, "environment.depth.belowTransducer": 4.5, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 1.679006740801912, "navigation.gnss.horizontalDilution": 3.4, "navigation.courseOverGroundMagnetic": 0.21467549804431932, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670964775} + }, + { + "time" : "2022-12-13 20:54:04.947", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.39700681666667, + "longitude" : 2.2833958666666665, + "speedoverground" : 4.9, + "courseovergroundtrue" : 16.5, + "windspeedapparent" : 8.0, + "anglespeedapparent" : 35.7, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.28797932664481857, "environment.wind.speedTrue": 2.6, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.28797932664481857, "environment.depth.belowKeel": 4.9, "navigation.speedThroughWater": 2.5207784163749767, "environment.water.temperature": 280.65, "environment.depth.belowSurface": 4.9, "environment.wind.directionTrue": 1.5219271080865564, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.611666666666668, "propulsion.engine_2.revolutions": 10, "environment.depth.belowTransducer": 4.9, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 1.5219271080865564, "navigation.gnss.horizontalDilution": 4.4, "navigation.courseOverGroundMagnetic": 0.28797932664481857, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670964835} + }, + { + "time" : "2022-12-13 20:55:04.978", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.39837505, + "longitude" : 2.283934583333333, + "speedoverground" : 4.9, + "courseovergroundtrue" : 16.5, + "windspeedapparent" : 9.4, + "anglespeedapparent" : 27.9, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.28797932664481857, "environment.wind.speedTrue": 2.6, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.28797932664481857, "environment.depth.belowKeel": 6, "navigation.speedThroughWater": 2.5207784163749767, "environment.water.temperature": 280.65, "environment.depth.belowSurface": 6, "environment.wind.directionTrue": 1.253146403218059, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.611666666666668, "propulsion.engine_2.revolutions": 10.2, "environment.depth.belowTransducer": 6, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 1.253146403218059, "navigation.gnss.horizontalDilution": 4.7, "navigation.courseOverGroundMagnetic": 0.28797932664481857, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670964895} + }, + { + "time" : "2022-12-13 20:56:04.996", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.39972915, + "longitude" : 2.2844581333333336, + "speedoverground" : 5.2, + "courseovergroundtrue" : 16.5, + "windspeedapparent" : 10.3, + "anglespeedapparent" : 23.8, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.28797932664481857, "environment.wind.speedTrue": 2.6, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.28797932664481857, "environment.depth.belowKeel": 5.4, "navigation.speedThroughWater": 2.675111788806098, "environment.water.temperature": 280.84999999999997, "environment.depth.belowSurface": 5.4, "environment.wind.directionTrue": 1.1362093433077387, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.486666666666668, "propulsion.engine_2.revolutions": 10.2, "environment.depth.belowTransducer": 5.4, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 1.1362093433077387, "navigation.gnss.horizontalDilution": 3.8, "navigation.courseOverGroundMagnetic": 0.28797932664481857, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670964954} + }, + { + "time" : "2022-12-13 20:57:05.017", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.401043683333334, + "longitude" : 2.284932, + "speedoverground" : 5.3, + "courseovergroundtrue" : 15.0, + "windspeedapparent" : 14.3, + "anglespeedapparent" : 33.6, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.261799387858926, "environment.wind.speedTrue": 5.3, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.261799387858926, "environment.depth.belowKeel": 4.9, "navigation.speedThroughWater": 2.726556246283138, "environment.water.temperature": 280.65, "environment.depth.belowSurface": 4.9, "environment.wind.directionTrue": 1.1362093433077387, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.611666666666668, "propulsion.engine_2.revolutions": 10.2, "environment.depth.belowTransducer": 4.9, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 1.1362093433077387, "navigation.gnss.horizontalDilution": 3.8, "navigation.courseOverGroundMagnetic": 0.261799387858926, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670965014} + }, + { + "time" : "2022-12-13 20:58:05.043", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.40248723333333, + "longitude" : 2.2853501666666665, + "speedoverground" : 5.2, + "courseovergroundtrue" : 11.2, + "windspeedapparent" : 25.2, + "anglespeedapparent" : 36.0, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.19547687626799803, "environment.wind.speedTrue": 7.6, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.19547687626799803, "environment.depth.belowKeel": 5.4, "navigation.speedThroughWater": 2.675111788806098, "environment.water.temperature": 280.65, "environment.depth.belowSurface": 5.4, "environment.wind.directionTrue": 1.0297442589117756, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.2, "propulsion.engine_2.revolutions": 10.2, "environment.depth.belowTransducer": 5.4, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 1.0297442589117756, "navigation.gnss.horizontalDilution": 4.4, "navigation.courseOverGroundMagnetic": 0.19547687626799803, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670965075} + }, + { + "time" : "2022-12-13 20:59:05.063", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.40396921666667, + "longitude" : 2.28573555, + "speedoverground" : 5.6, + "courseovergroundtrue" : 10.2, + "windspeedapparent" : 14.6, + "anglespeedapparent" : 27.6, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.17802358374406965, "environment.wind.speedTrue": 3.7, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.17802358374406965, "environment.depth.belowKeel": 5.4, "navigation.speedThroughWater": 2.8808896187142587, "environment.water.temperature": 280.65, "environment.depth.belowSurface": 5.4, "environment.wind.directionTrue": 1.0297442589117756, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.825, "propulsion.engine_2.revolutions": 10.611666666666668, "environment.depth.belowTransducer": 5.4, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 1.0297442589117756, "navigation.gnss.horizontalDilution": 4.4, "navigation.courseOverGroundMagnetic": 0.17802358374406965, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670965135} + }, + { + "time" : "2022-12-13 21:00:05.096", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.40549068333333, + "longitude" : 2.2861892666666668, + "speedoverground" : 5.5, + "courseovergroundtrue" : 13.6, + "windspeedapparent" : 15.4, + "anglespeedapparent" : 20.0, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.2373647783254262, "environment.wind.speedTrue": 5.3, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.2373647783254262, "environment.depth.belowKeel": 4.9, "navigation.speedThroughWater": 2.829445161237219, "environment.water.temperature": 280.65, "environment.depth.belowSurface": 4.9, "environment.wind.directionTrue": 0.7696902003052424, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.403333333333334, "propulsion.engine_2.revolutions": 10.825, "environment.depth.belowTransducer": 4.9, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.7696902003052424, "navigation.gnss.horizontalDilution": 4.7, "navigation.courseOverGroundMagnetic": 0.2373647783254262, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670965195} + }, + { + "time" : "2022-12-13 21:01:05.130", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.406966833333335, + "longitude" : 2.2866105, + "speedoverground" : 5.5, + "courseovergroundtrue" : 10.2, + "windspeedapparent" : 19.4, + "anglespeedapparent" : 24.7, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.17802358374406965, "environment.wind.speedTrue": 3.7, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.17802358374406965, "environment.depth.belowKeel": 4.5, "navigation.speedThroughWater": 2.829445161237219, "environment.water.temperature": 280.54999999999995, "environment.depth.belowSurface": 4.5, "environment.wind.directionTrue": 0.9337511500301693, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10, "propulsion.engine_2.revolutions": 12.19, "environment.depth.belowTransducer": 4.5, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.9337511500301693, "navigation.gnss.horizontalDilution": 5, "navigation.courseOverGroundMagnetic": 0.17802358374406965, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670965255} + }, + { + "time" : "2022-12-13 21:02:05.156", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.40843818333333, + "longitude" : 2.2869834833333336, + "speedoverground" : 5.3, + "courseovergroundtrue" : 10.2, + "windspeedapparent" : 14.6, + "anglespeedapparent" : 29.0, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.17802358374406965, "environment.wind.speedTrue": 5.3, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.17802358374406965, "environment.depth.belowKeel": 4.9, "navigation.speedThroughWater": 2.726556246283138, "environment.water.temperature": 280.25, "environment.depth.belowSurface": 4.9, "environment.wind.directionTrue": 0.9337511500301693, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.825, "propulsion.engine_2.revolutions": 11.716666666666667, "environment.depth.belowTransducer": 4.9, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.9337511500301693, "navigation.gnss.horizontalDilution": 3.3, "navigation.courseOverGroundMagnetic": 0.17802358374406965, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670965315} + }, + { + "time" : "2022-12-13 21:03:05.202", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.40989965, + "longitude" : 2.287289433333333, + "speedoverground" : 5.4, + "courseovergroundtrue" : 9.2, + "windspeedapparent" : 14.4, + "anglespeedapparent" : 26.7, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.16057029122014124, "environment.wind.speedTrue": 2.6, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.16057029122014124, "environment.depth.belowKeel": 6, "navigation.speedThroughWater": 2.7780007037601786, "environment.water.temperature": 280.25, "environment.depth.belowSurface": 6, "environment.wind.directionTrue": 1.1362093433077387, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.403333333333334, "propulsion.engine_2.revolutions": 11.261666666666667, "environment.depth.belowTransducer": 6, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 1.1362093433077387, "navigation.gnss.horizontalDilution": 3.8, "navigation.courseOverGroundMagnetic": 0.16057029122014124, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670965375} + }, + { + "time" : "2022-12-13 21:04:05.224", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.411323816666666, + "longitude" : 2.287555033333333, + "speedoverground" : 5.1, + "courseovergroundtrue" : 7.6, + "windspeedapparent" : 9.3, + "anglespeedapparent" : 22.7, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.1326450231818558, "environment.wind.speedTrue": 2.6, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.1326450231818558, "environment.depth.belowKeel": 5.4, "navigation.speedThroughWater": 2.6236673313290573, "environment.water.temperature": 279.95, "environment.depth.belowSurface": 5.4, "environment.wind.directionTrue": 0.9337511500301693, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.261666666666667, "propulsion.engine_2.revolutions": 10.825, "environment.depth.belowTransducer": 5.4, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.9337511500301693, "navigation.gnss.horizontalDilution": 3.3, "navigation.courseOverGroundMagnetic": 0.1326450231818558, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670965435} + }, + { + "time" : "2022-12-13 21:05:05.253", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.412672, + "longitude" : 2.2878124166666667, + "speedoverground" : 4.7, + "courseovergroundtrue" : 8.4, + "windspeedapparent" : 16.5, + "anglespeedapparent" : 24.7, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.14660765720099855, "environment.wind.speedTrue": 5.3, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.14660765720099855, "environment.depth.belowKeel": 4.5, "navigation.speedThroughWater": 2.417889501420896, "environment.water.temperature": 279.65, "environment.depth.belowSurface": 4.5, "environment.wind.directionTrue": 0.7696902003052424, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.261666666666667, "propulsion.engine_2.revolutions": 10.825, "environment.depth.belowTransducer": 4.5, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.7696902003052424, "navigation.gnss.horizontalDilution": 5, "navigation.courseOverGroundMagnetic": 0.14660765720099855, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670965495} + }, + { + "time" : "2022-12-13 21:06:05.281", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.413960216666666, + "longitude" : 2.288052583333333, + "speedoverground" : 4.8, + "courseovergroundtrue" : 7.6, + "windspeedapparent" : 19.1, + "anglespeedapparent" : 24.7, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.1326450231818558, "environment.wind.speedTrue": 7.6, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.1326450231818558, "environment.depth.belowKeel": 3.3, "navigation.speedThroughWater": 2.4693339588979364, "environment.water.temperature": 279.65, "environment.depth.belowSurface": 3.3, "environment.wind.directionTrue": 0.698131700957136, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.716666666666667, "propulsion.engine_2.revolutions": 11.716666666666667, "environment.depth.belowTransducer": 3.3, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.698131700957136, "navigation.gnss.horizontalDilution": 3.1, "navigation.courseOverGroundMagnetic": 0.1326450231818558, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670965555} + }, + { + "time" : "2022-12-13 21:07:05.315", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.41527805, + "longitude" : 2.288307083333333, + "speedoverground" : 4.8, + "courseovergroundtrue" : 7.6, + "windspeedapparent" : 22.1, + "anglespeedapparent" : 22.3, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.1326450231818558, "environment.wind.speedTrue": 5.3, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.1326450231818558, "environment.depth.belowKeel": 4, "navigation.speedThroughWater": 2.4693339588979364, "environment.water.temperature": 279.54999999999995, "environment.depth.belowSurface": 4, "environment.wind.directionTrue": 0.698131700957136, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.261666666666667, "propulsion.engine_2.revolutions": 12.681666666666667, "environment.depth.belowTransducer": 4, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.698131700957136, "navigation.gnss.horizontalDilution": 2.7, "navigation.courseOverGroundMagnetic": 0.1326450231818558, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670965615} + }, + { + "time" : "2022-12-13 21:08:05.353", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.41658073333333, + "longitude" : 2.2885240166666665, + "speedoverground" : 4.7, + "courseovergroundtrue" : 6.9, + "windspeedapparent" : 16.6, + "anglespeedapparent" : 12.4, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.12042771841510595, "environment.wind.speedTrue": 1.8, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.12042771841510595, "environment.depth.belowKeel": 4.9, "navigation.speedThroughWater": 2.417889501420896, "environment.water.temperature": 279.45, "environment.depth.belowSurface": 4.9, "environment.wind.directionTrue": 0.6318091893662081, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.716666666666667, "propulsion.engine_2.revolutions": 14.860000000000001, "environment.depth.belowTransducer": 4.9, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.6318091893662081, "navigation.gnss.horizontalDilution": 3.1, "navigation.courseOverGroundMagnetic": 0.12042771841510595, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670965675} + }, + { + "time" : "2022-12-13 21:09:05.371", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.41785333333333, + "longitude" : 2.2887258333333333, + "speedoverground" : 4.5, + "courseovergroundtrue" : 6.2, + "windspeedapparent" : 8.6, + "anglespeedapparent" : 9.2, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.10821041364835607, "environment.wind.speedTrue": 1.2, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.10821041364835607, "environment.depth.belowKeel": 6, "navigation.speedThroughWater": 2.3150005864668155, "environment.water.temperature": 279.25, "environment.depth.belowSurface": 6, "environment.wind.directionTrue": 0.5742133240372442, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.403333333333334, "propulsion.engine_2.revolutions": 13.195, "environment.depth.belowTransducer": 6, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.5742133240372442, "navigation.gnss.horizontalDilution": 2.7, "navigation.courseOverGroundMagnetic": 0.10821041364835607, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670965735} + }, + { + "time" : "2022-12-13 21:10:05.404", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.41911275, + "longitude" : 2.28890385, + "speedoverground" : 4.6, + "courseovergroundtrue" : 6.9, + "windspeedapparent" : 7.2, + "anglespeedapparent" : 7.8, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.12042771841510595, "environment.wind.speedTrue": 1, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.12042771841510595, "environment.depth.belowKeel": 7.3, "navigation.speedThroughWater": 2.3664450439438554, "environment.water.temperature": 279.25, "environment.depth.belowSurface": 7.3, "environment.wind.directionTrue": 0.5742133240372442, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.611666666666668, "propulsion.engine_2.revolutions": 12.681666666666667, "environment.depth.belowTransducer": 7.3, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.5742133240372442, "navigation.gnss.horizontalDilution": 2.7, "navigation.courseOverGroundMagnetic": 0.12042771841510595, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670965795} + }, + { + "time" : "2022-12-13 21:11:05.414", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.42043938333333, + "longitude" : 2.2891021, + "speedoverground" : 4.8, + "courseovergroundtrue" : 6.9, + "windspeedapparent" : 7.5, + "anglespeedapparent" : 9.6, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.12042771841510595, "environment.wind.speedTrue": 1, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.12042771841510595, "environment.depth.belowKeel": 7.3, "navigation.speedThroughWater": 2.4693339588979364, "environment.water.temperature": 279.54999999999995, "environment.depth.belowSurface": 7.3, "environment.wind.directionTrue": 0.698131700957136, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.04, "propulsion.engine_2.revolutions": 12.681666666666667, "environment.depth.belowTransducer": 7.3, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.698131700957136, "navigation.gnss.horizontalDilution": 4.1, "navigation.courseOverGroundMagnetic": 0.12042771841510595, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670965855} + }, + { + "time" : "2022-12-13 21:12:05.470", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.42173171666666, + "longitude" : 2.2892923166666668, + "speedoverground" : 4.5, + "courseovergroundtrue" : 5.7, + "windspeedapparent" : 7.3, + "anglespeedapparent" : 14.8, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.09948376738639188, "environment.wind.speedTrue": 1.5, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.09948376738639188, "environment.depth.belowKeel": 7.3, "navigation.speedThroughWater": 2.3150005864668155, "environment.water.temperature": 279.54999999999995, "environment.depth.belowSurface": 7.3, "environment.wind.directionTrue": 0.7696902003052424, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.04, "propulsion.engine_2.revolutions": 12.681666666666667, "environment.depth.belowTransducer": 7.3, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.7696902003052424, "navigation.gnss.horizontalDilution": 5, "navigation.courseOverGroundMagnetic": 0.09948376738639188, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670965915} + }, + { + "time" : "2022-12-13 21:13:05.493", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.42296415, + "longitude" : 2.28942895, + "speedoverground" : 4.4, + "courseovergroundtrue" : 4.2, + "windspeedapparent" : 6.9, + "anglespeedapparent" : 12.4, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.07330382860049928, "environment.wind.speedTrue": 1.2, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.07330382860049928, "environment.depth.belowKeel": 11.8, "navigation.speedThroughWater": 2.263556128989775, "environment.water.temperature": 279.84999999999997, "environment.depth.belowSurface": 11.8, "environment.wind.directionTrue": 0.698131700957136, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.2, "propulsion.engine_2.revolutions": 11.716666666666667, "environment.depth.belowTransducer": 11.8, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.698131700957136, "navigation.gnss.horizontalDilution": 4.1, "navigation.courseOverGroundMagnetic": 0.07330382860049928, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670965975} + }, + { + "time" : "2022-12-13 21:14:05.507", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.42416923333333, + "longitude" : 2.2895500166666665, + "speedoverground" : 4.4, + "courseovergroundtrue" : 4.7, + "windspeedapparent" : 11.3, + "anglespeedapparent" : 13.3, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.08203047486246347, "environment.wind.speedTrue": 2.6, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.08203047486246347, "environment.depth.belowKeel": 13, "navigation.speedThroughWater": 2.263556128989775, "environment.water.temperature": 280.04999999999995, "environment.depth.belowSurface": 13, "environment.wind.directionTrue": 0.5201081172130663, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.611666666666668, "propulsion.engine_2.revolutions": 11.261666666666667, "environment.depth.belowTransducer": 13, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.5201081172130663, "navigation.gnss.horizontalDilution": 4.7, "navigation.courseOverGroundMagnetic": 0.08203047486246347, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670966035} + }, + { + "time" : "2022-12-13 21:15:05.532", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.42538771666667, + "longitude" : 2.2896824166666665, + "speedoverground" : 4.5, + "courseovergroundtrue" : 4.7, + "windspeedapparent" : 9.1, + "anglespeedapparent" : 18.6, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.08203047486246347, "environment.wind.speedTrue": 2.6, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.08203047486246347, "environment.depth.belowKeel": 14.4, "navigation.speedThroughWater": 2.3150005864668155, "environment.water.temperature": 279.84999999999997, "environment.depth.belowSurface": 14.4, "environment.wind.directionTrue": 0.698131700957136, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.611666666666668, "propulsion.engine_2.revolutions": 12.19, "environment.depth.belowTransducer": 14.4, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.698131700957136, "navigation.gnss.horizontalDilution": 3.6, "navigation.courseOverGroundMagnetic": 0.08203047486246347, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670966095} + }, + { + "time" : "2022-12-13 21:16:05.578", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.42659741666667, + "longitude" : 2.2898227, + "speedoverground" : 4.4, + "courseovergroundtrue" : 4.7, + "windspeedapparent" : 11.2, + "anglespeedapparent" : 19.6, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.08203047486246347, "environment.wind.speedTrue": 3.7, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.08203047486246347, "environment.depth.belowKeel": 13, "navigation.speedThroughWater": 2.263556128989775, "environment.water.temperature": 279.45, "environment.depth.belowSurface": 13, "environment.wind.directionTrue": 0.6318091893662081, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.04, "propulsion.engine_2.revolutions": 12.681666666666667, "environment.depth.belowTransducer": 13, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.6318091893662081, "navigation.gnss.horizontalDilution": 5, "navigation.courseOverGroundMagnetic": 0.08203047486246347, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670966155} + }, + { + "time" : "2022-12-13 21:17:05.597", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.42780106666667, + "longitude" : 2.2899329666666666, + "speedoverground" : 4.3, + "courseovergroundtrue" : 4.2, + "windspeedapparent" : 12.5, + "anglespeedapparent" : 15.5, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.07330382860049928, "environment.wind.speedTrue": 1.2, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.07330382860049928, "environment.depth.belowKeel": 14.4, "navigation.speedThroughWater": 2.2121116715127345, "environment.water.temperature": 279.95, "environment.depth.belowSurface": 14.4, "environment.wind.directionTrue": 0.8482300166629202, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.611666666666668, "propulsion.engine_2.revolutions": 12.19, "environment.depth.belowTransducer": 14.4, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.8482300166629202, "navigation.gnss.horizontalDilution": 2.7, "navigation.courseOverGroundMagnetic": 0.07330382860049928, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670966215} + }, + { + "time" : "2022-12-13 21:18:05.608", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.42899953333333, + "longitude" : 2.2900571666666667, + "speedoverground" : 4.3, + "courseovergroundtrue" : 4.2, + "windspeedapparent" : 9.2, + "anglespeedapparent" : 32.1, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.07330382860049928, "environment.wind.speedTrue": 3.1, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.07330382860049928, "environment.depth.belowKeel": 15.8, "navigation.speedThroughWater": 2.2121116715127345, "environment.water.temperature": 279.84999999999997, "environment.depth.belowSurface": 15.8, "environment.wind.directionTrue": 1.0297442589117756, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.611666666666668, "propulsion.engine_2.revolutions": 11.716666666666667, "environment.depth.belowTransducer": 15.8, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 1.0297442589117756, "navigation.gnss.horizontalDilution": 3.1, "navigation.courseOverGroundMagnetic": 0.07330382860049928, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670966275} + }, + { + "time" : "2022-12-13 21:19:05.630", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.43017308333334, + "longitude" : 2.290175666666667, + "speedoverground" : 4.2, + "courseovergroundtrue" : 4.7, + "windspeedapparent" : 12.2, + "anglespeedapparent" : 26.6, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.08203047486246347, "environment.wind.speedTrue": 4.4, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.08203047486246347, "environment.depth.belowKeel": 11.8, "navigation.speedThroughWater": 2.1606672140356946, "environment.water.temperature": 279.95, "environment.depth.belowSurface": 11.8, "environment.wind.directionTrue": 0.7696902003052424, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.611666666666668, "propulsion.engine_2.revolutions": 13.728333333333333, "environment.depth.belowTransducer": 11.8, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.7696902003052424, "navigation.gnss.horizontalDilution": 3.6, "navigation.courseOverGroundMagnetic": 0.08203047486246347, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670966335} + }, + { + "time" : "2022-12-13 21:20:05.651", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.431364, + "longitude" : 2.2902968333333336, + "speedoverground" : 4.2, + "courseovergroundtrue" : 4.7, + "windspeedapparent" : 9.9, + "anglespeedapparent" : 14.2, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.08203047486246347, "environment.wind.speedTrue": 1.5, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.08203047486246347, "environment.depth.belowKeel": 9.7, "navigation.speedThroughWater": 2.1606672140356946, "environment.water.temperature": 279.95, "environment.depth.belowSurface": 9.7, "environment.wind.directionTrue": 0.698131700957136, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.611666666666668, "propulsion.engine_2.revolutions": 13.195, "environment.depth.belowTransducer": 9.7, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.698131700957136, "navigation.gnss.horizontalDilution": 3.6, "navigation.courseOverGroundMagnetic": 0.08203047486246347, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670966395} + }, + { + "time" : "2022-12-13 21:21:05.683", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.43257, + "longitude" : 2.2904335666666666, + "speedoverground" : 4.4, + "courseovergroundtrue" : 4.7, + "windspeedapparent" : 8.1, + "anglespeedapparent" : 19.1, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.08203047486246347, "environment.wind.speedTrue": 2.1, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.08203047486246347, "environment.depth.belowKeel": 11.8, "navigation.speedThroughWater": 2.263556128989775, "environment.water.temperature": 279.65, "environment.depth.belowSurface": 11.8, "environment.wind.directionTrue": 0.7696902003052424, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.486666666666668, "propulsion.engine_2.revolutions": 12.681666666666667, "environment.depth.belowTransducer": 11.8, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.7696902003052424, "navigation.gnss.horizontalDilution": 2.4, "navigation.courseOverGroundMagnetic": 0.08203047486246347, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670966455} + }, + { + "time" : "2022-12-13 21:22:05.702", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.4338153, + "longitude" : 2.2905634333333333, + "speedoverground" : 4.4, + "courseovergroundtrue" : 4.2, + "windspeedapparent" : 7.6, + "anglespeedapparent" : 10.9, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.07330382860049928, "environment.wind.speedTrue": 1, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.07330382860049928, "environment.depth.belowKeel": 13, "navigation.speedThroughWater": 2.263556128989775, "environment.water.temperature": 279.45, "environment.depth.belowSurface": 13, "environment.wind.directionTrue": 0.698131700957136, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.04, "propulsion.engine_2.revolutions": 13.195, "environment.depth.belowTransducer": 13, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.698131700957136, "navigation.gnss.horizontalDilution": 1.8, "navigation.courseOverGroundMagnetic": 0.07330382860049928, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670966515} + }, + { + "time" : "2022-12-13 21:23:05.714", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.43504795, + "longitude" : 2.2906984, + "speedoverground" : 4.5, + "courseovergroundtrue" : 4.7, + "windspeedapparent" : 8.0, + "anglespeedapparent" : 21.0, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.08203047486246347, "environment.wind.speedTrue": 2.1, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.08203047486246347, "environment.depth.belowKeel": 13, "navigation.speedThroughWater": 2.3150005864668155, "environment.water.temperature": 279.65, "environment.depth.belowSurface": 13, "environment.wind.directionTrue": 0.8482300166629202, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.2, "propulsion.engine_2.revolutions": 13.728333333333333, "environment.depth.belowTransducer": 13, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.8482300166629202, "navigation.gnss.horizontalDilution": 1.6, "navigation.courseOverGroundMagnetic": 0.08203047486246347, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670966575} + }, + { + "time" : "2022-12-13 21:24:05.728", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.436295183333336, + "longitude" : 2.2908305666666666, + "speedoverground" : 4.5, + "courseovergroundtrue" : 4.2, + "windspeedapparent" : 7.9, + "anglespeedapparent" : 20.9, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.07330382860049928, "environment.wind.speedTrue": 1.5, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.07330382860049928, "environment.depth.belowKeel": 11.8, "navigation.speedThroughWater": 2.3150005864668155, "environment.water.temperature": 279.54999999999995, "environment.depth.belowSurface": 11.8, "environment.wind.directionTrue": 1.0297442589117756, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.2, "propulsion.engine_2.revolutions": 14.281666666666666, "environment.depth.belowTransducer": 11.8, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 1.0297442589117756, "navigation.gnss.horizontalDilution": 1.4, "navigation.courseOverGroundMagnetic": 0.07330382860049928, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670966635} + }, + { + "time" : "2022-12-13 21:25:05.748", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.437534766666666, + "longitude" : 2.2909366166666665, + "speedoverground" : 4.5, + "courseovergroundtrue" : 3.1, + "windspeedapparent" : 7.9, + "anglespeedapparent" : 14.2, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.054105206824178034, "environment.wind.speedTrue": 1.5, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.054105206824178034, "environment.depth.belowKeel": 11.8, "navigation.speedThroughWater": 2.3150005864668155, "environment.water.temperature": 279.84999999999997, "environment.depth.belowSurface": 11.8, "environment.wind.directionTrue": 0.698131700957136, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10, "propulsion.engine_2.revolutions": 13.195, "environment.depth.belowTransducer": 11.8, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.698131700957136, "navigation.gnss.horizontalDilution": 0.9, "navigation.courseOverGroundMagnetic": 0.054105206824178034, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670966695} + }, + { + "time" : "2022-12-13 21:26:05.787", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.43881773333333, + "longitude" : 2.2910521833333335, + "speedoverground" : 4.6, + "courseovergroundtrue" : 4.2, + "windspeedapparent" : 8.5, + "anglespeedapparent" : 11.0, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.07330382860049928, "environment.wind.speedTrue": 1.5, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.07330382860049928, "environment.depth.belowKeel": 17.5, "navigation.speedThroughWater": 2.3664450439438554, "environment.water.temperature": 279.45, "environment.depth.belowSurface": 17.5, "environment.wind.directionTrue": 0.5742133240372442, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.825, "propulsion.engine_2.revolutions": 13.728333333333333, "environment.depth.belowTransducer": 17.5, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.5742133240372442, "navigation.gnss.horizontalDilution": 1.4, "navigation.courseOverGroundMagnetic": 0.07330382860049928, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670966755} + }, + { + "time" : "2022-12-13 21:27:05.827", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.4401189, + "longitude" : 2.2911686833333333, + "speedoverground" : 4.7, + "courseovergroundtrue" : 4.2, + "windspeedapparent" : 7.0, + "anglespeedapparent" : 7.7, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.07330382860049928, "environment.wind.speedTrue": 1.2, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.07330382860049928, "environment.depth.belowKeel": 23.4, "navigation.speedThroughWater": 2.417889501420896, "environment.water.temperature": 279.54999999999995, "environment.depth.belowSurface": 23.4, "environment.wind.directionTrue": 0.47123889814606673, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10, "propulsion.engine_2.revolutions": 14.281666666666666, "environment.depth.belowTransducer": 23.4, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.47123889814606673, "navigation.gnss.horizontalDilution": 1.2, "navigation.courseOverGroundMagnetic": 0.07330382860049928, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670966815} + }, + { + "time" : "2022-12-13 21:28:05.867", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.441560683333336, + "longitude" : 2.291303533333333, + "speedoverground" : 4.9, + "courseovergroundtrue" : 4.2, + "windspeedapparent" : 7.5, + "anglespeedapparent" : 11.8, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.07330382860049928, "environment.wind.speedTrue": 1.5, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.07330382860049928, "environment.depth.belowKeel": 28.4, "navigation.speedThroughWater": 2.5207784163749767, "environment.water.temperature": 279.45, "environment.depth.belowSurface": 28.4, "environment.wind.directionTrue": 0.6318091893662081, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.403333333333334, "propulsion.engine_2.revolutions": 16.085, "environment.depth.belowTransducer": 28.4, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.6318091893662081, "navigation.gnss.horizontalDilution": 1.1, "navigation.courseOverGroundMagnetic": 0.07330382860049928, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670966875} + }, + { + "time" : "2022-12-13 21:29:05.889", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.44287495, + "longitude" : 2.291422783333333, + "speedoverground" : 4.7, + "courseovergroundtrue" : 3.8, + "windspeedapparent" : 10.4, + "anglespeedapparent" : 12.2, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.0663225115909279, "environment.wind.speedTrue": 1.5, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.0663225115909279, "environment.depth.belowKeel": 28.4, "navigation.speedThroughWater": 2.417889501420896, "environment.water.temperature": 279.54999999999995, "environment.depth.belowSurface": 28.4, "environment.wind.directionTrue": 0.6318091893662081, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.825, "propulsion.engine_2.revolutions": 18.113333333333333, "environment.depth.belowTransducer": 28.4, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.6318091893662081, "navigation.gnss.horizontalDilution": 1.2, "navigation.courseOverGroundMagnetic": 0.0663225115909279, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670966935} + }, + { + "time" : "2022-12-13 21:30:05.922", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.44416415, + "longitude" : 2.2915161166666667, + "speedoverground" : 4.7, + "courseovergroundtrue" : 2.9, + "windspeedapparent" : 10.1, + "anglespeedapparent" : 20.9, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.050614548319392355, "environment.wind.speedTrue": 3.1, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.050614548319392355, "environment.depth.belowKeel": 23.4, "navigation.speedThroughWater": 2.417889501420896, "environment.water.temperature": 279.45, "environment.depth.belowSurface": 23.4, "environment.wind.directionTrue": 0.698131700957136, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.825, "propulsion.engine_2.revolutions": 15.46, "environment.depth.belowTransducer": 23.4, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.698131700957136, "navigation.gnss.horizontalDilution": 1.4, "navigation.courseOverGroundMagnetic": 0.050614548319392355, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670966995} + }, + { + "time" : "2022-12-13 21:31:05.937", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.44544285, + "longitude" : 2.2916172833333333, + "speedoverground" : 4.6, + "courseovergroundtrue" : 3.5, + "windspeedapparent" : 25.5, + "anglespeedapparent" : 23.5, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.06108652383374939, "environment.wind.speedTrue": 9.2, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.06108652383374939, "environment.depth.belowKeel": 19.3, "navigation.speedThroughWater": 2.3664450439438554, "environment.water.temperature": 279.25, "environment.depth.belowSurface": 19.3, "environment.wind.directionTrue": 0.5742133240372442, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.825, "propulsion.engine_2.revolutions": 16.085, "environment.depth.belowTransducer": 19.3, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.5742133240372442, "navigation.gnss.horizontalDilution": 1.6, "navigation.courseOverGroundMagnetic": 0.06108652383374939, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967055} + }, + { + "time" : "2022-12-13 21:32:05.953", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.44671025, + "longitude" : 2.2917142166666666, + "speedoverground" : 4.6, + "courseovergroundtrue" : 3.1, + "windspeedapparent" : 22.0, + "anglespeedapparent" : 17.4, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.054105206824178034, "environment.wind.speedTrue": 4.4, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.054105206824178034, "environment.depth.belowKeel": 21.2, "navigation.speedThroughWater": 2.3664450439438554, "environment.water.temperature": 279.54999999999995, "environment.depth.belowSurface": 21.2, "environment.wind.directionTrue": 0.5201081172130663, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.825, "propulsion.engine_2.revolutions": 16.735, "environment.depth.belowTransducer": 21.2, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.5201081172130663, "navigation.gnss.horizontalDilution": 1.4, "navigation.courseOverGroundMagnetic": 0.054105206824178034, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967114} + }, + { + "time" : "2022-12-13 21:33:05.972", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.447963533333336, + "longitude" : 2.2918140833333336, + "speedoverground" : 4.4, + "courseovergroundtrue" : 3.5, + "windspeedapparent" : 22.0, + "anglespeedapparent" : 21.8, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.06108652383374939, "environment.wind.speedTrue": 6.4, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.06108652383374939, "environment.depth.belowKeel": 23.4, "navigation.speedThroughWater": 2.263556128989775, "environment.water.temperature": 279.25, "environment.depth.belowSurface": 23.4, "environment.wind.directionTrue": 0.5742133240372442, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.825, "propulsion.engine_2.revolutions": 16.085, "environment.depth.belowTransducer": 23.4, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.5742133240372442, "navigation.gnss.horizontalDilution": 1.6, "navigation.courseOverGroundMagnetic": 0.06108652383374939, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967175} + }, + { + "time" : "2022-12-13 21:34:05.994", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.44916808333333, + "longitude" : 2.2919039666666667, + "speedoverground" : 4.3, + "courseovergroundtrue" : 3.1, + "windspeedapparent" : 21.7, + "anglespeedapparent" : 24.7, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.054105206824178034, "environment.wind.speedTrue": 6.4, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.054105206824178034, "environment.depth.belowKeel": 23.4, "navigation.speedThroughWater": 2.2121116715127345, "environment.water.temperature": 279.04999999999995, "environment.depth.belowSurface": 23.4, "environment.wind.directionTrue": 0.6318091893662081, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.261666666666667, "propulsion.engine_2.revolutions": 18.845000000000002, "environment.depth.belowTransducer": 23.4, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.6318091893662081, "navigation.gnss.horizontalDilution": 1.6, "navigation.courseOverGroundMagnetic": 0.054105206824178034, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967235} + }, + { + "time" : "2022-12-13 21:35:06.024", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.45040101666667, + "longitude" : 2.2919925833333332, + "speedoverground" : 4.5, + "courseovergroundtrue" : 3.5, + "windspeedapparent" : 14.3, + "anglespeedapparent" : 24.1, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.06108652383374939, "environment.wind.speedTrue": 4.4, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.06108652383374939, "environment.depth.belowKeel": 21.2, "navigation.speedThroughWater": 2.3150005864668155, "environment.water.temperature": 278.95, "environment.depth.belowSurface": 21.2, "environment.wind.directionTrue": 0.698131700957136, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10, "propulsion.engine_2.revolutions": 20.398333333333333, "environment.depth.belowTransducer": 21.2, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.698131700957136, "navigation.gnss.horizontalDilution": 1.8, "navigation.courseOverGroundMagnetic": 0.06108652383374939, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967295} + }, + { + "time" : "2022-12-13 21:36:06.057", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.451662666666664, + "longitude" : 2.2920915833333333, + "speedoverground" : 4.6, + "courseovergroundtrue" : 3.1, + "windspeedapparent" : 29.1, + "anglespeedapparent" : 39.0, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.054105206824178034, "environment.wind.speedTrue": 13.2, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.054105206824178034, "environment.depth.belowKeel": 19.3, "navigation.speedThroughWater": 2.3664450439438554, "environment.water.temperature": 279.04999999999995, "environment.depth.belowSurface": 19.3, "environment.wind.directionTrue": 0.8482300166629202, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.611666666666668, "propulsion.engine_2.revolutions": 19.60666666666667, "environment.depth.belowTransducer": 19.3, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.8482300166629202, "navigation.gnss.horizontalDilution": 1.8, "navigation.courseOverGroundMagnetic": 0.054105206824178034, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967355} + }, + { + "time" : "2022-12-13 21:37:06.080", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.45293165, + "longitude" : 2.2921954833333333, + "speedoverground" : 4.7, + "courseovergroundtrue" : 3.8, + "windspeedapparent" : 44.2, + "anglespeedapparent" : 26.1, + "status" : "sailing", + "metrics" : {"navigation.headingTrue": 0.0663225115909279, "environment.wind.speedTrue": 20.6, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.0663225115909279, "environment.depth.belowKeel": 17.5, "navigation.speedThroughWater": 2.417889501420896, "environment.water.temperature": 279.45, "environment.depth.belowSurface": 17.5, "environment.wind.directionTrue": 0.5742133240372442, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.04, "propulsion.engine_2.revolutions": 22.08, "environment.depth.belowTransducer": 17.5, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.5742133240372442, "navigation.gnss.horizontalDilution": 2.1, "navigation.courseOverGroundMagnetic": 0.0663225115909279, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967415} + }, + { + "time" : "2022-12-13 21:38:06.100", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.45424523333333, + "longitude" : 2.2922960833333335, + "speedoverground" : 4.8, + "courseovergroundtrue" : 3.1, + "windspeedapparent" : 37.6, + "anglespeedapparent" : 14.2, + "status" : "motoring", + "metrics" : {"navigation.headingTrue": 0.054105206824178034, "environment.wind.speedTrue": 4.8, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.054105206824178034, "environment.depth.belowKeel": 15.8, "navigation.speedThroughWater": 2.4693339588979364, "environment.water.temperature": 279.45, "environment.depth.belowSurface": 15.8, "environment.wind.directionTrue": 0.42760566683624573, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.04, "propulsion.engine_2.revolutions": 23.9, "environment.depth.belowTransducer": 15.8, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.42760566683624573, "navigation.gnss.horizontalDilution": 1.6, "navigation.courseOverGroundMagnetic": 0.054105206824178034, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967475} + }, + { + "time" : "2022-12-13 21:39:06.118", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.4555779, + "longitude" : 2.292398116666667, + "speedoverground" : 4.8, + "courseovergroundtrue" : 3.5, + "windspeedapparent" : 15.7, + "anglespeedapparent" : 10.8, + "status" : "motoring", + "metrics" : {"navigation.headingTrue": 0.06108652383374939, "environment.wind.speedTrue": 3.3, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.06108652383374939, "environment.depth.belowKeel": 15.8, "navigation.speedThroughWater": 2.4693339588979364, "environment.water.temperature": 279.45, "environment.depth.belowSurface": 15.8, "environment.wind.directionTrue": 0.38746309403121043, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.2, "propulsion.engine_2.revolutions": 22.08, "environment.depth.belowTransducer": 15.8, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.38746309403121043, "navigation.gnss.horizontalDilution": 1.4, "navigation.courseOverGroundMagnetic": 0.06108652383374939, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967535} + }, + { + "time" : "2022-12-13 21:40:06.142", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.45691458333334, + "longitude" : 2.2925072833333333, + "speedoverground" : 4.9, + "courseovergroundtrue" : 3.1, + "windspeedapparent" : 15.7, + "anglespeedapparent" : 15.7, + "status" : "motoring", + "metrics" : {"navigation.headingTrue": 0.054105206824178034, "environment.wind.speedTrue": 4.8, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.054105206824178034, "environment.depth.belowKeel": 15.8, "navigation.speedThroughWater": 2.5207784163749767, "environment.water.temperature": 279.65, "environment.depth.belowSurface": 15.8, "environment.wind.directionTrue": 0.47123889814606673, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.611666666666668, "propulsion.engine_2.revolutions": 25.87, "environment.depth.belowTransducer": 15.8, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.47123889814606673, "navigation.gnss.horizontalDilution": 0.8, "navigation.courseOverGroundMagnetic": 0.054105206824178034, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967595} + }, + { + "time" : "2022-12-13 21:41:06.155", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.458240233333335, + "longitude" : 2.2926219333333333, + "speedoverground" : 4.7, + "courseovergroundtrue" : 3.8, + "windspeedapparent" : 12.4, + "anglespeedapparent" : 9.2, + "status" : "motoring", + "metrics" : {"navigation.headingTrue": 0.0663225115909279, "environment.wind.speedTrue": 1.6, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.0663225115909279, "environment.depth.belowKeel": 14.4, "navigation.speedThroughWater": 2.417889501420896, "environment.water.temperature": 279.95, "environment.depth.belowSurface": 14.4, "environment.wind.directionTrue": 0.47123889814606673, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 10.611666666666668, "propulsion.engine_2.revolutions": 26.916666666666668, "environment.depth.belowTransducer": 14.4, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.47123889814606673, "navigation.gnss.horizontalDilution": 0.8, "navigation.courseOverGroundMagnetic": 0.0663225115909279, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967655} + }, + { + "time" : "2022-12-13 21:42:06.187", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.45955073333333, + "longitude" : 2.2927578, + "speedoverground" : 4.8, + "courseovergroundtrue" : 4.7, + "windspeedapparent" : 9.8, + "anglespeedapparent" : 12.4, + "status" : "motoring", + "metrics" : {"navigation.headingTrue": 0.08203047486246347, "environment.wind.speedTrue": 1.6, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.08203047486246347, "environment.depth.belowKeel": 13, "navigation.speedThroughWater": 2.4693339588979364, "environment.water.temperature": 279.84999999999997, "environment.depth.belowSurface": 13, "environment.wind.directionTrue": 0.6318091893662081, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.04, "propulsion.engine_2.revolutions": 25.87, "environment.depth.belowTransducer": 13, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.6318091893662081, "navigation.gnss.horizontalDilution": 0.6, "navigation.courseOverGroundMagnetic": 0.08203047486246347, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967715} + }, + { + "time" : "2022-12-13 21:43:06.208", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.46092023333333, + "longitude" : 2.2929017833333334, + "speedoverground" : 5.0, + "courseovergroundtrue" : 4.2, + "windspeedapparent" : 8.2, + "anglespeedapparent" : 11.7, + "status" : "motoring", + "metrics" : {"navigation.headingTrue": 0.07330382860049928, "environment.wind.speedTrue": 1.8, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.07330382860049928, "environment.depth.belowKeel": 13, "navigation.speedThroughWater": 2.572222873852017, "environment.water.temperature": 279.84999999999997, "environment.depth.belowSurface": 13, "environment.wind.directionTrue": 0.5742133240372442, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.04, "propulsion.engine_2.revolutions": 28.003333333333334, "environment.depth.belowTransducer": 13, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.5742133240372442, "navigation.gnss.horizontalDilution": 0.5, "navigation.courseOverGroundMagnetic": 0.07330382860049928, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967775} + }, + { + "time" : "2022-12-13 21:44:06.237", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.46235585, + "longitude" : 2.2930669666666668, + "speedoverground" : 5.3, + "courseovergroundtrue" : 5.1, + "windspeedapparent" : 10.6, + "anglespeedapparent" : 13.7, + "status" : "motoring", + "metrics" : {"navigation.headingTrue": 0.08901179187203483, "environment.wind.speedTrue": 1.8, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.08901179187203483, "environment.depth.belowKeel": 11.8, "navigation.speedThroughWater": 2.726556246283138, "environment.water.temperature": 279.65, "environment.depth.belowSurface": 11.8, "environment.wind.directionTrue": 0.698131700957136, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.04, "propulsion.engine_2.revolutions": 25.87, "environment.depth.belowTransducer": 11.8, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.698131700957136, "navigation.gnss.horizontalDilution": 0.6, "navigation.courseOverGroundMagnetic": 0.08901179187203483, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967835} + }, + { + "time" : "2022-12-13 21:45:06.284", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.46385398333334, + "longitude" : 2.2932485833333334, + "speedoverground" : 5.4, + "courseovergroundtrue" : 5.7, + "windspeedapparent" : 7.9, + "anglespeedapparent" : 7.3, + "status" : "motoring", + "metrics" : {"navigation.headingTrue": 0.09948376738639188, "environment.wind.speedTrue": 1, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.09948376738639188, "environment.depth.belowKeel": 9.7, "navigation.speedThroughWater": 2.7780007037601786, "environment.water.temperature": 280.04999999999995, "environment.depth.belowSurface": 9.7, "environment.wind.directionTrue": 0.5742133240372442, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 11.04, "propulsion.engine_2.revolutions": 23.9, "environment.depth.belowTransducer": 9.7, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.5742133240372442, "navigation.gnss.horizontalDilution": 0.5, "navigation.courseOverGroundMagnetic": 0.09948376738639188, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967895} + }, + { + "time" : "2022-12-13 21:46:06.327", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.46533328333334, + "longitude" : 2.2934791, + "speedoverground" : 5.5, + "courseovergroundtrue" : 6.9, + "windspeedapparent" : 9.3, + "anglespeedapparent" : 11.3, + "status" : "motoring", + "metrics" : {"navigation.headingTrue": 0.12042771841510595, "environment.wind.speedTrue": 1.8, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.12042771841510595, "environment.depth.belowKeel": 9.7, "navigation.speedThroughWater": 2.829445161237219, "environment.water.temperature": 280.25, "environment.depth.belowSurface": 9.7, "environment.wind.directionTrue": 0.6318091893662081, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 12.433333333333334, "propulsion.engine_2.revolutions": 22.971666666666668, "environment.depth.belowTransducer": 9.7, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.6318091893662081, "navigation.gnss.horizontalDilution": 0.6, "navigation.courseOverGroundMagnetic": 0.12042771841510595, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967955} + }, + { + "time" : "2022-12-13 21:47:06.327", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.46533328333334, + "longitude" : 2.2934791, + "speedoverground" : 5.5, + "courseovergroundtrue" : 6.9, + "windspeedapparent" : 9.3, + "anglespeedapparent" : 11.3, + "status" : "motoring", + "metrics" : {"navigation.headingTrue": 0.12042771841510595, "environment.wind.speedTrue": 1.8, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.12042771841510595, "environment.depth.belowKeel": 9.7, "navigation.speedThroughWater": 2.829445161237219, "environment.water.temperature": 280.25, "environment.depth.belowSurface": 9.7, "environment.wind.directionTrue": 0.6318091893662081, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 12.433333333333334, "propulsion.engine_2.revolutions": 22.971666666666668, "environment.depth.belowTransducer": 9.7, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.6318091893662081, "navigation.gnss.horizontalDilution": 0.6, "navigation.courseOverGroundMagnetic": 0.12042771841510595, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967955} + }, + { + "time" : "2022-12-13 21:48:06.327", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.46533328333334, + "longitude" : 2.2934791, + "speedoverground" : 5.5, + "courseovergroundtrue" : 6.9, + "windspeedapparent" : 9.3, + "anglespeedapparent" : 11.3, + "status" : "motoring", + "metrics" : {"navigation.headingTrue": 0.12042771841510595, "environment.wind.speedTrue": 1.8, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.12042771841510595, "environment.depth.belowKeel": 9.7, "navigation.speedThroughWater": 2.829445161237219, "environment.water.temperature": 280.25, "environment.depth.belowSurface": 9.7, "environment.wind.directionTrue": 0.6318091893662081, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 12.433333333333334, "propulsion.engine_2.revolutions": 22.971666666666668, "environment.depth.belowTransducer": 9.7, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.6318091893662081, "navigation.gnss.horizontalDilution": 0.6, "navigation.courseOverGroundMagnetic": 0.12042771841510595, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967955} + }, + { + "time" : "2022-12-13 21:49:06.327", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.46533328333334, + "longitude" : 2.2934791, + "speedoverground" : 5.5, + "courseovergroundtrue" : 6.9, + "windspeedapparent" : 9.3, + "anglespeedapparent" : 11.3, + "status" : "motoring", + "metrics" : {"navigation.headingTrue": 0.12042771841510595, "environment.wind.speedTrue": 1.8, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.12042771841510595, "environment.depth.belowKeel": 9.7, "navigation.speedThroughWater": 2.829445161237219, "environment.water.temperature": 280.25, "environment.depth.belowSurface": 9.7, "environment.wind.directionTrue": 0.6318091893662081, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 12.433333333333334, "propulsion.engine_2.revolutions": 22.971666666666668, "environment.depth.belowTransducer": 9.7, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.6318091893662081, "navigation.gnss.horizontalDilution": 0.6, "navigation.courseOverGroundMagnetic": 0.12042771841510595, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967955} + }, + { + "time" : "2022-12-13 21:50:06.327", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.46533328333334, + "longitude" : 2.2934791, + "speedoverground" : 5.5, + "courseovergroundtrue" : 6.9, + "windspeedapparent" : 9.3, + "anglespeedapparent" : 11.3, + "status" : "motoring", + "metrics" : {"navigation.headingTrue": 0.12042771841510595, "environment.wind.speedTrue": 1.8, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.12042771841510595, "environment.depth.belowKeel": 9.7, "navigation.speedThroughWater": 2.829445161237219, "environment.water.temperature": 280.25, "environment.depth.belowSurface": 9.7, "environment.wind.directionTrue": 0.6318091893662081, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 12.433333333333334, "propulsion.engine_2.revolutions": 22.971666666666668, "environment.depth.belowTransducer": 9.7, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.6318091893662081, "navigation.gnss.horizontalDilution": 0.6, "navigation.courseOverGroundMagnetic": 0.12042771841510595, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967955} + }, + { + "time" : "2022-12-13 21:51:06.327", + "client_id" : "vessels.urn:mrn:imo:mmsi:787654321", + "latitude" : 41.46533328333334, + "longitude" : 2.2934791, + "speedoverground" : 5.5, + "courseovergroundtrue" : 6.9, + "windspeedapparent" : 9.3, + "anglespeedapparent" : 11.3, + "status" : "moored", + "metrics" : {"navigation.headingTrue": 0.12042771841510595, "environment.wind.speedTrue": 1.8, "navigation.gnss.satellites": 4, "navigation.headingMagnetic": 0.12042771841510595, "environment.depth.belowKeel": 9.7, "navigation.speedThroughWater": 2.829445161237219, "environment.water.temperature": 280.25, "environment.depth.belowSurface": 9.7, "environment.wind.directionTrue": 0.6318091893662081, "navigation.gnss.antennaAltitude": 2, "navigation.gnss.differentialAge": 0, "propulsion.engine_1.revolutions": 12.433333333333334, "propulsion.engine_2.revolutions": 22.971666666666668, "environment.depth.belowTransducer": 9.7, "navigation.gnss.geoidalSeparation": 0, "environment.wind.directionMagnetic": 0.6318091893662081, "navigation.gnss.horizontalDilution": 0.6, "navigation.courseOverGroundMagnetic": 0.12042771841510595, "environment.depth.surfaceToTransducer": 0.3, "navigation.gnss.differentialReference": 0, "navigation.magneticVariationAgeOfService": 1670967955} + } +]} diff --git a/tests/sql/badges.sql b/tests/sql/badges.sql new file mode 100644 index 0000000..874ac0c --- /dev/null +++ b/tests/sql/badges.sql @@ -0,0 +1,85 @@ +--------------------------------------------------------------------------- +-- Listing +-- + +-- List current database +select current_database(); + +-- connect to the DB +\c signalk + +-- output display format +\x on + +SELECT v.vessel_id as "vessel_id" FROM auth.vessels v WHERE v.owner_email = 'demo+kapla@openplotter.cloud' \gset +--\echo :"vessel_id" +SELECT set_config('vessel.id', :'vessel_id', false) IS NOT NULL as vessel_id; + +\echo 'Insert new api.logbook for badges' +INSERT INTO api.logbook + (id, active, "name", "_from", "_from_lat", "_from_lng", "_to", "_to_lat", "_to_lng", track_geom, track_geog, track_geojson, "_from_time", "_to_time", distance, duration, avg_speed, max_speed, max_wind_speed, notes, vessel_id) + VALUES + (nextval('api.logbook_id_seq'), false, 'Tropics Zone', NULL, NULL, NULL, NULL, NULL, NULL, 'SRID=4326;LINESTRING (-63.151124640791096 14.01074681627324, -77.0912026418618 12.870995731013664)'::public.geometry, NULL, NULL, NOW(), NOW(), 123, NULL, NULL, NULL, NULL, NULL, current_setting('vessel.id', false)), + (nextval('api.logbook_id_seq'), false, 'Alaska Zone', NULL, NULL, NULL, NULL, NULL, NULL, 'SRID=4326;LINESTRING (-143.5773697471158 59.4404631255976, -152.35402122385003 56.58243132943173)'::public.geometry, NULL, NULL, NOW(), NOW(), 1234, NULL, NULL, NULL, NULL, NULL, current_setting('vessel.id', false)); + +\echo 'Set config' +SELECT set_config('user.email', 'demo+kapla@openplotter.cloud', false); +--SELECT set_config('vessel.client_id', 'vessels.urn:mrn:imo:mmsi:123456789', false); + +\echo 'Process badge' +SELECT badges_logbook_fn(5); +SELECT badges_logbook_fn(6); +SELECT badges_geom_fn(5); +SELECT badges_geom_fn(6); + +\echo 'Check badges for user' +SELECT jsonb_object_keys ( a.preferences->'badges' ) FROM auth.accounts a; + +\echo 'Check details from vessel_id kapla' +--SELECT get_user_settings_from_vesselid_fn('vessels.urn:mrn:imo:mmsi:123456789'::TEXT); +SELECT + json_build_object( + 'boat', v.name, + 'recipient', a.first, + 'email', v.owner_email, + --'settings', a.preferences, + 'pushover_key', a.preferences->'pushover_key' + --'badges', a.preferences->'badges' + ) as user_settings + FROM auth.accounts a, auth.vessels v, api.metadata m + WHERE m.vessel_id = v.vessel_id + AND m.vessel_id = current_setting('vessel.id', false) + AND lower(a.email) = current_setting('user.email', false); + +\echo 'Insert new api.moorages for badges' +INSERT INTO api.moorages + (id,"name",country,stay_id,stay_code,stay_duration,reference_count,latitude,longitude,geog,home_flag,notes,vessel_id) + VALUES + (5,'Badge Mooring Pro',NULL,5,3,'11 days 00:39:56.418',1,NULL,NULL,NULL,false,'Badge Mooring Pro',current_setting('vessel.id', false)), + (6,'Badge Anchormaster',NULL,5,2,'26 days 00:49:56.418',1,NULL,NULL,NULL,false,'Badge Anchormaster',current_setting('vessel.id', false)); + +\echo 'Set config' +SELECT set_config('user.email', 'demo+aava@openplotter.cloud', false); +--SELECT set_config('vessel.client_id', 'vessels.urn:mrn:imo:mmsi:787654321', false); +SELECT v.vessel_id as "vessel_id" FROM auth.vessels v WHERE v.owner_email = 'demo+aava@openplotter.cloud' \gset +--\echo :"vessel_id" +SELECT set_config('vessel.id', :'vessel_id', false) IS NOT NULL as vessel_id; + +\echo 'Process badge' +SELECT badges_moorages_fn(); + +\echo 'Check details from vessel_id aava' +--SELECT get_user_settings_from_vesselid_fn('vessels.urn:mrn:imo:mmsi:787654321'::TEXT); +SELECT + json_build_object( + 'boat', v.name, + 'recipient', a.first, + 'email', v.owner_email, + --'settings', a.preferences, + 'pushover_key', a.preferences->'pushover_key' + --'badges', a.preferences->'badges' + ) as user_settings + FROM auth.accounts a, auth.vessels v, api.metadata m + WHERE m.vessel_id = v.vessel_id + AND m.vessel_id = current_setting('vessel.id', false) + AND lower(a.email) = current_setting('user.email', false); diff --git a/tests/sql/badges.sql.output b/tests/sql/badges.sql.output new file mode 100644 index 0000000..e7b29bc --- /dev/null +++ b/tests/sql/badges.sql.output @@ -0,0 +1,82 @@ + current_database +------------------ + signalk +(1 row) + +You are now connected to database "signalk" as user "username". +Expanded display is on. +-[ RECORD 1 ] +vessel_id | t + +Insert new api.logbook for badges +INSERT 0 2 +Set config +-[ RECORD 1 ]---------------------------- +set_config | demo+kapla@openplotter.cloud + +Process badge +-[ RECORD 1 ]-----+- +badges_logbook_fn | + +-[ RECORD 1 ]-----+- +badges_logbook_fn | + +-[ RECORD 1 ]--+- +badges_geom_fn | + +-[ RECORD 1 ]--+- +badges_geom_fn | + +Check badges for user +-[ RECORD 1 ]-----+------------------ +jsonb_object_keys | Helmsman +-[ RECORD 2 ]-----+------------------ +jsonb_object_keys | Wake Maker +-[ RECORD 3 ]-----+------------------ +jsonb_object_keys | Balearic Sea +-[ RECORD 4 ]-----+------------------ +jsonb_object_keys | Stormtrooper +-[ RECORD 5 ]-----+------------------ +jsonb_object_keys | Gulf of Finland +-[ RECORD 6 ]-----+------------------ +jsonb_object_keys | Helmsman +-[ RECORD 7 ]-----+------------------ +jsonb_object_keys | Wake Maker +-[ RECORD 8 ]-----+------------------ +jsonb_object_keys | Club Alaska +-[ RECORD 9 ]-----+------------------ +jsonb_object_keys | Stormtrooper +-[ RECORD 10 ]----+------------------ +jsonb_object_keys | Captain Award +-[ RECORD 11 ]----+------------------ +jsonb_object_keys | Caribbean Sea +-[ RECORD 12 ]----+------------------ +jsonb_object_keys | Gulf of Alaska +-[ RECORD 13 ]----+------------------ +jsonb_object_keys | Gulf of Finland +-[ RECORD 14 ]----+------------------ +jsonb_object_keys | Navigator Award +-[ RECORD 15 ]----+------------------ +jsonb_object_keys | Tropical Traveler + +Check details from vessel_id kapla +-[ RECORD 1 ]-+----------------------------------------------------------------------------------------------------------------- +user_settings | {"boat" : "kapla", "recipient" : "First_kapla", "email" : "demo+kapla@openplotter.cloud", "pushover_key" : null} + +Insert new api.moorages for badges +INSERT 0 2 +Set config +-[ RECORD 1 ]--------------------------- +set_config | demo+aava@openplotter.cloud + +-[ RECORD 1 ] +vessel_id | t + +Process badge +-[ RECORD 1 ]------+- +badges_moorages_fn | + +Check details from vessel_id aava +-[ RECORD 1 ]-+-------------------------------------------------------------------------------------------------------------- +user_settings | {"boat" : "aava", "recipient" : "first_aava", "email" : "demo+aava@openplotter.cloud", "pushover_key" : null} + diff --git a/tests/sql/cron_post_jobs.sql b/tests/sql/cron_post_jobs.sql new file mode 100644 index 0000000..54c3e17 --- /dev/null +++ b/tests/sql/cron_post_jobs.sql @@ -0,0 +1,43 @@ +--------------------------------------------------------------------------- +-- Listing +-- + +-- List current database +select current_database(); + +-- connect to the DB +\c signalk + +-- output display format +\x on + +-- set user_id +SELECT a.user_id as "user_id" FROM auth.accounts a WHERE a.email = 'demo+kapla@openplotter.cloud' \gset +--\echo :"user_id" +SELECT set_config('user.id', :'user_id', false) IS NOT NULL as user_id; + +-- set vessel_id +SELECT v.vessel_id as "vessel_id" FROM auth.vessels v WHERE v.owner_email = 'demo+kapla@openplotter.cloud' \gset +--\echo :"vessel_id" +SELECT set_config('vessel.id', :'vessel_id', false) IS NOT NULL as vessel_id; + +-- Test logbook for user +\echo 'logbook' +SELECT count(*) FROM api.logbook WHERE vessel_id = current_setting('vessel.id', false); +\echo 'logbook' +SELECT name,_from_time IS NOT NULL AS _from_time,_to_time IS NOT NULL AS _to_time, track_geojson IS NOT NULL AS track_geojson, track_gpx IS NOT NULL AS track_gpx, track_geom, distance,duration,avg_speed,max_speed,max_wind_speed,notes,extra FROM api.logbook WHERE vessel_id = current_setting('vessel.id', false); + +-- Test stays for user +\echo 'stays' +SELECT count(*) FROM api.stays WHERE vessel_id = current_setting('vessel.id', false); +\echo 'stays' +SELECT active,name,geog,stay_code FROM api.stays WHERE vessel_id = current_setting('vessel.id', false); + +-- Test event logs view for user +\echo 'eventlogs_view' +select count(*) from api.eventlogs_view; + +-- Test event logs view for user +\echo 'stats_logs_fn' +select api.stats_logs_fn(null, null); +select api.stats_logs_fn('2022-01-01'::text,'2022-06-12'::text); diff --git a/tests/sql/cron_post_jobs.sql.output b/tests/sql/cron_post_jobs.sql.output new file mode 100644 index 0000000..a8ab0e6 --- /dev/null +++ b/tests/sql/cron_post_jobs.sql.output @@ -0,0 +1,79 @@ + current_database +------------------ + signalk +(1 row) + +You are now connected to database "signalk" as user "username". +Expanded display is on. +-[ RECORD 1 ] +user_id | t + +-[ RECORD 1 ] +vessel_id | t + +logbook +-[ RECORD 1 ] +count | 2 + +logbook +-[ RECORD 1 ]--+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +name | Bollsta to Strandallén +_from_time | t +_to_time | t +track_geojson | t +track_gpx | t +track_geom | 0102000020E61000001A00000020D26F5F0786374030BB270F0B094E400C6E7ED60F843740AA60545227084E40D60FC48C03823740593CE27D42074E407B39D9F322803740984C158C4A064E4091ED7C3F357E3740898BB63D54054E40A8A1208B477C37404BA3DC9059044E404C5CB4EDA17A3740C4F856115B034E40A9A44E4013793740D8F0F44A59024E40E4839ECDAA773740211FF46C56014E405408D147067637408229F03B73004E40787AA52C43743740F90FE9B7AFFF4D40F8098D4D18723740C217265305FF4D4084E82303537037409A2D464AA0FE4D4022474DCE636F37402912396A72FE4D408351499D806E374088CFB02B40FE4D4076711B0DE06D3740B356C7040FFE4D404EAC66B0BC6E374058A835CD3BFE4D40D7A3703D0A6F3740D3E10EC15EFE4D4087602F277B6E3740A779C7293AFE4D4087602F277B6E3740A779C7293AFE4D402063EE5A426E3740B5A679C729FE4D40381DEE10EC6D37409ECA7C1A0AFE4D40E2C46A06CB6B37400A43F7BF36FD4D4075931804566E3740320BDAD125FD4D409A2D464AA06E37404A5658830AFD4D40029A081B9E6E37404A5658830AFD4D40 +distance | 7.17 +duration | 00:25:00 +avg_speed | 3.6961538461538455 +max_speed | 6.1 +max_wind_speed | 22.1 +notes | new log note +extra | {"metrics": {"propulsion.main.runTime": 10}, "observations": {"seaState": -1, "visibility": -1, "cloudCoverage": -1}} +-[ RECORD 2 ]--+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +name | Knipan to Ekenäs +_from_time | t +_to_time | t +track_geojson | t +track_gpx | t +track_geom | 0102000020E6100000130000004806A6C0EF6C3740DA1B7C6132FD4D40FE65F7E461693740226C787AA5FC4D407DD3E10EC1663740B29DEFA7C6FB4D40898BB63D5465374068479724BCFA4D409A5271F6E1633740B6847CD0B3F94D40431CEBE236623740E9263108ACF84D402C6519E2585F37407E678EBFC7F74D4096218E75715B374027C5B45C23F74D402AA913D044583740968DE1C46AF64D405AF5B9DA8A5537407BEF829B9FF54D407449C2ABD253374086C954C1A8F44D407D1A0AB278543740F2B0506B9AF34D409D11A5BDC15737406688635DDCF24D4061C3D32B655937402CAF6F3ADCF14D408988888888583740B3319C58CDF04D4021FAC8C0145837408C94405DB7EF4D40B8F9593F105B37403DC0804BEDEE4D40DE4C5FE2A25D3740AE47E17A14EE4D40DE4C5FE2A25D3740AE47E17A14EE4D40 +distance | 8.6862 +duration | 00:18:00 +avg_speed | 6.026315789473684 +max_speed | 6.5 +max_wind_speed | 37.2 +notes | +extra | {"metrics": {"propulsion.main.runTime": 11}, "observations": {"seaState": -1, "visibility": -1, "cloudCoverage": -1}} + +stays +-[ RECORD 1 ] +count | 3 + +stays +-[ RECORD 1 ]------------------------------------------------- +active | f +name | Bollsta +geog | 0101000020E6100000B0DEBBE0E68737404DA938FBF0094E40 +stay_code | 2 +-[ RECORD 2 ]------------------------------------------------- +active | f +name | Strandallén +geog | 0101000020E6100000029A081B9E6E37404A5658830AFD4D40 +stay_code | 1 +-[ RECORD 3 ]------------------------------------------------- +active | t +name | Ekenäs +geog | 0101000020E6100000DE4C5FE2A25D3740AE47E17A14EE4D40 +stay_code | 2 + +eventlogs_view +-[ RECORD 1 ] +count | 13 + +stats_logs_fn +-[ RECORD 1 ]-+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +stats_logs_fn | {"count": 4, "max_speed": 7.1, "max_distance": 8.6862, "max_duration": "01:11:00", "max_speed_id": 3, "sum_duration": "02:37:00", "max_wind_speed": 44.2, "max_distance_id": 2, "max_wind_speed_id": 4} + +-[ RECORD 1 ]-+- +stats_logs_fn | + diff --git a/tests/sql/cron_run_jobs.sql b/tests/sql/cron_run_jobs.sql new file mode 100644 index 0000000..bb87858 --- /dev/null +++ b/tests/sql/cron_run_jobs.sql @@ -0,0 +1,20 @@ +--------------------------------------------------------------------------- +-- Listing +-- + +-- List current database +select current_database(); + +-- connect to the DB +\c signalk + +-- output display format +\x on + +-- Check the number of process pending +-- Should be 22 +SELECT count(*) as jobs from public.process_queue pq where pq.processed is null; +--set role scheduler +SELECT public.run_cron_jobs(); +-- Check any pending job +SELECT count(*) as any_pending_jobs from public.process_queue pq where pq.processed is null; diff --git a/tests/sql/cron_run_jobs.sql.output b/tests/sql/cron_run_jobs.sql.output new file mode 100644 index 0000000..bae986b --- /dev/null +++ b/tests/sql/cron_run_jobs.sql.output @@ -0,0 +1,16 @@ + current_database +------------------ + signalk +(1 row) + +You are now connected to database "signalk" as user "username". +Expanded display is on. +-[ RECORD 1 ] +jobs | 28 + +-[ RECORD 1 ]-+- +run_cron_jobs | + +-[ RECORD 1 ]----+-- +any_pending_jobs | 0 + diff --git a/tests/sql/grafana.sql b/tests/sql/grafana.sql new file mode 100644 index 0000000..457c6e2 --- /dev/null +++ b/tests/sql/grafana.sql @@ -0,0 +1,79 @@ +--------------------------------------------------------------------------- +-- Listing +-- + +-- List current database +select current_database(); + +-- connect to the DB +\c signalk + +-- output display format +\x on + +-- +-- grafana_auth +SET ROLE grafana_auth; +\echo 'ROLE grafana_auth current_setting' +SELECT current_user, current_setting('user.email', true), current_setting('vessel.client_id', true), current_setting('vessel.id', true); + +--SELECT a.pass,v.name,m.client_id FROM auth.accounts a JOIN auth.vessels v ON a.email = 'demo+kapla@openplotter.cloud' AND a.role = 'user_role' AND cast(a.preferences->>'email_valid' as Boolean) = True AND v.owner_email = a.email JOIN api.metadata m ON m.vessel_id = v.vessel_id; +--SELECT a.pass,v.name,m.client_id FROM auth.accounts a JOIN auth.vessels v ON a.email = 'demo+kapla@openplotter.cloud' AND a.role = 'user_role' AND v.owner_email = a.email JOIN api.metadata m ON m.vessel_id = v.vessel_id; +\echo 'link vessel and user based on current_setting' +SELECT v.name,m.client_id FROM auth.accounts a JOIN auth.vessels v ON a.role = 'user_role' AND v.owner_email = a.email JOIN api.metadata m ON m.vessel_id = v.vessel_id; + +\echo 'auth.accounts details' +SELECT a.userid IS NOT NULL AS userid, a.user_id IS NOT NULL AS user_id, a.email, a.first, a.last, a.pass IS NOT NULL AS pass, a.role, a.preferences->'telegram'->'chat' AS telegram, a.preferences->'pushover_user_key' AS pushover_user_key FROM auth.accounts AS a; +\echo 'auth.vessels details' +--SELECT 'SELECT ' || STRING_AGG('v.' || column_name, ', ') || ' FROM auth.vessels AS v' FROM information_schema.columns WHERE table_name = 'vessels' AND table_schema = 'auth' AND column_name NOT IN ('created_at', 'updated_at'); +SELECT v.vessel_id IS NOT NULL AS vessel_id, v.owner_email, v.mmsi, v.name, v.role FROM auth.vessels AS v; +\echo 'api.metadata details' +-- +SELECT m.id, m.name, m.mmsi, m.client_id, m.length, m.beam, m.height, m.ship_type, m.plugin_version, m.signalk_version, m.time IS NOT NULL AS time, m.active FROM api.metadata AS m; + +-- +-- grafana +SET ROLE grafana; +\echo 'ROLE grafana current_setting' + +\echo 'Set current_setting value' +SET "user.email" = 'demo+kapla@openplotter.cloud'; +--SET vessel.client_id = 'vessels.urn:mrn:imo:mmsi:123456789'; + +--select v.vessel_id FROM auth.vessels v WHERE v.owner_email = 'demo+kapla@openplotter.cloud'; +SELECT v.vessel_id as "vessel_id" FROM auth.vessels v WHERE v.owner_email = 'demo+kapla@openplotter.cloud' \gset +--\echo :"vessel_id" +SELECT set_config('vessel.id', :'vessel_id', false) IS NOT NULL as vessel_id; + +--SELECT current_user, current_setting('user.email', true), current_setting('vessel.client_id', true), current_setting('vessel.id', true); +SELECT current_user, current_setting('user.email', true), current_setting('vessel.client_id', true); + +SELECT v.name AS __text, m.client_id AS __value FROM auth.vessels v JOIN api.metadata m ON v.owner_email = 'demo+kapla@openplotter.cloud' and m.vessel_id = v.vessel_id; + +\echo 'auth.vessels details' +--SELECT * FROM auth.vessels v; +SELECT v.vessel_id IS NOT NULL AS vessel_id, v.owner_email, v.mmsi, v.name, v.role FROM auth.vessels AS v; +--SELECT * FROM api.metadata m; +\echo 'api.metadata details' +SELECT m.id, m.name, m.mmsi, m.client_id, m.length, m.beam, m.height, m.ship_type, m.plugin_version, m.signalk_version, m.time IS NOT NULL AS time, m.active FROM api.metadata AS m; + +\echo 'api.logs_view' +--SELECT * FROM api.logbook l; +--SELECT * FROM api.logs_view l; +SELECT l.id, "Name", "From", "To", "Distance", "Duration" FROM api.logs_view AS l; +--SELECT * FROM api.log_view l; + +\echo 'api.stays' +--SELECT * FROM api.stays s; +SELECT m.id, m.vessel_id IS NOT NULL AS vessel_id, m.active, m.name, m.latitude, m.longitude, m.geog, m.arrived IS NOT NULL AS arrived, m.departed IS NOT NULL AS departed, m.duration, m.stay_code, m.notes FROM api.stays AS m; + +\echo 'stays_view' +--SELECT * FROM api.stays_view s; +SELECT m.id, m.name IS NOT NULL AS name, m.moorage, m.moorage_id, m.duration, m.stayed_at, m.stayed_at_id, m.arrived IS NOT NULL AS arrived, m.departed IS NOT NULL AS departed, m.notes FROM api.stays_view AS m; + +\echo 'api.moorages' +--SELECT * FROM api.moorages m; +SELECT m.id, m.vessel_id IS NOT NULL AS vessel_id, m.name, m.country, m.stay_id, m.stay_code, m.stay_duration, m.reference_count, m.latitude, m.longitude, m.geog, m.home_flag, m.notes FROM api.moorages AS m; + +\echo 'api.moorages_view' +SELECT * FROM api.moorages_view s; diff --git a/tests/sql/grafana.sql.output b/tests/sql/grafana.sql.output new file mode 100644 index 0000000..cb2877b --- /dev/null +++ b/tests/sql/grafana.sql.output @@ -0,0 +1,253 @@ + current_database +------------------ + signalk +(1 row) + +You are now connected to database "signalk" as user "username". +Expanded display is on. +SET +ROLE grafana_auth current_setting +-[ RECORD 1 ]---+------------- +current_user | grafana_auth +current_setting | +current_setting | +current_setting | + +link vessel and user based on current_setting +-[ RECORD 1 ]---------------------------------------------------------------- +name | kapla +client_id | vessels.urn:mrn:signalk:uuid:5b4f7543-7153-4840-b139-761310b242fd +-[ RECORD 2 ]---------------------------------------------------------------- +name | aava +client_id | vessels.urn:mrn:imo:mmsi:787654321 + +auth.accounts details +-[ RECORD 1 ]-----+----------------------------- +userid | t +user_id | t +email | demo+kapla@openplotter.cloud +first | First_kapla +last | Last_kapla +pass | t +role | user_role +telegram | +pushover_user_key | +-[ RECORD 2 ]-----+----------------------------- +userid | t +user_id | t +email | demo+aava@openplotter.cloud +first | first_aava +last | last_aava +pass | t +role | user_role +telegram | +pushover_user_key | + +auth.vessels details +-[ RECORD 1 ]----------------------------- +vessel_id | t +owner_email | demo+kapla@openplotter.cloud +mmsi | +name | kapla +role | vessel_role +-[ RECORD 2 ]----------------------------- +vessel_id | t +owner_email | demo+aava@openplotter.cloud +mmsi | 787654321 +name | aava +role | vessel_role + +api.metadata details +-[ RECORD 1 ]---+------------------------------------------------------------------ +id | 1 +name | kapla +mmsi | 123456789 +client_id | vessels.urn:mrn:signalk:uuid:5b4f7543-7153-4840-b139-761310b242fd +length | 12 +beam | 10 +height | 24 +ship_type | 36 +plugin_version | 0.0.1 +signalk_version | signalk_version +time | t +active | t +-[ RECORD 2 ]---+------------------------------------------------------------------ +id | 2 +name | aava +mmsi | 787654321 +client_id | vessels.urn:mrn:imo:mmsi:787654321 +length | 12 +beam | 10 +height | 24 +ship_type | 37 +plugin_version | 1.0.2 +signalk_version | 1.20.0 +time | t +active | t + +SET +ROLE grafana current_setting +Set current_setting value +SET +-[ RECORD 1 ] +vessel_id | t + +-[ RECORD 1 ]---+----------------------------- +current_user | grafana +current_setting | demo+kapla@openplotter.cloud +current_setting | + +-[ RECORD 1 ]-------------------------------------------------------------- +__text | kapla +__value | vessels.urn:mrn:signalk:uuid:5b4f7543-7153-4840-b139-761310b242fd + +auth.vessels details +-[ RECORD 1 ]----------------------------- +vessel_id | t +owner_email | demo+kapla@openplotter.cloud +mmsi | +name | kapla +role | vessel_role + +api.metadata details +-[ RECORD 1 ]---+------------------------------------------------------------------ +id | 1 +name | kapla +mmsi | 123456789 +client_id | vessels.urn:mrn:signalk:uuid:5b4f7543-7153-4840-b139-761310b242fd +length | 12 +beam | 10 +height | 24 +ship_type | 36 +plugin_version | 0.0.1 +signalk_version | signalk_version +time | t +active | t + +api.logs_view +-[ RECORD 1 ]-------------- +id | 2 +Name | Knipan to Ekenäs +From | Knipan +To | Ekenäs +Distance | 8.6862 +Duration | 00:18:00 +-[ RECORD 2 ]-------------- +id | 1 +Name | patch log name 3 +From | Bollsta +To | Strandallén +Distance | 7.17 +Duration | 00:25:00 + +api.stays +-[ RECORD 1 ]------------------------------------------------- +id | 1 +vessel_id | t +active | f +name | patch stay name 3 +latitude | 60.077666666666666 +longitude | 23.530866666666668 +geog | 0101000020E6100000B0DEBBE0E68737404DA938FBF0094E40 +arrived | t +departed | t +duration | +stay_code | 2 +notes | new stay note 3 +-[ RECORD 2 ]------------------------------------------------- +id | 2 +vessel_id | t +active | f +name | Strandallén +latitude | 59.97688333333333 +longitude | 23.4321 +geog | 0101000020E6100000029A081B9E6E37404A5658830AFD4D40 +arrived | t +departed | t +duration | +stay_code | 1 +notes | +-[ RECORD 3 ]------------------------------------------------- +id | 3 +vessel_id | t +active | t +name | Ekenäs +latitude | 59.86 +longitude | 23.365766666666666 +geog | 0101000020E6100000DE4C5FE2A25D3740AE47E17A14EE4D40 +arrived | t +departed | f +duration | +stay_code | 2 +notes | + +stays_view +-[ RECORD 1 ]+------------------ +id | 2 +name | t +moorage | Strandallén +moorage_id | 2 +duration | 00:03:00 +stayed_at | Unknow +stayed_at_id | 1 +arrived | t +departed | t +notes | +-[ RECORD 2 ]+------------------ +id | 1 +name | t +moorage | patch stay name 3 +moorage_id | 1 +duration | 00:02:00 +stayed_at | Anchor +stayed_at_id | 2 +arrived | t +departed | t +notes | new stay note 3 + +api.moorages +-[ RECORD 1 ]---+--------------------------------------------------- +id | 1 +vessel_id | t +name | patch moorage name 3 +country | +stay_id | 1 +stay_code | 2 +stay_duration | 00:02:00 +reference_count | 1 +latitude | 60.077666666666666 +longitude | 23.530866666666668 +geog | 0101000020E6100000B0DEBBE0E68737404DA938FBF0094E40 +home_flag | t +notes | new moorage note 3 +-[ RECORD 2 ]---+--------------------------------------------------- +id | 2 +vessel_id | t +name | Strandallén +country | +stay_id | 2 +stay_code | 1 +stay_duration | 00:03:00 +reference_count | 1 +latitude | 59.97688333333333 +longitude | 23.4321 +geog | 0101000020E6100000029A081B9E6E37404A5658830AFD4D40 +home_flag | f +notes | + +api.moorages_view +-[ RECORD 1 ]-------+--------------------- +id | 1 +moorage | patch moorage name 3 +default_stay | Anchor +default_stay_id | 2 +total_stay | 0 +arrivals_departures | 1 +-[ RECORD 2 ]-------+--------------------- +id | 2 +moorage | Strandallén +default_stay | Unknow +default_stay_id | 1 +total_stay | 0 +arrivals_departures | 1 + diff --git a/tests/sql/monitoring.sql b/tests/sql/monitoring.sql new file mode 100644 index 0000000..5e5f77a --- /dev/null +++ b/tests/sql/monitoring.sql @@ -0,0 +1,53 @@ +--------------------------------------------------------------------------- +-- Listing +-- + +-- List current database +select current_database(); + +-- connect to the DB +\c signalk + +-- output display format +\x on + +\echo 'Set vessel_id and vessel.name' +-- set vessel_id +SELECT v.vessel_id as "vessel_id" FROM auth.vessels v WHERE v.owner_email = 'demo+kapla@openplotter.cloud' \gset +--\echo :"vessel_id" +SELECT set_config('vessel.id', :'vessel_id', false) IS NOT NULL as vessel_id; + +-- set name +SELECT v.name as "name" FROM auth.vessels v WHERE v.owner_email = 'demo+kapla@openplotter.cloud' \gset +--\echo :"vessel_id" +SELECT set_config('vessel.name', :'name', false) IS NOT NULL as name; + +\echo 'Test monitoring_view for user' +-- Test monitoring for user +--select * from api.monitoring_view; +select count(*) from api.monitoring_view; + +\echo 'Test monitoring_view2 for user' +-- Test monitoring for user +--select * from api.monitoring_view2; +select count(*) from api.monitoring_view2; + +\echo 'Test monitoring_view3 for user' +-- Test monitoring for user +--select * from api.monitoring_view3; +select count(*) from api.monitoring_view3; + +\echo 'Test monitoring_voltage for user' +-- Test monitoring for user +--select * from api.monitoring_voltage; +select count(*) from api.monitoring_voltage; + +\echo 'Test monitoring_temperatures for user' +-- Test monitoring for user +--select * from api.monitoring_temperatures; +select count(*) from api.monitoring_temperatures; + +\echo 'Test monitoring_humidity for user' +-- Test monitoring for user +--select * from api.monitoring_humidity; +select count(*) from api.monitoring_humidity; diff --git a/tests/sql/monitoring.sql.output b/tests/sql/monitoring.sql.output new file mode 100644 index 0000000..57fd01d --- /dev/null +++ b/tests/sql/monitoring.sql.output @@ -0,0 +1,38 @@ + current_database +------------------ + signalk +(1 row) + +You are now connected to database "signalk" as user "username". +Expanded display is on. +Set vessel_id and vessel.name +-[ RECORD 1 ] +vessel_id | t + +-[ RECORD 1 ] +name | t + +Test monitoring_view for user +-[ RECORD 1 ] +count | 1 + +Test monitoring_view2 for user +-[ RECORD 1 ] +count | 21 + +Test monitoring_view3 for user +-[ RECORD 1 ] +count | 3682 + +Test monitoring_voltage for user +-[ RECORD 1 ] +count | 46 + +Test monitoring_temperatures for user +-[ RECORD 1 ] +count | 119 + +Test monitoring_humidity for user +-[ RECORD 1 ] +count | 0 + diff --git a/tests/sql/otp.sql b/tests/sql/otp.sql new file mode 100644 index 0000000..2805ad4 --- /dev/null +++ b/tests/sql/otp.sql @@ -0,0 +1,26 @@ +--------------------------------------------------------------------------- +-- Listing +-- + +-- List current database +select current_database(); + +-- connect to the DB +\c signalk + +-- output display format +\x on + +-- +-- +\echo 'Count auth.accounts' +SELECT count(*) from auth.accounts; +\echo 'Settings auth.accounts' +SELECT preferences->'email_notifications' as email_notifications from auth.accounts; +SELECT preferences->'phone_notifications' as phone_notifications from auth.accounts; +SELECT preferences->'telegram'->'chat'->'id' as telegram from auth.accounts; +--SELECT preferences->'telegram'->'date' - INTERVAL 5 minutes from auth.accounts; + +SELECT count(*) + FROM auth.accounts + WHERE preferences->'telegram'->'chat'->'id' is null; \ No newline at end of file diff --git a/tests/sql/otp.sql.output b/tests/sql/otp.sql.output new file mode 100644 index 0000000..9205a69 --- /dev/null +++ b/tests/sql/otp.sql.output @@ -0,0 +1,30 @@ + current_database +------------------ + signalk +(1 row) + +You are now connected to database "signalk" as user "username". +Expanded display is on. +Count auth.accounts +-[ RECORD 1 ] +count | 2 + +Settings auth.accounts +-[ RECORD 1 ]-------+------ +email_notifications | false +-[ RECORD 2 ]-------+------ +email_notifications | false + +-[ RECORD 1 ]-------+------ +phone_notifications | false +-[ RECORD 2 ]-------+------ +phone_notifications | false + +-[ RECORD 1 ]-------- +telegram | 1234567890 +-[ RECORD 2 ]-------- +telegram | 9876543210 + +-[ RECORD 1 ] +count | 0 + diff --git a/tests/sql/summary.sql b/tests/sql/summary.sql new file mode 100644 index 0000000..146810e --- /dev/null +++ b/tests/sql/summary.sql @@ -0,0 +1,88 @@ +--------------------------------------------------------------------------- +-- Listing +-- + +-- List current database +select current_database(); + +-- connect to the DB +\c signalk + +-- output display format +\x on + +-- List PostgreSQL version +SELECT version(); + +-- List Postgis version +SELECT postgis_full_version(); + +-- List of installed extensions +-- \dx +--SELECT extname,extversion FROM pg_extension; +SELECT e.extname AS "Name", e.extversion AS "Version", n.nspname AS "Schema", c.description AS "Description" + FROM pg_catalog.pg_extension e + LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace + LEFT JOIN pg_catalog.pg_description c ON c.objoid = e.oid AND c.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass + ORDER BY 1; + +-- List of installed extensions available for upgrade +SELECT name, default_version, installed_version FROM pg_available_extensions where default_version <> installed_version; + +-- List Language +\echo 'List Language' +SELECT * FROM pg_language; + +-- List of databases +-- ICU Missing entry in some system? +--\l +SELECT datname,datconnlimit,datcollate,datctype,datallowconn FROM pg_database; + +-- List of relations +\echo 'List of relations' +\dtables + +-- List tables from schema api +select t.table_name as schema_api + from information_schema.tables t + where t.table_schema = 'api' + and t.table_type = 'BASE TABLE' + order by t.table_name; + +-- List tables from schema public +select t.table_name as schema_public + from information_schema.tables t + where t.table_schema = 'public' + and t.table_type = 'BASE TABLE' + order by t.table_name; + +-- List tables from schema auth +select t.table_name as schema_auth + from information_schema.tables t + where t.table_schema = 'auth' + and t.table_type = 'BASE TABLE' + order by t.table_name; + +-- List tables from schema jwt +select t.table_name as schema_jwt + from information_schema.tables t + where t.table_schema = 'jwt' + and t.table_type = 'BASE TABLE' + order by t.table_name; + +-- List Row Security Policies - todo reduce and improve output +\echo 'List Row Security Policies' +select * from pg_policies; + +-- Test functions +\echo 'Test nominatim reverse_geocode_py_fn' +SELECT public.reverse_geocode_py_fn('nominatim', 1.4440116666666667, 38.82985166666667); +\echo 'Test geoip reverse_geoip_py_fn' +--SELECT reverse_geoip_py_fn('62.74.13.231'); + +-- List details product versions +SELECT api.versions_fn(); +SELECT * FROM api.versions_view; + +-- List application settings +--SELECT * IS NOT NULl FROM public.app_settings; diff --git a/tests/sql/summary.sql.output b/tests/sql/summary.sql.output new file mode 100644 index 0000000..bcb9fbd --- /dev/null +++ b/tests/sql/summary.sql.output @@ -0,0 +1,608 @@ + current_database +------------------ + signalk +(1 row) + +You are now connected to database "signalk" as user "username". +Expanded display is on. +-[ RECORD 1 ]------------------------------------------------------------------------------------------------------------------------------ +version | PostgreSQL 15.4 (Debian 15.4-1.pgdg110+1) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit + +-[ RECORD 1 ]--------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +postgis_full_version | POSTGIS="3.4.0 0874ea3" [EXTENSION] PGSQL="150" GEOS="3.9.0-CAPI-1.16.2" PROJ="7.2.1 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/var/lib/postgresql/.local/share/proj DATABASE_PATH=/usr/share/proj/proj.db" LIBXML="2.9.10" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 (Internal)" + +-[ RECORD 1 ]-------------------------------------------------------------------------------------- +Name | citext +Version | 1.6 +Schema | public +Description | data type for case-insensitive character strings +-[ RECORD 2 ]-------------------------------------------------------------------------------------- +Name | jsonb_plpython3u +Version | 1.0 +Schema | public +Description | transform between jsonb and plpython3u +-[ RECORD 3 ]-------------------------------------------------------------------------------------- +Name | moddatetime +Version | 1.0 +Schema | public +Description | functions for tracking last modification time +-[ RECORD 4 ]-------------------------------------------------------------------------------------- +Name | pg_stat_statements +Version | 1.10 +Schema | public +Description | track planning and execution statistics of all SQL statements executed +-[ RECORD 5 ]-------------------------------------------------------------------------------------- +Name | pgcrypto +Version | 1.3 +Schema | public +Description | cryptographic functions +-[ RECORD 6 ]-------------------------------------------------------------------------------------- +Name | plpgsql +Version | 1.0 +Schema | pg_catalog +Description | PL/pgSQL procedural language +-[ RECORD 7 ]-------------------------------------------------------------------------------------- +Name | plpython3u +Version | 1.0 +Schema | pg_catalog +Description | PL/Python3U untrusted procedural language +-[ RECORD 8 ]-------------------------------------------------------------------------------------- +Name | postgis +Version | 3.4.0 +Schema | public +Description | PostGIS geometry and geography spatial types and functions +-[ RECORD 9 ]-------------------------------------------------------------------------------------- +Name | timescaledb +Version | 2.11.2 +Schema | public +Description | Enables scalable inserts and complex queries for time-series data (Community Edition) +-[ RECORD 10 ]------------------------------------------------------------------------------------- +Name | uuid-ossp +Version | 1.1 +Schema | public +Description | generate universally unique identifiers (UUIDs) + +(0 rows) + +List Language +-[ RECORD 1 ]-+----------- +oid | 12 +lanname | internal +lanowner | 10 +lanispl | f +lanpltrusted | f +lanplcallfoid | 0 +laninline | 0 +lanvalidator | 2246 +lanacl | +-[ RECORD 2 ]-+----------- +oid | 13 +lanname | c +lanowner | 10 +lanispl | f +lanpltrusted | f +lanplcallfoid | 0 +laninline | 0 +lanvalidator | 2247 +lanacl | +-[ RECORD 3 ]-+----------- +oid | 14 +lanname | sql +lanowner | 10 +lanispl | f +lanpltrusted | t +lanplcallfoid | 0 +laninline | 0 +lanvalidator | 2248 +lanacl | +-[ RECORD 4 ]-+----------- +oid | 13542 +lanname | plpgsql +lanowner | 10 +lanispl | t +lanpltrusted | t +lanplcallfoid | 13539 +laninline | 13540 +lanvalidator | 13541 +lanacl | +-[ RECORD 5 ]-+----------- +oid | 18174 +lanname | plpython3u +lanowner | 10 +lanispl | t +lanpltrusted | t +lanplcallfoid | 18171 +laninline | 18172 +lanvalidator | 18173 +lanacl | + +-[ RECORD 1 ]+----------- +datname | postgres +datconnlimit | -1 +datcollate | en_US.utf8 +datctype | en_US.utf8 +datallowconn | t +-[ RECORD 2 ]+----------- +datname | template1 +datconnlimit | -1 +datcollate | en_US.utf8 +datctype | en_US.utf8 +datallowconn | t +-[ RECORD 3 ]+----------- +datname | template0 +datconnlimit | -1 +datcollate | en_US.utf8 +datctype | en_US.utf8 +datallowconn | f +-[ RECORD 4 ]+----------- +datname | signalk +datconnlimit | 100 +datcollate | en_US.utf8 +datctype | en_US.utf8 +datallowconn | t + +List of relations +List of relations +-[ RECORD 1 ]--------------------------------- +Schema | public +Name | aistypes +Type | table +Owner | username +-[ RECORD 2 ]--------------------------------- +Schema | public +Name | app_settings +Type | table +Owner | username +-[ RECORD 3 ]--------------------------------- +Schema | public +Name | badges +Type | table +Owner | username +-[ RECORD 4 ]--------------------------------- +Schema | public +Name | email_templates +Type | table +Owner | username +-[ RECORD 5 ]--------------------------------- +Schema | public +Name | geocoders +Type | table +Owner | username +-[ RECORD 6 ]--------------------------------- +Schema | public +Name | iso3166 +Type | table +Owner | username +-[ RECORD 7 ]--------------------------------- +Schema | public +Name | mid +Type | table +Owner | username +-[ RECORD 8 ]--------------------------------- +Schema | public +Name | ne_10m_geography_marine_polys +Type | table +Owner | username +-[ RECORD 9 ]--------------------------------- +Schema | public +Name | ne_10m_geography_marine_polys_gid_seq +Type | sequence +Owner | username +-[ RECORD 10 ]-------------------------------- +Schema | public +Name | process_queue +Type | table +Owner | username +-[ RECORD 11 ]-------------------------------- +Schema | public +Name | process_queue_id_seq +Type | sequence +Owner | username +-[ RECORD 12 ]-------------------------------- +Schema | public +Name | spatial_ref_sys +Type | table +Owner | username + +-[ RECORD 1 ]-------- +schema_api | logbook +-[ RECORD 2 ]-------- +schema_api | metadata +-[ RECORD 3 ]-------- +schema_api | metrics +-[ RECORD 4 ]-------- +schema_api | moorages +-[ RECORD 5 ]-------- +schema_api | stays +-[ RECORD 6 ]-------- +schema_api | stays_at + +-[ RECORD 1 ]-+------------------------------ +schema_public | aistypes +-[ RECORD 2 ]-+------------------------------ +schema_public | app_settings +-[ RECORD 3 ]-+------------------------------ +schema_public | badges +-[ RECORD 4 ]-+------------------------------ +schema_public | email_templates +-[ RECORD 5 ]-+------------------------------ +schema_public | geocoders +-[ RECORD 6 ]-+------------------------------ +schema_public | iso3166 +-[ RECORD 7 ]-+------------------------------ +schema_public | mid +-[ RECORD 8 ]-+------------------------------ +schema_public | ne_10m_geography_marine_polys +-[ RECORD 9 ]-+------------------------------ +schema_public | process_queue +-[ RECORD 10 ]+------------------------------ +schema_public | spatial_ref_sys + +-[ RECORD 1 ]--------- +schema_auth | accounts +-[ RECORD 2 ]--------- +schema_auth | otp +-[ RECORD 3 ]--------- +schema_auth | vessels + +(0 rows) + +List Row Security Policies +-[ RECORD 1 ]------------------------------------------------------------------------------------------------------------------------------ +schemaname | api +tablename | metadata +policyname | admin_all +permissive | PERMISSIVE +roles | {username} +cmd | ALL +qual | true +with_check | true +-[ RECORD 2 ]------------------------------------------------------------------------------------------------------------------------------ +schemaname | api +tablename | metadata +policyname | api_vessel_role +permissive | PERMISSIVE +roles | {vessel_role} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, false)) +with_check | true +-[ RECORD 3 ]------------------------------------------------------------------------------------------------------------------------------ +schemaname | api +tablename | metadata +policyname | api_user_role +permissive | PERMISSIVE +roles | {user_role} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, true)) +with_check | (vessel_id = current_setting('vessel.id'::text, false)) +-[ RECORD 4 ]------------------------------------------------------------------------------------------------------------------------------ +schemaname | api +tablename | metadata +policyname | api_scheduler_role +permissive | PERMISSIVE +roles | {scheduler} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, false)) +with_check | (vessel_id = current_setting('vessel.id'::text, false)) +-[ RECORD 5 ]------------------------------------------------------------------------------------------------------------------------------ +schemaname | api +tablename | metadata +policyname | grafana_role +permissive | PERMISSIVE +roles | {grafana} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, false)) +with_check | false +-[ RECORD 6 ]------------------------------------------------------------------------------------------------------------------------------ +schemaname | api +tablename | metadata +policyname | grafana_proxy_role +permissive | PERMISSIVE +roles | {grafana_auth} +cmd | ALL +qual | true +with_check | false +-[ RECORD 7 ]------------------------------------------------------------------------------------------------------------------------------ +schemaname | api +tablename | metrics +policyname | admin_all +permissive | PERMISSIVE +roles | {username} +cmd | ALL +qual | true +with_check | true +-[ RECORD 8 ]------------------------------------------------------------------------------------------------------------------------------ +schemaname | api +tablename | metrics +policyname | api_vessel_role +permissive | PERMISSIVE +roles | {vessel_role} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, false)) +with_check | true +-[ RECORD 9 ]------------------------------------------------------------------------------------------------------------------------------ +schemaname | api +tablename | moorages +policyname | admin_all +permissive | PERMISSIVE +roles | {username} +cmd | ALL +qual | true +with_check | true +-[ RECORD 10 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | api +tablename | metrics +policyname | api_user_role +permissive | PERMISSIVE +roles | {user_role} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, true)) +with_check | (vessel_id = current_setting('vessel.id'::text, false)) +-[ RECORD 11 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | api +tablename | metrics +policyname | api_scheduler_role +permissive | PERMISSIVE +roles | {scheduler} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, false)) +with_check | (vessel_id = current_setting('vessel.id'::text, false)) +-[ RECORD 12 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | api +tablename | metrics +policyname | grafana_role +permissive | PERMISSIVE +roles | {grafana} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, false)) +with_check | false +-[ RECORD 13 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | api +tablename | logbook +policyname | admin_all +permissive | PERMISSIVE +roles | {username} +cmd | ALL +qual | true +with_check | true +-[ RECORD 14 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | api +tablename | logbook +policyname | api_vessel_role +permissive | PERMISSIVE +roles | {vessel_role} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, false)) +with_check | true +-[ RECORD 15 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | api +tablename | logbook +policyname | api_user_role +permissive | PERMISSIVE +roles | {user_role} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, true)) +with_check | (vessel_id = current_setting('vessel.id'::text, false)) +-[ RECORD 16 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | auth +tablename | vessels +policyname | grafana_proxy_role +permissive | PERMISSIVE +roles | {grafana_auth} +cmd | ALL +qual | true +with_check | false +-[ RECORD 17 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | auth +tablename | accounts +policyname | admin_all +permissive | PERMISSIVE +roles | {username} +cmd | ALL +qual | true +with_check | true +-[ RECORD 18 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | api +tablename | logbook +policyname | api_scheduler_role +permissive | PERMISSIVE +roles | {scheduler} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, false)) +with_check | (vessel_id = current_setting('vessel.id'::text, false)) +-[ RECORD 19 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | api +tablename | logbook +policyname | grafana_role +permissive | PERMISSIVE +roles | {grafana} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, false)) +with_check | false +-[ RECORD 20 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | api +tablename | stays +policyname | admin_all +permissive | PERMISSIVE +roles | {username} +cmd | ALL +qual | true +with_check | true +-[ RECORD 21 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | api +tablename | stays +policyname | api_vessel_role +permissive | PERMISSIVE +roles | {vessel_role} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, false)) +with_check | true +-[ RECORD 22 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | api +tablename | stays +policyname | api_user_role +permissive | PERMISSIVE +roles | {user_role} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, true)) +with_check | (vessel_id = current_setting('vessel.id'::text, false)) +-[ RECORD 23 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | api +tablename | stays +policyname | api_scheduler_role +permissive | PERMISSIVE +roles | {scheduler} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, false)) +with_check | (vessel_id = current_setting('vessel.id'::text, false)) +-[ RECORD 24 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | api +tablename | stays +policyname | grafana_role +permissive | PERMISSIVE +roles | {grafana} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, false)) +with_check | false +-[ RECORD 25 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | api +tablename | moorages +policyname | api_vessel_role +permissive | PERMISSIVE +roles | {vessel_role} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, false)) +with_check | true +-[ RECORD 26 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | api +tablename | moorages +policyname | api_user_role +permissive | PERMISSIVE +roles | {user_role} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, true)) +with_check | (vessel_id = current_setting('vessel.id'::text, false)) +-[ RECORD 27 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | api +tablename | moorages +policyname | api_scheduler_role +permissive | PERMISSIVE +roles | {scheduler} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, false)) +with_check | (vessel_id = current_setting('vessel.id'::text, false)) +-[ RECORD 28 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | api +tablename | moorages +policyname | grafana_role +permissive | PERMISSIVE +roles | {grafana} +cmd | ALL +qual | (vessel_id = current_setting('vessel.id'::text, false)) +with_check | false +-[ RECORD 29 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | auth +tablename | vessels +policyname | admin_all +permissive | PERMISSIVE +roles | {username} +cmd | ALL +qual | true +with_check | true +-[ RECORD 30 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | auth +tablename | vessels +policyname | api_user_role +permissive | PERMISSIVE +roles | {user_role} +cmd | ALL +qual | ((vessel_id = current_setting('vessel.id'::text, true)) AND ((owner_email)::text = current_setting('user.email'::text, true))) +with_check | ((vessel_id = current_setting('vessel.id'::text, true)) AND ((owner_email)::text = current_setting('user.email'::text, true))) +-[ RECORD 31 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | auth +tablename | vessels +policyname | grafana_role +permissive | PERMISSIVE +roles | {grafana} +cmd | ALL +qual | ((owner_email)::text = current_setting('user.email'::text, true)) +with_check | false +-[ RECORD 32 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | auth +tablename | accounts +policyname | api_user_role +permissive | PERMISSIVE +roles | {user_role} +cmd | ALL +qual | ((email)::text = current_setting('user.email'::text, true)) +with_check | ((email)::text = current_setting('user.email'::text, true)) +-[ RECORD 33 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | auth +tablename | accounts +policyname | api_scheduler_role +permissive | PERMISSIVE +roles | {scheduler} +cmd | ALL +qual | ((email)::text = current_setting('user.email'::text, true)) +with_check | ((email)::text = current_setting('user.email'::text, true)) +-[ RECORD 34 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | auth +tablename | accounts +policyname | grafana_proxy_role +permissive | PERMISSIVE +roles | {grafana_auth} +cmd | ALL +qual | true +with_check | false +-[ RECORD 35 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | public +tablename | process_queue +policyname | admin_all +permissive | PERMISSIVE +roles | {username} +cmd | ALL +qual | true +with_check | true +-[ RECORD 36 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | public +tablename | process_queue +policyname | api_vessel_role +permissive | PERMISSIVE +roles | {vessel_role} +cmd | ALL +qual | ((ref_id = current_setting('user.id'::text, true)) OR (ref_id = current_setting('vessel.id'::text, true))) +with_check | true +-[ RECORD 37 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | public +tablename | process_queue +policyname | api_user_role +permissive | PERMISSIVE +roles | {user_role} +cmd | ALL +qual | ((ref_id = current_setting('user.id'::text, true)) OR (ref_id = current_setting('vessel.id'::text, true))) +with_check | ((ref_id = current_setting('user.id'::text, true)) OR (ref_id = current_setting('vessel.id'::text, true))) +-[ RECORD 38 ]----------------------------------------------------------------------------------------------------------------------------- +schemaname | public +tablename | process_queue +policyname | api_scheduler_role +permissive | PERMISSIVE +roles | {scheduler} +cmd | ALL +qual | true +with_check | false + +Test nominatim reverse_geocode_py_fn +-[ RECORD 1 ]---------+------- +reverse_geocode_py_fn | España + +Test geoip reverse_geoip_py_fn +-[ RECORD 1 ]---------------------------------------------------------------------------------------------------------------------------------------------- +versions_fn | {"api_version" : "0.2.3", "sys_version" : "PostgreSQL 15.4", "timescaledb" : "2.11.2", "postgis" : "3.4.0", "postgrest" : "PostgREST 11.2.0"} + +-[ RECORD 1 ]----------------- +api_version | 0.2.3 +sys_version | PostgreSQL 15.4 +timescaledb | 2.11.2 +postgis | 3.4.0 +postgrest | PostgREST 11.2.0 + diff --git a/tests/sql/telegram.sql b/tests/sql/telegram.sql new file mode 100644 index 0000000..cea6e5a --- /dev/null +++ b/tests/sql/telegram.sql @@ -0,0 +1,48 @@ +--------------------------------------------------------------------------- +-- Listing +-- + +-- List current database +select current_database(); + +-- connect to the DB +\c signalk + +-- output display format +\x on + +-- +-- telegram +SET ROLE username; +-- Does chat id session exist? +SELECT auth.telegram_session_exists_fn(1234567890); +SELECT auth.telegram_session_exists_fn(9876543210); +SELECT auth.telegram_session_exists_fn(1472583690); + +-- Assign vessel_id var +SELECT v.vessel_id as "vessel_id_kapla" FROM auth.vessels v WHERE v.owner_email = 'demo+kapla@openplotter.cloud' \gset +SELECT v.vessel_id as "vessel_id_aava" FROM auth.vessels v WHERE v.owner_email = 'demo+aava@openplotter.cloud' \gset + +SET ROLE api_anonymous; +SELECT api.telegram(1234567890::BIGINT) IS NOT NULL as telegram_session; +SELECT api.telegram(9876543210::BIGINT) IS NOT NULL as telegram_session; +SELECT api.telegram(1472583690::BIGINT) IS NULL as telegram_session; + +SET ROLE user_role; +SET "user.email" = 'demo+kapla@openplotter.cloud'; +--SET vessel.id = 'f94e995cf4d3'; +SELECT set_config('vessel.id', :'vessel_id_kapla', false) IS NOT NULL as vessel_id; +SET vessel.name = 'kapla'; +--SET vessel.client_id = 'vessels.urn:mrn:imo:mmsi:123456789'; +--SELECT * FROM api.vessels_view v; +SELECT name, mmsi, created_at IS NOT NULL as created_at, last_contact IS NOT NULL as last_contact FROM api.vessels_view v; +SELECT name,geojson,watertemperature,insidetemperature,outsidetemperature FROM api.monitoring_view m; + +SET "user.email" = 'demo+aava@openplotter.cloud'; +SELECT set_config('vessel.id', :'vessel_id_aava', false) IS NOT NULL as vessel_id; +--SET vessel.id = '341dcfa30afb'; +SET vessel.name = 'aava'; +--SET vessel.client_id = 'vessels.urn:mrn:imo:mmsi:787654321'; +--SELECT * FROM api.vessels_view v; +SELECT name, mmsi, created_at IS NOT NULL as created_at, last_contact IS NOT NULL as last_contact FROM api.vessels_view v; +SELECT name,geojson,watertemperature,insidetemperature,outsidetemperature FROM api.monitoring_view m; diff --git a/tests/sql/telegram.sql.output b/tests/sql/telegram.sql.output new file mode 100644 index 0000000..43917aa --- /dev/null +++ b/tests/sql/telegram.sql.output @@ -0,0 +1,64 @@ + current_database +------------------ + signalk +(1 row) + +You are now connected to database "signalk" as user "username". +Expanded display is on. +SET +-[ RECORD 1 ]--------------+-- +telegram_session_exists_fn | f + +-[ RECORD 1 ]--------------+-- +telegram_session_exists_fn | f + +-[ RECORD 1 ]--------------+-- +telegram_session_exists_fn | f + +SET +-[ RECORD 1 ]----+-- +telegram_session | f + +-[ RECORD 1 ]----+-- +telegram_session | f + +-[ RECORD 1 ]----+-- +telegram_session | t + +SET +SET +-[ RECORD 1 ] +vessel_id | t + +SET +-[ RECORD 1 ]+------ +name | kapla +mmsi | +created_at | t +last_contact | t + +-[ RECORD 1 ]------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +name | kapla +geojson | {"type": "Feature", "geometry": {"type": "Point", "coordinates": [23.365766667, 59.86]}, "properties": {"name": "kapla", "latitude": 59.86, "longitude": 23.365766666666666}} +watertemperature | +insidetemperature | +outsidetemperature | + +SET +-[ RECORD 1 ] +vessel_id | t + +SET +-[ RECORD 1 ]+---------- +name | aava +mmsi | 787654321 +created_at | t +last_contact | t + +-[ RECORD 1 ]------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +name | aava +geojson | {"type": "Feature", "geometry": {"type": "Point", "coordinates": [2.2934791, 41.465333283]}, "properties": {"name": "aava", "latitude": 41.46533328333334, "longitude": 2.2934791}} +watertemperature | 280.25 +insidetemperature | +outsidetemperature | + diff --git a/tests/tests.sh b/tests/tests.sh new file mode 100644 index 0000000..22621c3 --- /dev/null +++ b/tests/tests.sh @@ -0,0 +1,143 @@ +# PostgSail Unit test + +if [[ -z "${PGSAIL_DB_URI}" ]]; then + echo "PGSAIL_DB_URI is undefined" + exit 1 +fi +if [[ -z "${PGSAIL_API_URI}" ]]; then + echo "PGSAIL_API_URI is undefined" + exit 1 +fi + +#npm install +npm install -g pnpm && pnpm install +# settings +export mymocha="./node_modules/mocha/bin/_mocha" +mkdir -p output/ && rm -rf output/* + +$mymocha index.js --reporter ./node_modules/mochawesome --reporter-options reportDir=output/,reportFilename=report1.html +if [ $? -eq 0 ]; then + echo OK +else + echo mocha index.js + exit 1 +fi + +$mymocha index2.js --reporter ./node_modules/mochawesome --reporter-options reportDir=output/,reportFilename=report2.html +if [ $? -eq 0 ]; then + echo OK +else + echo mocha index2.js + exit 1 +fi + +# https://www.postgresql.org/docs/current/app-psql.html +# run cron jobs +#psql -U ${POSTGRES_USER} -h 172.30.0.1 signalk < sql/cron_run_jobs.sql > output/cron_run_jobs.sql.output +psql ${PGSAIL_DB_URI} < sql/cron_run_jobs.sql > output/cron_run_jobs.sql.output +diff sql/cron_run_jobs.sql.output output/cron_run_jobs.sql.output > /dev/null +#diff -u sql/cron_run_jobs.sql.output output/cron_run_jobs.sql.output | wc -l +#echo 0 +if [ $? -eq 0 ]; then + echo OK +else + echo SQL cron_run_jobs.sql FAILED + diff -u sql/cron_run_jobs.sql.output output/cron_run_jobs.sql.output + exit 1 +fi + +# handle post processing +#psql -U ${POSTGRES_USER} -h 172.30.0.1 signalk < sql/cron_post_jobs.sql > output/cron_post_jobs.sql.output +psql ${PGSAIL_DB_URI} < sql/cron_post_jobs.sql > output/cron_post_jobs.sql.output +diff sql/cron_post_jobs.sql.output output/cron_post_jobs.sql.output > /dev/null +#diff -u sql/cron_post_jobs.sql.output output/cron_post_jobs.sql.output | wc -l +#echo 0 +if [ $? -eq 0 ]; then + echo OK +else + echo SQL cron_post_jobs.sql FAILED + diff -u sql/cron_post_jobs.sql.output output/cron_post_jobs.sql.output + exit 1 +fi + +$mymocha index3.js --reporter ./node_modules/mochawesome --reporter-options reportDir=output/,reportFilename=report3.html +#echo 0 +if [ $? -eq 0 ]; then + echo OK +else + echo mocha index3.js + exit 1 +fi + +# Grafana Auth Proxy and role unit tests +psql ${PGSAIL_DB_URI} < sql/grafana.sql > output/grafana.sql.output +diff sql/grafana.sql.output output/grafana.sql.output > /dev/null +#diff -u sql/grafana.sql.output output/grafana.sql.output | wc -l +#echo 0 +if [ $? -eq 0 ]; then + echo OK +else + echo SQL grafana.sql FAILED + diff -u sql/grafana.sql.output output/grafana.sql.output + exit 1 +fi + +# Telegram and role unit tests +psql ${PGSAIL_DB_URI} < sql/telegram.sql > output/telegram.sql.output +diff sql/telegram.sql.output output/telegram.sql.output > /dev/null +#diff -u sql/telegram.sql.output output/telegram.sql.output | wc -l +#echo 0 +if [ $? -eq 0 ]; then + echo OK +else + echo SQL telegram.sql FAILED + diff -u sql/telegram.sql.output output/telegram.sql.output + exit 1 +fi + +# Badges unit tests +psql ${PGSAIL_DB_URI} < sql/badges.sql > output/badges.sql.output +diff sql/badges.sql.output output/badges.sql.output > /dev/null +#diff -u sql/badges.sql.output output/badges.sql.output | wc -l +#echo 0 +if [ $? -eq 0 ]; then + echo OK +else + echo SQL badges.sql FAILED + diff -u sql/badges.sql.output output/badges.sql.output + exit +fi + +# Summary unit tests +psql ${PGSAIL_DB_URI} < sql/summary.sql > output/summary.sql.output +diff sql/summary.sql.output output/summary.sql.output > /dev/null +#diff -u sql/summary.sql.output output/summary.sql.output | wc -l +#echo 0 +if [ $? -eq 0 ]; then + echo OK +else + echo SQL summary.sql FAILED + diff -u sql/summary.sql.output output/summary.sql.output + exit 1 +fi + +$mymocha index4.js --reporter ./node_modules/mochawesome --reporter-options reportDir=output/,reportFilename=report4.html +if [ $? -eq 0 ]; then + echo OK +else + echo mocha index4.js + exit 1 +fi + +# Monitoring unit tests +psql ${PGSAIL_DB_URI} < sql/monitoring.sql > output/monitoring.sql.output +diff sql/monitoring.sql.output output/monitoring.sql.output > /dev/null +#diff -u sql/monitoring.sql.output output/monitoring.sql.output | wc -l +#echo 0 +if [ $? -eq 0 ]; then + echo OK +else + echo SQL monitoring.sql FAILED + diff -u sql/monitoring.sql.output output/monitoring.sql.output + exit 1 +fi \ No newline at end of file