nc_program_manager/Program.cs
dtrentin 60ce1c9d57 feat(15-logging): NLog structured logging — all output through NLog (v0.5 complete)
Phase 15 complete (2 plans):
- 15-01: NLog 5.2.8 + nlog.config (rolling file daily/7d + console); logger fields in
  FanucMachine, HeidenhainMachine, SiemensMachine, MitsubishiMachine, Lsv2Client, Program.cs;
  SetState event handler catches → _log.Warn; cleanup catches annotated; ISS-003/ISS-004 closed
- 15-02: All Console.Write/WriteLine in Program.cs replaced with _log.Info (103 calls);
  nlog.config console target layout=${message}, levels=Info only — Warn/Error file-only;
  operator console output identical; every interaction now timestamped in log file

Milestone v0.5 Operational Quality complete.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-18 23:57:27 +02:00

356 lines
16 KiB
C#
Executable file

using System;
using System.Collections.Generic;
using System.IO;
using NLog;
using NcProgramManager.Cnc;
using NcProgramManager.Cnc.Models;
using NcProgramManager.Licensing;
namespace NcProgramManager
{
internal class Program
{
private static readonly Logger _log = LogManager.GetCurrentClassLogger();
public static int Main(string[] args)
{
InputArgs inputArgs;
try
{
inputArgs = ArgParser.Parse(args);
}
catch (Exception e)
{
_log.Error(e, "Arg parsing failed");
_log.Info("Gestore Programmi FANUC: {0}", e.Message);
_log.Info("Errore parametri input. Consulta `-help' per maggiori informazioni.");
VediErrore(-101, false);
return -101;
}
if (inputArgs.mostraHelp)
{
MostraAiuto();
VediErrore(0, inputArgs.debugMode);
return 0;
}
string licFingerprint = new MachineFingerprint().GetFingerprint();
string licBase64;
string licPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "license.lic");
if (!LicenseFile.TryRead(licPath, out licBase64)
|| !new LicenseValidator().Validate(licFingerprint, licBase64))
{
_log.Info("Licenza ERRATA");
VediErrore(-100, inputArgs.debugMode);
return -1;
}
bool needsIp = inputArgs.manufacturer != CncManufacturer.Fanuc || inputArgs.nodoHssb == -1;
if (inputArgs.azione == "" || (needsIp && string.IsNullOrEmpty(inputArgs.ip)) || inputArgs.pathLocaleProgramma == "")
{
VediErrore(-102, inputArgs.debugMode);
return -102;
}
_log.Info("manufacturer: {0}", inputArgs.manufacturer);
_log.Info("IndirizzoIP: {0}", inputArgs.ip);
_log.Info("Porta: {0}", inputArgs.porta);
_log.Info("Compatibility: {0}", inputArgs.compatibilityMode);
_log.Info("commentoProgramma: {0}", inputArgs.commentoProgramma);
_log.Info("pathCNC: {0}", inputArgs.pathCNC);
_log.Info("pathLocaleProgramma: {0}", inputArgs.pathLocaleProgramma);
ICncMachine machine = null;
try
{
machine = CncMachineFactory.Create(inputArgs);
switch (inputArgs.azione.ToUpperInvariant())
{
case "SCARICA": return Scarica(machine, inputArgs);
case "INVIA": return Invia(machine, inputArgs);
default:
VediErrore(-103, inputArgs.debugMode);
return -103;
}
}
finally
{
if (machine != null)
machine.Dispose();
}
}
static int Scarica(ICncMachine macchina, InputArgs inputArgs)
{
_log.Info("RICEVI DA CNC-->");
bool connected = false;
try
{
var connResult = macchina.ConnectAsync().GetAwaiter().GetResult();
if (!connResult.Success)
{
_log.Info("Macchina non connessa");
PrintErrors(connResult.Errors);
VediErrore(-201, inputArgs.debugMode);
return -201;
}
connected = true;
_log.Info("Inizio RICEZIONE NCProgram");
var progResult = macchina.ReadProgramAsync(inputArgs.pathCNC.ToString()).GetAwaiter().GetResult();
_log.Info("Fine RICEZIONE NCProgram");
if (!progResult.Success || string.IsNullOrEmpty(progResult.Value))
{
PrintErrors(progResult.Errors);
VediErrore(-204, inputArgs.debugMode);
return -204;
}
FanucProgram programma = new FanucProgram(progResult.Value);
IFanucMachine fanuc = macchina as IFanucMachine;
if (inputArgs.hasToolOffsetData)
{
if (fanuc == null)
{
_log.Info("ToolOffset non supportato per questo produttore");
VediErrore(-205, inputArgs.debugMode);
return -205;
}
_log.Info("Inizio RICEZIONE ToolOffsetData");
var toolResult = fanuc.ReadToolDataAsync(inputArgs.pathCNC.ToString()).GetAwaiter().GetResult();
_log.Info("Fine RICEZIONE ToolOffsetData");
if (!toolResult.Success || string.IsNullOrEmpty(toolResult.Value))
{
PrintErrors(toolResult.Errors);
VediErrore(-205, inputArgs.debugMode);
return -205;
}
programma.setValue(toolResult.Value, FanucProgram.FILE_TYPE.TOOL_OFFEST_DATA);
}
if (inputArgs.hasWorkZeroOffsetData)
{
if (fanuc == null)
{
_log.Info("WorkZeroOffset non supportato per questo produttore");
VediErrore(-206, inputArgs.debugMode);
return -206;
}
_log.Info("Inizio RICEZIONE WorkZeroOffsetData");
var workResult = fanuc.ReadWorkZeroDataAsync(inputArgs.pathCNC.ToString()).GetAwaiter().GetResult();
_log.Info("Fine RICEZIONE WorkZeroOffsetData");
if (!workResult.Success || string.IsNullOrEmpty(workResult.Value))
{
PrintErrors(workResult.Errors);
VediErrore(-206, inputArgs.debugMode);
return -206;
}
programma.setValue(workResult.Value, FanucProgram.FILE_TYPE.WORK_ZERO_OFFSET);
}
File.WriteAllText(inputArgs.pathLocaleProgramma, programma.ToString());
VediErrore(0, inputArgs.debugMode);
return 0;
}
catch (Exception ex)
{
_log.Error(ex, "Scarica failed");
_log.Info("{0}", ex.Message);
VediErrore(-202, inputArgs.debugMode);
return -202;
}
finally
{
if (connected)
macchina.DisconnectAsync().GetAwaiter().GetResult();
}
}
static int Invia(ICncMachine macchina, InputArgs inputArgs)
{
_log.Info("INVIA A CNC-->");
bool connected = false;
try
{
var connResult = macchina.ConnectAsync().GetAwaiter().GetResult();
if (!connResult.Success)
{
_log.Info("Macchina non connessa");
PrintErrors(connResult.Errors);
VediErrore(-201, inputArgs.debugMode);
return -201;
}
connected = true;
FanucProgram programma = new FanucProgram(File.ReadAllText(inputArgs.pathLocaleProgramma));
if (!string.IsNullOrEmpty(inputArgs.commentoProgramma))
programma.ChangeComment(inputArgs.commentoProgramma);
if (programma.Program != null)
{
_log.Info("Inizio INVIO NCProgram");
var cncProg = new CncProgram
{
Name = programma.GetProgramTitle(),
Comment = programma.GetProgramComment(),
Content = programma.Program,
Path = inputArgs.pathCNC.ToString()
};
var writeResult = macchina.WriteProgramAsync(inputArgs.pathCNC.ToString(), cncProg).GetAwaiter().GetResult();
_log.Info("Fine INVIO NCProgram");
if (!writeResult.Success)
{
PrintErrors(writeResult.Errors);
VediErrore(-204, inputArgs.debugMode);
return -204;
}
}
IFanucMachine fanuc = macchina as IFanucMachine;
if (programma.ToolOffsetData != null && inputArgs.hasToolOffsetData)
{
if (fanuc == null)
{
_log.Info("ToolOffset non supportato per questo produttore");
VediErrore(-205, inputArgs.debugMode);
return -205;
}
_log.Info("Inizio INVIO ToolOffsetData");
var toolResult = fanuc.WriteToolDataAsync(inputArgs.pathCNC.ToString(), programma.ToolOffsetData).GetAwaiter().GetResult();
_log.Info("Fine INVIO ToolOffsetData");
if (!toolResult.Success)
{
PrintErrors(toolResult.Errors);
VediErrore(-205, inputArgs.debugMode);
return -205;
}
}
if (programma.WorkZeroOffsetData != null && inputArgs.hasWorkZeroOffsetData)
{
if (fanuc == null)
{
_log.Info("WorkZeroOffset non supportato per questo produttore");
VediErrore(-206, inputArgs.debugMode);
return -206;
}
_log.Info("Inizio INVIO WorkZeroOffsetData");
var workResult = fanuc.WriteWorkZeroDataAsync(inputArgs.pathCNC.ToString(), programma.WorkZeroOffsetData).GetAwaiter().GetResult();
_log.Info("Fine INVIO WorkZeroOffsetData");
if (!workResult.Success)
{
PrintErrors(workResult.Errors);
VediErrore(-206, inputArgs.debugMode);
return -206;
}
}
VediErrore(0, inputArgs.debugMode);
return 0;
}
catch (Exception ex)
{
_log.Error(ex, "Invia failed");
_log.Info("{0}", ex.Message);
VediErrore(-202, inputArgs.debugMode);
return -202;
}
finally
{
if (connected)
macchina.DisconnectAsync().GetAwaiter().GetResult();
}
}
static void PrintErrors(IReadOnlyList<CncError> errors)
{
if (errors == null) return;
foreach (var e in errors)
_log.Info(" {0}", e.ToString());
}
static void VediErrore(int errore, bool debugMode)
{
_log.Info("Errore:{0}", errore);
_log.Info("");
_log.Info("Codici Errori:");
_log.Info("-100 : Licenza Errata/non valida.");
_log.Info("-101 : Impossibile parsare i parametri.");
_log.Info("-102 : Parametri mancanti. ");
_log.Info("-103 : Codice connessione errato: 3->Ethernet 2->HSSB. ");
_log.Info("-201 : Macchina non connessa. ");
_log.Info("-202 : Eccezione nell'esecuzione dell'AZIONE. ");
_log.Info("-203 : L'azione è fallita. ");
_log.Info("-204 : Errore in fase invio/ricezione Programma CN. ");
_log.Info("-205 : Errore in fase invio/ricezione tool offset data ");
_log.Info("-206 : Errore in fase invio/ricezione work zero offest data");
_log.Info("-207 : Posizionare il CN in MDI o EDIT per eseguire l'invio di un programma");
_log.Info("-208 : Programma CN Caricato ma non settato a main.");
if (debugMode)
Console.ReadLine();
}
static void MostraAiuto()
{
_log.Info("Utilizzo del Software gestore Programmi FANUC");
_log.Info("Le funzioni pricipali sono due.");
_log.Info("INVIA: caricamento di programma su CNC.");
_log.Info("SCARICA: scaricamento di programma su CNC.");
_log.Info("");
_log.Info("");
_log.Info("Lista dei parametri da fornire all'eseguibile\nDevono essere separati da uno spazio tra l'uno e l'altro,\nnon andare a capo e non lasciare spazi dopo l'= ");
_log.Info("");
_log.Info("Il file 'license.lic' deve essere posizionato nella stessa cartella dell'eseguibile.");
_log.Info("-azione=");
_log.Info(" l'{AZIONE} da eseguire.");
_log.Info("-manufacturer=");
_log.Info(" Il produttore del CNC: fanuc (default), heidenhain, siemens, mitsubishi");
_log.Info("-tipo=");
_log.Info(" Il tipo di connessione utilizzato dalla macchina: 3 per ethernet\n 2 per HSSB (solo Fanuc, legacy)");
_log.Info("-ip=");
_log.Info(" Dato per Ethernet indirizzo IP della macchina");
_log.Info("-porta=");
_log.Info(" Dato per Ethernet PORTA di connessione");
_log.Info("-nodo=");
_log.Info(" Dato per HSSB Nodo di connesione (solo Fanuc)");
_log.Info("-username=");
_log.Info(" Username per autenticazione (Heidenhain/Siemens)");
_log.Info("-password=");
_log.Info(" Password per autenticazione (Heidenhain/Siemens)");
_log.Info("-compatibility");
_log.Info(" Attivazione modalità compatibilità");
_log.Info("-commento=");
_log.Info(" Commento da applicare al programma scelto");
_log.Info("-path=");
_log.Info(" Path dei programmi del CNC dove vengono salvati i programmi, se non definito è impostato a 1 cioè //CNC_MEM/USER/PATH1/");
_log.Info("-pathprogramma=");
_log.Info(" Necessario per INVIO: Path del programma locale da caricare sul CNC");
_log.Info("-workzero=");
_log.Info(" Invia/Scarica anche i dati relativi al workzero offset");
_log.Info("-tooloffset=");
_log.Info(" Invia/Scarica anche i dati relativi al tool offset");
_log.Info("-debug=");
_log.Info(" Mantiene il terminale aperto alla fine delle operazioni");
_log.Info("-help");
_log.Info(" Mostra questo messaggio e termina");
_log.Info("");
_log.Info("Codici Errori:");
_log.Info("-100 : Licenza Errata/non valida.");
_log.Info("-101 : Impossibile parsare i parametri.");
_log.Info("-102 : Parametri mancanti. ");
_log.Info("-103 : Codice connessione errato: 3->Ethernet 2->HSSB. ");
_log.Info("-201 : Macchina non connessa. ");
_log.Info("-202 : Eccezione nell'esecuzione dell'AZIONE. ");
_log.Info("-203 : L'azione è fallita. ");
_log.Info("-204 : Errore in fase invio/ricezione Programma CN. ");
_log.Info("-205 : Errore in fase invio/ricezione tool offset data ");
_log.Info("-206 : Errore in fase invio/ricezione work zero offest data");
_log.Info("-207 : Posizionare il CN in MDI o EDIT per eseguire l'invio di un programma");
_log.Info("-208 : Programma CN Caricato ma non settato a main.");
}
}
}