//======================================================================================================================================================================== // CONFIG_RESEAU_ONE_WIRE.QML // Ce fichier traite la configuration des devices One Wire. La page permet notamment de : // - Afficher tous les capteurs déjà configurés (présents ou absent mais utilisés sur un capteur) // - Déclencher la recherche de nouveaux capteurs OW // La page est appelée depuis la page PARAMETRES_AVANCES. //======================================================================================================================================================================== import QtQuick 2.12 import QtQuick.Controls 2.12 import qt.koriolan.shipheart 1.0 Shipheart_page { id: page_config_reseau_one_wire // Mis en forme : readonly property double affichage_hauteur_utile: shipheart_hauteur_page - shipheart_hauteur_bandeau_haut - shipheart_hauteur_bandeau_bas readonly property double pourcentage_largeur_labels_formulaire: 0.5 readonly property int nombre_capteurs_affiches_sur_une_colonne: 8 readonly property int nombre_sondes_affichees_sur_une_colonne: 8 readonly property double pourcentage_largeur_colonne_gauche: 0.75 readonly property int espace_colonnes_principales: 20 readonly property double pourcentage_bandeau_bas_largeur_zone_retour: 1.0 readonly property int periode_init_raffraichissement_parametres: 1 // En ms readonly property int periode_raffraichissement_parametres: 1000 // En ms /!\ Laisser à 1s afin que le compteur secondes fonctionne correctement... readonly property int periode_decouverte_reseau_ow: 10 // En secondes // Affichage : property int niveau_page: 0 property int defaut_bus_ow: 0 property int compteur_secondes: periode_decouverte_reseau_ow // Cette init permet de débuter par une découverte réseau // 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(); } if (stackView.depth === (niveau_page + 1)) // Désactive le raffraichissement quand la page n'est pas activée dans la pile { compteur_secondes ++; if (compteur_secondes >= periode_decouverte_reseau_ow) { compteur_secondes = 0; demande_decouverte_ow(); // On fait une découverte OW toutes les 10 secondes tant qu'on est sur cette page (et uniquement quand on est sur cette page !) } else { if (compteur_secondes >= 2) mise_a_jour_donnees(); // La mise à jour des données se fait toutes les secondes, sauf entre 0 et 2s (pour laisser le temps à la découverte réseau de se terminer et ainsi éviter les affichages tronqués) } } } } // Titre de la page : Shipheart_titre_1 {titre:qsTr("Réseau One Wire"); hauteur: shipheart_hauteur_bandeau_haut} //------------------------------------------------------- // Ecran de gauche (liste des capteurs) : //------------------------------------------------------- Rectangle { id: zone_affichage_gauche x: 0 y: shipheart_hauteur_bandeau_haut; width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: affichage_hauteur_utile color: "transparent" //------------------------------------------------------------------- // Grille pour afficher les devices : GridView { id: grille_principale width: parent.width height: affichage_hauteur_utile - (affichage_hauteur_utile / nombre_sondes_affichees_sur_une_colonne) cellWidth: parent.width; cellHeight: affichage_hauteur_utile / nombre_sondes_affichees_sur_une_colonne 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 visible: (defaut_bus_ow === 0) delegate: Rectangle { width: grille_principale.cellWidth height: grille_principale.cellHeight color: "transparent" Rectangle { width: parent.width - 10 height: parent.height - 10 anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter radius: shipheart_rayon_bouton color: (erreur === 0) ? shipheart_couleur_fond_bouton : couleur_rouge_transparent border.color: couleur_blanc_casse border.width: ((affecte === 0) && (erreur === 0)) ? 1 : 0 Text { anchors.fill: parent horizontalAlignment: Qt.AlignLeft verticalAlignment: Qt.AlignTop topPadding: 10 leftPadding: 20 text: "ID : " + rom_code color: ((affecte === 1) && (erreur === 0)) ? couleur_gris_moyen : couleur_blanc_casse font.pixelSize: 14 wrapMode: Label.Wrap } Text { anchors.fill: parent horizontalAlignment: Qt.AlignLeft verticalAlignment: Qt.AlignTop topPadding: 10 leftPadding: parent.width / 2 text: device_family + " [" + device_family_description + "]" color: ((affecte === 1) && (erreur === 0)) ? couleur_gris_moyen : couleur_blanc_casse font.pixelSize: 14 wrapMode: Label.Wrap } Text { anchors.fill: parent horizontalAlignment: Qt.AlignLeft verticalAlignment: Qt.AlignBottom bottomPadding: 10 leftPadding: 20 text: nom color: ((affecte === 1) && (erreur === 0)) ? couleur_gris_moyen : couleur_blanc_casse font.pixelSize: 18 font.weight: Font.Bold wrapMode: Label.Wrap } Text { anchors.fill: parent horizontalAlignment: Qt.AlignLeft verticalAlignment: Qt.AlignBottom bottomPadding: 10 leftPadding: parent.width / 2 text: emplacement color: ((affecte === 1) && (erreur === 0)) ? couleur_gris_moyen : couleur_blanc_casse font.pixelSize: 14 wrapMode: Label.Wrap } Text { anchors.fill: parent horizontalAlignment: Qt.AlignRight verticalAlignment: Qt.AlignVCenter rightPadding: 20 text: valeur color: ((affecte === 1) && (erreur === 0)) ? couleur_gris_moyen : couleur_blanc_casse font.pixelSize: 18 font.bold: true // wrapMode: Label.Wrap } } 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. anchors.fill: parent onPressAndHold: { shipheart_clic(); stackView.push("config_reseau_one_wire_modification.qml", {"rom_code": rom_code}); } onClicked: { shipheart_clic(); if (affecte === 0) stackView.push("config_capteur.qml", {"type_entrees": shipheart_capteur_type_entrees_ow, "entrees": rom_code}); } } } ListModel { id: modele_grille_principale } Label { anchors.fill: parent horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter visible: parent.count === 0 text: qsTr("Aucune sonde n'est encore installée...") color: couleur_rouge_transparent font.pixelSize: 15 font.bold: true wrapMode: Label.Wrap } } Rectangle { id: message_defaut_bus_ow anchors.fill: parent color: "transparent" border.width: 3 border.color: couleur_orange radius: shipheart_rayon_bouton visible: (defaut_bus_ow !== 0) Text { // Affiche parfaitement 1, 2 ou 3 lignes de texte. A partir de 4 et 5, ça mort sur le contour du rectangle mais c'est encore lisible. id: etat_circuit width: parent.width - anchors.leftMargin; wrapMode: Text.Wrap horizontalAlignment: Text.AlignHCenter text: qsTr("Le bus One Wire est actuellement détecté en court-circuit.
Cet état ne présente aucun danger mais l'empêche de fonctionner.

