Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions server/app.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const express = require('express');
const {logInfoMsgPrefix, logWarnMsgPrefix, logErrorMsgPrefix} = require('./utils/utils');

Check warning on line 2 in server/app.js

View workflow job for this annotation

GitHub Actions / build (20.x)

'logErrorMsgPrefix' is assigned a value but never used

Check warning on line 2 in server/app.js

View workflow job for this annotation

GitHub Actions / build (20.x)

'logWarnMsgPrefix' is assigned a value but never used

Check warning on line 2 in server/app.js

View workflow job for this annotation

GitHub Actions / build (18.x)

'logErrorMsgPrefix' is assigned a value but never used

Check warning on line 2 in server/app.js

View workflow job for this annotation

GitHub Actions / build (18.x)

'logWarnMsgPrefix' is assigned a value but never used

Check warning on line 2 in server/app.js

View workflow job for this annotation

GitHub Actions / build (22.x)

'logErrorMsgPrefix' is assigned a value but never used

Check warning on line 2 in server/app.js

View workflow job for this annotation

GitHub Actions / build (22.x)

'logWarnMsgPrefix' is assigned a value but never used
const packageLock = require('./package-lock.json');
const { wellsMeasurements } = require('./measurements/payloadMeasurements');
const packageLock = require('./package-lock.json');

// route imports, see ./routes folder
const payloadRouter = require('./routes/payloadRoutes');
const adcsController = require('./routes/adcsRoutes');

const app = express();

Expand Down Expand Up @@ -50,5 +50,6 @@

// routes for each endpoint, see ./routes folder
app.use('/payload', payloadRouter);
app.use('/adcs', adcsController);

module.exports = app;
145 changes: 145 additions & 0 deletions server/controllers/adcsController.js
Original file line number Diff line number Diff line change
@@ -1,0 +1,145 @@
const { logInfoMsgPrefix, logWarnMsgPrefix, logErrorMsgPrefix } = require('../utils/utils');
const { magFieldMeasurements, angVelocityMeasurements, adcsTags, magFieldMeasurementsTag, magFieldMeasurementsFields, angVelocityMeasurementsTag, angVelocityMeasurementsFields } = require('../measurements/adcsMeasurements');

Check warning on line 2 in server/controllers/adcsController.js

View workflow job for this annotation

GitHub Actions / build (20.x)

'angVelocityMeasurementsFields' is assigned a value but never used

Check warning on line 2 in server/controllers/adcsController.js

View workflow job for this annotation

GitHub Actions / build (20.x)

'angVelocityMeasurementsTag' is assigned a value but never used

Check warning on line 2 in server/controllers/adcsController.js

View workflow job for this annotation

GitHub Actions / build (20.x)

'magFieldMeasurementsFields' is assigned a value but never used

Check warning on line 2 in server/controllers/adcsController.js

View workflow job for this annotation

GitHub Actions / build (20.x)

'magFieldMeasurementsTag' is assigned a value but never used

Check warning on line 2 in server/controllers/adcsController.js

View workflow job for this annotation

GitHub Actions / build (20.x)

'adcsTags' is assigned a value but never used

Check warning on line 2 in server/controllers/adcsController.js

View workflow job for this annotation

GitHub Actions / build (18.x)

'angVelocityMeasurementsFields' is assigned a value but never used

Check warning on line 2 in server/controllers/adcsController.js

View workflow job for this annotation

GitHub Actions / build (18.x)

'angVelocityMeasurementsTag' is assigned a value but never used

Check warning on line 2 in server/controllers/adcsController.js

View workflow job for this annotation

GitHub Actions / build (18.x)

'magFieldMeasurementsFields' is assigned a value but never used

Check warning on line 2 in server/controllers/adcsController.js

View workflow job for this annotation

GitHub Actions / build (18.x)

'magFieldMeasurementsTag' is assigned a value but never used

Check warning on line 2 in server/controllers/adcsController.js

View workflow job for this annotation

GitHub Actions / build (18.x)

