Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ChessSim/Components/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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/")
6 changes: 6 additions & 0 deletions ChessSim/Components/GsStatusStore/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
register_fprime_library(
AUTOCODER_INPUTS
"${CMAKE_CURRENT_LIST_DIR}/GsStatusStore.fpp"
SOURCES
"${CMAKE_CURRENT_LIST_DIR}/GsStatusStore.cpp"
)
37 changes: 37 additions & 0 deletions ChessSim/Components/GsStatusStore/GsStatusStore.cpp
Original file line number Diff line number Diff line change
@@ -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
44 changes: 44 additions & 0 deletions ChessSim/Components/GsStatusStore/GsStatusStore.fpp
Original file line number Diff line number Diff line change
@@ -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={}"

}

}
31 changes: 31 additions & 0 deletions ChessSim/Components/GsStatusStore/GsStatusStore.hpp
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions DeploymentSim/Top/instances.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
# ----------------------------------------------------------------------
Expand Down
19 changes: 19 additions & 0 deletions DeploymentSim/Top/topology.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ module DeploymentSim {
instance cmdSeq
instance csvTM

# ----------------------------------------------------------------------
# Ground Software - State
# ----------------------------------------------------------------------
instance gsStatusStore

# ----------------------------------------------------------------------
# Pattern graph specifiers
# ----------------------------------------------------------------------
Expand Down Expand Up @@ -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
#}




}

}
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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
Expand Down
Binary file added __pycache__/command_reciever.cpython-312.pyc
Binary file not shown.
72 changes: 72 additions & 0 deletions command_reciever.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# comand_reciever.py
from pathlib import Path
import shlex
import subprocess

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field


app = FastAPI(title="Command Receiver")


ROOT = Path(__file__).resolve().parent
DICT_PATH = ROOT / "build-artifacts" / "Linux" / "DeploymentSim" / "dict" / "DeploymentSimTopologyDictionary.json"


class CommandRequest(BaseModel):
command: str
arguments: list[str] = Field(default_factory=list)


@app.get("/health")
def health():
return {"ok": True}


@app.post("/command-send")
def command_send(req: CommandRequest):
if not DICT_PATH.exists():
raise HTTPException(status_code=500, detail=f"Dictionary not found: {DICT_PATH}")

cmd = [
"fprime-cli",
"command-send",
"--tts-addr",
"127.0.0.1",
"--tts-port",
"50050",
"--dictionary",
str(DICT_PATH),
req.command,
"--arguments",
*[str(arg) for arg in req.arguments],
]

print("[FPRIME CLI CMD]", " ".join(shlex.quote(x) for x in cmd))

result = subprocess.run(
cmd,
capture_output=True,
text=True,
check=False,
cwd=ROOT,
)

if result.stdout:
print("[STDOUT]", result.stdout.strip())
if result.stderr:
print("[STDERR]", result.stderr.strip())

if result.returncode != 0:
raise HTTPException(
status_code=500,
detail=result.stderr.strip() or result.stdout.strip() or f"fprime-cli failed with code {result.returncode}",
)

return {
"ok": True,
"returncode": result.returncode,
"stdout": result.stdout,
"stderr": result.stderr,
}
26 changes: 26 additions & 0 deletions dashboard.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<dashboard-box title="GS Status Dashboard" border-color="black">

<dashboard-box title="GS Status" border-color="gray">
<channel-table
fields="'Channel Name' 'Channel Value' 'Last Sample Time'"
items-shown="
DeploymentSim.gsStatusStore.LatestGsStatus
DeploymentSim.gsStatusStore.LatestBackendHealth
DeploymentSim.gsStatusStore.LatestServiceStatusRaw
DeploymentSim.gsStatusStore.LatestDownlinkStatus
DeploymentSim.gsStatusStore.LatestPassActive
DeploymentSim.gsStatusStore.LatestTimeToAosS
DeploymentSim.gsStatusStore.LatestTimeToLosS
DeploymentSim.gsStatusStore.LatestRssiDbm
DeploymentSim.gsStatusStore.LatestSnrDb
"
/>
</dashboard-box>

<dashboard-box title="Events" border-color="gray">
<event-list
fields="'Event Time' 'Event Name' 'Event Severity' 'Event Description'"
/>
</dashboard-box>

</dashboard-box>
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@

# Local requirements:
-r ./lib/fprime/requirements.txt

fastapi==0.135.2
uvicorn==0.42.0
15 changes: 15 additions & 0 deletions run_local_stack.sh
Original file line number Diff line number Diff line change
@@ -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