Skip to content

Commit e3a8c43

Browse files
authored
Implement Main Table Migration (#653)
# Purpose Closes #630. Explain the purpose of the PR here if it doesn't match the linked issue. Be sure to add a comment in the linked issue explaining the changes. # New Changes Implemented main_commands.py, main_telemetry.py, main_commands.csv, telemetry.csv, updated migration.py to include telemetry # Testing Explain tests that you ran to verify code functionality. - [x] I have unit-tested this PR. Otherwise, explain why it cannot be unit-tested. - [ ] I have tested this PR on a board if the code will run on a board (Only required for firmware developers). - [ ] I have tested this PR by running the ARO website (Only required if the code will impact the ARO website). - [ ] I have tested this PR by running the MCC website (Only required if the code will impact the MCC website). - [x] I have included screenshots of the tests performed below. HOW TO TEST: 1. Follow database setup from documentation 2. Make sure existing main command / telemetry data is cleared psql -U username -d db gs=# DELETE FROM main.commands; gs=# DELETE FROM main.telemetry; 3. Run the migration script (make sure venv is active) python3 gs/backend/migrate.py 4. Verify the main commands and telemetry in the DB psql -U username -d db gs=# SELECT id FROM main.commands ORDER BY id; gs=# SELECT id FROM main.telemetry ORDER BY id; <img width="1360" height="136" alt="image" src="https://github.com/user-attachments/assets/89c085f3-2d4b-4033-8575-0fa3b88abc35" /> <img width="804" height="590" alt="image" src="https://github.com/user-attachments/assets/4b083f9b-8282-4921-b2cd-80a9ffe92f24" /> <img width="1322" height="818" alt="image" src="https://github.com/user-attachments/assets/8b203c33-c08d-4252-8ad9-a9004146f13d" /> # Outstanding Changes If there are non-critical changes (i.e. additional features) that can be made to this feature in the future, indicate them here.
1 parent 39a6cfb commit e3a8c43

File tree

9 files changed

+152
-31
lines changed

9 files changed

+152
-31
lines changed

gs/POSTGRESQL_SETUP.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ Now, you can start the backend as by running `fastapi dev gs/backend/main.py` fr
6969

7070
To migrate pre-determined datainto your local database, you can run `python3 gs/backend/migrate.py` from the top level directory.
7171

72-
Alternatively, you can include `callsigns` or `commands` as command arguments to migrate those respective datasets individually.
72+
Alternatively, you can include `callsigns`, `commands`, or `telemetries` as command arguments to migrate those respective datasets individually.
7373

7474
**[Back to top](#table-of-contents)**
7575

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
1,TLE Data Uplink,"Inclination (float), RAAN (float), Eccentricity (float),
2+
Argument of Perigee (float), Mean anomaly (float),
3+
Mean motion (double), Revolution # (32 bit int)","float, float, float, float, float, double, int32",44,45
4+
2,ARO Data: Passcode + Time + Roll angle,"Time tag UTC, Roll angle off nadir (float),
5+
ARO Callsign, passcode (24 characters/bytes)","datetime, float, varchar(6), varchar(24)",36,37
6+
3,Secondary payload activation,,,0,1
7+
4,,"Year, Month, Date, Day, Hour, Minute, Second in UTC","int16, uint8, uint8, uint8, uint8, uint8, uint8",7,8
8+
5,RTC Sync,"Time tag (UTC)",datetime,7,8
9+
6,Call EPS MCU reset,,,0,1
10+
7,Call CDH MCU reset,,,0,1
11+
8,"Time delayed image capture & downlink to MCC
12+
on next pass","Time tag (UTC), Roll angle off nadir (float)","datetime, float",11,12
13+
9,Direct EPS power rail control,"Power rail ID (given by a table)",int,1,2
14+
10,Comms echo back,32 bit integer to echo back,int32,4,5
15+
11,Change value in parameter manager,"Address, new value","int, int",2,3
16+
12,Echo back parameter manager value,Address,int,1,2
17+
13,"Manually activate an emergency mode for a
18+
specified amount of time","Emergency mode state number, time tag (UTC)","int, datetime",8,9
19+
14,Downlink full system logs on next pass,Log level,enum,1,2
Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,23 @@
1+
import csv
2+
13
from gs.backend.data.tables.main_tables import MainCommand
24

35

46
# TODO: Pull this from a config file so that it's synced with the OBC
5-
# TODO: Add more main commands
67
def main_commands() -> list[MainCommand]:
78
"""
89
Returns the list of main commands
910
"""
10-
return [
11-
MainCommand(
12-
id=1,
13-
name="RTC Sync",
14-
params="time",
15-
format="int 7 bytes",
16-
data_size=7,
17-
total_size=8,
18-
),
19-
MainCommand(
20-
id=2,
21-
name="Manually activate an emergency mode for a specified amount of time",
22-
params="mode_state_number,time",
23-
format="int 1 byte, int 7 bytes",
24-
data_size=8,
25-
total_size=9,
26-
),
27-
]
11+
with open("gs/backend/data/resources/main_commands.csv", newline="") as csvfile:
12+
file = csv.reader(csvfile)
13+
return [
14+
MainCommand(
15+
id=int(row[0]),
16+
name=row[1],
17+
params=row[2].strip() or None,
18+
format=row[3].strip() or None,
19+
data_size=int(row[4]),
20+
total_size=int(row[5]),
21+
)
22+
for row in file
23+
]
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import csv
2+
3+
from gs.backend.data.tables.main_tables import MainTelemetry
4+
5+
6+
def main_telemetry() -> list[MainTelemetry]:
7+
"""
8+
Returns the list of main telemetry
9+
"""
10+
with open("gs/backend/data/resources/telemetry.csv", newline="") as csvfile:
11+
file = csv.reader(csvfile)
12+
return [
13+
MainTelemetry(
14+
id=int(row[0]),
15+
name=row[1],
16+
format=row[2],
17+
data_size=int(row[3]),
18+
total_size=int(row[4]),
19+
)
20+
for row in file
21+
]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
1,Total received CSP packets at last MCC window,int,1,8
2+
2,Custom transceiver temperature sensor,12-bit,2,12960
3+
3,Temperature sensor,12-bit,2,12960
4+
4,Temperature sensor,12-bit,2,12960
5+
5,Temperature sensor,12-bit,2,12960
6+
6,Temperature sensor,12-bit,2,12960
7+
7,Temperature sensor,12-bit,2,12960
8+
8,Temperature sensor,12-bit,2,12960
9+
9,Temperature sensor,12-bit,2,12960
10+
10,Temperature sensor,12-bit,2,12960
11+
11,Current Sensor,12-bit,2,12960
12+
12,Current Sensor,12-bit,2,12960
13+
13,Current Sensor,12-bit,2,12960
14+
14,Current Sensor,12-bit,2,12960
15+
15,Current Sensor,12-bit,2,12960
16+
16,Current Sensor,12-bit,2,12960
17+
17,Voltage Sensor,12-bit,2,12960
18+
18,Voltage Sensor,12-bit,2,12960
19+
19,Voltage Sensor,12-bit,2,12960
20+
20,Voltage Sensor,12-bit,2,12960
21+
21,Voltage Sensor,12-bit,2,12960
22+
22,Voltage Sensor,12-bit,2,12960
23+
23,CC1120 onboard temperature sensor,12-bit,2,12960
24+
24,OBC State History: past 15 states,int,1,120
25+
25,EPS State History: past 15 states,int,1,120

gs/backend/data/resources/utils.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
from gs.backend.data.resources.callsigns import callsigns
44
from gs.backend.data.resources.main_commands import main_commands
5+
from gs.backend.data.resources.main_telemetry import main_telemetry
56
from gs.backend.data.tables.aro_user_tables import AROUserCallsigns
6-
from gs.backend.data.tables.main_tables import MainCommand
7+
from gs.backend.data.tables.main_tables import MainCommand, MainTelemetry
78

89

910
def add_main_commands(session: Session) -> None:
@@ -26,3 +27,14 @@ def add_callsigns(session: Session) -> None:
2627
if not result:
2728
session.add_all(callsigns())
2829
session.commit()
30+
31+
32+
def add_telemetry(session: Session) -> None:
33+
"""
34+
Setup the main telemetry to the database
35+
"""
36+
query = select(MainTelemetry).limit(1) # Check if the db is empty
37+
result = session.exec(query).first()
38+
if not result:
39+
session.add_all(main_telemetry())
40+
session.commit()

gs/backend/data/tables/main_tables.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class MainCommand(BaseSQLModel, table=True):
3131
name: str
3232
params: str | None = None # None if no params needed
3333
format: str | None = None # None if no format needed
34-
data_size: int = Field(gt=0)
34+
data_size: int = Field(ge=0)
3535
total_size: int = Field(gt=0)
3636

3737
# table information

gs/backend/migrate.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import sys
22

33
from gs.backend.data.database.engine import get_db_session
4-
from gs.backend.data.resources.utils import add_callsigns, add_main_commands
4+
from gs.backend.data.resources.utils import add_callsigns, add_main_commands, add_telemetry
55

66
"""
77
To migrate pre-determined datainto your local database,
88
you can run `python3 gs/backend/migrate.py` from the top
99
level directory.
1010
11-
Alternatively, you can include `callsigns` or `commands`
11+
Alternatively, you can include `callsigns`, `commands`, or 'telemetries'
1212
as command arguments to migrate those respective datasets
1313
individually.
1414
"""
@@ -21,11 +21,18 @@
2121
add_callsigns(get_db_session())
2222
print("Migrating main command data...")
2323
add_main_commands(get_db_session())
24-
elif sys.argv[1] == "callsigns":
25-
print("Migrating callsign data...")
26-
add_callsigns(get_db_session())
27-
elif sys.argv[1] == "commands":
28-
print("Migrating main command data...")
29-
add_main_commands(get_db_session())
24+
print("Migrating telemetry data...")
25+
add_telemetry(get_db_session())
3026
else:
31-
raise ValueError("Invalid input. Optional arguments include 'callsigns' or 'commands'.")
27+
match sys.argv[1]:
28+
case "callsigns":
29+
print("Migrating callsign data...")
30+
add_callsigns(get_db_session())
31+
case "commands":
32+
print("Migrating main command data...")
33+
add_main_commands(get_db_session())
34+
case "telemetries":
35+
print("Migrating telemetry data...")
36+
add_telemetry(get_db_session())
37+
case _:
38+
raise ValueError("Invalid input. Optional arguments include 'callsigns', 'commands', or 'telemetries'.")
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from alembic import op
2+
3+
"""
4+
updating main table parameters to allow data size of 0
5+
6+
Revision ID: 6c54d182bb55
7+
Revises: ee5986331915
8+
Create Date: 2026-01-16 12:46:02.225339
9+
10+
"""
11+
12+
13+
# revision identifiers, used by Alembic.
14+
revision = "6c54d182bb55"
15+
down_revision = "ee5986331915"
16+
branch_labels = None
17+
depends_on = None
18+
19+
20+
def upgrade() -> None:
21+
"""
22+
Allow the data size of main commands to be 0
23+
"""
24+
op.create_check_constraint(
25+
"ck_main_commands_data_size_ge_0", # OK
26+
"commands",
27+
"data_size >= 0",
28+
schema="main",
29+
)
30+
31+
32+
def downgrade() -> None:
33+
"""
34+
Revert the data size constraint on main commands
35+
"""
36+
op.drop_constraint(
37+
"ck_main_commands_data_size_ge_0",
38+
"commands",
39+
type_="check",
40+
schema="main",
41+
)

0 commit comments

Comments
 (0)