Merge branch 'develop' into new/dirSaveMgt

This commit is contained in:
Samuele Locatelli
2020-09-12 17:25:04 +02:00
18 changed files with 404 additions and 7 deletions
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="inputsOperator">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="realValueModal" type="valuesType" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="showValModal" type="showValType" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="buttonsListModal" type="buttonsType" minOccurs="0" maxOccurs="unbounded"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:complexType name="valuesType">
<xs:all>
<xs:element name="id" minOccurs='1' maxOccurs='1'/>
<xs:element name="title" type="translatedText" minOccurs='1' maxOccurs='1'/>
</xs:all>
</xs:complexType>
<xs:complexType name="showValType">
<xs:all>
<xs:element name="id" minOccurs='1' maxOccurs='1'/>
<xs:element name="title" type="translatedText" minOccurs='1' maxOccurs='1'/>
<xs:element name="buttons">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="button">
<xs:complexType>
<xs:all>
<xs:element name="value" minOccurs="1" maxOccurs="1" type="xs:int"></xs:element>
<xs:element name="title" type="translatedText" minOccurs='1' maxOccurs='1'/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
<xs:complexType name="buttonsType">
<xs:all>
<xs:element name="id" minOccurs='1' maxOccurs='1'/>
<xs:element name="title" type="translatedText" minOccurs='1' maxOccurs='1'/>
<xs:element name="buttons">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="button">
<xs:complexType>
<xs:all>
<xs:element name="value" minOccurs="1" maxOccurs="1" type="xs:int"></xs:element>
<xs:element name="title" type="translatedText" minOccurs='1' maxOccurs='1'/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
<!-- Translations field Type -->
<xs:complexType name="translatedText">
<xs:sequence>
<xs:element name="lang" type="langType" minOccurs="0" maxOccurs="unbounded">
</xs:element>
</xs:sequence>
</xs:complexType>
<!-- lang field -->
<xs:complexType name="langType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="langKey" use="required" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:schema>
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<inputsOperator>
<buttonsListModal>
<id>1</id>
<title>
<lang langKey="it">Hai rimosso manualmente anche il pezzo lavorato ?</lang>
<lang langKey="en">Have you also manually removed the workpiece ?</lang>
</title>
<buttons>
<button>
<value>0</value>
<title>
<lang langKey="it">No</lang>
<lang langKey="en">No</lang>
</title>
</button>
<button>
<value>1</value>
<title>
<lang langKey="it">Si</lang>
<lang langKey="en">Yes</lang>
</title>
</button>
</buttons>
</buttonsListModal>
<realValueModal>
<id>10</id>
<title>
<lang langKey="en">External water</lang>
<lang langKey="it">Acqua esterna</lang>
</title>
</realValueModal>
<realValueModal>
<id>11</id>
<title>
<lang langKey="en">External water</lang>
<lang langKey="it">Acqua esterna</lang>
</title>
</realValueModal>
<buttonsListModal>
<id>6</id>
<title>
<lang langKey="en">External water</lang>
<lang langKey="it">Acqua esterna</lang>
</title>
<buttons>
<button>
<value>3</value>
<title>
<lang langKey="en">External water</lang>
<lang langKey="it">Acqua esterna</lang>
</title>
</button>
<button>
<value>4</value>
<title>
<lang langKey="en">External water</lang>
<lang langKey="it">Acqua esterna</lang>
</title>
</button>
</buttons>
</buttonsListModal>
</inputsOperator>
+1 -2
View File
@@ -51,10 +51,9 @@ namespace Thermo.Active.Config
public static List<ScadaSchemaModel> SubscribedScada = new List<ScadaSchemaModel>();
public static List<string> MacrosConfig;
public static List<InputOperatorConfigModel> InputsOperatorConfig;
public static string CMSMainProgramContent;
// Thermo
public static List<ThermoProdConfigModel> ThermoProdConfig;
public static List<RecipeConfigModel> RecipeConfig;
@@ -41,6 +41,7 @@ namespace Thermo.Active.Config
// ReadCMSConnectConfig();
ReadMacros();
ReadScadaFile();
ReadM156();
}
catch (XmlException ex)
{
@@ -254,6 +255,47 @@ namespace Thermo.Active.Config
}
}
private static void ReadM156()
{
// Get Areas file handler
XDocument xmlConfigFile = GetXmlHandlerWithValidator(M156_CONFIG_SCHEMA_PATH, M156_CONFIG_PATH);
InputsOperatorConfig = xmlConfigFile
.Descendants("inputsOperator")
.Elements()
.Select(x => new InputOperatorConfigModel()
{
Id = Convert.ToInt32(x.Element("id").Value),
Messages = x.Element("title").Elements().ToDictionary( // Read localized names and convert into a dictionary
y => y.Attribute("langKey").Value, y => y.Value
),
Buttons = x.Element("buttons")?.Elements().ToDictionary( // Read buttons data and convert into a dictionary
y => Convert.ToByte(y.Element("value").Value),
y => y.Element("title").Elements().ToDictionary( // Read localized names and convert into a dictionary
z => z.Attribute("langKey").Value,
z => z.Value
)
),
Type = GetInputOperatoType(x.Name.ToString())
})
.ToList();
}
public static string GetInputOperatoType(string tagName)
{
switch (tagName)
{
case "modalValue":
return "REAL";
case "buttonsListModal":
return "MULTIPLE_BUTTONS";
case "showValModal":
return "SHOW_VAL";
default:
return "REAL";
}
}
#region Read config from file from configuration
@@ -51,6 +51,9 @@
<Content Include="Config\axesConfig.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Config\inputOperatorConfig.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Config\macrosConfig.xml">
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@@ -200,6 +203,10 @@
</ItemGroup>
<ItemGroup />
<ItemGroup>
<EmbeddedResource Include="Config\inputOperatorConfigValidator.xsd">
<SubType>Designer</SubType>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<None Include="Config\Recipes\template.tpl">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
+48
View File
@@ -957,6 +957,54 @@ public static class ThreadsFunctions
ncAdapter.Dispose();
}
}
public static void ReadMComandsData()
{
NcAdapter ncAdapter = new NcAdapter();
Stopwatch sw = new Stopwatch();
try
{
// Try connection
CmsError libraryError = ncAdapter.Connect();
if (libraryError.errorCode != 0)
ManageLibraryError(libraryError);
while (true)
{
sw.Restart();
if (ncAdapter.numericalControl.NC_IsConnected())
{
// solo x S7Net...
if (NcConfig.NcVendor == NC_VENDOR.S7NET)
{
libraryError = ncAdapter.GetM156Data(out List<DTOM156InputModel> m156Data);
if (libraryError.IsError())
ManageLibraryError(libraryError);
else
MessageServices.Current.Publish(SEND_M156_DATA, null, m156Data);
}
}
else
RestoreConnection();
sw.Stop();
//Update thread timer
UpdateStat(MethodBase.GetCurrentMethod().Name, sw.ElapsedMilliseconds);
// Wait
Thread.Sleep(CalcSleepTime(200, (int)sw.ElapsedMilliseconds));
}
}
catch (ThreadAbortException)
{
ncAdapter.Dispose();
}
}
public static void ReadM154Data()
{
NcAdapter ncAdapter = new NcAdapter();
+2
View File
@@ -35,7 +35,9 @@ namespace Thermo.Active.Core
ThreadsFunctions.ReadAreaData,
ThreadsFunctions.ReadModulesData,
ThreadsFunctions.ReadScadaData,
ThreadsFunctions.ReadMComandsData,
ThreadsFunctions.ReadM154Data // levare?
};
private static Action ThreadSetupCmsConnect = ThreadsFunctions.SetupCmsConnect;
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Thermo.Active.Model.ConfigModels
{
public class InputOperatorConfigModel
{
public int Id { get; set; }
public Dictionary<string, string> Messages { get; set; }
public Dictionary<byte, Dictionary<string, string>> Buttons { get; set; }
public string Type { get; set; }
}
}
+4
View File
@@ -231,6 +231,9 @@ namespace Thermo.Active.Model
public const string AREAS_CONFIG_SCHEMA_PATH = RESOURCE_DIRECTORY + "areasConfigValidator.xsd";
public const string AREAS_CONFIG_PATH = CONFIG_DIRECTORY + "areasConfig.xml";
public const string M156_CONFIG_SCHEMA_PATH = RESOURCE_DIRECTORY + "inputOperatorConfigValidator.xsd";
public const string M156_CONFIG_PATH = CONFIG_DIRECTORY + "inputOperatorConfig.xml";
public const string MAINTENANCES_CONFIG_SCHEMA_PATH = RESOURCE_DIRECTORY + "maintenancesConfigValidator.xsd";
public const string CUSTOMER_CONTACTS_CONFIG_SCHEMA_PATH = RESOURCE_DIRECTORY + "customerContactConfigValidator.xsd";
public const string MAINTENANCES_CONFIG_PATH = CONFIG_DIRECTORY + "maintenancesConfig.xml";
@@ -308,6 +311,7 @@ namespace Thermo.Active.Model
public const string SEND_ACTIVE_PROGRAM_DATA = "SEND_ACTIVE_PROGRAM_DATA";
public const string SEND_QUEUE_DATA = "SEND_QUEUE_DATA";
public const string SEND_M155_DATA = "SEND_M155_DATA";
public const string SEND_M156_DATA = "SEND_M156_DATA";
public const string SEND_SCADA_DATA = "SEND_SCADA_DATA";
// MVVM Messages for Thermo active specs
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static CMS_CORE_Library.Models.DataStructures;
namespace Thermo.Active.Model.DTOModels
{
public class DTOM156InputModel : M156InputIsNeededModel
{
public Dictionary<byte, string> Buttons;
public string Type;
public bool isM156 = true;
public override bool Equals(object obj)
{
if (!(obj is DTOM156InputModel item))
return false;
if (Process != item.Process)
return false;
if (Type != item.Type)
return false;
return true;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
}
@@ -63,6 +63,7 @@
<Compile Include="ConfigModels\AlarmsConfigModel.cs" />
<Compile Include="ConfigModels\CmsConnectConfigModel.cs" />
<Compile Include="ConfigModels\ExtSoftwareModel.cs" />
<Compile Include="ConfigModels\InputOperatorConfigModel.cs" />
<Compile Include="ConfigModels\ThermoProdConfigModel.cs" />
<Compile Include="ConfigModels\ModBlockConfigModel.cs" />
<Compile Include="ConfigModels\RiskConfigModel.cs" />
@@ -106,6 +107,7 @@
<Compile Include="DTOModels\DTOAxesModel.cs" />
<Compile Include="DTOModels\DTOAxisNameModel.cs" />
<Compile Include="DTOModels\DTOClientConfigurationModel.cs" />
<Compile Include="DTOModels\DTOM156InputModel.cs" />
<Compile Include="DTOModels\ThModules\DTOModulesBlock.cs" />
<Compile Include="DTOModels\ThProd\DTOProdInfo.cs" />
<Compile Include="DTOModels\ThProd\DTOThermoPanelProd.cs" />
+39
View File
@@ -1270,6 +1270,45 @@ namespace Thermo.Active.NC
return numericalControl.PLC_RM154Data(ref data, ref MTCStatus);
}
public CmsError GetM156Data(out List<DTOM156InputModel> data)
{
data = new List<DTOM156InputModel>();
List<M156InputIsNeededModel> ncData = new List<M156InputIsNeededModel>();
CmsError cmsError = numericalControl.PLC_RM156Data(ref ncData);
if (cmsError.IsError())
return cmsError;
if (ncData.Count() > 0)
{
foreach (var m156Message in ncData)
{
var inp = InputsOperatorConfig.Where(x => m156Message.Id == x.Id).FirstOrDefault();
var buttons = inp.Buttons?.ToDictionary(x => x.Key, x => x.Key.ToString());
if (inp != null)
{
data.Add(new DTOM156InputModel()
{
Id = inp.Id,
isM156 = true,
Buttons = buttons,
Type = inp.Type,
Process = m156Message.Process,
Value = m156Message.Value
});
}
}
}
return NO_ERROR;
}
public CmsError WriteM156Data(int process, double responseValue)
{
return numericalControl.PLC_WM156Response(process, responseValue);
}
public CmsError WriteM154Ack(int processId)
{
return numericalControl.PLC_W154ManageAck(processId);
@@ -183,6 +183,19 @@ namespace Thermo.Active.Controllers.SignalR
}
#endif
[SignalRAuthorize(FunctionAccess = GENERAL, Action = ACTIONS.WRITE)]
public void WriteM156Response(int process, double responseVal)
{
using (NcAdapter ncAdapter = new NcAdapter())
{
ncAdapter.Connect();
CmsError cmsError = ncAdapter.WriteM156Data(process, responseVal);
if (cmsError.IsError())
throw new HubException(cmsError.localizationKey);
}
}
[SignalRAuthorize(FunctionAccess = GENERAL, Action = ACTIONS.WRITE)]
public void WriteScadaValue(string memIndex, SCADA_MEM_TYPE memType, object value)
{
@@ -55,10 +55,10 @@ namespace Thermo.Active.Controllers.WebApi
Dictionary<string, string> alarmsNames = GetPlcAlarmsTranslations(language);
Dictionary<string, string> headsNames = GetLocalizedHeadsNames(language);
// scada
Dictionary<string, string> scadaTranslations = GetScadaTranslations(language);
Dictionary<string, string> m156Translations = GetM156Translations(language);
// THermo (modules and recipe enums) translations
// Thermo (modules and recipe enums) translations
Dictionary<string, string> thermoTranslations = GetThermoTranslations(language);
@@ -72,7 +72,9 @@ namespace Thermo.Active.Controllers.WebApi
translations = translations.Concat(headsNames).ToDictionary(x => x.Key, x => x.Value);
// Scada
translations = translations.Concat(scadaTranslations).ToDictionary(x => x.Key, x => x.Value);
// Scada
// M156
translations = translations.Concat(m156Translations).ToDictionary(x => x.Key, x => x.Value);
// Thermo
translations = translations.Concat(thermoTranslations).ToDictionary(x => x.Key, x => x.Value);
if (translations == null)
@@ -210,5 +212,31 @@ namespace Thermo.Active.Controllers.WebApi
return translatedNames;
}
public static Dictionary<string, string> GetM156Translations(string language)
{
Dictionary<string, string> translatedNames = new Dictionary<string, string>();
foreach (var input in InputsOperatorConfig)
{
translatedNames.Add(
"m156_title_" + input.Id,
GetValueFromLocalizationList(input.Messages, language, "Title_" + input.Id)
);
if (input.Buttons != null && input.Buttons.Count() > 0)
foreach (var button in input.Buttons)
{
// Add translated button text to the list
// Buttons have a Dictionary<string, string> with the translations
translatedNames.Add(
"m156_" + input.Id + "_button_" + button.Key,
GetValueFromLocalizationList(button.Value, language, "Button_" + button.Key)
);
}
}
return translatedNames;
}
}
}
@@ -86,6 +86,10 @@ namespace Thermo.Active.Listeners
{
SignalRListener.SetGatewayRebootStatus(a);
}));
infos.Add(MessageServices.Current.Subscribe(SEND_M156_DATA, (a, b) =>
{
SignalRListener.SendM156Data(a);
}));
// add specific modules for THERMO
infos.Add(MessageServices.Current.Subscribe(SEND_THERMO_RECIPE_FULL, (a, b) =>
@@ -239,6 +239,17 @@ namespace Thermo.Active.Listeners.SignalR
}
}
#endif
public static void SendM156Data(object data)
{
List<DTOM156InputModel> dtoM156Data = data as List<DTOM156InputModel>;
if (!LastM156Data.SequenceEqual(dtoM156Data))
{
LastM156Data = dtoM156Data;
var context = GlobalHost.ConnectionManager.GetHubContext<NcHub>();
context.Clients.Group("ncData").m156Data(dtoM156Data);
}
}
public static void SendScadaData(object scada)
{
@@ -455,6 +466,8 @@ namespace Thermo.Active.Listeners.SignalR
}
}
public static void SetGatewayRebootStatus(object status)
{
string msg = status.ToString();
@@ -514,7 +527,9 @@ namespace Thermo.Active.Listeners.SignalR
group.magazineIsActive(LastNcMagazineIsActive);
// Send PP Queue
group.partProgramQueue(LastPartProgramQueue);
// Send m156
group.m156Data(LastM156Data);
// Send Scada
group.scadaData(LastScadaData);
@@ -30,6 +30,7 @@ namespace Thermo.Active.Listeners
#if false
public static List<DTOM155InputModel> LastM155Data = new List<DTOM155InputModel>();
#endif
public static List<DTOM156InputModel> LastM156Data = new List<DTOM156InputModel>();
public static List<DTOScadaModel> LastScadaData = new List<DTOScadaModel>();
// FIXME TODO inserire oggetti corretti per THERMO
+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.13.79")]
[assembly: AssemblyVersion("0.14.80")]