Files
shipheart-qt/config_reservoir.qml
T

1596 lines
81 KiB
QML

//========================================================================================================================================================================
// CONFIG_RESERVOIR.QML
// Ce fichier traite la configuration d'un réservoir. La page permet notamment de :
// - Modifier la config du réservoir (ou de le créer la première fois),
// - Supprimer le réservoir
// La page est appelée depuis la page config_reservoirs_1, en cliquant sur le réservoir à modifier (ou sur le '+' en vue de sa création)
//========================================================================================================================================================================
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQml.Models
import qt.koriolan.shipheart 1.0
import"fonctions.js" as Fonctions
import"fonctions_reservoirs.js" as Fonctions_reservoirs
Shipheart_page {
id: page_config_reservoir
// 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.5
readonly property double pourcentage_largeur_unites_formulaire: 0.1
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
// Affichage :
// Données :
property bool flag_init: true // Permet de bloquer certains affichage tant que l'init n'est pas terminée
property int valeur_timer_appui_long: 0
property int id_reservoir: 0
property int adresse_module_init: 0
property int adresse_module: 0 // Contient l'adresse du module supportant la ou les entrées affectées à ce réservoir
property int type_entrees_init: 0 // Contient le type d'entrées configuré pour ce réservoir lors de l'init (permet, si cette valeur varie, de forcer un recalcul de la Liste_valeurs_niveaux).
property int type_entrees: 0
property string entrees_init: ""
property string entrees: ""
property int mode_entrees_init: 0 // Utile pour un réservoir en mode 'Entrée Level Sensor'. Contient le mode de cette entrée configuré lors de l'init ((permet, si ce nombre varie, de forcer un recalcul de la Liste_valeurs_niveaux).
property int mode_entrees: 0
property int type_sonde_entrees_init: 0 // Utile pour un réservoir en mode 'Entrée Level Sensor'. Contient le sous_mode de cette entrée configuré lors de l'init ((permet, si ce nombre varie, de forcer un recalcul de la Liste_valeurs_niveaux).
property int type_sonde_entrees: 0
property int nb_entrees_reservoir_init: 0 // Utile pour un réservoir en mode 'Entrées AUX'. Contient le nombre d'entrées configurées pour ce réservoir lors de l'init (permet, si ce nombre varie, de forcer un recalcul de la Liste_valeurs_niveaux).
property int nb_entrees_reservoir: 0
property int entree_en_cours: 0
// property int creation_no_carte: 0
// property int creation_no_circuit_carte: 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_reservoir(); // Mise à jour des données saisies dans la BDD et reconfiguration par l'application pour prise en compte.
timer_tempo_reconfiguration.restart(); // Lancement du timer pour attendre la fin de la reconfiguration
}
}
}
}
}
// Titre de la page :
Shipheart_titre_1 {titre: (id_reservoir === 0) ? qsTr("Création d'un réservoir") : qsTr("Configuration du réservoir"); 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 réservoir")
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 : Famille
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("Famille de réservoirs")
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 : Capacite
Rectangle {
width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2)
height: visible ? hauteur_ligne_formulaire : 0
color: "transparent"
visible: (champ_formulaire_Famille.currentIndex !== 0)
Shipheart_formulaire_label {
text: qsTr("Capacité du réservoir")
width: parent.width * pourcentage_largeur_labels_formulaire
couleur: (Number(champ_formulaire_Capacite.text) !== 0)
? shipheart_formulaire_couleur_texte_par_defaut
: shipheart_formulaire_couleur_texte_en_erreur
}
Shipheart_formulaire_textfield {
id: champ_formulaire_Capacite
width: parent.width * (1 - pourcentage_largeur_labels_formulaire - pourcentage_largeur_unites_formulaire)
x: parent.width * pourcentage_largeur_labels_formulaire
flag_num_only: true
}
Shipheart_formulaire_unite { // Unités :
text: qsTr("litres")
width: parent.width * pourcentage_largeur_unites_formulaire
}
Shipheart_formulaire_ligne_separation {
haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse
}
}
//-------------------------------------------------------------------------------
// Ligne de formulaire : Type d'entrées
Rectangle {
width: parent.width
height: visible ? hauteur_ligne_formulaire : 0
color: "transparent"
visible: (Number(champ_formulaire_Capacite.text) !== 0)
Shipheart_formulaire_label {
text: qsTr("Type de capteur de niveau")
width: parent.width * pourcentage_largeur_labels_formulaire
couleur: ((champ_formulaire_Type_entrees.currentIndex !== 0) && (nb_entrees_reservoir !== 0))
? shipheart_formulaire_couleur_texte_par_defaut
: shipheart_formulaire_couleur_texte_en_erreur
}
Shipheart_formulaire_combobox {
id: champ_formulaire_Type_entrees
model: ListModel { }
width: parent.width * (1 - pourcentage_largeur_labels_formulaire)
onActivated: {
//console.log("Valeur courante=" + model.get(currentIndex).valeur + "/init=" + type_entrees_init + " mode courant=" + model.get(currentIndex).mode + " /init=" + mode_reservoir_init + " sous_mode courant=" + model.get(currentIndex).sous_mode + " /init=" + sous_mode_reservoir);
shipheart_clic();
if (id_reservoir !== 0) // Si on change de type de capteur alors qu'on est sur une modification de réservoir existant, on alerte avant de valider la saisie :
{
boite_alerte_changement_type_capteur.open();
}
else // En création, on applique de suite le nouveau type d'entrée :
{
type_entrees = model.get(currentIndex).valeur;
mode_entrees = model.get(currentIndex).mode;
type_sonde_entrees = model.get(currentIndex).sous_mode;
if (type_entrees === shipheart_reservoir_type_entrees_aux) init_entrees_aux();
else if (type_entrees === shipheart_reservoir_type_entrees_level_sensor) init_entrees_level_sensor();
}
}
}
}
//-------------------------------------------------------------------------------
// Ligne de formulaire : Choix des entrées Auxiliaires
Rectangle {
width: parent.width
height: visible ? (hauteur_ligne_formulaire * 2) : 0
visible: (type_entrees === shipheart_reservoir_type_entrees_aux)
color: "transparent"
GridView {
id: entrees_aux_reservoir_grid
width: parent.width
height: parent.height
anchors.verticalCenter: parent.verticalCenter;
cellWidth: (width / 4) - 1 // Ce choix permet de laisser une zone libre à droite pour le scrollbar (nb : le '-1' est x 4 cells...)
cellHeight: height / 2
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: ListModel { }
delegate: Rectangle {
width: entrees_aux_reservoir_grid.cellWidth - 5
height: entrees_aux_reservoir_grid.cellHeight - 5
radius: shipheart_rayon_bouton
color: couleur_gris_tres_fonce_transparent
Text {
anchors.fill: parent
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
text: (model.no_entree_aux === 0) ? qsTr("%1 : Non définie").arg(model.no) : qsTr("%1 : %2").arg(model.no).arg(model.libelle)
color: (model.no_entree_aux === 0) ? couleur_gris_tres_pale_transparent : couleur_blanc_casse
font.pixelSize: 15
wrapMode: Label.Wrap
}
Text {
anchors.fill: parent
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignBottom
bottomPadding: 5
text: qsTr("Sonde la plus basse dans le réservoir")
color: (model.no_entree_aux === 0) ? couleur_gris_tres_pale : couleur_blanc_casse
font.pixelSize: 10
visible: model.no === 1
}
MouseArea {
id: mouse_area_entree_aux
anchors.fill: parent
onClicked: {
shipheart_clic();
entree_en_cours = model.no;
boite_selection_entree_aux.nom_equipement = Fonctions.nom_type_equipement(shipheart_source_mesure_reservoir);
boite_selection_entree_aux.open();
}
}
}
ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AlwaysOn
}
}
Shipheart_formulaire_ligne_separation {
haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse
}
}
//-------------------------------------------------------------------------------
// Ligne de formulaire : Choix de l'entrées Level Sensor
Rectangle {
width: parent.width
height: visible ? (hauteur_ligne_formulaire * 1) : 0
visible: (type_entrees === shipheart_reservoir_type_entrees_level_sensor)
color: "transparent"
GridView {
id: entree_level_sensor_reservoir_grid
width: parent.width * (1 - pourcentage_largeur_labels_formulaire);
height: parent.height - 10
anchors.verticalCenter: parent.verticalCenter;
anchors.right: parent.right
cellWidth: width
cellHeight: 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: ListModel { }
delegate: Rectangle {
width: entree_level_sensor_reservoir_grid.cellWidth
height: entree_level_sensor_reservoir_grid.cellHeight
radius: shipheart_rayon_bouton
color: couleur_gris_tres_fonce_transparent
Text {
anchors.fill: parent
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
text: (model.no_entree_level_sensor === 0) ? qsTr("Non définie") : model.libelle
color: (model.no_entree_level_sensor === 0) ? couleur_gris_tres_pale_transparent : couleur_blanc_casse
font.pixelSize: 15
wrapMode: Label.Wrap
}
MouseArea {
id: mouse_area_entree_level_sensor
anchors.fill: parent
onClicked: {
shipheart_clic();
entree_en_cours = model.no;
boite_selection_entree_level_sensor.open();
}
}
}
}
Shipheart_formulaire_ligne_separation {
haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse
}
}
//-------------------------------------------------------------------------------
// Ligne de formulaire : Logique inversée des entrées AUX
Rectangle {
id: ligne_logique_inversee
width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2)
height: visible ? hauteur_ligne_formulaire : 0
visible: (type_entrees === shipheart_reservoir_type_entrees_aux)
color: "transparent"
Shipheart_formulaire_label {
text: qsTr("Logique des entrées inversée")
width: parent.width * pourcentage_largeur_labels_formulaire
}
Shipheart_formulaire_checkbox {
id: champ_formulaire_Logique_inversee
width: parent.width * (1 - pourcentage_largeur_labels_formulaire)
}
Shipheart_formulaire_ligne_separation {
haut_bas_hautbas: shipheart_formulaire_ligne_separation_basse
}
}
//-------------------------------------------------------------------------------
// Ligne de formulaire : Logique
Rectangle {
width: parent.width
height: visible ? hauteur_ligne_formulaire : 0
color: "transparent"
visible: (champ_formulaire_Type_entrees.currentIndex !== 0) && (nb_entrees_reservoir !== 0)
Shipheart_formulaire_label {
text: qsTr("Logique d'alarme")
width: parent.width * pourcentage_largeur_labels_formulaire
}
Shipheart_formulaire_combobox {
id: champ_formulaire_Logique
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 : Niveau_coeff_filtrage
Rectangle {
width: parent.width
height: visible ? hauteur_ligne_formulaire : 0
color: "transparent"
visible: (champ_formulaire_Type_entrees.currentIndex !== 0) && (nb_entrees_reservoir !== 0)
Shipheart_formulaire_label {
text: qsTr("Filtrage des mesures")
width: parent.width * pourcentage_largeur_labels_formulaire
}
Shipheart_formulaire_combobox {
id: champ_formulaire_Niveau_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
}
}
}
}
}
//-------------------------------------------------------
// 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 {
id: bouton_enregistrer_creer
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_Famille.currentIndex !== 0) &&
(nb_entrees_reservoir !== 0) &&
(champ_formulaire_Type_entrees.currentIndex !== 0) &&
(Number(champ_formulaire_Capacite.text) !== 0)
Text {
anchors {
verticalCenter: parent.verticalCenter
horizontalCenter: parent.horizontalCenter
}
font.pixelSize: 20
text: (id_reservoir === 0) ? qsTr("Créer le réservoir") : qsTr("Enregistrer")
color: couleur_blanc_casse
}
MouseArea {
anchors.fill: parent
onClicked: {
shipheart_clic();
if (id_reservoir !== 0) mise_a_jour_reservoir(); // Mise à jour des données saisies dans la BDD et reconfiguration par l'application pour prise en compte.
else creation_reservoir();
timer_tempo_reconfiguration.restart();
}
}
}
//.......................................................
// Bouton de suppression
//.......................................................
Rectangle {
width: parent.width
height: hauteur_bouton_droit
color: shipheart_couleur_fond_bouton
radius: shipheart_rayon_bouton
visible: (!clavier.active)
&& (id_reservoir !== 0)
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
timer_appui_long.running = true;
valeur_timer_appui_long = 0;
shipheart_clic();
}
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;
}
}
}
//.......................................................
// Bouton d'accès à la config de la courbe de conversion
//.......................................................
Rectangle {
width: parent.width
height: hauteur_bouton_droit
color: shipheart_couleur_fond_bouton
radius: shipheart_rayon_bouton
visible: (!flag_init)
&& (bouton_enregistrer_creer.visible)
&& (id_reservoir !== 0)
&& (champ_formulaire_Type_entrees.model.get(champ_formulaire_Type_entrees.currentIndex).valeur === type_entrees_init)
&& (champ_formulaire_Type_entrees.model.get(champ_formulaire_Type_entrees.currentIndex).mode === mode_entrees_init)
&& (champ_formulaire_Type_entrees.model.get(champ_formulaire_Type_entrees.currentIndex).sous_mode === type_sonde_entrees_init)
&& (nb_entrees_reservoir === nb_entrees_reservoir_init)
Text {
anchors {
verticalCenter: parent.verticalCenter
horizontalCenter: parent.horizontalCenter
}
font.pixelSize: 20
text: qsTr("Etalonnage")
color: couleur_blanc_casse
}
MouseArea {
anchors.fill: parent
onClicked: {
shipheart_clic();
stackView.push("config_valeurs_niveaux.qml", {"table": "TB_Reservoirs", "id": id_reservoir})
}
}
}
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();
stackView.pop(); // Retour à la page de config des circuits
}
else timer_tempo_reconfiguration.interval = 100 // Tempo plus courte pour les lectures suivantes
//console.log("Passage dans le timer_tempo_reconfiguration")
}
}
}
}
//-------------------------------------------------------
// 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) - parent.leftPadding - (parent.spacing / 2)
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 sélection entrée aux :
//-------------------------------------------------------
Shipheart_boite_dialogue_entrees_aux {
id: boite_selection_entree_aux
boutonAnnuler: true
boutonAnnulerTexte: "Annuler"
onClicked: {
//console.log("Le Bouton [" + bouton + "] est appuyé");
if (bouton === shipheart_boite_dialogue_bouton_1)
{
var groupe = recherche_groupe_entree_aux(no_entree - 1);
if (modele_entrees_aux.get(groupe).valeurs.get((no_entree - 1) % 4).no_entree === entree_en_cours) // Si on reclique sur l'entrée déjà affectée, on supprime l'affectation.
{
entrees_aux_reservoir_grid.model.set((entree_en_cours - 1), {"no_entree_aux" : 0, "libelle": ""});
modele_entrees_aux.get(groupe).valeurs.set(((no_entree - 1) % 4), {"used": 0, "no_entree": 0});
nb_entrees_reservoir --;
}
else // Si on clique sur une autre entrée...
{
// ... on vérifie si le n° était déjà affecté à une entrée aux. Si oui, on supprime cette affectation avant de créer la nouvelle :
var i = entrees_aux_reservoir_grid.model.get(entree_en_cours - 1).no_entree_aux;
if (i !== 0)
{
var g = recherche_groupe_entree_aux(i - 1);
modele_entrees_aux.get(g).valeurs.set(((i - 1) % 4), {"used": 0, "no_entree": 0});
nb_entrees_reservoir --;
}
// On met ensuite à jour la nouvelle affectation :
entrees_aux_reservoir_grid.model.set((entree_en_cours - 1), {"no_entree_aux" : no_entree, "libelle": qsTr("AUX INPUT %1").arg(no_entree)});
modele_entrees_aux.get(groupe).valeurs.set(((no_entree - 1) % 4), {"used": 1, "no_entree": entree_en_cours});
nb_entrees_reservoir ++;
}
boite_selection_entree_aux.close();
}
}
}
ListModel {
id: modele_entrees_aux
}
//-------------------------------------------------------
// Boite de sélection entrée Level Sensor :
//-------------------------------------------------------
Shipheart_boite_dialogue_entrees_level_sensor {
id: boite_selection_entree_level_sensor
boutonAnnuler: true
boutonAnnulerTexte: "Annuler"
onClicked: {
//console.log("Le Bouton [" + bouton + "] est appuyé");
if (bouton === shipheart_boite_dialogue_bouton_1)
{
//console.log("Retour de choix d'entrée Level Sensor = " + no_entree + " et no_en_cours = " + no_entree_en_cours);
var groupe = recherche_groupe_entree_level_sensor(no_entree - 1);
if (modele_entrees_level_sensor.get(groupe).valeurs.get((no_entree - 1) % 4).no_entree === entree_en_cours) // Si on reclique sur l'entrée déjà affectée, on supprime l'affectation.
{
entree_level_sensor_reservoir_grid.model.set((entree_en_cours - 1), {"no_entree_level_sensor" : 0, "libelle": ""});
modele_entrees_level_sensor.get(groupe).valeurs.set(((no_entree - 1) % 4), {"used": 0, "no_entree": 0});
nb_entrees_reservoir --;
}
else // Si on clique sur une autre entrée...
{
// ... on vérifie si le n° était déjà affecté à une entrée level sensor. Si oui, on supprime cette affectation avant de créer la nouvelle :
var i = entree_level_sensor_reservoir_grid.model.get(entree_en_cours - 1).no_entree_level_sensor;
if (i !== 0)
{
var g = recherche_groupe_entree_level_sensor(i - 1);
modele_entrees_level_sensor.get(g).valeurs.set(((i - 1) % 4), {"used": 0, "no_entree": 0});
nb_entrees_reservoir --;
}
// On met ensuite à jour la nouvelle affectation :
entree_level_sensor_reservoir_grid.model.set((entree_en_cours - 1), {"no_entree_level_sensor" : no_entree, "libelle": qsTr("LEVEL SENSOR %1").arg(no_entree)});
modele_entrees_level_sensor.get(groupe).valeurs.set(((no_entree - 1) % 4), {"used": 1, "no_entree": entree_en_cours});
nb_entrees_reservoir ++;
}
boite_selection_entree_level_sensor.close();
}
}
}
ListModel {
id: modele_entrees_level_sensor
}
//-------------------------------------------------------
// Boite d'alerte changement type capteur :
//-------------------------------------------------------
Shipheart_boite_dialogue {
id: boite_alerte_changement_type_capteur
niveau: 2
imageTitreSource: "/images/attention.png"
message: qsTr("La modification du <b>type de capteur</b> va nécessiter la remise en <i>configuration usine</i> de tous les paramètres du réservoir.<br /><br />Si vous ne souhaitez pas que cette reconfiguration soit effectuée, cliquez sur ANNULER. <br /><br />Sinon, cliquez sur CONFIRMER pour valider le changement.");
boutonAnnuler: true
boutonOkTexte: qsTr("Confirmer")
onClicked: {
//console.log("Le Bouton [" + bouton + "] est appuyé");
if (bouton === shipheart_boite_dialogue_bouton_1)
{
if (champ_formulaire_Type_entrees.model.get(champ_formulaire_Type_entrees.currentIndex).valeur !== type_entrees)
{
// RAZ des entrées si on a change de type (il est dangereux de garder des n° d'entrées AUX pour les considérer comme des entrées Level Sensor ou réciproquement...) :
if (champ_formulaire_Type_entrees.model.get(champ_formulaire_Type_entrees.currentIndex).valeur !== type_entrees_init)
{
entrees = "";
nb_entrees_reservoir = 0;
}
else // Si on revient au type d'entrée initial, on reprend les entrées initiales :
{
entrees = entrees_init;
nb_entrees_reservoir = nb_entrees_reservoir_init;
}
type_entrees = champ_formulaire_Type_entrees.model.get(champ_formulaire_Type_entrees.currentIndex).valeur;
}
mode_entrees = champ_formulaire_Type_entrees.model.get(champ_formulaire_Type_entrees.currentIndex).mode; // Le fait de changer de Mode_entrees ne nécessite pas de RAZ le n° d'entrée qui reste, a priori, valable
type_sonde_entrees = champ_formulaire_Type_entrees.model.get(champ_formulaire_Type_entrees.currentIndex).sous_mode; // Le fait de changer de type_sonde_entrees ne nécessite pas de RAZ le n° d'entrée qui reste, a priori, valable
if (type_entrees === shipheart_reservoir_type_entrees_aux) init_entrees_aux();
else if (type_entrees === shipheart_reservoir_type_entrees_level_sensor) init_entrees_level_sensor();
}
if (bouton === shipheart_boite_dialogue_bouton_2)
{
// Repositionnement à la valeur d'origine :
champ_formulaire_Type_entrees.currentIndex = recherche_index_type_entree(type_entrees, mode_entrees, type_sonde_entrees);
}
}
}
//-------------------------------------------------------
// Boite d'info :
//-------------------------------------------------------
Shipheart_boite_dialogue {
id: boite_information
}
//===========================================================
// 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;
var niveau_coeff_filtrage, defaut_niveau_coeff_filtrage = 16;
var logique, defaut_logique = -1;
var id_famille;
//console.log("Id du réservoir = " + id_reservoir);
if (id_reservoir > 0) // Cas d'une modification de circuit existant :
{
req = 'SELECT Nom, ';
req += ' Adresse_module, ';
req += ' Type_entrees, ';
req += ' Entrees, ';
req += ' Mode_entrees, ';
req += ' Type_sonde_entrees, ';
req += ' ID_Famille, ';
req += ' Niveau_coeff_filtrage, ';
req += ' Liste_valeurs_niveaux, ';
req += ' Capacite, ';
req += ' Logique ';
req += ' FROM TB_Reservoirs ';
req += ' WHERE Cle_primaire=' + id_reservoir + ' ';
//console.log("req = [ " + 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 ++]);
type_entrees = Number(res[i ++]);
entrees = res[i ++];
mode_entrees = Number(res[i ++]);
type_sonde_entrees = Number(res[i ++]);
id_famille = Number(res[i ++]);
niveau_coeff_filtrage = Number(res[i ++]);
i++; // liste valeurs niveaux non utilisée ici (soit on n'y touche pas quand on ne change pas le nombre d'entrées du réservoir ; soit on la regénère automatiquement si changement de nombre d'entrées)
champ_formulaire_Capacite.text = res[i ++];
logique = Number(res[i ++]);
}
else // Cas d'une création de circuit :
{
adresse_module = 0;
type_entrees = 0;
entrees = "";
mode_entrees = 0;
type_sonde_entrees = 0;
champ_formulaire_Nom.text = "";
id_famille = 0;
champ_formulaire_Capacite.text = "0";
niveau_coeff_filtrage = defaut_niveau_coeff_filtrage;
logique = defaut_logique;
}
// Init des entrés selon leur type ;
if (type_entrees === shipheart_reservoir_type_entrees_aux) init_entrees_aux();
else if (type_entrees === shipheart_reservoir_type_entrees_level_sensor) init_entrees_level_sensor();
// Mémorisation des valeurs d'init :
adresse_module_init = adresse_module;
type_entrees_init = type_entrees;
entrees_init = entrees;
nb_entrees_reservoir_init = nb_entrees_reservoir;
mode_entrees_init = mode_entrees;
type_sonde_entrees_init = type_sonde_entrees;
//---------------------------------------------------------------------------------------
// Type d'entrées :
champ_formulaire_Type_entrees.model.clear();
champ_formulaire_Type_entrees.model.append({"valeur": 0, "mode": 0, "sous_mode": 0, "texte": qsTr("Non défini") });
champ_formulaire_Type_entrees.model.append({"valeur": shipheart_reservoir_type_entrees_aux, "mode": 0, "sous_mode": 0, "texte": qsTr("Electrodes plongées ou contacts secs") });
champ_formulaire_Type_entrees.model.append({"valeur": shipheart_reservoir_type_entrees_level_sensor, "mode": 2, "sous_mode": 1, "texte": qsTr("Résistif 0 - 190Ω") });
champ_formulaire_Type_entrees.model.append({"valeur": shipheart_reservoir_type_entrees_level_sensor, "mode": 2, "sous_mode": 2, "texte": qsTr("Résistif 240 - 30Ω") });
champ_formulaire_Type_entrees.model.append({"valeur": shipheart_reservoir_type_entrees_level_sensor, "mode": 2, "sous_mode": 0, "texte": qsTr("Résistif 0 - 700Ω") });
champ_formulaire_Type_entrees.model.append({"valeur": shipheart_reservoir_type_entrees_level_sensor, "mode": 3, "sous_mode": 0, "texte": qsTr("Boucle de courant 4 - 20mA") });
champ_formulaire_Type_entrees.model.append({"valeur": shipheart_reservoir_type_entrees_level_sensor, "mode": 1, "sous_mode": 0, "texte": qsTr("Tension 0 - 10V") });
// Positionnement de l'index sur la valeur en cours :
champ_formulaire_Type_entrees.currentIndex = recherche_index_type_entree(type_entrees, mode_entrees, type_sonde_entrees);
//---------------------------------------------------------------------------------------
// Logique inversée des entrées AUX :
if (type_entrees === shipheart_reservoir_type_entrees_aux)
{
if (mode_entrees === shipheart_reservoir_mode_entrees_aux_inverse) champ_formulaire_Logique_inversee.checked = true;
else champ_formulaire_Logique_inversee.checked = false;
}
//---------------------------------------------------------------------------------------
// Coefficient de filtrage des mesures (valeur en nombre d'échantillons ; mini = 1):
champ_formulaire_Niveau_coeff_filtrage.model.clear();
champ_formulaire_Niveau_coeff_filtrage.model.append({"valeur": 1, "texte": qsTr("Aucun filtrage") });
champ_formulaire_Niveau_coeff_filtrage.model.append({"valeur": 4, "texte": qsTr("Très faible") });
champ_formulaire_Niveau_coeff_filtrage.model.append({"valeur": 8, "texte": qsTr("Faible") });
champ_formulaire_Niveau_coeff_filtrage.model.append({"valeur": defaut_niveau_coeff_filtrage, "texte": qsTr("Moyen") });
champ_formulaire_Niveau_coeff_filtrage.model.append({"valeur": 64, "texte": qsTr("Elevé") });
champ_formulaire_Niveau_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(niveau_coeff_filtrage, champ_formulaire_Niveau_coeff_filtrage.model, "Niveau_coeff_filtrage");
if (i === -1) champ_formulaire_Niveau_coeff_filtrage.currentIndex = recherche_index_valeur_modele(defaut_niveau_coeff_filtrage, champ_formulaire_Niveau_coeff_filtrage.model, "Niveau_coeff_filtrage");
else champ_formulaire_Niveau_coeff_filtrage.currentIndex = i;
//---------------------------------------------------------------------------------------
// Logique :
champ_formulaire_Logique.model.clear();
champ_formulaire_Logique.model.append({"valeur": defaut_logique, "texte": qsTr("Alerte sur niveau faible") });
champ_formulaire_Logique.model.append({"valeur": 1, "texte": qsTr("Alerte sur niveau élevé") });
// champ_formulaire_Logique.model.append({"valeur": 0, "texte": qsTr("Alerte sur niveau faible ou élevé") });
// Positionnement de l'index sur la valeur en cours :
i = recherche_index_valeur_modele(logique, champ_formulaire_Logique.model, "Logique");
if (i === -1) champ_formulaire_Logique.currentIndex = recherche_index_valeur_modele(defaut_logique, champ_formulaire_Logique.model, "Logique");
else champ_formulaire_Logique.currentIndex = i;
//---------------------------------------------------------------------------------------
// Famille :
champ_formulaire_Famille.model.clear();
champ_formulaire_Famille.model.append({"valeur": 0, "texte": "Non défini" });
req = 'SELECT Cle_primaire, Nom FROM TB_Familles WHERE Type_source=' + shipheart_type_source_reservoirs + ' ORDER BY Priorite_affichage ';
//console.log("req = [ " + 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 = 0;
else champ_formulaire_Famille.currentIndex = i;
flag_init = false;
}
//=============================================================================================================
// Init des valeurs initiales des modèles liées aux entrées du réservoir lorsqu'il est dans l'un des modes utilisant les entrées AUX
// Il est important de noter l'utilisation de DEUX modèles de données :
// - 'entrees_aux_reservoir_grid.model' qui contient (a priori) 12 entrées ; chacune représentant l'une des entrée
// configurée sur ce réservoir.
// - 'modele_entrees_aux' qui contient les 32 AUX INPUTS disponibles sur ShipBase.
//=============================================================================================================
function init_entrees_aux()
{
var req, res;
var nb;
var i;
var val;
var chaines_entrees = [];
// Traitement de la chaine "entrees" pour définir les entrées actuelles du réservoir :
if (entrees !== "")
{
chaines_entrees = entrees.split(';');
nb_entrees_reservoir = chaines_entrees.length;
}
else
{
chaines_entrees[0] = "";
nb_entrees_reservoir = 0;
}
//---------------------------------------------------------------------------------------
// Entrées réservoir :
// Les 12 entrées qui sont affectables au réservoir
entrees_aux_reservoir_grid.model.clear();
for (i = 0; i < shipheart_reservoir_max_nombre_entrees_aux; i ++)
{
if (i < nb_entrees_reservoir) val = Number(chaines_entrees[i]);
else val = 0;
entrees_aux_reservoir_grid.model.append({"no": (i + 1), "no_entree_aux" : val, "libelle": (val === 0) ? "FFFFF" : qsTr("AUX INPUT %1").arg(val) });
}
//---------------------------------------------------------------------------------------
// Entrées auxiliaires :
// Les 32 entrées AUX de ShipBase par exemple
var entrees_aux = [];
// remplissage par défaut de toutes les entrées AUX possibles :
for (i=0; i<shipheart_entrees_aux_max_nombre; i++)
{
val = chaines_entrees.indexOf("" + (i+1) + "") + 1; // Le '+1' permet de passer de l'index (0..n) à un numéro d'entrée du réservoir (1..N) mais aussi de passer de l'erreur (-1) à la valeur par défaut (0)
entrees_aux.push({'used': 0, 'no_entree': val}); // Init par défaut
}
// Mise à jour en fonction des entrées déjà utilisées par ailleurs (capteurs et réservoirs) :
req = '(SELECT ' + shipheart_source_mesure_reservoir + ' AS Type, Entrees ';
req += 'FROM TB_Reservoirs WHERE ';
req += 'Type_entrees=' + shipheart_reservoir_type_entrees_aux + ') ';
req += ' UNION ';
req += '(SELECT ' + shipheart_source_mesure_capteur + ' AS Type, Entrees ';
req += 'FROM TB_Capteurs WHERE ';
req += 'Type_entrees=' + shipheart_reservoir_type_entrees_aux + ') ';
//console.log("req = [ " + req + "; ]");
nb = bdd.requete(req);
for (i = 0; i < nb; i ++)
{
res = bdd.lecture_ligne();
if (!res.isEmpty)
{
chaines_entrees = res[1].split(';');
var j;
var no;
for(j = 0; j < chaines_entrees.length; j ++)
{
no = Number(chaines_entrees[j]);
if ((no >= 1) && (no <= shipheart_entrees_aux_max_nombre)) entrees_aux[no - 1]['used'] = 1; // le n° d'entrée doit être dans [1; 32]
}
}
}
modele_entrees_aux.clear();
i = 17;
modele_entrees_aux.append({valeurs: [{no: i, used: entrees_aux[i-1]['used'], no_entree: entrees_aux[i-1]['no_entree'] },
{no: (i+1), used: entrees_aux[i+0]['used'], no_entree: entrees_aux[i+0]['no_entree'] },
{no: (i+2), used: entrees_aux[i+1]['used'], no_entree: entrees_aux[i+1]['no_entree'] },
{no: (i+3), used: entrees_aux[i+2]['used'], no_entree: entrees_aux[i+2]['no_entree'] }] } );
i = 21;
modele_entrees_aux.append({valeurs: [{no: i, used: entrees_aux[i-1]['used'], no_entree: entrees_aux[i-1]['no_entree'] },
{no: (i+1), used: entrees_aux[i+0]['used'], no_entree: entrees_aux[i+0]['no_entree'] },
{no: (i+2), used: entrees_aux[i+1]['used'], no_entree: entrees_aux[i+1]['no_entree'] },
{no: (i+3), used: entrees_aux[i+2]['used'], no_entree: entrees_aux[i+2]['no_entree'] }] } );
i = 25;
modele_entrees_aux.append({valeurs: [{no: i, used: entrees_aux[i-1]['used'], no_entree: entrees_aux[i-1]['no_entree'] },
{no: (i+1), used: entrees_aux[i+0]['used'], no_entree: entrees_aux[i+0]['no_entree'] },
{no: (i+2), used: entrees_aux[i+1]['used'], no_entree: entrees_aux[i+1]['no_entree'] },
{no: (i+3), used: entrees_aux[i+2]['used'], no_entree: entrees_aux[i+2]['no_entree'] }] } );
i = 29;
modele_entrees_aux.append({valeurs: [{no: i, used: entrees_aux[i-1]['used'], no_entree: entrees_aux[i-1]['no_entree'] },
{no: (i+1), used: entrees_aux[i+0]['used'], no_entree: entrees_aux[i+0]['no_entree'] },
{no: (i+2), used: entrees_aux[i+1]['used'], no_entree: entrees_aux[i+1]['no_entree'] },
{no: (i+3), used: entrees_aux[i+2]['used'], no_entree: entrees_aux[i+2]['no_entree'] }] } );
i = 1;
modele_entrees_aux.append({valeurs: [{no: i, used: entrees_aux[i-1]['used'], no_entree: entrees_aux[i-1]['no_entree'] },
{no: (i+1), used: entrees_aux[i+0]['used'], no_entree: entrees_aux[i+0]['no_entree'] },
{no: (i+2), used: entrees_aux[i+1]['used'], no_entree: entrees_aux[i+1]['no_entree'] },
{no: (i+3), used: entrees_aux[i+2]['used'], no_entree: entrees_aux[i+2]['no_entree'] }] } );
i = 5;
modele_entrees_aux.append({valeurs: [{no: i, used: entrees_aux[i-1]['used'], no_entree: entrees_aux[i-1]['no_entree'] },
{no: (i+1), used: entrees_aux[i+0]['used'], no_entree: entrees_aux[i+0]['no_entree'] },
{no: (i+2), used: entrees_aux[i+1]['used'], no_entree: entrees_aux[i+1]['no_entree'] },
{no: (i+3), used: entrees_aux[i+2]['used'], no_entree: entrees_aux[i+2]['no_entree'] }] } );
i = 9;
modele_entrees_aux.append({valeurs: [{no: i, used: entrees_aux[i-1]['used'], no_entree: entrees_aux[i-1]['no_entree'] },
{no: (i+1), used: entrees_aux[i+0]['used'], no_entree: entrees_aux[i+0]['no_entree'] },
{no: (i+2), used: entrees_aux[i+1]['used'], no_entree: entrees_aux[i+1]['no_entree'] },
{no: (i+3), used: entrees_aux[i+2]['used'], no_entree: entrees_aux[i+2]['no_entree'] }] } );
i = 13;
modele_entrees_aux.append({valeurs: [{no: i, used: entrees_aux[i-1]['used'], no_entree: entrees_aux[i-1]['no_entree'] },
{no: (i+1), used: entrees_aux[i+0]['used'], no_entree: entrees_aux[i+0]['no_entree'] },
{no: (i+2), used: entrees_aux[i+1]['used'], no_entree: entrees_aux[i+1]['no_entree'] },
{no: (i+3), used: entrees_aux[i+2]['used'], no_entree: entrees_aux[i+2]['no_entree'] }] } );
}
//=============================================================================================================
// Init des valeurs initiales des modèles liées aux entrées du réservoir lorsqu'il est dans l'un des modes utilisant une entrée Level Sensor
//=============================================================================================================
function init_entrees_level_sensor()
{
var req, res;
var nb;
var i;
var entree;
// Traitement de la chaine "entrees" pour définir les entrées actuelles du réservoir :
if (entrees !== "")
{
entree = Number(entrees);
nb_entrees_reservoir = 1;
}
else
{
entree = 0;
nb_entrees_reservoir = 0;
}
//---------------------------------------------------------------------------------------
// Entrée réservoir :
entree_level_sensor_reservoir_grid.model.clear();
entree_level_sensor_reservoir_grid.model.append({"no": 1, "no_entree_level_sensor" : entree, "libelle": (entree === 0) ? "" : qsTr("LEVEL SENSOR %1").arg(entree) });
//---------------------------------------------------------------------------------------
// Entrées Level Sensor :
var entrees_level_sensor = [];
for (i=0; i<shipheart_entrees_level_sensor_max_nombre; i++)
{
entrees_level_sensor.push({'used': 0, 'no_entree': (entree === (i+1)) ? 1 : 0}); // Init par défaut
}
// Mise à jour en fonction des entrées déjà utilisées par ailleurs (capteurs et réservoirs) :
req = '(SELECT ' + shipheart_source_mesure_reservoir + ' AS Type, Entrees ';
req += 'FROM TB_Reservoirs WHERE ';
req += 'Type_entrees=' + shipheart_reservoir_type_entrees_level_sensor + ') ';
req += ' UNION ';
req += '(SELECT ' + shipheart_source_mesure_capteur + ' AS Type, Entrees ';
req += 'FROM TB_Capteurs WHERE ';
req += 'Type_entrees=' + shipheart_reservoir_type_entrees_level_sensor + ') ';
//console.log("req = [ " + req + "; ]");
nb = bdd.requete(req);
for (i = 0; i < nb; i ++)
{
res = bdd.lecture_ligne();
if (!res.isEmpty)
{
var no;
no = Number(res[1]);
if ((no >= 1) && (no <= shipheart_entrees_level_sensor_max_nombre)) entrees_level_sensor[no - 1]['used'] = 1;
}
}
modele_entrees_level_sensor.clear();
i = 1;
modele_entrees_level_sensor.append({valeurs: [{no: i, used: entrees_level_sensor[i-1]['used'], no_entree: entrees_level_sensor[i-1]['no_entree'] },
{no: (i+1), used: entrees_level_sensor[i+0]['used'], no_entree: entrees_level_sensor[i+0]['no_entree'] },
{no: (i+2), used: entrees_level_sensor[i+1]['used'], no_entree: entrees_level_sensor[i+1]['no_entree'] },
{no: (i+3), used: entrees_level_sensor[i+2]['used'], no_entree: entrees_level_sensor[i+2]['no_entree'] }] } );
i = 5;
modele_entrees_level_sensor.append({valeurs: [{no: i, used: entrees_level_sensor[i-1]['used'], no_entree: entrees_level_sensor[i-1]['no_entree'] },
{no: (i+1), used: entrees_level_sensor[i+0]['used'], no_entree: entrees_level_sensor[i+0]['no_entree'] },
{no: (i+2), used: entrees_level_sensor[i+1]['used'], no_entree: entrees_level_sensor[i+1]['no_entree'] },
{no: (i+3), used: entrees_level_sensor[i+2]['used'], no_entree: entrees_level_sensor[i+2]['no_entree'] }] } );
}
//=============================================================================================================
// Mise à jour des valeurs saisies du réservoir
//=============================================================================================================
function mise_a_jour_reservoir()
{
var req;
var i, j;
var chaine_entrees = "";
var groupe;
// Création de la chaine représentant les n° d'entrées utilisées par le réservoir :
//-------------------------------------------------------------------------------------------------------
if (type_entrees === shipheart_reservoir_type_entrees_aux)
{
for (i = 0; i < shipheart_reservoir_max_nombre_entrees_aux; i ++)
{
j = entrees_aux_reservoir_grid.model.get(i).no_entree_aux
if (j !== 0)
{
if (chaine_entrees === "") chaine_entrees = j;
else chaine_entrees += ';' + j;
}
}
//console.log("chaine entrées = " + chaine_entrees);
// Mise à jour du champ Mode_entrees en fonction de la check-box d'inversion des entrées AUX :
// Pour mémoire, le champ 'Mode_entrees' : Si Type_entrees=1, 0=Normal, 1=logique inversée sur les entrées.
if (champ_formulaire_Logique_inversee.checked) mode_entrees = shipheart_reservoir_mode_entrees_aux_inverse;
else mode_entrees = shipheart_reservoir_mode_entrees_aux_normal;
}
//-------------------------------------------------------------------------------------------------------
else if (type_entrees === shipheart_reservoir_type_entrees_level_sensor)
{
j = entree_level_sensor_reservoir_grid.model.get(0).no_entree_level_sensor
if (j !== 0)
{
chaine_entrees = j;
}
else return; // On ne peut pas enregistrer un réservoir avec un # de Level sensor = 0
//console.log("chaine entrées = " + chaine_entrees);
}
// Mise à jour de l'entrée dans TB_Réservoirs :
req = 'UPDATE TB_Reservoirs SET Nom="' + champ_formulaire_Nom.text + '" ';
req += ', Adresse_module=' + adresse_module;
req += ', Type_entrees=' + type_entrees; // champ_formulaire_Type_entrees.model.get(champ_formulaire_Type_entrees.currentIndex).valeur;
req += ', Entrees="' + chaine_entrees + '" ';
req += ', Mode_entrees=' + mode_entrees;
req += ', Type_sonde_entrees=' + type_sonde_entrees;
req += ', ID_Famille=' + champ_formulaire_Famille.model.get(champ_formulaire_Famille.currentIndex).valeur;
req += ', Niveau_coeff_filtrage=' + champ_formulaire_Niveau_coeff_filtrage.model.get(champ_formulaire_Niveau_coeff_filtrage.currentIndex).valeur;
req += ', Capacite=' + Number(champ_formulaire_Capacite.text);
req += ', Logique=' + champ_formulaire_Logique.model.get(champ_formulaire_Logique.currentIndex).valeur;
if (type_entrees === shipheart_reservoir_type_entrees_aux)
{
if (nb_entrees_reservoir_init !== nb_entrees_reservoir) req += ', Liste_valeurs_niveaux="' + Fonctions_reservoirs.chaine_valeur_niveau_reservoir_usine(shipheart_reservoir_type_entrees_aux, nb_entrees_reservoir) + '" '; // On ne met à jour la table d'étalonnage que si le nombre d'entrées à changé...
}
else if (type_entrees === shipheart_reservoir_type_entrees_level_sensor)
{
if ((mode_entrees_init !== champ_formulaire_Type_entrees.model.get(champ_formulaire_Type_entrees.currentIndex).mode) ||
(type_sonde_entrees_init !== champ_formulaire_Type_entrees.model.get(champ_formulaire_Type_entrees.currentIndex).sous_mode))
{
req += ', Liste_valeurs_niveaux="' + Fonctions_reservoirs.chaine_valeur_niveau_reservoir_usine(shipheart_reservoir_type_entrees_level_sensor, champ_formulaire_Type_entrees.model.get(champ_formulaire_Type_entrees.currentIndex).mode, champ_formulaire_Type_entrees.model.get(champ_formulaire_Type_entrees.currentIndex).sous_mode) + '" '; // On ne met à jour la table d'étalonnage que si le mode ou le sous-mode à changé...
}
}
req += ' WHERE Cle_primaire=' + id_reservoir + ' '
//console.log("req = [ " + req + "; ]");
bdd.requete_unique(req);
synchro_bdd(shipheart_type_synchro_config);
}
//=============================================================================================================
// Création du réservoir
//=============================================================================================================
function creation_reservoir()
{
var req, res;
var i, j;
var chaine_entrees = "";
var nb_entrees;
//-----------------------------------------------------------------------------------------------------------
if (type_entrees === shipheart_reservoir_type_entrees_aux)
{
// Création de la chaine représentant les n° d'entrées utilisées par le réservoir :
nb_entrees = 0;
for (i = 0; i < shipheart_reservoir_max_nombre_entrees_aux; i ++)
{
j = entrees_aux_reservoir_grid.model.get(i).no_entree_aux
if (j !== 0)
{
if (chaine_entrees === "") chaine_entrees = j;
else chaine_entrees += ';' + j;
nb_entrees ++; // Nécessaire pour appeler la fonction 'create_liste_valeurs_niveaux()'
}
}
//console.log("chaine entrées = " + chaine_entrees);
// Mise à jour du champ Mode_entrees en fonction de la check-box d'inversion des entrées AUX :
// Pour mémoire, le champ 'Mode_entrees' : Si Type_entrees=1, 0=Normal, 1=logique inversée sur les entrées.
if (champ_formulaire_Logique_inversee.checked) mode_entrees = shipheart_reservoir_mode_entrees_aux_inverse;
else mode_entrees = shipheart_reservoir_mode_entrees_aux_normal;
}
//-----------------------------------------------------------------------------------------------------------
else if (type_entrees === shipheart_reservoir_type_entrees_level_sensor)
{
// Création de la chaine représentant les n° d'entrées utilisées par le réservoir :
j = entree_level_sensor_reservoir_grid.model.get(0).no_entree_level_sensor
if (j !== 0)
{
chaine_entrees = j;
}
else return; // On ne peut pas créer un réservoir avec un # de Level sensor = 0
}
// Création de l'entrée dans TB_Réservoirs :
req = 'INSERT INTO TB_Reservoirs ';
req += ' (Nom, ';
req += ' Adresse_module, ';
req += ' Type_entrees, ';
req += ' Entrees, ';
req += ' Mode_entrees, ';
req += ' Type_sonde_entrees, ';
req += ' ID_Famille, ';
req += ' Niveau_coeff_filtrage, ';
req += ' Liste_valeurs_niveaux, ';
req += ' Capacite, ';
req += ' Logique) '
req += ' VALUES (';
req += ' "' + champ_formulaire_Nom.text + '"';
req += ', ' + adresse_module + ' ';
req += ', ' + type_entrees; // champ_formulaire_Type_entrees.model.get(champ_formulaire_Type_entrees.currentIndex).valeur;
req += ', "' + chaine_entrees + '" ';
req += ', ' + mode_entrees + ' ';
req += ', ' + type_sonde_entrees + ' ';
req += ', ' + champ_formulaire_Famille.model.get(champ_formulaire_Famille.currentIndex).valeur;
req += ', ' + champ_formulaire_Niveau_coeff_filtrage.model.get(champ_formulaire_Niveau_coeff_filtrage.currentIndex).valeur;
if (type_entrees === shipheart_reservoir_type_entrees_aux) req += ', "' + Fonctions_reservoirs.chaine_valeur_niveau_reservoir_usine(shipheart_reservoir_type_entrees_aux, nb_entrees) + '" ';
else req += ', "' + Fonctions_reservoirs.chaine_valeur_niveau_reservoir_usine(shipheart_reservoir_type_entrees_level_sensor, champ_formulaire_Type_entrees.model.get(champ_formulaire_Type_entrees.currentIndex).mode, champ_formulaire_Type_entrees.model.get(champ_formulaire_Type_entrees.currentIndex).sous_mode) + '" ';
req += ', ' + Number(champ_formulaire_Capacite.text);
req += ', ' + champ_formulaire_Logique.model.get(champ_formulaire_Logique.currentIndex).valeur;
req += ') ';
//console.log("req = [ " + req + "; ]");
bdd.requete_unique(req);
// Mise à jour des entrées (après l'insertion du réservoir pour avoir sa nouvelle clé_primaire) :
req = 'SELECT Cle_primaire FROM TB_Reservoirs ORDER BY Cle_primaire DESC LIMIT 1 ';
//console.log("req = [ " + req + "; ]");
res = bdd.requete_unique(req);
id_reservoir = Number(res[0]);
// Demande de reconfiguration système via la BDD car on a modifié des valeurs de configuration :
synchro_bdd(shipheart_type_synchro_config);
}
//=============================================================================================================
// Check suppression du réservoir
//=============================================================================================================
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")
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_reservoir + ' AND ID_Source=' + id_reservoir + ' ';
req += ' ORDER BY Nom';
//console.log("Requête = [ " + req + "; ]")
nb = bdd.requete(req);
if (nb > 0)
{
if (nb === 1) message += "<br /><br />" + qsTr("Ce réservoir est utilisé par l'évènement ci-dessous.<br />Vous devez modifier ou supprimer cet évènement pour qu'il ne dépende plus de ce réservoir avant de pouvoir le supprimer.") + "<br /><br />";
else message += "<br /><br />" + qsTr("Ce réservoir est utilisé par les %1 évènements ci-dessous.<br />Vous devez modifier ou supprimer ces évènements pour qu'ils ne dépendent plus de ce réservoir avant de pouvoir le supprimer.").arg(nb) + "<br /><br />";
for (i = 0; i < nb; i ++)
{
res = bdd.lecture_ligne();
if (!res.isEmpty)
{
message += "&#8227; " + (i+1) + " : " + res[1] + "<br />";
}
}
}
//=========================================================================
// 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_reservoir + ':' + id_reservoir + '/%" ';
//console.log("Requête = [ " + req + "; ]")
nb = bdd.requete(req);
if (nb > 0)
{
if (nb === 1) message += "<br /><br />" + qsTr("Ce réservoir est utilisé par le capteur calculé ci-dessous.<br />Vous devez modifier ou supprimer ce capteur calculé pour qu'il ne dépende plus de ce réservoir avant de pouvoir le supprimer.") + "<br /><br />";
else message += "<br /><br />" + qsTr("Ce réservoir est utilisé par les %1 capteurs calculés ci-dessous.<br />Vous devez modifier ou supprimer ces capteurs calculés pour qu'ils ne dépendent plus de ce réservoir avant de pouvoir le supprimer.").arg(nb) + "<br /><br />";
for (i = 0; i < nb; i ++)
{
res = bdd.lecture_ligne();
if (!res.isEmpty)
{
message += "&#8227; " + (i+1) + " : " + res[0] + "<br />";
}
}
}
//=========================================================================
// 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.open();
return(-1);
}
}
//=============================================================================================================
// Suppression du réservoir
//=============================================================================================================
function suppression_reservoir()
{
var req;
var i, j;
// Suppression du réservoir dans TB_Réservoirs :
req = 'DELETE FROM TB_Reservoirs WHERE Cle_primaire=' + id_reservoir + ' ';
//console.log("Requête = " + req)
bdd.requete_unique(req);
// Demande de reconfiguration système via la BDD car on a modifié des valeurs de configuration :
synchro_bdd(shipheart_type_synchro_config);
}
//=============================================================================================================
// 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<modele.count; i ++)
{
if (modele.get(i).valeur === cible) break; // Cas où la valeur cible a été trouvée parmi les valeurs du modèle
}
if (i === modele.count)
{
console.log("Aucune valeur trouvée pour cible = [" + cible + "] du modèle = " + nom_modele);
i = -1; // Cas où la valeur n'a pas été trouvée parmi les valeurs du modèle
}
//else console.log("Valeur trouvée : [" + i + "] pour cible = [" + cible + "] soit texte = [" + modele.get(i).texte + "]");
return(i);
}
//=============================================================================================================
// Recherche groupe d'une entrée AUX à partir de son numéro et renvoit le n° de grpupe (entre 0 et 7)
//=============================================================================================================
function recherche_groupe_entree_aux(entree)
{
switch(Math.trunc(entree/4))
{
case 0: return(4);
case 1: return(5);
case 2: return(6);
case 3: return(7);
case 4: return(0);
case 5: return(1);
case 6: return(2);
case 7: return(3);
default:
console.log("Erreur de groupe d'entrée AUX")
return(-1);
}
}
//=============================================================================================================
// Recherche groupe d'une entrée LEVEL SENSOR à partir de son numéro et renvoit le n° de groupe (entre 0 et 1)
//=============================================================================================================
function recherche_groupe_entree_level_sensor(entree)
{
switch(Math.trunc(entree/4))
{
case 0: return(0);
case 1: return(1);
default:
console.log("Erreur de groupe d'entrée LEVEL SENSOR")
return(-1);
}
}
//=============================================================================================================
// Recherche l'index dans le modèle 'champ_formulaire_Type_entrees' qui correspond au 'type_entrees', au 'mode'
// et au 'sous_mode' reçus en paramètres
// NB : ce positionnement est particulier car il nécessite une analyse non seulement de 'type_entrees'
// mais aussi de 'Entrees' et de son contenu (mode et sous_mode).
//=============================================================================================================
function recherche_index_type_entree(type_entrees, mode, sous_mode)
{
var index = 0; // Valeur par défaut
switch(type_entrees)
{
case shipheart_reservoir_type_entrees_aux :
index = 1;
break;
case shipheart_reservoir_type_entrees_level_sensor:
switch (mode)
{
case 1: // 0-10V
index = 6;
break;
case 2: // 0-500R
switch(sous_mode) // Sous-mode :
{
case shipheart_reservoir_mode_entrees_level_sensor_500r_0_190r: // 0-190R
index = 2;
break;
case shipheart_reservoir_mode_entrees_level_sensor_500r_240_30r: // 240-30R
index = 3;
break;
case shipheart_reservoir_mode_entrees_level_sensor_500r_0_500r: // 0-500R
default:
index = 4;
break;
}
break;
case 3: // 4-20mA
index = 5;
break;
}
break;
case 0:
default:
index = 0;
break;
}
return(index);
}
}