From 1c4a270bdc6fa421b358057754a684b7f7d2cecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Ku=C3=A7i?= Date: Thu, 26 Mar 2026 21:09:30 +0100 Subject: [PATCH] Added GS status & Dashboard --- ChessSim/Components/CMakeLists.txt | 1 + .../Components/GsStatusStore/CMakeLists.txt | 6 ++ .../GsStatusStore/GsStatusStore.cpp | 37 +++++++++ .../GsStatusStore/GsStatusStore.fpp | 44 +++++++++++ .../GsStatusStore/GsStatusStore.hpp | 31 ++++++++ DeploymentSim/Top/instances.fpp | 6 ++ DeploymentSim/Top/topology.fpp | 19 +++++ README.md | 3 + __pycache__/command_reciever.cpython-312.pyc | Bin 0 -> 3247 bytes command_reciever.py | 72 ++++++++++++++++++ dashboard.xml | 26 +++++++ requirements.txt | 3 + run_local_stack.sh | 15 ++++ 13 files changed, 263 insertions(+) create mode 100644 ChessSim/Components/GsStatusStore/CMakeLists.txt create mode 100644 ChessSim/Components/GsStatusStore/GsStatusStore.cpp create mode 100644 ChessSim/Components/GsStatusStore/GsStatusStore.fpp create mode 100644 ChessSim/Components/GsStatusStore/GsStatusStore.hpp create mode 100644 __pycache__/command_reciever.cpython-312.pyc create mode 100644 command_reciever.py create mode 100644 dashboard.xml create mode 100644 run_local_stack.sh diff --git a/ChessSim/Components/CMakeLists.txt b/ChessSim/Components/CMakeLists.txt index 71acf80..176454f 100644 --- a/ChessSim/Components/CMakeLists.txt +++ b/ChessSim/Components/CMakeLists.txt @@ -2,3 +2,4 @@ # add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/MyComponent") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/CsvTM/") +add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/GsStatusStore/") diff --git a/ChessSim/Components/GsStatusStore/CMakeLists.txt b/ChessSim/Components/GsStatusStore/CMakeLists.txt new file mode 100644 index 0000000..b58d285 --- /dev/null +++ b/ChessSim/Components/GsStatusStore/CMakeLists.txt @@ -0,0 +1,6 @@ +register_fprime_library( + AUTOCODER_INPUTS + "${CMAKE_CURRENT_LIST_DIR}/GsStatusStore.fpp" + SOURCES + "${CMAKE_CURRENT_LIST_DIR}/GsStatusStore.cpp" +) \ No newline at end of file diff --git a/ChessSim/Components/GsStatusStore/GsStatusStore.cpp b/ChessSim/Components/GsStatusStore/GsStatusStore.cpp new file mode 100644 index 0000000..7ebe017 --- /dev/null +++ b/ChessSim/Components/GsStatusStore/GsStatusStore.cpp @@ -0,0 +1,37 @@ +#include "ChessSim/Components/GsStatusStore/GsStatusStore.hpp" + +namespace ChessSim { + +GsStatusStore::GsStatusStore(const char* const compName) + : GsStatusStoreComponentBase(compName) {} + +GsStatusStore::~GsStatusStore() {} + +void GsStatusStore::UPDATE_STATUS_cmdHandler( + const FwOpcodeType opCode, + const U32 cmdSeq, + const Fw::CmdStringArg& gs_status, + const Fw::CmdStringArg& backend_health, + const Fw::CmdStringArg& service_status_raw, + const Fw::CmdStringArg& downlink_status, + const bool pass_active, + const I32 time_to_aos_s, + const I32 time_to_los_s, + const F32 rssi_dbm, + const F32 snr_db +) { + this->tlmWrite_LatestGsStatus(gs_status); + this->tlmWrite_LatestBackendHealth(backend_health); + this->tlmWrite_LatestServiceStatusRaw(service_status_raw); + this->tlmWrite_LatestDownlinkStatus(downlink_status); + this->tlmWrite_LatestPassActive(pass_active); + this->tlmWrite_LatestTimeToAosS(time_to_aos_s); + this->tlmWrite_LatestTimeToLosS(time_to_los_s); + this->tlmWrite_LatestRssiDbm(rssi_dbm); + this->tlmWrite_LatestSnrDb(snr_db); + + this->log_ACTIVITY_HI_StatusUpdated(gs_status, backend_health, pass_active); + this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); +} + +} // namespace ChessSim \ No newline at end of file diff --git a/ChessSim/Components/GsStatusStore/GsStatusStore.fpp b/ChessSim/Components/GsStatusStore/GsStatusStore.fpp new file mode 100644 index 0000000..a6fecfa --- /dev/null +++ b/ChessSim/Components/GsStatusStore/GsStatusStore.fpp @@ -0,0 +1,44 @@ +module ChessSim { + + active component GsStatusStore { + + command recv port cmdIn + command reg port cmdRegOut + command resp port cmdResponseOut + + event port logOut + text event port logTextOut + telemetry port tlmOut + time get port timeGetOut + + async command UPDATE_STATUS( + gs_status: string size 32, + backend_health: string size 32, + service_status_raw: string size 32, + downlink_status: string size 32, + pass_active: bool, + time_to_aos_s: I32, + time_to_los_s: I32, + rssi_dbm: F32, + snr_db: F32 + ) + + telemetry LatestGsStatus: string size 32 format "{}" + telemetry LatestBackendHealth: string size 32 format "{}" + telemetry LatestServiceStatusRaw: string size 32 format "{}" + telemetry LatestDownlinkStatus: string size 32 format "{}" + telemetry LatestPassActive: bool format "{}" + telemetry LatestTimeToAosS: I32 format "{}" + telemetry LatestTimeToLosS: I32 format "{}" + telemetry LatestRssiDbm: F32 format "{}" + telemetry LatestSnrDb: F32 format "{}" + + event StatusUpdated( + gs_status: string size 32, + backend_health: string size 32, + pass_active: bool + ) severity activity high format "GS status={}, backend={}, pass_active={}" + + } + +} \ No newline at end of file diff --git a/ChessSim/Components/GsStatusStore/GsStatusStore.hpp b/ChessSim/Components/GsStatusStore/GsStatusStore.hpp new file mode 100644 index 0000000..419b499 --- /dev/null +++ b/ChessSim/Components/GsStatusStore/GsStatusStore.hpp @@ -0,0 +1,31 @@ +#ifndef CHESSSIM_COMPONENTS_GSSTATUSSTORE_GSSTATUSSTORE_HPP +#define CHESSSIM_COMPONENTS_GSSTATUSSTORE_GSSTATUSSTORE_HPP + +#include "ChessSim/Components/GsStatusStore/GsStatusStoreComponentAc.hpp" + +namespace ChessSim { + +class GsStatusStore : public GsStatusStoreComponentBase { + public: + GsStatusStore(const char* const compName); + ~GsStatusStore() override; + + private: + void UPDATE_STATUS_cmdHandler( + const FwOpcodeType opCode, + const U32 cmdSeq, + const Fw::CmdStringArg& gs_status, + const Fw::CmdStringArg& backend_health, + const Fw::CmdStringArg& service_status_raw, + const Fw::CmdStringArg& downlink_status, + const bool pass_active, + const I32 time_to_aos_s, + const I32 time_to_los_s, + const F32 rssi_dbm, + const F32 snr_db + ) override; +}; + +} // namespace ChessSim + +#endif \ No newline at end of file diff --git a/DeploymentSim/Top/instances.fpp b/DeploymentSim/Top/instances.fpp index b979cf0..4daec5d 100644 --- a/DeploymentSim/Top/instances.fpp +++ b/DeploymentSim/Top/instances.fpp @@ -51,6 +51,12 @@ module DeploymentSim { stack size Default.STACK_SIZE \ priority 100 + + instance gsStatusStore: ChessSim.GsStatusStore base id 0x10005000 \ + queue size Default.QUEUE_SIZE \ + stack size Default.STACK_SIZE \ + priority 98 + # ---------------------------------------------------------------------- # Queued component instances # ---------------------------------------------------------------------- diff --git a/DeploymentSim/Top/topology.fpp b/DeploymentSim/Top/topology.fpp index 10a1b13..a910762 100644 --- a/DeploymentSim/Top/topology.fpp +++ b/DeploymentSim/Top/topology.fpp @@ -34,6 +34,11 @@ module DeploymentSim { instance cmdSeq instance csvTM + # ---------------------------------------------------------------------- + # Ground Software - State + # ---------------------------------------------------------------------- + instance gsStatusStore + # ---------------------------------------------------------------------- # Pattern graph specifiers # ---------------------------------------------------------------------- @@ -134,6 +139,20 @@ module DeploymentSim { } + # connections GsStatusStore_CdhCore { + # CdhCore.cmdDisp.compCmdSend[0] -> gsStatusStore.cmdIn + # gsStatusStore.cmdRegOut -> CdhCore.cmdDisp.compCmdReg[0] + #gsStatusStore.cmdResponseOut -> CdhCore.cmdDisp.compCmdStat[0] +# + # gsStatusStore.logOut -> CdhCore.events.LogRecv + # #gsStatusStore.logTextOut -> CdhCore.textLogger.TextRecv + # gsStatusStore.tlmOut -> CdhCore.tlmSend.TlmRecv + # gsStatusStore.timeGetOut -> chronoTime.timeGet + #} + + + + } } diff --git a/README.md b/README.md index bf84678..4819eda 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ This installs: * F′ core tools, * the F′ GDS, * and all required Python dependencies. +* Fast API to run the command interface No additional packages are needed. @@ -108,6 +109,8 @@ Open that address in a browser. You should see: * telemetry updating once per second from `sim_data.csv`, * the `DeploymentSim` executable running automatically. +If you want the custom Dashboard view, open the `Dashboard` tab and upload `dashboard.xml` from the repository root. + --- ## 7. Stopping and restarting diff --git a/__pycache__/command_reciever.cpython-312.pyc b/__pycache__/command_reciever.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..48a01ae69a62ead3ade06e493f88dc7d83378a0d GIT binary patch literal 3247 zcmb6bU2GJ`dG_aa_x=x`|G-c#jcam^&u3Z!Qc6ha*$!?nShkVMMdY;XjO{)4ZjaeL zY+vliAyhF674TAn+KRTS6e3fV$2_(Vl`6Flci5`08>B{Rss2b(mSr#{%|uN5q3Y_oNlz#9G=17>@WG^X%>|{C2ofpJexJ z$8L?&AriuJ$&V0LT*7HWqvr+kOYUXpvKAR z7N9<`19jvn^)3>b7-_FwD6e$=l<4&JnS$*`@AhkP~LXG|Z{F0a${QRXW#~wamP>UA?-M z(8jBPT}A|@IgHZ$8AJpkV(utlnJ0;Kk8fBYEfa|d%zZ#1Fp4=b?r}nO9mdGTBC%{o z*0yv4Rl=A|szt-jFbzyP=Xg~*Rb--Dr{apEWHNa*M=}}5m&xQzTr}7?kjY#usz!Z9 zux#ptGZ{6XH*J-vV`VZ_hQl4v&|xtG!;jGhK=kB9GMBfLTJnrVsFnPonNJQ7>w;|- zk~#GPNm5cUEgb~WiIq&97#tr@jHJesb$K(CXgUEO^cCi45ZJk37Yr;GmOn<-VC4Oi zf9s0fZ(Zv;yg0mM-$-4ZTN4k{&IWNwPEHfmu&19fH4n?o+#4+aAh|fq>)bes3#T03 zyf8sK*mf7VjF^EPX^Rit3zK&EtpI>U^jRQsqkHLSS?q8REd?9GCoGc3jzGypt)6#4 zj}SZ2J^B#9Wn{ZZ2C@wMTx-O&)oM5Dfh%lt*U!)|_B`jkFd$G@E zUU6GFS1 za|^u9T;?_$z`<;|F>CfXbOp`x15b0l!Ka}Qhiv9;w`E%zqh>$P<1l;?yS0J4w`-+t zsRdzP$TCMg*J$@PxmtFn`KpT8lnwUoP#vG)AKjVe|K`tv?YV|qFC2mB9NQidU;mU@ z&U%?cUtfFJ7ls?A4R-Dz+n1s-yffX-=K^*Id*b$=i{lVeoEuj&DBf{O--L`RwKt1t z3@TA<(k$ljt1+nRehcbS(aLC0*c}NITh)z{Z?Zu397$+~UJBF;jGLn+Um{`KRzk&? zmb?eQbEK~yzJm>P!KAk1d8NPqmHtv7kzmDrtAdyO3AhXD#j_N7YiM+Acw{h^IyoFm zjSQS~xY#p^FM=Px3;)ItfHx5b$v=dEqz3kKXy!JNFNM^lqgm_1I#HT;BfzH!&0!osgy$ z>>?!@vuGEJwjCaQe)|xvkOQ*w{JBWGn4$IwUp;9wIn4 zqubLl=CxQ{q+LMd_$UGP`7KXcHilyy33@_lJnVP}hEo%n(c=>*9Er@r-D6Rf{gjmh z8e)LmMUDqNp9k5prk;0vR`Gm+ni{bzsLsW_BaWRuJwch?U`m_n1)5|#697PpeGD&v zpFx`(b|gwHxISGY#GtwMbsF)MVMe9jgDp&WYZCmrh(7nXuKT+x{;oCuzK5Z%yF&T! z$-kWa)0^c(KUxc&Eh}eh67sfHmG-LAT2-Ph48!!H;=eZhVW_J3uluk1t4dp~E#Q}G z?P&iu@8oXh{_5?$VO@K1N&Cr554^p#4p>`EZSF-LU)i_!mUd_Q_B6Qb6Kky}wfc?J znmF)zu;cpMSKkJH)sC)ea91@HeHe&r`lXPxI8=)uCG^3<<%Neza4CDM=T72wVtr4d zvL~^+C%LBdSLNVWtbQg3*X7QN+q?{UDC-_Xi9yN-($Tr6vs%7ZhT9wF?jA;Igb1yDFzZQr}zexTBR zpxV;8oVb~&caOZDfK)>skM#J9gUFY#;Q5UHu)AfbO^UZUaseKGhJK#1E0uOLa0q}S zPr^G;E$Ebmup23kQkcVP-qtnBIBdOQ1hr6LFQG|@NqGIp;BwQr1eK(qQg|rQ!;G?@ z0d~PT!W6OHSAiqKW5#yf|J>u@iE?!7F?Ea%!WNe9)?ENKf#bM;qRvlI;8V2gU+CL^ zN8frRAvsiT?OBr!EDA7D0!t^}e|KHpSCRLv%KO*lo{HSFC{_cJaFwQCD3<& ze + + + + + + + + + + \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index bdf85ba..465aa02 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,6 @@ # Local requirements: -r ./lib/fprime/requirements.txt + +fastapi==0.135.2 +uvicorn==0.42.0 diff --git a/run_local_stack.sh b/run_local_stack.sh new file mode 100644 index 0000000..c7532d0 --- /dev/null +++ b/run_local_stack.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -e + +source .venv/bin/activate + +uvicorn command_reciever:app --host 0.0.0.0 --port 8091 & +API_PID=$! + +cleanup() { + kill $API_PID 2>/dev/null || true +} +trap cleanup EXIT + +cd DeploymentSim +fprime-gds -n --dictionary ../build-artifacts/Linux/DeploymentSim/dict/DeploymentSimTopologyDictionary.json \ No newline at end of file