Merge branch 'feature/recipe' into develop

This commit is contained in:
Samuele Locatelli
2020-06-25 10:09:45 +02:00
19 changed files with 382 additions and 328 deletions
@@ -2,10 +2,7 @@
<modules>
<block>
<id>1</id>
<localizedLabels>
<lang langKey="en">DiscesaCZ ENG</lang>
<lang langKey="it">DiscesaCZ ITA</lang>
</localizedLabels>
<label>MB_DiscesaCZ</label>
<type>MOVEMENT</type>
<section>HEATING</section>
<idParam>-1</idParam>
@@ -15,10 +12,7 @@
</block>
<block>
<id>2</id>
<localizedLabels>
<lang langKey="en">MembDiscesaZ ENG</lang>
<lang langKey="it">MembDiscesaZ ITA</lang>
</localizedLabels>
<label>MB_MembDiscesaZ</label>
<type>MOVEMENT</type>
<section>HEATING</section>
<idParam>-1</idParam>
@@ -28,10 +22,7 @@
</block>
<block>
<id>3</id>
<localizedLabels>
<lang langKey="en">MembZ ENG</lang>
<lang langKey="it">MembZ ITA</lang>
</localizedLabels>
<label>MB_MembZ</label>
<type>MOVEMENT</type>
<section>HEATING</section>
<idParam>-1</idParam>
@@ -41,10 +32,7 @@
</block>
<block>
<id>4</id>
<localizedLabels>
<lang langKey="en">Mod_MembSalitaZ ENG</lang>
<lang langKey="it">Mod_MembSalitaZ ITA</lang>
</localizedLabels>
<label>MB_Mod_MembSalitaZ</label>
<type>MOVEMENT</type>
<section>HEATING</section>
<idParam>-1</idParam>
@@ -54,10 +42,7 @@
</block>
<block>
<id>6</id>
<localizedLabels>
<lang langKey="en">Mod_RiscaldoInf ENG</lang>
<lang langKey="it">Mod_RiscaldoInf ITA</lang>
</localizedLabels>
<label>MB_Mod_RiscaldoInf</label>
<type>HEATING</type>
<section>HEATING</section>
<idParam>-1</idParam>
@@ -67,10 +52,7 @@
</block>
<block>
<id>7</id>
<localizedLabels>
<lang langKey="en">Mod_RiscaldoSup ENG</lang>
<lang langKey="it">Mod_RiscaldoSup ITA</lang>
</localizedLabels>
<label>MB_Mod_RiscaldoSup</label>
<type>HEATING</type>
<section>HEATING</section>
<idParam>0</idParam>
@@ -80,10 +62,7 @@
</block>
<block>
<id>8</id>
<localizedLabels>
<lang langKey="en">Mod_PirometroRisc ENG</lang>
<lang langKey="it">Mod_PirometroRisc ITA</lang>
</localizedLabels>
<label>MB_Mod_PirometroRisc</label>
<type>HEATING</type>
<section>HEATING</section>
<idParam>80</idParam>
@@ -93,10 +72,7 @@
</block>
<block>
<id>13</id>
<localizedLabels>
<lang langKey="en">Mod_Imbutitura ENG</lang>
<lang langKey="it">Mod_Imbutitura ITA</lang>
</localizedLabels>
<label>MB_Mod_Imbutitura</label>
<type>DRAWING</type>
<section>FORMING</section>
<idParam>99</idParam>
@@ -106,10 +82,7 @@
</block>
<block>
<id>16</id>
<localizedLabels>
<lang langKey="en">Mod_Raffreddamento ENG</lang>
<lang langKey="it">Mod_Raffreddamento ITA</lang>
</localizedLabels>
<label>MB_Mod_Raffreddamento</label>
<type>COOLING</type>
<section>FORMING</section>
<idParam>-1</idParam>
@@ -119,10 +92,7 @@
</block>
<block>
<id>17</id>
<localizedLabels>
<lang langKey="en">Mod_PirometroRaffr ENG</lang>
<lang langKey="it">Mod_PirometroRaffr ITA</lang>
</localizedLabels>
<label>MB_Mod_PirometroRaffr</label>
<type>COOLING</type>
<section>FORMING</section>
<idParam>139</idParam>
@@ -132,10 +102,7 @@
</block>
<block>
<id>19</id>
<localizedLabels>
<lang langKey="en">Mod_Vuoto ENG</lang>
<lang langKey="it">Mod_Vuoto ITA</lang>
</localizedLabels>
<label>MB_Mod_Vuoto</label>
<type>VACUUM</type>
<section>FORMING</section>
<idParam>-1</idParam>
@@ -145,10 +112,7 @@
</block>
<block>
<id>21</id>
<localizedLabels>
<lang langKey="en">Mod_VuotoDiretto ENG</lang>
<lang langKey="it">Mod_VuotoDiretto ITA</lang>
</localizedLabels>
<label>MB_Mod_VuotoDiretto</label>
<type>VACUUM</type>
<section>FORMING</section>
<idParam>-1</idParam>
@@ -158,10 +122,7 @@
</block>
<block>
<id>36</id>
<localizedLabels>
<lang langKey="en">Mod_EstrazioneZ ENG</lang>
<lang langKey="it">Mod_EstrazioneZ ITA</lang>
</localizedLabels>
<label>MB_Mod_EstrazioneZ</label>
<type>EXTRACTION</type>
<section>EXTRACTION</section>
<idParam>-1</idParam>
@@ -171,10 +132,7 @@
</block>
<block>
<id>42</id>
<localizedLabels>
<lang langKey="en">Mod_SalitaCZ ENG</lang>
<lang langKey="it">Mod_SalitaCZ ITA</lang>
</localizedLabels>
<label>MB_Mod_SalitaCZ</label>
<type>MOVEMENT</type>
<section>EXTRACTION</section>
<idParam>-1</idParam>
@@ -8,14 +8,7 @@
<xs:complexType>
<xs:all>
<xs:element name="id" type="xs:int"/>
<xs:element name="localizedLabels">
<xs:complexType>
<xs:sequence>
<xs:element name="lang" type="langType" minOccurs="0" maxOccurs="unbounded">
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="label" type="xs:string" />
<xs:element name="type" type="mblockType" />
<xs:element name="section" type="mblockSection" />
<xs:element name="idParam" type="xs:int" />
-1
View File
@@ -62,7 +62,6 @@ namespace Thermo.Active.Config
public static List<RiskChannelModel> RiskChannelConfig;
public static List<RiskBoardModel> RiskBoardConfig;
public static LiveData RecipeLiveData = new LiveData();
}
}
+4 -199
View File
@@ -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)
{
@@ -633,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),
@@ -846,180 +825,6 @@ namespace Thermo.Active.Config
.Select(x => x.Value)
.ToList();
}
/// <summary>
/// Try to load live data from json persistence file
/// </summary>
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<LiveData>(rawData);
}
catch
{ }
answ = true;
}
else
{
// reload from template...
var rawData = File.ReadAllText(RECIPE_TEMPLATE_PATH);
try
{
// deserialize to object
RecipeLiveData = JsonConvert.DeserializeObject<LiveData>(rawData);
}
catch
{ }
// salva current
SaveRecipeCurrent();
answ = true;
}
// rendo se fatto
return answ;
}
/// <summary>
/// Try to load selected recipe to live data (memory and json persistence file)
/// </summary>
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<LiveData>(rawData);
}
catch
{ }
// update current live data!
SaveRecipeCurrent();
}
// rendo se fatto
return answ;
}
/// <summary>
/// Try to load template recipe
/// </summary>
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<LiveData>(rawData);
// update NAME
RecipeLiveData.RecipeName = $"{DateTime.Now:yyyyMMss_HHmmss}.json";
}
catch
{ }
// update current live data!
SaveRecipeCurrent();
}
// rendo se fatto
return answ;
}
/// <summary>
/// Try to write live data to json persistence file
/// </summary>
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;
}
/// <summary>
/// Try to save live recipe as NEW template
/// </summary>
public static bool SaveRecipeTemplate()
{
RecipeLiveData.RecipeName = "template.json";
return SaveRecipe(RECIPE_TEMPLATE_PATH);
}
/// <summary>
/// Try to save live recipe to selected filePath
/// </summary>
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())
@@ -55,7 +55,6 @@
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Compile Include="LiveData.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ServerConfig.cs" />
<Compile Include="ServerConfigController.cs" />
@@ -6,7 +6,7 @@ namespace Thermo.Active.Model.ConfigModels
public class ModBlockConfigModel
{
public int Id;
public Dictionary<string, string> 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; }
@@ -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;
}
@@ -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;
@@ -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
}
}
@@ -1,6 +1,6 @@
using System.Collections.Generic;
namespace Thermo.Active.Config
namespace Thermo.Active.Model.DTOModels.ThRecipe
{
/// <summary>
/// Live data for Thermo Active
@@ -19,6 +19,11 @@ namespace Thermo.Active.Config
/// Dictionary of all channels and relative setpoints
/// </summary>
public Dictionary<int, int> ChannelSetpoints;
/// <summary>
/// Recipe Overview
/// </summary>
public Dictionary<RecipeSection, RecipeCatStatus> RecipeOverview;
}
}
@@ -108,6 +108,7 @@
<Compile Include="DTOModels\ThModules\DTOModule.cs" />
<Compile Include="DTOModels\ThModules\DTOModuleConfigModel.cs" />
<Compile Include="DTOModels\ThModules\DTOModulesBlock.cs" />
<Compile Include="DTOModels\ThRecipe\LiveData.cs" />
<Compile Include="DTOModels\ThWarmers\DTOWarmers.cs" />
<Compile Include="DTOModels\ThRecipe\DTORecipeParam.cs" />
<Compile Include="DTOModels\ThRecipe\DTORecipeConfigModel .cs" />
+45 -36
View File
@@ -23,10 +23,12 @@ namespace Thermo.Active.NC
{
public class NcAdapter : IDisposable
{
/// <summary>
/// NC object
/// </summary>
public NcThermo numericalControl;
/// <summary>
/// Lock per connessione PLC
/// Lock semaphore for PLC connection step
/// </summary>
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<string, DTORecipeParam> prevRecipe);
@@ -302,7 +304,7 @@ namespace Thermo.Active.NC
return libraryError;
// save parameters to PLC!!!
Dictionary<string, DTORecipeParam> updtRecipe = new Dictionary<string, DTORecipeParam>();
foreach (var item in RecipeLiveData.RecipeParameters)
foreach (var item in NcFileAdapter.RecipeLiveData.RecipeParameters)
{
if (prevRecipe.ContainsKey(item.Key))
{
@@ -1886,12 +1888,13 @@ namespace Thermo.Active.NC
/// </summary>
/// <param name="currOverview">Oggetto overview ricetta corrente HMI</param>
/// <returns></returns>
public CmsError GetRecipeOverview(out Dictionary<string, RecipeCatStatus> currOverview)
public CmsError GetRecipeOverview(out Dictionary<RecipeSection, RecipeCatStatus> currOverview)
{
CmsError libraryError = NO_ERROR;
currOverview = new Dictionary<string, RecipeCatStatus>();
// overview di base: ultima salvata...
currOverview = new Dictionary<RecipeSection, RecipeCatStatus>();
// leggo la ricetta!
// leggo la ricetta dal PLC!
var currRecipe = new Dictionary<string, DTORecipeParam>();
libraryError = ReadFullRecipe(out currRecipe);
if (libraryError.IsError())
@@ -1913,15 +1916,31 @@ namespace Thermo.Active.NC
RecipeCatStatus currStatus = RecipeCatStatus.Unchanged;
// percorro conf ricetta...
// da conf ricetta --> se ci sono li leggo da li...
if (NcFileAdapter.RecipeLiveData.RecipeOverview != null)
{
currOverview = NcFileAdapter.RecipeLiveData.RecipeOverview;
}
bool changed = false;
foreach (var item in recipeConfig)
{
currStatus = RecipeCatStatus.Unchanged;
// cerco SE ci sia già uno status...
if (currOverview.ContainsKey(item.Category))
if (!currOverview.ContainsKey(getRecipeSection(item.Category)))
{
currStatus = currOverview[item.Category];
currOverview.Add(getRecipeSection(item.Category), RecipeCatStatus.Unchanged);
changed = true;
}
}
// se cambiato --> salvo in live data...
if (changed)
{
NcFileAdapter.RecipeLiveData.RecipeOverview = currOverview;
}
// ORA percorro conf ricetta x cercare eventuali ERRORI......
foreach (var item in recipeConfig)
{
currStatus = currOverview[getRecipeSection(item.Category)];
// se lo stato è errore --> esco...
if (currStatus == RecipeCatStatus.HasError)
@@ -1934,35 +1953,25 @@ namespace Thermo.Active.NC
// se in errore --> registro...
if (currRecipe[item.Label].Status.HasError)
{
currStatus = RecipeCatStatus.HasError;
currOverview[getRecipeSection(item.Category)] = 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;
}
}
// 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];
}
}
// restituisco cod errore se trovato
return libraryError;
}
/// <summary>
/// Conversione stringa --> enum
/// </summary>
/// <param name="strVal"></param>
/// <returns></returns>
protected RecipeSection getRecipeSection(string strVal)
{
RecipeSection answ = (RecipeSection)Enum.Parse(typeof(RecipeSection), strVal, true);
return answ;
}
/// <summary>
/// Legge tutti i parametri della ricetta
/// </summary>
@@ -2003,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,
+244
View File
@@ -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
{
/// <summary>
/// Recipe Live data
/// </summary>
public static LiveData RecipeLiveData = new LiveData();
/// <summary>
/// Read file from local devices ad give back string content
/// </summary>
@@ -582,5 +591,240 @@ namespace Thermo.Active.NC
return numericalControl.FILES_WCleanUploadFolder();
}
#region recipe file persistence
/// <summary>
/// Upsert recipe overview status
/// </summary>
/// <param name="section"></param>
/// <param name="status"></param>
public static void upsRecipeOverview(RecipeSection section, RecipeCatStatus status)
{
if (RecipeLiveData.RecipeOverview.ContainsKey(section))
{
RecipeLiveData.RecipeOverview[section] = status;
}
else
{
RecipeLiveData.RecipeOverview.Add(section, status);
}
}
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);
}
}
/// <summary>
/// Try to load live data from json persistence file
/// </summary>
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<LiveData>(rawData);
}
catch
{ }
answ = true;
}
else
{
// reload from template...
var rawData = File.ReadAllText(RECIPE_TEMPLATE_PATH);
try
{
// deserialize to object
RecipeLiveData = JsonConvert.DeserializeObject<LiveData>(rawData);
// from template --> reset (if present) overview data...
foreach (var item in RecipeLiveData.RecipeOverview)
{
RecipeLiveData.RecipeOverview[item.Key] = RecipeCatStatus.Unchanged;
}
}
catch
{ }
// salva current
SaveRecipeCurrent();
answ = true;
}
// rendo se fatto
return answ;
}
/// <summary>
/// Try to load selected recipe to live data (memory and json persistence file)
/// </summary>
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<LiveData>(rawData);
}
catch
{ }
// update current live data!
SaveRecipeCurrent();
}
// rendo se fatto
return answ;
}
/// <summary>
/// Try to load template recipe
/// </summary>
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<LiveData>(rawData);
// from template --> reset (if present) overview data...
if (RecipeLiveData.RecipeOverview != null)
{
foreach (var item in RecipeLiveData.RecipeOverview)
{
RecipeLiveData.RecipeOverview[item.Key] = RecipeCatStatus.Unchanged;
}
}
// update NAME
RecipeLiveData.RecipeName = $"{DateTime.Now:yyyyMMss_HHmmss}.json";
}
catch
{ }
// update current live data!
SaveRecipeCurrent();
}
// rendo se fatto
return answ;
}
/// <summary>
/// Try to write live data to json persistence file
/// </summary>
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;
}
/// <summary>
/// Try to save live recipe as NEW template
/// </summary>
public static bool SaveRecipeTemplate()
{
// duplicate data...
LiveData data2save = RecipeLiveData;
// template --> reset overview data...
data2save.RecipeOverview = new Dictionary<RecipeSection, RecipeCatStatus>();
return SaveRecipe(RECIPE_TEMPLATE_PATH, data2save);
}
/// <summary>
/// Try to save live recipe to selected filePath
/// </summary>
public static bool SaveRecipe(string filePath, LiveData currRecipe)
{
bool answ = false;
try
{
answ = true;
string fileName = Path.GetFileName(filePath);
if (!fileName.EndsWith(".json"))
{
fileName += ".json";
filePath += ".json";
}
// fix name!
currRecipe.RecipeName = fileName;
// serialize
string rawData = JsonConvert.SerializeObject(currRecipe);
// 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
}
}
+4
View File
@@ -33,6 +33,9 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
@@ -64,6 +67,7 @@
<None Include="Language\ERR_Spanish.INI">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\cms_core_library\CMS_CORE_Library\CMS_CORE_Library.csproj">
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net462" />
</packages>
@@ -30,7 +30,7 @@ namespace Thermo.Active.Controllers.WebApi
ThermoActiveLogger.LogError($"ncAdapter Not connected! | GetOverview | {libraryError.exception}");
}
libraryError = ncAdapter.GetRecipeOverview(out Dictionary<string, RecipeCatStatus> currOverview);
libraryError = ncAdapter.GetRecipeOverview(out Dictionary<RecipeSection, RecipeCatStatus> currOverview);
if (libraryError.IsError())
{
ThermoActiveLogger.LogError($"GetRecipeOverview error | {libraryError.exception}");
@@ -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();
@@ -123,11 +123,12 @@ namespace Thermo.Active.Controllers.WebApi
/// <summary>
/// Confirm recipe modification (parameters: HMI --> PLC)
/// </summary>
/// <param name="section">section confirmed (string as in overview)</param>
/// <returns></returns>
[Route("confirm"), HttpPut]
public IHttpActionResult ConfirmEdit()
public IHttpActionResult ConfirmEdit(RecipeSection section)
{
if (RecipeLiveData != null)
if (NcFileAdapter.RecipeLiveData != null)
{
// Try connection
CmsError libraryError = ncAdapter.Connect();
@@ -145,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<string, DTORecipeParam> currRecipe);
if (libraryError.IsError())
@@ -179,7 +193,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 +248,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 +274,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 +338,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, NcFileAdapter.RecipeLiveData);
// ritorno solo fatto!
return Ok();
@@ -363,7 +377,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<int, int>();
@@ -371,11 +385,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,16 +405,19 @@ 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)
{
ThermoActiveLogger.LogError($"Recipe | SaveCurrentRecipeParams exception | {exc}");
}
}
/// <summary>
/// write current recipe to PLC
/// </summary>
/// <returns></returns>
public static CmsError WriteCurrentRecipeToPlc()
{
CmsError checkError = NO_ERROR;
@@ -424,7 +441,7 @@ namespace Thermo.Active.Controllers.WebApi
// save parameters to PLC!!!
Dictionary<string, DTORecipeParam> updtRecipe = new Dictionary<string, DTORecipeParam>();
foreach (var item in RecipeLiveData.RecipeParameters)
foreach (var item in NcFileAdapter.RecipeLiveData.RecipeParameters)
{
if (prevRecipe.ContainsKey(item.Key))
{
@@ -452,7 +469,7 @@ namespace Thermo.Active.Controllers.WebApi
// process ch load setup...
Dictionary<int, int> newRisk = new Dictionary<int, int>();
foreach (var item in RecipeLiveData.ChannelSetpoints)
foreach (var item in NcFileAdapter.RecipeLiveData.ChannelSetpoints)
{
newRisk.Add(item.Key, item.Value);
}
@@ -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)
{
+1 -1
View File
@@ -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")]
+1 -1
View File
@@ -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