From 847675f91279cbf279d0e781d91defb920e52b20 Mon Sep 17 00:00:00 2001 From: whatdoes3plus1equalsto Date: Thu, 2 Oct 2025 00:39:23 -0400 Subject: [PATCH 1/9] ran into sql blocker --- server/app.js | 5 +- server/controllers/adcsController.js | 84 ++++++++++++++++++++ server/docs/api.md | 38 +++++++++ server/measurements/adcsMeasurements.js | 62 +++++++++++++++ server/routes/adcsRoutes.js | 27 +++++++ tools/telemetryInputCli/.env | 4 +- tools/telemetryInputCli/telemetryInputCli.py | 25 ++++++ 7 files changed, 242 insertions(+), 3 deletions(-) diff --git a/server/app.js b/server/app.js index 3159026..fbf65e7 100644 --- a/server/app.js +++ b/server/app.js @@ -1,10 +1,10 @@ const express = require('express'); const {logInfoMsgPrefix, logWarnMsgPrefix, logErrorMsgPrefix} = require('./utils/utils'); -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(); @@ -50,5 +50,6 @@ app.get("/health", (req, res) => { // routes for each endpoint, see ./routes folder app.use('/payload', payloadRouter); +app.use('/adcs', adcsController); module.exports = app; \ No newline at end of file diff --git a/server/controllers/adcsController.js b/server/controllers/adcsController.js index e69de29..326de59 100644 --- a/server/controllers/adcsController.js +++ b/server/controllers/adcsController.js @@ -0,0 +1,84 @@ +const { logInfoMsgPrefix, logWarnMsgPrefix, logErrorMsgPrefix } = require('../utils/utils'); +const { magFieldMeasurements, adcsTags, magFieldMeasurementsTag, magFieldMeasurementsFields, angVelocityMeasurementsTag, angVelocityMeasurementsFields } = require('../measurements/adcsMeasurements'); + +/** + * 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' }); + } +}; + +/** + * @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) => {}; + +/** + * @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) => {}; \ No newline at end of file diff --git a/server/docs/api.md b/server/docs/api.md index f68f3cf..2e65460 100644 --- a/server/docs/api.md +++ b/server/docs/api.md @@ -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 + \ No newline at end of file diff --git a/server/measurements/adcsMeasurements.js b/server/measurements/adcsMeasurements.js index e69de29..8316e81 100644 --- a/server/measurements/adcsMeasurements.js +++ b/server/measurements/adcsMeasurements.js @@ -0,0 +1,62 @@ +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); + } + }); + }); +} + +module.exports = { + magFieldMeasurements, + adcsTags, + magFieldMeasurementsTag, + magFieldMeasurementsFields, + angVelocityMeasurementsTag, + angVelocityMeasurementsFields +}; \ No newline at end of file diff --git a/server/routes/adcsRoutes.js b/server/routes/adcsRoutes.js index e69de29..6ae169b 100644 --- a/server/routes/adcsRoutes.js +++ b/server/routes/adcsRoutes.js @@ -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; \ No newline at end of file diff --git a/tools/telemetryInputCli/.env b/tools/telemetryInputCli/.env index f800734..01ea365 100644 --- a/tools/telemetryInputCli/.env +++ b/tools/telemetryInputCli/.env @@ -6,4 +6,6 @@ DB_PASSWORD = "adminPassword" DB_TOKEN = "umsatsAdminToken" PAYLOAD_TAG = "Payload" WELL_TEMP_FIELD = "temp" -WELL_LUMIN_FIELD = "lumin" \ No newline at end of file +WELL_LUMIN_FIELD = "lumin" +ADCS_TAG = "ADCS" +MAG_FIELD = "magField" \ No newline at end of file diff --git a/tools/telemetryInputCli/telemetryInputCli.py b/tools/telemetryInputCli/telemetryInputCli.py index ac5417b..744c630 100644 --- a/tools/telemetryInputCli/telemetryInputCli.py +++ b/tools/telemetryInputCli/telemetryInputCli.py @@ -38,6 +38,11 @@ def insertDataIntoWell(well: int, field: str, data: float, time: datetime, host: point = Point("well").tag("well", well).field(field, data).time(time, WritePrecision.NS).tag("host", host) write_api.write(bucket, org, point) +# insert data into magnetic field +def insertDataIntoMagField(variant: int, lsb: float, x: float, y: float, z: float, time: datetime, host: str, write_api, bucket: str, org: str): + point = Point("magField").tag("variant", variant).field("LSB", lsb).field("X", x).field("Y", y).field("Z", z).time(time, WritePrecision.NS).tag("host", host) + write_api.write(bucket, org, point) + class TelemetryInputCli(cmd.Cmd): # Set up the CLI url = config.get('URL') @@ -49,6 +54,8 @@ class TelemetryInputCli(cmd.Cmd): payloadTag = config.get('PAYLOAD_TAG') wellTempField = config.get('WELL_TEMP_FIELD') wellLuminField = config.get('WELL_LUMIN_FIELD') + adcsTag = config.get('ADCS_TAG') + magField = config.get('MAG_FIELD') client = InfluxDBClient(url=url, token=token, org=org) write_api = client.write_api(write_options=SYNCHRONOUS) prompt = '> ' @@ -79,6 +86,11 @@ def do_insert_lumin_well(self, arg): 'Insert luminance data into a specific well with specified time' self.insert_data_into_well(self.wellLuminField) + # insert magnetic field data with specified time + def do_insert_mag_field(self, arg): + 'Insert magnetic field data with specified time' + self.insert_data_into_mag_field(self.magField) + # helper function to insert data into all wells def insert_data_into_wells(self, field): period = askingForPeriod() @@ -103,6 +115,19 @@ def insert_data_into_well(self, field): insertDataIntoWell(well, field, data, calculatedTime, self.payloadTag, self.write_api, self.bucket, self.org) print("Data inserted successfully") + # helper function to insert magnetic field data + def insert_data_into_mag_field(self, field): + period = askingForPeriod() + calculatedTime = datetime.now(timezone.utc) - parsePeriod(period) + variant = int(input("Please enter the variant number: ")) # TODO: should be limited to 2 + lsb = float(input("Please enter the LSB value: ")) + x = float(input("Please enter the X value: ")) + y = float(input("Please enter the Y value: ")) + z = float(input("Please enter the Z value: ")) + + insertDataIntoMagField(variant, lsb, x, y, z, calculatedTime, self.adcsTag, self.write_api, self.bucket, self.org) + print("Magnetic field data inserted successfully") + # helper function to get data from user def get_data_from_user(self): print("Please enter the data you want to insert: ") From 3d4c8257bbd7c1d036efc4ef7b7c1102ce8bc55a Mon Sep 17 00:00:00 2001 From: whatdoes3plus1equalsto Date: Thu, 2 Oct 2025 00:39:23 -0400 Subject: [PATCH 2/9] ran into sql blocker --- server/app.js | 5 +- server/controllers/adcsController.js | 84 ++++++++++++++++++++ server/docs/api.md | 38 +++++++++ server/measurements/adcsMeasurements.js | 62 +++++++++++++++ server/routes/adcsRoutes.js | 27 +++++++ tools/telemetryInputCli/.env | 4 +- tools/telemetryInputCli/telemetryInputCli.py | 13 +++ 7 files changed, 230 insertions(+), 3 deletions(-) diff --git a/server/app.js b/server/app.js index 3159026..fbf65e7 100644 --- a/server/app.js +++ b/server/app.js @@ -1,10 +1,10 @@ const express = require('express'); const {logInfoMsgPrefix, logWarnMsgPrefix, logErrorMsgPrefix} = require('./utils/utils'); -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(); @@ -50,5 +50,6 @@ app.get("/health", (req, res) => { // routes for each endpoint, see ./routes folder app.use('/payload', payloadRouter); +app.use('/adcs', adcsController); module.exports = app; \ No newline at end of file diff --git a/server/controllers/adcsController.js b/server/controllers/adcsController.js index e69de29..326de59 100644 --- a/server/controllers/adcsController.js +++ b/server/controllers/adcsController.js @@ -0,0 +1,84 @@ +const { logInfoMsgPrefix, logWarnMsgPrefix, logErrorMsgPrefix } = require('../utils/utils'); +const { magFieldMeasurements, adcsTags, magFieldMeasurementsTag, magFieldMeasurementsFields, angVelocityMeasurementsTag, angVelocityMeasurementsFields } = require('../measurements/adcsMeasurements'); + +/** + * 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' }); + } +}; + +/** + * @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) => {}; + +/** + * @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) => {}; \ No newline at end of file diff --git a/server/docs/api.md b/server/docs/api.md index f68f3cf..2e65460 100644 --- a/server/docs/api.md +++ b/server/docs/api.md @@ -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 + \ No newline at end of file diff --git a/server/measurements/adcsMeasurements.js b/server/measurements/adcsMeasurements.js index e69de29..8316e81 100644 --- a/server/measurements/adcsMeasurements.js +++ b/server/measurements/adcsMeasurements.js @@ -0,0 +1,62 @@ +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); + } + }); + }); +} + +module.exports = { + magFieldMeasurements, + adcsTags, + magFieldMeasurementsTag, + magFieldMeasurementsFields, + angVelocityMeasurementsTag, + angVelocityMeasurementsFields +}; \ No newline at end of file diff --git a/server/routes/adcsRoutes.js b/server/routes/adcsRoutes.js index e69de29..6ae169b 100644 --- a/server/routes/adcsRoutes.js +++ b/server/routes/adcsRoutes.js @@ -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; \ No newline at end of file diff --git a/tools/telemetryInputCli/.env b/tools/telemetryInputCli/.env index f800734..01ea365 100644 --- a/tools/telemetryInputCli/.env +++ b/tools/telemetryInputCli/.env @@ -6,4 +6,6 @@ DB_PASSWORD = "adminPassword" DB_TOKEN = "umsatsAdminToken" PAYLOAD_TAG = "Payload" WELL_TEMP_FIELD = "temp" -WELL_LUMIN_FIELD = "lumin" \ No newline at end of file +WELL_LUMIN_FIELD = "lumin" +ADCS_TAG = "ADCS" +MAG_FIELD = "magField" \ No newline at end of file diff --git a/tools/telemetryInputCli/telemetryInputCli.py b/tools/telemetryInputCli/telemetryInputCli.py index 14426c6..fbde33e 100644 --- a/tools/telemetryInputCli/telemetryInputCli.py +++ b/tools/telemetryInputCli/telemetryInputCli.py @@ -200,6 +200,19 @@ def insert_data_from_df(self, table:str, filePath:str): return print(f"Data from {filePath} inserted into {table} table successfully.") + # helper function to insert magnetic field data + def insert_data_into_mag_field(self, field): + period = askingForPeriod() + calculatedTime = datetime.now(timezone.utc) - parsePeriod(period) + variant = int(input("Please enter the variant number: ")) # TODO: should be limited to 2 + lsb = float(input("Please enter the LSB value: ")) + x = float(input("Please enter the X value: ")) + y = float(input("Please enter the Y value: ")) + z = float(input("Please enter the Z value: ")) + + insertDataIntoMagField(variant, lsb, x, y, z, calculatedTime, self.adcsTag, self.write_api, self.bucket, self.org) + print("Magnetic field data inserted successfully") + # helper function to get data from user def get_data_from_user(self): print("Please enter the data you want to insert: ") From 2c4adcdf5a4e542083d17a98e276c11ac440ae13 Mon Sep 17 00:00:00 2001 From: Anton Frank Date: Mon, 20 Oct 2025 23:29:10 -0500 Subject: [PATCH 3/9] Added Angular Velocity Functions Added Angular Velocity Functions, worked on CLI a bit, needs more work, some things will need to be rewritten likely. --- server/controllers/adcsController.js | 67 +++++++++++++++++++- server/measurements/adcsMeasurements.js | 28 ++++++++ tools/telemetryInputCli/.env | 3 +- tools/telemetryInputCli/telemetryInputCli.py | 40 +++++++++++- 4 files changed, 131 insertions(+), 7 deletions(-) diff --git a/server/controllers/adcsController.js b/server/controllers/adcsController.js index 326de59..b41ce5b 100644 --- a/server/controllers/adcsController.js +++ b/server/controllers/adcsController.js @@ -1,5 +1,5 @@ const { logInfoMsgPrefix, logWarnMsgPrefix, logErrorMsgPrefix } = require('../utils/utils'); -const { magFieldMeasurements, adcsTags, magFieldMeasurementsTag, magFieldMeasurementsFields, angVelocityMeasurementsTag, angVelocityMeasurementsFields } = require('../measurements/adcsMeasurements'); +const { magFieldMeasurements, angVelocityMeasurements, adcsTags, magFieldMeasurementsTag, magFieldMeasurementsFields, angVelocityMeasurementsTag, angVelocityMeasurementsFields } = require('../measurements/adcsMeasurements'); /** * adcs.js @@ -67,13 +67,74 @@ const getMagFieldData = async (req, res) => { } }; +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) => {}; +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 @@ -81,4 +142,4 @@ exports.magFieldMeasurements = async (req, res) => {}; * @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) => {}; \ No newline at end of file +exports.angVelocityMeasurements = async (req, res) => getAngVelocityData(req, res); \ No newline at end of file diff --git a/server/measurements/adcsMeasurements.js b/server/measurements/adcsMeasurements.js index 8316e81..89d12c1 100644 --- a/server/measurements/adcsMeasurements.js +++ b/server/measurements/adcsMeasurements.js @@ -35,6 +35,7 @@ async function magFieldMeasurements(variant_num, start, end) { |> 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, { @@ -52,8 +53,35 @@ async function magFieldMeasurements(variant_num, start, end) { }); } +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, diff --git a/tools/telemetryInputCli/.env b/tools/telemetryInputCli/.env index 01ea365..9872aff 100644 --- a/tools/telemetryInputCli/.env +++ b/tools/telemetryInputCli/.env @@ -8,4 +8,5 @@ PAYLOAD_TAG = "Payload" WELL_TEMP_FIELD = "temp" WELL_LUMIN_FIELD = "lumin" ADCS_TAG = "ADCS" -MAG_FIELD = "magField" \ No newline at end of file +MAG_FIELD = "magField" +ANG_VEL = "angVelocity" \ No newline at end of file diff --git a/tools/telemetryInputCli/telemetryInputCli.py b/tools/telemetryInputCli/telemetryInputCli.py index fbde33e..56b4ce1 100644 --- a/tools/telemetryInputCli/telemetryInputCli.py +++ b/tools/telemetryInputCli/telemetryInputCli.py @@ -63,6 +63,15 @@ def insertDataIntoWell(well: int, field: str, data: float, time: datetime, host: point = Point("well").tag("well", well).field(field, data).time(time, WritePrecision.NS).tag("host", host) write_api.write(bucket, org, point) +# insert data into magnetic field +def insertDataIntoMagField(variant: int, lsb: float, x: float, y: float, z: float, time: datetime, host: str, write_api, bucket: str, org: str): + point = Point("magField").tag("variant", variant).field("LSB", lsb).field("X", x).field("Y", y).field("Z", z).time(time, WritePrecision.NS).tag("host", host) + write_api.write(bucket, org, point) + +def insertDataIntoAngVelocity(variant: int, x: float, y: float, z: float, time: datetime, host: str, write_api, bucket: str, org: str): + point = Point("angVelocity").tag("variant", variant).field("X", x).field("Y", y).field("Z", z).time(time, WritePrecision.NS).tag("host", host) + write_api.write(bucket, org, point) + # ask for file path def askingForFilePath() -> str: path = input("Please enter the file path: ") @@ -87,6 +96,8 @@ class TelemetryInputCli(cmd.Cmd): payloadTag = env.get('PAYLOAD_TAG') wellTempField = env.get('WELL_TEMP_FIELD') wellLuminField = env.get('WELL_LUMIN_FIELD') + magField = env.get('MAG_FIELD') + angVelocity = env.get('ANG_VEL') client = InfluxDBClient(url=url, token=token, org=org) write_api = client.write_api(write_options=SYNCHRONOUS) prompt = '> ' @@ -200,19 +211,42 @@ def insert_data_from_df(self, table:str, filePath:str): return print(f"Data from {filePath} inserted into {table} table successfully.") + # do_insert_data_into_mag_field and do_insert_data_into_angular_velocity need a + # more work, definitely need to rewrite some code, just wanted to get something + # "working" for the moment. + # Both of the following functions show up as "undocumented" in the CLI for the moment. + # helper function to insert magnetic field data - def insert_data_into_mag_field(self, field): + def do_insert_data_into_mag_field(self, field): + adcsTag = os.getenv("ADCS_TAG") # I don't like this, will probably do it another way period = askingForPeriod() calculatedTime = datetime.now(timezone.utc) - parsePeriod(period) - variant = int(input("Please enter the variant number: ")) # TODO: should be limited to 2 + variant = int(input("Please enter the variant number: ")) + while (variant != 1 and variant != 2): + variant = int(input("Please enter the variant number: ")) lsb = float(input("Please enter the LSB value: ")) x = float(input("Please enter the X value: ")) y = float(input("Please enter the Y value: ")) z = float(input("Please enter the Z value: ")) - insertDataIntoMagField(variant, lsb, x, y, z, calculatedTime, self.adcsTag, self.write_api, self.bucket, self.org) + insertDataIntoMagField(variant, lsb, x, y, z, calculatedTime, adcsTag, self.write_api, self.bucket, self.org) print("Magnetic field data inserted successfully") + # helper function to insert angular velocity data + def do_insert_data_into_angular_velocity(self, field): + adcsTag = os.getenv("ADCS_TAG") + period = askingForPeriod() + calculatedTime = datetime.now(timezone.utc) - parsePeriod(period) + variant = int(input("Please enter the variant number: ")) + while (variant != 1 and variant != 2): + variant = int(input("Please enter the variant number: ")) + x = float(input("Please enter the X value: ")) + y = float(input("Please enter the Y value: ")) + z = float(input("Please enter the Z value: ")) + + insertDataIntoAngVelocity(variant, x, y, z, calculatedTime, adcsTag, self.write_api, self.bucket, self.org) + print("Angular Velocity Data inserted successfully") + # helper function to get data from user def get_data_from_user(self): print("Please enter the data you want to insert: ") From e428b9cd8c5e0662d991a1f3ac3a1fc35c83839d Mon Sep 17 00:00:00 2001 From: Anton Frank Date: Mon, 20 Oct 2025 23:50:44 -0500 Subject: [PATCH 4/9] Update telemetryInputCli.py --- tools/telemetryInputCli/telemetryInputCli.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/telemetryInputCli/telemetryInputCli.py b/tools/telemetryInputCli/telemetryInputCli.py index aeeb5fc..8c658ed 100644 --- a/tools/telemetryInputCli/telemetryInputCli.py +++ b/tools/telemetryInputCli/telemetryInputCli.py @@ -229,7 +229,6 @@ def insert_data_from_df(self, table:str, filePath:str): # helper function to insert magnetic field data def insert_data_into_mag_field(self, field): - adcsTag = os.getenv("ADCS_TAG") # I don't like this, will probably do it another way period = askingForPeriod() calculatedTime = datetime.now(timezone.utc) - parsePeriod(period) variant = int(input("Please enter the variant number: ")) @@ -240,12 +239,11 @@ def insert_data_into_mag_field(self, field): y = float(input("Please enter the Y value: ")) z = float(input("Please enter the Z value: ")) - insertDataIntoMagField(variant, lsb, x, y, z, calculatedTime, adcsTag, self.write_api, self.bucket, self.org) + insertDataIntoMagField(variant, lsb, x, y, z, calculatedTime, self.adcsTag, self.write_api, self.bucket, self.org) print("Magnetic field data inserted successfully") # helper function to insert angular velocity data def insert_data_into_angular_velocity(self, field): - adcsTag = os.getenv("ADCS_TAG") period = askingForPeriod() calculatedTime = datetime.now(timezone.utc) - parsePeriod(period) variant = int(input("Please enter the variant number: ")) @@ -255,7 +253,7 @@ def insert_data_into_angular_velocity(self, field): y = float(input("Please enter the Y value: ")) z = float(input("Please enter the Z value: ")) - insertDataIntoAngVelocity(variant, x, y, z, calculatedTime, adcsTag, self.write_api, self.bucket, self.org) + insertDataIntoAngVelocity(variant, x, y, z, calculatedTime, self.adcsTag, self.write_api, self.bucket, self.org) print("Angular Velocity Data inserted successfully") # helper function to get data from user From 70e92600b952a13b86dce906e8b1460f6cceacd9 Mon Sep 17 00:00:00 2001 From: Anton Frank Date: Wed, 29 Oct 2025 21:50:03 -0500 Subject: [PATCH 5/9] ADCS Data is now Inserted into DB ADCS Data can now be inserted into the database through the CLI's bulk_insert command, changes are reflected in the admin panel for the db. --- server/measurements/adcsMeasurements.js | 2 +- tools/telemetryInputCli/.env | 4 +-- tools/telemetryInputCli/config.yaml | 19 +++++++++- tools/telemetryInputCli/telemetryInputCli.py | 38 ++++++++++++++++---- 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/server/measurements/adcsMeasurements.js b/server/measurements/adcsMeasurements.js index 0685100..a59d9cd 100644 --- a/server/measurements/adcsMeasurements.js +++ b/server/measurements/adcsMeasurements.js @@ -1,4 +1,4 @@ -const {queryApi} = require('../db/dbSingleton'); +const { queryApi } = require('../db/dbSingleton'); const { db_bucket } = require('../config/env'); const { logInfoMsgPrefix, logWarnMsgPrefix, logErrorMsgPrefix } = require('../utils/utils'); diff --git a/tools/telemetryInputCli/.env b/tools/telemetryInputCli/.env index 5697ca7..11ed37b 100644 --- a/tools/telemetryInputCli/.env +++ b/tools/telemetryInputCli/.env @@ -8,5 +8,5 @@ PAYLOAD_TAG = "Payload" WELL_TEMP_FIELD = "temp" WELL_LUMIN_FIELD = "lumin" ADCS_TAG = "ADCS" -MAG_FIELD = "magField" -ANG_VEL = "angVelocity" +MAG_FIELD = "magfield" +ANG_VEL = "angvel" diff --git a/tools/telemetryInputCli/config.yaml b/tools/telemetryInputCli/config.yaml index 422b86e..d0f2ce1 100644 --- a/tools/telemetryInputCli/config.yaml +++ b/tools/telemetryInputCli/config.yaml @@ -9,4 +9,21 @@ tables: # for read the data frame file columns: - timestamp - well_num - - luminosity \ No newline at end of file + - luminosity + + - name: angvel + columns: + - variant + - timestamp + - X + - Y + - Z + + - name: magfield + columns: + - variant + - timestamp + - LSB + - X + - Y + - Z \ No newline at end of file diff --git a/tools/telemetryInputCli/telemetryInputCli.py b/tools/telemetryInputCli/telemetryInputCli.py index 8c658ed..63fb3dc 100644 --- a/tools/telemetryInputCli/telemetryInputCli.py +++ b/tools/telemetryInputCli/telemetryInputCli.py @@ -194,6 +194,7 @@ def insert_data_from_df(self, table:str, filePath:str): else: print("Unsupported file format. Please provide a CSV file.") return + # print out record print(f"Loading {len(df)} records from {filePath} for table {table}.") if df.empty: @@ -205,6 +206,7 @@ def insert_data_from_df(self, table:str, filePath:str): else: print("No timestamp column found in the data.") return + # insert data into influxdb if table == self.wellTempField or table == self.wellLuminField: for index, row in df.iterrows(): @@ -217,16 +219,40 @@ def insert_data_from_df(self, table:str, filePath:str): insertDataIntoWell(well_num, table, data, time, self.payloadTag, self.write_api, self.bucket, self.org) else: print(f"Invalid well number {well_num} at index {index}. Skipping this record.") + + elif table == self.magField: + for index, row in df.iterrows(): + variant = row.get('variant') + if pd.notnull(variant) and (variant == 1 or variant == 2): + time = row.get('timestamp') + if time is not None: + lsb = row.get('LSB') # Figure out what the restriction is for lsb + x = row.get('X') + y = row.get('Y') + z = row.get('Z') + if pd.notnull(lsb): + insertDataIntoMagField(variant, lsb, x, y, z, time, self.adcsTag, self.write_api, self.bucket, self.org) + else: + print(f"Incorrect variant {variant} at index {index}. Skipping this record.") + + elif table == self.angVelocity: + for index, row in df.iterrows(): + variant = row.get('variant') + if pd.notnull(variant) and (variant == 1 or variant == 2): + time = row.get('timestamp') + if time is not None: + x = row.get('X') + y = row.get('Y') + z = row.get('Z') + insertDataIntoAngVelocity(variant, x, y, z, time, self.adcsTag, self.write_api, self.bucket, self.org) + else: + print(f"Incorrect variant {variant} at index {index}. Skipping this record.") + else: - print(f"Unsupported table {table}. Only 'temp' and 'lumin' are supported for bulk insert.") + print(f"Unsupported table {table}. Only 'temp', 'lumin', 'magfield', and 'angvel' are supported for bulk insert.") return print(f"Data from {filePath} inserted into {table} table successfully.") - # do_insert_data_into_mag_field and do_insert_data_into_angular_velocity need a - # more work, definitely need to rewrite some code, just wanted to get something - # "working" for the moment. - # Both of the following functions show up as "undocumented" in the CLI for the moment. - # helper function to insert magnetic field data def insert_data_into_mag_field(self, field): period = askingForPeriod() From 269d34fc29568590d6c6c54bf800273083169536 Mon Sep 17 00:00:00 2001 From: Arnav Gupta Date: Wed, 29 Oct 2025 23:08:36 -0500 Subject: [PATCH 6/9] Fix angvel query typos And add example angvel data. --- server/measurements/adcsMeasurements.js | 4 ++-- tools/telemetryInputCli/.gitignore | 3 ++- tools/telemetryInputCli/examples/data_angvel.csv | 7 +++++++ 3 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 tools/telemetryInputCli/examples/data_angvel.csv diff --git a/server/measurements/adcsMeasurements.js b/server/measurements/adcsMeasurements.js index a59d9cd..ed93d2a 100644 --- a/server/measurements/adcsMeasurements.js +++ b/server/measurements/adcsMeasurements.js @@ -58,8 +58,8 @@ async function angVelocityMeasurements(variant_num, start, 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])`; + |> keep(columns: ["_time", "_value", "variant", "_field"]) + |> group(columns: ["_time"])`; return new Promise((resolve, reject) => { let result = []; diff --git a/tools/telemetryInputCli/.gitignore b/tools/telemetryInputCli/.gitignore index 29249e0..2c73407 100644 --- a/tools/telemetryInputCli/.gitignore +++ b/tools/telemetryInputCli/.gitignore @@ -1,4 +1,5 @@ *.csv !examples/data_temp.csv -!examples/data_lumin.csv \ No newline at end of file +!examples/data_lumin.csv +!examples/data_angvel.csv diff --git a/tools/telemetryInputCli/examples/data_angvel.csv b/tools/telemetryInputCli/examples/data_angvel.csv new file mode 100644 index 0000000..a0b9bea --- /dev/null +++ b/tools/telemetryInputCli/examples/data_angvel.csv @@ -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 From f6655b933a1145b788020bf8710ca46dfbf86c78 Mon Sep 17 00:00:00 2001 From: Anton Frank Date: Fri, 21 Nov 2025 09:34:16 -0600 Subject: [PATCH 7/9] ADCS JSON issues fixed. --- server/controllers/adcsController.js | 74 ++++++++++++++----- server/controllers/payloadController.js | 2 +- server/measurements/adcsMeasurements.js | 4 +- tools/telemetryInputCli/.gitignore | 1 + .../examples/data_magField.csv | 4 + 5 files changed, 65 insertions(+), 20 deletions(-) create mode 100644 tools/telemetryInputCli/examples/data_magField.csv diff --git a/server/controllers/adcsController.js b/server/controllers/adcsController.js index a423786..b41b77a 100644 --- a/server/controllers/adcsController.js +++ b/server/controllers/adcsController.js @@ -1,6 +1,7 @@ const { logInfoMsgPrefix, logWarnMsgPrefix, logErrorMsgPrefix } = require('../utils/utils'); -const { magFieldMeasurements, angVelocityMeasurements, adcsTags, magFieldMeasurementsTag, magFieldMeasurementsFields, angVelocityMeasurementsTag, angVelocityMeasurementsFields } = require('../measurements/adcsMeasurements'); - +const { adcsTags, magFieldMeasurementsTag, magFieldMeasurementsFields, angVelocityMeasurementsTag, angVelocityMeasurementsFields } = require('../measurements/adcsMeasurements'); +const angVelocityMeasurements = require('../measurements/adcsMeasurements'); +const magFieldMeasurements = require('../measurements/adcsMeasurements'); /** * adcs.js * @brief This file contains the controller functions for the ADCS API @@ -53,14 +54,34 @@ const getMagFieldData = async (req, res) => { } 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 + const queryResult = await magFieldMeasurements.magFieldMeasurements(variant, start, end); + + const merged = {}; + + queryResult.forEach(item => { + const time = item._time; + + if (!merged[time]) { + merged[time] = { + variant: item.variant, + timestamp: time, + LSB: null, + X: null, + Y: null, + Z: null + }; + } + + const axis = item._field.toUpperCase(); + merged[time][axis] = item._value; + }); + + const finalOutput = Object.values(merged); + console.log(logInfoMsgPrefix('ADCS magnetic field data fetched successfully')); + + res.status(200).json(finalOutput); + } catch (error) { console.error(logErrorMsgPrefix('Error fetching ADCS magnetic field data'), error); res.status(500).json({ error: 'Internal server error' }); @@ -68,7 +89,7 @@ const getMagFieldData = async (req, res) => { }; const getAngVelocityData = async (req, res) => { - console.log(logInfoMsgPrefix('ADCS angular velocityy check'), 'request_body:', req.body); + console.log(logInfoMsgPrefix('ADCS angular velocity check'), 'request_body:', req.body); const variant = req.params.variant; let { start, end } = req.query; // extract query parameters @@ -114,14 +135,33 @@ const getAngVelocityData = async (req, res) => { } 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 + const queryResult = await angVelocityMeasurements.angVelocityMeasurements(variant, start, end); + + const merged = {}; + + queryResult.forEach(item => { + const time = item._time; + + if (!merged[time]) { + merged[time] = { + variant: item.variant, + timestamp: time, + X: null, + Y: null, + Z: null + }; + } + + const axis = item._field.toUpperCase(); + merged[time][axis] = item._value; + }); + + const finalOutput = Object.values(merged); + console.log(logInfoMsgPrefix('ADCS angular velocity data fetched successfully')); + + res.status(200).json(finalOutput); + } catch (error) { console.error(logErrorMsgPrefix('Error fetching ADCS angular velocity data'), error); res.status(500).json({ error: 'Internal server error' }); diff --git a/server/controllers/payloadController.js b/server/controllers/payloadController.js index 47645c5..cb7cb18 100644 --- a/server/controllers/payloadController.js +++ b/server/controllers/payloadController.js @@ -66,7 +66,7 @@ const getWellData = async (req, res, field) => { timestamp: item._time, [field]: item._value })); - + res.status(200).json(formattedResult); console.log(logInfoMsgPrefix(`Well ${field} data fetched successfully: ${wellNum}`)); } catch (error) { diff --git a/server/measurements/adcsMeasurements.js b/server/measurements/adcsMeasurements.js index ed93d2a..a57803d 100644 --- a/server/measurements/adcsMeasurements.js +++ b/server/measurements/adcsMeasurements.js @@ -33,8 +33,8 @@ async function magFieldMeasurements(variant_num, start, 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])`; + |> keep(columns: ["_time", "_value", "variant", "_field"]) + `; return new Promise((resolve, reject) => { let result = []; queryApi.queryRows(query, { diff --git a/tools/telemetryInputCli/.gitignore b/tools/telemetryInputCli/.gitignore index 2c73407..d21569e 100644 --- a/tools/telemetryInputCli/.gitignore +++ b/tools/telemetryInputCli/.gitignore @@ -3,3 +3,4 @@ !examples/data_temp.csv !examples/data_lumin.csv !examples/data_angvel.csv +!examples/data_magField.csv \ No newline at end of file diff --git a/tools/telemetryInputCli/examples/data_magField.csv b/tools/telemetryInputCli/examples/data_magField.csv new file mode 100644 index 0000000..17dbe35 --- /dev/null +++ b/tools/telemetryInputCli/examples/data_magField.csv @@ -0,0 +1,4 @@ +variant,timestamp,LSB,X,Y,Z +1,1756749600,65536,4,6,7 +1,1756836000,65536,4,7,9 +2,1756922400,65536,5,9,2 From 6346a564b57f381e1642b4389a2b0ea00f3fffd7 Mon Sep 17 00:00:00 2001 From: Arnav Gupta Date: Fri, 21 Nov 2025 20:47:11 -0600 Subject: [PATCH 8/9] Improve example dataset Just for some varied data when testing the frontend. + small 400 message fix --- server/controllers/adcsController.js | 4 ++-- tools/telemetryInputCli/examples/data_magField.csv | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/server/controllers/adcsController.js b/server/controllers/adcsController.js index b41b77a..bb6c339 100644 --- a/server/controllers/adcsController.js +++ b/server/controllers/adcsController.js @@ -22,7 +22,7 @@ const getMagFieldData = async (req, res) => { // 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' }); + res.status(400).json({ error: 'Invalid variant number provided, must be 1 or 2' }); return; } @@ -103,7 +103,7 @@ const getAngVelocityData = async (req, res) => { // 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' }); + res.status(400).json({ error: 'Invalid variant number provided, must be between 1 or 2' }); return; } diff --git a/tools/telemetryInputCli/examples/data_magField.csv b/tools/telemetryInputCli/examples/data_magField.csv index 17dbe35..ae76aef 100644 --- a/tools/telemetryInputCli/examples/data_magField.csv +++ b/tools/telemetryInputCli/examples/data_magField.csv @@ -1,4 +1,7 @@ -variant,timestamp,LSB,X,Y,Z -1,1756749600,65536,4,6,7 -1,1756836000,65536,4,7,9 -2,1756922400,65536,5,9,2 +timestamp,variant,LSB,X,Y,Z +1756749600,1,256,4,6,7 +1756836000,1,4096,4,7,9 +1756922400,1,65536,5,9,2 +1756749600,2,256,6,8,1 +1756836000,2,4096,4,1,9 +1756922400,2,65536,9,1,2 From 6ca3d48d8cb8499a54db12bf28c0c6adacf084c9 Mon Sep 17 00:00:00 2001 From: Arnav Gupta Date: Fri, 21 Nov 2025 20:55:12 -0600 Subject: [PATCH 9/9] Remove unused imports --- server/controllers/adcsController.js | 1 - 1 file changed, 1 deletion(-) diff --git a/server/controllers/adcsController.js b/server/controllers/adcsController.js index bb6c339..4d6d17f 100644 --- a/server/controllers/adcsController.js +++ b/server/controllers/adcsController.js @@ -1,5 +1,4 @@ const { logInfoMsgPrefix, logWarnMsgPrefix, logErrorMsgPrefix } = require('../utils/utils'); -const { adcsTags, magFieldMeasurementsTag, magFieldMeasurementsFields, angVelocityMeasurementsTag, angVelocityMeasurementsFields } = require('../measurements/adcsMeasurements'); const angVelocityMeasurements = require('../measurements/adcsMeasurements'); const magFieldMeasurements = require('../measurements/adcsMeasurements'); /**