From 1dd83f4e17f435e7d3e7fe0fb922db24e2c189ae Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 24 Jun 2020 18:45:22 +0200 Subject: [PATCH 1/4] Refactoring methods for File persistance --- Thermo.Active.Config/ServerConfig.cs | 1 - .../ServerConfigController.cs | 196 ---------------- .../Thermo.Active.Config.csproj | 1 - .../DTOModels/ThRecipe}/LiveData.cs | 7 +- .../Thermo.Active.Model.csproj | 1 + Thermo.Active.NC/NcAdapter.cs | 14 +- Thermo.Active.NC/NcFileAdapter.cs | 213 ++++++++++++++++++ Thermo.Active.NC/Thermo.Active.NC.csproj | 4 + Thermo.Active.NC/packages.config | 4 + .../Controllers/WebApi/RecipeController.cs | 28 +-- .../Controllers/WebApi/WarmersController.cs | 4 +- Thermo.Active/Properties/AssemblyInfo.cs | 2 +- Thermo.Active/program.cs | 2 +- 13 files changed, 253 insertions(+), 224 deletions(-) rename {Thermo.Active.Config => Thermo.Active.Model/DTOModels/ThRecipe}/LiveData.cs (76%) create mode 100644 Thermo.Active.NC/packages.config diff --git a/Thermo.Active.Config/ServerConfig.cs b/Thermo.Active.Config/ServerConfig.cs index ca673d75..089ef523 100644 --- a/Thermo.Active.Config/ServerConfig.cs +++ b/Thermo.Active.Config/ServerConfig.cs @@ -62,7 +62,6 @@ namespace Thermo.Active.Config public static List RiskChannelConfig; public static List RiskBoardConfig; - public static LiveData RecipeLiveData = new LiveData(); } } \ No newline at end of file diff --git a/Thermo.Active.Config/ServerConfigController.cs b/Thermo.Active.Config/ServerConfigController.cs index 7b5efcb9..bf1d76ce 100644 --- a/Thermo.Active.Config/ServerConfigController.cs +++ b/Thermo.Active.Config/ServerConfigController.cs @@ -57,28 +57,6 @@ namespace Thermo.Active.Config ExceptionManager.ManageError(ERROR_LEVEL.FATAL, message, true); } } - public static void ReadLastRecipe() - { - try - { - ReadLiveData(); - } - catch (XmlException ex) - { - ExceptionManager.ManageError(ERROR_LEVEL.FATAL, - "Error while reading file: " + ex.SourceUri + - "\n Error: " + ex.Message, - true - ); - } - catch (Exception ex) - { - var message = ex.Message; - if (ex.InnerException != null) - message += "\n" + ex.InnerException.Message; - ExceptionManager.ManageError(ERROR_LEVEL.FATAL, message, true); - } - } private static XDocument GetXmlHandlerWithValidator(string configSchemaFilePath, string configFilePath, bool isFullPath = false) { @@ -846,180 +824,6 @@ namespace Thermo.Active.Config .Select(x => x.Value) .ToList(); } - /// - /// Try to load live data from json persistence file - /// - public static bool ReadLiveData() - { - bool answ = false; - if (File.Exists(LIVE_RECIPE_PATH)) - { - // load all text data - var rawData = File.ReadAllText(LIVE_RECIPE_PATH); - try - { - // deserialize to object - RecipeLiveData = JsonConvert.DeserializeObject(rawData); - } - catch - { } - answ = true; - } - else - { - // reload from template... - var rawData = File.ReadAllText(RECIPE_TEMPLATE_PATH); - try - { - // deserialize to object - RecipeLiveData = JsonConvert.DeserializeObject(rawData); - } - catch - { } - // salva current - SaveRecipeCurrent(); - answ = true; - } - // rendo se fatto - return answ; - } - /// - /// Try to load selected recipe to live data (memory and json persistence file) - /// - public static bool LoadRecipe(string filePath) - { - bool answ = false; - - // check file extension - string fileName = Path.GetFileName(filePath); - if (!fileName.EndsWith(".json")) - { - fileName += ".json"; - filePath += ".json"; - } - - // check filePath... - if (!filePath.Contains(RECIPE_DIRECTORY) && filePath != RECIPE_TEMPLATE_PATH) - { - // aggiungo base path! - filePath = RECIPE_DIRECTORY + filePath; - } - if (File.Exists(filePath)) - { - answ = true; - - // load all text data - var rawData = File.ReadAllText(filePath); - try - { - // deserialize to object - RecipeLiveData = JsonConvert.DeserializeObject(rawData); - } - catch - { } - // update current live data! - SaveRecipeCurrent(); - } - // rendo se fatto - return answ; - } - /// - /// Try to load template recipe - /// - public static bool LoadTemplate() - { - bool answ = false; - // check filePath... - if (File.Exists(RECIPE_TEMPLATE_PATH)) - { - answ = true; - - // load all text data - var rawData = File.ReadAllText(RECIPE_TEMPLATE_PATH); - try - { - // deserialize to object - RecipeLiveData = JsonConvert.DeserializeObject(rawData); - // update NAME - RecipeLiveData.RecipeName = $"{DateTime.Now:yyyyMMss_HHmmss}.json"; - } - catch - { } - // update current live data! - SaveRecipeCurrent(); - } - // rendo se fatto - return answ; - } - /// - /// Try to write live data to json persistence file - /// - public static bool SaveRecipeCurrent() - { - bool answ = false; - try - { - answ = true; - // serialize - string rawData = JsonConvert.SerializeObject(RecipeLiveData); - // save live! - var dir = Path.GetDirectoryName(LIVE_RECIPE_PATH); - if (!Directory.Exists(dir)) - { - Directory.CreateDirectory(dir); - } - File.WriteAllText(LIVE_RECIPE_PATH, rawData); - } - catch - { } - // rendo se fatto - return answ; - } - /// - /// Try to save live recipe as NEW template - /// - public static bool SaveRecipeTemplate() - { - - RecipeLiveData.RecipeName = "template.json"; - return SaveRecipe(RECIPE_TEMPLATE_PATH); - } - /// - /// Try to save live recipe to selected filePath - /// - public static bool SaveRecipe(string filePath) - { - bool answ = false; - try - { - answ = true; - string fileName = Path.GetFileName(filePath); - if (!fileName.EndsWith(".json")) - { - fileName += ".json"; - filePath += ".json"; - } - // fix name! - RecipeLiveData.RecipeName = fileName; - // serialize - string rawData = JsonConvert.SerializeObject(RecipeLiveData); - // save live! - File.WriteAllText(LIVE_RECIPE_PATH, rawData); - // check filePath... - if (!filePath.Contains(RECIPE_DIRECTORY) && filePath != RECIPE_TEMPLATE_PATH) - { - // aggiungo base path! - filePath = RECIPE_DIRECTORY + filePath; - } - // save! - File.WriteAllText(filePath, rawData); - } - catch - { } - // rendo se fatto - return answ; - } - public static string CalculateHash(string filename) { using (var sha = SHA1.Create()) diff --git a/Thermo.Active.Config/Thermo.Active.Config.csproj b/Thermo.Active.Config/Thermo.Active.Config.csproj index bfee6bae..84b24ca5 100644 --- a/Thermo.Active.Config/Thermo.Active.Config.csproj +++ b/Thermo.Active.Config/Thermo.Active.Config.csproj @@ -55,7 +55,6 @@ Designer PreserveNewest - diff --git a/Thermo.Active.Config/LiveData.cs b/Thermo.Active.Model/DTOModels/ThRecipe/LiveData.cs similarity index 76% rename from Thermo.Active.Config/LiveData.cs rename to Thermo.Active.Model/DTOModels/ThRecipe/LiveData.cs index ea8d785f..d223d693 100644 --- a/Thermo.Active.Config/LiveData.cs +++ b/Thermo.Active.Model/DTOModels/ThRecipe/LiveData.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace Thermo.Active.Config +namespace Thermo.Active.Model.DTOModels.ThRecipe { /// /// Live data for Thermo Active @@ -19,6 +19,9 @@ namespace Thermo.Active.Config /// Dictionary of all channels and relative setpoints /// public Dictionary ChannelSetpoints; - + /// + /// Recipe Overview + /// + public Dictionary RecipeOverview; } } diff --git a/Thermo.Active.Model/Thermo.Active.Model.csproj b/Thermo.Active.Model/Thermo.Active.Model.csproj index 1d04ca14..169d38a2 100644 --- a/Thermo.Active.Model/Thermo.Active.Model.csproj +++ b/Thermo.Active.Model/Thermo.Active.Model.csproj @@ -108,6 +108,7 @@ + diff --git a/Thermo.Active.NC/NcAdapter.cs b/Thermo.Active.NC/NcAdapter.cs index e50428c4..ba2e6f68 100644 --- a/Thermo.Active.NC/NcAdapter.cs +++ b/Thermo.Active.NC/NcAdapter.cs @@ -23,10 +23,12 @@ namespace Thermo.Active.NC { public class NcAdapter : IDisposable { - + /// + /// NC object + /// public NcThermo numericalControl; /// - /// Lock per connessione PLC + /// Lock semaphore for PLC connection step /// private readonly static object connectLock = new object(); @@ -279,12 +281,12 @@ namespace Thermo.Active.NC public CmsError ManageConfRequest() { CmsError libraryError = NO_ERROR; - if (RecipeLiveData != null) + if (NcFileAdapter.RecipeLiveData != null) { // controllo SE HO richieste di configurazione if (ThermoReqConfWarmerStr) { - if (RecipeLiveData.ChannelSetpoints != null) + if (NcFileAdapter.RecipeLiveData.ChannelSetpoints != null) { // se si in questo caso scrivo configurazione... WriteRecipeWarmConfig(); @@ -294,7 +296,7 @@ namespace Thermo.Active.NC } if (ThermoReqConfRecipeStr) { - if (RecipeLiveData.RecipeParameters != null) + if (NcFileAdapter.RecipeLiveData.RecipeParameters != null) { // copy data to PLC libraryError = ReadFullRecipe(out Dictionary prevRecipe); @@ -302,7 +304,7 @@ namespace Thermo.Active.NC return libraryError; // save parameters to PLC!!! Dictionary updtRecipe = new Dictionary(); - foreach (var item in RecipeLiveData.RecipeParameters) + foreach (var item in NcFileAdapter.RecipeLiveData.RecipeParameters) { if (prevRecipe.ContainsKey(item.Key)) { diff --git a/Thermo.Active.NC/NcFileAdapter.cs b/Thermo.Active.NC/NcFileAdapter.cs index 513b9de8..3474cba1 100644 --- a/Thermo.Active.NC/NcFileAdapter.cs +++ b/Thermo.Active.NC/NcFileAdapter.cs @@ -11,11 +11,20 @@ using static CMS_CORE_Library.Models.DataStructures; using static Thermo.Active.Config.ServerConfig; using static Thermo.Active.Database.Controllers.QueueController; using static Thermo.Active.Model.Constants; +using Newtonsoft.Json; +using System.Xml; +using Thermo.Active.Model.DTOModels.ThRecipe; namespace Thermo.Active.NC { public class NcFileAdapter : NcAdapter { + + /// + /// Recipe Live data + /// + public static LiveData RecipeLiveData = new LiveData(); + /// /// Read file from local devices ad give back string content /// @@ -582,5 +591,209 @@ namespace Thermo.Active.NC return numericalControl.FILES_WCleanUploadFolder(); } + + #region recipe file persistence + + + public static void ReadLastRecipe() + { + try + { + ReadLiveData(); + } + catch (XmlException ex) + { + ExceptionManager.ManageError(ERROR_LEVEL.FATAL, + "Error while reading file: " + ex.SourceUri + + "\n Error: " + ex.Message, + true + ); + } + catch (Exception ex) + { + var message = ex.Message; + if (ex.InnerException != null) + message += "\n" + ex.InnerException.Message; + ExceptionManager.ManageError(ERROR_LEVEL.FATAL, message, true); + } + } + /// + /// Try to load live data from json persistence file + /// + public static bool ReadLiveData() + { + bool answ = false; + if (File.Exists(LIVE_RECIPE_PATH)) + { + // load all text data + var rawData = File.ReadAllText(LIVE_RECIPE_PATH); + try + { + // deserialize to object + RecipeLiveData = JsonConvert.DeserializeObject(rawData); + } + catch + { } + answ = true; + } + else + { + // reload from template... + var rawData = File.ReadAllText(RECIPE_TEMPLATE_PATH); + try + { + // deserialize to object + RecipeLiveData = JsonConvert.DeserializeObject(rawData); + } + catch + { } + // salva current + SaveRecipeCurrent(); + answ = true; + } + // rendo se fatto + return answ; + } + /// + /// Try to load selected recipe to live data (memory and json persistence file) + /// + public static bool LoadRecipe(string filePath) + { + bool answ = false; + + // check file extension + string fileName = Path.GetFileName(filePath); + if (!fileName.EndsWith(".json")) + { + fileName += ".json"; + filePath += ".json"; + } + + // check filePath... + if (!filePath.Contains(RECIPE_DIRECTORY) && filePath != RECIPE_TEMPLATE_PATH) + { + // aggiungo base path! + filePath = RECIPE_DIRECTORY + filePath; + } + if (File.Exists(filePath)) + { + answ = true; + + // load all text data + var rawData = File.ReadAllText(filePath); + try + { + // deserialize to object + RecipeLiveData = JsonConvert.DeserializeObject(rawData); + } + catch + { } + // update current live data! + SaveRecipeCurrent(); + } + // rendo se fatto + return answ; + } + /// + /// Try to load template recipe + /// + public static bool LoadTemplate() + { + bool answ = false; + // check filePath... + if (File.Exists(RECIPE_TEMPLATE_PATH)) + { + answ = true; + + // load all text data + var rawData = File.ReadAllText(RECIPE_TEMPLATE_PATH); + try + { + // deserialize to object + RecipeLiveData = JsonConvert.DeserializeObject(rawData); + // update NAME + RecipeLiveData.RecipeName = $"{DateTime.Now:yyyyMMss_HHmmss}.json"; + } + catch + { } + // update current live data! + SaveRecipeCurrent(); + } + // rendo se fatto + return answ; + } + /// + /// Try to write live data to json persistence file + /// + public static bool SaveRecipeCurrent() + { + bool answ = false; + try + { + answ = true; + // serialize + string rawData = JsonConvert.SerializeObject(RecipeLiveData); + // save live! + var dir = Path.GetDirectoryName(LIVE_RECIPE_PATH); + if (!Directory.Exists(dir)) + { + Directory.CreateDirectory(dir); + } + File.WriteAllText(LIVE_RECIPE_PATH, rawData); + } + catch + { } + // rendo se fatto + return answ; + } + /// + /// Try to save live recipe as NEW template + /// + public static bool SaveRecipeTemplate() + { + + RecipeLiveData.RecipeName = "template.json"; + return SaveRecipe(RECIPE_TEMPLATE_PATH); + } + /// + /// Try to save live recipe to selected filePath + /// + public static bool SaveRecipe(string filePath) + { + bool answ = false; + try + { + answ = true; + string fileName = Path.GetFileName(filePath); + if (!fileName.EndsWith(".json")) + { + fileName += ".json"; + filePath += ".json"; + } + // fix name! + RecipeLiveData.RecipeName = fileName; + // serialize + string rawData = JsonConvert.SerializeObject(RecipeLiveData); + // save live! + File.WriteAllText(LIVE_RECIPE_PATH, rawData); + // check filePath... + if (!filePath.Contains(RECIPE_DIRECTORY) && filePath != RECIPE_TEMPLATE_PATH) + { + // aggiungo base path! + filePath = RECIPE_DIRECTORY + filePath; + } + // save! + File.WriteAllText(filePath, rawData); + } + catch + { } + // rendo se fatto + return answ; + } + + + #endregion + + } } diff --git a/Thermo.Active.NC/Thermo.Active.NC.csproj b/Thermo.Active.NC/Thermo.Active.NC.csproj index 58647d15..cf63ac30 100644 --- a/Thermo.Active.NC/Thermo.Active.NC.csproj +++ b/Thermo.Active.NC/Thermo.Active.NC.csproj @@ -33,6 +33,9 @@ + + ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll + @@ -64,6 +67,7 @@ Always + diff --git a/Thermo.Active.NC/packages.config b/Thermo.Active.NC/packages.config new file mode 100644 index 00000000..7c080311 --- /dev/null +++ b/Thermo.Active.NC/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Thermo.Active/Controllers/WebApi/RecipeController.cs b/Thermo.Active/Controllers/WebApi/RecipeController.cs index 7d9a7126..c5081cea 100644 --- a/Thermo.Active/Controllers/WebApi/RecipeController.cs +++ b/Thermo.Active/Controllers/WebApi/RecipeController.cs @@ -65,7 +65,7 @@ namespace Thermo.Active.Controllers.WebApi { if (parametersList != null) { - if (RecipeLiveData != null) + if (NcFileAdapter.RecipeLiveData != null) { // Try connection CmsError libraryError = ncAdapter.Connect(); @@ -127,7 +127,7 @@ namespace Thermo.Active.Controllers.WebApi [Route("confirm"), HttpPut] public IHttpActionResult ConfirmEdit() { - if (RecipeLiveData != null) + if (NcFileAdapter.RecipeLiveData != null) { // Try connection CmsError libraryError = ncAdapter.Connect(); @@ -179,7 +179,7 @@ namespace Thermo.Active.Controllers.WebApi [Route("cancel"), HttpPut] public IHttpActionResult CancelEdit() { - if (RecipeLiveData != null) + if (NcFileAdapter.RecipeLiveData != null) { // Try connection CmsError libraryError = ncAdapter.Connect(); @@ -234,7 +234,7 @@ namespace Thermo.Active.Controllers.WebApi { // chiamo metodo di lettura... - bool fatto = ServerConfigController.LoadRecipe(newName); + bool fatto = NcFileAdapter.LoadRecipe(newName); if (!fatto) { ThermoActiveLogger.LogError($"LoadRecipe error"); @@ -260,7 +260,7 @@ namespace Thermo.Active.Controllers.WebApi public IHttpActionResult NewRecipe() { // chiamo metodo di lettura... - bool fatto = ServerConfigController.LoadTemplate(); + bool fatto = NcFileAdapter.LoadTemplate(); if (!fatto) { @@ -324,9 +324,9 @@ namespace Thermo.Active.Controllers.WebApi } // ora salvo ANCHE i dati live... - RecipeLiveData.RecipeParameters = currParams; + NcFileAdapter.RecipeLiveData.RecipeParameters = currParams; // e salvo su disco - ServerConfigController.SaveRecipe(newName); + NcFileAdapter.SaveRecipe(newName); // ritorno solo fatto! return Ok(); @@ -363,7 +363,7 @@ namespace Thermo.Active.Controllers.WebApi } // ora salvo nei dati live... - RecipeLiveData.RecipeParameters = currParams; + NcFileAdapter.RecipeLiveData.RecipeParameters = currParams; // carico i dati dei riscaldi... var currChSet = new Dictionary(); @@ -371,11 +371,11 @@ namespace Thermo.Active.Controllers.WebApi { currChSet.Add(item.Key, item.Value.SetpointHMI); } - RecipeLiveData.ChannelSetpoints = currChSet; + NcFileAdapter.RecipeLiveData.ChannelSetpoints = currChSet; // e salvo su disco - ServerConfigController.SaveRecipeTemplate(); + NcFileAdapter.SaveRecipeTemplate(); // ritorno solo fatto! return Ok(); @@ -391,9 +391,9 @@ namespace Thermo.Active.Controllers.WebApi try { // ora salvo ANCHE i dati live... - RecipeLiveData.RecipeParameters = currParams; + NcFileAdapter.RecipeLiveData.RecipeParameters = currParams; // e salvo su disco - ServerConfigController.SaveRecipeCurrent(); + NcFileAdapter.SaveRecipeCurrent(); } catch (Exception exc) { @@ -424,7 +424,7 @@ namespace Thermo.Active.Controllers.WebApi // save parameters to PLC!!! Dictionary updtRecipe = new Dictionary(); - foreach (var item in RecipeLiveData.RecipeParameters) + foreach (var item in NcFileAdapter.RecipeLiveData.RecipeParameters) { if (prevRecipe.ContainsKey(item.Key)) { @@ -452,7 +452,7 @@ namespace Thermo.Active.Controllers.WebApi // process ch load setup... Dictionary newRisk = new Dictionary(); - foreach (var item in RecipeLiveData.ChannelSetpoints) + foreach (var item in NcFileAdapter.RecipeLiveData.ChannelSetpoints) { newRisk.Add(item.Key, item.Value); } diff --git a/Thermo.Active/Controllers/WebApi/WarmersController.cs b/Thermo.Active/Controllers/WebApi/WarmersController.cs index 309faebf..f864cf38 100644 --- a/Thermo.Active/Controllers/WebApi/WarmersController.cs +++ b/Thermo.Active/Controllers/WebApi/WarmersController.cs @@ -233,9 +233,9 @@ namespace Thermo.Active.Controllers.WebApi try { // ora salvo ANCHE i dati live... - RecipeLiveData.ChannelSetpoints = chSetpoints; + NcFileAdapter.RecipeLiveData.ChannelSetpoints = chSetpoints; // e salvo su disco - ServerConfigController.SaveRecipeCurrent(); + NcFileAdapter.SaveRecipeCurrent(); } catch (Exception exc) { diff --git a/Thermo.Active/Properties/AssemblyInfo.cs b/Thermo.Active/Properties/AssemblyInfo.cs index 7002e76e..5e80ead3 100644 --- a/Thermo.Active/Properties/AssemblyInfo.cs +++ b/Thermo.Active/Properties/AssemblyInfo.cs @@ -30,4 +30,4 @@ using System.Runtime.InteropServices; // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("0.9.9")] +[assembly: AssemblyVersion("0.9.10")] diff --git a/Thermo.Active/program.cs b/Thermo.Active/program.cs index ceb0a981..ecb0b188 100644 --- a/Thermo.Active/program.cs +++ b/Thermo.Active/program.cs @@ -85,7 +85,7 @@ namespace Thermo.Active opt.Urls.Add("http://" + ServerStartupConfig.ServerAddress.ToString() + ":" + ServerStartupConfig.ServerPort.ToString()); // read and save last CURRENT RECIPE data... - ServerConfigController.ReadLastRecipe(); + NcFileAdapter.ReadLastRecipe(); RecipeController.WriteCurrentRecipeToPlc(); //starts threads From 4ea2cebfeb2cf29bf96e1f85aa8e725650751b36 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 24 Jun 2020 19:14:59 +0200 Subject: [PATCH 2/4] Draft for new overview calculation (to be checked) --- Thermo.Active.NC/NcAdapter.cs | 39 ++++++++++++++++--- Thermo.Active.NC/NcFileAdapter.cs | 16 ++++++++ .../Controllers/WebApi/RecipeController.cs | 14 ++++++- 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/Thermo.Active.NC/NcAdapter.cs b/Thermo.Active.NC/NcAdapter.cs index ba2e6f68..8ba155a0 100644 --- a/Thermo.Active.NC/NcAdapter.cs +++ b/Thermo.Active.NC/NcAdapter.cs @@ -1891,6 +1891,7 @@ namespace Thermo.Active.NC public CmsError GetRecipeOverview(out Dictionary currOverview) { CmsError libraryError = NO_ERROR; + // overview di base: ultima salvata... currOverview = new Dictionary(); // leggo la ricetta! @@ -1915,15 +1916,36 @@ namespace Thermo.Active.NC RecipeCatStatus currStatus = RecipeCatStatus.Unchanged; - // percorro conf ricetta... + // da conf ricetta --> verifico dati LIVE ricetta e se mancassero imposto unchanged.. + currOverview = NcFileAdapter.RecipeLiveData.RecipeOverview; + bool changed = false; foreach (var item in recipeConfig) { + if (!currOverview.ContainsKey(item.Category)) + { + currOverview.Add(item.Category, RecipeCatStatus.Unchanged); + changed = true; + } + } + // se cambiato --> salvo! + if (changed) + { + NcFileAdapter.RecipeLiveData.RecipeOverview = currOverview; + } + + // ORA percorro conf ricetta x cercare eventuali ERRORI...... + foreach (var item in recipeConfig) + { +#if false currStatus = RecipeCatStatus.Unchanged; // cerco SE ci sia già uno status... if (currOverview.ContainsKey(item.Category)) { currStatus = currOverview[item.Category]; - } + } +#endif + + currStatus = currOverview[item.Category]; // se lo stato è errore --> esco... if (currStatus == RecipeCatStatus.HasError) @@ -1936,8 +1958,12 @@ namespace Thermo.Active.NC // se in errore --> registro... if (currRecipe[item.Label].Status.HasError) { - currStatus = RecipeCatStatus.HasError; +#if false + currStatus = RecipeCatStatus.HasError; +#endif + currOverview[item.Category] = RecipeCatStatus.HasError; } +#if false // FARE verificare il significato di questo changed (se è da file o da HMI/PLC) else if (currRecipe[item.Label].SetpointHMI != currRecipe[item.Label].SetpointPLC) { @@ -1946,9 +1972,11 @@ namespace Thermo.Active.NC else { currStatus = RecipeCatStatus.Unchanged; - } + } +#endif } +#if false // ora verifico overview finale: se non c'è aggiungo if (!currOverview.ContainsKey(item.Category)) { @@ -1958,7 +1986,8 @@ namespace Thermo.Active.NC { // se il valore è maggiore --> aggiorno currOverview[item.Category] = (int)currStatus > (int)currOverview[item.Category] ? currStatus : currOverview[item.Category]; - } + } +#endif } // restituisco cod errore se trovato diff --git a/Thermo.Active.NC/NcFileAdapter.cs b/Thermo.Active.NC/NcFileAdapter.cs index 3474cba1..62de6cc8 100644 --- a/Thermo.Active.NC/NcFileAdapter.cs +++ b/Thermo.Active.NC/NcFileAdapter.cs @@ -594,6 +594,22 @@ namespace Thermo.Active.NC #region recipe file persistence + /// + /// Upsert recipe overview status + /// + /// + /// + public static void upsRecipeOverview(string section, RecipeCatStatus status) + { + if (RecipeLiveData.RecipeOverview.ContainsKey(section)) + { + RecipeLiveData.RecipeOverview[section] = status; + } + else + { + RecipeLiveData.RecipeOverview.Add(section, status); + } + } public static void ReadLastRecipe() { diff --git a/Thermo.Active/Controllers/WebApi/RecipeController.cs b/Thermo.Active/Controllers/WebApi/RecipeController.cs index c5081cea..226c8809 100644 --- a/Thermo.Active/Controllers/WebApi/RecipeController.cs +++ b/Thermo.Active/Controllers/WebApi/RecipeController.cs @@ -61,7 +61,7 @@ namespace Thermo.Active.Controllers.WebApi } [Route("update"), HttpPut] - public IHttpActionResult WriteParameters(Dictionary parametersList) + public IHttpActionResult WriteParameters(Dictionary parametersList, string section) { if (parametersList != null) { @@ -104,6 +104,18 @@ namespace Thermo.Active.Controllers.WebApi // scrivo sul PLC ncAdapter.WriteRecipeParams(updtRecipe); + // SE HO una section != null/empty --> salvo come modificata... + if (!string.IsNullOrEmpty(section)) + { + try + { + NcFileAdapter.upsRecipeOverview(section, RecipeCatStatus.ChangedOk); + } + catch (Exception exc) + { + ThermoActiveLogger.LogError($"Error on set recipe overview | section: {section}{Environment.NewLine}{exc}"); + } + } // ritorno solo fatto! return Ok(); } From e7e2601a8d1b2b94efb3d685f6a191778e580df2 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 25 Jun 2020 09:58:10 +0200 Subject: [PATCH 3/4] updated ModBLock controllers for new datamodel --- .../Config/moduleBlockConfig.xml | 70 ++++--------------- .../Config/moduleBlockConfigValidator.xsd | 9 +-- .../ServerConfigController.cs | 7 +- .../ConfigModels/ModBlockConfigModel.cs | 2 +- .../DTOModels/ThModules/DTOModulesBlock.cs | 4 +- .../DTOModels/ThRecipe/DTORecipeOverview.cs | 16 +++++ .../DTOModels/ThRecipe/LiveData.cs | 4 +- Thermo.Active.NC/NcAdapter.cs | 70 +++++++------------ Thermo.Active.NC/NcFileAdapter.cs | 25 +++++-- .../Controllers/WebApi/RecipeController.cs | 39 ++++++----- 10 files changed, 106 insertions(+), 140 deletions(-) diff --git a/Thermo.Active.Config/Config/moduleBlockConfig.xml b/Thermo.Active.Config/Config/moduleBlockConfig.xml index ef3095f8..c76f9bca 100644 --- a/Thermo.Active.Config/Config/moduleBlockConfig.xml +++ b/Thermo.Active.Config/Config/moduleBlockConfig.xml @@ -2,10 +2,7 @@ 1 - - DiscesaCZ ENG - DiscesaCZ ITA - + MOVEMENT
HEATING
-1 @@ -15,10 +12,7 @@
2 - - MembDiscesaZ ENG - MembDiscesaZ ITA - + MOVEMENT
HEATING
-1 @@ -28,10 +22,7 @@
3 - - MembZ ENG - MembZ ITA - + MOVEMENT
HEATING
-1 @@ -41,10 +32,7 @@
4 - - Mod_MembSalitaZ ENG - Mod_MembSalitaZ ITA - + MOVEMENT
HEATING
-1 @@ -54,10 +42,7 @@
6 - - Mod_RiscaldoInf ENG - Mod_RiscaldoInf ITA - + HEATING
HEATING
-1 @@ -67,10 +52,7 @@
7 - - Mod_RiscaldoSup ENG - Mod_RiscaldoSup ITA - + HEATING
HEATING
0 @@ -80,10 +62,7 @@
8 - - Mod_PirometroRisc ENG - Mod_PirometroRisc ITA - + HEATING
HEATING
80 @@ -93,10 +72,7 @@
13 - - Mod_Imbutitura ENG - Mod_Imbutitura ITA - + DRAWING
FORMING
99 @@ -106,10 +82,7 @@
16 - - Mod_Raffreddamento ENG - Mod_Raffreddamento ITA - + COOLING
FORMING
-1 @@ -119,10 +92,7 @@
17 - - Mod_PirometroRaffr ENG - Mod_PirometroRaffr ITA - + COOLING
FORMING
139 @@ -132,10 +102,7 @@
19 - - Mod_Vuoto ENG - Mod_Vuoto ITA - + VACUUM
FORMING
-1 @@ -145,10 +112,7 @@
21 - - Mod_VuotoDiretto ENG - Mod_VuotoDiretto ITA - + VACUUM
FORMING
-1 @@ -158,10 +122,7 @@
36 - - Mod_EstrazioneZ ENG - Mod_EstrazioneZ ITA - + EXTRACTION
EXTRACTION
-1 @@ -171,10 +132,7 @@
42 - - Mod_SalitaCZ ENG - Mod_SalitaCZ ITA - + MOVEMENT
EXTRACTION
-1 diff --git a/Thermo.Active.Config/Config/moduleBlockConfigValidator.xsd b/Thermo.Active.Config/Config/moduleBlockConfigValidator.xsd index 220ba2fb..71fcea52 100644 --- a/Thermo.Active.Config/Config/moduleBlockConfigValidator.xsd +++ b/Thermo.Active.Config/Config/moduleBlockConfigValidator.xsd @@ -8,14 +8,7 @@ - - - - - - - - + diff --git a/Thermo.Active.Config/ServerConfigController.cs b/Thermo.Active.Config/ServerConfigController.cs index bf1d76ce..3d7afa51 100644 --- a/Thermo.Active.Config/ServerConfigController.cs +++ b/Thermo.Active.Config/ServerConfigController.cs @@ -611,9 +611,10 @@ namespace Thermo.Active.Config .Select(x => new ModBlockConfigModel() { Id = Convert.ToInt16(x.Element("id").Value), - LocalizedLabels = x.Element("localizedLabels").Elements().ToDictionary( - y => y.Attribute("langKey").Value, y => y.Value - ), + Label = x.Element("label").Value, + //LocalizedLabels = x.Element("localizedLabels").Elements().ToDictionary( + // y => y.Attribute("langKey").Value, y => y.Value + // ), Type = GetTActMB_Type(x.Element("type").Value), Section = GetTActMB_Section(x.Element("section").Value), IdParam = Convert.ToInt16(x.Element("idParam").Value), diff --git a/Thermo.Active.Model/ConfigModels/ModBlockConfigModel.cs b/Thermo.Active.Model/ConfigModels/ModBlockConfigModel.cs index da75b24b..7f47779f 100644 --- a/Thermo.Active.Model/ConfigModels/ModBlockConfigModel.cs +++ b/Thermo.Active.Model/ConfigModels/ModBlockConfigModel.cs @@ -6,7 +6,7 @@ namespace Thermo.Active.Model.ConfigModels public class ModBlockConfigModel { public int Id; - public Dictionary LocalizedLabels { get; set; } + public string Label { get; set; } public TACT_MBLOCK_TYPE Type { get; set; } public TACT_MBLOCK_SECTION Section { get; set; } public int IdParam { get; set; } diff --git a/Thermo.Active.Model/DTOModels/ThModules/DTOModulesBlock.cs b/Thermo.Active.Model/DTOModels/ThModules/DTOModulesBlock.cs index c03051a4..e63cd958 100644 --- a/Thermo.Active.Model/DTOModels/ThModules/DTOModulesBlock.cs +++ b/Thermo.Active.Model/DTOModels/ThModules/DTOModulesBlock.cs @@ -7,7 +7,7 @@ namespace Thermo.Active.Model.DTOModels.ThModules public class DTOModulesBlock { public int Id { get; set; } = 0; - public string LocalizedLabel { get; set; } = ""; + public string Label { get; set; } = ""; public TACT_MBLOCK_TYPE Type { get; set; } = TACT_MBLOCK_TYPE.ND; public TACT_MBLOCK_SECTION Section { get; set; } = TACT_MBLOCK_SECTION.ND; public int IdParam { get; set; } = 0; @@ -30,7 +30,7 @@ namespace Thermo.Active.Model.DTOModels.ThModules if (Id != item.Id) return false; - if (LocalizedLabel != item.LocalizedLabel) + if (Label != item.Label) return false; if (Type != item.Type) return false; diff --git a/Thermo.Active.Model/DTOModels/ThRecipe/DTORecipeOverview.cs b/Thermo.Active.Model/DTOModels/ThRecipe/DTORecipeOverview.cs index 1e21678e..43872445 100644 --- a/Thermo.Active.Model/DTOModels/ThRecipe/DTORecipeOverview.cs +++ b/Thermo.Active.Model/DTOModels/ThRecipe/DTORecipeOverview.cs @@ -11,4 +11,20 @@ namespace Thermo.Active.Model.DTOModels.ThRecipe ChangedOk, HasError } + + [JsonConverter(typeof(StringEnumConverter))] + public enum RecipeSection + { + General = 1, + Positions, + Cycle, + Heats, + Pyrometer, + Drawing, + UpperPlate, + Cooling, + Vacuum, + Extraction, + Options + } } diff --git a/Thermo.Active.Model/DTOModels/ThRecipe/LiveData.cs b/Thermo.Active.Model/DTOModels/ThRecipe/LiveData.cs index d223d693..3cef6db1 100644 --- a/Thermo.Active.Model/DTOModels/ThRecipe/LiveData.cs +++ b/Thermo.Active.Model/DTOModels/ThRecipe/LiveData.cs @@ -22,6 +22,8 @@ namespace Thermo.Active.Model.DTOModels.ThRecipe /// /// Recipe Overview /// - public Dictionary RecipeOverview; + public Dictionary RecipeOverview; } + + } diff --git a/Thermo.Active.NC/NcAdapter.cs b/Thermo.Active.NC/NcAdapter.cs index 8ba155a0..4f7ae783 100644 --- a/Thermo.Active.NC/NcAdapter.cs +++ b/Thermo.Active.NC/NcAdapter.cs @@ -1888,13 +1888,13 @@ namespace Thermo.Active.NC /// /// Oggetto overview ricetta corrente HMI /// - public CmsError GetRecipeOverview(out Dictionary currOverview) + public CmsError GetRecipeOverview(out Dictionary currOverview) { CmsError libraryError = NO_ERROR; // overview di base: ultima salvata... - currOverview = new Dictionary(); + currOverview = new Dictionary(); - // leggo la ricetta! + // leggo la ricetta dal PLC! var currRecipe = new Dictionary(); libraryError = ReadFullRecipe(out currRecipe); if (libraryError.IsError()) @@ -1917,17 +1917,21 @@ namespace Thermo.Active.NC RecipeCatStatus currStatus = RecipeCatStatus.Unchanged; // da conf ricetta --> verifico dati LIVE ricetta e se mancassero imposto unchanged.. - currOverview = NcFileAdapter.RecipeLiveData.RecipeOverview; + if (NcFileAdapter.RecipeLiveData.RecipeOverview != null) + { + currOverview = NcFileAdapter.RecipeLiveData.RecipeOverview; + } + bool changed = false; foreach (var item in recipeConfig) { - if (!currOverview.ContainsKey(item.Category)) + if (!currOverview.ContainsKey(getRecipeSection(item.Category))) { - currOverview.Add(item.Category, RecipeCatStatus.Unchanged); + currOverview.Add(getRecipeSection(item.Category), RecipeCatStatus.Unchanged); changed = true; } } - // se cambiato --> salvo! + // se cambiato --> salvo in live data... if (changed) { NcFileAdapter.RecipeLiveData.RecipeOverview = currOverview; @@ -1936,16 +1940,7 @@ namespace Thermo.Active.NC // ORA percorro conf ricetta x cercare eventuali ERRORI...... foreach (var item in recipeConfig) { -#if false - currStatus = RecipeCatStatus.Unchanged; - // cerco SE ci sia già uno status... - if (currOverview.ContainsKey(item.Category)) - { - currStatus = currOverview[item.Category]; - } -#endif - - currStatus = currOverview[item.Category]; + currStatus = currOverview[getRecipeSection(item.Category)]; // se lo stato è errore --> esco... if (currStatus == RecipeCatStatus.HasError) @@ -1958,42 +1953,25 @@ namespace Thermo.Active.NC // se in errore --> registro... if (currRecipe[item.Label].Status.HasError) { -#if false - currStatus = RecipeCatStatus.HasError; -#endif - currOverview[item.Category] = RecipeCatStatus.HasError; + currOverview[getRecipeSection(item.Category)] = RecipeCatStatus.HasError; } -#if false - // FARE verificare il significato di questo changed (se è da file o da HMI/PLC) - else if (currRecipe[item.Label].SetpointHMI != currRecipe[item.Label].SetpointPLC) - { - currStatus = RecipeCatStatus.ChangedOk; - } - else - { - currStatus = RecipeCatStatus.Unchanged; - } -#endif } - -#if false - // ora verifico overview finale: se non c'è aggiungo - if (!currOverview.ContainsKey(item.Category)) - { - currOverview.Add(item.Category, currStatus); - } - else - { - // se il valore è maggiore --> aggiorno - currOverview[item.Category] = (int)currStatus > (int)currOverview[item.Category] ? currStatus : currOverview[item.Category]; - } -#endif } // restituisco cod errore se trovato return libraryError; } + /// + /// Conversione stringa --> enum + /// + /// + /// + protected RecipeSection getRecipeSection(string strVal) + { + RecipeSection answ = (RecipeSection)Enum.Parse(typeof(RecipeSection), strVal, true); + return answ; + } /// /// Legge tutti i parametri della ricetta /// @@ -2034,7 +2012,7 @@ namespace Thermo.Active.NC currVal = new DTOModulesBlock() { Id = item.Id, - LocalizedLabel = item.LocalizedLabels["it"], // FIXME TODO check come gestire traduzione!!! + Label = item.Label, Type = item.Type, Section = item.Section, IdParam = item.IdParam, diff --git a/Thermo.Active.NC/NcFileAdapter.cs b/Thermo.Active.NC/NcFileAdapter.cs index 62de6cc8..020a5a0e 100644 --- a/Thermo.Active.NC/NcFileAdapter.cs +++ b/Thermo.Active.NC/NcFileAdapter.cs @@ -599,7 +599,7 @@ namespace Thermo.Active.NC /// /// /// - public static void upsRecipeOverview(string section, RecipeCatStatus status) + public static void upsRecipeOverview(RecipeSection section, RecipeCatStatus status) { if (RecipeLiveData.RecipeOverview.ContainsKey(section)) { @@ -660,6 +660,11 @@ namespace Thermo.Active.NC { // deserialize to object RecipeLiveData = JsonConvert.DeserializeObject(rawData); + // from template --> reset (if present) overview data... + foreach (var item in RecipeLiveData.RecipeOverview) + { + RecipeLiveData.RecipeOverview[item.Key] = RecipeCatStatus.Unchanged; + } } catch { } @@ -727,6 +732,11 @@ namespace Thermo.Active.NC { // deserialize to object RecipeLiveData = JsonConvert.DeserializeObject(rawData); + // from template --> reset (if present) overview data... + foreach (var item in RecipeLiveData.RecipeOverview) + { + RecipeLiveData.RecipeOverview[item.Key] = RecipeCatStatus.Unchanged; + } // update NAME RecipeLiveData.RecipeName = $"{DateTime.Now:yyyyMMss_HHmmss}.json"; } @@ -768,13 +778,16 @@ namespace Thermo.Active.NC public static bool SaveRecipeTemplate() { - RecipeLiveData.RecipeName = "template.json"; - return SaveRecipe(RECIPE_TEMPLATE_PATH); + // duplicate data... + LiveData data2save = RecipeLiveData; + // template --> reset overview data... + data2save.RecipeOverview = new Dictionary(); + return SaveRecipe(RECIPE_TEMPLATE_PATH, data2save); } /// /// Try to save live recipe to selected filePath /// - public static bool SaveRecipe(string filePath) + public static bool SaveRecipe(string filePath, LiveData currRecipe) { bool answ = false; try @@ -787,9 +800,9 @@ namespace Thermo.Active.NC filePath += ".json"; } // fix name! - RecipeLiveData.RecipeName = fileName; + currRecipe.RecipeName = fileName; // serialize - string rawData = JsonConvert.SerializeObject(RecipeLiveData); + string rawData = JsonConvert.SerializeObject(currRecipe); // save live! File.WriteAllText(LIVE_RECIPE_PATH, rawData); // check filePath... diff --git a/Thermo.Active/Controllers/WebApi/RecipeController.cs b/Thermo.Active/Controllers/WebApi/RecipeController.cs index 226c8809..2e65778f 100644 --- a/Thermo.Active/Controllers/WebApi/RecipeController.cs +++ b/Thermo.Active/Controllers/WebApi/RecipeController.cs @@ -30,7 +30,7 @@ namespace Thermo.Active.Controllers.WebApi ThermoActiveLogger.LogError($"ncAdapter Not connected! | GetOverview | {libraryError.exception}"); } - libraryError = ncAdapter.GetRecipeOverview(out Dictionary currOverview); + libraryError = ncAdapter.GetRecipeOverview(out Dictionary currOverview); if (libraryError.IsError()) { ThermoActiveLogger.LogError($"GetRecipeOverview error | {libraryError.exception}"); @@ -61,7 +61,7 @@ namespace Thermo.Active.Controllers.WebApi } [Route("update"), HttpPut] - public IHttpActionResult WriteParameters(Dictionary parametersList, string section) + public IHttpActionResult WriteParameters(Dictionary parametersList) { if (parametersList != null) { @@ -104,18 +104,6 @@ namespace Thermo.Active.Controllers.WebApi // scrivo sul PLC ncAdapter.WriteRecipeParams(updtRecipe); - // SE HO una section != null/empty --> salvo come modificata... - if (!string.IsNullOrEmpty(section)) - { - try - { - NcFileAdapter.upsRecipeOverview(section, RecipeCatStatus.ChangedOk); - } - catch (Exception exc) - { - ThermoActiveLogger.LogError($"Error on set recipe overview | section: {section}{Environment.NewLine}{exc}"); - } - } // ritorno solo fatto! return Ok(); } @@ -135,9 +123,10 @@ namespace Thermo.Active.Controllers.WebApi /// /// Confirm recipe modification (parameters: HMI --> PLC) /// + /// section confirmed (string as in overview) /// [Route("confirm"), HttpPut] - public IHttpActionResult ConfirmEdit() + public IHttpActionResult ConfirmEdit(RecipeSection section) { if (NcFileAdapter.RecipeLiveData != null) { @@ -157,6 +146,19 @@ namespace Thermo.Active.Controllers.WebApi return BadRequest(libraryError.localizationKey); } + // SE HO una section != null/empty --> salvo come modificata... + if (section != null) + { + try + { + NcFileAdapter.upsRecipeOverview(section, RecipeCatStatus.ChangedOk); + } + catch (Exception exc) + { + ThermoActiveLogger.LogError($"Error on set recipe overview | section: {section}{Environment.NewLine}{exc}"); + } + } + // recupero i dati LIVE dei parametri HMI della ricetta... libraryError = ncAdapter.ReadFullRecipe(out Dictionary currRecipe); if (libraryError.IsError()) @@ -338,7 +340,7 @@ namespace Thermo.Active.Controllers.WebApi // ora salvo ANCHE i dati live... NcFileAdapter.RecipeLiveData.RecipeParameters = currParams; // e salvo su disco - NcFileAdapter.SaveRecipe(newName); + NcFileAdapter.SaveRecipe(newName, NcFileAdapter.RecipeLiveData); // ritorno solo fatto! return Ok(); @@ -412,7 +414,10 @@ namespace Thermo.Active.Controllers.WebApi ThermoActiveLogger.LogError($"Recipe | SaveCurrentRecipeParams exception | {exc}"); } } - + /// + /// write current recipe to PLC + /// + /// public static CmsError WriteCurrentRecipeToPlc() { CmsError checkError = NO_ERROR; From bc75c29f80626513c759d08972a47921ce5b8810 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 25 Jun 2020 10:09:31 +0200 Subject: [PATCH 4/4] Fix overview for recipe template/init --- .../DTOModels/ThModules/DTOModuleConfigModel.cs | 2 +- Thermo.Active.NC/NcAdapter.cs | 2 +- Thermo.Active.NC/NcFileAdapter.cs | 8 +++++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Thermo.Active.Model/DTOModels/ThModules/DTOModuleConfigModel.cs b/Thermo.Active.Model/DTOModels/ThModules/DTOModuleConfigModel.cs index abc0278c..7664def6 100644 --- a/Thermo.Active.Model/DTOModels/ThModules/DTOModuleConfigModel.cs +++ b/Thermo.Active.Model/DTOModels/ThModules/DTOModuleConfigModel.cs @@ -6,7 +6,7 @@ public string Label; public BlockType Type; public BlockSection Section; - public int IdMainParam = -1; // -1 = non visibile + public int IdMainParam = -1; // -1 = non visibile la parte a DX public bool DelayVisible; public int VisualPriority; } diff --git a/Thermo.Active.NC/NcAdapter.cs b/Thermo.Active.NC/NcAdapter.cs index 4f7ae783..2b812a25 100644 --- a/Thermo.Active.NC/NcAdapter.cs +++ b/Thermo.Active.NC/NcAdapter.cs @@ -1916,7 +1916,7 @@ namespace Thermo.Active.NC RecipeCatStatus currStatus = RecipeCatStatus.Unchanged; - // da conf ricetta --> verifico dati LIVE ricetta e se mancassero imposto unchanged.. + // da conf ricetta --> se ci sono li leggo da li... if (NcFileAdapter.RecipeLiveData.RecipeOverview != null) { currOverview = NcFileAdapter.RecipeLiveData.RecipeOverview; diff --git a/Thermo.Active.NC/NcFileAdapter.cs b/Thermo.Active.NC/NcFileAdapter.cs index 020a5a0e..d7c59272 100644 --- a/Thermo.Active.NC/NcFileAdapter.cs +++ b/Thermo.Active.NC/NcFileAdapter.cs @@ -733,9 +733,12 @@ namespace Thermo.Active.NC // deserialize to object RecipeLiveData = JsonConvert.DeserializeObject(rawData); // from template --> reset (if present) overview data... - foreach (var item in RecipeLiveData.RecipeOverview) + if (RecipeLiveData.RecipeOverview != null) { - RecipeLiveData.RecipeOverview[item.Key] = RecipeCatStatus.Unchanged; + foreach (var item in RecipeLiveData.RecipeOverview) + { + RecipeLiveData.RecipeOverview[item.Key] = RecipeCatStatus.Unchanged; + } } // update NAME RecipeLiveData.RecipeName = $"{DateTime.Now:yyyyMMss_HHmmss}.json"; @@ -777,7 +780,6 @@ namespace Thermo.Active.NC /// public static bool SaveRecipeTemplate() { - // duplicate data... LiveData data2save = RecipeLiveData; // template --> reset overview data...