Merge branch 'feature/recipe' into develop
This commit is contained in:
@@ -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" />
|
||||
|
||||
@@ -62,7 +62,6 @@ namespace Thermo.Active.Config
|
||||
public static List<RiskChannelModel> RiskChannelConfig;
|
||||
public static List<RiskBoardModel> RiskBoardConfig;
|
||||
|
||||
public static LiveData RecipeLiveData = new LiveData();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
+7
-2
@@ -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" />
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user