Skip to main content

Crate bhtune_core

Crate bhtune_core 

Source
Expand description

bhtune-core — the pure, I/O-free domain crate.

This crate holds (once implemented — see AGENTS.md for phase status):

  • The MRFT (Modified Relay Feedback Test) tuning algorithm, as a pure state machine: fn step(&mut self, tick: Tick) -> Vec<Action>. No clock reads, no network calls, no UI access — that constraint is what makes it possible to replay a recorded trace and assert the engine produces bit-identical results across changes.
  • The tuning-constant lookup matrices and PID unit conversion math.
  • The domain data model: tag maps, loop configuration, DCS/PLC template semantics, and the enums that model PID parameter types and controller direction.

Deliberately has no I/O, no async, and no clock reads (chrono’s clock/now features are disabled workspace-wide, so Utc::now() cannot even compile here — see core-mrft in AGENTS.md). This is a narrower rule than “no dependencies”: toml is a real dependency (template-catalog), justified because parsing an include_str!- embedded &'static str is not I/O; the optional, feature-gated utoipa dependency (openapi-contract) is justified the same way — a compile-time derive macro that describes a type’s shape, with zero runtime behavior of its own. Anything added here must be justified by the pure domain logic itself (or, for utoipa, by describing it accurately to a consumer), not by a consumer’s I/O or presentation needs — those belong in bhtune-driver, bhtune-db, bhtune-cli, or bhtune-server.

Re-exports§

pub use constants::ResponseLevel;
pub use constants::TuningConstants;
pub use constants::lookup;
pub use controller_type::ControllerType;
pub use direction::ControllerDirection;
pub use loop_config::LoopConfig;
pub use loop_config::LoopConfigError;
pub use mrft::Action;
pub use mrft::InitialReadings;
pub use mrft::MrftCompat;
pub use mrft::MrftEngine;
pub use mrft::MrftState;
pub use mrft::Tick;
pub use pid_config::DerivativeType;
pub use pid_config::IntegralType;
pub use pid_config::ProportionalType;
pub use pid_config::TimeUnit;
pub use process_type::ProcessType;
pub use range::MvRange;
pub use range::PvRange;
pub use range::RangeError;
pub use tags::LoopTags;
pub use tags::TagOrValue;
pub use tags::TagOverrides;
pub use tags::TagOverridesError;
pub use tags::derive_tag;
pub use template::DcsTemplate;
pub use template::built_in_templates;
pub use tuning_math::CheckedTuningResult;
pub use tuning_math::OpcWriteValues;
pub use tuning_math::Oscillation;
pub use tuning_math::PidParameters;
pub use tuning_math::TuningMathCompat;
pub use tuning_math::TuningResult;
pub use tuning_math::TuningResultInvalidReason;
pub use tuning_math::TuningResultStatus;
pub use tuning_math::calculate_all;
pub use tuning_math::calculate_all_checked;
pub use tuning_math::calculate_pid_parameters;
pub use tuning_math::calculate_tuning_result;
pub use tuning_math::measure_oscillation;
pub use tuning_math::opc_write_values;

Modules§

constants
Tuning-constant lookup matrices: per-process-type, per-response-level, per-controller type multipliers used to turn a measured relay-test oscillation into Kp/Ti/Td.
controller_type
The controller structures a tuning run can target: Proportional-only, Proportional + Integral, or full PID.
direction
Controller action direction: whether increasing the manipulated variable increases or decreases the process variable. Determines which way the relay steps during MRFT.
loop_config
Per-run test configuration: process type, controller type, relay amplitude, and MRFT cycle/timing parameters.
mrft
The MRFT (Modified Relay Feedback Test) engine: the pure, I/O-free relay-switching state machine at the heart of bhtune. See AGENTS.md’s “Key architectural decisions” for why this must never read a clock, perform network I/O, or touch a UI.
pid_config
Enums for how a DCS/PLC expresses PID parameters, avoiding the fragile pattern of comparing live values against magic display strings ("Kp - Proportional Gain", etc.).
process_type
The process types the tuning-constant matrices are calibrated for.
range
Validated PV/MV range types – the boundary a live OPC DA read or a CLI flag override must pass through before an untrusted number is treated as a range with a known, trustworthy shape (finite bounds, correctly ordered, non-zero span). See AGENTS.md’s “Live-plant safety hardening” section for the review finding this closes (--cycles-count 0 panicking mid-run was the same finding’s other symptom: no externally supplied number reached the engine validated).
tags
OPC tag-name derivation: expands a single PV tag into the full tag set a loop needs, using the active DCS/PLC template’s suffix conventions.
template
DCS/PLC template semantics: one instance per control-system convention (Yokogawa, Honeywell, etc.), describing how that DCS expresses PID parameters and the OPC item-name suffix convention used to derive a full tag set from a single PV tag (see crate::tags::derive_tag).
tuning_math
Tuning-constant math: turns a completed MRFT run’s peaks/troughs/switch-times into Kp/Ti/Td for all three ResponseLevels, then into the PID parameters in whatever representation/units a DCS/PLC template expects.