STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
HeartbeatRouter.hpp
Go to the documentation of this file.
1#ifndef FSW_HEARTBEAT_ROUTER_HPP
2#define FSW_HEARTBEAT_ROUTER_HPP
3
4#include <chrono>
5#include <cstdint>
6#include <map>
7
8#include "DiabloEnums.h"
9#include "DiabloPackets.h"
11
12namespace fsw {
13namespace routing {
14
15/**
16 * @brief Routes incoming BOARD_HEARTBEAT packets to Elodin DB.
17 *
18 * On each heartbeat:
19 * - Publishes a BoardHeartbeatElodinMessage to packet_id {0x10, board_id}.
20 * - Tracks per-board last-seen time to detect reconnects and Setup re-entry.
21 * - Returns a BoardEvent so the caller (daq_bridge_main) can gate SENSOR_CONFIG re-sends.
22 */
24public:
25 enum class BoardEvent {
27 RECONNECTED, // board was silent >2.5 s, now seen again
28 SETUP_REENTRY, // board transitioned back to SETUP state
29 };
30
31 explicit HeartbeatRouter(elodin::ElodinClient& elodin_client);
32 ~HeartbeatRouter() = default;
33
34 /**
35 * @brief Process one BOARD_HEARTBEAT and publish to Elodin.
36 *
37 * @param header Parsed packet header (for timestamp).
38 * @param heartbeat Parsed heartbeat body (DAQv2: firmware hash + id + states; no board_type on
39 * wire).
40 * @param board_type_wire Legacy wire enum byte for Elodin (from config when known, else 0).
41 * @param receive_ts_ns Monotonic receive timestamp (nanoseconds).
42 * @param elodin_board_id_if_known When >= 0 and <= 255, use this for Elodin packet_id {0x10,
43 * id} and for reconnect state keys — must match config.toml `board_id` so the thin backend
44 * `boardsStatus` and GUI stay aligned. Firmware often uses a slot index (1–8) while config
45 * uses composite IDs (e.g. 21 = PT board 1). Sensor streams still work via slot-based
46 * [0x20,…] IDs, so a wire/config mismatch only breaks board status / heartbeats UI unless
47 * overridden.
48 */
49 BoardEvent process_heartbeat(const daq::PacketHeader& header,
50 const daq::BoardHeartbeatPacket& heartbeat,
51 uint8_t board_type_wire, uint64_t receive_ts_ns,
52 int elodin_board_id_if_known = -1);
53
54private:
56 std::chrono::steady_clock::time_point last_seen;
58 bool seen_before = false;
59 };
60
62 std::map<uint8_t, PerBoardState> board_states_;
63
64 static constexpr auto RECONNECT_THRESHOLD = std::chrono::milliseconds(2500);
65};
66
67} // namespace routing
68} // namespace fsw
69
70#endif // FSW_HEARTBEAT_ROUTER_HPP
Standalone Elodin database client.
static constexpr auto RECONNECT_THRESHOLD
std::map< uint8_t, PerBoardState > board_states_
BoardEvent process_heartbeat(const daq::PacketHeader &header, const daq::BoardHeartbeatPacket &heartbeat, uint8_t board_type_wire, uint64_t receive_ts_ns, int elodin_board_id_if_known=-1)
Process one BOARD_HEARTBEAT and publish to Elodin.
elodin::ElodinClient & elodin_client_
HeartbeatRouter(elodin::ElodinClient &elodin_client)
BoardState
Defines the operational state of a board.
Definition DiabloEnums.h:31
Motorized ball valve position: raw ADC counts -> % open.
std::chrono::steady_clock::time_point last_seen