STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
SensorTables.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <optional>
5#include <string>
6#include <utility>
7#include <vector>
8
9#include "config/Config.hpp"
10
11namespace fsw {
12namespace config {
13
14/**
15 * Where a named PT sensor role lives: which board, which channel, and which Elodin table its
16 * calibrated pressure is published on.
17 *
18 * This walk — a name -> [sensor_roles_<board_key>] -> board -> table id — used to exist inline in
19 * exactly one place (config_broadcast_service_main.cpp) and nowhere else, so every other consumer
20 * that wanted a live pressure by name reached for a hardcoded channel number instead. That is how
21 * ControllerService ended up assigning `P_copv` from channel 6, which is "GN2 Regulated" on this
22 * rig and not the COPV at all, and how its subscriber filter came to drop every sensor on PT board
23 * 2 — "GN2 High" included. Resolving by role through config makes both unrepresentable.
24 */
25struct PtRoleRef {
26 /** The ESP32 PT board declaring this role. Points into the Config that was passed in, so it is
27 * valid exactly as long as that Config is. Null exactly when `t7` is set. */
28 const BoardConfig* board = nullptr;
29 /** The LabJack T7 this PT input is on (a [[boards.<name>.channels]] row with kind = "PT"), or
30 * null for an ESP32 PT. Its pressure arrives on the T7 calibrated table in the same message
31 * layout, so a pressure reader needs only table(); anything that talks to the board itself
32 * (abort thresholds in a config packet) must skip it. */
33 const T7Board* t7 = nullptr;
34 /** The board's section name with the "boards." prefix stripped, e.g. "pt_board_2". This is the
35 * suffix every per-board section is keyed by: sensor_roles_<key>, calibration_model_<key>,
36 * calibration_full_scale_<key>. Resolved here so callers do not each re-derive it. */
37 std::string board_key;
38 /** Canonical role name as config spells it, e.g. "GN2 High" — not a slug. */
39 std::string role;
40 /** Connector channel on that board, 1-based, straight from [sensor_roles_<key>]; the AIN
41 * number for a T7 input. */
42 int channel = 0;
43 /** Elodin slot, BoardConfig::slot() — board_id % 10, with 0 meaning 10. */
44 uint8_t board_number = 0;
45
46 /**
47 * The calibrated-PT table this sensor publishes on: {0x20, (slot-1)*0x20 + 0x10 + channel},
48 * or {0x26, (slot-1)*0x20 + 0x10 + ain} for a T7 input (t7::calibrated_table_id).
49 *
50 * The encoding is DatabaseConfig.cpp's, which is what actually registers the VTables — not
51 * [routing.pt_calibrated]'s description string, which claims board 2 lives at 0x1B-0x1E, has
52 * no consumer anywhere in the tree, and is wrong.
53 */
54 uint8_t table_hi = 0x20;
55 uint8_t table_lo = 0;
56
57 std::pair<uint8_t, uint8_t> table() const {
58 return {table_hi, table_lo};
59 }
60};
61
62/**
63 * Every PT sensor role declared by an enabled PT board, in board-declaration order, then every
64 * PT input on an enabled LabJack T7 (none while the T7 config has errors, as t7_bridge then
65 * refuses to stream).
66 *
67 * Boards that are disabled, not of type "PT", or carry no usable board_id are skipped, matching
68 * what the config-broadcast abort-threshold path has always done. A role declared on more than one
69 * board appears once per board; callers wanting a single answer should use find_pt_role.
70 */
71std::vector<PtRoleRef> pt_role_tables(const Config& cfg);
72
73/**
74 * Resolve one role by its canonical config name.
75 *
76 * First enabled PT board that declares the name wins, in config order — the same "not on this
77 * board, keep looking" rule the inline walk used — then the T7 PT inputs. (A role on both is
78 * refused by config validation.) Returns nullopt when no enabled PT board
79 * declares it, which callers must treat as a refusal rather than a default: a sensor that cannot
80 * be located has no safe stand-in value.
81 */
82std::optional<PtRoleRef> find_pt_role(const Config& cfg, const std::string& role);
83
84/** The board's section name minus a leading "boards.", e.g. "boards.pt_board_2" -> "pt_board_2". */
85std::string board_key_of(const BoardConfig& b);
86
87} // namespace config
88} // namespace fsw
*brief create JSON pointer *sa reference_tokens const string_t const string_t & b
Definition json.hpp:13878
std::optional< PtRoleRef > find_pt_role(const Config &cfg, const std::string &role)
Resolve one role by its canonical config name.
std::string board_key_of(const BoardConfig &b)
The board's section name minus a leading "boards.", e.g.
std::vector< PtRoleRef > pt_role_tables(const Config &cfg)
Every PT sensor role declared by an enabled PT board, in board-declaration order, then every PT input...
Motorized ball valve position: raw ADC counts -> % open.
Where a named PT sensor role lives: which board, which channel, and which Elodin table its calibrated...
int channel
Connector channel on that board, 1-based, straight from [sensor_roles_<key>]; the AIN number for a T7...
const BoardConfig * board
The ESP32 PT board declaring this role.
const T7Board * t7
The LabJack T7 this PT input is on (a [[boards.
uint8_t board_number
Elodin slot, BoardConfig::slot() — board_id % 10, with 0 meaning 10.
std::pair< uint8_t, uint8_t > table() const
std::string role
Canonical role name as config spells it, e.g.
std::string board_key
The board's section name with the "boards." prefix stripped, e.g.
uint8_t table_hi
The calibrated-PT table this sensor publishes on: {0x20, (slot-1)*0x20 + 0x10 + channel}...