'adcsTags' is assigned a value but never used

Check warning on line 2 in server/controllers/adcsController.js

View workflow job for this annotation

GitHub Actions / build (22.x)

'angVelocityMeasurementsFields' is assigned a value but never used

Check warning on line 2 in server/controllers/adcsController.js

View workflow job for this annotation

GitHub Actions / build (22.x)

'angVelocityMeasurementsTag' is assigned a value but never used

Check warning on line 2 in server/controllers/adcsController.js

View workflow job for this annotation

GitHub Actions / build (22.x)

'magFieldMeasurementsFields' is assigned a value but never used

Check warning on line 2 in server/controllers/adcsController.js

View workflow job for this annotation

GitHub Actions / build (22.x)

'magFieldMeasurementsTag' is assigned a value but never used

Check warning on line 2 in server/controllers/adcsController.js

View workflow job for this annotation

GitHub Actions / build (22.x)

'adcsTags' is assigned a value but never used

/**
* adcs.js
* @brief This file contains the controller functions for the ADCS API
*/

const getMagFieldData = async (req, res) => {
console.log(logInfoMsgPrefix('ADCS magnetic field check'), 'request_body:', req.body);
const variant = req.params.variant;
let { start, end } = req.query; // extract query parameters

// check if variant is provided, shouldn't happen
if (!variant) {
console.log(logWarnMsgPrefix('Variant number not provided'));
res.status(400).json({ error: 'Variant number not provided' });
return;
}

// check if variant is valid
if (variant < 1 || variant > 2) {
console.log(logWarnMsgPrefix(`Invalid variant number provided: ${variant}`));
res.status(400).json({ error: 'Invalid variant number provided, must be between 1 and 16' });
return;
}

// TODO: should be written into utils/utils.js
// check if start and end are provided, if not, set them to null
// time stamp format is in RFC3339 format, e.g. 2023-10-01T00:00:00Z
if (!start || !end) {
console.log(logWarnMsgPrefix('Start or end time not provided'));
res.status(400).json({ error: 'Start and end time must be provided' });
return;
} else {
// check if start and end are in valid RFC3339 format
const dateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/; // RFC3339 format: YYYY-MM-DDTHH:MM:SSZ
if (!dateRegex.test(start) || !dateRegex.test(end)) {
console.log(logWarnMsgPrefix(`Invalid date format provided: start=${start}, end=${end}`));
res.status(400).json({ error: 'Invalid date format provided, must be in RFC3339 format' });
return;
}

// convert start and end to Date objects to validate
const startDate = new Date(start);
const endDate = new Date(end);
// end date must be after start date
if (endDate <= startDate) {
console.log(logWarnMsgPrefix(`End date must be after start date: start=${start}, end=${end}`));
res.status(400).json({ error: 'End date must be after start date' });
return;
}
}

try {
const data = await magFieldMeasurements(variant, start, end);
console.log(logInfoMsgPrefix('ADCS magnetic field data fetched successfully'));
res.status(200).json({
variant: variant,
start: start,
end: end,
data: data
});
} catch (error) {
console.error(logErrorMsgPrefix('Error fetching ADCS magnetic field data'), error);
res.status(500).json({ error: 'Internal server error' });
}
};

