//======================================================================================================================================================================== // CONFIG_CIRCUIT.QML // Ce fichier traite la configuration d'un circuit. La page permet notamment de : // - Modifier la config du circuit (ou de le créer la première fois), // - Supprimer le circuit // La page est appelée depuis la page config_circuits_1, en cliquant sur le circuit à modifier (ou sur un circuit non affecté en vue de sa création) //======================================================================================================================================================================== import QtQuick 2.12 import QtQml.Models import qt.koriolan.shipheart 1.0 Shipheart_page { id: page_config_circuit // Mis en forme : readonly property double pourcentage_largeur_colonne_gauche: 0.75 readonly property double espace_colonnes_principales: 20 readonly property double pourcentage_hauteur_ligne_haut: 1 readonly property double espace_lignes_principales: 20 readonly property double affichage_hauteur_utile: shipheart_hauteur_page - shipheart_hauteur_bandeau_haut - shipheart_hauteur_bandeau_bas readonly property int hauteur_ligne_formulaire: 60 readonly property double pourcentage_largeur_labels_formulaire: 0.4 readonly property int hauteur_bouton_droit: 80 readonly property double pourcentage_bandeau_bas_largeur_zone_retour: 1 readonly property int periode_init_raffraichissement_parametres: 1 // En ms readonly property int periode_raffraichissement_parametres: 1000 // En ms readonly property int step_timer_appui_long: 30 // en ms readonly property int type_boite_information_alerte_changement_affectation: 0 readonly property int type_boite_information_supprimer: 1 // Affichage : property int protection_mode: 0 property bool flag_init: true // Permet de bloquer certains affichage tant que l'init n'est pas terminée // Données : property int valeur_timer_appui_long: 0 property int id_circuit: 0 property int priorite_affichage_accueil: 0 property int adresse_module: 0 property int no_circuit: 0 property int id_circuit_esclave: 0 property string requete_differee: "" // Permet de mémoriser le contenu d'une resquête qui sera exécuté après expiration d'un timer dédié. property int mode_commande_circuit: 0 property int old_consigne: 0 property var chaines_cdes_auto property int nb_cdes_auto: 0 // Modèles : // Note : les modèles chargés dans 'main.qml' n'ont pas à être rechargés dans les pages suivantes //=========================================================== // Timer periode raffraichissement parametres : //=========================================================== Timer { id: timer_raffraichissement_parametres interval: periode_init_raffraichissement_parametres triggeredOnStart: false running: true repeat: true onTriggered: { if (interval == periode_init_raffraichissement_parametres) { // Premier passage, 1ms après le premier chargement interval = periode_raffraichissement_parametres; init_page(); } else { } } } //=========================================================== // Timer pour gérer les appuis longs : //=========================================================== Timer { id: timer_appui_long interval: step_timer_appui_long triggeredOnStart: false repeat: true onTriggered: { if (valeur_timer_appui_long < shipheart_mouse_press_and_hold_interval_tres_long) valeur_timer_appui_long+= step_timer_appui_long; else // Le fait de ne pas utilise le OnPressandHold permet d'être sût que la sortie se fait au même moment que la fin du comptage (sinon, on peut avoir de petits décalages) { timer_appui_long.running = false; valeur_timer_appui_long = 0; if (mousearea_bouton_supprimer.pressed) { if (check_avant_suppression() !== -1) { suppression_circuit(); // Mise à jour des données saisies dans la BDD et reconfiguration par l'application pour prise en compte. if (requete_differee === "") timer_tempo_reconfiguration.restart(); // Si pas de requete différée, on lance le timer de reconfig immédiatement. else // Si requete différée : { timer_requete_differee.restart(); // ... on lance en le timer de requete différée shipheart_clic(); } } } } } } //=========================================================== // Lorsque la page est sur le point d'être affichée dans la pile : //=========================================================== // StackView.onActivating: { // } // Titre de la page : Shipheart_titre_1 {titre:qsTr("Configuration du circuit"); hauteur: shipheart_hauteur_bandeau_haut} //------------------------------------------------------- // Ecran Haut - Gauche : //------------------------------------------------------- Rectangle { id: zone_affichage_haut_gauche x: 0 y: shipheart_hauteur_bandeau_haut; width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: (affichage_hauteur_utile * pourcentage_hauteur_ligne_haut) - (espace_lignes_principales / 2); color: "transparent" ListView { id: grille_principale width: parent.width height: parent.height snapMode: GridView.SnapToRow // L'arret de l'affichage se fera sur une rangée entière clip: true // Nécessaire pour que les Delegates s'arretent à l'intérieur de la GridView model: modele_grille_principale footer: Rectangle { // Permet de dégager la place suffisante en fin de GridView pour accéder même au dernier élément lorsque que clavier est déplié height: shipheart_hauteur_clavier color: "transparent" } ObjectModel { id: modele_grille_principale //------------------------------------------------------------------------------- // Ligne de formulaire : Nom Rectangle { width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" Shipheart_formulaire_label { text: qsTr("Nom du circuit") width: parent.width * pourcentage_largeur_labels_formulaire couleur: (champ_formulaire_Nom.text !== "") ? shipheart_formulaire_couleur_texte_par_defaut : shipheart_formulaire_couleur_texte_en_erreur } Shipheart_formulaire_textfield { id: champ_formulaire_Nom width: parent.width * (1 - pourcentage_largeur_labels_formulaire) x: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Affectation Rectangle { width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: (adresse_module !== 0) // On n'autorise pas le changement d'affectation sur ShipBase Shipheart_formulaire_label { text: qsTr("Affectation") width: parent.width * pourcentage_largeur_labels_formulaire couleur: (champ_formulaire_Affectation.currentIndex !== 0) ? shipheart_formulaire_couleur_texte_par_defaut : shipheart_formulaire_couleur_texte_en_erreur } Shipheart_formulaire_combobox { id: champ_formulaire_Affectation model: ListModel { } width: parent.width * (1 - pourcentage_largeur_labels_formulaire) prefixe_repos: flag_init ? "" : champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).prefixe_repos onActivated: { shipheart_clic(); // Mise à jour de la valeur de seuil de disjonction en accord avec l'intensité maxi par circuit de la nouvelle carte sélectionnée (SDIR #185) : if (champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).valeur !== "-1/0") // Permet de garder les valeurs déjà enregistrées pour utilisation futures { var new_affectation = champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).valeur.split('/'); raffraichissement_modele_intensite_seuil_haut(new_affectation[0], champ_formulaire_Intensite_seuil_haut.model.get(champ_formulaire_Intensite_seuil_haut.currentIndex).valeur, champ_formulaire_Circuit_esclave.model.get(champ_formulaire_Circuit_esclave.currentIndex).valeur); } } } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Circuit renfort Rectangle { width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: !flag_init && (adresse_module !== 0) // Non autorisé sur ShipBase && (champ_formulaire_Affectation.currentIndex !== 0) && ((champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).type === shipheart_type_module_shippower812) || (champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).type === shipheart_type_module_shippower8DC) ) // Si l'affectation a changée depuis le dernier enregistrement, on dévalide l'accès au circuit esclave car le module a pu être changé et le modèle des circuits escalves n'est plus forcément à jour... : && (champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).valeur === adresse_module + "/" + no_circuit) && (id_circuit > 0) // SDIR #186 Shipheart_formulaire_label { text: qsTr("Circuit renfort") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_combobox { id: champ_formulaire_Circuit_esclave model: ListModel { } width: parent.width * (1 - pourcentage_largeur_labels_formulaire) prefixe_repos: flag_init ? "" : champ_formulaire_Circuit_esclave.model.get(champ_formulaire_Circuit_esclave.currentIndex).prefixe_repos onActivated: { shipheart_clic(); // Mise à jour de la valeur de seuil de disjonction en accord avec l'intensité maxi par circuit du fait du changement de circuit renfort : var new_affectation = champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).valeur.split('/'); raffraichissement_modele_intensite_seuil_haut(new_affectation[0], champ_formulaire_Intensite_seuil_haut.model.get(champ_formulaire_Intensite_seuil_haut.currentIndex).valeur, champ_formulaire_Circuit_esclave.model.get(champ_formulaire_Circuit_esclave.currentIndex).no); // ATTENTION : le 3ème paramètre ci-dessus est le No et non l'ID de l'esclave (que l'on n'a pas à ce stade puisqu'il n'est pas forcément créé). On utilise donc le n° puisque ce que l'on va en faire est juste de savoir s'il existe ou non. On n'a pas besoin de son ID à proprement parler. } } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Famille Rectangle { width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: !flag_init && (champ_formulaire_Affectation.currentIndex !== 0) Shipheart_formulaire_label { text: qsTr("Groupe de circuits") width: parent.width * pourcentage_largeur_labels_formulaire couleur: (champ_formulaire_Famille.currentIndex !== 0) ? shipheart_formulaire_couleur_texte_par_defaut : shipheart_formulaire_couleur_texte_en_erreur } Shipheart_formulaire_combobox { id: champ_formulaire_Famille model: ListModel { } width: parent.width * (1 - pourcentage_largeur_labels_formulaire) onActivated: { shipheart_clic(); } } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Mode de commande Rectangle { width: parent.width height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: !flag_init && (adresse_module !== 0) // Non autorisé sur ShipBase && (champ_formulaire_Affectation.currentIndex !== 0) && (champ_formulaire_Famille.currentIndex !== 0) && ((champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).type === shipheart_type_module_shippower812) || (champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).type === shipheart_type_module_shippower8DC) ) Shipheart_formulaire_label { text: qsTr("Mode de commande") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_combobox { id: champ_formulaire_Mode_commande model: ListModel { } width: parent.width * (1 - pourcentage_largeur_labels_formulaire) onActivated: { shipheart_clic(); } } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Vitesse de démarrage Rectangle { width: parent.width height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: !flag_init && (adresse_module !== 0) // Non autorisé sur ShipBase && (champ_formulaire_Affectation.currentIndex !== 0) && (champ_formulaire_Famille.currentIndex !== 0) && ((champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).type === shipheart_type_module_shippower812) || (champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).type === shipheart_type_module_shippower8DC) ) && (champ_formulaire_Mode_commande.model.get(champ_formulaire_Mode_commande.currentIndex).valeur > 0) Shipheart_formulaire_label { text: qsTr("Vitesse de démarrage/arrêt") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_combobox { id: champ_formulaire_Step_time model: ListModel { } width: parent.width * (1 - pourcentage_largeur_labels_formulaire) onActivated: { shipheart_clic(); } } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Time-out Rectangle { width: parent.width height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: !flag_init && (adresse_module !== 0) // Non autorisé sur ShipBase && (champ_formulaire_Affectation.currentIndex !== 0) && (champ_formulaire_Famille.currentIndex !== 0) && (champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).type !== shipheart_type_module_shipbase) Shipheart_formulaire_label { text: qsTr("Commande impulsionnelle") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_combobox { id: champ_formulaire_Time_out model: ListModel { } width: parent.width * (1 - pourcentage_largeur_labels_formulaire) onActivated: { shipheart_clic(); } } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Seuil de disjonction Rectangle { width: parent.width height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: !flag_init && (adresse_module !== 0) // Non autorisé sur ShipBase && (champ_formulaire_Affectation.currentIndex !== 0) && (champ_formulaire_Famille.currentIndex !== 0) && ((champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).type === shipheart_type_module_shippower812) || (champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).type === shipheart_type_module_shippower8DC) ) Shipheart_formulaire_label { text: qsTr("Seuil de disjonction") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_combobox { id: champ_formulaire_Intensite_seuil_haut model: ListModel { } width: parent.width * (1 - pourcentage_largeur_labels_formulaire) onActivated: { shipheart_clic(); } } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Intensite_seuil_haut_tempo Rectangle { width: parent.width height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: !flag_init && (adresse_module !== 0) // Non autorisé sur ShipBase && (champ_formulaire_Affectation.currentIndex !== 0) && (champ_formulaire_Famille.currentIndex !== 0) && ((champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).type === shipheart_type_module_shippower812) || (champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).type === shipheart_type_module_shippower8DC) ) Shipheart_formulaire_label { text: qsTr("Vitesse de disjonction") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_combobox { id: champ_formulaire_Intensite_seuil_haut_tempo model: ListModel { } width: parent.width * (1 - pourcentage_largeur_labels_formulaire) onActivated: { shipheart_clic(); } } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Intensite_coeff_filtrage Rectangle { width: parent.width height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" /* visible: !flag_init && (champ_formulaire_Affectation.currentIndex !== 0) && (champ_formulaire_Famille.currentIndex !== 0) */ visible: false Shipheart_formulaire_label { text: qsTr("Filtrage du courant consommé") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_combobox { id: champ_formulaire_Intensite_coeff_filtrage model: ListModel { } width: parent.width * (1 - pourcentage_largeur_labels_formulaire) onActivated: { shipheart_clic(); } } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } //------------------------------------------------------------------------------- // Ligne de formulaire : Masquage Rectangle { width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: visible ? hauteur_ligne_formulaire : 0 color: "transparent" visible: !flag_init && (champ_formulaire_Affectation.currentIndex !== 0) && (champ_formulaire_Famille.currentIndex !== 0) Shipheart_formulaire_label { text: qsTr("Masquer sur la page d'accueil") width: parent.width * pourcentage_largeur_labels_formulaire } Shipheart_formulaire_checkbox { id: champ_formulaire_Masquage width: parent.width * (1 - pourcentage_largeur_labels_formulaire) } Shipheart_formulaire_ligne_separation { haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse } } } // Fin de modele grille principale (ObjectModel ) } } //------------------------------------------------------- // Ecran Droite : //------------------------------------------------------- Rectangle { id: zone_affichage_droite x: zone_affichage_haut_gauche.width + espace_colonnes_principales y: shipheart_hauteur_bandeau_haut; width: (shipheart_largeur_page * (1 - pourcentage_largeur_colonne_gauche)) - (espace_colonnes_principales / 2) height: (affichage_hauteur_utile * pourcentage_hauteur_ligne_haut) - (espace_lignes_principales / 2); color: "transparent" Column { anchors.fill: parent spacing: 10 //....................................................... // Bouton Enregistrer/créer : //....................................................... Rectangle { width: parent.width height: hauteur_bouton_droit color: shipheart_couleur_fond_bouton radius: shipheart_rayon_bouton visible: // (!clavier.active) && // SDIR #255 (champ_formulaire_Nom.text !== "") && ( ( (champ_formulaire_Affectation.currentIndex !== 0) && (champ_formulaire_Famille.currentIndex !== 0) ) || ( (id_circuit > 0) // Pour un circuit existant, ... && (champ_formulaire_Famille.currentIndex !== 0) ) ) // ... on autorise l'affectation à Aucune Text { anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter } font.pixelSize: 20 text: (id_circuit === 0) ? qsTr("Créer le circuit") : qsTr("Enregistrer") color: couleur_blanc_casse } MouseArea { anchors.fill: parent onClicked: { shipheart_clic(); if (id_circuit !== 0) mise_a_jour_circuit(); // Mise à jour des données saisies dans la BDD et reconfiguration par l'application pour prise en compte. else creation_circuit(); if (requete_differee === "") timer_tempo_reconfiguration.restart(); // Si pas de requete différée, on lance le timer de reconfig immédiatement. else // Si requete différée : { shipheart_clic(); boite_information.niveau = 1 boite_information.imageTitreSource = "/images/ampoule.png" boite_information.message = qsTr("L'affectation du circuit vient d'être modifiée alors que le circuit était actif. \nAvant d'effectuer ce changement, le circuit a été passé sur OFF.\n\nPensez à le réactiver si besoin...") boite_information.type = type_boite_information_alerte_changement_affectation; boite_information.open(); // - on affiche la boite d'info pour signaler la désactivation du circuit timer_requete_differee.restart(); // - On lance en // le timer de requete différée } } } } //....................................................... // Bouton Supprimer //....................................................... Rectangle { width: parent.width height: hauteur_bouton_droit color: shipheart_couleur_fond_bouton radius: shipheart_rayon_bouton visible: (!clavier.active) && // Si le clavier est déplié... (id_circuit !== 0) && // ... ou si création (adresse_module !== 0) // ... ou si circuit de ShipBase, on ne propose pas le bouton Rectangle { // Barre grandissante pour montrer durée d'appui vs tempo nécessaire : width: (valeur_timer_appui_long / shipheart_mouse_press_and_hold_interval_tres_long) * parent.width height: parent.height color: couleur_rouge_transparent radius: shipheart_rayon_bouton visible: mousearea_bouton_supprimer.pressed } Text { anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter } font.pixelSize: 20 text: qsTr("Supprimer") color: couleur_blanc_casse } MouseArea { id: mousearea_bouton_supprimer anchors.fill: parent onPressed: { // Déclenché lors de l'appui inital shipheart_clic(); timer_appui_long.running = true; valeur_timer_appui_long = 0; } onClicked: { // Déclenché si l'appui n'a pas été suffisement long pour avoir un Press&Hold : timer_appui_long.running = false; valeur_timer_appui_long = 0; } onExited: { // Déclenché si le doigt sort de la zone du bouton (sinon, on continue à compter alors qu'on est sorti de la zone et même relaché le doigt !!) timer_appui_long.running = false; valeur_timer_appui_long = 0; } } } //....................................................... // Timer de requêtes différées //....................................................... Timer { id: timer_requete_differee // Timer lancé uniquement si une requete différée est à traiter interval: 250 // Théoriquement, le traitement par l'appli de la requete précédente sera fait dans les 100ms. triggeredOnStart: false running: false repeat: false onTriggered: { bdd.requete_unique(requete_differee); // A l'expiration du timer, la requete différée est exécutée synchro_bdd(shipheart_type_synchro_config); // Demande de reconfiguration système via la BDD car on a modifié des valeurs de configuration... timer_tempo_reconfiguration.restart(); // Lancement du timer d'attente de fin de reconfig } } //....................................................... // Timer de reconfiguration //....................................................... Timer { id: timer_tempo_reconfiguration interval: 250 // Cette tempo n'est utilisée que pour le premier cycle triggeredOnStart: false running: false repeat: true onTriggered: { if (bdd.check_fin_configuration()) { timer_tempo_reconfiguration.stop(); if (requete_differee !== "") requete_differee = ""; // Par principe if (boite_information.opened === false) stackView.pop(); // S'il y a eu une boite d'info ouverte, c'est le clic sur Ok sur la boite d'info qui fera le POP. } else timer_tempo_reconfiguration.interval = 100 // Tempo plus courte pour les lectures suivantes") } } } } //------------------------------------------------------- // Bandeau bas : //------------------------------------------------------- Row { x: 0 y: shipheart_hauteur_page - shipheart_hauteur_bandeau_bas; width: shipheart_largeur_page; height: shipheart_hauteur_bandeau_bas; spacing: 5 padding: 5 //................................................. // Bouton retour //................................................. Rectangle { id: bandeau_bas_zone_retour width: (parent.width * pourcentage_bandeau_bas_largeur_zone_retour) - (2 * parent.padding) height: shipheart_hauteur_bandeau_bas - parent.topPadding - parent.bottomPadding; radius: shipheart_rayon_bouton color: shipheart_couleur_fond_bouton Image { source: "/images/icone_retour.png" sourceSize.height: 30 anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter } } MouseArea { // Zone d'interaction. On est obligé de la mettre dans la grille pour que Rectangle et MouseArea soient frères ou parent/enfant ET qu'on n'occupe qu'un espace dans la grille. id: mouse_area_bandeau_bas_zone_retour anchors.fill: parent onClicked: { shipheart_clic(); stackView.pop() } } } } //------------------------------------------------------- // Boite de validation : //------------------------------------------------------- Shipheart_boite_dialogue { id: boite_information onClicked: { //console.log("Le Bouton [" + bouton + "] est appuyé"); switch (type) { case type_boite_information_alerte_changement_affectation: stackView.pop(); // Retour à la page de config des circuits (a priori, par appui sur Ok puisque c'est le seul bouton valide...) break; case type_boite_information_supprimer: break; default: ; } } } //=========================================================== // Busy Indicator : //=========================================================== Shipheart_busy_indicator { id: busy_indicator running: timer_tempo_reconfiguration.running } // Note : il est inutile de prévoir un Mousearea pour sortir de l'économiseur sur cette page puisqu'il // est systématiquement bloqué pour toutes les pages lancées depuis 'Paramètres Avancés'. //============================================================================================================= // Init de la page //============================================================================================================= function init_page() { var req, res; var nb; var i, j, k; var type_carte; var texte_carte; var texte_circuit; var nb_circuits; var defaut_no_carte = -1; var defaut_no_circuit = -1; var defaut_circuit_esclave = 0; var defaut_mode_commande = shipheart_mode_commande_circuit_tor; var intensite_coeff_filtrage, defaut_intensite_coeff_filtrage = 16; var intensite_seuil_haut; var intensite_seuil_haut_tempo, defaut_intensite_seuil_haut_tempo = 500; var step_time, defaut_step_time = 20; var time_out, defaut_time_out = 0; var id_famille, defaut_id_famille = 0; // Note préliminaire : // Chaque circuit est affecté à un n° de module (entre O et ...) ET à un n° de circuit sur le module (entre 0 et ...). // Le modèle d'affectation de cette page utilise donc 'adresse_module/no_circuit' comme valeur d'identification unique. // La valeur d'affectation 'Aucune' utilise la valeur particulière '-1/-1' pour être identifiée. // Dans la BDD, les valeurs de Adresse_module et No_circuit sont reportées telles qu'elles. //console.log("Id du circuit = " + id_circuit); if (id_circuit > 0) // Cas d'une modification de circuit existant : { req = 'SELECT Nom, '; req += ' Adresse_module, '; req += ' No_circuit, '; req += ' ID_Circuit_esclave, '; req += ' Mode_commande, '; req += ' Old_consigne, '; req += ' Intensite_coeff_filtrage, '; req += ' Intensite_seuil_haut, '; req += ' Intensite_seuil_haut_tempo, '; req += ' Step_time, '; req += ' Time_out, '; req += ' ID_Famille, '; req += ' Priorite_affichage_accueil '; req += ' FROM TB_Circuits '; req += ' WHERE Cle_primaire=' + id_circuit + ' '; //console.log("Requête = " + req) res = bdd.requete_unique(req); //--------------------------------------------------------------- // Mise à jour du champs de saisie de chaque zone de formulaire : i = 0; champ_formulaire_Nom.text = res[i ++]; adresse_module = Number(res[i ++]); no_circuit = Number(res[i ++]); id_circuit_esclave = Number(res[i ++]); mode_commande_circuit = Number(res[i ++]); old_consigne = Number(res[i ++]); intensite_coeff_filtrage = Number(res[i ++]); intensite_seuil_haut = Number(res[i ++]); intensite_seuil_haut_tempo = Number(res[i ++]); step_time = Number(res[i ++]); time_out = Number(res[i ++]); id_famille = Number(res[i ++]); priorite_affichage_accueil = Number(res[i ++]); if (priorite_affichage_accueil <= 0) champ_formulaire_Masquage.checked = true; else champ_formulaire_Masquage.checked = false; } else // Cas d'une création de circuit : { champ_formulaire_Nom.text = ""; adresse_module = defaut_no_carte; no_circuit = defaut_no_circuit; id_circuit_esclave = defaut_circuit_esclave; mode_commande_circuit = defaut_mode_commande; old_consigne = 0; intensite_coeff_filtrage = defaut_intensite_coeff_filtrage; intensite_seuil_haut = max_intensite_carte(adresse_module, id_circuit_esclave); // SDIR #185 intensite_seuil_haut_tempo = defaut_intensite_seuil_haut_tempo; step_time = defaut_step_time; time_out = defaut_time_out; id_famille = defaut_id_famille; champ_formulaire_Masquage.checked = false; } //console.log("circuit esclave = " + circuit_esclave); //--------------------------------------------------------------------------------------- // Affectation et Circuit esclave : champ_formulaire_Affectation.model.clear(); champ_formulaire_Affectation.model.append( { "type": -1, "valeur": defaut_no_carte + "/" + defaut_no_circuit, "texte": qsTr("Non affecté"), "groupe": false, "prefixe_repos": "", "actif": true } ); champ_formulaire_Circuit_esclave.model.clear(); champ_formulaire_Circuit_esclave.model.append({ "no": 0, "valeur": 0, "texte": qsTr("Aucun"), "prefixe_repos": "", "actif": true}); // Recherche des modules et création des enregistrements correspondant du modèle (ligne de groupe pour la carte + 8 lignes de circuits "non affectés" par défaut) : req = 'SELECT Adresse_k_bus, '; req += ' Type, '; req += ' Presence '; req += ' FROM TB_Modules_config '; req += ' WHERE '; req += ' ( Type=' + shipheart_type_module_shipbase + ' '; req += ' OR Type='+shipheart_type_module_shippower812+' '; req += ' OR Type='+shipheart_type_module_shippower4AC+' '; req += ' OR Type='+shipheart_type_module_shippower8DC+') '; req += ' AND '; req += ' ( Presence=1 '; req += ' OR Adresse_k_bus IN (SELECT Adresse_module FROM TB_Circuits GROUP BY Adresse_module ORDER BY Adresse_module) ) '; req += ' ORDER BY Adresse_k_bus'; //console.log("req = [ " + req + "; ]"); nb = bdd.requete(req); for (i = 0; i < nb; i ++) { res = bdd.lecture_ligne(); if (!res.isEmpty) { //console.log("carte trouvée : adresse= " + res[0] + " et Type=" + res[1]); nb_circuits = 0; switch(Number(res[1])) { //------------------------------- case shipheart_type_module_shipbase: type_carte = shipheart_type_module_shipbase; texte_carte = "ShipBase"; if (shipheart_generation_shipbase === shipheart_generation_shipbase_v2) nb_circuits = 3; else nb_circuits = 2; break; //------------------------------- case shipheart_type_module_shippower812: type_carte = shipheart_type_module_shippower812; texte_carte = qsTr("ShipPower812 [@ %1]").arg(res[0]); nb_circuits = 8; break; //------------------------------- case shipheart_type_module_shippower4AC: type_carte = shipheart_type_module_shippower4AC; texte_carte = qsTr("ShipPower4AC [@ %1]").arg(res[0]); nb_circuits = 4; break; //------------------------------- case shipheart_type_module_shippower8DC: type_carte = shipheart_type_module_shippower8DC; texte_carte = qsTr("ShipPower8DC [@ %1]").arg(res[0]); nb_circuits = 8; break; //------------------------------- default: type_carte = -1; console.log ("Type de carte inconnu dans 'init_page()'..."); break; } if (type_carte === -1) continue; // Ajout de l'entete du module : champ_formulaire_Affectation.model.append({ "type": type_carte, "valeur": "", "texte": texte_carte, "groupe": true, "prefixe_repos": "", "actif": false } ); // Création des entrées du modèle pour tous les circuits du module : for (j = 0; j < nb_circuits; j ++) { champ_formulaire_Affectation.model.append({ "type": type_carte, "valeur": Number(res[0]) + "/" + Number(j), "texte": qsTr("Circuit %1").arg(Number(j+1)), "groupe": false, "prefixe_repos": texte_carte + " - ", // "actif": true } ); "actif": (Number(res[2]) !== 0) } ); } // Si le module en cours est le module sur lequel le circuit est positionné, on rempli au passage le modèle des circuits renfort : if (adresse_module === Number(res[0])) { for (j = 0; j < nb_circuits; j ++) { champ_formulaire_Circuit_esclave.model.append({ "no": (j+1), "valeur": 0, "texte": qsTr("Circuit %1").arg(Number(j+1)), "prefixe_repos": texte_carte + " - ", "actif": true}); } } } } // Recherche des circuits présents et mise à jour des lignes correspondantes du modèle : var actif; req = 'SELECT '; req += ' Nom, '; req += ' Adresse_module, '; req += ' No_circuit, '; req += ' Cle_primaire '; req += ' FROM TB_Circuits '; req += ' WHERE Adresse_module>=0 '; // Evite qu'on "empile" sur le "Non affecté" tous les circuits non affectés... req += ' ORDER BY Adresse_module, No_circuit'; //console.log("req = [ " + req + "; ]"); nb_circuits = bdd.requete(req); for (i = 0; i < nb_circuits; i ++) { res = bdd.lecture_ligne(); if (!res.isEmpty) { if (Number(res[3]) === id_circuit) actif = true; // On laisse actif le choix actuel. else actif = false; // Les autres circuits présents sont par contre rendus inactifs. // On n'a pas d'autre choix que de parcourir toutes les entrées du modèle pour rechercher l'entrée dont le N° de carte / N° de circuit matche avec le circuit en cours : for (k = 0; k < champ_formulaire_Affectation.count; k ++) { if (champ_formulaire_Affectation.model.get(k).valeur === (res[1] + "/" + res[2])) { if (actif) texte_circuit = champ_formulaire_Affectation.model.get(k).texte; else texte_circuit = qsTr("%1 - %2").arg(champ_formulaire_Affectation.model.get(k).texte).arg(res[0]); champ_formulaire_Affectation.model.set(k, { "valeur": Number(res[1]) + "/" + Number(res[2]), "texte": texte_circuit, "actif": actif } ); break; // Il est inutile de continuer à boucler dès qu'on a trouvé l'entrée recherchée... } } // Recherche pour cicuit esclave : if (adresse_module === Number(res[1])) // Si on est sur la carte du circuit en cours { if (Number(res[3]) === id_circuit_esclave) actif = true; // On laisse actif le choix actuel. else actif = false; // Les autres circuits présents sont par contre rendus inactifs. // On n'a pas d'autre choix que de parcourir toutes les entrées du modèle pour rechercher l'entrée dont le N° de carte / N° de circuit matche avec le circuit en cours : for (k = 0; k < champ_formulaire_Circuit_esclave.count; k ++) { if (champ_formulaire_Circuit_esclave.model.get(k).no === (Number(res[2]) + 1)) { if (actif) texte_circuit = champ_formulaire_Circuit_esclave.model.get(k).texte; else texte_circuit = qsTr("%1 - %2").arg(champ_formulaire_Circuit_esclave.model.get(k).texte).arg(res[0]); champ_formulaire_Circuit_esclave.model.set(k, { "no": (Number(res[2]) + 1), "valeur": Number(res[3]), "texte": texte_circuit, "actif": actif } ); break; // Il est inutile de continuer à boucler dès qu'on a trouvé l'entrée recherchée... } } } } } // Positionnement de l'index sur la valeur en cours : i = recherche_index_valeur_modele(adresse_module + "/" + no_circuit, champ_formulaire_Affectation.model, "Affectation"); if (i === -1) champ_formulaire_Affectation.currentIndex = recherche_index_valeur_modele(defaut_no_carte + "/" + defaut_no_circuit, champ_formulaire_Affectation.model, "Affectation"); else champ_formulaire_Affectation.currentIndex = i; // Positionnement de l'index sur la valeur en cours : i = recherche_index_valeur_modele(id_circuit_esclave, champ_formulaire_Circuit_esclave.model, "Circuit_esclave"); if (i === -1) champ_formulaire_Circuit_esclave.currentIndex = recherche_index_valeur_modele(defaut_circuit_esclave, champ_formulaire_Circuit_esclave.model, "Circuit_esclave"); else champ_formulaire_Circuit_esclave.currentIndex = i; //--------------------------------------------------------------------------------------- // Mode de commande : champ_formulaire_Mode_commande.model.clear(); champ_formulaire_Mode_commande.model.append({"valeur": defaut_mode_commande, "texte": qsTr("On-Off") }); champ_formulaire_Mode_commande.model.append({"valeur": shipheart_mode_commande_circuit_soft_tor, "texte": qsTr("On-Off progressif") }); champ_formulaire_Mode_commande.model.append({"valeur": shipheart_mode_commande_circuit_soft_variable, "texte": qsTr("Variateur") }); // Positionnement de l'index sur la valeur en cours : i = recherche_index_valeur_modele(mode_commande_circuit, champ_formulaire_Mode_commande.model, "Mode_commande"); if (i === -1) champ_formulaire_Mode_commande.currentIndex = recherche_index_valeur_modele(defaut_mode_commande, champ_formulaire_Mode_commande.model, "Mode_commande"); else champ_formulaire_Mode_commande.currentIndex = i; //--------------------------------------------------------------------------------------- // Coefficient de filtrage du courant (valeur en nombre d'échantillons ; mini = 1): champ_formulaire_Intensite_coeff_filtrage.model.clear(); champ_formulaire_Intensite_coeff_filtrage.model.append({"valeur": 1, "texte": qsTr("Aucun filtrage") }); champ_formulaire_Intensite_coeff_filtrage.model.append({"valeur": 4, "texte": qsTr("Très faible") }); champ_formulaire_Intensite_coeff_filtrage.model.append({"valeur": 8, "texte": qsTr("Faible") }); champ_formulaire_Intensite_coeff_filtrage.model.append({"valeur": defaut_intensite_coeff_filtrage, "texte": qsTr("Moyen") }); champ_formulaire_Intensite_coeff_filtrage.model.append({"valeur": 64, "texte": qsTr("Elevé") }); champ_formulaire_Intensite_coeff_filtrage.model.append({"valeur": 96, "texte": qsTr("Très élevé") }); // Positionnement de l'index sur la valeur en cours : i = recherche_index_valeur_modele(intensite_coeff_filtrage, champ_formulaire_Intensite_coeff_filtrage.model, "Intensite_coeff_filtrage"); if (i === -1) champ_formulaire_Intensite_coeff_filtrage.currentIndex = recherche_index_valeur_modele(defaut_intensite_coeff_filtrage, champ_formulaire_Intensite_coeff_filtrage.model, "Intensite_coeff_filtrage"); else champ_formulaire_Intensite_coeff_filtrage.currentIndex = i; //--------------------------------------------------------------------------------------- // Seuil de disjonction (en mA) : intensite_seuil_haut = raffraichissement_modele_intensite_seuil_haut(adresse_module, intensite_seuil_haut, id_circuit_esclave); // L'intensité est ajustée au passage si nécessaire (notamment si le max de la nouvelle carte est < valeur courante) //--------------------------------------------------------------------------------------- // Vitesse de disjonction (valeur en ms): champ_formulaire_Intensite_seuil_haut_tempo.model.clear(); champ_formulaire_Intensite_seuil_haut_tempo.model.append({"valeur": 50, "texte": qsTr("Très rapide") }); champ_formulaire_Intensite_seuil_haut_tempo.model.append({"valeur": 200, "texte": qsTr("Rapide") }); champ_formulaire_Intensite_seuil_haut_tempo.model.append({"valeur": defaut_intensite_seuil_haut_tempo, "texte": qsTr("Moyenne") }); champ_formulaire_Intensite_seuil_haut_tempo.model.append({"valeur": 2000, "texte": qsTr("Lente") }); champ_formulaire_Intensite_seuil_haut_tempo.model.append({"valeur": 5000, "texte": qsTr("Très lente") }); // Positionnement de l'index sur la valeur en cours : i = recherche_index_valeur_modele(intensite_seuil_haut_tempo, champ_formulaire_Intensite_seuil_haut_tempo.model, "Intensite_seuil_haut_tempo"); if (i === -1) champ_formulaire_Intensite_seuil_haut_tempo.currentIndex = recherche_index_valeur_modele(defaut_intensite_seuil_haut_tempo, champ_formulaire_Intensite_seuil_haut_tempo.model, "Intensite_seuil_haut_tempo"); else champ_formulaire_Intensite_seuil_haut_tempo.currentIndex = i; //--------------------------------------------------------------------------------------- // Vitesse démarrage : // Note 26/01/2023 : pour les SP812, le nb de steps est passé ce jour à [nouvelle_consigne - ancienne_consigne] / 2 soit, en général, 50. Auparavant, le nb de steps était de 25. // pour les SP8DC, le nombre de pas est fixé à 50 et il est réduit si [nouvelle_consigne - ancienne_consigne] < 50. champ_formulaire_Step_time.model.clear(); champ_formulaire_Step_time.model.append({"valeur": 5, "texte": qsTr("Très rapide") }); champ_formulaire_Step_time.model.append({"valeur": 10, "texte": qsTr("Rapide") }); champ_formulaire_Step_time.model.append({"valeur": defaut_step_time, "texte": qsTr("Moyenne") }); champ_formulaire_Step_time.model.append({"valeur": 40, "texte": qsTr("Lente") }); champ_formulaire_Step_time.model.append({"valeur": 80, "texte": qsTr("Très lente") }); // Positionnement de l'index sur la valeur en cours : i = recherche_index_valeur_modele(step_time, champ_formulaire_Step_time.model, "Step-time"); if (i === -1) champ_formulaire_Step_time.currentIndex = recherche_index_valeur_modele(defaut_step_time, champ_formulaire_Step_time.model, "Step-time"); else champ_formulaire_Step_time.currentIndex = i; //--------------------------------------------------------------------------------------- // Time-out (en x 100ms) : champ_formulaire_Time_out.model.clear(); champ_formulaire_Time_out.model.append({"valeur": defaut_time_out, "texte": qsTr("Non") }); champ_formulaire_Time_out.model.append({"valeur": (1), "texte": qsTr("1 seconde") }); champ_formulaire_Time_out.model.append({"valeur": (2), "texte": qsTr("2 secondes") }); champ_formulaire_Time_out.model.append({"valeur": (5), "texte": qsTr("5 secondes") }); champ_formulaire_Time_out.model.append({"valeur": (15), "texte": qsTr("15 secondes") }); champ_formulaire_Time_out.model.append({"valeur": (30), "texte": qsTr("30 secondes") }); champ_formulaire_Time_out.model.append({"valeur": (45), "texte": qsTr("45 secondes") }); champ_formulaire_Time_out.model.append({"valeur": (1*60), "texte": qsTr("1 minute") }); champ_formulaire_Time_out.model.append({"valeur": (5*60), "texte": qsTr("5 minutes") }); champ_formulaire_Time_out.model.append({"valeur": (15*60), "texte": qsTr("15 minutes") }); champ_formulaire_Time_out.model.append({"valeur": (60*60), "texte": qsTr("1 heure") }); champ_formulaire_Time_out.model.append({"valeur": (4*60*60), "texte": qsTr("4 heures") }); // Positionnement de l'index sur la valeur en cours : i = recherche_index_valeur_modele(time_out, champ_formulaire_Time_out.model, "Time-out"); if (i === -1) champ_formulaire_Time_out.currentIndex = recherche_index_valeur_modele(defaut_time_out, champ_formulaire_Time_out.model, "Time-out"); else champ_formulaire_Time_out.currentIndex = i; //--------------------------------------------------------------------------------------- // Famille : champ_formulaire_Famille.model.clear(); champ_formulaire_Famille.model.append({"valeur": defaut_id_famille, "texte": "Non défini" }); req = 'SELECT Cle_primaire, Nom FROM TB_Familles WHERE Type_source=' + shipheart_type_source_circuits + ' ORDER BY Priorite_affichage '; //console.log("Requête = " + req) nb = bdd.requete(req); for (i = 0; i < nb; i ++) { res = bdd.lecture_ligne(); if (!res.isEmpty) { champ_formulaire_Famille.model.append({"valeur": Number(res[0]), "texte": res[1] }); } } // Positionnement de l'index sur la valeur en cours : i = recherche_index_valeur_modele(id_famille, champ_formulaire_Famille.model, "Famille"); if (i === -1) champ_formulaire_Famille.currentIndex = recherche_index_valeur_modele(defaut_id_famille, champ_formulaire_Famille.model, "Famille"); else champ_formulaire_Famille.currentIndex = i; flag_init = false; // Indique que l'init est terminée } //============================================================================================================= // Raffraichissement de la liste cdes_auto du circuit //============================================================================================================= function raffraichissement_modele_intensite_seuil_haut(adresse_module, intensite_seuil_haut, id_circuit_esclave) { var i; var max_intensite_seuil_haut; champ_formulaire_Intensite_seuil_haut.model.clear(); // Recherche du type de carte et de sa version pour déterminer la plage maximale possible : max_intensite_seuil_haut = max_intensite_carte(adresse_module, id_circuit_esclave); // Retour de 0 si adresse_module=-1 if (max_intensite_seuil_haut > 0) { for (i = 1; i <= max_intensite_seuil_haut; i ++ ) champ_formulaire_Intensite_seuil_haut.model.append({"valeur": i, "texte": i + " A" }); // Positionnement de l'index sur la valeur en cours : i = recherche_index_valeur_modele(intensite_seuil_haut, champ_formulaire_Intensite_seuil_haut.model, "Intensite_seuil_haut"); if (i !== -1) { champ_formulaire_Intensite_seuil_haut.currentIndex = i; //console.log("Retour de mise à jour modèle Intensité seuil haut = " + intensite_seuil_haut); return(intensite_seuil_haut); } else { champ_formulaire_Intensite_seuil_haut.currentIndex = recherche_index_valeur_modele(max_intensite_seuil_haut, champ_formulaire_Intensite_seuil_haut.model, "Intensite_seuil_haut"); //console.log("Retour de mise à jour modèle Intensité seuil haut = " + max_intensite_seuil_haut); return(max_intensite_seuil_haut); } } else // Cas où le type de carte n'est pas connu (permet d'éviter des erreurs mais ce cas n'est normalement jamais affiché)... { champ_formulaire_Intensite_seuil_haut.model.append({"valeur": 0, "texte": "Aucun" }); champ_formulaire_Intensite_seuil_haut.currentIndex = 0; //console.log("Retour de mise à jour modèle Intensité seuil haut = " + max_intensite_seuil_haut); return(max_intensite_seuil_haut); } } //============================================================================================================= // Mise à jour des valeurs saisies du circuit // Important : on considère qu'après exécution de cette fonction, on quitte la page (les propriétés globales // peuvent en effet être affectées et/ou pas à jour après cette fonction). //============================================================================================================= function mise_a_jour_circuit() { var req, res; // Traitement de Affectation : var valeur = champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).valeur const valeurs = valeur.split('/'); var new_no_carte = Number(valeurs[0]); var new_no_circuit_carte = Number(valeurs[1]); var paa; var mode = champ_formulaire_Mode_commande.model.get(champ_formulaire_Mode_commande.currentIndex).valeur; var step_time = champ_formulaire_Step_time.model.get(champ_formulaire_Step_time.currentIndex).valeur; var intensite_seuil_haut = champ_formulaire_Intensite_seuil_haut.model.get(champ_formulaire_Intensite_seuil_haut.currentIndex).valeur; var intensite_coeff_filtrage = champ_formulaire_Intensite_coeff_filtrage.model.get(champ_formulaire_Intensite_coeff_filtrage.currentIndex).valeur; // Traitement du circuit esclave : var new_id_circuit_esclave = champ_formulaire_Circuit_esclave.model.get(champ_formulaire_Circuit_esclave.currentIndex).valeur; var new_no_circuit_esclave = champ_formulaire_Circuit_esclave.model.get(champ_formulaire_Circuit_esclave.currentIndex).no; //-------------------------------------------------------------------------------------------------- // Changement d'affectation du circuit : if ((new_no_carte !== adresse_module) || (new_no_circuit_carte !== no_circuit)) { extinction_circuit_garantie(id_circuit); // L'extinction du circuit éteindra aussi (l'ancien) esclave s'il y en avait un. // Impact sur le circuit esclave : if (new_no_carte !== adresse_module) // Qu'il y en ait eu un ou pas, il ne peut y en avoir suite à un changement de module (puisqu'on n'a pas pu proposer un circuit esclave sur le nouveau module) { new_id_circuit_esclave = 0; new_no_circuit_esclave = 0; // C'est ce qui permettra sa suppression ensuite s'il y en avait un. } } //-------------------------------------------------------------------------------------------------- // Mise à jour de N° de carte et du n° de circuit : adresse_module = new_no_carte; no_circuit = new_no_circuit_carte; //-------------------------------------------------------------------------------------------------- // Vérification des paramètres spécifiques au type de module support du circuit : switch(type_carte(adresse_module)) { //------------------------------------------- case shipheart_type_module_shippower812: intensite_coeff_filtrage = 16; if (mode !== shipheart_mode_commande_circuit_soft_variable) old_consigne = 0; // SDIR #184 break; //------------------------------------------- case shipheart_type_module_shippower4AC: intensite_coeff_filtrage = 4; mode = shipheart_mode_commande_circuit_tor; // step_time = defaut_step_time; // SDIR #193 : mise en commentaire de la ligne car 'defaut_step_time' n'existe pas et met la page en erreur... new_id_circuit_esclave = 0; // Normalement ne doit pas arriver car déjà pris en compte de façon plus générale au § précédent (si on arrive sur un SP4AC, c'est qu'il y a eu changement de carte donc le circuit esclave a été déjà sucré...) new_no_circuit_esclave = 0; break; //------------------------------------------- case shipheart_type_module_shippower8DC: intensite_coeff_filtrage = 16; if (mode !== shipheart_mode_commande_circuit_soft_variable) old_consigne = 0; // SDIR #184 break; //------------------------------------------- default: // Ce cas correspond notamment aux circuits Non Affectés... intensite_coeff_filtrage = 16; break; } //-------------------------------------------------------------------------------------------------- // Vérification que le seuil de disjonction est compatible avec le module support : // NB : ce test ne peut pas être intégré au § précédent car la fonction 'max_intensite_carte()' teste non seulement le type mais aussi la version hardware (cas des SP812)... var max_intensite_seuil_haut = max_intensite_carte(adresse_module, new_id_circuit_esclave); if (intensite_seuil_haut > max_intensite_seuil_haut) intensite_seuil_haut = max_intensite_seuil_haut; //-------------------------------------------------------------------------------------------------- if (champ_formulaire_Masquage.checked) // Demande de masquage : { if (priorite_affichage_accueil <= 0) paa = priorite_affichage_accueil; // S'il était masqué, on garde la même valeur. else paa = - priorite_affichage_accueil; // S'il était démasqué (donc > 0), on prend son opposé (comme ça, on est bien <0 mais on garde en plus la position initiale en mémoire) } else // Demande de ne pas le masquer : { if (priorite_affichage_accueil > 0) paa = priorite_affichage_accueil; // S'il était démasqué, on garde la même valeur else if (priorite_affichage_accueil < 0) paa = - priorite_affichage_accueil; // S'il était masqué, avec une valeur mémorisée non nulle, on récupère la valeur mémorisée (l'opposé donc) else paa = 999; // S'il était masqué mais sans valeur mémorisée (donc nulle), on attribue arbitrairement une valeur très élevée pour mettre le circuit affiché mais en dernière position. } //-------------------------------------------------------------------------------------------------- // Traitement du circuit esclave avec, pour l'essentiel, les mêmes paramètres que le circuit maitre : //console.log("new_id_circuit_esclave = " + new_id_circuit_esclave + " et id_cicuit_esclave = " + id_circuit_esclave); // Suppression de l'ancien circuit esclave si besoin : if (id_circuit_esclave > 0) // Il y avait un circuit esclave : { if (new_id_circuit_esclave !== id_circuit_esclave) // Le nouveau circuit esclave est différent de l'ancien => Il faut supprimer l'ancien { // Suppression de la commande de l'ancien circuit esclave dans tous les cas) : extinction_circuit_garantie(id_circuit_esclave); // Suppression de l'ancien circuit esclave (dans tous les cas) : req = 'DELETE FROM TB_Circuits WHERE Cle_primaire=' + id_circuit_esclave + ' '; bdd.requete_unique(req); } } // Création du nouveau circuit esclave si besoin : if ( ((id_circuit_esclave > 0) && // Il y avait un circuit esclave... (new_id_circuit_esclave !== id_circuit_esclave) && // ... et le nouveau est différent de l'ancien... (new_no_circuit_esclave !== 0)) || // ... et le nouveau n'est pas nul OU ((id_circuit_esclave === 0) && // Il n'y avait pas de circuit esclave... (new_no_circuit_esclave !== 0)) ) // ... et le nouveau n'est pas nul { req = 'INSERT INTO TB_Circuits (Nom, Adresse_module, No_circuit, ID_Circuit_esclave, Mode_commande, Intensite_coeff_filtrage, Intensite_seuil_haut, Intensite_seuil_haut_tempo, Step_time, Time_out, ID_Famille, Priorite_affichage_accueil) ' req += ' VALUES ("' + champ_formulaire_Nom.text + '"'; req += ', ' + adresse_module; req += ', ' + (new_no_circuit_esclave - 1); req += ', ' + (id_circuit * (-1)); req += ', ' + mode; req += ', ' + intensite_coeff_filtrage; req += ', ' + intensite_seuil_haut; req += ', ' + champ_formulaire_Intensite_seuil_haut_tempo.model.get(champ_formulaire_Intensite_seuil_haut_tempo.currentIndex).valeur; req += ', ' + step_time; req += ', ' + champ_formulaire_Time_out.model.get(champ_formulaire_Time_out.currentIndex).valeur; req += ', ' + champ_formulaire_Famille.model.get(champ_formulaire_Famille.currentIndex).valeur; req += ', 0'; // Le circuit esclave est toujours masqué ! req += ') '; //console.log("Requête = " + req) bdd.requete_unique(req); // Récupération de la clé primaire du circuit esclave créé : req = 'SELECT Cle_primaire FROM TB_Circuits ORDER BY Cle_primaire DESC LIMIT 1'; res = bdd.requete_unique(req); // id_circuit_esclave = Number(res[0]); new_id_circuit_esclave = Number(res[0]); // SDIR #325 } // Interdiction de mode variateur si on a un circuit esclave : if (new_id_circuit_esclave > 0) { if (mode === shipheart_mode_commande_circuit_soft_variable) { mode = shipheart_mode_commande_circuit_soft_tor; old_consigne = 0; // SDIR #184 // SDIR #325 req = 'UPDATE TB_Circuits SET Mode_commande=' + mode + ' WHERE Cle_primaire=' + id_circuit_esclave + ' '; // Maj de l'esclave qui a été créé avec le "mauvais" mode req = 'UPDATE TB_Circuits SET Mode_commande=' + mode + ' WHERE Cle_primaire=' + new_id_circuit_esclave + ' '; // Maj de l'esclave qui a été créé avec le "mauvais" mode bdd.requete_unique(req); // Définition des paramètres de la boite de dialogue : boite_information.niveau = 1; boite_information.imageTitreSource = "/images/ampoule.png" boite_information.message = qsTr("L'utilisation d'un circuit de renfort rend l'utilisation du mode de commande [Variateur] impossible.

