Compare commits

...

216 Commits

Author SHA1 Message Date
2d6e9f826c Merge pull request 'action reply update' (#299) from small-action-reply-update into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #299
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-05-28 09:40:21 +02:00
e23b39e652
action reply update
All checks were successful
EIVE/-/pipeline/head This commit looks good
EIVE/-/pipeline/pr-main This commit looks good
2024-05-16 11:03:55 +02:00
9a55686a26 Merge pull request 'Some more fixes' (#298) from some-more-fixes-for-tmtccmd-bump into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #298
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-05-13 14:06:00 +02:00
067a016040
another small fix
All checks were successful
EIVE/-/pipeline/head This commit looks good
EIVE/-/pipeline/pr-main This commit looks good
2024-05-08 10:56:16 +02:00
dccbf89da1
some more fixes
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-05-08 10:49:20 +02:00
5cf76c07e9 Merge pull request 'Bump tmtccmd and fix CFDP' (#297) from bump-tmtccmd-fix-cfdp into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #297
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-05-07 14:17:40 +02:00
bc53f7e81a Merge remote-tracking branch 'origin/main' into bump-tmtccmd-fix-cfdp
Some checks are pending
EIVE/-/pipeline/head Build started...
2024-05-07 14:10:05 +02:00
d6b879da67 bump tmtccmd and fix CFDP code
Some checks are pending
EIVE/-/pipeline/head Build started...
2024-05-07 14:07:18 +02:00
9a06c64dfa prep v7.0.0
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-05-06 14:18:57 +02:00
cc7837a55b Merge pull request 'MPSoC Overhaul' (#296) from mpsoc-overhaul into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #296
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-05-06 14:18:02 +02:00
9cc4fa702c renaming
Some checks are pending
EIVE/-/pipeline/pr-main Build started...
2024-05-06 14:10:30 +02:00
ada099cab1 events
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-05-06 13:48:22 +02:00
376f94b167 update events
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-05-06 13:18:27 +02:00
86a68e25f7 need to fix action reply handler
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-05-06 11:23:31 +02:00
5e1b12fa52 Merge remote-tracking branch 'origin/main' into mpsoc-overhaul
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-04-30 14:36:41 +02:00
de34952df5 less confusing cmd names 2024-04-30 14:36:11 +02:00
5da55c3c99 Merge pull request 'PLOC SUPV TM handling' (#293) from ploc-supv-tm-handling into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #293
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-04-29 11:44:20 +02:00
3b903e5639 Merge branch 'main' into ploc-supv-tm-handling
Some checks are pending
EIVE/-/pipeline/pr-main Build queued...
2024-04-29 11:43:14 +02:00
da35c7fdf1 Merge pull request 'added missing act cmd' (#295) from gnss-improv into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #295
2024-04-29 11:42:51 +02:00
8c7cbd1bd6 changelog
Some checks are pending
EIVE/-/pipeline/pr-main Build queued...
2024-04-29 11:41:03 +02:00
ba0a3e35d2 cleanup
Some checks are pending
EIVE/-/pipeline/pr-main Build started...
2024-04-29 11:40:00 +02:00
fc2667c150 Merge branch 'main' into gnss-improv
Some checks are pending
EIVE/-/pipeline/pr-main Build started...
2024-04-29 11:33:10 +02:00
f9041f215a how the fuck did that work the last time?
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-04-26 15:27:44 +02:00
a59aceda75 odd things happening here
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-04-26 14:36:02 +02:00
c50f8c2ce2 some fixes
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-04-26 13:53:39 +02:00
dfa45dbdba
added some commands for preparing flash
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-04-25 17:26:57 +02:00
36d9323b57
added commands for flash formatting
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-04-25 12:11:18 +02:00
e04b5bf9d7
Merge remote-tracking branch 'origin/main' into mpsoc-overhaul
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-04-25 12:04:37 +02:00
3c0ac91227 Merge pull request 'CLock Events' (#291) from clock-events into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #291
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-04-17 16:43:29 +02:00
f61c485979 Merge branch 'main' into clock-events
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-04-17 16:20:09 +02:00
2ebbf750bd
handling for new clock events 2024-04-17 16:19:58 +02:00
847fccbe66 Merge pull request 'test script' (#294) from bestest-script into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #294
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-04-17 16:19:24 +02:00
c8292f4ee1 Merge branch 'main' into bestest-script
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-04-17 15:05:45 +02:00
3700769e46 Merge remote-tracking branch 'origin/main' into ploc-supv-tm-handling
Some checks failed
EIVE/-/pipeline/head Build queued...
EIVE/-/pipeline/pr-main There was a failure building this commit
2024-04-17 15:04:57 +02:00
69fda96d7a
bump major version
All checks were successful
EIVE/-/pipeline/head This commit looks good
EIVE/-/pipeline/pr-main This commit looks good
2024-04-17 15:02:20 +02:00
0c51cad813
remove old boot verification cmd
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-04-17 14:51:44 +02:00
05d5955236
split up in store file and stream file
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-04-17 14:43:15 +02:00
18860ec2c6
tricky
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-04-17 13:20:46 +02:00
fc5fb0eed3
add new submode commands
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-04-17 13:10:13 +02:00
d5bb6fe6c5
re-run generators
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-04-17 11:22:41 +02:00
37eafb722b
this should do the job
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-04-11 10:52:14 +02:00
1cafdc817f
clock events
All checks were successful
EIVE/-/pipeline/head This commit looks good
EIVE/-/pipeline/pr-main This commit looks good
2024-04-10 17:34:54 +02:00
5967dede97
add new events for clock handling
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-04-10 17:27:24 +02:00
a8d0143b1e Merge pull request 'Prep v6.2.0' (#290) from prep-v6.2.0 into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #290
2024-04-10 11:51:24 +02:00
a0ad5f8948 reran gens 2024-04-10 11:50:15 +02:00
20ecef5838 linter
Some checks are pending
EIVE/-/pipeline/head Build queued...
2024-04-10 11:48:04 +02:00
6d97841cbf bump version
Some checks are pending
EIVE/-/pipeline/head Build queued...
2024-04-10 11:47:05 +02:00
512f0e4530 changelog 2024-04-10 11:46:35 +02:00
e2f0221681 Merge pull request 'GNSS Fixes' (#289) from gnss-fixes into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #289
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-04-10 11:34:58 +02:00
e9eb45c088 Merge branch 'main' into gnss-fixes 2024-04-10 11:34:39 +02:00
ea72087d87 Merge pull request 'allow setting health for payload components' (#287) from set-health-cmd-payload into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #287
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-04-10 11:34:30 +02:00
d48c029b85 Merge branch 'main' into gnss-fixes
Some checks are pending
EIVE/-/pipeline/pr-main Build queued...
2024-04-10 11:30:01 +02:00
b5f4f2ddab
changelog
Some checks are pending
EIVE/-/pipeline/pr-main Build started...
2024-04-10 11:29:19 +02:00
64dd19bd12 Merge branch 'main' into set-health-cmd-payload
Some checks are pending
EIVE/-/pipeline/pr-main Build started...
2024-04-10 11:28:43 +02:00
102821fc71 Merge pull request 'Some PLOC commanding fixes' (#288) from ploc-tree-test into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #288
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-04-09 14:41:10 +02:00
24f3abdd5a Merge branch 'main' into ploc-tree-test 2024-04-09 14:40:36 +02:00
a880db5655 changelog
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-04-09 14:34:23 +02:00
4e0cbb1034 Merge branch 'main' into gnss-fixes 2024-04-09 14:33:33 +02:00
96636d59e9 Merge pull request 'relative timeshift' (#286) from relative-timeshift into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #286
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-04-09 14:32:28 +02:00
7dfdd40963 fixed PLOC mode commanding
Some checks are pending
EIVE/-/pipeline/pr-main Build queued...
2024-04-09 14:31:41 +02:00
6282686f2f lets just change the tmtc structure he said. everything will still work he said
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-04-09 13:29:01 +02:00
b160f079b1 small bugfix
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-04-09 13:19:25 +02:00
11d7ad0f8d start fixing PLOC tree
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-04-09 11:32:57 +02:00
5af69eb14e add supervisor
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-04-08 13:40:37 +02:00
5a0edbefa8 fix comment block
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-04-08 13:38:28 +02:00
5bdba2dbad update events
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-04-08 13:35:34 +02:00
3ae6ccfb77 this should do the job 2024-04-08 13:35:06 +02:00
de84bf112b changelog
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-04-08 13:25:45 +02:00
d182a9d5ec re-run black 2024-04-08 13:24:40 +02:00
c72a04b262 allow setting health for payload components
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-04-08 11:36:25 +02:00
492d364246 relative timeshift
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-04-08 11:35:05 +02:00
33cf7b1613 Merge pull request 'Fix for Heater Cmd' (#284) from heater-health into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #284
2024-04-02 13:28:06 +02:00
d8c49aed80 Merge branch 'main' into heater-health 2024-04-02 13:27:56 +02:00
97afd24e52 Merge pull request 'EPS command bugfix' (#285) from eps-bugfix into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #285
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-03-27 09:01:22 +01:00
4704616ca7 changelog
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-03-26 17:52:41 +01:00
92c0172b59 bugfix for EPS
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-03-26 17:50:37 +01:00
344f16099e test script
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-03-19 11:48:24 +01:00
49b55f01e3 s
All checks were successful
EIVE/-/pipeline/head This commit looks good
EIVE/-/pipeline/pr-main This commit looks good
2024-03-18 11:11:20 +01:00
f87095bf68 Merge pull request 'STR Improv' (#283) from str-version into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #283
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-03-14 10:55:59 +01:00
928759d1bc changelog
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-03-13 13:47:02 +01:00
dc17919108 smoll fix
Some checks are pending
EIVE/-/pipeline/head Build started...
2024-03-13 13:44:15 +01:00
5f71f27f0e size check
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-03-13 10:18:37 +01:00
f8d63e56cb version set
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-03-13 10:00:45 +01:00
c843356c8a Merge pull request 'Prep v6.1.1' (#282) from prep-v6.1.1 into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #282
2024-03-06 11:03:24 +01:00
49a614db10 cleanup
Some checks are pending
EIVE/-/pipeline/head Build started...
2024-03-06 11:02:10 +01:00
c90dd92162 bump version 2024-03-06 10:59:31 +01:00
bcb6a8b34e changelog 2024-03-06 10:59:09 +01:00
ed15bcaf35 Merge pull request 'Leap Seconds' (#281) from leap-seconds into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #281
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-03-06 10:53:57 +01:00
89202f2cfe changelog
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-03-06 09:51:03 +01:00
40c2a4b1f3 remove printout
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-03-05 11:53:00 +01:00
811786fd78 update leap seconds act cmd
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-03-05 11:43:18 +01:00
baf1b44d23 added missing act cmd
All checks were successful
EIVE/-/pipeline/head This commit looks good
EIVE/-/pipeline/pr-main This commit looks good
2024-03-01 10:20:07 +01:00
73a4260f33 Merge pull request 'Prep v6.1.0' (#280) from prep-v6.1.0 into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #280
2024-02-29 13:24:27 +01:00
3358de3e3e changelog
Some checks are pending
EIVE/-/pipeline/pr-main Build queued...
2024-02-29 13:22:06 +01:00
211e79c83e bumped version number 2024-02-29 13:20:07 +01:00
7f10e5c777 Merge branch 'main' into prep-v6.1.0 2024-02-29 13:19:44 +01:00
aab35c26c2 reran gens
Some checks are pending
EIVE/-/pipeline/pr-main Build queued...
2024-02-29 13:12:30 +01:00
6ade001d3d Merge pull request 'New ACS Ctrl Act Cmd' (#278) from acs-ctrl-new-stuff into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #278
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-02-29 12:34:50 +01:00
098bdcf82b
changelog 2024-02-29 12:34:04 +01:00
b131415ea7 Merge branch 'main' into acs-ctrl-new-stuff 2024-02-29 12:33:44 +01:00
b1dd5aa7d0 Merge pull request 'Add BlobStats TM handling STR' (#279) from add-blob-stats-str into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #279
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-02-29 12:33:31 +01:00
0201eb27c4
changelog
Some checks are pending
EIVE/-/pipeline/pr-main Build queued...
2024-02-29 12:27:27 +01:00
c070f18c5d
small fix
Some checks are pending
EIVE/-/pipeline/head Build queued...
2024-02-29 12:26:02 +01:00
00876ed0e0
tweak for HK filter feature 2024-02-29 12:09:53 +01:00
68ea889d0f
added blob stats set for STR
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-02-29 12:07:03 +01:00
771199e542 added new act cmd
All checks were successful
EIVE/-/pipeline/head This commit looks good
EIVE/-/pipeline/pr-main This commit looks good
2024-02-27 16:26:06 +01:00
588d7a8079 Merge pull request 'RW commanding fix' (#277) from rw-commanding-fix into main
Some checks are pending
EIVE/-/pipeline/head Build queued...
Reviewed-on: #277
2024-02-26 14:03:52 +01:00
83aff8bea5 Merge branch 'main' into rw-commanding-fix 2024-02-26 14:03:22 +01:00
1d982785e6 Merge pull request 'STR secondary firmware slot commands' (#276) from str-secondary-fw-slot-update into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #276
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-02-26 14:01:34 +01:00
d062a22a7a delete old function
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-02-20 11:29:20 +01:00
f8c3172e7a changelog
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-02-20 11:26:54 +01:00
7a56c604a6 RW commanding fixes 2024-02-20 11:26:36 +01:00
bbde4b5b20
changelog
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-02-19 17:25:06 +01:00
85fc106a9b
add commanding nodes
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-02-19 15:58:34 +01:00
d35bc01397
added command to select STR slot
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-02-19 15:27:27 +01:00
d811735b8d
add som enums
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-02-19 12:20:32 +01:00
265077a758
add command for second slot update
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-02-19 12:17:34 +01:00
1cd566a94c Merge pull request 'Fix the Errors of muellerr' (#275) from tm-store-fix into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #275
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-02-12 10:40:34 +01:00
9aa891ef78 fix the errors of muellerr
All checks were successful
EIVE/-/pipeline/head This commit looks good
EIVE/-/pipeline/pr-main This commit looks good
2024-02-09 12:06:38 +01:00
329aa76fbf Merge pull request 'prep v6.0.0' (#274) from prep-v6.0.0 into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #274
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-02-08 13:07:09 +01:00
4633e0cb13
prep v6.0.0
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-02-08 12:18:33 +01:00
a5ebac6266 Merge pull request 'Add SUPV latchup report handling, clean up code' (#273) from add-supv-latchup-report into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #273
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-02-06 13:52:55 +01:00
f3c6b509ec Merge branch 'main' into add-supv-latchup-report
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-02-06 11:37:39 +01:00
5aefa436f4 Merge pull request 'v6.0.0-dev' (#269) from v6.0.0-dev into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #269
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-02-06 10:28:28 +01:00
b0b8118dd5 Merge branch 'main' into v6.0.0-dev
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-02-05 09:58:44 +01:00
db384f8e9c Merge pull request 'print fix STR' (#272) from str-print-fix into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #272
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-02-05 09:05:36 +01:00
e5fe0ab95a
Merge branch 'v6.0.0-dev' into add-supv-latchup-report
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-01-31 17:06:33 +01:00
248df1d4df
added missing field parsing
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-01-31 16:57:59 +01:00
f93f713b0e
some minor bugfixes
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-01-31 16:49:54 +01:00
c6b2edf688
removed old commands
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-01-31 15:58:43 +01:00
5e3b60b3af
cleaned up PLOC SUPV a bit
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-01-31 15:56:03 +01:00
d69d16c3af
add latchup status report handling
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-01-31 15:38:01 +01:00
6376585c4e Merge remote-tracking branch 'origin/main' into v6.0.0-dev
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-01-30 10:54:12 +01:00
5b4a789c4b print fix
All checks were successful
EIVE/-/pipeline/head This commit looks good
EIVE/-/pipeline/pr-main This commit looks good
2024-01-30 10:39:59 +01:00
d33013ed58 Merge pull request 'Prep v5.13.0' (#271) from prep-v5.13.0 into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #271
2024-01-30 09:25:47 +01:00
7e39a481bd Merge branch 'main' into prep-v5.13.0
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-01-30 09:24:06 +01:00
4744de8a54 changelog
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-01-30 09:17:40 +01:00
916ce92bdc bump version 2024-01-30 09:17:31 +01:00
bb765ac8a0 Merge pull request 'Gens' (#270) from reran-gens into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #270
2024-01-30 09:14:38 +01:00
84f0f42783 gens
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-01-30 09:10:47 +01:00
ee2dade270 gens
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-01-30 09:07:56 +01:00
4f26c34c60 gens
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-01-29 17:14:18 +01:00
b5ae7c5f38 Merge pull request 'Add new param command' (#268) from ploc-mpsoc-skip-supv-commanding-param into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #268
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-01-29 10:15:11 +01:00
813f92f3d4
some cleaning up and some bugfixes
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-01-25 13:27:10 +01:00
f3eecfa8ac
fix TC handler
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-01-25 13:03:04 +01:00
b94c20dab1
changelog
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-01-25 11:22:10 +01:00
84aeaa4b65 Merge branch 'ploc-mpsoc-skip-supv-commanding-param' into v6.0.0-dev 2024-01-25 11:20:50 +01:00
caaf937003
changelog
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-01-25 11:20:38 +01:00
bcdd12caf0
basic printout for wrong mode reply
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-01-25 11:01:46 +01:00
6440048235
get rid of the stupid legacy printer
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-01-25 10:39:43 +01:00
c5dcc0b77d Merge branch 'v6.0.0-dev' of https://egit.irs.uni-stuttgart.de/eive/eive-tmtc into v6.0.0-dev
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-01-25 10:36:32 +01:00
ebd9792fb9
some minor fixes 2024-01-25 10:36:23 +01:00
9f1d61c3ef Merge pull request 'Introduce TM DB' (#255) from introduce_tm_db into v6.0.0-dev
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #255
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-01-25 10:26:06 +01:00
38eb43cf8d Merge branch 'v6.0.0-dev' into introduce_tm_db
Some checks are pending
EIVE/-/pipeline/pr-v6.0.0-dev Build started...
2024-01-25 10:25:56 +01:00
3d007c32a3
various fixes for ACS subsystem
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-01-25 10:22:04 +01:00
202a824d31
scex bug
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-01-25 10:06:10 +01:00
79b3c269e6
this works 2024-01-25 10:04:45 +01:00
839da7a224
Merge branch 'ploc-mpsoc-skip-supv-commanding-param' into v6.0.0-dev
All checks were successful
EIVE/-/pipeline/head This commit looks good
2024-01-25 10:01:39 +01:00
3a6abe1b62 Merge pull request 'Introduce new command definition tree' (#259) from bump-tmtccmd into v6.0.0-dev
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #259
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-01-25 09:43:47 +01:00
db70b33bd6
bump tmtccmd again
All checks were successful
EIVE/-/pipeline/pr-v6.0.0-dev This commit looks good
2024-01-24 17:59:16 +01:00
d53e9d61b0
Merge remote-tracking branch 'origin/main' into bump-tmtccmd
All checks were successful
EIVE/-/pipeline/pr-v6.0.0-dev This commit looks good
2024-01-24 17:49:39 +01:00
bac4473aa7 Merge branch 'main' into introduce_tm_db
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2024-01-24 17:40:23 +01:00
1831ea8b7a
add new param command
All checks were successful
EIVE/-/pipeline/head This commit looks good
EIVE/-/pipeline/pr-main This commit looks good
2024-01-24 14:30:57 +01:00
747ad34eec
prev v5.12.1
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-12-13 11:30:03 +01:00
2789453d57 Merge pull request 'the endianness is actually really important here' (#266) from add-cmds-to-test-scheduling into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #266
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-12-13 11:28:09 +01:00
5456d79965
the endianness is actually really important here
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-12-13 11:23:55 +01:00
342a3bbcc9 update PLOC Supversisor TM handling
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-12-12 15:28:32 +01:00
4c54aa7586 Merge pull request 'small fix' (#265) from small-fix into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #265
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-12-07 13:57:49 +01:00
1a132684a6 small fix
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-12-07 13:54:09 +01:00
f63a834d9a Merge pull request 'prep v5.12.0' (#264) from prep_v5.12.0 into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #264
2023-12-06 17:23:00 +01:00
58def42281
re-run generators
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-12-06 17:19:56 +01:00
ee955e96fb
prepare v5.12.0 2023-12-06 17:19:01 +01:00
97fb8a166f Merge pull request 'New ACS Stuff' (#263) from acs-stuff into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #263
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-12-06 17:16:55 +01:00
d477242881 strats
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-12-06 14:48:05 +01:00
451c2c07ee stuff
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-12-05 16:41:29 +01:00
8de88127c3 this is much better
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-12-05 09:57:07 +01:00
e7e97ff2d3 i never pushed this lul
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-12-01 13:03:38 +01:00
35e3f8b572 call action reply handling 2023-12-01 13:02:23 +01:00
77010937b8 tle action reply 2023-12-01 13:01:31 +01:00
c1f4a3f59d more health 2023-12-01 13:01:14 +01:00
7c3a72f85b Merge branch 'main' into introduce_tm_db
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-30 10:12:49 +01:00
4e25e2e6ca Merge branch 'main' into bump-tmtccmd
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-29 18:34:02 +01:00
eb302e5cf1
use released version of tmtccmd
Some checks failed
EIVE/-/pipeline/pr-main There was a failure building this commit
2023-11-29 18:33:09 +01:00
3da1c2c262
add some more ACS devices
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-29 17:27:24 +01:00
1660e27ec1
hopefully soon done
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-29 17:04:30 +01:00
6f86e72042
Merge remote-tracking branch 'origin/main' into bump-tmtccmd
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-29 15:12:48 +01:00
507c3e3ff3
Merge branch 'introduce_tm_db' into bump-tmtccmd
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-29 15:02:33 +01:00
bca2deae61 Merge branch 'main' into introduce_tm_db
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-29 15:00:09 +01:00
35e25bf6d0 small fix for STR node
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-28 17:42:52 +01:00
d4147d8402 not much missing
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-28 17:41:46 +01:00
3cf312073a continue conversion
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-28 17:34:34 +01:00
76fee820e9 continuing node setup
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-28 17:24:25 +01:00
d2fc53c1fa cmd history introduction
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-28 16:05:19 +01:00
947bcf57f5
done for today
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-22 19:44:24 +01:00
77c2c91539
health and system cmds
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-22 19:42:26 +01:00
756944cae3
that should be it
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-22 19:38:04 +01:00
2bb917eab7
last bugfixes
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-22 19:25:04 +01:00
f756df43a2
last tests 2023-11-22 19:22:51 +01:00
688602e486
cleaning up
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-22 19:13:22 +01:00
21a38ae76a
use new the new leaf suppression feature
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-22 18:39:12 +01:00
af02c106b9
looking good
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-11-22 16:40:27 +01:00
ae239031ed
removed old service provider API
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-11-22 14:13:00 +01:00
d640d547bd
OOF3
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-11-22 13:51:33 +01:00
02d9d6adfc
OOF2
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-11-22 11:21:26 +01:00
ba24faefa9
this is hardcore 2023-11-22 10:51:26 +01:00
b3920524ab
OOF 2023-11-22 10:17:05 +01:00
7cb5766a7a
added another helper/wrapper type
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-13 14:50:49 +01:00
6e87a0249c
no need for file logging here anymore
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-13 13:51:53 +01:00
c0ab3351c9
that's a lot of work..
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-13 13:48:08 +01:00
2259d269dd
separate function for raw TM insertion
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-13 13:19:42 +01:00
57a225f926
start adding raw TM DB
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-13 11:37:57 +01:00
d9e4ff6973 Merge remote-tracking branch 'origin/main' into introduce_tm_db
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-13 11:15:02 +01:00
02dc6174bf Merge branch 'main' into introduce_tm_db
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-11-13 11:13:38 +01:00
ce363e3785
this seems to work well
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-11-13 11:12:18 +01:00
b3c3363591
Merge branch 'bump_tmtccmd_dependency' into introduce_tm_db
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-11-13 09:50:01 +01:00
3fe51b08a6
let's try a DB
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-11-13 08:50:51 +01:00
78 changed files with 3663 additions and 2644 deletions

5
.gitignore vendored
View File

@ -6,6 +6,7 @@ log
/gps_log.txt
/config/*.json
/.tmtc-history.txt
/scex_conf.json
/tmtc_conf.json
/seqcnt*.txt
@ -27,3 +28,7 @@ log
/.installed.cfg
/*.egg
/MANIFEST
# Telemetry database.
/tm.db

View File

@ -10,6 +10,80 @@ list yields a list of all related PRs for each release.
# [unreleased]
# [v7.0.0] 2024-05-06
- Reworked PLOC MPSoC commanding to be inline with OBSW update.
## Fixed
- GNSS commands working again (again).
## Added
- Added handling for new clock events.
# [v6.2.0] 2024-04-10
## Added
- Added version set for STR.
- Command for relative timeshift.
- Health commands for payload components.
## Fixed
- EPS power commands working again.
- GNSS commands working again.
## Changed
- Fixed PLOC commanding
# [v6.1.1] 2024-03-06
## Added
- Added Core Ctrl cmd to update leap seconds.
# [v6.1.0] 2024-02-29
## Added
- Added commands to unlock and use STR secondary firmware slot.
- STR BlobStats TM handling
- New ACS CTRL commands.
## Fixed
- RW commanding
# [v6.0.0] 2024-02-08
## Changed
- Bumped `tmccmd` to `v8.0.0rc1` to introduce new command tree handling.
- Added new PLOC SUPV commands to test sets, cleaned up PLOC SUPV commanding.
# [v5.13.0] 2024-01-30
## Added
- First variant of TM handling with a DB which might serve as a foundation for better TM
handling with an ORM in the future.
- Added new parameter commands for PLOC MPSoC to skip SUPV commanding.
# [v5.12.1] 2023-12-13
## Added
- A few new commands to test the TC scheduler.
# [v5.12.0] 2023-12-06
## Added
- New ACS controller commands.
# [v5.11.0] 2023-11-30
## Added

View File

@ -1,20 +1,28 @@
import logging
from spacepackets.cfdp import ConditionCode
from tmtccmd.cfdp.mib import DefaultFaultHandlerBase
from spacepackets.cfdp import ConditionCode, TransactionId
from cfdppy.mib import DefaultFaultHandlerBase
_LOGGER = logging.getLogger(__name__)
class EiveCfdpFaultHandler(DefaultFaultHandlerBase):
def notice_of_suspension_cb(self, cond: ConditionCode):
def notice_of_suspension_cb(
self, transaction_id: TransactionId, cond: ConditionCode, progress: int
):
_LOGGER.info(f"Received notice of suspension: {cond!r}")
def notice_of_cancellation_cb(self, cond: ConditionCode):
def notice_of_cancellation_cb(
self, transaction_id: TransactionId, cond: ConditionCode, progress: int
):
_LOGGER.info(f"Received notice of cancellation: {cond!r}")
def abandoned_cb(self, cond: ConditionCode):
def abandoned_cb(
self, transaction_id: TransactionId, cond: ConditionCode, progress: int
):
_LOGGER.info(f"Abandoned transaction: {cond!r}")
def ignore_cb(self, cond: ConditionCode):
def ignore_cb(
self, transaction_id: TransactionId, cond: ConditionCode, progress: int
):
_LOGGER.info(f"Ignored transaction: {cond!r}")

View File

@ -5,22 +5,22 @@ import deprecation
from spacepackets import PacketType, SpacePacket, SpacePacketHeader
from spacepackets.cfdp import GenericPduPacket, PduFactory
from spacepackets.cfdp.pdu import PduHolder
from tmtccmd.cfdp import (
from cfdppy import (
CfdpUserBase,
LocalEntityCfg,
RemoteEntityCfgTable,
)
from tmtccmd.cfdp.defs import CfdpState
from tmtccmd.cfdp.handler import (
from cfdppy.defs import CfdpState
from cfdppy.handler import (
DestHandler,
DestStateWrapper,
SourceHandler,
SourceStateWrapper,
)
from tmtccmd.cfdp.handler.common import PacketDestination, get_packet_destination
from tmtccmd.cfdp.mib import CheckTimerProvider
from tmtccmd.cfdp.request import PutRequest
from tmtccmd.util import ProvidesSeqCount
from cfdppy.handler.common import PacketDestination, get_packet_destination
from cfdppy.mib import CheckTimerProvider
from cfdppy.request import PutRequest
from spacepackets.seqcount import ProvidesSeqCount
from tmtccmd.version import get_version
@ -62,13 +62,7 @@ class CfdpHandler:
)
def put_request(self, request: PutRequest):
if not self.remote_cfg_table.get_cfg(request.destination_id):
raise ValueError(
f"No remote CFDP config found for entity ID {request.destination_id}"
)
self.source_handler.put_request(
request, self.remote_cfg_table.get_cfg(request.destination_id) # type: ignore
)
self.source_handler.put_request(request)
def pull_next_source_packet(self) -> Optional[PduHolder]:
res = self.source_handler.state_machine()

View File

@ -4,7 +4,7 @@ from typing import Any
from eive_tmtc.config.definitions import CFDP_APID
from spacepackets.ccsds import SPACE_PACKET_HEADER_SIZE
from spacepackets.cfdp import PduFactory, PduType
from tmtccmd.cfdp.handler import CfdpInCcsdsHandler
from eive_tmtc.cfdp.handler import CfdpInCcsdsHandler
from tmtccmd.tmtc import SpecificApidHandlerBase
_LOGGER = logging.getLogger(__name__)

View File

@ -3,12 +3,13 @@ import logging
from spacepackets.cfdp import ConditionCode
from spacepackets.util import UnsignedByteField
from tmtccmd.cfdp import CfdpUserBase, TransactionId
from tmtccmd.cfdp.mib import CheckTimerProvider, Countdown, EntityType
from tmtccmd.cfdp.user import (
from cfdppy import CfdpUserBase, TransactionId
from cfdppy.mib import CheckTimerProvider, Countdown, EntityType
from cfdppy.user import (
TransactionFinishedParams,
MetadataRecvParams,
FileSegmentRecvdParams,
TransactionParams,
)
_LOGGER = logging.getLogger(__name__)
@ -25,17 +26,22 @@ class EiveCheckTimerProvider(CheckTimerProvider):
class EiveCfdpUser(CfdpUserBase):
def transaction_indication(self, transaction_id: TransactionId):
_LOGGER.info(f"CFDP User: Start of File {transaction_id}")
def transaction_indication(
self,
transaction_indication_params: TransactionParams,
):
_LOGGER.info(
f"CFDP User: Start of File {transaction_indication_params.transaction_id}"
)
def eof_sent_indication(self, transaction_id: TransactionId):
_LOGGER.info(f"CFDP User: EOF sent for {transaction_id}")
def transaction_finished_indication(self, params: TransactionFinishedParams):
_LOGGER.info(f"CFDP User: {params.transaction_id} finished")
_LOGGER.info(f"Delivery Code: {params.delivery_code!r}")
_LOGGER.info(f"Condition code: {params.condition_code!r}")
_LOGGER.info(f"File delivery status: {params.delivery_code!r}")
_LOGGER.info(f"Delivery Code: {params.finished_params.delivery_code!r}")
_LOGGER.info(f"Condition code: {params.finished_params.condition_code!r}")
_LOGGER.info(f"File delivery status: {params.finished_params.delivery_code!r}")
def metadata_recv_indication(self, params: MetadataRecvParams):
pass

View File

@ -0,0 +1 @@
from .definitions import * # noqa

View File

@ -3,6 +3,7 @@
@details Template configuration file. Copy this folder to the TMTC commander root and adapt
it to your needs.
"""
import enum
from tmtccmd import CcsdsTmtcBackend

View File

@ -11,6 +11,15 @@ from spacepackets.ccsds import PacketId
from spacepackets.util import UnsignedByteField
TM_DB_PATH = "tm.db"
# Separate DB or not? Not sure..
# RAW_TM_PATH = "raw_tm.db"
# TODO: The cleanest way would be to load those from the config file..
PRINT_RAW_HK_B64_STR = False
PRINT_RAW_ACTION_DATA_REPLY_B64_STR = True
PRINT_RAW_EVENTS_B64_STR = False
PUS_APID = 0x65
CFDP_APID = 0x66
PUS_PACKET_ID = PacketId(PacketType.TM, True, PUS_APID)

View File

@ -75,9 +75,12 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
7902;0x1ede;BIT_LOCK;INFO;A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
7903;0x1edf;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
7905;0x1ee1;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
8900;0x22c4;CLOCK_SET;INFO;No description;fsfw/src/fsfw/pus/Service9TimeManagement.h
8901;0x22c5;CLOCK_DUMP;INFO;No description;fsfw/src/fsfw/pus/Service9TimeManagement.h
8902;0x22c6;CLOCK_SET_FAILURE;LOW;No description;fsfw/src/fsfw/pus/Service9TimeManagement.h
8900;0x22c4;CLOCK_SET;INFO;Clock has been set. P1: old timeval seconds. P2: new timeval seconds.;fsfw/src/fsfw/pus/Service9TimeManagement.h
8901;0x22c5;CLOCK_DUMP_LEGACY;INFO;Clock dump event. P1: timeval seconds P2: timeval milliseconds.;fsfw/src/fsfw/pus/Service9TimeManagement.h
8902;0x22c6;CLOCK_SET_FAILURE;LOW;Clock could not be set. P1: Returncode.;fsfw/src/fsfw/pus/Service9TimeManagement.h
8903;0x22c7;CLOCK_DUMP;INFO;Clock dump event. P1: timeval seconds P2: timeval microseconds.;fsfw/src/fsfw/pus/Service9TimeManagement.h
8904;0x22c8;CLOCK_DUMP_BEFORE_SETTING_TIME;INFO;No description;fsfw/src/fsfw/pus/Service9TimeManagement.h
8905;0x22c9;CLOCK_DUMP_AFTER_SETTING_TIME;INFO;No description;fsfw/src/fsfw/pus/Service9TimeManagement.h
9100;0x238c;TC_DELETION_FAILED;MEDIUM;Deletion of a TC from the map failed. P1: First 32 bit of request ID, P2. Last 32 bit of Request ID;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
9700;0x25e4;TEST;INFO;No description;fsfw/src/fsfw/pus/Service17Test.h
10600;0x2968;CHANGE_OF_SETUP_PARAMETER;LOW;No description;fsfw/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h
@ -88,14 +91,17 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
10804;0x2a34;FILENAME_TOO_LARGE_ERROR;LOW;P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name;fsfw/src/fsfw/cfdp/handler/defs.h
10805;0x2a35;HANDLING_CFDP_REQUEST_FAILED;LOW;CFDP request handling failed. P2: Returncode.;fsfw/src/fsfw/cfdp/handler/defs.h
11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;The limits for the rotation in safe mode were violated.;mission/acs/defs.h
11201;0x2bc1;SAFE_RATE_RECOVERY;MEDIUM;The system has recovered from a safe rate rotation violation.;mission/acs/defs.h
11201;0x2bc1;RATE_RECOVERY;MEDIUM;The system has recovered from a rate rotation violation.;mission/acs/defs.h
11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;Multiple RWs are invalid, uncommandable and therefore higher ACS modes cannot be maintained.;mission/acs/defs.h
11203;0x2bc3;MEKF_INVALID_INFO;INFO;MEKF was not able to compute a solution. P1: MEKF state on exit;mission/acs/defs.h
11204;0x2bc4;MEKF_RECOVERY;INFO;MEKF is able to compute a solution again.;mission/acs/defs.h
11205;0x2bc5;MEKF_AUTOMATIC_RESET;INFO;MEKF performed an automatic reset after detection of nonfinite values.;mission/acs/defs.h
11206;0x2bc6;MEKF_INVALID_MODE_VIOLATION;HIGH;MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time.;mission/acs/defs.h
11206;0x2bc6;PTG_CTRL_NO_ATTITUDE_INFORMATION;HIGH;For a prolonged time, no attitude information was available for the Pointing Controller. Falling back to Safe Mode.;mission/acs/defs.h
11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h
11208;0x2bc8;TLE_TOO_OLD;INFO;The TLE for the SGP4 Propagator has become too old.;mission/acs/defs.h
11209;0x2bc9;TLE_FILE_READ_FAILED;LOW;The TLE could not be read from the filesystem.;mission/acs/defs.h
11210;0x2bca;PTG_RATE_VIOLATION;MEDIUM;The limits for the rotation in pointing mode were violated.;mission/acs/defs.h
11211;0x2bcb;DETUMBLE_TRANSITION_FAILED;HIGH;The detumble transition has failed. //! P1: Last detumble state before failure.;mission/acs/defs.h
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
@ -122,14 +128,15 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11506;0x2cf2;DEPL_SA1_GPIO_SWTICH_OFF_FAILED;HIGH;No description;mission/SolarArrayDeploymentHandler.h
11507;0x2cf3;DEPL_SA2_GPIO_SWTICH_OFF_FAILED;HIGH;No description;mission/SolarArrayDeploymentHandler.h
11508;0x2cf4;AUTONOMOUS_DEPLOYMENT_COMPLETED;INFO;No description;mission/SolarArrayDeploymentHandler.h
11601;0x2d51;MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC crc failure in telemetry packet;linux/payload/PlocMpsocHandler.h
11602;0x2d52;ACK_FAILURE;LOW;PLOC receive acknowledgment failure report P1: Command Id which leads the acknowledgment failure report P2: The status field inserted by the MPSoC into the data field;linux/payload/PlocMpsocHandler.h
11603;0x2d53;EXE_FAILURE;LOW;PLOC receive execution failure report P1: Command Id which leads the execution failure report P2: The status field inserted by the MPSoC into the data field;linux/payload/PlocMpsocHandler.h
11604;0x2d54;MPSOC_HANDLER_CRC_FAILURE;LOW;PLOC reply has invalid crc;linux/payload/PlocMpsocHandler.h
11605;0x2d55;MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH;LOW;Packet sequence count in received space packet does not match expected count P1: Expected sequence count P2: Received sequence count;linux/payload/PlocMpsocHandler.h
11606;0x2d56;MPSOC_SHUTDOWN_FAILED;HIGH;Supervisor fails to shutdown MPSoC. Requires to power off the PLOC and thus also to shutdown the supervisor.;linux/payload/PlocMpsocHandler.h
11607;0x2d57;SUPV_NOT_ON;LOW;SUPV not on for boot or shutdown process. P1: 0 for OFF transition, 1 for ON transition.;linux/payload/PlocMpsocHandler.h
11608;0x2d58;SUPV_REPLY_TIMEOUT;LOW;No description;linux/payload/PlocMpsocHandler.h
11601;0x2d51;MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC crc failure in telemetry packet;linux/payload/plocMpsocHelpers.h
11602;0x2d52;ACK_FAILURE;LOW;PLOC receive acknowledgment failure report P1: Command Id which leads the acknowledgment failure report P2: The status field inserted by the MPSoC into the data field;linux/payload/plocMpsocHelpers.h
11603;0x2d53;EXE_FAILURE;LOW;PLOC receive execution failure report P1: Command Id which leads the execution failure report P2: The status field inserted by the MPSoC into the data field;linux/payload/plocMpsocHelpers.h
11604;0x2d54;MPSOC_HANDLER_CRC_FAILURE;LOW;PLOC reply has invalid crc;linux/payload/plocMpsocHelpers.h
11605;0x2d55;MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH;LOW;Packet sequence count in received space packet does not match expected count P1: Expected sequence count P2: Received sequence count;linux/payload/plocMpsocHelpers.h
11606;0x2d56;MPSOC_SHUTDOWN_FAILED;HIGH;Supervisor fails to shutdown MPSoC. Requires to power off the PLOC and thus also to shutdown the supervisor.;linux/payload/plocMpsocHelpers.h
11607;0x2d57;SUPV_NOT_ON;LOW;SUPV not on for boot or shutdown process. P1: 0 for OFF transition, 1 for ON transition.;linux/payload/plocMpsocHelpers.h
11608;0x2d58;SUPV_REPLY_TIMEOUT;LOW;SUPV reply timeout.;linux/payload/plocMpsocHelpers.h
11609;0x2d59;CAM_MUST_BE_ON_FOR_SNAPSHOT_MODE;LOW;Camera must be commanded on first.;linux/payload/plocMpsocHelpers.h
11701;0x2db5;SELF_TEST_I2C_FAILURE;LOW;Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h
11702;0x2db6;SELF_TEST_SPI_FAILURE;LOW;Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h
11703;0x2db7;SELF_TEST_ADC_FAILURE;LOW;Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h
@ -230,8 +237,9 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h
12903;0x3267;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/SusAssembly.h
13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;No description;mission/system/tcs/TcsBoardAssembly.h
13100;0x332c;GPS_FIX_CHANGE;INFO;Fix has changed. P1: Old fix. P2: New fix 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix;mission/acs/archive/GPSDefinitions.h
13101;0x332d;CANT_GET_FIX;LOW;Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on.;mission/acs/archive/GPSDefinitions.h
13100;0x332c;GPS_FIX_CHANGE;INFO;Fix has changed. P1: New fix. P2: Missed fix changes 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix;linux/acs/GPSDefinitions.h
13101;0x332d;CANT_GET_FIX;MEDIUM;Could not get fix in maximum allowed time. Trying to reset both GNSS devices. P1: Maximum allowed time to get a fix after the GPS was switched on.;linux/acs/GPSDefinitions.h
13102;0x332e;RESET_FAIL;HIGH;Failed to reset an GNNS Device. P1: Board-Side.;linux/acs/GPSDefinitions.h
13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/power/P60DockHandler.h
13201;0x3391;BATT_MODE;INFO;Battery mode is broadcasted at startup. P1: Mode;mission/power/P60DockHandler.h
13202;0x3392;BATT_MODE_CHANGED;MEDIUM;Battery mode has changed. P1: Old mode. P2: New mode;mission/power/P60DockHandler.h

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
75 7902 0x1ede BIT_LOCK INFO A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0 fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
76 7903 0x1edf BIT_LOCK_LOST INFO A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0 fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
77 7905 0x1ee1 FRAME_PROCESSING_FAILED LOW The CCSDS Board could not interpret a TC fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
78 8900 0x22c4 CLOCK_SET INFO No description Clock has been set. P1: old timeval seconds. P2: new timeval seconds. fsfw/src/fsfw/pus/Service9TimeManagement.h
79 8901 0x22c5 CLOCK_DUMP CLOCK_DUMP_LEGACY INFO No description Clock dump event. P1: timeval seconds P2: timeval milliseconds. fsfw/src/fsfw/pus/Service9TimeManagement.h
80 8902 0x22c6 CLOCK_SET_FAILURE LOW No description Clock could not be set. P1: Returncode. fsfw/src/fsfw/pus/Service9TimeManagement.h
81 8903 0x22c7 CLOCK_DUMP INFO Clock dump event. P1: timeval seconds P2: timeval microseconds. fsfw/src/fsfw/pus/Service9TimeManagement.h
82 8904 0x22c8 CLOCK_DUMP_BEFORE_SETTING_TIME INFO No description fsfw/src/fsfw/pus/Service9TimeManagement.h
83 8905 0x22c9 CLOCK_DUMP_AFTER_SETTING_TIME INFO No description fsfw/src/fsfw/pus/Service9TimeManagement.h
84 9100 0x238c TC_DELETION_FAILED MEDIUM Deletion of a TC from the map failed. P1: First 32 bit of request ID, P2. Last 32 bit of Request ID fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
85 9700 0x25e4 TEST INFO No description fsfw/src/fsfw/pus/Service17Test.h
86 10600 0x2968 CHANGE_OF_SETUP_PARAMETER LOW No description fsfw/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h
91 10804 0x2a34 FILENAME_TOO_LARGE_ERROR LOW P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name fsfw/src/fsfw/cfdp/handler/defs.h
92 10805 0x2a35 HANDLING_CFDP_REQUEST_FAILED LOW CFDP request handling failed. P2: Returncode. fsfw/src/fsfw/cfdp/handler/defs.h
93 11200 0x2bc0 SAFE_RATE_VIOLATION MEDIUM The limits for the rotation in safe mode were violated. mission/acs/defs.h
94 11201 0x2bc1 SAFE_RATE_RECOVERY RATE_RECOVERY MEDIUM The system has recovered from a safe rate rotation violation. The system has recovered from a rate rotation violation. mission/acs/defs.h
95 11202 0x2bc2 MULTIPLE_RW_INVALID HIGH Multiple RWs are invalid, uncommandable and therefore higher ACS modes cannot be maintained. mission/acs/defs.h
96 11203 0x2bc3 MEKF_INVALID_INFO INFO MEKF was not able to compute a solution. P1: MEKF state on exit mission/acs/defs.h
97 11204 0x2bc4 MEKF_RECOVERY INFO MEKF is able to compute a solution again. mission/acs/defs.h
98 11205 0x2bc5 MEKF_AUTOMATIC_RESET INFO MEKF performed an automatic reset after detection of nonfinite values. mission/acs/defs.h
99 11206 0x2bc6 MEKF_INVALID_MODE_VIOLATION PTG_CTRL_NO_ATTITUDE_INFORMATION HIGH MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time. For a prolonged time, no attitude information was available for the Pointing Controller. Falling back to Safe Mode. mission/acs/defs.h
100 11207 0x2bc7 SAFE_MODE_CONTROLLER_FAILURE HIGH The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate mission/acs/defs.h
101 11208 0x2bc8 TLE_TOO_OLD INFO The TLE for the SGP4 Propagator has become too old. mission/acs/defs.h
102 11209 0x2bc9 TLE_FILE_READ_FAILED LOW The TLE could not be read from the filesystem. mission/acs/defs.h
103 11210 0x2bca PTG_RATE_VIOLATION MEDIUM The limits for the rotation in pointing mode were violated. mission/acs/defs.h
104 11211 0x2bcb DETUMBLE_TRANSITION_FAILED HIGH The detumble transition has failed. //! P1: Last detumble state before failure. mission/acs/defs.h
105 11300 0x2c24 SWITCH_CMD_SENT INFO Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index mission/power/defs.h
106 11301 0x2c25 SWITCH_HAS_CHANGED INFO Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index mission/power/defs.h
107 11302 0x2c26 SWITCHING_Q7S_DENIED MEDIUM No description mission/power/defs.h
128 11506 0x2cf2 DEPL_SA1_GPIO_SWTICH_OFF_FAILED HIGH No description mission/SolarArrayDeploymentHandler.h
129 11507 0x2cf3 DEPL_SA2_GPIO_SWTICH_OFF_FAILED HIGH No description mission/SolarArrayDeploymentHandler.h
130 11508 0x2cf4 AUTONOMOUS_DEPLOYMENT_COMPLETED INFO No description mission/SolarArrayDeploymentHandler.h
131 11601 0x2d51 MEMORY_READ_RPT_CRC_FAILURE LOW PLOC crc failure in telemetry packet linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
132 11602 0x2d52 ACK_FAILURE LOW PLOC receive acknowledgment failure report P1: Command Id which leads the acknowledgment failure report P2: The status field inserted by the MPSoC into the data field linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
133 11603 0x2d53 EXE_FAILURE LOW PLOC receive execution failure report P1: Command Id which leads the execution failure report P2: The status field inserted by the MPSoC into the data field linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
134 11604 0x2d54 MPSOC_HANDLER_CRC_FAILURE LOW PLOC reply has invalid crc linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
135 11605 0x2d55 MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH LOW Packet sequence count in received space packet does not match expected count P1: Expected sequence count P2: Received sequence count linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
136 11606 0x2d56 MPSOC_SHUTDOWN_FAILED HIGH Supervisor fails to shutdown MPSoC. Requires to power off the PLOC and thus also to shutdown the supervisor. linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
137 11607 0x2d57 SUPV_NOT_ON LOW SUPV not on for boot or shutdown process. P1: 0 for OFF transition, 1 for ON transition. linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
138 11608 0x2d58 SUPV_REPLY_TIMEOUT LOW No description SUPV reply timeout. linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
139 11609 0x2d59 CAM_MUST_BE_ON_FOR_SNAPSHOT_MODE LOW Camera must be commanded on first. linux/payload/plocMpsocHelpers.h
140 11701 0x2db5 SELF_TEST_I2C_FAILURE LOW Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA mission/acs/ImtqHandler.h
141 11702 0x2db6 SELF_TEST_SPI_FAILURE LOW Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA mission/acs/ImtqHandler.h
142 11703 0x2db7 SELF_TEST_ADC_FAILURE LOW Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA mission/acs/ImtqHandler.h
237 12902 0x3266 POWER_STATE_MACHINE_TIMEOUT MEDIUM No description mission/system/acs/SusAssembly.h
238 12903 0x3267 SIDE_SWITCH_TRANSITION_NOT_ALLOWED LOW Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination mission/system/acs/SusAssembly.h
239 13000 0x32c8 CHILDREN_LOST_MODE MEDIUM No description mission/system/tcs/TcsBoardAssembly.h
240 13100 0x332c GPS_FIX_CHANGE INFO Fix has changed. P1: Old fix. P2: New fix 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix Fix has changed. P1: New fix. P2: Missed fix changes 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix mission/acs/archive/GPSDefinitions.h linux/acs/GPSDefinitions.h
241 13101 0x332d CANT_GET_FIX LOW MEDIUM Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on. Could not get fix in maximum allowed time. Trying to reset both GNSS devices. P1: Maximum allowed time to get a fix after the GPS was switched on. mission/acs/archive/GPSDefinitions.h linux/acs/GPSDefinitions.h
242 13102 0x332e RESET_FAIL HIGH Failed to reset an GNNS Device. P1: Board-Side. linux/acs/GPSDefinitions.h
243 13200 0x3390 P60_BOOT_COUNT INFO P60 boot count is broadcasted once at SW startup. P1: Boot count mission/power/P60DockHandler.h
244 13201 0x3391 BATT_MODE INFO Battery mode is broadcasted at startup. P1: Mode mission/power/P60DockHandler.h
245 13202 0x3392 BATT_MODE_CHANGED MEDIUM Battery mode has changed. P1: Old mode. P2: New mode mission/power/P60DockHandler.h

View File

@ -1,33 +1,147 @@
from typing import Optional
from eive_tmtc.config.definitions import SPACE_PACKET_IDS
from tmtccmd import HookBase, CcsdsTmtcBackend
from prompt_toolkit.history import FileHistory
from tmtccmd import CcsdsTmtcBackend, HookBase
from tmtccmd.com import ComInterface
from tmtccmd.config import TmtcDefinitionWrapper
from eive_tmtc.config.retvals import get_retval_dict
from eive_tmtc.pus_tc.cmd_definitions import get_eive_service_op_code_dict
from tmtccmd.config import CmdTreeNode
from tmtccmd.config.hook import History
from tmtccmd.util import ObjectIdDictT, RetvalDictT
from eive_tmtc.config.definitions import SPACE_PACKET_IDS
from eive_tmtc.config.retvals import get_retval_dict
from eive_tmtc.tmtc.acs.acs_board import create_acs_board_node
from eive_tmtc.tmtc.acs.acs_ctrl import create_acs_ctrl_node
from eive_tmtc.tmtc.acs.gps import create_gnss_node
from eive_tmtc.tmtc.acs.gyros import create_gyros_node
from eive_tmtc.tmtc.acs.imtq import create_mgt_node
from eive_tmtc.tmtc.acs.mgms import create_mgms_node
from eive_tmtc.tmtc.acs.reaction_wheels import (
create_reaction_wheel_assembly_node,
create_reaction_wheels_nodes,
)
from eive_tmtc.tmtc.acs.star_tracker import create_str_node
from eive_tmtc.tmtc.acs.subsystem import create_acs_subsystem_node
from eive_tmtc.tmtc.com.ccsds_handler import create_ccsds_node
from eive_tmtc.tmtc.com.subsystem import create_com_subsystem_node
from eive_tmtc.tmtc.com.syrlinks_handler import create_syrlinks_node
from eive_tmtc.tmtc.core import create_core_node
from eive_tmtc.tmtc.health import create_global_health_node
from eive_tmtc.tmtc.payload.ploc_mpsoc import create_ploc_mpsoc_node
from eive_tmtc.tmtc.payload.ploc_supervisor import create_ploc_supv_node
from eive_tmtc.tmtc.payload.plpcdu import create_pl_pcdu_node
from eive_tmtc.tmtc.payload.scex import create_scex_node
from eive_tmtc.tmtc.payload.subsystem import create_payload_subsystem_node
from eive_tmtc.tmtc.power.acu import create_acu_node
from eive_tmtc.tmtc.power.bpx_batt import create_bpx_batt_node
from eive_tmtc.tmtc.power.p60dock import create_p60_dock_node
from eive_tmtc.tmtc.power.pdu1 import create_pdu1_node
from eive_tmtc.tmtc.power.pdu2 import create_pdu2_node
from eive_tmtc.tmtc.power.power import create_power_node
from eive_tmtc.tmtc.power.pwr_ctrl import create_pwr_ctrl_node
from eive_tmtc.tmtc.power.subsystem import create_eps_subsystem_node
from eive_tmtc.tmtc.system import create_system_node
from eive_tmtc.tmtc.tcs.ctrl import create_tcs_ctrl_node
from eive_tmtc.tmtc.tcs.heater import create_heater_node
from eive_tmtc.tmtc.tcs.rtd import create_rtd_node
from eive_tmtc.tmtc.tcs.tmp1075 import create_tmp_sens_node
from eive_tmtc.tmtc.test import create_test_node
from eive_tmtc.tmtc.time import create_time_node
from eive_tmtc.tmtc.tm_store import create_persistent_tm_store_node
from eive_tmtc.tmtc.wdt import create_wdt_node
class EiveHookObject(HookBase):
def __init__(self, json_cfg_path: str):
super().__init__(json_cfg_path=json_cfg_path)
super().__init__(json_cfg_path)
def get_tmtc_definitions(self) -> TmtcDefinitionWrapper:
return get_eive_service_op_code_dict()
def assign_communication_interface(self, com_if_key: str) -> Optional[ComInterface]:
from tmtccmd.config.com import (
create_com_interface_default,
create_com_interface_cfg_default,
def get_command_definitions(self) -> CmdTreeNode:
root_node = CmdTreeNode.root_node()
acs_node = create_acs_subsystem_node()
acs_brd_assy_node = create_acs_board_node()
acs_brd_assy_node.add_child(create_mgms_node())
acs_brd_assy_node.add_child(create_gyros_node())
acs_ctrl = create_acs_ctrl_node()
rw_list = create_reaction_wheels_nodes()
rws = CmdTreeNode("rws", "Reaction Wheel Devices")
for rw in rw_list:
rws.add_child(rw)
rws.add_child(create_reaction_wheel_assembly_node())
star_tracker = create_str_node()
star_tracker_img_helper = CmdTreeNode(
"str_img_helper", "Star Tracker Image Helper"
)
star_tracker.add_child(star_tracker_img_helper)
gnss_devs = create_gnss_node()
acs_node.add_child(acs_brd_assy_node)
acs_node.add_child(acs_ctrl)
acs_node.add_child(rws)
acs_node.add_child(create_mgt_node())
acs_node.add_child(star_tracker)
acs_node.add_child(gnss_devs)
tcs_node = CmdTreeNode("tcs", "TCS Subsystem")
tmp_1075_node = create_tmp_sens_node()
rtds_node = create_rtd_node()
heaters_node = create_heater_node()
tcs_ctrl = create_tcs_ctrl_node()
tcs_node.add_child(rtds_node)
tcs_node.add_child(tmp_1075_node)
tcs_node.add_child(tcs_ctrl)
tcs_node.add_child(heaters_node)
tcs_brd_assy = CmdTreeNode("tcs_brd_assy", "TCS Board Assembly")
tcs_node.add_child(tcs_brd_assy)
com_node = create_com_subsystem_node()
com_node.add_child(create_syrlinks_node())
com_node.add_child(create_ccsds_node())
eps_node = create_eps_subsystem_node()
eps_node.add_child(create_pwr_ctrl_node())
eps_node.add_child(create_power_node())
eps_node.add_child(create_acu_node())
eps_node.add_child(create_pdu1_node())
eps_node.add_child(create_pdu2_node())
eps_node.add_child(create_p60_dock_node())
eps_node.add_child(create_bpx_batt_node())
payload_node = create_payload_subsystem_node()
payload_node.add_child(create_pl_pcdu_node())
payload_node.add_child(create_scex_node())
payload_node.add_child(create_ploc_mpsoc_node())
payload_node.add_child(create_ploc_supv_node())
obdh_node = CmdTreeNode("obdh", "OBDH Subsystem")
obdh_node.add_child(create_wdt_node())
obdh_node.add_child(create_core_node())
obdh_node.add_child(create_time_node())
obdh_node.add_child(create_persistent_tm_store_node())
root_node.add_child(create_test_node())
root_node.add_child(create_system_node())
root_node.add_child(create_global_health_node())
root_node.add_child(acs_node)
root_node.add_child(tcs_node)
root_node.add_child(com_node)
root_node.add_child(eps_node)
root_node.add_child(payload_node)
root_node.add_child(obdh_node)
return root_node
def get_communication_interface(self, com_if_key: str) -> Optional[ComInterface]:
from tmtccmd.config.com import (
create_com_interface_cfg_default,
create_com_interface_default,
)
assert self.cfg_path is not None
cfg = create_com_interface_cfg_default(
com_if_key=com_if_key,
json_cfg_path=self.cfg_path,
space_packet_ids=SPACE_PACKET_IDS,
)
assert cfg is not None
return create_com_interface_default(cfg)
def perform_mode_operation(self, tmtc_backend: CcsdsTmtcBackend, mode: int):
@ -42,3 +156,6 @@ class EiveHookObject(HookBase):
def get_retval_dict(self) -> RetvalDictT:
return get_retval_dict()
def get_cmd_history(self) -> Optional[History]:
return FileHistory(".tmtc-history.txt")

View File

@ -3,6 +3,7 @@
@details Template configuration file. Copy this folder to the TMTC commander root and adapt
it to your needs.
"""
import logging
import os.path
from typing import Dict

View File

@ -56,6 +56,7 @@
0x44330015;PLOC_MPSOC_HANDLER
0x44330016;PLOC_SUPERVISOR_HANDLER
0x44330017;PLOC_SUPERVISOR_HELPER
0x44330018;PLOC_MPSOC_COMMUNICATION
0x44330032;SCEX
0x444100A2;SOLAR_ARRAY_DEPL_HANDLER
0x444100A4;HEATER_HANDLER

1 0x00005060 P60DOCK_TEST_TASK
56 0x44330015 PLOC_MPSOC_HANDLER
57 0x44330016 PLOC_SUPERVISOR_HANDLER
58 0x44330017 PLOC_SUPERVISOR_HELPER
59 0x44330018 PLOC_MPSOC_COMMUNICATION
60 0x44330032 SCEX
61 0x444100A2 SOLAR_ARRAY_DEPL_HANDLER
62 0x444100A4 HEATER_HANDLER

View File

@ -387,6 +387,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x4304;PUS11_InvalidRelativeTime;No description;4;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4305;PUS11_ContainedTcTooSmall;No description;5;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4306;PUS11_ContainedTcCrcMissmatch;No description;6;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4307;PUS11_MapIsFull;No description;7;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4400;FILS_GenericFileError;No description;0;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h
0x4401;FILS_GenericDirError;No description;1;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h
0x4402;FILS_FilesystemInactive;No description;2;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h
@ -453,6 +454,12 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x5208;IMTQ_CmdErrUnknown;No description;8;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x5209;IMTQ_StartupCfgError;No description;9;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x520a;IMTQ_UnexpectedSelfTestReply;The status reply to a self test command was received but no self test command has been sent. This should normally never happen.;10;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x53a0;RWHA_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000];160;RW_HANDLER;mission/acs/RwHandler.h
0x53a1;RWHA_InvalidRampTime;Action Message with invalid ramp time was received.;161;RW_HANDLER;mission/acs/RwHandler.h
0x53a2;RWHA_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;162;RW_HANDLER;mission/acs/RwHandler.h
0x53a3;RWHA_ExecutionFailed;Command execution failed;163;RW_HANDLER;mission/acs/RwHandler.h
0x53a4;RWHA_CrcError;Reaction wheel reply has invalid crc;164;RW_HANDLER;mission/acs/RwHandler.h
0x53a5;RWHA_ValueNotRead;No description;165;RW_HANDLER;mission/acs/RwHandler.h
0x53b0;RWHA_SpiWriteFailure;No description;176;RW_HANDLER;mission/acs/rwHelpers.h
0x53b1;RWHA_SpiReadFailure;Used by the spi send function to tell a failing read call;177;RW_HANDLER;mission/acs/rwHelpers.h
0x53b2;RWHA_MissingStartSign;Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E;178;RW_HANDLER;mission/acs/rwHelpers.h
@ -498,12 +505,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x58a1;PLSPVhLP_ProcessTerminated;Process has been terminated by command;161;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h
0x58a2;PLSPVhLP_PathNotExists;Received command with invalid pathname;162;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h
0x58a3;PLSPVhLP_EventBufferReplyInvalidApid;Expected event buffer TM but received space packet with other APID;163;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h
0x59a0;SUSS_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000];160;SUS_HANDLER;mission/acs/RwHandler.h
0x59a1;SUSS_InvalidRampTime;Action Message with invalid ramp time was received.;161;SUS_HANDLER;mission/acs/RwHandler.h
0x59a2;SUSS_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;162;SUS_HANDLER;mission/acs/RwHandler.h
0x59a3;SUSS_ExecutionFailed;Command execution failed;163;SUS_HANDLER;mission/acs/RwHandler.h
0x59a4;SUSS_CrcError;Reaction wheel reply has invalid crc;164;SUS_HANDLER;mission/acs/RwHandler.h
0x59a5;SUSS_ValueNotRead;No description;165;SUS_HANDLER;mission/acs/RwHandler.h
0x59a0;SUSS_ErrorUnlockMutex;No description;160;SUS_HANDLER;mission/acs/archive/LegacySusHandler.h
0x59a1;SUSS_ErrorLockMutex;No description;161;SUS_HANDLER;mission/acs/archive/LegacySusHandler.h
0x5aa0;IPCI_PapbBusy;No description;160;CCSDS_IP_CORE_BRIDGE;linux/ipcore/PapbVcInterface.h
0x5ba0;PTME_UnknownVcId;No description;160;PTME;linux/ipcore/Ptme.h
0x5d01;STRHLP_SdNotMounted;SD card specified in path string not mounted;1;STR_HELPER;linux/acs/StrComHandler.h
@ -558,16 +561,17 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x67a2;SADPL_MainSwitchTimeoutFailure;No description;162;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
0x67a3;SADPL_SwitchingDeplSa1Failed;No description;163;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
0x67a4;SADPL_SwitchingDeplSa2Failed;No description;164;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
0x68a0;MPSOCRTVIF_CrcFailure;Space Packet received from PLOC has invalid CRC;160;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h
0x68a1;MPSOCRTVIF_ReceivedAckFailure;Received ACK failure reply from PLOC;161;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h
0x68a2;MPSOCRTVIF_ReceivedExeFailure;Received execution failure reply from PLOC;162;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h
0x68a3;MPSOCRTVIF_InvalidApid;Received space packet with invalid APID from PLOC;163;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h
0x68a4;MPSOCRTVIF_InvalidLength;Received command with invalid length;164;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h
0x68a5;MPSOCRTVIF_FilenameTooLong;Filename of file in OBC filesystem is too long;165;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h
0x68a6;MPSOCRTVIF_MpsocHelperExecuting;MPSoC helper is currently executing a command;166;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h
0x68a7;MPSOCRTVIF_MpsocFilenameTooLong;Filename of MPSoC file is to long (max. 256 bytes);167;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h
0x68a8;MPSOCRTVIF_InvalidParameter;Command has invalid parameter;168;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h
0x68a9;MPSOCRTVIF_NameTooLong;Received command has file string with invalid length;169;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h
0x6810;MPSOCRTVIF_CommandTimeout;Command has timed out.;16;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a0;MPSOCRTVIF_CrcFailure;Space Packet received from PLOC has invalid CRC;160;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a1;MPSOCRTVIF_ReceivedAckFailure;Received ACK failure reply from PLOC;161;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a2;MPSOCRTVIF_ReceivedExeFailure;Received execution failure reply from PLOC;162;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a3;MPSOCRTVIF_InvalidApid;Received space packet with invalid APID from PLOC;163;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a4;MPSOCRTVIF_InvalidLength;Received command with invalid length;164;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a5;MPSOCRTVIF_FilenameTooLong;Filename of file in OBC filesystem is too long;165;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a6;MPSOCRTVIF_MpsocHelperExecuting;MPSoC helper is currently executing a command;166;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a7;MPSOCRTVIF_MpsocFilenameTooLong;Filename of MPSoC file is to long (max. 256 bytes);167;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a8;MPSOCRTVIF_InvalidParameter;Command has invalid parameter;168;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a9;MPSOCRTVIF_NameTooLong;Received command has file string with invalid length;169;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x69a0;SPVRTVIF_CrcFailure;Space Packet received from PLOC supervisor has invalid CRC;160;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
0x69a1;SPVRTVIF_InvalidServiceId;No description;161;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
0x69a2;SPVRTVIF_ReceivedAckFailure;Received ACK failure reply from PLOC supervisor;162;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
@ -592,7 +596,11 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x69b5;SPVRTVIF_SupvHelperExecuting;Supervisor helper task ist currently executing a command (wait until helper tas has finished or interrupt by sending the terminate command);181;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
0x69c0;SPVRTVIF_BufTooSmall;No description;192;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
0x69c1;SPVRTVIF_NoReplyTimeout;No description;193;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
0x6a00;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;0;ACS_CTRL;mission/controller/AcsController.h
0x6aa0;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;160;ACS_CTRL;mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
0x6aa1;ACSCTRL_WriteFileFailed;Writing the TLE to the file has failed.;161;ACS_CTRL;mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
0x6aa2;ACSCTRL_ReadFileFailed;Reading the TLE to the file has failed.;162;ACS_CTRL;mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
0x6aa3;ACSCTRL_SingleRwUnavailable;A single RW has failed.;163;ACS_CTRL;mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
0x6aa4;ACSCTRL_MultipleRwUnavailable;Multiple RWs have failed.;164;ACS_CTRL;mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
0x6b02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6b03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6b04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
@ -619,4 +627,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x6f02;TMS_NoWriteActive;No description;2;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x6f03;TMS_Timeout;No description;3;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x7000;VCS_ChannelDoesNotExist;No description;0;VIRTUAL_CHANNEL;mission/com/VirtualChannel.h
0x7200;SCBU_KeyNotFound;No description;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h
0x7100;PLMPCOM_PacketReceived;No description;0;PLOC_MPSOC_COM;linux/payload/MpsocCommunication.h
0x7101;PLMPCOM_FaultyPacketSize;No description;1;PLOC_MPSOC_COM;linux/payload/MpsocCommunication.h
0x7102;PLMPCOM_CrcCheckFailed;No description;2;PLOC_MPSOC_COM;linux/payload/MpsocCommunication.h
0x7300;SCBU_KeyNotFound;No description;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h

1 Full ID (hex) Name Description Unique ID Subsytem Name File Path
387 0x4304 PUS11_InvalidRelativeTime No description 4 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
388 0x4305 PUS11_ContainedTcTooSmall No description 5 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
389 0x4306 PUS11_ContainedTcCrcMissmatch No description 6 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
390 0x4307 PUS11_MapIsFull No description 7 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
391 0x4400 FILS_GenericFileError No description 0 FILE_SYSTEM fsfw/src/fsfw/filesystem/HasFileSystemIF.h
392 0x4401 FILS_GenericDirError No description 1 FILE_SYSTEM fsfw/src/fsfw/filesystem/HasFileSystemIF.h
393 0x4402 FILS_FilesystemInactive No description 2 FILE_SYSTEM fsfw/src/fsfw/filesystem/HasFileSystemIF.h
454 0x5208 IMTQ_CmdErrUnknown No description 8 IMTQ_HANDLER mission/acs/imtqHelpers.h
455 0x5209 IMTQ_StartupCfgError No description 9 IMTQ_HANDLER mission/acs/imtqHelpers.h
456 0x520a IMTQ_UnexpectedSelfTestReply The status reply to a self test command was received but no self test command has been sent. This should normally never happen. 10 IMTQ_HANDLER mission/acs/imtqHelpers.h
457 0x53a0 RWHA_InvalidSpeed Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000] 160 RW_HANDLER mission/acs/RwHandler.h
458 0x53a1 RWHA_InvalidRampTime Action Message with invalid ramp time was received. 161 RW_HANDLER mission/acs/RwHandler.h
459 0x53a2 RWHA_SetSpeedCommandInvalidLength Received set speed command has invalid length. Should be 6. 162 RW_HANDLER mission/acs/RwHandler.h
460 0x53a3 RWHA_ExecutionFailed Command execution failed 163 RW_HANDLER mission/acs/RwHandler.h
461 0x53a4 RWHA_CrcError Reaction wheel reply has invalid crc 164 RW_HANDLER mission/acs/RwHandler.h
462 0x53a5 RWHA_ValueNotRead No description 165 RW_HANDLER mission/acs/RwHandler.h
463 0x53b0 RWHA_SpiWriteFailure No description 176 RW_HANDLER mission/acs/rwHelpers.h
464 0x53b1 RWHA_SpiReadFailure Used by the spi send function to tell a failing read call 177 RW_HANDLER mission/acs/rwHelpers.h
465 0x53b2 RWHA_MissingStartSign Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E 178 RW_HANDLER mission/acs/rwHelpers.h
505 0x58a1 PLSPVhLP_ProcessTerminated Process has been terminated by command 161 PLOC_SUPV_HELPER linux/payload/PlocSupvUartMan.h
506 0x58a2 PLSPVhLP_PathNotExists Received command with invalid pathname 162 PLOC_SUPV_HELPER linux/payload/PlocSupvUartMan.h
507 0x58a3 PLSPVhLP_EventBufferReplyInvalidApid Expected event buffer TM but received space packet with other APID 163 PLOC_SUPV_HELPER linux/payload/PlocSupvUartMan.h
508 0x59a0 SUSS_InvalidSpeed SUSS_ErrorUnlockMutex Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000] No description 160 SUS_HANDLER mission/acs/RwHandler.h mission/acs/archive/LegacySusHandler.h
509 0x59a1 SUSS_InvalidRampTime SUSS_ErrorLockMutex Action Message with invalid ramp time was received. No description 161 SUS_HANDLER mission/acs/RwHandler.h mission/acs/archive/LegacySusHandler.h
0x59a2 SUSS_SetSpeedCommandInvalidLength Received set speed command has invalid length. Should be 6. 162 SUS_HANDLER mission/acs/RwHandler.h
0x59a3 SUSS_ExecutionFailed Command execution failed 163 SUS_HANDLER mission/acs/RwHandler.h
0x59a4 SUSS_CrcError Reaction wheel reply has invalid crc 164 SUS_HANDLER mission/acs/RwHandler.h
0x59a5 SUSS_ValueNotRead No description 165 SUS_HANDLER mission/acs/RwHandler.h
510 0x5aa0 IPCI_PapbBusy No description 160 CCSDS_IP_CORE_BRIDGE linux/ipcore/PapbVcInterface.h
511 0x5ba0 PTME_UnknownVcId No description 160 PTME linux/ipcore/Ptme.h
512 0x5d01 STRHLP_SdNotMounted SD card specified in path string not mounted 1 STR_HELPER linux/acs/StrComHandler.h
561 0x67a2 SADPL_MainSwitchTimeoutFailure No description 162 SA_DEPL_HANDLER mission/SolarArrayDeploymentHandler.h
562 0x67a3 SADPL_SwitchingDeplSa1Failed No description 163 SA_DEPL_HANDLER mission/SolarArrayDeploymentHandler.h
563 0x67a4 SADPL_SwitchingDeplSa2Failed No description 164 SA_DEPL_HANDLER mission/SolarArrayDeploymentHandler.h
564 0x68a0 0x6810 MPSOCRTVIF_CrcFailure MPSOCRTVIF_CommandTimeout Space Packet received from PLOC has invalid CRC Command has timed out. 160 16 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
565 0x68a1 0x68a0 MPSOCRTVIF_ReceivedAckFailure MPSOCRTVIF_CrcFailure Received ACK failure reply from PLOC Space Packet received from PLOC has invalid CRC 161 160 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
566 0x68a2 0x68a1 MPSOCRTVIF_ReceivedExeFailure MPSOCRTVIF_ReceivedAckFailure Received execution failure reply from PLOC Received ACK failure reply from PLOC 162 161 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
567 0x68a3 0x68a2 MPSOCRTVIF_InvalidApid MPSOCRTVIF_ReceivedExeFailure Received space packet with invalid APID from PLOC Received execution failure reply from PLOC 163 162 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
568 0x68a4 0x68a3 MPSOCRTVIF_InvalidLength MPSOCRTVIF_InvalidApid Received command with invalid length Received space packet with invalid APID from PLOC 164 163 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
569 0x68a5 0x68a4 MPSOCRTVIF_FilenameTooLong MPSOCRTVIF_InvalidLength Filename of file in OBC filesystem is too long Received command with invalid length 165 164 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
570 0x68a6 0x68a5 MPSOCRTVIF_MpsocHelperExecuting MPSOCRTVIF_FilenameTooLong MPSoC helper is currently executing a command Filename of file in OBC filesystem is too long 166 165 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
571 0x68a7 0x68a6 MPSOCRTVIF_MpsocFilenameTooLong MPSOCRTVIF_MpsocHelperExecuting Filename of MPSoC file is to long (max. 256 bytes) MPSoC helper is currently executing a command 167 166 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
572 0x68a8 0x68a7 MPSOCRTVIF_InvalidParameter MPSOCRTVIF_MpsocFilenameTooLong Command has invalid parameter Filename of MPSoC file is to long (max. 256 bytes) 168 167 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
573 0x68a9 0x68a8 MPSOCRTVIF_NameTooLong MPSOCRTVIF_InvalidParameter Received command has file string with invalid length Command has invalid parameter 169 168 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
574 0x68a9 MPSOCRTVIF_NameTooLong Received command has file string with invalid length 169 MPSOC_RETURN_VALUES_IF linux/payload/plocMpsocHelpers.h
575 0x69a0 SPVRTVIF_CrcFailure Space Packet received from PLOC supervisor has invalid CRC 160 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
576 0x69a1 SPVRTVIF_InvalidServiceId No description 161 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
577 0x69a2 SPVRTVIF_ReceivedAckFailure Received ACK failure reply from PLOC supervisor 162 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
596 0x69b5 SPVRTVIF_SupvHelperExecuting Supervisor helper task ist currently executing a command (wait until helper tas has finished or interrupt by sending the terminate command) 181 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
597 0x69c0 SPVRTVIF_BufTooSmall No description 192 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
598 0x69c1 SPVRTVIF_NoReplyTimeout No description 193 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
599 0x6a00 0x6aa0 ACSCTRL_FileDeletionFailed File deletion failed and at least one file is still existent. 0 160 ACS_CTRL mission/controller/AcsController.h mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
600 0x6aa1 ACSCTRL_WriteFileFailed Writing the TLE to the file has failed. 161 ACS_CTRL mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
601 0x6aa2 ACSCTRL_ReadFileFailed Reading the TLE to the file has failed. 162 ACS_CTRL mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
602 0x6aa3 ACSCTRL_SingleRwUnavailable A single RW has failed. 163 ACS_CTRL mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
603 0x6aa4 ACSCTRL_MultipleRwUnavailable Multiple RWs have failed. 164 ACS_CTRL mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
604 0x6b02 ACSMEKF_MekfUninitialized No description 2 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
605 0x6b03 ACSMEKF_MekfNoGyrData No description 3 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
606 0x6b04 ACSMEKF_MekfNoModelVectors No description 4 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
627 0x6f02 TMS_NoWriteActive No description 2 TM_SINK mission/tmtc/DirectTmSinkIF.h
628 0x6f03 TMS_Timeout No description 3 TM_SINK mission/tmtc/DirectTmSinkIF.h
629 0x7000 VCS_ChannelDoesNotExist No description 0 VIRTUAL_CHANNEL mission/com/VirtualChannel.h
630 0x7200 0x7100 SCBU_KeyNotFound PLMPCOM_PacketReceived No description 0 SCRATCH_BUFFER PLOC_MPSOC_COM bsp_q7s/memory/scratchApi.h linux/payload/MpsocCommunication.h
631 0x7101 PLMPCOM_FaultyPacketSize No description 1 PLOC_MPSOC_COM linux/payload/MpsocCommunication.h
632 0x7102 PLMPCOM_CrcCheckFailed No description 2 PLOC_MPSOC_COM linux/payload/MpsocCommunication.h
633 0x7300 SCBU_KeyNotFound No description 0 SCRATCH_BUFFER bsp_q7s/memory/scratchApi.h

View File

@ -1,21 +0,0 @@
from tmtccmd.config import TmtcDefinitionWrapper, OpCodeEntry, CoreServiceList
from tmtccmd.config.tmtc import (
call_all_definitions_providers,
)
from tmtccmd.config.globals import get_default_tmtc_defs
def get_eive_service_op_code_dict() -> TmtcDefinitionWrapper:
"""Call all registered TMTC definition providers. They were registered using
the :py:func:`tmtc_definitions_provider` decorator.
"""
def_wrapper = get_default_tmtc_defs()
srv_5 = OpCodeEntry()
srv_5.add("0", "Event Test")
def_wrapper.add_service(
name=CoreServiceList.SERVICE_5.value,
info="PUS Service 5 Event",
op_code_entry=srv_5,
)
call_all_definitions_providers(def_wrapper)
return def_wrapper

View File

@ -0,0 +1,309 @@
"""Hook function which packs telecommands based on service and operation code string
"""
import logging
from typing import List, cast
from tmtccmd import TreeCommandingProcedure
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.util import ObjectIdU32
import eive_tmtc.config.object_ids as oids
from eive_tmtc.config.object_ids import (
ACU_HANDLER_ID,
CCSDS_HANDLER_ID,
HEATER_CONTROLLER_ID,
IMTQ_HANDLER_ID,
P60_DOCK_HANDLER,
PDEC_HANDLER_ID,
PDU_1_HANDLER_ID,
PDU_2_HANDLER_ID,
RAD_SENSOR_ID,
RW1_ID,
RW2_ID,
RW3_ID,
RW4_ID,
RW_ASSEMBLY,
STAR_TRACKER_ID,
STR_IMG_HELPER_ID,
SYRLINKS_HANDLER_ID,
TMP1075_HANDLER_IF_BRD_ID,
TMP1075_HANDLER_PLPCDU_0_ID,
TMP1075_HANDLER_TCS_BRD_0_ID,
TMP1075_HANDLER_TCS_BRD_1_ID,
get_object_ids,
)
from eive_tmtc.tmtc.acs.acs_board import pack_acs_board_command
from eive_tmtc.tmtc.acs.acs_ctrl import pack_acs_ctrl_command
from eive_tmtc.tmtc.acs.gps import pack_gps_command
from eive_tmtc.tmtc.acs.gyros import handle_gyr_cmd
from eive_tmtc.tmtc.acs.imtq import create_imtq_command
from eive_tmtc.tmtc.acs.mgms import handle_mgm_cmd
from eive_tmtc.tmtc.acs.reaction_wheels import (
create_single_rw_cmd,
pack_rw_ass_cmds,
)
from eive_tmtc.tmtc.acs.star_tracker import pack_star_tracker_commands
from eive_tmtc.tmtc.acs.str_img_helper import pack_str_img_helper_command
from eive_tmtc.tmtc.acs.subsystem import build_acs_subsystem_cmd
from eive_tmtc.tmtc.com.ccsds_handler import pack_ccsds_handler_command
from eive_tmtc.tmtc.com.pdec_handler import pack_pdec_handler_commands
from eive_tmtc.tmtc.com.subsystem import build_com_subsystem_procedure
from eive_tmtc.tmtc.com.syrlinks_handler import pack_syrlinks_command
from eive_tmtc.tmtc.core import pack_core_commands
from eive_tmtc.tmtc.health import build_health_cmds
from eive_tmtc.tmtc.payload.subsystem import create_payload_subsystem_cmd
from eive_tmtc.tmtc.payload.ploc_mpsoc import pack_ploc_mpsoc_commands
from eive_tmtc.tmtc.payload.ploc_supervisor import pack_ploc_supv_commands
from eive_tmtc.tmtc.payload.plpcdu import pack_pl_pcdu_commands
from eive_tmtc.tmtc.payload.rad_sensor import create_rad_sensor_cmd
from eive_tmtc.tmtc.payload.scex import pack_scex_cmds
from eive_tmtc.tmtc.power.acu import pack_acu_commands
from eive_tmtc.tmtc.power.p60dock import pack_p60dock_cmds
from eive_tmtc.tmtc.power.pdu1 import pack_pdu1_commands
from eive_tmtc.tmtc.power.pdu2 import pack_pdu2_commands
from eive_tmtc.tmtc.power.power import pack_power_commands
from eive_tmtc.tmtc.power.pwr_ctrl import pack_power_ctrl_command
from eive_tmtc.tmtc.system import build_system_cmds
from eive_tmtc.tmtc.tcs.ctrl import pack_tcs_ctrl_commands
from eive_tmtc.tmtc.tcs.heater import pack_heater_cmds
from eive_tmtc.tmtc.tcs.rtd import pack_rtd_commands
from eive_tmtc.tmtc.tcs.subsystem import pack_tcs_sys_commands
from eive_tmtc.tmtc.tcs.tmp1075 import pack_tmp1075_test_into
from eive_tmtc.tmtc.test import build_test_commands
from eive_tmtc.tmtc.time import pack_time_management_cmd
from eive_tmtc.tmtc.tm_store import pack_tm_store_commands
from eive_tmtc.tmtc.wdt import pack_wdt_commands
from eive_tmtc.utility.input_helper import InputHelper
def handle_pus_procedure(
info: TreeCommandingProcedure,
queue_helper: DefaultPusQueueHelper,
):
cmd_path = info.cmd_path
assert cmd_path is not None
cmd_path_list = cmd_path.split("/")
if cmd_path_list[0] == "":
cmd_path_list = cmd_path_list[1:]
if len(cmd_path_list) == 0:
raise ValueError(
"command path list empty. Full command path {cmd_path} might have invalid format"
)
if cmd_path_list[0] == "system":
assert len(cmd_path_list) >= 1
return build_system_cmds(queue_helper, cmd_path_list[1])
if cmd_path_list[0] == "health":
assert len(cmd_path_list) >= 1
return build_health_cmds(queue_helper, cmd_path_list[1])
if cmd_path_list[0] == "eps":
return handle_eps_procedure(queue_helper, cmd_path_list[1:])
if cmd_path_list[0] == "tcs":
return handle_tcs_procedure(queue_helper, cmd_path_list[1:])
if cmd_path_list[0] == "acs":
return handle_acs_procedure(queue_helper, cmd_path_list[1:])
if cmd_path_list[0] == "payload":
return handle_payload_procedure(queue_helper, cmd_path_list[1:])
if cmd_path_list[0] == "obdh":
return handle_obdh_procedure(queue_helper, cmd_path_list[1:])
if cmd_path_list[0] == "test":
assert len(cmd_path_list) >= 1
return build_test_commands(queue_helper, cmd_path_list[1])
if cmd_path_list[0] == "com":
return handle_com_procedure(queue_helper, cmd_path_list[1:])
logging.getLogger(__name__).warning(
f"invalid or unimplemented command path {cmd_path}"
)
def handle_eps_procedure(queue_helper: DefaultPusQueueHelper, cmd_path_list: List[str]):
obj_id_man = get_object_ids()
assert len(cmd_path_list) >= 1
if cmd_path_list[0] == "power":
return pack_power_commands(queue_helper, cmd_path_list[1])
if cmd_path_list[0] == "pwr_ctrl":
return pack_power_ctrl_command(queue_helper, cmd_path_list[1])
if cmd_path_list[0] == "p60_dock":
object_id = cast(ObjectIdU32, obj_id_man.get(P60_DOCK_HANDLER))
return pack_p60dock_cmds(
object_id=object_id, q=queue_helper, cmd_str=cmd_path_list[1]
)
if cmd_path_list[0] == "pdu1":
object_id = cast(ObjectIdU32, obj_id_man.get(PDU_1_HANDLER_ID))
return pack_pdu1_commands(
object_id=object_id, q=queue_helper, cmd_str=cmd_path_list[1]
)
if cmd_path_list[0] == "pdu2":
object_id = cast(ObjectIdU32, obj_id_man.get(PDU_2_HANDLER_ID))
return pack_pdu2_commands(
object_id=object_id, q=queue_helper, cmd_str=cmd_path_list[1]
)
if cmd_path_list[0] == "acu":
object_id = cast(ObjectIdU32, obj_id_man.get(ACU_HANDLER_ID))
return pack_acu_commands(
object_id=object_id, q=queue_helper, cmd_str=cmd_path_list[1]
)
def handle_tcs_procedure(queue_helper: DefaultPusQueueHelper, cmd_path_list: List[str]):
obj_id_man = get_object_ids()
if len(cmd_path_list) == 1:
return pack_tcs_sys_commands(q=queue_helper, cmd_str=cmd_path_list[0])
assert len(cmd_path_list) >= 2
if cmd_path_list[0] == "tcs_brd_assy":
return pack_tcs_sys_commands(q=queue_helper, cmd_str=cmd_path_list[1])
if cmd_path_list[0] == "rtd_devs":
assert len(cmd_path_list) >= 2
return pack_rtd_commands(
object_id=None, q=queue_helper, cmd_str=cmd_path_list[1]
)
if cmd_path_list[0] == "tcs_ctrl":
assert len(cmd_path_list) >= 2
return pack_tcs_ctrl_commands(q=queue_helper, cmd_str=cmd_path_list[2])
if cmd_path_list[0] == "tmp1075_devs":
menu_dict = {
"0": ("TMP1075 TCS Board 0", TMP1075_HANDLER_TCS_BRD_0_ID),
"1": ("TMP1075 TCS Board 1", TMP1075_HANDLER_TCS_BRD_1_ID),
"2": ("TMP1075 PL PCDU 0", TMP1075_HANDLER_PLPCDU_0_ID),
"3": ("TMP1075 PL PCDU 1", oids.TMP1075_HANDLER_PLPCDU_1_ID),
"4": ("TMP1075 IF Board", TMP1075_HANDLER_IF_BRD_ID),
}
input_helper = InputHelper(menu_dict)
tmp_select = input_helper.get_key()
assert len(cmd_path_list) >= 2
object_id = obj_id_man.get(menu_dict[tmp_select][1])
assert object_id is not None
return pack_tmp1075_test_into(
object_id=object_id, q=queue_helper, cmd_str=cmd_path_list[1]
)
if cmd_path_list[0] == "heaters":
object_id = HEATER_CONTROLLER_ID
return pack_heater_cmds(
object_id=object_id, q=queue_helper, cmd_str=cmd_path_list[1]
)
def handle_acs_procedure(queue_helper: DefaultPusQueueHelper, cmd_path_list: List[str]):
obj_id_man = get_object_ids()
if len(cmd_path_list) == 1:
return build_acs_subsystem_cmd(queue_helper, cmd_path_list[0])
assert len(cmd_path_list) >= 2
if cmd_path_list[0] == "mgt":
object_id = cast(ObjectIdU32, obj_id_man.get(IMTQ_HANDLER_ID))
return create_imtq_command(
object_id=object_id, q=queue_helper, cmd_str=cmd_path_list[1]
)
if cmd_path_list[0] == "str":
object_id = cast(ObjectIdU32, obj_id_man.get(STAR_TRACKER_ID))
return pack_star_tracker_commands(
object_id=object_id, q=queue_helper, cmd_str=cmd_path_list[1]
)
if cmd_path_list[0] == "rws":
assert len(cmd_path_list) >= 2
if cmd_path_list[1] == "rw_assy":
assert len(cmd_path_list) >= 3
return pack_rw_ass_cmds(
q=queue_helper, object_id=RW_ASSEMBLY, cmd_str=cmd_path_list[2]
)
if cmd_path_list[1] == "rw_1":
assert len(cmd_path_list) >= 3
return create_single_rw_cmd(
object_id=RW1_ID, rw_idx=1, q=queue_helper, cmd_str=cmd_path_list[2]
)
if cmd_path_list[1] == "rw_2":
assert len(cmd_path_list) >= 3
return create_single_rw_cmd(
object_id=RW2_ID, rw_idx=2, q=queue_helper, cmd_str=cmd_path_list[2]
)
if cmd_path_list[1] == "rw_3":
assert len(cmd_path_list) >= 3
return create_single_rw_cmd(
object_id=RW3_ID, rw_idx=3, q=queue_helper, cmd_str=cmd_path_list[2]
)
if cmd_path_list[1] == "rw_4":
assert len(cmd_path_list) >= 3
return create_single_rw_cmd(
object_id=RW4_ID, rw_idx=4, q=queue_helper, cmd_str=cmd_path_list[2]
)
if cmd_path_list[0] == "gnss_ctrl":
return pack_gps_command(
object_id=oids.GPS_CONTROLLER, q=queue_helper, cmd_str=cmd_path_list[1]
)
if cmd_path_list[0] == "acs_brd_assy":
if len(cmd_path_list) == 2:
return pack_acs_board_command(q=queue_helper, cmd_str=cmd_path_list[1])
else:
if cmd_path_list[1] == "mgm_devs":
return handle_mgm_cmd(q=queue_helper, cmd_str=cmd_path_list[2])
if cmd_path_list[1] == "gyro_devs":
assert len(cmd_path_list) >= 3
return handle_gyr_cmd(q=queue_helper, cmd_str=cmd_path_list[2])
if cmd_path_list[0] == "str_img_helper":
object_id = cast(ObjectIdU32, obj_id_man.get(STR_IMG_HELPER_ID))
return pack_str_img_helper_command(
object_id=object_id, q=queue_helper, op_code=cmd_path_list[1]
)
if cmd_path_list[0] == "acs_ctrl":
return pack_acs_ctrl_command(queue_helper, cmd_path_list[1])
def handle_payload_procedure(
queue_helper: DefaultPusQueueHelper, cmd_path_list: List[str]
):
obj_id_man = get_object_ids()
if cmd_path_list[0] == "subsystem":
return create_payload_subsystem_cmd(queue_helper, cmd_path_list[1])
if cmd_path_list[0] == "ploc_mpsoc":
return pack_ploc_mpsoc_commands(queue_helper, cmd_path_list[1])
if cmd_path_list[0] == "ploc_supv":
return pack_ploc_supv_commands(queue_helper, cmd_path_list[1])
if cmd_path_list[0] == "rad_sensor":
assert len(cmd_path_list) >= 3
object_id = cast(ObjectIdU32, obj_id_man.get(RAD_SENSOR_ID))
return create_rad_sensor_cmd(
object_id=object_id, q=queue_helper, cmd_str=cmd_path_list[1]
)
if cmd_path_list[0] == "pl_pcdu":
return pack_pl_pcdu_commands(q=queue_helper, cmd_str=cmd_path_list[1])
if cmd_path_list[0] == "scex":
return pack_scex_cmds(
cmd_str=cmd_path_list[1],
q=queue_helper,
)
def handle_obdh_procedure(
queue_helper: DefaultPusQueueHelper, cmd_path_list: List[str]
):
assert len(cmd_path_list) >= 2
if cmd_path_list[0] == "core":
return pack_core_commands(q=queue_helper, cmd_str=cmd_path_list[1])
if cmd_path_list[0] == "xiphos_wdt":
return pack_wdt_commands(queue_helper, cmd_path_list[1])
if cmd_path_list[0] == "time":
return pack_time_management_cmd(queue_helper, cmd_path_list[1])
if cmd_path_list[0] == "tm_store":
return pack_tm_store_commands(queue_helper, cmd_path_list[1])
def handle_com_procedure(queue_helper: DefaultPusQueueHelper, cmd_path_list: List[str]):
obj_id_man = get_object_ids()
if len(cmd_path_list) == 1:
return build_com_subsystem_procedure(queue_helper, cmd_path_list[0])
assert len(cmd_path_list) >= 2
if cmd_path_list[0] == "ccsds":
object_id = cast(ObjectIdU32, obj_id_man.get(CCSDS_HANDLER_ID))
return pack_ccsds_handler_command(
object_id=object_id, q=queue_helper, cmd_str=cmd_path_list[2]
)
if cmd_path_list[0] == "pdec":
return pack_pdec_handler_commands(
object_id=PDEC_HANDLER_ID, q=queue_helper, cmd_str=cmd_path_list[2]
)
if cmd_path_list[0] == "syrlinks":
object_id = cast(ObjectIdU32, obj_id_man.get(SYRLINKS_HANDLER_ID))
return pack_syrlinks_command(
object_id=object_id, q=queue_helper, cmd_str=cmd_path_list[2]
)

View File

@ -1,220 +0,0 @@
"""Hook function which packs telecommands based on service and operation code string
"""
import logging
from typing import cast
from eive_tmtc.tmtc.acs.gyros import handle_gyr_cmd
from eive_tmtc.tmtc.acs.mgms import handle_mgm_cmd
from eive_tmtc.tmtc.power.power import pack_power_commands
from eive_tmtc.tmtc.tcs.ctrl import pack_tcs_ctrl_commands
from eive_tmtc.tmtc.tcs.rtd import pack_rtd_commands
from eive_tmtc.tmtc.payload.scex import pack_scex_cmds
from eive_tmtc.tmtc.tcs.subsystem import pack_tcs_sys_commands
from tmtccmd import DefaultProcedureInfo, TcHandlerBase
from tmtccmd.config import CoreServiceList
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.tmtc.decorator import (
route_to_registered_service_handlers,
ServiceProviderParams,
)
from eive_tmtc.tmtc.misc.s200_test import pack_service_200_test_into
from eive_tmtc.tmtc.power.p60dock import pack_p60dock_cmds
from eive_tmtc.tmtc.power.pdu2 import pack_pdu2_commands
from eive_tmtc.tmtc.power.pdu1 import pack_pdu1_commands
from eive_tmtc.tmtc.power.acu import pack_acu_commands
from eive_tmtc.tmtc.acs.imtq import pack_imtq_test_into
from eive_tmtc.tmtc.tcs.heater import pack_heater_cmds
from eive_tmtc.tmtc.acs.reaction_wheels import (
pack_single_rw_test_into,
pack_rw_ass_cmds,
)
from eive_tmtc.tmtc.payload.ploc_memory_dumper import pack_ploc_memory_dumper_cmd
from eive_tmtc.tmtc.com.ccsds_handler import pack_ccsds_handler_command
from eive_tmtc.tmtc.core import pack_core_commands
from eive_tmtc.tmtc.acs.star_tracker import pack_star_tracker_commands
from eive_tmtc.tmtc.com.syrlinks_handler import pack_syrlinks_command
from eive_tmtc.tmtc.com.pdec_handler import pack_pdec_handler_test
from eive_tmtc.tmtc.wdt import pack_wdt_commands
from eive_tmtc.tmtc.acs.acs_board import pack_acs_command
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.config.object_ids import (
P60_DOCK_HANDLER,
PDU_1_HANDLER_ID,
PDU_2_HANDLER_ID,
ACU_HANDLER_ID,
TMP1075_HANDLER_TCS_BRD_0_ID,
TMP1075_HANDLER_TCS_BRD_1_ID,
TMP1075_HANDLER_PLPCDU_0_ID,
TMP1075_HANDLER_IF_BRD_ID,
HEATER_CONTROLLER_ID,
IMTQ_HANDLER_ID,
RW1_ID,
RW2_ID,
RW3_ID,
RW4_ID,
RAD_SENSOR_ID,
STAR_TRACKER_ID,
PLOC_MEMORY_DUMPER_ID,
CCSDS_HANDLER_ID,
PDEC_HANDLER_ID,
STR_IMG_HELPER_ID,
SYRLINKS_HANDLER_ID,
RW_ASSEMBLY,
get_object_ids,
)
from eive_tmtc.tmtc.tcs.tmp1075 import pack_tmp1075_test_into
from eive_tmtc.tmtc.acs.gps import pack_gps_command
from eive_tmtc.tmtc.payload.rad_sensor import pack_rad_sensor_test_into
from eive_tmtc.tmtc.payload.plpcdu import pack_pl_pcdu_commands
from eive_tmtc.tmtc.acs.str_img_helper import pack_str_img_helper_command
from eive_tmtc.pus_tc.system.proc import pack_proc_commands
import eive_tmtc.config.object_ids as oids
from tmtccmd.util import ObjectIdU32
from eive_tmtc.utility.input_helper import InputHelper
def handle_default_procedure( # noqa C901: Complexity okay here.
tc_base: TcHandlerBase,
info: DefaultProcedureInfo,
queue_helper: DefaultPusQueueHelper,
):
service = info.service
op_code = info.op_code
obj_id_man = get_object_ids()
if service == CoreServiceList.SERVICE_200.value:
return pack_service_200_test_into(q=queue_helper)
if service == CustomServiceList.P60DOCK.value:
object_id = cast(ObjectIdU32, obj_id_man.get(P60_DOCK_HANDLER))
return pack_p60dock_cmds(object_id=object_id, q=queue_helper, op_code=op_code)
if service == CustomServiceList.RTD.value:
return pack_rtd_commands(object_id=None, q=queue_helper, op_code=op_code)
if service == CustomServiceList.PDU1.value:
object_id = cast(ObjectIdU32, obj_id_man.get(PDU_1_HANDLER_ID))
return pack_pdu1_commands(object_id=object_id, q=queue_helper, op_code=op_code)
if service == CustomServiceList.PDU2.value:
object_id = cast(ObjectIdU32, obj_id_man.get(PDU_2_HANDLER_ID))
return pack_pdu2_commands(object_id=object_id, q=queue_helper, op_code=op_code)
if service == CustomServiceList.ACU.value:
object_id = cast(ObjectIdU32, obj_id_man.get(ACU_HANDLER_ID))
return pack_acu_commands(object_id=object_id, q=queue_helper, op_code=op_code)
if service == CustomServiceList.TCS_SS.value:
return pack_tcs_sys_commands(q=queue_helper, op_code=op_code)
if service == CustomServiceList.TCS_CTRL.value:
return pack_tcs_ctrl_commands(q=queue_helper, op_code=op_code)
if service == CustomServiceList.TMP1075.value:
menu_dict = {
"0": ("TMP1075 TCS Board 0", TMP1075_HANDLER_TCS_BRD_0_ID),
"1": ("TMP1075 TCS Board 1", TMP1075_HANDLER_TCS_BRD_1_ID),
"2": ("TMP1075 PL PCDU 0", TMP1075_HANDLER_PLPCDU_0_ID),
"3": ("TMP1075 PL PCDU 1", oids.TMP1075_HANDLER_PLPCDU_1_ID),
"4": ("TMP1075 IF Board", TMP1075_HANDLER_IF_BRD_ID),
}
input_helper = InputHelper(menu_dict)
tmp_select = input_helper.get_key()
object_id = obj_id_man.get(menu_dict[tmp_select][1])
return pack_tmp1075_test_into(
object_id=object_id, q=queue_helper, op_code=op_code
)
if service == CustomServiceList.HEATER.value:
object_id = HEATER_CONTROLLER_ID
return pack_heater_cmds(object_id=object_id, q=queue_helper, op_code=op_code)
if service == CustomServiceList.IMTQ.value:
object_id = cast(ObjectIdU32, obj_id_man.get(IMTQ_HANDLER_ID))
return pack_imtq_test_into(object_id=object_id, q=queue_helper, op_code=op_code)
if service == CustomServiceList.REACTION_WHEEL_1.value:
return pack_single_rw_test_into(
object_id=RW1_ID, rw_idx=1, q=queue_helper, op_code=op_code
)
if service == CustomServiceList.REACTION_WHEEL_2.value:
return pack_single_rw_test_into(
object_id=RW2_ID, rw_idx=2, q=queue_helper, op_code=op_code
)
if service == CustomServiceList.REACTION_WHEEL_3.value:
return pack_single_rw_test_into(
object_id=RW3_ID, rw_idx=3, q=queue_helper, op_code=op_code
)
if service == CustomServiceList.REACTION_WHEEL_4.value:
return pack_single_rw_test_into(
object_id=RW4_ID, rw_idx=4, q=queue_helper, op_code=op_code
)
if service == CustomServiceList.MGMS.value:
return handle_mgm_cmd(q=queue_helper, op_code=op_code)
if service == CustomServiceList.RAD_SENSOR.value:
object_id = cast(ObjectIdU32, obj_id_man.get(RAD_SENSOR_ID))
return pack_rad_sensor_test_into(
object_id=object_id, q=queue_helper, op_code=op_code
)
if service == CustomServiceList.STAR_TRACKER.value:
object_id = cast(ObjectIdU32, obj_id_man.get(STAR_TRACKER_ID))
return pack_star_tracker_commands(
object_id=object_id, q=queue_helper, op_code=op_code
)
if service == CustomServiceList.STR_IMG_HELPER.value:
object_id = cast(ObjectIdU32, obj_id_man.get(STR_IMG_HELPER_ID))
return pack_str_img_helper_command(
object_id=object_id, q=queue_helper, op_code=op_code
)
if service == CustomServiceList.CORE.value:
return pack_core_commands(q=queue_helper, op_code=op_code)
if service == CustomServiceList.PLOC_MEMORY_DUMPER.value:
object_id = cast(ObjectIdU32, obj_id_man.get(PLOC_MEMORY_DUMPER_ID))
return pack_ploc_memory_dumper_cmd(
object_id=object_id, q=queue_helper, op_code=op_code
)
if service == CustomServiceList.POWER.value:
return pack_power_commands(queue_helper, op_code)
if service == CustomServiceList.ACS.value:
return pack_acs_command(q=queue_helper, op_code=op_code)
if service == CustomServiceList.GPS_CTRL.value:
return pack_gps_command(
object_id=oids.GPS_CONTROLLER, q=queue_helper, op_code=op_code
)
if service == CustomServiceList.CCSDS_HANDLER.value:
object_id = cast(ObjectIdU32, obj_id_man.get(CCSDS_HANDLER_ID))
return pack_ccsds_handler_command(
object_id=object_id, q=queue_helper, op_code=op_code
)
if service == CustomServiceList.PDEC_HANDLER.value:
return pack_pdec_handler_test(
object_id=PDEC_HANDLER_ID, q=queue_helper, op_code=op_code
)
if service == CustomServiceList.SYRLINKS.value:
object_id = cast(ObjectIdU32, obj_id_man.get(SYRLINKS_HANDLER_ID))
return pack_syrlinks_command(
object_id=object_id, q=queue_helper, op_code=op_code
)
if service == CustomServiceList.GYRO.value:
return handle_gyr_cmd(q=queue_helper, op_code=op_code)
if service == CustomServiceList.PROCEDURE.value:
return pack_proc_commands(q=queue_helper, op_code=op_code)
if service == CustomServiceList.PL_PCDU.value:
return pack_pl_pcdu_commands(q=queue_helper, op_code=op_code)
if service == CustomServiceList.TCS_ASS.value:
return pack_tcs_sys_commands(q=queue_helper, op_code=op_code)
if service == CustomServiceList.RW_ASSEMBLY.value:
return pack_rw_ass_cmds(q=queue_helper, object_id=RW_ASSEMBLY, op_code=op_code)
if service == CustomServiceList.SCEX.value:
return pack_scex_cmds(
ServiceProviderParams(
handler_base=tc_base,
op_code=op_code,
info=info,
queue_helper=queue_helper,
)
)
if service == CustomServiceList.XIPHOS_WDT.value:
return pack_wdt_commands(queue_helper, op_code)
if not route_to_registered_service_handlers(
service,
ServiceProviderParams(
handler_base=tc_base,
op_code=op_code,
info=info,
queue_helper=queue_helper,
),
):
logging.getLogger(__name__).warning(f"Invalid Service {service}")

View File

@ -34,9 +34,9 @@ from eive_tmtc.pus_tc.system.controllers import (
pack_cmd_ctrl_to_off,
pack_cmd_ctrl_to_nml,
)
from eive_tmtc.tmtc.acs.acs_board import pack_acs_command
from eive_tmtc.tmtc.acs.acs_board import pack_acs_board_command
from eive_tmtc.tmtc.acs.sus_board import pack_sus_cmds
from eive_tmtc.tmtc.acs.imtq import pack_imtq_test_into, pack_dipole_command
from eive_tmtc.tmtc.acs.imtq import create_imtq_command, pack_dipole_command
from eive_tmtc.tmtc.acs.star_tracker import pack_star_tracker_commands
from eive_tmtc.tmtc.acs.reaction_wheels import pack_rw_ass_cmds, pack_set_speed_command
@ -312,7 +312,7 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
# Enable scheduling
q.add_pus_tc(create_enable_tc_sched_cmd())
# check whether tcs_assembly also has to be commanded to NORMAL Mode
pack_tcs_sys_commands(q=q, op_code=TcsOpCodes.TCS_BOARD_ASS_NORMAL[0])
pack_tcs_sys_commands(q=q, cmd_str=TcsOpCodes.TCS_BOARD_ASS_NORMAL[0])
pack_cmd_ctrl_to_nml(q=q, object_id=obj_id_dict.get(oids.THERMAL_CONTROLLER_ID))
if op_code in OpCode.TV_TEARDOWN_TCS_FT_OFF:
@ -337,7 +337,7 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
]
d_side_pairs = a_side_pairs + b_side_pairs
diag_list = [False, False, True, False, False]
pack_acs_command(q=q, op_code="acs-a")
pack_acs_board_command(q=q, cmd_str="acs-a")
for a_side_dev in a_side_pairs:
oid = a_side_dev[0]
@ -351,9 +351,9 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
cfg=GenericHkListeningCfg.default(),
)
pack_acs_command(q=q, op_code="acs-off")
pack_acs_board_command(q=q, cmd_str="acs-off")
q.add_wait_seconds(5.0)
pack_acs_command(q=q, op_code="acs-b")
pack_acs_board_command(q=q, cmd_str="acs-b")
sid_list.clear()
diag_list = [False, False, True, False, False]
@ -370,9 +370,9 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
cfg=GenericHkListeningCfg.default(),
)
pack_acs_command(q=q, op_code="acs-off")
pack_acs_board_command(q=q, cmd_str="acs-off")
q.add_wait_seconds(5.0)
pack_acs_command(q=q, op_code="acs-d")
pack_acs_board_command(q=q, cmd_str="acs-d")
sid_list.clear()
@ -400,7 +400,7 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
cfg=GenericHkListeningCfg.default(),
)
pack_acs_command(q=q, op_code="acs-off")
pack_acs_board_command(q=q, cmd_str="acs-off")
if op_code in OpCode.MGT_FT:
key = KAI.MGT_FT[0]
@ -416,10 +416,10 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
]
# Command MGT to mode on
pack_imtq_test_into(oids.IMTQ_HANDLER_ID, q=q, op_code="1")
create_imtq_command(oids.IMTQ_HANDLER_ID, q=q, cmd_str="1")
q.add_wait_seconds(5.0)
# Command MGT to normal mode
pack_imtq_test_into(oids.IMTQ_HANDLER_ID, q=q, op_code="2")
create_imtq_command(oids.IMTQ_HANDLER_ID, q=q, cmd_str="2")
for imtq_dev in imtq_pairs:
oid = imtq_dev[0]
@ -433,7 +433,7 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
cfg=GenericHkListeningCfg.default(),
)
pack_imtq_test_into(oids.IMTQ_HANDLER_ID, q=q, op_code="0")
create_imtq_command(oids.IMTQ_HANDLER_ID, q=q, cmd_str="0")
if op_code in OpCode.MGT_FT_DP:
key = KAI.MGT_FT_DP[0]
@ -472,12 +472,12 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
True,
True,
]
pack_acs_command(q=q, op_code="acs-d")
pack_acs_board_command(q=q, cmd_str="acs-d")
# Command MGT to mode on
pack_imtq_test_into(oids.IMTQ_HANDLER_ID, q=q, op_code="1")
create_imtq_command(oids.IMTQ_HANDLER_ID, q=q, cmd_str="1")
q.add_wait_seconds(20.0)
# Command MGT to normal mode
pack_imtq_test_into(oids.IMTQ_HANDLER_ID, q=q, op_code="2")
create_imtq_command(oids.IMTQ_HANDLER_ID, q=q, cmd_str="2")
for d_side_and_imtq_dev in d_side_and_imtq_pairs:
oid = d_side_and_imtq_dev[0]
@ -494,8 +494,8 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
cfg=cfg,
)
pack_imtq_test_into(oids.IMTQ_HANDLER_ID, q=q, op_code="0")
pack_acs_command(q=q, op_code="acs-off")
create_imtq_command(oids.IMTQ_HANDLER_ID, q=q, cmd_str="0")
pack_acs_board_command(q=q, cmd_str="acs-off")
if op_code in OpCode.SUS_FT:
key = KAI.SUS_FT[0]
@ -538,7 +538,7 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
cfg=GenericHkListeningCfg.default(),
)
pack_acs_command(q=q, op_code="sus-off")
pack_acs_board_command(q=q, cmd_str="sus-off")
q.add_wait_seconds(5.0)
pack_sus_cmds(q=q, op_code="sus-red")
@ -562,7 +562,7 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
cfg=GenericHkListeningCfg.default(),
)
pack_acs_command(q=q, op_code="sus-off")
pack_acs_board_command(q=q, cmd_str="sus-off")
q.add_wait_seconds(5.0)
pack_sus_cmds(q=q, op_code="sus-d")
@ -593,7 +593,7 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
cfg=GenericHkListeningCfg.default(),
)
pack_acs_command(q=q, op_code="sus-off")
pack_acs_board_command(q=q, cmd_str="sus-off")
if op_code in OpCode.SYRLINKS_FT:
key = KAI.SYRLINKS_FT[0]
@ -612,7 +612,7 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
if op_code in OpCode.STR_FT:
key = KAI.STR_FT[0]
pack_star_tracker_commands(object_id=oids.STAR_TRACKER_ID, q=q, op_code="2")
pack_star_tracker_commands(object_id=oids.STAR_TRACKER_ID, q=q, cmd_str="2")
# STR
sid_list.append(make_sid(oids.STAR_TRACKER_ID, StrSetIds.TEMPERATURE))
@ -625,7 +625,7 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
cfg=GenericHkListeningCfg.default(),
)
pack_star_tracker_commands(object_id=oids.STAR_TRACKER_ID, q=q, op_code="3")
pack_star_tracker_commands(object_id=oids.STAR_TRACKER_ID, q=q, cmd_str="3")
if op_code in OpCode.RW_FT_ONE_RW:
key = KAI.RW_FT_ONE_RW[0]
@ -658,7 +658,7 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
False,
]
# RW NORMAL
pack_rw_ass_cmds(object_id=oids.RW_ASSEMBLY, q=q, op_code="nml")
pack_rw_ass_cmds(object_id=oids.RW_ASSEMBLY, q=q, cmd_str="nml")
# RW HK für alle RWs nur einzeln
for rw_dev in rw_pairs:
@ -673,7 +673,7 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
cfg=GenericHkListeningCfg(mgt=False, one_rw=True, two_rws=False),
)
# RW OFF
pack_rw_ass_cmds(object_id=oids.RW_ASSEMBLY, q=q, op_code="off")
pack_rw_ass_cmds(object_id=oids.RW_ASSEMBLY, q=q, cmd_str="off")
# ass command with 2 rws to speed
if op_code in OpCode.RW_FT_TWO_RWS:
@ -715,7 +715,7 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
False,
]
# RW NORMAL
pack_rw_ass_cmds(object_id=oids.RW_ASSEMBLY, q=q, op_code="nml")
pack_rw_ass_cmds(object_id=oids.RW_ASSEMBLY, q=q, cmd_str="nml")
# RW
for rw_dev in rw_pairs:
@ -730,7 +730,7 @@ def pack_proc_commands( # noqa C901: Complexity is okay here.
cfg=GenericHkListeningCfg(mgt=False, one_rw=False, two_rws=True),
)
# RW OFF
pack_rw_ass_cmds(object_id=oids.RW_ASSEMBLY, q=q, op_code="off")
pack_rw_ass_cmds(object_id=oids.RW_ASSEMBLY, q=q, cmd_str="off")
def enable_listen_to_hk_for_x_seconds(

View File

@ -6,10 +6,10 @@ from eive_tmtc.config.definitions import (
PUS_APID,
CFDP_LOCAL_ENTITY_ID,
)
from eive_tmtc.pus_tc.procedure_packer import handle_default_procedure
from eive_tmtc.pus_tc.cmd_demux import handle_pus_procedure
from eive_tmtc.cfdp.handler import CfdpInCcsdsHandler
from tmtccmd import TcHandlerBase, ProcedureWrapper
from tmtccmd.cfdp.defs import CfdpRequestType
from tmtccmd.cfdp.handler import CfdpInCcsdsHandler
from cfdppy.defs import CfdpRequestType
from tmtccmd.logging import get_current_time_string
from tmtccmd.logging.pus import RawTmtcTimedLogWrapper
from tmtccmd.tmtc import (
@ -22,7 +22,7 @@ from tmtccmd.tmtc import (
)
from tmtccmd.config.cfdp import generic_cfdp_params_to_put_request
from spacepackets.ecss import PusVerificator
from tmtccmd.util import FileSeqCountProvider
from spacepackets.seqcount import FileSeqCountProvider
from spacepackets.cfdp import PduHolder, DirectiveType
@ -68,8 +68,8 @@ class TcHandler(TcHandlerBase):
def feed_cb(self, info: ProcedureWrapper, wrapper: FeedWrapper):
self.queue_helper.queue_wrapper = wrapper.queue_wrapper
if info.proc_type == TcProcedureType.DEFAULT:
handle_default_procedure(self, info.to_def_procedure(), self.queue_helper)
if info.proc_type == TcProcedureType.TREE_COMMANDING:
handle_pus_procedure(info.to_tree_commanding_procedure(), self.queue_helper)
elif info.proc_type == TcProcedureType.CFDP:
self.handle_cfdp_procedure(info)
@ -124,40 +124,38 @@ class TcHandler(TcHandlerBase):
_LOGGER.info(
f"CFDP: Starting file put request with parameters:\n{put_req}"
)
assert put_req is not None
self.cfdp_in_ccsds_handler.cfdp_handler.put_request(put_req)
self.cfdp_handler_started = True
for source_pair, dest_pair in self.cfdp_in_ccsds_handler:
pdu, sp = source_pair
pdu = cast(PduHolder, pdu)
if pdu.is_file_directive:
if pdu.pdu_directive_type == DirectiveType.METADATA_PDU:
metadata = pdu.to_metadata_pdu()
for source_pair, _ in self.cfdp_in_ccsds_handler:
if source_pair is not None:
pdu, sp = source_pair
pdu = cast(PduHolder, pdu)
if pdu.is_file_directive:
if pdu.pdu_directive_type == DirectiveType.METADATA_PDU:
metadata = pdu.to_metadata_pdu()
self.queue_helper.add_log_cmd(
"CFDP Source: Sending Metadata PDU for file with size "
f"{metadata.file_size}"
)
elif pdu.pdu_directive_type == DirectiveType.EOF_PDU:
self.queue_helper.add_log_cmd(
"CFDP Source: Sending EOF PDU"
)
else:
fd_pdu = pdu.to_file_data_pdu()
self.queue_helper.add_log_cmd(
"CFDP Source: Sending Metadata PDU for file with size "
f"{metadata.file_size}"
"CFDP Source: Sending File Data PDU for segment at offset "
f"{fd_pdu.offset} with length {len(fd_pdu.file_data)}"
)
elif pdu.pdu_directive_type == DirectiveType.EOF_PDU:
self.queue_helper.add_log_cmd(
"CFDP Source: Sending EOF PDU"
)
else:
fd_pdu = pdu.to_file_data_pdu()
self.queue_helper.add_log_cmd(
"CFDP Source: Sending File Data PDU for segment at offset "
f"{fd_pdu.offset} with length {len(fd_pdu.file_data)}"
)
self.queue_helper.add_ccsds_tc(sp)
self.cfdp_in_ccsds_handler.confirm_source_packet_sent()
self.queue_helper.add_ccsds_tc(sp)
self.cfdp_in_ccsds_handler.source_handler.state_machine()
def queue_finished_cb(self, info: ProcedureWrapper):
if info is not None:
if info.proc_type == TcQueueEntryType.PUS_TC:
def_proc = info.to_def_procedure()
_LOGGER.info(
f"Finished queue for service {def_proc.service} and op code"
f" {def_proc.op_code}"
)
def_proc = info.to_tree_commanding_procedure()
_LOGGER.info(f"Finished queue for command {def_proc.cmd_path}")
elif info.proc_type == TcProcedureType.CFDP:
_LOGGER.info("Finished CFDP queue")

View File

@ -1,5 +1,10 @@
import base64
import logging
import struct
from spacepackets.ecss import PusTm
from tmtccmd.pus.s8_fsfw_action_defs import CustomSubservice
from eive_tmtc.config.definitions import PRINT_RAW_ACTION_DATA_REPLY_B64_STR
from eive_tmtc.config.object_ids import (
ACU_HANDLER_ID,
PDU_1_HANDLER_ID,
@ -10,6 +15,7 @@ from eive_tmtc.config.object_ids import (
CORE_CONTROLLER_ID,
STAR_TRACKER_ID,
P60_DOCK_HANDLER,
ACS_CONTROLLER,
)
from eive_tmtc.tmtc.acs.imtq import ImtqActionId
from eive_tmtc.pus_tm.defs import PrintWrapper
@ -17,55 +23,78 @@ from eive_tmtc.tmtc.core import handle_core_ctrl_action_replies
from eive_tmtc.tmtc.payload.ploc_mpsoc import handle_mpsoc_data_reply
from eive_tmtc.tmtc.payload.ploc_supervisor import SupvActionId
from eive_tmtc.tmtc.acs.star_tracker import handle_star_tracker_action_replies
from eive_tmtc.tmtc.acs.acs_ctrl import handle_acs_ctrl_action_replies
from eive_tmtc.tmtc.power.tm import handle_get_param_data_reply
from tmtccmd.pus.s8_fsfw_action import Service8FsfwTm
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from spacepackets.ccsds.time import CdsShortTimestamp
from tmtccmd.util import ObjectIdDictT
from tmtccmd.util import ObjectIdBase, ObjectIdDictT, ObjectIdU32
_LOGGER = logging.getLogger(__name__)
def handle_action_reply(
raw_tm: bytes, printer: FsfwTmTcPrinter, obj_id_dict: ObjectIdDictT
_LOGGER = logging.getLogger(__name__)
def handle_action_service_tm(
raw_tm: bytes, pw: PrintWrapper, obj_id_dict: ObjectIdDictT
):
"""Core Action reply handler
:return:
"""
tm_packet = Service8FsfwTm.unpack(
raw_telemetry=raw_tm, time_reader=CdsShortTimestamp.empty()
)
object_id = obj_id_dict.get(tm_packet.source_object_id_as_bytes)
pw = PrintWrapper(printer.file_logger)
custom_data = tm_packet.custom_data
action_id = tm_packet.action_id
generic_print_str = printer.generic_action_packet_tm_print(
packet=tm_packet, obj_id=object_id
)
pw.dlog(generic_print_str)
if object_id.as_bytes == IMTQ_HANDLER_ID:
return handle_imtq_replies(action_id, pw, custom_data)
elif object_id.as_bytes == PLOC_MPSOC_ID:
return handle_mpsoc_data_reply(action_id, pw, custom_data)
elif object_id.as_bytes == PLOC_SUPV_ID:
return handle_supervisor_replies(action_id, pw, custom_data)
elif object_id.as_bytes == CORE_CONTROLLER_ID:
return handle_core_ctrl_action_replies(action_id, pw, custom_data)
elif object_id.as_bytes == STAR_TRACKER_ID:
return handle_star_tracker_action_replies(action_id, pw, custom_data)
elif object_id.as_bytes in [
ACU_HANDLER_ID,
PDU_1_HANDLER_ID,
PDU_2_HANDLER_ID,
P60_DOCK_HANDLER,
]:
return handle_get_param_data_reply(object_id, action_id, pw, custom_data)
tm_packet = PusTm.unpack(raw_tm, timestamp_len=CdsShortTimestamp.TIMESTAMP_SIZE)
if len(tm_packet.source_data) < 8:
_LOGGER.warning(
"received action service reply with source data smaller than 8 bytes"
)
return
object_id_raw = struct.unpack("!I", tm_packet.source_data[0:4])[0]
action_id = struct.unpack("!I", tm_packet.source_data[4:8])[0]
object_id = obj_id_dict.get(object_id_raw)
custom_data = tm_packet.source_data[8:]
if object_id is None:
object_id = ObjectIdU32(object_id_raw, "Unknown ID")
if tm_packet.subservice == CustomSubservice.TM_DATA_REPLY:
if PRINT_RAW_ACTION_DATA_REPLY_B64_STR:
print(f"PUS TM Base64: {base64.b64encode(raw_tm)}")
if object_id.as_bytes == IMTQ_HANDLER_ID:
return handle_imtq_replies(action_id, pw, custom_data)
elif object_id.as_bytes == PLOC_MPSOC_ID:
return handle_mpsoc_data_reply(action_id, pw, custom_data)
elif object_id.as_bytes == PLOC_SUPV_ID:
return handle_supervisor_replies(action_id, pw, custom_data)
elif object_id.as_bytes == CORE_CONTROLLER_ID:
return handle_core_ctrl_action_replies(action_id, pw, custom_data)
elif object_id.as_bytes == STAR_TRACKER_ID:
return handle_star_tracker_action_replies(action_id, pw, custom_data)
elif object_id.as_bytes == ACS_CONTROLLER:
return handle_acs_ctrl_action_replies(action_id, pw, custom_data)
elif object_id.as_bytes in [
ACU_HANDLER_ID,
PDU_1_HANDLER_ID,
PDU_2_HANDLER_ID,
P60_DOCK_HANDLER,
]:
return handle_get_param_data_reply(object_id, action_id, pw, custom_data)
else:
# TODO: Could add a handler here depending on action ID and object ID.
handle_action_data_reply(tm_packet, object_id, action_id, pw)
else:
pw.dlog(f"No dedicated action reply handler found for reply from {object_id}")
pw.dlog(f"Raw Data: {tm_packet.custom_data.hex(sep=',')}")
pw.dlog(
f"service 8 packet from {object_id} with action ID {action_id} "
f"and unknown subservice {tm_packet.subservice}"
)
def handle_imtq_replies(action_id: int, pw: PrintWrapper, custom_data: bytearray):
def handle_action_data_reply(
tm_packet: PusTm, named_obj_id: ObjectIdBase, action_id: int, printer: PrintWrapper
):
print_string = (
f"service 8 data reply from {named_obj_id} with action ID {action_id} "
f"and data size {len(tm_packet.tm_data[8:])}"
)
printer.dlog(print_string)
def handle_imtq_replies(action_id: int, pw: PrintWrapper, custom_data: bytes):
if action_id == struct.unpack("!I", ImtqActionId.get_commanded_dipole)[0]:
header_list = [
"Commanded X-Dipole",
@ -78,7 +107,7 @@ def handle_imtq_replies(action_id: int, pw: PrintWrapper, custom_data: bytearray
pw.dlog(f"{content_list}")
def handle_supervisor_replies(action_id: int, pw: PrintWrapper, custom_data: bytearray):
def handle_supervisor_replies(action_id: int, pw: PrintWrapper, custom_data: bytes):
if action_id == SupvActionId.DUMP_MRAM:
header_list = ["MRAM Dump"]
content_list = [custom_data[: len(custom_data)]]

View File

@ -1,7 +1,9 @@
import logging
import datetime
import sys
import base64
from eive_tmtc.config.definitions import PRINT_RAW_EVENTS_B64_STR
from eive_tmtc.config.events import get_event_dict
from eive_tmtc.config.object_ids import get_object_ids
from eive_tmtc.pus_tm.defs import PrintWrapper
@ -21,7 +23,9 @@ _LOGGER = logging.getLogger(__name__)
def handle_event_packet( # noqa C901: Complexity okay here
raw_tm: bytes, pw: PrintWrapper
): # noqa C901: Complexity okay here
tm = Service5Tm.unpack(data=raw_tm, time_reader=CdsShortTimestamp.empty())
if PRINT_RAW_EVENTS_B64_STR:
print(f"PUS Event TM Base64: {base64.b64encode(raw_tm)}")
tm = Service5Tm.unpack(data=raw_tm, timestamp_len=CdsShortTimestamp.TIMESTAMP_SIZE)
event_dict = get_event_dict()
event_def = tm.event_definition
info = event_dict.get(event_def.event_id)
@ -36,9 +40,10 @@ def handle_event_packet( # noqa C901: Complexity okay here
obj_name = event_def.reporter_id.hex(sep=",")
else:
obj_name = obj_id_obj.name
timestamp = CdsShortTimestamp.unpack(tm.timestamp)
generic_event_string = (
f"Object {obj_name} generated Event {info.name} (ID: {event_def.event_id:#04x})"
f" at {tm.time_provider.as_date_time()}"
f" at {timestamp.as_date_time()}"
)
_LOGGER.info(generic_event_string)
pw.file_logger.info(
@ -122,12 +127,22 @@ def handle_event_packet( # noqa C901: Complexity okay here
new_time_dt = datetime.datetime.fromtimestamp(new_time, datetime.timezone.utc)
pw.dlog(f"Old time (UTC): {old_time_dt}")
pw.dlog(f"New time (UTC): {new_time_dt}")
if info.name == "CLOCK_DUMP":
if info.name == "CLOCK_DUMP_LEGACY":
specific_handler = True
# param 1 is timeval seconds, param 2 is timeval subsecond milliseconds
time = event_def.param1 + event_def.param2 / 1000.0
time_dt = datetime.datetime.fromtimestamp(time, datetime.timezone.utc)
pw.dlog(f"Current time: {time_dt}")
if (
info.name == "CLOCK_DUMP"
or info.name == "CLOCK_DUMP_BEFORE_SETTING_TIME"
or info.name == "CLOCK_DUMP_AFTER_SETTING_TIME"
):
specific_handler = True
# param 1 is timeval seconds, param 2 is timeval subsecond microseconds
time = event_def.param1 + event_def.param2 / 1000000.0
time_dt = datetime.datetime.fromtimestamp(time, datetime.timezone.utc)
pw.dlog(f"Clock dump event {info.name}. Current time: {time_dt}")
if info.name == "ACTIVE_SD_INFO":
sd_0_state = (event_def.param2 >> 16) & 0xFFFF
sd_1_state = event_def.param2 & 0xFFFF

18
eive_tmtc/pus_tm/hk.py Normal file
View File

@ -0,0 +1,18 @@
import uuid
import dataclasses
import datetime
import sqlite3
from spacepackets.ecss.tm import CdsShortTimestamp, PusTm
@dataclasses.dataclass
class HkTmInfo:
packet_uuid: uuid.UUID
hk_packet: PusTm
set_id: int
db_con: sqlite3.Connection
hk_data: bytes
@property
def packet_datetime(self) -> datetime.datetime:
return CdsShortTimestamp.unpack(self.hk_packet.timestamp).as_datetime()

View File

@ -1,7 +1,17 @@
"""HK Handling for EIVE OBSW"""
import dataclasses
import logging
from typing import List
import base64
import sqlite3
import struct
from typing import List, cast
from uuid import UUID
from spacepackets.ccsds.time import CdsShortTimestamp
from spacepackets.ecss import PusTm
from eive_tmtc.config.definitions import PRINT_RAW_HK_B64_STR
from eive_tmtc.pus_tm.hk import HkTmInfo
from eive_tmtc.tmtc.acs.acs_ctrl import handle_acs_ctrl_hk_data
from eive_tmtc.tmtc.internal_err_reporter import handle_ier_hk_data
@ -13,15 +23,11 @@ from eive_tmtc.tmtc.payload.rad_sensor import handle_rad_sensor_data
from eive_tmtc.tmtc.acs.sus import handle_sus_hk
from eive_tmtc.tmtc.payload.ploc_supervisor import handle_supv_hk_data
from eive_tmtc.tmtc.acs.reaction_wheels import handle_rw_hk_data
from eive_tmtc.tmtc.power.pwr_ctrl import handle_pwr_ctrl_hk_data
from eive_tmtc.tmtc.com.syrlinks_handler import handle_syrlinks_hk_data
from eive_tmtc.tmtc.tcs import handle_thermal_controller_hk_data
from eive_tmtc.tmtc.tcs.tmp1075 import handle_tmp_1075_hk_data
from spacepackets.ecss import PusTelemetry
from tmtccmd.pus.tm.s3_fsfw_hk import (
Service3Base,
HkContentType,
Service3FsfwTm,
)
from tmtccmd.pus.tm.s3_hk_base import HkContentType
from tmtccmd.util.obj_id import ObjectIdU32, ObjectIdDictT
from eive_tmtc.tmtc.power.bpx_batt import handle_bpx_hk_data
@ -50,45 +56,54 @@ FORWARD_SENSOR_TEMPS = False
@dataclasses.dataclass
class HkFilter:
object_ids: List[ObjectIdU32]
object_ids: List[bytes]
set_ids: List[int]
def handle_hk_packet(
raw_tm: bytes,
packet_uuid: UUID,
obj_id_dict: ObjectIdDictT,
printer: FsfwTmTcPrinter,
hk_filter: HkFilter,
hk_level: int,
db_con: sqlite3.Connection,
):
tm_packet = Service3FsfwTm.unpack(raw_telemetry=raw_tm, custom_hk_handling=False)
named_obj_id = obj_id_dict.get(tm_packet.object_id.as_bytes)
tm_packet = PusTm.unpack(raw_tm, CdsShortTimestamp.TIMESTAMP_SIZE)
obj_id_raw = struct.unpack("!I", tm_packet.tm_data[0:4])[0]
named_obj_id = cast(ObjectIdU32, obj_id_dict.get(obj_id_raw))
if named_obj_id is None:
named_obj_id = tm_packet.object_id
named_obj_id = ObjectIdU32(obj_id_raw, "Unknown ID")
if tm_packet.subservice == 25 or tm_packet.subservice == 26:
set_id = struct.unpack("!I", tm_packet.tm_data[4:8])[0]
hk_data = tm_packet.tm_data[8:]
if named_obj_id in hk_filter.object_ids:
if named_obj_id.as_bytes in hk_filter.object_ids:
if PRINT_RAW_HK_B64_STR:
print(f"PUS TM Base64: {base64.b64encode(raw_tm)}")
handle_regular_hk_print(
printer=printer,
set_id=set_id,
packet_uuid=packet_uuid,
object_id=named_obj_id,
hk_packet=tm_packet,
tm=tm_packet.pus_tm,
hk_data=hk_data,
db=db_con,
)
return
try:
if hk_level >= 1:
printer.generic_hk_tm_print(
HkContentType.HK, named_obj_id, tm_packet.set_id, hk_data
HkContentType.HK, named_obj_id, set_id, hk_data
)
if hk_level >= 1:
handle_regular_hk_print(
printer=printer,
set_id=set_id,
packet_uuid=packet_uuid,
object_id=named_obj_id,
hk_packet=tm_packet,
tm=tm_packet.pus_tm,
hk_data=hk_data,
db=db_con,
)
except ValueError as e:
_LOGGER.exception(
@ -99,26 +114,41 @@ def handle_hk_packet(
def handle_regular_hk_print( # noqa C901: Complexity okay here
printer: FsfwTmTcPrinter,
object_id: ObjectIdU32,
hk_packet: Service3Base,
tm: PusTelemetry,
hk_packet: PusTm,
set_id: int,
packet_uuid: UUID,
hk_data: bytes,
db: sqlite3.Connection,
object_id: ObjectIdU32,
printer: FsfwTmTcPrinter,
):
objb = object_id.as_bytes
set_id = hk_packet.set_id
packet_dt = tm.time_provider.as_date_time()
hk_info = HkTmInfo(
packet_uuid=packet_uuid,
hk_packet=hk_packet,
db_con=db,
hk_data=hk_data,
set_id=set_id,
)
timestamp = CdsShortTimestamp.unpack(hk_packet.timestamp)
packet_dt = timestamp.as_datetime()
pw = PrintWrapper(printer.file_logger)
"""This function is called when a Service 3 Housekeeping packet is received."""
if objb in [obj_ids.RW1_ID, obj_ids.RW2_ID, obj_ids.RW3_ID, obj_ids.RW4_ID]:
return handle_rw_hk_data(pw, object_id, set_id, hk_data)
elif objb == obj_ids.SYRLINKS_HANDLER_ID:
return handle_syrlinks_hk_data(pw=pw, hk_data=hk_data, set_id=set_id)
return handle_syrlinks_hk_data(
hk_info=hk_info,
pw=pw,
)
elif objb == obj_ids.IMTQ_HANDLER_ID:
return handle_imtq_hk(pw=pw, hk_data=hk_data, set_id=set_id)
elif objb == obj_ids.GPS_CONTROLLER:
return handle_gps_data(
pw=pw, set_id=set_id, hk_data=hk_data, packet_time=packet_dt
pw=pw,
set_id=set_id,
hk_data=hk_data,
packet_time=timestamp.as_datetime(),
)
elif objb == obj_ids.PCDU_HANDLER_ID:
return handle_pcdu_hk(pw=pw, set_id=set_id, hk_data=hk_data)
@ -127,9 +157,21 @@ def handle_regular_hk_print( # noqa C901: Complexity okay here
elif objb == obj_ids.CORE_CONTROLLER_ID:
return handle_core_hk_data(pw=pw, hk_data=hk_data, set_id=set_id)
elif objb == obj_ids.PDU_1_HANDLER_ID:
return handle_pdu_data(pw=pw, pdu_idx=1, set_id=set_id, hk_data=hk_data)
return handle_pdu_data(
hk_info=hk_info,
pw=pw,
pdu_idx=1,
set_id=set_id,
hk_data=hk_data,
)
elif objb == obj_ids.PDU_2_HANDLER_ID:
return handle_pdu_data(pw=pw, pdu_idx=2, set_id=set_id, hk_data=hk_data)
return handle_pdu_data(
hk_info=hk_info,
pw=pw,
pdu_idx=2,
set_id=set_id,
hk_data=hk_data,
)
elif objb == obj_ids.PLOC_MPSOC_ID:
return handle_ploc_mpsoc_hk_data(pw=pw, hk_data=hk_data, set_id=set_id)
elif objb == obj_ids.ACU_HANDLER_ID:
@ -201,6 +243,10 @@ def handle_regular_hk_print( # noqa C901: Complexity okay here
return handle_acs_ctrl_hk_data(
pw=pw, set_id=set_id, hk_data=hk_data, packet_time=packet_dt
)
elif objb == obj_ids.PWR_CONTROLLER:
return handle_pwr_ctrl_hk_data(
pw=pw, set_id=set_id, hk_data=hk_data, packet_time=packet_dt
)
else:
_LOGGER.info(
f"Service 3 TM: Parsing for object {object_id} and set ID {set_id} "

View File

@ -1,126 +0,0 @@
"""Core EIVE TM handler module
"""
import logging
from spacepackets.ccsds.time import CdsShortTimestamp
from spacepackets.ecss import PusTelemetry
from spacepackets.ecss.pus_17_test import Service17Tm
from spacepackets.util import PrintFormats
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.logging.pus import RawTmtcTimedLogWrapper
from tmtccmd.pus import VerificationWrapper
from tmtccmd.pus.s20_fsfw_param import Service20FsfwTm, Service20ParamDumpWrapper
from tmtccmd.pus.s20_fsfw_param_defs import CustomSubservice as ParamSubservice
from tmtccmd.pus.s200_fsfw_mode import Service200FsfwTm
from tmtccmd.pus.s200_fsfw_mode import Subservice as ModeSubservice
from eive_tmtc.config.object_ids import get_object_ids
from .action_reply_handler import handle_action_reply
from .defs import PrintWrapper
from .event_handler import handle_event_packet
from .hk_handler import HkFilter, handle_hk_packet
from .verification_handler import generic_retval_printout, handle_service_1_fsfw_packet
_LOGGER = logging.getLogger(__name__)
def pus_factory_hook( # noqa C901 : Complexity okay here
packet: bytes,
verif_wrapper: VerificationWrapper,
printer: FsfwTmTcPrinter,
raw_logger: RawTmtcTimedLogWrapper,
hk_level: int,
hk_filter: HkFilter,
):
if len(packet) < 8:
_LOGGER.warning("Detected packet shorter than 8 bytes!")
return
try:
tm_packet = PusTelemetry.unpack(packet, CdsShortTimestamp.empty())
# _LOGGER.info(f"Sequence count: {tm_packet.seq_count}")
except ValueError as value_error:
_LOGGER.warning(f"{value_error}")
_LOGGER.warning("Could not generate PUS TM object from raw data")
_LOGGER.warning(f"Raw Packet: [{packet.hex(sep=',')}], REPR: {packet!r}")
return
service = tm_packet.service
obj_id_dict = get_object_ids()
pw = PrintWrapper(printer.file_logger)
dedicated_handler = True
if service == 1:
handle_service_1_fsfw_packet(wrapper=verif_wrapper, raw_tm=packet)
elif service == 3:
handle_hk_packet(
printer=printer,
raw_tm=packet,
obj_id_dict=obj_id_dict,
hk_level=hk_level,
hk_filter=hk_filter,
)
elif service == 5:
handle_event_packet(raw_tm=packet, pw=pw)
elif service == 8:
handle_action_reply(raw_tm=packet, printer=printer, obj_id_dict=obj_id_dict)
elif service == 17:
tm_packet = Service17Tm.unpack(
data=packet, time_reader=CdsShortTimestamp.empty()
)
if tm_packet.subservice == 2:
verif_wrapper.dlog("Received Ping Reply TM[17,2]")
dedicated_handler = True
elif service == 20:
param_packet = Service20FsfwTm.unpack(
raw_telemetry=packet, time_reader=CdsShortTimestamp.empty()
)
if tm_packet.subservice == ParamSubservice.TM_DUMP_REPLY:
param_wrapper = Service20ParamDumpWrapper(param_tm=param_packet)
try:
param = param_wrapper.get_param()
obj = obj_id_dict.get(param_wrapper.param_tm.object_id)
pw.dlog(f"Received parameter dump TM from {obj}")
pw.dlog(f"Parameter: {param}")
if param.rows == 1 and param.columns == 1:
try:
scalar_param = param.parse_scalar_param()
if isinstance(scalar_param, int):
pw.dlog(f"Scalar integer parameter: {scalar_param}")
elif isinstance(scalar_param, float):
pw.dlog(f"Scalar floating point parameter: {scalar_param}")
except ValueError as e:
pw.dlog(f"received {e} trying to parse scalar parameter")
else:
# TODO: Could improve display further by actually displaying a matrix as a
# matrix using row and column information
pw.dlog(
"Received vector or matrix data:"
f" {param.param_raw.hex(sep=',')}"
)
except ValueError as e:
pw.dlog(f"received {e} when trying to parse parameters")
except NotImplementedError as e:
pw.dlog(f"received {e} when trying to parse parameters")
else:
pw.dlog(f"unknown subservice {tm_packet.subservice} for parameter service")
elif service == 200:
tm_packet = Service200FsfwTm.unpack(
raw_telemetry=packet, time_reader=CdsShortTimestamp.empty()
)
if tm_packet.subservice == ModeSubservice.TM_CANT_REACH_MODE:
obj_id = tm_packet.object_id
obj_id_obj = obj_id_dict.get(obj_id)
retval = tm_packet.return_value
string_list = generic_retval_printout(retval)
pw.dlog(f"Received Mode Reply from {obj_id_obj}: Can't reach mode.")
for string in string_list:
pw.dlog(f"Reason: {string}")
dedicated_handler = True
else:
dedicated_handler = False
else:
_LOGGER.info(f"The service {service} is not implemented in Telemetry Factory")
tm_packet.print_source_data(PrintFormats.HEX)
dedicated_handler = True
if not dedicated_handler and tm_packet is not None:
printer.handle_long_tm_print(packet_if=tm_packet, info_if=tm_packet)
raw_logger.log_tm(tm_packet)

View File

@ -0,0 +1,218 @@
"""Core EIVE TM handler module
"""
import logging
import sqlite3
import uuid
from typing import Any
from spacepackets.ccsds.time import CdsShortTimestamp
from spacepackets.ecss import PusTelemetry
from spacepackets.ecss.pus_17_test import Service17Tm
from spacepackets.util import PrintFormats
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.logging.pus import RawTmtcTimedLogWrapper
from tmtccmd.pus import VerificationWrapper
from tmtccmd.pus.s20_fsfw_param import Service20FsfwTm, Service20ParamDumpWrapper
from tmtccmd.pus.s20_fsfw_param_defs import CustomSubservice as ParamSubservice
from tmtccmd.pus.s200_fsfw_mode import Service200FsfwTm
from tmtccmd.pus.s200_fsfw_mode import Subservice as ModeSubservice
from tmtccmd.tmtc import GenericApidHandlerBase, SpecificApidHandlerBase
from eive_tmtc.config.definitions import TM_DB_PATH, PUS_APID
from eive_tmtc.config.object_ids import get_object_ids
from .action_reply_handler import handle_action_service_tm
from .defs import PrintWrapper
from .event_handler import handle_event_packet
from .hk_handler import HkFilter, handle_hk_packet
from .verification_handler import generic_retval_printout, handle_service_1_fsfw_packet
_LOGGER = logging.getLogger(__name__)
class PusHandler(SpecificApidHandlerBase):
def __init__(
self,
wrapper: VerificationWrapper,
printer: FsfwTmTcPrinter,
raw_logger: RawTmtcTimedLogWrapper,
hk_level: int,
):
super().__init__(PUS_APID, None)
self.printer = printer
self.verif_wrapper = wrapper
self.raw_logger = raw_logger
self.hk_level = hk_level
self.these_objs_hk_only = []
self.hk_filter = HkFilter(object_ids=self.these_objs_hk_only, set_ids=[])
self.obj_id_dict = get_object_ids()
self.pw = PrintWrapper(printer.file_logger)
def handle_tm(self, packet: bytes, _user_args: Any):
self.pus_handler(
packet,
)
def pus_handler( # noqa C901 : Complexity okay here
self,
packet: bytes,
):
packet_uuid = uuid.uuid4()
if len(packet) < 8:
_LOGGER.warning("Detected packet shorter than 8 bytes!")
return
try:
tm_packet = PusTelemetry.unpack(packet, CdsShortTimestamp.TIMESTAMP_SIZE)
# _LOGGER.info(f"Sequence count: {tm_packet.seq_count}")
except ValueError as value_error:
_LOGGER.warning(f"{value_error}")
_LOGGER.warning("Could not generate PUS TM object from raw data")
_LOGGER.warning(f"Raw Packet: [{packet.hex(sep=',')}], REPR: {packet!r}")
return
timestamp = CdsShortTimestamp.unpack(tm_packet.timestamp)
db_con = sqlite3.connect(TM_DB_PATH)
self._store_packet_in_db(
db_con=db_con,
packet=packet,
tm_packet=tm_packet,
timestamp=timestamp,
packet_uuid=packet_uuid,
)
service = tm_packet.service
dedicated_handler = True
if service == 1:
handle_service_1_fsfw_packet(wrapper=self.verif_wrapper, raw_tm=packet)
elif service == 3:
handle_hk_packet(
db_con=db_con,
packet_uuid=packet_uuid,
printer=self.printer,
raw_tm=packet,
obj_id_dict=self.obj_id_dict,
hk_level=self.hk_level,
hk_filter=self.hk_filter,
)
elif service == 5:
handle_event_packet(raw_tm=packet, pw=self.pw)
elif service == 8:
handle_action_service_tm(
raw_tm=packet, pw=self.pw, obj_id_dict=self.obj_id_dict
)
elif service == 17:
pus17_tm = Service17Tm.unpack(
data=packet, timestamp_len=CdsShortTimestamp.TIMESTAMP_SIZE
)
if pus17_tm.subservice == 2:
self.verif_wrapper.dlog("Received Ping Reply TM[17,2]")
dedicated_handler = True
elif service == 20:
self._handle_param_packet(packet, tm_packet)
elif service == 200:
dedicated_handler = self._handle_mode_packet(packet, tm_packet)
else:
_LOGGER.info(
f"The service {service} is not implemented in Telemetry Factory"
)
tm_packet.print_source_data(PrintFormats.HEX)
dedicated_handler = True
if not dedicated_handler and tm_packet is not None:
_LOGGER.info(
f"TM [{service},{tm_packet.subservice}] does not have a dedicated handler"
)
self.raw_logger.log_tm(tm_packet)
def _store_packet_in_db(
self,
db_con: sqlite3.Connection,
packet: bytes,
timestamp: CdsShortTimestamp,
tm_packet: PusTelemetry,
packet_uuid: uuid.UUID,
):
cursor = db_con.cursor()
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS pus_tm(
packet_uuid TEXT PRIMARY KEY,
generation_time TEXT,
service NUM,
subservice NUM,
data_len NUM,
raw_data BLOB
)"""
)
cursor.execute(
"INSERT INTO pus_tm VALUES(?, ?, ?, ?, ?, ?)",
(
str(packet_uuid),
timestamp.as_datetime(),
tm_packet.service,
tm_packet.subservice,
len(packet),
packet,
),
)
db_con.commit()
def _handle_param_packet(self, raw_data: bytes, tm_packet: PusTelemetry):
param_packet = Service20FsfwTm.unpack(
raw_telemetry=raw_data, timestamp_len=CdsShortTimestamp.TIMESTAMP_SIZE
)
if tm_packet.subservice == ParamSubservice.TM_DUMP_REPLY:
param_wrapper = Service20ParamDumpWrapper(param_tm=param_packet)
try:
param = param_wrapper.get_param()
obj = self.obj_id_dict.get(param_wrapper.param_tm.object_id)
self.pw.dlog(f"Received parameter dump TM from {obj}")
self.pw.dlog(f"Parameter: {param}")
if param.rows == 1 and param.columns == 1:
try:
scalar_param = param.parse_scalar_param()
if isinstance(scalar_param, int):
self.pw.dlog(f"Scalar integer parameter: {scalar_param}")
elif isinstance(scalar_param, float):
self.pw.dlog(
f"Scalar floating point parameter: {scalar_param}"
)
except ValueError as e:
self.pw.dlog(f"received {e} trying to parse scalar parameter")
else:
# TODO: Could improve display further by actually displaying a matrix as a
# matrix using row and column information
self.pw.dlog(
"Received vector or matrix data:"
f" {param.param_raw.hex(sep=',')}"
)
except ValueError as e:
self.pw.dlog(f"received {e} when trying to parse parameters")
except NotImplementedError as e:
self.pw.dlog(f"received {e} when trying to parse parameters")
else:
self.pw.dlog(
f"unknown subservice {tm_packet.subservice} for parameter service"
)
def _handle_mode_packet(self, raw_data: bytes, _: PusTelemetry) -> bool:
tm_packet = Service200FsfwTm.unpack(
raw_telemetry=raw_data, time_reader=CdsShortTimestamp.empty()
)
if tm_packet.subservice == ModeSubservice.TM_CANT_REACH_MODE:
obj_id = tm_packet.object_id
obj_id_obj = self.obj_id_dict.get(obj_id)
retval = tm_packet.return_value
string_list = generic_retval_printout(retval)
self.pw.dlog(f"Received Mode Reply from {obj_id_obj}: Can't reach mode.")
for string in string_list:
self.pw.dlog(f"Reason: {string}")
return True
if tm_packet.subservice == ModeSubservice.TM_WRONG_MODE_REPLY:
self.pw.dlog(f"Received Mode TM wrong mode reply, mode: {tm_packet.mode}")
return False
class UnknownApidHandler(GenericApidHandlerBase):
def handle_tm(self, apid: int, packet: bytes, _user_args: Any):
_LOGGER.warning(
f"Packet with unknown APID {apid} detected: {packet.hex(sep=',')}"
)

View File

@ -17,7 +17,7 @@ def handle_service_1_fsfw_packet(wrapper: VerificationWrapper, raw_tm: bytes):
)
# Error code with length 2 is FSFW specific
tm_packet = Service1Tm.unpack(
data=raw_tm, params=UnpackParams(CdsShortTimestamp.empty(), 1, 2)
data=raw_tm, params=UnpackParams(CdsShortTimestamp.TIMESTAMP_SIZE, 1, 2)
)
fsfw_wrapper = Service1FsfwWrapper(tm_packet)
res = wrapper.verificator.add_tm(tm_packet)

View File

@ -1,8 +1,3 @@
from .payload.subsystem import add_payload_subsystem_cmds
from .solar_array_deployment import add_sa_depl_cmds
from .test import add_test_defs
from .time import add_time_cmds
from .health import add_health_cmd_defs
from .system import add_system_cmd_defs
from .tm_store import add_persistent_tm_store_cmd_defs
from .tcs import add_tmp_sens_cmds

View File

@ -1,16 +1,16 @@
import enum
from eive_tmtc.config.definitions import CustomServiceList
from tmtccmd.config.tmtc import (
tmtc_definitions_provider,
TmtcDefinitionWrapper,
CmdTreeNode,
OpCodeEntry,
TmtcDefinitionWrapper,
tmtc_definitions_provider,
)
from tmtccmd.tmtc import service_provider, DefaultPusQueueHelper
from tmtccmd.tmtc.decorator import ServiceProviderParams
from tmtccmd.pus.s200_fsfw_mode import Mode
from eive_tmtc.config.object_ids import ACS_BOARD_ASS_ID
from tmtccmd.tmtc import DefaultPusQueueHelper
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.config.object_ids import ACS_BOARD_ASS_ID
from eive_tmtc.tmtc.common import pack_mode_cmd_with_info
@ -30,8 +30,8 @@ class DualSideSubmode(enum.IntEnum):
DUAL_SIDE = 2
def pack_acs_command(q: DefaultPusQueueHelper, op_code: str):
if op_code in AcsOpCodes.ACS_ASS_A_SIDE:
def pack_acs_board_command(q: DefaultPusQueueHelper, cmd_str: str):
if cmd_str in AcsOpCodes.ACS_ASS_A_SIDE:
pack_mode_cmd_with_info(
object_id=ACS_BOARD_ASS_ID,
mode=Mode.NORMAL,
@ -39,7 +39,7 @@ def pack_acs_command(q: DefaultPusQueueHelper, op_code: str):
q=q,
info="Switching to ACS board assembly A side",
)
if op_code in AcsOpCodes.ACS_ASS_B_SIDE:
if cmd_str in AcsOpCodes.ACS_ASS_B_SIDE:
pack_mode_cmd_with_info(
object_id=ACS_BOARD_ASS_ID,
mode=Mode.NORMAL,
@ -47,7 +47,7 @@ def pack_acs_command(q: DefaultPusQueueHelper, op_code: str):
q=q,
info="Switching to ACS board assembly B side",
)
if op_code in AcsOpCodes.ACS_ASS_DUAL_MODE:
if cmd_str in AcsOpCodes.ACS_ASS_DUAL_MODE:
pack_mode_cmd_with_info(
object_id=ACS_BOARD_ASS_ID,
mode=Mode.NORMAL,
@ -55,7 +55,7 @@ def pack_acs_command(q: DefaultPusQueueHelper, op_code: str):
q=q,
info="Switching to ACS board assembly dual mode",
)
if op_code in AcsOpCodes.ACS_ASS_A_ON:
if cmd_str in AcsOpCodes.ACS_ASS_A_ON:
pack_mode_cmd_with_info(
object_id=ACS_BOARD_ASS_ID,
mode=Mode.ON,
@ -63,7 +63,7 @@ def pack_acs_command(q: DefaultPusQueueHelper, op_code: str):
q=q,
info="Switching ACS board assembly A side on",
)
if op_code in AcsOpCodes.ACS_ASS_B_ON:
if cmd_str in AcsOpCodes.ACS_ASS_B_ON:
pack_mode_cmd_with_info(
object_id=ACS_BOARD_ASS_ID,
mode=Mode.ON,
@ -71,7 +71,7 @@ def pack_acs_command(q: DefaultPusQueueHelper, op_code: str):
q=q,
info="Switching ACS board assembly B side on",
)
if op_code in AcsOpCodes.ACS_ASS_DUAL_ON:
if cmd_str in AcsOpCodes.ACS_ASS_DUAL_ON:
pack_mode_cmd_with_info(
object_id=ACS_BOARD_ASS_ID,
mode=Mode.ON,
@ -79,7 +79,7 @@ def pack_acs_command(q: DefaultPusQueueHelper, op_code: str):
q=q,
info="Switching ACS board assembly dual side on",
)
if op_code in AcsOpCodes.ACS_ASS_OFF:
if cmd_str in AcsOpCodes.ACS_ASS_OFF:
pack_mode_cmd_with_info(
object_id=ACS_BOARD_ASS_ID,
mode=Mode.OFF,
@ -89,11 +89,51 @@ def pack_acs_command(q: DefaultPusQueueHelper, op_code: str):
)
@service_provider(CustomServiceList.ACS_BRD_ASS)
def pack_acs_command_provider(p: ServiceProviderParams):
op_code = p.op_code
q = p.queue_helper
pack_acs_command(q, op_code)
def create_acs_board_node() -> CmdTreeNode:
node = CmdTreeNode("acs_brd", "ACS Board", hide_children_which_are_leaves=True)
node.add_child(
CmdTreeNode(
AcsOpCodes.ACS_ASS_A_SIDE[1],
"Switch to ACS board A side",
)
)
node.add_child(
CmdTreeNode(
AcsOpCodes.ACS_ASS_B_SIDE[1],
"Switch to ACS board B side",
)
)
node.add_child(
CmdTreeNode(
AcsOpCodes.ACS_ASS_DUAL_MODE[1],
"Switch to ACS board dual mode",
)
)
node.add_child(
CmdTreeNode(
AcsOpCodes.ACS_ASS_A_ON[1],
"Switch ACS board A side on",
)
)
node.add_child(
CmdTreeNode(
AcsOpCodes.ACS_ASS_B_ON[1],
"Switch ACS board B side on",
)
)
node.add_child(
CmdTreeNode(
AcsOpCodes.ACS_ASS_DUAL_ON[1],
"Switch ACS board dual mode on",
)
)
node.add_child(
CmdTreeNode(
AcsOpCodes.ACS_ASS_OFF[1],
"Switch off ACS board",
)
)
return node
@tmtc_definitions_provider

View File

@ -7,12 +7,8 @@ import struct
from socket import AF_INET
from typing import Tuple
from tmtccmd.config.tmtc import (
OpCodeEntry,
TmtcDefinitionWrapper,
tmtc_definitions_provider,
)
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.config.tmtc import CmdTreeNode
from tmtccmd.fsfw.tmtc_printer import get_validity_buffer_str
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from tmtccmd.pus.s20_fsfw_param import create_load_param_cmd
from tmtccmd.pus.s20_fsfw_param_defs import (
@ -29,16 +25,13 @@ from tmtccmd.pus.s20_fsfw_param_defs import (
from tmtccmd.pus.s200_fsfw_mode import Mode, pack_mode_command
from tmtccmd.pus.tc.s3_fsfw_hk import (
create_request_one_diag_command,
create_request_one_hk_command,
disable_periodic_hk_command,
enable_periodic_hk_command_with_interval,
generate_one_hk_command,
make_sid,
)
from tmtccmd.tmtc import service_provider
from tmtccmd.tmtc.decorator import ServiceProviderParams
from tmtccmd.tmtc.queue import DefaultPusQueueHelper
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.config.object_ids import ACS_CONTROLLER
from eive_tmtc.pus_tm.defs import PrintWrapper
from eive_tmtc.tmtc.acs.defs import AcsMode, SafeSubmode
@ -54,10 +47,17 @@ class SetId(enum.IntEnum):
GYR_RAW_SET = 4
GYR_PROC_SET = 5
GPS_PROC_SET = 6
MEKF_DATA = 7
ATTITUDE_ESTIMATION_DATA = 7
CTRL_VAL_DATA = 8
ACTUATOR_CMD_DATA = 9
FUSED_ROT_RATE_DATA = 10
FUSED_ROT_RATE_SOURCE_DATA = 11
class DataSetRequest(enum.IntEnum):
ONESHOT = 0
ENABLE = 1
DISABLE = 2
class ActionId(enum.IntEnum):
@ -65,6 +65,8 @@ class ActionId(enum.IntEnum):
RESET_MEKF = 1
RESTORE_MEKF_NONFINITE_RECOVERY = 2
UPDATE_TLE = 3
READ_TLE = 4
UPDATE_MEKF_STANDARD_DEVIATIONS = 5
CTRL_STRAT_DICT = {
@ -85,67 +87,47 @@ CTRL_STRAT_DICT = {
19: "SAFE_ECLIPSE_IDELING",
20: "DETUMBLE_FULL",
21: "DETUMBLE_DETERIORATED",
30: "PTG_MEKF",
31: "PTG_RAW",
100: "PTG_MEKF",
101: "PTG_STR",
102: "PTG_QUEST",
}
GPS_COURCE_DICT = {
GPS_SOURCE_DICT = {
0: "NONE",
1: "GPS",
2: "GPS_EXTRAPOLATED",
3: "SGP4",
}
FUSED_ROT_RATE_SOURCE_DICT = {
0: "NONE",
1: "SUSMGM",
2: "QUEST",
3: "STR",
}
class OpCodes:
OFF = ["off"]
SAFE = ["safe"]
DTBL = ["safe_detumble"]
IDLE = ["ptg_idle"]
NADIR = ["ptg_nadir"]
TARGET = ["ptg_target"]
GS = ["ptg_target_gs"]
INERTIAL = ["ptg_inertial"]
SAFE_PTG = ["confirm_deployment"]
RESET_MEKF = ["reset_mekf"]
RESTORE_MEKF_NONFINITE_RECOVERY = ["restore_mekf_nonfinite_recovery"]
UPDATE_TLE = ["update_tle"]
SET_PARAMETER_SCALAR = ["set_scalar_param"]
SET_PARAMETER_VECTOR = ["set_vector_param"]
SET_PARAMETER_MATRIX = ["set_matrix_param"]
REQUEST_RAW_MGM_HK = ["mgm_raw_hk"]
ENABLE_RAW_MGM_HK = ["mgm_raw_enable_hk"]
DISABLE_RAW_MGM_HK = ["mgm_raw_disable_hk"]
REQUEST_PROC_MGM_HK = ["mgm_proc_hk"]
ENABLE_PROC_MGM_HK = ["mgm_proc_enable_hk"]
DISABLE_PROC_MGM_HK = ["mgm_proc_disable_hk"]
REQUEST_RAW_SUS_HK = ["sus_raw_hk"]
ENABLE_RAW_SUS_HK = ["sus_raw_enable_hk"]
DISABLE_RAW_SUS_HK = ["sus_raw_disable_hk"]
REQUEST_PROC_SUS_HK = ["sus_proc_hk"]
ENABLE_PROC_SUS_HK = ["sus_proc_enable_hk"]
DISABLE_PROC_SUS_HK = ["sus_proc_disable_hk"]
REQUEST_RAW_GYR_HK = ["gyr_raw_hk"]
ENABLE_RAW_GYR_HK = ["gyr_raw_enable_hk"]
DISABLE_RAW_GYR_HK = ["gyr_raw_disable_hk"]
REQUEST_PROC_GYR_HK = ["gyr_proc_hk"]
ENABLE_PROC_GYR_HK = ["gyr_proc_enable_hk"]
DISABLE_PROC_GYR_HK = ["gyr_proc_disable_hk"]
REQUEST_PROC_GPS_HK = ["gps_proc_hk"]
ENABLE_PROC_GPS_HK = ["gps_proc_enable_hk"]
DISABLE_PROC_GPS_HK = ["gps_proc_disable_hk"]
REQUEST_MEKF_HK = ["mekf_hk"]
ENABLE_MEKF_HK = ["mekf_enable_hk"]
DISABLE_MEKF_HK = ["mekf_disable_hk"]
REQUEST_CTRL_VAL_HK = ["ctrl_val_hk"]
ENABLE_CTRL_VAL_HK = ["ctrl_val_enable_hk"]
DISABLE_CTRL_VAL_HK = ["ctrl_val_disable_hk"]
REQUEST_ACT_CMD_HK = ["act_cmd_hk"]
ENABLE_ACT_CMD_HK = ["act_cmd_enable_hk"]
DISABLE_ACT_CMD_HK = ["act_cmd_disable_hk"]
REQUEST_FUSED_ROT_RATE_HK = ["f_rot_rate_hk"]
ENABLE_FUSED_ROT_RATE_HK = ["f_rot_rate_enable_hk"]
DISABLE_FUSED_ROT_RATE_HK = ["f_rot_rate_disable_hk"]
OFF = "off"
SAFE = "safe"
DTBL = "safe_detumble"
IDLE = "ptg_idle"
NADIR = "ptg_nadir"
TARGET = "ptg_target"
GS = "ptg_target_gs"
INERTIAL = "ptg_inertial"
SAFE_PTG = "confirm_deployment"
RESET_MEKF = "reset_mekf"
RESTORE_MEKF_NONFINITE_RECOVERY = "restore_mekf_nonfinite_recovery"
UPDATE_TLE = "update_tle"
READ_TLE = "read_tle"
UPDATE_MEKF_STANDARD_DEVIATIONS = "update_mekf_standard_deviations"
SET_PARAMETER_SCALAR = "set_scalar_param"
SET_PARAMETER_VECTOR = "set_vector_param"
SET_PARAMETER_MATRIX = "set_matrix_param"
ONE_SHOOT_HK = "one_shot_hk"
ENABLE_HK = "enable_hk"
DISABLE_HK = "disable_hk"
class Info:
@ -161,42 +143,17 @@ class Info:
RESET_MEKF = "Reset the MEKF"
RESTORE_MEKF_NONFINITE_RECOVERY = "Restore MEKF non-finite recovery"
UPDATE_TLE = "Update TLE"
READ_TLE = "Read the currently stored TLE"
UPDATE_MEKF_STANDARD_DEVIATIONS = (
"Update the Standard Deviations within the MEKF to the current ACS Parameter "
"Values"
)
SET_PARAMETER_SCALAR = "Set Scalar Parameter"
SET_PARAMETER_VECTOR = "Set Vector Parameter"
SET_PARAMETER_MATRIX = "Set Matrix Parameter"
REQUEST_RAW_MGM_HK = "Request Raw MGM HK once"
ENABLE_RAW_MGM_HK = "Enable Raw MGM HK data generation"
DISABLE_RAW_MGM_HK = "Disable Raw MGM HK data generation"
REQUEST_PROC_MGM_HK = "Request Processed MGM HK"
ENABLE_PROC_MGM_HK = "Enable Processed MGM HK data generation"
DISABLE_PROC_MGM_HK = "Disable Processed MGM HK data generation"
REQUEST_RAW_SUS_HK = "Request Raw SUS HK"
ENABLE_RAW_SUS_HK = "Enable Raw SUS HK data generation"
DISABLE_RAW_SUS_HK = "Disable Raw SUS HK data generation"
REQUEST_PROC_SUS_HK = "Request Processed SUS HK"
ENABLE_PROC_SUS_HK = "Enable Processed SUS HK data generation"
DISABLE_PROC_SUS_HK = "Disable Processed MGM HK data generation"
REQUEST_RAW_GYR_HK = "Request Raw GYR HK"
ENABLE_RAW_GYR_HK = "Enable Raw GYR HK data generation"
DISABLE_RAW_GYR_HK = "Disable Raw GYR HK data generation"
REQUEST_PROC_GYR_HK = "Request Processed GYR HK"
ENABLE_PROC_GYR_HK = "Enable Processed GYR HK data generation"
DISABLE_PROC_GYR_HK = "Disable Processed GYR HK data generation"
REQUEST_PROC_GPS_HK = "Request Processed GPS HK"
ENABLE_PROC_GPS_HK = "Enable Processed GPS HK data generation"
DISABLE_PROC_GPS_HK = "Disable Processed GPS HK data generation"
REQUEST_MEKF_HK = "Request MEKF HK"
ENABLE_MEKF_HK = "Enable MEKF HK data generation"
DISABLE_MEKF_HK = "Disable MEKF HK data generation"
REQUEST_CTRL_VAL_HK = "Request Control Values HK"
ENABLE_CTRL_VAL_HK = "Enable Control Values HK data generation"
DISABLE_CTRL_VAL_HK = "Disable Control Values HK data generation"
REQUEST_ACT_CMD_HK = "Request Actuator Commands HK"
ENABLE_ACT_CMD_HK = "Enable Actuator Commands HK data generation"
DISABLE_ACT_CMD_HK = "Disable Actuator Commands HK data generation"
REQUEST_FUSED_ROT_RATE_HK = "Request Fused Rotational Rates HK"
ENABLE_FUSED_ROT_RATE_HK = "Enable Fused Rotational Rates HK data generation"
DISABLE_FUSED_ROT_RATE_HK = "Disable Fused Rotational Rates HK data generation"
ONE_SHOOT_HK = "One shoot HK Set"
ENABLE_HK = "Enable Periodic HK"
DISABLE_HK = "Disable Periodic HK"
PERFORM_MGM_CALIBRATION = False
@ -211,113 +168,66 @@ if PERFORM_MGM_CALIBRATION:
CALIBR_SOCKET.connect(CALIBRATION_ADDR)
@tmtc_definitions_provider
def acs_cmd_defs(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(keys=OpCodes.OFF, info=Info.OFF)
oce.add(keys=OpCodes.SAFE, info=Info.SAFE)
oce.add(keys=OpCodes.DTBL, info=Info.DTBL)
oce.add(keys=OpCodes.IDLE, info=Info.IDLE)
oce.add(keys=OpCodes.NADIR, info=Info.NADIR)
oce.add(keys=OpCodes.TARGET, info=Info.TARGET)
oce.add(keys=OpCodes.GS, info=Info.GS)
oce.add(keys=OpCodes.INERTIAL, info=Info.INERTIAL)
oce.add(keys=OpCodes.SAFE_PTG, info=Info.SAFE_PTG)
oce.add(keys=OpCodes.RESET_MEKF, info=Info.RESET_MEKF)
oce.add(
keys=OpCodes.RESTORE_MEKF_NONFINITE_RECOVERY,
info=Info.RESTORE_MEKF_NONFINITE_RECOVERY,
)
oce.add(keys=OpCodes.UPDATE_TLE, info=Info.UPDATE_TLE)
oce.add(keys=OpCodes.SET_PARAMETER_SCALAR, info=Info.SET_PARAMETER_SCALAR)
oce.add(keys=OpCodes.SET_PARAMETER_VECTOR, info=Info.SET_PARAMETER_VECTOR)
oce.add(keys=OpCodes.SET_PARAMETER_MATRIX, info=Info.SET_PARAMETER_MATRIX)
oce.add(keys=OpCodes.REQUEST_RAW_MGM_HK, info=Info.REQUEST_RAW_MGM_HK)
oce.add(keys=OpCodes.ENABLE_RAW_MGM_HK, info=Info.ENABLE_RAW_MGM_HK)
oce.add(keys=OpCodes.DISABLE_RAW_MGM_HK, info=Info.DISABLE_RAW_MGM_HK)
oce.add(keys=OpCodes.REQUEST_PROC_MGM_HK, info=Info.REQUEST_PROC_MGM_HK)
oce.add(keys=OpCodes.ENABLE_PROC_MGM_HK, info=Info.ENABLE_PROC_MGM_HK)
oce.add(keys=OpCodes.DISABLE_PROC_MGM_HK, info=Info.DISABLE_PROC_MGM_HK)
oce.add(keys=OpCodes.REQUEST_RAW_SUS_HK, info=Info.REQUEST_RAW_SUS_HK)
oce.add(keys=OpCodes.ENABLE_RAW_SUS_HK, info=Info.ENABLE_RAW_SUS_HK)
oce.add(keys=OpCodes.DISABLE_RAW_SUS_HK, info=Info.DISABLE_RAW_SUS_HK)
oce.add(keys=OpCodes.REQUEST_PROC_SUS_HK, info=Info.REQUEST_PROC_SUS_HK)
oce.add(keys=OpCodes.ENABLE_PROC_SUS_HK, info=Info.ENABLE_PROC_SUS_HK)
oce.add(keys=OpCodes.DISABLE_PROC_SUS_HK, info=Info.DISABLE_PROC_SUS_HK)
oce.add(keys=OpCodes.REQUEST_RAW_GYR_HK, info=Info.REQUEST_RAW_GYR_HK)
oce.add(keys=OpCodes.ENABLE_RAW_GYR_HK, info=Info.ENABLE_RAW_GYR_HK)
oce.add(keys=OpCodes.DISABLE_RAW_GYR_HK, info=Info.DISABLE_RAW_GYR_HK)
oce.add(keys=OpCodes.REQUEST_PROC_GYR_HK, info=Info.REQUEST_PROC_GYR_HK)
oce.add(keys=OpCodes.ENABLE_PROC_GYR_HK, info=Info.ENABLE_PROC_GYR_HK)
oce.add(keys=OpCodes.DISABLE_PROC_GYR_HK, info=Info.DISABLE_PROC_GYR_HK)
oce.add(keys=OpCodes.REQUEST_PROC_GPS_HK, info=Info.REQUEST_PROC_GPS_HK)
oce.add(keys=OpCodes.ENABLE_PROC_GPS_HK, info=Info.ENABLE_PROC_GPS_HK)
oce.add(keys=OpCodes.DISABLE_PROC_GPS_HK, info=Info.DISABLE_PROC_GPS_HK)
oce.add(keys=OpCodes.REQUEST_MEKF_HK, info=Info.REQUEST_MEKF_HK)
oce.add(keys=OpCodes.ENABLE_MEKF_HK, info=Info.ENABLE_MEKF_HK)
oce.add(keys=OpCodes.DISABLE_MEKF_HK, info=Info.DISABLE_MEKF_HK)
oce.add(keys=OpCodes.REQUEST_CTRL_VAL_HK, info=Info.REQUEST_CTRL_VAL_HK)
oce.add(keys=OpCodes.ENABLE_CTRL_VAL_HK, info=Info.ENABLE_CTRL_VAL_HK)
oce.add(keys=OpCodes.DISABLE_CTRL_VAL_HK, info=Info.DISABLE_CTRL_VAL_HK)
oce.add(keys=OpCodes.REQUEST_ACT_CMD_HK, info=Info.REQUEST_ACT_CMD_HK)
oce.add(keys=OpCodes.ENABLE_ACT_CMD_HK, info=Info.ENABLE_ACT_CMD_HK)
oce.add(keys=OpCodes.DISABLE_ACT_CMD_HK, info=Info.DISABLE_ACT_CMD_HK)
oce.add(keys=OpCodes.REQUEST_FUSED_ROT_RATE_HK, info=Info.REQUEST_FUSED_ROT_RATE_HK)
oce.add(keys=OpCodes.ENABLE_FUSED_ROT_RATE_HK, info=Info.ENABLE_FUSED_ROT_RATE_HK)
oce.add(keys=OpCodes.DISABLE_FUSED_ROT_RATE_HK, info=Info.DISABLE_FUSED_ROT_RATE_HK)
defs.add_service(
name=CustomServiceList.ACS_CTRL.value, info="ACS Controller", op_code_entry=oce
def create_acs_ctrl_node() -> CmdTreeNode:
# Zip the two classes together into a dictionary
op_code_strs = [
getattr(OpCodes, key) for key in dir(OpCodes) if not key.startswith("__")
]
info_strs = [getattr(Info, key) for key in dir(OpCodes) if not key.startswith("__")]
combined_dict = dict(zip(op_code_strs, info_strs))
acs_ctrl = CmdTreeNode(
"acs_ctrl", "ACS Controller", hide_children_which_are_leaves=True
)
for op_code, info in combined_dict.items():
acs_ctrl.add_child(CmdTreeNode(op_code, info))
return acs_ctrl
@service_provider(CustomServiceList.ACS_CTRL.value)
def pack_acs_ctrl_command(p: ServiceProviderParams): # noqa C901
op_code = p.op_code
q = p.queue_helper
if op_code in OpCodes.OFF:
def pack_acs_ctrl_command(q: DefaultPusQueueHelper, cmd_str: str): # noqa C901
if cmd_str in OpCodes.OFF:
q.add_log_cmd(f"{Info.OFF}")
q.add_pus_tc(pack_mode_command(ACS_CONTROLLER, Mode.OFF, 0))
elif op_code in OpCodes.SAFE:
elif cmd_str in OpCodes.SAFE:
q.add_log_cmd(f"{Info.SAFE}")
q.add_pus_tc(
pack_mode_command(ACS_CONTROLLER, AcsMode.SAFE, SafeSubmode.DEFAULT)
)
elif op_code in OpCodes.DTBL:
elif cmd_str in OpCodes.DTBL:
q.add_log_cmd(f"{Info.DTBL}")
q.add_pus_tc(
pack_mode_command(ACS_CONTROLLER, AcsMode.SAFE, SafeSubmode.DETUMBLE)
)
elif op_code in OpCodes.IDLE:
elif cmd_str in OpCodes.IDLE:
q.add_log_cmd(f"{Info.IDLE}")
q.add_pus_tc(pack_mode_command(ACS_CONTROLLER, AcsMode.IDLE, 0))
elif op_code in OpCodes.NADIR:
elif cmd_str in OpCodes.NADIR:
q.add_log_cmd(f"{Info.NADIR}")
q.add_pus_tc(pack_mode_command(ACS_CONTROLLER, AcsMode.PTG_NADIR, 0))
elif op_code in OpCodes.TARGET:
elif cmd_str in OpCodes.TARGET:
q.add_log_cmd(f"{Info.TARGET}")
q.add_pus_tc(pack_mode_command(ACS_CONTROLLER, AcsMode.PTG_TARGET, 0))
elif op_code in OpCodes.GS:
elif cmd_str in OpCodes.GS:
q.add_log_cmd(f"{Info.GS}")
q.add_pus_tc(pack_mode_command(ACS_CONTROLLER, AcsMode.PTG_TARGET_GS, 0))
elif op_code in OpCodes.INERTIAL:
elif cmd_str in OpCodes.INERTIAL:
q.add_log_cmd(f"{Info.INERTIAL}")
q.add_pus_tc(pack_mode_command(ACS_CONTROLLER, AcsMode.PTG_INERTIAL, 0))
elif op_code in OpCodes.SAFE_PTG:
elif cmd_str in OpCodes.SAFE_PTG:
q.add_log_cmd(f"{Info.SAFE_PTG}")
q.add_pus_tc(
create_action_cmd(
ACS_CONTROLLER, ActionId.SOLAR_ARRAY_DEPLOYMENT_SUCCESSFUL
)
)
elif op_code in OpCodes.RESET_MEKF:
elif cmd_str in OpCodes.RESET_MEKF:
q.add_log_cmd(f"{Info.RESET_MEKF}")
q.add_pus_tc(create_action_cmd(ACS_CONTROLLER, ActionId.RESET_MEKF))
elif op_code in OpCodes.RESTORE_MEKF_NONFINITE_RECOVERY:
elif cmd_str in OpCodes.RESTORE_MEKF_NONFINITE_RECOVERY:
q.add_log_cmd(f"{Info.RESTORE_MEKF_NONFINITE_RECOVERY}")
q.add_pus_tc(
create_action_cmd(ACS_CONTROLLER, ActionId.RESTORE_MEKF_NONFINITE_RECOVERY)
)
elif op_code in OpCodes.UPDATE_TLE:
elif cmd_str in OpCodes.UPDATE_TLE:
q.add_log_cmd(f"{Info.UPDATE_TLE}")
while True:
line1 = input("Please input the first line of the TLE: ")
@ -333,237 +243,82 @@ def pack_acs_ctrl_command(p: ServiceProviderParams): # noqa C901
print("The line does not have the required length of 69 characters")
tle = line1.encode() + line2.encode()
q.add_pus_tc(create_action_cmd(ACS_CONTROLLER, ActionId.UPDATE_TLE, tle))
elif op_code in OpCodes.SET_PARAMETER_SCALAR:
elif cmd_str == OpCodes.READ_TLE:
q.add_log_cmd(f"{Info.READ_TLE}")
q.add_pus_tc(create_action_cmd(ACS_CONTROLLER, ActionId.READ_TLE))
elif cmd_str == OpCodes.UPDATE_MEKF_STANDARD_DEVIATIONS:
q.add_log_cmd(f"{Info.UPDATE_MEKF_STANDARD_DEVIATIONS}")
q.add_pus_tc(
create_action_cmd(ACS_CONTROLLER, ActionId.UPDATE_MEKF_STANDARD_DEVIATIONS)
)
elif cmd_str == OpCodes.SET_PARAMETER_SCALAR:
q.add_log_cmd(f"{Info.SET_PARAMETER_SCALAR}")
set_acs_ctrl_param_scalar(q)
elif op_code in OpCodes.SET_PARAMETER_VECTOR:
elif cmd_str == OpCodes.SET_PARAMETER_VECTOR:
q.add_log_cmd(f"{Info.SET_PARAMETER_VECTOR}")
set_acs_ctrl_param_vector(q)
elif op_code in OpCodes.SET_PARAMETER_MATRIX:
elif cmd_str == OpCodes.SET_PARAMETER_MATRIX:
q.add_log_cmd(f"{Info.SET_PARAMETER_MATRIX}")
set_acs_ctrl_param_matrix(q)
elif op_code in OpCodes.REQUEST_RAW_MGM_HK:
q.add_log_cmd(Info.REQUEST_RAW_MGM_HK)
q.add_pus_tc(
generate_one_hk_command(make_sid(ACS_CONTROLLER, SetId.MGM_RAW_SET))
)
elif op_code in OpCodes.ENABLE_RAW_MGM_HK:
interval = float(input("Please specify interval in floating point seconds: "))
q.add_log_cmd(Info.ENABLE_RAW_MGM_HK)
cmd_tuple = enable_periodic_hk_command_with_interval(
False, make_sid(ACS_CONTROLLER, SetId.MGM_RAW_SET), interval
)
q.add_pus_tc(cmd_tuple[0])
q.add_pus_tc(cmd_tuple[1])
elif op_code in OpCodes.DISABLE_RAW_MGM_HK:
q.add_log_cmd(Info.DISABLE_RAW_MGM_HK)
q.add_pus_tc(
disable_periodic_hk_command(
False, make_sid(ACS_CONTROLLER, SetId.MGM_RAW_SET)
)
)
elif op_code in OpCodes.REQUEST_PROC_MGM_HK:
q.add_log_cmd(Info.REQUEST_PROC_MGM_HK)
q.add_pus_tc(
generate_one_hk_command(make_sid(ACS_CONTROLLER, SetId.MGM_PROC_SET))
)
elif op_code in OpCodes.ENABLE_PROC_MGM_HK:
interval = float(input("Please specify interval in floating point seconds: "))
q.add_log_cmd(Info.ENABLE_PROC_MGM_HK)
cmd_tuple = enable_periodic_hk_command_with_interval(
False, make_sid(ACS_CONTROLLER, SetId.MGM_PROC_SET), interval
)
q.add_pus_tc(cmd_tuple[0])
q.add_pus_tc(cmd_tuple[1])
elif op_code in OpCodes.DISABLE_PROC_MGM_HK:
q.add_log_cmd(Info.DISABLE_PROC_MGM_HK)
q.add_pus_tc(
disable_periodic_hk_command(
False, make_sid(ACS_CONTROLLER, SetId.MGM_PROC_SET)
)
)
elif op_code in OpCodes.REQUEST_RAW_SUS_HK:
q.add_log_cmd(Info.REQUEST_RAW_SUS_HK)
q.add_pus_tc(
generate_one_hk_command(make_sid(ACS_CONTROLLER, SetId.SUS_RAW_SET))
)
elif op_code in OpCodes.ENABLE_RAW_SUS_HK:
interval = float(input("Please specify interval in floating point seconds: "))
q.add_log_cmd(Info.ENABLE_RAW_SUS_HK)
cmd_tuple = enable_periodic_hk_command_with_interval(
False, make_sid(ACS_CONTROLLER, SetId.SUS_RAW_SET), interval
)
q.add_pus_tc(cmd_tuple[0])
q.add_pus_tc(cmd_tuple[1])
elif op_code in OpCodes.DISABLE_RAW_SUS_HK:
q.add_log_cmd(Info.DISABLE_RAW_SUS_HK)
q.add_pus_tc(
disable_periodic_hk_command(
False, make_sid(ACS_CONTROLLER, SetId.SUS_RAW_SET)
)
)
elif op_code in OpCodes.REQUEST_PROC_SUS_HK:
q.add_log_cmd(Info.REQUEST_PROC_SUS_HK)
q.add_pus_tc(
generate_one_hk_command(make_sid(ACS_CONTROLLER, SetId.SUS_PROC_SET))
)
elif op_code in OpCodes.ENABLE_PROC_SUS_HK:
interval = float(input("Please specify interval in floating point seconds: "))
q.add_log_cmd(Info.ENABLE_PROC_SUS_HK)
cmd_tuple = enable_periodic_hk_command_with_interval(
False, make_sid(ACS_CONTROLLER, SetId.SUS_PROC_SET), interval
)
q.add_pus_tc(cmd_tuple[0])
q.add_pus_tc(cmd_tuple[1])
elif op_code in OpCodes.DISABLE_PROC_SUS_HK:
q.add_log_cmd(Info.DISABLE_PROC_SUS_HK)
q.add_pus_tc(
disable_periodic_hk_command(
False, make_sid(ACS_CONTROLLER, SetId.SUS_PROC_SET)
)
)
elif op_code in OpCodes.REQUEST_RAW_GYR_HK:
q.add_log_cmd(Info.REQUEST_RAW_GYR_HK)
q.add_pus_tc(
create_request_one_diag_command(make_sid(ACS_CONTROLLER, SetId.GYR_RAW_SET))
)
elif op_code in OpCodes.ENABLE_RAW_GYR_HK:
interval = float(input("Please specify interval in floating point seconds: "))
q.add_log_cmd(Info.ENABLE_RAW_GYR_HK)
cmd_tuple = enable_periodic_hk_command_with_interval(
True, make_sid(ACS_CONTROLLER, SetId.GYR_RAW_SET), interval
)
q.add_pus_tc(cmd_tuple[0])
q.add_pus_tc(cmd_tuple[1])
elif op_code in OpCodes.DISABLE_RAW_GYR_HK:
q.add_log_cmd(Info.DISABLE_RAW_GYR_HK)
q.add_pus_tc(
disable_periodic_hk_command(
True, make_sid(ACS_CONTROLLER, SetId.GYR_RAW_SET)
)
)
elif op_code in OpCodes.REQUEST_PROC_GYR_HK:
q.add_log_cmd(Info.REQUEST_PROC_GYR_HK)
q.add_pus_tc(
create_request_one_diag_command(
make_sid(ACS_CONTROLLER, SetId.GYR_PROC_SET)
)
)
elif op_code in OpCodes.ENABLE_PROC_GYR_HK:
interval = float(input("Please specify interval in floating point seconds: "))
q.add_log_cmd(Info.ENABLE_PROC_GYR_HK)
cmd_tuple = enable_periodic_hk_command_with_interval(
True, make_sid(ACS_CONTROLLER, SetId.GYR_PROC_SET), interval
)
q.add_pus_tc(cmd_tuple[0])
q.add_pus_tc(cmd_tuple[1])
elif op_code in OpCodes.DISABLE_PROC_GYR_HK:
q.add_log_cmd(Info.DISABLE_PROC_GYR_HK)
q.add_pus_tc(
disable_periodic_hk_command(
True, make_sid(ACS_CONTROLLER, SetId.GYR_PROC_SET)
)
)
elif op_code in OpCodes.REQUEST_PROC_GPS_HK:
q.add_log_cmd(Info.REQUEST_PROC_GPS_HK)
q.add_pus_tc(
generate_one_hk_command(make_sid(ACS_CONTROLLER, SetId.GPS_PROC_SET))
)
elif op_code in OpCodes.ENABLE_PROC_GPS_HK:
interval = float(input("Please specify interval in floating point seconds: "))
q.add_log_cmd(Info.ENABLE_PROC_GPS_HK)
cmd_tuple = enable_periodic_hk_command_with_interval(
False, make_sid(ACS_CONTROLLER, SetId.GPS_PROC_SET), interval
)
q.add_pus_tc(cmd_tuple[0])
q.add_pus_tc(cmd_tuple[1])
elif op_code in OpCodes.DISABLE_PROC_GPS_HK:
q.add_log_cmd(Info.DISABLE_PROC_GPS_HK)
q.add_pus_tc(
disable_periodic_hk_command(
False, make_sid(ACS_CONTROLLER, SetId.GPS_PROC_SET)
)
)
elif op_code in OpCodes.REQUEST_MEKF_HK:
q.add_log_cmd(Info.REQUEST_MEKF_HK)
q.add_pus_tc(
create_request_one_diag_command(make_sid(ACS_CONTROLLER, SetId.MEKF_DATA))
)
elif op_code in OpCodes.ENABLE_MEKF_HK:
interval = float(input("Please specify interval in floating point seconds: "))
q.add_log_cmd(Info.ENABLE_MEKF_HK)
cmd_tuple = enable_periodic_hk_command_with_interval(
True, make_sid(ACS_CONTROLLER, SetId.MEKF_DATA), interval
)
q.add_pus_tc(cmd_tuple[0])
q.add_pus_tc(cmd_tuple[1])
elif op_code in OpCodes.DISABLE_MEKF_HK:
q.add_log_cmd(Info.DISABLE_MEKF_HK)
q.add_pus_tc(
disable_periodic_hk_command(True, make_sid(ACS_CONTROLLER, SetId.MEKF_DATA))
)
elif op_code in OpCodes.REQUEST_CTRL_VAL_HK:
q.add_log_cmd(Info.REQUEST_CTRL_VAL_HK)
q.add_pus_tc(
generate_one_hk_command(make_sid(ACS_CONTROLLER, SetId.CTRL_VAL_DATA))
)
elif op_code in OpCodes.ENABLE_CTRL_VAL_HK:
interval = float(input("Please specify interval in floating point seconds: "))
q.add_log_cmd(Info.ENABLE_CTRL_VAL_HK)
cmd_tuple = enable_periodic_hk_command_with_interval(
False, make_sid(ACS_CONTROLLER, SetId.CTRL_VAL_DATA), interval
)
q.add_pus_tc(cmd_tuple[0])
q.add_pus_tc(cmd_tuple[1])
elif op_code in OpCodes.DISABLE_CTRL_VAL_HK:
q.add_log_cmd(Info.DISABLE_CTRL_VAL_HK)
q.add_pus_tc(
disable_periodic_hk_command(
False, make_sid(ACS_CONTROLLER, SetId.CTRL_VAL_DATA)
)
)
elif op_code in OpCodes.REQUEST_ACT_CMD_HK:
q.add_log_cmd(Info.REQUEST_ACT_CMD_HK)
q.add_pus_tc(
generate_one_hk_command(make_sid(ACS_CONTROLLER, SetId.ACTUATOR_CMD_DATA))
)
elif op_code in OpCodes.ENABLE_ACT_CMD_HK:
interval = float(input("Please specify interval in floating point seconds: "))
q.add_log_cmd(Info.ENABLE_ACT_CMD_HK)
cmd_tuple = enable_periodic_hk_command_with_interval(
False, make_sid(ACS_CONTROLLER, SetId.ACTUATOR_CMD_DATA), interval
)
q.add_pus_tc(cmd_tuple[0])
q.add_pus_tc(cmd_tuple[1])
elif op_code in OpCodes.DISABLE_ACT_CMD_HK:
q.add_log_cmd(Info.DISABLE_ACT_CMD_HK)
q.add_pus_tc(
disable_periodic_hk_command(
False, make_sid(ACS_CONTROLLER, SetId.ACTUATOR_CMD_DATA)
)
)
elif op_code in OpCodes.REQUEST_FUSED_ROT_RATE_HK:
q.add_log_cmd(Info.REQUEST_FUSED_ROT_RATE_HK)
q.add_pus_tc(
generate_one_hk_command(make_sid(ACS_CONTROLLER, SetId.FUSED_ROT_RATE_DATA))
)
elif op_code in OpCodes.ENABLE_FUSED_ROT_RATE_HK:
interval = float(input("Please specify interval in floating point seconds: "))
q.add_log_cmd(Info.ENABLE_FUSED_ROT_RATE_HK)
cmd_tuple = enable_periodic_hk_command_with_interval(
False, make_sid(ACS_CONTROLLER, SetId.FUSED_ROT_RATE_DATA), interval
)
q.add_pus_tc(cmd_tuple[0])
q.add_pus_tc(cmd_tuple[1])
elif op_code in OpCodes.DISABLE_FUSED_ROT_RATE_HK:
q.add_log_cmd(Info.DISABLE_FUSED_ROT_RATE_HK)
q.add_pus_tc(
disable_periodic_hk_command(
False, make_sid(ACS_CONTROLLER, SetId.FUSED_ROT_RATE_DATA)
)
)
elif cmd_str == OpCodes.ONE_SHOOT_HK:
q.add_log_cmd(Info.ONE_SHOOT_HK)
request_dataset(q, DataSetRequest.ONESHOT)
elif cmd_str == OpCodes.ENABLE_HK:
q.add_log_cmd(Info.ENABLE_HK)
request_dataset(q, DataSetRequest.ENABLE)
elif cmd_str == OpCodes.DISABLE_HK:
q.add_log_cmd(Info.DISABLE_HK)
request_dataset(q, DataSetRequest.DISABLE)
else:
logging.getLogger(__name__).info(f"Unknown op code {op_code}")
logging.getLogger(__name__).info(f"Unknown op code {cmd_str}")
def request_dataset(q: DefaultPusQueueHelper, req_type: DataSetRequest):
for val in SetId:
print("{:<2}: {:<20}".format(val, val.name))
set_id = int(input("Specify the dataset \n" ""))
if set_id in [
SetId.GYR_RAW_SET,
SetId.GPS_PROC_SET,
SetId.ATTITUDE_ESTIMATION_DATA,
]:
is_diag = True
else:
is_diag = False
match req_type:
case DataSetRequest.ONESHOT:
if is_diag:
q.add_pus_tc(
create_request_one_diag_command(make_sid(ACS_CONTROLLER, set_id))
)
else:
q.add_pus_tc(
create_request_one_hk_command(make_sid(ACS_CONTROLLER, set_id))
)
case DataSetRequest.ENABLE:
interval = float(
input("Please specify interval in floating point seconds: ")
)
if is_diag:
cmd_tuple = enable_periodic_hk_command_with_interval(
True, make_sid(ACS_CONTROLLER, set_id), interval
)
else:
cmd_tuple = enable_periodic_hk_command_with_interval(
False, make_sid(ACS_CONTROLLER, set_id), interval
)
q.add_pus_tc(cmd_tuple[0])
q.add_pus_tc(cmd_tuple[1])
case DataSetRequest.DISABLE:
if is_diag:
q.add_pus_tc(
disable_periodic_hk_command(True, make_sid(ACS_CONTROLLER, set_id))
)
else:
q.add_pus_tc(
disable_periodic_hk_command(False, make_sid(ACS_CONTROLLER, set_id))
)
def set_acs_ctrl_param_scalar(q: DefaultPusQueueHelper):
@ -659,7 +414,7 @@ def set_acs_ctrl_param_vector(q: DefaultPusQueueHelper):
domain_id=sid,
unique_id=pid,
parameters=param,
).pack()
)
)
)
else:
@ -771,14 +526,16 @@ def handle_acs_ctrl_hk_data(
handle_gyr_data_processed(pw, hk_data)
case SetId.GPS_PROC_SET:
handle_gps_data_processed(pw, hk_data)
case SetId.MEKF_DATA:
handle_mekf_data(pw, hk_data)
case SetId.ATTITUDE_ESTIMATION_DATA:
handle_attitude_estimation_data(pw, hk_data)
case SetId.CTRL_VAL_DATA:
handle_ctrl_val_data(pw, hk_data)
case SetId.ACTUATOR_CMD_DATA:
handle_act_cmd_data(pw, hk_data)
case SetId.FUSED_ROT_RATE_DATA:
handle_fused_rot_rate_data(pw, hk_data)
case SetId.FUSED_ROT_RATE_SOURCE_DATA:
handle_fused_rot_rate_source_data(pw, hk_data)
def handle_acs_ctrl_sus_raw_data(pw: PrintWrapper, hk_data: bytes):
@ -800,7 +557,7 @@ def handle_acs_ctrl_sus_raw_data(pw: PrintWrapper, hk_data: bytes):
sus_list_formatted = vec_fmt.format(*sus_list)
current_idx += length
pw.dlog(f"SUS {idx} RAW: {sus_list_formatted}")
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=12)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=12))
def handle_acs_ctrl_sus_processed_data(pw: PrintWrapper, hk_data: bytes):
@ -836,7 +593,7 @@ def handle_acs_ctrl_sus_processed_data(pw: PrintWrapper, hk_data: bytes):
sun_ijk_model = vec_fmt.format(*sun_ijk_model)
current_idx += inc_len
pw.dlog(f"{'SUS ijk Model'.ljust(25)}: {sun_ijk_model}")
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=15)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=15))
def handle_raw_mgm_data(pw: PrintWrapper, hk_data: bytes):
@ -850,7 +607,7 @@ def handle_raw_mgm_data(pw: PrintWrapper, hk_data: bytes):
pw.dlog(f"Raw Data: {hk_data.hex(sep=',')}")
return
def unpack_float_tuple(idx: int) -> (tuple, int):
def unpack_float_tuple(idx: int) -> Tuple[tuple, int]:
f_tuple = struct.unpack(
float_tuple_fmt_str,
hk_data[idx : idx + struct.calcsize(float_tuple_fmt_str)],
@ -892,7 +649,7 @@ def handle_raw_mgm_data(pw: PrintWrapper, hk_data: bytes):
pw.dlog(f"{entry[0].ljust(28)}: {entry[1]}")
current_idx += 1
assert current_idx == 61
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=6)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=6))
def handle_mgm_data_processed(pw: PrintWrapper, hk_data: bytes):
@ -946,7 +703,7 @@ def handle_mgm_data_processed(pw: PrintWrapper, hk_data: bytes):
current_idx += inc_len
if PERFORM_MGM_CALIBRATION:
perform_mgm_calibration(pw, mgm_3)
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=8)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=8))
def handle_gyr_data_raw(pw: PrintWrapper, hk_data: bytes):
@ -980,7 +737,7 @@ def handle_gyr_data_raw(pw: PrintWrapper, hk_data: bytes):
pw.dlog(f"{'GYR 1 L3'.ljust(15)}: {float_str_fmt.format(*gyr_1_l3)}")
pw.dlog(f"{'GYR 2 ADIS'.ljust(15)}: {float_str_fmt.format(*gyr_2_adis)}")
pw.dlog(f"{'GYR 3 L3'.ljust(15)}: {float_str_fmt.format(*gyr_3_l3)}")
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], 4)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], 4))
GYR_NAMES = ["GYR 0 ADIS", "GYR 1 L3", "GYR 2 ADIS", "GYR 3 L3"]
@ -1006,7 +763,7 @@ def handle_gyr_data_processed(pw: PrintWrapper, hk_data: bytes):
]
pw.dlog(f"GYR Vec Total: {gyr_vec_tot}")
current_idx += inc_len
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=5)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=5))
def handle_gps_data_processed(pw: PrintWrapper, hk_data: bytes):
@ -1060,8 +817,8 @@ def handle_gps_data_processed(pw: PrintWrapper, hk_data: bytes):
fmt_source, hk_data[current_idx : current_idx + inc_len_source]
)[0]
current_idx += inc_len_source
if GPS_COURCE_DICT.get(source) is not None:
pw.dlog(f"GPS Source: {GPS_COURCE_DICT[source]}")
if GPS_SOURCE_DICT.get(source) is not None:
pw.dlog(f"GPS Source: {GPS_SOURCE_DICT[source]}")
else:
pw.dlog(f"'GPS Source (key unknown)': {source}")
pw.dlog(f"GPS Latitude: {lat} [deg]")
@ -1069,10 +826,10 @@ def handle_gps_data_processed(pw: PrintWrapper, hk_data: bytes):
pw.dlog(f"GPS Altitude: {alt} [m]")
pw.dlog(f"GPS Position: {pos} [m]")
pw.dlog(f"GPS Velocity: {velo} [m/s]")
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=6)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=6))
def handle_mekf_data(pw: PrintWrapper, hk_data: bytes):
def handle_attitude_estimation_data(pw: PrintWrapper, hk_data: bytes):
mekf_status = {
0: "UNINITIALIZED",
1: "NO_GYR_DATA",
@ -1083,7 +840,7 @@ def handle_mekf_data(pw: PrintWrapper, hk_data: bytes):
10: "INITIALIZED",
11: "RUNNING",
}
pw.dlog("Received MEKF Set")
pw.dlog("Received Attitude Estimation Set")
fmt_quat = "!dddd"
fmt_str_4 = "[{:8.3f}, {:8.3f}, {:8.3f}, {:8.3f}]"
fmt_str_3 = "[{:8.3f}, {:8.3f}, {:8.3f}]"
@ -1092,11 +849,16 @@ def handle_mekf_data(pw: PrintWrapper, hk_data: bytes):
inc_len_quat = struct.calcsize(fmt_quat)
inc_len_vec = struct.calcsize(fmt_vec)
inc_len_sts = struct.calcsize(fmt_sts)
if len(hk_data) < inc_len_quat + inc_len_vec + inc_len_sts:
pw.dlog("Received HK set too small")
old_size = inc_len_quat + inc_len_vec + inc_len_sts + 1
new_size = 2 * inc_len_quat + inc_len_vec + inc_len_sts + 1
size = len(hk_data)
if size not in [old_size, new_size]:
pw.dlog(f"Received Attitude Estimation HK Set of unexpected size: {size}")
return
current_idx = 0
quat = struct.unpack(fmt_quat, hk_data[current_idx : current_idx + inc_len_quat])
mekf_quat = struct.unpack(
fmt_quat, hk_data[current_idx : current_idx + inc_len_quat]
)
current_idx += inc_len_quat
rates = [
rate * 180 / math.pi
@ -1111,9 +873,17 @@ def handle_mekf_data(pw: PrintWrapper, hk_data: bytes):
pw.dlog(f"{'MEKF Status'.ljust(25)}: {mekf_status[status]}")
else:
pw.dlog(f"{'MEKF Raw Status (key unknown)'.ljust(25)}: {status}")
pw.dlog(f"{'MEKF Quaternion'.ljust(25)}: {fmt_str_4.format(*quat)}")
pw.dlog(f"{'MEKF Quaternion'.ljust(25)}: {fmt_str_4.format(*mekf_quat)}")
pw.dlog(f"{'MEKF Rotational Rate'.ljust(25)}: {fmt_str_3.format(*rates)}")
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=3)
if size == new_size:
quest_quat = struct.unpack(
fmt_quat, hk_data[current_idx : current_idx + inc_len_quat]
)
current_idx += inc_len_quat
pw.dlog(f"{'QUEST Quaternion'.ljust(25)}: {fmt_str_4.format(*quest_quat)}")
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=4))
return
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=3))
def handle_ctrl_val_data(pw: PrintWrapper, hk_data: bytes):
@ -1163,14 +933,14 @@ def handle_ctrl_val_data(pw: PrintWrapper, hk_data: bytes):
]
current_idx += inc_len_vec
if CTRL_STRAT_DICT.get(strat) is not None:
pw.dlog(f"{'Safe Ctrl Strategy'.ljust(25)}: {CTRL_STRAT_DICT[strat]}")
pw.dlog(f"{'Ctrl Strategy'.ljust(25)}: {CTRL_STRAT_DICT[strat]}")
else:
pw.dlog(f"{'Safe Ctrl Strategy (key unknown)'.ljust(25)}: {strat}")
pw.dlog(f"{'Ctrl Strategy (key unknown)'.ljust(25)}: {strat}")
pw.dlog(f"Control Values Target Quaternion: {tgt_quat}")
pw.dlog(f"Control Values Error Quaternion: {err_quat}")
pw.dlog(f"Control Values Error Angle: {err_ang} [deg]")
pw.dlog(f"Control Values Target Rotational Rate: {tgt_rot} [deg/s]")
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=5)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=5))
def handle_act_cmd_data(pw: PrintWrapper, hk_data: bytes):
@ -1209,15 +979,20 @@ def handle_act_cmd_data(pw: PrintWrapper, hk_data: bytes):
pw.dlog(f"Actuator Commands RW Target Torque: {rw_tgt_torque}")
pw.dlog(f"Actuator Commands RW Target Speed: {rw_tgt_speed}")
pw.dlog(f"Actuator Commands MTQ Target Dipole: {mtq_tgt_dipole}")
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=3)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=3))
def handle_fused_rot_rate_data(pw: PrintWrapper, hk_data: bytes):
pw.dlog("Received Fused Rotation Rates Data Set")
fmt_vec3_double = "!ddd"
inc_len_vec3_double = struct.calcsize(fmt_vec3_double)
if len(hk_data) < 3 * inc_len_vec3_double:
pw.dlog("Received HK set too small")
fmt_source = "!B"
inc_len_source = struct.calcsize(fmt_source)
old_size = 3 * inc_len_vec3_double + 1
new_size = 3 * inc_len_vec3_double + inc_len_source + 1
size = len(hk_data)
if size not in [old_size, new_size]:
pw.dlog(f"Received Fused Rot Rate HK set of unexpected size: {len(hk_data)}")
return
current_idx = 0
rot_rate_orthogonal = [
@ -1244,13 +1019,100 @@ def handle_fused_rot_rate_data(pw: PrintWrapper, hk_data: bytes):
pw.dlog(f"Fused Rotational Rate Orthogonal: {rot_rate_orthogonal} [deg/s]")
pw.dlog(f"Fused Rotational Rate Parallel: {rot_rate_parallel} [deg/s]")
pw.dlog(f"Fused Rotational Rate Total: {rot_rate_total} [deg/s]")
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=3)
if size == new_size:
rot_rate_source = struct.unpack(
fmt_source, hk_data[current_idx : current_idx + inc_len_source]
)[0]
current_idx += inc_len_source
if FUSED_ROT_RATE_SOURCE_DICT.get(rot_rate_source) is not None:
pw.dlog(
f"Fused Rotational Rate Source: {FUSED_ROT_RATE_SOURCE_DICT[rot_rate_source]}"
)
else:
pw.dlog(f"Ctrl Strategy (key unknown): {rot_rate_source}")
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=4))
return
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=3))
def handle_fused_rot_rate_source_data(pw: PrintWrapper, hk_data: bytes):
pw.dlog("Received Fused Rotation Rates Sources Data Set")
fmt_vec3_double = "!ddd"
inc_len_vec3_double = struct.calcsize(fmt_vec3_double)
if len(hk_data) < 5 * inc_len_vec3_double:
pw.dlog("Received HK set too small")
return
current_idx = 0
rot_rate_orthogonal_susmgm = [
f"{val*180/math.pi:8.3f}"
for val in struct.unpack(
fmt_vec3_double, hk_data[current_idx : current_idx + inc_len_vec3_double]
)
]
current_idx += inc_len_vec3_double
rot_rate_parallel_susmgm = [
f"{val*180/math.pi:8.3f}"
for val in struct.unpack(
fmt_vec3_double, hk_data[current_idx : current_idx + inc_len_vec3_double]
)
]
current_idx += inc_len_vec3_double
rot_rate_total_susmgm = [
f"{val*180/math.pi:8.3f}"
for val in struct.unpack(
fmt_vec3_double, hk_data[current_idx : current_idx + inc_len_vec3_double]
)
]
current_idx += inc_len_vec3_double
rot_rate_total_quest = [
f"{val * 180 / math.pi:8.3f}"
for val in struct.unpack(
fmt_vec3_double, hk_data[current_idx : current_idx + inc_len_vec3_double]
)
]
current_idx += inc_len_vec3_double
rot_rate_total_str = [
f"{val * 180 / math.pi:8.3f}"
for val in struct.unpack(
fmt_vec3_double, hk_data[current_idx : current_idx + inc_len_vec3_double]
)
]
current_idx += inc_len_vec3_double
pw.dlog(
f"Fused Rotational Rate Orthogonal SUSMGM: {rot_rate_orthogonal_susmgm} [deg/s]"
)
pw.dlog(
f"Fused Rotational Rate Parallel SUSMGM: {rot_rate_parallel_susmgm} [deg/s]"
)
pw.dlog(f"Fused Rotational Rate Total SUSMGM: {rot_rate_total_susmgm} [deg/s]")
pw.dlog(f"Fused Rotational Rate Total QUEST: {rot_rate_total_quest} [deg/s]")
pw.dlog(f"Fused Rotational Rate Total STR: {rot_rate_total_str} [deg/s]")
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=5))
def handle_acs_ctrl_action_replies(
action_id: int, pw: PrintWrapper, custom_data: bytes
):
if action_id == ActionId.READ_TLE:
handle_read_tle(pw, custom_data)
def handle_read_tle(pw: PrintWrapper, custom_data: bytes):
pw.dlog("Received TLE")
data_length = 69 * 2
if len(custom_data) != data_length:
raise ValueError(f"Received data of unexpected length {len(custom_data)}")
tle = custom_data.decode()
pw.dlog(f"{tle[0:69]}\n{tle[69:69*2]}")
def perform_mgm_calibration( # noqa C901: Complexity okay
pw: PrintWrapper, mgm_tuple: Tuple
): # noqa C901: Complexity okay
global CALIBR_SOCKET, CALIBRATION_ADDR
if not PERFORM_MGM_CALIBRATION:
return
assert CALIBR_SOCKET is not None
try:
declare_api_cmd = "declare_api_version 2"
CALIBR_SOCKET.sendall(f"{declare_api_cmd}\n".encode())

View File

@ -3,10 +3,8 @@ import enum
import logging
import struct
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.pus_tm.defs import PrintWrapper
from tmtccmd.config import TmtcDefinitionWrapper, OpCodeEntry
from tmtccmd.config.tmtc import tmtc_definitions_provider
from tmtccmd.config import CmdTreeNode
from tmtccmd.pus.s200_fsfw_mode import create_mode_command, Mode
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.tc.s3_fsfw_hk import (
@ -15,7 +13,8 @@ from tmtccmd.pus.tc.s3_fsfw_hk import (
create_enable_periodic_hk_command_with_interval_with_diag,
create_disable_periodic_hk_command_with_diag,
)
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.pus.tc.s8_fsfw_action import create_action_cmd
from tmtccmd.fsfw.tmtc_printer import get_validity_buffer_str
_LOGGER = logging.getLogger(__name__)
@ -24,16 +23,25 @@ class GpsInfo:
MAX_SATELLITES = 30
class ActIds:
RESET_GNSS = 5
class AcsBoardSides(enum.IntEnum):
A_SIDE = 0
B_SIDE = 1
class OpCode:
OFF = "off"
ON = "on"
REQ_CORE_HK = ["core_hk_request"]
ENABLE_CORE_HK = ["core_hk_enable"]
DISABLE_CORE_HK = ["core_hk_disable"]
REQ_SKYVIEW_HK = ["skyview_hk_request"]
ENABLE_SKYVIEW_HK = ["skyview_hk_enable"]
DISABLE_SKYVIEW_HK = ["skyview_hk_disable"]
RESET_GNSS = ["reset"]
REQ_CORE_HK = "core_hk_request"
ENABLE_CORE_HK = "core_hk_enable"
DISABLE_CORE_HK = "core_hk_disable"
REQ_SKYVIEW_HK = "skyview_hk_request"
ENABLE_SKYVIEW_HK = "skyview_hk_enable"
DISABLE_SKYVIEW_HK = "skyview_hk_disable"
RESET_GNSS = "reset_gnss"
class Info:
@ -53,32 +61,34 @@ class SetId(enum.IntEnum):
SKYVIEW_HK = 1
@tmtc_definitions_provider
def add_gps_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(keys=OpCode.OFF, info=Info.OFF)
oce.add(keys=OpCode.ON, info=Info.ON)
oce.add(keys=OpCode.RESET_GNSS, info=Info.RESET_GNSS)
oce.add(keys=OpCode.REQ_CORE_HK, info=Info.REQ_CORE_HK)
oce.add(keys=OpCode.ENABLE_CORE_HK, info=Info.ENABLE_CORE_HK)
oce.add(keys=OpCode.DISABLE_CORE_HK, info=Info.DISABLE_CORE_HK)
oce.add(keys=OpCode.REQ_SKYVIEW_HK, info=Info.REQ_SKYVIEW_HK)
oce.add(keys=OpCode.ENABLE_SKYVIEW_HK, info=Info.ENABLE_SKYVIEW_HK)
oce.add(keys=OpCode.DISABLE_SKYVIEW_HK, info=Info.DISABLE_SKYVIEW_HK)
defs.add_service(
name=CustomServiceList.GPS_CTRL.value,
info="GPS/GNSS Controller",
op_code_entry=oce,
)
def create_gnss_node() -> CmdTreeNode:
op_code_strs = [
getattr(OpCode, key) for key in dir(OpCode) if not key.startswith("__")
]
info_strs = [getattr(Info, key) for key in dir(OpCode) if not key.startswith("__")]
combined_dict = dict(zip(op_code_strs, info_strs))
node = CmdTreeNode("gnss_ctrl", "GNSS Ctrl", hide_children_for_print=True)
for op_code, info in combined_dict.items():
node.add_child(CmdTreeNode(op_code, info))
return node
def pack_gps_command( # noqa: C901
object_id: bytes, q: DefaultPusQueueHelper, op_code: str
object_id: bytes, q: DefaultPusQueueHelper, cmd_str: str
): # noqa: C901:
if op_code in OpCode.RESET_GNSS:
# TODO: This needs to be re-implemented
_LOGGER.warning("Reset pin handling needs to be re-implemented")
if op_code in OpCode.ENABLE_CORE_HK:
if cmd_str == OpCode.RESET_GNSS:
for val in AcsBoardSides:
print("{:<2}: {:<20}".format(val, val.name))
board_side = int(input("Select Board Side \n" ""))
q.add_log_cmd(f"GPS: {Info.RESET_GNSS}")
q.add_pus_tc(
create_action_cmd(
object_id=object_id,
action_id=ActIds.RESET_GNSS,
user_data=bytearray([board_side]),
)
)
if cmd_str == OpCode.ENABLE_CORE_HK:
interval = float(input("Please specify interval in floating point seconds: "))
if interval <= 0:
raise ValueError("invalid interval")
@ -90,21 +100,21 @@ def pack_gps_command( # noqa: C901
)
for cmd in cmds:
q.add_pus_tc(cmd)
if op_code in OpCode.DISABLE_CORE_HK:
if cmd_str == OpCode.DISABLE_CORE_HK:
q.add_log_cmd(f"gps: {Info.DISABLE_CORE_HK}")
q.add_pus_tc(
create_disable_periodic_hk_command_with_diag(
diag=False, sid=make_sid(object_id=object_id, set_id=SetId.CORE_HK)
)
)
if op_code in OpCode.REQ_CORE_HK:
if cmd_str == OpCode.REQ_CORE_HK:
q.add_log_cmd(f"GPS: {Info.REQ_CORE_HK}")
q.add_pus_tc(
create_request_one_hk_command(
sid=make_sid(object_id=object_id, set_id=SetId.CORE_HK)
)
)
if op_code in OpCode.ENABLE_SKYVIEW_HK:
if cmd_str == OpCode.ENABLE_SKYVIEW_HK:
interval = float(input("Please specify interval in floating point seconds: "))
if interval <= 0:
raise ValueError("invalid interval")
@ -116,24 +126,24 @@ def pack_gps_command( # noqa: C901
)
for cmd in cmds:
q.add_pus_tc(cmd)
if op_code in OpCode.DISABLE_SKYVIEW_HK:
if cmd_str == OpCode.DISABLE_SKYVIEW_HK:
q.add_log_cmd(f"gps: {Info.DISABLE_SKYVIEW_HK}")
q.add_pus_tc(
create_disable_periodic_hk_command_with_diag(
diag=False, sid=make_sid(object_id=object_id, set_id=SetId.SKYVIEW_HK)
)
)
if op_code in OpCode.REQ_SKYVIEW_HK:
if cmd_str == OpCode.REQ_SKYVIEW_HK:
q.add_log_cmd(f"GPS: {Info.REQ_SKYVIEW_HK}")
q.add_pus_tc(
create_request_one_hk_command(
sid=make_sid(object_id=object_id, set_id=SetId.SKYVIEW_HK)
)
)
if op_code in OpCode.ON:
if cmd_str == OpCode.ON:
q.add_log_cmd(f"GPS: {Info.ON}")
q.add_pus_tc(create_mode_command(object_id, Mode.ON, 0))
if op_code in OpCode.OFF:
if cmd_str == OpCode.OFF:
q.add_log_cmd(f"GPS: {Info.OFF}")
q.add_pus_tc(create_mode_command(object_id, Mode.OFF, 0))
@ -193,9 +203,7 @@ def handle_core_data(pw: PrintWrapper, hk_data: bytes):
)
pw.dlog(f"GNSS Date: {date_string}")
pw.dlog(f"Unix seconds {unix_seconds}")
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=hk_data[current_idx:], num_vars=14
)
pw.dlog(get_validity_buffer_str(validity_buffer=hk_data[current_idx:], num_vars=14))
def handle_skyview_data(pw: PrintWrapper, hk_data: bytes):
@ -255,6 +263,4 @@ def handle_skyview_data(pw: PrintWrapper, hk_data: bytes):
used[idx],
)
)
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=hk_data[current_idx:], num_vars=6
)
pw.dlog(get_validity_buffer_str(validity_buffer=hk_data[current_idx:], num_vars=6))

View File

@ -3,6 +3,7 @@ import logging
import struct
from spacepackets.ecss import PusTelecommand
from tmtccmd.config import CmdTreeNode
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s201_fsfw_health import pack_set_health_cmd_data, FsfwHealth
from tmtccmd.pus.s201_fsfw_health import Subservice
@ -59,7 +60,7 @@ GYR_SEL_DICT = {
}
def handle_gyr_cmd(q: DefaultPusQueueHelper, op_code: str):
def handle_gyr_cmd(q: DefaultPusQueueHelper, cmd_str: str):
print("Please select the Gyro Device")
for k, v in GYR_SEL_DICT.items():
print(f"{k}: {v[0]}")
@ -72,23 +73,23 @@ def handle_gyr_cmd(q: DefaultPusQueueHelper, op_code: str):
core_hk_id = AdisGyroSetId.CORE_HK
else:
core_hk_id = L3gGyroSetId.CORE_HK
if op_code == OpCode.NML:
if cmd_str == OpCode.NML:
q.add_log_cmd(f"Gyro {gyr_info[0]} NORMAL mode")
q.add_pus_tc(create_mode_command(gyr_obj_id, Mode.NORMAL, 0))
if op_code == OpCode.OFF:
if cmd_str == OpCode.OFF:
q.add_log_cmd(f"Gyro {gyr_info[0]} OFF mode")
q.add_pus_tc(create_mode_command(gyr_obj_id, Mode.OFF, 0))
elif op_code == OpCode.CORE_HK:
elif cmd_str == OpCode.CORE_HK:
q.add_log_cmd(f"Gyro {gyr_info[0]} Core HK")
q.add_pus_tc(create_request_one_hk_command(make_sid(gyr_obj_id, core_hk_id)))
elif op_code == OpCode.CFG_HK:
elif cmd_str == OpCode.CFG_HK:
if not is_adis:
raise ValueError("No config HK for L3 device")
q.add_log_cmd(f"Gyro {gyr_info[0]} CFG HK")
q.add_pus_tc(
create_request_one_hk_command(make_sid(gyr_obj_id, AdisGyroSetId.CFG_HK))
)
elif op_code == OpCode.SET_FAULTY:
elif cmd_str == OpCode.SET_FAULTY:
q.add_log_cmd(f"Gyro {gyr_info[0]} set faulty")
q.add_pus_tc(
PusTelecommand(
@ -101,7 +102,7 @@ def handle_gyr_cmd(q: DefaultPusQueueHelper, op_code: str):
)
else:
logging.getLogger(__name__).warning(
f"invalid op code {op_code} for gyro command"
f"invalid op code {cmd_str} for gyro command"
)
@ -177,6 +178,16 @@ def handle_l3g_gyro_hk(
pw.dlog(f"Temperature {temp} °C")
def create_gyros_node() -> CmdTreeNode:
node = CmdTreeNode("gyros", "Gyroscope devices")
node.add_child(CmdTreeNode(OpCode.CORE_HK, "Request Core HK"))
node.add_child(CmdTreeNode(OpCode.CFG_HK, "Request CFG HK"))
node.add_child(CmdTreeNode(OpCode.NML, "Normal Mode"))
node.add_child(CmdTreeNode(OpCode.OFF, "Off Mode"))
node.add_child(CmdTreeNode(OpCode.SET_FAULTY, "Set Faulty"))
return node
@tmtc_definitions_provider
def add_gyr_cmd_defs(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()

View File

@ -10,6 +10,8 @@ import logging
import struct
from typing import List
from tmtccmd.config import CmdTreeNode
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.pus_tm.defs import PrintWrapper
from spacepackets.ecss.tc import PusTelecommand
@ -29,7 +31,7 @@ from tmtccmd.pus.tc.s3_fsfw_hk import (
)
from tmtccmd.pus.s200_fsfw_mode import pack_mode_data, Mode
from tmtccmd.util import ObjectIdU32
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.fsfw.tmtc_printer import get_validity_buffer_str
_LOGGER = logging.getLogger(__name__)
@ -91,6 +93,74 @@ class ImtqActionId:
read_self_test_results = bytearray([0x0, 0x0, 0x0, 0x0D])
CTN = CmdTreeNode
def create_mgt_node() -> CmdTreeNode:
node = CmdTreeNode(
"mgt", "iMTQ MGT device node", hide_children_which_are_leaves=True
)
node.add_child(CmdTreeNode(OpCode.OFF, "Mode OFF"))
node.add_child(CmdTreeNode(OpCode.ON, "Mode ON"))
node.add_child(CmdTreeNode(OpCode.NORMAL, "Mode Normal"))
node.add_child(CmdTreeNode(OpCode.OFF, "Mode OFF"))
node.add_child(
CmdTreeNode(OpCode.REQUEST_ENG_HK_NO_TORQUE, "Request Engineering HK One Shot")
)
node.add_child(
CmdTreeNode(
OpCode.REQUEST_ENG_HK_WITH_TORQUE,
"Request Engineering HK One Shot during Torque",
)
)
node.add_child(
CmdTreeNode(OpCode.ENABLE_ENG_HK_NO_TORQUE, "Enable ENG HK not torque")
)
node.add_child(
CmdTreeNode(OpCode.ENABLE_ENG_HK_WITH_TORQUE, "Enable ENG HK with torque")
)
node.add_child(
CmdTreeNode(OpCode.DISABLE_ENG_HK_NO_TORQUE, "Disable ENG HK not torque")
)
node.add_child(
CmdTreeNode(OpCode.DISABLE_ENG_HK_WITH_TORQUE, "Disable ENG HK with torque")
)
node.add_child(
CmdTreeNode(
OpCode.REQUEST_MGM_RAW_NO_TORQUE,
"Request MGM Raw Without Torque HK One Shot",
)
)
node.add_child(
CmdTreeNode(OpCode.ENABLE_MGM_RAW_NO_TORQUE, "Enable MGM Raw Without Torque HK")
)
node.add_child(
CmdTreeNode(
OpCode.DISABLE_MGM_RAW_NO_TORQUE, "Disable MGM Raw Without Torque HK"
)
)
node.add_child(
CmdTreeNode(
OpCode.REQUEST_MGM_RAW_WITH_TORQUE,
"Request MGM Raw With Torque HK One Shot",
)
)
node.add_child(
CmdTreeNode(OpCode.ENABLE_MGM_RAW_WITH_TORQUE, "Enable MGM Raw With Torque HK")
)
node.add_child(
CTN(OpCode.DISABLE_MGM_RAW_WITH_TORQUE, "Disable MGM Raw With Torque HK")
)
node.add_child(CTN(OpCode.POS_X_SELF_TEST, "IMTQ perform pos X self test"))
node.add_child(CTN(OpCode.NEG_X_SELF_TEST, "IMTQ perform neg X self test"))
node.add_child(CTN(OpCode.POS_Y_SELF_TEST, "IMTQ perform pos Y self test"))
node.add_child(CTN(OpCode.NEG_Y_SELF_TEST, "IMTQ perform neg Y self test"))
node.add_child(CTN(OpCode.POS_Z_SELF_TEST, "IMTQ perform pos Z self test"))
node.add_child(CTN(OpCode.NEG_Z_SELF_TEST, "IMTQ perform neg Z self test"))
node.add_child(CTN(OpCode.SET_DIPOLE, "IMTQ command dipole"))
return node
@tmtc_definitions_provider
def add_imtq_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
@ -128,26 +198,26 @@ def add_imtq_cmds(defs: TmtcDefinitionWrapper):
defs.add_service(CustomServiceList.IMTQ.value, "IMQT Device", oce)
def pack_imtq_test_into( # noqa C901
object_id: ObjectIdU32, q: DefaultPusQueueHelper, op_code: str
def create_imtq_command( # noqa C901
object_id: ObjectIdU32, q: DefaultPusQueueHelper, cmd_str: str
):
q.add_log_cmd(
f"Testing ISIS IMTQ handler with object id: {object_id.as_hex_string}"
)
if op_code == OpCode.OFF:
if cmd_str == OpCode.OFF:
q.add_log_cmd("IMTQ: Set mode off")
command = pack_mode_data(object_id.as_bytes, Mode.OFF, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=command))
if op_code == OpCode.ON:
if cmd_str == OpCode.ON:
q.add_log_cmd("IMTQ: Set mode on")
command = pack_mode_data(object_id.as_bytes, Mode.ON, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=command))
if op_code == OpCode.NORMAL:
if cmd_str == OpCode.NORMAL:
q.add_log_cmd("IMTQ: Mode Normal")
command = pack_mode_data(object_id.as_bytes, Mode.NORMAL, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=command))
if op_code == OpCode.POS_X_SELF_TEST:
if cmd_str == OpCode.POS_X_SELF_TEST:
q.add_log_cmd("IMTQ: Perform positive x self test")
command = object_id.as_bytes + ImtqActionId.perform_positive_x_test
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
@ -160,7 +230,7 @@ def pack_imtq_test_into( # noqa C901
sid = make_sid(object_id.as_bytes, ImtqSetId.POSITIVE_X_TEST)
q.add_pus_tc(generate_one_hk_command(sid))
if op_code == OpCode.NEG_X_SELF_TEST:
if cmd_str == OpCode.NEG_X_SELF_TEST:
q.add_log_cmd("IMTQ: Perform negative x self test")
command = object_id.as_bytes + ImtqActionId.perform_negative_x_test
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
@ -171,7 +241,7 @@ def pack_imtq_test_into( # noqa C901
sid = make_sid(object_id.as_bytes, ImtqSetId.NEGATIVE_X_TEST)
q.add_pus_tc(generate_one_hk_command(sid))
if op_code == OpCode.POS_Y_SELF_TEST:
if cmd_str == OpCode.POS_Y_SELF_TEST:
q.add_log_cmd("IMTQ: Perform positive y self test")
command = object_id.as_bytes + ImtqActionId.perform_positive_y_test
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
@ -183,7 +253,7 @@ def pack_imtq_test_into( # noqa C901
sid = make_sid(object_id.as_bytes, ImtqSetId.POSITIVE_Y_TEST)
q.add_pus_tc(generate_one_hk_command(sid))
if op_code == OpCode.NEG_Y_SELF_TEST:
if cmd_str == OpCode.NEG_Y_SELF_TEST:
q.add_log_cmd("IMTQ: Perform negative y self test")
command = object_id.as_bytes + ImtqActionId.perform_negative_y_test
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
@ -196,7 +266,7 @@ def pack_imtq_test_into( # noqa C901
sid = make_sid(object_id.as_bytes, ImtqSetId.NEGATIVE_Y_TEST)
q.add_pus_tc(generate_one_hk_command(sid))
if op_code == OpCode.POS_Z_SELF_TEST:
if cmd_str == OpCode.POS_Z_SELF_TEST:
q.add_log_cmd("IMTQ: Perform positive z self test")
command = object_id.as_bytes + ImtqActionId.perform_positive_z_test
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
@ -209,7 +279,7 @@ def pack_imtq_test_into( # noqa C901
sid = make_sid(object_id.as_bytes, ImtqSetId.POSITIVE_Y_TEST)
q.add_pus_tc(generate_one_hk_command(sid))
if op_code == OpCode.NEG_Z_SELF_TEST:
if cmd_str == OpCode.NEG_Z_SELF_TEST:
q.add_log_cmd("IMTQ: Perform negative z self test")
command = object_id.as_bytes + ImtqActionId.perform_negative_z_test
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
@ -220,7 +290,7 @@ def pack_imtq_test_into( # noqa C901
sid = make_sid(object_id.as_bytes, ImtqSetId.NEGATIVE_Z_TEST)
q.add_pus_tc(generate_one_hk_command(sid))
if op_code in OpCode.SET_DIPOLE:
if cmd_str in OpCode.SET_DIPOLE:
x_dipole = int(input("Specify X dipole [range [0, 2000] * 10^-4 * Am^2]: "))
y_dipole = int(input("Specify Y dipole [range [0, 2000] * 10^-4 * Am^2]: "))
z_dipole = int(input("Specify Z dipole [range [0, 2000] * 10^-4 * Am^2]: "))
@ -241,12 +311,12 @@ def pack_imtq_test_into( # noqa C901
)
)
if op_code == "10": # doesnt seem to work anymore
if cmd_str == "10": # doesnt seem to work anymore
q.add_log_cmd("IMTQ: Get commanded dipole")
command = object_id.as_bytes + ImtqActionId.get_commanded_dipole
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == OpCode.ENABLE_ENG_HK_NO_TORQUE:
if cmd_str == OpCode.ENABLE_ENG_HK_NO_TORQUE:
q.add_log_cmd("IMTQ: Enable ENG HK")
interval = float(input("Please enter collection interval in seconds: "))
cmds = create_enable_periodic_hk_command_with_interval_with_diag(
@ -256,14 +326,14 @@ def pack_imtq_test_into( # noqa C901
)
for cmd in cmds:
q.add_pus_tc(cmd)
if op_code == OpCode.DISABLE_ENG_HK_NO_TORQUE:
if cmd_str == OpCode.DISABLE_ENG_HK_NO_TORQUE:
q.add_log_cmd("IMTQ: Disable ENG HK (No Torque)")
q.add_pus_tc(
create_disable_periodic_hk_command_with_diag(
True, make_sid(object_id.as_bytes, ImtqSetId.ENG_HK_NO_TORQUE)
)
)
if op_code == OpCode.REQUEST_ENG_HK_WITH_TORQUE:
if cmd_str == OpCode.REQUEST_ENG_HK_WITH_TORQUE:
q.add_log_cmd("IMTQ: Get engineering hk set with torque")
q.add_pus_tc(
create_request_one_diag_command(
@ -273,7 +343,7 @@ def pack_imtq_test_into( # noqa C901
)
)
)
if op_code == OpCode.ENABLE_ENG_HK_WITH_TORQUE:
if cmd_str == OpCode.ENABLE_ENG_HK_WITH_TORQUE:
q.add_log_cmd("IMTQ: Enable ENG HK with torque")
interval = float(input("Please enter collection interval in seconds: "))
cmds = create_enable_periodic_hk_command_with_interval_with_diag(
@ -283,14 +353,14 @@ def pack_imtq_test_into( # noqa C901
)
for cmd in cmds:
q.add_pus_tc(cmd)
if op_code == OpCode.DISABLE_ENG_HK_WITH_TORQUE:
if cmd_str == OpCode.DISABLE_ENG_HK_WITH_TORQUE:
q.add_log_cmd("IMTQ: Disable ENG HK with Torque")
q.add_pus_tc(
create_disable_periodic_hk_command_with_diag(
True, make_sid(object_id.as_bytes, ImtqSetId.ENG_HK_SET_WITH_TORQUE)
)
)
if op_code == OpCode.REQUEST_ENG_HK_NO_TORQUE:
if cmd_str == OpCode.REQUEST_ENG_HK_NO_TORQUE:
q.add_log_cmd("IMTQ: Get engineering hk set (no torque)")
q.add_pus_tc(
generate_one_diag_command(
@ -300,7 +370,7 @@ def pack_imtq_test_into( # noqa C901
)
)
if op_code == "12":
if cmd_str == "12":
q.add_log_cmd("IMTQ: Get calibrated MTM hk set")
q.add_pus_tc(
create_request_one_diag_command(
@ -308,7 +378,7 @@ def pack_imtq_test_into( # noqa C901
)
)
if op_code == OpCode.REQUEST_MGM_RAW_NO_TORQUE:
if cmd_str == OpCode.REQUEST_MGM_RAW_NO_TORQUE:
q.add_log_cmd("IMTQ: Get raw MTM hk set")
q.add_pus_tc(
create_request_one_diag_command(
@ -318,14 +388,14 @@ def pack_imtq_test_into( # noqa C901
)
)
if op_code == OpCode.DISABLE_MGM_RAW_NO_TORQUE:
if cmd_str == OpCode.DISABLE_MGM_RAW_NO_TORQUE:
q.add_log_cmd("IMTQ: Disable MGM RAW HK (No Torque)")
q.add_pus_tc(
create_disable_periodic_hk_command_with_diag(
True, make_sid(object_id.as_bytes, ImtqSetId.RAW_MTM_NO_TORQUE)
)
)
if op_code == OpCode.ENABLE_MGM_RAW_NO_TORQUE:
if cmd_str == OpCode.ENABLE_MGM_RAW_NO_TORQUE:
q.add_log_cmd("IMTQ: Enable MGM RAW HK (No Torque)")
interval = float(input("Please enter collection interval in seconds: "))
cmds = create_enable_periodic_hk_command_with_interval_with_diag(
@ -335,7 +405,7 @@ def pack_imtq_test_into( # noqa C901
)
for cmd in cmds:
q.add_pus_tc(cmd)
if op_code == OpCode.REQUEST_MGM_RAW_WITH_TORQUE:
if cmd_str == OpCode.REQUEST_MGM_RAW_WITH_TORQUE:
q.add_log_cmd("IMTQ: Get raw MTM hk set")
q.add_pus_tc(
create_request_one_diag_command(
@ -344,7 +414,7 @@ def pack_imtq_test_into( # noqa C901
)
)
)
if op_code == OpCode.ENABLE_MGM_RAW_WITH_TORQUE:
if cmd_str == OpCode.ENABLE_MGM_RAW_WITH_TORQUE:
q.add_log_cmd("IMTQ: Enable MGM RAW HK (No Torque)")
interval = float(input("Please enter collection interval in seconds: "))
cmds = create_enable_periodic_hk_command_with_interval_with_diag(
@ -354,7 +424,7 @@ def pack_imtq_test_into( # noqa C901
)
for cmd in cmds:
q.add_pus_tc(cmd)
if op_code == OpCode.DISABLE_MGM_RAW_WITH_TORQUE:
if cmd_str == OpCode.DISABLE_MGM_RAW_WITH_TORQUE:
q.add_log_cmd("IMTQ: Disable MGM RAW HK (No Torque)")
q.add_pus_tc(
create_disable_periodic_hk_command_with_diag(
@ -473,7 +543,7 @@ def handle_dipole_set(pw: PrintWrapper, hk_data: bytes):
pw.dlog(f"Dipole Y: {dipole_y}")
pw.dlog(f"Dipole Z: {dipole_z}")
pw.dlog(f"Current torque duration: {current_torque_duration}")
FsfwTmTcPrinter.get_validity_buffer(hk_data[fmt_len:], 2)
pw.dlog(get_validity_buffer_str(hk_data[fmt_len:], 2))
def unpack_eng_hk(hk_data: bytes) -> List:
@ -513,9 +583,7 @@ def handle_eng_set(pw: PrintWrapper, hk_data: bytes, torque_on: bool):
for k, v in zip(ENG_HK_HEADERS, content_list):
pw.dlog(f"{k.ljust(30)}: {v}")
pw.dlog(
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=validity_buffer, num_vars=num_of_vars
)
get_validity_buffer_str(validity_buffer=validity_buffer, num_vars=num_of_vars)
)
@ -527,9 +595,7 @@ def handle_status_set(pw: PrintWrapper, hk_data: bytes):
for k, v in zip(STATUS_HEADERS, content_list):
pw.dlog(f"{k.ljust(30)}: {v}")
pw.dlog(
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=validity_buffer, num_vars=num_of_vars
)
get_validity_buffer_str(validity_buffer=validity_buffer, num_vars=num_of_vars)
)
@ -550,9 +616,7 @@ def handle_calibrated_mtm_measurement(pw: PrintWrapper, hk_data: bytes):
pw.dlog(str(header_list))
pw.dlog(str(content_list))
pw.dlog(
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=validity_buffer, num_vars=num_of_vars
)
get_validity_buffer_str(validity_buffer=validity_buffer, num_vars=num_of_vars)
)
@ -574,9 +638,7 @@ def handle_raw_mtm_measurement(pw: PrintWrapper, hk_data: bytes, torque_status:
pw.dlog(str(header_list))
pw.dlog(str(content_list))
pw.dlog(
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=validity_buffer, num_vars=num_of_vars
)
get_validity_buffer_str(validity_buffer=validity_buffer, num_vars=num_of_vars)
)
@ -713,7 +775,5 @@ def handle_self_test_data(pw: PrintWrapper, hk_data: bytes):
pw.dlog(str(header_list))
pw.dlog(str(content_list))
pw.dlog(
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=validity_buffer, num_vars=num_of_vars
)
get_validity_buffer_str(validity_buffer=validity_buffer, num_vars=num_of_vars)
)

View File

@ -2,7 +2,7 @@ import enum
import struct
from eive_tmtc.config.definitions import CustomServiceList
from tmtccmd.config import OpCodeEntry
from tmtccmd.config import CmdTreeNode, OpCodeEntry
import eive_tmtc.config.object_ids as obj_ids
from eive_tmtc.config.object_ids import (
@ -47,17 +47,17 @@ MGM_SEL_DICT = {
}
def handle_mgm_cmd(q: DefaultPusQueueHelper, op_code: str):
def handle_mgm_cmd(q: DefaultPusQueueHelper, cmd_str: str):
print("Please select the MGM Device")
for k, v in MGM_SEL_DICT.items():
print(f"{k}: {v[0]}")
sel_idx = int(input("Select MGM device by index: "))
mgm_info = MGM_SEL_DICT[MgmSel(sel_idx)]
mgm_obj_id = mgm_info[1]
if op_code == OpCode.NORMAL:
if cmd_str == OpCode.NORMAL:
q.add_log_cmd(f"Gyro {mgm_info[0]} NORMAL mode")
q.add_pus_tc(create_mode_command(mgm_obj_id, Mode.NORMAL, 0))
if op_code == OpCode.OFF:
if cmd_str == OpCode.OFF:
q.add_log_cmd(f"Gyro {mgm_info[0]} OFF mode")
q.add_pus_tc(create_mode_command(mgm_obj_id, Mode.OFF, 0))
@ -107,6 +107,13 @@ def handle_mgm_rm3100_hk_data(
)
def create_mgms_node() -> CmdTreeNode:
node = CmdTreeNode("mgms", "Magnetometer devices")
node.add_child(CmdTreeNode(OpCode.NORMAL, "Normal Mode"))
node.add_child(CmdTreeNode(OpCode.OFF, "Off Mode"))
return node
@tmtc_definitions_provider
def add_mgm_cmd_defs(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()

View File

@ -6,12 +6,11 @@
"""
import enum
import struct
from typing import List
from typing import List, Tuple
from eive_tmtc.pus_tm.defs import PrintWrapper
from eive_tmtc.config.object_ids import RW1_ID, RW2_ID, RW3_ID, RW4_ID
from tmtccmd.config import TmtcDefinitionWrapper, OpCodeEntry
from tmtccmd.config.tmtc import tmtc_definitions_provider
from tmtccmd.config import CmdTreeNode
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.tc.s3_fsfw_hk import (
generate_one_hk_command,
@ -23,9 +22,8 @@ from tmtccmd.pus.tc.s3_fsfw_hk import (
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.pus.s200_fsfw_mode import pack_mode_data, Mode, Subservice
from eive_tmtc.config.definitions import CustomServiceList
from tmtccmd.util import ObjectIdU32
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.fsfw.tmtc_printer import get_validity_buffer_str
class OpCodesDev:
@ -53,11 +51,11 @@ class InfoDev:
class OpCodesAss:
ON = ["0", "on"]
NML = ["1", "nml"]
OFF = ["2", "off"]
ALL_SPEED_UP = ["3", "speed_up"]
ALL_SPEED_OFF = ["4", "speed_off"]
ON = "on"
NML = "nml"
OFF = "off"
ALL_SPEED_UP = "speed_up"
ALL_SPEED_OFF = "speed_off"
class ActionId:
@ -99,55 +97,45 @@ class RampTime:
MS_1000 = 1000
@tmtc_definitions_provider
def add_rw_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(info=InfoDev.SPEED, keys=OpCodesDev.SPEED)
oce.add(info=InfoDev.ON, keys=OpCodesDev.ON)
oce.add(info=InfoDev.OFF, keys=OpCodesDev.OFF)
oce.add(info=InfoDev.NML, keys=OpCodesDev.NML)
oce.add(info=InfoDev.REQ_TM, keys=OpCodesDev.REQ_TM)
oce.add(info=InfoDev.GET_STATUS, keys=OpCodesDev.GET_STATUS)
oce.add(info=InfoDev.GET_TM, keys=OpCodesDev.GET_TM)
oce.add(info=InfoDev.ENABLE_STATUS_HK, keys=OpCodesDev.ENABLE_STATUS_HK)
oce.add(info=InfoDev.DISABLE_STATUS_HK, keys=OpCodesDev.DISABLE_STATUS_HK)
defs.add_service(
name=CustomServiceList.REACTION_WHEEL_1.value,
info="Reaction Wheel 1",
op_code_entry=oce,
)
defs.add_service(
name=CustomServiceList.REACTION_WHEEL_2.value,
info="Reaction Wheel 2",
op_code_entry=oce,
)
defs.add_service(
name=CustomServiceList.REACTION_WHEEL_3.value,
info="Reaction Wheel 3",
op_code_entry=oce,
)
defs.add_service(
name=CustomServiceList.REACTION_WHEEL_4.value,
info="Reaction Wheel 4",
op_code_entry=oce,
)
oce = OpCodeEntry()
oce.add(info=InfoAss.ON, keys=OpCodesAss.ON)
oce.add(info=InfoAss.NML, keys=OpCodesAss.NML)
oce.add(info=InfoAss.OFF, keys=OpCodesAss.OFF)
oce.add(info=InfoAss.ALL_SPEED_UP, keys=OpCodesAss.ALL_SPEED_UP)
oce.add(info=InfoAss.ALL_SPEED_OFF, keys=OpCodesAss.ALL_SPEED_OFF)
defs.add_service(
name=CustomServiceList.RW_ASSEMBLY.value,
info="Reaction Wheel Assembly",
op_code_entry=oce,
)
def create_reaction_wheels_nodes() -> List[CmdTreeNode]:
nodes = []
for i in range(4):
next_node = CmdTreeNode(
f"rw_{i}", f"Reaction Wheel {i}", hide_children_which_are_leaves=True
)
next_node.add_child(CmdTreeNode(InfoDev.SPEED, OpCodesDev.SPEED))
next_node.add_child(CmdTreeNode(InfoDev.ON, OpCodesDev.ON))
next_node.add_child(CmdTreeNode(InfoDev.OFF, OpCodesDev.OFF))
next_node.add_child(CmdTreeNode(InfoDev.NML, OpCodesDev.NML))
next_node.add_child(CmdTreeNode(InfoDev.REQ_TM, OpCodesDev.REQ_TM))
next_node.add_child(CmdTreeNode(InfoDev.GET_STATUS, OpCodesDev.GET_STATUS))
next_node.add_child(CmdTreeNode(InfoDev.GET_TM, OpCodesDev.GET_TM))
next_node.add_child(
CmdTreeNode(InfoDev.ENABLE_STATUS_HK, OpCodesDev.ENABLE_STATUS_HK)
)
next_node.add_child(
CmdTreeNode(InfoDev.DISABLE_STATUS_HK, OpCodesDev.DISABLE_STATUS_HK)
)
nodes.append(next_node)
return nodes
def pack_single_rw_test_into( # noqa C901: Complexity is okay here.
object_id: bytes, rw_idx: int, q: DefaultPusQueueHelper, op_code: str
def create_reaction_wheel_assembly_node() -> CmdTreeNode:
node = CmdTreeNode(
"rw_assy", "Reaction Wheels Assembly", hide_children_which_are_leaves=True
)
node.add_child(CmdTreeNode(OpCodesAss.ON, InfoAss.ON))
node.add_child(CmdTreeNode(OpCodesAss.NML, InfoAss.NML))
node.add_child(CmdTreeNode(OpCodesAss.OFF, InfoAss.OFF))
node.add_child(CmdTreeNode(OpCodesAss.ALL_SPEED_UP, InfoAss.ALL_SPEED_UP))
node.add_child(CmdTreeNode(OpCodesAss.ALL_SPEED_OFF, InfoAss.ALL_SPEED_OFF))
return node
def create_single_rw_cmd( # noqa C901: Complexity is okay here.
object_id: bytes, rw_idx: int, q: DefaultPusQueueHelper, cmd_str: str
):
if op_code == OpCodesDev.SPEED:
if cmd_str == OpCodesDev.SPEED:
speed, ramp_time = prompt_speed_ramp_time()
q.add_log_cmd(
f"RW {rw_idx}: {InfoDev.SPEED} with target "
@ -155,41 +143,41 @@ def pack_single_rw_test_into( # noqa C901: Complexity is okay here.
)
q.add_pus_tc(pack_set_speed_command(object_id, speed, ramp_time))
if op_code == OpCodesDev.ON:
if cmd_str == OpCodesDev.ON:
q.add_log_cmd(f"RW {rw_idx}: {InfoDev.ON}")
mode_data = pack_mode_data(object_id, Mode.ON, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=mode_data))
if op_code == OpCodesDev.NML:
if cmd_str == OpCodesDev.NML:
q.add_log_cmd(f"RW {rw_idx}: {InfoDev.NML}")
mode_data = pack_mode_data(object_id, Mode.NORMAL, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=mode_data))
if op_code == OpCodesDev.OFF:
if cmd_str == OpCodesDev.OFF:
q.add_log_cmd(f"RW {rw_idx}: {InfoDev.OFF}")
mode_data = pack_mode_data(object_id, Mode.OFF, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=mode_data))
if op_code == OpCodesDev.GET_TM:
if cmd_str == OpCodesDev.GET_TM:
q.add_log_cmd(f"RW {rw_idx}: {InfoDev.GET_TM}")
q.add_pus_tc(
generate_one_hk_command(
sid=make_sid(object_id=object_id, set_id=RwSetId.TM_SET)
)
)
if op_code == OpCodesDev.REQ_TM:
if cmd_str == OpCodesDev.REQ_TM:
q.add_log_cmd(f"RW {rw_idx}: {InfoDev.REQ_TM}")
q.add_pus_tc(
create_action_cmd(object_id=object_id, action_id=ActionId.REQUEST_TM)
)
if op_code in OpCodesDev.GET_STATUS:
if cmd_str == OpCodesDev.GET_STATUS:
q.add_log_cmd(f"RW {rw_idx}: {InfoDev.GET_STATUS}")
q.add_pus_tc(
generate_one_diag_command(
sid=make_sid(object_id=object_id, set_id=RwSetId.STATUS_SET_ID)
)
)
if op_code in OpCodesDev.ENABLE_STATUS_HK:
if cmd_str == OpCodesDev.ENABLE_STATUS_HK:
q.add_log_cmd(f"RW {rw_idx}: {InfoDev.ENABLE_STATUS_HK}")
interval = float(input("Please enter HK interval in floating point seconds: "))
cmds = enable_periodic_hk_command_with_interval(
@ -197,7 +185,7 @@ def pack_single_rw_test_into( # noqa C901: Complexity is okay here.
)
for cmd in cmds:
q.add_pus_tc(cmd)
if op_code in OpCodesDev.DISABLE_STATUS_HK:
if cmd_str == OpCodesDev.DISABLE_STATUS_HK:
q.add_log_cmd(f"RW {rw_idx}: {InfoDev.DISABLE_STATUS_HK}")
q.add_pus_tc(
disable_periodic_hk_command(
@ -206,38 +194,38 @@ def pack_single_rw_test_into( # noqa C901: Complexity is okay here.
)
def pack_rw_ass_cmds(q: DefaultPusQueueHelper, object_id: bytes, op_code: str):
if op_code in OpCodesAss.OFF:
def pack_rw_ass_cmds(q: DefaultPusQueueHelper, object_id: bytes, cmd_str: str):
if cmd_str in OpCodesAss.OFF:
data = pack_mode_data(object_id=object_id, mode=Mode.OFF, submode=0)
q.add_pus_tc(
PusTelecommand(
service=200, subservice=Subservice.TC_MODE_COMMAND, app_data=data
)
)
if op_code in OpCodesAss.ON:
if cmd_str in OpCodesAss.ON:
data = pack_mode_data(object_id=object_id, mode=Mode.ON, submode=0)
q.add_pus_tc(
PusTelecommand(
service=200, subservice=Subservice.TC_MODE_COMMAND, app_data=data
)
)
if op_code in OpCodesAss.NML:
if cmd_str in OpCodesAss.NML:
data = pack_mode_data(object_id=object_id, mode=Mode.NORMAL, submode=0)
q.add_pus_tc(
PusTelecommand(
service=200, subservice=Subservice.TC_MODE_COMMAND, app_data=data
)
)
if op_code in OpCodesAss.ALL_SPEED_UP:
if cmd_str in OpCodesAss.ALL_SPEED_UP:
speed, ramp_time = prompt_speed_ramp_time()
rw_speed_up_cmd_consec(q, [RW1_ID, RW2_ID, RW3_ID, RW4_ID], speed, ramp_time)
if op_code in OpCodesAss.ALL_SPEED_OFF:
if cmd_str in OpCodesAss.ALL_SPEED_OFF:
rw_speed_down_cmd_consec(
q, [RW1_ID, RW2_ID, RW3_ID, RW4_ID], prompt_ramp_time()
)
def prompt_speed_ramp_time() -> (int, int):
def prompt_speed_ramp_time() -> Tuple[int, int]:
speed = int(
input("Specify speed [0.1 RPM, 0 or range [-65000, -1000] and [1000, 65000]: ")
)
@ -313,7 +301,7 @@ def handle_rw_hk_data(
f"Current Limit Control mode {clc_mode}. 0: Low Current Mode (0.3 A), "
"1: High Current Mode (0.6 A)"
)
pw.dlog(FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], 5))
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], 5))
if set_id == RwSetId.LAST_RESET:
pw.dlog(
f"Received Last Reset HK (ID {set_id}) from Reaction Wheel {object_id.name}"
@ -402,7 +390,7 @@ def handle_rw_hk_data(
)
if current_idx > 0:
pw.dlog(
FsfwTmTcPrinter.get_validity_buffer(
get_validity_buffer_str(
validity_buffer=hk_data[current_idx:], num_vars=27
)
)

View File

@ -9,13 +9,12 @@ import datetime
import enum
import logging
import struct
from typing import List, Tuple
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.pus_tm.defs import PrintWrapper
from eive_tmtc.utility.input_helper import InputHelper
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.config import TmtcDefinitionWrapper, OpCodeEntry
from tmtccmd.config.tmtc import tmtc_definitions_provider
from tmtccmd.config import CmdTreeNode
from tmtccmd.pus.tc.s3_fsfw_hk import (
create_request_one_diag_command,
create_request_one_hk_command,
@ -23,16 +22,27 @@ from tmtccmd.pus.tc.s3_fsfw_hk import (
disable_periodic_hk_command,
make_sid,
)
from tmtccmd.pus.s20_fsfw_param import create_load_param_cmd, create_scalar_u8_parameter
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s200_fsfw_mode import pack_mode_data, Mode
from tmtccmd.util import ObjectIdU32
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.fsfw.tmtc_printer import get_validity_buffer_str
from eive_tmtc.config.object_ids import STR_ASSEMBLY, STAR_TRACKER_ID
_LOGGER = logging.getLogger(__name__)
class FirmwareTarget(enum.IntEnum):
MAIN = 1
BACKUP = 10
class ParamId(enum.IntEnum):
FIRMWARE_TARGET = 1
FIRMWARE_TARGET_PERSISTENT = 2
class StarTrackerActionId(enum.IntEnum):
PING = 0
BOOT = 1
@ -95,7 +105,10 @@ class StarTrackerActionId(enum.IntEnum):
LOGLEVEL = 81
LOG_SUBSCRIPTION = 82
DEBUG_CAMERA = 83
# Legacy variable.
FIRMWARE_UPDATE = 84
FIRMWARE_UPDATE_MAIN = 84
FIRMWARE_UPDATE_BACKUP = 101
SET_TIME_FROM_SYS_TIME = 87
ADD_SECONDARY_TM_TO_NORMAL_MODE = 95
RESET_SECONDARY_TM_SET = 96
@ -119,12 +132,23 @@ class OpCode:
UPLOAD_IMAGE = "upload_image"
DOWNLOAD_IMAGE = "download_image"
SET_IMG_PROCESSOR_MODE = "set_img_proc_mode"
FW_UPDATE = "fw_update"
FW_UPDATE_MAIN = "fw_update_main"
SET_TIME_FROM_SYS_TIME = "set_time"
RELOAD_JSON_CFG_FILE = "reload_json_cfg"
FW_UPDATE_BACKUP = "fw_update_backup"
SELECT_TARGET_FIRMWARE_MAIN = "fw_main"
SELECT_TARGET_FIRMWARE_BACKUP = "fw_backup"
SELECT_TARGET_FIRMWARE_MAIN_PERSISTENT = "fw_main_persistent"
SELECT_TARGET_FIRMWARE_BACKUP_PERSISTENT = "fw_backup_persistent"
REQUEST_VERSION = "request_version"
class Info:
ON_BOOTLOADER = "Switch to Mode On, Submode Bootloder"
ON_FIRMWARE = "Switch to Mode On, Submode Firmware"
NORMAL = "Switch to Mode Normal"
OFF = "Switch to Mode Off"
PING = "Send Ping"
ONE_SHOOT_HK = "One shoot HK Set"
ENABLE_HK = "Enable Periodic HK"
DISABLE_HK = "Disable Periodic HK"
@ -135,9 +159,17 @@ class Info:
DOWNLOAD_IMAGE = "Download Optical Image"
TAKE_IMAGE = "Take Image"
SET_IMG_PROCESSOR_MODE = "Set Image Processor Mode"
FW_UPDATE = "Firmware Update"
FW_UPDATE_MAIN = "Update Main Firmware Slot"
FW_UPDATE_BACKUP = "Update Backup Firmware Slot"
SET_TIME_FROM_SYS_TIME = "Set time from system time"
RELOAD_JSON_CFG_FILE = "Reload JSON configuration file. Reboot still required."
SELECT_TARGET_FIRMWARE_MAIN = "Select main firmware slot"
SELECT_TARGET_FIRMWARE_BACKUP = "Select backup firmware slot"
SELECT_TARGET_FIRMWARE_MAIN_PERSISTENT = "Select main firmware slot persistently"
SELECT_TARGET_FIRMWARE_BACKUP_PERSISTENT = (
"Select backup firmware slot persistently"
)
REQUEST_VERSION = "Request the active Firmware Version"
class SetId(enum.IntEnum):
@ -159,6 +191,7 @@ class SetId(enum.IntEnum):
BLOBS = 92
CENTROID = 93
CENTROIDS = 94
BLOB_STATS = 102
class DataSetRequest(enum.IntEnum):
@ -241,68 +274,64 @@ def prompt_object_id_mode_cmd() -> bytes:
def pack_star_tracker_commands( # noqa C901
object_id: ObjectIdU32, q: DefaultPusQueueHelper, op_code: str
object_id: ObjectIdU32, q: DefaultPusQueueHelper, cmd_str: str
):
q.add_log_cmd(
f"Generate command for star tracker with object id: {object_id.as_hex_string}"
)
obyt = object_id.as_bytes
if op_code == OpCode.ON_BOOTLOADER:
if cmd_str == OpCode.ON_BOOTLOADER:
q.add_log_cmd("Star tracker: Mode On, Submode Bootloader")
data = pack_mode_data(prompt_object_id_mode_cmd(), Mode.ON, Submode.BOOTLOADER)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=data))
if op_code == OpCode.ON_FIRMWARE:
if cmd_str == OpCode.ON_FIRMWARE:
q.add_log_cmd("Star tracker: Mode On, Submode Firmware")
data = pack_mode_data(prompt_object_id_mode_cmd(), Mode.ON, Submode.FIRMWARE)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=data))
if op_code == OpCode.NORMAL:
if cmd_str == OpCode.NORMAL:
q.add_log_cmd("Star tracker: Mode Normal")
data = pack_mode_data(prompt_object_id_mode_cmd(), Mode.NORMAL, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=data))
if op_code == OpCode.OFF:
if cmd_str == OpCode.OFF:
q.add_log_cmd("Star tracker: Mode Off")
data = pack_mode_data(prompt_object_id_mode_cmd(), Mode.OFF, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=data))
if op_code == OpCode.ONE_SHOOT_HK:
if cmd_str == OpCode.ONE_SHOOT_HK:
q.add_log_cmd(Info.ONE_SHOOT_HK)
request_dataset(q, DataSetRequest.ONESHOT)
if op_code == OpCode.ENABLE_HK:
if cmd_str == OpCode.ENABLE_HK:
q.add_log_cmd(Info.ENABLE_HK)
request_dataset(q, DataSetRequest.ENABLE)
if op_code == OpCode.DISABLE_HK:
if cmd_str == OpCode.DISABLE_HK:
q.add_log_cmd(Info.DISABLE_HK)
request_dataset(q, DataSetRequest.DISABLE)
if op_code == "4":
if cmd_str == "4":
q.add_log_cmd("Star tracker: Mode Raw")
data = pack_mode_data(obyt, Mode.RAW, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=data))
if op_code == OpCode.PING:
if cmd_str == OpCode.PING:
q.add_log_cmd("Star tracker: Ping")
data = obyt + struct.pack("!I", StarTrackerActionId.PING)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "6":
if cmd_str == "6":
q.add_log_cmd("Star tracker: Switch to bootloader program")
data = obyt + struct.pack(
"!I", StarTrackerActionId.SWITCH_TO_BOOTLOADER_PROGRAM
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "7":
if cmd_str == "7":
q.add_log_cmd("Star tracker: Temperature request")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_TEMPERATURE)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "8":
q.add_log_cmd("Star tracker: Request version")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_VERSION)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "9":
if cmd_str == "9":
q.add_log_cmd("Star tracker: Request interface")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_INTERFACE)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "10":
if cmd_str == "10":
q.add_log_cmd("Star tracker: Request power")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_POWER)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "11":
if cmd_str == "11":
q.add_log_cmd("Star tracker: Set subscription parameters")
json_file = get_config_file()
data = (
@ -311,15 +340,15 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(json_file, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "12":
if cmd_str == "12":
q.add_log_cmd("Star tracker: Boot")
data = obyt + struct.pack("!I", StarTrackerActionId.BOOT)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "13":
if cmd_str == "13":
q.add_log_cmd("Star tracker: Request time")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_TIME)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.UPLOAD_IMAGE:
if cmd_str == OpCode.UPLOAD_IMAGE:
q.add_log_cmd("Star tracker: Upload image")
image = get_upload_image()
data = (
@ -328,7 +357,7 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(image, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.DOWNLOAD_IMAGE:
if cmd_str == OpCode.DOWNLOAD_IMAGE:
q.add_log_cmd(f"STR: {Info.DOWNLOAD_IMAGE}")
path = input("Specify storage location (default - /mnt/sd0/startracker): ")
if not path:
@ -339,7 +368,7 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(path, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "17":
if cmd_str == "17":
q.add_log_cmd("Star tracker: Set limits")
json_file = get_config_file()
data = (
@ -348,7 +377,7 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(json_file, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "18":
if cmd_str == "18":
q.add_log_cmd("Star tracker: Set tracking parameters")
json_file = get_config_file()
data = (
@ -357,7 +386,7 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(json_file, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "19":
if cmd_str == "19":
q.add_log_cmd("Star tracker: Mounting")
json_file = get_config_file()
data = (
@ -366,7 +395,7 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(json_file, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "20":
if cmd_str == "20":
q.add_log_cmd("Star tracker: Camera")
json_file = get_config_file()
data = (
@ -375,7 +404,7 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(json_file, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "22":
if cmd_str == "22":
q.add_log_cmd("Star tracker: Centroiding")
json_file = get_config_file()
data = (
@ -384,7 +413,7 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(json_file, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "23":
if cmd_str == "23":
q.add_log_cmd("Star tracker: LISA")
json_file = get_config_file()
data = (
@ -393,7 +422,7 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(json_file, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "24":
if cmd_str == "24":
q.add_log_cmd("Star tracker: Matching")
json_file = get_config_file()
data = (
@ -402,7 +431,7 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(json_file, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "25":
if cmd_str == "25":
q.add_log_cmd("Star tracker: Validation")
json_file = get_config_file()
data = (
@ -411,7 +440,7 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(json_file, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "26":
if cmd_str == "26":
q.add_log_cmd("Star tracker: Algo")
json_file = get_config_file()
data = (
@ -420,7 +449,7 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(json_file, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.TAKE_IMAGE:
if cmd_str == OpCode.TAKE_IMAGE:
q.add_log_cmd("Star tracker: Take image")
actionid = int(
input("Specify parameter ID (4: take image, 7: get histogram): ")
@ -431,11 +460,11 @@ def pack_star_tracker_commands( # noqa C901
+ struct.pack("!B", actionid)
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "28":
if cmd_str == "28":
q.add_log_cmd("Star tracker: Stop str helper")
data = obyt + struct.pack("!I", StarTrackerActionId.STOP_STR_HELPER)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "30":
if cmd_str == "30":
q.add_log_cmd("Star tracker: Set name of download image")
filename = input("Specify download image name: ")
data = (
@ -444,15 +473,15 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(filename, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "31":
if cmd_str == "31":
q.add_log_cmd("Star tracker: Request histogram")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_HISTOGRAM)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "32":
if cmd_str == "32":
q.add_log_cmd("Star tracker: Request contrast")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_CONTRAST)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "33":
if cmd_str == "33":
q.add_log_cmd("Star tracker: Set json filename")
json_file = get_config_file()
data = (
@ -461,11 +490,11 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(json_file, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "35":
if cmd_str == "35":
q.add_log_cmd("Star tracker: Flash read")
data = pack_read_command(obyt)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "36":
if cmd_str == "36":
q.add_log_cmd("Star tracker: Set flash read filename")
filename = input("Specify filename: ")
data = (
@ -474,15 +503,15 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(filename, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "37":
if cmd_str == "37":
q.add_log_cmd("Star tracker: Get checksum")
data = pack_checksum_command(obyt)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.SET_TIME_FROM_SYS_TIME:
if cmd_str == OpCode.SET_TIME_FROM_SYS_TIME:
q.add_log_cmd(Info.SET_TIME_FROM_SYS_TIME)
data = obyt + struct.pack("!I", StarTrackerActionId.SET_TIME_FROM_SYS_TIME)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "39":
if cmd_str == "39":
q.add_log_cmd("Star tracker: Download Centroid")
id = 0
data = (
@ -491,7 +520,7 @@ def pack_star_tracker_commands( # noqa C901
+ struct.pack("!B", id)
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "41":
if cmd_str == "41":
q.add_log_cmd("Star tracker: Download matched star")
id = 0
data = (
@ -500,7 +529,7 @@ def pack_star_tracker_commands( # noqa C901
+ struct.pack("!B", id)
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "42":
if cmd_str == "42":
q.add_log_cmd("Star tracker: Download DB Image")
id = 0
data = (
@ -509,7 +538,7 @@ def pack_star_tracker_commands( # noqa C901
+ struct.pack("!B", id)
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "43":
if cmd_str == "43":
q.add_log_cmd("Star tracker: Download Blob Pixel")
id = 0
type = 1 # 0 - normal, 1 - fast
@ -520,7 +549,7 @@ def pack_star_tracker_commands( # noqa C901
+ struct.pack("!B", type)
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "47":
if cmd_str == "47":
q.add_log_cmd("Star tracker: FPGA action")
id = 3
data = (
@ -529,19 +558,19 @@ def pack_star_tracker_commands( # noqa C901
+ struct.pack("!B", id)
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "48":
if cmd_str == "48":
q.add_log_cmd("Star tracker: Unlock")
data = obyt + struct.pack("!I", StarTrackerActionId.UNLOCK)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "49":
if cmd_str == "49":
q.add_log_cmd("Star tracker: Request camera parameters")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_CAMERA_PARAMS)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "50":
if cmd_str == "50":
q.add_log_cmd("Star tracker: Request limits")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_LIMITS)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.SET_IMG_PROCESSOR_MODE:
if cmd_str == OpCode.SET_IMG_PROCESSOR_MODE:
q.add_log_cmd(Info.SET_IMG_PROCESSOR_MODE)
json_file = get_config_file()
data = (
@ -550,7 +579,7 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(json_file, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "52":
if cmd_str == "52":
q.add_log_cmd("Star tracker: EGSE load ground config camera parameters")
data = (
obyt
@ -558,7 +587,7 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(FileDefs.egse_ground_config, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "53":
if cmd_str == "53":
q.add_log_cmd("Star tracker: EGSE load flight config camera parameters")
data = (
obyt
@ -566,55 +595,55 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(FileDefs.egse_flight_config, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "54":
if cmd_str == "54":
q.add_log_cmd("Star tracker: Request log level parameters")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_LOG_LEVEL)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "55":
if cmd_str == "55":
q.add_log_cmd("Star tracker: Request mounting parameters")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_MOUNTING)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "56":
if cmd_str == "56":
q.add_log_cmd("Star tracker: Request image processor parameters")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_IMAGE_PROCESSOR)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "57":
if cmd_str == "57":
q.add_log_cmd("Star tracker: Request centroiding parameters")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_CENTROIDING)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "58":
if cmd_str == "58":
q.add_log_cmd("Star tracker: Request lisa parameters")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_LISA)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "59":
if cmd_str == "59":
q.add_log_cmd("Star tracker: Request matching parameters")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_MATCHING)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "60":
if cmd_str == "60":
q.add_log_cmd("Star tracker: Request tracking parameters")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_TRACKING)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "61":
if cmd_str == "61":
q.add_log_cmd("Star tracker: Request validation parameters")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_VALIDATION)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "62":
if cmd_str == "62":
q.add_log_cmd("Star tracker: Request algo parameters")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_ALGO)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "63":
if cmd_str == "63":
q.add_log_cmd("Star tracker: Request subscription parameters")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_SUBSCRIPTION)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "64":
if cmd_str == "64":
q.add_log_cmd("Star tracker: Request log subscription parameters")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_LOG_SUBSCRIPTION)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "65":
if cmd_str == "65":
q.add_log_cmd("Star tracker: Request debug camera parameters")
data = obyt + struct.pack("!I", StarTrackerActionId.REQ_DEBUG_CAMERA)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "66":
if cmd_str == "66":
q.add_log_cmd("Star tracker: Set log level parameters")
json_file = get_config_file()
data = (
@ -623,7 +652,7 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(json_file, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "67":
if cmd_str == "67":
q.add_log_cmd("Star tracker: Set log subscription parameters")
json_file = get_config_file()
@ -633,7 +662,7 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(json_file, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "68":
if cmd_str == "68":
q.add_log_cmd("Star tracker: Set debug camera parameters")
json_file = get_config_file()
data = (
@ -642,16 +671,25 @@ def pack_star_tracker_commands( # noqa C901
+ bytearray(json_file, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.FW_UPDATE:
q.add_log_cmd(Info.FW_UPDATE)
if cmd_str == OpCode.FW_UPDATE_MAIN:
q.add_log_cmd(Info.FW_UPDATE_MAIN)
firmware = get_firmware()
data = (
obyt
+ struct.pack("!I", StarTrackerActionId.FIRMWARE_UPDATE)
+ struct.pack("!I", StarTrackerActionId.FIRMWARE_UPDATE_MAIN)
+ firmware.encode()
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.ADD_SECONDARY_TM_TO_NORMAL_MODE:
if cmd_str == OpCode.FW_UPDATE_BACKUP:
q.add_log_cmd(Info.FW_UPDATE_BACKUP)
firmware = get_firmware()
data = (
obyt
+ struct.pack("!I", StarTrackerActionId.FIRMWARE_UPDATE_BACKUP)
+ firmware.encode()
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if cmd_str == OpCode.ADD_SECONDARY_TM_TO_NORMAL_MODE:
q.add_log_cmd(Info.ADD_SECONDARY_TM_TO_NORMAL_MODE)
for val in SetId:
print("{:<2}: {:<20}".format(val, val.name))
@ -663,7 +701,7 @@ def pack_star_tracker_commands( # noqa C901
struct.pack("!I", set_id),
)
)
if op_code == OpCode.RESET_SECONDARY_TM_SET:
if cmd_str == OpCode.RESET_SECONDARY_TM_SET:
q.add_log_cmd(Info.RESET_SECONDARY_TM_SET)
q.add_pus_tc(
create_action_cmd(
@ -671,18 +709,55 @@ def pack_star_tracker_commands( # noqa C901
StarTrackerActionId.RESET_SECONDARY_TM_SET,
)
)
if op_code == OpCode.READ_SECONDARY_TM_SET:
if cmd_str == OpCode.READ_SECONDARY_TM_SET:
q.add_log_cmd(Info.READ_SECONDARY_TM_SET)
q.add_pus_tc(
create_action_cmd(
STAR_TRACKER_ID, StarTrackerActionId.READ_SECONDARY_TM_SET
)
)
if op_code == OpCode.RELOAD_JSON_CFG_FILE:
if cmd_str == OpCode.RELOAD_JSON_CFG_FILE:
q.add_log_cmd(Info.RELOAD_JSON_CFG_FILE)
q.add_pus_tc(
create_action_cmd(STAR_TRACKER_ID, StarTrackerActionId.RELOAD_JSON_CFG_FILE)
)
if cmd_str == OpCode.SELECT_TARGET_FIRMWARE_MAIN:
q.add_log_cmd(Info.SELECT_TARGET_FIRMWARE_MAIN)
q.add_pus_tc(create_update_firmware_target_cmd(False, FirmwareTarget.MAIN))
if cmd_str == OpCode.SELECT_TARGET_FIRMWARE_BACKUP:
q.add_log_cmd(Info.SELECT_TARGET_FIRMWARE_BACKUP)
q.add_pus_tc(create_update_firmware_target_cmd(False, FirmwareTarget.BACKUP))
if cmd_str == OpCode.SELECT_TARGET_FIRMWARE_MAIN_PERSISTENT:
q.add_log_cmd(Info.SELECT_TARGET_FIRMWARE_BACKUP)
q.add_pus_tc(create_update_firmware_target_cmd(True, FirmwareTarget.MAIN))
if cmd_str == OpCode.SELECT_TARGET_FIRMWARE_BACKUP_PERSISTENT:
q.add_log_cmd(Info.SELECT_TARGET_FIRMWARE_BACKUP)
q.add_pus_tc(create_update_firmware_target_cmd(True, FirmwareTarget.BACKUP))
if cmd_str == OpCode.REQUEST_VERSION:
q.add_log_cmd(Info.REQUEST_VERSION)
q.add_pus_tc(
create_action_cmd(
object_id=STAR_TRACKER_ID, action_id=StarTrackerActionId.REQ_VERSION
)
)
def create_update_firmware_target_cmd(
persistent: bool, fw_target: FirmwareTarget
) -> PusTelecommand:
if persistent:
param_id = ParamId.FIRMWARE_TARGET_PERSISTENT
else:
param_id = ParamId.FIRMWARE_TARGET
return create_load_param_cmd(
parameter=create_scalar_u8_parameter(
STAR_TRACKER_ID,
0,
param_id,
fw_target,
),
apid=0,
)
def request_dataset(q: DefaultPusQueueHelper, req_type: DataSetRequest):
@ -814,6 +889,10 @@ def handle_str_hk_data(set_id: int, hk_data: bytes, pw: PrintWrapper):
handle_centroids_set(hk_data, pw)
elif set_id == SetId.CONTRAST:
handle_contrast_set(hk_data, pw)
elif set_id == SetId.BLOB_STATS:
handle_blob_stats_set(hk_data, pw)
elif set_id == SetId.VERSION:
handle_version_set(hk_data, pw)
else:
_LOGGER.warning(f"HK parsing for Star Tracker set ID {set_id} unimplemented")
@ -836,6 +915,25 @@ def unpack_time_hk(hk_data: bytes, current_idx: int, pw: PrintWrapper) -> int:
return current_idx
def handle_version_set(hk_data: bytes, pw: PrintWrapper):
pw.dlog("Received Version Set")
if len(hk_data) != 16:
_LOGGER.warning(
f"Version dataset HK with length {len(hk_data)} of unexpected size"
)
current_idx = unpack_time_hk(hk_data, 0, pw)
program = struct.unpack("!B", hk_data[current_idx : current_idx + 1])[0]
pw.dlog(f"Program: {program}")
current_idx += 1
major = struct.unpack("!B", hk_data[current_idx : current_idx + 1])[0]
pw.dlog(f"Major: {major}")
current_idx += 1
minor = struct.unpack("!B", hk_data[current_idx : current_idx + 1])[0]
pw.dlog(f"Minor: {minor}")
current_idx += 1
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=5))
def handle_temperature_set(hk_data: bytes, pw: PrintWrapper):
pw.dlog("Received temperature set")
if len(hk_data) < 24:
@ -850,7 +948,7 @@ def handle_temperature_set(hk_data: bytes, pw: PrintWrapper):
pw.dlog(f"CMOS Temperature: {cmos_temp}")
pw.dlog(f"FPGA Temperature: {fpga_temp}")
current_idx += fmt_len
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], 5)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], 5))
def handle_solution_set(hk_data: bytes, pw: PrintWrapper):
@ -924,7 +1022,7 @@ def handle_solution_set(hk_data: bytes, pw: PrintWrapper):
solution_strategy = hk_data[current_idx]
pw.dlog(f"Solution strategy: {solution_strategy}")
current_idx += 1
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], 23)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], 23))
def handle_blob_set(hk_data: bytes, pw: PrintWrapper):
@ -935,7 +1033,7 @@ def handle_blob_set(hk_data: bytes, pw: PrintWrapper):
current_idx = unpack_time_hk(hk_data, 0, pw)
blob_count = struct.unpack("!I", hk_data[current_idx : current_idx + 4])[0]
pw.dlog(f"Blob count: {blob_count}")
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx + 4 :], num_vars=3)
pw.dlog(get_validity_buffer_str(hk_data[current_idx + 4 :], num_vars=3))
def handle_blobs_set(hk_data: bytes, pw: PrintWrapper):
@ -963,7 +1061,7 @@ def handle_blobs_set(hk_data: bytes, pw: PrintWrapper):
for idx in range(8):
pw.dlog("{:<8} {:<8}".format(x_coords[idx], y_coords[idx]))
assert current_idx == len(hk_data) - 1
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=7)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=7))
def handle_centroid_set(hk_data: bytes, pw: PrintWrapper):
@ -977,7 +1075,7 @@ def handle_centroid_set(hk_data: bytes, pw: PrintWrapper):
current_idx += 4
pw.dlog(f"Centroid count: {centroid_count}")
assert current_idx == len(hk_data) - 1
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=3)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=3))
def handle_centroids_set(hk_data: bytes, pw: PrintWrapper):
@ -1004,7 +1102,7 @@ def handle_centroids_set(hk_data: bytes, pw: PrintWrapper):
)
)
assert current_idx == len(hk_data) - 1
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=6)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=6))
def handle_matched_centroids_set(hk_data: bytes, pw: PrintWrapper):
@ -1048,7 +1146,7 @@ def handle_matched_centroids_set(hk_data: bytes, pw: PrintWrapper):
)
)
assert current_idx == len(hk_data) - 1
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=8)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=8))
def handle_auto_blob_set(hk_data: bytes, pw: PrintWrapper):
@ -1066,7 +1164,7 @@ def handle_auto_blob_set(hk_data: bytes, pw: PrintWrapper):
current_idx += inc_len
assert current_idx == len(hk_data) - 1
pw.dlog(f"Threshold {threshold}")
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=3)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=3))
def handle_histo_or_contrast_set(name: str, hk_data: bytes, pw: PrintWrapper):
@ -1116,6 +1214,35 @@ def handle_contrast_set(hk_data: bytes, pw: PrintWrapper):
handle_histo_or_contrast_set("Contrast", hk_data, pw)
def handle_blob_stats_set(hk_data: bytes, pw: PrintWrapper):
pw.dlog("Received Blob Stats Set")
if len(hk_data) < 65:
raise ValueError(
f"Matched BlobStats set with length {len(hk_data)} too short. Expected 65 bytes."
)
current_idx = unpack_time_hk(hk_data, 0, pw)
def fill_list(current_idx: int) -> Tuple[List[int], int]:
list_to_fill = []
for _ in range(16):
list_to_fill.append(hk_data[current_idx])
current_idx += 1
return list_to_fill, current_idx
noise_list, current_idx = fill_list(current_idx)
threshold_list, current_idx = fill_list(current_idx)
lvalid_list, current_idx = fill_list(current_idx)
oflow_list, current_idx = fill_list(current_idx)
pw.dlog("Index | Noise | Threshold | LValid | Oflow")
for i in range(16):
pw.dlog(
"{:<3} {:<3} {:<3} {:<3} {:<3}".format(
i, noise_list[i], threshold_list[i], lvalid_list[i], oflow_list[i]
)
)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=6))
def handle_star_tracker_action_replies(
action_id: int, pw: PrintWrapper, custom_data: bytes
):
@ -1155,27 +1282,16 @@ def handle_read_secondary_tm_set(pw: PrintWrapper, custom_data: bytes):
pw.dlog(f"Unknown Set ID {set_id}")
@tmtc_definitions_provider
def add_str_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(OpCode.ON_BOOTLOADER, "Mode On, Submode Bootloader")
oce.add(OpCode.ON_FIRMWARE, "Mode On, Submode Firmware")
oce.add(OpCode.NORMAL, "Mode Normal")
oce.add(OpCode.OFF, "Mode Off")
oce.add(OpCode.PING, "Star Tracker: Ping")
oce.add(OpCode.TAKE_IMAGE, "Take Image")
oce.add(OpCode.UPLOAD_IMAGE, Info.UPLOAD_IMAGE)
oce.add(OpCode.DOWNLOAD_IMAGE, Info.DOWNLOAD_IMAGE)
oce.add(OpCode.ONE_SHOOT_HK, Info.ONE_SHOOT_HK)
oce.add(OpCode.ENABLE_HK, Info.ENABLE_HK)
oce.add(OpCode.DISABLE_HK, Info.DISABLE_HK)
oce.add(OpCode.SET_IMG_PROCESSOR_MODE, Info.SET_IMG_PROCESSOR_MODE)
oce.add(
OpCode.ADD_SECONDARY_TM_TO_NORMAL_MODE, Info.ADD_SECONDARY_TM_TO_NORMAL_MODE
def create_str_node() -> CmdTreeNode:
# Zip the two classes together into a dictionary
op_code_strs = [
getattr(OpCode, key) for key in dir(OpCode) if not key.startswith("__")
]
info_strs = [getattr(Info, key) for key in dir(OpCode) if not key.startswith("__")]
combined_dict = dict(zip(op_code_strs, info_strs))
node = CmdTreeNode(
"str", "Star Tracker Device", hide_children_which_are_leaves=True
)
oce.add(OpCode.READ_SECONDARY_TM_SET, Info.READ_SECONDARY_TM_SET)
oce.add(OpCode.RESET_SECONDARY_TM_SET, Info.RESET_SECONDARY_TM_SET)
oce.add(OpCode.FW_UPDATE, Info.FW_UPDATE)
oce.add(OpCode.SET_TIME_FROM_SYS_TIME, Info.SET_TIME_FROM_SYS_TIME)
oce.add(OpCode.RELOAD_JSON_CFG_FILE, Info.RELOAD_JSON_CFG_FILE)
defs.add_service(CustomServiceList.STAR_TRACKER.value, "Star Tracker", oce)
for op_code, info in combined_dict.items():
node.add_child(CmdTreeNode(op_code, info))
return node

View File

@ -1,22 +1,19 @@
import enum
from typing import Tuple, Dict
from typing import Dict, Tuple
from eive_tmtc.tmtc.acs.defs import AcsMode, SafeSubmode
from spacepackets.ecss import PusTelecommand
from eive_tmtc.tmtc.common import pack_mode_cmd_with_info
from eive_tmtc.config.object_ids import ACS_SUBSYSTEM_ID
from eive_tmtc.config.definitions import CustomServiceList
from tmtccmd.config.tmtc import (
tmtc_definitions_provider,
TmtcDefinitionWrapper,
OpCodeEntry,
CmdTreeNode,
)
from tmtccmd.pus.s200_fsfw_mode import Subservice as ModeSubservices
from tmtccmd.tmtc import service_provider
from tmtccmd.tmtc.decorator import ServiceProviderParams
from tmtccmd.tmtc import DefaultPusQueueHelper
from eive_tmtc.config.object_ids import ACS_SUBSYSTEM_ID
from eive_tmtc.tmtc.acs.defs import AcsMode, SafeSubmode
from eive_tmtc.tmtc.common import pack_mode_cmd_with_info
class OpCode(str, enum.Enum):
class CmdStr(str, enum.Enum):
OFF = "off"
SAFE = "safe"
DETUMBLE = "detumble"
@ -41,23 +38,20 @@ class Info(str, enum.Enum):
HANDLER_LIST: Dict[str, Tuple[int, int, str]] = {
OpCode.OFF: (AcsMode.OFF, 0, Info.OFF),
OpCode.SAFE: (AcsMode.SAFE, SafeSubmode.DEFAULT, Info.SAFE),
OpCode.DETUMBLE: (AcsMode.SAFE, SafeSubmode.DETUMBLE, Info.DETUMBLE),
OpCode.IDLE: (AcsMode.IDLE, 0, Info.IDLE),
OpCode.PTG_TARGET: (AcsMode.PTG_TARGET, 0, Info.PTG_TARGET),
OpCode.PTG_TARGET_GS: (AcsMode.PTG_TARGET_GS, 0, Info.PTG_TARGET_GS),
OpCode.PTG_TARGET_NADIR: (AcsMode.PTG_NADIR, 0, Info.PTG_TARGET_NADIR),
OpCode.PTG_TARGET_INERTIAL: (AcsMode.PTG_INERTIAL, 0, Info.PTG_TARGET_INERTIAL),
CmdStr.OFF: (AcsMode.OFF, 0, Info.OFF),
CmdStr.SAFE: (AcsMode.SAFE, SafeSubmode.DEFAULT, Info.SAFE),
CmdStr.DETUMBLE: (AcsMode.SAFE, SafeSubmode.DETUMBLE, Info.DETUMBLE),
CmdStr.IDLE: (AcsMode.IDLE, 0, Info.IDLE),
CmdStr.PTG_TARGET: (AcsMode.PTG_TARGET, 0, Info.PTG_TARGET),
CmdStr.PTG_TARGET_GS: (AcsMode.PTG_TARGET_GS, 0, Info.PTG_TARGET_GS),
CmdStr.PTG_TARGET_NADIR: (AcsMode.PTG_NADIR, 0, Info.PTG_TARGET_NADIR),
CmdStr.PTG_TARGET_INERTIAL: (AcsMode.PTG_INERTIAL, 0, Info.PTG_TARGET_INERTIAL),
}
@service_provider(CustomServiceList.ACS_SS.value)
def build_acs_subsystem_cmd(p: ServiceProviderParams):
op_code = p.op_code
q = p.queue_helper
def build_acs_subsystem_cmd(q: DefaultPusQueueHelper, cmd_path: str):
info_prefix = "ACS Subsystem"
if op_code in OpCode.REPORT_ALL_MODES:
if cmd_path in CmdStr.REPORT_ALL_MODES:
q.add_log_cmd(f"{info_prefix}: {Info.REPORT_ALL_MODES}")
q.add_pus_tc(
PusTelecommand(
@ -66,7 +60,7 @@ def build_acs_subsystem_cmd(p: ServiceProviderParams):
app_data=ACS_SUBSYSTEM_ID,
)
)
mode_info_tup = HANDLER_LIST.get(op_code)
mode_info_tup = HANDLER_LIST.get(cmd_path)
if mode_info_tup is None:
return
pack_mode_cmd_with_info(
@ -78,10 +72,9 @@ def build_acs_subsystem_cmd(p: ServiceProviderParams):
)
@tmtc_definitions_provider
def add_acs_subsystem_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
for op_code, (_, _, info) in HANDLER_LIST.items():
oce.add(op_code, info)
oce.add(OpCode.REPORT_ALL_MODES, Info.REPORT_ALL_MODES)
defs.add_service(CustomServiceList.ACS_SS, "ACS Subsystem", oce)
def create_acs_subsystem_node() -> CmdTreeNode:
node = CmdTreeNode("acs", "ACS Subsystem", hide_children_which_are_leaves=True)
for cmd_str, (_, _, info) in HANDLER_LIST.items():
node.add_child(CmdTreeNode(cmd_str, info))
node.add_child(CmdTreeNode(CmdStr.REPORT_ALL_MODES, Info.REPORT_ALL_MODES))
return node

View File

@ -3,7 +3,7 @@ import struct
from eive_tmtc.pus_tm.defs import PrintWrapper
from tmtccmd.util import ObjectIdU32
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.fsfw.tmtc_printer import get_validity_buffer_str
class SetId(enum.IntEnum):
@ -26,6 +26,6 @@ def handle_sus_hk(
pw.dlog("AIN Channel | Raw Value (hex) | Raw Value (dec)")
for idx, val in enumerate(channels):
pw.dlog(f"{idx} | {val[0]:#06x} |" + str(val[0]).ljust(5))
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=hk_data[current_idx:], num_vars=7
pw.dlog(
get_validity_buffer_str(validity_buffer=hk_data[current_idx:], num_vars=7)
)

View File

@ -1,22 +1,19 @@
from eive_tmtc.config.definitions import CustomServiceList
from tmtccmd.config.tmtc import (
CmdTreeNode,
)
from tmtccmd.pus.s200_fsfw_mode import Mode
from tmtccmd.tmtc import DefaultPusQueueHelper
from eive_tmtc.config.object_ids import SUS_BOARD_ASS_ID
from eive_tmtc.tmtc.acs.acs_board import DualSideSubmode
from eive_tmtc.tmtc.common import pack_mode_cmd_with_info
from tmtccmd.config.tmtc import (
tmtc_definitions_provider,
TmtcDefinitionWrapper,
OpCodeEntry,
)
from tmtccmd.tmtc import service_provider, DefaultPusQueueHelper
from tmtccmd.tmtc.decorator import ServiceProviderParams
from tmtccmd.pus.s200_fsfw_mode import Mode
class SusOpCode:
SUS_ASS_NOM_SIDE = ["0", "nom"]
SUS_ASS_RED_SIDE = ["1", "red"]
SUS_ASS_DUAL_MODE = ["2", "dual"]
SUS_ASS_OFF = ["3", "off"]
SUS_ASS_NOM_SIDE = "nom"
SUS_ASS_RED_SIDE = "red"
SUS_ASS_DUAL_MODE = "dual"
SUS_ASS_OFF = "off"
def pack_sus_cmds(q: DefaultPusQueueHelper, op_code: str):
@ -54,34 +51,16 @@ def pack_sus_cmds(q: DefaultPusQueueHelper, op_code: str):
)
@service_provider(CustomServiceList.SUS_BRD_ASS)
def pack_sus_cmds_prvoider(p: ServiceProviderParams):
op_code = p.op_code
q = p.queue_helper
pack_sus_cmds(q, op_code)
@tmtc_definitions_provider
def add_sus_board_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(
keys=SusOpCode.SUS_ASS_NOM_SIDE,
info="Switch SUS board to nominal side",
def create_sus_board_node() -> CmdTreeNode:
node = CmdTreeNode("sus_brd_assy", "SUS board assembly")
node.add_child(
CmdTreeNode(SusOpCode.SUS_ASS_RED_SIDE, "Switch SUS board to nominal side")
)
oce.add(
keys=SusOpCode.SUS_ASS_RED_SIDE,
info="Switch SUS board to redundant side",
node.add_child(
CmdTreeNode(SusOpCode.SUS_ASS_RED_SIDE, "Switch SUS board to redundant side")
)
oce.add(
keys=SusOpCode.SUS_ASS_OFF,
info="Switch off SUS board",
)
oce.add(
keys=SusOpCode.SUS_ASS_DUAL_MODE,
info="Switch SUS board to dual mode",
)
defs.add_service(
name=CustomServiceList.SUS_BRD_ASS.value,
info="SUS Board Assembly",
op_code_entry=oce,
node.add_child(CmdTreeNode(SusOpCode.SUS_ASS_OFF, "Switch SUS board off"))
node.add_child(
CmdTreeNode(SusOpCode.SUS_ASS_DUAL_MODE, "Switch SUS board to dual mode")
)
return node

View File

@ -1 +0,0 @@
from .subsystem import add_com_subsystem_cmds

View File

@ -8,6 +8,8 @@
import enum
import struct
from tmtccmd.config import CmdTreeNode
from eive_tmtc.config.definitions import CustomServiceList
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.config.tmtc import (
@ -51,11 +53,11 @@ class Submode(enum.IntEnum):
class OpCode:
ENABLE_WITH_LOW_DATARATE = ["enable_low_datarate"]
ENABLE_WITH_HIGH_DATARATE = ["enable_high_datarate"]
DISABLE = ["disable"]
ENABLE_ACTION = ["legacy_enable_tx"]
DISABLE_ACTION = ["legacy_disable_tx"]
ENABLE_WITH_LOW_DATARATE = "enable_low_datarate"
ENABLE_WITH_HIGH_DATARATE = "enable_high_datarate"
DISABLE = "disable"
ENABLE_ACTION = "legacy_enable_tx"
DISABLE_ACTION = "legacy_disable_tx"
class Info:
@ -67,29 +69,29 @@ class Info:
def pack_ccsds_handler_command( # noqa C901
object_id: ObjectIdU32, q: DefaultPusQueueHelper, op_code: str
object_id: ObjectIdU32, q: DefaultPusQueueHelper, cmd_str: str
):
obyt = object_id.as_bytes
prefix = "CCSDS Handler"
q.add_log_cmd(f"Testing CCSDS handler with object id: {object_id.as_hex_string}")
if op_code in OpCode.ENABLE_WITH_LOW_DATARATE:
if cmd_str in OpCode.ENABLE_WITH_LOW_DATARATE:
q.add_log_cmd(f"{prefix}: {Info.ENABLE_WITH_LOW_DATARATE}")
q.add_pus_tc(create_mode_command(obyt, Mode.ON, Submode.DATARATE_LOW))
if op_code in OpCode.ENABLE_WITH_HIGH_DATARATE:
if cmd_str in OpCode.ENABLE_WITH_HIGH_DATARATE:
q.add_log_cmd(f"{prefix}: {Info.ENABLE_WITH_HIGH_DATARATE}")
q.add_pus_tc(create_mode_command(obyt, Mode.ON, Submode.DATARATE_HIGH))
if op_code in OpCode.DISABLE:
if cmd_str in OpCode.DISABLE:
q.add_log_cmd(f"{prefix}: {Info.DISABLE}")
q.add_pus_tc(create_mode_command(obyt, Mode.OFF, 0))
if op_code in OpCode.ENABLE_ACTION:
if cmd_str in OpCode.ENABLE_ACTION:
q.add_log_cmd(f"{prefix}: {Info.ENABLE_ACTION}")
command = obyt + struct.pack("!I", ActionId.EN_TRANSMITTER)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code in OpCode.DISABLE_ACTION:
if cmd_str in OpCode.DISABLE_ACTION:
q.add_log_cmd(f"{prefix}: {Info.DISABLE_ACTION}")
command = obyt + struct.pack("!I", ActionId.DIS_TRANSMITTER)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "4":
if cmd_str == "4":
q.add_log_cmd("CCSDS Handler: Set arbitrary bitrate")
bitrate = int(input("Specify bit rate (bps): "))
command = (
@ -98,24 +100,36 @@ def pack_ccsds_handler_command( # noqa C901
+ struct.pack("!I", bitrate)
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "5":
if cmd_str == "5":
q.add_log_cmd("CCSDS Handler: Enable tx clock manipulator")
command = obyt + struct.pack("!I", ActionId.ENABLE_TX_CLK_MANIPULATOR)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "6":
if cmd_str == "6":
q.add_log_cmd("CCSDS Handler: Disable tx clock manipulator")
command = obyt + struct.pack("!I", ActionId.DISABLE_TX_CLK_MANIPULATOR)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "7":
if cmd_str == "7":
q.add_log_cmd("CCSDS Handler: Update tx data on rising edge of tx clock")
command = obyt + struct.pack("!I", ActionId.UPDATE_ON_RISING_EDGE)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "8":
if cmd_str == "8":
q.add_log_cmd("CCSDS Handler: Update tx data on falling edge of tx clock")
command = obyt + struct.pack("!I", ActionId.UPDATE_ON_FALLING_EDGE)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
def create_ccsds_node() -> CmdTreeNode:
op_code_strs = [
getattr(OpCode, key) for key in dir(OpCode) if not key.startswith("__")
]
info_strs = [getattr(Info, key) for key in dir(OpCode) if not key.startswith("__")]
combined_dict = dict(zip(op_code_strs, info_strs))
node = CmdTreeNode("ccsds", "CCSDS Handler", hide_children_for_print=True)
for op_code, info in combined_dict.items():
node.add_child(CmdTreeNode(op_code, info))
return node
@tmtc_definitions_provider
def add_ccsds_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()

View File

@ -60,51 +60,53 @@ class Info:
RESET_NO_INIT = "Reset with mandatory initialization"
def pack_pdec_handler_test(
object_id: bytearray, q: DefaultPusQueueHelper, op_code: str
def pack_pdec_handler_commands(
object_id: bytes, q: DefaultPusQueueHelper, cmd_str: str
):
q.add_log_cmd(f"Testing PDEC handler with object id: {object_id.hex()}")
prefix = "PDEC Handler "
if op_code == OpCode.PRINT_CLCW:
if cmd_str == OpCode.PRINT_CLCW:
q.add_log_cmd(f"{prefix}: {Info.PRINT_CLCW}")
command = object_id + CommandId.PRINT_CLCW
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == OpCode.PRINT_MON_REG:
if cmd_str == OpCode.PRINT_MON_REG:
q.add_log_cmd(f"{prefix}: {Info.PRINT_MON_REG}")
command = object_id + CommandId.PRINT_PDEC_MON
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == OpCode.POSITIVE_WINDOW:
if cmd_str == OpCode.POSITIVE_WINDOW:
q.add_log_cmd(f"{prefix}: {Info.POSITIVE_WINDOW}")
pw = int(input("Specify positive window to set: "))
q.add_pus_tc(
create_load_param_cmd(
create_scalar_u8_parameter(
parameter=create_scalar_u8_parameter(
object_id,
0,
ParameterId.POSITIVE_WINDOW,
pw,
)
),
apid=0,
)
)
if op_code == OpCode.NEGATIVE_WINDOW:
if cmd_str == OpCode.NEGATIVE_WINDOW:
q.add_log_cmd(f"{prefix}: {Info.NEGATIVE_WINDOW}")
nw = int(input("Specify negative window to set: "))
q.add_pus_tc(
create_load_param_cmd(
create_scalar_u8_parameter(
parameter=create_scalar_u8_parameter(
object_id,
0,
ParameterId.NEGATIVE_WINDOW,
nw,
)
),
apid=0,
)
)
if op_code == OpCode.RESET_NO_INIT:
if cmd_str == OpCode.RESET_NO_INIT:
q.add_log_cmd(f"{prefix}: {Info.RESET_NO_INIT}")
q.add_pus_tc(
create_action_cmd(object_id=object_id, action_id=ActionId.RESET_NO_INIT)
)
if op_code == OpCode.RESET_WITH_INIT:
if cmd_str == OpCode.RESET_WITH_INIT:
q.add_log_cmd(f"{prefix}: {Info.RESET_WITH_INIT}")
q.add_pus_tc(
create_action_cmd(object_id=object_id, action_id=ActionId.RESET_WITH_INIT)

View File

@ -1,30 +1,25 @@
import enum
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.config.object_ids import COM_SUBSYSTEM_ID
from eive_tmtc.tmtc.com.syrlinks_handler import Datarate
from tmtccmd.pus.s20_fsfw_param_defs import create_scalar_u8_parameter
from .defs import Mode as ComMode
from tmtccmd.config.tmtc import (
tmtc_definitions_provider,
TmtcDefinitionWrapper,
OpCodeEntry,
)
from tmtccmd.tmtc import service_provider
from tmtccmd.tmtc.decorator import ServiceProviderParams
from tmtccmd.pus.s200_fsfw_mode import (
create_mode_command,
create_read_mode_command,
create_announce_mode_command,
create_announce_mode_recursive_command,
CmdTreeNode,
)
from tmtccmd.pus.s20_fsfw_param import (
create_load_param_cmd,
create_scalar_u32_parameter,
)
from tmtccmd.pus.s20_fsfw_param_defs import create_scalar_u8_parameter
from tmtccmd.pus.s200_fsfw_mode import (
create_announce_mode_command,
create_announce_mode_recursive_command,
create_mode_command,
create_read_mode_command,
)
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s20_fsfw_param import create_scalar_u32_parameter
from eive_tmtc.config.object_ids import COM_SUBSYSTEM_ID
from eive_tmtc.tmtc.com.syrlinks_handler import Datarate
from .defs import Mode as ComMode
class ParameterId(enum.IntEnum):
@ -48,9 +43,9 @@ class OpCode:
class Info:
RX_ONLY = "Syrlinks RX Only"
TX_AND_RX_DEF_DATARATE = "Syrlinks with TX default datarate"
TX_AND_RX_LOW_DATARATE = "Syrlinks with TX low datarate (BPSK modulation)"
TX_AND_RX_HIGH_DATARATE = "Syrlinks with TX high datarate (0QPSK modulation)"
TX_AND_RX_DEF_RATE = "Syrlinks with TX default datarate"
TX_AND_RX_LOW_RATE = "Syrlinks with TX low datarate (BPSK modulation)"
TX_AND_RX_HIGH_RATE = "Syrlinks with TX high datarate (0QPSK modulation)"
TX_AND_RX_CARRIER_WAVE = "Syrlinks with TX carrier wave"
UPDATE_DEFAULT_DATARATE_LOW = "Configure default low datarate (BPSK modulation)"
UPDATE_DEFAULT_DATARATE_HIGH = "Configure default high datarate (0QPSK modulation)"
@ -60,30 +55,27 @@ class Info:
ANNOUNCE_MODE_RECURSIVE = "Announce mode recursively"
@service_provider(CustomServiceList.COM_SS)
def build_com_subsystem_cmd(p: ServiceProviderParams): # noqa C901
q = p.queue_helper
o = p.op_code
def build_com_subsystem_procedure(q: DefaultPusQueueHelper, cmd_str: str): # noqa C901
prefix = "COM Subsystem"
if o == OpCode.RX_ONLY:
if cmd_str == OpCode.RX_ONLY:
q.add_log_cmd(Info.RX_ONLY)
q.add_pus_tc(create_mode_command(COM_SUBSYSTEM_ID, ComMode.RX_ONLY, 0))
elif o == OpCode.TX_AND_RX_DEF_RATE:
q.add_log_cmd(Info.TX_AND_RX_DEF_DATARATE)
elif cmd_str == OpCode.TX_AND_RX_DEF_RATE:
q.add_log_cmd(Info.TX_AND_RX_DEF_RATE)
q.add_pus_tc(
create_mode_command(COM_SUBSYSTEM_ID, ComMode.RX_AND_TX_DEF_DATARATE, 0)
)
elif o == OpCode.TX_AND_RX_LOW_RATE:
q.add_log_cmd(Info.TX_AND_RX_LOW_DATARATE)
elif cmd_str == OpCode.TX_AND_RX_LOW_RATE:
q.add_log_cmd(Info.TX_AND_RX_LOW_RATE)
q.add_pus_tc(
create_mode_command(COM_SUBSYSTEM_ID, ComMode.RX_AND_TX_LOW_DATARATE, 0)
)
elif o == OpCode.TX_AND_RX_HIGH_RATE:
q.add_log_cmd(Info.TX_AND_RX_HIGH_DATARATE)
elif cmd_str == OpCode.TX_AND_RX_HIGH_RATE:
q.add_log_cmd(Info.TX_AND_RX_HIGH_RATE)
q.add_pus_tc(
create_mode_command(COM_SUBSYSTEM_ID, ComMode.RX_AND_TX_HIGH_DATARATE, 0)
)
if o == OpCode.UPDATE_DEFAULT_DATARATE_LOW:
if cmd_str == OpCode.UPDATE_DEFAULT_DATARATE_LOW:
q.add_log_cmd(f"{prefix}: {Info.UPDATE_DEFAULT_DATARATE_LOW}")
q.add_pus_tc(
create_load_param_cmd(
@ -95,7 +87,7 @@ def build_com_subsystem_cmd(p: ServiceProviderParams): # noqa C901
)
)
)
if o == OpCode.UPDATE_DEFAULT_DATARATE_HIGH:
if cmd_str == OpCode.UPDATE_DEFAULT_DATARATE_HIGH:
q.add_log_cmd(f"{prefix}: {Info.UPDATE_DEFAULT_DATARATE_HIGH}")
q.add_pus_tc(
create_load_param_cmd(
@ -107,12 +99,12 @@ def build_com_subsystem_cmd(p: ServiceProviderParams): # noqa C901
)
)
)
elif o == OpCode.TX_AND_RX_CARRIER_WAVE:
elif cmd_str == OpCode.TX_AND_RX_CARRIER_WAVE:
q.add_log_cmd(Info.TX_AND_RX_CARRIER_WAVE)
q.add_pus_tc(
create_mode_command(COM_SUBSYSTEM_ID, ComMode.RX_AND_TX_CARRIER_WAVE, 0)
)
elif o == OpCode.CHANGE_TRANSMITTER_TIMEOUT:
elif cmd_str == OpCode.CHANGE_TRANSMITTER_TIMEOUT:
timeout = int(input("Specify timeout to set [ms]: "))
q.add_log_cmd(Info.CHANGE_TRANSMITTER_TIMEOUT)
q.add_pus_tc(
@ -125,28 +117,24 @@ def build_com_subsystem_cmd(p: ServiceProviderParams): # noqa C901
)
)
)
elif o == OpCode.READ_MODE:
elif cmd_str == OpCode.READ_MODE:
q.add_log_cmd(Info.READ_MODE)
q.add_pus_tc(create_read_mode_command(COM_SUBSYSTEM_ID))
elif o == OpCode.ANNOUNCE_MODE:
elif cmd_str == OpCode.ANNOUNCE_MODE:
q.add_log_cmd(Info.ANNOUNCE_MODE)
q.add_pus_tc(create_announce_mode_command(COM_SUBSYSTEM_ID))
elif o == OpCode.ANNOUNCE_MODE_RECURSIVE:
elif cmd_str == OpCode.ANNOUNCE_MODE_RECURSIVE:
q.add_log_cmd(Info.ANNOUNCE_MODE_RECURSIVE)
q.add_pus_tc(create_announce_mode_recursive_command(COM_SUBSYSTEM_ID))
@tmtc_definitions_provider
def add_com_subsystem_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(OpCode.RX_ONLY, Info.RX_ONLY)
oce.add(OpCode.TX_AND_RX_LOW_RATE, Info.TX_AND_RX_LOW_DATARATE)
oce.add(OpCode.TX_AND_RX_HIGH_RATE, Info.TX_AND_RX_HIGH_DATARATE)
oce.add(OpCode.TX_AND_RX_DEF_RATE, Info.TX_AND_RX_DEF_DATARATE)
oce.add(OpCode.UPDATE_DEFAULT_DATARATE_LOW, Info.UPDATE_DEFAULT_DATARATE_LOW)
oce.add(OpCode.UPDATE_DEFAULT_DATARATE_HIGH, Info.UPDATE_DEFAULT_DATARATE_HIGH)
oce.add(OpCode.CHANGE_TRANSMITTER_TIMEOUT, Info.CHANGE_TRANSMITTER_TIMEOUT)
oce.add(OpCode.READ_MODE, Info.READ_MODE)
oce.add(OpCode.ANNOUNCE_MODE, Info.ANNOUNCE_MODE)
oce.add(OpCode.ANNOUNCE_MODE_RECURSIVE, Info.ANNOUNCE_MODE_RECURSIVE)
defs.add_service(CustomServiceList.COM_SS, "COM Subsystem", oce)
def create_com_subsystem_node() -> CmdTreeNode:
op_code_strs = [
getattr(OpCode, key) for key in dir(OpCode) if not key.startswith("__")
]
info_strs = [getattr(Info, key) for key in dir(OpCode) if not key.startswith("__")]
combined_dict = dict(zip(op_code_strs, info_strs))
node = CmdTreeNode("com", "COM Subsystem", hide_children_which_are_leaves=True)
for op_code, info in combined_dict.items():
node.add_child(CmdTreeNode(op_code, info))
return node

View File

@ -8,30 +8,32 @@
import enum
import logging
import math
from eive_tmtc.pus_tm.defs import PrintWrapper
from eive_tmtc.tmtc.com.defs import Mode as ComMode
from eive_tmtc.config.definitions import CustomServiceList
from tmtccmd.config.tmtc import (
tmtc_definitions_provider,
TmtcDefinitionWrapper,
OpCodeEntry,
)
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.tc.s3_fsfw_hk import (
make_sid,
create_request_one_diag_command,
create_request_one_hk_command,
create_enable_periodic_hk_command_with_interval_with_diag,
create_disable_periodic_hk_command_with_diag,
)
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.pus.s200_fsfw_mode import Mode, create_mode_command
from eive_tmtc.config.object_ids import SYRLINKS_HANDLER_ID
import struct
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.config.tmtc import (
CmdTreeNode,
OpCodeEntry,
TmtcDefinitionWrapper,
tmtc_definitions_provider,
)
from tmtccmd.fsfw.tmtc_printer import get_validity_buffer_str
from tmtccmd.pus.s200_fsfw_mode import Mode, create_mode_command
from tmtccmd.pus.tc.s3_fsfw_hk import (
create_disable_periodic_hk_command_with_diag,
create_enable_periodic_hk_command_with_interval_with_diag,
create_request_one_diag_command,
create_request_one_hk_command,
make_sid,
)
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.util import ObjectIdU32
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.config.object_ids import SYRLINKS_HANDLER_ID
from eive_tmtc.pus_tm.defs import PrintWrapper
from eive_tmtc.pus_tm.hk import HkTmInfo
from eive_tmtc.tmtc.com.defs import Mode as ComMode
class SetId(enum.IntEnum):
@ -57,6 +59,7 @@ class OpCode:
HK_TX_REGS = "hk_tx_regs"
TX_STATUS = "tx_status"
RX_STATUS = "rx_status"
SET_CW = "tx_cw"
class Info:
@ -102,6 +105,18 @@ class Datarate(enum.IntEnum):
HIGH_RATE_MODULATION_0QPSK = 1
def create_syrlinks_node() -> CmdTreeNode:
op_code_strs = [
getattr(OpCode, key) for key in dir(OpCode) if not key.startswith("__")
]
info_strs = [getattr(Info, key) for key in dir(OpCode) if not key.startswith("__")]
combined_dict = dict(zip(op_code_strs, info_strs))
node = CmdTreeNode("syrlinks", "Syrlinks Device", hide_children_for_print=True)
for op_code, info in combined_dict.items():
node.add_child(CmdTreeNode(op_code, info))
return node
@tmtc_definitions_provider
def add_syrlinks_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
@ -143,42 +158,42 @@ def normal_mode_cmd(q: DefaultPusQueueHelper, info: str, submode: int):
def pack_syrlinks_command( # noqa C901: Complexity okay here.
object_id: ObjectIdU32, q: DefaultPusQueueHelper, op_code: str
object_id: ObjectIdU32, q: DefaultPusQueueHelper, cmd_str: str
):
obyt = object_id.as_bytes
prefix = "Syrlinks"
q.add_log_cmd(f"Testing Syrlinks with object id: {object_id.as_hex_string}")
if op_code == OpCode.OFF:
if cmd_str == OpCode.OFF:
q.add_log_cmd(f"{prefix}: {Info.OFF}")
q.add_pus_tc(create_mode_command(obyt, Mode.OFF, 0))
if op_code == OpCode.ON:
if cmd_str == OpCode.ON:
q.add_log_cmd(f"{prefix}: {Info.ON}")
q.add_pus_tc(create_mode_command(obyt, Mode.ON, ComMode.RX_ONLY))
if op_code == OpCode.NORMAL_RX_ONLY:
if cmd_str == OpCode.NORMAL_RX_ONLY:
normal_mode_cmd(q, Info.NORMAL_RX_ONLY, ComMode.RX_ONLY)
if op_code == OpCode.NORMAL_RX_AND_TX_LOW_DATARATE:
if cmd_str == OpCode.NORMAL_RX_AND_TX_LOW_DATARATE:
normal_mode_cmd(
q, Info.NORMAL_RX_AND_TX_LOW_DATARATE, ComMode.RX_AND_TX_LOW_DATARATE
)
if op_code == OpCode.NORMAL_RX_AND_TX_DEF_DATARATE:
if cmd_str == OpCode.NORMAL_RX_AND_TX_DEF_DATARATE:
normal_mode_cmd(
q, Info.NORMAL_RX_AND_TX_DEF_DATARATE, ComMode.RX_AND_TX_DEF_DATARATE
)
if op_code == OpCode.NORMAL_RX_AND_TX_HIGH_DATARATE:
if cmd_str == OpCode.NORMAL_RX_AND_TX_HIGH_DATARATE:
normal_mode_cmd(
q, Info.NORMAL_RX_AND_TX_HIGH_DATARATE, ComMode.RX_AND_TX_HIGH_DATARATE
)
if op_code in OpCode.NORMAL_RX_AND_TX_CW:
if cmd_str in OpCode.NORMAL_RX_AND_TX_CW:
normal_mode_cmd(q, Info.NORMAL_RX_AND_TX_CW, ComMode.RX_AND_TX_CARRIER_WAVE)
if op_code in OpCode.HK_RX_REGS:
if cmd_str in OpCode.HK_RX_REGS:
q.add_log_cmd(f"{prefix}: {Info.HK_RX_REGS}")
sid = make_sid(obyt, SetId.RX_REGISTERS_DATASET)
q.add_pus_tc(create_request_one_diag_command(sid))
if op_code in OpCode.HK_TEMPS:
if cmd_str in OpCode.HK_TEMPS:
q.add_log_cmd(f"{prefix}: {Info.HK_TEMPS}")
sid = make_sid(obyt, SetId.TEMPERATURE_SET_ID)
q.add_pus_tc(create_request_one_hk_command(sid))
if op_code in OpCode.ENABLE_HK_RX_REGS:
if cmd_str in OpCode.ENABLE_HK_RX_REGS:
q.add_log_cmd(f"{prefix}: {Info.ENABLE_HK_RX_REGS}")
sid = make_sid(obyt, SetId.RX_REGISTERS_DATASET)
interval = float(input("HK interval in floating point seconds"))
@ -187,11 +202,11 @@ def pack_syrlinks_command( # noqa C901: Complexity okay here.
)
for cmd in cmds:
q.add_pus_tc(cmd)
if op_code in OpCode.DISABLE_HK_RX_REGS:
if cmd_str in OpCode.DISABLE_HK_RX_REGS:
q.add_log_cmd(f"{prefix}: {Info.DISABLE_HK_RX_REGS}")
sid = make_sid(obyt, SetId.RX_REGISTERS_DATASET)
q.add_pus_tc(create_disable_periodic_hk_command_with_diag(True, sid))
if op_code in OpCode.ENABLE_HK_TX_REGS:
if cmd_str in OpCode.ENABLE_HK_TX_REGS:
q.add_log_cmd(f"{prefix}: {Info.ENABLE_HK_TX_REGS}")
sid = make_sid(obyt, SetId.TX_REGISTERS_DATASET)
interval = float(input("HK interval in floating point seconds"))
@ -200,86 +215,96 @@ def pack_syrlinks_command( # noqa C901: Complexity okay here.
)
for cmd in cmds:
q.add_pus_tc(cmd)
if op_code in OpCode.DISABLE_HK_TX_REGS:
if cmd_str in OpCode.DISABLE_HK_TX_REGS:
q.add_log_cmd(f"{prefix}: {Info.DISABLE_HK_TX_REGS}")
sid = make_sid(obyt, SetId.TX_REGISTERS_DATASET)
q.add_pus_tc(create_disable_periodic_hk_command_with_diag(True, sid))
if op_code in OpCode.HK_TX_REGS:
if cmd_str in OpCode.HK_TX_REGS:
q.add_log_cmd(f"{prefix}: {Info.HK_TX_REGS}")
sid = make_sid(obyt, SetId.TX_REGISTERS_DATASET)
q.add_pus_tc(create_request_one_diag_command(sid))
if op_code in OpCode.TX_STATUS:
if cmd_str in OpCode.TX_STATUS:
q.add_log_cmd(f"{prefix}: {Info.TX_STATUS}")
command = obyt + struct.pack("!I", CommandId.READ_TX_STATUS)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "9":
if cmd_str == "9":
q.add_log_cmd("Syrlinks: Read TX waveform")
command = obyt + struct.pack("!I", CommandId.READ_TX_WAVEFORM)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "10":
if cmd_str == "10":
q.add_log_cmd("Syrlinks: Read TX AGC value high byte")
command = obyt + struct.pack("!I", CommandId.READ_TX_AGC_VALUE_HIGH_BYTE)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "11":
if cmd_str == "11":
q.add_log_cmd("Syrlinks: Read TX AGC value low byte")
command = obyt + struct.pack("!I", CommandId.READ_TX_AGC_VALUE_LOW_BYTE)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "12":
if cmd_str == "12":
q.add_log_cmd("Syrlinks: Write LCL config")
command = obyt + struct.pack("!I", CommandId.WRITE_LCL_CONFIG)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "13":
if cmd_str == "13":
q.add_log_cmd("Syrlinks: Read RX status registers")
command = obyt + struct.pack("!I", CommandId.READ_RX_STATUS_REGISTERS)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "14":
if cmd_str == "14":
q.add_log_cmd("Syrlinks: Read LCL config register")
command = obyt + struct.pack("!I", CommandId.READ_LCL_CONFIG_REGISTER)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "15":
if cmd_str == "15":
q.add_log_cmd("Syrlinks: Set waveform OQPSK")
command = obyt + struct.pack("!I", CommandId.SET_WAVEFORM_OQPSK)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "16":
if cmd_str == "16":
q.add_log_cmd("Syrlinks: Set waveform BPSK")
command = obyt + struct.pack("!I", CommandId.SET_WAVEFORM_BPSK)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "17":
if cmd_str == "17":
q.add_log_cmd("Syrlinks: Set second config")
command = obyt + struct.pack("!I", CommandId.SET_SECOND_CONFIG)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "18":
if cmd_str == "18":
q.add_log_cmd("Syrlinks: Enable debug printout")
command = obyt + struct.pack("!I", CommandId.ENABLE_DEBUG)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "19":
if cmd_str == "19":
q.add_log_cmd("Syrlinks: Disable debug printout")
command = obyt + struct.pack("!I", CommandId.DISABLE_DEBUG)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
def handle_syrlinks_hk_data(pw: PrintWrapper, set_id: int, hk_data: bytes):
if set_id == SetId.RX_REGISTERS_DATASET:
return handle_syrlinks_rx_registers_dataset(pw, hk_data)
elif set_id == SetId.TX_REGISTERS_DATASET:
return handle_syrlinks_tx_registers_dataset(pw, hk_data)
elif set_id == SetId.TEMPERATURE_SET_ID:
return handle_syrlinks_temp_dataset(pw, hk_data)
def handle_syrlinks_hk_data(
hk_info: HkTmInfo,
pw: PrintWrapper,
):
if hk_info.set_id == SetId.RX_REGISTERS_DATASET:
return handle_syrlinks_rx_registers_dataset(hk_info, pw)
elif hk_info.set_id == SetId.TX_REGISTERS_DATASET:
return handle_syrlinks_tx_registers_dataset(hk_info, pw)
elif hk_info.set_id == SetId.TEMPERATURE_SET_ID:
return handle_syrlinks_temp_dataset(hk_info, pw)
else:
pw.dlog(f"Service 3 TM: Syrlinks handler reply with unknown set ID {set_id}")
pw.dlog(
f"Service 3 TM: Syrlinks handler reply with unknown set ID {hk_info.set_id}"
)
def handle_syrlinks_temp_dataset(pw: PrintWrapper, hk_data: bytes):
def handle_syrlinks_temp_dataset(hk_info: HkTmInfo, pw: PrintWrapper):
hk_data = hk_info.hk_data
if len(hk_data) < 8:
raise ValueError("expected at least 8 bytes of HK data")
temp_power_amplifier = struct.unpack("!f", hk_data[0:4])[0]
temp_baseband_board = struct.unpack("!f", hk_data[4:8])[0]
pw.dlog(f"Temperatur Power Amplifier [C]: {temp_power_amplifier}")
pw.dlog(f"Temperatur Baseband Board [C]: {temp_baseband_board}")
pw.dlog(FsfwTmTcPrinter.get_validity_buffer(hk_data[8:], 2))
pw.dlog(get_validity_buffer_str(hk_data[8:], 2))
def handle_syrlinks_rx_registers_dataset(pw: PrintWrapper, hk_data: bytes):
def handle_syrlinks_rx_registers_dataset(
hk_info: HkTmInfo,
pw: PrintWrapper,
):
hk_data = hk_info.hk_data
header_list = [
"RX Status",
"RX Sensitivity",
@ -339,17 +364,45 @@ def handle_syrlinks_rx_registers_dataset(pw: PrintWrapper, hk_data: bytes):
validity_buffer = hk_data[22:]
for header, content in zip(header_list, content_list):
pw.dlog(f"{header}: {content}")
pw.dlog(
FsfwTmTcPrinter.get_validity_buffer(validity_buffer=validity_buffer, num_vars=8)
pw.dlog(get_validity_buffer_str(validity_buffer=validity_buffer, num_vars=8))
print(f"Carrier Detect: {carrier_detect}")
print(f"Carrier Lock: {carrier_lock}")
print(f"Data Lock (data clock recovery loop lock status): {data_lock}")
print(f"Data Valid (valid if TEB < 10e-5): {data_valid}")
print(f"Data Lock (data clock recovery loop lock status): {data_lock}")
print(f"RX AGC Inhibit: {rx_agc_inhibit}")
print(f"RX AGC: {rx_agc}")
print(f"Eb / E0RX [dB]: {eb_to_n0}")
cursor = hk_info.db_con.cursor()
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS syrlinks_rx_regs(
packet_uuid TEXT PRIMARY KEY,
generation_time TEXT,
carrier_detect NUM,
carrier_lock NUM,
data_lock NUM,
data_valid NUM,
rx_agc_inhibit NUM,
rx_agc NUM,
eb_to_e0_rx NUM
)"""
)
pw.dlog(f"Carrier Detect: {carrier_detect}")
pw.dlog(f"Carrier Lock: {carrier_lock}")
pw.dlog(f"Data Lock (data clock recovery loop lock status): {data_lock}")
pw.dlog(f"Data Valid (valid if TEB < 10e-5): {data_valid}")
pw.dlog(f"Data Lock (data clock recovery loop lock status): {data_lock}")
pw.dlog(f"RX AGC Inhibit: {rx_agc_inhibit}")
pw.dlog(f"RX AGC: {rx_agc}")
pw.dlog(f"Eb / E0RX [dB]: {eb_to_n0}")
cursor.execute(
"INSERT INTO syrlinks_rx_regs VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)",
(
str(hk_info.packet_uuid),
hk_info.packet_datetime,
carrier_detect,
carrier_lock,
data_lock,
data_valid,
rx_agc_inhibit,
rx_agc,
eb_to_n0,
),
)
hk_info.db_con.commit()
class TxConv(enum.IntEnum):
@ -375,11 +428,11 @@ WAVEFORM_STRINGS = ["OFF", "CW", "QPSK", "0QPSK", "PCM/PM", "PSK/PM", "BPSK"]
def handle_syrlinks_tx_registers_dataset(
hk_info: HkTmInfo,
pw: PrintWrapper,
hk_data: bytes,
):
header_list = ["TX Status Raw", "TX Waveform", "TX AGC value"]
tx_status = hk_data[0]
tx_status = hk_info.hk_data[0]
"""
try:
tx_conv = TxConv(tx_status & 0b111)
@ -397,9 +450,10 @@ def handle_syrlinks_tx_registers_dataset(
logging.getLogger(__name__).warning(
f"invalid TX conf set {(tx_status >> 2) & 0b11}"
)
tx_conf_set = -1
# Hack to make DB insertion work.
tx_conf_set = TxCfgSet.START_WITH_CURRENT_CFG
tx_clock_detect = (tx_status >> 4) & 0b1
tx_waveform = hk_data[1]
tx_waveform = hk_info.hk_data[1]
waveform = tx_waveform & 0b1111
try:
waveform_str = WAVEFORM_STRINGS[waveform]
@ -407,22 +461,56 @@ def handle_syrlinks_tx_registers_dataset(
logging.getLogger(__name__).warning(f"Unknown waveform value {waveform}")
waveform_str = "Unknown"
pcm_mode = (tx_waveform >> 4) & 0b1
tx_agc_value = struct.unpack("!H", hk_data[2:4])[0]
tx_agc_value = struct.unpack("!H", hk_info.hk_data[2:4])[0]
tx_agc_inhibit = (tx_agc_value >> 15) & 0b1
tx_agc = tx_agc_value & 0xFFF
content_list = [tx_status, tx_waveform, tx_agc_value]
validity_buffer = hk_data[4:]
validity_buffer = hk_info.hk_data[4:]
for header, content in zip(header_list, content_list):
pw.dlog(f"{header}: {content}")
pw.dlog(
FsfwTmTcPrinter.get_validity_buffer(validity_buffer=validity_buffer, num_vars=3)
)
pw.dlog(get_validity_buffer_str(validity_buffer=validity_buffer, num_vars=3))
# pw.dlog(f"TX CONV: {tx_conv!r}")
# pw.dlog(f"TX DIFF (differential encoder enable): {tx_diff_encoder_enable}")
pw.dlog(f"TX Status: {tx_status_status!r}")
pw.dlog(f"TX Config Set: {tx_conf_set!r}")
pw.dlog(f"TX Clock Detect: {tx_clock_detect}")
pw.dlog(f"Waveform: {waveform_str}")
pw.dlog(f"PCM Mode: {pcm_mode}")
pw.dlog(f"TX AGC Inhibit: {tx_agc_inhibit}")
pw.dlog(f"TX AGC: {tx_agc}")
print(f"TX Status: {tx_status_status!r}")
print(f"TX Config Set: {tx_conf_set!r}")
print(f"TX Clock Detect: {tx_clock_detect}")
print(f"Waveform: {waveform_str}")
print(f"PCM Mode: {pcm_mode}")
print(f"TX AGC Inhibit: {tx_agc_inhibit}")
print(f"TX AGC: {tx_agc}")
cursor = hk_info.db_con.cursor()
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS syrlinks_tx_regs(
packet_uuid TEXT PRIMARY KEY,
generation_time TEXT,
tx_status NUM,
tx_status_str TEXT,
tx_cfg_set NUM,
tx_cfg_set_str TEXT,
tx_clock_detect NUM,
waveform NUM,
waveform_str TEXT,
pcm_mode NUM,
tx_agc_inhibut NUM,
tx_agc NUM
)"""
)
cursor.execute(
"INSERT INTO syrlinks_tx_regs VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
(
str(hk_info.packet_uuid),
hk_info.packet_datetime,
tx_status_status,
tx_status_status.name,
tx_conf_set,
tx_conf_set.name,
tx_clock_detect,
waveform,
waveform_str,
pcm_mode,
tx_agc_inhibit,
tx_agc,
),
)
hk_info.db_con.commit()

View File

@ -5,11 +5,8 @@ import struct
from pathlib import Path
from typing import Tuple
from eive_tmtc.pus_tm.defs import PrintWrapper
from eive_tmtc.config.definitions import CustomServiceList
from spacepackets.ecss import PusTelecommand
from tmtccmd.config import TmtcDefinitionWrapper
from tmtccmd.config import CmdTreeNode
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
@ -18,9 +15,14 @@ from tmtccmd.pus.s20_fsfw_param import (
create_scalar_u8_parameter,
create_load_param_cmd,
)
from tmtccmd.config.tmtc import OpCodeEntry, tmtc_definitions_provider
from tmtccmd.fsfw.tmtc_printer import get_validity_buffer_str
from tmtccmd.pus.s11_tc_sched import (
create_enable_tc_sched_cmd,
create_disable_tc_sched_cmd,
)
from eive_tmtc.config.object_ids import CORE_CONTROLLER_ID
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from eive_tmtc.pus_tm.defs import PrintWrapper
_LOGGER = logging.getLogger(__name__)
@ -66,6 +68,8 @@ class ActionId(enum.IntEnum):
MV_HELPER = 53
RM_HELPER = 54
MKDIR_HELPER = 55
ENABLE_SCHEDULER = 56
UPDATE_LEAP_SECONRS = 60
class ParamId(enum.IntEnum):
@ -90,20 +94,20 @@ class OpCode:
RM_HELPER = "rm_helper"
MKDIR_HELPER = "mkdir_helper"
SET_PREF_SD = "set_pref_sd"
REBOOT_XSC = ["reboot_xsc"]
XSC_REBOOT_SELF = ["reboot_self"]
XSC_REBOOT_0_0 = ["reboot_00"]
XSC_REBOOT_0_1 = ["reboot_01"]
XSC_REBOOT_1_0 = ["reboot_10"]
XSC_REBOOT_1_1 = ["reboot_11"]
REBOOT_FULL = ["reboot_regular"]
GET_HK = ["get_hk"]
OBSW_UPDATE_FROM_SD_0 = ["obsw_update_sd0"]
OBSW_UPDATE_FROM_SD_1 = ["obsw_update_sd1"]
OBSW_UPDATE_FROM_TMP = ["obsw_update_tmp"]
SWITCH_TO_SD_0 = ["switch_to_sd_0"]
SWITCH_TO_SD_1 = ["switch_to_sd_1"]
SWITCH_TO_BOTH_SD_CARDS = ["switch_to_both_sd_cards"]
REBOOT_XSC = "reboot_xsc"
XSC_REBOOT_SELF = "reboot_self"
XSC_REBOOT_0_0 = "reboot_00"
XSC_REBOOT_0_1 = "reboot_01"
XSC_REBOOT_1_0 = "reboot_10"
XSC_REBOOT_1_1 = "reboot_11"
REBOOT_FULL = "reboot_regular"
GET_HK = "get_hk"
OBSW_UPDATE_FROM_SD_0 = "obsw_update_sd0"
OBSW_UPDATE_FROM_SD_1 = "obsw_update_sd1"
OBSW_UPDATE_FROM_TMP = "obsw_update_tmp"
SWITCH_TO_SD_0 = "switch_to_sd_0"
SWITCH_TO_SD_1 = "switch_to_sd_1"
SWITCH_TO_BOTH_SD_CARDS = "switch_to_both_sd_cards"
READ_REBOOT_MECHANISM_INFO = "rbh_info"
ENABLE_REBOOT_FILE_HANDLING = "rwd_on"
DISABLE_REBOOT_FILE_HANDLING = "rwd_off"
@ -115,6 +119,9 @@ class OpCode:
RWD_SET_MAX_REBOOT_CNT = "rwd_max_cnt"
AUTO_SWITCH_ENABLE = "auto_switch_enable"
AUTO_SWITCH_DISABLE = "auto_switch_disable"
ENABLE_SCHEDULER = "enable_scheduler"
DISABLE_SCHEDULER = "disable_scheduler"
UPDATE_LEAP_SECONDS = "leap_seconds_update"
class Info:
@ -127,6 +134,11 @@ class Info:
SET_PREF_SD = "Set preferred SD card"
REBOOT_XSC = "XSC reboot with prompt"
REBOOT_FULL = "Full regular reboot"
XSC_REBOOT_SELF = "Reboot Self"
XSC_REBOOT_0_0 = "Reboot to 0 0"
XSC_REBOOT_0_1 = "Reboot to 0 1"
XSC_REBOOT_1_0 = "Reboot to 1 0"
XSC_REBOOT_1_1 = "Reboot to 1 1"
OBSW_UPDATE_FROM_SD_0 = "Update OBSW from SD Card 0"
OBSW_UPDATE_FROM_SD_1 = "Update OBSW from SD Card 1"
OBSW_UPDATE_FROM_TMP = "Update OBSW from tmp folder"
@ -140,8 +152,20 @@ class Info:
MV_HELPER = "Filesystem Move Helper"
RM_HELPER = "Filesystem Removal Helper"
MKDIR_HELPER = "Filesystem Directory Creation Helper"
ENABLE_REBOOT_FILE_HANDLING = "Enable reboot file handling"
DISABLE_REBOOT_FILE_HANDLING = "Disable reboot file handling"
RESET_ALL_REBOOT_COUNTERS = "Reset all reboot counters"
RWD_RESET_REBOOT_COUNTER_00 = "Reset reboot counter 0 0"
RWD_RESET_REBOOT_COUNTER_01 = "Reset reboot counter 0 0"
RWD_RESET_REBOOT_COUNTER_10 = "Reset reboot counter 1 0"
GET_HK = "Get HK set"
RWD_RESET_REBOOT_COUNTER_11 = "Reset reboot counter 1 1"
RWD_SET_MAX_REBOOT_CNT = "rwd_max_cnt"
AUTO_SWITCH_ENABLE = "Enable Auto-Switch Feature with a specific target image"
AUTO_SWITCH_DISABLE = "Disable Auto-Switch Feature"
ENABLE_SCHEDULER = "Enable scheduler"
DISABLE_SCHEDULER = "Disable scheduler"
UPDATE_LEAP_SECONDS = "Updates the Leap Seconds"
class Chip(enum.IntEnum):
@ -162,105 +186,35 @@ class SystemctlCmd(enum.IntEnum):
RESTART = 2
@tmtc_definitions_provider
def add_core_controller_definitions(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(keys=OpCode.ANNOUNCE_VERSION, info=Info.ANNOUNCE_VERSION)
oce.add(keys=OpCode.ANNOUNCE_CURRENT_IMAGE, info=Info.ANNOUNCE_CURRENT_IMAGE)
oce.add(keys=OpCode.ANNOUNCE_BOOT_COUNTS, info=Info.ANNOUNCE_BOOT_COUNTS)
oce.add(keys=OpCode.REBOOT_XSC, info=Info.REBOOT_XSC)
oce.add(keys=OpCode.REBOOT_XSC, info=Info.REBOOT_XSC)
oce.add(keys=OpCode.REBOOT_FULL, info=Info.REBOOT_FULL)
oce.add(keys=OpCode.XSC_REBOOT_SELF, info="Reboot Self")
oce.add(keys=OpCode.XSC_REBOOT_0_0, info="Reboot 0 0")
oce.add(keys=OpCode.XSC_REBOOT_0_1, info="Reboot 0 1")
oce.add(keys=OpCode.XSC_REBOOT_1_0, info="Reboot 1 0")
oce.add(keys=OpCode.XSC_REBOOT_1_1, info="Reboot 1 1")
oce.add(keys=OpCode.SET_PREF_SD, info=Info.SET_PREF_SD)
oce.add(
keys=OpCode.READ_REBOOT_MECHANISM_INFO, info=Info.READ_REBOOT_MECHANISM_INFO
)
oce.add(keys=OpCode.OBSW_UPDATE_FROM_TMP, info=Info.OBSW_UPDATE_FROM_TMP)
oce.add(keys=OpCode.OBSW_UPDATE_FROM_SD_0, info=Info.OBSW_UPDATE_FROM_SD_0)
oce.add(keys=OpCode.OBSW_UPDATE_FROM_SD_1, info=Info.OBSW_UPDATE_FROM_SD_1)
oce.add(keys=OpCode.AUTO_SWITCH_ENABLE, info=Info.AUTO_SWITCH_ENABLE)
oce.add(keys=OpCode.AUTO_SWITCH_DISABLE, info=Info.AUTO_SWITCH_DISABLE)
oce.add(keys=OpCode.SYSTEMCTL_CMD_EXECUTOR, info=Info.SYSTEMCTL_CMD_EXECUTOR)
oce.add(
keys=OpCode.EXECUTE_SHELL_CMD_BLOCKING, info=Info.EXECUTE_SHELL_CMD_BLOCKING
)
oce.add(
keys=OpCode.EXECUTE_SHELL_CMD_NON_BLOCKING,
info=Info.EXECUTE_SHELL_CMD_NON_BLOCKING,
)
oce.add(
keys=OpCode.GET_HK,
info="Request housekeeping set",
)
oce.add(
keys=OpCode.ENABLE_REBOOT_FILE_HANDLING,
info="Enable reboot file handling",
)
oce.add(
keys=OpCode.DISABLE_REBOOT_FILE_HANDLING,
info="Disable reboot file handling",
)
oce.add(
keys=OpCode.RESET_ALL_REBOOT_COUNTERS,
info="Reset all reboot counters",
)
oce.add(
keys=OpCode.RWD_RESET_REBOOT_COUNTER_00,
info="Reset reboot counter 0 0",
)
oce.add(
keys=OpCode.RWD_RESET_REBOOT_COUNTER_01,
info="Reset reboot counter 0 1",
)
oce.add(
keys=OpCode.RWD_RESET_REBOOT_COUNTER_10,
info="Reset reboot counter 1 0",
)
oce.add(
keys=OpCode.RWD_RESET_REBOOT_COUNTER_11,
info="Reset reboot counter 1 1",
)
oce.add(
keys=OpCode.RWD_SET_MAX_REBOOT_CNT,
info="Reset max reboot count for reboot watchdog",
)
oce.add(keys=OpCode.OBSW_UPDATE_FROM_SD_0, info=Info.OBSW_UPDATE_FROM_SD_0)
oce.add(keys=OpCode.OBSW_UPDATE_FROM_SD_1, info=Info.OBSW_UPDATE_FROM_SD_1)
oce.add(keys=OpCode.OBSW_UPDATE_FROM_TMP, info=Info.OBSW_UPDATE_FROM_TMP)
oce.add(keys=OpCode.SWITCH_TO_SD_0, info=Info.SWITCH_TO_SD_0)
oce.add(keys=OpCode.SWITCH_TO_SD_1, info=Info.SWITCH_TO_SD_1)
oce.add(keys=OpCode.SWITCH_TO_BOTH_SD_CARDS, info=Info.SWITCH_TO_BOTH_SD_CARDS)
oce.add(keys=OpCode.LIST_DIR_INTO_FILE, info=Info.LIST_DIR_INTO_FILE)
oce.add(keys=OpCode.LIST_DIR_DUMP_DIRECTLY, info=Info.LIST_DIR_DUMP_DIRECTLY)
oce.add(keys=OpCode.MV_HELPER, info=Info.MV_HELPER)
oce.add(keys=OpCode.CP_HELPER, info=Info.CP_HELPER)
oce.add(keys=OpCode.RM_HELPER, info=Info.RM_HELPER)
oce.add(keys=OpCode.MKDIR_HELPER, info=Info.MKDIR_HELPER)
defs.add_service(CustomServiceList.CORE.value, "Core Controller", oce)
def create_core_node() -> CmdTreeNode:
op_code_strs = [
getattr(OpCode, key) for key in dir(OpCode) if not key.startswith("__")
]
info_strs = [getattr(Info, key) for key in dir(OpCode) if not key.startswith("__")]
combined_dict = dict(zip(op_code_strs, info_strs))
node = CmdTreeNode("core", "Core Controller", hide_children_for_print=True)
for op_code, info in combined_dict.items():
node.add_child(CmdTreeNode(op_code, info))
return node
def pack_core_commands( # noqa C901
q: DefaultPusQueueHelper, op_code: str
q: DefaultPusQueueHelper, cmd_str: str
): # noqa: C901 , complexity okay here
if op_code == OpCode.ANNOUNCE_VERSION:
if cmd_str == OpCode.ANNOUNCE_VERSION:
q.add_log_cmd(f"{Info.ANNOUNCE_VERSION}")
q.add_pus_tc(create_action_cmd(CORE_CONTROLLER_ID, ActionId.ANNOUNCE_VERSION))
elif op_code == OpCode.ANNOUNCE_CURRENT_IMAGE:
elif cmd_str == OpCode.ANNOUNCE_CURRENT_IMAGE:
q.add_log_cmd(f"{Info.ANNOUNCE_CURRENT_IMAGE}")
q.add_pus_tc(
create_action_cmd(CORE_CONTROLLER_ID, ActionId.ANNOUNCE_CURRENT_IMAGE)
)
elif op_code == OpCode.ANNOUNCE_BOOT_COUNTS:
elif cmd_str == OpCode.ANNOUNCE_BOOT_COUNTS:
q.add_log_cmd(f"{Info.ANNOUNCE_BOOT_COUNTS}")
q.add_pus_tc(
create_action_cmd(CORE_CONTROLLER_ID, ActionId.ANNOUNCE_BOOT_COUNTS)
)
elif op_code in OpCode.REBOOT_XSC:
elif cmd_str == OpCode.REBOOT_XSC:
reboot_self, chip_select, copy_select = determine_reboot_params()
add_xsc_reboot_cmd(
q=q,
@ -268,16 +222,16 @@ def pack_core_commands( # noqa C901
chip=chip_select,
copy=copy_select,
)
elif op_code in OpCode.REBOOT_FULL:
elif cmd_str == OpCode.REBOOT_FULL:
q.add_log_cmd(f"Core Command: {Info.REBOOT_FULL}")
q.add_pus_tc(
create_action_cmd(
object_id=CORE_CONTROLLER_ID, action_id=ActionId.FULL_REBOOT
)
)
elif op_code in OpCode.XSC_REBOOT_SELF:
elif cmd_str == OpCode.XSC_REBOOT_SELF:
add_xsc_reboot_cmd(q=q, reboot_self=True)
elif op_code == OpCode.SYSTEMCTL_CMD_EXECUTOR:
elif cmd_str == OpCode.SYSTEMCTL_CMD_EXECUTOR:
print("systemctl command types: ")
for entry in SystemctlCmd:
print(f"{entry}: {entry.name}")
@ -286,7 +240,7 @@ def pack_core_commands( # noqa C901
)
unit_name = input("Specify unit name: ")
q.add_pus_tc(create_systemctl_cmd(systemctl_cmd, unit_name))
elif op_code == OpCode.EXECUTE_SHELL_CMD_BLOCKING:
elif cmd_str == OpCode.EXECUTE_SHELL_CMD_BLOCKING:
custom_cmd = input("Please specify command to execute: ")
q.add_pus_tc(
create_action_cmd(
@ -295,7 +249,7 @@ def pack_core_commands( # noqa C901
user_data=custom_cmd.encode(),
)
)
elif op_code == OpCode.EXECUTE_SHELL_CMD_NON_BLOCKING:
elif cmd_str == OpCode.EXECUTE_SHELL_CMD_NON_BLOCKING:
custom_cmd = input("Please specify command to execute: ")
q.add_pus_tc(
create_action_cmd(
@ -304,29 +258,29 @@ def pack_core_commands( # noqa C901
user_data=custom_cmd.encode(),
)
)
elif op_code in OpCode.XSC_REBOOT_0_0:
elif cmd_str == OpCode.XSC_REBOOT_0_0:
add_xsc_reboot_cmd(
q=q, reboot_self=False, chip=Chip.CHIP_0, copy=Copy.COPY_0_NOM
)
elif op_code in OpCode.XSC_REBOOT_0_1:
elif cmd_str == OpCode.XSC_REBOOT_0_1:
add_xsc_reboot_cmd(
q=q,
reboot_self=False,
chip=Chip.CHIP_0,
copy=Copy.COPY_1_GOLD,
)
elif op_code in OpCode.XSC_REBOOT_1_0:
elif cmd_str == OpCode.XSC_REBOOT_1_0:
add_xsc_reboot_cmd(
q=q, reboot_self=False, chip=Chip.CHIP_1, copy=Copy.COPY_0_NOM
)
elif op_code in OpCode.XSC_REBOOT_1_1:
elif cmd_str == OpCode.XSC_REBOOT_1_1:
add_xsc_reboot_cmd(
q=q,
reboot_self=False,
chip=Chip.CHIP_1,
copy=Copy.COPY_1_GOLD,
)
elif op_code == OpCode.READ_REBOOT_MECHANISM_INFO:
elif cmd_str == OpCode.READ_REBOOT_MECHANISM_INFO:
q.add_log_cmd(Info.READ_REBOOT_MECHANISM_INFO)
q.add_pus_tc(
create_action_cmd(
@ -334,7 +288,7 @@ def pack_core_commands( # noqa C901
action_id=ActionId.READ_REBOOT_MECHANISM_INFO,
)
)
elif op_code == OpCode.DISABLE_REBOOT_FILE_HANDLING:
elif cmd_str == OpCode.DISABLE_REBOOT_FILE_HANDLING:
q.add_log_cmd("Disabling reboot file handling")
user_data = bytearray([0])
q.add_pus_tc(
@ -344,7 +298,7 @@ def pack_core_commands( # noqa C901
user_data=user_data,
)
)
elif op_code == OpCode.ENABLE_REBOOT_FILE_HANDLING:
elif cmd_str == OpCode.ENABLE_REBOOT_FILE_HANDLING:
q.add_log_cmd("Enabling reboot file handling")
user_data = bytearray([1])
q.add_pus_tc(
@ -354,7 +308,7 @@ def pack_core_commands( # noqa C901
user_data=user_data,
)
)
elif op_code == OpCode.RESET_ALL_REBOOT_COUNTERS:
elif cmd_str == OpCode.RESET_ALL_REBOOT_COUNTERS:
q.add_log_cmd("Resetting all reboot counters")
q.add_pus_tc(
create_action_cmd(
@ -362,15 +316,15 @@ def pack_core_commands( # noqa C901
action_id=ActionId.RESET_REBOOT_COUNTER,
)
)
elif op_code == OpCode.RWD_RESET_REBOOT_COUNTER_00:
elif cmd_str == OpCode.RWD_RESET_REBOOT_COUNTER_00:
reset_specific_boot_counter(q, 0, 0)
elif op_code == OpCode.RWD_RESET_REBOOT_COUNTER_01:
elif cmd_str == OpCode.RWD_RESET_REBOOT_COUNTER_01:
reset_specific_boot_counter(q, 0, 1)
elif op_code == OpCode.RWD_RESET_REBOOT_COUNTER_10:
elif cmd_str == OpCode.RWD_RESET_REBOOT_COUNTER_10:
reset_specific_boot_counter(q, 1, 0)
elif op_code == OpCode.RWD_RESET_REBOOT_COUNTER_11:
elif cmd_str == OpCode.RWD_RESET_REBOOT_COUNTER_11:
reset_specific_boot_counter(q, 1, 1)
elif op_code == OpCode.RWD_SET_MAX_REBOOT_CNT:
elif cmd_str == OpCode.RWD_SET_MAX_REBOOT_CNT:
max_count = int(input("Set new maximum reboot threshold [1, 50]: "))
if max_count < 1 or max_count > 50:
raise ValueError("Invalid value, must be in range 1 to 50")
@ -381,16 +335,16 @@ def pack_core_commands( # noqa C901
user_data=bytes([max_count]),
)
)
elif op_code in OpCode.OBSW_UPDATE_FROM_SD_0:
elif cmd_str == OpCode.OBSW_UPDATE_FROM_SD_0:
q.add_log_cmd(Info.OBSW_UPDATE_FROM_SD_0)
q.add_pus_tc(pack_obsw_update_cmd(ActionId.UPDATE_OBSW_FROM_SD_0))
elif op_code in OpCode.OBSW_UPDATE_FROM_SD_1:
elif cmd_str == OpCode.OBSW_UPDATE_FROM_SD_1:
q.add_log_cmd(Info.OBSW_UPDATE_FROM_SD_1)
q.add_pus_tc(pack_obsw_update_cmd(ActionId.UPDATE_OBSW_FROM_SD_1))
elif op_code in OpCode.OBSW_UPDATE_FROM_TMP:
elif cmd_str == OpCode.OBSW_UPDATE_FROM_TMP:
q.add_log_cmd(Info.OBSW_UPDATE_FROM_TMP)
q.add_pus_tc(pack_obsw_update_cmd(ActionId.UPDATE_OBSW_FROM_TMP))
elif op_code in OpCode.AUTO_SWITCH_ENABLE:
elif cmd_str == OpCode.AUTO_SWITCH_ENABLE:
q.add_log_cmd(Info.AUTO_SWITCH_ENABLE)
chip, copy = determine_chip_and_copy()
user_data = bytes([chip, copy])
@ -399,26 +353,26 @@ def pack_core_commands( # noqa C901
CORE_CONTROLLER_ID, ActionId.AUTO_SWITCH_ENABLE, user_data
)
)
elif op_code in OpCode.AUTO_SWITCH_DISABLE:
elif cmd_str == OpCode.AUTO_SWITCH_DISABLE:
q.add_log_cmd(Info.AUTO_SWITCH_DISABLE)
q.add_pus_tc(
create_action_cmd(CORE_CONTROLLER_ID, ActionId.AUTO_SWITCH_DISABLE)
)
elif op_code in OpCode.SWITCH_TO_SD_0:
elif cmd_str == OpCode.SWITCH_TO_SD_0:
q.add_log_cmd(Info.SWITCH_TO_SD_0)
q.add_pus_tc(
create_action_cmd(
object_id=CORE_CONTROLLER_ID, action_id=ActionId.SWITCH_TO_SD_0
)
)
elif op_code in OpCode.SWITCH_TO_SD_1:
elif cmd_str == OpCode.SWITCH_TO_SD_1:
q.add_log_cmd(Info.SWITCH_TO_SD_1)
q.add_pus_tc(
create_action_cmd(
object_id=CORE_CONTROLLER_ID, action_id=ActionId.SWITCH_TO_SD_1
)
)
elif op_code in OpCode.SWITCH_TO_BOTH_SD_CARDS:
elif cmd_str == OpCode.SWITCH_TO_BOTH_SD_CARDS:
while True:
active_sd_card = int(input("Please specify active SD card [0/1]: "))
if active_sd_card not in [0, 1]:
@ -432,11 +386,11 @@ def pack_core_commands( # noqa C901
user_data=bytes([active_sd_card]),
)
)
elif op_code in OpCode.GET_HK:
elif cmd_str == OpCode.GET_HK:
q.add_log_cmd("Requesting housekeeping set")
sid = make_sid(object_id=CORE_CONTROLLER_ID, set_id=SetId.HK)
q.add_pus_tc(generate_one_hk_command(sid))
elif op_code in OpCode.SET_PREF_SD:
elif cmd_str == OpCode.SET_PREF_SD:
q.add_log_cmd("Set preferred SD card")
pref_sd = int(
input("Specify which SD card to set as the preferred one (0/1): ")
@ -445,15 +399,16 @@ def pack_core_commands( # noqa C901
raise ValueError("Only 0 or 1 allowed for preferred SD card")
q.add_pus_tc(
create_load_param_cmd(
create_scalar_u8_parameter(
parameter=create_scalar_u8_parameter(
object_id=CORE_CONTROLLER_ID,
domain_id=0,
unique_id=ParamId.PREF_SD,
parameter=pref_sd,
)
),
apid=0,
)
)
elif op_code == OpCode.CP_HELPER:
elif cmd_str == OpCode.CP_HELPER:
cp_recursive = int(input("Copy recursively (0/1) ?: "))
if cp_recursive not in [0, 1]:
raise ValueError("Invalid value, only 0 or 1 allowed")
@ -466,13 +421,13 @@ def pack_core_commands( # noqa C901
q.add_pus_tc(
create_action_cmd(CORE_CONTROLLER_ID, ActionId.CP_HELPER, user_data)
)
elif op_code == OpCode.MV_HELPER:
elif cmd_str == OpCode.MV_HELPER:
user_data = packet_source_dest_path("Move")
q.add_log_cmd(Info.MV_HELPER)
q.add_pus_tc(
create_action_cmd(CORE_CONTROLLER_ID, ActionId.MV_HELPER, user_data)
)
elif op_code == OpCode.RM_HELPER:
elif cmd_str == OpCode.RM_HELPER:
rm_recursive = int(input("Remove with recursive (-r) option (0/1) ?: "))
if rm_recursive not in [0, 1]:
raise ValueError("Invalid value, only 0 or 1 allowed")
@ -487,7 +442,7 @@ def pack_core_commands( # noqa C901
q.add_pus_tc(
create_action_cmd(CORE_CONTROLLER_ID, ActionId.RM_HELPER, user_data)
)
elif op_code == OpCode.LIST_DIR_INTO_FILE:
elif cmd_str == OpCode.LIST_DIR_INTO_FILE:
q.add_log_cmd(Info.LIST_DIR_INTO_FILE)
user_data = list_directory_base_user_data()
dest_file_path = input("Destination file path: ")
@ -498,7 +453,7 @@ def pack_core_commands( # noqa C901
CORE_CONTROLLER_ID, ActionId.LIST_DIR_INTO_FILE, user_data
)
)
elif op_code == OpCode.LIST_DIR_DUMP_DIRECTLY:
elif cmd_str == OpCode.LIST_DIR_DUMP_DIRECTLY:
q.add_log_cmd(Info.LIST_DIR_DUMP_DIRECTLY)
user_data = list_directory_base_user_data()
q.add_pus_tc(
@ -506,7 +461,7 @@ def pack_core_commands( # noqa C901
CORE_CONTROLLER_ID, ActionId.LIST_DIR_DUMP_DIRECTLY, user_data
)
)
elif op_code == OpCode.MKDIR_HELPER:
elif cmd_str == OpCode.MKDIR_HELPER:
q.add_log_cmd(Info.MKDIR_HELPER)
user_data = input("Specify absolute path of newly created directory: ")
user_data = bytearray(user_data.encode())
@ -514,9 +469,25 @@ def pack_core_commands( # noqa C901
q.add_pus_tc(
create_action_cmd(CORE_CONTROLLER_ID, ActionId.MKDIR_HELPER, user_data)
)
elif cmd_str == OpCode.ENABLE_SCHEDULER:
q.add_log_cmd(Info.ENABLE_SCHEDULER)
q.add_pus_tc(create_enable_tc_sched_cmd())
elif cmd_str == OpCode.DISABLE_SCHEDULER:
q.add_log_cmd(Info.DISABLE_SCHEDULER)
q.add_pus_tc(create_disable_tc_sched_cmd())
elif cmd_str == OpCode.UPDATE_LEAP_SECONDS:
q.add_log_cmd(Info.UPDATE_LEAP_SECONDS)
leap_seconds = int(input("Specify new Leap Seconds Value: ")).to_bytes(
length=2, signed=False, byteorder="big"
)
q.add_pus_tc(
create_action_cmd(
CORE_CONTROLLER_ID, ActionId.UPDATE_LEAP_SECONRS, leap_seconds
)
)
else:
_LOGGER.warning(
f"Unknown operation code {op_code} for core controller commands"
f"Unknown operation code {cmd_str} for core controller commands"
)
@ -662,9 +633,7 @@ def handle_core_hk_data(pw: PrintWrapper, set_id: int, hk_data: bytes):
f"PL Voltage [mV] {pl_voltage}"
)
pw.dlog(printout)
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=hk_data[inc_len:], num_vars=3
)
pw.dlog(get_validity_buffer_str(validity_buffer=hk_data[inc_len:], num_vars=3))
def handle_core_ctrl_action_replies(

View File

@ -1,14 +1,12 @@
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.tmtc.obj_prompt import prompt_object
from spacepackets.ecss import PusTelecommand
from tmtccmd.config.tmtc import (
tmtc_definitions_provider,
TmtcDefinitionWrapper,
OpCodeEntry,
CmdTreeNode,
)
from tmtccmd.tmtc import service_provider
from tmtccmd.pus.s201_fsfw_health import Subservice, FsfwHealth
from tmtccmd.tmtc.decorator import ServiceProviderParams
from tmtccmd.pus.s201_fsfw_health import FsfwHealth, Subservice
from tmtccmd.tmtc import DefaultPusQueueHelper
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.tmtc.obj_prompt import prompt_object
class OpCode:
@ -30,11 +28,8 @@ def prompt_health() -> FsfwHealth:
return FsfwHealth(health_idx)
@service_provider(CustomServiceList.HEALTH)
def pack_test_command(p: ServiceProviderParams):
o = p.op_code
q = p.queue_helper
if o == OpCode.SET_HEALTH:
def build_health_cmds(q: DefaultPusQueueHelper, cmd_str: str):
if cmd_str == OpCode.SET_HEALTH:
app_data = bytearray(prompt_object())
health = prompt_health()
app_data.append(health)
@ -44,7 +39,7 @@ def pack_test_command(p: ServiceProviderParams):
service=201, subservice=Subservice.TC_SET_HEALTH, app_data=app_data
)
)
elif o == OpCode.ANNOUNCE_HEALTH:
elif cmd_str == OpCode.ANNOUNCE_HEALTH:
app_data = bytearray(prompt_object())
q.add_log_cmd(Info.ANNOUNCE_HEALTH)
q.add_pus_tc(
@ -52,19 +47,22 @@ def pack_test_command(p: ServiceProviderParams):
service=201, subservice=Subservice.TC_ANNOUNCE_HEALTH, app_data=app_data
)
)
elif o == OpCode.ANNOUNCE_HEALTH_ALL:
elif cmd_str == OpCode.ANNOUNCE_HEALTH_ALL:
q.add_log_cmd(Info.ANNOUNCE_HEALTH_ALL)
q.add_pus_tc(
PusTelecommand(service=201, subservice=Subservice.TC_ANNOUNCE_HEALTH_ALL)
)
else:
raise ValueError(f"unknown op code {o} for service {CustomServiceList.HEALTH}")
raise ValueError(
f"unknown command string {cmd_str} for service {CustomServiceList.HEALTH}"
)
@tmtc_definitions_provider
def add_health_cmd_defs(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(OpCode.ANNOUNCE_HEALTH_ALL, Info.ANNOUNCE_HEALTH_ALL)
oce.add(OpCode.ANNOUNCE_HEALTH, Info.ANNOUNCE_HEALTH)
oce.add(OpCode.SET_HEALTH, Info.SET_HEALTH)
defs.add_service(CustomServiceList.HEALTH, info="Health Service", op_code_entry=oce)
def create_global_health_node() -> CmdTreeNode:
health_node = CmdTreeNode("health", "Health Commands")
health_node.add_child(
CmdTreeNode(OpCode.ANNOUNCE_HEALTH_ALL, Info.ANNOUNCE_HEALTH_ALL)
)
health_node.add_child(CmdTreeNode(OpCode.ANNOUNCE_HEALTH, Info.ANNOUNCE_HEALTH))
health_node.add_child(CmdTreeNode(OpCode.SET_HEALTH, Info.SET_HEALTH))
return health_node

View File

@ -1,9 +1,8 @@
import enum
import struct
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from eive_tmtc.pus_tm.defs import PrintWrapper
from tmtccmd.fsfw.tmtc_printer import get_validity_buffer_str
class SetId(enum.IntEnum):
@ -21,4 +20,4 @@ def handle_ier_hk_data(pw: PrintWrapper, hk_data: bytes, set_id: int):
pw.dlog(f"TM Errors: {tm_errors}")
pw.dlog(f"Queue Errors: {queue_errors}")
pw.dlog(f"Store Errors: {store_hits}")
pw.dlog(FsfwTmTcPrinter.get_validity_buffer(hk_data[inc_len:], 3))
pw.dlog(get_validity_buffer_str(hk_data[inc_len:], 3))

View File

@ -4,7 +4,10 @@ from eive_tmtc.config.object_ids import (
GPS_0_HEALTH_DEV,
GYRO_0_ADIS_HANDLER_ID,
GYRO_1_L3G_HANDLER_ID,
GYRO_2_ADIS_HANDLER_ID,
ACS_BOARD_ASS_ID,
PLOC_MPSOC_ID,
PLOC_SUPV_ID,
RW_ASSEMBLY,
SUS_BOARD_ASS_ID,
MGM_0_LIS3_HANDLER_ID,
@ -27,6 +30,7 @@ SUBSYSTEM_DICT = {
0: "acs",
1: "tcs",
2: "com",
3: "payload",
}
ACS_OBJ_DICT = {
@ -38,14 +42,15 @@ ACS_OBJ_DICT = {
5: ("iMTQ MGT", IMTQ_HANDLER_ID),
6: ("GYR 0 ADIS", GYRO_0_ADIS_HANDLER_ID),
7: ("GYR 1 L3G", GYRO_1_L3G_HANDLER_ID),
8: ("MGM 0 LIS3", MGM_0_LIS3_HANDLER_ID),
9: ("MGM 1 RM3100", MGM_1_RM3100_HANDLER_ID),
10: ("GPS 0 Health Device", GPS_0_HEALTH_DEV),
11: ("SUS 0", SUS_0_N_LOC_XFYFZM_PT_XF),
12: ("SUS 6", SUS_6_R_LOC_XFYBZM_PT_XF),
13: ("RW 1", RW1_ID),
14: ("RW 2", RW2_ID),
15: ("STR", STAR_TRACKER_ID),
8: ("GYR 2 ADIS", GYRO_2_ADIS_HANDLER_ID),
9: ("MGM 0 LIS3", MGM_0_LIS3_HANDLER_ID),
10: ("MGM 1 RM3100", MGM_1_RM3100_HANDLER_ID),
11: ("GPS 0 Health Device", GPS_0_HEALTH_DEV),
12: ("SUS 0", SUS_0_N_LOC_XFYFZM_PT_XF),
13: ("SUS 6", SUS_6_R_LOC_XFYBZM_PT_XF),
14: ("RW 1", RW1_ID),
15: ("RW 2", RW2_ID),
16: ("STR", STAR_TRACKER_ID),
}
TCS_OBJ_DICT = {
@ -57,6 +62,11 @@ TCS_OBJ_DICT = {
5: ("TMP1075 IF BOARD", TMP1075_HANDLER_IF_BRD_ID),
}
PAYLOAD_OBJ_DICT = {
0: ("Payload MPSoC", PLOC_MPSOC_ID),
1: ("Payload Supervisor", PLOC_SUPV_ID),
}
def get_obj_if_from_dict(lut: dict) -> bytes:
for k, v in lut.items():
@ -79,6 +89,8 @@ def prompt_object() -> bytes:
return get_obj_if_from_dict(ACS_OBJ_DICT)
elif subsystem == "tcs":
return get_obj_if_from_dict(TCS_OBJ_DICT)
elif subsystem == "payload":
return get_obj_if_from_dict(PAYLOAD_OBJ_DICT)
else:
print(f"No object for subsystem {subsystem}")
return bytes()

View File

@ -11,25 +11,24 @@ import logging
import struct
import enum
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.config.object_ids import get_object_ids, PLOC_MPSOC_ID
from eive_tmtc.pus_tm.defs import PrintWrapper
from tmtccmd.config.tmtc import (
tmtc_definitions_provider,
OpCodeEntry,
TmtcDefinitionWrapper,
CmdTreeNode,
)
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.tmtc import service_provider
from tmtccmd.tmtc.decorator import ServiceProviderParams
from tmtccmd.tmtc import DefaultPusQueueHelper
from eive_tmtc.utility.input_helper import InputHelper
from tmtccmd.pus.s200_fsfw_mode import pack_mode_data, Mode
from tmtccmd.pus.s200_fsfw_mode import pack_mode_data, Mode, create_mode_command
from tmtccmd.pus.s20_fsfw_param import create_load_param_cmd, create_scalar_u8_parameter
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
_LOGGER = logging.getLogger(__name__)
MANUAL_INPUT = "1"
CRIT_CMD_APID_DICT = {"1": ("flash_mkfs", 0x12A)}
OBC_WRITE_FILE_DICT = {
MANUAL_INPUT: ("manual input", ""),
"2": ("/mnt/sd0/ploc/mpsoc/flash_write.bin", "/mnt/sd0/ploc/mpsoc/flash_write.bin"),
@ -85,12 +84,26 @@ class ActionId(enum.IntEnum):
SET_UART_TX_TRISTATE = 20
RELEASE_UART_TX = 21
TC_CAM_TAKE_PIC = 22
TC_SIMPLEX_SEND_FILE = 23
TC_SIMPLEX_STREAM_FILE = 23
TC_DOWNLINK_DATA_MODULATE = 24
TC_MODE_SNAPSHOT = 25
TC_FLASH_DIR_GET_CONTENT = 28
TM_FLASH_DIRECTORY_CONTENT = 29
TC_FLASH_READ_FULL_FILE = 30
TC_SPLIT_FILE = 31
TC_VERIFY_BOOT = 32
TC_ENABLE_TC_EXECUTION = 33
TC_FLASH_MKFS = 34
class Submode(enum.IntEnum):
IDLE_OR_NONE = 0
REPLAY = 1
SNAPSHOT = 2
class ParamId(enum.IntEnum):
PLOC_SUPV_SKIP_CMD_TO_ON = 1
class OpCode:
@ -98,8 +111,6 @@ class OpCode:
OFF = "off"
NORMAL = "normal"
VERIFY_BOOT = "verify_boot"
MODE_REPLAY = "mode_replay"
MODE_IDLE = "mode_idle"
REPLAY_WRITE_SEQ = "replay_write"
DOWNLINK_PWR_ON = "downlink_pwr_on"
MEM_WRITE = "memory_write"
@ -111,10 +122,18 @@ class OpCode:
FLASH_GET_DIR_CONTENT = "flash_get_dir_content"
REPLAY_STOP = "replay_stop"
REPLAY_START = "replay_start"
CAM_CMD_SEND = "cam_cmd_send"
CAM_TAKE_PIC = "cam_take_pic"
SIMPLEX_SEND_FILE = "simplex_send_file"
SIMPLEX_STREAM_FILE = "simplex_stream_file"
SPLIT_FILE = "split_file"
DOWNLINK_DATA_MODULATE = "downlink_data_modulate"
ENABLE_PLOC_SUPV_COMMANDING_TO_ON = "enable_ploc_supv_cmd_to_on"
DISABLE_PLOC_SUPV_COMMANDING_TO_ON = "disable_ploc_supv_cmd_to_on"
MODE_IDLE = "mode_idle"
MODE_REPLAY = "mode_replay"
MODE_SNAPSHOT = "mode_snapshot"
ENABLE_TC_EXECUTION = "enable_tc_exec"
FLASH_MKFS = "flash_mkfs"
class Info:
@ -128,77 +147,66 @@ class Info:
REPLAY_WRITE_SEQ = "Replay write sequence"
DOWNLINK_PWR_ON = "Downlink Power On"
DOWNLINK_PWR_OFF = "Downlink Power Off"
MEM_WRITE = "Write to Memory"
MEM_READ = "Read from Memory"
REPLAY_START = "Replay Start"
CAM_TAKE_PIC = "Cam Take Picture"
SIMPLEX_SEND_FILE = "Simplex Send File"
CAM_CMD_SEND = "Send Camera Command"
SIMPLEX_STREAM_FILE = "Simplex Stream File with E-Band"
SPLIT_FILE = "Split file on MPSoC Flash"
FLASH_READ_FILE = "Copy file from MPSoC to OBC"
FLASH_WRITE_FILE = "Copy file from OBC to MPSoC"
FLASH_DELETE_FILE = "Delete file on MPSoC"
FLASH_GET_DIR_CONTENT = "Get flash directory content on MPSoC"
DOWNLINK_DATA_MODULATE = "Downlink data modulate"
MODE_SNAPSHOT = "Mode Snapshot"
ENABLE_PLOC_SUPV_COMMANDING_TO_ON = "Enable PLOC SUPV commanding when switching ON"
DISABLE_PLOC_SUPV_COMMANDING_TO_ON = (
"Disable PLOC SUPV commanding when switching ON"
)
ENABLE_TC_EXECUTION = "Enable execution of critical commands"
FLASH_MKFS = "Flash MKFS command"
class MemAddresses(enum.IntEnum):
DEADBEEF = 0x40000004
@tmtc_definitions_provider
def add_ploc_mpsoc_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(OpCode.OFF, Info.OFF)
oce.add(OpCode.ON, Info.ON)
oce.add(OpCode.NORMAL, Info.NORMAL)
oce.add(OpCode.MEM_WRITE, "Ploc MPSoC: Memory write")
oce.add(OpCode.MEM_READ, "Ploc MPSoC: Memory read")
oce.add(OpCode.FLASH_WRITE_FILE, Info.FLASH_WRITE_FILE)
oce.add(OpCode.FLASH_READ_FILE, Info.FLASH_READ_FILE)
oce.add(OpCode.FLASH_DELETE_FILE, Info.FLASH_DELETE_FILE)
oce.add(OpCode.FLASH_GET_DIR_CONTENT, Info.FLASH_GET_DIR_CONTENT)
oce.add(OpCode.REPLAY_START, Info.REPLAY_START)
oce.add(OpCode.REPLAY_STOP, Info.REPLAY_STOP)
oce.add(OpCode.DOWNLINK_PWR_ON, Info.DOWNLINK_PWR_ON)
oce.add(OpCode.DOWNLINK_PWR_OFF, Info.DOWNLINK_PWR_OFF)
oce.add(OpCode.REPLAY_WRITE_SEQ, Info.REPLAY_WRITE_SEQ)
oce.add("12", "Ploc MPSoC: OBSW reset sequence count")
oce.add(OpCode.VERIFY_BOOT, Info.VERIFY_BOOT)
oce.add(OpCode.MODE_REPLAY, Info.MODE_REPLAY)
oce.add(OpCode.MODE_IDLE, Info.MODE_IDLE)
oce.add("16", "Ploc MPSoC: Tc cam command send")
oce.add("17", "Ploc MPSoC: Set UART TX tristate")
oce.add("18", "Ploc MPSoC: Relesase UART TX")
oce.add(OpCode.CAM_TAKE_PIC, Info.CAM_TAKE_PIC)
oce.add(OpCode.SIMPLEX_SEND_FILE, Info.SIMPLEX_SEND_FILE)
oce.add(OpCode.DOWNLINK_DATA_MODULATE, Info.DOWNLINK_DATA_MODULATE)
oce.add(OpCode.MODE_SNAPSHOT, Info.MODE_SNAPSHOT)
defs.add_service(CustomServiceList.PLOC_MPSOC.value, "Ploc MPSoC", oce)
def create_ploc_mpsoc_node() -> CmdTreeNode:
op_code_strs = [
getattr(OpCode, key) for key in dir(OpCode) if not key.startswith("__")
]
info_strs = [getattr(Info, key) for key in dir(OpCode) if not key.startswith("__")]
combined_dict = dict(zip(op_code_strs, info_strs))
node = CmdTreeNode("ploc_mpsoc", "PLOC MPSoC", hide_children_for_print=True)
for op_code, info in combined_dict.items():
node.add_child(CmdTreeNode(op_code, info))
return node
@service_provider(CustomServiceList.PLOC_MPSOC)
def pack_ploc_mpsoc_commands( # noqa C901
p: ServiceProviderParams,
def pack_ploc_mpsoc_commands(
q: DefaultPusQueueHelper, cmd_str: str
): # noqa C901: Complexity okay here.
object_id = get_object_ids().get(PLOC_MPSOC_ID)
q = p.queue_helper
assert object_id is not None
prefix = "PLOC MPSoC"
op_code = p.op_code
q.add_log_cmd(
f"Generate command for PLOC MPSoC with object id: {object_id.as_hex_string}"
)
obyt = object_id.as_bytes
if op_code == OpCode.OFF:
if cmd_str == OpCode.OFF:
q.add_log_cmd(f"{prefix}: {Info.OFF}")
command = pack_mode_data(obyt, Mode.OFF, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=command))
if op_code == OpCode.ON:
if cmd_str == OpCode.ON:
q.add_log_cmd(f"{prefix}: {Info.ON}")
data = pack_mode_data(obyt, Mode.ON, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=data))
if op_code == OpCode.NORMAL:
if cmd_str == OpCode.NORMAL:
q.add_log_cmd(f"{prefix}: {Info.NORMAL}")
data = pack_mode_data(object_id.as_bytes, Mode.NORMAL, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=data))
if op_code == OpCode.MEM_WRITE:
if cmd_str == OpCode.MEM_WRITE:
q.add_log_cmd("PLOC MPSoC: TC mem write test")
memory_address = int(
input("PLOC MPSoC: Tc Mem Write: Type memory address: 0x"), 16
@ -210,39 +218,35 @@ def pack_ploc_mpsoc_commands( # noqa C901
object_id.as_bytes, memory_address, memory_data, mem_len
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "4":
q.add_log_cmd("PLOC MPSoC: TC mem read test")
data = prepare_mem_read_command(object_id=object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.FLASH_WRITE_FILE:
if cmd_str == OpCode.FLASH_WRITE_FILE:
q.add_log_cmd(f"{prefix}: {Info.FLASH_WRITE_FILE}")
data = prepare_flash_write_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.FLASH_READ_FILE:
if cmd_str == OpCode.FLASH_READ_FILE:
q.add_log_cmd(f"{prefix}: {Info.FLASH_READ_FILE}")
data = prepare_flash_read_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.FLASH_DELETE_FILE:
if cmd_str == OpCode.FLASH_DELETE_FILE:
q.add_log_cmd("PLOC MPSoC: Flash delete")
data = prepare_flash_delete_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code in OpCode.REPLAY_START:
if cmd_str in OpCode.REPLAY_START:
q.add_log_cmd(f"{prefix}: {Info.REPLAY_START}")
data = prepare_replay_start_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.REPLAY_STOP:
if cmd_str == OpCode.REPLAY_STOP:
q.add_log_cmd("PLOC MPSoC: Replay stop")
data = object_id.as_bytes + struct.pack("!I", ActionId.TC_REPLAY_STOP)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.DOWNLINK_PWR_ON:
if cmd_str == OpCode.DOWNLINK_PWR_ON:
q.add_log_cmd(f"{prefix}: {OpCode.DOWNLINK_PWR_ON}")
data = prepare_downlink_pwr_on_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.DOWNLINK_PWR_OFF:
if cmd_str == OpCode.DOWNLINK_PWR_OFF:
q.add_log_cmd("PLOC MPSoC: Downlink pwr off")
data = object_id.as_bytes + struct.pack("!I", ActionId.TC_DOWNLINK_PWR_OFF)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.FLASH_GET_DIR_CONTENT:
if cmd_str == OpCode.FLASH_GET_DIR_CONTENT:
q.add_log_cmd(f"{prefix}: {Info.FLASH_GET_DIR_CONTENT}")
dir_name = input("Please specify MPSoC directory name to get information for: ")
dir_name = bytearray(dir_name.encode("utf-8"))
@ -254,34 +258,20 @@ def pack_ploc_mpsoc_commands( # noqa C901
user_data=dir_name,
)
)
if op_code == OpCode.REPLAY_WRITE_SEQ:
if cmd_str == OpCode.REPLAY_WRITE_SEQ:
q.add_log_cmd(f"{prefix}: {Info.REPLAY_WRITE_SEQ}")
data = prepare_replay_write_sequence_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "12":
if cmd_str == "12":
q.add_log_cmd("PLOC MPSoC: Reset OBSW sequence count")
data = object_id.as_bytes + struct.pack("!I", ActionId.OBSW_RESET_SEQ_COUNT)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.VERIFY_BOOT:
num_words = 1
if cmd_str == OpCode.VERIFY_BOOT:
q.add_log_cmd(f"{prefix} {Info.VERIFY_BOOT}")
data = (
object_id.as_bytes
+ struct.pack("!I", ActionId.TC_MEM_READ)
+ struct.pack("!I", MemAddresses.DEADBEEF)
+ struct.pack("!H", num_words)
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.MODE_REPLAY:
q.add_log_cmd("PLOC MPSoC: Tc mode replay")
data = object_id.as_bytes + struct.pack("!I", ActionId.TC_MODE_REPLAY)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.MODE_IDLE:
q.add_log_cmd("PLOC MPSoC: Tc mode idle")
data = object_id.as_bytes + struct.pack("!I", ActionId.TC_MODE_IDLE)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "16":
q.add_log_cmd("PLOC MPSoC: Tc cam command send")
app_data = object_id.as_bytes + struct.pack("!I", ActionId.TC_VERIFY_BOOT)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=app_data))
if cmd_str == OpCode.CAM_CMD_SEND:
q.add_log_cmd(Info.CAM_CMD_SEND)
cam_cmd = input("Specify cam command string: ")
data = (
object_id.as_bytes
@ -289,30 +279,112 @@ def pack_ploc_mpsoc_commands( # noqa C901
+ bytearray(cam_cmd, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "17":
if cmd_str == OpCode.ENABLE_TC_EXECUTION:
q.add_log_cmd(Info.ENABLE_TC_EXECUTION)
while True:
for key, val in CRIT_CMD_APID_DICT.items():
print(f"{key}: {val[0]} with APID {val[1]}")
key = input("Please specify the command to enable by key: ")
if key not in CRIT_CMD_APID_DICT:
print("invalid key")
continue
apid = CRIT_CMD_APID_DICT[key][1]
break
app_data = struct.pack("!H", apid)
q.add_pus_tc(
create_action_cmd(PLOC_MPSOC_ID, ActionId.TC_ENABLE_TC_EXECUTION, app_data)
)
if cmd_str == OpCode.FLASH_MKFS:
q.add_log_cmd(Info.FLASH_MKFS)
while True:
flash_select = int(input("Please select the flash ID (0 or 1): "))
if flash_select != 0 and flash_select != 1:
_LOGGER.warn("invalid flash select")
continue
break
q.add_pus_tc(
create_action_cmd(
PLOC_MPSOC_ID, ActionId.TC_FLASH_MKFS, bytes([flash_select])
)
)
if cmd_str == OpCode.SPLIT_FILE:
q.add_log_cmd(Info.SPLIT_FILE)
q.add_pus_tc(
create_action_cmd(
PLOC_MPSOC_ID,
ActionId.TC_SPLIT_FILE,
user_data=prepare_simplex_store_file_user_data(),
)
)
if cmd_str == "17":
q.add_log_cmd("PLOC MPSoC: Set UART TX tristate")
data = object_id.as_bytes + struct.pack("!I", ActionId.SET_UART_TX_TRISTATE)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "18":
if cmd_str == "18":
q.add_log_cmd("PLOC MPSoC: Release UART TX")
data = object_id.as_bytes + struct.pack("!I", ActionId.RELEASE_UART_TX)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.CAM_TAKE_PIC:
if cmd_str == OpCode.CAM_TAKE_PIC:
q.add_log_cmd("PLOC MPSoC: Cam take picture")
data = prepare_cam_take_pic_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.SIMPLEX_SEND_FILE:
q.add_log_cmd("PLOC MPSoC: Simplex send file")
data = prepare_simplex_send_file_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.DOWNLINK_DATA_MODULATE:
if cmd_str == OpCode.SIMPLEX_STREAM_FILE:
q.add_log_cmd(Info.SIMPLEX_STREAM_FILE)
data = prepare_simplex_stream_file_user_data()
q.add_pus_tc(
create_action_cmd(
PLOC_MPSOC_ID, ActionId.TC_SIMPLEX_STREAM_FILE, user_data=data
)
)
if cmd_str == OpCode.DOWNLINK_DATA_MODULATE:
q.add_log_cmd("PLOC MPSoC: Downlink data modulate")
data = prepare_downlink_data_modulate_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.MODE_SNAPSHOT:
q.add_log_cmd("PLOC MPSoC: Mode snapshot")
data = object_id.as_bytes + struct.pack("!I", ActionId.TC_MODE_SNAPSHOT)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if cmd_str == OpCode.MODE_SNAPSHOT:
q.add_log_cmd(Info.MODE_SNAPSHOT)
mode = prompt_mode_for_submode_change()
q.add_pus_tc(create_mode_command(PLOC_MPSOC_ID, mode, Submode.SNAPSHOT))
if cmd_str == OpCode.MODE_IDLE:
q.add_log_cmd(Info.MODE_IDLE)
mode = prompt_mode_for_submode_change()
q.add_pus_tc(create_mode_command(PLOC_MPSOC_ID, mode, Submode.IDLE_OR_NONE))
if cmd_str == OpCode.MODE_REPLAY:
q.add_log_cmd(Info.MODE_REPLAY)
mode = prompt_mode_for_submode_change()
q.add_pus_tc(create_mode_command(PLOC_MPSOC_ID, mode, Submode.REPLAY))
if cmd_str == OpCode.ENABLE_PLOC_SUPV_COMMANDING_TO_ON:
q.add_log_cmd(Info.ENABLE_PLOC_SUPV_COMMANDING_TO_ON)
q.add_pus_tc(
create_load_param_cmd(
create_scalar_u8_parameter(
object_id.as_bytes, 0, ParamId.PLOC_SUPV_SKIP_CMD_TO_ON, 0
)
)
)
if cmd_str == OpCode.DISABLE_PLOC_SUPV_COMMANDING_TO_ON:
q.add_log_cmd(Info.DISABLE_PLOC_SUPV_COMMANDING_TO_ON)
q.add_pus_tc(
create_load_param_cmd(
create_scalar_u8_parameter(
object_id.as_bytes, 0, ParamId.PLOC_SUPV_SKIP_CMD_TO_ON, 1
)
)
)
def prompt_mode_for_submode_change() -> int:
while True:
mode = input("Please specify primary mode [0: ON, 1: NORMAL]: ")
if mode == "0":
mode = Mode.ON
elif mode == "1":
mode = Mode.NORMAL
else:
print("Invalid mode")
continue
break
return mode
def generate_write_mem_command(
@ -422,10 +494,10 @@ def prepare_replay_write_sequence_cmd(object_id: bytes) -> bytearray:
return bytearray(command)
def prepare_cam_take_pic_cmd(object_id: bytes) -> bytearray:
selection = input("Use default parameter? (Y/N): ")
def prepare_cam_take_pic_cmd(object_id: bytes) -> bytes:
filename = input("Specify target filename: ")
selection = input("Use default parameter? (y/n): ")
if selection.lower() in ["y", "1", "yes"]:
filename = "0:/test"
encoder_setting_y = 7
quantization_y = 0
encoder_setting_cb = 7
@ -434,7 +506,6 @@ def prepare_cam_take_pic_cmd(object_id: bytes) -> bytearray:
quantization_cr = 0
bypass_compressor = 0
else:
filename = input("Specify filename: ")
encoder_setting_y = int(input("Specify encoderSetting_Y: "))
quantization_y = int(input("Specify quantization_Y: "))
encoder_setting_cb = int(input("Specify encoderSetting_Cb: "))
@ -445,7 +516,7 @@ def prepare_cam_take_pic_cmd(object_id: bytes) -> bytearray:
command = (
object_id
+ struct.pack("!I", ActionId.TC_CAM_TAKE_PIC)
+ bytearray(filename, "utf-8")
+ filename.encode()
+ bytes([0])
+ struct.pack("!B", encoder_setting_y)
+ struct.pack("!Q", quantization_y)
@ -455,18 +526,23 @@ def prepare_cam_take_pic_cmd(object_id: bytes) -> bytearray:
+ struct.pack("!Q", quantization_cr)
+ struct.pack("!B", bypass_compressor)
)
return bytearray(command)
return command
def prepare_simplex_send_file_cmd(object_id: bytes) -> bytearray:
def prepare_simplex_stream_file_user_data() -> bytes:
filename = input("Specify filename: ")
command = filename.encode() + bytes([0])
return command
def prepare_simplex_store_file_user_data() -> bytes:
num_of_chunks = int(input("Please specify the number of chunks: "))
assert num_of_chunks >= 0
filename = input("Specify filename: ")
command = (
object_id
+ struct.pack("!I", ActionId.TC_SIMPLEX_SEND_FILE)
+ bytearray(filename, "utf-8")
+ bytes([0])
struct.pack("!I", num_of_chunks) + bytearray(filename, "utf-8") + bytes([0])
)
return bytearray(command)
return command
def prepare_downlink_data_modulate_cmd(object_id: bytes) -> bytearray:
@ -641,7 +717,7 @@ class DirElement:
size: int
def handle_mpsoc_data_reply(action_id: int, pw: PrintWrapper, custom_data: bytearray):
def handle_mpsoc_data_reply(action_id: int, pw: PrintWrapper, custom_data: bytes):
if action_id == ActionId.TM_MEM_READ_RPT:
header_list = [
"PLOC Memory Address",
@ -669,7 +745,8 @@ def handle_mpsoc_data_reply(action_id: int, pw: PrintWrapper, custom_data: bytea
"PLOC MPSoC flash directory data shorter than minimum 16 bytes"
)
current_idx = 0
dir_name_short = custom_data[current_idx : current_idx + 12].decode("utf-8")
end_of_str = custom_data[current_idx : current_idx + 12].index(b"\x00")
dir_name_short = custom_data[current_idx : current_idx + end_of_str].decode()
current_idx += 12
num_elements = struct.unpack("!I", custom_data[current_idx : current_idx + 4])[
0
@ -690,9 +767,7 @@ def handle_mpsoc_data_reply(action_id: int, pw: PrintWrapper, custom_data: bytea
# It is as weird as it looks..
for _ in range(num_elements):
end_of_str = custom_data[current_idx : current_idx + 12].index(b"\x00")
elem_name = custom_data[current_idx : current_idx + end_of_str].decode(
"utf-8"
)
elem_name = custom_data[current_idx : current_idx + end_of_str].decode()
current_idx += 12
elem_names.append(elem_name)
for _ in range(num_elements):

View File

@ -6,23 +6,20 @@
@author J. Meier
@date 10.07.2021
"""
from datetime import datetime
import enum
import logging
import struct
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.config import TmtcDefinitionWrapper
from tmtccmd.config.tmtc import OpCodeEntry, tmtc_definitions_provider
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from tmtccmd.pus.s200_fsfw_mode import Mode, pack_mode_data
from tmtccmd.pus.tc.s3_fsfw_hk import generate_one_hk_command, make_sid
from tmtccmd.tmtc import service_provider
from tmtccmd.tmtc.decorator import ServiceProviderParams
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.config.object_ids import PLOC_SUPV_ID, get_object_ids
from eive_tmtc.pus_tm.defs import PrintWrapper
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.pus.tc.s3_fsfw_hk import generate_one_hk_command, make_sid
from tmtccmd.config.tmtc import CmdTreeNode
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s200_fsfw_mode import pack_mode_data, Mode
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from tmtccmd.fsfw.tmtc_printer import get_validity_buffer_str
from eive_tmtc.utility.input_helper import InputHelper
_LOGGER = logging.getLogger(__name__)
@ -42,14 +39,14 @@ MANUAL_INPUT = "1"
HARDCODED_FILE = "/home/rmueller/EIVE/mpsoc_boot.bin"
UPDATE_FILE_DICT = {
HARDCODED: ["hardcoded", ""],
MANUAL_INPUT: ["manual input", ""],
"2": ["/mnt/sd0/ploc/mpsoc/image.bin", "/mnt/sd0/ploc/mpsoc/image.bin"],
HARDCODED: ("hardcoded", ""),
MANUAL_INPUT: ("manual input", ""),
"2": ("/mnt/sd0/ploc/mpsoc/image.bin", "/mnt/sd0/ploc/mpsoc/image.bin"),
}
EVENT_BUFFER_PATH_DICT = {
MANUAL_INPUT: ["manual input", ""],
"2": ["/mnt/sd0/ploc/supervisor", "/mnt/sd0/ploc/supervisor"],
MANUAL_INPUT: ("manual input", ""),
"2": ("/mnt/sd0/ploc/supervisor", "/mnt/sd0/ploc/supervisor"),
}
@ -115,7 +112,7 @@ class SupvActionId(enum.IntEnum):
REQUEST_ADC_REPORT = 57
RESET_PL = 58
ENABLE_NVMS = 59
CONTINUE_UPDATE = 60
RESUME_UPDATE = 60
MEM_CHECK = 61
@ -133,126 +130,90 @@ class OpCode:
ON = "on"
NORMAL = "nml"
HK_TO_OBC = "hk_to_obc"
REQUEST_HK_SET_FROM_DEV = "req_hk_from_dev"
REQUEST_HK_SET = "req_hk"
REQUEST_GENERIC_HK_SET = "req_generic_hk"
START_MPSOC = "start_mpsoc"
SHUTDOWN_MPSOC = "stop_mpsoc"
SEL_NVM = "sel_nvm"
SET_TIME_REF = "set_time_ref"
FACTORY_FLASH = "factory_flash"
REQ_BOOT_STATUS_REPORT = "boot_report"
START_UPDATE = "start_update"
PERFORM_UPDATE = "update"
RESUME_UPDATE = "resum_update"
FACTORY_RESET = "factory_reset"
MEM_CHECK = "mem_check"
RESET_MPSOC = "reset_mpsoc"
SET_GPIO = "set_gpio"
READ_GPIO = "read_gpio"
READ_STATUS_REPORT = "read_status_report"
class Info(str, enum.Enum):
value: str
OFF = "Switch Off"
ON = "Switch On"
NML = "Switch Normal"
NORMAL = "Switch Normal"
HK_TO_OBC = "Request HK from PLOC SUPV"
REQUEST_HK_SET_FROM_DEV = "Request HK set from the device to the PLOC Handler"
REQUEST_HK_SET = "Request HK set from PLOC Handler"
REQUEST_GENERIC_HK_SET = "Request prompted HK set from PLOC Handler"
START_MPSOC = "Start MPSoC"
SHUTDOWN_MPSOC = "Shutdown MPSoC"
SET_TIME_REF = "Set time reference"
FACTORY_FLASH = "Factory Flash Mode"
PERFORM_UPDATE = "Start or continue MPSoC SW update at starting bytes"
RESUME_UPDATE = "Start or continue MPSoC SW update at starting bytes"
START_UPDATE = "Start new MPSoC SW update"
FACTORY_RESET = "Factory Reset of loggers"
REQ_BOOT_STATUS_REPORT = "Request boot status report and HK"
MEM_CHECK = "Memory Check"
SEL_NVM = "Select NVM"
RESET_MPSOC = "Reset MPSoC"
SET_GPIO = "Set GPIO"
READ_GPIO = "Read GPIO"
READ_STATUS_REPORT = "Read HK status report"
@tmtc_definitions_provider
def add_ploc_supv_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(OpCode.OFF, Info.OFF)
oce.add(OpCode.ON, Info.ON)
oce.add(OpCode.NORMAL, Info.NML)
oce.add(OpCode.HK_TO_OBC, Info.HK_TO_OBC)
oce.add(OpCode.REQUEST_HK_SET, Info.REQUEST_HK_SET)
oce.add(OpCode.REQUEST_HK_SET_FROM_DEV, Info.REQUEST_HK_SET_FROM_DEV)
oce.add(OpCode.START_MPSOC, "PLOC Supervisor: Start MPSoC")
oce.add(OpCode.SHUTDOWN_MPSOC, "PLOC Supervisor: Shutdown MPSoC")
oce.add(OpCode.SEL_NVM, Info.SEL_NVM)
oce.add(OpCode.SET_TIME_REF, Info.SET_TIME_REF)
oce.add(OpCode.FACTORY_RESET, Info.FACTORY_RESET)
oce.add(OpCode.RESET_MPSOC, Info.RESET_MPSOC)
oce.add("8", "PLOC Supervisor: Set max restart tries")
oce.add("11", "PLOC Supervisor: Set boot timeout")
oce.add("12", "PLOC Supervisor: Disable Hk")
oce.add(OpCode.REQ_BOOT_STATUS_REPORT, Info.REQ_BOOT_STATUS_REPORT)
oce.add("17", "PLOC Supervisor: Enable latchup alert")
oce.add("18", "PLOC Supervisor: Disable latchup alert")
oce.add("20", "PLOC Supervisor: Set alert limit")
oce.add("23", "PLOC Supervisor: Set ADC enabled channels")
oce.add("24", "PLOC Supervisor: Set ADC window and stride")
oce.add("25", "PLOC Supervisor: Set ADC threshold")
oce.add("26", "PLOC Supervisor: Request latchup status report")
oce.add("27", "PLOC Supervisor: Copy ADC data to MRAM")
oce.add("30", "PLOC Supervisor: Run auto EM tests")
oce.add("31", "PLOC Supervisor: MRAM Wipe")
oce.add("35", "PLOC Supervisor: Set GPIO")
oce.add("36", "PLOC Supervisor: Read GPIO")
oce.add("37", "PLOC Supervisor: Restart supervisor")
oce.add(OpCode.PERFORM_UPDATE, Info.PERFORM_UPDATE)
oce.add(OpCode.START_UPDATE, Info.START_UPDATE)
oce.add("43", "PLOC Supervisor: Terminate supervisor process")
oce.add("44", "PLOC Supervisor: Start MPSoC quiet")
oce.add("45", "PLOC Supervisor: Set shutdown timeout")
oce.add(OpCode.FACTORY_FLASH, Info.FACTORY_FLASH)
oce.add("47", "PLOC Supervisor: Enable auto TM")
oce.add("48", "PLOC Supervisor: Disable auto TM")
oce.add("51", "PLOC Supervisor: Logging request event buffers")
oce.add("52", "PLOC Supervisor: Logging clear counters")
oce.add("53", "PLOC Supervisor: Logging set topic")
oce.add("54", "PLOC Supervisor: Logging request counters")
oce.add("55", "PLOC Supervisor: Request ADC Report")
oce.add("56", "PLOC Supervisor: Reset PL")
oce.add("57", "PLOC Supervisor: Enable NVMs")
oce.add("58", "PLOC Supervisor: Continue update")
oce.add(OpCode.MEM_CHECK, Info.MEM_CHECK)
defs.add_service(CustomServiceList.PLOC_SUPV.value, "PLOC Supervisor", oce)
def create_ploc_supv_node() -> CmdTreeNode:
op_code_strs = [
getattr(OpCode, key) for key in dir(OpCode) if not key.startswith("__")
]
info_strs = [getattr(Info, key) for key in dir(OpCode) if not key.startswith("__")]
combined_dict = dict(zip(op_code_strs, info_strs))
node = CmdTreeNode("ploc_supv", "PLOC Supervisor", hide_children_for_print=True)
for op_code, info in combined_dict.items():
node.add_child(CmdTreeNode(op_code, info))
return node
@service_provider(CustomServiceList.PLOC_SUPV)
def pack_ploc_supv_commands(p: ServiceProviderParams): # noqa C901
q = p.queue_helper
op_code = p.op_code
def pack_ploc_supv_commands(q: DefaultPusQueueHelper, cmd_str: str): # noqa C901
object_id = get_object_ids().get(PLOC_SUPV_ID)
assert object_id is not None
q.add_log_cmd(f"Testing PLOC Supervisor with object id: {object_id.as_hex_string}")
obyt = object_id.as_bytes
prefix = "PLOC Supervisor"
if op_code == OpCode.OFF:
if cmd_str == OpCode.OFF:
q.add_log_cmd(f"{prefix}: {Info.OFF}")
command = pack_mode_data(object_id.as_bytes, Mode.OFF, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=command))
if op_code == OpCode.ON:
if cmd_str == OpCode.ON:
q.add_log_cmd(f"{prefix}: {Info.ON}")
command = pack_mode_data(object_id.as_bytes, Mode.ON, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=command))
if op_code == OpCode.NORMAL:
q.add_log_cmd(f"{prefix}: {Info.NML}")
if cmd_str == OpCode.NORMAL:
q.add_log_cmd(f"{prefix}: {Info.NORMAL}")
command = pack_mode_data(object_id.as_bytes, Mode.NORMAL, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=command))
if op_code == OpCode.HK_TO_OBC:
if cmd_str == OpCode.HK_TO_OBC:
q.add_log_cmd(f"{prefix}: {Info.HK_TO_OBC}")
command = obyt + struct.pack("!I", SupvActionId.REQUEST_HK_REPORT)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == OpCode.REQUEST_HK_SET:
q.add_log_cmd(f"{prefix}: {Info.REQUEST_HK_SET}")
sid = make_sid(object_id.as_bytes, prompt_set_id())
cmd = generate_one_hk_command(sid)
q.add_pus_tc(cmd)
if op_code == OpCode.REQUEST_HK_SET_FROM_DEV:
q.add_log_cmd(f"{prefix}: {Info.REQUEST_HK_SET_FROM_DEV}")
if cmd_str == OpCode.START_MPSOC:
q.add_log_cmd("PLOC Supervisor: Start MPSoC")
command = obyt + struct.pack("!I", SupvActionId.START_MPSOC)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if cmd_str == OpCode.SHUTDOWN_MPSOC:
q.add_log_cmd("PLOC Supervisor: Shutdown MPSoC")
command = object_id.as_bytes + struct.pack("!I", SupvActionId.SHUTWOWN_MPSOC)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if cmd_str == OpCode.READ_STATUS_REPORT:
q.add_log_cmd(f"{prefix}: {Info.READ_STATUS_REPORT}")
set_id = prompt_set_id()
action_cmd = None
# First read the set from the device.
if set_id == SetId.HK_REPORT:
action_cmd = create_action_cmd(PLOC_SUPV_ID, SupvActionId.REQUEST_HK_REPORT)
if set_id == SetId.ADC_REPORT:
@ -263,17 +224,33 @@ def pack_ploc_supv_commands(p: ServiceProviderParams): # noqa C901
action_cmd = create_action_cmd(
PLOC_SUPV_ID, SupvActionId.REQUEST_LOGGING_COUNTERS
)
assert action_cmd is not None
if set_id == SetId.LATCHUP_REPORT:
action_cmd = create_action_cmd(
PLOC_SUPV_ID, SupvActionId.GET_LATCHUP_STATUS_REPORT
)
if set_id == SetId.BOOT_STATUS_REPORT:
action_cmd = create_action_cmd(
PLOC_SUPV_ID, SupvActionId.GET_BOOT_STATUS_REPORT
)
if action_cmd is None:
_LOGGER.warning(f"invalid set ID {set_id!r} for PLOC SUPV")
return
# Now dump the HK set.
sid = make_sid(object_id.as_bytes, set_id)
req_hk = generate_one_hk_command(sid)
q.add_pus_tc(action_cmd)
elif op_code == OpCode.START_MPSOC:
q.add_wait_seconds(2.0)
q.add_pus_tc(req_hk)
assert action_cmd is not None
elif cmd_str == OpCode.START_MPSOC:
q.add_log_cmd("PLOC Supervisor: Start MPSoC")
command = obyt + struct.pack("!I", SupvActionId.START_MPSOC)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == OpCode.SHUTDOWN_MPSOC:
if cmd_str == OpCode.SHUTDOWN_MPSOC:
q.add_log_cmd("PLOC Supervisor: Shutdown MPSoC")
command = object_id.as_bytes + struct.pack("!I", SupvActionId.SHUTWOWN_MPSOC)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == OpCode.SEL_NVM:
if cmd_str == OpCode.SEL_NVM:
q.add_log_cmd("PLOC Supervisor: Select MPSoC boot image")
mem = int(input("MEM (NVM0 - 0 or NVM1 - 1): "))
bp0 = int(input("BP0 (0 or 1): "))
@ -281,7 +258,7 @@ def pack_ploc_supv_commands(p: ServiceProviderParams): # noqa C901
bp2 = int(input("BP2 (0 or 1): "))
command = pack_sel_boot_image_cmd(object_id.as_bytes, mem, bp0, bp1, bp2)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == OpCode.FACTORY_RESET:
if cmd_str == OpCode.FACTORY_RESET:
q.add_log_cmd(f"{prefix}: {Info.FACTORY_RESET}")
while True:
print("Please select the key for a factory reset operation")
@ -298,7 +275,7 @@ def pack_ploc_supv_commands(p: ServiceProviderParams): # noqa C901
user_data=bytes([key]),
)
)
if op_code == "8":
if cmd_str == "8":
q.add_log_cmd("PLOC Supervisor: Set max restart tries")
restart_tries = int(input("Specify maximum restart tries: "))
command = (
@ -307,15 +284,15 @@ def pack_ploc_supv_commands(p: ServiceProviderParams): # noqa C901
+ struct.pack("!B", restart_tries)
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == OpCode.RESET_MPSOC:
if cmd_str == OpCode.RESET_MPSOC:
q.add_log_cmd(Info.RESET_MPSOC)
command = object_id.as_bytes + struct.pack("!I", SupvActionId.RESET_MPSOC)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == OpCode.SET_TIME_REF:
if cmd_str == OpCode.SET_TIME_REF:
q.add_log_cmd("PLOC Supervisor: Set time reference")
command = object_id.as_bytes + struct.pack("!I", SupvActionId.SET_TIME_REF)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "11":
if cmd_str == "11":
q.add_log_cmd("PLOC Supervisor: Set boot timeout")
boot_timeout = int(input("Specify boot timeout [ms]: "))
command = (
@ -324,143 +301,63 @@ def pack_ploc_supv_commands(p: ServiceProviderParams): # noqa C901
+ struct.pack("!I", boot_timeout)
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "12":
q.add_log_cmd("PLOC Supervisor: Disable HK")
command = object_id.as_bytes + struct.pack("!I", SupvActionId.DISABLE_HK)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code in OpCode.REQ_BOOT_STATUS_REPORT:
q.add_log_cmd(f"{prefix}: {Info.REQ_BOOT_STATUS_REPORT}")
command = object_id.as_bytes + struct.pack(
"!I", SupvActionId.GET_BOOT_STATUS_REPORT
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
q.add_wait_seconds(2.0)
sid = make_sid(object_id.as_bytes, SetId.BOOT_STATUS_REPORT)
req_hk = generate_one_hk_command(sid)
q.add_pus_tc(req_hk)
if op_code == "17":
q.add_log_cmd("PLOC Supervisor: Enable latchup alert")
command = pack_lachtup_alert_cmd(object_id.as_bytes, True)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "18":
q.add_log_cmd("PLOC Supervisor: Disable latchup alert")
command = pack_lachtup_alert_cmd(object_id.as_bytes, False)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "20":
q.add_log_cmd("PLOC Supervisor: Set alert limit")
command = pack_set_alert_limit_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "23":
if cmd_str == "23":
q.add_log_cmd("PLOC Supervisor: Set ADC enabled channels")
command = pack_set_adc_enabled_channels_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "24":
if cmd_str == "24":
q.add_log_cmd("PLOC Supervisor: Set ADC window and stride")
command = pack_set_adc_window_and_stride_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "25":
if cmd_str == "25":
q.add_log_cmd("PLOC Supervisor: Set ADC threshold")
command = pack_set_adc_threshold_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "26":
q.add_log_cmd("PLOC Supervisor: Request latchup status report")
command = object_id.as_bytes + struct.pack(
"!I", SupvActionId.GET_LATCHUP_STATUS_REPORT
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "27":
q.add_log_cmd("PLOC Supervisor: Copy ADC data to MRAM")
command = object_id.as_bytes + struct.pack(
"!I", SupvActionId.COPY_ADC_DATA_TO_MRAM
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "30":
q.add_log_cmd("PLOC Supervisor: Run auto EM tests")
command = pack_auto_em_tests_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "31":
q.add_log_cmd("PLOC Supervisor: Wipe MRAM")
command = pack_mram_wipe_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "35":
if cmd_str == OpCode.SET_GPIO:
q.add_log_cmd("PLOC Supervisor: Set GPIO command")
command = pack_set_gpio_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "36":
if cmd_str == OpCode.READ_GPIO:
q.add_log_cmd("PLOC Supervisor: Read GPIO command")
command = pack_read_gpio_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "37":
if cmd_str == "37":
q.add_log_cmd("PLOC Supervisor: Restart supervisor")
command = object_id.as_bytes + struct.pack(
"!I", SupvActionId.RESTART_SUPERVISOR
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code in OpCode.START_UPDATE:
if cmd_str in OpCode.START_UPDATE:
q.add_log_cmd("PLOC Supversior: Start new MPSoC SW update")
command = pack_update_command(object_id.as_bytes, True)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code in OpCode.PERFORM_UPDATE:
if cmd_str in OpCode.RESUME_UPDATE:
q.add_log_cmd("PLOC Supervisor: Perform MPSoC SW update")
command = pack_update_command(object_id.as_bytes, False)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "43":
if cmd_str == "43":
q.add_log_cmd("PLOC Supervisor: Terminate supervisor process")
command = object_id.as_bytes + struct.pack(
"!I", SupvActionId.TERMINATE_SUPV_HELPER
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "44":
if cmd_str == "44":
q.add_log_cmd("PLOC Supervisor: Start MPSoC quiet")
command = object_id.as_bytes + struct.pack("!I", SupvActionId.START_MPSOC_QUIET)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "45":
if cmd_str == "45":
q.add_log_cmd("PLOC Supervisor: Set shutdown timeout")
command = pack_set_shutdown_timeout_command(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code in OpCode.FACTORY_FLASH:
if cmd_str in OpCode.FACTORY_FLASH:
q.add_log_cmd(f"{prefix}: {Info.FACTORY_FLASH}")
command = object_id.as_bytes + struct.pack("!I", SupvActionId.FACTORY_FLASH)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "47":
q.add_log_cmd("PLOC Supervisor: Enable auto TM")
command = object_id.as_bytes + struct.pack("!I", SupvActionId.ENABLE_AUTO_TM)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "48":
q.add_log_cmd("PLOC Supervisor: Disable auto TM")
command = object_id.as_bytes + struct.pack("!I", SupvActionId.DISABLE_AUTO_TM)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "51":
q.add_log_cmd("PLOC Supervisor: Logging request event buffers")
command = pack_logging_buffer_request(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "52":
q.add_log_cmd("PLOC Supervisor: Logging clear counters")
command = object_id.as_bytes + struct.pack(
"!I", SupvActionId.LOGGING_CLEAR_COUNTERS
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "53":
q.add_log_cmd("PLOC Supervisor: Logging set topic")
command = pack_logging_set_topic(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "54":
q.add_log_cmd("PLOC Supervisor: Logging request counters")
command = object_id.as_bytes + struct.pack(
"!I", SupvActionId.REQUEST_LOGGING_COUNTERS
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "55":
q.add_log_cmd("PLOC Supervisor: Request ADC report")
command = object_id.as_bytes + struct.pack(
"!I", SupvActionId.REQUEST_ADC_REPORT
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "56":
if cmd_str == "56":
q.add_log_cmd("PLOC Supervisor: Reset PL")
command = object_id.as_bytes + struct.pack("!I", SupvActionId.RESET_PL)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "57":
if cmd_str == "57":
q.add_log_cmd("PLOC Supervisor: Enable NVMs")
nvm01 = int(input("Enable (1) or disable(0) NVM 0 and 1: "))
nvm3 = int(input("Enable (1) or disable(0) NVM 3: "))
@ -471,11 +368,11 @@ def pack_ploc_supv_commands(p: ServiceProviderParams): # noqa C901
+ struct.pack("B", nvm3)
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == "58":
if cmd_str == "58":
q.add_log_cmd("PLOC Supervisor: Continue update")
command = object_id.as_bytes + struct.pack("!I", SupvActionId.CONTINUE_UPDATE)
command = object_id.as_bytes + struct.pack("!I", SupvActionId.RESUME_UPDATE)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code == OpCode.MEM_CHECK:
if cmd_str == OpCode.MEM_CHECK:
custom_data = bytearray()
update_file = get_update_file()
memory_id = int(input("Specify memory ID: "))
@ -753,8 +650,10 @@ def get_event_buffer_path() -> str:
class SocState(enum.IntEnum):
OFF = 0
BOOTING = 1
OPERATIONAL = 2
SHUTDOWN = 3
UPDATE = 2
OPERATIONAL = 3
RESET = 4
FAULTY = 5
def handle_supv_hk_data(set_id: int, hk_data: bytes, pw: PrintWrapper):
@ -766,6 +665,8 @@ def handle_supv_hk_data(set_id: int, hk_data: bytes, pw: PrintWrapper):
handle_adc_report(hk_data)
elif set_id == SetId.COUNTERS_REPORT:
handle_counters_report(hk_data)
elif set_id == SetId.LATCHUP_REPORT:
handle_latchup_status_report(hk_data)
else:
pw.dlog(f"PLOC SUPV: HK handling not implemented for set ID {set_id}")
pw.dlog(f"Raw Data: 0x[{hk_data.hex(sep=',')}]")
@ -792,12 +693,15 @@ def handle_hk_report(hk_data: bytes, pw: PrintWrapper):
pw.dlog(f"Temp PS {temp_ps} C | Temp PL {temp_pl} C | Temp SUP {temp_sup} C")
pw.dlog(f"Uptime {uptime} | CPU Load {cpu_load} | Avail Heap {avail_heap}")
pw.dlog(f"Number TCs {num_tcs} | Number TMs {num_tms}")
pw.dlog(f"SOC state {SocState(soc_state)}")
try:
pw.dlog(f"SOC state {SocState(soc_state)}")
except ValueError:
pw.dlog(f"Invalid SOC state {soc_state}")
pw.dlog(f"NVM 01 State {nvm_0_1_state}")
pw.dlog(f"NVM 3 State {nvm_3_state}")
pw.dlog(f"Mission IO state {mission_io_state}")
pw.dlog(f"FMC state {fmc_state}")
pw.dlog(FsfwTmTcPrinter.get_validity_buffer(hk_data[inc_len:], 13))
pw.dlog(get_validity_buffer_str(hk_data[inc_len:], 13))
def handle_boot_report(hk_data: bytes, pw: PrintWrapper):
@ -826,7 +730,7 @@ def handle_boot_report(hk_data: bytes, pw: PrintWrapper):
pw.dlog(f"Active NVM: {active_nvm}")
pw.dlog(f"BP0 State {bp_0_state} | BP1 State {bp_1_state} | BP2 State {bp_2_state}")
pw.dlog(f"Boot State {boot_state} | Boot Cycles {boot_cycles}")
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], 10)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], 10))
def handle_adc_report(hk_data: bytes):
@ -907,3 +811,53 @@ def handle_counters_report(hk_data: bytes):
print(f"MM task lost: {mm_task_lost}")
print(f"HK task lost: {hk_task_lost}")
print(f"DL task lost: {dl_task_lost}")
def handle_latchup_status_report(hk_data: bytes):
# 1 byte ID, 7 times 2 bytes of counts, and 8 bytes of time and 1 byte sync status.
if len(hk_data) < 24:
raise ValueError("Latchup status report smaller than expected")
current_idx = 0
id = hk_data[current_idx]
current_idx += 1
counts_of_alerts = []
for _ in range(7):
counts_of_alerts.append(
struct.unpack("!H", hk_data[current_idx : current_idx + 2])[0]
)
current_idx += 2
print(f"ID: {id}")
print(f"Counts of alerts: {counts_of_alerts}")
time_ms = struct.unpack("!H", hk_data[current_idx : current_idx + 2])[0]
current_idx += 2
time_seconds = hk_data[current_idx]
current_idx += 1
time_minutes = hk_data[current_idx]
current_idx += 1
time_hour = hk_data[current_idx]
current_idx += 1
time_day = hk_data[current_idx]
current_idx += 1
time_month = hk_data[current_idx]
current_idx += 1
# Is stored as years since 1900.
time_year = 1900 + hk_data[current_idx]
current_idx += 1
is_synced = hk_data[current_idx]
print(f"Time Sync Status: {is_synced}")
try:
dt = datetime(
year=time_year,
month=time_month,
day=time_day,
hour=time_hour,
minute=time_minutes,
second=time_seconds,
microsecond=time_ms * 1000,
)
print(f"Time Now: {dt}")
except ValueError:
print(
f"Time: {time_day}.{time_month}.{time_year}T"
f"{time_hour}:{time_minutes}:{time_seconds}.{time_ms}"
)

View File

@ -6,7 +6,7 @@ from typing import Optional
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.pus_tm.defs import PrintWrapper
from tmtccmd.config import TmtcDefinitionWrapper
from tmtccmd.config import CmdTreeNode, TmtcDefinitionWrapper
from tmtccmd.config.tmtc import OpCodeEntry, tmtc_definitions_provider
from tmtccmd.tmtc import DefaultPusQueueHelper
@ -28,13 +28,12 @@ from tmtccmd.pus.s20_fsfw_param import (
)
from spacepackets.ecss.tc import PusTelecommand
from eive_tmtc.config.object_ids import PL_PCDU_ID
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.fsfw.tmtc_printer import get_validity_buffer_str
_LOGGER = logging.getLogger(__name__)
class OpCode:
SWITCH_HPA_ON_PROC = ["0", "proc_hpa"]
SWITCH_ON = "on"
SWITCH_OFF = "off"
NORMAL_SSR = "nml_ssr"
@ -76,12 +75,17 @@ class Info:
NORMAL_HPA = f"{NORMAL}, HPA on"
NORMAL_CUSTOM = f"{NORMAL}, Custom Channel Settings"
REQ_OS_HK = "Request One Shot HK"
SWITCH_HPA_ON_PROC = "Switch HPA on procedure"
ENABLE_HK = "Enable HK"
DISABLE_HK = "Disable HK"
UPDATE_I_UPPER_LIMIT = "Update upper current parameter"
UPDATE_V_LOWER_LIMIT = "Update lower voltage parameter"
UPDATE_V_UPPER_LIMIT = "Update upper voltage parameter"
INJECT_SSR_TO_DRO_FAILURE = "Inject SSR to DRO failure"
INJECT_DRO_TO_X8_FAILURE = "Inject DRO to X8 failure"
INJECT_X8_TO_TX_FAILURE = "Inject X8 to TX failure"
INJECT_TX_TO_MPA_FAILURE = "Inject TX to MPA failure"
INJECT_MPA_TO_HPA_FAILURE = "Inject MPA to HPA failure"
INJECT_ALL_ON_FAILURE = "Inject all on failure"
DISABLE_ORDER_CHECKING = "Disable order checks"
ENABLE_ORDER_CHECKING = "Enable order checks"
@ -182,10 +186,21 @@ class DevSelect(enum.IntEnum):
HPA = 5
def create_pl_pcdu_node() -> CmdTreeNode:
op_code_strs = [
getattr(OpCode, key) for key in dir(OpCode) if not key.startswith("__")
]
info_strs = [getattr(Info, key) for key in dir(OpCode) if not key.startswith("__")]
combined_dict = dict(zip(op_code_strs, info_strs))
node = CmdTreeNode("pl_pcdu", "Payload PCDU", hide_children_for_print=True)
for op_code, info in combined_dict.items():
node.add_child(CmdTreeNode(op_code, info))
return node
@tmtc_definitions_provider
def add_pl_pcdu_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(keys=OpCode.SWITCH_HPA_ON_PROC, info=Info.SWITCH_HPA_ON_PROC)
oce.add(keys=OpCode.SWITCH_ON, info=Info.SWITCH_ON)
oce.add(keys=OpCode.SWITCH_OFF, info=Info.SWITCH_OFF)
oce.add(keys=OpCode.NORMAL_SSR, info=Info.NORMAL_SSR)
@ -227,13 +242,13 @@ def add_pl_pcdu_cmds(defs: TmtcDefinitionWrapper):
def pack_pl_pcdu_commands( # noqa C901: Complexity is okay here.
q: DefaultPusQueueHelper, op_code: str
q: DefaultPusQueueHelper, cmd_str: str
): # noqa C901: Complexity is okay here.
if op_code == OpCode.SWITCH_ON:
if cmd_str == OpCode.SWITCH_ON:
pack_pl_pcdu_mode_cmd(q=q, info=Info.SWITCH_ON, mode=Mode.ON, submode=0)
if op_code == OpCode.SWITCH_OFF:
if cmd_str == OpCode.SWITCH_OFF:
pack_pl_pcdu_mode_cmd(q=q, info=Info.SWITCH_OFF, mode=Mode.OFF, submode=0)
if op_code in OpCode.ENABLE_HK:
if cmd_str in OpCode.ENABLE_HK:
interval = float(
input("Please enter HK collection interval in floating point seconds: ")
)
@ -243,13 +258,13 @@ def pack_pl_pcdu_commands( # noqa C901: Complexity is okay here.
q.add_log_cmd(f"Enable PL PCDU HK with interval of {interval} seconds")
for cmd in cmds:
q.add_pus_tc(cmd)
if op_code == OpCode.DISABLE_HK:
if cmd_str == OpCode.DISABLE_HK:
cmd = disable_periodic_hk_command(
diag=True, sid=make_sid(PL_PCDU_ID, SetId.ADC)
)
q.add_log_cmd("Disabling PL PCDU HK")
q.add_pus_tc(cmd)
if op_code == OpCode.NORMAL_SSR:
if cmd_str == OpCode.NORMAL_SSR:
pack_pl_pcdu_mode_cmd(
q=q,
info=Info.NORMAL_SSR,
@ -258,57 +273,57 @@ def pack_pl_pcdu_commands( # noqa C901: Complexity is okay here.
NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON
),
)
if op_code == OpCode.NORMAL_DRO:
if cmd_str == OpCode.NORMAL_DRO:
pack_pl_pcdu_mode_cmd(
q=q,
info=Info.NORMAL_DRO,
mode=Mode.NORMAL,
submode=submode_mask_to_submode(NormalSubmodesMask.DRO_ON),
)
if op_code == OpCode.NORMAL_X8:
if cmd_str == OpCode.NORMAL_X8:
pack_pl_pcdu_mode_cmd(
q=q,
info=Info.NORMAL_X8,
mode=Mode.NORMAL,
submode=submode_mask_to_submode(NormalSubmodesMask.X8_ON),
)
if op_code == OpCode.NORMAL_TX:
if cmd_str == OpCode.NORMAL_TX:
pack_pl_pcdu_mode_cmd(
q=q,
info=Info.NORMAL_TX,
mode=Mode.NORMAL,
submode=submode_mask_to_submode(NormalSubmodesMask.TX_ON),
)
if op_code == OpCode.NORMAL_MPA:
if cmd_str == OpCode.NORMAL_MPA:
pack_pl_pcdu_mode_cmd(
q=q,
info=Info.NORMAL_MPA,
mode=Mode.NORMAL,
submode=submode_mask_to_submode(NormalSubmodesMask.MPA_ON),
)
if op_code == OpCode.NORMAL_HPA:
if cmd_str == OpCode.NORMAL_HPA:
pack_pl_pcdu_mode_cmd(
q=q,
info=Info.NORMAL_HPA,
mode=Mode.NORMAL,
submode=submode_mask_to_submode(NormalSubmodesMask.HPA_ON),
)
if op_code == OpCode.NORMAL_CUSTOM:
if cmd_str == OpCode.NORMAL_CUSTOM:
pack_pl_pcdu_mode_cmd(
q=q,
info=Info.NORMAL_CUSTOM,
mode=Mode.NORMAL,
submode=prompt_custom_normal_submode(),
)
if op_code == OpCode.REQ_OS_HK:
if cmd_str == OpCode.REQ_OS_HK:
q.add_log_cmd(f"PL PCDU: {Info.REQ_OS_HK}")
q.add_pus_tc(
generate_one_diag_command(
sid=make_sid(object_id=PL_PCDU_ID, set_id=SetId.ADC)
)
)
if op_code == OpCode.DISABLE_ORDER_CHECKING:
if cmd_str == OpCode.DISABLE_ORDER_CHECKING:
q.add_log_cmd(Info.DISABLE_ORDER_CHECKING)
q.add_pus_tc(
create_load_param_cmd(
@ -318,7 +333,7 @@ def pack_pl_pcdu_commands( # noqa C901: Complexity is okay here.
)
)
if op_code == OpCode.ENABLE_ORDER_CHECKING:
if cmd_str == OpCode.ENABLE_ORDER_CHECKING:
q.add_log_cmd(Info.ENABLE_ORDER_CHECKING)
q.add_pus_tc(
create_load_param_cmd(
@ -328,7 +343,7 @@ def pack_pl_pcdu_commands( # noqa C901: Complexity is okay here.
)
)
if op_code == OpCode.UPDATE_I_UPPER_LIMIT:
if cmd_str == OpCode.UPDATE_I_UPPER_LIMIT:
q.add_log_cmd(Info.UPDATE_I_UPPER_LIMIT)
print("Select device to update lower current limit for: ")
param_id = dev_select_to_upper_i_update_param_id(dev_select_prompt(True))
@ -340,7 +355,7 @@ def pack_pl_pcdu_commands( # noqa C901: Complexity is okay here.
create_scalar_double_parameter(PL_PCDU_ID, 0, param_id, new_param_value)
)
)
if op_code == OpCode.UPDATE_V_LOWER_LIMIT:
if cmd_str == OpCode.UPDATE_V_LOWER_LIMIT:
q.add_log_cmd(Info.UPDATE_V_LOWER_LIMIT)
print("Select device to update lower voltage limit for: ")
param_id = dev_select_to_lower_u_update_param_id(dev_select_prompt(False))
@ -352,7 +367,7 @@ def pack_pl_pcdu_commands( # noqa C901: Complexity is okay here.
create_scalar_double_parameter(PL_PCDU_ID, 0, param_id, new_param_value)
)
)
if op_code == OpCode.UPDATE_V_UPPER_LIMIT:
if cmd_str == OpCode.UPDATE_V_UPPER_LIMIT:
q.add_log_cmd(Info.UPDATE_V_UPPER_LIMIT)
print("Select device to update upper voltage limit for: ")
param_id = dev_select_to_upper_u_update_param_id(dev_select_prompt(False))
@ -364,9 +379,7 @@ def pack_pl_pcdu_commands( # noqa C901: Complexity is okay here.
create_scalar_double_parameter(PL_PCDU_ID, 0, param_id, new_param_value)
)
)
if op_code == OpCode.SWITCH_HPA_ON_PROC:
hpa_on_procedure(q)
if op_code == OpCode.INJECT_ALL_ON_FAILURE:
if cmd_str == OpCode.INJECT_ALL_ON_FAILURE:
pack_failure_injection_cmd(
q=q,
param_id=ParamId.INJECT_ALL_ON_FAILURE,
@ -602,8 +615,8 @@ def handle_plpcdu_hk(pw: PrintWrapper, set_id: int, hk_data: bytes):
pw.dlog(ch_print)
for i in range(12):
pw.dlog(f"{ADC_CHANNELS_NAMED[i].ljust(24)} | {processed_vals[i]}")
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=hk_data[current_idx:], num_vars=3
pw.dlog(
get_validity_buffer_str(validity_buffer=hk_data[current_idx:], num_vars=3)
)

View File

@ -18,7 +18,7 @@ from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s200_fsfw_mode import Mode, pack_mode_data
from tmtccmd.pus.tc.s3_fsfw_hk import generate_one_hk_command, make_sid
from tmtccmd.util import ObjectIdU32
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.fsfw.tmtc_printer import get_validity_buffer_str
class SetId(enum.IntEnum):
@ -66,27 +66,27 @@ def add_rad_sens_cmds(defs: TmtcDefinitionWrapper):
)
def pack_rad_sensor_test_into(
object_id: ObjectIdU32, q: DefaultPusQueueHelper, op_code: str
def create_rad_sensor_cmd(
object_id: ObjectIdU32, q: DefaultPusQueueHelper, cmd_str: str
):
q.add_log_cmd(f"Commanding Radiation sensor handler {object_id}")
if op_code in OpCode.ON:
if cmd_str in OpCode.ON:
rad_sensor_mode_cmd(object_id, Mode.ON, Info.ON, q)
if op_code in OpCode.NORMAL:
if cmd_str in OpCode.NORMAL:
rad_sensor_mode_cmd(object_id, Mode.NORMAL, Info.NORMAL, q)
if op_code in OpCode.OFF:
if cmd_str in OpCode.OFF:
rad_sensor_mode_cmd(object_id, Mode.OFF, Info.OFF, q)
if op_code in OpCode.REQ_HK_ONCE:
if cmd_str in OpCode.REQ_HK_ONCE:
q.add_log_cmd(f"Rad sensor: {Info.REQ_OS_HK}")
q.add_pus_tc(
generate_one_hk_command(sid=make_sid(object_id.as_bytes, set_id=SetId.HK))
)
if op_code in OpCode.DEBUG_ON:
if cmd_str in OpCode.DEBUG_ON:
q.add_log_cmd(f"Rad sensor: {Info.DEBUG_ON}")
command = object_id.as_bytes + struct.pack("!I", CommandId.ENABLE_DEBUG_OUTPUT)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code in OpCode.DEBUG_OFF:
if cmd_str in OpCode.DEBUG_OFF:
q.add_log_cmd(f"Rad sensor: {Info.DEBUG_OFF}")
command = object_id.as_bytes + struct.pack("!I", CommandId.DISABLE_DEBUG_OUTPUT)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
@ -115,6 +115,6 @@ def handle_rad_sensor_data(pw: PrintWrapper, set_id: int, hk_data: bytes):
for idx, val in ain_dict.items():
pw.dlog(f"{idx} | {val:#06x} | {str(val).ljust(5)}")
current_idx += inc_len
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=hk_data[current_idx:], num_vars=7
pw.dlog(
get_validity_buffer_str(validity_buffer=hk_data[current_idx:], num_vars=7)
)

View File

@ -2,16 +2,12 @@ import enum
import json
from spacepackets.ecss import PusTelecommand
from eive_tmtc.config.definitions import CustomServiceList
from tmtccmd.config.tmtc import tmtc_definitions_provider
from tmtccmd.pus.s200_fsfw_mode import Mode, pack_mode_data, Subservice
from tmtccmd.tmtc import service_provider
from tmtccmd.tmtc.decorator import ServiceProviderParams
from tmtccmd.config.tmtc import CmdTreeNode
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from tmtccmd.config import OpCodeEntry, TmtcDefinitionWrapper
from eive_tmtc.config.object_ids import SCEX_HANDLER_ID
from tmtccmd.pus.s200_fsfw_mode import Mode, Subservice, pack_mode_data
from tmtccmd.tmtc import DefaultPusQueueHelper
from eive_tmtc.config.object_ids import SCEX_HANDLER_ID
USE_SCEX_CONF_FILE = True
@ -26,10 +22,8 @@ class OpCode:
ALL_CELLS_CMD = "allcells"
FRAM = "fram"
ON = "on"
SWITCH_ON = "on"
OFF = "off"
SWITCH_OFF = OFF
SWITCH_OFF = "off"
NORMAL = "normal"
@ -59,31 +53,20 @@ class Info:
NORMAL = "Switch SCEX to normal mode"
@tmtc_definitions_provider
def add_scex_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(keys=OpCode.PING, info=Info.PING)
oce.add(keys=OpCode.ION_CMD, info=Info.ION_CMD)
oce.add(keys=OpCode.TEMP_CMD, info=Info.TEMP_CMD)
oce.add(keys=OpCode.EXP_STATUS_CMD, info=Info.EXP_STATUS_CMD)
oce.add(keys=OpCode.ONE_CELLS_CMD, info=Info.ONE_CELLS_CMD)
oce.add(keys=OpCode.ALL_CELLS_CMD, info=Info.ALL_CELLS_CMD)
oce.add(keys=OpCode.FRAM, info=Info.FRAM)
oce.add(keys=OpCode.ON, info=Info.SWITCH_ON)
oce.add(keys=OpCode.OFF, info=Info.SWITCH_OFF)
oce.add(keys=OpCode.NORMAL, info=Info.NORMAL)
defs.add_service(
name=CustomServiceList.SCEX.value, info="SCEX Device", op_code_entry=oce
)
def create_scex_node() -> CmdTreeNode:
op_code_strs = [
getattr(OpCode, key) for key in dir(OpCode) if not key.startswith("__")
]
info_strs = [getattr(Info, key) for key in dir(OpCode) if not key.startswith("__")]
combined_dict = dict(zip(op_code_strs, info_strs))
scex_node = CmdTreeNode("scex", "Solar Cell Experiment")
for op_code, info in combined_dict.items():
scex_node.add_child(CmdTreeNode(op_code, info))
return scex_node
@service_provider(CustomServiceList.SCEX.value)
def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
op_code = p.op_code
q = p.queue_helper
if op_code == OpCode.ON:
def pack_scex_cmds(q: DefaultPusQueueHelper, cmd_str: str): # noqa C901
if cmd_str == OpCode.SWITCH_ON:
q.add_log_cmd(Info.SWITCH_ON)
q.add_pus_tc(
PusTelecommand(
@ -92,7 +75,7 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
app_data=pack_mode_data(SCEX_HANDLER_ID, Mode.ON, 0),
)
)
if op_code == OpCode.NORMAL:
if cmd_str == OpCode.NORMAL:
q.add_log_cmd(Info.NORMAL)
q.add_pus_tc(
PusTelecommand(
@ -101,7 +84,7 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
app_data=pack_mode_data(SCEX_HANDLER_ID, Mode.NORMAL, 0),
)
)
if op_code == OpCode.OFF:
if cmd_str == OpCode.SWITCH_OFF:
q.add_log_cmd(Info.SWITCH_OFF)
q.add_pus_tc(
PusTelecommand(
@ -110,20 +93,20 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
app_data=pack_mode_data(SCEX_HANDLER_ID, Mode.OFF, 0),
)
)
if op_code == OpCode.PING:
if cmd_str == OpCode.PING:
q.add_log_cmd(Info.PING)
app_data = bytes([0])
q.add_pus_tc(create_action_cmd(SCEX_HANDLER_ID, ActionId.PING, app_data))
if op_code == OpCode.ION_CMD:
if cmd_str == OpCode.ION_CMD:
q.add_log_cmd(Info.ION_CMD)
app_data = bytes([0])
q.add_pus_tc(create_action_cmd(SCEX_HANDLER_ID, ActionId.ION_CMD, app_data))
if op_code == OpCode.TEMP_CMD:
if cmd_str == OpCode.TEMP_CMD:
q.add_log_cmd(Info.TEMP_CMD)
app_data = bytes([0])
q.add_pus_tc(create_action_cmd(SCEX_HANDLER_ID, ActionId.TEMP_CMD, app_data))
if op_code == OpCode.EXP_STATUS_CMD:
if cmd_str == OpCode.EXP_STATUS_CMD:
q.add_log_cmd(Info.EXP_STATUS_CMD)
app_data = bytes([0])
q.add_pus_tc(
@ -131,7 +114,7 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
)
# one cell
if op_code == OpCode.ONE_CELLS_CMD:
if cmd_str == OpCode.ONE_CELLS_CMD:
q.add_log_cmd(Info.ONE_CELLS_CMD)
app_data = bytearray([0])
@ -161,7 +144,8 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
dac_weight1 = json_data["dac_weight1"]
dac_weight2 = json_data["dac_weight2"]
dac_weight3 = json_data["dac_weight3"]
else:
raise ValueError("CLI support for SCEX params not implemented")
# in app_data
# app_data.extend(struct.pack("!H", first_dac))
app_data.append(cell_select)
@ -178,7 +162,7 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
create_action_cmd(SCEX_HANDLER_ID, ActionId.ONE_CELLS_CMD, app_data)
)
if op_code == OpCode.ALL_CELLS_CMD:
if cmd_str == OpCode.ALL_CELLS_CMD:
q.add_log_cmd(Info.ALL_CELLS_CMD)
app_data = bytearray([0])
@ -195,6 +179,8 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
dac_weight2 = json_data["dac_weight2"]
dac_weight3 = json_data["dac_weight3"]
else:
raise ValueError("CLI support for SCEX params not implemented")
# in app_data
# app_data.extend(struct.pack("!H", first_dac))
append_16_bit_val(packet=app_data, val=first_dac[cn])
@ -210,7 +196,7 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
create_action_cmd(SCEX_HANDLER_ID, ActionId.ALL_CELLS_CMD, app_data)
)
if op_code == OpCode.FRAM:
if cmd_str == OpCode.FRAM:
q.add_log_cmd(Info.FRAM)
app_data = bytes([0])
q.add_pus_tc(create_action_cmd(SCEX_HANDLER_ID, ActionId.FRAM, app_data))

View File

@ -1,14 +1,11 @@
import enum
from typing import Dict, Tuple
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.config.object_ids import PL_SUBSYSTEM_ID
from spacepackets.ecss import PusTelecommand
from eive_tmtc.tmtc.common import pack_mode_cmd_with_info
from tmtccmd.config import TmtcDefinitionWrapper, OpCodeEntry
from tmtccmd.config.tmtc import tmtc_definitions_provider
from tmtccmd.tmtc import service_provider
from tmtccmd.tmtc.decorator import ServiceProviderParams
from tmtccmd.config import CmdTreeNode
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s200_fsfw_mode import Subservice as ModeSubservice
@ -24,24 +21,28 @@ class ModeId(enum.IntEnum):
class OpCode(str, enum.Enum):
OFF = "off"
REPORT_ALL_MODES = "report_modes"
MPSOC_STREAM = "mode_mpsoc_stream"
CAM_STREAM = "mode_cam_stream"
EARTH_OBSV = "mode_eart_obsv"
class Info(str, enum.Enum):
OFF = "Off Command"
REPORT_ALL_MODES = "Report all modes"
MPSOC_STREAM = "MPSoC Stream Mode"
CAM_STREAM = "Camera Stream Mode"
EARTH_OBSV = "Earth Observation Mode"
HANDLER_LIST: Dict[str, Tuple[int, str]] = {
OpCode.OFF: (ModeId.OFF, Info.OFF),
OpCode.MPSOC_STREAM: (ModeId.MPSOC_STREAM, Info.MPSOC_STREAM),
}
@service_provider(CustomServiceList.PL_SS)
def build_acs_subsystem_cmd(p: ServiceProviderParams):
op_code = p.op_code
q = p.queue_helper
info_prefix = "ACS Subsystem"
if op_code in OpCode.REPORT_ALL_MODES:
def create_payload_subsystem_cmd(q: DefaultPusQueueHelper, cmd_str: str):
info_prefix = "Payload Subsystem"
if cmd_str == OpCode.REPORT_ALL_MODES:
q.add_log_cmd(f"{info_prefix}: {Info.REPORT_ALL_MODES}")
q.add_pus_tc(
PusTelecommand(
@ -50,21 +51,29 @@ def build_acs_subsystem_cmd(p: ServiceProviderParams):
app_data=PL_SUBSYSTEM_ID,
)
)
mode_info_tup = HANDLER_LIST.get(op_code)
mode_info_tup = HANDLER_LIST.get(cmd_str)
assert mode_info_tup is not None
if mode_info_tup is None:
return
pack_mode_cmd_with_info(
object_id=PL_SUBSYSTEM_ID,
info=f"{info_prefix}: {mode_info_tup[1]}",
submode=0,
mode=mode_info_tup[0],
submode=0,
q=q,
)
@tmtc_definitions_provider
def add_payload_subsystem_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(OpCode.OFF, Info.OFF)
oce.add(OpCode.REPORT_ALL_MODES, Info.REPORT_ALL_MODES)
defs.add_service(CustomServiceList.PL_SS, "Payload Subsystem", oce)
def create_payload_subsystem_node() -> CmdTreeNode:
payload_node = CmdTreeNode("payload", "Payload Subsystem")
subsystem_node = CmdTreeNode("subsystem", "Subsystem Commands")
subsystem_node.add_child(CmdTreeNode(OpCode.OFF, Info.OFF))
subsystem_node.add_child(CmdTreeNode(OpCode.MPSOC_STREAM, Info.MPSOC_STREAM))
subsystem_node.add_child(CmdTreeNode(OpCode.EARTH_OBSV, Info.EARTH_OBSV))
subsystem_node.add_child(CmdTreeNode(OpCode.CAM_STREAM, Info.CAM_STREAM))
subsystem_node.add_child(
CmdTreeNode(OpCode.REPORT_ALL_MODES, Info.REPORT_ALL_MODES)
)
payload_node.add_child(subsystem_node)
return payload_node

View File

@ -1,2 +0,0 @@
from .subsystem import add_eps_subsystem_cmds
from .pwr_ctrl import pwr_cmd_defs

View File

@ -8,6 +8,7 @@ import struct
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.pus_tm.defs import PrintWrapper
from eive_tmtc.tmtc.power.common_power import (
add_gomspace_nodes,
pack_common_gomspace_cmds,
add_gomspace_cmd_defs,
req_hk_cmds,
@ -16,7 +17,7 @@ from eive_tmtc.tmtc.power.common_power import (
OBC_ENDIANNESS,
unpack_array_in_data,
)
from tmtccmd.config import TmtcDefinitionWrapper, OpCodeEntry
from tmtccmd.config import CmdTreeNode, TmtcDefinitionWrapper, OpCodeEntry
from tmtccmd.config.tmtc import tmtc_definitions_provider
from tmtccmd.tmtc import DefaultPusQueueHelper
@ -50,6 +51,15 @@ class Info:
TEST = "ACU Test"
def create_acu_node() -> CmdTreeNode:
node = CmdTreeNode(
"acu", "P60 PCDU ACU device", hide_children_which_are_leaves=True
)
add_gomspace_nodes(node)
node.add_child(CmdTreeNode(OpCode.TEST[0], Info.TEST))
return node
@tmtc_definitions_provider
def add_acu_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
@ -63,16 +73,16 @@ def add_acu_cmds(defs: TmtcDefinitionWrapper):
)
def pack_acu_commands(object_id: ObjectIdU32, q: DefaultPusQueueHelper, op_code: str):
def pack_acu_commands(object_id: ObjectIdU32, q: DefaultPusQueueHelper, cmd_str: str):
q.add_log_cmd("Handling ACU command")
pack_common_power_cmds("ACU", object_id, q, op_code)
pack_common_gomspace_cmds("ACU", object_id, q, op_code)
acu_req_hk_cmds(q, op_code)
pack_common_power_cmds("ACU", object_id, q, cmd_str)
pack_common_gomspace_cmds("ACU", object_id, q, cmd_str)
acu_req_hk_cmds(q, cmd_str)
pack_test_cmds(object_id=object_id, q=q)
def acu_req_hk_cmds(q: DefaultPusQueueHelper, op_code: str):
req_hk_cmds("ACU", q, op_code, ACU_HANDLER_ID, [SetId.CORE, SetId.AUX])
req_hk_cmds("ACU", q, op_code, ACU_HANDLER_ID, (SetId.CORE, SetId.AUX))
class ACUTestProcedure:

View File

@ -1,23 +1,19 @@
import enum
import struct
from eive_tmtc.pus_tm.defs import PrintWrapper
from spacepackets.ecss import PusTelecommand
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.config.object_ids import BPX_HANDLER_ID
from tmtccmd.config.tmtc import (
tmtc_definitions_provider,
TmtcDefinitionWrapper,
OpCodeEntry,
CmdTreeNode,
)
from tmtccmd.tmtc import service_provider
from tmtccmd.tmtc.decorator import ServiceProviderParams
from tmtccmd.fsfw.tmtc_printer import get_validity_buffer_str
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from tmtccmd.pus.tc.s3_fsfw_hk import generate_one_hk_command, make_sid
from tmtccmd.pus.s200_fsfw_mode import pack_mode_data, Mode
from tmtccmd.pus.s200_fsfw_mode import Mode, pack_mode_data
from tmtccmd.pus.s200_fsfw_mode import Subservice as ModeSubservices
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.pus.tc.s3_fsfw_hk import generate_one_hk_command, make_sid
from tmtccmd.tmtc import DefaultPusQueueHelper
from eive_tmtc.config.object_ids import BPX_HANDLER_ID
from eive_tmtc.pus_tm.defs import PrintWrapper
class BpxSetId(enum.IntEnum):
@ -54,38 +50,38 @@ class BpxOpCode:
REBOOT = "reboot"
@tmtc_definitions_provider
def add_bpx_cmd_definitions(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(keys=BpxOpCode.ON, info="On command")
oce.add(keys=BpxOpCode.OFF, info="Off command")
oce.add(keys=BpxOpCode.HK, info="Request BPX HK")
oce.add(keys=BpxOpCode.RST_BOOT_CNT, info="Reset Boot Count")
oce.add(keys=BpxOpCode.RST_CFG, info="Reset Config to stored default settings")
oce.add(keys=BpxOpCode.SET_CFG, info="Set BPX configuration")
oce.add(keys=BpxOpCode.MAN_HEATER_ON, info="Manual heater on")
oce.add(keys=BpxOpCode.MAN_HEATER_OFF, info="Manual heater off")
oce.add(keys=BpxOpCode.REQUEST_CFG, info="Request Configuration Struct (Step 1)")
oce.add(
keys=BpxOpCode.REQUEST_CFG_HK, info="Request Configuration Struct HK (Step 2)"
def create_bpx_batt_node() -> CmdTreeNode:
node = CmdTreeNode("bat", "BPX battery device", hide_children_for_print=True)
node.add_child(CmdTreeNode(BpxOpCode.ON, "ON command"))
node.add_child(CmdTreeNode(BpxOpCode.OFF, "OFF command"))
node.add_child(CmdTreeNode(BpxOpCode.HK, "HK command"))
node.add_child(CmdTreeNode(BpxOpCode.RST_BOOT_CNT, "Reset boot count"))
node.add_child(
CmdTreeNode(BpxOpCode.RST_CFG, "Reset Config to stored default settings")
)
oce.add(keys=BpxOpCode.REBOOT, info="Reboot Command")
defs.add_service(
name=CustomServiceList.BPX_BATTERY.value,
info="BPX Battery Handler",
op_code_entry=oce,
node.add_child(CmdTreeNode(BpxOpCode.SET_CFG, "Set BPX configuration"))
node.add_child(CmdTreeNode(BpxOpCode.MAN_HEATER_ON, "Manual heater on"))
node.add_child(CmdTreeNode(BpxOpCode.MAN_HEATER_OFF, "Manual heater off"))
node.add_child(
CmdTreeNode(BpxOpCode.REQUEST_CFG, "Request Configuration Struct (Step 1)")
)
node.add_child(
CmdTreeNode(
BpxOpCode.REQUEST_CFG_HK, "Request Configuration Struct HK (Step 2)"
)
)
node.add_child(CmdTreeNode(BpxOpCode.REBOOT, "Reboot Command"))
return node
@service_provider(CustomServiceList.BPX_BATTERY.value)
def pack_bpx_commands(p: ServiceProviderParams): # noqa C901: Complexity is okay here.
op_code = p.op_code
q = p.queue_helper
if op_code == BpxOpCode.HK:
def pack_bpx_commands(
q: DefaultPusQueueHelper, cmd_str: str
): # noqa C901: Complexity is okay here.
if cmd_str == BpxOpCode.HK:
q.add_log_cmd("Requesting BPX battery HK set")
sid = make_sid(object_id=BPX_HANDLER_ID, set_id=BpxSetId.GET_HK_SET)
q.add_pus_tc(generate_one_hk_command(sid=sid))
if op_code == BpxOpCode.OFF:
if cmd_str == BpxOpCode.OFF:
q.add_log_cmd("Off mode")
mode_cmd = pack_mode_data(BPX_HANDLER_ID, Mode.OFF, 0)
q.add_pus_tc(
@ -95,7 +91,7 @@ def pack_bpx_commands(p: ServiceProviderParams): # noqa C901: Complexity is oka
app_data=mode_cmd,
)
)
if op_code == BpxOpCode.ON:
if cmd_str == BpxOpCode.ON:
q.add_log_cmd("On mode")
mode_cmd = pack_mode_data(BPX_HANDLER_ID, Mode.ON, 0)
q.add_pus_tc(
@ -105,21 +101,21 @@ def pack_bpx_commands(p: ServiceProviderParams): # noqa C901: Complexity is oka
app_data=mode_cmd,
)
)
if op_code == BpxOpCode.RST_BOOT_CNT:
if cmd_str == BpxOpCode.RST_BOOT_CNT:
q.add_log_cmd("Resetting reboot counters")
q.add_pus_tc(
create_action_cmd(
object_id=BPX_HANDLER_ID, action_id=BpxActionId.RESET_COUNTERS
)
)
if op_code == BpxOpCode.RST_CFG:
if cmd_str == BpxOpCode.RST_CFG:
q.add_log_cmd("Reset BPX configuration")
q.add_pus_tc(
create_action_cmd(
object_id=BPX_HANDLER_ID, action_id=BpxActionId.CONFIG_CMD
)
)
if op_code == BpxOpCode.SET_CFG:
if cmd_str == BpxOpCode.SET_CFG:
q.add_log_cmd("Setting BPX configuration")
user_data = bytearray()
batt_mode = BpxHeaterModeSelect(
@ -137,21 +133,21 @@ def pack_bpx_commands(p: ServiceProviderParams): # noqa C901: Complexity is oka
user_data=user_data,
)
)
if op_code == BpxOpCode.REQUEST_CFG:
if cmd_str == BpxOpCode.REQUEST_CFG:
q.add_log_cmd("Requesting configuration struct")
q.add_pus_tc(
create_action_cmd(object_id=BPX_HANDLER_ID, action_id=BpxActionId.GET_CFG)
)
if op_code == BpxOpCode.REQUEST_CFG_HK:
if cmd_str == BpxOpCode.REQUEST_CFG_HK:
q.add_log_cmd("Requesting configuration struct HK")
sid = make_sid(object_id=BPX_HANDLER_ID, set_id=BpxSetId.GET_CFG_SET)
q.add_pus_tc(generate_one_hk_command(sid=sid))
if op_code == BpxOpCode.REBOOT:
if cmd_str == BpxOpCode.REBOOT:
q.add_log_cmd("Rebooting BPX battery")
q.add_pus_tc(
create_action_cmd(object_id=BPX_HANDLER_ID, action_id=BpxActionId.REBOOT)
)
if op_code == BpxOpCode.MAN_HEATER_ON:
if cmd_str == BpxOpCode.MAN_HEATER_ON:
q.add_log_cmd("BPX manual heater on with seconds burntime")
burn_time = int(input("BPX heater burn time in seconds [1-65535]: "))
if burn_time < 1 or burn_time > 65535:
@ -163,7 +159,7 @@ def pack_bpx_commands(p: ServiceProviderParams): # noqa C901: Complexity is oka
user_data=struct.pack("!H", burn_time),
)
)
if op_code == BpxOpCode.MAN_HEATER_OFF:
if cmd_str == BpxOpCode.MAN_HEATER_OFF:
q.add_log_cmd("BPX manual heater off")
q.add_pus_tc(
create_action_cmd(
@ -217,9 +213,7 @@ def handle_bpx_hk_data(pw: PrintWrapper, set_id: int, hk_data: bytes):
validity_buffer = hk_data[inc_len:]
pw.dlog(str(HEADER_LIST))
pw.dlog(str(content_list))
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=validity_buffer, num_vars=10
)
pw.dlog(get_validity_buffer_str(validity_buffer=validity_buffer, num_vars=10))
elif set_id == BpxSetId.GET_CFG_SET:
battheat_mode = hk_data[0]
battheat_low = struct.unpack("!b", hk_data[1:2])[0]
@ -233,6 +227,4 @@ def handle_bpx_hk_data(pw: PrintWrapper, set_id: int, hk_data: bytes):
validity_buffer = hk_data[3:]
pw.dlog(str(header_list))
pw.dlog(str(content_list))
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=validity_buffer, num_vars=10
)
pw.dlog(get_validity_buffer_str(validity_buffer=validity_buffer, num_vars=10))

View File

@ -1,6 +1,6 @@
import enum
import struct
from typing import List
from typing import List, Tuple
from eive_tmtc.gomspace.gomspace_common import (
pack_set_u8_param_command,
@ -14,8 +14,7 @@ from eive_tmtc.gomspace.gomspace_common import (
pack_reboot_command,
)
from eive_tmtc.gomspace.gomspace_pdu_definitions import OUT_ENABLE_LIST
from spacepackets.ecss import PusTelecommand
from tmtccmd.config import OpCodeEntry
from tmtccmd.config import CmdTreeNode, OpCodeEntry
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.tc.s3_fsfw_hk import (
make_sid,
@ -258,7 +257,7 @@ def req_hk_cmds(
q: DefaultPusQueueHelper,
op_code: str,
obj_id: bytes,
set_id_pair: [int, int],
set_id_pair: Tuple[int, int],
):
if op_code in PowerOpCodes.REQUEST_CORE_HK_ONCE:
q.add_log_cmd(f"{prefix}: {PowerInfo.REQUEST_CORE_HK_ONCE}")
@ -270,10 +269,6 @@ def req_hk_cmds(
q.add_pus_tc(generate_one_hk_command(sid=hk_sid))
def pack_pdu_disable_safe_off_cmd() -> PusTelecommand:
pass
def generic_on_cmd(
object_id: bytes, q: DefaultPusQueueHelper, info_str: str, out_idx: int
):
@ -311,6 +306,54 @@ def add_common_power_defs(oce: OpCodeEntry):
oce.add(keys=PowerOpCodes.DISABLE_INFO_HK, info=PowerInfo.DISABLE_INFO_HK)
def add_gomspace_nodes(node: CmdTreeNode):
node.add_child(
CmdTreeNode(
PowerOpCodes.REQUEST_CORE_HK_ONCE[0], PowerInfo.REQUEST_CORE_HK_ONCE
)
)
node.add_child(
CmdTreeNode(PowerOpCodes.REQUEST_AUX_HK_ONCE[0], PowerInfo.REQUEST_AUX_HK_ONCE)
)
node.add_child(
CmdTreeNode(PowerOpCodes.ENABLE_INFO_HK[0], PowerInfo.ENABLE_INFO_HK)
)
node.add_child(
CmdTreeNode(PowerOpCodes.DISABLE_INFO_HK[0], PowerInfo.DISABLE_INFO_HK)
)
node.add_child(
CmdTreeNode(
PowerOpCodes.REQUEST_CORE_HK_ONCE[0],
PowerInfo.REQUEST_CORE_HK_ONCE,
)
)
node.add_child(
CmdTreeNode(
PowerOpCodes.REQUEST_AUX_HK_ONCE[0],
PowerInfo.REQUEST_AUX_HK_ONCE,
)
)
node.add_child(
CmdTreeNode(PowerOpCodes.PRINT_LATCHUPS[0], PowerInfo.PRINT_LATCHUPS)
)
node.add_child(CmdTreeNode(GomspaceOpCode.GET_PARAM[0], GsInfo.GET_PARAMETER))
node.add_child(CmdTreeNode(GomspaceOpCode.REBOOT[0], GsInfo.REBOOT))
node.add_child(
CmdTreeNode(GomspaceOpCode.SET_INTEGER_PARAM[0], GsInfo.SET_PARAMETER)
)
node.add_child(
CmdTreeNode(GomspaceOpCode.REQUEST_CONFIG_TABLE[0], GsInfo.REQUEST_CONFIG_TABLE)
)
node.add_child(CmdTreeNode(GomspaceOpCode.SAVE_TABLE[0], GsInfo.SAVE_TABLE))
node.add_child(
CmdTreeNode(GomspaceOpCode.SAVE_TABLE_DEFAULT[0], GsInfo.SAVE_TABLE_DEFAULT)
)
node.add_child(CmdTreeNode(GomspaceOpCode.LOAD_TABLE[0], GsInfo.LOAD_TABLE))
node.add_child(
CmdTreeNode(GomspaceOpCode.RESET_GND_WATCHDOG[0], GsInfo.RESET_GND_WATCHDOG)
)
def add_gomspace_cmd_defs(oce: OpCodeEntry):
oce.add(
keys=PowerOpCodes.REQUEST_CORE_HK_ONCE,

View File

@ -5,7 +5,9 @@
@author J. Meier
@date 13.12.2020
"""
from tmtccmd.config import CmdTreeNode
from eive_tmtc.tmtc.power.common_power import (
add_gomspace_nodes,
pack_common_gomspace_cmds,
req_hk_cmds,
pack_common_power_cmds,
@ -27,22 +29,24 @@ from eive_tmtc.config.object_ids import P60_DOCK_HANDLER
from tmtccmd.util import ObjectIdU32
class P60OpCode:
class CmdString:
STACK_3V3_ON = "stack_3v3_on"
STACK_3V3_OFF = "stack_3v3_off"
STACK_5V_ON = "stack_5v_on"
STACK_5V_OFF = "stack_5v_off"
TEST = "test"
ACU_OFF = "acu_off"
ACU_ON = "acu_on"
TEST = ["test", "0"]
class P60Info:
class CmdInfo:
PREFIX = "P60 Dock"
STACK_3V3_ON = f"{PREFIX}: Turn Stack 3V3 on"
STACK_3V3_OFF = f"{PREFIX}: Turn Stack 3V3 off"
STACK_5V_ON = f"{PREFIX}: Turn Stack 5V on"
STACK_5V_OFF = f"{PREFIX}: Turn Stack 5V off"
ACU_OFF = "Switch ACU off"
ACU_ON = "Switch ACU on"
class P60DockTestProcedure:
@ -101,14 +105,14 @@ class P60DockHkTable:
def pack_p60dock_cmds( # noqa C901: Complexity okay here.
object_id: ObjectIdU32, q: DefaultPusQueueHelper, op_code: str
object_id: ObjectIdU32, q: DefaultPusQueueHelper, cmd_str: str
):
objb = object_id.as_bytes
pack_common_power_cmds("P60 Dock", object_id, q, op_code)
pack_common_gomspace_cmds("P60 Dock", object_id, q, op_code)
p60_dock_req_hk_cmds(q, op_code)
if op_code in P60OpCode.STACK_3V3_ON:
q.add_log_cmd(P60Info.STACK_3V3_ON)
pack_common_power_cmds("P60 Dock", object_id, q, cmd_str)
pack_common_gomspace_cmds("P60 Dock", object_id, q, cmd_str)
p60_dock_req_hk_cmds(q, cmd_str)
if cmd_str == CmdString.STACK_3V3_ON:
q.add_log_cmd(CmdInfo.STACK_3V3_ON)
q.add_pus_tc(
pack_set_u8_param_command(
objb,
@ -116,8 +120,8 @@ def pack_p60dock_cmds( # noqa C901: Complexity okay here.
Channel.on,
)
)
if op_code in P60OpCode.STACK_3V3_OFF:
q.add_log_cmd(P60Info.STACK_3V3_OFF)
if cmd_str == CmdString.STACK_3V3_OFF:
q.add_log_cmd(CmdInfo.STACK_3V3_OFF)
q.add_pus_tc(
pack_set_u8_param_command(
objb,
@ -125,8 +129,8 @@ def pack_p60dock_cmds( # noqa C901: Complexity okay here.
Channel.off,
)
)
if op_code in P60OpCode.STACK_5V_ON:
q.add_log_cmd(P60Info.STACK_5V_ON)
if cmd_str == CmdString.STACK_5V_ON:
q.add_log_cmd(CmdInfo.STACK_5V_ON)
q.add_pus_tc(
pack_set_u8_param_command(
objb,
@ -134,8 +138,8 @@ def pack_p60dock_cmds( # noqa C901: Complexity okay here.
Channel.on,
)
)
if op_code in P60OpCode.STACK_5V_OFF:
q.add_log_cmd(P60Info.STACK_5V_OFF)
if cmd_str == CmdString.STACK_5V_OFF:
q.add_log_cmd(CmdInfo.STACK_5V_OFF)
q.add_pus_tc(
pack_set_u8_param_command(
objb,
@ -241,5 +245,18 @@ def pack_p60dock_cmds( # noqa C901: Complexity okay here.
q.add_pus_tc(pack_set_u16_param_command(objb, invalid_address, parameter))
def create_p60_dock_node() -> CmdTreeNode:
node = CmdTreeNode(
"p60_dock", "P60 PCDU dock device", hide_children_which_are_leaves=True
)
add_gomspace_nodes(node)
node.add_child(CmdTreeNode(CmdString.STACK_3V3_ON, CmdInfo.STACK_3V3_ON))
node.add_child(CmdTreeNode(CmdString.STACK_3V3_OFF, CmdInfo.STACK_3V3_OFF))
node.add_child(CmdTreeNode(CmdString.STACK_5V_ON, CmdInfo.STACK_5V_ON))
node.add_child(CmdTreeNode(CmdString.STACK_5V_OFF, CmdInfo.STACK_5V_OFF))
node.add_child(CmdTreeNode(CmdString.TEST, "P60 Tests"))
return node
def p60_dock_req_hk_cmds(q: DefaultPusQueueHelper, op_code: str):
req_hk_cmds("P60 Dock", q, op_code, P60_DOCK_HANDLER, [SetId.CORE, SetId.AUX])
req_hk_cmds("P60 Dock", q, op_code, P60_DOCK_HANDLER, (SetId.CORE, SetId.AUX))

View File

@ -14,6 +14,7 @@ from eive_tmtc.gomspace.gomspace_common import (
)
from eive_tmtc.gomspace.gomspace_pdu_definitions import PduHkTable
from eive_tmtc.tmtc.power.common_power import (
add_gomspace_nodes,
pack_common_gomspace_cmds,
req_hk_cmds,
PowerOpCodes,
@ -23,14 +24,12 @@ from eive_tmtc.tmtc.power.common_power import (
create_generic_on_cmd,
create_generic_off_cmd,
pack_common_power_cmds,
GomspaceOpCode,
GsInfo,
add_common_power_defs,
SetId,
)
from spacepackets.ecss import PusTelecommand
from tmtccmd.config import OpCodeEntry, TmtcDefinitionWrapper
from tmtccmd.config import CmdTreeNode, OpCodeEntry, TmtcDefinitionWrapper
from tmtccmd.config.tmtc import tmtc_definitions_provider
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.util import ObjectIdU32
@ -75,13 +74,13 @@ class PDU1TestProcedure:
turn_channel_3_off = False
def pack_pdu1_commands(object_id: ObjectIdU32, q: DefaultPusQueueHelper, op_code: str):
def pack_pdu1_commands(object_id: ObjectIdU32, q: DefaultPusQueueHelper, cmd_str: str):
q.add_log_cmd("Commanding PDU1")
objb = object_id.as_bytes
pdu1_switch_cmds(q, op_code)
pdu1_req_hk_cmds(q, op_code)
pack_common_power_cmds("PDU1", object_id, q, op_code)
pack_common_gomspace_cmds("PDU1", object_id, q, op_code)
pdu1_switch_cmds(q, cmd_str)
pdu1_req_hk_cmds(q, cmd_str)
pack_common_power_cmds("PDU1", object_id, q, cmd_str)
pack_common_gomspace_cmds("PDU1", object_id, q, cmd_str)
if PDU1TestProcedure.all or PDU1TestProcedure.ping:
q.add_log_cmd("PDU1: Ping Test")
ping_data = bytearray([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
@ -99,7 +98,7 @@ def pack_pdu1_commands(object_id: ObjectIdU32, q: DefaultPusQueueHelper, op_code
def pdu1_req_hk_cmds(q: DefaultPusQueueHelper, op_code: str):
req_hk_cmds("PDU1", q, op_code, PDU_1_HANDLER_ID, [SetId.CORE, SetId.AUX])
req_hk_cmds("PDU1", q, op_code, PDU_1_HANDLER_ID, (SetId.CORE, SetId.AUX))
def info_on_pdu1(base: str) -> str:
@ -111,39 +110,39 @@ def info_off_pdu1(base: str) -> str:
def pdu1_switch_cmds( # noqa C901: Complexity is okay here.
q: DefaultPusQueueHelper, op_code: str
q: DefaultPusQueueHelper, cmd_str: str
): # noqa C901: Complexity okay here
if op_code in PowerOpCodes.TCS_ON:
if cmd_str in PowerOpCodes.TCS_ON:
tcs_on_cmd(q)
elif op_code in PowerOpCodes.TCS_OFF:
elif cmd_str in PowerOpCodes.TCS_OFF:
tcs_off_cmd(q)
elif op_code in PowerOpCodes.SYRLINKS_ON:
elif cmd_str in PowerOpCodes.SYRLINKS_ON:
syrlinks_on_cmd(q)
elif op_code in PowerOpCodes.SYRLINKS_OFF:
elif cmd_str in PowerOpCodes.SYRLINKS_OFF:
syrlinks_off_cmd(q)
elif op_code in PowerOpCodes.STAR_TRACKER_ON:
elif cmd_str in PowerOpCodes.STAR_TRACKER_ON:
startracker_on_cmd(q)
elif op_code in PowerOpCodes.STAR_TRACKER_OFF:
elif cmd_str in PowerOpCodes.STAR_TRACKER_OFF:
startracker_off_cmd(q)
elif op_code in PowerOpCodes.MGT_ON:
elif cmd_str in PowerOpCodes.MGT_ON:
mgt_on_cmd(q)
elif op_code in PowerOpCodes.MGT_OFF:
elif cmd_str in PowerOpCodes.MGT_OFF:
mgt_off_cmd(q)
elif op_code in PowerOpCodes.SUS_N_ON:
elif cmd_str in PowerOpCodes.SUS_N_ON:
sun_sensor_nominal_on_cmd(q)
elif op_code in PowerOpCodes.SUS_N_OFF:
elif cmd_str in PowerOpCodes.SUS_N_OFF:
sun_sensor_nominal_off_cmd(q)
elif op_code in PowerOpCodes.SCEX_ON:
elif cmd_str in PowerOpCodes.SCEX_ON:
solar_cell_experiment_on_cmd(q)
elif op_code in PowerOpCodes.SCEX_OFF:
elif cmd_str in PowerOpCodes.SCEX_OFF:
solar_cell_experiment_off_cmd(q)
elif op_code in PowerOpCodes.PLOC_ON:
elif cmd_str in PowerOpCodes.PLOC_ON:
ploc_on_cmd(q)
elif op_code in PowerOpCodes.PLOC_OFF:
elif cmd_str in PowerOpCodes.PLOC_OFF:
ploc_off_cmd(q)
elif op_code in PowerOpCodes.ACS_A_ON:
elif cmd_str in PowerOpCodes.ACS_A_ON:
acs_board_a_on_cmd(q)
elif op_code in PowerOpCodes.ACS_A_OFF:
elif cmd_str in PowerOpCodes.ACS_A_OFF:
acs_board_a_off_cmd(q)
@ -166,6 +165,67 @@ def add_pdu1_common_defs(oce: OpCodeEntry):
oce.add(keys=PowerOpCodes.SCEX_OFF, info=info_off_pdu1(Pdu1InfoBase.SCEX))
def add_pdu1_subnodes(node: CmdTreeNode):
node.add_child(CmdTreeNode(PowerOpCodes.TCS_ON[0], info_on_pdu1(Pdu1InfoBase.TCS)))
node.add_child(
CmdTreeNode(PowerOpCodes.TCS_OFF[0], info_off_pdu1(Pdu1InfoBase.TCS))
)
node.add_child(
CmdTreeNode(PowerOpCodes.STAR_TRACKER_ON[0], info_on_pdu1(Pdu1InfoBase.STR))
)
node.add_child(
CmdTreeNode(PowerOpCodes.STAR_TRACKER_OFF[0], info_off_pdu1(Pdu1InfoBase.STR))
)
node.add_child(
CmdTreeNode(PowerOpCodes.SUS_N_ON[0], info_on_pdu1(Pdu1InfoBase.SUS_N))
)
node.add_child(
CmdTreeNode(PowerOpCodes.SUS_N_OFF[0], info_off_pdu1(Pdu1InfoBase.SUS_N))
)
node.add_child(
CmdTreeNode(PowerOpCodes.ACS_A_ON[0], info_on_pdu1(Pdu1InfoBase.ACS_A))
)
node.add_child(
CmdTreeNode(PowerOpCodes.ACS_A_OFF[0], info_off_pdu1(Pdu1InfoBase.ACS_A))
)
node.add_child(
CmdTreeNode(PowerOpCodes.SYRLINKS_ON[0], info_on_pdu1(Pdu1InfoBase.SYRLINKS))
)
node.add_child(
CmdTreeNode(PowerOpCodes.SYRLINKS_OFF[0], info_off_pdu1(Pdu1InfoBase.SYRLINKS))
)
node.add_child(CmdTreeNode(PowerOpCodes.MGT_ON[0], info_on_pdu1(Pdu1InfoBase.MGT)))
node.add_child(
CmdTreeNode(PowerOpCodes.MGT_OFF[0], info_off_pdu1(Pdu1InfoBase.MGT))
)
node.add_child(
CmdTreeNode(PowerOpCodes.PLOC_ON[0], info_on_pdu1(Pdu1InfoBase.PLOC))
)
node.add_child(
CmdTreeNode(PowerOpCodes.PLOC_OFF[0], info_off_pdu1(Pdu1InfoBase.PLOC))
)
node.add_child(
CmdTreeNode(PowerOpCodes.SCEX_ON[0], info_on_pdu1(Pdu1InfoBase.SCEX))
)
node.add_child(
CmdTreeNode(PowerOpCodes.SCEX_OFF[0], info_off_pdu1(Pdu1InfoBase.SCEX))
)
def create_pdu1_node() -> CmdTreeNode:
node = CmdTreeNode(
"pdu1", "P60 PCDU PDU1 device", hide_children_which_are_leaves=True
)
add_gomspace_nodes(node)
add_pdu1_subnodes(node)
node.add_child(
CmdTreeNode(
PowerOpCodes.PRINT_SWITCH_V_I[0], "PDU1: Print Switches, Voltages, Currents"
)
)
return node
@tmtc_definitions_provider
def add_pdu1_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
@ -176,7 +236,6 @@ def add_pdu1_cmds(defs: TmtcDefinitionWrapper):
keys=PowerOpCodes.PRINT_SWITCH_V_I,
info="PDU1: Print Switches, Voltages, Currents",
)
oce.add(keys=GomspaceOpCode.GET_PARAM, info=GsInfo.GET_PARAMETER)
defs.add_service(
name=CustomServiceList.PDU1.value,

View File

@ -19,6 +19,7 @@ from eive_tmtc.gomspace.gomspace_common import (
)
from eive_tmtc.gomspace.gomspace_pdu_definitions import PduHkTable, PduConfigTable
from eive_tmtc.tmtc.power.common_power import (
add_gomspace_nodes,
pack_common_gomspace_cmds,
req_hk_cmds,
PowerOpCodes,
@ -32,7 +33,7 @@ from eive_tmtc.tmtc.power.common_power import (
add_common_power_defs,
)
from spacepackets.ecss import PusTelecommand
from tmtccmd.config import OpCodeEntry, TmtcDefinitionWrapper
from tmtccmd.config import CmdTreeNode, OpCodeEntry, TmtcDefinitionWrapper
from tmtccmd.config.tmtc import tmtc_definitions_provider
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.util import ObjectIdU32
@ -88,13 +89,13 @@ class PDU2TestProcedure:
request_hk_table = False
def pack_pdu2_commands(object_id: ObjectIdU32, q: DefaultPusQueueHelper, op_code: str):
def pack_pdu2_commands(object_id: ObjectIdU32, q: DefaultPusQueueHelper, cmd_str: str):
q.add_log_cmd("Testing PDU2")
objb = object_id.as_bytes
pdu2_switch_cmds(q, op_code)
pdu2_req_hk_cmds(q, op_code)
pack_common_power_cmds("PDU2", object_id, q, op_code)
pack_common_gomspace_cmds("PDU2", object_id, q, op_code)
pdu2_switch_cmds(q, cmd_str)
pdu2_req_hk_cmds(q, cmd_str)
pack_common_power_cmds("PDU2", object_id, q, cmd_str)
pack_common_gomspace_cmds("PDU2", object_id, q, cmd_str)
if PDU2TestProcedure.all or PDU2TestProcedure.reboot:
q.add_log_cmd("PDU2: Reboot")
q.add_pus_tc(pack_reboot_command(object_id))
@ -171,6 +172,85 @@ def add_pdu2_cmds(defs: TmtcDefinitionWrapper):
)
def add_pdu2_subnodes(node: CmdTreeNode):
node.add_child(
CmdTreeNode(PowerOpCodes.ACS_B_ON[0], info_on_pdu2(Pdu2InfoBase.ACS_B))
)
node.add_child(
CmdTreeNode(PowerOpCodes.ACS_B_OFF[0], info_off_pdu2(Pdu2InfoBase.ACS_B))
)
node.add_child(
CmdTreeNode(PowerOpCodes.SUS_R_ON[0], info_on_pdu2(Pdu2InfoBase.SUS_R))
)
node.add_child(
CmdTreeNode(PowerOpCodes.SUS_R_OFF[0], info_off_pdu2(Pdu2InfoBase.SUS_R))
)
node.add_child(CmdTreeNode(PowerOpCodes.RW_ON[0], info_on_pdu2(Pdu2InfoBase.RW)))
node.add_child(CmdTreeNode(PowerOpCodes.RW_OFF[0], info_off_pdu2(Pdu2InfoBase.RW)))
node.add_child(
CmdTreeNode(
PowerOpCodes.PL_PCDU_VBAT_NOM_ON[0],
info_on_pdu2(Pdu2InfoBase.PL_PCDU_BAT_NOM),
)
)
node.add_child(
CmdTreeNode(
PowerOpCodes.PL_PCDU_VBAT_NOM_OFF[0],
info_off_pdu2(Pdu2InfoBase.PL_PCDU_BAT_NOM),
)
)
node.add_child(
CmdTreeNode(
PowerOpCodes.PL_PCDU_VBAT_RED_ON[0],
info_on_pdu2(Pdu2InfoBase.PL_PCDU_BAT_RED),
)
)
node.add_child(
CmdTreeNode(
PowerOpCodes.PL_PCDU_VBAT_RED_OFF[0],
info_off_pdu2(Pdu2InfoBase.PL_PCDU_BAT_RED),
)
)
node.add_child(
CmdTreeNode(PowerOpCodes.HEATER_ON[0], info_on_pdu2(Pdu2InfoBase.HEATER))
)
node.add_child(
CmdTreeNode(PowerOpCodes.HEATER_OFF[0], info_off_pdu2(Pdu2InfoBase.HEATER))
)
node.add_child(
CmdTreeNode(
PowerOpCodes.SOLAR_ARRAY_DEPL_ON[0],
info_on_pdu2(Pdu2InfoBase.SOLAR_ARRAY_DEPL),
)
)
node.add_child(
CmdTreeNode(
PowerOpCodes.SOLAR_ARRAY_DEPL_OFF[0],
info_off_pdu2(Pdu2InfoBase.SOLAR_ARRAY_DEPL),
)
)
node.add_child(
CmdTreeNode(PowerOpCodes.PL_CAM_ON[0], info_on_pdu2(Pdu2InfoBase.PL_CAM))
)
node.add_child(
CmdTreeNode(PowerOpCodes.PL_CAM_OFF[0], info_off_pdu2(Pdu2InfoBase.PL_CAM))
)
def create_pdu2_node() -> CmdTreeNode:
node = CmdTreeNode(
"pdu2", "P60 PCDU PDU2 device", hide_children_which_are_leaves=True
)
add_gomspace_nodes(node)
add_pdu2_subnodes(node)
node.add_child(
CmdTreeNode(
PowerOpCodes.PRINT_SWITCH_V_I[0], "PDU2: Print Switches, Voltages, Currents"
)
)
return node
def pdu2_switch_cmds(q: DefaultPusQueueHelper, op_code: str): # noqa C901
if op_code in PowerOpCodes.PL_PCDU_VBAT_NOM_ON:
pl_pcdu_bat_nom_on_cmd(q)
@ -252,7 +332,7 @@ def add_pdu2_common_defs(oce: OpCodeEntry):
def pdu2_req_hk_cmds(q: DefaultPusQueueHelper, op_code: str):
req_hk_cmds("PDU2", q, op_code, PDU_2_HANDLER_ID, [SetId.CORE, SetId.AUX])
req_hk_cmds("PDU2", q, op_code, PDU_2_HANDLER_ID, (SetId.CORE, SetId.AUX))
def pl_pcdu_bat_nom_on_cmd(q: DefaultPusQueueHelper):

View File

@ -16,21 +16,23 @@ from eive_tmtc.config.object_ids import (
get_object_ids,
)
from eive_tmtc.tmtc.power.pdu1 import (
add_pdu1_subnodes,
pdu1_req_hk_cmds,
pdu1_switch_cmds,
add_pdu1_common_defs,
add_pdu1_cmds,
)
from eive_tmtc.tmtc.power.pdu2 import (
add_pdu2_subnodes,
pdu2_req_hk_cmds,
add_pdu2_common_defs,
pdu2_switch_cmds,
add_pdu2_cmds,
)
from tmtccmd.config import TmtcDefinitionWrapper, OpCodeEntry
from tmtccmd.config import CmdTreeNode, TmtcDefinitionWrapper, OpCodeEntry
from eive_tmtc.config.object_ids import PCDU_HANDLER_ID
from eive_tmtc.tmtc.power.p60dock import P60OpCode, P60Info, p60_dock_req_hk_cmds
from eive_tmtc.tmtc.power.p60dock import CmdString, CmdInfo, p60_dock_req_hk_cmds
from eive_tmtc.tmtc.power.acu import add_acu_cmds, acu_req_hk_cmds
from tmtccmd.pus.tc.s3_fsfw_hk import (
create_request_one_diag_command,
@ -73,29 +75,29 @@ class PcduSwitches(enum.IntEnum):
P60_DOCK_3V3_STACK = 19
def pack_power_commands(q: DefaultPusQueueHelper, op_code: str):
pdu1_switch_cmds(q, op_code)
pdu2_switch_cmds(q, op_code)
if op_code in PowerOpCodes.SWITCHER_HK:
def pack_power_commands(q: DefaultPusQueueHelper, cmd_str: str):
pdu1_switch_cmds(q, cmd_str)
pdu2_switch_cmds(q, cmd_str)
if cmd_str in PowerOpCodes.SWITCHER_HK:
q.add_log_cmd("Requesting switcher state HK")
q.add_pus_tc(
create_request_one_diag_command(
make_sid(PCDU_HANDLER_ID, PcduSetIds.SWITCHER_SET)
)
)
if op_code in PowerOpCodes.INFO_CORE:
if cmd_str in PowerOpCodes.INFO_CORE:
pdu1_req_hk_cmds(q, PowerOpCodes.REQUEST_CORE_HK_ONCE[0])
pdu2_req_hk_cmds(q, PowerOpCodes.REQUEST_CORE_HK_ONCE[0])
p60_dock_req_hk_cmds(q, PowerOpCodes.REQUEST_CORE_HK_ONCE[0])
acu_req_hk_cmds(q, PowerOpCodes.REQUEST_CORE_HK_ONCE[0])
q.add_wait_seconds(8.0)
elif op_code in PowerOpCodes.INFO_AUX:
elif cmd_str in PowerOpCodes.INFO_AUX:
pdu1_req_hk_cmds(q, PowerOpCodes.REQUEST_AUX_HK_ONCE[0])
pdu2_req_hk_cmds(q, PowerOpCodes.REQUEST_AUX_HK_ONCE[0])
p60_dock_req_hk_cmds(q, PowerOpCodes.REQUEST_AUX_HK_ONCE[0])
acu_req_hk_cmds(q, PowerOpCodes.REQUEST_AUX_HK_ONCE[0])
q.add_wait_seconds(8.0)
elif op_code in PowerOpCodes.INFO_ALL:
elif cmd_str in PowerOpCodes.INFO_ALL:
pdu1_req_hk_cmds(q, PowerOpCodes.REQUEST_CORE_HK_ONCE[0])
pdu2_req_hk_cmds(q, PowerOpCodes.REQUEST_CORE_HK_ONCE[0])
pdu1_req_hk_cmds(q, PowerOpCodes.REQUEST_AUX_HK_ONCE[0])
@ -105,7 +107,7 @@ def pack_power_commands(q: DefaultPusQueueHelper, op_code: str):
acu_req_hk_cmds(q, PowerOpCodes.REQUEST_CORE_HK_ONCE[0])
acu_req_hk_cmds(q, PowerOpCodes.REQUEST_AUX_HK_ONCE[0])
q.add_wait_seconds(8.0)
elif op_code in PowerOpCodes.RESET_ALL_GND_WDTS:
elif cmd_str in PowerOpCodes.RESET_ALL_GND_WDTS:
oids = get_object_ids()
pack_reset_gnd_wdt_cmd(q, "P60 Dock", oids[P60_DOCK_HANDLER])
pack_reset_gnd_wdt_cmd(q, "ACU", oids[ACU_HANDLER_ID])
@ -114,24 +116,38 @@ def pack_power_commands(q: DefaultPusQueueHelper, op_code: str):
q.add_wait_seconds(5.0)
if q.empty():
logging.getLogger(__name__).info(
f"Queue is empty, no stack for op code {op_code}"
f"Queue is empty, no stack for op code {cmd_str}"
)
@tmtc_definitions_provider
def add_p60_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(keys=P60OpCode.STACK_3V3_ON, info=P60Info.STACK_3V3_ON)
oce.add(keys=P60OpCode.STACK_3V3_OFF, info=P60Info.STACK_3V3_OFF)
oce.add(keys=P60OpCode.STACK_5V_ON, info=P60Info.STACK_5V_ON)
oce.add(keys=P60OpCode.STACK_5V_OFF, info=P60Info.STACK_5V_OFF)
oce.add(keys=CmdString.STACK_3V3_ON, info=CmdInfo.STACK_3V3_ON)
oce.add(keys=CmdString.STACK_3V3_OFF, info=CmdInfo.STACK_3V3_OFF)
oce.add(keys=CmdString.STACK_5V_ON, info=CmdInfo.STACK_5V_ON)
oce.add(keys=CmdString.STACK_5V_OFF, info=CmdInfo.STACK_5V_OFF)
add_gomspace_cmd_defs(oce)
oce.add(keys=P60OpCode.TEST, info="P60 Tests")
oce.add(keys=CmdString.TEST, info="P60 Tests")
defs.add_service(
name=CustomServiceList.P60DOCK.value, info="P60 Device", op_code_entry=oce
)
def create_power_node() -> CmdTreeNode:
node = CmdTreeNode("power", "Power commands", hide_children_which_are_leaves=True)
add_pdu1_subnodes(node)
add_pdu2_subnodes(node)
node.add_child(CmdTreeNode(PowerOpCodes.SWITCHER_HK[0], PowerInfo.SWITCHER_HK))
node.add_child(CmdTreeNode(PowerOpCodes.INFO_ALL[0], PowerInfo.INFO_ALL))
node.add_child(CmdTreeNode(PowerOpCodes.INFO_CORE[0], PowerInfo.INFO_CORE))
node.add_child(CmdTreeNode(PowerOpCodes.INFO_AUX[0], PowerInfo.INFO_AUX))
node.add_child(
CmdTreeNode(PowerOpCodes.RESET_ALL_GND_WDTS[0], PowerInfo.RESET_ALL_GND_WDTS)
)
return node
@tmtc_definitions_provider
def add_power_cmd_defs(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()

View File

@ -3,32 +3,26 @@ import enum
import logging
import struct
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.config.object_ids import PWR_CONTROLLER
from eive_tmtc.pus_tm.defs import PrintWrapper
from tmtccmd.config.tmtc import (
tmtc_definitions_provider,
TmtcDefinitionWrapper,
OpCodeEntry,
CmdTreeNode,
)
from tmtccmd.fsfw.tmtc_printer import get_validity_buffer_str
from tmtccmd.pus.s20_fsfw_param import create_load_param_cmd
from tmtccmd.pus.s20_fsfw_param_defs import (
create_scalar_double_parameter,
create_scalar_float_parameter,
)
from tmtccmd.tmtc import service_provider
from tmtccmd.tmtc.queue import DefaultPusQueueHelper
from tmtccmd.pus.s200_fsfw_mode import Mode, pack_mode_command
from tmtccmd.tmtc.decorator import ServiceProviderParams
from tmtccmd.pus.tc.s3_fsfw_hk import (
disable_periodic_hk_command,
enable_periodic_hk_command_with_interval,
generate_one_hk_command,
make_sid,
enable_periodic_hk_command_with_interval,
disable_periodic_hk_command,
)
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.tmtc.queue import DefaultPusQueueHelper
from tmtccmd.pus.s20_fsfw_param import create_load_param_cmd
from tmtccmd.pus.s20_fsfw_param_defs import (
create_scalar_float_parameter,
create_scalar_double_parameter,
)
from eive_tmtc.config.object_ids import PWR_CONTROLLER
from eive_tmtc.pus_tm.defs import PrintWrapper
_LOGGER = logging.getLogger(__name__)
@ -51,17 +45,17 @@ class ParamId(enum.IntEnum):
HIGHER_MODES_LIMIT = 6
class OpCodes:
OFF = ["mode_off"]
ON = ["mode_on"]
NML = ["mode_normal"]
SET_PARAMETER = ["set_parameter"]
REQUEST_CORE_HK = ["core_hk"]
ENABLE_CORE_HK = ["core_enable_hk"]
DISABLE_CORE_HK = ["core_disable_hk"]
REQUEST_ENABLE_PL_HK = ["enable_pl_hk"]
ENABLE_ENABLE_PL_HK = ["enable_pl_enable_hk"]
DISABLE_ENABLE_PL_HK = ["enable_pl_disable_hk"]
class OpCode:
OFF = "off"
ON = "on"
NML = "normal"
SET_PARAMETER = "set_parameter"
REQUEST_CORE_HK = "core_hk"
ENABLE_CORE_HK = "core_enable_hk"
DISABLE_CORE_HK = "core_disable_hk"
REQUEST_ENABLE_PL_HK = "enable_pl_hk"
ENABLE_ENABLE_PL_HK = "enable_pl_enable_hk"
DISABLE_ENABLE_PL_HK = "enable_pl_disable_hk"
class Info:
@ -77,46 +71,37 @@ class Info:
DISABLE_ENABLE_PL_HK = "Disable Enable PL HK Data Generation"
@tmtc_definitions_provider
def pwr_cmd_defs(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(keys=OpCodes.OFF, info=Info.OFF)
oce.add(keys=OpCodes.ON, info=Info.ON)
oce.add(keys=OpCodes.NML, info=Info.NML)
oce.add(keys=OpCodes.SET_PARAMETER, info=Info.SET_PARAMETER)
oce.add(keys=OpCodes.REQUEST_CORE_HK, info=Info.REQUEST_CORE_HK)
oce.add(keys=OpCodes.ENABLE_CORE_HK, info=Info.ENABLE_CORE_HK)
oce.add(keys=OpCodes.DISABLE_CORE_HK, info=Info.DISABLE_CORE_HK)
oce.add(keys=OpCodes.REQUEST_ENABLE_PL_HK, info=Info.REQUEST_ENABLE_PL_HK)
oce.add(keys=OpCodes.ENABLE_ENABLE_PL_HK, info=Info.ENABLE_ENABLE_PL_HK)
oce.add(keys=OpCodes.DISABLE_ENABLE_PL_HK, info=Info.DISABLE_ENABLE_PL_HK)
defs.add_service(
name=CustomServiceList.PWR_CTRL.value, info="PWR Controller", op_code_entry=oce
)
def create_pwr_ctrl_node() -> CmdTreeNode:
op_code_strs = [
getattr(OpCode, key) for key in dir(OpCode) if not key.startswith("__")
]
info_strs = [getattr(Info, key) for key in dir(OpCode) if not key.startswith("__")]
combined_dict = dict(zip(op_code_strs, info_strs))
node = CmdTreeNode("pwr_ctrl", "Power Controller", hide_children_for_print=True)
for op_code, info in combined_dict.items():
node.add_child(CmdTreeNode(op_code, info))
return node
@service_provider(CustomServiceList.PWR_CTRL.value)
def pack_acs_ctrl_command(p: ServiceProviderParams):
op_code = p.op_code
q = p.queue_helper
if op_code in OpCodes.OFF:
def pack_power_ctrl_command(q: DefaultPusQueueHelper, cmd_str: str):
if cmd_str == OpCode.OFF:
q.add_log_cmd(f"{Info.OFF}")
q.add_pus_tc(pack_mode_command(PWR_CONTROLLER, Mode.OFF, 0))
elif op_code in OpCodes.ON:
elif cmd_str == OpCode.ON:
q.add_log_cmd(f"{Info.ON}")
q.add_pus_tc(pack_mode_command(PWR_CONTROLLER, Mode.ON, 0))
elif op_code in OpCodes.NML:
elif cmd_str == OpCode.NML:
q.add_log_cmd(f"{Info.NML}")
q.add_pus_tc(pack_mode_command(PWR_CONTROLLER, Mode.NORMAL, 0))
elif op_code in OpCodes.SET_PARAMETER:
elif cmd_str in OpCode.SET_PARAMETER:
q.add_log_cmd(f"{Info.SET_PARAMETER}")
set_pwr_ctrl_param(q)
elif op_code in OpCodes.REQUEST_CORE_HK:
elif cmd_str == OpCode.REQUEST_CORE_HK:
q.add_log_cmd(Info.REQUEST_CORE_HK)
q.add_pus_tc(
generate_one_hk_command(make_sid(PWR_CONTROLLER, SetId.CORE_HK_SET))
)
elif op_code in OpCodes.ENABLE_CORE_HK:
elif cmd_str == OpCode.ENABLE_CORE_HK:
interval = float(input("Please specify interval in floating point seconds: "))
q.add_log_cmd(Info.ENABLE_CORE_HK)
cmd_tuple = enable_periodic_hk_command_with_interval(
@ -124,19 +109,19 @@ def pack_acs_ctrl_command(p: ServiceProviderParams):
)
q.add_pus_tc(cmd_tuple[0])
q.add_pus_tc(cmd_tuple[1])
elif op_code in OpCodes.DISABLE_CORE_HK:
elif cmd_str == OpCode.DISABLE_CORE_HK:
q.add_log_cmd(Info.DISABLE_CORE_HK)
q.add_pus_tc(
disable_periodic_hk_command(
False, make_sid(PWR_CONTROLLER, SetId.CORE_HK_SET)
)
)
elif op_code in OpCodes.REQUEST_ENABLE_PL_HK:
elif cmd_str == OpCode.REQUEST_ENABLE_PL_HK:
q.add_log_cmd(Info.REQUEST_ENABLE_PL_HK)
q.add_pus_tc(
generate_one_hk_command(make_sid(PWR_CONTROLLER, SetId.ENABLE_PL_SET))
)
elif op_code in OpCodes.ENABLE_ENABLE_PL_HK:
elif cmd_str == OpCode.ENABLE_ENABLE_PL_HK:
interval = float(input("Please specify interval in floating point seconds: "))
q.add_log_cmd(Info.ENABLE_ENABLE_PL_HK)
cmd_tuple = enable_periodic_hk_command_with_interval(
@ -144,7 +129,7 @@ def pack_acs_ctrl_command(p: ServiceProviderParams):
)
q.add_pus_tc(cmd_tuple[0])
q.add_pus_tc(cmd_tuple[1])
elif op_code in OpCodes.DISABLE_ENABLE_PL_HK:
elif cmd_str == OpCode.DISABLE_ENABLE_PL_HK:
q.add_log_cmd(Info.DISABLE_ENABLE_PL_HK)
q.add_pus_tc(
disable_periodic_hk_command(
@ -283,7 +268,7 @@ def handle_core_hk_data(pw: PrintWrapper, hk_data: bytes):
pw.dlog(f"Total Battery Current: {total_battery_current} [mA]")
pw.dlog(f"Open Circuit Voltage Charge: {open_circuit_voltage_charge*100:8.3f} [%]")
pw.dlog(f"Coulomb Counter Charge: {coulomb_counter_charge*100:8.3f} [%]")
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=3)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=3))
def handle_enable_pl_data(pw: PrintWrapper, hk_data: bytes):
@ -299,4 +284,4 @@ def handle_enable_pl_data(pw: PrintWrapper, hk_data: bytes):
)[0]
current_idx += inc_len_uint16
pw.dlog(f"PL Use Allowed: {pl_use_allowed}")
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=1)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], num_vars=1))

View File

@ -1,18 +1,16 @@
import enum
from typing import Tuple, Dict
from typing import Dict, Tuple
from spacepackets.ecss import PusTelecommand
from eive_tmtc.tmtc.common import pack_mode_cmd_with_info
from eive_tmtc.config.object_ids import EPS_SUBSYSTEM_ID
from eive_tmtc.config.definitions import CustomServiceList
from tmtccmd.config.tmtc import (
tmtc_definitions_provider,
TmtcDefinitionWrapper,
OpCodeEntry,
CmdTreeNode,
)
from tmtccmd.pus.s200_fsfw_mode import Subservice as ModeSubservices, Mode
from tmtccmd.tmtc import service_provider
from tmtccmd.tmtc.decorator import ServiceProviderParams
from tmtccmd.pus.s200_fsfw_mode import Mode
from tmtccmd.pus.s200_fsfw_mode import Subservice as ModeSubservices
from tmtccmd.tmtc import DefaultPusQueueHelper
from eive_tmtc.config.object_ids import EPS_SUBSYSTEM_ID
from eive_tmtc.tmtc.common import pack_mode_cmd_with_info
class OpCode(str, enum.Enum):
@ -33,12 +31,9 @@ HANDLER_LIST: Dict[str, Tuple[int, int, str]] = {
}
@service_provider(CustomServiceList.EPS_SS.value)
def build_eps_subsystem_cmd(p: ServiceProviderParams):
op_code = p.op_code
q = p.queue_helper
def build_eps_subsystem_cmd(q: DefaultPusQueueHelper, cmd_str: str):
info_prefix = "EPS Subsystem"
if op_code in OpCode.REPORT_ALL_MODES:
if cmd_str in OpCode.REPORT_ALL_MODES:
q.add_log_cmd(f"{info_prefix}: {Info.REPORT_ALL_MODES}")
q.add_pus_tc(
PusTelecommand(
@ -47,7 +42,7 @@ def build_eps_subsystem_cmd(p: ServiceProviderParams):
app_data=EPS_SUBSYSTEM_ID,
)
)
mode_info_tup = HANDLER_LIST.get(op_code)
mode_info_tup = HANDLER_LIST.get(cmd_str)
if mode_info_tup is None:
return
pack_mode_cmd_with_info(
@ -59,10 +54,9 @@ def build_eps_subsystem_cmd(p: ServiceProviderParams):
)
@tmtc_definitions_provider
def add_eps_subsystem_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
for op_code, (_, _, info) in HANDLER_LIST.items():
oce.add(op_code, info)
oce.add(OpCode.REPORT_ALL_MODES, Info.REPORT_ALL_MODES)
defs.add_service(CustomServiceList.EPS_SS, "EPS Subsystem", oce)
def create_eps_subsystem_node() -> CmdTreeNode:
eps_node = CmdTreeNode("eps", "EPS Subsystem")
for cmd_str, (_, _, info) in HANDLER_LIST.items():
eps_node.add_child(CmdTreeNode(cmd_str, info))
eps_node.add_child(CmdTreeNode(OpCode.REPORT_ALL_MODES, Info.REPORT_ALL_MODES))
return eps_node

View File

@ -1,5 +1,9 @@
import dataclasses
import struct
import logging
import sqlite3
from typing import List, Tuple
from eive_tmtc.pus_tm.hk import HkTmInfo
from eive_tmtc.tmtc.power.acu import acu_config_table_handler
from eive_tmtc.tmtc.power.common_power import (
@ -9,7 +13,7 @@ from eive_tmtc.tmtc.power.common_power import (
)
from eive_tmtc.tmtc.power.power import PcduSetIds
from tmtccmd.util import ObjectIdBase
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter, get_validity_buffer_str
from eive_tmtc.pus_tm.defs import PrintWrapper
from eive_tmtc.gomspace.gomspace_common import GomspaceDeviceActionId
from eive_tmtc.config.object_ids import (
@ -19,6 +23,8 @@ from eive_tmtc.config.object_ids import (
ACU_HANDLER_ID,
)
_LOGGER = logging.getLogger(__name__)
P60_INDEX_LIST = [
"ACU VCC",
"PDU1 VCC",
@ -119,6 +125,8 @@ class DevicesInfoParser:
return current_idx
def print(self, pw: PrintWrapper):
if self.dev_types is None or self.dev_statuses is None:
return
pw.dlog("Device Type | Device State (0:None | 1:OK | 3:ERROR | 4:NOT FOUND)")
for i in range(len(self.dev_types)):
pw.dlog(
@ -146,7 +154,25 @@ class DevicesInfoParser:
return "Unknown Type"
def handle_pdu_data(pw: PrintWrapper, pdu_idx: int, set_id: int, hk_data: bytes):
@dataclasses.dataclass
class PduData:
boot_count: int
batt_mode: int
temperature: float
vcc: int
vbat: int
out_enables: List[bool]
voltages: List[int]
currents: List[int]
def handle_pdu_data(
hk_data: bytes,
hk_info: HkTmInfo,
pw: PrintWrapper,
pdu_idx: int,
set_id: int,
):
current_idx = 0
priv_idx = pdu_idx - 1
if set_id == SetId.AUX or set_id == SetId.AUX:
@ -219,7 +245,86 @@ def handle_pdu_data(pw: PrintWrapper, pdu_idx: int, set_id: int, hk_data: bytes)
f"Boot Count {boot_count} | Battery Mode {batt_mode} | "
f"Temperature {temperature} | VCC {vcc} | VBAT {vbat}"
)
pw.dlog(info)
try:
handle_pdu_db_insertion(
hk_info,
pdu_idx,
PduData(
boot_count,
batt_mode,
temperature,
vcc,
vbat,
output_enb_list,
voltage_list,
current_list,
),
)
except sqlite3.OperationalError as e:
_LOGGER.warning(f"SQLite error {e}")
_LOGGER.info(info)
def handle_pdu_db_insertion(
hk_info: HkTmInfo,
pdu_idx: int,
pdu_data: PduData,
):
cursor = hk_info.db_con.cursor()
if pdu_idx == 1:
tbl_base_name = "pdu1"
channel_list = PDU1_CHANNELS_NAMES
else:
tbl_base_name = "pdu2"
channel_list = PDU2_CHANNELS_NAMES
cursor.execute(
f"""
CREATE TABLE IF NOT EXISTS {tbl_base_name}(
packet_uuid TEXT PRIMARY KEY,
generation_time TEXT,
boot_count NUM,
bat_mode NUM,
temp REAL,
vcc NUM,
vbat NUM
)"""
)
cursor.execute(
f"INSERT INTO {tbl_base_name} VALUES(?, ?, ?, ?, ?, ?, ?)",
(
str(hk_info.packet_uuid),
hk_info.packet_datetime,
pdu_data.boot_count,
pdu_data.batt_mode,
pdu_data.temperature,
pdu_data.vcc,
pdu_data.vbat,
),
)
for idx, name in enumerate(channel_list):
words = name.split()
camel_case_name = "_".join(word.lower() for word in words)
tbl_name = f"{tbl_base_name}_{camel_case_name}"
cursor.execute(
f"""
CREATE TABLE IF NOT EXISTS {tbl_name}(
packet_uuid TEXT PRIMARY KEY,
generation_time TEXT,
out_enable NUM,
voltage NUM,
current NUM
)"""
)
value_tuple = (
str(hk_info.packet_uuid),
hk_info.packet_datetime,
pdu_data.out_enables[idx],
pdu_data.voltages[idx],
pdu_data.currents[idx],
)
cursor.execute(f"INSERT INTO {tbl_name} VALUES(?, ?, ?, ?, ?)", value_tuple)
hk_info.db_con.commit()
def handle_p60_hk_data(pw: PrintWrapper, set_id: int, hk_data: bytes):
@ -269,8 +374,8 @@ def handle_p60_hk_data(pw: PrintWrapper, set_id: int, hk_data: bytes):
temps = f"In C: Temp 0 {temp_0} | Temp 1 {temp_1} | "
pw.dlog(temps)
pw.dlog(batt_info)
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=hk_data[current_idx:], num_vars=9
pw.dlog(
get_validity_buffer_str(validity_buffer=hk_data[current_idx:], num_vars=9)
)
if set_id == SetId.AUX:
pw.dlog("Received P60 AUX HK. Voltages in mV, currents in mA")
@ -337,8 +442,8 @@ def handle_p60_hk_data(pw: PrintWrapper, set_id: int, hk_data: bytes):
"6:TempSens(BatPack)|7:TempSens(BatPack)"
)
dev_parser.print(pw=pw)
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=hk_data[current_idx:], num_vars=27
pw.dlog(
get_validity_buffer_str(validity_buffer=hk_data[current_idx:], num_vars=27)
)
@ -390,8 +495,8 @@ def handle_acu_hk_data(pw: PrintWrapper, set_id: int, hk_data: bytes):
f"Boot Count {bootcnt} | Uptime {uptime} sec | "
f"MPPT Time {mppt_time} msec | MPPT Period {mppt_period} msec"
)
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=hk_data[current_idx:], num_vars=12
pw.dlog(
get_validity_buffer_str(validity_buffer=hk_data[current_idx:], num_vars=12)
)
if set_id == SetId.AUX:
current_idx = 0
@ -428,13 +533,13 @@ def handle_acu_hk_data(pw: PrintWrapper, set_id: int, hk_data: bytes):
"ACU Dev Types: 0:FRAM|1:ADC|2:ADC|3:DAC|4:DAC|5:DAC|6:TempSens|7:Reserved"
)
dev_parser.print(pw=pw)
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=hk_data[current_idx:], num_vars=8
pw.dlog(
get_validity_buffer_str(validity_buffer=hk_data[current_idx:], num_vars=8)
)
def handle_get_param_data_reply(
obj_id: ObjectIdBase, action_id: int, pw: PrintWrapper, custom_data: bytearray
obj_id: ObjectIdBase, action_id: int, pw: PrintWrapper, custom_data: bytes
):
if action_id == GomspaceDeviceActionId.PARAM_GET:
pw.dlog(f"Parameter Get Request received for object {obj_id}")
@ -574,4 +679,4 @@ def handle_pcdu_hk(pw: PrintWrapper, set_id: int, hk_data: bytes):
pw.dlog(f"{name.ljust(25)}: {val}")
pw.dlog(f"{'P60 Dock 5V Stack'.ljust(25)}: {p60_stack_5v_val}")
pw.dlog(f"{'P60 Dock 3V3 Stack'.ljust(25)}: {p60_stack_3v3_val}")
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], 4)
pw.dlog(get_validity_buffer_str(hk_data[current_idx:], 4))

View File

@ -9,17 +9,14 @@
import logging
import struct
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.config.object_ids import SOLAR_ARRAY_DEPLOYMENT_ID
from spacepackets.ecss import PusTelecommand
from tmtccmd.config.tmtc import (
tmtc_definitions_provider,
TmtcDefinitionWrapper,
OpCodeEntry,
CmdTreeNode,
)
from tmtccmd.tmtc import service_provider, DefaultPusQueueHelper
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from tmtccmd.tmtc.decorator import ServiceProviderParams
from tmtccmd.tmtc import DefaultPusQueueHelper
from eive_tmtc.config.object_ids import SOLAR_ARRAY_DEPLOYMENT_ID
class OpCode:
@ -38,25 +35,17 @@ class ActionId:
MANUAL_DEPLOYMENT = 5
@tmtc_definitions_provider
def add_sa_depl_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(keys=OpCode.MANUAL_DEPLOYMENT, info=Info.MANUAL_DEPLOYMENT)
oce.add(keys=OpCode.BURN_SA_0_ONLY, info=Info.BURN_SA_0_ONLY)
oce.add(keys=OpCode.BURN_SA_1_ONLY, info=Info.BURN_SA_1_ONLY)
defs.add_service(
name=CustomServiceList.SA_DEPLYOMENT,
info="Solar Array Deployment",
op_code_entry=oce,
)
def add_solar_array_deployment_node() -> CmdTreeNode:
node = CmdTreeNode("solar_array_deployment", "Solar Array Deployment")
node.add_child(CmdTreeNode(OpCode.MANUAL_DEPLOYMENT, Info.MANUAL_DEPLOYMENT))
node.add_child(CmdTreeNode(OpCode.BURN_SA_0_ONLY, Info.BURN_SA_0_ONLY))
node.add_child(CmdTreeNode(OpCode.BURN_SA_1_ONLY, Info.BURN_SA_1_ONLY))
return node
@service_provider(CustomServiceList.SA_DEPLYOMENT)
def pack_solar_array_deployment_test_into(p: ServiceProviderParams):
q = p.queue_helper
op_code = p.op_code
def pack_solar_array_deployment_test_into(q: DefaultPusQueueHelper, cmd_str: str):
switch_interval_ms = 0
if op_code == OpCode.MANUAL_DEPLOYMENT:
if cmd_str == OpCode.MANUAL_DEPLOYMENT:
while True:
burn_time_secs = prompt_burn_time()
if burn_time_secs < 0:
@ -80,9 +69,9 @@ def pack_solar_array_deployment_test_into(p: ServiceProviderParams):
q.add_pus_tc(
pack_manual_array_depl_cmd(burn_time_secs, switch_interval_ms, dry_run)
)
elif op_code in OpCode.BURN_SA_0_ONLY:
elif cmd_str == OpCode.BURN_SA_0_ONLY:
burn_one_channel_only(q, 0)
elif op_code in OpCode.BURN_SA_1_ONLY:
elif cmd_str == OpCode.BURN_SA_1_ONLY:
burn_one_channel_only(q, 1)

View File

@ -3,18 +3,18 @@ import enum
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.tmtc.acs.subsystem import AcsMode
from tmtccmd.config.tmtc import (
CmdTreeNode,
tmtc_definitions_provider,
TmtcDefinitionWrapper,
OpCodeEntry,
)
from tmtccmd.tmtc import service_provider
from tmtccmd.tmtc import DefaultPusQueueHelper
from eive_tmtc.config.object_ids import EIVE_SYSTEM_ID
from tmtccmd.pus.s200_fsfw_mode import (
create_mode_command,
create_announce_mode_recursive_command,
)
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from tmtccmd.tmtc.decorator import ServiceProviderParams
class SystemMode:
@ -55,40 +55,49 @@ class Info:
REBOOT_I2C = "Reboot I2C bus"
@service_provider(CustomServiceList.SYSTEM.value)
def build_system_cmds(p: ServiceProviderParams):
o = p.op_code
q = p.queue_helper
def build_system_cmds(q: DefaultPusQueueHelper, cmd_str: str):
prefix = "EIVE System"
if o == OpCode.SAFE_MODE:
if cmd_str == OpCode.SAFE_MODE:
q.add_log_cmd(f"{prefix}: {Info.SAFE_MODE}")
q.add_pus_tc(create_mode_command(EIVE_SYSTEM_ID, SystemMode.SAFE, 0))
elif o == OpCode.IDLE_MODE:
elif cmd_str == OpCode.IDLE_MODE:
q.add_log_cmd(f"{prefix}: {Info.IDLE_MODE}")
q.add_pus_tc(create_mode_command(EIVE_SYSTEM_ID, SystemMode.IDLE, 0))
elif o == OpCode.NADIR_MODE:
elif cmd_str == OpCode.NADIR_MODE:
q.add_log_cmd(f"{prefix}: {Info.NADIR_MODE}")
q.add_pus_tc(create_mode_command(EIVE_SYSTEM_ID, SystemMode.PTG_NADIR, 0))
elif o == OpCode.TARGET_MODE:
elif cmd_str == OpCode.TARGET_MODE:
q.add_log_cmd(f"{prefix}: {Info.TARGET_MODE}")
q.add_pus_tc(create_mode_command(EIVE_SYSTEM_ID, SystemMode.PTG_TARGET, 0))
elif o == OpCode.TARGET_GS_MODE:
elif cmd_str == OpCode.TARGET_GS_MODE:
q.add_log_cmd(f"{prefix}: {Info.TARGET_GS_MODE}")
q.add_pus_tc(create_mode_command(EIVE_SYSTEM_ID, SystemMode.PTG_TARGET_GS, 0))
elif o == OpCode.INERTIAL_MODE:
elif cmd_str == OpCode.INERTIAL_MODE:
q.add_log_cmd(f"{prefix}: {Info.INERTIAL_MODE}")
q.add_pus_tc(create_mode_command(EIVE_SYSTEM_ID, SystemMode.PTG_INERTIAL, 0))
elif o == OpCode.ANNOUNCE_MODES:
elif cmd_str == OpCode.ANNOUNCE_MODES:
q.add_log_cmd(f"{prefix}: {Info.ANNOUNCE_MODES}")
q.add_pus_tc(create_announce_mode_recursive_command(EIVE_SYSTEM_ID))
elif o == OpCode.BOOT_MODE:
elif cmd_str == OpCode.BOOT_MODE:
q.add_log_cmd(f"{prefix}: {Info.BOOT_MODE}")
q.add_pus_tc(create_mode_command(EIVE_SYSTEM_ID, SystemMode.BOOT, 0))
elif o == OpCode.REBOOT_I2C:
elif cmd_str == OpCode.REBOOT_I2C:
q.add_log_cmd(f"{prefix}: {Info.REBOOT_I2C}")
q.add_pus_tc(create_action_cmd(EIVE_SYSTEM_ID, ActionId.EXECUTE_I2C_REBOOT))
def create_system_node() -> CmdTreeNode:
op_code_strs = [
getattr(OpCode, key) for key in dir(OpCode) if not key.startswith("__")
]
info_strs = [getattr(Info, key) for key in dir(OpCode) if not key.startswith("__")]
combined_dict = dict(zip(op_code_strs, info_strs))
node = CmdTreeNode("system", "EIVE System")
for op_code, info in combined_dict.items():
node.add_child(CmdTreeNode(op_code, info))
return node
@tmtc_definitions_provider
def add_system_cmd_defs(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()

View File

@ -3,6 +3,7 @@ from eive_tmtc.config.object_ids import TCS_CONTROLLER
from eive_tmtc.tmtc.tcs import CtrlSetId
from eive_tmtc.tmtc.tcs.brd_assy import pack_tcs_ass_cmds
from tmtccmd.config.tmtc import (
CmdTreeNode,
tmtc_definitions_provider,
TmtcDefinitionWrapper,
OpCodeEntry,
@ -17,7 +18,7 @@ from tmtccmd.pus.tc.s3_fsfw_hk import (
)
class OpCode:
class CmdStr:
REQUEST_PRIMARY_TEMP_SET = "temp"
ENABLE_TEMP_SET = "enable_temp_set"
REQUEST_DEVICE_TEMP_SET = "temp_devs"
@ -26,7 +27,7 @@ class OpCode:
REQUEST_TCS_CTRL_INFO = "tcs_ctrl_info"
class Info:
class CmdInfo:
ENABLE_TEMP_SET = "Enable Primary Temperature Set"
REQUEST_PRIMARY_TEMP_SET = "Request HK set of primary sensor temperatures"
REQUEST_DEVICE_TEMP_SET = "Request HK set of device sensor temperatures"
@ -35,56 +36,74 @@ class Info:
REQUEST_TCS_CTRL_INFO = "Request TCS controller information"
def pack_tcs_ctrl_commands(q: DefaultPusQueueHelper, op_code: str):
if op_code == OpCode.REQUEST_PRIMARY_TEMP_SET:
def pack_tcs_ctrl_commands(q: DefaultPusQueueHelper, cmd_str: str):
if cmd_str == CmdStr.REQUEST_PRIMARY_TEMP_SET:
sensor_set_sid = make_sid(TCS_CONTROLLER, CtrlSetId.PRIMARY_SENSORS)
q.add_log_cmd(Info.REQUEST_PRIMARY_TEMP_SET)
q.add_log_cmd(CmdInfo.REQUEST_PRIMARY_TEMP_SET)
q.add_pus_tc(generate_one_hk_command(sensor_set_sid))
if op_code == OpCode.REQUEST_DEVICE_TEMP_SET:
q.add_log_cmd(Info.REQUEST_DEVICE_TEMP_SET)
if cmd_str == CmdStr.REQUEST_DEVICE_TEMP_SET:
q.add_log_cmd(CmdInfo.REQUEST_DEVICE_TEMP_SET)
q.add_pus_tc(
generate_one_hk_command(make_sid(TCS_CONTROLLER, CtrlSetId.DEVICE_SENSORS))
)
if op_code == OpCode.REQUEST_DEVICE_SUS_SET:
q.add_log_cmd(Info.REQUEST_DEVICE_SUS_SET)
if cmd_str == CmdStr.REQUEST_DEVICE_SUS_SET:
q.add_log_cmd(CmdInfo.REQUEST_DEVICE_SUS_SET)
q.add_pus_tc(
generate_one_hk_command(
make_sid(TCS_CONTROLLER, CtrlSetId.SUS_TEMP_SENSORS)
)
)
if op_code == OpCode.REQUEST_HEATER_INFO:
q.add_log_cmd(Info.REQUEST_HEATER_INFO)
if cmd_str == CmdStr.REQUEST_HEATER_INFO:
q.add_log_cmd(CmdInfo.REQUEST_HEATER_INFO)
q.add_pus_tc(
create_request_one_diag_command(
make_sid(TCS_CONTROLLER, CtrlSetId.HEATER_INFO)
)
)
if op_code == OpCode.REQUEST_TCS_CTRL_INFO:
q.add_log_cmd(Info.REQUEST_TCS_CTRL_INFO)
if cmd_str == CmdStr.REQUEST_TCS_CTRL_INFO:
q.add_log_cmd(CmdInfo.REQUEST_TCS_CTRL_INFO)
q.add_pus_tc(
create_request_one_hk_command(
make_sid(TCS_CONTROLLER, CtrlSetId.TCS_CTRL_INFO)
)
)
if op_code == OpCode.ENABLE_TEMP_SET:
if cmd_str == CmdStr.ENABLE_TEMP_SET:
interval_seconds = float(input("Please specify interval in seconds: "))
cmds = create_enable_periodic_hk_command_with_interval_with_diag(
False, make_sid(TCS_CONTROLLER, CtrlSetId.PRIMARY_SENSORS), interval_seconds
)
for cmd in cmds:
q.add_pus_tc(cmd)
pack_tcs_ass_cmds(q, op_code)
pack_tcs_ass_cmds(q, cmd_str)
CTN = CmdTreeNode
def create_tcs_ctrl_node() -> CmdTreeNode:
node = CmdTreeNode(
"tcs_ctrl", "TCS Controller", hide_children_which_are_leaves=True
)
node.add_child(CTN(CmdStr.ENABLE_TEMP_SET, CmdInfo.ENABLE_TEMP_SET))
node.add_child(
CTN(CmdStr.REQUEST_PRIMARY_TEMP_SET, CmdInfo.REQUEST_PRIMARY_TEMP_SET)
)
node.add_child(CTN(CmdStr.REQUEST_DEVICE_TEMP_SET, CmdInfo.REQUEST_DEVICE_TEMP_SET))
node.add_child(CTN(CmdStr.REQUEST_DEVICE_SUS_SET, CmdInfo.REQUEST_DEVICE_SUS_SET))
node.add_child(CTN(CmdStr.REQUEST_HEATER_INFO, CmdInfo.REQUEST_HEATER_INFO))
node.add_child(CTN(CmdStr.REQUEST_TCS_CTRL_INFO, CmdInfo.REQUEST_TCS_CTRL_INFO))
return node
@tmtc_definitions_provider
def add_tcs_ctrl_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(keys=OpCode.ENABLE_TEMP_SET, info=Info.ENABLE_TEMP_SET)
oce.add(keys=OpCode.REQUEST_PRIMARY_TEMP_SET, info=Info.REQUEST_PRIMARY_TEMP_SET)
oce.add(keys=OpCode.REQUEST_DEVICE_TEMP_SET, info=Info.REQUEST_DEVICE_TEMP_SET)
oce.add(keys=OpCode.REQUEST_DEVICE_SUS_SET, info=Info.REQUEST_DEVICE_SUS_SET)
oce.add(keys=OpCode.REQUEST_HEATER_INFO, info=Info.REQUEST_HEATER_INFO)
oce.add(keys=OpCode.REQUEST_TCS_CTRL_INFO, info=Info.REQUEST_TCS_CTRL_INFO)
oce.add(keys=CmdStr.ENABLE_TEMP_SET, info=CmdInfo.ENABLE_TEMP_SET)
oce.add(keys=CmdStr.REQUEST_PRIMARY_TEMP_SET, info=CmdInfo.REQUEST_PRIMARY_TEMP_SET)
oce.add(keys=CmdStr.REQUEST_DEVICE_TEMP_SET, info=CmdInfo.REQUEST_DEVICE_TEMP_SET)
oce.add(keys=CmdStr.REQUEST_DEVICE_SUS_SET, info=CmdInfo.REQUEST_DEVICE_SUS_SET)
oce.add(keys=CmdStr.REQUEST_HEATER_INFO, info=CmdInfo.REQUEST_HEATER_INFO)
oce.add(keys=CmdStr.REQUEST_TCS_CTRL_INFO, info=CmdInfo.REQUEST_TCS_CTRL_INFO)
defs.add_service(
name=CustomServiceList.TCS_CTRL,
info="TCS controller",

View File

@ -5,21 +5,21 @@
"""
import enum
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.config import CmdTreeNode, OpCodeEntry, TmtcDefinitionWrapper
from tmtccmd.config.tmtc import tmtc_definitions_provider
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from tmtccmd.pus.s201_fsfw_health import (
FsfwHealth,
Subservice,
pack_set_health_cmd_data,
)
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.util.obj_id import ObjectIdU32
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.config.object_ids import get_object_ids
from eive_tmtc.tmtc.tcs.defs import Heater
from tmtccmd.config import TmtcDefinitionWrapper, OpCodeEntry
from tmtccmd.config.tmtc import tmtc_definitions_provider
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.util.obj_id import ObjectIdU32
from tmtccmd.pus.s201_fsfw_health import (
pack_set_health_cmd_data,
FsfwHealth,
Subservice,
)
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from spacepackets.ecss.tc import PusTelecommand
HEATER_LOCATION = [
"PLOC Processing Board",
@ -34,10 +34,10 @@ HEATER_LOCATION = [
class OpCode:
HEATER_CMD = ["switch_cmd"]
HEATER_EXT_CTRL = ["set_ext_ctrl"]
HEATER_FAULTY_CMD = ["set_faulty"]
HEATER_HEALTHY_CMD = ["set_healthy"]
HEATER_CMD = "switch_cmd"
HEATER_EXT_CTRL = "set_ext_ctrl"
HEATER_FAULTY_CMD = "set_faulty"
HEATER_HEALTHY_CMD = "set_healthy"
class Info:
@ -55,6 +55,18 @@ class ActionIds(enum.IntEnum):
SWITCH_HEATER = 0
CTN = CmdTreeNode
def create_heater_node() -> CmdTreeNode:
node = CmdTreeNode("heaters", "Heater Device", hide_children_which_are_leaves=True)
node.add_child(CTN(OpCode.HEATER_CMD, Info.HEATER_CMD))
node.add_child(CTN(OpCode.HEATER_HEALTHY_CMD, Info.HEATER_HEALTHY_CMD))
node.add_child(CTN(OpCode.HEATER_EXT_CTRL, Info.HEATER_EXT_CTRL))
node.add_child(CTN(OpCode.HEATER_FAULTY_CMD, Info.HEATER_FAULTY_CMD))
return node
@tmtc_definitions_provider
def add_heater_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
@ -69,8 +81,8 @@ def add_heater_cmds(defs: TmtcDefinitionWrapper):
)
def pack_heater_cmds(object_id: bytearray, op_code: str, q: DefaultPusQueueHelper):
if op_code in OpCode.HEATER_CMD:
def pack_heater_cmds(object_id: bytes, cmd_str: str, q: DefaultPusQueueHelper):
if cmd_str == OpCode.HEATER_CMD:
q.add_log_cmd("Heater Switching")
heater_number = prompt_heater()
while True:
@ -90,7 +102,7 @@ def pack_heater_cmds(object_id: bytearray, op_code: str, q: DefaultPusQueueHelpe
debug_string = f"Switching heater {heater_number} {act_str}"
q.add_log_cmd(debug_string)
q.add_pus_tc(pack_switch_heater_command(object_id, heater_number, action))
if op_code in OpCode.HEATER_EXT_CTRL:
if cmd_str == OpCode.HEATER_EXT_CTRL:
heater_number = prompt_heater()
obj_id = heater_idx_to_obj(heater_number)
health_cmd(
@ -100,7 +112,7 @@ def pack_heater_cmds(object_id: bytearray, op_code: str, q: DefaultPusQueueHelpe
health_str="External Control",
heater_idx=heater_number,
)
if op_code in OpCode.HEATER_FAULTY_CMD:
if cmd_str == OpCode.HEATER_FAULTY_CMD:
heater_number = prompt_heater()
obj_id = heater_idx_to_obj(heater_number)
health_cmd(
@ -110,7 +122,7 @@ def pack_heater_cmds(object_id: bytearray, op_code: str, q: DefaultPusQueueHelpe
health_str="Faulty",
heater_idx=heater_number,
)
if op_code in OpCode.HEATER_HEALTHY_CMD:
if cmd_str == OpCode.HEATER_HEALTHY_CMD:
heater_number = prompt_heater()
obj_id = heater_idx_to_obj(heater_number)
health_cmd(

View File

@ -5,7 +5,7 @@ import struct
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.pus_tm.defs import PrintWrapper
from spacepackets.ecss import PusTelecommand
from tmtccmd.config import TmtcDefinitionWrapper, OpCodeEntry
from tmtccmd.config import CmdTreeNode, TmtcDefinitionWrapper, OpCodeEntry
from tmtccmd.config.tmtc import tmtc_definitions_provider
from tmtccmd.tmtc import DefaultPusQueueHelper
@ -13,7 +13,7 @@ from tmtccmd.util import ObjectIdU32
from tmtccmd.pus.s200_fsfw_mode import Mode, pack_mode_data, Subservice
import eive_tmtc.config.object_ids as oids
from eive_tmtc.config.object_ids import get_object_ids
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.fsfw.tmtc_printer import get_validity_buffer_str
RTD_IDS = [
oids.RTD_0_PLOC_HSPD,
@ -81,34 +81,43 @@ class SetId(enum.IntEnum):
TEMPERATURE = 1
class OpCode:
ON = ["0", "on"]
OFF = ["1", "off"]
NORMAL = ["2", "normal"]
WRITE_CONFIG = ["3", "Write config"]
class CmdStr:
ON = "on"
OFF = "off"
NORMAL = "normal"
WRITE_CONFIG = "write_cfg"
class Info:
class CmdInfo:
ON = "Switch handler on"
OFF = "Switch handler off"
NORMAL = "Switch handler normal"
WRITE_CONFIG = "Write config"
def create_rtd_node() -> CmdTreeNode:
node = CmdTreeNode("rtd", "RTD commands", hide_children_which_are_leaves=True)
node.add_child(CmdTreeNode(CmdStr.ON, CmdInfo.ON))
node.add_child(CmdTreeNode(CmdStr.NORMAL, CmdInfo.NORMAL))
node.add_child(CmdTreeNode(CmdStr.OFF, CmdInfo.OFF))
node.add_child(CmdTreeNode(CmdStr.WRITE_CONFIG, CmdInfo.WRITE_CONFIG))
return node
@tmtc_definitions_provider
def specify_rtd_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(keys=OpCode.ON, info=Info.ON)
oce.add(keys=OpCode.NORMAL, info=Info.NORMAL)
oce.add(keys=OpCode.OFF, info=Info.OFF)
oce.add(keys=OpCode.WRITE_CONFIG, info=Info.WRITE_CONFIG)
oce.add(keys=CmdStr.ON, info=CmdInfo.ON)
oce.add(keys=CmdStr.NORMAL, info=CmdInfo.NORMAL)
oce.add(keys=CmdStr.OFF, info=CmdInfo.OFF)
oce.add(keys=CmdStr.WRITE_CONFIG, info=CmdInfo.WRITE_CONFIG)
defs.add_service(
name=CustomServiceList.RTD.value, info="RTD commands", op_code_entry=oce
)
def pack_rtd_commands(
op_code: str, object_id: Optional[ObjectIdU32], q: DefaultPusQueueHelper
cmd_str: str, object_id: Optional[ObjectIdU32], q: DefaultPusQueueHelper
):
if object_id is not None and object_id not in RTD_IDS:
print("Specified object ID not a valid RTD ID")
@ -117,14 +126,14 @@ def pack_rtd_commands(
tgt_rtd_idx = prompt_rtd_idx()
object_id_dict = get_object_ids()
object_id = object_id_dict.get(RTD_IDS[tgt_rtd_idx])
if op_code in OpCode.ON:
if cmd_str == CmdStr.ON:
app_data = pack_mode_data(object_id=object_id.as_bytes, mode=Mode.ON, submode=0)
q.add_pus_tc(
PusTelecommand(
service=200, subservice=Subservice.TC_MODE_COMMAND, app_data=app_data
)
)
if op_code in OpCode.NORMAL:
if cmd_str == CmdStr.NORMAL:
app_data = pack_mode_data(
object_id=object_id.as_bytes, mode=Mode.NORMAL, submode=0
)
@ -133,7 +142,7 @@ def pack_rtd_commands(
service=200, subservice=Subservice.TC_MODE_COMMAND, app_data=app_data
)
)
if op_code in OpCode.OFF:
if cmd_str == CmdStr.OFF:
app_data = pack_mode_data(
object_id=object_id.as_bytes, mode=Mode.OFF, submode=0
)
@ -142,7 +151,7 @@ def pack_rtd_commands(
service=200, subservice=Subservice.TC_MODE_COMMAND, app_data=app_data
)
)
if op_code in OpCode.WRITE_CONFIG:
if cmd_str in CmdStr.WRITE_CONFIG:
command = object_id.as_bytes + struct.pack("!I", CommandId.WRITE_CONFIG)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
@ -161,7 +170,7 @@ def handle_rtd_hk(object_id: bytes, hk_data: bytes, pw: PrintWrapper):
pw.dlog(f"RTD Value: {rtd_val}")
pw.dlog(f"Error Byte: {error_byte}")
pw.dlog(f"Last Error Byte: {last_err_byte}")
FsfwTmTcPrinter.get_validity_buffer(hk_data[fmt_len:], 4)
pw.dlog(get_validity_buffer_str(hk_data[fmt_len:], 4))
def prompt_rtd_idx():

View File

@ -23,17 +23,17 @@ class InfoSys:
ANNOUNCE_MODES = "Announce Modes recursively"
def pack_tcs_sys_commands(q: DefaultPusQueueHelper, op_code: str):
if op_code == OpCode.OFF:
def pack_tcs_sys_commands(q: DefaultPusQueueHelper, cmd_str: str):
if cmd_str == OpCode.OFF:
q.add_log_cmd(InfoSys.OFF)
pack_mode_cmd_with_info(TCS_SUBSYSTEM_ID, Mode.OFF, 0, q, InfoSys.OFF)
if op_code == OpCode.NML:
if cmd_str == OpCode.NML:
q.add_log_cmd(InfoSys.NML)
pack_mode_cmd_with_info(TCS_SUBSYSTEM_ID, Mode.NORMAL, 0, q, InfoSys.OFF)
if op_code == OpCode.ANNOUNCE_MODES:
if cmd_str == OpCode.ANNOUNCE_MODES:
q.add_log_cmd(InfoSys.ANNOUNCE_MODES)
q.add_pus_tc(create_announce_mode_recursive_command(TCS_SUBSYSTEM_ID))
pack_tcs_ass_cmds(q, op_code)
pack_tcs_ass_cmds(q, cmd_str)
@tmtc_definitions_provider

View File

@ -8,6 +8,8 @@
import enum
import struct
from tmtccmd.config import CmdTreeNode
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.pus_tm.defs import PrintWrapper
from spacepackets.ecss.tc import PusTelecommand
@ -16,21 +18,21 @@ from tmtccmd.config.tmtc import (
TmtcDefinitionWrapper,
OpCodeEntry,
)
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.fsfw.tmtc_printer import get_validity_buffer_str
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s200_fsfw_mode import Mode, pack_mode_data
from tmtccmd.pus.tc.s3_fsfw_hk import create_request_one_hk_command, make_sid
from tmtccmd.util import ObjectIdU32
class OpCode:
class CmdStr:
OFF = "off"
ON = "on"
NML = "nml"
HK = "hk"
class Info:
class CmdInfo:
OFF = "Off"
ON = "On"
NML = "Normal"
@ -47,37 +49,46 @@ class SetId(enum.IntEnum):
def pack_tmp1075_test_into(
object_id: ObjectIdU32, op_code: str, q: DefaultPusQueueHelper
object_id: ObjectIdU32, cmd_str: str, q: DefaultPusQueueHelper
):
q.add_log_cmd(
f"Testing Tmp1075 Temperature Sensor Handler with object id: {object_id}"
)
obyt = object_id.as_bytes
if op_code == OpCode.OFF:
if cmd_str == CmdStr.OFF:
q.add_log_cmd("TMP1075: Set Normal Off")
mode_data = pack_mode_data(obyt, Mode.OFF, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=mode_data))
if op_code == OpCode.NML:
if cmd_str == CmdStr.NML:
q.add_log_cmd("TMP1075: Set Mode Normal")
mode_data = pack_mode_data(obyt, Mode.NORMAL, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=mode_data))
if op_code == OpCode.ON:
if cmd_str == CmdStr.ON:
q.add_log_cmd("TMP1075: Set Mode On")
mode_data = pack_mode_data(obyt, Mode.ON, 0)
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=mode_data))
if op_code == OpCode.HK:
if cmd_str == CmdStr.HK:
q.add_log_cmd("TMP1075: Request One-Shot HK")
q.add_pus_tc(create_request_one_hk_command(make_sid(obyt, SetId.TEMPERATURE)))
return q
def create_tmp_sens_node() -> CmdTreeNode:
node = CmdTreeNode("tmp_1075", "TMP1075 Temperatur Sensors")
node.add_child(CmdTreeNode(CmdStr.OFF, CmdInfo.OFF))
node.add_child(CmdTreeNode(CmdStr.ON, CmdInfo.ON))
node.add_child(CmdTreeNode(CmdStr.NML, CmdInfo.NML))
node.add_child(CmdTreeNode(CmdStr.HK, CmdInfo.HK))
return node
@tmtc_definitions_provider
def add_tmp_sens_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(OpCode.OFF, Info.OFF)
oce.add(OpCode.ON, Info.ON)
oce.add(OpCode.NML, Info.NML)
oce.add(OpCode.HK, Info.HK)
oce.add(CmdStr.OFF, CmdInfo.OFF)
oce.add(CmdStr.ON, CmdInfo.ON)
oce.add(CmdStr.NML, CmdInfo.NML)
oce.add(CmdStr.HK, CmdInfo.HK)
defs.add_service(CustomServiceList.TMP1075.value, "TMP1075 Temperature Sensor", oce)
@ -85,4 +96,4 @@ def handle_tmp_1075_hk_data(set_id: int, hk_data: bytes, pw: PrintWrapper):
if set_id == SetId.TEMPERATURE:
temp = struct.unpack("!f", hk_data[0:4])[0]
pw.dlog(f"TMP1075 Temperature: {temp}")
pw.dlog(FsfwTmTcPrinter.get_validity_buffer(hk_data[4:], 1))
pw.dlog(get_validity_buffer_str(hk_data[4:], 1))

View File

@ -1,52 +1,60 @@
from spacepackets.ecss import PusTelecommand, PusService
from tmtccmd.config import CoreServiceList
from tmtccmd.config.tmtc import (
tmtc_definitions_provider,
TmtcDefinitionWrapper,
OpCodeEntry,
)
import datetime
import math
import struct
from spacepackets.ecss import PusService, PusTelecommand
from tmtccmd.config import CmdTreeNode
from tmtccmd.pus.s11_tc_sched import create_time_tagged_cmd
from tmtccmd.pus.s17_test import create_service_17_ping_command
from tmtccmd.tmtc import service_provider
from tmtccmd.tmtc.decorator import ServiceProviderParams
from tmtccmd.tmtc import DefaultPusQueueHelper
class OpCodes:
class OpCode:
PING = "ping"
TRIGGER_EVENT = "trig_event"
PING_WITH_DATA = "ping_with_data"
SCHEDULE_PING = "sched_ping"
class Info:
PING = "Simple Ping and Connection Test"
TRIGGER_EVENT = "Trigger an event"
PING_WITH_DATA = "Ping with data. Size of sent data is sent back"
SCHEDULE_PING = "Schedule a ping"
@tmtc_definitions_provider
def add_test_defs(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(keys=OpCodes.PING, info=Info.PING)
oce.add(keys=OpCodes.TRIGGER_EVENT, info=Info.TRIGGER_EVENT)
oce.add(keys=OpCodes.PING_WITH_DATA, info=Info.PING_WITH_DATA)
defs.add_service(
name=CoreServiceList.SERVICE_17_ALT,
info="PUS 17 Test Service",
op_code_entry=oce,
)
def create_test_node() -> CmdTreeNode:
node = CmdTreeNode("test", "Test Commands")
node.add_child(CmdTreeNode(OpCode.PING, Info.PING))
node.add_child(CmdTreeNode(OpCode.TRIGGER_EVENT, Info.TRIGGER_EVENT))
node.add_child(CmdTreeNode(OpCode.PING_WITH_DATA, Info.PING_WITH_DATA))
node.add_child(CmdTreeNode(OpCode.SCHEDULE_PING, Info.SCHEDULE_PING))
return node
@service_provider(CoreServiceList.SERVICE_17_ALT)
def pack_test_command(p: ServiceProviderParams):
info = p.info
q = p.queue_helper
if info.op_code == OpCodes.PING:
def build_test_commands(q: DefaultPusQueueHelper, cmd_path: str):
if cmd_path == OpCode.PING:
q.add_log_cmd("Sending PUS TC [17,1]")
q.add_pus_tc(create_service_17_ping_command())
if info.op_code == OpCodes.TRIGGER_EVENT:
if cmd_path == OpCode.TRIGGER_EVENT:
q.add_log_cmd("Sending PUS TC Event Trigger [17, 128]")
q.add_pus_tc(PusTelecommand(service=PusService.S17_TEST, subservice=128))
if info.op_code == OpCodes.PING_WITH_DATA:
if cmd_path == OpCode.SCHEDULE_PING:
q.add_log_cmd("Sending scheduled PUS ping")
# Generate a UNIX timestamp 30 seconds in the future using the datetime API with a UTC timezone
now = datetime.datetime.now(tz=datetime.timezone.utc)
second_offset_to_now = input("Please specify offset to now in seconds: ")
now += datetime.timedelta(seconds=int(second_offset_to_now))
unix_stamp = struct.pack("!I", math.floor(now.timestamp()))
print(f"Sending ping scheuled at {now}")
ping = PusTelecommand(service=PusService.S17_TEST, subservice=128)
q.add_pus_tc(
create_time_tagged_cmd(
release_time=unix_stamp,
tc_to_insert=ping,
)
)
if cmd_path == OpCode.PING_WITH_DATA:
q.add_log_cmd("Sending Ping With Data, Size Reported Back [17, 129]")
while True:
data_size = int(input("Please specify data size [0-1024]: "))
@ -55,7 +63,7 @@ def pack_test_command(p: ServiceProviderParams):
break
dummy_data = bytearray()
next_byte = True
for i in range(data_size):
for _ in range(data_size):
dummy_data.append(int(next_byte))
next_byte = not next_byte
q.add_pus_tc(

View File

@ -1,44 +1,42 @@
import enum
import struct
import logging
from datetime import datetime
import datetime
from eive_tmtc.config.definitions import CustomServiceList
from spacepackets.ecss import PusTelecommand, PusService
from tmtccmd.config.tmtc import (
tmtc_definitions_provider,
TmtcDefinitionWrapper,
OpCodeEntry,
)
from tmtccmd.tmtc import service_provider
from tmtccmd.tmtc.decorator import ServiceProviderParams
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.config import CmdTreeNode
_LOGGER = logging.getLogger(__name__)
class Subservice(enum.IntEnum):
SET_TIME = 128
DUMP_TIME = 129
RELATIVE_TIMESHIFT = 130
class OpCode:
SET_CURRENT_TIME = ["set_curr_time"]
DUMP_TIME = ["dump_time"]
class CmdStr:
SET_CURRENT_TIME = "set_curr_time"
RELATIVE_TIMESHIFT = "relative_timeshift"
DUMP_TIME = "dump_time"
class Info:
SET_CURRENT_TIME = "Setting current time in ASCII format"
RELATIVE_TIMESHIFT = "Shift time with a relative offset"
DUMP_TIME = "Dump system time as event"
@service_provider(CustomServiceList.TIME.value)
def pack_set_current_time_ascii_command(p: ServiceProviderParams):
q = p.queue_helper
o = p.op_code
if o in OpCode.SET_CURRENT_TIME:
current_time = datetime.utcnow().isoformat() + "Z" + "\0"
current_time_ascii = current_time.encode("ascii")
logging.getLogger(__name__).info(
f"Current time in ASCII format: {current_time_ascii}"
def pack_time_management_cmd(q: DefaultPusQueueHelper, cmd_str: str):
if cmd_str == CmdStr.SET_CURRENT_TIME:
current_time = (
datetime.datetime.now(datetime.timezone.utc).isoformat() + "Z" + "\0"
)
current_time_ascii = current_time.encode("ascii")
_LOGGER.info(f"Current time in ASCII format: {current_time_ascii}")
q.add_log_cmd(Info.SET_CURRENT_TIME)
q.add_pus_tc(
PusTelecommand(
@ -47,7 +45,18 @@ def pack_set_current_time_ascii_command(p: ServiceProviderParams):
app_data=current_time_ascii,
)
)
elif o in OpCode.DUMP_TIME:
elif cmd_str == CmdStr.RELATIVE_TIMESHIFT:
nanos = int(input("Specify relative timeshift in nanoseconds: "))
nanos_packed = struct.pack("!q", nanos)
q.add_log_cmd(Info.RELATIVE_TIMESHIFT)
q.add_pus_tc(
PusTelecommand(
service=PusService.S9_TIME_MGMT,
subservice=Subservice.RELATIVE_TIMESHIFT,
app_data=nanos_packed,
)
)
elif cmd_str == CmdStr.DUMP_TIME:
q.add_log_cmd(Info.DUMP_TIME)
q.add_pus_tc(
PusTelecommand(
@ -56,16 +65,9 @@ def pack_set_current_time_ascii_command(p: ServiceProviderParams):
)
@tmtc_definitions_provider
def add_time_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(
keys=OpCode.SET_CURRENT_TIME,
info=Info.SET_CURRENT_TIME,
)
oce.add(keys=OpCode.DUMP_TIME, info=Info.DUMP_TIME)
defs.add_service(
name=CustomServiceList.TIME.value,
info="Time Service",
op_code_entry=oce,
)
def create_time_node() -> CmdTreeNode:
time_node = CmdTreeNode("time", "Time Management")
time_node.add_child(CmdTreeNode(CmdStr.SET_CURRENT_TIME, "Set current time"))
time_node.add_child(CmdTreeNode(CmdStr.DUMP_TIME, "Dumpy current time"))
time_node.add_child(CmdTreeNode(CmdStr.RELATIVE_TIMESHIFT, Info.RELATIVE_TIMESHIFT))
return time_node

View File

@ -5,24 +5,23 @@ import math
import struct
from typing import Tuple
from dateutil.parser import parse
from spacepackets.ecss.pus_15_tm_storage import Subservice
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.config import CmdTreeNode, TmtcDefinitionWrapper
from tmtccmd.config.tmtc import OpCodeEntry
from tmtccmd.tmtc.queue import DefaultPusQueueHelper
from tmtccmd.util import ObjectIdU32
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.config.object_ids import (
CFDP_TM_STORE,
HK_TM_STORE,
MISC_TM_STORE,
OK_TM_STORE,
NOT_OK_TM_STORE,
CFDP_TM_STORE,
OK_TM_STORE,
get_object_ids,
)
from eive_tmtc.config.definitions import CustomServiceList
from tmtccmd.config import TmtcDefinitionWrapper
from tmtccmd.config.tmtc import tmtc_definitions_provider, OpCodeEntry
from tmtccmd.tmtc import service_provider
from tmtccmd.tmtc.decorator import ServiceProviderParams
from dateutil.parser import parse
from spacepackets.ecss.tc import PusTelecommand
from spacepackets.ecss.pus_15_tm_storage import Subservice
from tmtccmd.util import ObjectIdU32
class CustomSubservice(enum.IntEnum):
@ -44,12 +43,9 @@ class Info:
_LOGGER = logging.getLogger(__name__)
@service_provider(CustomServiceList.TM_STORE)
def pack_tm_store_commands(p: ServiceProviderParams):
q = p.queue_helper
o = p.op_code
if o == OpCode.DELETE_UP_TO:
obj_id, _ = store_select_prompt()
def pack_tm_store_commands(q: DefaultPusQueueHelper, cmd_path: str):
if cmd_path == OpCode.DELETE_UP_TO:
obj_id, store_string = store_select_prompt()
app_data = bytearray(obj_id.as_bytes)
delete_up_to_time = time_prompt("Determining deletion end time")
end_stamp = int(math.floor(delete_up_to_time.timestamp()))
@ -62,7 +58,7 @@ def pack_tm_store_commands(p: ServiceProviderParams):
service=15, subservice=Subservice.DELETE_UP_TO, app_data=app_data
)
)
elif o == OpCode.RETRIEVAL_BY_TIME_RANGE:
elif cmd_path == OpCode.RETRIEVAL_BY_TIME_RANGE:
q.add_log_cmd(Info.RETRIEVAL_BY_TIME_RANGE)
obj_id, _ = store_select_prompt()
app_data = bytearray(obj_id.as_bytes)
@ -84,7 +80,7 @@ def pack_tm_store_commands(p: ServiceProviderParams):
app_data=app_data,
)
)
elif o == OpCode.DELETE_BY_TIME_RANGE:
elif cmd_path == OpCode.DELETE_BY_TIME_RANGE:
q.add_log_cmd(Info.DELETE_BY_TIME_RANGE)
obj_id, _ = store_select_prompt()
app_data = bytearray(obj_id.as_bytes)
@ -108,7 +104,16 @@ def pack_tm_store_commands(p: ServiceProviderParams):
)
@tmtc_definitions_provider
def create_persistent_tm_store_node() -> CmdTreeNode:
node = CmdTreeNode("tm_store", "Persistent TM Store")
node.add_child(CmdTreeNode(OpCode.DELETE_UP_TO, Info.DELETE_UP_TO))
node.add_child(CmdTreeNode(OpCode.DELETE_BY_TIME_RANGE, Info.DELETE_BY_TIME_RANGE))
node.add_child(
CmdTreeNode(OpCode.RETRIEVAL_BY_TIME_RANGE, Info.RETRIEVAL_BY_TIME_RANGE)
)
return node
def add_persistent_tm_store_cmd_defs(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(keys=OpCode.DELETE_UP_TO, info=Info.DELETE_UP_TO)
@ -159,8 +164,7 @@ def time_prompt(info_str: str) -> datetime.datetime:
return time_prompt_fully_manually()
elif time_input_key == 2:
return time_prompt_offset_from_now()
else:
raise ValueError()
raise ValueError("can not determine datetime")
def time_prompt_fully_manually() -> datetime.datetime:
@ -207,5 +211,6 @@ def store_select_prompt() -> Tuple[ObjectIdU32, str]:
break
obj_id_raw = desc_and_obj_id[0]
obj_id = obj_id_dict.get(obj_id_raw)
assert obj_id is not None
print(f"Selected store: {obj_id} ({desc_and_obj_id[1]})")
return obj_id_dict.get(obj_id_raw), desc_and_obj_id[1]
return obj_id, desc_and_obj_id[1]

View File

@ -1,5 +1,6 @@
import enum
from tmtccmd.config.tmtc import (
CmdTreeNode,
OpCodeEntry,
TmtcDefinitionWrapper,
tmtc_definitions_provider,
@ -26,13 +27,20 @@ class ActionId(enum.IntEnum):
DISABLE = 1
def pack_wdt_commands(q: DefaultPusQueueHelper, op_code: str):
if op_code == OpCode.ENABLE:
def pack_wdt_commands(q: DefaultPusQueueHelper, cmd_str: str):
if cmd_str == OpCode.ENABLE:
q.add_pus_tc(create_action_cmd(XIPHOS_WDT_ID, ActionId.ENABLE))
if op_code == OpCode.DISABLE:
if cmd_str == OpCode.DISABLE:
q.add_pus_tc(create_action_cmd(XIPHOS_WDT_ID, ActionId.DISABLE))
def create_wdt_node() -> CmdTreeNode:
node = CmdTreeNode("xiphos_wdt", "Xiphos Watchdog Timer")
node.add_child(CmdTreeNode(OpCode.ENABLE, Info.ENABLE))
node.add_child(CmdTreeNode(OpCode.DISABLE, Info.DISABLE))
return node
@tmtc_definitions_provider
def add_xiphos_wdt_defs(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()

View File

@ -6,32 +6,33 @@ build-backend = "setuptools.build_meta"
name = "eive-tmtc"
description = "TMTC Commander EIVE"
readme = "README.md"
version = "5.11.0"
version = "7.1.0"
requires-python = ">=3.10"
license = {text = "Apache-2.0"}
authors = [
{name = "Robin Mueller", email = "muellerr@irs.uni-stuttgart.de"},
{name = "Jakob Meier", email = "meierj@irs.uni-stuttgart.de"},
{name = "Robin Mueller", email = "muellerr@irs.uni-stuttgart.de"},
{name = "Jakob Meier", email = "meierj@irs.uni-stuttgart.de"},
]
keywords = ["eive", "space", "communication", "commanding"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"License :: OSI Approved :: Apache Software License",
"Natural Language :: English",
"Operating System :: POSIX",
"Operating System :: Microsoft :: Windows",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Topic :: Communications",
"Topic :: Software Development :: Libraries",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Scientific/Engineering"
"Development Status :: 5 - Production/Stable",
"License :: OSI Approved :: Apache Software License",
"Natural Language :: English",
"Operating System :: POSIX",
"Operating System :: Microsoft :: Windows",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Topic :: Communications",
"Topic :: Software Development :: Libraries",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Scientific/Engineering"
]
dependencies = [
"tmtccmd ~= 7.0",
"python-dateutil ~= 2.8",
# "tmtccmd @ git+https://github.com/robamu-org/tmtccmd@main"
"tmtccmd ~= 8.0.1",
# "tmtccmd @ git+https://github.com/robamu-org/tmtccmd@main",
"cfdp-py~=0.1.0",
"python-dateutil ~= 2.8",
]
[project.urls]
@ -44,7 +45,7 @@ include-package-data = true
[tool.setuptools.packages]
find = {}
[tool.ruff]
[tool.ruff.lint]
ignore = ["E501"]
[tool.ruff.extend-per-file-ignores]
[tool.ruff.lint.extend-per-file-ignores]
"__init__.py" = ["F401"]

14
scripts/raw-analysis.py Executable file
View File

@ -0,0 +1,14 @@
#!/usr/bin/env python3
from base64 import b64decode
from spacepackets.ccsds.time import CdsShortTimestamp
from spacepackets.ecss.tm import PusTelemetry
from spacepackets.ecss.pus_1_verification import Service1Tm, UnpackParams
bruh = "CGX6cQAdIAEIOzcAAEBedwUTOzkYZe5WAAEAAAAAAAAAAF4z"
data = b64decode(bruh)
tm = PusTelemetry.unpack(data, CdsShortTimestamp.empty())
srv1_tm = Service1Tm.from_tm(
tm, UnpackParams(time_reader=CdsShortTimestamp.empty(), bytes_err_code=2)
)
print(f"service {tm.service} subservice {tm.subservice}")
print(f"error code: {srv1_tm.error_code}")

View File

@ -7,20 +7,20 @@ from pathlib import Path
from typing import Tuple
import tmtccmd
from cfdppy.handler import RemoteEntityCfgTable
from cfdppy.mib import (
IndicationCfg,
LocalEntityCfg,
RemoteEntityCfg,
)
from spacepackets.cfdp import (
ChecksumType,
TransmissionMode,
)
from spacepackets.ecss import PusVerificator
from spacepackets.seqcount import FileSeqCountProvider, PusFileSeqCountProvider
from spacepackets.version import get_version as get_sp_version
from tmtccmd import BackendBase
from tmtccmd.cfdp.handler import RemoteEntityCfgTable
from eive_tmtc.cfdp.handler import CfdpInCcsdsHandler
from tmtccmd.cfdp.mib import (
IndicationCfg,
LocalEntityCfg,
RemoteEntityCfg,
)
from tmtccmd.config import (
SetupWrapper,
default_json_path,
@ -30,6 +30,7 @@ from tmtccmd.config.args import (
PreArgsParsingWrapper,
ProcedureParamsWrapper,
SetupParams,
perform_tree_printout,
)
from tmtccmd.core import BackendRequest
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
@ -40,11 +41,11 @@ from tmtccmd.logging.pus import (
TimedLogWhen,
)
from tmtccmd.pus import VerificationWrapper
from tmtccmd.tmtc import CcsdsTmHandler, GenericApidHandlerBase, SpecificApidHandlerBase
from tmtccmd.util import FileSeqCountProvider, PusFileSeqCountProvider
from tmtccmd.tmtc import CcsdsTmHandler
from eive_tmtc import APP_LOGGER
from eive_tmtc.cfdp.fault_handler import EiveCfdpFaultHandler
from eive_tmtc.cfdp.handler import CfdpInCcsdsHandler
from eive_tmtc.cfdp.tm import CfdpInCcsdsWrapper
from eive_tmtc.cfdp.user import EiveCfdpUser, EiveCheckTimerProvider
from eive_tmtc.config.definitions import (
@ -55,8 +56,7 @@ from eive_tmtc.config.definitions import (
)
from eive_tmtc.config.hook import EiveHookObject
from eive_tmtc.pus_tc.tc_handler import TcHandler
from eive_tmtc.pus_tm.hk_handler import HkFilter
from eive_tmtc.pus_tm.pus_demux import pus_factory_hook
from eive_tmtc.pus_tm.pus_handler import PusHandler, UnknownApidHandler
_LOGGER = APP_LOGGER
_LOG_LEVEL = logging.INFO
@ -66,42 +66,6 @@ ROTATING_TIMED_LOGGER_INTERVAL_WHEN = TimedLogWhen.PER_MINUTE
ROTATING_TIMED_LOGGER_INTERVAL = 30
class PusHandler(SpecificApidHandlerBase):
def __init__(
self,
wrapper: VerificationWrapper,
printer: FsfwTmTcPrinter,
raw_logger: RawTmtcTimedLogWrapper,
hk_level: int,
):
super().__init__(PUS_APID, None)
self.printer = printer
self.verif_wrapper = wrapper
self.raw_logger = raw_logger
self.hk_level = hk_level
self.these_objs_hk_only = []
self.hk_filter = HkFilter(object_ids=self.these_objs_hk_only, set_ids=[])
def handle_tm(self, packet: bytes, _user_args: any):
# with open("tc.bin", "wb") as of:
# of.write(packet)
pus_factory_hook(
packet,
self.verif_wrapper,
self.printer,
self.raw_logger,
self.hk_level,
self.hk_filter,
)
class UnknownApidHandler(GenericApidHandlerBase):
def handle_tm(self, apid: int, packet: bytes, _user_args: any):
_LOGGER.warning(
f"Packet with unknown APID {apid} detected: {packet.hex(sep=',')}"
)
class CustomCcsdsTmHandler(CcsdsTmHandler):
def user_hook(self, apid: int, packet: bytes):
_LOGGER.debug(f"Received packet {packet.hex(sep=',')} with APID {apid}")
@ -133,6 +97,9 @@ def setup_params() -> Tuple[SetupWrapper, int]:
hk_level = int(post_arg_parsing_wrapper.args_raw.hk)
else:
hk_level = 0
if params.cmd_params.print_tree:
perform_tree_printout(params.cmd_params, hook_obj.get_command_definitions())
sys.exit(0)
params.apid = PUS_APID
if params.com_if is None:
raise ValueError("could not determine a COM interface.")
@ -205,6 +172,7 @@ def setup_tmtc_handlers(
ccsds_handler.add_apid_handler(pus_handler)
ccsds_handler.add_apid_handler(cfdp_in_ccsds_wrapper)
seq_count_provider = PusFileSeqCountProvider()
assert printer.file_logger is not None
tc_handler = TcHandler(
seq_count_provider=seq_count_provider,
pus_verificator=verificator,