1using Dreamine.PLC.Abstractions.Clients;
2using Dreamine.PLC.Abstractions.Connections;
3using Dreamine.PLC.Core.Clients;
4using Dreamine.PLC.Core.Devices;
5using Dreamine.PLC.Core.Simulation;
6using Dreamine.PLC.Mitsubishi.MC.Clients;
7using Dreamine.PLC.Mitsubishi.MC.Options;
8using Dreamine.PLC.Mitsubishi.MC.Simulation;
9using Dreamine.PLC.Mitsubishi.MxComponent.Clients;
10using Dreamine.PLC.Mitsubishi.MxComponent.Options;
11using Dreamine.PLC.Omron.CxComponent.Clients;
12using Dreamine.PLC.Omron.CxComponent.Options;
13using Dreamine.PLC.Omron.Fins.Clients;
14using Dreamine.PLC.Omron.Fins.Options;
15using Dreamine.PLC.Omron.Fins.Simulation;
16using Dreamine.PLC.Wpf.ViewModels;
203 Monitor.StatusMessage =
"InMemory PLC client selected.";
240 Monitor.StatusMessage =
"PLC Simulator TCP client selected.";
286 if (!Enum.TryParse<MitsubishiMcTransportType>(transportText, ignoreCase:
true, out var transportType))
288 Monitor.StatusMessage =
"MC transport must be Tcp or Udp.";
296 TransportType = transportType,
297 RetryCount = Math.Max(1, retryCount),
298 ConnectTimeoutMs = 3000,
299 ReceiveTimeoutMs = 3000,
305 Monitor.StatusMessage = $
"Mitsubishi MC {transportType} client selected.";
351 if (!Enum.TryParse<OmronFinsTransportType>(transportText, ignoreCase:
true, out var transportType))
353 Monitor.StatusMessage =
"FINS transport must be Tcp or Udp.";
361 TransportType = transportType,
362 RetryCount = Math.Max(1, retryCount),
363 ConnectTimeoutMs = 3000,
364 ReceiveTimeoutMs = 3000,
365 DestinationNode = 0x00,
371 Monitor.StatusMessage = $
"Omron FINS {transportType} client selected.";
402 ProgId =
string.IsNullOrWhiteSpace(progId) ? MitsubishiMxComponentOptions.DefaultProgId : progId.Trim(),
403 LogicalStationNumber = logicalStationNumber
408 Monitor.StatusMessage =
"Mitsubishi MX Component client selected. Vendor runtime must be installed before Connect.";
439 ProgId =
string.IsNullOrWhiteSpace(progId) ?
"OMRON.Compolet.CJ2Compolet" : progId.Trim(),
440 PeerAddress =
string.IsNullOrWhiteSpace(peerAddress) ?
"127.0.0.1" : peerAddress.Trim()
445 Monitor.StatusMessage =
"Omron CX-Compolet client selected. Vendor runtime must be installed before Connect.";
493 ServerStatus = $
"Server already running. mode={_activeServerMode}. Stop the current server first.";
505 EnableAutoWordResponse =
true,
506 AutoResponseTriggerAddress =
"D100",
507 AutoResponseAddress =
"D101",
508 AutoResponseIncrement = 1
545 Monitor.StatusMessage =
"Server mode must be SimulatorTcp, McTcp, McUdp, FinsTcp, or FinsUdp.";
549 ServerStatus = $
"{_activeServerMode} server running. {host}:{port}";
728 CancellationToken cancellationToken =
default)
732 Monitor.StatusMessage =
"Handshake iterations must be greater than zero.";
733 Monitor.AppendLog(
"Handshake",
"D100/D101", iterations.ToString(),
false,
Monitor.StatusMessage);
739 Monitor.StatusMessage =
"Handshake test requires a connected PLC client.";
740 Monitor.AppendLog(
"Handshake",
"D100/D101",
string.Empty,
false,
Monitor.StatusMessage);
746 var value = startValue;
748 for (var index = 0; index < iterations; index++)
750 cancellationToken.ThrowIfCancellationRequested();
752 var writeResult = await
_activeClient.WriteWordsAsync(clientWriteAddress, [value], cancellationToken).ConfigureAwait(
true);
753 if (!writeResult.IsSuccess)
755 Monitor.StatusMessage = writeResult.Message ??
"Handshake write failed.";
756 Monitor.AppendLog(
"HandshakeWrite",
"D100", value.ToString(),
false,
Monitor.StatusMessage);
760 var rawExpected = value + 1;
761 if (rawExpected >
short.MaxValue)
763 Monitor.StatusMessage = $
"Handshake stopped before 16-bit overflow. last={value}, next={rawExpected}.";
764 Monitor.AppendLog(
"Handshake",
"D100/D101", $
"last={value}, next={rawExpected}",
false,
Monitor.StatusMessage);
768 var expected = (short)rawExpected;
769 var readResult = await
_activeClient.ReadWordsAsync(serverResponseAddress, 1, cancellationToken).ConfigureAwait(
true);
770 var actual = readResult.Value is { Length: > 0 } ? readResult.Value[0] :
short.MinValue;
771 if (!readResult.IsSuccess || actual != expected)
773 Monitor.StatusMessage = readResult.IsSuccess
774 ? $
"Handshake mismatch. expected={expected}, actual={actual}."
775 : readResult.Message ??
"Handshake read failed.";
776 Monitor.AppendLog(
"HandshakeRead",
"D101", $
"expected={expected}, actual={actual}",
false,
Monitor.StatusMessage);
780 Monitor.StatusMessage = $
"Handshake OK {index + 1}/{iterations}. D100={value}, D101={actual}";
781 Monitor.AppendLog(
"Handshake",
"D100/D101", $
"{value}->{actual}",
true,
Monitor.StatusMessage);
786 await Task.Delay(delayMs, cancellationToken).ConfigureAwait(
true);
826 return new MitsubishiMcSimulatorServerOptions
830 EnableAutoWordResponse =
true,
831 AutoResponseTriggerDeviceCode = 0xA8,
832 AutoResponseTriggerOffset = 100,
833 AutoResponseDeviceCode = 0xA8,
834 AutoResponseOffset = 101,
835 AutoResponseIncrement = 1
873 return new OmronFinsSimulatorServerOptions
877 EnableAutoWordResponse =
true,
878 AutoResponseTriggerOffset = 100,
879 AutoResponseOffset = 101,
880 AutoResponseIncrement = 1
935 return string.IsNullOrWhiteSpace(modeText)
937 : modeText.Trim().ToUpperInvariant();
967 Monitor.StatusMessage = e;
MitsubishiMcUdpSimulatorServer? _mcUdpSimulatorServer
OmronFinsUdpSimulatorServer? _finsUdpSimulatorServer
PlcSimulatorServer? _simulatorServer
MitsubishiMcPlcClient? _mitsubishiMcClient
Task StopSimulatorServerAsync()
OmronFinsPlcClient? _omronFinsClient
static MitsubishiMcSimulatorServerOptions CreateMcSimulatorOptions(string host, int port)
async Task StartProtocolServerAsync(string modeText, string host, int port)
MitsubishiMcTcpSimulatorServer? _mcTcpSimulatorServer
void UseMitsubishiMcClient(string host, int port, string transportText, int retryCount)
readonly InMemoryPlcClient _inMemoryClient
OmronFinsTcpSimulatorServer? _finsTcpSimulatorServer
static string NormalizeMode(string? modeText)
Task StartSimulatorServerAsync(string host, int port)
void UseOmronCxComponentClient(string progId, string peerAddress)
void UseMitsubishiMxComponentClient(string progId, int logicalStationNumber)
void UseSimulatorTcpClient(string host, int port)
MitsubishiMxComponentPlcClient? _mitsubishiMxComponentClient
PlcSimulatorTcpClient? _simulatorClient
void UseOmronFinsClient(string host, int port, string transportText, int retryCount)
PlcMonitorViewModel Monitor
static OmronFinsSimulatorServerOptions CreateFinsSimulatorOptions(string host, int port)
bool IsAnyServerRunning()
void OnSimulatorServerStatusChanged(object? sender, string e)
async Task StopProtocolServerAsync()
readonly DefaultPlcAddressParser _addressParser
async Task RunHandshakeTestAsync(short startValue, int iterations, int delayMs, CancellationToken cancellationToken=default)
OmronCxComponentPlcClient? _omronCxComponentClient