diff --git a/Thermo.Active.Config/LiveData.cs b/Thermo.Active.Config/LiveData.cs
new file mode 100644
index 00000000..e729d7d3
--- /dev/null
+++ b/Thermo.Active.Config/LiveData.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Thermo.Active.Config
+{
+ ///
+ /// Live data for Thermo Active
+ ///
+ public class LiveData
+ {
+ ///
+ /// Current loaded recipe
+ ///
+ public string RecipeName = "current.json";
+ ///
+ /// Dictionary of all parameters and values
+ ///
+ public Dictionary RecipeParameters;
+ ///
+ /// Dictionary of all channels and relative setpoints
+ ///
+ public Dictionary ChannelSetpoints;
+
+ }
+}
diff --git a/Thermo.Active.Config/ServerConfig.cs b/Thermo.Active.Config/ServerConfig.cs
index e18c1028..3cc50e77 100644
--- a/Thermo.Active.Config/ServerConfig.cs
+++ b/Thermo.Active.Config/ServerConfig.cs
@@ -32,10 +32,8 @@ namespace Thermo.Active.Config
public static List NcSoftKeysConfig;
public static List InitialAlarmsConfig;
public static List HeadsConfig;
- public static List RecipeConfig;
- public static List ModBlockConfig;
- public static List RiskResistConfig;
- public static List RiskChannelConfig;
+
+
public static CmsConnectConfigModel CmsConnectConfig;
public static AreasConfigModel ProductionConfig;
@@ -55,5 +53,15 @@ namespace Thermo.Active.Config
public static List MacrosConfig;
public static string CMSMainProgramContent;
+
+
+ // Thermo
+ public static List RecipeConfig;
+ public static List ModBlockConfig;
+ public static List RiskResistConfig;
+ public static List RiskChannelConfig;
+
+ public static LiveData RecipeLiveData;
}
+
}
\ No newline at end of file
diff --git a/Thermo.Active.Config/ServerConfigController.cs b/Thermo.Active.Config/ServerConfigController.cs
index 86c811d4..b9c4c7be 100644
--- a/Thermo.Active.Config/ServerConfigController.cs
+++ b/Thermo.Active.Config/ServerConfigController.cs
@@ -15,6 +15,7 @@ using System.Xml.Serialization;
using static Thermo.Active.Config.ServerConfig;
using static Thermo.Active.Model.Constants;
using static Thermo.Active.Utils.SupportFunctions;
+using Newtonsoft.Json;
namespace Thermo.Active.Config
{
@@ -39,7 +40,7 @@ namespace Thermo.Active.Config
// ReadCMSConnectConfig();
ReadMacros();
ReadScadaFile();
- //ReadMainProgram();
+ ReadLiveData();
}
catch (XmlException ex)
{
@@ -687,7 +688,7 @@ namespace Thermo.Active.Config
{
// cerco il TIPO...
var riferimento = Riferimenti.Find(x => x.Id == resistenza.Tipo);
- if(riferimento!=null)
+ if (riferimento != null)
{
RiskChannelConfig.Add(new RiskChannelModel()
{
@@ -790,15 +791,109 @@ namespace Thermo.Active.Config
.Select(x => x.Value)
.ToList();
}
+ ///
+ /// Try to load live data from json persistence file
+ ///
+ public static void ReadLiveData()
+ {
+ 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
+ { }
+ }
+ else
+ {
+ // setup new object
+ RecipeLiveData = new LiveData()
+ {
+ RecipeName = "current.json",
+ ChannelSetpoints = new Dictionary(),
+ RecipeParameters = new Dictionary()
+ };
+ }
+ }
+ ///
+ /// Try to write live data to json persistence file
+ ///
+ public static void WriteLiveData()
+ {
+ try
+ {
+ // serialize
+ string rawData = JsonConvert.SerializeObject(RecipeLiveData);
+ // save live!
+ File.WriteAllText(LIVE_RECIPE_PATH, rawData);
+ }
+ catch
+ { }
+ }
+ ///
+ /// Try to load selected recipe to live data (memory and json persistence file)
+ ///
+ public static void LoadRecipe(string filePath)
+ {
+ if (File.Exists(filePath))
+ {
+ // check filePath...
+ if (!filePath.Contains(RECIPE_DIRECTORY))
+ {
+ // aggiungo base path!
+ filePath = RECIPE_DIRECTORY + filePath;
+ }
+ // load all text data
+ var rawData = File.ReadAllText(filePath);
+ try
+ {
+ // deserialize to object
+ RecipeLiveData = JsonConvert.DeserializeObject(rawData);
+ }
+ catch
+ { }
+ // update current live data!
+ WriteLiveData();
+ }
+ }
+ ///
+ /// Try to save live recipe to selected filePath
+ ///
+ public static void SaveRecipe(string filePath)
+ {
+ try
+ {
+ // serialize
+ string rawData = JsonConvert.SerializeObject(RecipeLiveData);
+ // save live!
+ File.WriteAllText(LIVE_RECIPE_PATH, rawData);
+ // check filePath...
+ if (!filePath.Contains(RECIPE_DIRECTORY))
+ {
+ // aggiungo base path!
+ filePath = RECIPE_DIRECTORY + filePath;
+ }
+ // save!
+ File.WriteAllText(filePath, rawData);
+ }
+ catch
+ { }
+ }
+#if false
public static void ReadMainProgram()
{
if (File.Exists(MAIN_PROGRAM_CONFIG_PATH))
{
CMSMainProgramContent = File.ReadAllText(MAIN_PROGRAM_CONFIG_PATH);
}
- }
+ }
+#endif
public static string CalculateHash(string filename)
{
diff --git a/Thermo.Active.Config/Thermo.Active.Config.csproj b/Thermo.Active.Config/Thermo.Active.Config.csproj
index 27d70235..59b4e97b 100644
--- a/Thermo.Active.Config/Thermo.Active.Config.csproj
+++ b/Thermo.Active.Config/Thermo.Active.Config.csproj
@@ -32,6 +32,9 @@
4
+
+ ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll
+
@@ -52,6 +55,7 @@
Designer
PreserveNewest
+
@@ -175,5 +179,11 @@
Designer
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Thermo.Active.Config/packages.config b/Thermo.Active.Config/packages.config
new file mode 100644
index 00000000..7c080311
--- /dev/null
+++ b/Thermo.Active.Config/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/Thermo.Active.Model/Constants.cs b/Thermo.Active.Model/Constants.cs
index 480e679d..fb3022fa 100644
--- a/Thermo.Active.Model/Constants.cs
+++ b/Thermo.Active.Model/Constants.cs
@@ -210,6 +210,7 @@ namespace Thermo.Active.Model
public static string WEBSITE_DIRECTORY = BASE_PATH + "\\view";
#endif
public const string CONFIG_DIRECTORY = "Config\\";
+ public const string RECIPE_DIRECTORY = "Recipes\\";
public const string RESOURCE_DIRECTORY = @"Thermo.Active.Config.Config.";
public const string SERVER_CONFIG_SCHEMA_PATH = RESOURCE_DIRECTORY + @"serverConfigValidator.xsd";
public const string SERVER_CONFIG_PATH = CONFIG_DIRECTORY + "serverConfig.xml";
@@ -252,6 +253,8 @@ namespace Thermo.Active.Model
public const string MAIN_PROGRAM_CONFIG_PATH = CONFIG_DIRECTORY + "customMainProgram.txt";
+ public const string LIVE_RECIPE_PATH = RECIPE_DIRECTORY + "current.json";
+
public static string LANGUAGE_PACK_DIRECTORY = BASE_PATH + "\\languages\\";
public static string LANGUAGE_SCHEMA_PATH = BASE_PATH + "\\LanguageValidator.xsd";
diff --git a/Thermo.Active.NC/NcAdapter.cs b/Thermo.Active.NC/NcAdapter.cs
index 9efc234e..1b79e3f7 100644
--- a/Thermo.Active.NC/NcAdapter.cs
+++ b/Thermo.Active.NC/NcAdapter.cs
@@ -1621,15 +1621,11 @@ namespace Thermo.Active.NC
CmsError cmsError = NO_ERROR;
currOverview = new Dictionary();
- // !!!FARE davvero!!!
-#if false
- // gestione errore
- cmsError = ReadScadaData(schema, out currParam);
+ // leggo la ricetta!
+ var currRecipe = new Dictionary();
+ cmsError = ReadFullRecipe(out currRecipe);
if (cmsError.IsError())
- return cmsError;
-#endif
-
- // calcolo!
+ return cmsError;
// leggo l'intero array delle DB... QUI FAKE sulle DB configurate...
List recipeConfig = RecipeConfig.Select(x => new DTORecipeConfigModel()
@@ -1645,34 +1641,51 @@ namespace Thermo.Active.NC
}).ToList();
RecipeCatStatus currStatus = RecipeCatStatus.Unchanged;
- int countCat = 0;
+
+ // percorro conf ricetta...
foreach (var item in recipeConfig)
{
- // ogni 20 incremento...
- if (countCat < 20)
+ currStatus = RecipeCatStatus.Unchanged;
+ // cerco SE ci sia già uno status...
+ if (currOverview.ContainsKey(item.Category))
{
- currStatus = RecipeCatStatus.Unchanged;
+ currStatus = currOverview[item.Category];
}
- else if (countCat < 40)
+
+ // se lo stato è errore --> esco...
+ if (currStatus == RecipeCatStatus.HasError)
{
- currStatus = RecipeCatStatus.ChangedOk;
+ continue;
}
+ // altrimenti controllo
else
{
- currStatus = RecipeCatStatus.HasError;
+ // se in errore --> registro...
+ if (currRecipe[item.Label].Status.HasError)
+ {
+ currStatus = RecipeCatStatus.HasError;
+ }
+ // 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;
+ }
}
- // se non c'è aggiungo
+
+ // ora verifico overview finale: se non c'è aggiungo
if (!currOverview.ContainsKey(item.Category))
{
currOverview.Add(item.Category, currStatus);
- countCat = 0;
}
else
{
// se il valore è maggiore --> aggiorno
currOverview[item.Category] = (int)currStatus > (int)currOverview[item.Category] ? currStatus : currOverview[item.Category];
}
- countCat++;
}
// restituisco cod errore se trovato
@@ -1731,6 +1744,28 @@ namespace Thermo.Active.NC
return cmsError;
}
+ ///
+ /// Returns resistances configuration
+ ///
+ /// List of configured resistances
+ ///
+ public CmsError GetWarmersResistances(out Dictionary currWarmersResistances)
+ {
+ CmsError cmsError = NO_ERROR;
+ currWarmersResistances = new Dictionary();
+
+ // read and return config
+ if (NcConfig.NcVendor == NC_VENDOR.S7NET)
+ {
+ foreach (var item in RiskResistConfig)
+ {
+ currWarmersResistances.Add(item.Id, item);
+ }
+ }
+
+ // restituisco cod errore se trovato
+ return cmsError;
+ }
#endregion Read Data
diff --git a/Thermo.Active.NC/NcFileAdapter.cs b/Thermo.Active.NC/NcFileAdapter.cs
index 34ea08f7..83366ebf 100644
--- a/Thermo.Active.NC/NcFileAdapter.cs
+++ b/Thermo.Active.NC/NcFileAdapter.cs
@@ -19,6 +19,61 @@ namespace Thermo.Active.NC
{
public class NcFileAdapter : NcAdapter
{
+ ///
+ /// Read file from local devices ad give back string content
+ ///
+ ///
+ ///
+ ///
+ public CmsError ReadFileContent(string path, out string fileContent)
+ {
+ // init
+ fileContent = "";
+ if (!string.IsNullOrEmpty(path))
+ {
+ // check existing
+ if (File.Exists(path))
+ {
+ // read all lines as string
+ fileContent = File.ReadAllText(path);
+ }
+ else
+ {
+ return FILE_NOT_FOUND_ERROR;
+ }
+ }
+ else
+ {
+ return FILE_NOT_FOUND_ERROR;
+ }
+
+ return NO_ERROR;
+ }
+ ///
+ /// Save string content to file
+ ///
+ ///
+ ///
+ ///
+ public CmsError WriteFileContent(string path, string fileContent)
+ {
+ if (!string.IsNullOrEmpty(path))
+ {
+ if (!string.IsNullOrEmpty(fileContent))
+ {
+ File.WriteAllText(path, fileContent);
+ }
+ }
+ else
+ {
+ return FILE_NOT_FOUND_ERROR;
+ }
+
+ return NO_ERROR;
+ }
+
+
+
public CmsError GetFileList(string path, out List fileList)
{
fileList = new List();
@@ -41,8 +96,8 @@ namespace Thermo.Active.NC
if (cmsError.IsError())
return cmsError;
- string [] names = fileInfo.Name.Split('/');
- if(names.Length > 0)
+ string[] names = fileInfo.Name.Split('/');
+ if (names.Length > 0)
{
string name = names.Last();
if (!String.IsNullOrWhiteSpace(name))
diff --git a/Thermo.Active/Controllers/WebApi/RecipeController.cs b/Thermo.Active/Controllers/WebApi/RecipeController.cs
index 92614144..8466f6a0 100644
--- a/Thermo.Active/Controllers/WebApi/RecipeController.cs
+++ b/Thermo.Active/Controllers/WebApi/RecipeController.cs
@@ -13,6 +13,7 @@ using static CMS_CORE_Library.Models.DataStructures;
using static Thermo.Active.Config.ServerConfig;
using static Thermo.Active.Model.Constants;
using Thermo.Active.Model.DTOModels.Recipe;
+using Thermo.Active.Config;
namespace Thermo.Active.Controllers.WebApi
{
@@ -54,8 +55,6 @@ namespace Thermo.Active.Controllers.WebApi
}
}
-
-
[Route("update"), HttpPut]
public IHttpActionResult WriteParameters(Dictionary parametersList)
{
@@ -116,6 +115,23 @@ namespace Thermo.Active.Controllers.WebApi
if (cmsError.IsError())
return BadRequest(cmsError.localizationKey);
+ // recupero i dati LIVE dei parametri HMI della ricetta...
+ cmsError = ncAdapter.ReadFullRecipe(out Dictionary currRecipe);
+ if (cmsError.IsError())
+ return BadRequest(cmsError.localizationKey);
+
+ // rileggo la ricetta
+ var currParams = new Dictionary();
+ foreach (var item in currRecipe)
+ {
+ currParams.Add(item.Key, item.Value.SetpointHMI);
+ }
+
+ // ora salvo ANCHE i dati live...
+ RecipeLiveData.RecipeParameters = currParams;
+ // e salvo su disco
+ ServerConfigController.WriteLiveData();
+
// ritorno solo fatto!
return Ok();
}
@@ -140,11 +156,117 @@ namespace Thermo.Active.Controllers.WebApi
if (cmsError.IsError())
return BadRequest(cmsError.localizationKey);
+ // recupero i dati LIVE dei parametri HMI della ricetta...
+ cmsError = ncAdapter.ReadFullRecipe(out Dictionary currRecipe);
+ if (cmsError.IsError())
+ return BadRequest(cmsError.localizationKey);
+
+ var currParams = new Dictionary();
+ foreach (var item in currRecipe)
+ {
+ currParams.Add(item.Key, item.Value.SetpointPLC);
+ }
+
+ // ora salvo ANCHE i dati live...
+ RecipeLiveData.RecipeParameters = currParams;
+ // e salvo su disco
+ ServerConfigController.WriteLiveData();
+
// ritorno solo fatto!
return Ok();
}
}
+ ///
+ /// Save current recipe from PLC to default
+ ///
+ ///
+ [Route("save"), HttpPut]
+ public IHttpActionResult Save()
+ {
+ using (NcFileAdapter ncAdapter = new NcFileAdapter())
+ {
+ // Try connection
+ CmsError libraryError = ncAdapter.Connect();
+ if (libraryError.errorCode != 0)
+ return NotFound();
+
+ // recupero i dati LIVE dei parametri HMI della ricetta...
+ CmsError cmsError = ncAdapter.ReadFullRecipe(out Dictionary currRecipe);
+ if (cmsError.IsError())
+ return BadRequest(cmsError.localizationKey);
+
+ var currParams = new Dictionary();
+ foreach (var item in currRecipe)
+ {
+ currParams.Add(item.Key, item.Value.SetpointPLC);
+ }
+
+ // ora salvo ANCHE i dati live...
+ RecipeLiveData.RecipeParameters = currParams;
+ // e salvo su disco
+ ServerConfigController.WriteLiveData();
+
+ // ritorno solo fatto!
+ return Ok();
+ }
+ }
+
+ ///
+ /// Save current recipe from PLC with new name
+ ///
+ ///
+ [Route("saveAs"), HttpPut]
+ public IHttpActionResult SaveAs(string newName)
+ {
+ using (NcFileAdapter ncAdapter = new NcFileAdapter())
+ {
+ // Try connection
+ CmsError libraryError = ncAdapter.Connect();
+ if (libraryError.errorCode != 0)
+ return NotFound();
+
+ // recupero i dati LIVE dei parametri HMI della ricetta...
+ CmsError cmsError = ncAdapter.ReadFullRecipe(out Dictionary currRecipe);
+ if (cmsError.IsError())
+ return BadRequest(cmsError.localizationKey);
+
+ var currParams = new Dictionary();
+ foreach (var item in currRecipe)
+ {
+ currParams.Add(item.Key, item.Value.SetpointPLC);
+ }
+
+ // ora salvo ANCHE i dati live...
+ RecipeLiveData.RecipeParameters = currParams;
+ // e salvo su disco
+ ServerConfigController.SaveRecipe(newName);
+
+ // ritorno solo fatto!
+ return Ok();
+ }
+ }
+ ///
+ /// load recipe from file and send to PLC
+ ///
+ ///
+ [Route("load"), HttpPut]
+ public IHttpActionResult Load(string newName)
+ {
+ using (NcFileAdapter ncAdapter = new NcFileAdapter())
+ {
+ // Try connection
+ CmsError libraryError = ncAdapter.Connect();
+ if (libraryError.errorCode != 0)
+ return NotFound();
+
+ // chiamo metodo di lettura...
+ ServerConfigController.LoadRecipe(newName);
+
+ // ritorno solo fatto!
+ return Ok();
+ }
+ }
}
}
\ No newline at end of file
diff --git a/Thermo.Active/Controllers/WebApi/WarmersController.cs b/Thermo.Active/Controllers/WebApi/WarmersController.cs
index f437f5b5..595fd2bc 100644
--- a/Thermo.Active/Controllers/WebApi/WarmersController.cs
+++ b/Thermo.Active/Controllers/WebApi/WarmersController.cs
@@ -19,8 +19,8 @@ namespace Thermo.Active.Controllers.WebApi
[RoutePrefix("api/warmers")]
public class WarmersController : ApiController
{
- [Route("current"), HttpGet]
- public IHttpActionResult GetCurrentWarmers()
+ [Route("channels"), HttpGet]
+ public IHttpActionResult GetCurrentWarmersChannels()
{
using (NcAdapter ncAdapter = new NcAdapter())
{
@@ -36,18 +36,39 @@ namespace Thermo.Active.Controllers.WebApi
return Ok(currWarmers);
}
}
-
-
- // FIXME TODO determinare IN PRIMIS nel modello COSA e come aggiornare...
-#if false
- [Route("update"), HttpPut]
- public IHttpActionResult WriteWarmers(Dictionary parametersList)
+ [Route("resistances"), HttpGet]
+ public IHttpActionResult GetCurrentWarmersResistances()
{
using (NcAdapter ncAdapter = new NcAdapter())
{
// Try connection
CmsError libraryError = ncAdapter.Connect();
+ if (libraryError.errorCode != 0)
+ return NotFound();
+ CmsError cmsError = ncAdapter.GetWarmersResistances(out Dictionary currWarmers);
+ if (cmsError.IsError())
+ return BadRequest(cmsError.localizationKey);
+
+ return Ok(currWarmers);
+ }
+ }
+
+
+ [Route("update"), HttpPut]
+ public IHttpActionResult WriteSetpoints(Dictionary channelsList)
+ {
+ // scrive su CHp da ricetta oppure da override x parametri utente...
+
+ using (NcAdapter ncAdapter = new NcAdapter())
+ {
+#if false
+ // Try connection
+ CmsError libraryError = ncAdapter.Connect();
+ if (libraryError.errorCode != 0)
+ return NotFound();
+
+ // read recipe!
CmsError cmsError = ncAdapter.ReadFullRecipe(out Dictionary prevRecipe);
if (cmsError.IsError())
return BadRequest(cmsError.localizationKey);
@@ -71,13 +92,66 @@ namespace Thermo.Active.Controllers.WebApi
}
// scrivo sul PLC
- ncAdapter.WriteRecipeParams(updtRecipe);
+ ncAdapter.WriteRecipeParams(updtRecipe);
+#endif
// ritorno solo fatto!
return Ok();
}
- }
+ }
+
+ ///
+ /// Confirm recipe modification (parameters: HMI --> PLC)
+ ///
+ ///
+ [Route("confirm"), HttpPut]
+ public IHttpActionResult ConfirmEdit()
+ {
+ using (NcAdapter ncAdapter = new NcAdapter())
+ {
+#if false
+ // Try connection
+ CmsError libraryError = ncAdapter.Connect();
+ if (libraryError.errorCode != 0)
+ return NotFound();
+
+ // scrivo sul PLC il comando conferma!
+ CmsError cmsError = ncAdapter.ConfirmRecipeData(true);
+ if (cmsError.IsError())
+ return BadRequest(cmsError.localizationKey);
#endif
+ // ritorno solo fatto!
+ return Ok();
+ }
+ }
+
+ ///
+ /// Cancel recipe modification (parameters: PLC --> HMI)
+ ///
+ ///
+ [Route("cancel"), HttpPut]
+ public IHttpActionResult CancelEdit()
+ {
+ using (NcAdapter ncAdapter = new NcAdapter())
+ {
+#if false
+ // Try connection
+ CmsError libraryError = ncAdapter.Connect();
+ if (libraryError.errorCode != 0)
+ return NotFound();
+
+ // scrivo sul PLC il comando annula!
+ CmsError cmsError = ncAdapter.ConfirmRecipeData(false);
+ if (cmsError.IsError())
+ return BadRequest(cmsError.localizationKey);
+#endif
+
+ // ritorno solo fatto!
+ return Ok();
+ }
+ }
+
+
}
}
\ No newline at end of file