New Cnc/Mazak/ machine integration mirroring the Fagor/Mitsubishi FTP pattern: MazakConnectionConfig, IMazakFtpClient, MazakFtpClient, MazakMachine (ICncMachine). Transfers EIA/ISO G-code text over FTP to Smooth-family controllers. Mazatrol CMT (proprietary binary) out of scope. Design (verified against Mazak Matrix EIA manual + field reports): - Filenames preserved verbatim; no O#### rename, no extension append. - Symmetric ResolvePath for Read/Write/Delete (avoids ISS-020 class; Delete resolved too, unlike copied Mitsubishi source). - Validator = full passthrough for Mazak (EIA permits ';' EOB, '[ ]', '#'; restrictive Fanuc checks would false-reject valid programs). - Port 21 default, -porta=23 for Smooth Ai IIS variant. - ProgramDirectory site-specific, no default. Wiring: CncManufacturer.Mazak, ArgParser 'mazak' token, CncMachineFactory. Tests: MazakMachineTests (unit), MazakMachineIntegrationTests (FTP-stub roundtrip + symmetry guard), Mazak cases in validator/factory tests. Docs: README Controller Mazak section + table row; ISS-021 (constraints, EIA-option requirement), ISS-022 (Mitsubishi delete asymmetry logged). NOT build-verified (no .NET toolchain in build env) — verify on Windows. Projects: NcProgramManager, NcProgramManager.Tests Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
71 lines
2.7 KiB
C#
71 lines
2.7 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Text;
|
|
|
|
namespace NcProgramManager.Cnc.Mazak
|
|
{
|
|
/// <summary>Client FTP per trasferimento programmi Mazak CNC.</summary>
|
|
internal sealed class MazakFtpClient : IMazakFtpClient
|
|
{
|
|
private readonly MazakConnectionConfig _config;
|
|
|
|
public MazakFtpClient(MazakConnectionConfig config)
|
|
{
|
|
_config = config ?? throw new ArgumentNullException("config");
|
|
}
|
|
|
|
/// <summary>Verifica raggiungibilita server FTP listando la directory programmi.</summary>
|
|
public bool Ping()
|
|
{
|
|
try
|
|
{
|
|
var req = CreateRequest(_config.ProgramDirectory, WebRequestMethods.Ftp.ListDirectory);
|
|
using (var resp = (FtpWebResponse)req.GetResponse())
|
|
return resp.StatusCode == FtpStatusCode.DataAlreadyOpen
|
|
|| resp.StatusCode == FtpStatusCode.OpeningData
|
|
|| (int)resp.StatusCode / 100 == 2;
|
|
}
|
|
catch { return false; }
|
|
}
|
|
|
|
/// <summary>Scarica file dal Mazak in stringa.</summary>
|
|
public string DownloadFile(string ncPath)
|
|
{
|
|
var req = CreateRequest(ncPath, WebRequestMethods.Ftp.DownloadFile);
|
|
using (var resp = (FtpWebResponse)req.GetResponse())
|
|
using (var reader = new StreamReader(resp.GetResponseStream(), Encoding.ASCII))
|
|
return reader.ReadToEnd();
|
|
}
|
|
|
|
/// <summary>Carica contenuto stringa su Mazak.</summary>
|
|
public void UploadFile(string ncPath, string content)
|
|
{
|
|
var req = CreateRequest(ncPath, WebRequestMethods.Ftp.UploadFile);
|
|
byte[] data = Encoding.ASCII.GetBytes(content);
|
|
req.ContentLength = data.Length;
|
|
using (var stream = req.GetRequestStream())
|
|
stream.Write(data, 0, data.Length);
|
|
using ((FtpWebResponse)req.GetResponse()) { }
|
|
}
|
|
|
|
public void DeleteFile(string ncPath)
|
|
{
|
|
var req = CreateRequest(ncPath, WebRequestMethods.Ftp.DeleteFile);
|
|
using ((FtpWebResponse)req.GetResponse()) { }
|
|
}
|
|
|
|
private FtpWebRequest CreateRequest(string path, string method)
|
|
{
|
|
string uri = string.Format("ftp://{0}:{1}{2}", _config.IpAddress, _config.Port, path);
|
|
var req = (FtpWebRequest)WebRequest.Create(uri);
|
|
req.Method = method;
|
|
req.Credentials = new NetworkCredential(_config.Username, _config.Password);
|
|
req.Timeout = (int)_config.RequestTimeout.TotalMilliseconds;
|
|
req.KeepAlive = false;
|
|
req.UseBinary = false;
|
|
req.UsePassive = true;
|
|
return req;
|
|
}
|
|
}
|
|
}
|