const getAngVelocityData = async (req, res) => {
console.log(logInfoMsgPrefix('ADCS angular velocityy check'), 'request_body:', req.body);
const variant = req.params.variant;
let { start, end } = req.query; // extract query parameters

// check if variant is provided, shouldn't happen
if (!variant) {
console.log(logWarnMsgPrefix('Variant number not provided'));
res.status(400).json({ error: 'Variant number not provided' });
return;
}

// check if variant is valid
if (variant < 1 || variant > 2) {
console.log(logWarnMsgPrefix(`Invalid variant number provided: ${variant}`));
res.status(400).json({ error: 'Invalid variant number provided, must be between 1 and 16' });
return;
}

// TODO: should be written into utils/utils.js
// check if start and end are provided, if not, set them to null
// time stamp format is in RFC3339 format, e.g. 2023-10-01T00:00:00Z
if (!start || !end) {
console.log(logWarnMsgPrefix('Start or end time not provided'));
res.status(400).json({ error: 'Start and end time must be provided' });
return;
} else {
// check if start and end are in valid RFC3339 format
const dateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/; // RFC3339 format: YYYY-MM-DDTHH:MM:SSZ
if (!dateRegex.test(start) || !dateRegex.test(end)) {
console.log(logWarnMsgPrefix(`Invalid date format provided: start=${start}, end=${end}`));
res.status(400).json({ error: 'Invalid date format provided, must be in RFC3339 format' });
return;
}

// convert start and end to Date objects to validate
const startDate = new Date(start);
const endDate = new Date(end);
// end date must be after start date
if (endDate <= startDate) {
console.log(logWarnMsgPrefix(`End date must be after start date: start=${start}, end=${end}`));
res.status(400).json({ error: 'End date must be after start date' });
return;
}
}

try {
const data = await angVelocityMeasurements(variant, start, end);
console.log(logInfoMsgPrefix('ADCS angular velocity data fetched successfully'));
res.status(200).json({
variant: variant,
start: start,
end: end,
data: data
});
} catch (error) {
console.error(logErrorMsgPrefix('Error fetching ADCS angular velocity data'), error);
res.status(500).json({ error: 'Internal server error' });
}
};

/**
* @brief This function is used to get the measurement of the magnetic field, the data is fetched from the database
* @param variant The variant number
* @query start The start time of the period to get the data
* @query end The end time of the period to get the data
*/
exports.magFieldMeasurements = async (req, res) => getMagFieldData(req, res);

/**
* @brief This function is used to get the measurement of the angular velocity, the data is fetched from the database
* @param variant The variant number
* @query start The start time of the period to get the data
* @query end The end time of the period to get the data
*/
exports.angVelocityMeasurements = async (req, res) => getAngVelocityData(req, res);
38 changes: 38 additions & 0 deletions server/docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,41 @@
- end
- end time of the query range
- must in seconds-only RFC3339 date format

### ADCS

#### Magnetic Field

- /adcs/magf/{:variant number}?{start}&{end}
- must have start and end query parameters with seconds-only RFC3339 date format (no fractional seconds)
- will return magnetic field telemetry of the given period
- includes:
- XYZ LSBs (00XXYYZZ)
- X-value MSB
- Y-value MSB
- Z-value MSB
- query parameters
- start
- start time of the query range
- must in seconds-only RFC3339 date format
- end
- end time of the query range
- must in seconds-only RFC3339 date format

#### Angular Velocity

- /adcs/angv/{:variant number}?{start}&{end}
- must have start and end query parameters with seconds-only RFC3339 date format (no fractional seconds)
- will return angular velocity telemetry of the given period
- includes:
- X-value
- Y-value
- Z-value
- query parameters
- start
- start time of the query range
- must in seconds-only RFC3339 date format
- end
- end time of the query range
- must in seconds-only RFC3339 date format

89 changes: 89 additions & 0 deletions server/measurements/adcsMeasurements.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
const { queryApi } = require('../db/dbSingleton');
const { db_bucket } = require('../config/env');
const { logInfoMsgPrefix, logWarnMsgPrefix, logErrorMsgPrefix } = require('../utils/utils');

/**
* adcsMeasurements.js
* @brief This file contains the functions to fetch ADCS related measurements
*/

// Tag for the ADCS
const adcsTags = 'ADCS';
// Tag for the magnetic field measurements
const magFieldMeasurementsTag = 'magField';
// fields for the magnetic field measurements
const magFieldMeasurementsFields = {
LSB: 'LSB',
X: 'X',
Y: 'Y',
Z: 'Z'
};
// Tag for the angular velocity measurements
const angVelocityMeasurementsTag = 'angVelocity';
// fields for the angular velocity measurements
const angVelocityMeasurementsFields = {
X: 'X',
Y: 'Y',
Z: 'Z'
};

