refactor(driver-focas): extract FocasDriverOptions to .Contracts
Move FocasDriverOptions (and companion option types), FocasCncSeries, and the FocasDataType enum to a new Driver.FOCAS.Contracts sibling project. FocasDataTypeExtensions (which uses DriverDataType from Core.Abstractions) stays in the runtime driver as FocasDataTypeExtensions.cs. Convert two doc-comment references: <see cref="FocasDriver.InitializeAsync"/> → <c>FocasDriver.InitializeAsync</c> <see cref="FocasAddress.TryParse"/> → <c>FocasAddress.TryParse</c> per the approved decision — no compilable usings were present in the moved files. The runtime Driver.FOCAS project gains a ProjectReference to .Contracts; the .slnx is updated accordingly.
This commit is contained in:
@@ -1,47 +0,0 @@
|
||||
namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS;
|
||||
|
||||
/// <summary>
|
||||
/// Fanuc CNC controller series. Used by <see cref="FocasCapabilityMatrix"/> to
|
||||
/// gate which FOCAS addresses + value ranges the driver accepts against a given
|
||||
/// CNC — the FOCAS API surface varies meaningfully between series (macro ranges,
|
||||
/// PMC address letters, parameter numbers). A tag reference that's valid on a
|
||||
/// 30i might be out-of-range on an 0i-MF; validating at driver
|
||||
/// <c>InitializeAsync</c> time surfaces the mismatch as a fast config error
|
||||
/// instead of a runtime read failure after the server's already running.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Values chosen from the Fanuc FOCAS Developer Kit documented series
|
||||
/// matrix. Add a new entry + a row to <see cref="FocasCapabilityMatrix"/> when
|
||||
/// a new controller is targeted — the driver will refuse the device until both
|
||||
/// sides of the enum are filled in.</para>
|
||||
/// <para>Defaults to <see cref="Unknown"/> when the operator doesn't specify;
|
||||
/// the capability matrix treats Unknown as permissive (no range validation,
|
||||
/// same as pre-matrix behaviour) so old configs don't break on upgrade.</para>
|
||||
/// </remarks>
|
||||
public enum FocasCncSeries
|
||||
{
|
||||
/// <summary>No series declared; capability matrix is permissive (legacy behaviour).</summary>
|
||||
Unknown = 0,
|
||||
|
||||
/// <summary>Series 0i-D — compact CNC, narrow macro + PMC ranges.</summary>
|
||||
Zero_i_D,
|
||||
/// <summary>Series 0i-F — successor to 0i-D; widened macro range, added Plus variant.</summary>
|
||||
Zero_i_F,
|
||||
/// <summary>Series 0i-MF / 0i-MF Plus — machining-centre variants of 0i-F.</summary>
|
||||
Zero_i_MF,
|
||||
/// <summary>Series 0i-TF / 0i-TF Plus — turning-centre variants of 0i-F.</summary>
|
||||
Zero_i_TF,
|
||||
|
||||
/// <summary>Series 16i / 18i / 21i — mid-range legacy; narrow ranges, limited PMC letters.</summary>
|
||||
Sixteen_i,
|
||||
|
||||
/// <summary>Series 30i — high-end; widest macro / PMC / parameter ranges.</summary>
|
||||
Thirty_i,
|
||||
/// <summary>Series 31i — subset of 30i (fewer axes, same FOCAS surface).</summary>
|
||||
ThirtyOne_i,
|
||||
/// <summary>Series 32i — compact 30i variant.</summary>
|
||||
ThirtyTwo_i,
|
||||
|
||||
/// <summary>Power Motion i — motion-control variant; atypical macro coverage.</summary>
|
||||
PowerMotion_i,
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS;
|
||||
|
||||
/// <summary>
|
||||
/// FOCAS atomic data types. Narrower than Logix/IEC — FANUC CNCs expose mostly integer +
|
||||
/// floating-point data with no UDT concept; macro variables are double-precision floats
|
||||
/// and PMC reads return byte / signed word / signed dword.
|
||||
/// </summary>
|
||||
public enum FocasDataType
|
||||
{
|
||||
/// <summary>Single bit (PMC bit, or bit within a CNC parameter).</summary>
|
||||
Bit,
|
||||
/// <summary>8-bit signed byte (PMC 1-byte read).</summary>
|
||||
Byte,
|
||||
/// <summary>16-bit signed word (PMC 2-byte read, or CNC parameter as short).</summary>
|
||||
Int16,
|
||||
/// <summary>32-bit signed int (PMC 4-byte read, or CNC parameter as int).</summary>
|
||||
Int32,
|
||||
/// <summary>32-bit IEEE-754 float (rare; some CNC macro variables).</summary>
|
||||
Float32,
|
||||
/// <summary>64-bit IEEE-754 double (most macro variables are double-precision).</summary>
|
||||
Float64,
|
||||
/// <summary>ASCII string (alarm text, parameter names, some PMC string areas).</summary>
|
||||
String,
|
||||
}
|
||||
|
||||
public static class FocasDataTypeExtensions
|
||||
{
|
||||
/// <summary>Converts a FOCAS data type to the corresponding driver data type.</summary>
|
||||
/// <param name="t">The FOCAS data type to convert.</param>
|
||||
/// <returns>The equivalent driver data type.</returns>
|
||||
public static DriverDataType ToDriverDataType(this FocasDataType t) => t switch
|
||||
{
|
||||
FocasDataType.Bit => DriverDataType.Boolean,
|
||||
FocasDataType.Byte or FocasDataType.Int16 or FocasDataType.Int32 => DriverDataType.Int32,
|
||||
FocasDataType.Float32 => DriverDataType.Float32,
|
||||
FocasDataType.Float64 => DriverDataType.Float64,
|
||||
FocasDataType.String => DriverDataType.String,
|
||||
_ => DriverDataType.Int32,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS;
|
||||
|
||||
public static class FocasDataTypeExtensions
|
||||
{
|
||||
/// <summary>Converts a FOCAS data type to the corresponding driver data type.</summary>
|
||||
/// <param name="t">The FOCAS data type to convert.</param>
|
||||
/// <returns>The equivalent driver data type.</returns>
|
||||
public static DriverDataType ToDriverDataType(this FocasDataType t) => t switch
|
||||
{
|
||||
FocasDataType.Bit => DriverDataType.Boolean,
|
||||
FocasDataType.Byte or FocasDataType.Int16 or FocasDataType.Int32 => DriverDataType.Int32,
|
||||
FocasDataType.Float32 => DriverDataType.Float32,
|
||||
FocasDataType.Float64 => DriverDataType.Float64,
|
||||
FocasDataType.String => DriverDataType.String,
|
||||
_ => DriverDataType.Int32,
|
||||
};
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS;
|
||||
|
||||
/// <summary>
|
||||
/// FOCAS driver configuration. One instance supports N CNC devices. Per plan decision #144
|
||||
/// each device gets its own <c>(DriverInstanceId, HostAddress)</c> bulkhead key at the
|
||||
/// Phase 6.1 resilience layer.
|
||||
/// </summary>
|
||||
public sealed class FocasDriverOptions
|
||||
{
|
||||
/// <summary>Gets the list of configured CNC devices.</summary>
|
||||
public IReadOnlyList<FocasDeviceOptions> Devices { get; init; } = [];
|
||||
/// <summary>Gets the list of FOCAS tag definitions.</summary>
|
||||
public IReadOnlyList<FocasTagDefinition> Tags { get; init; } = [];
|
||||
/// <summary>Gets the probe options.</summary>
|
||||
public FocasProbeOptions Probe { get; init; } = new();
|
||||
/// <summary>Gets the timeout duration for operations.</summary>
|
||||
public TimeSpan Timeout { get; init; } = TimeSpan.FromSeconds(2);
|
||||
/// <summary>Gets the alarm projection options.</summary>
|
||||
public FocasAlarmProjectionOptions AlarmProjection { get; init; } = new();
|
||||
/// <summary>Gets the handle recycle options.</summary>
|
||||
public FocasHandleRecycleOptions HandleRecycle { get; init; } = new();
|
||||
/// <summary>Gets the fixed tree options.</summary>
|
||||
public FocasFixedTreeOptions FixedTree { get; init; } = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fixed-node tree exposed by FOCAS per <c>docs/v2/driver-specs.md §7</c> —
|
||||
/// <c>Identity/</c>, <c>Axes/{name}/</c>, etc. populated from
|
||||
/// <c>cnc_sysinfo</c> / <c>cnc_rdaxisname</c> / <c>cnc_rddynamic2</c>. Disabled by
|
||||
/// default so existing configs that only use user-authored tags don't grow new
|
||||
/// nodes on upgrade.
|
||||
/// </summary>
|
||||
public sealed class FocasFixedTreeOptions
|
||||
{
|
||||
/// <summary>Gets or sets a value indicating whether the fixed-node tree is enabled for every configured device.</summary>
|
||||
public bool Enabled { get; init; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Poll cadence for <c>cnc_rddynamic2</c>. Each tick calls the API once per
|
||||
/// configured axis + publishes OnDataChange for the axis subtree. Real CNCs
|
||||
/// serve ~100ms loops comfortably; the default is conservative.
|
||||
/// </summary>
|
||||
public TimeSpan PollInterval { get; init; } = TimeSpan.FromMilliseconds(250);
|
||||
|
||||
/// <summary>
|
||||
/// Poll cadence for program + operation-mode info. Slower than the axis
|
||||
/// poll because program / mode transitions happen on operator timescales.
|
||||
/// Zero / negative disables the program poll entirely.
|
||||
/// </summary>
|
||||
public TimeSpan ProgramPollInterval { get; init; } = TimeSpan.FromSeconds(1);
|
||||
|
||||
/// <summary>
|
||||
/// Poll cadence for timers (power-on / operating / cutting / cycle).
|
||||
/// These change at human timescales — default is 30s. Zero / negative
|
||||
/// disables the timer poll entirely.
|
||||
/// </summary>
|
||||
public TimeSpan TimerPollInterval { get; init; } = TimeSpan.FromSeconds(30);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Proactive session-recycle cadence. Fanuc CNCs have a finite FWLIB handle pool
|
||||
/// (~5–10 concurrent connections) and certain series have documented handle-leak bugs
|
||||
/// that manifest after long uptime. When <see cref="Enabled"/> is <c>true</c> the
|
||||
/// driver closes + reopens each device's session on the <see cref="Interval"/> cadence,
|
||||
/// forcing FWLIB to release its handle slot back to the pool. Reads / writes during
|
||||
/// recycle wait for the reconnect rather than failing — worst case an operator sees a
|
||||
/// brief read latency spike once per cadence.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Disabled by default because a healthy CNC + driver doesn't need it. Enable when
|
||||
/// field experience shows handle exhaustion against a specific series / firmware.
|
||||
/// Typical tuning: 30 min for sites running multiple OtOpcUa instances against the
|
||||
/// same CNC (they share the pool); 6 h for a single-client deployment.
|
||||
/// </remarks>
|
||||
public sealed class FocasHandleRecycleOptions
|
||||
{
|
||||
/// <summary>Gets or sets a value indicating whether handle recycling is enabled.</summary>
|
||||
public bool Enabled { get; init; } = false;
|
||||
/// <summary>Gets or sets the interval for handle recycle operations.</summary>
|
||||
public TimeSpan Interval { get; init; } = TimeSpan.FromHours(1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Controls the CNC active-alarm polling projection that surfaces FOCAS alarms via
|
||||
/// <c>IAlarmSource</c>. Disabled by default — operators opt in by setting
|
||||
/// <see cref="Enabled"/> in <c>appsettings.json</c>.
|
||||
/// </summary>
|
||||
public sealed class FocasAlarmProjectionOptions
|
||||
{
|
||||
/// <summary>Gets or sets a value indicating whether alarm projection is enabled.</summary>
|
||||
public bool Enabled { get; init; } = false;
|
||||
|
||||
/// <summary>Poll cadence. One <c>cnc_rdalmmsg2</c> call per device per tick.</summary>
|
||||
public TimeSpan PollInterval { get; init; } = TimeSpan.FromSeconds(2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// One CNC the driver talks to. <paramref name="Series"/> enables per-series
|
||||
/// address validation at <see cref="FocasDriver.InitializeAsync"/>; leave as
|
||||
/// <see cref="FocasCncSeries.Unknown"/> to skip validation (legacy behaviour).
|
||||
/// </summary>
|
||||
public sealed record FocasDeviceOptions(
|
||||
string HostAddress,
|
||||
string? DeviceName = null,
|
||||
FocasCncSeries Series = FocasCncSeries.Unknown);
|
||||
|
||||
/// <summary>
|
||||
/// One FOCAS-backed OPC UA variable. <paramref name="Address"/> is the canonical FOCAS
|
||||
/// address string that parses via <see cref="FocasAddress.TryParse"/> —
|
||||
/// <c>X0.0</c> / <c>R100</c> / <c>PARAM:1815/0</c> / <c>MACRO:500</c>.
|
||||
/// </summary>
|
||||
public sealed record FocasTagDefinition(
|
||||
string Name,
|
||||
string DeviceHostAddress,
|
||||
string Address,
|
||||
FocasDataType DataType,
|
||||
bool Writable = true,
|
||||
bool WriteIdempotent = false);
|
||||
|
||||
public sealed class FocasProbeOptions
|
||||
{
|
||||
/// <summary>Gets or sets a value indicating whether probing is enabled.</summary>
|
||||
public bool Enabled { get; init; } = true;
|
||||
/// <summary>Gets or sets the probe interval.</summary>
|
||||
public TimeSpan Interval { get; init; } = TimeSpan.FromSeconds(5);
|
||||
/// <summary>Gets or sets the probe timeout.</summary>
|
||||
public TimeSpan Timeout { get; init; } = TimeSpan.FromSeconds(2);
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Contracts\ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Contracts.csproj"/>
|
||||
<ProjectReference Include="..\..\Core\ZB.MOM.WW.OtOpcUa.Core.Abstractions\ZB.MOM.WW.OtOpcUa.Core.Abstractions.csproj"/>
|
||||
<ProjectReference Include="..\..\Core\ZB.MOM.WW.OtOpcUa.Core\ZB.MOM.WW.OtOpcUa.Core.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user