Skip to content

Commit 720d57c

Browse files
fa-yoshinobuclaude
andcommitted
fix: update samples to ProbeAllProfilesAsync / explicit OpenAndConnectAsync
- HighLevelSample: add ProbeAllProfilesAsync probe step before OpenAndConnectAsync - QueuedSample: replace ResolveProfileAsync with ProbeAllProfilesAsync + FirstOrDefault - Cli: change autoProfileCache / WarmAutoProfileAsync / ResolveAutoProfileAsync to use SlmpProfileProbeResult and ProbeAllProfilesAsync Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent acb5131 commit 720d57c

File tree

3 files changed

+26
-19
lines changed

3 files changed

+26
-19
lines changed

samples/PlcComm.Slmp.Cli/Program.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
using System.Collections.Concurrent;
55
using PlcComm.Slmp;
66

7-
var autoProfileCache = new ConcurrentDictionary<string, Lazy<Task<SlmpProfileRecommendation>>>(StringComparer.Ordinal);
7+
var autoProfileCache = new ConcurrentDictionary<string, Lazy<Task<SlmpProfileProbeResult>>>(StringComparer.Ordinal);
88
var autoProfileLogged = new ConcurrentDictionary<string, byte>(StringComparer.Ordinal);
99

1010
string GetOption(IReadOnlyList<string> args, string name, string defaultValue)
@@ -43,17 +43,18 @@ string BuildAutoProfileKey(string host, int port, SlmpTransportMode transport, S
4343
return $"{host}:{port}:{transport}:{target.Network:X2}:{target.Station:X2}:{target.ModuleIo:X4}:{target.Multidrop:X2}";
4444
}
4545

46-
async Task<SlmpProfileRecommendation> ResolveAutoProfileAsync(string host, int port, SlmpTransportMode transport, SlmpTargetAddress target)
46+
async Task<SlmpProfileProbeResult> ResolveAutoProfileAsync(string host, int port, SlmpTransportMode transport, SlmpTargetAddress target)
4747
{
4848
using var probeClient = new SlmpClient(host, port, transport)
4949
{
5050
TargetAddress = target,
5151
};
52-
await probeClient.OpenAsync().ConfigureAwait(false);
53-
return await probeClient.ResolveProfileAsync().ConfigureAwait(false);
52+
var results = await probeClient.ProbeAllProfilesAsync().ConfigureAwait(false);
53+
return results.FirstOrDefault(r => r.Success)
54+
?? throw new SlmpError($"Could not detect PLC profile at {host}:{port}");
5455
}
5556

56-
async Task<SlmpProfileRecommendation?> WarmAutoProfileAsync(IReadOnlyList<string> args, SlmpTargetAddress target)
57+
async Task<SlmpProfileProbeResult?> WarmAutoProfileAsync(IReadOnlyList<string> args, SlmpTargetAddress target)
5758
{
5859
var host = GetOption(args, "--host", "192.168.250.100");
5960
var port = int.Parse(GetOption(args, "--port", "1025"), CultureInfo.InvariantCulture);
@@ -69,10 +70,10 @@ async Task<SlmpProfileRecommendation> ResolveAutoProfileAsync(string host, int p
6970
var autoKey = BuildAutoProfileKey(host, port, transport, target);
7071
var lazyProfile = autoProfileCache.GetOrAdd(
7172
autoKey,
72-
_ => new Lazy<Task<SlmpProfileRecommendation>>(() => ResolveAutoProfileAsync(host, port, transport, target))
73+
_ => new Lazy<Task<SlmpProfileProbeResult>>(() => ResolveAutoProfileAsync(host, port, transport, target))
7374
);
7475

75-
SlmpProfileRecommendation profile;
76+
SlmpProfileProbeResult profile;
7677
try
7778
{
7879
profile = await lazyProfile.Value.ConfigureAwait(false);

samples/PlcComm.Slmp.HighLevelSample/Program.cs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,29 @@
1919
var port = args.Length > 1 ? int.Parse(args[1]) : 1025;
2020

2121
// -------------------------------------------------------------------------
22-
// 1. OpenAndConnectAsync (recommended entry point)
22+
// 1. Probe + OpenAndConnectAsync (recommended entry point)
2323
//
24-
// Auto-detects the optimal frame type (3E or 4E) and PLC series (iQ-R / Q/L)
25-
// by probing four candidate combinations in order:
26-
// (4E, iQ-R) -> (3E, Q/L) -> (3E, iQ-R) -> (4E, Q/L)
24+
// ProbeAllProfilesAsync tries all 4 frame/compat combinations in order:
25+
// (4E, iQ-R) -> (4E, Q/L) -> (3E, Q/L) -> (3E, iQ-R)
26+
// and returns results for each so you can pick or present them to the user.
2727
//
28-
// Returns a QueuedSlmpClient - a thread-safe wrapper that serializes all
29-
// requests through a SemaphoreSlim, so multiple concurrent Tasks can share
30-
// one TCP connection without interleaving protocol frames.
31-
//
32-
// Throws SlmpError when no candidate succeeded (e.g. wrong port, PLC offline).
28+
// OpenAndConnectAsync then opens a QueuedSlmpClient with explicit settings.
29+
// QueuedSlmpClient is a thread-safe wrapper that serializes all requests
30+
// through a SemaphoreSlim, so multiple concurrent Tasks can share one TCP
31+
// connection without interleaving protocol frames.
3332
//
3433
// port options:
3534
// 1025 iQ-R / iQ-F Ethernet module SLMP port (default)
3635
// 5000 GX Works3 / GX Works2 simulation port
3736
// 5007 Q/L series Ethernet module SLMP port
3837
// -------------------------------------------------------------------------
39-
Console.WriteLine($"Connecting to {host}:{port} ...");
40-
await using var queuedClient = await SlmpClient.OpenAndConnectAsync(host, port);
38+
Console.WriteLine($"Probing {host}:{port} ...");
39+
using var probeOnly = new SlmpClient(host, port);
40+
var probeResults = await probeOnly.ProbeAllProfilesAsync();
41+
var best = probeResults.FirstOrDefault(r => r.Success)
42+
?? throw new SlmpError($"Could not connect to {host}:{port} - check host, port, and PLC power");
43+
Console.WriteLine($"[ProbeAllProfilesAsync] using {best.Label} model={best.ModelName ?? "unknown"}");
44+
await using var queuedClient = await SlmpClient.OpenAndConnectAsync(host, port, best.FrameType, best.CompatibilityMode);
4145
Console.WriteLine($"[OpenAndConnectAsync] frame={queuedClient.FrameType} series={queuedClient.CompatibilityMode}");
4246

4347
// All extension methods target SlmpClient; access it via InnerClient.

samples/PlcComm.Slmp.QueuedSample/Program.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
};
1919
await using var queuedClient = new QueuedSlmpClient(rawClient);
2020

21-
var profile = await queuedClient.ResolveProfileAsync().ConfigureAwait(false);
21+
var probeResults = await rawClient.ProbeAllProfilesAsync().ConfigureAwait(false);
22+
var profile = probeResults.FirstOrDefault(r => r.Success)
23+
?? throw new SlmpError("Could not detect PLC profile - check host, port, and PLC power");
2224
queuedClient.FrameType = profile.FrameType;
2325
queuedClient.CompatibilityMode = profile.CompatibilityMode;
2426
await queuedClient.OpenAsync().ConfigureAwait(false);

0 commit comments

Comments
 (0)