665ecd55c2
The ODBM wire payload is [i32 mantissa][i16 length, a constant 10][i16 dec_val]. ReadMacroAsync read the decimal at offset 4, so every macro decoded without failing but wrongly: the captured #500 = 1.0 (05 f5 e1 00 00 0a 00 08) published 0.01. FANUC normalises macros to a 9-significant-digit mantissa, so the error was never small. - dec_val is read at [6..7]; a payload < 8 bytes is refused, not guessed at. - A vacant variable (dec_val 0xFFFF) publishes BadNoData, never a Good 0. - Integer-typed tags get the exact whole value (integer arithmetic); a fractional macro on an integer tag is BadTypeMismatch, a whole value that does not fit the type BadOutOfRange. Float tags get mantissa / 10^dec. Ported from the sister ignitionoee FOCAS driver v0.15.0 (Focas.Wire-013, Focas-017/018); live vectors from Makino Z-34184 (31i-B, G431). Adds a WireFixtures helper that loads the raw 31i-B captures in Fixtures/v3.
32 lines
1.6 KiB
C#
32 lines
1.6 KiB
C#
using ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Wire;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests;
|
|
|
|
/// <summary>
|
|
/// Loads the raw FOCAS response PDUs under <c>Fixtures/v3/</c> — byte-for-byte captures from a
|
|
/// real FANUC 31i-B (Makino, series G431) — and splits them into response blocks with the
|
|
/// production <see cref="FocasWireProtocol.ParseResponseBlocks"/>. The <c>live-*</c> captures
|
|
/// were taken by the sister ignitionoee FOCAS driver's read-only probes of Z-34184 (2026-08-12)
|
|
/// and are shared verbatim; the <c>ref-*</c> ones are this repo's own 2026-06-25 capture.
|
|
/// </summary>
|
|
internal static class WireFixtures
|
|
{
|
|
private const int PduHeaderLength = 10;
|
|
|
|
/// <summary>Every response block of the named capture, in wire order.</summary>
|
|
/// <param name="name">File name under <c>Fixtures/v3/</c>.</param>
|
|
/// <returns>The parsed response blocks.</returns>
|
|
public static IReadOnlyList<ResponseBlock> Blocks(string name)
|
|
{
|
|
var raw = File.ReadAllBytes(Path.Combine(AppContext.BaseDirectory, "Fixtures", "v3", name));
|
|
return FocasWireProtocol.ParseResponseBlocks(raw.AsSpan(PduHeaderLength));
|
|
}
|
|
|
|
/// <summary>The payload of the first block carrying <paramref name="command"/>.</summary>
|
|
/// <param name="name">File name under <c>Fixtures/v3/</c>.</param>
|
|
/// <param name="command">The FOCAS command id to locate.</param>
|
|
/// <returns>That block's payload bytes.</returns>
|
|
public static byte[] Payload(string name, ushort command) =>
|
|
Blocks(name).First(b => b.Command == command).Payload;
|
|
}
|