Ajout de données dans fichier XML
FerméTintin2256 Messages postés 25 Date d'inscription mardi 3 octobre 2017 Statut Membre Dernière intervention 18 septembre 2023 - 17 nov. 2022 à 14:44
- Ajout de données dans fichier XML
- Fichier rar - Guide
- Fichier host - Guide
- Fichier iso - Guide
- Comment réduire la taille d'un fichier - Guide
- Xml viewer - Télécharger - Édition & Programmation
21 réponses
13 nov. 2022 à 10:11
Bonjour
Tout d'abord, quelques points généraux
- pour pouvoir t'aider efficacement, il faudrait un jeu de données d'entrée représentatif sans être "confidentiel" et le fichier de sortie que tu voudrais avoir à partir de ça.
- il est fortement déconseillé d'utiliser des signes diacritiques dans les noms de variables, classes, méthodes, espaces de noms etc....
- la construction de strings par des + est archaïque et génératrice de bug, il existe depuis le début de C# (plus de 20 ans donc) 2 autres solutions, le string.Format et la classe stringbuilder, et depuis VS2017 (je crois), une implémentation simplifiée de string.Format avec le caractère clé $ en début de string (comme le @ pour les \)
Ensuite, ton code spécifiquement, je pense que tu te compliques la vie inutilement.
- Tes classes d'entêtes :
- elles sont identiques :
- Au pire une seule suffirait avec si besoin une propriété pour distinguer de quel entête il s'agit
- Si pour une autre raison que ce code, tu as vraiment besoin de classes différentes, alors une classe abstraite dans laquelle le commun est implémenté et des classes dérivées vides ou quasi vides serait une bien meilleure implémentation.
- elles ne font rien d'autre que d'ajouter un saut de ligne à une string
- je pense que ces classes ne sont pas utiles
- elles sont identiques :
- Tes classes d'entrées et sorties :
- ne remplissent pas les propriétés communes dans le constructeur
- sont quasiment identiques :
- même signature du constructeur
- 3 propriétés communes
- une propriété spécifique qui est construite selon la classe
- c'est exactement le type de cas où une classe abstraite et des classes dérivées doit être utilisé
- tu nommes la propriété spécifique avec un nom générique (Texte par exemple) et tu n'implémentes que ce code dans les classes dérivées, ou encore, puisque qu'il s'agit de strings, tu overrides ToString()
Avantages
- moins de code à écrire et à maintenir
- utilisation du polymorphisme, par exemple, une liste de la classe abstraite peut contenir des instances des classes dérivées.
- ça devrait être moins le fouillis dans le code de génération du xml
Exemple avec la proprétié Texte à implémenter dans les classes dérivées (pas de diacritique et string.Format via $ )
public abstract class EntreesSortie { public EntreesSortie(string Mnemonique, string Adresse, int Index) { this.Mnemonique = Mnemonique; this.Adresse= Adresse; this.Index= Index; } public abstract string Texte { get; } public string Mnemonique { get; set; } public string Adresse { get; set; } public int Index { get; set; } } public class EANA_API : EntreesSortie { public EANA_API(string Mnemonique, string Adresse, int Index) : base(Mnemonique, Adresse, Index) { } public override string Texte { get { return $"IF AOM_AO[{Index}] = 0 THEN {Mnemonique} := {Adresse}; ELSE {Mnemonique} := A_MODIFIER[{Index}]; END_IF;\n"; } } }
Exemple avec utilisation de ToString dans les classes dérivées
public abstract class EntreesSortie2 { public EntreesSortie2(string Mnemonique, string Adresse, int Index) { this.Mnemonique = Mnemonique; this.Adresse = Adresse; this.Index = Index; } public string Mnemonique { get; set; } public string Adresse { get; set; } public int Index { get; set; } } public class EANA_API2 : EntreesSortie2 { public EANA_API2(string Mnemonique, string Adresse, int Index) : base(Mnemonique, Adresse, Index) { } public override string ToString() { return $"IF AOM_AO[{Index}] = 0 THEN {Mnemonique} := {Adresse}; ELSE {Mnemonique} := A_MODIFIER[{Index}]; END_IF;\n"; } }
14 nov. 2022 à 09:50
Salut Whismeril,
Merci pour ton retour. Je me suis servi de bout de code que tu m'avais donné il y a 5ans et j'ai tout mixé pour arriver à ce que je voulais. N'étant pas informaticien, j'avoue que mon code est plutôt brouillon...
Pour la source, c'est un fichier Excel dont j'extrais les données qui m'intéresse avec OLEDB.
OleDbConnection MyConnection = default(OleDbConnection); DataSet dataSetES = default(DataSet); OleDbDataAdapter MyCommand = default(OleDbDataAdapter); MyConnection = new OleDbConnection("Provider = Microsoft.ACE.OLEDB.12.0; Data Source = " + NomFichierSource.Text + "; Extended Properties = 'Excel 12.0 XML;HDR=YES;'; "); MyCommand = new OleDbDataAdapter("select * from [Liste_ES$]", MyConnection); MyConnection.Open(); dataSetES = new DataSet(); MyCommand.Fill(dataSetES); //Calcul du nombre de lignes et de colonnes pour dimensionner le tableau qui accueillera les données int nb_col = dataSetES.Tables[0].Columns.Count; nb_lignesES = dataSetES.Tables[0].Rows.Count; //Création du tableau qui accueillera les données du fichier excel string[,] Tableau_SourceES = new string[nb_lignesES + 1, nb_col + 1]; int x = 0; int y = 0; for (x = 0; x <= nb_lignesES - 1; x++) { for (y = 0; y <= nb_col - 1; y++) { Tableau_SourceES[x, y] = dataSetES.Tables[0].Rows[x].ItemArray[y].ToString(); } } MyConnection.Close(); int NB_EANA = 0; int NB_ETOR = 0; int NB_STOR = 0; int NB_SANA = 0; //Calcul du nombre d'entrées ANA, entrées TOR, sorties TOR, sorties ANA dans le tableau for (x = 0; x <= nb_lignesES - 1; x++) { if (Tableau_SourceES[x, 1].Contains("AI_")) { NB_EANA = NB_EANA + 1; } if (Tableau_SourceES[x, 1].Contains("DI.C")) { NB_ETOR = NB_ETOR + 1; } if (Tableau_SourceES[x, 1].Contains("DO.C")) { NB_STOR = NB_STOR + 1; } if (Tableau_SourceES[x, 1].Contains("AO_")) { NB_SANA = NB_SANA + 1; } } //Déclaration des tableaux d'entrées/sorties string[,] Tab_EANA = new string[NB_EANA, 3]; string[,] Tab_ETOR = new string[NB_ETOR, 3]; string[,] Tab_STOR = new string[NB_STOR, 3]; string[,] Tab_SANA = new string[NB_SANA, 3]; //Remplissage des tableaux d'entrées/sorties int Index_EANA =0; int Index_ETOR =0; int Index_STOR = 0; int Index_SANA = 0; for (x = 0; x <= nb_lignesES - 1; x++) { if (Tableau_SourceES[x, 1].Contains("AI_")) { Tab_EANA[Index_EANA, 0] = Tableau_SourceES[x, 1]; // Récupération de l'adresse de l'entrée Tab_EANA[Index_EANA, 1] = Tableau_SourceES[x, 9]; // Récupération du Mnémonique Tab_EANA[Index_EANA, 2] = Tableau_SourceES[x, 5] + " " + Tableau_SourceES[x, 7]; // Récupération du commentaire Index_EANA = Index_EANA + 1; } if (Tableau_SourceES[x, 1].Contains("DI.C")) { Tab_ETOR[Index_ETOR, 0] = Tableau_SourceES[x, 1]; // Récupération de l'adresse de l'entrée Tab_ETOR[Index_ETOR, 1] = Tableau_SourceES[x, 9]; // Récupération du Mnémonique Tab_ETOR[Index_ETOR, 2] = Tableau_SourceES[x, 5] + " " + Tableau_SourceES[x, 7]; // Récupération du commentaire Index_ETOR = Index_ETOR + 1; } if (Tableau_SourceES[x, 1].Contains("DO.C")) { Tab_STOR[Index_STOR, 0] = Tableau_SourceES[x, 1]; // Récupération de l'adresse de l'entrée Tab_STOR[Index_STOR, 1] = Tableau_SourceES[x, 9]; // Récupération du Mnémonique Tab_STOR[Index_STOR, 2] = Tableau_SourceES[x, 5] + " " + Tableau_SourceES[x, 7]; // Récupération du commentaire Index_STOR = Index_STOR + 1; } if (Tableau_SourceES[x, 1].Contains("AO_")) { Tab_SANA[Index_SANA, 0] = Tableau_SourceES[x, 1]; // Récupération de l'adresse de l'entrée Tab_SANA[Index_SANA, 1] = Tableau_SourceES[x, 9]; // Récupération du Mnémonique Tab_SANA[Index_SANA, 2] = Tableau_SourceES[x, 5] + " " + Tableau_SourceES[x, 7]; // Récupération du commentaire Index_SANA = Index_SANA + 1; } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////// //////////////////////////////////// //////////////////////////////////// Génération section de recopie E/S //////////////////////////////////// //////////////////////////////////// //////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if (RecopieE_S.Checked == true) { // Création du fichier de sortie //Déclaration des différentes variables List<EnteteEANA> EnteteEAna = new List<EnteteEANA>(); List<EANA_API> Liste_EANA_API = new List<EANA_API>(); List<EnteteETOR> Entete_ETOR = new List<EnteteETOR>(); List<ETOR_API> Liste_ETOR_API = new List<ETOR_API>(); List<EnteteSTOR> Entete_STOR = new List<EnteteSTOR>(); List<STOR_API> Liste_STOR_API = new List<STOR_API>(); List<EnteteSANA> Entete_SANA = new List<EnteteSANA>(); List<SANA_API> Liste_SANA_API = new List<SANA_API>(); //Création des différentes entête de chaque partie EnteteEAna.Add(new EnteteEANA("(*Copies des entrees Analogiques *)")); Entete_SANA.Add(new EnteteSANA(" ")); Entete_SANA.Add(new EnteteSANA("(*Copies des sorties Analogiques *)")); Entete_ETOR.Add(new EnteteETOR(" ")); Entete_ETOR.Add(new EnteteETOR("(*Copies des entrees TOR *)")); Entete_STOR.Add(new EnteteSTOR(" ")); Entete_STOR.Add(new EnteteSTOR("(*Copies des sorties TOR *)")); int Index; //Ajout des différentes entrées ANA for (Index = 0; Index <= NB_EANA - 1; Index++) { Liste_EANA_API.Add(new EANA_API(Tab_EANA[Index, 1],Tab_EANA[Index, 0], Index)); } //Ajout des différentes entrées TOR for (Index = 0; Index <= NB_ETOR - 1; Index++) { Liste_ETOR_API.Add(new ETOR_API(Tab_ETOR[Index, 1], Tab_ETOR[Index, 0], Index)); } //Ajout des différentes sorties TOR for (Index = 0; Index <= NB_STOR - 1; Index++) { Liste_STOR_API.Add(new STOR_API(Tab_STOR[Index, 1], Tab_STOR[Index, 0], Index)); } //Ajout des différentes sorties ANA for (Index = 0; Index <= NB_SANA - 1; Index++) { Liste_SANA_API.Add(new SANA_API(Tab_SANA[Index, 1], Tab_SANA[Index, 0], Index)); } //Création du fichier XML source XDocument XmlDoc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"), new XElement("STExchangeFile", new XElement("fileHeader", new XAttribute("company", "Schneider Automation"), new XAttribute("product", "Control Expert V14.1 - 191122A"), new XAttribute("dateTime", "date_and_time#2018-3-12-16:50:53"), new XAttribute("content", "Fichier source ST"), new XAttribute("DTDVersion", "41")), new XElement("contentHeader", new XAttribute("name", "Projet"), new XAttribute("version", "0.0.710"), new XAttribute("dateTime", "date_and_time#2018-2-14-14:39:27")), new XElement("program", new XElement("identProgram", new XAttribute("name", "Copie_E_S"), new XAttribute("type", "section"), new XAttribute("task", "MAST")), new XElement("STSource", from p in EnteteEAna select new XText(p.texte), from p in Liste_EANA_API select new XText(p.EANA), from p in Entete_ETOR select new XText(p.texte), from p in Liste_ETOR_API select new XText(p.ETOR), from p in Entete_STOR select new XText(p.texte), from p in Liste_STOR_API select new XText(p.STOR), from p in Entete_SANA select new XText(p.texte), from p in Liste_SANA_API select new XText(p.SANA))), new XElement("dataBlock",new XElement("variables", new XAttribute("version", "0.0.710"))))); //Test si le fichier existe déjà if (File.Exists(NomDossierDest.Text + @"\Sections_ST.xst")) { MessageBox.Show("Un fichier section existe déjà dans le dossier de destination. Annulation de l'opération"); } else { //Récupération du nom de la zone pour définir le nom du fichier XmlDoc.Save(NomDossierDest.Text + @"\Sections_ST.xst"); } } public class EnteteEANA { public EnteteEANA() { } public EnteteEANA(String texte) { this.texte = texte + "\n"; } public string texte { get; set; } } public class EANA_API { public EANA_API() { } public EANA_API(string Mnémonique, string Adresse, int Index) { this.EANA = "IF AOM_AO[" + Index + "] = 0 THEN " + Mnémonique + " := " + Adresse + "; ELSE " + Mnémonique + " := A_MODIFIER[" + Index + "]; END_IF;" + "\n"; } public string EANA { get; set; } public string Mnémonique { get; set; } public string Adresse { get; set; } public int Index { get; set; } } public class EnteteETOR { public EnteteETOR() { } public EnteteETOR(String texte) { this.texte = texte + "\n"; } public string texte { get; set; } } public class ETOR_API { public ETOR_API() { } public ETOR_API(string Mnémonique, string Adresse, int Index) { this.ETOR = Mnémonique + " := (" + Adresse + " AND AOM_I[" + Index + "] = 0) OR AOM_I[" + Index + "] = 1;" + "\n"; } public string ETOR { get; set; } public string Mnémonique { get; set; } public string Adresse { get; set; } public int Index { get; set; } } public class EnteteSTOR { public EnteteSTOR() { } public EnteteSTOR(String texte) { this.texte = texte + "\n"; } public string texte { get; set; } } public class STOR_API { public STOR_API() { } public STOR_API(string Mnémonique, string Adresse, int Index) { this.STOR = Adresse + " := (" + Mnémonique + " AND AOM_O[" + Index + "] = 0) OR AOM_O[" + Index + "] = 1;" + "\n"; } public string STOR { get; set; } public string Mnémonique { get; set; } public string Adresse { get; set; } public int Index { get; set; } } public class EnteteSANA { public EnteteSANA() { } public EnteteSANA(String texte) { this.texte = texte + "\n"; } public string texte { get; set; } } public class SANA_API { public SANA_API() { } public SANA_API(string Mnémonique, string Adresse, int Index) { this.SANA = "IF AOM_AO[" + Index + "] = 0 THEN " + Adresse + " := " + Mnémonique + "; ELSE " + Adresse + " := A_MODIFIER[" + Index + "]; END_IF;" + "\n"; } public string SANA { get; set; } public string Mnémonique { get; set; } public string Adresse { get; set; } public int Index { get; set; } }
Mon fichier de sortie ressemble à ça:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <STExchangeFile> <fileHeader company="Schneider Automation" product="Control Expert V14.1 - 191122A" dateTime="date_and_time#2022-11-12-8:51:59" content="Fichier source ST" DTDVersion="41"></fileHeader> <contentHeader name="Projet" version="0.0.533" dateTime="date_and_time#2022-7-1-15:22:18"></contentHeader> <program> <identProgram name="Copie_E_S" type="section" task="MAST"></identProgram> <STSource>(*Copies des entrees ANA depuis le Wago *) EA_LT_Forage1 := Ilo_Wago_IN_AI_C1_V1 ; EA_LT_Forage2 := Ilo_Wago_IN_AI_C1_V2 ; EA_LT_Forage3 := Ilo_Wago_IN_AI_C1_V3 ; EA_FT_Lavage := Ilo_Wago_IN_AI_C1_V4 ; EA_LT_Stockage := Ilo_Wago_IN_AI_C1_V5 ; EA_AI_Chlore := Ilo_Wago_IN_AI_C1_V6 ; EA_AI_pH := Ilo_Wago_IN_AI_C1_V7 ; EA_PT_PmpRprise1 := Ilo_Wago_IN_AI_C1_V8 ; EA_PT_PmpRprise2 := Ilo_Wago_IN_AI_C2_V1 ; EA_FT_EauTraitee := Ilo_Wago_IN_AI_C2_V2 ; EA_AI2_V3 := Ilo_Wago_IN_AI_C2_V3 ; EA_AI2_V4 := Ilo_Wago_IN_AI_C2_V4 ; EA_AI2_V5 := Ilo_Wago_IN_AI_C2_V5 ; EA_AI2_V6 := Ilo_Wago_IN_AI_C2_V6 ; EA_AI2_V7 := Ilo_Wago_IN_AI_C2_V7 ; EA_AI2_V8 := Ilo_Wago_IN_AI_C2_V8 ; (*Copies des entrees TOR depuis le Wago*) CPE_BP_Klaxon :=(Ilo_Wago_IN_DI_C1.0 AND AOM_I[0]= 0) OR AOM_I[0]=1; CPE_CM3_AirOK :=(Ilo_Wago_IN_DI_C1.1 AND AOM_I[1]= 0) OR AOM_I[1]=1; CPE_RM_Forg1 :=(Ilo_Wago_IN_DI_C1.2 AND AOM_I[2]= 0) OR AOM_I[2]=1; CPE_DEF_Forg1 :=(Ilo_Wago_IN_DI_C1.3 AND AOM_I[3]= 0) OR AOM_I[3]=1; CPE_RM_Forg2 :=(Ilo_Wago_IN_DI_C1.4 AND AOM_I[4]= 0) OR AOM_I[4]=1; CPE_DEF_Forg2 :=(Ilo_Wago_IN_DI_C1.5 AND AOM_I[5]= 0) OR AOM_I[5]=1; CPE_RM_Forg3 :=(Ilo_Wago_IN_DI_C1.6 AND AOM_I[6]= 0) OR AOM_I[6]=1; CPE_DEF_Forg3 :=(Ilo_Wago_IN_DI_C1.7 AND AOM_I[7]= 0) OR AOM_I[7]=1; CPE_RM_PmpPurg :=(Ilo_Wago_IN_DI_C1.8 AND AOM_I[8]= 0) OR AOM_I[8]=1; CPE_DEF_PmpPurg :=(Ilo_Wago_IN_DI_C1.9 AND AOM_I[9]= 0) OR AOM_I[9]=1; CPE_LSH_EauPurg :=(Ilo_Wago_IN_DI_C1.10 AND AOM_I[10]= 0) OR AOM_I[10]=1; CPE_CPT_EauBrute :=(Ilo_Wago_IN_DI_C1.11 AND AOM_I[11]= 0) OR AOM_I[11]=1; CPE_CM1_EauBrute :=(Ilo_Wago_IN_DI_C1.12 AND AOM_I[12]= 0) OR AOM_I[12]=1; CPE_RM_SouflAir :=(Ilo_Wago_IN_DI_C1.13 AND AOM_I[13]= 0) OR AOM_I[13]=1; CPE_DEF_SouflAir :=(Ilo_Wago_IN_DI_C1.14 AND AOM_I[14]= 0) OR AOM_I[14]=1; CPE_RM_PmpLavg :=(Ilo_Wago_IN_DI_C1.15 AND AOM_I[15]= 0) OR AOM_I[15]=1; CPE_DEF_PmpLavg :=(Ilo_Wago_IN_DI_C2.0 AND AOM_I[16]= 0) OR AOM_I[16]=1; CPE_CM2_EauLavg :=(Ilo_Wago_IN_DI_C2.1 AND AOM_I[17]= 0) OR AOM_I[17]=1; CPE_D2_EauLavg :=(Ilo_Wago_IN_DI_C2.2 AND AOM_I[18]= 0) OR AOM_I[18]=1; CPE_PosOuvP00 :=(Ilo_Wago_IN_DI_C2.3 AND AOM_I[19]= 0) OR AOM_I[19]=1; CPE_PosFermP00 :=(Ilo_Wago_IN_DI_C2.4 AND AOM_I[20]= 0) OR AOM_I[20]=1; CPE_PosOuvP01 :=(Ilo_Wago_IN_DI_C2.5 AND AOM_I[21]= 0) OR AOM_I[21]=1; CPE_PosFermP01 :=(Ilo_Wago_IN_DI_C2.6 AND AOM_I[22]= 0) OR AOM_I[22]=1; CPE_PosOuvP02 :=(Ilo_Wago_IN_DI_C2.7 AND AOM_I[23]= 0) OR AOM_I[23]=1; CPE_PosFermP02 :=(Ilo_Wago_IN_DI_C2.8 AND AOM_I[24]= 0) OR AOM_I[24]=1; CPE_PosOuvEV0 :=(Ilo_Wago_IN_DI_C2.9 AND AOM_I[25]= 0) OR AOM_I[25]=1; CPE_PosFermEV0 :=(Ilo_Wago_IN_DI_C2.10 AND AOM_I[26]= 0) OR AOM_I[26]=1; CPE_PosOuvP10 :=(Ilo_Wago_IN_DI_C2.11 AND AOM_I[27]= 0) OR AOM_I[27]=1; CPE_PosFermP10 :=(Ilo_Wago_IN_DI_C2.12 AND AOM_I[28]= 0) OR AOM_I[28]=1; CPE_PosOuvP11 :=(Ilo_Wago_IN_DI_C2.13 AND AOM_I[29]= 0) OR AOM_I[29]=1; CPE_PosFermP11 :=(Ilo_Wago_IN_DI_C2.14 AND AOM_I[30]= 0) OR AOM_I[30]=1; CPE_PosOuvP12 :=(Ilo_Wago_IN_DI_C2.15 AND AOM_I[31]= 0) OR AOM_I[31]=1; CPE_PosFermP12 :=(Ilo_Wago_IN_DI_C3.0 AND AOM_I[32]= 0) OR AOM_I[32]=1; CPE_PosOuvP13 :=(Ilo_Wago_IN_DI_C3.1 AND AOM_I[33]= 0) OR AOM_I[33]=1; CPE_PosFermP13 :=(Ilo_Wago_IN_DI_C3.2 AND AOM_I[34]= 0) OR AOM_I[34]=1; CPE_PosOuvEV1 :=(Ilo_Wago_IN_DI_C3.3 AND AOM_I[35]= 0) OR AOM_I[35]=1; CPE_PosFermEV1 :=(Ilo_Wago_IN_DI_C3.4 AND AOM_I[36]= 0) OR AOM_I[36]=1; CPE_PosOuvP20 :=(Ilo_Wago_IN_DI_C3.5 AND AOM_I[37]= 0) OR AOM_I[37]=1; CPE_PosFermP20 :=(Ilo_Wago_IN_DI_C3.6 AND AOM_I[38]= 0) OR AOM_I[38]=1; CPE_PosOuvP21 :=(Ilo_Wago_IN_DI_C3.7 AND AOM_I[39]= 0) OR AOM_I[39]=1; CPE_PosFermP21 :=(Ilo_Wago_IN_DI_C3.8 AND AOM_I[40]= 0) OR AOM_I[40]=1; CPE_PosOuvP22 :=(Ilo_Wago_IN_DI_C3.9 AND AOM_I[41]= 0) OR AOM_I[41]=1; CPE_PosFermP22 :=(Ilo_Wago_IN_DI_C3.10 AND AOM_I[42]= 0) OR AOM_I[42]=1; CPE_PosOuvP23 :=(Ilo_Wago_IN_DI_C3.11 AND AOM_I[43]= 0) OR AOM_I[43]=1; CPE_PosFermP23 :=(Ilo_Wago_IN_DI_C3.12 AND AOM_I[44]= 0) OR AOM_I[44]=1; CPE_PosOuvEV2 :=(Ilo_Wago_IN_DI_C3.13 AND AOM_I[45]= 0) OR AOM_I[45]=1; CPE_PosFermEV2 :=(Ilo_Wago_IN_DI_C3.14 AND AOM_I[46]= 0) OR AOM_I[46]=1; CPE_PosOuvP30 :=(Ilo_Wago_IN_DI_C3.15 AND AOM_I[47]= 0) OR AOM_I[47]=1; CPE_PosFermP30 :=(Ilo_Wago_IN_DI_C4.0 AND AOM_I[48]= 0) OR AOM_I[48]=1; CPE_PosOuvP31 :=(Ilo_Wago_IN_DI_C4.1 AND AOM_I[49]= 0) OR AOM_I[49]=1; CPE_PosFermP31 :=(Ilo_Wago_IN_DI_C4.2 AND AOM_I[50]= 0) OR AOM_I[50]=1; CPE_PosOuvP32 :=(Ilo_Wago_IN_DI_C4.3 AND AOM_I[51]= 0) OR AOM_I[51]=1; CPE_PosFermP32 :=(Ilo_Wago_IN_DI_C4.4 AND AOM_I[52]= 0) OR AOM_I[52]=1; CPE_PosOuvP33 :=(Ilo_Wago_IN_DI_C4.5 AND AOM_I[53]= 0) OR AOM_I[53]=1; CPE_PosFermP33 :=(Ilo_Wago_IN_DI_C4.6 AND AOM_I[54]= 0) OR AOM_I[54]=1; CPE_PosOuvEV3 :=(Ilo_Wago_IN_DI_C4.7 AND AOM_I[55]= 0) OR AOM_I[55]=1; CPE_PosFermEV3 :=(Ilo_Wago_IN_DI_C4.8 AND AOM_I[56]= 0) OR AOM_I[56]=1; CPE_PosOuvP40 :=(Ilo_Wago_IN_DI_C4.9 AND AOM_I[57]= 0) OR AOM_I[57]=1; CPE_PosFermP40 :=(Ilo_Wago_IN_DI_C4.10 AND AOM_I[58]= 0) OR AOM_I[58]=1; CPE_PosOuvP41 :=(Ilo_Wago_IN_DI_C4.11 AND AOM_I[59]= 0) OR AOM_I[59]=1; CPE_PosFermP41 :=(Ilo_Wago_IN_DI_C4.12 AND AOM_I[60]= 0) OR AOM_I[60]=1; CPE_PosOuvP42 :=(Ilo_Wago_IN_DI_C4.13 AND AOM_I[61]= 0) OR AOM_I[61]=1; CPE_PosFermP42 :=(Ilo_Wago_IN_DI_C4.14 AND AOM_I[62]= 0) OR AOM_I[62]=1; CPE_PosOuvP43 :=(Ilo_Wago_IN_DI_C4.15 AND AOM_I[63]= 0) OR AOM_I[63]=1; CPE_PosFermP43 :=(Ilo_Wago_IN_DI_C5.0 AND AOM_I[64]= 0) OR AOM_I[64]=1; CPE_PosOuvEV4 :=(Ilo_Wago_IN_DI_C5.1 AND AOM_I[65]= 0) OR AOM_I[65]=1; CPE_PosFermEV4 :=(Ilo_Wago_IN_DI_C5.2 AND AOM_I[66]= 0) OR AOM_I[66]=1; CPE_PosOuvP50 :=(Ilo_Wago_IN_DI_C5.3 AND AOM_I[67]= 0) OR AOM_I[67]=1; CPE_PosFermP50 :=(Ilo_Wago_IN_DI_C5.4 AND AOM_I[68]= 0) OR AOM_I[68]=1; CPE_PosOuvP51 :=(Ilo_Wago_IN_DI_C5.5 AND AOM_I[69]= 0) OR AOM_I[69]=1; CPE_PosFermP51 :=(Ilo_Wago_IN_DI_C5.6 AND AOM_I[70]= 0) OR AOM_I[70]=1; CPE_PosOuvP52 :=(Ilo_Wago_IN_DI_C5.7 AND AOM_I[71]= 0) OR AOM_I[71]=1; CPE_PosFermP52 :=(Ilo_Wago_IN_DI_C5.8 AND AOM_I[72]= 0) OR AOM_I[72]=1; CPE_PosOuvP53 :=(Ilo_Wago_IN_DI_C5.9 AND AOM_I[73]= 0) OR AOM_I[73]=1; CPE_PosFermP53 :=(Ilo_Wago_IN_DI_C5.10 AND AOM_I[74]= 0) OR AOM_I[74]=1; CPE_PosOuvEV5 :=(Ilo_Wago_IN_DI_C5.11 AND AOM_I[75]= 0) OR AOM_I[75]=1; CPE_PosFermEV5 :=(Ilo_Wago_IN_DI_C5.12 AND AOM_I[76]= 0) OR AOM_I[76]=1; CPE_PosOuvP1 :=(Ilo_Wago_IN_DI_C5.13 AND AOM_I[77]= 0) OR AOM_I[77]=1; CPE_PosFermP1 :=(Ilo_Wago_IN_DI_C5.14 AND AOM_I[78]= 0) OR AOM_I[78]=1; CPE_PosOuvP2 :=(Ilo_Wago_IN_DI_C5.15 AND AOM_I[79]= 0) OR AOM_I[79]=1; CPE_PosFermP2 :=(Ilo_Wago_IN_DI_C6.0 AND AOM_I[80]= 0) OR AOM_I[80]=1; CPE_PulsAnalyseur :=(Ilo_Wago_IN_DI_C6.1 AND AOM_I[81]= 0) OR AOM_I[81]=1; CPE_DefAnalyseur :=(Ilo_Wago_IN_DI_C6.2 AND AOM_I[82]= 0) OR AOM_I[82]=1; CPE_RM_PmpReprs1 :=(Ilo_Wago_IN_DI_C6.3 AND AOM_I[83]= 0) OR AOM_I[83]=1; CPE_DEF_PmpReprs1 :=(Ilo_Wago_IN_DI_C6.4 AND AOM_I[84]= 0) OR AOM_I[84]=1; CPE_RM_PmpReprs2 :=(Ilo_Wago_IN_DI_C6.5 AND AOM_I[85]= 0) OR AOM_I[85]=1; CPE_DEF_PmpReprs2 :=(Ilo_Wago_IN_DI_C6.6 AND AOM_I[86]= 0) OR AOM_I[86]=1; CPE_D1_EauTrait :=(Ilo_Wago_IN_DI_C6.7 AND AOM_I[87]= 0) OR AOM_I[87]=1; CPE_RM_PmpChlor :=(Ilo_Wago_IN_DI_C6.8 AND AOM_I[88]= 0) OR AOM_I[88]=1; CPE_DEF_PmpChlor :=(Ilo_Wago_IN_DI_C6.9 AND AOM_I[89]= 0) OR AOM_I[89]=1; DI_C6.10 :=(Ilo_Wago_IN_DI_C6.10 AND AOM_I[90]= 0) OR AOM_I[90]=1; DI_C6.11 :=(Ilo_Wago_IN_DI_C6.11 AND AOM_I[91]= 0) OR AOM_I[91]=1; DI_C6.12 :=(Ilo_Wago_IN_DI_C6.12 AND AOM_I[92]= 0) OR AOM_I[92]=1; DI_C6.13 :=(Ilo_Wago_IN_DI_C6.13 AND AOM_I[93]= 0) OR AOM_I[93]=1; DI_C6.14 :=(Ilo_Wago_IN_DI_C6.14 AND AOM_I[94]= 0) OR AOM_I[94]=1; DI_C6.15 :=(Ilo_Wago_IN_DI_C6.15 AND AOM_I[95]= 0) OR AOM_I[95]=1; DI_C7.0 :=(Ilo_Wago_IN_DI_C7.0 AND AOM_I[96]= 0) OR AOM_I[96]=1; DI_C7.1 :=(Ilo_Wago_IN_DI_C7.1 AND AOM_I[97]= 0) OR AOM_I[97]=1; DI_C7.2 :=(Ilo_Wago_IN_DI_C7.2 AND AOM_I[98]= 0) OR AOM_I[98]=1; DI_C7.3 :=(Ilo_Wago_IN_DI_C7.3 AND AOM_I[99]= 0) OR AOM_I[99]=1; DI_C7.4 :=(Ilo_Wago_IN_DI_C7.4 AND AOM_I[100]= 0) OR AOM_I[100]=1; DI_C7.5 :=(Ilo_Wago_IN_DI_C7.5 AND AOM_I[101]= 0) OR AOM_I[101]=1; DI_C7.6 :=(Ilo_Wago_IN_DI_C7.6 AND AOM_I[102]= 0) OR AOM_I[102]=1; DI_C7.7 :=(Ilo_Wago_IN_DI_C7.7 AND AOM_I[103]= 0) OR AOM_I[103]=1; DI_C7.8 :=(Ilo_Wago_IN_DI_C7.8 AND AOM_I[104]= 0) OR AOM_I[104]=1; DI_C7.9 :=(Ilo_Wago_IN_DI_C7.9 AND AOM_I[105]= 0) OR AOM_I[105]=1; DI_C7.10 :=(Ilo_Wago_IN_DI_C7.10 AND AOM_I[106]= 0) OR AOM_I[106]=1; DI_C7.11 :=(Ilo_Wago_IN_DI_C7.11 AND AOM_I[107]= 0) OR AOM_I[107]=1; DI_C7.12 :=(Ilo_Wago_IN_DI_C7.12 AND AOM_I[108]= 0) OR AOM_I[108]=1; DI_C7.13 :=(Ilo_Wago_IN_DI_C7.13 AND AOM_I[109]= 0) OR AOM_I[109]=1; DI_C7.14 :=(Ilo_Wago_IN_DI_C7.14 AND AOM_I[110]= 0) OR AOM_I[110]=1; DI_C7.15 :=(Ilo_Wago_IN_DI_C7.15 AND AOM_I[111]= 0) OR AOM_I[111]=1; (*Copies des sorties TOR dans le Wago*) Ilo_Wago_OUT_DO_C1.0 :=(CPS_Alarme AND AOM_O[0]= 0) OR AOM_O[0]=1; Ilo_Wago_OUT_DO_C1.1 :=(CPS_Klaxon AND AOM_O[1]= 0) OR AOM_O[1]=1; Ilo_Wago_OUT_DO_C1.2 :=(CPS_Gyrophare AND AOM_O[2]= 0) OR AOM_O[2]=1; Ilo_Wago_OUT_DO_C1.3 :=(CPS_Cmd_Forg1 AND AOM_O[3]= 0) OR AOM_O[3]=1; Ilo_Wago_OUT_DO_C1.4 :=(CPS_Autors_Forg1 AND AOM_O[4]= 0) OR AOM_O[4]=1; Ilo_Wago_OUT_DO_C1.5 :=(CPS_Cmd_Forg2 AND AOM_O[5]= 0) OR AOM_O[5]=1; Ilo_Wago_OUT_DO_C1.6 :=(CPS_Autors_Forg2 AND AOM_O[6]= 0) OR AOM_O[6]=1; Ilo_Wago_OUT_DO_C1.7 :=(CPS_Cmd_Forg3 AND AOM_O[7]= 0) OR AOM_O[7]=1; Ilo_Wago_OUT_DO_C1.8 :=(CPS_Autors_Forg3 AND AOM_O[8]= 0) OR AOM_O[8]=1; Ilo_Wago_OUT_DO_C1.9 :=(CPS_Cmd_PmpPurg AND AOM_O[9]= 0) OR AOM_O[9]=1; Ilo_Wago_OUT_DO_C1.10 :=(CPS_Cmd_EV10 AND AOM_O[10]= 0) OR AOM_O[10]=1; Ilo_Wago_OUT_DO_C1.11 :=(CPS_Cmd_SouflAir AND AOM_O[11]= 0) OR AOM_O[11]=1; Ilo_Wago_OUT_DO_C1.12 :=(CPS_Cmd_PmpLavg AND AOM_O[12]= 0) OR AOM_O[12]=1; Ilo_Wago_OUT_DO_C1.13 :=(CPS_Cmd_P00 AND AOM_O[13]= 0) OR AOM_O[13]=1; Ilo_Wago_OUT_DO_C1.14 :=(CPS_Cmd_P01 AND AOM_O[14]= 0) OR AOM_O[14]=1; Ilo_Wago_OUT_DO_C1.15 :=(CPS_Cmd_P02 AND AOM_O[15]= 0) OR AOM_O[15]=1; Ilo_Wago_OUT_DO_C2.0 :=(CPS_Cmd_EV0 AND AOM_O[16]= 0) OR AOM_O[16]=1; Ilo_Wago_OUT_DO_C2.1 :=(CPS_Cmd_P10 AND AOM_O[17]= 0) OR AOM_O[17]=1; Ilo_Wago_OUT_DO_C2.2 :=(CPS_Cmd_P11 AND AOM_O[18]= 0) OR AOM_O[18]=1; Ilo_Wago_OUT_DO_C2.3 :=(CPS_Cmd_P12 AND AOM_O[19]= 0) OR AOM_O[19]=1; Ilo_Wago_OUT_DO_C2.4 :=(CPS_Cmd_P13 AND AOM_O[20]= 0) OR AOM_O[20]=1; Ilo_Wago_OUT_DO_C2.5 :=(CPS_Cmd_EV1 AND AOM_O[21]= 0) OR AOM_O[21]=1; Ilo_Wago_OUT_DO_C2.6 :=(CPS_Cmd_P20 AND AOM_O[22]= 0) OR AOM_O[22]=1; Ilo_Wago_OUT_DO_C2.7 :=(CPS_Cmd_P21 AND AOM_O[23]= 0) OR AOM_O[23]=1; Ilo_Wago_OUT_DO_C2.8 :=(CPS_Cmd_P22 AND AOM_O[24]= 0) OR AOM_O[24]=1; Ilo_Wago_OUT_DO_C2.9 :=(CPS_Cmd_P23 AND AOM_O[25]= 0) OR AOM_O[25]=1; Ilo_Wago_OUT_DO_C2.10 :=(CPS_Cmd_EV2 AND AOM_O[26]= 0) OR AOM_O[26]=1; Ilo_Wago_OUT_DO_C2.11 :=(CPS_Cmd_EV11 AND AOM_O[27]= 0) OR AOM_O[27]=1; Ilo_Wago_OUT_DO_C2.12 :=(CPS_Cmd_P30 AND AOM_O[28]= 0) OR AOM_O[28]=1; Ilo_Wago_OUT_DO_C2.13 :=(CPS_Cmd_P31 AND AOM_O[29]= 0) OR AOM_O[29]=1; Ilo_Wago_OUT_DO_C2.14 :=(CPS_Cmd_P32 AND AOM_O[30]= 0) OR AOM_O[30]=1; Ilo_Wago_OUT_DO_C2.15 :=(CPS_Cmd_P33 AND AOM_O[31]= 0) OR AOM_O[31]=1; Ilo_Wago_OUT_DO_C3.0 :=(CPS_Cmd_EV3 AND AOM_O[32]= 0) OR AOM_O[32]=1; Ilo_Wago_OUT_DO_C3.1 :=(CPS_Cmd_P40 AND AOM_O[33]= 0) OR AOM_O[33]=1; Ilo_Wago_OUT_DO_C3.2 :=(CPS_Cmd_P41 AND AOM_O[34]= 0) OR AOM_O[34]=1; Ilo_Wago_OUT_DO_C3.3 :=(CPS_Cmd_P42 AND AOM_O[35]= 0) OR AOM_O[35]=1; Ilo_Wago_OUT_DO_C3.4 :=(CPS_Cmd_P43 AND AOM_O[36]= 0) OR AOM_O[36]=1; Ilo_Wago_OUT_DO_C3.5 :=(CPS_Cmd_EV4 AND AOM_O[37]= 0) OR AOM_O[37]=1; Ilo_Wago_OUT_DO_C3.6 :=(CPS_Cmd_P50 AND AOM_O[38]= 0) OR AOM_O[38]=1; Ilo_Wago_OUT_DO_C3.7 :=(CPS_Cmd_P51 AND AOM_O[39]= 0) OR AOM_O[39]=1; Ilo_Wago_OUT_DO_C3.8 :=(CPS_Cmd_P52 AND AOM_O[40]= 0) OR AOM_O[40]=1; Ilo_Wago_OUT_DO_C3.9 :=(CPS_Cmd_P53 AND AOM_O[41]= 0) OR AOM_O[41]=1; Ilo_Wago_OUT_DO_C3.10 :=(CPS_Cmd_EV5 AND AOM_O[42]= 0) OR AOM_O[42]=1; Ilo_Wago_OUT_DO_C3.11 :=(CPS_LSB_Stockg AND AOM_O[43]= 0) OR AOM_O[43]=1; Ilo_Wago_OUT_DO_C3.12 :=(CPS_LSH_Stockg AND AOM_O[44]= 0) OR AOM_O[44]=1; Ilo_Wago_OUT_DO_C3.13 :=(CPS_Cmd_P1 AND AOM_O[45]= 0) OR AOM_O[45]=1; Ilo_Wago_OUT_DO_C3.14 :=(CPS_Cmd_P2 AND AOM_O[46]= 0) OR AOM_O[46]=1; Ilo_Wago_OUT_DO_C3.15 :=(CPS_Cmd_Analyseur AND AOM_O[47]= 0) OR AOM_O[47]=1; Ilo_Wago_OUT_DO_C4.0 :=(CPS_Cmd_V_CH1 AND AOM_O[48]= 0) OR AOM_O[48]=1; Ilo_Wago_OUT_DO_C4.1 :=(CPS_Cmd_V_CH2 AND AOM_O[49]= 0) OR AOM_O[49]=1; Ilo_Wago_OUT_DO_C4.2 :=(CPS_Cmd_PmpChlor AND AOM_O[50]= 0) OR AOM_O[50]=1; Ilo_Wago_OUT_DO_C4.3 :=(DO_C4.3 AND AOM_O[51]= 0) OR AOM_O[51]=1; Ilo_Wago_OUT_DO_C4.4 :=(DO_C4.4 AND AOM_O[52]= 0) OR AOM_O[52]=1; Ilo_Wago_OUT_DO_C4.5 :=(DO_C4.5 AND AOM_O[53]= 0) OR AOM_O[53]=1; Ilo_Wago_OUT_DO_C4.6 :=(DO_C4.6 AND AOM_O[54]= 0) OR AOM_O[54]=1; Ilo_Wago_OUT_DO_C4.7 :=(DO_C4.7 AND AOM_O[55]= 0) OR AOM_O[55]=1; Ilo_Wago_OUT_DO_C4.8 :=(DO_C4.8 AND AOM_O[56]= 0) OR AOM_O[56]=1; Ilo_Wago_OUT_DO_C4.9 :=(DO_C4.9 AND AOM_O[57]= 0) OR AOM_O[57]=1; Ilo_Wago_OUT_DO_C4.10 :=(DO_C4.10 AND AOM_O[58]= 0) OR AOM_O[58]=1; Ilo_Wago_OUT_DO_C4.11 :=(DO_C4.11 AND AOM_O[59]= 0) OR AOM_O[59]=1; Ilo_Wago_OUT_DO_C4.12 :=(DO_C4.12 AND AOM_O[60]= 0) OR AOM_O[60]=1; Ilo_Wago_OUT_DO_C4.13 :=(DO_C4.13 AND AOM_O[61]= 0) OR AOM_O[61]=1; Ilo_Wago_OUT_DO_C4.14 :=(DO_C4.14 AND AOM_O[62]= 0) OR AOM_O[62]=1; Ilo_Wago_OUT_DO_C4.15 :=(DO_C4.15 AND AOM_O[63]= 0) OR AOM_O[63]=1; </STSource> </program> <dataBlock> <variables name="Ilo_Wago_IN_AI_C1_V8" typeName="INT" topologicalAddress="%MW3023"></variables> <variables name="CPS_Cmd_PmpPurg" typeName="BOOL" topologicalAddress="%MW303.0"> <comment>ORDRE MARCHE - POMPE REPRISE EAU DE PURGE</comment> </variables> <variables name="CPE_PosFermP43" typeName="BOOL" topologicalAddress="%MW331.2"> <comment>POSITION FERMEE - VANNE P43</comment> </variables> <variables name="CPE_PosOuvEV1" typeName="BOOL" topologicalAddress="%MW317.1"> <comment>POSITION OUVERTE - VANNE EV1</comment> </variables> <variables name="CPE_PosOuvP23" typeName="BOOL" topologicalAddress="%MW321.1"> <comment>POSITION OUVERTE - VANNE P23</comment> </variables> <variables name="Ilo_Wago_IN_DI_C2" typeName="WORD" topologicalAddress="%MW3033"></variables> <variables name="CPS_Cmd_EV3" typeName="BOOL" topologicalAddress="%MW327.0"> <comment>OUVERTURE - VANNE EV3</comment> </variables> <variables name="EA_LT_Forage2" typeName="INT"></variables> <variables name="CPE_PosFermP22" typeName="BOOL" topologicalAddress="%MW320.2"> <comment>POSITION FERMEE - VANNE P22</comment> </variables> <variables name="CPE_PosOuvP52" typeName="BOOL" topologicalAddress="%MW335.1"> <comment>POSITION OUVERTE - VANNE P52</comment> </variables> <variables name="CPE_PosFermEV2" typeName="BOOL" topologicalAddress="%MW322.2"> <comment>POSITION FERMEE - VANNE EV2</comment> </variables> <variables name="CPE_PosOuvP33" typeName="BOOL" topologicalAddress="%MW326.1"> <comment>POSITION OUVERTE - VANNE P33</comment> </variables> <variables name="CPE_PosFermP53" typeName="BOOL" topologicalAddress="%MW336.2"> <comment>POSITION FERMEE - VANNE P53</comment> </variables> <variables name="EA_PT_PmpRprise1" typeName="INT"></variables> <variables name="Ilo_Wago_IN_AI_C2_V4" typeName="INT" topologicalAddress="%MW3027"></variables> <variables name="CPE_PosFermP2" typeName="BOOL" topologicalAddress="%MW340.2"> <comment>POSITION FERMEE - VANNE P2</comment> </variables> <variables name="CPE_D1_EauTrait" typeName="BOOL"> <comment>IMPULSIONS DEBITMETRE D1 - EAU TRAITEE</comment> </variables> <variables name="CPE_RM_Forg2" typeName="BOOL" topologicalAddress="%MW301.3"> <comment>RETOUR MARCHE - POMPE FORAGE 2</comment> </variables> <variables name="CPE_PulsAnalyseur" typeName="BOOL"> <comment>RETOUR TOP DOSAGE - ANALYSEUR CHLORE + PH</comment> </variables> <variables name="CPE_PosFermP12" typeName="BOOL" topologicalAddress="%MW315.2"> <comment>POSITION FERMEE - VANNE P12</comment> </variables> <variables name="CPS_Cmd_EV11" typeName="BOOL" topologicalAddress="%MW338.0"> <comment>ELECTROVANNE EV11 - AIR OXYDATION</comment> </variables> <variables name="EA_AI2_V7" typeName="INT"></variables> <variables name="CPS_Cmd_P32" typeName="BOOL" topologicalAddress="%MW325.0"> <comment>OUVERTURE - VANNE P32</comment> </variables> <variables name="Ilo_Wago_IN_AI_C1_V3" typeName="INT" topologicalAddress="%MW3018"></variables> <variables name="CPE_PosOuvP1" typeName="BOOL" topologicalAddress="%MW339.1"> <comment>POSITION OUVERTE - VANNE P1</comment> </variables> <variables name="CPS_Cmd_PmpChlor" typeName="BOOL" topologicalAddress="%MW343.0"></variables> <variables name="Ilo_Wago_IN_DI_C3" typeName="WORD" topologicalAddress="%MW3034"></variables> <variables name="CPE_PosOuvEV0" typeName="BOOL" topologicalAddress="%MW312.1"> <comment>POSITION OUVERTE - VANNE PEV0</comment> </variables> <variables name="CPE_PosOuvP20" typeName="BOOL" topologicalAddress="%MW318.1"> <comment>POSITION OUVERTE - VANNE P20</comment> </variables> <variables name="Ilo_Wago_IN_AI_C2_V5" typeName="INT" topologicalAddress="%MW3028"></variables> <variables name="CPE_PosFermEV1" typeName="BOOL" topologicalAddress="%MW317.2"> <comment>POSITION FERMEE - VANNE EV1</comment> </variables> <variables name="CPE_CM2_EauLavg" typeName="BOOL"> <comment>CONTACTEUR MANOMETRIQUE CM2 - SECURITE SURPESSION</comment> </variables> <variables name="CPS_Cmd_P2" typeName="BOOL" topologicalAddress="%MW340.0"> <comment>OUVERTURE - VANNE P2</comment> </variables> <variables name="CPE_PosFermP23" typeName="BOOL" topologicalAddress="%MW321.2"> <comment>POSITION FERMEE - VANNE P23</comment> </variables> <variables name="CPE_PosFermP52" typeName="BOOL" topologicalAddress="%MW335.2"> <comment>POSITION FERMEE - VANNE P52</comment> </variables> <variables name="CPS_Cmd_P33" typeName="BOOL" topologicalAddress="%MW326.0"> <comment>OUVERTURE - VANNE P33</comment> </variables> <variables name="CPS_Cmd_EV4" typeName="BOOL" topologicalAddress="%MW332.0"> <comment>OUVERTURE - VANNE EV4</comment> </variables> <variables name="CPS_Gyrophare" typeName="BOOL"> <comment>GYROPHARE</comment> </variables> <variables name="CPE_PosOuvP32" typeName="BOOL" topologicalAddress="%MW325.1"> <comment>POSITION OUVERTE - VANNE P32</comment> </variables> <variables name="CPE_RM_Forg3" typeName="BOOL" topologicalAddress="%MW302.3"> <comment>RETOUR MARCHE - POMPE FORAGE 3</comment> </variables> <variables name="CPS_Cmd_P21" typeName="BOOL" topologicalAddress="%MW319.0"> <comment>OUVERTURE - VANNE P21</comment> </variables> <variables name="EA_AI2_V6" typeName="INT"></variables> <variables name="CPS_Cmd_EV10" typeName="BOOL" topologicalAddress="%MW308.0"> <comment>ELECTROVANNE EV10 - AIR OXYDATION</comment> </variables> <variables name="CPE_PosFermP33" typeName="BOOL" topologicalAddress="%MW326.2"> <comment>POSITION FERMEE - VANNE P33</comment> </variables> <variables name="CPE_PosFermP32" typeName="BOOL" topologicalAddress="%MW325.2"> <comment>POSITION FERMEE - VANNE P32</comment> </variables> <variables name="EA_FT_Lavage" typeName="INT"></variables> <variables name="CPE_DEF_Forg1" typeName="BOOL"> <comment>DEFAUT - POMPE FORAGE 1</comment> </variables> <variables name="CPS_Cmd_P12" typeName="BOOL" topologicalAddress="%MW315.0"> <comment>OUVERTURE - VANNE P12</comment> </variables> <variables name="CPE_PosOuvP2" typeName="BOOL" topologicalAddress="%MW340.1"> <comment>POSITION OUVERTE - VANNE P2</comment> </variables> <variables name="Ilo_Wago_IN_AI_C1_V2" typeName="INT" topologicalAddress="%MW3017"></variables> <variables name="CPS_Cmd_V_CH1" typeName="BOOL" topologicalAddress="%MW341.0"> <comment>OUVERTURE - VANNE CH1</comment> </variables> <variables name="AOM_O" typeName="ARRAY[0..100] OF INT" topologicalAddress="%MW2200"> <comment>Tableau d'AOM forçage sorties</comment> <instanceElementDesc name="[0]"> <comment>Prealarme générale (30KA1)</comment> </instanceElementDesc> <instanceElementDesc name="[1]"> <comment>Alarme générale (30KA2)</comment> </instanceElementDesc> <instanceElementDesc name="[2]"> <comment>Niveau Eau forage OK (1 = niveau recouvert / Atteint) (36KA1)</comment> </instanceElementDesc> <instanceElementDesc name="[3]"> <comment>S2- Démarrage à distance Tête régul. Adoucisseur n°1 (S2_16REG01)</comment> </instanceElementDesc> <instanceElementDesc name="[4]"> <comment>S2- démarrage à distance Tête régul. Adoucisseur n°2 (S2_16REG02)</comment> </instanceElementDesc> <instanceElementDesc name="[5]"> <comment>Consigne pompe doseuse 1 / Javel (puls) (7DP01)</comment> </instanceElementDesc> <instanceElementDesc name="[6]"> <comment>Consigne pompe doseuse 2 / Soude (puls) (7DP02)</comment> </instanceElementDesc> <instanceElementDesc name="[7]"> <comment>Niveau cuve de stockage ok (1 = niveau recouvert) (61KA1)</comment> </instanceElementDesc> <instanceElementDesc name="[8]"> <comment>DO1_V9</comment> </instanceElementDesc> <instanceElementDesc name="[9]"> <comment>DO1_V10</comment> </instanceElementDesc> <instanceElementDesc name="[10]"> <comment>DO1_V11</comment> </instanceElementDesc> <instanceElementDesc name="[11]"> <comment>DO1_V12</comment> </instanceElementDesc> <instanceElementDesc name="[12]"> <comment>DO1_V13</comment> </instanceElementDesc> <instanceElementDesc name="[13]"> <comment>DO1_V14</comment> </instanceElementDesc> <instanceElementDesc name="[14]"> <comment>DO1_V15</comment> </instanceElementDesc> <instanceElementDesc name="[15]"> <comment>DO1_V16</comment> </instanceElementDesc> <instanceElementDesc name="[16]"> <comment>Ordre de marche variateur Pompe de forage 1 (35KA1)</comment> </instanceElementDesc> <instanceElementDesc name="[17]"> <comment>S1-signal inhibition Tete régul. adoucisseur n°1 (S1_16REG01)</comment> </instanceElementDesc> <instanceElementDesc name="[18]"> <comment>Ouverture EV P00 eaux brutes vers dénitratation n°1 (41P00)</comment> </instanceElementDesc> <instanceElementDesc name="[19]"> <comment>Ouverture EV P02 retour eaux vers dénitratation n°1 (41P02)</comment> </instanceElementDesc> <instanceElementDesc name="[20]"> <comment>S1-signal inhibition Tete régul. adoucisseur n°2 (S1_16REG02)</comment> </instanceElementDesc> <instanceElementDesc name="[21]"> <comment>Ouverture EV P10 eaux brutes vers dénitratation n°2 (43P10)</comment> </instanceElementDesc> <instanceElementDesc name="[22]"> <comment>Ouverture EV P12 retour eaux traitées vers dénitratation n°2 (43P12)</comment> </instanceElementDesc> <instanceElementDesc name="[23]"> <comment>Ouverture EV P1 sortie filtre charbon actif vers égoût (45P1)</comment> </instanceElementDesc> <instanceElementDesc name="[24]"> <comment>Ouverture EV P2 sortie filtre charbon actif vers cuve (46P2)</comment> </instanceElementDesc> <instanceElementDesc name="[25]"> <comment>Ordre de marche pompe doseuse 1 / Javel (7DP01)</comment> </instanceElementDesc> <instanceElementDesc name="[26]"> <comment>Ordre de marche pompe doseuse 2 / Soude (7DP02)</comment> </instanceElementDesc> <instanceElementDesc name="[27]"> <comment>Ordre de marche thermoplongeur soude (0= arrêt ) (52TH01)</comment> </instanceElementDesc> <instanceElementDesc name="[28]"> <comment>Ordre de marche pompe de lavage PPL01 (55KM4)</comment> </instanceElementDesc> <instanceElementDesc name="[29]"> <comment>Ouverture EV P3 appoint eau de ville dans cuve (60P3)</comment> </instanceElementDesc> <instanceElementDesc name="[30]"> <comment>Ouverture EV P4 retour eau traitée vers cuve (61P4)</comment> </instanceElementDesc> <instanceElementDesc name="[31]"> <comment>DO2_V16</comment> </instanceElementDesc> </variables> <variables name="CPE_CM1_EauBrute" typeName="BOOL"> <comment>CONTACTEUR MANOMETRIQUE CM1 - SECURITE SURPESSION</comment> </variables> <variables name="CPE_PosOuvP21" typeName="BOOL" topologicalAddress="%MW319.1"> <comment>POSITION OUVERTE - VANNE P21</comment> </variables> <variables name="CPE_PosFermEV0" typeName="BOOL" topologicalAddress="%MW312.2"> <comment>POSITION FERMEE - VANNE PEV0</comment> </variables> <variables name="EA_AI_pH" typeName="INT"></variables> <variables name="CPS_Cmd_P1" typeName="BOOL" topologicalAddress="%MW339.0"> <comment>OUVERTURE - VANNE P1</comment> </variables> <variables name="CPS_Cmd_P20" typeName="BOOL" topologicalAddress="%MW318.0"> <comment>OUVERTURE - VANNE P20</comment> </variables> <variables name="EA_AI_Chlore" typeName="INT"></variables> <variables name="Ilo_Wago_IN_AI_C2_V2" typeName="INT" topologicalAddress="%MW3025"></variables> <variables name="Ilo_Wago_IN_DI_C4" typeName="WORD" topologicalAddress="%MW3035"></variables> <variables name="CPS_Cmd_EV5" typeName="BOOL" topologicalAddress="%MW337.0"> <comment>OUVERTURE - VANNE EV5</comment> </variables> <variables name="CPS_Autors_Forg3" typeName="BOOL"> <comment>SECURITE NIVEAU BAS - FORAGE 3</comment> </variables> <variables name="CPE_PosOuvP31" typeName="BOOL" topologicalAddress="%MW324.1"> <comment>POSITION OUVERTE - VANNE P31</comment> </variables> <variables name="CPE_PosFermP20" typeName="BOOL" topologicalAddress="%MW318.2"> <comment>POSITION FERMEE - VANNE P20</comment> </variables> <variables name="CPS_Autors_Forg2" typeName="BOOL"> <comment>SECURITE NIVEAU BAS - FORAGE 2</comment> </variables> <variables name="CPE_PosOuvP30" typeName="BOOL" topologicalAddress="%MW323.1"> <comment>POSITION OUVERTE - VANNE P30</comment> </variables> <variables name="CPE_PosFermP31" typeName="BOOL" topologicalAddress="%MW324.2"> <comment>POSITION FERMEE - VANNE P31</comment> </variables> <variables name="CPS_Cmd_P13" typeName="BOOL" topologicalAddress="%MW316.0"> <comment>OUVERTURE - VANNE P13</comment> </variables> <variables name="CPE_PosOuvEV5" typeName="BOOL" topologicalAddress="%MW337.1"> <comment>POSITION OUVERTE - VANNE EV5</comment> </variables> <variables name="CPS_LSH_Stockg" typeName="BOOL"> <comment>NIVEAU HAUT CUVE STOCKAGE</comment> </variables> <variables name="CPE_DEF_Forg2" typeName="BOOL"> <comment>DEFAUT - POMPE FORAGE 2</comment> </variables> <variables name="Ilo_Wago_IN_AI_C1_V5" typeName="INT" topologicalAddress="%MW3020"></variables> <variables name="Ilo_Wago_IN_AI_C2_V8" typeName="INT" topologicalAddress="%MW3031"></variables> <variables name="Ilo_Wago_IN_DI_C5" typeName="WORD" topologicalAddress="%MW3036"></variables> <variables name="CPE_PosFermP21" typeName="BOOL" topologicalAddress="%MW319.2"> <comment>POSITION FERMEE - VANNE P21</comment> </variables> <variables name="CPE_DEF_PmpReprs2" typeName="BOOL"> <comment>DEFAUT - POMPE REPRISE PR2</comment> </variables> <variables name="CPS_Cmd_P23" typeName="BOOL" topologicalAddress="%MW321.0"> <comment>OUVERTURE - VANNE P23</comment> </variables> <variables name="Ilo_Wago_IN_AI_C2_V3" typeName="INT" topologicalAddress="%MW3026"></variables> <variables name="CPS_Cmd_P52" typeName="BOOL" topologicalAddress="%MW335.0"> <comment>OUVERTURE - VANNE P52</comment> </variables> <variables name="CPS_Alarme" typeName="BOOL"> <comment>ALARME</comment> </variables> <variables name="CPS_Cmd_P53" typeName="BOOL" topologicalAddress="%MW336.0"> <comment>OUVERTURE - VANNE P53</comment> </variables> <variables name="CPS_Autors_Forg1" typeName="BOOL"> <comment>SECURITE NIVEAU BAS - FORAGE 1</comment> </variables> <variables name="CPE_PosFermP30" typeName="BOOL" topologicalAddress="%MW323.2"> <comment>POSITION FERMEE - VANNE P30</comment> </variables> <variables name="Ilo_Wago_IN_AI_C1_V4" typeName="INT" topologicalAddress="%MW3019"></variables> <variables name="CPS_Cmd_P10" typeName="BOOL" topologicalAddress="%MW313.0"> <comment>OUVERTURE - VANNE P10</comment> </variables> <variables name="CPE_PosOuvP00" typeName="BOOL" topologicalAddress="%MW309.1"> <comment>POSITION OUVERTE - VANNE P00</comment> </variables> <variables name="CPE_PosOuvP11" typeName="BOOL" topologicalAddress="%MW314.1"> <comment>POSITION OUVERTE - VANNE P11</comment> </variables> <variables name="CPE_PosOuvP01" typeName="BOOL" topologicalAddress="%MW310.1"> <comment>POSITION OUVERTE - VANNE P01</comment> </variables> <variables name="AOM_I" typeName="ARRAY[0..150] OF INT" topologicalAddress="%MW2000"> <comment>Tableau d'AOM forçcage entrées</comment> <instanceElementDesc name="[0]"> <comment>Arrêt d'urgence général (0 = AU) (31AU1)</comment> </instanceElementDesc> <instanceElementDesc name="[1]"> <comment>Général auxiliaire 10Q1 disjoncté (0 = Disjonction) (10Q1)</comment> </instanceElementDesc> <instanceElementDesc name="[2]"> <comment>Capteur Manque AIR , (0 = manque air) (32CMF0)</comment> </instanceElementDesc> <instanceElementDesc name="[3]"> <comment>compteur de cycle BY-PASS (32C1)</comment> </instanceElementDesc> <instanceElementDesc name="[4]"> <comment>compteur de cycle eau de ville (32C2)</comment> </instanceElementDesc> <instanceElementDesc name="[5]"> <comment>compteur de cycle regénération (32C3)</comment> </instanceElementDesc> <instanceElementDesc name="[6]"> <comment>retour de marche pompe de forage PPF1 (R1_4VF_PR1)</comment> </instanceElementDesc> <instanceElementDesc name="[7]"> <comment>retour de défaut variateur pompe forage PPF1 (R2_4VF_PR1)</comment> </instanceElementDesc> <instanceElementDesc name="[8]"> <comment>Fonct. en auto. pompe forage ( 1 = AUTO) (Commutateur 35S1)</comment> </instanceElementDesc> <instanceElementDesc name="[9]"> <comment>impulsion débimètre sortie pompe forage (15FIT01)</comment> </instanceElementDesc> <instanceElementDesc name="[10]"> <comment>capteur de surpression pompe forage (0 = surpression) (36CMPPF01)</comment> </instanceElementDesc> <instanceElementDesc name="[11]"> <comment>S3 - signal en service / regénération Tête régul. adoucisseur n°1 (S3_16REG01)</comment> </instanceElementDesc> <instanceElementDesc name="[12]"> <comment>FDC vanne P00 ouverte (41P00_O1)</comment> </instanceElementDesc> <instanceElementDesc name="[13]"> <comment>FDC vanne P00 fermée (41P00_F1)</comment> </instanceElementDesc> <instanceElementDesc name="[14]"> <comment>FDC vanne P02 ouverte (41P02_O1)</comment> </instanceElementDesc> <instanceElementDesc name="[15]"> <comment>FDC vanne P02 fermée (41P02_F1)</comment> </instanceElementDesc> </variables> <variables name="CPE_DEF_Forg3" typeName="BOOL"> <comment>DEFAUT - POMPE FORAGE 3</comment> </variables> <variables name="Ilo_Wago_IN_DI_C6" typeName="WORD" topologicalAddress="%MW3037"></variables> <variables name="DI_C6" typeName="WORD"></variables> <variables name="CPS_Cmd_Forg3" typeName="BOOL" topologicalAddress="%MW302.0"> <comment>SECURITE NIVEAU BAS - FORAGE 3</comment> </variables> <variables name="Ilo_Wago_OUT_DO_C4" typeName="WORD" topologicalAddress="%MW3219"></variables> <variables name="CPE_PosOuvEV4" typeName="BOOL" topologicalAddress="%MW332.1"> <comment>POSITION OUVERTE - VANNE EV4</comment> </variables> <variables name="CPS_Cmd_P02" typeName="BOOL" topologicalAddress="%MW311.0"> <comment>OUVERTURE - VANNE P02</comment> </variables> <variables name="CPS_LSB_Stockg" typeName="BOOL"> <comment>NIVEAU BAS CUVE STOCKAGE</comment> </variables> <variables name="CPE_DEF_PmpChlor" typeName="BOOL"> <comment>DEFAUT - POMPE CHLORATION</comment> </variables> <variables name="EA_AI2_V8" typeName="INT"></variables> <variables name="CPS_Cmd_P22" typeName="BOOL" topologicalAddress="%MW320.0"> <comment>OUVERTURE - VANNE P22</comment> </variables> <variables name="CPE_PosFermEV5" typeName="BOOL" topologicalAddress="%MW337.2"> <comment>POSITION FERMEE - VANNE EV5</comment> </variables> <variables name="EA_AI2_V3" typeName="INT"></variables> <variables name="CPS_Cmd_P43" typeName="BOOL" topologicalAddress="%MW331.0"> <comment>OUVERTURE - VANNE P43</comment> </variables> <variables name="CPE_D2_EauLavg" typeName="BOOL"> <comment>IMPULSIONS DEBITMETRE D2 - LAVAGE</comment> </variables> <variables name="CPE_DEF_PmpReprs1" typeName="BOOL"> <comment>DEFAUT - POMPE REPRISE PR1</comment> </variables> <variables name="EA_LT_Stockage" typeName="INT"></variables> <variables name="Ilo_Wago_IN_AI_C2_V1" typeName="INT" topologicalAddress="%MW3024"></variables> <variables name="CPS_Cmd_P42" typeName="BOOL" topologicalAddress="%MW330.0"> <comment>OUVERTURE - VANNE P42</comment> </variables> <variables name="EA_LT_Forage1" typeName="INT"></variables> <variables name="CPE_PosFermP11" typeName="BOOL" topologicalAddress="%MW314.2"> <comment>POSITION FERMEE - VANNE P11</comment> </variables> <variables name="CPE_RM_PmpLavg" typeName="BOOL" topologicalAddress="%MW305.3"> <comment>RETOUR MARCHE - POMPE LAVAGE FILTRES</comment> </variables> <variables name="CPE_PosOuvP51" typeName="BOOL" topologicalAddress="%MW334.1"> <comment>POSITION OUVERTE - VANNE P51</comment> </variables> <variables name="CPE_DEF_PmpLavg" typeName="BOOL"> <comment>DEFAUT - POMPE LAVAGE FILTRES</comment> </variables> <variables name="Ilo_Wago_OUT_DO_C3" typeName="WORD" topologicalAddress="%MW3218"></variables> <variables name="Ilo_Wago_IN_AI_C1_V7" typeName="INT" topologicalAddress="%MW3022"></variables> <variables name="CPE_PosOuvP40" typeName="BOOL" topologicalAddress="%MW328.1"> <comment>POSITION OUVERTE - VANNE P40</comment> </variables> <variables name="Ilo_Wago_IN_DI_C7" typeName="WORD" topologicalAddress="%MW3038"></variables> <variables name="CPS_Cmd_EV0" typeName="BOOL" topologicalAddress="%MW312.0"> <comment>OUVERTURE - VANNE EV0</comment> </variables> <variables name="DI_C7" typeName="WORD"></variables> <variables name="CPE_PosOuvP02" typeName="BOOL" topologicalAddress="%MW311.1"> <comment>POSITION OUVERTE - VANNE P02</comment> </variables> <variables name="CPS_Cmd_V_CH2" typeName="BOOL" topologicalAddress="%MW342.0"> <comment>OUVERTURE - VANNE CH2</comment> </variables> <variables name="CPS_Cmd_P50" typeName="BOOL" topologicalAddress="%MW333.0"> <comment>OUVERTURE - VANNE P50</comment> </variables> <variables name="DO_C4" typeName="WORD"></variables> <variables name="CPE_PosFermP00" typeName="BOOL" topologicalAddress="%MW309.2"> <comment>POSITION FERMEE - VANNE P00</comment> </variables> <variables name="CPE_DEF_PmpPurg" typeName="BOOL"> <comment>DEFAUT - POMPE REPRISE EAU DE PURGE</comment> </variables> <variables name="CPS_Cmd_Analyseur" typeName="BOOL"> <comment>ORDRE ANALYSE - ANALYSEUR CHLORE + PH AMI TRIDES</comment> </variables> <variables name="CPE_PosFermP01" typeName="BOOL" topologicalAddress="%MW310.2"> <comment>POSITION FERMEE - VANNE P01</comment> </variables> <variables name="CPE_RM_PmpChlor" typeName="BOOL" topologicalAddress="%MW343.3"> <comment>RETOUR MARCHE - POMPE CHLORATION</comment> </variables> <variables name="CPS_Cmd_Forg2" typeName="BOOL" topologicalAddress="%MW301.0"> <comment>ORDRE MARCHE - POMPE FORAGE 2</comment> </variables> <variables name="CPS_Cmd_P11" typeName="BOOL" topologicalAddress="%MW314.0"> <comment>OUVERTURE - VANNE P11</comment> </variables> <variables name="CPS_Cmd_P01" typeName="BOOL" topologicalAddress="%MW310.0"> <comment>OUVERTURE - VANNE P01</comment> </variables> <variables name="CPE_PosOuvP10" typeName="BOOL" topologicalAddress="%MW313.1"> <comment>POSITION OUVERTE - VANNE P10</comment> </variables> <variables name="CPE_PosFermEV4" typeName="BOOL" topologicalAddress="%MW332.2"> <comment>POSITION FERMEE - VANNE EV4</comment> </variables> <variables name="CPE_PosOuvP50" typeName="BOOL" topologicalAddress="%MW333.1"> <comment>POSITION OUVERTE - VANNE P50</comment> </variables> <variables name="CPS_Cmd_EV1" typeName="BOOL" topologicalAddress="%MW317.0"> <comment>OUVERTURE - VANNE EV1</comment> </variables> <variables name="CPE_CPT_EauBrute" typeName="BOOL"> <comment>COMPTEUR ARRIVEE EAU BRUTE</comment> </variables> <variables name="CPE_PosOuvP13" typeName="BOOL" topologicalAddress="%MW316.1"> <comment>POSITION OUVERTE - VANNE P13</comment> </variables> <variables name="CPE_DefAnalyseur" typeName="BOOL"> <comment>RETOUR DEFAUT - ANALYSEUR CHLORE + PH</comment> </variables> <variables name="CPE_PosOuvEV3" typeName="BOOL" topologicalAddress="%MW327.1"> <comment>POSITION OUVERTE - VANNE EV3</comment> </variables> <variables name="Ilo_Wago_IN_AI_C2_V6" typeName="INT" topologicalAddress="%MW3029"></variables> <variables name="CPE_RM_PmpPurg" typeName="BOOL" topologicalAddress="%MW303.3"> <comment>RETOUR MARCHE - POMPE REPRISE EAU DE PURGE</comment> </variables> <variables name="CPE_LSH_EauPurg" typeName="BOOL"> <comment>POIRE NIVEAU HAUT EAUX DE PURGE</comment> </variables> <variables name="Ilo_Wago_OUT_DO_C2" typeName="WORD" topologicalAddress="%MW3217"></variables> <variables name="EA_FT_EauTraitee" typeName="INT"></variables> <variables name="CPE_PosFermP51" typeName="BOOL" topologicalAddress="%MW334.2"> <comment>POSITION FERMEE - VANNE P51</comment> </variables> <variables name="CPE_PosOuvP41" typeName="BOOL" topologicalAddress="%MW329.1"> <comment>POSITION OUVERTE - VANNE P41</comment> </variables> <variables name="CPE_BP_Klaxon" typeName="BOOL"> <comment>BP Arret Klaxon</comment> </variables> <variables name="CPE_PosFermP10" typeName="BOOL" topologicalAddress="%MW313.2"> <comment>POSITION FERMEE - VANNE P10</comment> </variables> <variables name="Ilo_Wago_IN_AI_C1_V6" typeName="INT" topologicalAddress="%MW3021"></variables> <variables name="CPS_Cmd_P30" typeName="BOOL" topologicalAddress="%MW323.0"> <comment>OUVERTURE - VANNE P30</comment> </variables> <variables name="CPS_Cmd_P41" typeName="BOOL" topologicalAddress="%MW329.0"> <comment>OUVERTURE - VANNE P41</comment> </variables> <variables name="EA_AI2_V5" typeName="INT"></variables> <variables name="CPS_Cmd_P51" typeName="BOOL" topologicalAddress="%MW334.0"> <comment>OUVERTURE - VANNE P51</comment> </variables> <variables name="CPE_RM_PmpReprs2" typeName="BOOL" topologicalAddress="%MW307.3"> <comment>RETOUR MARCHE - POMPE REPRISE PR2</comment> </variables> <variables name="CPE_PosFermP40" typeName="BOOL" topologicalAddress="%MW328.2"> <comment>POSITION FERMEE - VANNE P40</comment> </variables> <variables name="CPE_PosFermP02" typeName="BOOL" topologicalAddress="%MW311.2"> <comment>POSITION FERMEE - VANNE P02</comment> </variables> <variables name="CPE_PosOuvP42" typeName="BOOL" topologicalAddress="%MW330.1"> <comment>POSITION OUVERTE - VANNE P42</comment> </variables> <variables name="CPS_Cmd_Forg1" typeName="BOOL" topologicalAddress="%MW300.0"> <comment>ORDRE MARCHE - POMPE FORAGE 1</comment> </variables> <variables name="CPS_Cmd_P00" typeName="BOOL" topologicalAddress="%MW309.0"> <comment>OUVERTURE - VANNE P00</comment> </variables> <variables name="Ilo_Wago_IN_DI_C1" typeName="WORD" topologicalAddress="%MW3032"></variables> <variables name="CPE_PosOuvEV2" typeName="BOOL" topologicalAddress="%MW322.1"> <comment>POSITION OUVERTE - VANNE EV2</comment> </variables> <variables name="Ilo_Wago_IN_AI_C2_V7" typeName="INT" topologicalAddress="%MW3030"></variables> <variables name="CPE_PosFermEV3" typeName="BOOL" topologicalAddress="%MW327.2"> <comment>POSITION FERMEE - VANNE EV3</comment> </variables> <variables name="CPS_Cmd_P40" typeName="BOOL" topologicalAddress="%MW328.0"> <comment>OUVERTURE - VANNE P40</comment> </variables> <variables name="EA_PT_PmpRprise2" typeName="INT"></variables> <variables name="CPE_RM_Forg1" typeName="BOOL" topologicalAddress="%MW300.3"> <comment>RETOUR MARCHE - POMPE FORAGE 1</comment> </variables> <variables name="CPS_Cmd_PmpLavg" typeName="BOOL" topologicalAddress="%MW305.0"> <comment>ORDRE MARCHE - POMPE LAVAGE FILTRE</comment> </variables> <variables name="CPE_DEF_SouflAir" typeName="BOOL"> <comment>DEFAUT - GROUPE D'AIR</comment> </variables> <variables name="CPE_CM3_AirOK" typeName="BOOL"> <comment>CONTACTEUR MANOMETRIQUE CM3 - PRESENCE AIR COMPRIME</comment> </variables> <variables name="CPE_PosFermP41" typeName="BOOL" topologicalAddress="%MW329.2"> <comment>POSITION FERMEE - VANNE P41</comment> </variables> <variables name="CPE_PosFermP42" typeName="BOOL" topologicalAddress="%MW330.2"> <comment>POSITION FERMEE - VANNE P42</comment> </variables> <variables name="Ilo_Wago_IN_AI_C1_V1" typeName="INT" topologicalAddress="%MW3016"></variables> <variables name="CPE_PosOuvP12" typeName="BOOL" topologicalAddress="%MW315.1"> <comment>POSITION OUVERTE - VANNE P12</comment> </variables> <variables name="CPE_PosOuvP22" typeName="BOOL" topologicalAddress="%MW320.1"> <comment>POSITION OUVERTE - VANNE P22</comment> </variables> <variables name="EA_LT_Forage3" typeName="INT"></variables> <variables name="CPE_PosFermP13" typeName="BOOL" topologicalAddress="%MW316.2"> <comment>POSITION FERMEE - VANNE P13</comment> </variables> <variables name="CPE_PosOuvP53" typeName="BOOL" topologicalAddress="%MW336.1"> <comment>POSITION OUVERTE - VANNE P53</comment> </variables> <variables name="CPS_Cmd_P31" typeName="BOOL" topologicalAddress="%MW324.0"> <comment>OUVERTURE - VANNE P31</comment> </variables> <variables name="CPS_Klaxon" typeName="BOOL"> <comment>KLAXON</comment> </variables> <variables name="CPE_PosFermP50" typeName="BOOL" topologicalAddress="%MW333.2"> <comment>POSITION FERMEE - VANNE P50</comment> </variables> <variables name="CPS_Cmd_EV2" typeName="BOOL" topologicalAddress="%MW322.0"> <comment>OUVERTURE - VANNE EV2</comment> </variables> <variables name="CPE_PosFermP1" typeName="BOOL" topologicalAddress="%MW339.2"> <comment>POSITION FERMEE - VANNE P1</comment> </variables> <variables name="EA_AI2_V4" typeName="INT"></variables> <variables name="Ilo_Wago_OUT_DO_C1" typeName="WORD" topologicalAddress="%MW3216"></variables> <variables name="CPS_Cmd_SouflAir" typeName="BOOL" topologicalAddress="%MW304.0"> <comment>ORDRE MARCHE - GROUPE D'AIR</comment> </variables> <variables name="CPE_RM_PmpReprs1" typeName="BOOL" topologicalAddress="%MW306.3"> <comment>RETOUR MARCHE - POMPE REPRISE PR1</comment> </variables> <variables name="CPE_PosOuvP43" typeName="BOOL" topologicalAddress="%MW331.1"> <comment>POSITION OUVERTE - VANNE P43</comment> </variables> <variables name="CPE_RM_SouflAir" typeName="BOOL" topologicalAddress="%MW304.3"> <comment>RETOUR MARCHE - GROUPE D'AIR</comment> </variables> </dataBlock> </STExchangeFile>
Mon fichier source étant un fichier Excel, je ne sais pas comment te le transférer sur le forum mais après, c'est pas forcément le plus important je dirai car l'extraction des données est fonctionnelle
14 nov. 2022 à 20:53
, c'est pas forcément le plus important je dirai car l'extraction des données est fonctionnelle
Pour t'aider, il faut qu'on essaye de notre côté, et franchement, je n'ai pas envie de passer des heures à me bricoler un jeu de données, qui pourrait ne pas être correct.
Je ne te demande pas un fichier complet et confidentiel, mais 3 ou 4 "lignes" de chaque "type".
Tu peux le poster sur un site de partage comme cjoint ou autre
14 nov. 2022 à 21:06
SAlut Whismeril,
Oui je comprends. Je te donne ça:
https://wetransfer.com/downloads/bf6088c9030754479d18a397543a1c9d20221114200609/03498c
Je t'ai fait un weTransfer en espérant que ça fonctionne
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question15 nov. 2022 à 06:46
Je regarde ça ce soir
15 nov. 2022 à 18:44
Alors, ton de lecture du fichier Excel par OLEBD ne fonctionne pas chez moi, je ne dois pas avoir le bon driver ou la même version d'Excel que toi.
Du coup, je voulais lire le fichier autrement, mais je ne retrouve pas les données de ce fichier Excel dans les 2 exemples de xml que tu as mis plus haut.
Donc, je ne peux toujours pas tester de mon côté.
Dans mon premier message, je t'avais pourtant demandé un jeu de données d'entrée et le xml qui en découle.
Deuxième point, dans ton code de lecture, tu initialises des tableaux, puis tu crées des listes de tes classes à partir de ces tableaux.
Est-ce que ces tableaux te servent ailleurs, dans la négative, ils n'ont pas d'intérêt et ça charge la RAM inutilement, tes données sont à la fois dans
- le dataset
- les tableaux
- les listes.
15 nov. 2022 à 20:34
Salut Whismeril,
Je viens de te faire un Excel source et un xml:
https://wetransfer.com/downloads/87815fbefb9e8849ae3a570f376b2b8520221115193116/d02f0a
J'ai vachement simplifié par rapport au premier Excel car ça suffira pour avoir une base je pense.
Pour répondre à ta question sur mes tableaux, non ils ne me servent pas donc effectivement, il pourrait sauter. ça allègerait mon code en plus.
Je me penche sur le sujet.
Merci
15 nov. 2022 à 21:22
OleDbConnection MyConnection = default(OleDbConnection); DataSet dataSetES = default(DataSet); OleDbDataAdapter MyCommand = default(OleDbDataAdapter); MyConnection = new OleDbConnection("Provider = Microsoft.ACE.OLEDB.12.0; Data Source = " + NomFichierSource.Text + "; Extended Properties = 'Excel 12.0 XML;HDR=YES;'; "); MyCommand = new OleDbDataAdapter("select * from [Liste_ES$]", MyConnection); MyConnection.Open(); dataSetES = new DataSet(); MyCommand.Fill(dataSetES); //Calcul du nombre de lignes et de colonnes pour dimensionner le tableau qui accueillera les données int nb_col = dataSetES.Tables[0].Columns.Count; nb_lignesES = dataSetES.Tables[0].Rows.Count; //Création du tableau qui accueillera les données du fichier excel string[,] Tableau_SourceES = new string[nb_lignesES + 1, nb_col + 1]; int x = 0; int y = 0; for (x = 0; x <= nb_lignesES - 1; x++) { for (y = 0; y <= nb_col - 1; y++) { Tableau_SourceES[x, y] = dataSetES.Tables[0].Rows[x].ItemArray[y].ToString(); } } MyConnection.Close(); //Remplissage des tableaux d'entrées/sorties int Index_EANA = 0; int Index_ETOR = 0; int Index_STOR = 0; int Index_SANA = 0; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////// //////////////////////////////////// //////////////////////////////////// Génération section de recopie E/S //////////////////////////////////// //////////////////////////////////// //////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if (RecopieE_S.Checked == true) { // Création du fichier de sortie //Déclaration des différentes variables List<EANA_API> Liste_EANA_API = new List<EANA_API>(); List<ETOR_API> Liste_ETOR_API = new List<ETOR_API>(); List<STOR_API> Liste_STOR_API = new List<STOR_API>(); List<SANA_API> Liste_SANA_API = new List<SANA_API>(); for (int Index = 0; Index <= nb_lignesES - 1; Index++) { //Ajout des différentes entrées ANA if (Tableau_SourceES[Index, 1].Contains("AI_")) { Liste_EANA_API.Add(new EANA_API(Tableau_SourceES[Index, 9], Tableau_SourceES[Index, 1], Index_EANA)); Index_EANA = Index_EANA + 1; } //Ajout des différentes entrées TOR if (Tableau_SourceES[Index, 1].Contains("DI.C")) { Liste_ETOR_API.Add(new ETOR_API(Tableau_SourceES[Index, 9], Tableau_SourceES[Index, 1], Index_ETOR)); Index_ETOR = Index_ETOR + 1; } //Ajout des différentes sorties TOR if (Tableau_SourceES[Index, 1].Contains("DI.C")) { Liste_STOR_API.Add(new STOR_API(Tableau_SourceES[Index, 9], Tableau_SourceES[Index, 1], Index_STOR)); Index_STOR = Index_STOR + 1; } //Ajout des différentes sorties ANA if (Tableau_SourceES[Index, 1].Contains("AO_")) { Liste_SANA_API.Add(new SANA_API(Tableau_SourceES[Index, 9], Tableau_SourceES[Index, 1], Index_SANA)); Index_SANA = Index_SANA + 1; } } //Création du fichier XML source XDocument XmlDoc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"), new XElement("STExchangeFile", new XElement("fileHeader", new XAttribute("company", "Schneider Automation"), new XAttribute("product", "Control Expert V14.1 - 191122A"), new XAttribute("dateTime", "date_and_time#2018-3-12-16:50:53"), new XAttribute("content", "Fichier source ST"), new XAttribute("DTDVersion", "41")), new XElement("contentHeader", new XAttribute("name", "Projet"), new XAttribute("version", "0.0.710"), new XAttribute("dateTime", "date_and_time#2018-2-14-14:39:27")), new XElement("program", new XElement("identProgram", new XAttribute("name", "Copie_E_S"), new XAttribute("type", "section"), new XAttribute("task", "MAST")), new XElement("STSource", new XText("(*Copies des entrees Analogiques *)" + "\n"), from p in Liste_EANA_API select new XText(p.EANA), new XText("\n"), new XText("(*Copies des entrées TOR *)" + "\n"), from p in Liste_ETOR_API select new XText(p.ETOR), new XText("\n"), new XText("(*Copies des sorties TOR *)" + "\n"), from p in Liste_STOR_API select new XText(p.STOR), new XText("\n"), new XText("(*Copies des sorties Analogiques *)" + "\n"), from p in Liste_SANA_API select new XText(p.SANA))), new XElement("dataBlock",new XElement("variables", new XAttribute("version", "0.0.710"))))); //Test si le fichier existe déjà if (File.Exists(NomDossierDest.Text + @"\Sections_ST.xst")) { MessageBox.Show("Un fichier section existe déjà dans le dossier de destination. Annulation de l'opération"); } else { //Récupération du nom de la zone pour définir le nom du fichier XmlDoc.Save(NomDossierDest.Text + @"\Sections_ST.xst"); } }
Code mis à jour suite à tes remarques Whismeril. J'ai sauté mes classes "En_tête" qui n'apportait rien
15 nov. 2022 à 23:00
Alors, j'ai exporté ton excel en csv.
Ça je n'ai pas de problème de compatibilité ou autre avec mon vieux Excel.
J'ai réécrit tes classes comme ça (mais y'a encore du code redondant, il faudra faire mieux)
public abstract class EntreesSortie { /// <summary> /// Le constructeur prend en paramètres un tableau de string qui correspond à une ligne du csv, et l'index /// </summary> /// <param name="LigneCSV"></param> /// <param name="Index"></param> public EntreesSortie(string[] LigneCSV, int Index) { this.Mnemonique = LigneCSV[9]; this.Adresse = LigneCSV[1]; this.Comment = $"{LigneCSV[5]} {LigneCSV[7]}"; this.Index = Index; } public abstract string Texte { get; } public string Mnemonique { get; set; } public string Adresse { get; set; } public int Index { get; set; } public string Comment { get; set; } } public class EANA_API : EntreesSortie { //le constructeur appelle directement celui de la classe abstraite, et rien d'autre public EANA_API(string[] LigneCSV, int Index) : base(LigneCSV, Index) { } public override string Texte { get { return $"{Mnemonique} := {Adresse}"; } } //Overrider ToString est utile pour le débug, quand on regarde le contenu d'une liste, c'est ça qui est affiché public override string ToString() { return $"Index: {Index}, Adresse: {Adresse}, Mnémonique: {Mnemonique}"; } } public class SANA_API : EntreesSortie { public SANA_API(string[] LigneCSV, int Index) : base(LigneCSV, Index) { } public override string Texte { get { return $"{Mnemonique} := {Adresse}"; } } public override string ToString() { return $"Index: {Index}, Adresse: {Adresse}, Mnémonique: {Mnemonique}"; } } public class ETOR_API : EntreesSortie { public ETOR_API(string[] LigneCSV, int Index) : base(LigneCSV, Index) { } public override string Texte { get { return $"{Mnemonique} := ({Adresse} AND AOM_I[{Index}] = 0) OR AOM_I[{Index}] = 1;"; } } public override string ToString() { return $"Index: {Index}, Adresse: {Adresse}, Mnémonique: {Mnemonique}"; } } public class STOR_API : EntreesSortie { public STOR_API(string[] LigneCSV, int Index) : base(LigneCSV, Index) { } public override string Texte { get { return $"{Adresse} := ({Mnemonique} AND AOM_O[{Index}] = 0) OR AOM_O[{Index}] = 1;"; } } public override string ToString() { return $"Index: {Index}, Adresse: {Adresse}, Mnémonique: {Mnemonique}"; } }
Je lis le fichier csv de façon à enfaire une liste de tableaux, chaque tableau correspond à une ligne et chaque item d'un tableau à une cellule de cette ligne, tu pourras transposer avec ton dataset.
//Je lis toutes les lignes du CSV, je les splite et j'en fais une liste de tableaux, 1 tableau par ligne du CSV List<string[]> lignes = File.ReadAllLines("Exemple fichier ES Whismeril.csv").Select(l => l.Split(';')).ToList();
Je lis toutes les entrées et sorties pour en faire une liste unique
//Constitution de la liste d'EntreeSortie List<EntreesSortie> entreesSorties = new List<EntreesSortie>(); entreesSorties.AddRange(lignes.Where(l => l.Length > 1 && l[1].Contains("AI_")).Select((l, i) => new EANA_API(l, i))); entreesSorties.AddRange(lignes.Where(l => l.Length > 1 && l[1].Contains("AO_")).Select((l, i) => new SANA_API(l, i))); entreesSorties.AddRange(lignes.Where(l => l.Length > 1 && l[1].Contains("DI.C")).Select((l, i) => new ETOR_API(l, i))); entreesSorties.AddRange(lignes.Where(l => l.Length > 1 && l[1].Contains("DO.C")).Select((l, i) => new STOR_API(l, i)));
Ensuite, j'en extrais le contenu de la balise STSource sous forme de liste, une ligne par item
//Je constitue le contenu de la balise STSource à part, afin de vérifier que c'est correct en débug List<string> stSource = new List<string> { "(*Copies des entrees Analogiques *)" }; stSource.AddRange(entreesSorties.OfType<EANA_API>().Select(e => e.Texte)); stSource.Add(""); stSource.Add("(*Copies des entrees TOR *)"); stSource.AddRange(entreesSorties.OfType<ETOR_API>().Select(e => e.Texte)); stSource.Add(""); stSource.Add("(*Copies des sorties TOR *)"); stSource.AddRange(entreesSorties.OfType<STOR_API>().Select(e => e.Texte)); stSource.Add(""); stSource.Add("(*Copies des sorties Analogiques *)"); stSource.AddRange(entreesSorties.OfType<SANA_API>().Select(e => e.Texte));
Enfin, j'édite le fichier xml
XDocument XmlDoc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"), new XElement("STExchangeFile", new XElement("fileHeader", new XAttribute("company", "Schneider Automation"), new XAttribute("product", "Control Expert V14.1 - 191122A"), new XAttribute("dateTime", "date_and_time#2018-3-12-16:50:53"), new XAttribute("content", "Fichier source ST"), new XAttribute("DTDVersion", "41")), new XElement("contentHeader", new XAttribute("name", "Projet"), new XAttribute("version", "0.0.710"), new XAttribute("dateTime", "date_and_time#2018-2-14-14:39:27")), new XElement("program", new XElement("identProgram", new XAttribute("name", "Copie_E_S"), new XAttribute("type", "section"), new XAttribute("task", "MAST")), new XElement("STSource", string.Join("\n",stSource)), new XElement("dataBlock", from es in entreesSorties select new XElement("variables", new XAttribute("name", es.Mnemonique), new XAttribute("typeName", "INT"), string.IsNullOrWhiteSpace(es.Comment) ? null : new XElement("comment", es.Comment))) ))); XmlDoc.Save("Test.xml");
Je n'arrive pas exactement au même fichier que toi, tu peux tester mon code avec le csv là https://cjoint.com/c/LKpv5bFEyXx
Ce que je n'ai pas compris, c'est comment tu détermines que telle est un int et telle autre un bool?
J'avais commencé à coder les commentaires, mais sans être sûr d'avoir compris, je les ai laissés, tu me diras
16 nov. 2022 à 08:03
Salut Whismeril,
Merci pour ton aide. Je vais regarder plus en détail ton code.
Pour la détermination du type "INT" ou "BOOL", c'est en fonction de l'adresse de ma variable. Sur mon automate, j'ai deux types d'entrées/sorties. Il y a ce qu'on appelle du TOR (tout ou rien = 0 ou 1) et des analogiques (Nombre de points entre 0 et 32768 selon le modèle d'automate). En interne, on a une codification à savoir: DI = Digital input = entrée TOR, DO= Digital output = sortie TOR, AI = analog input = entrée analogique et AO = Analog output = sortie analogique.
Donc lorsque je lit mon fichier, si j'ai DI ou DO dans l'adresse, je sais que c'est un BOOL et si j'ai AI ou AO, ce sera du INT.
En espérant avoir répondu à ton interrogation
16 nov. 2022 à 08:25
Ok, c'est ce que j'avais supposé, mais j'avais quand même un doute sur la terminologie, pour moi (je suis dans la mesures) analogique c'est pas pas un nombre déjà encodé, c'est avant le CAN.
Et puis dans le xml du message #2, il y a aussi des variables de type word, comment on sait pour celles là ?
Dans ce même xml, il y a un attribut topologicalAddress, ça sort d'où ?
Quand au code que j'ai posté hier, teste le, regarde le, mais ne le prends pas pour argent comptant.
Les classes dérivées sont tellement proches les une des autres (entrée et sortie analogique sont identiques et les TOR n'ont qu'un paramètre d'écart dans Texte) que je pense pourvoir ne faire qu'une classe et sans dériver.
Cela dit ce code reste un petit exemple de polymorphisme.
16 nov. 2022 à 08:39
Pour les variables de type "WORD", je ne les déclare pas car c'est du spécifique. Pour faire simple, je récupère les données via une communication avec un module déportées. Il me donne un "WORD" que je viens ensuite décomposer pour en extraire les bits un à un. En gros, j'ai un word par tranche de 16 entrées TOR.
Pour la topogical adresse, c'est une adresse interne dans l'automate mais c'est pareil, c'est trop spécifique au projet donc je ne gère pas. Ce sera fait quand je fais ma config automate.
J'ai repris ton code et il y a juste la transposition de mon dataset en list que je n'arrive pas à faire. J'ai regardé pas mal d'exemple mais j'avoue ne pas bien les comprendre donc pour les mettre en oeuvre....
16 nov. 2022 à 11:13
Y'a pas besoin de liste puisque tu as un dataset.
J'ai utilisé une collection de lignes, chaque ligne étant un tableau.
Un dataset est aussi une collection de lignes, chaque ligne étant une datarow ou un truc dans le genre.
Tu peux modifier les constructeurs pour qu'ils prenent un datarow en paramètre à la place du tableau.
16 nov. 2022 à 11:14
Tu peux aussi, remettre des constructeurs comme tu avais fais avec chacun des paramètres que tu veux utliser.
D'ailleurs, à quoi te sert l'index?
16 nov. 2022 à 11:35
C'est bon, j'ai enfin compris le principe. J'ai modifié pour avoir mon Dataset en entrée et ça fonctionne. J'ai modifié quelques bricoles pour correspondre à ce que je voulais et ça me va. Un grand merci de ton aide Whismeril
Pour répondre à ta question, l'index sert à balayer mon tableau dans le code automate
16 nov. 2022 à 11:40
Oui, donc si je te propose une solution sans l'index ça ne change rien pour toi?
16 nov. 2022 à 11:50
Tant que la partie "texte" est la même que celle que j'ai donné, il n'y a aucun soucis pour moi. Après, j'ai envie de te dire que la solution que tu m'as donné fonctionne donc je ne voudrais pas abuser de ta gentillesse.
16 nov. 2022 à 11:56
Oui, mais comme je te l'ai dit y'a du code redondant. C'est pas bien.
16 nov. 2022 à 18:33
Alors avec une seule classe EntreeSortie codée comme ça
public class EntreesSortie { //pour les index de chaque nature private static int indexAI = 0; private static int indexAO = 0; private static int indexDI = 0; private static int indexDO = 0; /// <summary> /// Le constructeur prend en paramètres un tableau de string qui correspond à une ligne du csv, et l'index /// </summary> /// <param name="LigneCSV"></param> /// <param name="Index"></param> public EntreesSortie(string[] LigneCSV) { this.Mnemonique = LigneCSV[9]; this.Adresse = LigneCSV[1]; this.Comment = $"{LigneCSV[5]} {LigneCSV[7]}"; //on détermine si c'est une entrée ou une sortie if (Adresse.Contains("AI_")) { Nature = Nature.Entree | Nature.Analogique; Index = indexAI++;//on affecte l'index et ensuite la variable static est incrémentée } else if (Adresse.Contains("AO_")) { Nature = Nature.Sortie | Nature.Analogique; Index = indexAO++; } else if (Adresse.Contains("DI.C")) { Nature = Nature.Entree | Nature.TOR; Index = indexDI++; } else if (Adresse.Contains("DO.C")) { Nature = Nature.Sortie | Nature.TOR; Index = indexDO++; } if (Nature == Nature.Indefinie)//il y a un problème on génére une erreur throw new Exception("Y'a un problème"); } /// <summary> /// Retourne un texte qui dépend de la nature de l'instance /// </summary> public string Texte { get { //dans ton dernier fichier exemple, je me suis aperçu ce soir, que les datas sont inversées entre l'entrée et la sorties string champ1 = Nature.HasFlag(Nature.Entree) ? Mnemonique : Adresse; string champ2 = Nature.HasFlag(Nature.Entree) ? Adresse : Mnemonique; if (Nature.HasFlag(Nature.Analogique)) return $"{champ1} := {champ2}"; //de même pour les TOR, y'a un I qui se change en O string io = Nature.HasFlag(Nature.Entree) ? "I" : "0"; return $"{champ1} := ({champ2} AND AOM_{io}[{Index}] = 0) OR AOM_{io}[{Index}] = 1;"; } } public string TypeVariable { get { return Nature.HasFlag(Nature.Analogique) ? "INT" : "BOOL"; } } public string Mnemonique { get; private set; } public string Adresse { get; private set; } public string Comment { get; private set; } public int Index { get; private set; } public Nature Nature { get; private set; } } /// <summary> /// Enumérable permetant de savoir à quoi correspond cette instance /// </summary> /// <remarks>Cet enum est flagable => il peut prendre plusieurs valeurs</remarks> [Flags()] public enum Nature { Indefinie = 0, Entree = 1, Sortie = 2, Analogique = 4, TOR = 8 }
Et la lecture du fichier CSV, puis l'export en xml codé comme ça
//Je lis toutes les lignes du CSV, je les splite et j'en fais une liste de tableaux, 1 tableau par ligne du CSV List<string[]> lignes = File.ReadAllLines("Exemple fichier ES Whismeril.csv").Select(l => l.Split(';')).ToList(); //Constitution de la liste d'EntreeSortie List<EntreesSortie> entreesSorties = lignes.Where(l => l.Length > 1 && (l[1].Contains("AI_") || l[1].Contains("AO_") || l[1].Contains("DI.C") || l[1].Contains("DO.C"))) .Select(l => new EntreesSortie(l)) .ToList(); //Je constitue le contenu de la balise STSource à part, afin de vérifier que c'est correct en débug List<string> stSource = new List<string> { "(*Copies des entrees Analogiques *)" }; stSource.AddRange(entreesSorties.Where(es => es.Nature == (Nature.Entree | Nature.Analogique)).Select(e => e.Texte)); stSource.Add(""); stSource.Add("(*Copies des entrees TOR *)"); stSource.AddRange(entreesSorties.Where(es => es.Nature == (Nature.Entree | Nature.TOR)).Select(e => e.Texte)); stSource.Add(""); stSource.Add("(*Copies des sorties TOR *)"); stSource.AddRange(entreesSorties.Where(es => es.Nature == (Nature.Sortie | Nature.TOR)).Select(e => e.Texte)); stSource.Add(""); stSource.Add("(*Copies des sorties Analogiques *)"); stSource.AddRange(entreesSorties.Where(es => es.Nature == (Nature.Sortie | Nature.Analogique)).Select(e => e.Texte)); XDocument XmlDoc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"), new XElement("STExchangeFile", new XElement("fileHeader", new XAttribute("company", "Schneider Automation"), new XAttribute("product", "Control Expert V14.1 - 191122A"), new XAttribute("dateTime", "date_and_time#2018-3-12-16:50:53"), new XAttribute("content", "Fichier source ST"), new XAttribute("DTDVersion", "41")), new XElement("contentHeader", new XAttribute("name", "Projet"), new XAttribute("version", "0.0.710"), new XAttribute("dateTime", "date_and_time#2018-2-14-14:39:27")), new XElement("program", new XElement("identProgram", new XAttribute("name", "Copie_E_S"), new XAttribute("type", "section"), new XAttribute("task", "MAST")), new XElement("STSource", string.Join("\n",stSource)), new XElement("dataBlock", from es in entreesSorties select new XElement("variables", new XAttribute("name", es.Mnemonique), new XAttribute("typeName", es.TypeVariable), string.IsNullOrWhiteSpace(es.Comment) ? null : new XElement("comment", es.Comment))) ))); XmlDoc.Save("Test.xml");
J'arrive à un fichier plus proche qu'hier, mais pas exactement le même :
- Il y a de tabulations que je n'ai pas mises, je ne sais pas si c'est important, dans l'affirmative, il faut les ajouter dans la propriété Texte.
- Les noms des variables sont différents, le jeu de données d'entrées l'est peut-être encore un peu.
Je me suis servi d'un enumérable flaggable (c'est-à-dire qu'il peut prendre plusieurs valeurs, détails ici) afin de savoir la nature de l'instance (entrée ou sortie, analogique ou TOR).
Tantôt, je teste la valeur exacte, tantôt, une partie (est-ce une entrée ou une sortie).
Le code d'hier, si tu ne le conserves pas dans ton projet, garde le dans un coin comme exemple de polymorphisme.
Celui d'aujourd'hui est un exemple d'enum flaggable.
17 nov. 2022 à 13:39
Salut Whismeril,
Merci beaucoup. Le premier code me semble plus simple d'un point de vue compréhension pour le non-informaticien que je suis. Il consomme sûrement plus de ressource mais c'est pas grave car le code est utilisé une fois, au début du projet et c'est tout donc même si la génération prend 2min de plus, c'est pas ça qui va me tuer vu le temps que je gagne à côté.
Il me reste maintenant à bosser sur le reste de la génération de code mais j'aurai sûrement besoin de tes conseils si tu es ok
17 nov. 2022 à 14:37
Plus de ressources pas sûr, mais, pas de code redondant donc maintenance simplifiée.
Après comme je te l'ai dit l'un ou l'autre son des exemples de 2 implémentations du même besoin