Le mode de commande vient donc d'être ramené à [On-Off Progressif]."); boite_information.open(); } } //-------------------------------------------------------------------------------------------------- // Génération de la requête de mise à jour du circuit : req = 'UPDATE TB_Circuits SET Nom="' + champ_formulaire_Nom.text + '" '; req += ', Adresse_module=' + adresse_module + ' '; req += ', No_circuit=' + no_circuit + ' '; req += ', ID_Circuit_esclave=' + new_id_circuit_esclave + ' '; // SDIR #325 req += ', Mode_commande=' + mode + ' '; req += ', Old_consigne=' + old_consigne + ' '; req += ', Intensite_coeff_filtrage=' + intensite_coeff_filtrage + ' '; req += ', Intensite_seuil_haut=' + champ_formulaire_Intensite_seuil_haut.model.get(champ_formulaire_Intensite_seuil_haut.currentIndex).valeur + ' '; req += ', Intensite_seuil_haut_tempo=' + champ_formulaire_Intensite_seuil_haut_tempo.model.get(champ_formulaire_Intensite_seuil_haut_tempo.currentIndex).valeur + ' '; req += ', Step_time=' + champ_formulaire_Step_time.model.get(champ_formulaire_Step_time.currentIndex).valeur + ' '; req += ', Time_out=' + champ_formulaire_Time_out.model.get(champ_formulaire_Time_out.currentIndex).valeur + ' '; req += ', ID_Famille=' + champ_formulaire_Famille.model.get(champ_formulaire_Famille.currentIndex).valeur + ' '; req += ', Priorite_affichage_accueil=' + paa + ' '; req += ' WHERE Cle_primaire=' + id_circuit + ' ' //console.log("Requête = " + req) bdd.requete_unique(req); // Demande de synchro : synchro_bdd(shipheart_type_synchro_config); } //============================================================================================================= // Création du circuit // Note : l'utilisation d'un circuit esclave est impossible lors de la création du circuit... //============================================================================================================= function creation_circuit() { var req, res; // Traitement de Affectation : var valeur = champ_formulaire_Affectation.model.get(champ_formulaire_Affectation.currentIndex).valeur const valeurs = valeur.split('/'); var adresse_module = Number(valeurs[0]); var no_circuit = Number(valeurs[1]); var paa; var mode = champ_formulaire_Mode_commande.model.get(champ_formulaire_Mode_commande.currentIndex).valeur; var intensite_coeff_filtrage = champ_formulaire_Intensite_coeff_filtrage.model.get(champ_formulaire_Intensite_coeff_filtrage.currentIndex).valeur; //-------------------------------------------------------------------------------------------------- // Vérification des paramètres spécifiques au type de module support du circuit : switch(type_carte(adresse_module)) { //------------------------------------------- case shipheart_type_module_shipbase: intensite_coeff_filtrage = 16; break; //------------------------------------------- case shipheart_type_module_shippower812: intensite_coeff_filtrage = 16; break; //------------------------------------------- case shipheart_type_module_shippower4AC: intensite_coeff_filtrage = 4; break; //------------------------------------------- case shipheart_type_module_shippower8DC: intensite_coeff_filtrage = 16; break; //------------------------------------------- default: // Ce cas correspond notamment aux circuits Non Affectés... intensite_coeff_filtrage = 16; break; } if (champ_formulaire_Masquage.checked) paa = 0; else paa = 999; req = 'INSERT INTO TB_Circuits (Nom, Adresse_module, No_circuit, ID_Circuit_esclave, Mode_commande, Intensite_coeff_filtrage, Intensite_seuil_haut, Intensite_seuil_haut_tempo, Step_time, Time_out, ID_Famille, Priorite_affichage_accueil) ' req += ' VALUES ("' + champ_formulaire_Nom.text + '"'; req += ', ' + adresse_module; req += ', ' + no_circuit; req += ', ' + 0; req += ', ' + mode; req += ', ' + intensite_coeff_filtrage; req += ', ' + champ_formulaire_Intensite_seuil_haut.model.get(champ_formulaire_Intensite_seuil_haut.currentIndex).valeur; req += ', ' + champ_formulaire_Intensite_seuil_haut_tempo.model.get(champ_formulaire_Intensite_seuil_haut_tempo.currentIndex).valeur; req += ', ' + champ_formulaire_Step_time.model.get(champ_formulaire_Step_time.currentIndex).valeur; req += ', ' + champ_formulaire_Time_out.model.get(champ_formulaire_Time_out.currentIndex).valeur; req += ', ' + champ_formulaire_Famille.model.get(champ_formulaire_Famille.currentIndex).valeur; req += ', ' + paa; req += ') '; //console.log("Requête = " + req) bdd.requete_unique(req); // Récupération de la clé primaire du circuit maitre : var id_circuit_maitre; req = 'SELECT Cle_primaire FROM TB_Circuits ORDER BY Cle_primaire DESC LIMIT 1'; res = bdd.requete_unique(req); id_circuit_maitre = Number(res[0]); // Demande de synchro : synchro_bdd(shipheart_type_synchro_config); } //============================================================================================================= // Recherche du type de carte à partir de son n° sur K-Bus //============================================================================================================= function type_carte(adresse_module) { var req, res; var max = 0; if (adresse_module >= 0) { req = 'SELECT Type FROM TB_Modules_config WHERE Presence=1 AND Adresse_k_bus=' + adresse_module + ' '; res = bdd.requete_unique(req); return(Number(res[0])); } else return (-1); // Cas d'un circuit non affecté } //============================================================================================================= // Calcul de l'intensité maxi pour une carte //============================================================================================================= function max_intensite_carte(adresse_module, id_circuit_esclave) { var req, res; var max = 0; if (adresse_module < 0) return(0); // Cas d'un circuit non affecté req = 'SELECT Type, Hardware_version FROM TB_Modules_physiques WHERE Presence=1 AND Adresse_k_bus=' + adresse_module + ' '; //console.log("req = [ " + req + "; ]"); res = bdd.requete_unique(req); switch(Number(res[0])) { //------------------------------------------- case shipheart_type_module_shipbase: max = 0; break; //------------------------------------------- case shipheart_type_module_shippower812: if (Number(res[1]) === 0) // Hardware version = 0 : { if (id_circuit_esclave > 0) max = 35; // Cas d'un circuit avec circuit esclave else max = 20; } else // Hardware version >= 1 : { if (id_circuit_esclave > 0) max = 40; // Cas d'un circuit avec circuit esclave else max = 25; } break; //------------------------------------------- case shipheart_type_module_shippower4AC: max = 32; break; //------------------------------------------- case shipheart_type_module_shippower8DC: if (id_circuit_esclave > 0) max = 40; // Cas d'un circuit avec circuit esclave else return(25); break; //------------------------------------------- default: console.log ("Type de carte inconnu dans 'max_intensite_carte()'..."); max = 0; break; } return(max); } //============================================================================================================= // Check suppression du circuit //============================================================================================================= function check_avant_suppression() { var req, res; var nb; var i; var message = ""; //========================================================================= // Recherche de l'impact de cette suppression sur les spécifiques clients : switch(Number(shipheart_specifique_client[0])) { //------------------------------------------------------ default: case shipheart_specifique_client_tous: //console.log("Tous les clients") break; //------------------------------------------------------ case shipheart_specifique_client_suncy: //console.log("Client Suncy") for (i = 1; i < shipheart_specifique_client.length; i ++) // On commence à 1 car le premier champ est déjà traité... { var parametre = shipheart_specifique_client[i].split('='); switch(parametre[0]) { //-------------------------------------------------------- case 'id_circuit_activation_moteur': if (id_circuit === Number(parametre[1])) // Cas où le circuit qu'on envisage de supprimer est celui utilisé pour démarrer le moteur.... { message = qsTr("Ce circuit est utilisé pour la commande du moteur.
Vous devez d'abord affecter la commande moteur à un autre circuit avant de pouvoir supprimer celui-ci. ") } break; //-------------------------------------------------------- default : break; } } break; } //========================================================================= // Recherche de l'impact de cette suppression sur les évènements : req = 'SELECT Cle_primaire, Nom FROM TB_Events WHERE Type_source=' + shipheart_source_mesure_circuit + ' AND ID_Source=' + id_circuit + ' '; req += ' UNION'; req += ' SELECT Cle_primaire, Nom FROM TB_Events WHERE Action_circuits LIKE "%' + id_circuit + '/%"'; req += ' ORDER BY Nom'; //console.log("Requête = [ " + req + "; ]") nb = bdd.requete(req); if (nb > 0) { if (nb === 1) message += "

