DRAFT: Recipe local persistence file

This commit is contained in:
Samuele Locatelli
2020-06-05 23:13:46 +02:00
parent 2a66160e84
commit 020d8304a5
8 changed files with 310 additions and 14 deletions
+28
View File
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Thermo.Active.Config
{
/// <summary>
/// Live data for Thermo Active
/// </summary>
public class LiveData
{
/// <summary>
/// Current loaded recipe
/// </summary>
public string RecipeName = "current.json";
/// <summary>
/// Dictionary of all parameters and values
/// </summary>
public Dictionary<string, double> RecipeParameters;
/// <summary>
/// Dictionary of all channels and relative setpoints
/// </summary>
public Dictionary<int, double> ChannelSetpoints;
}
}
+12 -4
View File
@@ -32,10 +32,8 @@ namespace Thermo.Active.Config
public static List<NcSoftKeysModel> NcSoftKeysConfig;
public static List<AlarmsConfigModel> InitialAlarmsConfig;
public static List<HeadsConfigModel> HeadsConfig;
public static List<RecipeConfigModel> RecipeConfig;
public static List<ModBlockConfigModel> ModBlockConfig;
public static List<RiskResistModel> RiskResistConfig;
public static List<RiskChannelModel> RiskChannelConfig;
public static CmsConnectConfigModel CmsConnectConfig;
public static AreasConfigModel ProductionConfig;
@@ -55,5 +53,15 @@ namespace Thermo.Active.Config
public static List<string> MacrosConfig;
public static string CMSMainProgramContent;
// Thermo
public static List<RecipeConfigModel> RecipeConfig;
public static List<ModBlockConfigModel> ModBlockConfig;
public static List<RiskResistModel> RiskResistConfig;
public static List<RiskChannelModel> RiskChannelConfig;
public static LiveData RecipeLiveData;
}
}
+86 -4
View File
@@ -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,96 @@ namespace Thermo.Active.Config
.Select(x => x.Value)
.ToList();
}
/// <summary>
/// Try to load live data from json persistence file
/// </summary>
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<LiveData>(rawData);
}
catch
{ }
}
else
{
// setup new object
RecipeLiveData = new LiveData()
{
RecipeName = "current.json",
ChannelSetpoints = new Dictionary<int, double>(),
RecipeParameters = new Dictionary<string, double>()
};
}
}
/// <summary>
/// Try to write live data to json persistence file
/// </summary>
public static void WriteLiveData()
{
try
{
// serialize
string rawData = JsonConvert.SerializeObject(RecipeLiveData);
// save live!
File.WriteAllText(LIVE_RECIPE_PATH, rawData);
}
catch
{ }
}
/// <summary>
/// Try to load selected recipe to live data (memory and json persistence file)
/// </summary>
public static void LoadRecipe(string filePath)
{
if (File.Exists(filePath))
{
// load all text data
var rawData = File.ReadAllText(filePath);
try
{
// deserialize to object
RecipeLiveData = JsonConvert.DeserializeObject<LiveData>(rawData);
}
catch
{ }
// update current live data!
WriteLiveData();
}
}
/// <summary>
/// Try to save live recipe to selected filePath
/// </summary>
public static void SaveRecipe(string filePath)
{
try
{
// serialize
string rawData = JsonConvert.SerializeObject(RecipeLiveData);
// save live!
File.WriteAllText(LIVE_RECIPE_PATH, rawData);
// 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)
{
@@ -32,6 +32,9 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<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" />
@@ -52,6 +55,7 @@
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Compile Include="LiveData.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ServerConfig.cs" />
<Compile Include="ServerConfigController.cs" />
@@ -175,5 +179,11 @@
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Folder Include="Recipes\" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
+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>
+3
View File
@@ -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";
+57 -2
View File
@@ -19,6 +19,61 @@ namespace Thermo.Active.NC
{
public class NcFileAdapter : NcAdapter
{
/// <summary>
/// Read file from local devices ad give back string content
/// </summary>
/// <param name="path"></param>
/// <param name="fileContent"></param>
/// <returns></returns>
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;
}
/// <summary>
/// Save string content to file
/// </summary>
/// <param name="path"></param>
/// <param name="fileContent"></param>
/// <returns></returns>
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<PreviewFileModel> fileList)
{
fileList = new List<PreviewFileModel>();
@@ -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))
@@ -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
{
@@ -99,7 +100,7 @@ namespace Thermo.Active.Controllers.WebApi
/// Confirm recipe modification (parameters: HMI --> PLC)
/// </summary>
/// <returns></returns>
[Route("confirm"), HttpPut]
[Route("Confirm"), HttpPut]
public IHttpActionResult ConfirmEdit()
{
using (NcAdapter ncAdapter = new NcAdapter())
@@ -109,8 +110,24 @@ namespace Thermo.Active.Controllers.WebApi
if (libraryError.errorCode != 0)
return NotFound();
// recupero i dati LIVE dei parametri HMI della ricetta...
CmsError cmsError = ncAdapter.ReadFullRecipe(out Dictionary<string, DTORecipeParam> currRecipe);
if (cmsError.IsError())
return BadRequest(cmsError.localizationKey);
var currParams = new Dictionary<string, double>();
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();
// scrivo sul PLC il comando conferma!
CmsError cmsError = ncAdapter.ConfirmRecipeData(true);
cmsError = ncAdapter.ConfirmRecipeData(true);
if (cmsError.IsError())
return BadRequest(cmsError.localizationKey);
@@ -123,10 +140,100 @@ namespace Thermo.Active.Controllers.WebApi
/// Cancel recipe modification (parameters: PLC --> HMI)
/// </summary>
/// <returns></returns>
[Route("cancel"), HttpPut]
[Route("Cancel"), HttpPut]
public IHttpActionResult CancelEdit()
{
using (NcAdapter ncAdapter = new NcAdapter())
{
// 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<string, DTORecipeParam> currRecipe);
if (cmsError.IsError())
return BadRequest(cmsError.localizationKey);
var currParams = new Dictionary<string, double>();
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();
// scrivo sul PLC il comando annula!
cmsError = ncAdapter.ConfirmRecipeData(false);
if (cmsError.IsError())
return BadRequest(cmsError.localizationKey);
// ritorno solo fatto!
return Ok();
}
}
/// <summary>
/// Save current recipe from PLC to default
/// </summary>
/// <returns></returns>
[Route("Save"), HttpPut]
public IHttpActionResult Save()
{
using (NcFileAdapter ncAdapter = new NcFileAdapter())
{
// Try connection
CmsError libraryError = ncAdapter.Connect();
if (libraryError.errorCode != 0)
return NotFound();
// serialize current recipe as JSon
//// scrivo sul PLC il comando annula!
//CmsError cmsError = ncAdapter.ConfirmRecipeData(false);
//if (cmsError.IsError())
// return BadRequest(cmsError.localizationKey);
// ritorno solo fatto!
return Ok();
}
}
/// <summary>
/// Save current recipe from PLC with new name
/// </summary>
/// <returns></returns>
[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();
// scrivo sul PLC il comando annula!
CmsError cmsError = ncAdapter.ConfirmRecipeData(false);
if (cmsError.IsError())
return BadRequest(cmsError.localizationKey);
// ritorno solo fatto!
return Ok();
}
}
/// <summary>
/// load recipe from file and send to PLC
/// </summary>
/// <returns></returns>
[Route("Load"), HttpPut]
public IHttpActionResult Load(string newName)
{
using (NcFileAdapter ncAdapter = new NcFileAdapter())
{
// Try connection
CmsError libraryError = ncAdapter.Connect();
@@ -143,6 +250,5 @@ namespace Thermo.Active.Controllers.WebApi
}
}
}
}