Skip to content
Draft
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
18 changes: 18 additions & 0 deletions daq-server/config/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ interval_ms = 200 # Same as server_heartbeat
broadcast_ip = "192.168.2.255"
broadcast_port = 5005

# =============================================================================
# Stacklight Service - STACKLIGHT_COMMAND to stacklight board (C++)
# =============================================================================
[stacklight_service]
enabled = true
interval_ms = 1000 # Keepalive resend interval (state changes send immediately)
target_ip = "192.168.2.70" # Should match boards.stacklight_board.ip
target_port = 5005 # Should match boards.stacklight_board.listen_port
elodin_host = "127.0.0.1"
elodin_port = 2240

# =============================================================================
# Config Broadcast Service - ACTUATOR_CONFIG / SENSOR_CONFIG to boards (C++ preferred for flight)
# =============================================================================
Expand Down Expand Up @@ -339,6 +350,13 @@ necessary_for_abort = false
designated_survivor = false
voltage_reference = 1
active_connectors = [1, 2]
[boards.stacklight_board]
type = "STACKLIGHT"
ip = "192.168.2.70" # PLACEHOLDER — update once team assigns a real IP
listen_port = 5005 # Board listens for STACKLIGHT_COMMAND here
board_id = 70 # PLACEHOLDER — update once team confirms
enabled = true
enable_serial_printing = false

# =============================================================================
# Multiple Boards Example (commented out - uncomment to use)
Expand Down
73 changes: 71 additions & 2 deletions daq-server/diablo_server/frontend/app/status/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,45 @@ const HP_PT_SENSORS = PRESSURE_SENSORS.filter((s) =>
['PT_Cal.GSE_Mid', 'PT_Cal.GSE_High', 'PT_Cal.GN2_High'].includes(s.entity)
).map(({ label, entity, color }) => ({ label, entity, color }));

interface StacklightState {
red: boolean;
yellow: boolean;
green: boolean;
buzzer: boolean;
}

/**
* Mirrors stateToStacklight() in
* daq-server/diablo_server/services/stacklight/stacklight_service_main.cpp
* Keep these two in sync manually — no shared source of truth yet.
*/
function sequencerStateToStacklight(state: number | null): StacklightState {
const off: StacklightState = { red: false, yellow: false, green: false, buzzer: false };
if (state === null) return off;

switch (state) {
case 1: // IDLE
return { ...off, green: true };
case 0: // DEBUG
case 14: // CALIBRATE
case 6: case 8: case 10: case 12: case 13: // VENT states
return { ...off, yellow: true };
case 2: // ARMED
case 15: // READY
case 20: // PRESS_STANDBY
return { ...off, red: true, yellow: true };
case 3: case 4: // FUEL_FILL, OX_FILL
case 5: case 7: case 9: case 11: // PRESS states
return { ...off, red: true };
case 16: // FIRE
return { ...off, red: true, buzzer: true };
case 17: case 18: case 19: // ABORT states
return { ...off, red: true, buzzer: true };
default: // UNKNOWN
return { red: true, yellow: true, green: true, buzzer: true };
}
}

function fmtValue(v: number | null): string {
if (v === null || !isFinite(v)) return '---';
const abs = Math.abs(v);
Expand Down Expand Up @@ -69,7 +108,7 @@ export default function StatusPage() {
</div>
</div>

<div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
<div className="grid grid-cols-1 lg:grid-cols-4 gap-4">
{/* Pressure Sensors */}
<div className="bg-card rounded-lg p-4 border border-gray-800">
<h2 className="text-lg font-bold text-text-muted uppercase tracking-wider mb-3">Pressure Sensors</h2>
Expand Down Expand Up @@ -194,7 +233,37 @@ export default function StatusPage() {
</div>
)}
</div>
</div>

{/* Stacklight */}
<div className="bg-card rounded-lg p-4 border border-gray-800">
<h2 className="text-lg font-bold text-text-muted uppercase tracking-wider mb-3">Stacklight</h2>
{(() => {
const light = sequencerStateToStacklight(currentState);
const dot = (on: boolean, color: string) =>
`w-8 h-8 rounded-full border-2 border-gray-700 ${on ? color : 'bg-gray-900'}`;
return (
<div className="flex items-center justify-around py-4">
<div className="flex flex-col items-center gap-2">
<div className={dot(light.red, 'bg-red-500 shadow-[0_0_12px_2px_rgba(239,68,68,0.7)]')} />
<span className="text-xs text-text-muted font-mono uppercase">Red</span>
</div>
<div className="flex flex-col items-center gap-2">
<div className={dot(light.yellow, 'bg-yellow-400 shadow-[0_0_12px_2px_rgba(250,204,21,0.7)]')} />
<span className="text-xs text-text-muted font-mono uppercase">Yellow</span>
</div>
<div className="flex flex-col items-center gap-2">
<div className={dot(light.green, 'bg-green-500 shadow-[0_0_12px_2px_rgba(34,197,94,0.7)]')} />
<span className="text-xs text-text-muted font-mono uppercase">Green</span>
</div>
<div className="flex flex-col items-center gap-2">
<div className={`text-2xl ${light.buzzer ? 'text-amber-400 animate-pulse' : 'text-gray-700'}`}>🔊</div>
<span className="text-xs text-text-muted font-mono uppercase">Buzzer</span>
</div>
</div>
);
})()}
</div>
</div>

{/* High Pressure PT Sensors Section */}
<div className="mt-4">
Expand Down
1 change: 1 addition & 0 deletions daq-server/diablo_server/frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions daq-server/diablo_server/services/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ target_link_libraries(heartbeat_service
fsw_daq_lib daq_comms_lib Threads::Threads pthread ${RT_LIBRARY}
)

# ── Stacklight Service ────────────────────────────────────────────────────────
# STACKLIGHT_COMMAND UDP unicast; reads sequencer state from Elodin [0x5000]
add_executable(stacklight_service stacklight/stacklight_service_main.cpp)
target_include_directories(stacklight_service PRIVATE ${COMMON_INCLUDES})
target_link_libraries(stacklight_service
fsw_daq_lib daq_comms_lib daqv2_comms Threads::Threads pthread ${RT_LIBRARY}
)

# ── Config Broadcast Service ──────────────────────────────────────────────────
# ACTUATOR_CONFIG / SENSOR_CONFIG UDP broadcast
add_executable(config_broadcast_service config_broadcast/config_broadcast_service_main.cpp)
Expand Down Expand Up @@ -86,5 +94,6 @@ endif()
install(TARGETS
sequencer_service controller_service calibration_service
heartbeat_service config_broadcast_service ota_service data_logger_service
stacklight_service
RUNTIME DESTINATION bin
)
Loading