" + qsTr("Ce circuit est utilisé par l'évènement ci-dessous.
Vous devez modifier ou supprimer cet évènement pour qu'il ne dépende plus de ce circuit avant de pouvoir le supprimer.") + "

"; else message += "

" + qsTr("Ce circuit est utilisé par les %1 évènements ci-dessous.
Vous devez modifier ou supprimer ces évènements pour qu'ils ne dépendent plus de ce circuit avant de pouvoir le supprimer.").arg(nb) + "

"; for (i = 0; i < nb; i ++) { res = bdd.lecture_ligne(); if (!res.isEmpty) { message += "‣ " + (i+1) + " : " + res[1] + "
"; } } } //========================================================================= // Recherche de l'impact de cette suppression sur les capteurs calculés : /* Retour de la forme : +-------------+ | Nom_capteur | +-------------+ | Calculation | | Calcul 2 | +-------------+ */ req = 'SELECT Nom FROM TB_Capteurs '; req += ' WHERE Type_entrees=' + shipheart_capteur_type_entrees_calculee_booleen + ' '; req += ' AND Entrees LIKE "%/' + shipheart_source_mesure_circuit + ':' + id_circuit + '/%" '; //console.log("Requête = [ " + req + "; ]") nb = bdd.requete(req); if (nb > 0) { if (nb === 1) message += "

