73 std::chrono::steady_clock::time_point
deadline)
81 std::chrono::steady_clock::time_point
deadline;
91 return "invalid channel";
93 return "invalid value";
95 return "not connected";
97 return "communication failure";
99 return "command queue rejected the request";
101 return "protocol rejected the request";
103 return "value unavailable";
105 return "invalid connection state";
107 return "device busy";
109 return "operation cancelled";
111 return "unknown error";
128 return "heater enabled state";
130 return "heater mode";
137 return operation.
kind == kind && operation.
index == index;
142 operations.erase(std::remove_if(operations.begin(), operations.end(),
145 return sameLogicalOperation(operation, replacement.kind, replacement.index);
146 }), operations.end());
147 operations.push_back(replacement);
173 std::chrono::steady_clock::time_point now)
213 if (std::strcmp(name,
"AUTO") == 0)
218 if (std::strcmp(name,
"MANUAL_PWM") == 0)
223 if (std::strcmp(name,
"SWITCH") == 0)
255 const auto *payload = std::get_if<instrumentation::ConnectionPayload>(&event.
payload);
256 if (payload ==
nullptr)
259 switch (payload->state)
276 std::lock_guard<std::mutex> lock(mutex_);
279 stagedTelemetry_.emplace(snapshot);
280 latestTelemetry_.emplace(snapshot);
281 telemetryDirty_ =
true;
287 std::lock_guard<std::mutex> lock(mutex_);
290 stagedConnectionEvents_.push_back(event);
296 std::lock_guard<std::mutex> lock(mutex_);
297 if (!telemetryDirty_ || !stagedTelemetry_)
299 std::optional<TelemetrySnapshot> snapshot;
300 snapshot.emplace(*stagedTelemetry_);
301 telemetryDirty_ =
false;
307 std::lock_guard<std::mutex> lock(mutex_);
308 if (!latestTelemetry_)
310 std::optional<TelemetrySnapshot> snapshot;
311 snapshot.emplace(*latestTelemetry_);
317 std::lock_guard<std::mutex> lock(mutex_);
318 std::deque<ConnectionEvent> events;
319 events.swap(stagedConnectionEvents_);
325 std::lock_guard<std::mutex> lock(mutex_);
326 stagedTelemetry_.reset();
327 latestTelemetry_.reset();
328 stagedConnectionEvents_.clear();
329 telemetryDirty_ =
false;
334 std::lock_guard<std::mutex> lock(mutex_);
336 stagedTelemetry_.reset();
337 latestTelemetry_.reset();
338 stagedConnectionEvents_.clear();
339 telemetryDirty_ =
false;
343 mutable std::mutex mutex_;
344 std::optional<TelemetrySnapshot> stagedTelemetry_;
345 std::optional<TelemetrySnapshot> latestTelemetry_;
346 std::deque<ConnectionEvent> stagedConnectionEvents_;
347 bool telemetryDirty_ =
false;
348 bool shutdown_ =
false;
static ValueResult< OperationTarget > usbOutput(std::size_t channel, bool enabled)
static ValueResult< OperationTarget > heaterEnabled(std::size_t channel, bool enabled)
static ValueResult< OperationTarget > dcOutput(std::size_t channel, bool enabled)
static ValueResult< OperationTarget > heaterMode(std::size_t channel, HeaterMode mode)
static ValueResult failure(Error error)
std::optional< TelemetrySnapshot > takeTelemetry()
bool stageTelemetry(const TelemetrySnapshot &snapshot)
std::optional< TelemetrySnapshot > latestTelemetry() const
std::deque< ConnectionEvent > takeConnectionEvents()
bool stageConnectionEvent(ConnectionEvent event)
const char * errorName(Error error)
ValueResult< OperationTarget > makeHeaterModeTarget(std::size_t index, HeaterMode mode)
bool heaterModeFromSwitchName(const char *name, HeaterMode &mode)
std::size_t heaterModeSwitchIndex(HeaterMode mode)
bool instrumentationDuplicatesSemanticDriverLog(const instrumentation::Event &event)
DriverPropertyState propertyStateForImmediateResult(Result result)
bool manualPowerIsTelemetryConfirmable()
ValueResult< OperationTarget > makeBooleanTarget(PendingOperationKind kind, std::size_t index, bool enabled)
PendingEvaluation evaluatePendingOperation(const PendingOperation &operation, const TelemetrySnapshot *snapshot, std::chrono::steady_clock::time_point now)
bool sameLogicalOperation(const PendingOperation &operation, PendingOperationKind kind, std::size_t index)
const char * heaterModeName(HeaterMode mode)
void replacePendingOperation(std::vector< PendingOperation > &operations, PendingOperation replacement)
const char * pendingOperationName(PendingOperationKind kind)
Confirmation confirmOperation(const DcOutputTarget &target, const TelemetrySnapshot *snapshot)
PendingOperationKind kind
std::chrono::steady_clock::time_point deadline
PendingOperation(PendingOperationKind kind, std::size_t index, OperationTarget target, std::chrono::steady_clock::time_point deadline)