34std::array<uint8_t, 2>
table_id(uint8_t slot, uint8_t ain);
62class T7Error :
public std::runtime_error {
78 virtual void open(
const std::string& ip) = 0;
80 virtual void write_names(
const std::vector<std::string>& names,
81 const std::vector<double>& values) = 0;
83 virtual std::vector<double>
read_names(
const std::vector<std::string>& names) = 0;
85 virtual double stream_start(
const std::vector<std::string>& scan_names,
int scans_per_read,
86 double scan_rate_hz) = 0;
104 std::vector<std::optional<config::T7Channel>>
channels;
146 using Clock = std::function<uint64_t()>;
160 void stop() noexcept;
215 explicit FakeT7Unit(std::string state_path =
"");
223 double reg(
const std::string& name,
double fallback = 0.0)
const;
259 std::function<double(
int ain,
double t)>
signal;
262 std::shared_ptr<FakeT7Unit>
unit;
274 void open(
const std::string& ip)
override;
276 void write_names(
const std::vector<std::string>& names,
277 const std::vector<double>& values)
override;
278 std::vector<double>
read_names(
const std::vector<std::string>& names)
override;
280 double scan_rate_hz)
override;
281 Backlog
stream_read(std::vector<double>& data)
override;
283 void close()
override;
287 std::vector<std::pair<std::string, double>>
writes;
299 double volts(
int ain,
double t)
const;
Per-board clock sync for DAQ sample timestamping.
double stream_start(const std::vector< std::string > &scan_names, int scans_per_read, double scan_rate_hz) override
Starts the stream; returns the scan rate the device will actually run at.
std::vector< std::string > scan_names
Backlog stream_read(std::vector< double > &data) override
Fills data with scans_per_read scans, channels interleaved.
void write_names(const std::vector< std::string > &names, const std::vector< double > &values) override
void stream_stop() override
void open(const std::string &ip) override
uint64_t my_stream_
unit stream_id this handle started; 0 = none
int64_t serial_number() override
std::vector< std::string > reads
every name read_names() was asked for
std::vector< double > read_names(const std::vector< std::string > &names) override
Command-response reads; only valid while no stream is running.
bool streaming
this handle's own stream is running
std::vector< std::pair< std::string, double > > writes
double volts(int ain, double t) const
Volts on ain at t: Options::signal, else the default described above.
The stand-in T7 itself, as distinct from a connection to it.
std::vector< std::pair< std::string, double > > registers
last value written per name
void load()
from state_path; no-op without one or when the file is absent
void power_cycle()
Power off and on: no stream, registers back to defaults.
std::vector< std::string > scan_names
the running (or last) stream's scan list
void set_reg(const std::string &name, double value)
FakeT7Unit(std::string state_path="")
uint64_t stream_id
bumped by every stream start; a handle reads only its own stream
virtual double stream_start(const std::vector< std::string > &scan_names, int scans_per_read, double scan_rate_hz)=0
Starts the stream; returns the scan rate the device will actually run at.
virtual ~T7Device()=default
virtual int64_t serial_number()=0
virtual void write_names(const std::vector< std::string > &names, const std::vector< double > &values)=0
virtual void stream_stop()=0
virtual void open(const std::string &ip)=0
virtual std::vector< double > read_names(const std::vector< std::string > &names)=0
Command-response reads; only valid while no stream is running.
virtual Backlog stream_read(std::vector< double > &data)=0
Fills data with scans_per_read scans, channels interleaved.
T7Error(const std::string &what, int code=0)
Block read()
Reads and decodes one block.
double actual_rate_hz() const
double start()
Opens the device, checks its serial number if the config gives one, writes the setup,...
std::vector< double > buffer_
const config::T7Board & board() const
int64_t serial() const
The device's serial number, read by start(); 0 before then.
time::BoardClockSync clock_sync_
double cjc_device_offset_k() const
AIN14 offset taken at start (K); see t7::cjc_device_offset_k.
T7Session(config::T7Board board, std::unique_ptr< T7Device > device, const time::TimeSyncConfig &time_sync, Clock clock)
const StreamPlan & plan() const
std::function< uint64_t()> Clock
epoch ns
bool stopped_leftover_stream() const
start() found a stream already running on the device (left by a bridge that was killed,...
double cjc_device_offset_k_
std::unique_ptr< T7Device > device_
void stop() noexcept
Stops the stream and closes the device; never throws.
LJM and device error codes the session acts on (labjack/ljm_constants, LJM errorcodes).
constexpr int kStreamNotInitialized
LJME_STREAM_NOT_INITIALIZED (LJM, this handle).
constexpr int kDeviceStreamNotRunning
device: "Stream was already disabled"
constexpr int kStreamNotRunning
LJME_STREAM_NOT_RUNNING.
constexpr int kSynchronizationTimeout
LJME_SYNCHRONIZATION_TIMEOUT (no stream data).
constexpr int kStreamIsActive
device: "can not be performed while stream is running"
StreamPlan plan_stream(const config::T7Board &board)
bool is_stream_not_running(int code)
True for every way a stop can answer "there was no stream to stop".
std::string entity_name(uint8_t slot, uint8_t ain)
Elodin entity name for one AIN, e.g.
constexpr uint8_t kTypeHi
Elodin table-id high byte for T7 analog inputs (0x20-0x25 are the ESP32 sensor types).
std::array< uint8_t, 2 > calibrated_table_id(uint8_t slot, uint8_t ain)
Calibrated table for one AIN: table_id + 0x10, e.g.
std::array< uint8_t, 2 > table_id(uint8_t slot, uint8_t ain)
Table id for one AIN: {0x26, (slot-1)*0x20 + ain}, the same layout as the ESP32 boards.
constexpr uint8_t kCjcAin
The T7's internal temperature sensor, streamed for thermocouple cold-junction compensation whenever a...
std::string calibrated_entity_name(uint8_t slot, uint8_t ain)
Calibrated entity name, e.g.
constexpr double kDummyValue
What LJM writes into a scan lost to stream auto-recovery (LJM_DUMMY_VALUE).
Motorized ball valve position: raw ADC counts -> % open.
A decoded LJM_eStreamRead block.
uint64_t skipped_samples
values that were kDummyValue (auto-recovery), not published
uint64_t scans
scans in the block, including lost ones
std::vector< Sample > samples
std::vector< ColdJunction > cold_junction
One per scan with a readable AIN14, on a board with a TC; empty otherwise.
T7Device::Backlog backlog
One scan's thermocouple cold-junction temperature (the T7's terminals), in °C.
bool stop_only_own_stream
LJM answers eStreamStop locally (1225) on a handle that did not start the stream, without telling the...
int fail_read_after
>=0: throw on the read after this many succeed
double rate_cap_hz
>0: the "device" rounds the scan rate down to this
std::function< double(int ain, double t)> signal
Volts on ain at t seconds into the stream; empty = the default sine.
uint64_t dummy_scan_every
>0: every Nth scan comes back as kDummyValue
double device_temp_k
what TEMPERATURE_DEVICE_K (and AIN14) report
std::shared_ptr< FakeT7Unit > unit
The device this handle talks to; null = a fresh unit of its own.
int fail_stop_code
!=0: every stream stop fails with this code (e.g.
bool realtime
sleep each read as long as the scans would take
uint32_t sample_ms
ms since stream start (wraps at 2^32)
What to write before streaming and what to stream, derived from a board's config.
std::vector< std::optional< config::T7Channel > > channels
The configured channel behind each scan entry; nullopt for AIN14 (CJC).
std::vector< uint8_t > ains
same order as scan_names
std::vector< double > setup_values
std::vector< std::string > scan_names
"AIN1", ... in config order, then AIN14 for CJC
int cjc_index
position of AIN14 in the scan, or -1 when there is no TC
std::vector< std::string > setup_names
int device_scans
scans still in the T7's buffer
int ljm_scans
scans still in LJM's buffer
std::string board(const std::string &name, const std::string &id, bool enabled=true)