" + qsTr("Ce circuit est utilisé par le capteur calculé ci-dessous.
Vous devez modifier ou supprimer ce capteur calculé pour qu'il ne dépende plus de ce circuit avant de pouvoir le supprimer.") + "

"; else message += "

" + qsTr("Ce circuit est utilisé par les %1 capteurs calculés ci-dessous.
Vous devez modifier ou supprimer ces capteurs calculés pour qu'ils ne dépendent plus de ce circuit avant de pouvoir le supprimer.").arg(nb) + "

"; for (i = 0; i < nb; i ++) { res = bdd.lecture_ligne(); if (!res.isEmpty) { message += "‣ " + (i+1) + " : " + res[0] + "
"; } } } //========================================================================= // Conclusion : if (message === "") return(0); // Aucune réserve à supprimer le message.... else // Affichage de la boite de dialogue. La suppression n'est pas autorisée... { boite_information.niveau = 1; boite_information.imageTitreSource = "/images/attention.png" boite_information.message = message; boite_information.alignementMessage = Text.AlignLeft boite_information.type = type_boite_information_supprimer; boite_information.open(); return(-1); } } //============================================================================================================= // Suppression du circuit //============================================================================================================= function suppression_circuit() { var req, res; // Mise à l'arret du circuit (et donc de son éventuel esclave) : extinction_circuit_garantie(id_circuit); // Recherche d'un éventuel circuit esclave : req = 'SELECT ID_Circuit_esclave FROM TB_Circuits WHERE Cle_primaire=' + id_circuit + ' '; res = bdd.requete_unique(req); if (Number(res[0]) > 0) // ..; et supression s'il y en a un { req = 'DELETE FROM TB_Circuits WHERE Cle_primaire=' + Number(res[0]) + ' '; bdd.requete_unique(req); } // Suppression du circuit : req = 'DELETE FROM TB_Circuits WHERE Cle_primaire=' + id_circuit + ' '; bdd.requete_unique(req); // Demande de synchro : synchro_bdd(shipheart_type_synchro_config); } //============================================================================================================= // Extinction garantie du circuit // Cela se traduit par l'envoi d'une demande d'extinction puis une boucle d'attente (avec time out) jusqu'à ce // que le circuit ait effectivement sa consigne à 0. //============================================================================================================= function extinction_circuit_garantie(id_circuit) { var req, res; var i; var limite = 200; // Mise à l'arret du circuit : bdd.requete_unique("UPDATE TB_Circuits SET New_consigne=0, Old_consigne=0 WHERE Cle_primaire='" + id_circuit + "'") // Ajout de la RAZ de Old_consigne (SDIR # 184) synchro_bdd(shipheart_type_synchro_data); // Avec cette synchro, le traitement par l'appli sera fait dans 100ms maxi. // Boucle d'attente du passage effectif à 0 : for (i = 0; i < limite; i ++) { req = "SELECT Consigne FROM TB_Circuits WHERE Cle_primaire='" + id_circuit + "' "; res = bdd.requete_unique(req); if (Number(res[0]) === 0) break; } if (i === limite) console.log("La boucle d'extinction garantie n'a pas pu effectuer la RAZ avant l'expiration de son time out (" + limite + " boucles)"); else console.log("L'extinction garantie s'est déroulée correctement et est sortie après " + i + " boucles"); } //============================================================================================================= // Recherche de l'index d'une certaine valeur dans un modele //============================================================================================================= function recherche_index_valeur_modele(cible, modele, nom_modele) { var i; for (i=0; i