9460da513c
ReadNameRecord read only the first 2 bytes of each 4-byte 0x0089/0x008A record, so the real 31i-B's paired axes 'AA6'/'AA7' (live capture ref-axisname-0x0089.bin) both decoded as 'AA' -- the 'Makino with two AA axes' that #548 then had to disambiguate as AA_1/AA_2. The name is now the record's ASCII up to its FIRST NUL (not trailing-NUL trimming), so buffer residue such as Z-34184's spindle record 53 31 00 4e ('S1' + an 'N' left from an earlier 'CNC') is discarded. Client-visible: on such a machine Axes/AA_1 and Axes/AA_2 become Axes/AA6 and Axes/AA7 (the old names were a decode artefact). #548's disambiguation stays as the guard for genuinely duplicate names. Ported from the sister ignitionoee FOCAS driver (Focas.Wire-001, Focas.Wire-022 / v0.18.1).
79 lines
3.2 KiB
C#
79 lines
3.2 KiB
C#
using Shouldly;
|
|
using Xunit;
|
|
using ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Wire;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests;
|
|
|
|
/// <summary>
|
|
/// Axis-name (0x0089) / spindle-name (0x008A) record decode. Each record is 4 bytes; the name is
|
|
/// the ASCII up to the record's FIRST NUL. Ported from the sister ignitionoee FOCAS driver
|
|
/// (Focas.Wire-001 and Focas.Wire-022, v0.18.1).
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para><b>Reading only 2 bytes collides real names.</b> The live 31i-B capture
|
|
/// (<c>ref-axisname-0x0089.bin</c>) carries <c>"AA6"</c> and <c>"AA7"</c>; the old 2-byte read
|
|
/// turned both into <c>"AA"</c>, which is exactly the "one observed Makino returns two axis
|
|
/// folders both called AA" that Gitea #548 then had to disambiguate as <c>AA_1</c>/<c>AA_2</c>.</para>
|
|
/// <para><b>Trailing-only trimming keeps buffer residue.</b> A control writes only the bytes the
|
|
/// name needs; on Makino Z-34184 (2026-08-19) <c>cnc_rdspdlname</c> came back
|
|
/// <c>53 31 00 4e</c> — <c>"S1"</c> then the <c>'N'</c> of an earlier <c>"CNC"</c>. The name
|
|
/// ends at the first NUL.</para>
|
|
/// </remarks>
|
|
[Trait("Category", "Unit")]
|
|
public sealed class FocasNameRecordTests
|
|
{
|
|
[Fact]
|
|
public void The_live_axis_name_capture_keeps_three_character_names_distinct()
|
|
{
|
|
var payload = WireFixtures.Payload("ref-axisname-0x0089.bin", 0x0089);
|
|
|
|
var names = FocasWireClient.ReadNameRecords(payload, 32, (index, name) => (index, name));
|
|
|
|
names.Select(n => n.name).ShouldBe(["X", "Y", "Z", "B", "C", "AA6", "AA7"]);
|
|
names.Select(n => n.index).ShouldBe([(short)1, 2, 3, 4, 5, 6, 7]);
|
|
}
|
|
|
|
[Fact]
|
|
public void The_live_spindle_name_capture_decodes()
|
|
{
|
|
var payload = WireFixtures.Payload("ref-spdlname-0x008a.bin", 0x008a);
|
|
|
|
FocasWireClient.ReadNameRecords(payload, 8, (_, name) => name).ShouldBe(["S1"]);
|
|
}
|
|
|
|
[Fact]
|
|
public void A_name_ends_at_its_first_NUL_so_residue_after_it_is_discarded()
|
|
{
|
|
// The Z-34184 spindle-name record: "S1", NUL, then an 'N' left over from a previous "CNC".
|
|
FocasWireProtocol.ReadNameRecord([0x53, 0x31, 0x00, 0x4e]).ShouldBe("S1");
|
|
// A single-character name with residue in BOTH trailing bytes.
|
|
FocasWireProtocol.ReadNameRecord([0x58, 0x00, 0x43, 0x4e]).ShouldBe("X");
|
|
}
|
|
|
|
[Fact]
|
|
public void All_four_record_bytes_are_name_bytes()
|
|
{
|
|
FocasWireProtocol.ReadNameRecord("AA6\0"u8.ToArray()).ShouldBe("AA6");
|
|
FocasWireProtocol.ReadNameRecord("ABCD"u8.ToArray()).ShouldBe("ABCD");
|
|
FocasWireProtocol.ReadNameRecord("X \0\0"u8.ToArray()).ShouldBe("X");
|
|
}
|
|
|
|
[Fact]
|
|
public void A_record_that_starts_with_NUL_is_blank()
|
|
{
|
|
FocasWireProtocol.ReadNameRecord([0x00, 0x41, 0x41, 0x00]).ShouldBe(string.Empty);
|
|
}
|
|
|
|
[Fact]
|
|
public void Servo_meter_names_come_out_whole_too()
|
|
{
|
|
var blocks = WireFixtures.Blocks("svmeter-pair-0x0056-0x0089.bin");
|
|
var sv = blocks.First(b => b.Command == 0x0056).Payload;
|
|
var names = blocks.First(b => b.Command == 0x0089).Payload;
|
|
|
|
var meters = FocasWireClient.ParseServoMeters(sv, names, maxCount: 32);
|
|
|
|
meters.Take(7).Select(m => m.Name).ShouldBe(["X", "Y", "Z", "B", "C", "AA6", "AA7"]);
|
|
}
|
|
}
|