Vérifier le câblage correspondant jusqu'à ce que ce message disparaisse."); anchors { horizontalCenter: parent.horizontalCenter verticalCenter: parent.verticalCenter } font.pixelSize: 18 color: couleur_blanc_casse } } } //------------------------------------------------------- // Ecran de droite (liste des sondes de température) : //------------------------------------------------------- Rectangle { id: zone_affichage_droite x: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) + (espace_colonnes_principales / 2) y: shipheart_hauteur_bandeau_haut; width: (shipheart_largeur_page * (1 - pourcentage_largeur_colonne_gauche)) - (espace_colonnes_principales / 2) height: affichage_hauteur_utile color: "transparent" } //------------------------------------------------------- // Bandeau bas : //------------------------------------------------------- Row { x: 0 y: shipheart_hauteur_page - shipheart_hauteur_bandeau_bas; width: shipheart_largeur_page; height: shipheart_hauteur_bandeau_bas; padding: 5 spacing: 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() } } } } // 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'. // Principes : // L'état de chaque device est caractérisé par 3 indicateurs : // - Affectation : indique si le device est utilisé par un capteur (ou un équipement en général). // - si 0 : le device n'est PAS utilisé // - si 1 : le device est utilisé // - Présence : indique si le device est physiquement présent (et donc qu'il a communiqué correctement lors de la dernière communication de la part du Compagnon) // - si 0 : le device est absent // - si 1 : le device est présent // - Etat : indique l'état du device lui-même ou, par extension, l'état du réseau. // - si 0 : le device fonctionne correctement // - si -1 : le device comporte une erreur interne // - si -2 : l'ensemble du bus est en erreur (cf alors également 'Defaut_bus_ow' dans TB_Système) // // Dans TB_One_wire, il n'y a JAMAIS d'entrée avec Présence=0 et Affectation=0. En effet, dans ce cas, l'entrée est supprimée. // // L'indicateur d'erreur est calculé comme la synthèse entre 'Etat<0' OU 'Affecté=1 ET Présence=0'. Si l'une de ces condition est vraie, l'indicateur d'erreur est vrai. // Au-delà de 'erreur' qui prévaut pour l'affichage, on utilise 'Affectation' pour indiquer si le device est occupé ou pas. // // En synthèse, on gère 3 états distincts pour un device : // 1. Erreur=0 et Affecté=1 : cas normal d'un device utilisé // 2. Erreur=0 et Affecté=0 : cas normal d'un device non utilisé // 3. Erreur=1 : cas d'un device en erreur (et a priori, utilisé car sinon, il est peu probabe qu'il soit dans la liste) // A noter qu'un 4ème état existe mais il est global : si TB_Systeme.defaut_bus_ow=1, une page dédiée est affichée sur tout l'écran pour indiquer un défaut bus global. //============================================================================================================= // Init de la page //============================================================================================================= function init_page() { niveau_page = stackView.depth - 1; // Permet de stocker le niveau de la page dans la Stackview mise_a_jour_donnees(); } //============================================================================================================= // Mise à jour des données //============================================================================================================= function mise_a_jour_donnees() { var req, res; var i; var nb_sondes; var device_family; var device_family_description; var erreur; //======================================================================= // Grille principale (liste des sondes de température configurées) : modele_grille_principale.clear(); // RAZ des valeurs existantes req = 'SELECT Valeur FROM TB_Systeme WHERE Nom="Defaut_bus_ow" '; res = bdd.requete_unique(req); defaut_bus_ow = Number(res[0]); if (defaut_bus_ow === 0) // Si un défaut de bus OW est en cours, il est inutile d'afficher quoi que ce soit... { req = 'SELECT '; req += ' Rom_code, '; req += ' CONV(substring_index(Rom_code,":",1), 16, 10) AS Type, ' // Extrait le premier octet du Rom_Code qui contient le Device-Family puis le convertit de Hexa en Décimal req += ' Affecte, '; req += ' Presence, '; req += ' Etat, '; req += ' Valeur, '; req += ' Emplacement '; req += ' FROM TB_One_wire '; req += ' ORDER BY Rom_code'; nb_sondes = bdd.requete(req); //console.log("Requête =" + req + " et nb réponses = " + nb_sondes); for (i = 0; i < nb_sondes; i ++) { res = bdd.lecture_ligne(); if (!res.isEmpty) { // Recherche du type de device en fonction de ROM_CODE_0 : switch(Number(res[1])) { case 0x01: device_family = "DS1990A, DS1990R, DS2401, DS2411"; device_family_description= "Serial number"; break; case 0x02: device_family = "DS1991"; device_family_description= "Secure memory"; break; case 0x04: device_family = "DS2404"; device_family_description= "EconoRAM time chip"; break; case 0x05: device_family = "DS2405"; device_family_description= "Addressable switch"; break; case 0x06: device_family = "DS1993"; device_family_description= "4Kb Memory button"; break; case 0x08: device_family = "DS1992"; device_family_description= "1kb memory button"; break; case 0x0A: device_family = "DS1995"; device_family_description= "16kb memory button"; break; case 0x0B: device_family = "DS1985, DS2505"; device_family_description= "16kb add-only memory"; break; case 0x0C: device_family = "DS1996"; device_family_description= "64kb memory button"; break; case 0x0F: device_family = "DS1986, DS2506"; device_family_description= "64kb add-only memory"; break; case 0x10: device_family = "DS18S20"; device_family_description= "Temperature sensor"; break; case 0x12: device_family = "DS2406, DS2407"; device_family_description= "Dual addressable switch"; break; case 0x14: device_family = "DS1971, DS2430A"; device_family_description= "256b EEPROM"; break; case 0x16: device_family = "DS1954, DS1957"; device_family_description= "Coprocessor ibutton"; break; case 0x18: device_family = "DS1962, DS1963S"; device_family_description= "4kb monetary device with SHA"; break; case 0x1A: device_family = "DS1963L"; device_family_description= "4kb monetary device"; break; case 0x1B: device_family = "DS2436"; device_family_description= "Battery ID/monitor"; break; case 0x1C: device_family = "DS28E04-100"; device_family_description= "4kb EEPROM with PIO"; break; case 0x1D: device_family = "DS2423"; device_family_description= "4kb 1Wire RAM with counter"; break; case 0x1E: device_family = "DS2437"; device_family_description= "Smart battery monitor IC"; break; case 0x1F: device_family = "DS2409"; device_family_description= "Microlan coupler"; break; case 0x20: device_family = "DS2450"; device_family_description= "Quad ADC"; break; case 0x21: device_family = "DS1921G, DS1921H, DS1921Z"; device_family_description= "Thermochron loggers"; break; case 0x22: device_family = "DS1822"; device_family_description= "Econo digital thermometer"; break; case 0x23: device_family = "DS1973, DS2433"; device_family_description= "4kb EEPROM"; break; case 0x24: device_family = "DS2415"; device_family_description= "Time chip"; break; case 0x26: device_family = "DS2438"; device_family_description= "Smart battery monitor"; break; case 0x27: device_family = "DS2417"; device_family_description= "Time chip"; break; case 0x28: device_family = "DS18B20"; device_family_description= "Temperature sensor"; break; // Cas des DS18B20 case 0x29: device_family = "DS2408"; device_family_description= "8-channel switch"; break; case 0x2C: device_family = "DS2890"; device_family_description= "Digital potentiometer"; break; case 0x2D: device_family = "DS1972, DS2431"; device_family_description= "1024b memory"; break; case 0x2E: device_family = "DS2770"; device_family_description= "Battery monitor/charge controller"; break; case 0x30: device_family = "DS2760"; device_family_description= "Precision li+ battery monitor"; break; case 0x31: device_family = "DS2720"; device_family_description= "Single cell li+ protection IC"; break; case 0x32: device_family = "DS2780"; device_family_description= "Fuel gauge IC"; break; case 0x33: device_family = "DS1961S, DS2432"; device_family_description= "1kb memory with SHA"; break; case 0x34: device_family = "DS2703"; device_family_description= "Sha battery authentication"; break; case 0x35: device_family = "DS2755"; device_family_description= "Fuel gauge"; break; case 0x36: device_family = "DS2740"; device_family_description= "Coulomb counter"; break; case 0x37: device_family = "DS1977"; device_family_description= "32kb memory"; break; case 0x3D: device_family = "DS2781"; device_family_description= "Fuel gauge IC"; break; case 0x3A: device_family = "DS2413"; device_family_description= "Two-channel switch"; break; case 0x3B: device_family = "DS1825, MAX31826, MAX31850"; device_family_description= "Temperature sensor, TC reader"; break; case 0x41: device_family = "DS1923, DS1922E, DS1922L, DS1922T"; device_family_description= "Hygrochrons"; break; case 0x42: device_family = "DS28EA00"; device_family_description= "Digital thermometer with sequence detect"; break; case 0x43: device_family = "DS28EC20"; device_family_description= "20kb memory"; break; case 0x44: device_family = "DS28E10"; device_family_description= "Sha1 authenticator"; break; case 0x51: device_family = "DS2751"; device_family_description= "Battery fuel gauge"; break; case 0x7E: device_family = "EDS00xx"; device_family_description= "EDS sensor adapter"; break; case 0x81: device_family = "USBID, DS1420"; device_family_description= "ID"; break; case 0x82: device_family = "DS1425"; device_family_description= "ID and pw protected RAM"; break; default: device_family = "" + qsTr("Type inconnu") + ""; break; } erreur = 0; if (Number(res[4]) < 0) erreur = 1; else { if ((Number(res[2]) === 1) && (Number(res[3]) === 0)) erreur = 1; } //console.log("Sonde OW trouvée : ROM_Code = [" + res[0] + "] donc Device_type = " + device_family_description); modele_grille_principale.append({ "rom_code": res[0], "nom": qsTr("Sonde non affectée"), "device_family": device_family, "device_family_description": device_family_description, "affecte": Number(res[2]), "presence": Number(res[3]), "erreur": erreur, "valeur": Number(res[5]).toFixed(2) + " °C", "emplacement": res[6] }); console.log("ID:" + res[0] + " est " + Number(res[2])); } } // Mise à jour du nom des capteurs utilisant ces sondes : for (i = 0; i < modele_grille_principale.count; i ++) { if (modele_grille_principale.get(i).affecte > 0) { req = 'SELECT Nom FROM TB_Capteurs WHERE Adresse_module=0 AND Type_entrees=' + shipheart_capteur_type_entrees_ow + ' AND Entrees="' + modele_grille_principale.get(i).rom_code + '" '; //console.log("Requête = [ " + req + "; ]"); var nb = bdd.requete(req); if (nb > 0) { res = bdd.lecture_ligne(); modele_grille_principale.setProperty(i, "nom", res[0]); } } } } } //============================================================================================================= // Demande de découverte OW //============================================================================================================= function demande_decouverte_ow() { var req, res; var i; var nb; req = 'UPDATE TB_Systeme SET Valeur=1 WHERE Nom="Demande_decouverte_ow" '; //console.log("req =" + req); bdd.requete_unique(req); } }