using CMS_CORE_Library.Models; using System; using System.Collections.Generic; using System.Web.Http; using TeamDev.SDK.MVVM; using Thermo.Active.Config; using Thermo.Active.Model.DTOModels.ThRecipe; using Thermo.Active.Model.DTOModels.ThWarmers; using Thermo.Active.NC; using Thermo.Active.Utils; using static Thermo.Active.Config.ServerConfig; using static Thermo.Active.Model.Constants; using static CMS_CORE_Library.Models.DataStructures; using System.Web.Http.Description; using Thermo.Active.Thermocamera; using System.Linq; namespace Thermo.Active.Controllers.WebApi { [RoutePrefix("api/warmers")] public class WarmersController : ApiController { #region Protected Fields /// /// Oggetto adapter condiviso da WebAPI /// protected static NcAdapter ncAdapter = new NcAdapter(); protected Dictionary MeasurePoints = new Dictionary(); /// /// Libreria x gestione dati thermocamera /// protected ThermoCamComunicator TCCom = new ThermoCamComunicator(false); #endregion Protected Fields #region Private Methods /// /// Do actual recipe warmers SetpointHMI File-Save /// /// private static void saveCurrentRecipeWarmersData(Dictionary chSetpoints, Dictionary chTCamTempReq, Dictionary chTCamEnab) { try { // ora salvo ANCHE i dati live... NcAdapter.RecipeLiveData.ChannelSetpoints = chSetpoints; NcAdapter.RecipeLiveData.ChannelTCamTempReq = chTCamTempReq; NcAdapter.RecipeLiveData.ChannelTCamEnab = chTCamEnab; // e salvo su disco NcFileAdapter.SaveRecipeCurrent(); } catch (Exception exc) { ThermoActiveLogger.LogError($"Warmers | saveCurrentRecipeWarmersData exception | {exc}"); } notifyHmi(); } #endregion Private Methods #region Protected Methods /// /// Esegue notifica HMI delle modifiche sulla ricetta/riscaldi /// /// protected static CmsError notifyHmi() { CmsError libraryError = NO_ERROR; // invio dati NUOVA ricetta (DOPO aver sistemato PLC) DTORecipeStatus message = new DTORecipeStatus() { recipeName = NcAdapter.RecipeLiveData.RecipeName, hasChanged = NcAdapter.RecipeLiveData.hasChanged, forceSend = true }; MessageServices.Current.Publish(SEND_THERMO_RECIPE_CHANGED, null, message); // invio dati warmers aggiornati... // Get new data from PLC libraryError = ncAdapter.ReadWarmers(false, out Dictionary currWarmers); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"Load error | ReadWarmers | {libraryError.errorCode} | {libraryError.exception} | {libraryError.localizationKey}"); return libraryError; } // pubblico MessageServices.Current.Publish(SEND_THERMO_WARMERS_DATA, null, currWarmers); return libraryError; } #endregion Protected Methods #region Public Methods /// /// Add point to list for thermo data acquisition /// /// [Route("addMeasurePoint"), HttpPut] public IHttpActionResult AddMeasurePoint(int posX, int posY) { int nextId = MeasurePoints.Count; // aggiungo punto ThermoPoint result = new ThermoPoint() { X = posX, Y = posY }; MeasurePoints.Add(nextId, result); // ritorno! return Ok(); } /// /// Cancel recipe modification (parameters: PLC --> HMI) /// /// [Route("cancel"), HttpPut] [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.RECIPE_MANAGER, Action = ACTIONS.READ)] public IHttpActionResult CancelEdit() { // Try connection CmsError libraryError = ncAdapter.Connect(); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"NC Not connected! | Recipe CancelEdit | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // scrivo sul PLC il comando annula! libraryError = ncAdapter.ConfirmRecipeData(false); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"Warmers CancelEdit error | ConfirmRecipeData | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // recupero i dati LIVE dei parametri HMI dei riscaldi... libraryError = ncAdapter.ReadWarmers(false, out Dictionary currWarmers); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"Warmers ConfirmEdit error | ReadWarmers | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // preparo SetpointHMI var currSetpointHMI = new Dictionary(); foreach (var item in currWarmers) { currSetpointHMI.Add(item.Key, item.Value.SetpointHMI); } // preparo TCamTempReq var currTCamTempReq = new Dictionary(); foreach (var item in currWarmers) { currTCamTempReq.Add(item.Key, item.Value.TCamTempSet); } // preparo SetpointHMI var currTCamEnab = new Dictionary(); foreach (var item in currWarmers) { currTCamEnab.Add(item.Key, item.Value.TCamActive); } // salvo! saveCurrentRecipeWarmersData(currSetpointHMI, currTCamTempReq, currTCamEnab); // ritorno solo fatto! return Ok(); } /// /// Confirm recipe modification (parameters: HMI --> PLC) /// /// [Route("confirm"), HttpPut] [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.RECIPE_MANAGER, Action = ACTIONS.READ)] public IHttpActionResult ConfirmEdit() { // Try connection CmsError libraryError = ncAdapter.Connect(); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"NC Not connected! | Warmers ConfirmEdit | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // sezione riscaldi --> salvo come modificata... RecipeSection section = RecipeSection.Heats; try { NcFileAdapter.upsRecipeOverview(section, RecipeCatStatus.ChangedOk); } catch (Exception exc) { ThermoActiveLogger.LogError($"Error on set recipe overview | section: {section}{Environment.NewLine}{exc}"); } // scrivo sul PLC il comando conferma! libraryError = ncAdapter.ConfirmRecipeData(true); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"Warmers ConfirmEdit error | ConfirmRecipeData | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // recupero i dati LIVE dei parametri HMI dei riscaldi... libraryError = ncAdapter.ReadWarmers(false, out Dictionary currWarmers); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"Warmers ConfirmEdit error | ReadWarmers | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // preparo SetpointHMI var currSetpointHMI = new Dictionary(); foreach (var item in currWarmers) { currSetpointHMI.Add(item.Key, item.Value.SetpointHMI); } // preparo TCamTempReq var currTCamTempReq = new Dictionary(); foreach (var item in currWarmers) { currTCamTempReq.Add(item.Key, item.Value.TCamTempSet); } // preparo SetpointHMI var currTCamEnab = new Dictionary(); foreach (var item in currWarmers) { currTCamEnab.Add(item.Key, item.Value.TCamActive); } // salvo! saveCurrentRecipeWarmersData(currSetpointHMI, currTCamTempReq, currTCamEnab); // ritorno solo fatto! return Ok(); } /// /// Get area info (plate) for display on HMI /// /// [Route("area"), HttpGet] public IHttpActionResult GetCurrentAreaPerc() { // Try connection CmsError libraryError = ncAdapter.Connect(); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"NC Not connected! | GetCurrentAreaPerc | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // recupera aree % X / Y libraryError = ncAdapter.GetWarmMaterialArea(out Dictionary currAreaPerc); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"GetCurrentAreaPerc error | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } return Ok(currAreaPerc); } /// /// Current status related to ThermoCamera /// /// [ResponseType(typeof(DTOThermoCam))] [Route("TCamData"), HttpGet] public IHttpActionResult GetCurrentTCamData() { // Try connection CmsError libraryError = ncAdapter.Connect(); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"NC Not connected! | GetCurrentTCamData | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } libraryError = ncAdapter.ReadTCamData(out DTOThermoCam currTCamData); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"GetCurrentTCamData error | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } return Ok(currTCamData); } /// /// Current channels status /// /// [Route("channels"), HttpGet] public IHttpActionResult GetCurrentWarmersChannels() { // Try connection CmsError libraryError = ncAdapter.Connect(); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"NC Not connected! | GetCurrentWarmersChannels | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } libraryError = ncAdapter.ReadWarmers(false, out Dictionary currWarmers); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"GetCurrentWarmersChannels error | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } return Ok(currWarmers); } /// /// Resistance setup info /// /// [Route("resistances"), HttpGet] public IHttpActionResult GetCurrentWarmersResistances() { // Try connection CmsError libraryError = ncAdapter.Connect(); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"NC Not connected! | GetCurrentWarmersResistances | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } libraryError = ncAdapter.GetWarmersResistances(out Dictionary currWarmers); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"GetCurrentWarmersResistances error | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } return Ok(currWarmers); } [ResponseType(typeof(List))] [Route("getMeasurePoints"), HttpGet] public IHttpActionResult GetMeasurePoints(string setName) { // init punti... List resultPoints = new List(); // Chiamo l'oggetto thermocam x il set richiesto... TCCom.readMultiTemperatures(setName, MeasurePoints, out resultPoints); // ritorno! return Ok(resultPoints); } /// /// Force reset point list for thermo data acquisition /// /// [Route("resetMeasurePoint"), HttpPut] public IHttpActionResult ResetMeasurePoints() { MeasurePoints = new Dictionary(); // ritorno solo fatto! return Ok(); } /// /// Force write risk setup + others warmers data (ex ThermoCam) /// /// [Route("setConfig"), HttpPut] [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.RECIPE_MANAGER, Action = ACTIONS.READ)] public IHttpActionResult SetConfig() { // scrive configurazioni RISK // Try connection CmsError libraryError = ncAdapter.Connect(); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"NC Not connected! | SetConfig | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // scrivo sul PLC setup warmers libraryError = ncAdapter.WriteRecipeWarmConfig(); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"Warmers SetConfig error | WriteRecipeWarmConfig | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // ritorno solo fatto! return Ok(); } /// /// Set/Unset ThermoCam mode /// /// /// [Route("setTCamMode"), HttpPut] [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.RECIPE_MANAGER, Action = ACTIONS.READ)] public IHttpActionResult SetTCamMode(bool enableTCam) { // scrive su CommandWord attivazione funzione ThermoCam // Try connection CmsError libraryError = ncAdapter.Connect(); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"NC Not connected! | SetTCamMode | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // scrivo sul PLC libraryError = ncAdapter.SetTCamMode(enableTCam); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"SetTCamMode error | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // ritorno solo fatto! return Ok(); } /// /// Set ThermoCam On/Off /// /// /// [Route("setTCamOn"), HttpPut] [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.RECIPE_MANAGER, Action = ACTIONS.READ)] public IHttpActionResult SetTCamOn(bool setTCamOn) { // scrive su CommandWord attivazione funzione ThermoCam // Try connection CmsError libraryError = ncAdapter.Connect(); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"NC Not connected! | setTCamOn | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // scrivo sul PLC libraryError = ncAdapter.SetTCamActiv(setTCamOn); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"setTCamOn error | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // ritorno solo fatto! return Ok(); } /// /// Simulate Flir image req from PLC /// /// /// [Route("simReqFlirImg"), HttpPut] [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.RECIPE_MANAGER, Action = ACTIONS.READ)] public IHttpActionResult SimReqFlirImg() { // Try connection CmsError libraryError = ncAdapter.Connect(); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"NC Not connected! | SimReqFlirImg | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // recupero valori attuali libraryError = ncAdapter.ReadWarmers(false, out Dictionary currWarmers); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"SimReqFlirImg | GetRecipeOverview error | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // scrivo sul PLC i dati SIMULATI di una lettura Flir Dictionary chSimTemp = new Dictionary(); Random rnd = new Random(); double simVal = 0; foreach (var item in currWarmers) { if (item.Value.TCamTempSet > 100) { simVal = item.Value.TCamTempSet + (rnd.NextDouble() * 10 - 5); } else { simVal = rnd.NextDouble() * 200 + 100; } // accodo! chSimTemp.Add(item.Key, simVal); } libraryError = ncAdapter.WriteRecipeWarmChTCamTempAct(chSimTemp); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"SimReqFlirImg error | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // recupero valori attuali post update libraryError = ncAdapter.ReadWarmers(false, out Dictionary newWarmers); // pubblico MessageServices.Current.Publish(SEND_THERMO_WARMERS_DATA, null, newWarmers); // ritorno solo fatto! return Ok(); } /// /// Write SetpointHMI (%) /// /// /// [Route("update"), HttpPut] [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.RECIPE_MANAGER, Action = ACTIONS.READ)] public IHttpActionResult WriteSetpoints(Dictionary channelsLoad) { // scrive su CHp da ricetta oppure da override x parametri utente... if (channelsLoad != null) { // Try connection CmsError libraryError = ncAdapter.Connect(); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"NC Not connected! | WriteSetpoints | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // scrivo sul PLC libraryError = ncAdapter.WriteRecipeWarmChSetpHMI(channelsLoad); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"WriteSetpoints error | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // ritorno solo fatto! return Ok(); } else { return NotFound(); } } /// /// Write Termocam channels ENABLED /// /// /// [Route("updateTCamEnab"), HttpPut] [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.RECIPE_MANAGER, Action = ACTIONS.READ)] public IHttpActionResult WriteTCamEnab(Dictionary channelsEnab) { // scrive su CHp da ricetta oppure da override x parametri utente... if (channelsEnab != null) { // Try connection CmsError libraryError = ncAdapter.Connect(); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"NC Not connected! | WriteTCamEnab | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // scrivo sul PLC libraryError = ncAdapter.WriteRecipeWarmChTCamEnab(channelsEnab); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"WriteTCamEnab error | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // ritorno solo fatto! return Ok(); } else { return NotFound(); } } /// /// Write Termocam Temperature Setpoint (°C) /// /// /// [Route("updateTCamTemp"), HttpPut] [WebApiAuthorize(FunctionAccess = FUNCTIONALITY_NAMES.RECIPE_MANAGER, Action = ACTIONS.READ)] public IHttpActionResult WriteTCamTempSet(Dictionary channelsTemp) { // scrive su CHp da ricetta oppure da override x parametri utente... if (channelsTemp != null) { // Try connection CmsError libraryError = ncAdapter.Connect(); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"NC Not connected! | WriteTCamTempSet | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // scrivo sul PLC libraryError = ncAdapter.WriteRecipeWarmChTCamTempSet(channelsTemp); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"WriteTCamTempSet error | {libraryError.exception}"); return BadRequest(libraryError.localizationKey); } // ritorno solo fatto! return Ok(); } else { return NotFound(); } } #endregion Public Methods } }