Compare commits

...

234 Commits

Author SHA1 Message Date
Marius Eggert 5da55c3c99 Merge pull request 'PLOC SUPV TM handling' (#293) from ploc-supv-tm-handling into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #293
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-04-29 11:44:20 +02:00
Marius Eggert 3b903e5639 Merge branch 'main' into ploc-supv-tm-handling
EIVE/-/pipeline/pr-main Build queued... Details
2024-04-29 11:43:14 +02:00
Marius Eggert da35c7fdf1 Merge pull request 'added missing act cmd' (#295) from gnss-improv into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #295
2024-04-29 11:42:51 +02:00
Marius Eggert 8c7cbd1bd6 changelog
EIVE/-/pipeline/pr-main Build queued... Details
2024-04-29 11:41:03 +02:00
Marius Eggert ba0a3e35d2 cleanup
EIVE/-/pipeline/pr-main Build started... Details
2024-04-29 11:40:00 +02:00
Marius Eggert fc2667c150 Merge branch 'main' into gnss-improv
EIVE/-/pipeline/pr-main Build started... Details
2024-04-29 11:33:10 +02:00
Marius Eggert 3c0ac91227 Merge pull request 'CLock Events' (#291) from clock-events into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #291
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-04-17 16:43:29 +02:00
Robin Müller f61c485979 Merge branch 'main' into clock-events
EIVE/-/pipeline/pr-main This commit looks good Details
2024-04-17 16:20:09 +02:00
Robin Müller 2ebbf750bd
handling for new clock events 2024-04-17 16:19:58 +02:00
Robin Müller 847fccbe66 Merge pull request 'test script' (#294) from bestest-script into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #294
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-04-17 16:19:24 +02:00
Robin Müller c8292f4ee1 Merge branch 'main' into bestest-script
EIVE/-/pipeline/pr-main This commit looks good Details
2024-04-17 15:05:45 +02:00
Robin Müller 3700769e46 Merge remote-tracking branch 'origin/main' into ploc-supv-tm-handling
EIVE/-/pipeline/head Build queued... Details
EIVE/-/pipeline/pr-main There was a failure building this commit Details
2024-04-17 15:04:57 +02:00
Robin Müller 1cafdc817f
clock events
EIVE/-/pipeline/head This commit looks good Details
EIVE/-/pipeline/pr-main This commit looks good Details
2024-04-10 17:34:54 +02:00
Robin Müller 5967dede97
add new events for clock handling
EIVE/-/pipeline/head This commit looks good Details
2024-04-10 17:27:24 +02:00
Marius Eggert a8d0143b1e Merge pull request 'Prep v6.2.0' (#290) from prep-v6.2.0 into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #290
2024-04-10 11:51:24 +02:00
Marius Eggert a0ad5f8948 reran gens 2024-04-10 11:50:15 +02:00
Marius Eggert 20ecef5838 linter
EIVE/-/pipeline/head Build queued... Details
2024-04-10 11:48:04 +02:00
Marius Eggert 6d97841cbf bump version
EIVE/-/pipeline/head Build queued... Details
2024-04-10 11:47:05 +02:00
Marius Eggert 512f0e4530 changelog 2024-04-10 11:46:35 +02:00
Marius Eggert e2f0221681 Merge pull request 'GNSS Fixes' (#289) from gnss-fixes into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #289
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-04-10 11:34:58 +02:00
Marius Eggert e9eb45c088 Merge branch 'main' into gnss-fixes 2024-04-10 11:34:39 +02:00
Marius Eggert ea72087d87 Merge pull request 'allow setting health for payload components' (#287) from set-health-cmd-payload into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #287
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-04-10 11:34:30 +02:00
Robin Müller d48c029b85 Merge branch 'main' into gnss-fixes
EIVE/-/pipeline/pr-main Build queued... Details
2024-04-10 11:30:01 +02:00
Robin Müller b5f4f2ddab
changelog
EIVE/-/pipeline/pr-main Build started... Details
2024-04-10 11:29:19 +02:00
Robin Müller 64dd19bd12 Merge branch 'main' into set-health-cmd-payload
EIVE/-/pipeline/pr-main Build started... Details
2024-04-10 11:28:43 +02:00
Marius Eggert 102821fc71 Merge pull request 'Some PLOC commanding fixes' (#288) from ploc-tree-test into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #288
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-04-09 14:41:10 +02:00
Marius Eggert 24f3abdd5a Merge branch 'main' into ploc-tree-test 2024-04-09 14:40:36 +02:00
Marius Eggert a880db5655 changelog
EIVE/-/pipeline/pr-main This commit looks good Details
2024-04-09 14:34:23 +02:00
Marius Eggert 4e0cbb1034 Merge branch 'main' into gnss-fixes 2024-04-09 14:33:33 +02:00
Robin Müller 96636d59e9 Merge pull request 'relative timeshift' (#286) from relative-timeshift into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #286
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-04-09 14:32:28 +02:00
Robin Müller 7dfdd40963 fixed PLOC mode commanding
EIVE/-/pipeline/pr-main Build queued... Details
2024-04-09 14:31:41 +02:00
Marius Eggert 6282686f2f lets just change the tmtc structure he said. everything will still work he said
EIVE/-/pipeline/head This commit looks good Details
2024-04-09 13:29:01 +02:00
Robin Müller b160f079b1 small bugfix
EIVE/-/pipeline/head This commit looks good Details
2024-04-09 13:19:25 +02:00
Robin Müller 11d7ad0f8d start fixing PLOC tree
EIVE/-/pipeline/head This commit looks good Details
2024-04-09 11:32:57 +02:00
Robin Müller 5af69eb14e add supervisor
EIVE/-/pipeline/pr-main This commit looks good Details
2024-04-08 13:40:37 +02:00
Robin Müller 5a0edbefa8 fix comment block
EIVE/-/pipeline/pr-main This commit looks good Details
2024-04-08 13:38:28 +02:00
Robin Müller 5bdba2dbad update events
EIVE/-/pipeline/pr-main This commit looks good Details
2024-04-08 13:35:34 +02:00
Robin Müller 3ae6ccfb77 this should do the job 2024-04-08 13:35:06 +02:00
Robin Müller de84bf112b changelog
EIVE/-/pipeline/pr-main This commit looks good Details
2024-04-08 13:25:45 +02:00
Robin Müller d182a9d5ec re-run black 2024-04-08 13:24:40 +02:00
Robin Müller c72a04b262 allow setting health for payload components
EIVE/-/pipeline/head This commit looks good Details
2024-04-08 11:36:25 +02:00
Robin Müller 492d364246 relative timeshift
EIVE/-/pipeline/head This commit looks good Details
2024-04-08 11:35:05 +02:00
Robin Müller 33cf7b1613 Merge pull request 'Fix for Heater Cmd' (#284) from heater-health into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #284
2024-04-02 13:28:06 +02:00
Robin Müller d8c49aed80 Merge branch 'main' into heater-health 2024-04-02 13:27:56 +02:00
Marius Eggert 97afd24e52 Merge pull request 'EPS command bugfix' (#285) from eps-bugfix into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #285
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-03-27 09:01:22 +01:00
Robin Müller 4704616ca7 changelog
EIVE/-/pipeline/head This commit looks good Details
2024-03-26 17:52:41 +01:00
Robin Müller 92c0172b59 bugfix for EPS
EIVE/-/pipeline/head This commit looks good Details
2024-03-26 17:50:37 +01:00
Robin Müller 344f16099e test script
EIVE/-/pipeline/head This commit looks good Details
2024-03-19 11:48:24 +01:00
Marius Eggert 49b55f01e3 s
EIVE/-/pipeline/head This commit looks good Details
EIVE/-/pipeline/pr-main This commit looks good Details
2024-03-18 11:11:20 +01:00
Robin Müller f87095bf68 Merge pull request 'STR Improv' (#283) from str-version into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #283
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-03-14 10:55:59 +01:00
Marius Eggert 928759d1bc changelog
EIVE/-/pipeline/pr-main This commit looks good Details
2024-03-13 13:47:02 +01:00
Marius Eggert dc17919108 smoll fix
EIVE/-/pipeline/head Build started... Details
2024-03-13 13:44:15 +01:00
Marius Eggert 5f71f27f0e size check
EIVE/-/pipeline/head This commit looks good Details
2024-03-13 10:18:37 +01:00
Marius Eggert f8d63e56cb version set
EIVE/-/pipeline/head This commit looks good Details
2024-03-13 10:00:45 +01:00
Marius Eggert c843356c8a Merge pull request 'Prep v6.1.1' (#282) from prep-v6.1.1 into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #282
2024-03-06 11:03:24 +01:00
Marius Eggert 49a614db10 cleanup
EIVE/-/pipeline/head Build started... Details
2024-03-06 11:02:10 +01:00
Marius Eggert c90dd92162 bump version 2024-03-06 10:59:31 +01:00
Marius Eggert bcb6a8b34e changelog 2024-03-06 10:59:09 +01:00
Marius Eggert ed15bcaf35 Merge pull request 'Leap Seconds' (#281) from leap-seconds into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #281
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-03-06 10:53:57 +01:00
Marius Eggert 89202f2cfe changelog
EIVE/-/pipeline/pr-main This commit looks good Details
2024-03-06 09:51:03 +01:00
Marius Eggert 40c2a4b1f3 remove printout
EIVE/-/pipeline/head This commit looks good Details
2024-03-05 11:53:00 +01:00
Marius Eggert 811786fd78 update leap seconds act cmd
EIVE/-/pipeline/head This commit looks good Details
2024-03-05 11:43:18 +01:00
Marius Eggert baf1b44d23 added missing act cmd
EIVE/-/pipeline/head This commit looks good Details
EIVE/-/pipeline/pr-main This commit looks good Details
2024-03-01 10:20:07 +01:00
Marius Eggert 73a4260f33 Merge pull request 'Prep v6.1.0' (#280) from prep-v6.1.0 into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #280
2024-02-29 13:24:27 +01:00
Marius Eggert 3358de3e3e changelog
EIVE/-/pipeline/pr-main Build queued... Details
2024-02-29 13:22:06 +01:00
Marius Eggert 211e79c83e bumped version number 2024-02-29 13:20:07 +01:00
Marius Eggert 7f10e5c777 Merge branch 'main' into prep-v6.1.0 2024-02-29 13:19:44 +01:00
Marius Eggert aab35c26c2 reran gens
EIVE/-/pipeline/pr-main Build queued... Details
2024-02-29 13:12:30 +01:00
Robin Müller 6ade001d3d Merge pull request 'New ACS Ctrl Act Cmd' (#278) from acs-ctrl-new-stuff into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #278
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-02-29 12:34:50 +01:00
Robin Müller 098bdcf82b
changelog 2024-02-29 12:34:04 +01:00
Robin Müller b131415ea7 Merge branch 'main' into acs-ctrl-new-stuff 2024-02-29 12:33:44 +01:00
Marius Eggert b1dd5aa7d0 Merge pull request 'Add BlobStats TM handling STR' (#279) from add-blob-stats-str into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #279
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-02-29 12:33:31 +01:00
Robin Müller 0201eb27c4
changelog
EIVE/-/pipeline/pr-main Build queued... Details
2024-02-29 12:27:27 +01:00
Robin Müller c070f18c5d
small fix
EIVE/-/pipeline/head Build queued... Details
2024-02-29 12:26:02 +01:00
Robin Müller 00876ed0e0
tweak for HK filter feature 2024-02-29 12:09:53 +01:00
Robin Müller 68ea889d0f
added blob stats set for STR
EIVE/-/pipeline/head This commit looks good Details
2024-02-29 12:07:03 +01:00
Marius Eggert 771199e542 added new act cmd
EIVE/-/pipeline/head This commit looks good Details
EIVE/-/pipeline/pr-main This commit looks good Details
2024-02-27 16:26:06 +01:00
Marius Eggert 588d7a8079 Merge pull request 'RW commanding fix' (#277) from rw-commanding-fix into main
EIVE/-/pipeline/head Build queued... Details
Reviewed-on: #277
2024-02-26 14:03:52 +01:00
Marius Eggert 83aff8bea5 Merge branch 'main' into rw-commanding-fix 2024-02-26 14:03:22 +01:00
Marius Eggert 1d982785e6 Merge pull request 'STR secondary firmware slot commands' (#276) from str-secondary-fw-slot-update into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #276
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-02-26 14:01:34 +01:00
Robin Müller d062a22a7a delete old function
EIVE/-/pipeline/pr-main This commit looks good Details
2024-02-20 11:29:20 +01:00
Robin Müller f8c3172e7a changelog
EIVE/-/pipeline/head This commit looks good Details
2024-02-20 11:26:54 +01:00
Robin Müller 7a56c604a6 RW commanding fixes 2024-02-20 11:26:36 +01:00
Robin Müller bbde4b5b20
changelog
EIVE/-/pipeline/pr-main This commit looks good Details
2024-02-19 17:25:06 +01:00
Robin Müller 85fc106a9b
add commanding nodes
EIVE/-/pipeline/head This commit looks good Details
2024-02-19 15:58:34 +01:00
Robin Müller d35bc01397
added command to select STR slot
EIVE/-/pipeline/head This commit looks good Details
2024-02-19 15:27:27 +01:00
Robin Müller d811735b8d
add som enums
EIVE/-/pipeline/head This commit looks good Details
2024-02-19 12:20:32 +01:00
Robin Müller 265077a758
add command for second slot update
EIVE/-/pipeline/head This commit looks good Details
2024-02-19 12:17:34 +01:00
Robin Müller 1cd566a94c Merge pull request 'Fix the Errors of muellerr' (#275) from tm-store-fix into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #275
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-02-12 10:40:34 +01:00
Marius Eggert 9aa891ef78 fix the errors of muellerr
EIVE/-/pipeline/head This commit looks good Details
EIVE/-/pipeline/pr-main This commit looks good Details
2024-02-09 12:06:38 +01:00
Marius Eggert 329aa76fbf Merge pull request 'prep v6.0.0' (#274) from prep-v6.0.0 into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #274
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-02-08 13:07:09 +01:00
Robin Müller 4633e0cb13
prep v6.0.0
EIVE/-/pipeline/head This commit looks good Details
2024-02-08 12:18:33 +01:00
Marius Eggert a5ebac6266 Merge pull request 'Add SUPV latchup report handling, clean up code' (#273) from add-supv-latchup-report into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #273
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-02-06 13:52:55 +01:00
Robin Müller f3c6b509ec Merge branch 'main' into add-supv-latchup-report
EIVE/-/pipeline/pr-main This commit looks good Details
2024-02-06 11:37:39 +01:00
Marius Eggert 5aefa436f4 Merge pull request 'v6.0.0-dev' (#269) from v6.0.0-dev into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #269
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-02-06 10:28:28 +01:00
Marius Eggert b0b8118dd5 Merge branch 'main' into v6.0.0-dev
EIVE/-/pipeline/pr-main This commit looks good Details
2024-02-05 09:58:44 +01:00
Marius Eggert db384f8e9c Merge pull request 'print fix STR' (#272) from str-print-fix into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #272
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-02-05 09:05:36 +01:00
Robin Müller e5fe0ab95a
Merge branch 'v6.0.0-dev' into add-supv-latchup-report
EIVE/-/pipeline/pr-main This commit looks good Details
2024-01-31 17:06:33 +01:00
Robin Müller 248df1d4df
added missing field parsing
EIVE/-/pipeline/head This commit looks good Details
2024-01-31 16:57:59 +01:00
Robin Müller f93f713b0e
some minor bugfixes
EIVE/-/pipeline/head This commit looks good Details
2024-01-31 16:49:54 +01:00
Robin Müller c6b2edf688
removed old commands
EIVE/-/pipeline/head This commit looks good Details
2024-01-31 15:58:43 +01:00
Robin Müller 5e3b60b3af
cleaned up PLOC SUPV a bit
EIVE/-/pipeline/head This commit looks good Details
2024-01-31 15:56:03 +01:00
Robin Müller d69d16c3af
add latchup status report handling
EIVE/-/pipeline/head This commit looks good Details
2024-01-31 15:38:01 +01:00
Robin Müller 6376585c4e Merge remote-tracking branch 'origin/main' into v6.0.0-dev
EIVE/-/pipeline/pr-main This commit looks good Details
2024-01-30 10:54:12 +01:00
Robin Müller 5b4a789c4b print fix
EIVE/-/pipeline/head This commit looks good Details
EIVE/-/pipeline/pr-main This commit looks good Details
2024-01-30 10:39:59 +01:00
Marius Eggert d33013ed58 Merge pull request 'Prep v5.13.0' (#271) from prep-v5.13.0 into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #271
2024-01-30 09:25:47 +01:00
Marius Eggert 7e39a481bd Merge branch 'main' into prep-v5.13.0
EIVE/-/pipeline/pr-main This commit looks good Details
2024-01-30 09:24:06 +01:00
Marius Eggert 4744de8a54 changelog
EIVE/-/pipeline/head This commit looks good Details
2024-01-30 09:17:40 +01:00
Marius Eggert 916ce92bdc bump version 2024-01-30 09:17:31 +01:00
Marius Eggert bb765ac8a0 Merge pull request 'Gens' (#270) from reran-gens into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #270
2024-01-30 09:14:38 +01:00
Marius Eggert 84f0f42783 gens
EIVE/-/pipeline/pr-main This commit looks good Details
2024-01-30 09:10:47 +01:00
Marius Eggert ee2dade270 gens
EIVE/-/pipeline/pr-main This commit looks good Details
2024-01-30 09:07:56 +01:00
Marius Eggert 4f26c34c60 gens
EIVE/-/pipeline/head This commit looks good Details
2024-01-29 17:14:18 +01:00
Marius Eggert b5ae7c5f38 Merge pull request 'Add new param command' (#268) from ploc-mpsoc-skip-supv-commanding-param into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #268
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-01-29 10:15:11 +01:00
Robin Müller 813f92f3d4
some cleaning up and some bugfixes
EIVE/-/pipeline/pr-main This commit looks good Details
2024-01-25 13:27:10 +01:00
Robin Müller f3eecfa8ac
fix TC handler
EIVE/-/pipeline/pr-main This commit looks good Details
2024-01-25 13:03:04 +01:00
Robin Müller b94c20dab1
changelog
EIVE/-/pipeline/pr-main This commit looks good Details
2024-01-25 11:22:10 +01:00
Robin Müller 84aeaa4b65 Merge branch 'ploc-mpsoc-skip-supv-commanding-param' into v6.0.0-dev 2024-01-25 11:20:50 +01:00
Robin Müller caaf937003
changelog
EIVE/-/pipeline/pr-main This commit looks good Details
2024-01-25 11:20:38 +01:00
Robin Müller bcdd12caf0
basic printout for wrong mode reply
EIVE/-/pipeline/pr-main This commit looks good Details
2024-01-25 11:01:46 +01:00
Robin Müller 6440048235
get rid of the stupid legacy printer
EIVE/-/pipeline/pr-main This commit looks good Details
2024-01-25 10:39:43 +01:00
Robin Müller c5dcc0b77d Merge branch 'v6.0.0-dev' of https://egit.irs.uni-stuttgart.de/eive/eive-tmtc into v6.0.0-dev
EIVE/-/pipeline/pr-main This commit looks good Details
2024-01-25 10:36:32 +01:00
Robin Müller ebd9792fb9
some minor fixes 2024-01-25 10:36:23 +01:00
Robin Müller 9f1d61c3ef Merge pull request 'Introduce TM DB' (#255) from introduce_tm_db into v6.0.0-dev
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #255
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-01-25 10:26:06 +01:00
Robin Müller 38eb43cf8d Merge branch 'v6.0.0-dev' into introduce_tm_db
EIVE/-/pipeline/pr-v6.0.0-dev Build started... Details
2024-01-25 10:25:56 +01:00
Robin Müller 3d007c32a3
various fixes for ACS subsystem
EIVE/-/pipeline/head This commit looks good Details
2024-01-25 10:22:04 +01:00
Robin Müller 202a824d31
scex bug
EIVE/-/pipeline/head This commit looks good Details
2024-01-25 10:06:10 +01:00
Robin Müller 79b3c269e6
this works 2024-01-25 10:04:45 +01:00
Robin Müller 839da7a224
Merge branch 'ploc-mpsoc-skip-supv-commanding-param' into v6.0.0-dev
EIVE/-/pipeline/head This commit looks good Details
2024-01-25 10:01:39 +01:00
Marius Eggert 3a6abe1b62 Merge pull request 'Introduce new command definition tree' (#259) from bump-tmtccmd into v6.0.0-dev
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #259
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-01-25 09:43:47 +01:00
Robin Müller db70b33bd6
bump tmtccmd again
EIVE/-/pipeline/pr-v6.0.0-dev This commit looks good Details
2024-01-24 17:59:16 +01:00
Robin Müller d53e9d61b0
Merge remote-tracking branch 'origin/main' into bump-tmtccmd
EIVE/-/pipeline/pr-v6.0.0-dev This commit looks good Details
2024-01-24 17:49:39 +01:00
Robin Müller bac4473aa7 Merge branch 'main' into introduce_tm_db
EIVE/-/pipeline/pr-main This commit looks good Details
2024-01-24 17:40:23 +01:00
Robin Müller 1831ea8b7a
add new param command
EIVE/-/pipeline/head This commit looks good Details
EIVE/-/pipeline/pr-main This commit looks good Details
2024-01-24 14:30:57 +01:00
Robin Müller 747ad34eec
prev v5.12.1
EIVE/-/pipeline/head This commit looks good Details
2023-12-13 11:30:03 +01:00
Marius Eggert 2789453d57 Merge pull request 'the endianness is actually really important here' (#266) from add-cmds-to-test-scheduling into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #266
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-12-13 11:28:09 +01:00
Robin Müller 5456d79965
the endianness is actually really important here
EIVE/-/pipeline/head This commit looks good Details
2023-12-13 11:23:55 +01:00
Robin Müller 342a3bbcc9 update PLOC Supversisor TM handling
EIVE/-/pipeline/head This commit looks good Details
2023-12-12 15:28:32 +01:00
Robin Müller 4c54aa7586 Merge pull request 'small fix' (#265) from small-fix into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #265
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-12-07 13:57:49 +01:00
Marius Eggert 1a132684a6 small fix
EIVE/-/pipeline/head This commit looks good Details
2023-12-07 13:54:09 +01:00
Robin Müller f63a834d9a Merge pull request 'prep v5.12.0' (#264) from prep_v5.12.0 into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #264
2023-12-06 17:23:00 +01:00
Robin Müller 58def42281
re-run generators
EIVE/-/pipeline/head This commit looks good Details
2023-12-06 17:19:56 +01:00
Robin Müller ee955e96fb
prepare v5.12.0 2023-12-06 17:19:01 +01:00
Marius Eggert 97fb8a166f Merge pull request 'New ACS Stuff' (#263) from acs-stuff into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #263
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-12-06 17:16:55 +01:00
Marius Eggert d477242881 strats
EIVE/-/pipeline/head This commit looks good Details
2023-12-06 14:48:05 +01:00
Marius Eggert 451c2c07ee stuff
EIVE/-/pipeline/head This commit looks good Details
2023-12-05 16:41:29 +01:00
Marius Eggert 8de88127c3 this is much better
EIVE/-/pipeline/head This commit looks good Details
2023-12-05 09:57:07 +01:00
Marius Eggert e7e97ff2d3 i never pushed this lul
EIVE/-/pipeline/head This commit looks good Details
2023-12-01 13:03:38 +01:00
Marius Eggert 35e3f8b572 call action reply handling 2023-12-01 13:02:23 +01:00
Marius Eggert 77010937b8 tle action reply 2023-12-01 13:01:31 +01:00
Marius Eggert c1f4a3f59d more health 2023-12-01 13:01:14 +01:00
Marius Eggert 74e55b16dc Merge pull request 'prepare next release' (#262) from prep_v5.11.0 into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #262
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-11-30 14:34:57 +01:00
Robin Müller f1f4a1e9a0
prepare next release
EIVE/-/pipeline/head This commit looks good Details
2023-11-30 10:16:29 +01:00
Robin Müller 7c3a72f85b Merge branch 'main' into introduce_tm_db
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-30 10:12:49 +01:00
Robin Müller 4e25e2e6ca Merge branch 'main' into bump-tmtccmd
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-29 18:34:02 +01:00
Robin Müller eb302e5cf1
use released version of tmtccmd
EIVE/-/pipeline/pr-main There was a failure building this commit Details
2023-11-29 18:33:09 +01:00
Robin Müller 3da1c2c262
add some more ACS devices
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-29 17:27:24 +01:00
Robin Müller 1660e27ec1
hopefully soon done
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-29 17:04:30 +01:00
Marius Eggert 40aa648e6b Merge pull request 'update returnvalues' (#261) from update-retvals into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #261
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-11-29 15:49:15 +01:00
Robin Müller 098843a74f
update returnvalues
EIVE/-/pipeline/head This commit looks good Details
2023-11-29 15:15:06 +01:00
Robin Müller 6f86e72042
Merge remote-tracking branch 'origin/main' into bump-tmtccmd
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-29 15:12:48 +01:00
Robin Müller 507c3e3ff3
Merge branch 'introduce_tm_db' into bump-tmtccmd
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-29 15:02:33 +01:00
Robin Müller bca2deae61 Merge branch 'main' into introduce_tm_db
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-29 15:00:09 +01:00
Robin Müller 1ea255d3e8 Merge pull request 'STR reload json cfg cmd' (#257) from str-reload-json-cfg-cmd into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #257
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-11-29 14:59:58 +01:00
Robin Müller b1caaff672
Merge remote-tracking branch 'origin/main' into str-reload-json-cfg-cmd
EIVE/-/pipeline/pr-main Build queued... Details
2023-11-29 14:59:41 +01:00
Robin Müller 3b047094e6 Merge pull request 'Disable Order Check PL PCDU' (#260) from disable-order-check-plpcdu into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #260
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-11-29 14:56:34 +01:00
Robin Müller 56ebfb1000 Merge branch 'main' into disable-order-check-plpcdu
EIVE/-/pipeline/pr-main Build queued... Details
2023-11-29 14:56:26 +01:00
Robin Müller a41dc9b691 Merge pull request 'PLOC SUPV Extensions' (#258) from ploc-supv-extensions into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #258
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-11-29 14:22:40 +01:00
Robin Müller 1d121c40b2 Merge branch 'main' into ploc-supv-extensions
EIVE/-/pipeline/pr-main Build queued... Details
2023-11-29 14:18:32 +01:00
Robin Müller 0a417a89e9 Merge pull request 'Deletion by time range cmd' (#256) from add-deletion-by-time-range-cmd into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #256
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-11-29 14:09:30 +01:00
Robin Müller 35e25bf6d0 small fix for STR node
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-28 17:42:52 +01:00
Robin Müller d4147d8402 not much missing
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-28 17:41:46 +01:00
Robin Müller 3cf312073a continue conversion
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-28 17:34:34 +01:00
Robin Müller 76fee820e9 continuing node setup
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-28 17:24:25 +01:00
Robin Müller d2fc53c1fa cmd history introduction
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-28 16:05:19 +01:00
Robin Müller 7abce63a56 changelog
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-28 15:39:56 +01:00
Robin Müller af24a95475 some fixes and improvements for parsing of TM
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-28 15:35:54 +01:00
Robin Müller 6ea3312b62 that should do the job
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-28 14:20:04 +01:00
Robin Müller d7e61f1395 add new commands to request HK sets
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-28 12:52:13 +01:00
Robin Müller 51227100af added PLOC SUPV TM handling
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-28 12:43:30 +01:00
Robin Müller fc243b76cf
Merge remote-tracking branch 'origin/main' into disable-order-check-plpcdu
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-27 12:20:06 +01:00
Robin Müller 62b16028e6
small fix and tweak
EIVE/-/pipeline/head This commit looks good Details
2023-11-27 12:18:39 +01:00
Robin Müller 4ae659cb4e
changelog update
EIVE/-/pipeline/head This commit looks good Details
2023-11-27 12:01:45 +01:00
Robin Müller 228065bf3b
add new commands to test new feature 2023-11-27 12:01:03 +01:00
Robin Müller 947bcf57f5
done for today
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-22 19:44:24 +01:00
Robin Müller 77c2c91539
health and system cmds
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-22 19:42:26 +01:00
Robin Müller 756944cae3
that should be it
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-22 19:38:04 +01:00
Robin Müller 2bb917eab7
last bugfixes
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-22 19:25:04 +01:00
Robin Müller f756df43a2
last tests 2023-11-22 19:22:51 +01:00
Robin Müller 688602e486
cleaning up
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-22 19:13:22 +01:00
Robin Müller 21a38ae76a
use new the new leaf suppression feature
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-22 18:39:12 +01:00
Robin Müller af02c106b9
looking good
EIVE/-/pipeline/head This commit looks good Details
2023-11-22 16:40:27 +01:00
Robin Müller ae239031ed
removed old service provider API
EIVE/-/pipeline/head This commit looks good Details
2023-11-22 14:13:00 +01:00
Robin Müller d640d547bd
OOF3
EIVE/-/pipeline/head This commit looks good Details
2023-11-22 13:51:33 +01:00
Robin Müller 02d9d6adfc
OOF2
EIVE/-/pipeline/head This commit looks good Details
2023-11-22 11:21:26 +01:00
Robin Müller ba24faefa9
this is hardcore 2023-11-22 10:51:26 +01:00
Robin Müller b3920524ab
OOF 2023-11-22 10:17:05 +01:00
Robin Müller 1508acb7ae Merge remote-tracking branch 'origin/main' into ploc-supv-extensions
EIVE/-/pipeline/head This commit looks good Details
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-21 17:49:01 +01:00
Robin Müller 2642a772ad update generator scripts
EIVE/-/pipeline/head This commit looks good Details
2023-11-21 16:45:10 +01:00
Robin Müller 7c94ab3404 remove old image locations
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-21 16:18:12 +01:00
Robin Müller 38b3166b3f STR reload json cfg cmd
EIVE/-/pipeline/head This commit looks good Details
2023-11-21 15:23:41 +01:00
Robin Müller e285ac1c47 add missing op code
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-16 11:09:47 +01:00
Robin Müller 534d0dc1af
deletion by time range cmd
EIVE/-/pipeline/head This commit looks good Details
2023-11-15 15:48:07 +01:00
Robin Müller 7cb5766a7a
added another helper/wrapper type
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-13 14:50:49 +01:00
Robin Müller 6e87a0249c
no need for file logging here anymore
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-13 13:51:53 +01:00
Robin Müller c0ab3351c9
that's a lot of work..
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-13 13:48:08 +01:00
Robin Müller 2259d269dd
separate function for raw TM insertion
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-13 13:19:42 +01:00
Robin Müller 57a225f926
start adding raw TM DB
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-13 11:37:57 +01:00
Robin Müller d9e4ff6973 Merge remote-tracking branch 'origin/main' into introduce_tm_db
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-13 11:15:02 +01:00
Robin Müller 07b13c153d Merge pull request 'tmtccmd v7.0.0' (#254) from bump_tmtccmd_dependency into main
EIVE/-/pipeline/head There was a failure building this commit Details
Reviewed-on: #254
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-11-13 11:14:46 +01:00
Robin Müller 02dc6174bf Merge branch 'main' into introduce_tm_db
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-13 11:13:38 +01:00
Robin Müller ce363e3785
this seems to work well
EIVE/-/pipeline/head This commit looks good Details
2023-11-13 11:12:18 +01:00
Robin Müller b3c3363591
Merge branch 'bump_tmtccmd_dependency' into introduce_tm_db
EIVE/-/pipeline/head This commit looks good Details
2023-11-13 09:50:01 +01:00
Robin Müller aad725a4e5 Merge branch 'main' into bump_tmtccmd_dependency
EIVE/-/pipeline/pr-main This commit looks good Details
2023-11-13 09:07:50 +01:00
Robin Müller fd714a118d Merge pull request 'Auto Switch Enable / Disable' (#246) from auto-switch-image-feature into main
EIVE/-/pipeline/head There was a failure building this commit Details
Reviewed-on: #246
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-11-13 09:06:13 +01:00
Robin Müller 4446e471d9
CFDP fixes
EIVE/-/pipeline/head This commit looks good Details
2023-11-13 09:05:34 +01:00
Robin Müller 3fe51b08a6
let's try a DB
EIVE/-/pipeline/head This commit looks good Details
2023-11-13 08:50:51 +01:00
Robin Müller 6a8f48c493
moved high level handler from tmtccmd to EIVE
EIVE/-/pipeline/head This commit looks good Details
2023-11-10 19:37:03 +01:00
Robin Müller 0f6e7eb159
thats a lot of import fixes 2023-11-10 19:23:06 +01:00
Robin Müller c4bd355146 PLOC SUPV extensions
EIVE/-/pipeline/head This commit looks good Details
2023-11-08 18:18:40 +01:00
Robin Müller 92fe9d92de
Merge remote-tracking branch 'origin/main' into auto-switch-image-feature
EIVE/-/pipeline/pr-main This commit looks good Details
2023-10-30 14:45:08 +01:00
Robin Müller 99c6c8bbd0
v5.10.1
EIVE/-/pipeline/head This commit looks good Details
2023-10-27 15:02:25 +02:00
Marius Eggert 26552ebeca Merge pull request 'more cleaning' (#252) from str-cleaning into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #252
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-10-27 14:37:00 +02:00
Marius Eggert 76e80c259c Merge branch 'main' into str-cleaning
EIVE/-/pipeline/pr-main Build queued... Details
2023-10-27 14:36:50 +02:00
Marius Eggert f59c2b9a9e Merge pull request 'improve supv reset cmd' (#251) from improve-supv-reset-cmd into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #251
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-10-27 14:36:22 +02:00
Marius Eggert bf3565f497 Merge branch 'main' into improve-supv-reset-cmd
EIVE/-/pipeline/pr-main Build queued... Details
2023-10-27 14:36:17 +02:00
Marius Eggert 7f119f36d2 Merge pull request 're-run generators' (#250) from update-events into main
EIVE/-/pipeline/head This commit looks good Details
Reviewed-on: #250
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-10-27 14:35:48 +02:00
Robin Müller 18728731ed Merge branch 'main' into str-cleaning
EIVE/-/pipeline/pr-main This commit looks good Details
2023-10-27 14:26:16 +02:00
Robin Müller 14334dae92
re-run generators
EIVE/-/pipeline/head This commit looks good Details
EIVE/-/pipeline/pr-main This commit looks good Details
2023-10-27 14:24:31 +02:00
Robin Müller b08f9d9af6
more cleaning
EIVE/-/pipeline/head This commit looks good Details
2023-10-27 12:28:55 +02:00
Robin Müller 84f50bab83
improve supv reset cmd
EIVE/-/pipeline/head This commit looks good Details
EIVE/-/pipeline/pr-main This commit looks good Details
2023-10-26 11:18:30 +02:00
Robin Müller 728b7c647c
changelog
EIVE/-/pipeline/head This commit looks good Details
EIVE/-/pipeline/pr-main This commit looks good Details
2023-10-19 15:02:50 +02:00
Robin Müller a5e38a6856
missing log printout 2023-10-19 15:02:24 +02:00
Robin Müller f400dea799
done
EIVE/-/pipeline/head This commit looks good Details
2023-10-19 15:01:23 +02:00
82 changed files with 4138 additions and 2672 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,89 @@ list yields a list of all related PRs for each release.
# [unreleased]
## 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
- Added new commands to disable channel order checks partially for the payload PCDU normal modes.
- Core controller auto switch enable and disable command.
- Star Tracker JSON reload command. Reboot still required.
- PLOC SUPV ADC and Counters report TM handling.
# [v5.10.1] 2023-10-27
- Minor improvements, update event translation.
# [v5.10.0] 2023-10-27
- Added new STR commands to allow more debugging.

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}")

259
eive_tmtc/cfdp/handler.py Normal file
View File

@ -0,0 +1,259 @@
from dataclasses import dataclass
from typing import Optional, Tuple
import deprecation
from spacepackets import PacketType, SpacePacket, SpacePacketHeader
from spacepackets.cfdp import GenericPduPacket, PduFactory
from spacepackets.cfdp.pdu import PduHolder
from cfdppy import (
CfdpUserBase,
LocalEntityCfg,
RemoteEntityCfgTable,
)
from cfdppy.defs import CfdpState
from cfdppy.handler import (
DestHandler,
DestStateWrapper,
SourceHandler,
SourceStateWrapper,
)
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
@dataclass
class StateWrapper:
source_handler_state = SourceStateWrapper()
dest_handler_state = DestStateWrapper()
class CfdpHandler:
"""Wrapper class which wraps both the :py:class:`tmtccmd.cfdp.handler.source.SourceHandler` and
:py:class:`tmtccmd.cfdp.handler.dest.DestHandler` in a sensible way.
If you have special requirements, for example you want to spawn a new destination handler
for each file copy transfer to allow multiple consecutive file transfers, it might be a good
idea to write a custom wrapper."""
def __init__(
self,
cfg: LocalEntityCfg,
user: CfdpUserBase,
seq_cnt_provider: ProvidesSeqCount,
remote_cfg_table: RemoteEntityCfgTable,
check_timer_provider: CheckTimerProvider,
):
self.remote_cfg_table = remote_cfg_table
self.dest_handler = DestHandler(
cfg=cfg,
user=user,
remote_cfg_table=remote_cfg_table,
check_timer_provider=check_timer_provider,
)
self.source_handler = SourceHandler(
cfg=cfg,
seq_num_provider=seq_cnt_provider,
user=user,
remote_cfg_table=remote_cfg_table,
check_timer_provider=check_timer_provider,
)
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
)
def pull_next_source_packet(self) -> Optional[PduHolder]:
res = self.source_handler.state_machine()
if res.states.num_packets_ready:
return self.source_handler.get_next_packet()
return None
def pull_next_dest_packet(self) -> Optional[PduHolder]:
res = self.dest_handler.state_machine()
if res.states.packets_ready:
return self.dest_handler.get_next_packet()
return None
def __iter__(self):
return self
def __next__(self) -> Tuple[Optional[PduHolder], Optional[PduHolder]]:
"""The iterator for this class will returns a tuple of optional PDUs wrapped b a
:py:class:`PduHolder`.
:return: Can be a tuple where the first entry can hold a source packet and the second entry
can be a destination packet. If both packets are None, a StopIteration will be raised.
"""
next_source_packet = self.pull_next_source_packet()
next_dest_packet = self.pull_next_dest_packet()
if not next_dest_packet and not next_source_packet:
raise StopIteration
return next_source_packet, next_dest_packet
def put_request_pending(self) -> bool:
return self.source_handler.states.state != CfdpState.IDLE
@deprecation.deprecated(
deprecated_in="6.0.0rc0",
current_version=get_version(),
details="Use insert_packet instead",
)
def pass_packet(self, packet: GenericPduPacket):
self.insert_packet(packet)
def insert_packet(self, packet: GenericPduPacket):
"""This function routes the packets based on PDU type and directive type if applicable.
The routing is based on section 4.5 of the CFDP standard which specifies the PDU forwarding
procedure."""
if get_packet_destination(packet) == PacketDestination.DEST_HANDLER:
self.dest_handler.insert_packet(packet)
elif get_packet_destination(packet) == PacketDestination.SOURCE_HANDLER:
self.source_handler.insert_packet(packet) # type: ignore
class CfdpInCcsdsHandler:
"""Wrapper helper type used to wrap PDU packets into CCSDS packets and to extract PDU
packets from CCSDS packets.
:param cfg: Local CFDP entity configuration.
:param user: User wrapper. This contains the indication callback implementations and the
virtual filestore implementation.
:param cfdp_seq_cnt_provider: Every CFDP file transfer has a transaction sequence number.
This provider is used to retrieve that sequence number.
:param ccsds_seq_cnt_provider: Each CFDP PDU is wrapped into a CCSDS space packet, and each
space packet has a dedicated sequence count. This provider is used to retrieve the
sequence count.
:param ccsds_apid: APID to use for the CCSDS space packet header wrapped around each PDU.
This is important so that the OBSW can distinguish between regular PUS packets and
CFDP packets."""
def __init__(
self,
cfg: LocalEntityCfg,
user: CfdpUserBase,
remote_cfg_table: RemoteEntityCfgTable,
ccsds_apid: int,
cfdp_seq_cnt_provider: ProvidesSeqCount,
ccsds_seq_cnt_provider: ProvidesSeqCount,
check_timer_provider: CheckTimerProvider,
):
self.cfdp_handler = CfdpHandler(
cfg=cfg,
user=user,
seq_cnt_provider=cfdp_seq_cnt_provider,
remote_cfg_table=remote_cfg_table,
check_timer_provider=check_timer_provider,
)
self.ccsds_seq_cnt_provider = ccsds_seq_cnt_provider
self.ccsds_apid = ccsds_apid
def put_request_pending(self):
return self.cfdp_handler.put_request_pending()
def state_machine(self):
self.source_handler.state_machine()
self.dest_handler.state_machine()
@deprecation.deprecated(
deprecated_in="6.0.0rc1",
current_version=get_version(),
details="Use state_machine instead",
)
def fsm(self):
self.state_machine()
@property
def source_handler(self):
return self.cfdp_handler.source_handler
@property
def dest_handler(self):
return self.cfdp_handler.dest_handler
def pull_next_source_packet(self) -> Optional[Tuple[PduHolder, SpacePacket]]:
"""Retrieves the next PDU to send and wraps it into a space packet"""
next_packet = self.cfdp_handler.pull_next_source_packet()
if next_packet is None:
return next_packet
sp_header = SpacePacketHeader(
packet_type=PacketType.TC,
apid=self.ccsds_apid,
seq_count=self.ccsds_seq_cnt_provider.get_and_increment(),
data_len=next_packet.packet_len - 1,
)
return next_packet, SpacePacket(sp_header, None, next_packet.pack())
def pull_next_dest_packet(self) -> Optional[Tuple[PduHolder, SpacePacket]]:
"""Retrieves the next PDU to send and wraps it into a space packet"""
next_packet = self.cfdp_handler.pull_next_dest_packet()
if next_packet is None:
return next_packet
sp_header = SpacePacketHeader(
packet_type=PacketType.TC,
apid=self.ccsds_apid,
seq_count=self.ccsds_seq_cnt_provider.get_and_increment(),
data_len=next_packet.packet_len - 1,
)
return next_packet, SpacePacket(sp_header, None, next_packet.pack())
@deprecation.deprecated(
deprecated_in="6.0.0rc1",
current_version=get_version(),
details="Use insert_space_packet instead",
)
def pass_space_packet(self, space_packet: SpacePacket):
self.insert_space_packet(space_packet)
def insert_space_packet(self, space_packet: SpacePacket) -> bool:
if space_packet.user_data is None:
raise ValueError(
"space packet is empty, expected packet containing a CFDP PDU"
)
# Unwrap the user data and pass it to the handler
pdu_raw = space_packet.user_data
pdu_base = PduFactory.from_raw(pdu_raw)
if pdu_base:
self.insert_pdu_packet(pdu_base)
return True
return False
def insert_pdu_packet(self, pdu: GenericPduPacket):
self.cfdp_handler.insert_packet(pdu)
@deprecation.deprecated(
deprecated_in="6.0.0rc1",
current_version=get_version(),
details="Use insert_pdu_packet instead",
)
def pass_pdu_packet(self, pdu_base: GenericPduPacket):
self.insert_pdu_packet(pdu_base)
def __iter__(self):
return self
def __next__(
self,
) -> Tuple[
Optional[Tuple[PduHolder, SpacePacket]],
Optional[Tuple[PduHolder, SpacePacket]],
]:
"""The iterator for this class will returns a tuple of optional PDUs wrapped b a
:py:class:`PduHolder`.
:return: Can be a tuple where the first entry can hold a source packet and the second entry
can be a destination packet. If both packets are None, a StopIteration will be raised.
"""
next_source_tuple = self.pull_next_source_packet()
next_dest_tuple = self.pull_next_dest_packet()
if not next_source_tuple and not next_dest_tuple:
raise StopIteration
return next_source_tuple, next_dest_tuple

View File

@ -1,27 +1,29 @@
import logging
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, DirectiveType
from tmtccmd.cfdp.handler import CfdpInCcsdsHandler
from tmtccmd.tm import SpecificApidHandlerBase
from spacepackets.cfdp import PduFactory, PduType
from eive_tmtc.cfdp.handler import CfdpInCcsdsHandler
from tmtccmd.tmtc import SpecificApidHandlerBase
_LOGGER = logging.getLogger(__name__)
class CfdpInCcsdsWrapper(SpecificApidHandlerBase):
def __init__(self, cfdp_in_ccsds_handler: CfdpInCcsdsHandler):
super().__init__(CFDP_APID, None)
self.handler = cfdp_in_ccsds_handler
super().__init__(CFDP_APID, None)
def handle_tm(self, packet: bytes, _user_args: any):
def handle_tm(self, packet: bytes, _user_args: Any):
# Ignore the space packet header. Its only purpose is to use the same protocol and
# have a seaprate APID for space packets. If this function is called, the APID is correct.
pdu = packet[SPACE_PACKET_HEADER_SIZE:]
pdu_base = PduFactory.from_raw(pdu)
if pdu_base.pdu_type == PduType.FILE_DATA:
generic_pdu = PduFactory.from_raw(pdu)
assert generic_pdu is not None
if generic_pdu.pdu_type == PduType.FILE_DATA:
_LOGGER.info("Received File Data PDU")
else:
directive_type = DirectiveType(pdu_base.directive_type)
directive_type = PduFactory.pdu_directive_type(pdu)
_LOGGER.info(f"Received File Directive PDU with type {directive_type!r}")
self.handler.insert_pdu_packet(pdu_base)
self.handler.insert_pdu_packet(generic_pdu)

View File

@ -1,28 +1,47 @@
from datetime import timedelta
import logging
from spacepackets.cfdp import ConditionCode
from tmtccmd.cfdp import CfdpUserBase, TransactionId
from tmtccmd.cfdp.user import (
from spacepackets.util import UnsignedByteField
from cfdppy import CfdpUserBase, TransactionId
from cfdppy.mib import CheckTimerProvider, Countdown, EntityType
from cfdppy.user import (
TransactionFinishedParams,
MetadataRecvParams,
FileSegmentRecvdParams,
TransactionParams,
)
_LOGGER = logging.getLogger(__name__)
class EiveCheckTimerProvider(CheckTimerProvider):
def provide_check_timer(
self,
local_entity_id: UnsignedByteField,
remote_entity_id: UnsignedByteField,
entity_type: EntityType,
) -> Countdown:
return Countdown(timedelta(seconds=5.0))
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,14 @@ 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_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
@ -143,14 +149,16 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11901;0x2e7d;BOOTING_FIRMWARE_FAILED_EVENT;LOW;Failed to boot firmware;mission/acs/str/StarTrackerHandler.h
11902;0x2e7e;BOOTING_BOOTLOADER_FAILED_EVENT;LOW;Failed to boot star tracker into bootloader mode;mission/acs/str/StarTrackerHandler.h
11903;0x2e7f;COM_ERROR_REPLY_RECEIVED;LOW;Received COM error. P1: Communication Error ID (datasheet p32);mission/acs/str/StarTrackerHandler.h
12001;0x2ee1;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;linux/payload/PlocSupervisorHandler.h
12002;0x2ee2;SUPV_UNKNOWN_TM;LOW;Unhandled event. P1: APID, P2: Service ID;linux/payload/PlocSupervisorHandler.h
12003;0x2ee3;SUPV_UNINIMPLEMENTED_TM;LOW;No description;linux/payload/PlocSupervisorHandler.h
12004;0x2ee4;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;linux/payload/PlocSupervisorHandler.h
12005;0x2ee5;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report P1: ID of command for which the execution failed P2: Status code sent by the supervisor handler;linux/payload/PlocSupervisorHandler.h
12006;0x2ee6;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;linux/payload/PlocSupervisorHandler.h
12007;0x2ee7;SUPV_HELPER_EXECUTING;LOW;Supervisor helper currently executing a command;linux/payload/PlocSupervisorHandler.h
12008;0x2ee8;SUPV_MPSOC_SHUTDOWN_BUILD_FAILED;LOW;Failed to build the command to shutdown the MPSoC;linux/payload/PlocSupervisorHandler.h
12001;0x2ee1;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;linux/payload/plocSupvDefs.h
12002;0x2ee2;SUPV_UNKNOWN_TM;LOW;Unhandled event. P1: APID, P2: Service ID;linux/payload/plocSupvDefs.h
12003;0x2ee3;SUPV_UNINIMPLEMENTED_TM;LOW;No description;linux/payload/plocSupvDefs.h
12004;0x2ee4;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;linux/payload/plocSupvDefs.h
12005;0x2ee5;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report P1: ID of command for which the execution failed P2: Status code sent by the supervisor handler;linux/payload/plocSupvDefs.h
12006;0x2ee6;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;linux/payload/plocSupvDefs.h
12007;0x2ee7;SUPV_HELPER_EXECUTING;LOW;Supervisor helper currently executing a command;linux/payload/plocSupvDefs.h
12008;0x2ee8;SUPV_MPSOC_SHUTDOWN_BUILD_FAILED;LOW;Failed to build the command to shutdown the MPSoC;linux/payload/plocSupvDefs.h
12009;0x2ee9;SUPV_ACK_UNKNOWN_COMMAND;LOW;Received ACK, but no related command is unknown or has not been sent by this software instance. P1: Module APID. P2: Service ID.;linux/payload/plocSupvDefs.h
12010;0x2eea;SUPV_EXE_ACK_UNKNOWN_COMMAND;LOW;Received ACK EXE, but no related command is unknown or has not been sent by this software instance. P1: Module APID. P2: Service ID.;linux/payload/plocSupvDefs.h
12100;0x2f44;SANITIZATION_FAILED;LOW;No description;bsp_q7s/fs/SdCardManager.h
12101;0x2f45;MOUNTED_SD_CARD;INFO;No description;bsp_q7s/fs/SdCardManager.h
12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/payload/PlocMemoryDumper.h
@ -228,8 +236,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
@ -312,5 +321,5 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
14313;0x37e9;DUMP_HK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14314;0x37ea;DUMP_CFDP_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14500;0x38a4;TEMPERATURE_ALL_ONES_START;MEDIUM;Detected invalid values, starting invalid message counting;mission/acs/SusHandler.h
14501;0x38a5;TEMPERATURE_ALL_ONES_RECOVERY;INFO;Detected valid values again, resetting invalid message counter. P1: Invalid message counter.;mission/acs/SusHandler.h
14501;0x38a5;TEMPERATURE_ALL_ONES_RECOVERY;INFO;Detected valid values for a prolonged time again, resetting all counters. P1: Number of periods with invalid messages. P2: Maximum invalid message counter.;mission/acs/SusHandler.h
14600;0x3908;FAULT_HANDLER_TRIGGERED;LOW;P1: CFDP fault handler code. P2: CFDP condition code.;mission/cfdp/defs.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
149 11901 0x2e7d BOOTING_FIRMWARE_FAILED_EVENT LOW Failed to boot firmware mission/acs/str/StarTrackerHandler.h
150 11902 0x2e7e BOOTING_BOOTLOADER_FAILED_EVENT LOW Failed to boot star tracker into bootloader mode mission/acs/str/StarTrackerHandler.h
151 11903 0x2e7f COM_ERROR_REPLY_RECEIVED LOW Received COM error. P1: Communication Error ID (datasheet p32) mission/acs/str/StarTrackerHandler.h
152 12001 0x2ee1 SUPV_MEMORY_READ_RPT_CRC_FAILURE LOW PLOC supervisor crc failure in telemetry packet linux/payload/PlocSupervisorHandler.h linux/payload/plocSupvDefs.h
153 12002 0x2ee2 SUPV_UNKNOWN_TM LOW Unhandled event. P1: APID, P2: Service ID linux/payload/PlocSupervisorHandler.h linux/payload/plocSupvDefs.h
154 12003 0x2ee3 SUPV_UNINIMPLEMENTED_TM LOW No description linux/payload/PlocSupervisorHandler.h linux/payload/plocSupvDefs.h
155 12004 0x2ee4 SUPV_ACK_FAILURE LOW PLOC supervisor received acknowledgment failure report linux/payload/PlocSupervisorHandler.h linux/payload/plocSupvDefs.h
156 12005 0x2ee5 SUPV_EXE_FAILURE LOW PLOC received execution failure report P1: ID of command for which the execution failed P2: Status code sent by the supervisor handler linux/payload/PlocSupervisorHandler.h linux/payload/plocSupvDefs.h
157 12006 0x2ee6 SUPV_CRC_FAILURE_EVENT LOW PLOC supervisor reply has invalid crc linux/payload/PlocSupervisorHandler.h linux/payload/plocSupvDefs.h
158 12007 0x2ee7 SUPV_HELPER_EXECUTING LOW Supervisor helper currently executing a command linux/payload/PlocSupervisorHandler.h linux/payload/plocSupvDefs.h
159 12008 0x2ee8 SUPV_MPSOC_SHUTDOWN_BUILD_FAILED LOW Failed to build the command to shutdown the MPSoC linux/payload/PlocSupervisorHandler.h linux/payload/plocSupvDefs.h
160 12009 0x2ee9 SUPV_ACK_UNKNOWN_COMMAND LOW Received ACK, but no related command is unknown or has not been sent by this software instance. P1: Module APID. P2: Service ID. linux/payload/plocSupvDefs.h
161 12010 0x2eea SUPV_EXE_ACK_UNKNOWN_COMMAND LOW Received ACK EXE, but no related command is unknown or has not been sent by this software instance. P1: Module APID. P2: Service ID. linux/payload/plocSupvDefs.h
162 12100 0x2f44 SANITIZATION_FAILED LOW No description bsp_q7s/fs/SdCardManager.h
163 12101 0x2f45 MOUNTED_SD_CARD INFO No description bsp_q7s/fs/SdCardManager.h
164 12300 0x300c SEND_MRAM_DUMP_FAILED LOW Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command linux/payload/PlocMemoryDumper.h
236 12902 0x3266 POWER_STATE_MACHINE_TIMEOUT MEDIUM No description mission/system/acs/SusAssembly.h
237 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
238 13000 0x32c8 CHILDREN_LOST_MODE MEDIUM No description mission/system/tcs/TcsBoardAssembly.h
239 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
240 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
241 13102 0x332e RESET_FAIL HIGH Failed to reset an GNNS Device. P1: Board-Side. linux/acs/GPSDefinitions.h
242 13200 0x3390 P60_BOOT_COUNT INFO P60 boot count is broadcasted once at SW startup. P1: Boot count mission/power/P60DockHandler.h
243 13201 0x3391 BATT_MODE INFO Battery mode is broadcasted at startup. P1: Mode mission/power/P60DockHandler.h
244 13202 0x3392 BATT_MODE_CHANGED MEDIUM Battery mode has changed. P1: Old mode. P2: New mode mission/power/P60DockHandler.h
321 14313 0x37e9 DUMP_HK_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
322 14314 0x37ea DUMP_CFDP_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
323 14500 0x38a4 TEMPERATURE_ALL_ONES_START MEDIUM Detected invalid values, starting invalid message counting mission/acs/SusHandler.h
324 14501 0x38a5 TEMPERATURE_ALL_ONES_RECOVERY INFO Detected valid values again, resetting invalid message counter. P1: Invalid message counter. Detected valid values for a prolonged time again, resetting all counters. P1: Number of periods with invalid messages. P2: Maximum invalid message counter. mission/acs/SusHandler.h
325 14600 0x3908 FAULT_HANDLER_TRIGGERED LOW P1: CFDP fault handler code. P2: CFDP condition code. mission/cfdp/defs.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)
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
@ -167,6 +168,9 @@ NOT_OK_TM_STORE = bytes([0x73, 0x02, 0x00, 0x03])
HK_TM_STORE = bytes([0x73, 0x02, 0x00, 0x04])
CFDP_TM_STORE = bytes([0x73, 0x03, 0x00, 0x00])
SUPV_FILTER_SET = [PLOC_SUPV_ID, PDU_2_HANDLER_ID, PDU_1_HANDLER_ID]
ObjectIdDict = Dict[bytes, ObjectIdU32]

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
@ -592,7 +595,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
@ -617,5 +624,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x6f00;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x6f01;TMS_PartiallyWritten;No description;1;TM_SINK;mission/tmtc/DirectTmSinkIF.h
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

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
595 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
596 0x69c0 SPVRTVIF_BufTooSmall No description 192 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
597 0x69c1 SPVRTVIF_NoReplyTimeout No description 193 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
598 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
599 0x6aa1 ACSCTRL_WriteFileFailed Writing the TLE to the file has failed. 161 ACS_CTRL mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
600 0x6aa2 ACSCTRL_ReadFileFailed Reading the TLE to the file has failed. 162 ACS_CTRL mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
601 0x6aa3 ACSCTRL_SingleRwUnavailable A single RW has failed. 163 ACS_CTRL mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
602 0x6aa4 ACSCTRL_MultipleRwUnavailable Multiple RWs have failed. 164 ACS_CTRL mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
603 0x6b02 ACSMEKF_MekfUninitialized No description 2 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
604 0x6b03 ACSMEKF_MekfNoGyrData No description 3 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
605 0x6b04 ACSMEKF_MekfNoModelVectors No description 4 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
624 0x6f00 TMS_IsBusy No description 0 TM_SINK mission/tmtc/DirectTmSinkIF.h
625 0x6f01 TMS_PartiallyWritten No description 1 TM_SINK mission/tmtc/DirectTmSinkIF.h
626 0x6f02 TMS_NoWriteActive No description 2 TM_SINK mission/tmtc/DirectTmSinkIF.h
627 0x6f03 TMS_Timeout No description 3 TM_SINK mission/tmtc/DirectTmSinkIF.h
628 0x7000 VCS_ChannelDoesNotExist No description 0 VIRTUAL_CHANNEL mission/com/VirtualChannel.h
629 0x7200 SCBU_KeyNotFound No description 0 SCRATCH_BUFFER bsp_q7s/memory/scratchApi.h

View File

@ -11,8 +11,8 @@ import struct
from typing import Union
from spacepackets.ecss import PusTelecommand
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.pus.s8_fsfw_funccmd import create_action_cmd
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from tmtccmd.util import ObjectIdU32, ObjectIdBase

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 DefaultProcedureInfo
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: DefaultProcedureInfo,
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.tc import DefaultPusQueueHelper
from tmtccmd.tc.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

@ -1,7 +1,7 @@
from typing import Union
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_200_fsfw_mode import Mode
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s200_fsfw_mode import Mode
from tmtccmd.util import ObjectIdU32, ObjectIdBase
from eive_tmtc.tmtc.common import pack_mode_cmd_with_info

View File

@ -10,7 +10,7 @@ from spacepackets.ecss import PusTelecommand
from tmtccmd.config import TmtcDefinitionWrapper, OpCodeEntry
from tmtccmd.config.tmtc import tmtc_definitions_provider
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s11_tc_sched import (
create_time_tagged_cmd,
create_enable_tc_sched_cmd,
@ -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
@ -50,7 +50,7 @@ from eive_tmtc.tmtc.acs.gyros import (
L3gGyroSetId as L3gGyroSetIds_1_3,
)
from eive_tmtc.tmtc.acs.gps import SetId as GpsSetIds
from tmtccmd.tc.pus_3_fsfw_hk import (
from tmtccmd.pus.tc.s3_fsfw_hk import (
make_sid,
disable_periodic_hk_command,
create_enable_periodic_hk_command_with_interval,
@ -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,13 +6,13 @@ 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.tc import (
from tmtccmd.tmtc import (
DefaultPusQueueHelper,
QueueWrapper,
FeedWrapper,
@ -22,7 +22,7 @@ from tmtccmd.tc 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
@ -69,7 +69,7 @@ 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)
handle_pus_procedure(info.to_def_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}"
)
_LOGGER.info(f"Finished queue for command {def_proc.cmd_path}")
elif info.proc_type == TcProcedureType.CFDP:
_LOGGER.info("Finished CFDP queue")

View File

@ -10,6 +10,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,8 +18,9 @@ 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.tm import Service8FsfwTm
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
@ -53,6 +55,8 @@ def handle_action_reply(
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,

View File

@ -1,17 +1,19 @@
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
from eive_tmtc.pus_tm.verification_handler import generic_retval_printout
from eive_tmtc.tmtc.acs.subsystem import AcsMode
from eive_tmtc.tmtc.core import SdState, SdCardSelect
from tmtccmd.tc.pus_200_fsfw_mode import Mode
from tmtccmd.tc.pus_201_fsfw_health import FsfwHealth
from tmtccmd.pus.s200_fsfw_mode import Mode
from tmtccmd.pus.s201_fsfw_health import FsfwHealth
from tmtccmd.tm import Service5Tm
from tmtccmd.pus.s5_fsfw_event import Service5Tm
from tmtccmd.fsfw import EventInfo
from spacepackets.ccsds.time import CdsShortTimestamp
@ -21,6 +23,8 @@ _LOGGER = logging.getLogger(__name__)
def handle_event_packet( # noqa C901: Complexity okay here
raw_tm: bytes, pw: PrintWrapper
): # noqa C901: Complexity okay here
if PRINT_RAW_EVENTS_B64_STR:
print(f"PUS Event TM Base64: {base64.b64encode(raw_tm)}")
tm = Service5Tm.unpack(data=raw_tm, time_reader=CdsShortTimestamp.empty())
event_dict = get_event_dict()
event_def = tm.event_definition
@ -36,6 +40,7 @@ def handle_event_packet( # noqa C901: Complexity okay here
obj_name = event_def.reporter_id.hex(sep=",")
else:
obj_name = obj_id_obj.name
assert tm.time_provider is not None
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()}"
@ -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

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

@ -0,0 +1,21 @@
import uuid
import dataclasses
import datetime
import sqlite3
from tmtccmd.pus.tm.s3_fsfw_hk import Service3FsfwTm
@dataclasses.dataclass
class HkTmInfo:
packet_uuid: uuid.UUID
hk_packet: Service3FsfwTm
db_con: sqlite3.Connection
hk_data: bytes
@property
def packet_datetime(self) -> datetime.datetime:
return self.hk_packet.pus_tm.time_provider.as_datetime()
@property
def set_id(self) -> int:
return self.hk_packet.set_id

View File

@ -1,7 +1,13 @@
"""HK Handling for EIVE OBSW"""
import dataclasses
import logging
from typing import List
import base64 # noqa
import sqlite3
from typing import List, cast
from uuid import UUID
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 +19,14 @@ 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.tm.pus_3_fsfw_hk import (
Service3Base,
HkContentType,
from tmtccmd.pus.tm.s3_fsfw_hk import (
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,31 +55,35 @@ 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)
named_obj_id = cast(ObjectIdU32, obj_id_dict.get(tm_packet.object_id.as_bytes))
if named_obj_id is None:
named_obj_id = tm_packet.object_id
if tm_packet.subservice == 25 or tm_packet.subservice == 26:
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,
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:
@ -85,10 +94,11 @@ def handle_hk_packet(
if hk_level >= 1:
handle_regular_hk_print(
printer=printer,
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 +109,37 @@ 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: Service3FsfwTm,
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
)
assert hk_packet.pus_tm.time_provider is not None
packet_dt = hk_packet.pus_tm.time_provider.as_date_time()
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=packet_dt,
)
elif objb == obj_ids.PCDU_HANDLER_ID:
return handle_pcdu_hk(pw=pw, set_id=set_id, hk_data=hk_data)
@ -127,9 +148,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 +234,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,125 +0,0 @@
"""Core EIVE TM handler module
"""
import logging
from eive_tmtc.config.object_ids import get_object_ids
from spacepackets.ecss import PusTelemetry
from spacepackets.ecss.pus_17_test import Service17Tm
from spacepackets.util import PrintFormats
from spacepackets.ccsds.time import CdsShortTimestamp
from tmtccmd.logging.pus import RawTmtcTimedLogWrapper
from tmtccmd.pus import VerificationWrapper
from tmtccmd.tm import Service20FsfwTm, Service200FsfwTm
from tmtccmd.tm.pus_20_fsfw_param import Service20ParamDumpWrapper
from tmtccmd.pus.s20_fsfw_param_defs import CustomSubservice as ParamSubservice
from tmtccmd.tm.pus_200_fsfw_mode import Subservice as ModeSubservice
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from .defs import PrintWrapper
from .event_handler import handle_event_packet
from .verification_handler import handle_service_1_fsfw_packet, generic_retval_printout
from .hk_handler import handle_hk_packet, HkFilter
from .action_reply_handler import handle_action_reply
_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,211 @@
"""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_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__)
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.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
db_con = sqlite3.connect(TM_DB_PATH)
self._store_packet_in_db(db_con, packet, tm_packet, 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_reply(
raw_tm=packet, printer=self.printer, obj_id_dict=self.obj_id_dict
)
elif service == 17:
pus17_tm = Service17Tm.unpack(
data=packet, time_reader=CdsShortTimestamp.empty()
)
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,
tm_packet: PusTelemetry,
packet_uuid: uuid.UUID,
):
cursor = db_con.cursor()
assert tm_packet.time_provider is not None
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),
tm_packet.time_provider.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, 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 = 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

@ -4,7 +4,7 @@ from typing import List, Optional
from spacepackets.ccsds import CdsShortTimestamp
from spacepackets.ecss.pus_1_verification import UnpackParams, Service1Tm
from tmtccmd.pus import VerificationWrapper
from tmtccmd.tm.pus_1_verification import Service1FsfwWrapper
from tmtccmd.pus.s1_verification import Service1FsfwWrapper
from eive_tmtc.config.retvals import get_retval_dict
_LOGGER = logging.getLogger(__name__)

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.tc import service_provider, DefaultPusQueueHelper
from tmtccmd.tc.decorator import ServiceProviderParams
from tmtccmd.tc.pus_200_fsfw_mode import Mode
from eive_tmtc.config.object_ids import ACS_BOARD_ASS_ID
from tmtccmd.pus.s200_fsfw_mode import Mode
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

@ -1,49 +1,40 @@
import datetime
import enum
import logging
import math
import socket
import struct
import math
from socket import AF_INET
from typing import Tuple
from eive_tmtc.config.definitions import CustomServiceList
from tmtccmd.config.tmtc import CmdTreeNode
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
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 (
create_matrix_double_parameter,
create_matrix_float_parameter,
create_scalar_double_parameter,
create_scalar_float_parameter,
create_scalar_i32_parameter,
create_scalar_u8_parameter,
create_scalar_u16_parameter,
create_vector_double_parameter,
create_vector_float_parameter,
)
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,
make_sid,
)
from tmtccmd.tmtc.queue import DefaultPusQueueHelper
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
from tmtccmd.config.tmtc import (
tmtc_definitions_provider,
TmtcDefinitionWrapper,
OpCodeEntry,
)
from tmtccmd.tc import service_provider
from tmtccmd.tc.queue import DefaultPusQueueHelper
from tmtccmd.tc.pus_200_fsfw_mode import Mode, pack_mode_command
from tmtccmd.tc.decorator import ServiceProviderParams
from tmtccmd.tc.pus_3_fsfw_hk import (
generate_one_hk_command,
make_sid,
enable_periodic_hk_command_with_interval,
disable_periodic_hk_command,
create_request_one_diag_command,
)
from tmtccmd.pus.s8_fsfw_funccmd import create_action_cmd
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.tc.pus_20_fsfw_param import create_load_param_cmd
from tmtccmd.pus.s20_fsfw_param_defs import (
create_scalar_u8_parameter,
create_scalar_u16_parameter,
create_scalar_i32_parameter,
create_scalar_float_parameter,
create_scalar_double_parameter,
create_vector_float_parameter,
create_vector_double_parameter,
create_matrix_float_parameter,
create_matrix_double_parameter,
)
_LOGGER = logging.getLogger(__name__)
@ -56,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):
@ -67,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 = {
@ -87,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:
@ -163,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
@ -213,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: ")
@ -335,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):
@ -661,7 +414,7 @@ def set_acs_ctrl_param_vector(q: DefaultPusQueueHelper):
domain_id=sid,
unique_id=pid,
parameters=param,
).pack()
)
)
)
else:
@ -773,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):
@ -802,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(FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=12))
def handle_acs_ctrl_sus_processed_data(pw: PrintWrapper, hk_data: bytes):
@ -838,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(FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=15))
def handle_raw_mgm_data(pw: PrintWrapper, hk_data: bytes):
@ -852,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)],
@ -894,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(FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=6))
def handle_mgm_data_processed(pw: PrintWrapper, hk_data: bytes):
@ -948,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(FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=8))
def handle_gyr_data_raw(pw: PrintWrapper, hk_data: bytes):
@ -982,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(FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], 4))
GYR_NAMES = ["GYR 0 ADIS", "GYR 1 L3", "GYR 2 ADIS", "GYR 3 L3"]
@ -1008,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(FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=5))
def handle_gps_data_processed(pw: PrintWrapper, hk_data: bytes):
@ -1062,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]")
@ -1071,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(FsfwTmTcPrinter.get_validity_buffer(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",
@ -1085,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}]"
@ -1094,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
@ -1113,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(FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=4))
return
pw.dlog(FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=3))
def handle_ctrl_val_data(pw: PrintWrapper, hk_data: bytes):
@ -1165,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(FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=5))
def handle_act_cmd_data(pw: PrintWrapper, hk_data: bytes):
@ -1211,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(FsfwTmTcPrinter.get_validity_buffer(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 = [
@ -1246,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(FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=4))
return
pw.dlog(FsfwTmTcPrinter.get_validity_buffer(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(FsfwTmTcPrinter.get_validity_buffer(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,18 +3,17 @@ 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.tc.pus_200_fsfw_mode import create_mode_command, Mode
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_3_fsfw_hk import (
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 (
make_sid,
create_request_one_hk_command,
create_enable_periodic_hk_command_with_interval_with_diag,
create_disable_periodic_hk_command_with_diag,
)
from tmtccmd.pus.tc.s8_fsfw_action import create_action_cmd
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
_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))

View File

@ -3,13 +3,14 @@ import logging
import struct
from spacepackets.ecss import PusTelecommand
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_201_fsfw_health import pack_set_health_cmd_data, FsfwHealth
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
import eive_tmtc.config.object_ids as obj_ids
from tmtccmd.tc.pus_200_fsfw_mode import create_mode_command, Mode
from tmtccmd.tc.pus_3_fsfw_hk import create_request_one_hk_command, make_sid
from tmtccmd.pus.s200_fsfw_mode import create_mode_command, Mode
from tmtccmd.pus.tc.s3_fsfw_hk import create_request_one_hk_command, make_sid
from tmtccmd.config.tmtc import (
tmtc_definitions_provider,
OpCodeEntry,
@ -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
@ -18,8 +20,8 @@ from tmtccmd.config.tmtc import (
OpCodeEntry,
TmtcDefinitionWrapper,
)
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_3_fsfw_hk import (
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.tc.s3_fsfw_hk import (
make_sid,
generate_one_diag_command,
generate_one_hk_command,
@ -27,7 +29,7 @@ from tmtccmd.tc.pus_3_fsfw_hk import (
create_enable_periodic_hk_command_with_interval_with_diag,
create_disable_periodic_hk_command_with_diag,
)
from tmtccmd.tc.pus_200_fsfw_mode import pack_mode_data, Mode
from tmtccmd.pus.s200_fsfw_mode import pack_mode_data, Mode
from tmtccmd.util import ObjectIdU32
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
@ -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(

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 (
@ -14,8 +14,8 @@ from eive_tmtc.config.object_ids import (
from eive_tmtc.pus_tm.defs import PrintWrapper
from tmtccmd.config.tmtc import tmtc_definitions_provider, TmtcDefinitionWrapper
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_200_fsfw_mode import create_mode_command, Mode
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s200_fsfw_mode import create_mode_command, Mode
from tmtccmd.util import ObjectIdU32
@ -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,24 +6,22 @@
"""
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.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_3_fsfw_hk import (
from tmtccmd.config import CmdTreeNode
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.tc.s3_fsfw_hk import (
generate_one_hk_command,
generate_one_diag_command,
make_sid,
enable_periodic_hk_command_with_interval,
disable_periodic_hk_command,
)
from tmtccmd.tc.pus_8_fsfw_funccmd import create_action_cmd
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.tc.pus_200_fsfw_mode import pack_mode_data, Mode, Subservice
from eive_tmtc.config.definitions import CustomServiceList
from tmtccmd.pus.s200_fsfw_mode import pack_mode_data, Mode, Subservice
from tmtccmd.util import ObjectIdU32
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
@ -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]: ")
)

View File

@ -9,23 +9,23 @@ 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.tc.pus_3_fsfw_hk import (
from tmtccmd.config import CmdTreeNode
from tmtccmd.pus.tc.s3_fsfw_hk import (
create_request_one_diag_command,
create_request_one_hk_command,
enable_periodic_hk_command_with_interval,
disable_periodic_hk_command,
make_sid,
)
from tmtccmd.pus.s8_fsfw_funccmd import create_action_cmd
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_200_fsfw_mode import pack_mode_data, Mode
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 eive_tmtc.config.object_ids import STR_ASSEMBLY, STAR_TRACKER_ID
@ -33,6 +33,16 @@ 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,14 +105,18 @@ 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
READ_SECONDARY_TM_SET = 97
RELOAD_JSON_CFG_FILE = 100
class OpCodes:
class OpCode:
ON_BOOTLOADER = "on_bootloader"
ON_FIRMWARE = "on_firmware"
NORMAL = "nml"
@ -116,23 +130,46 @@ class OpCodes:
READ_SECONDARY_TM_SET = "read_secondary_tm"
TAKE_IMAGE = "take_image"
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"
ADD_SECONDARY_TM_TO_NORMAL_MODE = "Add specific Dataset to secondary TM"
RESET_SECONDARY_TM_SET = "Reset secondary TM to Temperature Set only"
READ_SECONDARY_TM_SET = "Read list of secondary TM Sets"
UPLOAD_IMAGE = "Upload Image"
UPLOAD_IMAGE = "Upload Optical Image"
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):
@ -154,6 +191,7 @@ class SetId(enum.IntEnum):
BLOBS = 92
CENTROID = 93
CENTROIDS = 94
BLOB_STATS = 102
class DataSetRequest(enum.IntEnum):
@ -236,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 == OpCodes.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 == OpCodes.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 == OpCodes.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 == OpCodes.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 == OpCodes.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 == OpCodes.ENABLE_HK:
if cmd_str == OpCode.ENABLE_HK:
q.add_log_cmd(Info.ENABLE_HK)
request_dataset(q, DataSetRequest.ENABLE)
if op_code == OpCodes.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 == OpCodes.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 = (
@ -306,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 == OpCodes.UPLOAD_IMAGE:
if cmd_str == OpCode.UPLOAD_IMAGE:
q.add_log_cmd("Star tracker: Upload image")
image = get_upload_image()
data = (
@ -323,8 +357,8 @@ 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 == "16":
q.add_log_cmd("Star tracker: 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:
path = FileDefs.download_path
@ -334,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 = (
@ -343,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 = (
@ -352,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 = (
@ -361,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 = (
@ -370,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 = (
@ -379,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 = (
@ -388,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 = (
@ -397,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 = (
@ -406,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 = (
@ -415,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 == OpCodes.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): ")
@ -426,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 = (
@ -439,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 = (
@ -456,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 = (
@ -469,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 == OpCodes.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 = (
@ -486,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 = (
@ -495,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 = (
@ -504,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
@ -515,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 = (
@ -524,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 == OpCodes.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 = (
@ -545,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
@ -553,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
@ -561,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 = (
@ -618,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()
@ -628,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 = (
@ -637,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 == OpCodes.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 == OpCodes.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))
@ -658,7 +701,7 @@ def pack_star_tracker_commands( # noqa C901
struct.pack("!I", set_id),
)
)
if op_code == OpCodes.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(
@ -666,13 +709,54 @@ def pack_star_tracker_commands( # noqa C901
StarTrackerActionId.RESET_SECONDARY_TM_SET,
)
)
if op_code == OpCodes.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 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(
create_scalar_u8_parameter(
STAR_TRACKER_ID,
0,
param_id,
fw_target,
)
)
def request_dataset(q: DefaultPusQueueHelper, req_type: DataSetRequest):
@ -804,6 +888,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")
@ -826,6 +914,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(FsfwTmTcPrinter.get_validity_buffer(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:
@ -914,7 +1021,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)
print(FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], 23))
def handle_blob_set(hk_data: bytes, pw: PrintWrapper):
@ -1106,6 +1213,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(FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=6))
def handle_star_tracker_action_replies(
action_id: int, pw: PrintWrapper, custom_data: bytes
):
@ -1145,72 +1281,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(OpCodes.ON_BOOTLOADER, "Mode On, Submode Bootloader")
oce.add(OpCodes.ON_FIRMWARE, "Mode On, Submode Firmware")
oce.add(OpCodes.NORMAL, "Mode Normal")
oce.add(OpCodes.OFF, "Mode Off")
oce.add(OpCodes.PING, "Star Tracker: Ping")
oce.add(OpCodes.TAKE_IMAGE, "Take Image")
oce.add(OpCodes.ONE_SHOOT_HK, Info.ONE_SHOOT_HK)
oce.add(OpCodes.ENABLE_HK, Info.ENABLE_HK)
oce.add(OpCodes.DISABLE_HK, Info.DISABLE_HK)
oce.add(OpCodes.UPLOAD_IMAGE, Info.UPLOAD_IMAGE)
oce.add(OpCodes.SET_IMG_PROCESSOR_MODE, Info.SET_IMG_PROCESSOR_MODE)
oce.add(
OpCodes.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(OpCodes.READ_SECONDARY_TM_SET, Info.READ_SECONDARY_TM_SET)
oce.add(OpCodes.RESET_SECONDARY_TM_SET, Info.RESET_SECONDARY_TM_SET)
# oce.add("6", "Star Tracker: Switch to bootloader program")
# oce.add("7", "Star Tracker: Request temperature")
# oce.add("8", "Star Tracker: Request version")
# oce.add("9", "Star Tracker: Request interface")
# oce.add("10", "Star Tracker: Request power")
# oce.add("11", "Star Tracker: Set subscription parameters")
# oce.add("12", "Star Tracker: Boot image (requires bootloader mode)")
# oce.add("13", "Star Tracker: Request time")
# oce.add("14", "Star Tracker: Request solution")
# oce.add("16", "Star Tracker: Download image")
# oce.add("17", "Star Tracker: Set limit parameters")
# oce.add("17", "Star Tracker: Set limit parameters")
# oce.add("18", "Star Tracker: Set tracking parameters")
# oce.add("19", "Star Tracker: Set mounting parameters")
# oce.add("20", "Star Tracker: Set camera parameters")
# oce.add("22", "Star Tracker: Set centroiding parameters")
# oce.add("23", "Star Tracker: Set LISA parameters")
# oce.add("24", "Star Tracker: Set matching parameters")
# oce.add("25", "Star Tracker: Set validation parameters")
# oce.add("26", "Star Tracker: Set algo parameters")
# oce.add("28", "Star Tracker: Stop str helper")
# oce.add("30", "Star Tracker: Set name of download image")
# oce.add("31", "Star Tracker: Request histogram")
# oce.add("32", "Star Tracker: Request contrast")
# oce.add("33", "Star Tracker: Set json filename")
# oce.add("35", "Star Tracker: Flash read")
# oce.add("36", "Star Tracker: Set flash read filename")
# oce.add("37", "Star Tracker: Get checksum")
# oce.add("49", "Star Tracker: Request camera parameter")
# oce.add("50", "Star Tracker: Request limits")
# oce.add("52", "Star Tracker: (EGSE only) Load camera ground config")
# oce.add("53", "Star Tracker: (EGSE only) Load camera flight config")
# oce.add("54", "Star Tracker: Request log level parameters")
# oce.add("55", "Star Tracker: Request mounting parameters")
# oce.add("56", "Star Tracker: Request image processor parameters")
# oce.add("57", "Star Tracker: Request centroiding parameters")
# oce.add("58", "Star Tracker: Request lisa parameters")
# oce.add("59", "Star Tracker: Request matching parameters")
# oce.add("60", "Star Tracker: Request tracking parameters")
# oce.add("61", "Star Tracker: Request validation parameters")
# oce.add("62", "Star Tracker: Request algo parameters")
# oce.add("63", "Star Tracker: Request subscription parameters")
# oce.add("64", "Star Tracker: Request log subscription parameters")
# oce.add("65", "Star Tracker: Request debug camera parameters")
# oce.add("66", "Star Tracker: Set log level parameters")
# oce.add("67", "Star Tracker: Set log subscription parameters")
# oce.add("68", "Star Tracker: Set debug camera parameters")
oce.add(OpCodes.FW_UPDATE, Info.FW_UPDATE)
oce.add(OpCodes.SET_TIME_FROM_SYS_TIME, Info.SET_TIME_FROM_SYS_TIME)
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

@ -12,7 +12,7 @@
import struct
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.util import ObjectIdU32

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.tc.pus_200_fsfw_mode import Subservice as ModeSubservices
from tmtccmd.tc import service_provider
from tmtccmd.tc.decorator import ServiceProviderParams
from tmtccmd.pus.s200_fsfw_mode import Subservice as ModeSubservices
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

@ -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.tc import service_provider, DefaultPusQueueHelper
from tmtccmd.tc.decorator import ServiceProviderParams
from tmtccmd.tc.pus_200_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 (
@ -15,8 +17,8 @@ from tmtccmd.config.tmtc import (
OpCodeEntry,
TmtcDefinitionWrapper,
)
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_200_fsfw_mode import create_mode_command, Mode
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s200_fsfw_mode import create_mode_command, Mode
from tmtccmd.util import ObjectIdU32
@ -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

@ -8,10 +8,10 @@
import enum
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.tc.pus_20_fsfw_param import create_load_param_cmd
from tmtccmd.tc.pus_8_fsfw_funccmd import create_action_cmd
from tmtccmd.pus.s20_fsfw_param import create_load_param_cmd
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from tmtccmd.pus.s20_fsfw_param_defs import create_scalar_u8_parameter
from tmtccmd.config.tmtc import (
@ -60,20 +60,20 @@ 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(
@ -86,7 +86,7 @@ def pack_pdec_handler_test(
)
)
)
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(
@ -99,12 +99,12 @@ def pack_pdec_handler_test(
)
)
)
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,
CmdTreeNode,
)
from tmtccmd.tc import service_provider
from tmtccmd.tc.decorator import ServiceProviderParams
from tmtccmd.tc.pus_200_fsfw_mode import (
create_mode_command,
create_read_mode_command,
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.tc.pus_20_fsfw_param import (
create_load_param_cmd,
)
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.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_3_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.tc.pus_200_fsfw_mode import Mode, create_mode_command
from eive_tmtc.config.object_ids import SYRLINKS_HANDLER_ID
import struct
from tmtccmd.util import ObjectIdU32
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.config.tmtc import (
CmdTreeNode,
OpCodeEntry,
TmtcDefinitionWrapper,
tmtc_definitions_provider,
)
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
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 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,76 +215,82 @@ 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]
@ -279,7 +300,11 @@ def handle_syrlinks_temp_dataset(pw: PrintWrapper, hk_data: bytes):
pw.dlog(FsfwTmTcPrinter.get_validity_buffer(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",
@ -342,14 +367,44 @@ def handle_syrlinks_rx_registers_dataset(pw: PrintWrapper, hk_data: bytes):
pw.dlog(
FsfwTmTcPrinter.get_validity_buffer(validity_buffer=validity_buffer, num_vars=8)
)
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}")
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
)"""
)
cursor.execute(
"INSERT INTO syrlinks_rx_regs VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)",
(
str(hk_info.packet_uuid),
hk_info.hk_packet.pus_tm.time_provider.as_datetime(), # type: ignore
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 +430,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 +452,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,11 +463,11 @@ 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(
@ -419,10 +475,46 @@ def handle_syrlinks_tx_registers_dataset(
)
# 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.hk_packet.pus_tm.time_provider.as_datetime(), # type: ignore
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

@ -1,8 +1,8 @@
from typing import Union
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_200_fsfw_mode import pack_mode_data, Mode, Subservice
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s200_fsfw_mode import pack_mode_data, Mode, Subservice
from tmtccmd.util import ObjectIdU32

View File

@ -3,23 +3,26 @@ import logging
import os
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.tc import DefaultPusQueueHelper
from tmtccmd.pus.s8_fsfw_funccmd import create_action_cmd
from tmtccmd.tc.pus_3_fsfw_hk import make_sid, generate_one_hk_command
from tmtccmd.tc.pus_20_fsfw_param import (
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from tmtccmd.pus.tc.s3_fsfw_hk import make_sid, generate_one_hk_command
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 eive_tmtc.config.object_ids import CORE_CONTROLLER_ID
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
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 eive_tmtc.pus_tm.defs import PrintWrapper
_LOGGER = logging.getLogger(__name__)
@ -52,6 +55,8 @@ class ActionId(enum.IntEnum):
SWITCH_TO_SD_0 = 16
SWITCH_TO_SD_1 = 17
SWITCH_TO_BOTH_SD_CARDS = 18
AUTO_SWITCH_ENABLE = 19
AUTO_SWITCH_DISABLE = 20
XSC_REBOOT = 32
FULL_REBOOT = 34
EXECUTE_SHELL_CMD_BLOCKING = 40
@ -63,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):
@ -87,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"
@ -110,6 +117,11 @@ class OpCode:
RWD_RESET_REBOOT_COUNTER_10 = "rwd_reset_10"
RWD_RESET_REBOOT_COUNTER_11 = "rwd_reset_11"
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:
@ -122,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"
@ -135,6 +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):
@ -155,103 +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.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,
@ -259,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}")
@ -277,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(
@ -286,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(
@ -295,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(
@ -325,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(
@ -335,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(
@ -345,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(
@ -353,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")
@ -372,30 +335,44 @@ 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.SWITCH_TO_SD_0:
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])
q.add_pus_tc(
create_action_cmd(
CORE_CONTROLLER_ID, ActionId.AUTO_SWITCH_ENABLE, user_data
)
)
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 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]:
@ -409,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): ")
@ -430,7 +407,7 @@ def pack_core_commands( # noqa C901
)
)
)
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")
@ -443,13 +420,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")
@ -464,7 +441,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: ")
@ -475,7 +452,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(
@ -483,7 +460,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())
@ -491,9 +468,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"
)
@ -551,18 +544,17 @@ def create_full_reboot_cmds() -> PusTelecommand:
)
def determine_reboot_params() -> (bool, Chip, Copy):
chip_select = -1
copy_select = -1
def determine_reboot_params() -> Tuple[bool, Chip, Copy]:
reboot_self = input("Reboot self? [y/n]: ")
if reboot_self in ["y", "yes", "1"]:
_LOGGER.info("Rebooting currently running image")
return True, chip_select, copy_select
return True, Chip.NONE, Copy.NONE
_LOGGER.info("Rebooting image specified by chip and copy")
return False, determine_chip_and_copy()
chip, copy = determine_chip_and_copy()
return False, chip, copy
def determine_chip_and_copy() -> (int, int):
def determine_chip_and_copy() -> Tuple[Chip, Copy]:
while True:
chip_select = input("Chip select [0/1]: ")
if chip_select in ["0", "1"]:

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.tc import service_provider
from tmtccmd.pus.s201_fsfw_health import Subservice, FsfwHealth
from tmtccmd.tc.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

@ -6,8 +6,8 @@
@date 02.05.2020
"""
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_200_fsfw_mode import pack_mode_data, Mode
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s200_fsfw_mode import pack_mode_data, Mode
from eive_tmtc.config.object_ids import TEST_DEVICE_ID
TEST_DEVICE_OBJ_ID = TEST_DEVICE_ID

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

@ -12,7 +12,7 @@ from eive_tmtc.config.definitions import CustomServiceList
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.config import TmtcDefinitionWrapper
from tmtccmd.config.tmtc import tmtc_definitions_provider, OpCodeEntry
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.util import ObjectIdU32

View File

@ -15,16 +15,17 @@ 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 (
CmdTreeNode,
tmtc_definitions_provider,
OpCodeEntry,
TmtcDefinitionWrapper,
)
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.tc import service_provider
from tmtccmd.tc.decorator import ServiceProviderParams
from tmtccmd.tmtc import DefaultPusQueueHelper
from eive_tmtc.utility.input_helper import InputHelper
from tmtccmd.tc.pus_200_fsfw_mode import pack_mode_data, Mode
from tmtccmd.tc.pus_8_fsfw_funccmd import create_action_cmd
from tmtccmd.pus.s200_fsfw_mode import pack_mode_data, Mode
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__)
@ -93,6 +94,10 @@ class ActionId(enum.IntEnum):
TC_FLASH_READ_FULL_FILE = 30
class ParamId(enum.IntEnum):
PLOC_SUPV_SKIP_CMD_TO_ON = 1
class OpCode:
ON = "on"
OFF = "off"
@ -115,6 +120,8 @@ class OpCode:
SIMPLEX_SEND_FILE = "simplex_send_file"
DOWNLINK_DATA_MODULATE = "downlink_data_modulate"
MODE_SNAPSHOT = "mode_snapshot"
ENABLE_PLOC_SUPV_COMMANDING_TO_ON = "enable_ploc_supv_cmd_to_on"
DISABLE_PLOC_SUPV_COMMANDING_TO_ON = "disable_ploc_supv_cmd_to_on"
class Info:
@ -128,6 +135,8 @@ 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"
@ -137,12 +146,29 @@ class Info:
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"
)
class MemAddresses(enum.IntEnum):
DEADBEEF = 0x40000004
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
# Legacy command definitions.
@tmtc_definitions_provider
def add_ploc_mpsoc_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
@ -171,34 +197,39 @@ def add_ploc_mpsoc_cmds(defs: TmtcDefinitionWrapper):
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)
oce.add(
OpCode.ENABLE_PLOC_SUPV_COMMANDING_TO_ON, Info.ENABLE_PLOC_SUPV_COMMANDING_TO_ON
)
oce.add(
OpCode.DISABLE_PLOC_SUPV_COMMANDING_TO_ON,
Info.DISABLE_PLOC_SUPV_COMMANDING_TO_ON,
)
defs.add_service(CustomServiceList.PLOC_MPSOC.value, "Ploc MPSoC", oce)
@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 +241,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,15 +281,15 @@ 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:
if cmd_str == OpCode.VERIFY_BOOT:
num_words = 1
q.add_log_cmd(f"{prefix} {Info.VERIFY_BOOT}")
data = (
@ -272,15 +299,15 @@ def pack_ploc_mpsoc_commands( # noqa C901
+ struct.pack("!H", num_words)
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == OpCode.MODE_REPLAY:
if cmd_str == 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:
if cmd_str == 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":
if cmd_str == "16":
q.add_log_cmd("PLOC MPSoC: Tc cam command send")
cam_cmd = input("Specify cam command string: ")
data = (
@ -289,30 +316,48 @@ 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 == "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:
if cmd_str == 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.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:
if cmd_str == 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.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 generate_write_mem_command(
@ -674,7 +719,6 @@ def handle_mpsoc_data_reply(action_id: int, pw: PrintWrapper, custom_data: bytea
num_elements = struct.unpack("!I", custom_data[current_idx : current_idx + 4])[
0
]
current_idx += 4
elem_names = []
elem_attrs = []
elem_sizes = []

View File

@ -6,27 +6,25 @@
@author J. Meier
@date 10.07.2021
"""
from datetime import datetime
import enum
import logging
import struct
from eive_tmtc.config.object_ids import PLOC_SUPV_ID, get_object_ids
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.pus_tm.defs import PrintWrapper
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.tc.pus_3_fsfw_hk import generate_one_hk_command, make_sid
from tmtccmd.config import TmtcDefinitionWrapper
from tmtccmd.config.tmtc import tmtc_definitions_provider, OpCodeEntry
from tmtccmd.tc import service_provider
from tmtccmd.tc.decorator import ServiceProviderParams
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_funccmd import create_action_cmd
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from eive_tmtc.utility.input_helper import InputHelper
_LOGGER = logging.getLogger(__name__)
latchup_id_dict = {
LATCHUP_ID_DICT = {
"0": "0.85V",
"1": "1.8V",
"2": "MISC",
@ -40,27 +38,15 @@ HARDCODED = "0"
MANUAL_INPUT = "1"
HARDCODED_FILE = "/home/rmueller/EIVE/mpsoc_boot.bin"
update_file_dict = {
HARDCODED: ["hardcoded", ""],
MANUAL_INPUT: ["manual input", ""],
"2": ["/mnt/sd0/ploc/supervisor/update.bin", "/mnt/sd0/ploc/supervisor/update.bin"],
"3": [
"/mnt/sd0/ploc/supervisor/update-large.bin",
"/mnt/sd0/ploc/supervisor/update-large.bin",
],
"4": [
"/mnt/sd0/ploc/supervisor/update-small.bin",
"/mnt/sd0/ploc/supervisor/update-small.bin",
],
"5": [
"/mnt/sd0/ploc/supervisor/mpsoc-uart-working.bin",
"/mnt/sd0/ploc/supervisor/mpsoc-uart-working.bin",
],
UPDATE_FILE_DICT = {
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"],
EVENT_BUFFER_PATH_DICT = {
MANUAL_INPUT: ("manual input", ""),
"2": ("/mnt/sd0/ploc/supervisor", "/mnt/sd0/ploc/supervisor"),
}
@ -84,7 +70,7 @@ FACTORY_RESET_OPS = {
class SupvActionId(enum.IntEnum):
HK_REPORT = 1
REQUEST_HK_REPORT = 1
START_MPSOC = 3
SHUTWOWN_MPSOC = 4
SEL_MPSOC_BOOT_IMAGE = 5
@ -111,7 +97,7 @@ class SupvActionId(enum.IntEnum):
SET_GPIO = 34
READ_GPIO = 35
RESTART_SUPERVISOR = 36
LOGGING_REQUEST_COUNTERS = 38
REQUEST_LOGGING_COUNTERS = 38
FACTORY_RESET = 39
START_MPSOC_QUIET = 45
SET_SHUTDOWN_TIMEOUT = 46
@ -130,135 +116,141 @@ class SupvActionId(enum.IntEnum):
MEM_CHECK = 61
class SetIds(enum.IntEnum):
class SetId(enum.IntEnum):
HK_REPORT = 102
BOOT_STATUS_REPORT = 103
LATCHUP_REPORT = 104
COUNTERS_REPORT = 105
ADC_REPORT = 106
UPDATE_STATUS_REPORT = 107
class OpCodes:
OFF = ["0", "off"]
ON = ["1", "on"]
NORMAL = ["2", "nml"]
HK_TO_OBC = ["3", "hk_to_obc"]
REQUEST_HK = ["4", "req_hk"]
START_MPSOC = ["5", "start_mpsoc"]
SHUTDOWN_MPSOC = ["6", "stop_mpsoc"]
SEL_NVM = ["7", "sel_nvm"]
SET_TIME_REF = ["set_time_ref"]
FACTORY_FLASH = ["factory_flash"]
REQ_BOOT_STATUS_REPORT = ["13", "boot_report"]
START_UPDATE = ["42", "start_update"]
PERFORM_UPDATE = ["update"]
FACTORY_RESET = ["factory_reset"]
MEM_CHECK = ["mem_check"]
class OpCode:
OFF = "off"
ON = "on"
NORMAL = "nml"
HK_TO_OBC = "hk_to_obc"
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"
START_UPDATE = "start_update"
PERFORM_UPDATE = "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 = "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"
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(OpCodes.OFF, Info.OFF)
oce.add(OpCodes.ON, Info.ON)
oce.add(OpCodes.NORMAL, Info.NML)
oce.add(OpCodes.HK_TO_OBC, Info.HK_TO_OBC)
oce.add(OpCodes.REQUEST_HK, Info.REQUEST_HK)
oce.add(OpCodes.START_MPSOC, "PLOC Supervisor: Start MPSoC")
oce.add(OpCodes.SHUTDOWN_MPSOC, "PLOC Supervisor: Shutdown MPSoC")
oce.add(OpCodes.SEL_NVM, Info.SEL_NVM)
oce.add(OpCodes.SET_TIME_REF, Info.SET_TIME_REF)
oce.add(OpCodes.FACTORY_RESET, Info.FACTORY_RESET)
oce.add("8", "PLOC Supervisor: Set max restart tries")
oce.add("9", "PLOC Supervisor: Reset MPSoC")
oce.add("11", "PLOC Supervisor: Set boot timeout")
oce.add("12", "PLOC Supervisor: Disable Hk")
oce.add(OpCodes.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(OpCodes.PERFORM_UPDATE, Info.PERFORM_UPDATE)
oce.add(OpCodes.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(OpCodes.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(OpCodes.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 in OpCodes.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 in OpCodes.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 in OpCodes.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 in OpCodes.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.HK_REPORT)
command = obyt + struct.pack("!I", SupvActionId.REQUEST_HK_REPORT)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code in OpCodes.REQUEST_HK:
q.add_log_cmd(f"{prefix}: {Info.REQUEST_HK}")
sid = make_sid(object_id.as_bytes, SetIds.HK_REPORT)
cmd = generate_one_hk_command(sid)
q.add_pus_tc(cmd)
elif op_code in OpCodes.START_MPSOC:
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 op_code in OpCodes.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 in OpCodes.SEL_NVM:
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:
action_cmd = create_action_cmd(
PLOC_SUPV_ID, SupvActionId.REQUEST_ADC_REPORT
)
if set_id == SetId.COUNTERS_REPORT:
action_cmd = create_action_cmd(
PLOC_SUPV_ID, SupvActionId.REQUEST_LOGGING_COUNTERS
)
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)
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 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.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): "))
@ -266,9 +258,8 @@ 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 in OpCodes.FACTORY_RESET:
if cmd_str == OpCode.FACTORY_RESET:
q.add_log_cmd(f"{prefix}: {Info.FACTORY_RESET}")
key = -1
while True:
print("Please select the key for a factory reset operation")
for key, val in FACTORY_RESET_OPS.items():
@ -284,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 = (
@ -293,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 == "9":
q.add_log_cmd("PLOC Supervisor: 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 in OpCodes.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 = (
@ -310,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 OpCodes.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, SetIds.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 OpCodes.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 OpCodes.PERFORM_UPDATE:
if cmd_str in OpCode.PERFORM_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 OpCodes.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.LOGGING_REQUEST_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: "))
@ -457,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)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
if op_code in OpCodes.MEM_CHECK:
if cmd_str == OpCode.MEM_CHECK:
custom_data = bytearray()
update_file = get_update_file()
memory_id = int(input("Specify memory ID: "))
@ -480,6 +391,20 @@ def pack_ploc_supv_commands(p: ServiceProviderParams): # noqa C901
q.add_pus_tc(command)
def prompt_set_id() -> SetId:
for set_id in SetId:
print(f"{set_id}: {set_id.name}")
while True:
set_id = int(input("Please select the set ID to request: "))
try:
set_id_typed = SetId(set_id)
except ValueError:
_LOGGER.warning("invalid set ID, try again")
continue
break
return set_id_typed
def pack_sel_boot_image_cmd(
object_id: bytes, mem: int, bp0: int, bp1: int, bp2: int
) -> bytearray:
@ -544,9 +469,9 @@ def get_latchup_id() -> int:
description_string = "Description".ljust(description_column_width)
print(f"{key_string} | {description_string}")
print(separator_string)
for key in latchup_id_dict:
for key in LATCHUP_ID_DICT:
key_string = key.ljust(key_column_width)
description_string = latchup_id_dict[key].ljust(description_column_width)
description_string = LATCHUP_ID_DICT[key].ljust(description_column_width)
print(f"{key_string} | {description_string}")
return int(input("Specify latchup ID: "))
@ -675,10 +600,10 @@ def pack_set_gpio_cmd(object_id: bytes) -> bytearray:
port = int(input("Specify port: 0x"), 16)
pin = int(input("Specify pin: 0x"), 16)
val = int(input("Specify val: 0x"), 16)
command = object_id + struct.pack("!I", SupvActionId.SET_GPIO)
command = command + struct.pack("!B", port)
command = command + struct.pack("!B", pin)
command = command + struct.pack("!B", val)
command = bytearray(object_id + struct.pack("!I", SupvActionId.SET_GPIO))
command.append(port)
command.append(pin)
command.append(val)
return bytearray(command)
@ -700,92 +625,239 @@ def pack_logging_set_topic(object_id: bytes) -> bytearray:
def get_update_file() -> str:
_LOGGER.info("Specify update file ")
input_helper = InputHelper(update_file_dict)
input_helper = InputHelper(UPDATE_FILE_DICT)
key = input_helper.get_key()
if key == HARDCODED:
file = HARDCODED_FILE
elif key == MANUAL_INPUT:
file = input("Ploc Supervisor: Specify absolute name of update file: ")
else:
file = update_file_dict[key][1]
file = UPDATE_FILE_DICT[key][1]
return file
def get_event_buffer_path() -> str:
_LOGGER.info("Specify path where to store event buffer file ")
input_helper = InputHelper(event_buffer_path_dict)
input_helper = InputHelper(EVENT_BUFFER_PATH_DICT)
key = input_helper.get_key()
if key == MANUAL_INPUT:
file = input("Ploc Supervisor: Specify path: ")
else:
file = event_buffer_path_dict[key][1]
file = EVENT_BUFFER_PATH_DICT[key][1]
return file
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):
current_idx = 0
if set_id == SetIds.HK_REPORT:
fmt_str = "!IIIQIIIIIBBBB"
inc_len = struct.calcsize(fmt_str)
(
temp_ps,
temp_pl,
temp_sup,
uptime,
cpu_load,
avail_heap,
num_tcs,
num_tms,
soc_state,
nvm_0_1_state,
nvm_3_state,
mission_io_state,
fmc_state,
) = struct.unpack(fmt_str, hk_data[:inc_len])
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)}")
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))
elif set_id == SetIds.BOOT_STATUS_REPORT:
fmt_str = "!BBIIBBBBBB"
inc_len = struct.calcsize(fmt_str)
(
soc_state,
power_cycles,
boot_after_ms,
boot_timeout_ms,
active_nvm,
bp_0_state,
bp_1_state,
bp_2_state,
boot_state,
boot_cycles,
) = struct.unpack(fmt_str, hk_data[0 : 0 + inc_len])
current_idx += inc_len
pw.dlog(
"SoC state (0:off, 1:booting, 2:update, 3:operating, 4:shutdown, 5:reset):"
f" {soc_state}"
)
pw.dlog(f"Power Cycles {power_cycles}")
pw.dlog(f"Boot after {boot_after_ms} ms | Boot timeout {boot_timeout_ms} ms")
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)
if set_id == SetId.HK_REPORT:
handle_hk_report(hk_data, pw)
elif set_id == SetId.BOOT_STATUS_REPORT:
handle_boot_report(hk_data, pw)
elif set_id == SetId.ADC_REPORT:
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=',')}]")
def handle_hk_report(hk_data: bytes, pw: PrintWrapper):
fmt_str = "!IIIQIIIIIBBBB"
inc_len = struct.calcsize(fmt_str)
(
temp_ps,
temp_pl,
temp_sup,
uptime,
cpu_load,
avail_heap,
num_tcs,
num_tms,
soc_state,
nvm_0_1_state,
nvm_3_state,
mission_io_state,
fmc_state,
) = struct.unpack(fmt_str, hk_data[:inc_len])
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}")
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))
def handle_boot_report(hk_data: bytes, pw: PrintWrapper):
current_idx = 0
fmt_str = "!BBIIBBBBBB"
inc_len = struct.calcsize(fmt_str)
(
soc_state,
power_cycles,
boot_after_ms,
boot_timeout_ms,
active_nvm,
bp_0_state,
bp_1_state,
bp_2_state,
boot_state,
boot_cycles,
) = struct.unpack(fmt_str, hk_data[0 : 0 + inc_len])
current_idx += inc_len
pw.dlog(
"SoC state (0:off, 1:booting, 2:update, 3:operating, 4:shutdown, 5:reset):"
f" {soc_state}"
)
pw.dlog(f"Power Cycles {power_cycles}")
pw.dlog(f"Boot after {boot_after_ms} ms | Boot timeout {boot_timeout_ms} ms")
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)
def handle_adc_report(hk_data: bytes):
if len(hk_data) < 64:
_LOGGER.warning("ADC report smaller than 64 bytes")
current_idx = 0
adc_raw = []
adc_eng = []
for _ in range(16):
adc_raw.append(struct.unpack("!H", hk_data[current_idx : current_idx + 2])[0])
current_idx += 2
for _ in range(16):
adc_eng.append(struct.unpack("!H", hk_data[current_idx : current_idx + 2])[0])
current_idx += 2
print(f"{'Index'.ljust(10)} | {'ADC RAW'.ljust(10)} | {'ADC ENG'.ljust(10)}")
for i in range(16):
print(f"{i: >10} | {adc_raw[i]: >10} | {adc_eng[i]: >10}")
def handle_counters_report(hk_data: bytes):
current_idx = 0
signature = struct.unpack("!I", hk_data[current_idx : current_idx + 4])[0]
current_idx += 4
latchup_counters = []
for _ in range(7):
latchup_counters.append(
struct.unpack("!I", hk_data[current_idx : current_idx + 4])[0]
)
current_idx += 4
fmt_str = "!IIIIIIIIIIIIIIIIIIII"
inc_len = struct.calcsize(fmt_str)
(
adc_deviation_triggers_cnt,
tc_received_cnt,
tm_available_cnt,
supervisor_boots,
mpsoc_boots,
mpsoc_boot_failed_attempts,
mpsoc_powerup,
mpsoc_updates,
mpsoc_heartbeat_resets,
cpu_wdt_resets,
ps_heartbeats_lost,
pl_heartbeats_lost,
eb_task_lost,
bm_task_lost,
lm_task_lost,
am_task_lost,
tctmm_task_lost,
mm_task_lost,
hk_task_lost,
dl_task_lost,
) = struct.unpack(fmt_str, hk_data[current_idx : current_idx + inc_len])
current_idx += inc_len
_redwire_tasks_lost = []
for _ in range(3):
_redwire_tasks_lost.append(
struct.unpack("!I", hk_data[current_idx : current_idx + 4])[0]
)
print(f"Signature: {signature}")
print(f"Latchup Counters: {latchup_counters}")
print(f"ADC Deviation Triggers Count: {adc_deviation_triggers_cnt}")
print(f"TCs received: {tc_received_cnt} | TMs Available: {tm_available_cnt}")
print(f"Supervisor Boots: {supervisor_boots} | MPSoC boots: {mpsoc_boots}")
print(f"MPSoC boot failed attempts: {mpsoc_boot_failed_attempts}")
print(f"MPSoC powerup: {mpsoc_powerup}")
print(f"MPSoC updates: {mpsoc_updates}")
print(f"MPSoC heartbeat resets: {mpsoc_heartbeat_resets}")
print(f"CPU WDT resets: {cpu_wdt_resets}")
print(f"PS heartbeats lost: {ps_heartbeats_lost}")
print(f"PL heartbeats lost: {pl_heartbeats_lost}")
print(f"EB task lost: {eb_task_lost}")
print(f"BM task lost: {bm_task_lost}")
print(f"LM task lost: {lm_task_lost}")
print(f"AM task lost: {am_task_lost}")
print(f"TCTMM task lost: {tctmm_task_lost}")
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,23 +6,22 @@ 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.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_3_fsfw_hk import (
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.tc.s3_fsfw_hk import (
make_sid,
generate_one_diag_command,
enable_periodic_hk_command_with_interval,
disable_periodic_hk_command,
)
from tmtccmd.tc.pus_11_tc_sched import (
from tmtccmd.pus.s11_tc_sched import (
create_enable_tc_sched_cmd,
create_time_tagged_cmd,
)
from tmtccmd.pus.s200_fsfw_mode import Subservice
from tmtccmd.tc.pus_200_fsfw_mode import pack_mode_data, Mode
from tmtccmd.tc.pus_20_fsfw_param import (
from tmtccmd.pus.s200_fsfw_mode import Subservice, pack_mode_data, Mode
from tmtccmd.pus.s20_fsfw_param import (
create_scalar_double_parameter,
create_load_param_cmd,
create_scalar_boolean_parameter,
@ -35,7 +34,6 @@ _LOGGER = logging.getLogger(__name__)
class OpCode:
SWITCH_HPA_ON_PROC = ["0", "proc_hpa"]
SWITCH_ON = "on"
SWITCH_OFF = "off"
NORMAL_SSR = "nml_ssr"
@ -44,21 +42,25 @@ class OpCode:
NORMAL_TX = "nml_tx"
NORMAL_MPA = "nml_mpa"
NORMAL_HPA = "nml_hpa"
NORMAL_CUSTOM = "nml_custom"
ENABLE_HK = "enable_hk"
DISABLE_HK = "disable_hk"
REQ_OS_HK = "hk_os"
DISABLE_ORDER_CHECKING = "disable_order_checking"
ENABLE_ORDER_CHECKING = "enable_order_checking"
UPDATE_I_UPPER_LIMIT = "update_i_upper_limit"
UPDATE_V_LOWER_LIMIT = "update_v_lower_limit"
UPDATE_V_UPPER_LIMIT = "update_v_upper_limit"
INJECT_SSR_TO_DRO_FAILURE = ["10", "inject_ssr_dro_fault"]
INJECT_DRO_TO_X8_FAILURE = ["11", "inject_dro_x8_fault"]
INJECT_X8_TO_TX_FAILURE = ["12", "inject_x8_tx_fault"]
INJECT_TX_TO_MPA_FAILURE = ["13", "inject_tx_mpa_fault"]
INJECT_MPA_TO_HPA_FAILURE = ["14", "inject_mpa_hpa_fault"]
INJECT_ALL_ON_FAILURE = ["15", "inject_all_on_fault"]
INJECT_SSR_TO_DRO_FAILURE = "inject_ssr_dro_fault"
INJECT_DRO_TO_X8_FAILURE = "inject_dro_x8_fault"
INJECT_X8_TO_TX_FAILURE = "inject_x8_tx_fault"
INJECT_TX_TO_MPA_FAILURE = "inject_tx_mpa_fault"
INJECT_MPA_TO_HPA_FAILURE = "inject_mpa_hpa_fault"
INJECT_ALL_ON_FAILURE = "inject_all_on_fault"
class Info:
@ -71,13 +73,21 @@ class Info:
NORMAL_TX = f"{NORMAL}, TX on"
NORMAL_MPA = f"{NORMAL}, MPA on"
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"
class SetId(enum.IntEnum):
@ -164,6 +174,8 @@ class ParamId(enum.IntEnum):
INJECT_MPA_TO_HPA_FAILURE = 34
INJECT_ALL_ON_FAILURE = 35
DISABLE_ORDER_CHECK_CHANNELS = 40
class DevSelect(enum.IntEnum):
SSR_NEG_V = 0
@ -174,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)
@ -186,6 +209,7 @@ def add_pl_pcdu_cmds(defs: TmtcDefinitionWrapper):
oce.add(keys=OpCode.NORMAL_TX, info=Info.NORMAL_TX)
oce.add(keys=OpCode.NORMAL_MPA, info=Info.NORMAL_MPA)
oce.add(keys=OpCode.NORMAL_HPA, info=Info.NORMAL_HPA)
oce.add(keys=OpCode.NORMAL_CUSTOM, info=Info.NORMAL_CUSTOM)
oce.add(keys=OpCode.REQ_OS_HK, info=Info.REQ_OS_HK)
oce.add(keys=OpCode.ENABLE_HK, info=Info.ENABLE_HK)
oce.add(keys=OpCode.UPDATE_V_LOWER_LIMIT, info=Info.UPDATE_V_LOWER_LIMIT)
@ -212,17 +236,19 @@ def add_pl_pcdu_cmds(defs: TmtcDefinitionWrapper):
info="Inject failure in MPA to HPA transition",
)
oce.add(keys=OpCode.INJECT_ALL_ON_FAILURE, info="Inject failure in all on mode")
oce.add(keys=OpCode.DISABLE_ORDER_CHECKING, info=Info.DISABLE_ORDER_CHECKING)
oce.add(keys=OpCode.ENABLE_ORDER_CHECKING, info=Info.ENABLE_ORDER_CHECKING)
defs.add_service(CustomServiceList.PL_PCDU.value, "PL PCDU", oce)
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: ")
)
@ -232,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,
@ -247,49 +273,77 @@ 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.REQ_OS_HK:
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 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.UPDATE_I_UPPER_LIMIT:
if cmd_str == OpCode.DISABLE_ORDER_CHECKING:
q.add_log_cmd(Info.DISABLE_ORDER_CHECKING)
q.add_pus_tc(
create_load_param_cmd(
create_scalar_boolean_parameter(
PL_PCDU_ID, 0, ParamId.DISABLE_ORDER_CHECK_CHANNELS, True
)
)
)
if cmd_str == OpCode.ENABLE_ORDER_CHECKING:
q.add_log_cmd(Info.ENABLE_ORDER_CHECKING)
q.add_pus_tc(
create_load_param_cmd(
create_scalar_boolean_parameter(
PL_PCDU_ID, 0, ParamId.DISABLE_ORDER_CHECK_CHANNELS, False
)
)
)
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))
@ -301,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))
@ -313,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))
@ -325,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,
@ -635,3 +687,31 @@ def dev_select_to_upper_u_update_param_id(dev_select: DevSelect) -> ParamId:
if param_id is None:
raise ValueError("invalid parameter ID")
return param_id
def prompt_custom_normal_submode() -> int:
print("Prompting custom submode.")
submode = 0
def prompt_channel(submode: int, channel_str: str, mask: NormalSubmodesMask) -> int:
while True:
channel_on = input(f" {channel_str} ON? [y/n]: ")
if channel_on in ["y", "1", "yes"]:
submode |= 1 << mask
elif channel_on in ["n", "0", "no"]:
pass
else:
_LOGGER.warning("invalid input, try again")
continue
break
return submode
submode = prompt_channel(
submode, "SSR", NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON
)
submode = prompt_channel(submode, "DRO", NormalSubmodesMask.DRO_ON)
submode = prompt_channel(submode, "X8", NormalSubmodesMask.X8_ON)
submode = prompt_channel(submode, "TX", NormalSubmodesMask.TX_ON)
submode = prompt_channel(submode, "MPA", NormalSubmodesMask.MPA_ON)
submode = prompt_channel(submode, "HPA", NormalSubmodesMask.HPA_ON)
return submode

View File

@ -14,9 +14,9 @@ from eive_tmtc.pus_tm.defs import PrintWrapper
from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.config import TmtcDefinitionWrapper, OpCodeEntry
from tmtccmd.config.tmtc import tmtc_definitions_provider
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_200_fsfw_mode import Mode, pack_mode_data
from tmtccmd.tc.pus_3_fsfw_hk import generate_one_hk_command, make_sid
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
@ -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))

View File

@ -2,17 +2,13 @@ import enum
import json
from spacepackets.ecss import PusTelecommand
from tmtccmd.config.tmtc import CmdTreeNode
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from tmtccmd.pus.s200_fsfw_mode import Mode, Subservice, pack_mode_data
from tmtccmd.tmtc import DefaultPusQueueHelper
from eive_tmtc.config.definitions import CustomServiceList
from tmtccmd.config.tmtc import tmtc_definitions_provider
from tmtccmd.tc.pus_200_fsfw_mode import Mode, pack_mode_data, Subservice
from tmtccmd.tc import service_provider
from tmtccmd.tc.decorator import ServiceProviderParams
from tmtccmd.pus.s8_fsfw_funccmd import create_action_cmd
from tmtccmd.config import OpCodeEntry, TmtcDefinitionWrapper
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,15 +1,12 @@
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.tc import service_provider
from tmtccmd.tc.decorator import ServiceProviderParams
from tmtccmd.tc.pus_200_fsfw_mode import Subservice as ModeSubservice
from tmtccmd.config import CmdTreeNode
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s200_fsfw_mode import Subservice as ModeSubservice
class ModeId(enum.IntEnum):
@ -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,10 +17,10 @@ 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.tc import DefaultPusQueueHelper
from tmtccmd.tmtc import DefaultPusQueueHelper
import eive_tmtc.gomspace.gomspace_common as gs
from eive_tmtc.config.object_ids import ACU_HANDLER_ID
from tmtccmd.util import ObjectIdU32
@ -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,11 +73,11 @@ 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)

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.tc import service_provider
from tmtccmd.tc.decorator import ServiceProviderParams
from tmtccmd.pus.s8_fsfw_funccmd import create_action_cmd
from tmtccmd.tc.pus_3_fsfw_hk import generate_one_hk_command, make_sid
from tmtccmd.tc.pus_200_fsfw_mode import pack_mode_data, Mode
from tmtccmd.tc.pus_200_fsfw_mode import Subservice as ModeSubservices
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.s200_fsfw_mode import Subservice as ModeSubservices
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(

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,17 +14,16 @@ 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.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_3_fsfw_hk import (
from tmtccmd.config import CmdTreeNode, OpCodeEntry
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.tc.s3_fsfw_hk import (
make_sid,
generate_one_diag_command,
generate_one_hk_command,
enable_periodic_hk_command_with_interval,
disable_periodic_hk_command,
)
from tmtccmd.pus.s8_fsfw_funccmd import create_action_cmd
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from tmtccmd.util import ObjectIdU32, ObjectIdBase
@ -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,13 +5,15 @@
@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,
SetId,
)
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tmtc import DefaultPusQueueHelper
from eive_tmtc.gomspace.gomspace_common import (
TableEntry,
Channel,
@ -27,20 +29,24 @@ from eive_tmtc.config.object_ids import P60_DOCK_HANDLER
from tmtccmd.util import ObjectIdU32
class P60OpCode:
STACK_3V3_ON = ["stack_3v3_on", "1"]
STACK_3V3_OFF = ["stack_3v3_off", "2"]
STACK_5V_ON = ["stack_5v_on", "3"]
STACK_5V_OFF = ["stack_5v_off", "4"]
TEST = ["test", "0"]
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"
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:
@ -99,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,
@ -114,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,
@ -123,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,
@ -132,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,
@ -239,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])

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,16 +24,14 @@ 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.tc import DefaultPusQueueHelper
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])
@ -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,9 +33,9 @@ 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.tc import DefaultPusQueueHelper
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)

View File

@ -16,28 +16,30 @@ 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.tc.pus_3_fsfw_hk import (
from tmtccmd.pus.tc.s3_fsfw_hk import (
create_request_one_diag_command,
make_sid,
)
from tmtccmd.config.tmtc import tmtc_definitions_provider
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tmtc import DefaultPusQueueHelper
class SetId(enum.IntEnum):
@ -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,
)
from tmtccmd.tc import service_provider
from tmtccmd.tc.queue import DefaultPusQueueHelper
from tmtccmd.tc.pus_200_fsfw_mode import Mode, pack_mode_command
from tmtccmd.tc.decorator import ServiceProviderParams
from tmtccmd.tc.pus_3_fsfw_hk import (
generate_one_hk_command,
make_sid,
enable_periodic_hk_command_with_interval,
disable_periodic_hk_command,
CmdTreeNode,
)
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.tc.pus_20_fsfw_param import create_load_param_cmd
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,
create_scalar_float_parameter,
)
from tmtccmd.pus.s200_fsfw_mode import Mode, pack_mode_command
from tmtccmd.pus.tc.s3_fsfw_hk import (
disable_periodic_hk_command,
enable_periodic_hk_command_with_interval,
generate_one_hk_command,
make_sid,
)
from tmtccmd.tmtc.queue import DefaultPusQueueHelper
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(

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.tc.pus_200_fsfw_mode import Subservice as ModeSubservices, Mode
from tmtccmd.tc import service_provider
from tmtccmd.tc.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 (
@ -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",
@ -146,7 +152,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 +243,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):

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.tc import service_provider, DefaultPusQueueHelper
from tmtccmd.pus.s8_fsfw_funccmd import create_action_cmd
from tmtccmd.tc.decorator import ServiceProviderParams
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
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.tc import service_provider
from tmtccmd.tmtc import DefaultPusQueueHelper
from eive_tmtc.config.object_ids import EIVE_SYSTEM_ID
from tmtccmd.tc.pus_200_fsfw_mode import (
from tmtccmd.pus.s200_fsfw_mode import (
create_mode_command,
create_announce_mode_recursive_command,
)
from tmtccmd.tc.pus_8_fsfw_funccmd import create_action_cmd
from tmtccmd.tc.decorator import ServiceProviderParams
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
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

@ -6,8 +6,8 @@ from tmtccmd.config.tmtc import (
TmtcDefinitionWrapper,
OpCodeEntry,
)
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_200_fsfw_mode import Mode
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s200_fsfw_mode import Mode
class InfoAssy:

View File

@ -3,12 +3,13 @@ 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,
)
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_3_fsfw_hk import (
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.tc.s3_fsfw_hk import (
make_sid,
generate_one_hk_command,
create_request_one_diag_command,
@ -17,7 +18,7 @@ from tmtccmd.tc.pus_3_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.tc 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_funccmd 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,12 +5,12 @@ 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.tc import DefaultPusQueueHelper
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.util import ObjectIdU32
from tmtccmd.tc.pus_200_fsfw_mode import Mode, pack_mode_data, Subservice
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
@ -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))

View File

@ -7,8 +7,8 @@ from tmtccmd.config.tmtc import (
TmtcDefinitionWrapper,
OpCodeEntry,
)
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_200_fsfw_mode import Mode, create_announce_mode_recursive_command
from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s200_fsfw_mode import Mode, create_announce_mode_recursive_command
class OpCode:
@ -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
@ -17,20 +19,20 @@ from tmtccmd.config.tmtc import (
OpCodeEntry,
)
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_200_fsfw_mode import Mode, pack_mode_data
from tmtccmd.tc.pus_3_fsfw_hk import create_request_one_hk_command, make_sid
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)

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.tc import service_provider
from tmtccmd.tc.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.tc import service_provider
from tmtccmd.tc.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

@ -3,46 +3,48 @@ import enum
import logging
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.tc import service_provider
from tmtccmd.tc.decorator import ServiceProviderParams
from dateutil.parser import parse
from spacepackets.ecss import PusService # noqa
from spacepackets.ecss.tc import PusTelecommand
from spacepackets.ecss.pus_15_tm_storage import Subservice
from tmtccmd.util import ObjectIdU32
class CustomSubservice(enum.IntEnum):
DELETE_BY_TIME_RANGE = 128
class OpCode:
RETRIEVAL_BY_TIME_RANGE = "retrieval_time_range"
DELETE_UP_TO = "delete_up_to"
DELETE_BY_TIME_RANGE = "delete_time_range"
class Info:
RETRIEVAL_BY_TIME_RANGE = "Dump Telemetry Packets by time range"
DELETE_UP_TO = "Delete Telemetry Packets up to time"
DELETE_BY_TIME_RANGE = "Delete Telemetry by time range"
_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:
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")
@ -56,9 +58,9 @@ 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_string = store_select_prompt()
obj_id, _ = store_select_prompt()
app_data = bytearray(obj_id.as_bytes)
start_of_dump_time = time_prompt("Determining retrieval start time")
start_stamp = int(math.floor(start_of_dump_time.timestamp()))
@ -78,13 +80,45 @@ def pack_tm_store_commands(p: ServiceProviderParams):
app_data=app_data,
)
)
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)
start_of_dump_time = time_prompt("Determining deletion start time")
start_stamp = int(math.floor(start_of_dump_time.timestamp()))
end_of_dump_time = time_prompt("Determining deletion end time")
end_stamp = int(math.floor(end_of_dump_time.timestamp()))
app_data.extend(struct.pack("!I", start_stamp))
app_data.extend(struct.pack("!I", end_stamp))
q.add_log_cmd(Info.DELETE_BY_TIME_RANGE)
q.add_log_cmd(f"Selected Store: {obj_id}")
q.add_log_cmd(
f"Deletion from time {start_of_dump_time} up to time {end_of_dump_time}"
)
q.add_pus_tc(
PusTelecommand(
service=15,
subservice=CustomSubservice.DELETE_BY_TIME_RANGE,
app_data=app_data,
)
)
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
@tmtc_definitions_provider
def add_persistent_tm_store_cmd_defs(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(keys=OpCode.DELETE_UP_TO, info=Info.DELETE_UP_TO)
oce.add(keys=OpCode.RETRIEVAL_BY_TIME_RANGE, info=Info.RETRIEVAL_BY_TIME_RANGE)
oce.add(keys=OpCode.DELETE_BY_TIME_RANGE, info=Info.DELETE_BY_TIME_RANGE)
defs.add_service(
CustomServiceList.TM_STORE, "Persistent TM Store", op_code_entry=oce
)
@ -130,6 +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()
raise ValueError("can not determine datetime")
def time_prompt_fully_manually() -> datetime.datetime:
@ -160,7 +195,7 @@ def time_prompt_offset_from_now() -> datetime.datetime:
return time_now_with_offset
def store_select_prompt() -> (ObjectIdU32, str):
def store_select_prompt() -> Tuple[ObjectIdU32, str]:
obj_id_dict = get_object_ids()
print("Available TM stores:")
for k, v in STORE_DICT.items():
@ -176,5 +211,6 @@ def store_select_prompt() -> (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,11 +1,12 @@
import enum
from tmtccmd.config.tmtc import (
CmdTreeNode,
OpCodeEntry,
TmtcDefinitionWrapper,
tmtc_definitions_provider,
)
from tmtccmd.pus.s8_fsfw_funccmd import create_action_cmd
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.pus.s8_fsfw_action import create_action_cmd
from tmtccmd.tmtc import DefaultPusQueueHelper
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.config.object_ids import XIPHOS_WDT_ID
@ -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,7 +6,7 @@ build-backend = "setuptools.build_meta"
name = "eive-tmtc"
description = "TMTC Commander EIVE"
readme = "README.md"
version = "5.10.0"
version = "6.2.0"
requires-python = ">=3.10"
license = {text = "Apache-2.0"}
authors = [
@ -29,9 +29,10 @@ classifiers = [
"Topic :: Scientific/Engineering"
]
dependencies = [
"tmtccmd ~= 6.0",
"tmtccmd ~= 8.0.0rc1",
"cfdp-py~=0.1.0",
# "tmtccmd @ git+https://github.com/robamu-org/tmtccmd@main",
"python-dateutil ~= 2.8",
# "tmtccmd @ git+https://github.com/robamu-org/tmtccmd@main"
]
[project.urls]

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}")

119
tmtcc.py
View File

@ -2,60 +2,61 @@
import logging
import sys
import time
from importlib.metadata import version
from pathlib import Path
from typing import Tuple
import tmtccmd
from eive_tmtc.cfdp.fault_handler import EiveCfdpFaultHandler
from eive_tmtc.cfdp.tm import CfdpInCcsdsWrapper
from eive_tmtc.cfdp.user import EiveCfdpUser
from spacepackets.ecss import PusVerificator
from spacepackets.version import get_version as get_sp_version
from cfdppy.handler import RemoteEntityCfgTable
from cfdppy.mib import (
IndicationCfg,
LocalEntityCfg,
RemoteEntityCfg,
)
from spacepackets.cfdp import (
ChecksumType,
TransmissionMode,
)
from eive_tmtc.pus_tc.tc_handler import TcHandler
from eive_tmtc.pus_tm.hk_handler import HkFilter
from tmtccmd.logging import add_colorlog_console_logger
from tmtccmd.cfdp.handler import CfdpInCcsdsHandler
from tmtccmd.cfdp.mib import (
LocalEntityCfg,
IndicationCfg,
RemoteEntityCfg,
)
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.util import FileSeqCountProvider, PusFileSeqCountProvider
from tmtccmd.config import (
SetupWrapper,
default_json_path,
params_to_procedure_conversion,
)
from tmtccmd.config.args import (
PreArgsParsingWrapper,
ProcedureParamsWrapper,
SetupParams,
perform_tree_printout,
)
from tmtccmd.core import BackendRequest
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from tmtccmd.logging import add_colorlog_console_logger
from tmtccmd.logging.pus import (
RawTmtcTimedLogWrapper,
RegularTmtcLogWrapper,
TimedLogWhen,
)
from tmtccmd.pus import VerificationWrapper
from tmtccmd.tm import SpecificApidHandlerBase, GenericApidHandlerBase, CcsdsTmHandler
from tmtccmd.core import BackendRequest
from tmtccmd.config import (
default_json_path,
SetupWrapper,
params_to_procedure_conversion,
)
from tmtccmd.config.args import (
SetupParams,
PreArgsParsingWrapper,
ProcedureParamsWrapper,
)
from tmtccmd.tmtc import CcsdsTmHandler
from eive_tmtc import APP_LOGGER
from importlib.metadata import version
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 (
PUS_APID,
CFDP_APID,
CFDP_LOCAL_ENTITY_ID,
CFDP_REMOTE_ENTITY_ID,
PUS_APID,
)
from eive_tmtc.config.hook import EiveHookObject
from eive_tmtc.pus_tm.pus_demux import pus_factory_hook
from eive_tmtc.pus_tc.tc_handler import TcHandler
from eive_tmtc.pus_tm.pus_handler import PusHandler, UnknownApidHandler
_LOGGER = APP_LOGGER
_LOG_LEVEL = logging.INFO
@ -65,48 +66,12 @@ 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}")
def setup_params() -> (SetupWrapper, int):
def setup_params() -> Tuple[SetupWrapper, int]:
hook_obj = EiveHookObject(default_json_path())
params = SetupParams()
parser_wrapper = PreArgsParsingWrapper()
@ -132,6 +97,9 @@ def setup_params() -> (SetupWrapper, int):
hk_level = int(post_arg_parsing_wrapper.args_raw.hk)
else:
hk_level = 0
if params.app_params.print_tree:
perform_tree_printout(params.app_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.")
@ -152,7 +120,8 @@ def setup_cfdp_handler() -> CfdpInCcsdsWrapper:
closure_requested=False,
entity_id=CFDP_LOCAL_ENTITY_ID,
max_file_segment_len=990,
check_limit=None,
max_packet_len=1024,
check_limit=5,
crc_on_transmission=False,
crc_type=ChecksumType.CRC_32,
default_transmission_mode=TransmissionMode.UNACKNOWLEDGED,
@ -161,11 +130,13 @@ def setup_cfdp_handler() -> CfdpInCcsdsWrapper:
closure_requested=False,
entity_id=CFDP_REMOTE_ENTITY_ID,
max_file_segment_len=990,
check_limit=None,
max_packet_len=1024,
check_limit=5,
crc_on_transmission=False,
crc_type=ChecksumType.CRC_32,
default_transmission_mode=TransmissionMode.UNACKNOWLEDGED,
)
check_timer_provider = EiveCheckTimerProvider()
cfdp_seq_count_provider = FileSeqCountProvider(
max_bit_width=16, file_name=Path("seqcnt_cfdp_transaction.txt")
)
@ -175,7 +146,8 @@ def setup_cfdp_handler() -> CfdpInCcsdsWrapper:
cfdp_user = EiveCfdpUser()
cfdp_in_ccsds_handler = CfdpInCcsdsHandler(
cfg=cfdp_cfg,
remote_cfgs=[remote_cfg, self_as_remote],
check_timer_provider=check_timer_provider,
remote_cfg_table=RemoteEntityCfgTable([remote_cfg, self_as_remote]),
ccsds_apid=CFDP_APID,
ccsds_seq_cnt_provider=cfdp_ccsds_seq_count_provider,
cfdp_seq_cnt_provider=cfdp_seq_count_provider,
@ -190,7 +162,7 @@ def setup_tmtc_handlers(
raw_logger: RawTmtcTimedLogWrapper,
gui: bool,
hk_level: int,
) -> (CcsdsTmHandler, TcHandler):
) -> Tuple[CcsdsTmHandler, TcHandler]:
cfdp_in_ccsds_wrapper = setup_cfdp_handler()
verification_wrapper = VerificationWrapper(
verificator, _LOGGER, printer.file_logger
@ -200,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,