using Microsoft.AspNetCore.Mvc; using MP.Core.DTO; using MP.IOC.Data; using Newtonsoft.Json; using NLog; using System.Reflection; namespace MP.IOC.Controllers { [Route("api/[controller]")] [ApiController] public class IOBController : ControllerBase { #region Public Constructors public IOBController(IConfiguration configuration, MpDataService DataService) { _configuration = configuration; DService = DataService; } #endregion Public Constructors #region Public Methods /// SALVA x macchina KVP parametro/valore: /// GET: api/IOB/addOptPar/SIMUL_03?pName=PZREQ&pValue=1000 /// [HttpGet("addOptPar/{id}")] public async Task AddOptPar(string id, string pName, string pValue) { DService.ScriviKeepAlive(id, DateTime.Now); try { DService.AddOptPar4Machine(id, pName, pValue); return await GetOptPar(id); } catch { return StatusCode(StatusCodes.Status500InternalServerError, "Errore interno | AddOptPar"); } } /// /// GET: IOB/ /// /// [HttpGet] public IActionResult Alive() { return Ok("OK"); // Restituisce Status 200 } /// /// GET: IOB/enabled/SIMUL_03 /// /// /// [HttpGet("enabled/{id}")] public IActionResult Enabled(string id) { if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID"); if (DService.IobInsEnab(id)) { return Ok("OK"); } else { //return StatusCode(503, "NO"); return UnprocessableEntity("NO"); } } /// /// Recupera COUNTER x macchina: /// GET: IOB/getCounter/SIMUL_03 /// /// /// Il conteggio pezzi o un errore strutturato [HttpGet("getCounter/{id}")] public async Task GetCounter(string id) { if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID"); try { var pzCount = await DService.pzCounter(id); return Ok(pzCount); } catch (Exception exc) { Log.Error(exc, "Errore durante il recupero del counter per la macchina {MachineId}", id); return StatusCode(StatusCodes.Status500InternalServerError, "Errore interno | GetCounter"); } } /// /// Recupera COUNTER x macchina dal CONTEGGIO dei TCRecorded: /// /// GET: IOB/getCounterTCRec/5 /// /// /// Il conteggio pezzi o un errore strutturato [HttpGet("getCounterTCRec/{id}")] public async Task GetCounterTCRec(string id) { if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID"); // Multi: gestione carattere "|" trasformato in "#" id = id.Replace("|", "#"); try { var pzCount = await DService.pzCounterTcAsync(id); return Ok(pzCount); } catch (Exception exc) { Log.Error(exc, "Errore durante il recupero del counter TC per la macchina {MachineId}", id); //return StatusCode(StatusCodes.Status500InternalServerError, "NO"); return StatusCode(StatusCodes.Status500InternalServerError, "Errore interno | GetCounterTCRec"); } } /// /// GET elenco parametri correnti x IOB /// /// /// [HttpGet("getCurrObjItems/{id}")] public async Task GetCurrObjItems(string id) { if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID"); // Multi: gestione carattere "|" trasformato in "#" id = id.Replace("|", "#"); var rawData = await DService.MachineParamListAsync(id); List actValues = new List(); // ordino! actValues = rawData .OrderBy(x => x.displOrdinal) .ThenBy(x => x.description) .ToList(); return Ok(actValues); } /// /// Recupera ODL corrente x macchina: /// GET: IOB/getCurrODL/SIMUL_03 /// /// /// [HttpGet("getCurrODL/{id}")] public async Task GetCurrODL(string id) { if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID"); // Multi: gestione carattere "|" trasformato in "#" id = id.Replace("|", "#"); try { var odl = await DService.GetCurrOdlAsync(id); return Ok($"{odl}"); } catch (Exception exc) { Log.Error(exc, "Errore GetCurrODL | macchina {MachineId}", id); return StatusCode(StatusCodes.Status500InternalServerError, "NO"); //return StatusCode(StatusCodes.Status500InternalServerError, "Errore interno | GetCurrODL"); } } /// /// Restituisce la quantità pezzi dell'odl correntemente in lavorazione sulla macchina... /// GET: IOB/getCurrOdlQtaReq/SIMUL_01 /// /// /// [HttpGet("getCurrOdlQtaReq/{id}")] public async Task GetCurrOdlQtaReq(string id) { if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID"); // Multi: gestione carattere "|" trasformato in "#" id = id.Replace("|", "#"); int answ = 0; // chiamo metodo redis/db... try { var odlData = await DService.OdlCurrByMaccAsync(id); if (odlData != null && odlData.DataInizio.HasValue) { answ = odlData.NumPezzi; } } catch (Exception exc) { Log.Error($"Eccezione in recupero GetCurrOdlQtaReq{Environment.NewLine}{exc}"); return StatusCode(StatusCodes.Status500InternalServerError, "NO"); } return Ok(answ); } /// /// Restituisce data-ora inizio dell'odl correntemente in lavorazione sulla macchina... /// es: http://url_site/MP/IO/IOB/getCurrOdlStart/SIMUL_03 /// /// /// [HttpGet("getCurrOdlStart/{id}")] public async Task GetCurrOdlStart(string id) { if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID"); // Multi: gestione carattere "|" trasformato in "#" id = id.Replace("|", "#"); DateTime answ = new DateTime(DateTime.Now.Year - 1, 12, 31); // chiamo metodo redis/db... try { var odlData = await DService.OdlCurrByMaccAsync(id); if (odlData != null && odlData.DataInizio.HasValue) { answ = odlData.DataInizio.Value; } } catch (Exception exc) { Log.Error($"Eccezione in recupero getCurrOdlStart{Environment.NewLine}{exc}"); return StatusCode(StatusCodes.Status500InternalServerError, "NO"); } return Ok(answ.ToString("yyyy-MM-dd HH:mm:ss")); } /// /// Recupera TASK richiesto x macchina: /// GET: IOB/getOptPar/SIMUL_03 /// /// /// Json contenente 1..n task da eseguire [HttpGet("getOptPar/{id}")] public async Task GetOptPar(string id) { if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID"); // Multi: gestione carattere "|" trasformato in "#" id = id.Replace("|", "#"); string answ = ""; // scrivo keep alive!!! (se necessario, altrimenti è in cache...) DService.ScriviKeepAlive(id, DateTime.Now); try { // leggo da REDIS eventuale elenco task x macchina... Dictionary valori = DService.mOptParMacchina(id); answ = JsonConvert.SerializeObject(valori); } catch { } return Ok(answ); } /// /// Recupera TASK richiesto x macchina: /// GET: IOB/getTask2Exe/SIMUL_03 /// /// /// Json contenente 1..n task da eseguire [HttpGet("getTask2Exe/{id}")] public async Task GetTask2Exe(string id) { if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID"); // Multi: gestione carattere "|" trasformato in "#" id = id.Replace("|", "#"); string answ = ""; DService.ScriviKeepAlive(id, DateTime.Now); // leggo da REDIS eventuale elenco task x macchina... Dictionary valori = await DService.GetTask2ExeMacchinaAsync(id); answ = JsonConvert.SerializeObject(valori); return Ok(answ); } /// /// Metodo di dichiarazione "improprio" tramite get call totalmetne definita da URL /// GET: IOB/input/SIMUL_03?valore=3&dtEve=20181206180600000&dtCurr=20181206180600000&cnt=999 /// /// /// /// /// /// /// [HttpGet("input/{id}")] public async Task Input(string id, string valore, string dtEve, string dtCurr, string cnt) { if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID"); string answ = ""; if (cnt == null) { cnt = "0"; } DateTime dataOraEvento = DateTime.Now; try { answ = DService.processInput(id, valore, dtEve, dtCurr, cnt); return Ok(answ); } catch (Exception exc) { Log.Error($"Errore in processInput{Environment.NewLine}{exc}"); return StatusCode(StatusCodes.Status500InternalServerError, "NO"); } } /// /// Processa una chiamata POST per l'invio di una Dictionary HashList da salvare in redis /// POST: IOB/saveMachineIobConf/SIMUL_03 /// /// ID dell'IOB /// [HttpPost] [HttpPost("saveMachineIobConf/{id}")] public async Task SaveMachineIobConf(string id, [FromBody] Dictionary currDict) { if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID"); // Multi: gestione carattere "|" trasformato in "#" id = id.Replace("|", "#"); string answ = "NA"; try { bool fatto = await DService.SaveMachineIobConf(id, currDict); answ = fatto ? "OK" : "KO"; } catch (Exception exc) { Log.Error($"Errore in saveMachineIobConf{Environment.NewLine}{exc}"); return StatusCode(StatusCodes.Status500InternalServerError, "NO"); } return Ok(answ); } /// /// SALVA in blocco un incremento pezzi x macchina restituendo il valore appena inviato o, /// se mancasse chaive redis, del valore da DB /// /// GET: IOB/savePzCountInc/5?qty=10 /// /// codice macchina /// num peziz da salvare in blocco /// [HttpGet("savePzCountInc/{id}")] public async Task SavePzCountInc(string id, string qty) { if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID"); // Multi: gestione carattere "|" trasformato in "#" id = id.Replace("|", "#"); string answ = ""; DateTime dataOraEvento = DateTime.Now; // salvo SEMPRE log x questo tipo di dati! Log.Info($"Salvataggio incremento contapezzi | id: {id} | pezzi: {qty}"); try { answ = await DService.saveCaricoPezzi(id, qty); return Ok(answ); } catch (Exception exc) { Log.Error($"Errore in savePzCountInc{Environment.NewLine}{exc}"); return StatusCode(StatusCodes.Status500InternalServerError, "NO"); } } /// /// SALVA Counter x macchina restituendo il valore appena inviato o, se mancasse chiave /// redis, del valore da DB /// /// GET: IOB/setCounter/5?counter=10 /// /// cod macchina /// contapezzi da salvare /// [HttpGet("setCounter/{id}")] public async Task SetCounter(string id, string counter) { if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID"); // Multi: gestione carattere "|" trasformato in "#" id = id.Replace("|", "#"); string answ = "-1"; DateTime dataOraEvento = DateTime.Now; Log.Debug($"Salvataggio counter | id: {id} | pzCount: {counter}"); answ = DService.saveCounter(id, counter); return Ok(answ); } /// /// Processa una chiamata POST per l'invio di una List Json di UNO O PIU' oggetti objItem /// POST: IOB/upsertObjItems/SIMUL_03 /// /// ID dell'IOB /// [HttpPost("upsertObjItems/{id}")] public async Task UpsertObjItems(string id, [FromBody] List innovazioni) { if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID"); // Multi: gestione carattere "|" trasformato in "#" id = id.Replace("|", "#"); string answ = "NA"; try { // se != null --> salvo! if (innovazioni != null) { // salvo bool fatto = await DService.MachineParamUpsertAsync(id, innovazioni); answ = "OK"; } } catch (Exception exc) { Log.Error($"Errore in upsertObjItems{Environment.NewLine}{exc}"); return StatusCode(StatusCodes.Status500InternalServerError, "NO"); } return Ok(answ); } /// /// Verifica versione corrente REST API /// /// [HttpGet("version")] public IActionResult Version() { var version = Assembly .GetExecutingAssembly() .GetName() .Version? .ToString() ?? "unknown"; return Ok(version); } #endregion Public Methods #region Private Fields private static IConfiguration _configuration = null!; private static Logger Log = LogManager.GetCurrentClassLogger(); #endregion Private Fields #region Private Properties /// /// Dataservice x accesso DB /// private MpDataService DService { get; set; } #endregion Private Properties } }