Skip to main content

bhtune_core/
lib.rs

1//! `bhtune-core` — the pure, I/O-free domain crate.
2//!
3//! This crate implements:
4//! - The MRFT (Modified Relay Feedback Test) tuning algorithm, as a pure
5//!   state machine: `fn step(&mut self, tick: Tick) -> Vec<Action>`. No
6//!   clock reads, no network calls, no UI access — that constraint is what
7//!   makes it possible to replay a recorded trace and assert the engine
8//!   produces bit-identical results across changes.
9//! - The tuning-constant lookup matrices and PID unit conversion math.
10//! - The domain data model: tag maps, loop configuration, DCS/PLC template
11//!   semantics, and the enums that model PID parameter types and controller
12//!   direction.
13//!
14//! Deliberately has no I/O, no async, and no clock reads. Callers supply time as `Tick` data;
15//! this source/API contract is not enforced by Cargo feature isolation, since application
16//! dependencies can enable chrono's clock features through unification. This is a narrower
17//! rule than "no dependencies": `toml` is a real dependency because parsing an
18//! `include_str!`-embedded `&'static str` is not I/O; the optional, feature-gated `utoipa`
19//! dependency is similarly limited to compile-time derives that describe a type's shape.
20//! Anything added here must be justified by the pure domain logic itself (or, for `utoipa`,
21//! by describing it accurately to a consumer), not by a consumer's I/O or presentation needs
22//! — those belong in `bhtune-driver`, `bhtune-db`, `bhtune-runtime`, or the CLI/server adapters.
23
24#![cfg_attr(
25    test,
26    allow(
27        clippy::unwrap_used,
28        clippy::expect_used,
29        clippy::panic,
30        reason = "unit tests may use unwrap, expect, and panic; production code must return typed errors"
31    )
32)]
33
34pub mod constants;
35pub mod controller_type;
36pub mod direction;
37pub mod loop_config;
38pub mod mrft;
39pub mod pid_config;
40pub mod process_type;
41pub mod range;
42pub mod tags;
43pub mod template;
44pub mod tuning_math;
45
46pub use constants::{ResponseLevel, TuningConstants, lookup};
47pub use controller_type::ControllerType;
48pub use direction::ControllerDirection;
49pub use loop_config::{LoopConfig, LoopConfigError};
50pub use mrft::{Action, InitialReadings, MrftEngine, MrftState, Tick};
51pub use pid_config::{
52    DerivativeType, IntegralType, PidRounding, PidRoundingError, PidRoundingKind, ProportionalType,
53    RoundedPidValue, TimeUnit,
54};
55pub use process_type::ProcessType;
56pub use range::{MvRange, PvRange, RangeError};
57pub use tags::{LoopTags, TagOrValue, TagOverrides, TagOverridesError, derive_tag};
58pub use template::{DcsTemplate, built_in_templates};
59pub use tuning_math::{
60    CheckedTuningResult, ControllerPidError, ControllerPidValues, OpcWriteValues, Oscillation,
61    PidParameters, TuningResult, TuningResultInvalidReason, TuningResultStatus, calculate_all,
62    calculate_all_checked, calculate_pid_parameters, calculate_tuning_result,
63    controller_pid_values, measure_oscillation, opc_write_values,
64};