Compare commits

...

101 Commits

Author SHA1 Message Date
b50c75c13c Merge pull request 'PLOC SUPV HK parsing' (#231) from parse-ploc-supv-hk into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #231
2023-08-15 14:39:09 +02:00
36799ef51d v5.4.3
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-15 14:38:28 +02:00
772ef5b323 changelog
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-15 14:35:45 +02:00
2f8bed4581 works
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-15 14:31:49 +02:00
72def77d40 parse ploc supv HK
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-15 14:15:06 +02:00
bc1a1774a6 Merge pull request 'added none entry for new enum' (#230) from submode-enum-none-entry into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #230
2023-08-15 13:58:07 +02:00
4b08f5dd5b prep v5.4.2
Some checks are pending
EIVE/-/pipeline/pr-main Build queued...
2023-08-15 13:57:43 +02:00
b0562ea9c7 added none entry for new enum
Some checks are pending
EIVE/-/pipeline/head Build queued...
2023-08-15 13:54:18 +02:00
f76cd94535 prep v5.4.1
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-15 13:28:54 +02:00
8a1e5b7b99 changelog
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-15 13:21:10 +02:00
0e208629b0 subsystem enum is int enum now 2023-08-15 13:20:43 +02:00
403657110b prep v5.4.0
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-15 13:13:06 +02:00
23f21b40eb Merge pull request 'PL PCDU enum' (#229) from new-pl-pcdu-enum into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #229
2023-08-15 13:07:40 +02:00
a6b3ccb4cc more better names
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-15 11:51:41 +02:00
d7b494a950 better name 2023-08-15 11:51:12 +02:00
73bc043538 move enum
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-15 11:50:39 +02:00
02e7e809de PL PCDU enum
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-15 11:47:07 +02:00
d6f6aff139 Merge pull request 'SGP4 Propagator Prep' (#227) from spg4-propagator into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #227
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-08-15 10:46:27 +02:00
d39a49bd4c Merge branch 'main' into spg4-propagator
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-15 09:31:15 +02:00
f42318bc57 deprecated import
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-14 15:58:44 +02:00
fd3a799019 Merge pull request 'new pdec event' (#228) from pdec-config-readback into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #228
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-08-14 15:47:07 +02:00
1664e6adb5 Merge branch 'main' into pdec-config-readback
Some checks are pending
EIVE/-/pipeline/pr-main Build queued...
2023-08-14 15:46:57 +02:00
8042f3607d new pdec event
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-14 15:09:34 +02:00
59278447fd Merge branch 'main' into spg4-propagator
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-14 14:13:03 +02:00
b58977fd65 naming
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-14 12:50:50 +02:00
beae6b3f05 Merge pull request 'More GPS TM' (#226) from more-gps-tm into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #226
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-08-14 10:38:16 +02:00
12c60ac310 goddamnit
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-09 14:58:28 +02:00
1acbb8bb43 less copy-pasta helps sometimes
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-08 13:39:36 +02:00
051e9e6ffb lets be clean about this
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-08 10:01:50 +02:00
6d88746ec3 fix
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-08 09:40:37 +02:00
5571a6852e init 2023-08-07 14:21:58 +02:00
1ddb93410e wörks
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-04 16:24:16 +02:00
b0b186ac1f we need this sed_id thingy
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-04 15:39:40 +02:00
f95331742b fix
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-04 15:38:32 +02:00
c91ad9e08b bump
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-04 15:01:34 +02:00
fcabaa5b09 rework gps data handling
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-04 14:51:55 +02:00
bf9ab7edf7 this was the fun part
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-04 14:35:09 +02:00
4b054b7628 Merge pull request 'new scex event' (#225) from scex-event into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #225
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-08-02 09:46:09 +02:00
9001a28545 new scex event
Some checks are pending
EIVE/-/pipeline/head Build queued...
2023-08-02 09:41:19 +02:00
6b2fbc6917 Merge pull request 'SCEX code improvements' (#224) from scex-code-improvements into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #224
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-07-27 11:21:38 +02:00
ab770a0057 Merge remote-tracking branch 'origin/main' into scex-code-improvements
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-27 09:59:49 +02:00
0cbf28f25c scex code improvenemtns
Some checks are pending
EIVE/-/pipeline/head Build queued...
2023-07-27 09:59:34 +02:00
cbcc06ede7 Merge pull request 'ACS downwards compatibility' (#223) from acs-downwards-compat into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #223
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-07-26 13:17:35 +02:00
a55aa4a667 added comments
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-26 13:15:08 +02:00
d2324dace9 changelog and init
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-26 13:13:41 +02:00
1e4e524f95 update CTRL STATE enum and make it global 2023-07-26 13:12:12 +02:00
39d6ec73c2 Merge pull request 'prep v5.3.0' (#222) from prep-v5.3.0 into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #222
2023-07-26 12:56:18 +02:00
74cfa2949a flake8 and black
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-07-26 12:54:13 +02:00
ffdb4451f6 prep v5.3.0
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-26 12:51:56 +02:00
15716c988b Merge pull request 'new safe mode' (#221) from new-safe into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #221
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-07-26 09:51:26 +02:00
f5ec50b674 guess i added PTG strats in june ...
All checks were successful
EIVE/-/pipeline/head This commit looks good
EIVE/-/pipeline/pr-main This commit looks good
2023-07-24 09:47:52 +02:00
02b70ee203 Merge branch 'main' into new-safe
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-24 09:25:22 +02:00
95b6954175 Merge pull request 'new event' (#220) from active-sd-info-event into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #220
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-07-21 11:49:59 +02:00
a82cbff5a8 works well
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-07-21 11:47:37 +02:00
87b766dfb8 active SD info
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-07-21 11:36:01 +02:00
09b7a01ff6 init
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-21 11:20:20 +02:00
fd6b76bfdd update events.csv
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-07-21 11:04:32 +02:00
40c086086b new event
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-21 10:26:37 +02:00
83e8fe0587 Merge pull request 'TMTC improvements' (#219) from tmtc-improvements into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #219
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-07-19 14:46:51 +02:00
6cffae4397 the name is okay..
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-19 14:42:02 +02:00
d73ef3a314 better name for HK module
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-19 14:41:19 +02:00
0b8bd61e80 Merge pull request 'Update STR Commands' (#218) from update-str-cmds into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #218
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-07-14 12:24:50 +02:00
380a02ee94 add new STR COM error event
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-07-13 21:09:14 +02:00
c6e2e2de49 Merge branch 'main' into update-str-cmds
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-07-13 18:28:15 +02:00
6479aeda63 Merge pull request 'STR: time conversion bugfix' (#217) from str-time-conversion-fix into main
Some checks reported errors
EIVE/-/pipeline/head Something is wrong with the build of this commit
Reviewed-on: #217
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-07-13 14:59:58 +02:00
26cf112121 Merge branch 'str-time-conversion-fix' into update-str-cmds
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-13 14:59:03 +02:00
62bd535622 time conversion bugfix
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-13 14:49:03 +02:00
eea7683581 Merge pull request 'prep v5.2.0' (#216) from prep_v5.2.0 into main
Some checks reported errors
EIVE/-/pipeline/head Something is wrong with the build of this commit
Reviewed-on: #216
2023-07-13 11:55:26 +02:00
df6aa80169 changelog
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-13 11:47:47 +02:00
2fd1a46e66 bump tmtccmd to v5.0.0 2023-07-13 11:46:38 +02:00
2153aa2842 prep v5.2.0
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-13 11:30:43 +02:00
1f2f2aac13 update STR commands
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-13 10:53:42 +02:00
9be81f1725 Merge pull request 'max burn time event' (#213) from tcs-heater-upper-limit into main
Some checks failed
EIVE/-/pipeline/head There was a failure building this commit
Reviewed-on: #213
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-07-11 10:15:55 +02:00
601adfc9c2 Merge branch 'main' into tcs-heater-upper-limit
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-07-11 09:45:37 +02:00
ac84ac2c3e Merge pull request 'TCS CTRL Info Set' (#215) from tcs-ctrl-info-set into main
Some checks failed
EIVE/-/pipeline/head There was a failure building this commit
Reviewed-on: #215
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-07-11 09:31:49 +02:00
7ed18bd570 Merge pull request 'HK level is a CLI argument now' (#214) from hk-level-as-cli-arg into main
Some checks failed
EIVE/-/pipeline/head There was a failure building this commit
Reviewed-on: #214
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-07-11 09:21:39 +02:00
e27ad147d4 done
All checks were successful
EIVE/-/pipeline/head This commit looks good
EIVE/-/pipeline/pr-main This commit looks good
2023-07-10 18:29:24 +02:00
ba47757b50 added way to request new HK set
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-10 16:29:54 +02:00
7e9c626ec8 add command demultiplexing for tcs ctrl 2023-07-10 16:25:44 +02:00
8d6dd97d85 Merge branch 'hk-level-as-cli-arg' into tcs-ctrl-info-set
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-10 16:11:18 +02:00
2fae5613ce fix
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-07-10 16:09:42 +02:00
fdb14cbdc5 HK level is a CLI argument now
Some checks failed
EIVE/-/pipeline/head There was a failure building this commit
2023-07-10 16:07:01 +02:00
0cef3fa924 and now it works
Some checks failed
EIVE/-/pipeline/head There was a failure building this commit
2023-07-10 16:04:36 +02:00
37a35c4446 cli argument
Some checks failed
EIVE/-/pipeline/head There was a failure building this commit
2023-07-10 16:03:08 +02:00
15d25b4c5b max burn time event
All checks were successful
EIVE/-/pipeline/head This commit looks good
EIVE/-/pipeline/pr-main This commit looks good
2023-07-07 12:06:27 +02:00
069f84d220 Merge pull request 'Add TCS CTRL heater events' (#212) from add-tcs-ctrl-heater-events into main
Some checks failed
EIVE/-/pipeline/head There was a failure building this commit
Reviewed-on: #212
2023-07-07 10:53:32 +02:00
627a16d51a Merge branch 'main' into add-tcs-ctrl-heater-events
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-07-06 19:03:27 +02:00
fcfae1f67f Merge pull request 'add cmd to set max reboot watchdog count' (#210) from rwd-improvements into main
Some checks failed
EIVE/-/pipeline/head There was a failure building this commit
Reviewed-on: #210
2023-07-06 19:03:05 +02:00
01ebd356ba Merge branch 'main' into rwd-improvements 2023-07-06 19:02:58 +02:00
5785bbd0cc changelog
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-06 19:01:15 +02:00
d3e6101447 add new events 2023-07-06 19:00:39 +02:00
6d5bde40db add back TMP1075 health commands
Some checks failed
EIVE/-/pipeline/head There was a failure building this commit
2023-07-06 16:00:10 +02:00
c48f04eed5 add TCS submode
Some checks failed
EIVE/-/pipeline/head There was a failure building this commit
2023-07-06 14:15:28 +02:00
18304c31fa prep v5.1.0
Some checks failed
EIVE/-/pipeline/head There was a failure building this commit
2023-06-28 13:39:20 +02:00
8caa408cbd Merge pull request 'Internal error reporter' (#211) from internal-error-reporter into main
Some checks failed
EIVE/-/pipeline/head There was a failure building this commit
Reviewed-on: #211
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-06-28 13:16:37 +02:00
4a983958bf changelog
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-06-28 13:15:01 +02:00
03ec5bdc39 changelog
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-06-28 13:14:07 +02:00
9c5d6a15db APP logger should be root logger
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-06-28 13:10:10 +02:00
ddc80071e0 changelogge
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-06-28 10:43:11 +02:00
deb0275bb5 add cmd to set max reboot watchdog count
All checks were successful
EIVE/-/pipeline/head This commit looks good
EIVE/-/pipeline/pr-main This commit looks good
2023-06-24 18:36:33 +02:00
ec0ebc3653 handle FW info event
Some checks failed
EIVE/-/pipeline/head There was a failure building this commit
2023-06-23 02:05:04 +02:00
31 changed files with 844 additions and 278 deletions

View File

@ -10,7 +10,76 @@ list yields a list of all related PRs for each release.
# [unreleased]
# [v5.0.0]
# [v5.4.3] 2023-08-15
## Added
- PLOC SUPV HK parsing.
# [v5.4.2] 2023-08-15
## Added
- New NONE entry for PL PCDU submode enum.
# [v5.4.1] 2023-08-15
## Added
- New event TLE_TOO_OLD
## Changed
- PL Subsystem mode ID is int enum now.
# [v5.4.0] 2023-08-15
## Added
- New enumeration for PL PCDU commanding.
- Some new events
# [v5.3.1] 2023-07-26
## Changed
- Adaptions for ACS CTRL strategy enum to make it compatible to software. Also make it re-usable
by putting it in global scope.
# [v5.3.0] 2023-07-26
## Added
- Dataset handling for new ACS fused rot rate dataset.
# [v5.2.0] 2023-07-13
- `tmtccmd` v5.0.0
## Added
- New TCS controller events
## Changed
- HK level can be specified as CLI argument now.
# [v5.1.0] 2023-06-28
## Added
- Internal error reporter dataset handling.
## Fixed
- `APP_LOGGER` is the root logger now.
## Changed
- HK is only displayed in brief format per default now. This will soon be adaptable by CLI
argument.
# [v5.0.0] 2023-06-22
## Changed

View File

@ -1,14 +1,14 @@
__version__ = "5.0.0"
__version__ = "5.4.3"
import logging
from pathlib import Path
SW_NAME = "eive-tmtc"
VERSION_MAJOR = 5
VERSION_MINOR = 0
VERSION_REVISION = 0
VERSION_MINOR = 4
VERSION_REVISION = 3
EIVE_TMTC_ROOT = Path(__file__).parent
PACKAGE_ROOT = EIVE_TMTC_ROOT.parent
APP_LOGGER = logging.getLogger(__name__)
APP_LOGGER = logging.getLogger()

View File

@ -65,7 +65,8 @@ class CustomServiceList(str, enum.Enum):
PL_SS = "pl_subsystem"
ACS_BRD_ASS = "acs_brd_ass"
SUS_BRD_ASS = "sus_brd_ass"
TCS = "tcs"
TCS_SS = "tcs_subsystem"
TCS_CTRL = "tcs_ctrl"
TCS_ASS = "tcs_ass"
TIME = "time"
PROCEDURE = "proc"

View File

@ -94,6 +94,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
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
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
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
@ -133,6 +134,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11802;0x2e1a;RESET_OCCURED;LOW;No description;mission/acs/rwHelpers.h
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
@ -160,6 +162,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
12412;0x307c;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/pdec.h
12413;0x307d;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/pdec.h
12414;0x307e;PDEC_INIT_FAILED;HIGH;PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues.;linux/ipcore/pdec.h
12415;0x307f;PDEC_CONFIG_CORRUPTED;HIGH;The PDEC configuration area has been corrupted P1: The first configuration word P2: The second configuration word;linux/ipcore/pdec.h
12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h
12501;0x30d5;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;linux/acs/StrComHandler.h
12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h
@ -254,6 +257,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
13800;0x35e8;MISSING_PACKET;LOW;No description;mission/payload/scexHelpers.h
13801;0x35e9;EXPERIMENT_TIMEDOUT;LOW;No description;mission/payload/scexHelpers.h
13802;0x35ea;MULTI_PACKET_COMMAND_DONE;INFO;No description;mission/payload/scexHelpers.h
13803;0x35eb;FS_UNUSABLE;LOW;No description;mission/payload/scexHelpers.h
13901;0x364d;SET_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
13902;0x364e;GET_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
13903;0x364f;INSERT_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
@ -272,6 +276,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
14011;0x36bb;I2C_REBOOT;HIGH;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h
14012;0x36bc;PDEC_REBOOT;HIGH;PDEC recovery through reset was not possible, performing full reboot.;mission/sysDefs.h
14013;0x36bd;FIRMWARE_INFO;INFO;Version information of the firmware (not OBSW). P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;mission/sysDefs.h
14014;0x36be;ACTIVE_SD_INFO;INFO;Active SD card info. SD States: 0: OFF, 1: ON, 2: MOUNTED. P1: Active SD Card Index, 0 if none is active P2: First two bytes: SD state of SD card 0, last two bytes SD state of SD card 1;mission/sysDefs.h
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
@ -280,6 +285,9 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
14106;0x371a;PCDU_SYSTEM_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
14107;0x371b;HEATER_NOT_OFF_FOR_OFF_MODE;MEDIUM;No description;mission/controller/tcsDefs.h
14108;0x371c;MGT_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
14109;0x371d;TCS_SWITCHING_HEATER_ON;INFO;P1: Module index. P2: Heater index;mission/controller/tcsDefs.h
14110;0x371e;TCS_SWITCHING_HEATER_OFF;INFO;P1: Module index. P2: Heater index;mission/controller/tcsDefs.h
14111;0x371f;TCS_HEATER_MAX_BURN_TIME_REACHED;MEDIUM;P1: Heater index. P2: Maximum burn time for heater.;mission/controller/tcsDefs.h
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/com/ComSubsystem.h
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/com/ComSubsystem.h
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
94 11205 0x2bc5 MEKF_AUTOMATIC_RESET INFO MEKF performed an automatic reset after detection of nonfinite values. mission/acs/defs.h
95 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
96 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
97 11208 0x2bc8 TLE_TOO_OLD INFO The TLE for the SGP4 Propagator has become too old. mission/acs/defs.h
98 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
99 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
100 11302 0x2c26 SWITCHING_Q7S_DENIED MEDIUM No description mission/power/defs.h
134 11802 0x2e1a RESET_OCCURED LOW No description mission/acs/rwHelpers.h
135 11901 0x2e7d BOOTING_FIRMWARE_FAILED_EVENT LOW Failed to boot firmware mission/acs/str/StarTrackerHandler.h
136 11902 0x2e7e BOOTING_BOOTLOADER_FAILED_EVENT LOW Failed to boot star tracker into bootloader mode mission/acs/str/StarTrackerHandler.h
137 11903 0x2e7f COM_ERROR_REPLY_RECEIVED LOW Received COM error. P1: Communication Error ID (datasheet p32) mission/acs/str/StarTrackerHandler.h
138 12001 0x2ee1 SUPV_MEMORY_READ_RPT_CRC_FAILURE LOW PLOC supervisor crc failure in telemetry packet linux/payload/PlocSupervisorHandler.h
139 12002 0x2ee2 SUPV_UNKNOWN_TM LOW Unhandled event. P1: APID, P2: Service ID linux/payload/PlocSupervisorHandler.h
140 12003 0x2ee3 SUPV_UNINIMPLEMENTED_TM LOW No description linux/payload/PlocSupervisorHandler.h
162 12412 0x307c PDEC_RESET_FAILED HIGH Failed to pull PDEC reset to low linux/ipcore/pdec.h
163 12413 0x307d OPEN_IRQ_FILE_FAILED HIGH Failed to open the IRQ uio file linux/ipcore/pdec.h
164 12414 0x307e PDEC_INIT_FAILED HIGH PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues. linux/ipcore/pdec.h
165 12415 0x307f PDEC_CONFIG_CORRUPTED HIGH The PDEC configuration area has been corrupted P1: The first configuration word P2: The second configuration word linux/ipcore/pdec.h
166 12500 0x30d4 IMAGE_UPLOAD_FAILED LOW Image upload failed linux/acs/StrComHandler.h
167 12501 0x30d5 IMAGE_DOWNLOAD_FAILED LOW Image download failed linux/acs/StrComHandler.h
168 12502 0x30d6 IMAGE_UPLOAD_SUCCESSFUL LOW Uploading image to star tracker was successfulop linux/acs/StrComHandler.h
257 13800 0x35e8 MISSING_PACKET LOW No description mission/payload/scexHelpers.h
258 13801 0x35e9 EXPERIMENT_TIMEDOUT LOW No description mission/payload/scexHelpers.h
259 13802 0x35ea MULTI_PACKET_COMMAND_DONE INFO No description mission/payload/scexHelpers.h
260 13803 0x35eb FS_UNUSABLE LOW No description mission/payload/scexHelpers.h
261 13901 0x364d SET_CONFIGFILEVALUE_FAILED MEDIUM No description mission/utility/GlobalConfigHandler.h
262 13902 0x364e GET_CONFIGFILEVALUE_FAILED MEDIUM No description mission/utility/GlobalConfigHandler.h
263 13903 0x364f INSERT_CONFIGFILEVALUE_FAILED MEDIUM No description mission/utility/GlobalConfigHandler.h
276 14011 0x36bb I2C_REBOOT HIGH I2C is unavailable. Recovery did not work, performing full reboot. mission/sysDefs.h
277 14012 0x36bc PDEC_REBOOT HIGH PDEC recovery through reset was not possible, performing full reboot. mission/sysDefs.h
278 14013 0x36bd FIRMWARE_INFO INFO Version information of the firmware (not OBSW). P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set. mission/sysDefs.h
279 14014 0x36be ACTIVE_SD_INFO INFO Active SD card info. SD States: 0: OFF, 1: ON, 2: MOUNTED. P1: Active SD Card Index, 0 if none is active P2: First two bytes: SD state of SD card 0, last two bytes SD state of SD card 1 mission/sysDefs.h
280 14100 0x3714 NO_VALID_SENSOR_TEMPERATURE MEDIUM No description mission/controller/tcsDefs.h
281 14101 0x3715 NO_HEALTHY_HEATER_AVAILABLE MEDIUM No description mission/controller/tcsDefs.h
282 14102 0x3716 SYRLINKS_OVERHEATING HIGH No description mission/controller/tcsDefs.h
285 14106 0x371a PCDU_SYSTEM_OVERHEATING HIGH No description mission/controller/tcsDefs.h
286 14107 0x371b HEATER_NOT_OFF_FOR_OFF_MODE MEDIUM No description mission/controller/tcsDefs.h
287 14108 0x371c MGT_OVERHEATING HIGH No description mission/controller/tcsDefs.h
288 14109 0x371d TCS_SWITCHING_HEATER_ON INFO P1: Module index. P2: Heater index mission/controller/tcsDefs.h
289 14110 0x371e TCS_SWITCHING_HEATER_OFF INFO P1: Module index. P2: Heater index mission/controller/tcsDefs.h
290 14111 0x371f TCS_HEATER_MAX_BURN_TIME_REACHED MEDIUM P1: Heater index. P2: Maximum burn time for heater. mission/controller/tcsDefs.h
291 14201 0x3779 TX_TIMER_EXPIRED INFO The transmit timer to protect the Syrlinks expired P1: The current timer value mission/system/com/ComSubsystem.h
292 14202 0x377a BIT_LOCK_TX_ON INFO Transmitter will be turned on due to detection of bitlock mission/system/com/ComSubsystem.h
293 14300 0x37dc POSSIBLE_FILE_CORRUPTION LOW P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp. mission/persistentTmStoreDefs.h

View File

@ -18,6 +18,7 @@ __OBJECT_ID_DICT = None
# Core Object IDs
SOLAR_ARRAY_DEPLOYMENT_ID = bytes([0x44, 0x41, 0x00, 0xA2])
INTERNAL_ERROR_REPORTER_ID = bytes([0x53, 0x04, 0x00, 0x00])
# Power Object IDs
PCDU_HANDLER_ID = bytes([0x44, 0x20, 0x00, 0xA1])

View File

@ -6,6 +6,7 @@ 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
@ -99,8 +100,10 @@ def handle_default_procedure( # noqa C901: Complexity okay here.
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.value:
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),

View File

@ -765,7 +765,6 @@ def gen_disable_listen_to_hk_for_x_seconds(
def activate_mgts_alternately(
q: DefaultPusQueueHelper,
):
q.add_pus_tc(
pack_dipole_command(
object_id=oids.IMTQ_HANDLER_ID,

View File

@ -7,6 +7,7 @@ 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
@ -95,7 +96,7 @@ def handle_event_packet( # noqa C901: Complexity okay here
if info.name == "REBOOT_COUNTER":
boot_count = (event_def.param1 << 32) | event_def.param2
pw.dlog(f"Total boot count: {boot_count}")
if info.name == "VERSION_INFO":
if info.name == "VERSION_INFO" or info.name == "FIRMWARE_INFO":
specific_handler = True
ver_major = (event_def.param1 >> 24) & 0xFF
ver_minor = (event_def.param1 >> 16) & 0xFF
@ -105,8 +106,11 @@ def handle_event_packet( # noqa C901: Complexity okay here
if has_git_sha:
p2_as_bytes = event_def.param2.to_bytes(4, sys.byteorder)
git_sha = p2_as_bytes.decode("ascii")
version_string = f"v{ver_major}.{ver_minor}.{ver_rev}"
pw.dlog(f"Version {version_string}")
if info.name == "VERSION_INFO":
name = "OBSW version: "
else:
name = "Firmware version: "
pw.dlog(f"{name} v{ver_major}.{ver_minor}.{ver_rev}")
if has_git_sha:
pw.dlog(f"Git SHA first four letters: {git_sha}")
if info.name == "CLOCK_SET":
@ -123,6 +127,21 @@ def handle_event_packet( # noqa C901: Complexity okay here
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 == "ACTIVE_SD_INFO":
sd_0_state = (event_def.param2 >> 16) & 0xFFFF
sd_1_state = event_def.param2 & 0xFFFF
active_sd = event_def.param1
try:
active_sd = SdCardSelect(event_def.param1)
sd_0_state = SdState((event_def.param2 >> 16) & 0xFFFF)
sd_1_state = SdState(event_def.param2 & 0xFFFF)
except IndexError:
_LOGGER.error(f"Received invalid event fields for event {event_def}")
finally:
pw.dlog(
f"Active SD card {active_sd!r} | SD 0 State {sd_0_state!r} | SD 1 "
f"State {sd_1_state!r}"
)
if info.name == "HEALTH_INFO":
specific_handler = True
health = FsfwHealth(event_def.param1)

View File

@ -1,8 +1,8 @@
"""HK Handling for EIVE OBSW"""
import logging
# from pus_tm.tcp_server_objects import TCP_SEVER_SENSOR_TEMPERATURES
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
from eive_tmtc.tmtc.payload.ploc_mpsoc import handle_ploc_mpsoc_hk_data
from eive_tmtc.tmtc.tcs.rtd import RTD_NAMES, handle_rtd_hk
from eive_tmtc.tmtc.acs.star_tracker import handle_str_hk_data
@ -44,14 +44,10 @@ _LOGGER = logging.getLogger(__name__)
FORWARD_SENSOR_TEMPS = False
# TODO: Transform this into a CLI argument
HK_OUTPUT_LEVEL = 1
def handle_hk_packet(
raw_tm: bytes,
obj_id_dict: ObjectIdDictT,
printer: FsfwTmTcPrinter,
raw_tm: bytes, obj_id_dict: ObjectIdDictT, printer: FsfwTmTcPrinter, hk_level: int
):
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)
@ -59,20 +55,18 @@ def handle_hk_packet(
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 FORWARD_SENSOR_TEMPS:
# TODO: Maybe use singleton?
# TCP_SEVER_SENSOR_TEMPERATURES.report_raw_hk_data(
# object_id=named_obj_id, set_id=tm_packet.set_id, hk_data=hk_data
# )
pass
printer.generic_hk_tm_print(
content_type=HkContentType.HK,
object_id=named_obj_id,
set_id=tm_packet.set_id,
hk_data=hk_data,
)
try:
if HK_OUTPUT_LEVEL > 0:
if hk_level == 1:
pass
elif hk_level > 1:
handle_regular_hk_print(
printer=printer,
object_id=named_obj_id,
@ -107,7 +101,9 @@ def handle_regular_hk_print( # noqa C901: Complexity okay here
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, hk_data=hk_data)
return handle_gps_data(
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)
elif objb == obj_ids.BPX_HANDLER_ID:
@ -122,6 +118,8 @@ def handle_regular_hk_print( # noqa C901: Complexity okay here
return handle_ploc_mpsoc_hk_data(pw=pw, hk_data=hk_data, set_id=set_id)
elif objb == obj_ids.ACU_HANDLER_ID:
return handle_acu_hk_data(pw=pw, hk_data=hk_data, set_id=set_id)
elif objb == obj_ids.INTERNAL_ERROR_REPORTER_ID:
return handle_ier_hk_data(pw=pw, hk_data=hk_data, set_id=set_id)
elif objb == obj_ids.RAD_SENSOR_ID:
return handle_rad_sensor_data(pw=pw, hk_data=hk_data, set_id=set_id)
elif objb in [obj_ids.RW1_ID, obj_ids.RW2_ID, obj_ids.RW3_ID, obj_ids.RW4_ID]:

View File

@ -18,7 +18,7 @@ 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_handling import handle_hk_packet
from .hk_handler import handle_hk_packet
from .action_reply_handler import handle_action_reply
_LOGGER = logging.getLogger(__name__)
@ -29,12 +29,14 @@ def pus_factory_hook( # noqa C901 : Complexity okay here
verif_wrapper: VerificationWrapper,
printer: FsfwTmTcPrinter,
raw_logger: RawTmtcTimedLogWrapper,
hk_level: int,
):
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")
@ -47,7 +49,9 @@ def pus_factory_hook( # noqa C901 : Complexity okay here
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)
handle_hk_packet(
printer=printer, raw_tm=packet, obj_id_dict=obj_id_dict, hk_level=hk_level
)
elif service == 5:
handle_event_packet(raw_tm=packet, pw=pw)
elif service == 8:

View File

@ -12,7 +12,6 @@ _LOGGER = logging.getLogger(__name__)
class TmTcpServer:
def __init__(self, ip_address: str, port: int):
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.bind((ip_address, port))
@ -46,7 +45,6 @@ class TmTcpServer:
self.client_connection.setblocking(False)
print("Client connected")
except IOError:
return
data_json_bytes = json.dumps(dictionary).encode()
@ -65,7 +63,6 @@ class TmTcpServer:
self.client_connection = None
def report_raw_hk_data(self, object_id: ObjectIdU32, set_id: int, hk_data: bytes):
data_dict = {
"type": "TM",
"tmType": "Raw HK",

View File

@ -59,12 +59,44 @@ class SetId(enum.IntEnum):
MEKF_DATA = 7
CTRL_VAL_DATA = 8
ACTUATOR_CMD_DATA = 9
FUSED_ROT_RATE_DATA = 10
class ActionId(enum.IntEnum):
SOLAR_ARRAY_DEPLOYMENT_SUCCESSFUL = 0
RESET_MEKF = 1
RESTORE_MEKF_NONFINITE_RECOVERY = 2
UPDATE_TLE = 3
CTRL_STRAT_DICT = {
0: "OFF",
1: "NO_MAG_FIELD_FOR_CONTROL",
2: "NO_SENSORS_FOR_CONTROL",
# OBSW <= v6.1.0
10: "LEGACY_SAFE_MEKF",
11: "LEGACY_WITHOUT_MEKF",
12: "LEGACY_ECLIPSE_DAMPING",
13: "LEGACY_ECLIPSE_IDELING",
# Added in OBSW v6.2.0
14: "SAFE_MEKF",
15: "SAFE_GYR",
16: "SAFE_SUSMGM",
17: "SAFE_ECLIPSE_DAMPING_GYR",
18: "SAFE_ECLIPSE_DAMPING_SUSMGM",
19: "SAFE_ECLIPSE_IDELING",
20: "DETUMBLE_FULL",
21: "DETUMBLE_DETERIORATED",
30: "PTG_MEKF",
31: "PTG_RAW",
}
GPS_COURCE_DICT = {
0: "NONE",
1: "GPS",
2: "GPS_EXTRAPOLATED",
3: "SGP4",
}
class OpCodes:
@ -79,6 +111,7 @@ class OpCodes:
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"]
@ -112,6 +145,9 @@ class OpCodes:
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"]
class Info:
@ -126,6 +162,7 @@ class Info:
SAFE_PTG = "Confirm deployment of both solar arrays"
RESET_MEKF = "Reset the MEKF"
RESTORE_MEKF_NONFINITE_RECOVERY = "Restore MEKF non-finite recovery"
UPDATE_TLE = "Update TLE"
SET_PARAMETER_SCALAR = "Set Scalar Parameter"
SET_PARAMETER_VECTOR = "Set Vector Parameter"
SET_PARAMETER_MATRIX = "Set Matrix Parameter"
@ -159,6 +196,9 @@ class Info:
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"
PERFORM_MGM_CALIBRATION = False
@ -190,6 +230,7 @@ def acs_cmd_defs(defs: TmtcDefinitionWrapper):
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)
@ -223,6 +264,9 @@ def acs_cmd_defs(defs: TmtcDefinitionWrapper):
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
)
@ -275,6 +319,22 @@ def pack_acs_ctrl_command(p: ServiceProviderParams): # noqa C901
q.add_pus_tc(
create_action_cmd(ACS_CONTROLLER, ActionId.RESTORE_MEKF_NONFINITE_RECOVERY)
)
elif op_code in OpCodes.UPDATE_TLE:
q.add_log_cmd(f"{Info.UPDATE_TLE}")
while True:
line1 = input("Please input the first line of the TLE: ")
if len(line1) == 69:
break
else:
print("The line does not have the required length of 69 characters")
while True:
line2 = input("Please input the second line of the TLE: ")
if len(line2) == 69:
break
else:
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:
q.add_log_cmd(f"{Info.SET_PARAMETER_SCALAR}")
set_acs_ctrl_param_scalar(q)
@ -484,6 +544,26 @@ def pack_acs_ctrl_command(p: ServiceProviderParams): # noqa C901
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)
)
)
else:
logging.getLogger(__name__).info(f"Unknown op code {op_code}")
@ -699,6 +779,8 @@ def handle_acs_ctrl_hk_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)
def handle_acs_ctrl_sus_raw_data(pw: PrintWrapper, hk_data: bytes):
@ -930,11 +1012,13 @@ def handle_gyr_data_processed(pw: PrintWrapper, hk_data: bytes):
def handle_gps_data_processed(pw: PrintWrapper, hk_data: bytes):
pw.dlog("Received GPS Processed Set")
fmt_source = "!B"
fmt_scalar = "!d"
fmt_vec = "!ddd"
inc_len_source = struct.calcsize(fmt_source)
inc_len_scalar = struct.calcsize(fmt_scalar)
inc_len_vec = struct.calcsize(fmt_vec)
if len(hk_data) < 2 * inc_len_scalar + 2 * inc_len_vec:
if len(hk_data) < 2 * inc_len_scalar + 2 * inc_len_vec + inc_len_source:
pw.dlog("Received HK set too small")
return
current_idx = 0
@ -973,12 +1057,20 @@ def handle_gps_data_processed(pw: PrintWrapper, hk_data: bytes):
)
]
current_idx += inc_len_vec
source = struct.unpack(
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]}")
else:
pw.dlog(f"'GPS Source (key unknown)': {source}")
pw.dlog(f"GPS Latitude: {lat} [deg]")
pw.dlog(f"GPS Longitude: {long} [deg]")
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=5)
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=6)
def handle_mekf_data(pw: PrintWrapper, hk_data: bytes):
@ -1026,17 +1118,6 @@ def handle_mekf_data(pw: PrintWrapper, hk_data: bytes):
def handle_ctrl_val_data(pw: PrintWrapper, hk_data: bytes):
safe_strat = {
0: "OFF",
1: "NO_MAG_FIELD_FOR_CONTROL",
2: "NO_SENSORS_FOR_CONTROL",
10: "ACTIVE_MEKF",
11: "WITHOUT_MEKF",
12: "ECLIPSE_DAMPING",
13: "ECLIPSE_IDELING",
20: "DETUMBLE_FULL",
21: "DETUMBLE_DETERIORATED",
}
pw.dlog("Received CTRL Values Set")
fmt_strat = "!B"
fmt_quat = "!dddd"
@ -1082,8 +1163,8 @@ def handle_ctrl_val_data(pw: PrintWrapper, hk_data: bytes):
)
]
current_idx += inc_len_vec
if safe_strat.get(strat) is not None:
pw.dlog(f"{'Safe Ctrl Strategy'.ljust(25)}: {safe_strat[strat]}")
if CTRL_STRAT_DICT.get(strat) is not None:
pw.dlog(f"{'Safe Ctrl Strategy'.ljust(25)}: {CTRL_STRAT_DICT[strat]}")
else:
pw.dlog(f"{'Safe Ctrl Strategy (key unknown)'.ljust(25)}: {strat}")
pw.dlog(f"Control Values Target Quaternion: {tgt_quat}")
@ -1132,6 +1213,41 @@ def handle_act_cmd_data(pw: PrintWrapper, hk_data: bytes):
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")
return
current_idx = 0
rot_rate_orthogonal = [
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 = [
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 = [
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: {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)
def perform_mgm_calibration( # noqa C901: Complexity okay
pw: PrintWrapper, mgm_tuple: Tuple
): # noqa C901: Complexity okay

View File

@ -20,37 +20,51 @@ from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
_LOGGER = logging.getLogger(__name__)
class GpsInfo:
MAX_SATELLITES = 30
class OpCode:
OFF = "off"
ON = "on"
REQ_OS_HK = ["hk"]
ENABLE_HK = ["enable_hk"]
DISABLE_HK = ["disable_hk"]
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"]
class Info:
OFF = "Off"
ON = "On"
REQ_OS_HK = "Request One-Shot HK"
ENABLE_HK = "Enable HK"
DISABLE_HK = "Disable HK"
REQ_CORE_HK = "Request Core HK"
ENABLE_CORE_HK = "Enable Core HK"
DISABLE_CORE_HK = "Disable Core HK"
REQ_SKYVIEW_HK = "Request Skyview HK"
ENABLE_SKYVIEW_HK = "Enable Skyview HK"
DISABLE_SKYVIEW_HK = "Disable Skyview HK"
RESET_GNSS = "Reset GNSS using reset pin"
class SetId(enum.IntEnum):
HK = 0
CORE_HK = 0
SKYVIEW_HK = 1
@tmtc_definitions_provider
def add_gps_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(keys=OpCode.RESET_GNSS, info=Info.RESET_GNSS)
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.DISABLE_HK, info=Info.DISABLE_HK)
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",
@ -58,27 +72,64 @@ def add_gps_cmds(defs: TmtcDefinitionWrapper):
)
def pack_gps_command(object_id: bytes, q: DefaultPusQueueHelper, op_code: str):
sid = make_sid(object_id=object_id, set_id=SetId.HK)
def pack_gps_command( # noqa: C901
object_id: bytes, q: DefaultPusQueueHelper, op_code: 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_HK:
if op_code in OpCode.ENABLE_CORE_HK:
interval = float(input("Please specify interval in floating point seconds: "))
if interval <= 0:
raise ValueError("invalid interval")
q.add_log_cmd(f"GPS: {Info.ENABLE_HK}")
q.add_log_cmd(f"GPS: {Info.ENABLE_CORE_HK}")
cmds = create_enable_periodic_hk_command_with_interval(
diag=False, sid=sid, interval_seconds=interval
diag=False,
sid=make_sid(object_id=object_id, set_id=SetId.CORE_HK),
interval_seconds=interval,
)
for cmd in cmds:
q.add_pus_tc(cmd)
if op_code in OpCode.DISABLE_HK:
q.add_log_cmd(f"gps: {Info.DISABLE_HK}")
q.add_pus_tc(create_disable_periodic_hk_command(diag=False, sid=sid))
if op_code in OpCode.REQ_OS_HK:
q.add_log_cmd(f"GPS: {Info.REQ_OS_HK}")
q.add_pus_tc(create_request_one_hk_command(sid=sid))
if op_code in OpCode.DISABLE_CORE_HK:
q.add_log_cmd(f"gps: {Info.DISABLE_CORE_HK}")
q.add_pus_tc(
create_disable_periodic_hk_command(
diag=False, sid=make_sid(object_id=object_id, set_id=SetId.CORE_HK)
)
)
if op_code in 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:
interval = float(input("Please specify interval in floating point seconds: "))
if interval <= 0:
raise ValueError("invalid interval")
q.add_log_cmd(f"GPS: {Info.ENABLE_SKYVIEW_HK}")
cmds = create_enable_periodic_hk_command_with_interval(
diag=False,
sid=make_sid(object_id=object_id, set_id=SetId.SKYVIEW_HK),
interval_seconds=interval,
)
for cmd in cmds:
q.add_pus_tc(cmd)
if op_code in OpCode.DISABLE_SKYVIEW_HK:
q.add_log_cmd(f"gps: {Info.DISABLE_SKYVIEW_HK}")
q.add_pus_tc(
create_disable_periodic_hk_command(
diag=False, sid=make_sid(object_id=object_id, set_id=SetId.SKYVIEW_HK)
)
)
if op_code in 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:
q.add_log_cmd(f"GPS: {Info.ON}")
q.add_pus_tc(create_mode_command(object_id, Mode.ON, 0))
@ -87,8 +138,27 @@ def pack_gps_command(object_id: bytes, q: DefaultPusQueueHelper, op_code: str):
q.add_pus_tc(create_mode_command(object_id, Mode.OFF, 0))
def handle_gps_data(pw: PrintWrapper, hk_data: bytes):
pw.dlog(f"Received GPS data, HK data length {len(hk_data)}")
def handle_gps_data(
pw: PrintWrapper,
set_id: int,
hk_data: bytes,
packet_time: datetime.datetime,
):
pw.ilog(_LOGGER, f"Received GPS CTRL HK with packet time {packet_time}")
match set_id:
case SetId.CORE_HK:
handle_core_data(pw, hk_data)
case SetId.SKYVIEW_HK:
handle_skyview_data(pw, hk_data)
def handle_core_data(pw: PrintWrapper, hk_data: bytes):
if len(hk_data) < 4 * 8 + 4 + 2 + 8:
pw.dlog(
f"GPS Core dataset with size {len(hk_data)} does not have expected size"
f" of {4*8+4+2+8} bytes"
)
return
current_idx = 0
fmt_str = "!ddddBBBHBBBBBI"
inc_len = struct.calcsize(fmt_str)
@ -126,3 +196,65 @@ def handle_gps_data(pw: PrintWrapper, hk_data: bytes):
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=hk_data[current_idx:], num_vars=14
)
def handle_skyview_data(pw: PrintWrapper, hk_data: bytes):
data_length = 8 + GpsInfo.MAX_SATELLITES * (8 + 3 * 2 + 1)
if len(hk_data) < data_length:
pw.dlog(
f"GPS Skyview dataset with size {len(hk_data)} does not have expected size"
f" of {data_length} bytes"
)
return
current_idx = 0
fmt_str_unix = "!d"
fmt_str_int16 = "!" + "h" * GpsInfo.MAX_SATELLITES
fmt_str_double = "!" + "d" * GpsInfo.MAX_SATELLITES
fmt_str_uint8 = "!" + "B" * GpsInfo.MAX_SATELLITES
inc_len_unix = struct.calcsize(fmt_str_unix)
inc_len_int16 = struct.calcsize(fmt_str_int16)
inc_len_double = struct.calcsize(fmt_str_double)
inc_len_uint8 = struct.calcsize(fmt_str_uint8)
unix = struct.unpack(
fmt_str_unix, hk_data[current_idx : current_idx + inc_len_unix]
)
current_idx += inc_len_unix
prn_id = struct.unpack(
fmt_str_int16, hk_data[current_idx : current_idx + inc_len_int16]
)
current_idx += inc_len_int16
azimuth = struct.unpack(
fmt_str_int16, hk_data[current_idx : current_idx + inc_len_int16]
)
current_idx += inc_len_int16
elevation = struct.unpack(
fmt_str_int16, hk_data[current_idx : current_idx + inc_len_int16]
)
current_idx += inc_len_int16
signal_to_noise = struct.unpack(
fmt_str_double, hk_data[current_idx : current_idx + inc_len_double]
)
current_idx += inc_len_double
used = struct.unpack(
fmt_str_uint8, hk_data[current_idx : current_idx + inc_len_uint8]
)
current_idx += inc_len_uint8
pw.dlog(f"Skyview Time: {unix} unix-sec")
pw.dlog(
"{:<8} {:<8} {:<8} {:<8} {:<8}".format(
"PRN_ID", "AZ [°]", "EL [°]", "S2N [dBW]", "USED"
)
)
for idx in range(GpsInfo.MAX_SATELLITES):
pw.dlog(
"{:<8} {:<8} {:<8} {:<8} {:<8}".format(
prn_id[idx],
azimuth[idx],
elevation[idx],
signal_to_noise[idx],
used[idx],
)
)
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=hk_data[current_idx:], num_vars=6
)

View File

@ -61,7 +61,7 @@ GYR_SEL_DICT = {
def handle_gyr_cmd(q: DefaultPusQueueHelper, op_code: str):
print("Please select the Gyro Device")
for (k, v) in GYR_SEL_DICT.items():
for k, v in GYR_SEL_DICT.items():
print(f"{k}: {v[0]}")
sel_idx = int(input("Select gyro device by index: "))
gyr_info = GYR_SEL_DICT[GyrSel(sel_idx)]

View File

@ -49,7 +49,7 @@ MGM_SEL_DICT = {
def handle_mgm_cmd(q: DefaultPusQueueHelper, op_code: str):
print("Please select the MGM Device")
for (k, v) in MGM_SEL_DICT.items():
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)]

View File

@ -290,7 +290,6 @@ def pack_set_speed_command(
def handle_rw_hk_data(
pw: PrintWrapper, object_id: ObjectIdU32, set_id: int, hk_data: bytes
):
current_idx = 0
if set_id == RwSetId.STATUS_SET_ID:
pw.dlog(

View File

@ -65,7 +65,6 @@ class StarTrackerActionId(enum.IntEnum):
CHANGE_DOWNLOAD_IMAGE = 57
SET_JSON_FILE_NAME = 58
SET_FLASH_READ_FILENAME = 59
SET_TIME = 60
DOWNLOAD_DBIMAGE = 61
DOWNLOAD_BLOBPIXEL = 62
DOWNLOAD_FPGA_IMAGE = 63
@ -90,6 +89,7 @@ class StarTrackerActionId(enum.IntEnum):
LOG_SUBSCRIPTION = 82
DEBUG_CAMERA = 83
FIRMWARE_UPDATE = 84
SET_TIME_FROM_SYS_TIME = 87
class OpCodes:
@ -104,6 +104,7 @@ class OpCodes:
UPLOAD_IMAGE = "upload_image"
SET_IMG_PROCESSOR_MODE = "set_img_proc_mode"
FW_UPDATE = "fw_update"
SET_TIME_FROM_SYS_TIME = "set_time"
class Info:
@ -113,6 +114,7 @@ class Info:
TAKE_IMAGE = "Take Image"
SET_IMG_PROCESSOR_MODE = "Set Image Processor Mode"
FW_UPDATE = "Firmware Update"
SET_TIME_FROM_SYS_TIME = "Set time from system time"
class SetId(enum.IntEnum):
@ -438,14 +440,9 @@ def pack_star_tracker_commands( # noqa C901
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 == "38":
q.add_log_cmd("Star tracker: Set time")
unix_time = 1640783543
data = (
obyt
+ struct.pack("!I", StarTrackerActionId.SET_TIME)
+ struct.pack("!Q", unix_time)
)
if op_code == OpCodes.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":
q.add_log_cmd("Star tracker: Download Centroid")
@ -485,34 +482,6 @@ 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 == "44":
q.add_log_cmd("Star tracker: Download FPGA Image")
position = int(input("Start position: "))
length = int(input("Size to download: "))
data = (
obyt
+ struct.pack("!I", StarTrackerActionId.DOWNLOAD_FPGA_IMAGE)
+ struct.pack("!I", position)
+ struct.pack("!I", length)
+ bytearray(FileDefs.downloadFpgaImagePath, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "45":
q.add_log_cmd("Star tracker: Change donwload FPGA image file name")
data = (
obyt
+ struct.pack("!I", StarTrackerActionId.CHANGE_FPGA_DOWNLOAD_FILE)
+ bytearray(FileDefs.downloadFpgaImageName, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "46":
q.add_log_cmd("Star tracker: Upload FPGA image")
data = (
obyt
+ struct.pack("!I", StarTrackerActionId.UPLOAD_FPGA_IMAGE)
+ bytearray(FileDefs.uploadFpgaImageName, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "47":
q.add_log_cmd("Star tracker: FPGA action")
id = 3
@ -724,7 +693,7 @@ def unpack_time_hk(hk_data: bytes, current_idx: int, pw: PrintWrapper) -> int:
ticks_time_fmt, hk_data[current_idx : current_idx + fmt_len]
)
unix_as_dt = datetime.datetime.fromtimestamp(
int(round(unix_time / 10e6)), tz=datetime.timezone.utc
int(round(unix_time / 1e6)), tz=datetime.timezone.utc
)
pw.dlog(f"Ticks: {ticks} | UNIX time: {unix_time}")
pw.dlog(f"UNIX as datetime: {unix_as_dt}")
@ -887,4 +856,5 @@ def add_str_cmds(defs: TmtcDefinitionWrapper):
oce.add(OpCodes.FW_UPDATE, Info.FW_UPDATE)
oce.add("70", "Star Tracker: Disable timestamp generation")
oce.add("71", "Star Tracker: Enable timestamp generation")
oce.add(OpCodes.SET_TIME_FROM_SYS_TIME, Info.SET_TIME_FROM_SYS_TIME)
defs.add_service(CustomServiceList.STAR_TRACKER.value, "Star Tracker", oce)

View File

@ -24,6 +24,19 @@ from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
_LOGGER = logging.getLogger(__name__)
class SdState(enum.IntEnum):
OFF = 0
ON = 1
MOUNTED = 2
class SdCardSelect(enum.IntEnum):
SD_0 = 0
SD_1 = 1
BOTH = 2
NONE = 3
class ActionId(enum.IntEnum):
ANNOUNCE_VERSION = 1
ANNOUNCE_CURRENT_IMAGE = 2
@ -89,14 +102,14 @@ class OpCode:
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 = "rbh_off"
DISABLE_REBOOT_FILE_HANDLING = "rbh_on"
RESET_ALL_REBOOT_COUNTERS = "rbh_reset_a"
RESET_REBOOT_COUNTER_00 = "rbh_reset_00"
RESET_REBOOT_COUNTER_01 = "rbh_reset_01"
RESET_REBOOT_COUNTER_10 = "rbh_reset_10"
RESET_REBOOT_COUNTER_11 = "rbh_reset_11"
SET_MAX_REBOOT_CNT = ["rbh_max_cnt"]
ENABLE_REBOOT_FILE_HANDLING = "rwd_on"
DISABLE_REBOOT_FILE_HANDLING = "rwd_off"
RESET_ALL_REBOOT_COUNTERS = "rwd_reset_a"
RWD_RESET_REBOOT_COUNTER_00 = "rwd_reset_00"
RWD_RESET_REBOOT_COUNTER_01 = "rwd_reset_01"
RWD_RESET_REBOOT_COUNTER_10 = "rwd_reset_10"
RWD_RESET_REBOOT_COUNTER_11 = "rwd_reset_11"
RWD_SET_MAX_REBOOT_CNT = "rwd_max_cnt"
class Info:
@ -188,21 +201,25 @@ def add_core_controller_definitions(defs: TmtcDefinitionWrapper):
info="Reset all reboot counters",
)
oce.add(
keys=OpCode.RESET_REBOOT_COUNTER_00,
keys=OpCode.RWD_RESET_REBOOT_COUNTER_00,
info="Reset reboot counter 0 0",
)
oce.add(
keys=OpCode.RESET_REBOOT_COUNTER_01,
keys=OpCode.RWD_RESET_REBOOT_COUNTER_01,
info="Reset reboot counter 0 1",
)
oce.add(
keys=OpCode.RESET_REBOOT_COUNTER_10,
keys=OpCode.RWD_RESET_REBOOT_COUNTER_10,
info="Reset reboot counter 1 0",
)
oce.add(
keys=OpCode.RESET_REBOOT_COUNTER_11,
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)
@ -336,14 +353,25 @@ def pack_core_commands( # noqa C901
action_id=ActionId.RESET_REBOOT_COUNTER,
)
)
elif op_code == OpCode.RESET_REBOOT_COUNTER_00:
elif op_code == OpCode.RWD_RESET_REBOOT_COUNTER_00:
reset_specific_boot_counter(q, 0, 0)
elif op_code == OpCode.RESET_REBOOT_COUNTER_01:
elif op_code == OpCode.RWD_RESET_REBOOT_COUNTER_01:
reset_specific_boot_counter(q, 0, 1)
elif op_code == OpCode.RESET_REBOOT_COUNTER_10:
elif op_code == OpCode.RWD_RESET_REBOOT_COUNTER_10:
reset_specific_boot_counter(q, 1, 0)
elif op_code == OpCode.RESET_REBOOT_COUNTER_11:
elif op_code == OpCode.RWD_RESET_REBOOT_COUNTER_11:
reset_specific_boot_counter(q, 1, 1)
elif op_code == 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")
q.add_pus_tc(
create_action_cmd(
CORE_CONTROLLER_ID,
ActionId.SET_MAX_REBOOT_CNT,
user_data=bytes([max_count]),
)
)
elif op_code in 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))

View File

@ -0,0 +1,24 @@
import enum
import struct
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
from eive_tmtc.pus_tm.defs import PrintWrapper
class SetId(enum.IntEnum):
ERROR_ID = 0
def handle_ier_hk_data(pw: PrintWrapper, hk_data: bytes, set_id: int):
pw.dlog(f"Received internal error reporter HK data with set ID {set_id}")
if set_id == SetId.ERROR_ID:
fmt_str = "!III"
inc_len = struct.calcsize(fmt_str)
(tm_errors, queue_errors, store_hits) = struct.unpack(
fmt_str, hk_data[:inc_len]
)
pw.dlog(f"TM Errors: {tm_errors}")
pw.dlog(f"Queue Errors: {queue_errors}")
pw.dlog(f"Store Errors: {store_hits}")
pw.dlog(FsfwTmTcPrinter.get_validity_buffer(hk_data[inc_len:], 3))

View File

@ -14,6 +14,13 @@ from eive_tmtc.config.object_ids import (
RW1_ID,
RW2_ID,
RTD_0_PLOC_HSPD,
TMP1075_HANDLER_TCS_BRD_1_ID,
TMP1075_HANDLER_TCS_BRD_0_ID,
TMP1075_HANDLER_PLPCDU_0_ID,
TMP1075_HANDLER_PLPCDU_1_ID,
TMP1075_HANDLER_IF_BRD_ID,
STR_ASSEMBLY,
STAR_TRACKER_ID,
)
SUBSYSTEM_DICT = {
@ -27,20 +34,27 @@ ACS_OBJ_DICT = {
1: ("SUS Assembly", SUS_BOARD_ASS_ID),
2: ("ACS Board Assembly", ACS_BOARD_ASS_ID),
3: ("RW Assembly", RW_ASSEMBLY),
4: ("iMTQ MGT", IMTQ_HANDLER_ID),
5: ("GYR 0 ADIS", GYRO_0_ADIS_HANDLER_ID),
6: ("GYR 1 L3G", GYRO_1_L3G_HANDLER_ID),
7: ("MGM 0 LIS3", MGM_0_LIS3_HANDLER_ID),
8: ("MGM 1 RM3100", MGM_1_RM3100_HANDLER_ID),
9: ("GPS 0 Health Device", GPS_0_HEALTH_DEV),
10: ("SUS 0", SUS_0_N_LOC_XFYFZM_PT_XF),
11: ("SUS 6", SUS_6_R_LOC_XFYBZM_PT_XF),
12: ("RW 1", RW1_ID),
13: ("RW 2", RW2_ID),
4: ("STR Assembly", STR_ASSEMBLY),
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),
}
TCS_OBJ_DICT = {
0: ("RTD 0", RTD_0_PLOC_HSPD),
1: ("TMP1075 PL PCDU 0", TMP1075_HANDLER_PLPCDU_0_ID),
2: ("TMP1075 PL PCDU 1", TMP1075_HANDLER_PLPCDU_1_ID),
3: ("TMP1075 TCS 0", TMP1075_HANDLER_TCS_BRD_0_ID),
4: ("TMP1075 TCS 1", TMP1075_HANDLER_TCS_BRD_1_ID),
5: ("TMP1075 IF BOARD", TMP1075_HANDLER_IF_BRD_ID),
}

View File

@ -172,7 +172,6 @@ class Info(str, enum.Enum):
@tmtc_definitions_provider
def add_ploc_supv_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(OpCodes.OFF, Info.OFF)
oce.add(OpCodes.ON, Info.ON)
@ -723,10 +722,42 @@ def get_event_buffer_path() -> str:
return file
class SocState(enum.IntEnum):
OFF = 0
BOOTING = 1
OPERATIONAL = 2
SHUTDOWN = 3
def handle_supv_hk_data(set_id: int, hk_data: bytes, pw: PrintWrapper):
current_idx = 0
if set_id == SetIds.HK_REPORT:
pass
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)

View File

@ -17,17 +17,17 @@ USE_SCEX_CONF_FILE = True
class OpCode:
PING = ["0", "ping"]
ION_CMD = ["1", "ion"]
TEMP_CMD = ["2", "temp"]
EXP_STATUS_CMD = ["3", "expstatus"]
PING = "ping"
ION_CMD = "ion"
TEMP_CMD = "temp"
EXP_STATUS_CMD = "expstatus"
ONE_CELLS_CMD = ["4", "onecell"]
ALL_CELLS_CMD = ["5", "allcells"]
FRAM = ["6", "fram"]
ONE_CELLS_CMD = "onecell"
ALL_CELLS_CMD = "allcells"
FRAM = "fram"
SWITCH_ON = ["7", "on"]
SWITCH_OFF = ["8", "off"]
SWITCH_ON = "on"
SWITCH_OFF = "off"
class ActionId(enum.IntEnum):
@ -78,7 +78,7 @@ def add_scex_cmds(defs: TmtcDefinitionWrapper):
def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
op_code = p.op_code
q = p.queue_helper
if op_code in OpCode.SWITCH_ON:
if op_code == OpCode.SWITCH_ON:
q.add_log_cmd(Info.SWITCH_ON)
q.add_pus_tc(
PusTelecommand(
@ -87,7 +87,7 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
app_data=pack_mode_data(SCEX_HANDLER_ID, Mode.ON, 0),
)
)
if op_code in OpCode.SWITCH_OFF:
if op_code == OpCode.SWITCH_OFF:
q.add_log_cmd(Info.SWITCH_OFF)
q.add_pus_tc(
PusTelecommand(
@ -96,20 +96,20 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
app_data=pack_mode_data(SCEX_HANDLER_ID, Mode.OFF, 0),
)
)
if op_code in OpCode.PING:
if op_code == 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 in OpCode.ION_CMD:
if op_code == 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 in OpCode.TEMP_CMD:
if op_code == 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 in OpCode.EXP_STATUS_CMD:
if op_code == OpCode.EXP_STATUS_CMD:
q.add_log_cmd(Info.EXP_STATUS_CMD)
app_data = bytes([0])
q.add_pus_tc(
@ -117,7 +117,7 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
)
# one cell
if op_code in OpCode.ONE_CELLS_CMD:
if op_code == OpCode.ONE_CELLS_CMD:
q.add_log_cmd(Info.ONE_CELLS_CMD)
app_data = bytearray([0])
@ -165,7 +165,7 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
create_action_cmd(SCEX_HANDLER_ID, ActionId.ONE_CELLS_CMD, app_data)
)
if op_code in OpCode.ALL_CELLS_CMD:
if op_code == OpCode.ALL_CELLS_CMD:
q.add_log_cmd(Info.ALL_CELLS_CMD)
app_data = bytearray([0])
@ -197,7 +197,7 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
create_action_cmd(SCEX_HANDLER_ID, ActionId.ALL_CELLS_CMD, app_data)
)
if op_code in OpCode.FRAM:
if op_code == 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

@ -12,7 +12,7 @@ from tmtccmd.tc.decorator import ServiceProviderParams
from tmtccmd.tc.pus_200_fsfw_mode import Subservice as ModeSubservice
class ModeId:
class ModeId(enum.IntEnum):
OFF = 0
SUPV_ONLY = 10
MPSOC_STREAM = 11

View File

@ -85,6 +85,40 @@ class NormalSubmodesMask(enum.IntEnum):
HPA_ON = 5
class SubmodeForNormalMode(enum.IntEnum):
NONE = 0
SSR_ON = 1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON
DRO_ON = 1 << NormalSubmodesMask.DRO_ON | (
1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON
)
X8_ON = (
1 << NormalSubmodesMask.DRO_ON
| (1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON)
| (1 << NormalSubmodesMask.X8_ON)
)
TX_ON = (
1 << NormalSubmodesMask.DRO_ON
| (1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON)
| (1 << NormalSubmodesMask.X8_ON)
| (1 << NormalSubmodesMask.TX_ON)
)
MPA_ON = (
1 << NormalSubmodesMask.DRO_ON
| (1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON)
| (1 << NormalSubmodesMask.X8_ON)
| (1 << NormalSubmodesMask.TX_ON)
| (1 << NormalSubmodesMask.MPA_ON)
)
HPA_ON = (
1 << NormalSubmodesMask.DRO_ON
| (1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON)
| (1 << NormalSubmodesMask.X8_ON)
| (1 << NormalSubmodesMask.TX_ON)
| (1 << NormalSubmodesMask.MPA_ON)
| (1 << NormalSubmodesMask.HPA_ON)
)
class ParamIds(enum.IntEnum):
NEG_V_LOWER_BOUND = 0
NEG_V_UPPER_BOUND = 1
@ -383,41 +417,17 @@ def request_wait_time() -> Optional[float]:
def submode_mask_to_submode(on_tgt: NormalSubmodesMask) -> int:
if on_tgt == NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON:
return 1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON
return SubmodeForNormalMode.SSR_ON
if on_tgt == NormalSubmodesMask.DRO_ON:
return 1 << NormalSubmodesMask.DRO_ON | (
1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON
)
return SubmodeForNormalMode.DRO_ON
if on_tgt == NormalSubmodesMask.X8_ON:
return (
1 << NormalSubmodesMask.DRO_ON
| (1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON)
| (1 << NormalSubmodesMask.X8_ON)
)
return SubmodeForNormalMode.X8_ON
if on_tgt == NormalSubmodesMask.TX_ON:
return (
1 << NormalSubmodesMask.DRO_ON
| (1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON)
| (1 << NormalSubmodesMask.X8_ON)
| (1 << NormalSubmodesMask.TX_ON)
)
return SubmodeForNormalMode.TX_ON
if on_tgt == NormalSubmodesMask.MPA_ON:
return (
1 << NormalSubmodesMask.DRO_ON
| (1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON)
| (1 << NormalSubmodesMask.X8_ON)
| (1 << NormalSubmodesMask.TX_ON)
| (1 << NormalSubmodesMask.MPA_ON)
)
return SubmodeForNormalMode.MPA_ON
if on_tgt == NormalSubmodesMask.HPA_ON:
return (
1 << NormalSubmodesMask.DRO_ON
| (1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON)
| (1 << NormalSubmodesMask.X8_ON)
| (1 << NormalSubmodesMask.TX_ON)
| (1 << NormalSubmodesMask.MPA_ON)
| (1 << NormalSubmodesMask.HPA_ON)
)
return SubmodeForNormalMode.HPA_ON
def pack_wait_time_cmd(q: DefaultPusQueueHelper, param_id: int, print_str: str):

View File

@ -0,0 +1,92 @@
from eive_tmtc.config.definitions import CustomServiceList
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 (
tmtc_definitions_provider,
TmtcDefinitionWrapper,
OpCodeEntry,
)
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_3_fsfw_hk import (
make_sid,
generate_one_hk_command,
create_request_one_diag_command,
create_enable_periodic_hk_command_with_interval,
create_request_one_hk_command,
)
class OpCode:
REQUEST_PRIMARY_TEMP_SET = "temp"
ENABLE_TEMP_SET = "enable_temp_set"
REQUEST_DEVICE_TEMP_SET = "temp_devs"
REQUEST_DEVICE_SUS_SET = "temp_sus"
REQUEST_HEATER_INFO = "heater_info"
REQUEST_TCS_CTRL_INFO = "tcs_ctrl_info"
class Info:
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"
REQUEST_DEVICE_SUS_SET = "Request HK set of the SUS temperatures"
REQUEST_HEATER_INFO = "Request heater information"
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:
sensor_set_sid = make_sid(TCS_CONTROLLER, CtrlSetId.PRIMARY_SENSORS)
q.add_log_cmd(Info.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)
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)
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)
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)
q.add_pus_tc(
create_request_one_hk_command(
make_sid(TCS_CONTROLLER, CtrlSetId.TCS_CTRL_INFO)
)
)
if op_code == OpCode.ENABLE_TEMP_SET:
interval_seconds = float(input("Please specify interval in seconds: "))
cmds = create_enable_periodic_hk_command_with_interval(
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)
@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)
defs.add_service(
name=CustomServiceList.TCS_CTRL,
info="TCS controller",
op_code_entry=oce,
)

View File

@ -6,3 +6,22 @@ class CtrlSetId(enum.IntEnum):
DEVICE_SENSORS = 1
SUS_TEMP_SENSORS = 2
HEATER_INFO = 4
TCS_CTRL_INFO = 5
class TcsSubmode(enum.IntEnum):
DEFAULT = 0
NO_HEATER_CTRL = 1
class Heater(enum.IntEnum):
HEATER_0_PLOC_PROC_BRD = 0
HEATER_1_PCDU_BRD = 1
HEATER_2_ACS_BRD = 2
HEATER_3_OBC_BRD = 3
HEATER_4_CAMERA = 4
HEATER_5_STR = 5
HEATER_6_DRO = 6
HEATER_7_SYRLINKS = 7
NUMBER_OF_SWITCHES = 8
NONE = 0xFF

View File

@ -7,6 +7,7 @@ import enum
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
@ -20,18 +21,6 @@ from tmtccmd.pus.s8_fsfw_funccmd import create_action_cmd
from spacepackets.ecss.tc import PusTelecommand
class Heater(enum.IntEnum):
HEATER_0_PLOC_PROC_BRD = 0
HEATER_1_PCDU_BRD = 1
HEATER_2_ACS_BRD = 2
HEATER_3_OBC_BRD = 3
HEATER_4_CAMERA = 4
HEATER_5_STR = 5
HEATER_6_DRO = 6
HEATER_7_SYRLINKS = 7
NUMBER_OF_SWITCHES = 8
HEATER_LOCATION = [
"PLOC Processing Board",
"PCDU PDU",

View File

@ -1,6 +1,5 @@
from .defs import CtrlSetId
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.config.object_ids import TCS_CONTROLLER, TCS_SUBSYSTEM_ID
from eive_tmtc.config.object_ids import TCS_SUBSYSTEM_ID
from eive_tmtc.tmtc.common import pack_mode_cmd_with_info
from eive_tmtc.tmtc.tcs.brd_assy import pack_tcs_ass_cmds
from tmtccmd.config.tmtc import (
@ -10,74 +9,28 @@ from tmtccmd.config.tmtc import (
)
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_200_fsfw_mode import Mode, create_announce_mode_recursive_command
from tmtccmd.tc.pus_3_fsfw_hk import (
make_sid,
generate_one_hk_command,
create_enable_periodic_hk_command_with_interval,
create_request_one_diag_command,
)
class OpCodeSys:
OFF = ["off"]
NML = ["nml"]
REQUEST_PRIMARY_TEMP_SET = ["temp"]
ENABLE_TEMP_SET = "enable_temp_set"
REQUEST_DEVICE_TEMP_SET = ["temp_devs"]
REQUEST_DEVICE_SUS_SET = ["temp_sus"]
REQUEST_HEATER_INFO = "heater_info"
class OpCode:
OFF = "off"
NML = "nml"
ANNOUNCE_MODES = "announce_modes"
class InfoSys:
OFF = "Switch TCS subsystem OFF"
NML = "Switch TCS subsystem NORMAL (nominal)"
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"
REQUEST_DEVICE_SUS_SET = "Request HK set of the SUS temperatures"
REQUEST_HEATER_INFO = "Request heater information"
ANNOUNCE_MODES = "Announce Modes recursively"
def pack_tcs_sys_commands(q: DefaultPusQueueHelper, op_code: str):
if op_code in OpCodeSys.REQUEST_PRIMARY_TEMP_SET:
sensor_set_sid = make_sid(TCS_CONTROLLER, CtrlSetId.PRIMARY_SENSORS)
q.add_log_cmd(InfoSys.REQUEST_PRIMARY_TEMP_SET)
q.add_pus_tc(generate_one_hk_command(sensor_set_sid))
if op_code in OpCodeSys.REQUEST_DEVICE_TEMP_SET:
q.add_log_cmd(InfoSys.REQUEST_DEVICE_TEMP_SET)
q.add_pus_tc(
generate_one_hk_command(make_sid(TCS_CONTROLLER, CtrlSetId.DEVICE_SENSORS))
)
if op_code in OpCodeSys.REQUEST_DEVICE_SUS_SET:
q.add_log_cmd(InfoSys.REQUEST_DEVICE_SUS_SET)
q.add_pus_tc(
generate_one_hk_command(
make_sid(TCS_CONTROLLER, CtrlSetId.SUS_TEMP_SENSORS)
)
)
if op_code == OpCodeSys.REQUEST_HEATER_INFO:
q.add_log_cmd(InfoSys.REQUEST_HEATER_INFO)
q.add_pus_tc(
create_request_one_diag_command(
make_sid(TCS_CONTROLLER, CtrlSetId.HEATER_INFO)
)
)
if op_code in OpCodeSys.OFF:
if op_code == 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 in OpCodeSys.NML:
if op_code == 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 == OpCodeSys.ENABLE_TEMP_SET:
interval_seconds = float(input("Please specify interval in seconds: "))
cmds = create_enable_periodic_hk_command_with_interval(
False, make_sid(TCS_CONTROLLER, CtrlSetId.PRIMARY_SENSORS), interval_seconds
)
for cmd in cmds:
q.add_pus_tc(cmd)
if op_code == OpCodeSys.ANNOUNCE_MODES:
if op_code == 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)
@ -86,20 +39,11 @@ def pack_tcs_sys_commands(q: DefaultPusQueueHelper, op_code: str):
@tmtc_definitions_provider
def add_tcs_subsystem_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
oce.add(keys=OpCodeSys.OFF, info=InfoSys.OFF)
oce.add(keys=OpCodeSys.NML, info=InfoSys.NML)
oce.add(
keys=OpCodeSys.REQUEST_PRIMARY_TEMP_SET, info=InfoSys.REQUEST_PRIMARY_TEMP_SET
)
oce.add(
keys=OpCodeSys.REQUEST_DEVICE_TEMP_SET, info=InfoSys.REQUEST_DEVICE_TEMP_SET
)
oce.add(keys=OpCodeSys.REQUEST_DEVICE_SUS_SET, info=InfoSys.REQUEST_DEVICE_SUS_SET)
oce.add(keys=OpCodeSys.REQUEST_HEATER_INFO, info=InfoSys.REQUEST_HEATER_INFO)
oce.add(keys=OpCodeSys.ANNOUNCE_MODES, info=InfoSys.ANNOUNCE_MODES)
oce.add(keys=OpCodeSys.ENABLE_TEMP_SET, info=InfoSys.ENABLE_TEMP_SET)
oce.add(keys=OpCode.OFF, info=InfoSys.OFF)
oce.add(keys=OpCode.NML, info=InfoSys.NML)
oce.add(keys=OpCode.ANNOUNCE_MODES, info=InfoSys.ANNOUNCE_MODES)
defs.add_service(
name=CustomServiceList.TCS,
info="TCS",
name=CustomServiceList.TCS_SS,
info="TCS subsystem",
op_code_entry=oce,
)

View File

@ -1,7 +1,11 @@
import dataclasses
import datetime
import enum
import logging
import struct
from eive_tmtc.pus_tm.defs import PrintWrapper
from eive_tmtc.tmtc.tcs.defs import Heater
from tmtccmd.fsfw import validity_buffer_list
from tmtccmd.util import ObjectIdU32
from .defs import CtrlSetId
@ -11,7 +15,46 @@ from .heater import HEATER_LOCATION
_LOGGER = logging.getLogger(__name__)
def handle_thermal_controller_hk_data(
class ThermalComponent(enum.IntEnum):
NONE = 0
ACS_BOARD = 1
MGT = 2
RW = 3
STR = 4
IF_BOARD = 5
TCS_BOARD = 6
OBC = 7
LEGACY_OBCIF_BOARD = 8
SBAND_TRANSCEIVER = 9
PCDUP60_BOARD = 10
PCDUACU = 11
PCDUPDU = 12
PLPCDU_BOARD = 13
PLOCMISSION_BOARD = 14
PLOCPROCESSING_BOARD = 15
DAC = 16
CAMERA = 17
DRO = 18
X8 = 19
HPA = 20
TX = 21
MPA = 22
SCEX_BOARD = 23
NUM_ENTRIES = 24
@dataclasses.dataclass
class TcsCtrlComponentInfo:
component: ThermalComponent
# Heater on or off?
state: bool
used_sensor_idx: int
used_heater: Heater
start_time: datetime.datetime
end_time: datetime.datetime
def handle_thermal_controller_hk_data( # noqa C901: complexity is okay.
object_id: ObjectIdU32, pw: PrintWrapper, set_id: int, hk_data: bytes
):
# need a better solutuon for this is this is used again..
@ -119,5 +162,50 @@ def handle_thermal_controller_hk_data(
)
current_draw = struct.unpack("!H", hk_data[8:10])[0]
print(f"Heater Power Channel Current Draw: {current_draw} mA")
elif set_id == CtrlSetId.TCS_CTRL_INFO:
pw.dlog("Received TCS CTRL information set")
current_idx = 0
heater_states = hk_data[0 : ThermalComponent.NUM_ENTRIES]
current_idx += ThermalComponent.NUM_ENTRIES
used_sensor_idx = hk_data[
current_idx : current_idx + ThermalComponent.NUM_ENTRIES
]
current_idx += ThermalComponent.NUM_ENTRIES
used_heater_idx = hk_data[
current_idx : current_idx + ThermalComponent.NUM_ENTRIES
]
current_idx += ThermalComponent.NUM_ENTRIES
start_and_end_time_fmt_str = "!IIIIIIIIIIIIIIIIIIIIIIII"
data_len = struct.calcsize(start_and_end_time_fmt_str)
start_times = struct.unpack(
start_and_end_time_fmt_str, hk_data[current_idx : current_idx + data_len]
)
current_idx += data_len
end_times = struct.unpack(
start_and_end_time_fmt_str, hk_data[current_idx : current_idx + data_len]
)
current_idx += data_len
component_list = []
for i in range(ThermalComponent.NUM_ENTRIES):
info = TcsCtrlComponentInfo(
component=ThermalComponent(i),
state=bool(heater_states[i]),
used_sensor_idx=used_sensor_idx[i],
used_heater=Heater(used_heater_idx[i]),
start_time=datetime.datetime.fromtimestamp(
start_times[i], datetime.timezone.utc
),
end_time=datetime.datetime.fromtimestamp(
end_times[i], datetime.timezone.utc
),
)
component_str = f"{info.component!r}".ljust(46)
state_str = "ON" if info.state else "OFF"
pw.dlog(
f"{component_str}: {state_str.ljust(4)} | Sensor Index "
f"{info.used_sensor_idx} | {info.used_heater!r} | Start "
f"{info.start_time} | End {info.end_time}"
)
component_list.append(info)
else:
_LOGGER.warning(f"Unimplemented set ID {set_id}")

View File

@ -29,9 +29,9 @@ classifiers = [
"Topic :: Scientific/Engineering"
]
dependencies = [
"tmtccmd ~= 5.0.0rc0",
"tmtccmd ~= 5.0",
"python-dateutil ~= 2.8",
# tmtccmd @ git+https://github.com/robamu-org/tmtccmd@<gitRev>#egg=tmtccmd
# "tmtccmd @ git+https://github.com/robamu-org/tmtccmd@1b110d321ef85#egg=tmtccmd"
]
[project.urls]

View File

@ -94,7 +94,7 @@ from eive_tmtc.config.definitions import (
CFDP_REMOTE_ENTITY_ID,
)
from eive_tmtc.config.hook import EiveHookObject
from eive_tmtc.pus_tm.factory_hook import pus_factory_hook
from eive_tmtc.pus_tm.pus_demux import pus_factory_hook
from eive_tmtc.pus_tc.procedure_packer import handle_default_procedure
_LOGGER = APP_LOGGER
@ -166,16 +166,20 @@ class PusHandler(SpecificApidHandlerBase):
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
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)
pus_factory_hook(
packet, self.verif_wrapper, self.printer, self.raw_logger, self.hk_level
)
class UnknownApidHandler(GenericApidHandlerBase):
@ -335,13 +339,18 @@ class TcHandler(TcHandlerBase):
_LOGGER.info("Finished CFDP queue")
def setup_params() -> SetupWrapper:
def setup_params() -> (SetupWrapper, int):
hook_obj = EiveHookObject(default_json_path())
params = SetupParams()
parser_wrapper = PreArgsParsingWrapper()
parser_wrapper.create_default_parent_parser()
parser_wrapper.create_default_parser()
parser_wrapper.add_def_proc_and_cfdp_as_subparsers()
tmtc_parser, cfdp_parser = parser_wrapper.add_def_proc_and_cfdp_as_subparsers()
tmtc_parser.add_argument(
"--hk",
help="HK output level",
default=2,
)
post_arg_parsing_wrapper = parser_wrapper.parse(
setup_params=params, hook_obj=hook_obj
)
@ -352,13 +361,14 @@ def setup_params() -> SetupWrapper:
post_arg_parsing_wrapper.set_params_with_prompts(proc_param_wrapper)
else:
post_arg_parsing_wrapper.set_params_without_prompts(proc_param_wrapper)
hk_level = int(post_arg_parsing_wrapper.args_raw.hk)
params.apid = PUS_APID
if params.com_if is None:
raise ValueError("could not determine a COM interface.")
setup_wrapper = SetupWrapper(
hook_obj=hook_obj, setup_params=params, proc_param_wrapper=proc_param_wrapper
)
return setup_wrapper
return setup_wrapper, hk_level
def setup_cfdp_handler() -> CfdpInCcsdsWrapper:
@ -400,12 +410,13 @@ def setup_tmtc_handlers(
printer: FsfwTmTcPrinter,
raw_logger: RawTmtcTimedLogWrapper,
gui: bool,
hk_level: int,
) -> (CcsdsTmHandler, TcHandler):
cfdp_in_ccsds_wrapper = setup_cfdp_handler()
verification_wrapper = VerificationWrapper(
verificator, _LOGGER, printer.file_logger
)
pus_handler = PusHandler(verification_wrapper, printer, raw_logger)
pus_handler = PusHandler(verification_wrapper, printer, raw_logger, hk_level)
ccsds_handler = CustomCcsdsTmHandler(generic_handler=UnknownApidHandler(None))
ccsds_handler.add_apid_handler(pus_handler)
ccsds_handler.add_apid_handler(cfdp_in_ccsds_wrapper)
@ -444,7 +455,7 @@ def main(): # noqa C901: Complexity okay here.
# TODO: -V CLI argument to enable this?
_LOGGER.setLevel(_LOG_LEVEL)
try:
setup_wrapper = setup_params()
setup_wrapper, hk_level = setup_params()
except KeyboardInterrupt as e:
_LOGGER.info(f"{e}. Exiting")
sys.exit(0)
@ -457,7 +468,7 @@ def main(): # noqa C901: Complexity okay here.
)
pus_verificator = PusVerificator()
ccsds_handler, tc_handler = setup_tmtc_handlers(
pus_verificator, printer, raw_logger, setup_wrapper.params.use_gui
pus_verificator, printer, raw_logger, setup_wrapper.params.use_gui, hk_level
)
tmtccmd.setup(setup_wrapper)