async function magFieldMeasurements(variant_num, start, end) {
const query = `from(bucket: "${db_bucket}")
|> range(start: ${start}, stop: ${end})
|> filter(fn: (r) => r["_measurement"] == "${magFieldMeasurementsTag}")
|> filter(fn: (r) => r["host"] == "${adcsTags}")
|> filter(fn: (r) => r["variant"] == "${variant_num}")
|> keep(columns: ["_time", "_value", "variant", _field])
|> group(columns: ["_time])`;
return new Promise((resolve, reject) => {
let result = [];
queryApi.queryRows(query, {
next(row, tableMeta) {
const o = tableMeta.toObject(row);
result.push(o);
},
error(error) {
reject(error);
},
complete() {
resolve(result);
}
});
});
}

async function angVelocityMeasurements(variant_num, start, end) {
const query = `from(bucket: "${db_bucket}")
|> range(start: ${start}, stop: ${end})
|> filter(fn: (r) => r["_measurement"] == "${angVelocityMeasurementsTag}")
|> filter(fn: (r) => r["host"] == "${adcsTags}")
|> filter(fn: (r) => r["variant"] == "${variant_num}")
|> keep(columns: ["_time", "_value", "variant", "_field"])
|> group(columns: ["_time"])`;

return new Promise((resolve, reject) => {
let result = [];
queryApi.queryRows(query, {
next(row, tableMeta) {
const o = tableMeta.toObject(row);
result.push(o);
},
error(error) {
reject(error);
},
complete() {
resolve(result);
}
})
})
}

module.exports = {
magFieldMeasurements,
angVelocityMeasurements,
adcsTags,
magFieldMeasurementsTag,
magFieldMeasurementsFields,
angVelocityMeasurementsTag,
angVelocityMeasurementsFields
};
27 changes: 27 additions & 0 deletions server/routes/adcsRoutes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const express = require('express');
const adcsController = require('../controllers/adcsController');

const router = express.Router();

/**
* adcsRoutes.js
* @brief This file contains the routes for the ADCS API
*/

/**
* @brief This route is used to get the magnetic field data of a variant
* @param variant The variant number
* @query start The start time of the period to get the data
* @query end The end time of the period to get the data
*/
router.route('/magf/:variant').get(adcsController.magFieldMeasurements);

/**
* @brief This route is used to get the angular velocity data of a variant
* @param variant The variant number
* @query start The start time of the period to get the data
* @query end The end time of the period to get the data
*/
router.route('/angv/:variant').get(adcsController.angVelocityMeasurements);

module.exports = router;
5 changes: 4 additions & 1 deletion tools/telemetryInputCli/.env
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ DB_PASSWORD = "adminPassword"
DB_TOKEN = "umsatsAdminToken"
PAYLOAD_TAG = "Payload"
WELL_TEMP_FIELD = "temp"
WELL_LUMIN_FIELD = "lumin"
WELL_LUMIN_FIELD = "lumin"
ADCS_TAG = "ADCS"
MAG_FIELD = "magfield"
ANG_VEL = "angvel"
3 changes: 2 additions & 1 deletion tools/telemetryInputCli/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
*.csv

!examples/data_temp.csv
!examples/data_lumin.csv
!examples/data_lumin.csv
!examples/data_angvel.csv
19 changes: 18 additions & 1 deletion tools/telemetryInputCli/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,21 @@ tables: # for read the data frame file
columns:
- timestamp
- well_num
- luminosity
- luminosity

- name: angvel
columns:
- variant
- timestamp
- X
- Y
- Z

- name: magfield
columns:
- variant
- timestamp
- LSB
- X
- Y
- Z
7 changes: 7 additions & 0 deletions tools/telemetryInputCli/examples/data_angvel.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
timestamp,variant,X,Y,Z
1756749600,1,3,4,1
1756749600,2,3,5,6
1756836000,1,4,7,5
1756836000,2,7,1,7
1756922400,1,2,1,6
1756922400,2,7,5,4
Loading
Loading