Différences entre les versions de « Niveau de liquide dans une cuve ou un forage »
(84 versions intermédiaires par 2 utilisateurs non affichées) | |||
Ligne 2 : | Ligne 2 : | ||
{{Infobox IPX800 | {{Infobox IPX800 | ||
| titre = Niveau de liquide | | titre = Niveau de liquide | ||
| image = | | image =Niveau-cuve-pres.PNG | ||
| famille = | | famille = Widgets | ||
| date-create = 04/10/2020 | | date-create = 04/10/2020 | ||
| date-update = | | date-update = 25/05/2021 | ||
| auteur = fgtoul | | auteur = fgtoul | ||
}} | }} | ||
Ligne 12 : | Ligne 12 : | ||
==Présentation== | ==Présentation== | ||
Déterminer le volume de fioul restant dans une cuve peut parfois être complexe. Pour nous aider, les constructeurs de cuves nous fournissent des abaques, tableaux dans lesquels le volume restant est déterminé à partir de la hauteur mesurée du liquide. | |||
L'IPX800 V4, associée à des capteurs de niveaux, peut nous aider dans cette tâche, en nous offrant la possibilité d'avoir le volume en lecture directe. | |||
Voici quelques widgets écrits en javascript et HTML. | Voici quelques widgets écrits en javascript et HTML. | ||
Vous pourrez les personnaliser et les utiliser sur | Vous pourrez les personnaliser et les utiliser librement sur le dashboard de votre [[IPX800 V4]]. | ||
Attention, si vous mesurez le niveau d'un produit corrosif ou d'un hydrocarbure (fioul, ...) dans une cuve, il faudra utiliser un capteur spécifique (anti-corrosion, | Attention, si vous mesurez le niveau d'un produit corrosif ou d'un hydrocarbure (fioul, ...) dans une cuve, il faudra utiliser un capteur spécifique (anti-corrosion, antidéflagrant, ...). De même il existe des capteurs spécifiques pour des eaux sales, eaux noires, ... | ||
Pour la construction des widgets ci-dessous, il vous sera demandé d'entrer des dimensions en cm.<br> | Pour la construction des widgets ci-dessous, il vous sera demandé d'entrer des dimensions en cm.<br> | ||
Pensez à entrer les dimensions internes de la cuve (dimensions externes moins 2 fois l'épaisseur de l'enveloppe). | Pensez à entrer les dimensions internes de la cuve (dimensions externes moins 2 fois l'épaisseur de l'enveloppe). | ||
== | ==Prérequis== | ||
Tous les widgets présentés ci-dessous nécessitent la création d'une source de données sur le dashboard de l'[[IPX800 V4]]. | |||
Cliquez sur le menu "Créer une source de données" puis renseignez les paramètres comme suit : | |||
[[fichier:status_xml.png|750px]] | |||
Renseignez l'utilisateur et mot de passe si vous les avez activés. | |||
==Exemples avec un capteur analogique== | |||
Il existe différents types de capteurs permettant de mesurer un niveau. | Il existe différents types de capteurs permettant de mesurer un niveau. | ||
Ligne 26 : | Ligne 39 : | ||
* à laser, infrarouges ou ultrasons | * '''à laser, infrarouges ou ultrasons''' | ||
ils mesurent la hauteur vide en haut de cuve grâce au temps pris par le signal pour parcourir la distance (aller/retour).<br> Connaissant la célérité du signal qui est une caractéristique physique propre à sa nature (lumière, son), il suffit de mesurer le temps du parcours pour en déterminer la distance | |||
Distance<sub>vide</sub> = célérité<sub>signal</sub> * temps / 2). | |||
===Cas d'une cuve | Il est alors question de mesure dite ToF ('''T'''ime '''o'''f '''F'''light) . | ||
La hauteur de liquide s'obtient par soustraction de la mesure à la hauteur totale de la cuve (Hauteur<sub>liquide</sub> = Hauteur<sub>cuve</sub> - D<sub>vide</sub>). | |||
* '''composés d'une sonde immergée''' | |||
ils calculent la hauteur de liquide grâce à la pression lue en fond de cuve. La sonde à pression différentielle est plus précise car elle réajuste la mesure en fonction de la pression athmosphérique. La hauteur du liquide est déterminée par équation en fonction de la pression mesurée. la hauteur de liquide est en lecture directe. | |||
* '''résistifs ou capacitifs''' | |||
ils mesurent la hauteur de liquide en contact avec leur partie immergée (tige, fil conducteur, ...) grâce à la variation d'une caractéristique du circuit électrique. La hauteur du liquide est déterminée directement par une formule. | |||
Nous admettrons que vous avez correctement configuré votre entrée analogique afin d'obtenir une hauteur en '''mètres''' (dans les exemples ci-dessous, la valeur est multipliée par 100 afin d'être reconvertie en cm). | |||
Pour cela, vous aurez adapté les formules de conversion dans la configuration de l'entrée analogique concernée, en fonction des caractéristiques du capteur. | |||
===Cas d'une cuve parallélépipédique=== | |||
[[fichier: | [[fichier:CuveParallelepipedique2.png]] [[fichier:NiveauCubique.png]] | ||
'''usage : ''' | '''usage : ''' | ||
* Sur le dashboard, créez une source de données nommée '''STATUS''' vers le fichier Status.xml de l'ipx800. | * Sur le dashboard, créez une source de données nommée '''STATUS''' vers le fichier Status.xml de l'ipx800. | ||
* Renseignez le volume total de la cuve en litres, | * Renseignez le volume total de la cuve en litres, ses 3 dimensions en cm, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . la hauteur de liquide est attendue en cm. | ||
* créez un widget de type HTML, hauteur 2 blocs. | * créez un widget de type HTML, hauteur 2 blocs. | ||
* insérez et ajustez ce code dans le widget : | * insérez et ajustez ce code dans le widget : | ||
Ligne 45 : | Ligne 71 : | ||
<div class="mw-collapsible mw-collapsed" data-expandtext="{{int:show}}" data-collapsetext="{{int:hide}}" style="width:730px;"> | <div class="mw-collapsible mw-collapsed" data-expandtext="{{int:show}}" data-collapsetext="{{int:hide}}" style="width:730px;"> | ||
''' | '''Afficher le code du widget''' | ||
<div class="mw-collapsible-content"> | <div class="mw-collapsible-content"> | ||
Ligne 52 : | Ligne 78 : | ||
var hauteurFuel=(datasources["STATUS"]["response"]["analog0"] * 100).toFixed(2); | var hauteurFuel=(datasources["STATUS"]["response"]["analog0"] * 100).toFixed(2); | ||
var hauteurCuve=120; //hauteur cuve en cm | |||
var largeurCuve=120; //largeur cuve en cm | |||
var longueurCuve=209; //longueur cuve en cm | |||
var volumeCuve=3000; //volume cuve pleine en litres | |||
var mesureToF=0;//renseignez 1 si vous utilisez un capteur ultrasons/infrarouges ou laser | |||
//ne pas modifier le code ci-dessous | |||
var | if (mesureToF==1){hauteurFuel=hauteurCuve-hauteurFuel;} // si mesure ToF | ||
var pourcentage=100 - (100*hauteurFuel/hauteurCuve); | |||
//calcul de la consommation à partir de la baisse du niveau | |||
var consommation=((hauteurCuve-hauteurFuel)*largeurCuve*longueurCuve)/1000 //consommation en litres | |||
//calcul de la | |||
var | |||
//calcul volume Fuel | //calcul volume Fuel | ||
var vf=0; | var vf=0; | ||
vf=hauteurFuel*largeurCuve*longueurCuve; | |||
vf=(vf/1000).toFixed(0); | |||
return ` | return ` | ||
<style> | <style> | ||
.box{ | .box{ | ||
height: 80px; | height: 80px; | ||
Ligne 87 : | Ligne 106 : | ||
transform: translate(0, -50%); | transform: translate(0, -50%); | ||
background: #666666; | background: #666666; | ||
border-radius: | border-radius:15%; | ||
overflow: hidden; | overflow: hidden; | ||
} | } | ||
Ligne 97 : | Ligne 116 : | ||
width: 80px; | width: 80px; | ||
height: 80px; | height: 80px; | ||
transform:translate(0,${pourcentage}%); | transform:translate(0,${pourcentage}%); | ||
background:#76B558; | background:#76B558; | ||
} | } | ||
Ligne 106 : | Ligne 125 : | ||
<div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;"> | <div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;"> | ||
<span >Contenance cuve: ${volumeCuve}</span> litres<br> | <span >Contenance cuve: ${volumeCuve}</span> litres<br> | ||
<span > | <span >consommation : ${consommation} </span> litres<br> | ||
<span >Hauteur Fioul : ${hauteurFuel}</span> cm<br> | <span >Hauteur Fioul : ${hauteurFuel}</span> cm<br> | ||
<span style="font-weight:bold;">Volume Fioul : ${vf} litres</span><br> | <span style="font-weight:bold;">Volume Fioul : ${vf} litres</span><br> | ||
<span >Ratio volume : ${(vf/volumeCuve*100).toFixed(2)}</span> %<br> | <span >Ratio volume : ${(vf/volumeCuve*100).toFixed(2)}</span> %<br> | ||
</div> | </div> | ||
Ligne 119 : | Ligne 137 : | ||
===Cas d'une cuve cylindrique verticale=== | ===Cas d'une cuve cylindrique verticale=== | ||
[[fichier: | [[fichier:CuveCylindriqueV.PNG]] [[fichier:CuveCylindriqueVerticaleW.jpg]] | ||
''' | '''Usage : ''' | ||
* Sur le dashboard, créez une source de données nommée '''STATUS''' vers le fichier Status.xml de l'ipx800. | * Sur le dashboard, créez une source de données nommée '''STATUS''' vers le fichier Status.xml de l'ipx800. | ||
* Renseignez le volume total de la cuve en litres, le diamètre de la cuve en cm, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . La hauteur est attendue en cm. | * Renseignez le volume total de la cuve en litres, le diamètre de la cuve en cm, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . La hauteur de liquide est attendue en cm. | ||
* créez un widget de type HTML, hauteur 2 blocs. | * créez un widget de type HTML, hauteur 2 blocs. | ||
* insérez et ajustez ce code dans le widget : | * insérez et ajustez ce code dans le widget : | ||
Ligne 129 : | Ligne 147 : | ||
<div class="mw-collapsible mw-collapsed" data-expandtext="{{int:show}}" data-collapsetext="{{int:hide}}" style="width:730px;"> | <div class="mw-collapsible mw-collapsed" data-expandtext="{{int:show}}" data-collapsetext="{{int:hide}}" style="width:730px;"> | ||
''' | '''Afficher le code du widget''' | ||
<div class="mw-collapsible-content"> | <div class="mw-collapsible-content"> | ||
Ligne 137 : | Ligne 155 : | ||
var diametreCuve=86; //diametre en cm | var diametreCuve=86; //diametre en cm | ||
var volumeCuve=2000; //volume cuve pleine en litres | var volumeCuve=2000; //volume cuve pleine en litres | ||
var mesureToF=0;//renseignez 1 si vous utilisez un capteur ultrasons/infrarouges ou laser | |||
//ne pas modifier le code ci-dessous | |||
var vc=volumeCuve/1000; //conversion en m3 | var vc=volumeCuve/1000; //conversion en m3 | ||
var d=diametreCuve/100; //conversion en m | var d=diametreCuve/100; //conversion en m | ||
Ligne 145 : | Ligne 165 : | ||
//calcul de la longueur de la cuve | //calcul de la longueur de la cuve | ||
var lc=(vc/Math.PI/Math.pow(r,2)).toFixed(2); | var lc=(vc/Math.PI/Math.pow(r,2)).toFixed(2); | ||
if (mesureToF==1){hauteurFuel=lc-hauteurFuel;} // si mesure ToF | |||
var pourcentage=100 - (100*h/lc); | var pourcentage=100 - (100*h/lc); | ||
Ligne 192 : | Ligne 213 : | ||
</div></div> | </div></div> | ||
=== | ===Cas d'une cuve cylindrique horizontale=== | ||
[[fichier: | [[fichier:CuveCylindriqueH.PNG]] [[fichier:NiveauCylindrique.png]] | ||
''' | '''Usage : ''' | ||
* Sur le dashboard, créez une source de données nommée '''STATUS''' vers le fichier Status.xml de l'ipx800. | * Sur le dashboard, créez une source de données nommée '''STATUS''' vers le fichier Status.xml de l'ipx800. | ||
* Renseignez le volume total de la cuve en litres, | * Renseignez le volume total de la cuve en litres, le diamètre de la cuve en cm, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . La hauteur de liquide est attendue en cm. | ||
* | * créez un widget de type HTML, hauteur 2 blocs. | ||
* insérez et ajustez ce code dans le widget : | * insérez et ajustez ce code dans le widget : | ||
<div class="mw-collapsible mw-collapsed" data-expandtext="{{int:show}}" data-collapsetext="{{int:hide}}" style="width:730px;"> | <div class="mw-collapsible mw-collapsed" data-expandtext="{{int:show}}" data-collapsetext="{{int:hide}}" style="width:730px;"> | ||
''' | '''Afficher le code du widget''' | ||
<div class="mw-collapsible-content"> | <div class="mw-collapsible-content"> | ||
Ligne 210 : | Ligne 231 : | ||
<source> | <source> | ||
var hauteurFuel=(datasources["STATUS"]["response"]["analog0"] * 100).toFixed(2); | var hauteurFuel=(datasources["STATUS"]["response"]["analog0"] * 100).toFixed(2); | ||
var diametreCuve=86; //diametre en cm | |||
var volumeCuve=2000; //volume cuve pleine en litres | |||
var mesureToF=0;//renseignez 1 si vous utilisez un capteur ultrasons/infrarouges ou laser | |||
//ne pas modifier le code ci-dessous | |||
if (mesureToF==1){hauteurFuel=diametreCuve-hauteurFuel;} // si mesure ToF | |||
var | var pourcentage=100 - (100*hauteurFuel/diametreCuve); | ||
var | var vc=volumeCuve/1000; //conversion en m3 | ||
var d=diametreCuve/100; //conversion en m | |||
var r=d/2; | |||
var h=hauteurFuel/100; //conversion en m | |||
//calcul de la | //calcul de la longueur de la cuve | ||
var | var lc=(vc/Math.PI/Math.pow(r,2)).toFixed(2); | ||
//calcul volume Fuel | //calcul volume Fuel | ||
var vf=0; | var vf=0; | ||
vf= | |||
vf=(vf | if(h<=r && h>=0){// hauteur inférieure à rayon cuve | ||
vf=(Math.sqrt(r*r-(h-r)*(h-r))*(h-r)+r*r*Math.asin(Math.sqrt(r*r-(h-r)*(h-r))/r))*vc/(Math.PI*r*r); | |||
} | |||
else if (h>r && h<=2*r) {// hauteur supérieure à rayon cuve | |||
vf=(Math.PI*r*r-Math.sqrt(r*r-(2*r-h-r)*(2*r-h-r))*(2*r-h-r)-r*r*Math.asin(Math.sqrt(r*r-(2*r-h-r)*(2*r-h-r))/r))*vc/(Math.PI*r*r); | |||
} | |||
vf=(vf*1000).toFixed(0); | |||
return ` | return ` | ||
<style> | <style> | ||
.box{ | .box{ | ||
height: 80px; | height: 80px; | ||
Ligne 242 : | Ligne 269 : | ||
transform: translate(0, -50%); | transform: translate(0, -50%); | ||
background: #666666; | background: #666666; | ||
border-radius: | border-radius:100%; | ||
overflow: hidden; | overflow: hidden; | ||
} | } | ||
Ligne 261 : | Ligne 288 : | ||
<div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;"> | <div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;"> | ||
<span >Contenance cuve: ${volumeCuve}</span> litres<br> | <span >Contenance cuve: ${volumeCuve}</span> litres<br> | ||
<span > | <span >Longueur cuve: ${lc}</span> m<br> | ||
<span >Diamètre cuve : ${diametreCuve} </span> cm<br> | |||
<span >Hauteur Fioul : ${hauteurFuel}</span> cm<br> | <span >Hauteur Fioul : ${hauteurFuel}</span> cm<br> | ||
<span style="font-weight:bold;">Volume Fioul : ${vf} litres</span><br> | <span style="font-weight:bold;">Volume Fioul : ${vf} litres</span><br> | ||
<span >Ratio volume : ${(vf/volumeCuve*100).toFixed(2)}</span> %<br> | |||
</div> | </div> | ||
Ligne 271 : | Ligne 299 : | ||
</div></div> | </div></div> | ||
=== | ===Cas d'une citerne à bouts sphériques=== | ||
[[fichier: | [[fichier:CuveBoutSpherique.PNG|350px]] [[fichier:citerneW3.JPG]] | ||
''' | Ce type de citerne présente deux extrémités en forme de demi-sphère. Leur rayon est égal au rayon de la cuve. | ||
'''Usage : ''' | |||
* Sur le dashboard, créez une source de données nommée '''STATUS''' vers le fichier Status.xml de l'ipx800. | * Sur le dashboard, créez une source de données nommée '''STATUS''' vers le fichier Status.xml de l'ipx800. | ||
* Renseignez le diamètre de la citerne et sa longueur totale en cm, son volume total en litres, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . la hauteur est attendue en cm. | * Renseignez le diamètre de la citerne et sa longueur totale en cm, son volume total en litres, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . la hauteur est attendue en cm. | ||
Ligne 283 : | Ligne 313 : | ||
<div class="mw-collapsible mw-collapsed" data-expandtext="{{int:show}}" data-collapsetext="{{int:hide}}" style="width:730px;"> | <div class="mw-collapsible mw-collapsed" data-expandtext="{{int:show}}" data-collapsetext="{{int:hide}}" style="width:730px;"> | ||
''' | '''Afficher le code du widget''' | ||
<div class="mw-collapsible-content"> | <div class="mw-collapsible-content"> | ||
<source> | <source> | ||
var HauteurFuel = (datasources["STATUS"]["response"]["analog0"] * 100).toFixed(2); | |||
var Diametre = 120; //en cm | var Diametre = 120; //en cm | ||
var Longueur = 350; //en cm | var Longueur = 350; //en cm | ||
var volumeCuve=3900; //en litres | var volumeCuve=3900; //en litres | ||
var mesureToF=0;//renseignez 1 si vous utilisez un capteur ultrasons/infrarouges ou laser | |||
//ne pas modifier le code ci-dessous | |||
if (mesureToF==1){HauteurFuel=Diametre-HauteurFuel;} // si mesure ToF | |||
var R = Diametre /2; | var R = Diametre /2; | ||
Ligne 359 : | Ligne 393 : | ||
</div></div> | </div></div> | ||
=== | ===Cas d'une cuve à extrémités en forme d'ellipsoïde === | ||
[[fichier: | [[fichier:CuveEllipsoide2.PNG|350px]] [[fichier:cuveEllipsoideW.JPG]] | ||
En général, la profondeur de l'ellipsoïde formant les extrémités est d'environ le quart du diamètre de la citerne. | |||
Il arrive que cette ellipsoïde soit simplement sphérique. La profondeur est alors égale au rayon de la cuve (diamètre/2). | |||
'''Usage :''' | |||
Sur le dashboard, créez une source de données nommée STATUS vers le fichier Status.xml de l'ipx800. | Sur le dashboard, créez une source de données nommée STATUS vers le fichier Status.xml de l'ipx800. | ||
Renseignez le diamètre de la citerne, sa longueur totale et la profondeur de l'ellipsoïde en cm, son volume total en litres, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . la hauteur est attendue en cm. | Renseignez le diamètre de la citerne, sa longueur totale et la profondeur de l'ellipsoïde en cm, son volume total en litres, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . la hauteur est attendue en cm. | ||
Remarques : | '''Remarques : ''' | ||
* une citerne avec une profondeur d'ellipse à zéro est une cuve cylindrique, | * une citerne avec une profondeur d'ellipse à zéro est une cuve cylindrique, | ||
* une citerne avec une profondeur d'ellipse égale à son rayon est une citerne à bouts sphériques | * une citerne avec une profondeur d'ellipse égale à son rayon est une citerne à bouts sphériques | ||
Créez un widget de type HTML, hauteur 2 blocs. | |||
Insérez et ajustez ce code dans le widget : | |||
<div class="mw-collapsible mw-collapsed" data-expandtext="{{int:show}}" data-collapsetext="{{int:hide}}" style="width:730px;"> | <div class="mw-collapsible mw-collapsed" data-expandtext="{{int:show}}" data-collapsetext="{{int:hide}}" style="width:730px;"> | ||
''' | '''Afficher le code du widget''' | ||
<div class="mw-collapsible-content"> | <div class="mw-collapsible-content"> | ||
Ligne 389 : | Ligne 427 : | ||
var ellipse=43; //profondeur de l'ellipse en cm | var ellipse=43; //profondeur de l'ellipse en cm | ||
var volumeCuve=1832; //volume cuve pleine en litres | var volumeCuve=1832; //volume cuve pleine en litres | ||
var mesureToF=0;//renseignez 1 si vous utilisez un capteur ultrasons/infrarouges ou laser | |||
//ne pas modifier le code ci-dessous | |||
if (mesureToF==1){hauteurFuel=diametreCuve-hauteurFuel;} // si mesure ToF | |||
var pourcentage=100 - (100*hauteurFuel/diametreCuve); | var pourcentage=100 - (100*hauteurFuel/diametreCuve); | ||
Ligne 455 : | Ligne 497 : | ||
</div></div> | </div></div> | ||
== | ===Cas d'un forage=== | ||
[[fichier:niveauForage3.JPG]] [[fichier:NiveauForageW3.JPG]] | |||
Ce widget permet de calculer le volume d'eau utile restant dans un puits . Il indique également l'état de fonctionnement de la pompe. | |||
'''Usage :''' | |||
* Pour un forage, un capteur de pression '''différentielle''' à sortie analogique est fortement conseillé. | |||
Ce capteur devra être immergé au plus bas du forage. La sonde mesurera la pression hydrostatique exercée par la colonne d'eau, à raison d'un bar pour 10 mètres. | |||
'''Remarque:''' | |||
Si vous prenez soin de choisir un modèle à pression '''différentielle''', la pression atmosphérique sera alors également mesurée (un tuyau capillaire doit remonter en surface, à l'air libre) et déduite automatiquement par le capteur. | |||
Cela permettra d'obtenir une plus grande précision. | |||
* Sur le dashboard, créez une source de données nommée '''STATUS''' vers le fichier '''''Status.xml''''' de l'ipx800. | |||
* Renseignez la profondeur totale du forage, la hauteur du niveau maximum, ainsi que le niveau minimum en cm, | |||
* renseignez le diamètre intérieur du forage, | |||
* Liez la variable hauteurEau à la source de données crée précédemment, sur l’analogique de la sonde . la hauteur mesurée est attendue en cm. | |||
* Renseignez le numéro de la sortie physique (relais) qui contrôle la pompe (de 0 à 55). | |||
* Renseignez la variable mesureToF si vous utilisez un capteur ultrasons ou infrarouges à la place de la sonde immergée, | |||
* créez un widget de type HTML, hauteur 3 blocs. | |||
* insérez et ajustez ce code dans le widget : | |||
<div class="mw-collapsible mw-collapsed" data-expandtext="{{int:show}}" data-collapsetext="{{int:hide}}" style="width:730px;"> | |||
'''Afficher le code du widget''' | |||
<div class="mw-collapsible-content"> | |||
<source> | |||
var profondeurPuits=900; //profondeur du forage en cm | |||
var diametreInterieur=80; //diametre intérieur du forage en cm | |||
var niveauMini=30; //niveau d'eau mini en cm dans le forage | |||
var niveauMaxi=700;//niveau d'eau maxi en cm dans le forage | |||
var relaisPompe=0; //renseigner le numéro du relais connecté à la pompe. de 0 à 55 | |||
var hauteurEau=(datasources["STATUS"]["response"]["analog0"]*100).toFixed(2); | |||
var mesureToF=0;//renseignez 1 si vous utilisez un capteur ultrasons/infrarouges ou laser | |||
//ne pas modifier le code ci-dessous | |||
if(datasources["STATUS"]["response"]["led"+relaisPompe]=="1") {statusP="Pompe en marche";} else {statusP="Pompe à l'arrêt";} | |||
r=diametreInterieur/2; | |||
var pourcentage1=100 - (100*hauteurEau/profondeurPuits); | |||
var pourcentage2=100 - (100*niveauMini/profondeurPuits); | |||
var pourcentage3=100 - (100*niveauMaxi/profondeurPuits); | |||
var volumeForage=Math.PI*r*r*niveauMaxi; //volume max forage en litres | |||
if (mesureToF==1){hauteurEau=niveauMaxi-hauteurEau;} // si mesure ToF | |||
//calcul volume eau | |||
var ve=(Math.PI * Math.pow(r,2) * hauteurEau).toFixed(0);//volume en litres | |||
var vu=(Math.PI * Math.pow(r,2) * (hauteurEau-niveauMini)).toFixed(0);//volume en litres | |||
return ` | |||
<style> | |||
.box{ | |||
height: 150px; | |||
width: 80px; | |||
position: absolute; | |||
top: 50%; | |||
left: 20px; | |||
transform: translate(0, -50%); | |||
background: #666666; | |||
border-radius:0; | |||
overflow: hidden; | |||
} | |||
.eau1{ | |||
position: absolute; | |||
left: 5px; | |||
width: 70px; | |||
height: 150px; | |||
transform:translate(0,${pourcentage1}%); | |||
background:#73a0ca; | |||
} | |||
.eau2{ | |||
position: absolute; | |||
left: 5px; | |||
width: 70px; | |||
height: 150px; | |||
transform:translate(0,${pourcentage2}%); | |||
background:#4d759c; | |||
} | |||
.miniN{ | |||
position: absolute; | |||
top: ${pourcentage2}%; | |||
width: 80px; | |||
height: 3px; | |||
background:#f00; | |||
} | |||
.maxiN{ | |||
position: absolute; | |||
top: ${pourcentage3}%; | |||
width: 80px; | |||
height: 3px; | |||
background:#0f0; | |||
} | |||
</style> | |||
<div class="box"> | |||
<div class="eau1"></div> | |||
<div class="eau2"></div> | |||
<div class="miniN"></div> | |||
<div class="maxiN"></div> | |||
</div> | |||
<div style="float:left;margin-left:110px;margin-top:15px;font-size:12px;"> | |||
<span >Volume total : ${(volumeForage/1000).toFixed(0)}</span> litres<br><br> | |||
<span >Hauteur eau utile: ${hauteurEau-niveauMini}</span> cm<br> | |||
<span >Volume eau utile : ${(vu/1000).toFixed(0)} litres</span><br> | |||
<span style="position:absolute;left:135px;top: 135px;width: 120px;background-color:#333;" name="Pompe"> ${statusP} </span> | |||
</div> | |||
`; | |||
</source> | |||
</div></div> | |||
==Exemple avec des capteurs tout ou rien (interrupteurs à flotteur)== | |||
[[fichier:flotteurH.png|150px]] | [[fichier:flotteurH.png|150px]] | ||
=== | ===Cas d'une cuve parallélépipédique=== | ||
[[fichier: | [[fichier:CuveParallelepipedique2.png]] [[fichier:FlotteursSch2.png]] [[fichier:NiveauCubiqueTOR.png]] | ||
''' | '''Usage : ''' | ||
* Montez les flotteurs à intervalle régulier sur la hauteur de la cuve.<br> | * Montez les flotteurs à intervalle régulier sur la hauteur de la cuve.<br> | ||
Ici, nous allons supposer que le premier flotteur, situé à 20 cm du fond de la cuve, est connecté sur l'entrée digitale 21 ("btn20" dans le code).<br> | Ici, nous allons supposer que le premier flotteur, situé à 20 cm du fond de la cuve, est connecté sur l'entrée digitale 21 ("btn20" dans le code).<br> | ||
Le deuxième flotteur est situé 14 cm plus haut, connecté à l'entrée digitale 22 | Le deuxième flotteur est situé 14 cm plus haut, il est connecté à l'entrée digitale 22 ("btn21" dans le code),<br> | ||
Le troisième flotteur est situé 14 cm au dessus du 2ème, connecté à l'entrée digitale 23 | Le troisième flotteur est situé 14 cm au dessus du 2ème, il est connecté à l'entrée digitale 23 ("btn22" dans le code),<br> | ||
et ainsi de suite jusqu' | et ainsi de suite jusqu'au 8ème flotteur. | ||
* Sur le dashboard, créez une source de données nommée ''' | * Sur le dashboard, créez une source de données nommée '''STATUS''' vers le fichier '''''Status.xml''''' de l'ipx800. | ||
* Renseignez le volume total de la cuve en litres, la hauteur et la longueur de la cuve en cm, puis liez la variable hauteurFuel à la | * Renseignez le volume total de la cuve en litres, la hauteur et la longueur de la cuve en cm, puis liez la variable hauteurFuel à la source de données crée précédemment, sur l’analogique de la sonde . la hauteur mesurée est attendue en cm. | ||
* créez un widget de type HTML, hauteur 2 blocs. | * créez un widget de type HTML, hauteur 2 blocs. | ||
* insérez et ajustez ce code dans le widget : | * insérez et ajustez ce code dans le widget : | ||
Ligne 478 : | Ligne 637 : | ||
<div class="mw-collapsible mw-collapsed" data-expandtext="{{int:show}}" data-collapsetext="{{int:hide}}" style="width:730px;"> | <div class="mw-collapsible mw-collapsed" data-expandtext="{{int:show}}" data-collapsetext="{{int:hide}}" style="width:730px;"> | ||
''' | '''Afficher le code du widget''' | ||
<div class="mw-collapsible-content"> | <div class="mw-collapsible-content"> | ||
Ligne 485 : | Ligne 644 : | ||
var intervalle=14; //intervalle entre 2 flotteurs en cm; | var intervalle=14; //intervalle entre 2 flotteurs en cm; | ||
var basDeCuve=20;//hauteur sous le flotteur du bas | var basDeCuve=20;//hauteur sous le flotteur du bas | ||
var hauteurEau=(datasources[" | var hauteurEau=(datasources["STATUS"]["response"]["btn20"] == 0) * basDeCuve ; | ||
hauteurEau=hauteurEau+(datasources[" | hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn21"] == 0) * intervalle ; | ||
hauteurEau=hauteurEau+(datasources[" | hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn22"] == 0) * intervalle ; | ||
hauteurEau=hauteurEau+(datasources[" | hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn23"] == 0) * intervalle ; | ||
hauteurEau=hauteurEau+(datasources[" | hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn24"] == 0) * intervalle ; | ||
hauteurEau=hauteurEau+(datasources[" | hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn25"] == 0) * intervalle ; | ||
hauteurEau=hauteurEau+(datasources[" | hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn26"] == 0) * intervalle ; | ||
hauteurEau=hauteurEau+(datasources[" | hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn27"] == 0) * intervalle ; | ||
var largeurCuve=104; //largeur cuve en cm | var largeurCuve=104; //largeur cuve en cm | ||
Ligne 514 : | Ligne 673 : | ||
return ` | return ` | ||
<style> | <style> | ||
.box{ | .box{ | ||
Ligne 560 : | Ligne 713 : | ||
</div></div> | </div></div> | ||
''' | '''Remarque : ''' | ||
Ligne 569 : | Ligne 722 : | ||
Pour des capteurs qui passent ON lorsqu'ils sont immergés, il faudra comparer l'état de l'entrée digitale à 1 au lieu de 0. | Pour des capteurs qui passent ON lorsqu'ils sont immergés, il faudra comparer l'état de l'entrée digitale à 1 au lieu de 0. | ||
exemple : | Exemple : | ||
<source> | |||
var hauteurEau=(datasources["STATUS"]["response"]["btn20"] == 1) * basDeCuve ; | |||
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn21"] == 1) * intervalle ; //capteur du bas | |||
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn22"] == 1) * intervalle ; | |||
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn23"] == 1) * intervalle ; | |||
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn24"] == 1) * intervalle ; | |||
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn25"] == 1) * intervalle ; | |||
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn26"] == 1) * intervalle ; | |||
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn27"] == 1) * intervalle ; //capteur du haut | |||
</source> | |||
===Cas d'une cuve cylindrique verticale=== | |||
[[fichier:Recuperateur.JPG|300px]] [[fichier:recuperateur1.jpg|250px]] [[fichier:recuperateur2.jpg|250px]] [[fichier:recuperateur3.jpg|250px]] | |||
'''Usage : ''' | |||
* Montez les flotteurs à intervalle régulier sur la hauteur de la cuve.<br> | |||
Ici, nous allons supposer que le premier flotteur, situé à 20 cm du fond de la cuve, est connecté sur l'entrée digitale 21 ("btn20" dans le code).<br> | |||
Le deuxième flotteur est situé 20 cm plus haut, il est connecté à l'entrée digitale 22 ("btn21" dans le code),<br> | |||
Le troisième flotteur est situé 20 cm au dessus du 2ème, il est connecté à l'entrée digitale 23 ("btn22" dans le code),<br> | |||
et ainsi de suite jusqu'au 10ème flotteur. | |||
* Sur le dashboard, créez une source de données nommée '''STATUS''' vers le fichier '''''Status.xml''''' de l'ipx800. | |||
* créez un widget de type HTML, hauteur 2 blocs. | |||
* insérez et ajustez le code dans le widget | |||
* Renseignez le diamètre intérieur de la cuve en cm | |||
* Renseignez les hauteurs d'installation des flotteurs dans la table ''hauteurs[]'' | |||
* Renseignez le numéro des entrées digitales pour chaque flotteur. Comme vu précédemment, nous supposons dans l'exemple que le flotteur bas est connecté à l'entrée digitale n°21 ("btn20" dans status.xml). | |||
* Renseignez la variable statusON avec la valeur prise par les capteurs à l'état ON (1 ou 0) | |||
* Décommentez le jeu de couleur souhaité. Les captures ci-dessus ont été construites avec le 'jeu 1'. <br>Le jeu 2 propose un thème plus sombre avec les couleurs GCE, le jeu 3 propose un camaïeu de bleu. | |||
[[fichier:recuperateur1J2.jpg|250px]] [[fichier:recuperateur2J2.jpg|250px]] [[fichier:Recuperateur3J2.jpg|250px]] [[fichier:Recuperateur3J3.png|250px]] | |||
Vous pouvez concevoir vos propres thèmes de couleurs. | |||
<div class="mw-collapsible mw-collapsed" data-expandtext="{{int:show}}" data-collapsetext="{{int:hide}}" style="width:730px;"> | |||
'''Afficher le code du widget''' | |||
<div class="mw-collapsible-content"> | |||
<source> | <source> | ||
var | var diametreInterieur=120; //largeur cuve en cm | ||
var hauteurs=[0, 20, 40, 60, 120, 140, 160, 180, 200, 220, 240];//hauteurs des flotteurs en partant du fond / en cm | |||
var btn=[20,21,22,23,24,25,26,27,28,29];//numéros des entrées digitales pour chaque flotteur, en partant du flotteur le plus bas | |||
var statusON=0;//renseignez la valeur 0 ou 1 prise par un capteur à l'état ON | |||
//jeu couleurs 1 | |||
var couleursON=['ff851b','0f0','0f0','0f0','0f0','0f0','0f0','0f0','0f0','0f0','ff0']; | |||
var couleursOFF=['f00','666','666','666','666','666','666','666','666','666','666']; | |||
//jeu couleurs 2 | |||
//var couleursON=['ff851b','3fb740','3fb740','3fb740','3fb740','3fb740','3fb740','3fb740','3fb740','ff0']; | |||
//var couleursOFF=['f00','222','222','222','222','222','222','222','222','222']; | |||
//jeu couleurs 3 | |||
//var couleursON=['000033','000066','000066','000099','000099','000099','0000cc','0000cc','0000ff','3300ff']; | |||
//var couleursOFF=['f00','222','222','222','222','222','222','222','222','222']; | |||
//ne pas modifier ci-dessous | |||
var rang=0; | |||
var i; | |||
//test entrées digitales avec capteurs | |||
for (i=0;i<=(btn.length-1);i++){ | |||
if(datasources["STATUS"]["response"]["btn" + btn[i]] == statusON) { | |||
rang=rang + 1;} | |||
} | |||
//calcul volume Eau / volume total mini et utile | |||
var ve=hauteurs[rang] * Math.pow(diametreInterieur/2,2) * Math.PI; | |||
var vt=hauteurs[hauteurs.length - 1] * Math.pow(diametreInterieur/2,2) * Math.PI; | |||
var vm=hauteurs[1]* Math.pow(diametreInterieur/2,2) * Math.PI; | |||
var vu=ve-vm; | |||
if (ve<=0){vu=0;} | |||
return ` | |||
<style> | |||
.box2{ | |||
height: 152px; | |||
width: 40px; | |||
position: absolute; | |||
top: 5px; | |||
left: 10px; | |||
background: #333; | |||
border-radius:1%; | |||
overflow: hidden; | |||
} | |||
.led{ | |||
position: absolute; | |||
left: 10px; | |||
width: 20px; | |||
height: 8px; | |||
} | |||
</style> | |||
<div class="box2"> | |||
<div class="led" style="top:95px;background:#${ rang>=1 ? couleursON[0] : couleursOFF[0]};"></div> | |||
<div class="led" style="top:85px;background:#${ rang>=2 ? couleursON[1] : couleursOFF[1]};"></div> | |||
<div class="led" style="top:75px;background: #${ rang>=3 ? couleursON[2] : couleursOFF[2]};"></div> | |||
<div class="led" style="top:65px;background: #${ rang>=4 ? couleursON[3] : couleursOFF[3]};"></div> | |||
<div class="led" style="top:55px;background: #${ rang>=5 ? couleursON[4] : couleursOFF[4]};"></div> | |||
<div class="led" style="top:45px;background: #${ rang>=6 ? couleursON[5] : couleursOFF[5]};"></div> | |||
<div class="led" style="top:35px;background: #${ rang>=7 ? couleursON[6] : couleursOFF[6]};"></div> | |||
<div class="led" style="top:25px;background: #${ rang>=8 ? couleursON[7] : couleursOFF[7]};"></div> | |||
<div class="led" style="top:15px;background: #${ rang>=9 ? couleursON[8] : couleursOFF[8]};"></div> | |||
<div class="led" style="top:5px;background: #${ rang>=10 ? couleursON[9] : couleursOFF[9]};"></div> | |||
</div> | |||
<div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;"> | |||
<br> | |||
<span >Contenance cuve: ${(vt/1000).toFixed(0)}</span> litres<br> | |||
<span >Hauteur Eau : ${hauteurs[rang]}</span> cm<br> | |||
<span style="font-weight:bold;">Volume total Eau : ${(ve/1000).toFixed(0)} litres</span><br> | |||
<span style="font-weight:bold;">Volume mini : ${(vm/1000).toFixed(0)} litres</span><br><br> | |||
<span style="font-weight:bold;background:#666">Volume utile Eau : ${(vu/1000).toFixed(0)} litres</span><br> | |||
</div> | |||
`; | |||
</source> | </source> | ||
</div></div> | |||
===Autres formes de cuve=== | ===Autres formes de cuve=== |
Version actuelle datée du 25 mai 2021 à 13:03
| |||
---|---|---|---|
Nom | Niveau de liquide | ||
Famille | Widgets | ||
Wiki créé le | 04/10/2020 | ||
Wiki mis à jour le | 25/05/2021 | ||
Auteur | fgtoul |
Présentation
Déterminer le volume de fioul restant dans une cuve peut parfois être complexe. Pour nous aider, les constructeurs de cuves nous fournissent des abaques, tableaux dans lesquels le volume restant est déterminé à partir de la hauteur mesurée du liquide.
L'IPX800 V4, associée à des capteurs de niveaux, peut nous aider dans cette tâche, en nous offrant la possibilité d'avoir le volume en lecture directe.
Voici quelques widgets écrits en javascript et HTML. Vous pourrez les personnaliser et les utiliser librement sur le dashboard de votre IPX800 V4.
Attention, si vous mesurez le niveau d'un produit corrosif ou d'un hydrocarbure (fioul, ...) dans une cuve, il faudra utiliser un capteur spécifique (anti-corrosion, antidéflagrant, ...). De même il existe des capteurs spécifiques pour des eaux sales, eaux noires, ...
Pour la construction des widgets ci-dessous, il vous sera demandé d'entrer des dimensions en cm.
Pensez à entrer les dimensions internes de la cuve (dimensions externes moins 2 fois l'épaisseur de l'enveloppe).
Prérequis
Tous les widgets présentés ci-dessous nécessitent la création d'une source de données sur le dashboard de l'IPX800 V4.
Cliquez sur le menu "Créer une source de données" puis renseignez les paramètres comme suit :
Renseignez l'utilisateur et mot de passe si vous les avez activés.
Exemples avec un capteur analogique
Il existe différents types de capteurs permettant de mesurer un niveau.
- à laser, infrarouges ou ultrasons
ils mesurent la hauteur vide en haut de cuve grâce au temps pris par le signal pour parcourir la distance (aller/retour).
Connaissant la célérité du signal qui est une caractéristique physique propre à sa nature (lumière, son), il suffit de mesurer le temps du parcours pour en déterminer la distance
Distancevide = céléritésignal * temps / 2).
Il est alors question de mesure dite ToF (Time of Flight) .
La hauteur de liquide s'obtient par soustraction de la mesure à la hauteur totale de la cuve (Hauteurliquide = Hauteurcuve - Dvide).
- composés d'une sonde immergée
ils calculent la hauteur de liquide grâce à la pression lue en fond de cuve. La sonde à pression différentielle est plus précise car elle réajuste la mesure en fonction de la pression athmosphérique. La hauteur du liquide est déterminée par équation en fonction de la pression mesurée. la hauteur de liquide est en lecture directe.
- résistifs ou capacitifs
ils mesurent la hauteur de liquide en contact avec leur partie immergée (tige, fil conducteur, ...) grâce à la variation d'une caractéristique du circuit électrique. La hauteur du liquide est déterminée directement par une formule.
Nous admettrons que vous avez correctement configuré votre entrée analogique afin d'obtenir une hauteur en mètres (dans les exemples ci-dessous, la valeur est multipliée par 100 afin d'être reconvertie en cm).
Pour cela, vous aurez adapté les formules de conversion dans la configuration de l'entrée analogique concernée, en fonction des caractéristiques du capteur.
Cas d'une cuve parallélépipédique
usage :
- Sur le dashboard, créez une source de données nommée STATUS vers le fichier Status.xml de l'ipx800.
- Renseignez le volume total de la cuve en litres, ses 3 dimensions en cm, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . la hauteur de liquide est attendue en cm.
- créez un widget de type HTML, hauteur 2 blocs.
- insérez et ajustez ce code dans le widget :
Afficher le code du widget
var hauteurFuel=(datasources["STATUS"]["response"]["analog0"] * 100).toFixed(2);
var hauteurCuve=120; //hauteur cuve en cm
var largeurCuve=120; //largeur cuve en cm
var longueurCuve=209; //longueur cuve en cm
var volumeCuve=3000; //volume cuve pleine en litres
var mesureToF=0;//renseignez 1 si vous utilisez un capteur ultrasons/infrarouges ou laser
//ne pas modifier le code ci-dessous
if (mesureToF==1){hauteurFuel=hauteurCuve-hauteurFuel;} // si mesure ToF
var pourcentage=100 - (100*hauteurFuel/hauteurCuve);
//calcul de la consommation à partir de la baisse du niveau
var consommation=((hauteurCuve-hauteurFuel)*largeurCuve*longueurCuve)/1000 //consommation en litres
//calcul volume Fuel
var vf=0;
vf=hauteurFuel*largeurCuve*longueurCuve;
vf=(vf/1000).toFixed(0);
return `
<style>
.box{
height: 80px;
width: 80px;
position: absolute;
top: 50%;
left: 10px;
transform: translate(0, -50%);
background: #666666;
border-radius:15%;
overflow: hidden;
}
.fuel{
position: absolute;
left: 0;
top: 0;
width: 80px;
height: 80px;
transform:translate(0,${pourcentage}%);
background:#76B558;
}
</style>
<div class="box">
<div id="fuel" class="fuel"></div>
</div>
<div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;">
<span >Contenance cuve: ${volumeCuve}</span> litres<br>
<span >consommation : ${consommation} </span> litres<br>
<span >Hauteur Fioul : ${hauteurFuel}</span> cm<br>
<span style="font-weight:bold;">Volume Fioul : ${vf} litres</span><br>
<span >Ratio volume : ${(vf/volumeCuve*100).toFixed(2)}</span> %<br>
</div>
`;
Cas d'une cuve cylindrique verticale
Usage :
- Sur le dashboard, créez une source de données nommée STATUS vers le fichier Status.xml de l'ipx800.
- Renseignez le volume total de la cuve en litres, le diamètre de la cuve en cm, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . La hauteur de liquide est attendue en cm.
- créez un widget de type HTML, hauteur 2 blocs.
- insérez et ajustez ce code dans le widget :
Afficher le code du widget
var hauteurFuel=(datasources["STATUS"]["response"]["analog0"] * 100).toFixed(2);
var diametreCuve=86; //diametre en cm
var volumeCuve=2000; //volume cuve pleine en litres
var mesureToF=0;//renseignez 1 si vous utilisez un capteur ultrasons/infrarouges ou laser
//ne pas modifier le code ci-dessous
var vc=volumeCuve/1000; //conversion en m3
var d=diametreCuve/100; //conversion en m
var r=d/2;
var h=hauteurFuel/100; //conversion en m
//calcul de la longueur de la cuve
var lc=(vc/Math.PI/Math.pow(r,2)).toFixed(2);
if (mesureToF==1){hauteurFuel=lc-hauteurFuel;} // si mesure ToF
var pourcentage=100 - (100*h/lc);
//calcul volume Fuel
var vf=0;
vf=Math.PI * Math.pow(r,2) * h;
vf=(vf*1000).toFixed(0); //conversion en litres
return `
<style>
.box{
height: 80px;
width: 40px;
position: absolute;
top: 50%;
left: 20px;
transform: translate(0, -50%);
background: #666666;
border-radius:15%;
overflow: hidden;
}
.fuel{
position: absolute;
left: 0;
top: 0;
width: 40px;
height: 80px;
transform:translate(0,${pourcentage}%);
background:#76B558;
}
</style>
<div class="box">
<div id="fuel" class="fuel"></div>
</div>
<div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;">
<span >Contenance cuve: ${volumeCuve}</span> litres<br>
<span >Hauteur cuve: ${lc}</span> m<br>
<span >Diamètre cuve : ${diametreCuve} </span> cm<br>
<span >Hauteur Fioul : ${hauteurFuel}</span> cm<br>
<span style="font-weight:bold;">Volume Fioul : ${vf} litres</span><br>
<span >Ratio volume : ${(vf/volumeCuve*100).toFixed(2)}</span> %<br>
</div>
`;
Cas d'une cuve cylindrique horizontale
Usage :
- Sur le dashboard, créez une source de données nommée STATUS vers le fichier Status.xml de l'ipx800.
- Renseignez le volume total de la cuve en litres, le diamètre de la cuve en cm, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . La hauteur de liquide est attendue en cm.
- créez un widget de type HTML, hauteur 2 blocs.
- insérez et ajustez ce code dans le widget :
Afficher le code du widget
var hauteurFuel=(datasources["STATUS"]["response"]["analog0"] * 100).toFixed(2);
var diametreCuve=86; //diametre en cm
var volumeCuve=2000; //volume cuve pleine en litres
var mesureToF=0;//renseignez 1 si vous utilisez un capteur ultrasons/infrarouges ou laser
//ne pas modifier le code ci-dessous
if (mesureToF==1){hauteurFuel=diametreCuve-hauteurFuel;} // si mesure ToF
var pourcentage=100 - (100*hauteurFuel/diametreCuve);
var vc=volumeCuve/1000; //conversion en m3
var d=diametreCuve/100; //conversion en m
var r=d/2;
var h=hauteurFuel/100; //conversion en m
//calcul de la longueur de la cuve
var lc=(vc/Math.PI/Math.pow(r,2)).toFixed(2);
//calcul volume Fuel
var vf=0;
if(h<=r && h>=0){// hauteur inférieure à rayon cuve
vf=(Math.sqrt(r*r-(h-r)*(h-r))*(h-r)+r*r*Math.asin(Math.sqrt(r*r-(h-r)*(h-r))/r))*vc/(Math.PI*r*r);
}
else if (h>r && h<=2*r) {// hauteur supérieure à rayon cuve
vf=(Math.PI*r*r-Math.sqrt(r*r-(2*r-h-r)*(2*r-h-r))*(2*r-h-r)-r*r*Math.asin(Math.sqrt(r*r-(2*r-h-r)*(2*r-h-r))/r))*vc/(Math.PI*r*r);
}
vf=(vf*1000).toFixed(0);
return `
<style>
.box{
height: 80px;
width: 80px;
position: absolute;
top: 50%;
left: 10px;
transform: translate(0, -50%);
background: #666666;
border-radius:100%;
overflow: hidden;
}
.fuel{
position: absolute;
left: 0;
top: 0;
width: 80px;
height: 80px;
transform:translate(0,${pourcentage}%);
background:#76B558;
}
</style>
<div class="box">
<div id="fuel" class="fuel"></div>
</div>
<div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;">
<span >Contenance cuve: ${volumeCuve}</span> litres<br>
<span >Longueur cuve: ${lc}</span> m<br>
<span >Diamètre cuve : ${diametreCuve} </span> cm<br>
<span >Hauteur Fioul : ${hauteurFuel}</span> cm<br>
<span style="font-weight:bold;">Volume Fioul : ${vf} litres</span><br>
<span >Ratio volume : ${(vf/volumeCuve*100).toFixed(2)}</span> %<br>
</div>
`;
Cas d'une citerne à bouts sphériques
Ce type de citerne présente deux extrémités en forme de demi-sphère. Leur rayon est égal au rayon de la cuve.
Usage :
- Sur le dashboard, créez une source de données nommée STATUS vers le fichier Status.xml de l'ipx800.
- Renseignez le diamètre de la citerne et sa longueur totale en cm, son volume total en litres, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . la hauteur est attendue en cm.
- créez un widget de type HTML, hauteur 2 blocs.
- insérez et ajustez ce code dans le widget :
Afficher le code du widget
var HauteurFuel = (datasources["STATUS"]["response"]["analog0"] * 100).toFixed(2);
var Diametre = 120; //en cm
var Longueur = 350; //en cm
var volumeCuve=3900; //en litres
var mesureToF=0;//renseignez 1 si vous utilisez un capteur ultrasons/infrarouges ou laser
//ne pas modifier le code ci-dessous
if (mesureToF==1){HauteurFuel=Diametre-HauteurFuel;} // si mesure ToF
var R = Diametre /2;
var H=HauteurFuel;
pourcentage=100-100*H/Diametre;
if ( H >= R && H < Diametre)
{
H=(2*R)-H;
A = 0.25 * (Math.PI * Math.pow(R, 2)) - (Math.atan(((R - H) / R) / Math.sqrt(1-((R - H) / R)*((R - H) / R)))) * (Math.PI * Math.pow(R, 2)) / (Math.PI * 2);
A = A - 0.5 * (R-H)* Math.sqrt(2*R*H-H*H);
A = 2 * A;
A = (Math.PI * Math.pow(R, 2)) - A;
}
else if( H==0 )
{
A = 0;
}
else if (H==Diametre )
{
A = Math.PI * Math.pow(R, 2);
}
else if (H > 0 && H < R )
{
A = 0.25 * (Math.PI * Math.pow(R, 2)) - (Math.atan(((R - H) / R) / Math.sqrt(1 - ((R - H) / R) * ((R - H) / R)))) * (Math.PI * Math.pow(R, 2)) / (Math.PI * 2);
A = A - 0.5 * (R - H) * Math.sqrt(2 * R * H - H * H);
A = 2 * A;
}
var volume = Math.round(A * Longueur / 1000);
if (volume>volumeCuve){volume=volumeCuve;}
return `
<style>
.box2{
height: 40px;
width: 80px;
position: absolute;
top: 50%;
left: 10px;
transform: translate(0, -50%);
background: #666666;
border-radius:20px;
overflow: hidden;
}
.fuel2{
position: absolute;
left: 0;
top: 0;
width: 80px;
height: 40px;
transform:translate(0,${pourcentage}%);
background:#76B558;
}
</style>
<div class="box2">
<div id="fuel" class="fuel2"></div>
</div>
<div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;">
<span >Contenance cuve: ${volumeCuve}</span> litres<br><br>
<span >Hauteur Fioul: ${HauteurFuel}</span> cm<br>
<span style="font-weight:bold;">Volume Fioul : ${volume} litres</span><br>
<br>
<span >volume idéal à commander : ${(volumeCuve-volume).toFixed(0)}</span> litres<br>
</div>
`;
Cas d'une cuve à extrémités en forme d'ellipsoïde
En général, la profondeur de l'ellipsoïde formant les extrémités est d'environ le quart du diamètre de la citerne.
Il arrive que cette ellipsoïde soit simplement sphérique. La profondeur est alors égale au rayon de la cuve (diamètre/2).
Usage :
Sur le dashboard, créez une source de données nommée STATUS vers le fichier Status.xml de l'ipx800. Renseignez le diamètre de la citerne, sa longueur totale et la profondeur de l'ellipsoïde en cm, son volume total en litres, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . la hauteur est attendue en cm.
Remarques : * une citerne avec une profondeur d'ellipse à zéro est une cuve cylindrique, * une citerne avec une profondeur d'ellipse égale à son rayon est une citerne à bouts sphériques
Créez un widget de type HTML, hauteur 2 blocs.
Insérez et ajustez ce code dans le widget :
Afficher le code du widget
var hauteurFuel=(datasources["STATUS"]["response"]["analog0"] * 100).toFixed(2);
var diametreCuve=86; //diametre en cm
var longueurCuve=344; //longueur totale de la cuve en cm
var ellipse=43; //profondeur de l'ellipse en cm
var volumeCuve=1832; //volume cuve pleine en litres
var mesureToF=0;//renseignez 1 si vous utilisez un capteur ultrasons/infrarouges ou laser
//ne pas modifier le code ci-dessous
if (mesureToF==1){hauteurFuel=diametreCuve-hauteurFuel;} // si mesure ToF
var pourcentage=100 - (100*hauteurFuel/diametreCuve);
var vc=volumeCuve/1000; //conversion en m3
var d=diametreCuve/100; //conversion en m
var r=d/2;
var h=hauteurFuel/100; //conversion en m
var e=ellipse/100; //conversion en m
//e=2*e;
//calcul de la longueur de la cuve
var lc=(longueurCuve/100-2*e).toFixed(2);
//calcul volume Fuel dans le cylindre
var vf1=0;
if(h<=r && h>=0){// hauteur inférieure à rayon cuve
vf1=(Math.sqrt(r*r-(h-r)*(h-r))*(h-r)+r*r*Math.asin(Math.sqrt(r*r-(h-r)*(h-r))/r))*lc;
}
else if (h>r && h<=2*r) {// hauteur supérieure à rayon cuve
vf1=(Math.PI*r*r-Math.sqrt(r*r-(2*r-h-r)*(2*r-h-r))*(2*r-h-r)-r*r*Math.asin(Math.sqrt(r*r-(2*r-h-r)*(2*r-h-r))/r))*lc;
}
//calcul volume fuel dans ellipsoide
var a=e,b=r,c=r;
var x=c-h;
var vf2=0;
vf2=Math.PI*a*b*(2*c/3 - x + (x*x*x)/(3*c*c));
//calcul volume total de fioul
var vf=((vf1+vf2)*1000).toFixed(0);
if (vf>volumeCuve){vf=volumeCuve;}
return `
<style>
.box4{
height: 40px;
width: 80px;
position: absolute;
top: 50%;
left: 10px;
transform: translate(0, -50%);
background: #666666;
border-radius:16px;
overflow: hidden;
}
.fuel4{
position: absolute;
left: 0;
top: 0;
width: 80px;
height: 40px;
transform:translate(0,${pourcentage}%);
background:#76B558;
}
</style>
<div class="box4">
<div id="fuel" class="fuel4"></div>
</div>
<div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;">
<span >Contenance cuve: ${volumeCuve}</span> litres<br>
<span >Hauteur Fioul : ${hauteurFuel}</span> cm<br>
<span style="font-weight:bold;"> Volume Fioul: ${vf} litres</span><br>
<span >Ratio volume : ${(100*vf/volumeCuve).toFixed(2)}</span> %<br> <br>
<span >Volume Cmde idéale : ${(volumeCuve-vf).toFixed(0)}</span> litres<br>
</div>
`;
Cas d'un forage
Ce widget permet de calculer le volume d'eau utile restant dans un puits . Il indique également l'état de fonctionnement de la pompe.
Usage :
- Pour un forage, un capteur de pression différentielle à sortie analogique est fortement conseillé.
Ce capteur devra être immergé au plus bas du forage. La sonde mesurera la pression hydrostatique exercée par la colonne d'eau, à raison d'un bar pour 10 mètres.
Remarque: Si vous prenez soin de choisir un modèle à pression différentielle, la pression atmosphérique sera alors également mesurée (un tuyau capillaire doit remonter en surface, à l'air libre) et déduite automatiquement par le capteur. Cela permettra d'obtenir une plus grande précision.
- Sur le dashboard, créez une source de données nommée STATUS vers le fichier Status.xml de l'ipx800.
- Renseignez la profondeur totale du forage, la hauteur du niveau maximum, ainsi que le niveau minimum en cm,
- renseignez le diamètre intérieur du forage,
- Liez la variable hauteurEau à la source de données crée précédemment, sur l’analogique de la sonde . la hauteur mesurée est attendue en cm.
- Renseignez le numéro de la sortie physique (relais) qui contrôle la pompe (de 0 à 55).
- Renseignez la variable mesureToF si vous utilisez un capteur ultrasons ou infrarouges à la place de la sonde immergée,
- créez un widget de type HTML, hauteur 3 blocs.
- insérez et ajustez ce code dans le widget :
Afficher le code du widget
var profondeurPuits=900; //profondeur du forage en cm
var diametreInterieur=80; //diametre intérieur du forage en cm
var niveauMini=30; //niveau d'eau mini en cm dans le forage
var niveauMaxi=700;//niveau d'eau maxi en cm dans le forage
var relaisPompe=0; //renseigner le numéro du relais connecté à la pompe. de 0 à 55
var hauteurEau=(datasources["STATUS"]["response"]["analog0"]*100).toFixed(2);
var mesureToF=0;//renseignez 1 si vous utilisez un capteur ultrasons/infrarouges ou laser
//ne pas modifier le code ci-dessous
if(datasources["STATUS"]["response"]["led"+relaisPompe]=="1") {statusP="Pompe en marche";} else {statusP="Pompe à l'arrêt";}
r=diametreInterieur/2;
var pourcentage1=100 - (100*hauteurEau/profondeurPuits);
var pourcentage2=100 - (100*niveauMini/profondeurPuits);
var pourcentage3=100 - (100*niveauMaxi/profondeurPuits);
var volumeForage=Math.PI*r*r*niveauMaxi; //volume max forage en litres
if (mesureToF==1){hauteurEau=niveauMaxi-hauteurEau;} // si mesure ToF
//calcul volume eau
var ve=(Math.PI * Math.pow(r,2) * hauteurEau).toFixed(0);//volume en litres
var vu=(Math.PI * Math.pow(r,2) * (hauteurEau-niveauMini)).toFixed(0);//volume en litres
return `
<style>
.box{
height: 150px;
width: 80px;
position: absolute;
top: 50%;
left: 20px;
transform: translate(0, -50%);
background: #666666;
border-radius:0;
overflow: hidden;
}
.eau1{
position: absolute;
left: 5px;
width: 70px;
height: 150px;
transform:translate(0,${pourcentage1}%);
background:#73a0ca;
}
.eau2{
position: absolute;
left: 5px;
width: 70px;
height: 150px;
transform:translate(0,${pourcentage2}%);
background:#4d759c;
}
.miniN{
position: absolute;
top: ${pourcentage2}%;
width: 80px;
height: 3px;
background:#f00;
}
.maxiN{
position: absolute;
top: ${pourcentage3}%;
width: 80px;
height: 3px;
background:#0f0;
}
</style>
<div class="box">
<div class="eau1"></div>
<div class="eau2"></div>
<div class="miniN"></div>
<div class="maxiN"></div>
</div>
<div style="float:left;margin-left:110px;margin-top:15px;font-size:12px;">
<span >Volume total : ${(volumeForage/1000).toFixed(0)}</span> litres<br><br>
<span >Hauteur eau utile: ${hauteurEau-niveauMini}</span> cm<br>
<span >Volume eau utile : ${(vu/1000).toFixed(0)} litres</span><br>
<span style="position:absolute;left:135px;top: 135px;width: 120px;background-color:#333;" name="Pompe"> ${statusP} </span>
</div>
`;
Exemple avec des capteurs tout ou rien (interrupteurs à flotteur)
Cas d'une cuve parallélépipédique
Usage :
- Montez les flotteurs à intervalle régulier sur la hauteur de la cuve.
Ici, nous allons supposer que le premier flotteur, situé à 20 cm du fond de la cuve, est connecté sur l'entrée digitale 21 ("btn20" dans le code).
Le deuxième flotteur est situé 14 cm plus haut, il est connecté à l'entrée digitale 22 ("btn21" dans le code),
Le troisième flotteur est situé 14 cm au dessus du 2ème, il est connecté à l'entrée digitale 23 ("btn22" dans le code),
et ainsi de suite jusqu'au 8ème flotteur.
- Sur le dashboard, créez une source de données nommée STATUS vers le fichier Status.xml de l'ipx800.
- Renseignez le volume total de la cuve en litres, la hauteur et la longueur de la cuve en cm, puis liez la variable hauteurFuel à la source de données crée précédemment, sur l’analogique de la sonde . la hauteur mesurée est attendue en cm.
- créez un widget de type HTML, hauteur 2 blocs.
- insérez et ajustez ce code dans le widget :
Afficher le code du widget
var intervalle=14; //intervalle entre 2 flotteurs en cm;
var basDeCuve=20;//hauteur sous le flotteur du bas
var hauteurEau=(datasources["STATUS"]["response"]["btn20"] == 0) * basDeCuve ;
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn21"] == 0) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn22"] == 0) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn23"] == 0) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn24"] == 0) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn25"] == 0) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn26"] == 0) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn27"] == 0) * intervalle ;
var largeurCuve=104; //largeur cuve en cm
var hauteurCuve=117; //hauteur cuve en cm
var longueurCuve=250; //longueur cuve en cm
//calcul du ratio
var pourcentage=(hauteurEau/hauteurCuve)*100;
//calcul volume Eau et volume total
var ve=0; var vt=0;
ve=hauteurEau * largeurCuve * longueurCuve;
ve=(ve/1000).toFixed(0);
vt=hauteurCuve * largeurCuve * longueurCuve;
vt=(vt/1000).toFixed(0);
if (hauteurEau <= 20) {
couleurEau="#e25d6b";
} else {
couleurEau="#5dade2";
}
return `
<style>
.box{
height: 70px;
width: 70px;
position: absolute;
top: 50%;
left: 10px;
transform: translate(0, -50%);
background: #666666;
border-radius:15%;
overflow: hidden;
}
.eau{
position: absolute;
left: 0;
top: 0;
width: 70px;
height: 70px;
transform:translate(0,${100-pourcentage}%);
background: ${couleurEau} ;
}
</style>
<body>
<div class="box">
<div id="eau" class="eau"></div>
</div>
<div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;">
<br>
<span >Contenance cuve: ${vt}</span> litres<br>
<span >Hauteur Eau : ${hauteurEau}</span> cm<br>
<span style="font-weight:bold;">Volume Eau : ${ve} litres</span><br>
<span >Ratio volume : ${(ve/vt*100).toFixed(2)}</span> %<br>
</div>
`;
Remarque :
Il faudra ajuster le code en fonction des capteurs utilisés.
Pour l'exemple, nous avons utilisé des capteurs NF qui seront à l'état OFF lorsqu'ils seront immergés.
Pour des capteurs qui passent ON lorsqu'ils sont immergés, il faudra comparer l'état de l'entrée digitale à 1 au lieu de 0.
Exemple :
var hauteurEau=(datasources["STATUS"]["response"]["btn20"] == 1) * basDeCuve ;
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn21"] == 1) * intervalle ; //capteur du bas
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn22"] == 1) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn23"] == 1) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn24"] == 1) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn25"] == 1) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn26"] == 1) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS"]["response"]["btn27"] == 1) * intervalle ; //capteur du haut
Cas d'une cuve cylindrique verticale
Usage :
- Montez les flotteurs à intervalle régulier sur la hauteur de la cuve.
Ici, nous allons supposer que le premier flotteur, situé à 20 cm du fond de la cuve, est connecté sur l'entrée digitale 21 ("btn20" dans le code).
Le deuxième flotteur est situé 20 cm plus haut, il est connecté à l'entrée digitale 22 ("btn21" dans le code),
Le troisième flotteur est situé 20 cm au dessus du 2ème, il est connecté à l'entrée digitale 23 ("btn22" dans le code),
et ainsi de suite jusqu'au 10ème flotteur.
- Sur le dashboard, créez une source de données nommée STATUS vers le fichier Status.xml de l'ipx800.
- créez un widget de type HTML, hauteur 2 blocs.
- insérez et ajustez le code dans le widget
- Renseignez le diamètre intérieur de la cuve en cm
- Renseignez les hauteurs d'installation des flotteurs dans la table hauteurs[]
- Renseignez le numéro des entrées digitales pour chaque flotteur. Comme vu précédemment, nous supposons dans l'exemple que le flotteur bas est connecté à l'entrée digitale n°21 ("btn20" dans status.xml).
- Renseignez la variable statusON avec la valeur prise par les capteurs à l'état ON (1 ou 0)
- Décommentez le jeu de couleur souhaité. Les captures ci-dessus ont été construites avec le 'jeu 1'.
Le jeu 2 propose un thème plus sombre avec les couleurs GCE, le jeu 3 propose un camaïeu de bleu.
Vous pouvez concevoir vos propres thèmes de couleurs.
Afficher le code du widget
var diametreInterieur=120; //largeur cuve en cm
var hauteurs=[0, 20, 40, 60, 120, 140, 160, 180, 200, 220, 240];//hauteurs des flotteurs en partant du fond / en cm
var btn=[20,21,22,23,24,25,26,27,28,29];//numéros des entrées digitales pour chaque flotteur, en partant du flotteur le plus bas
var statusON=0;//renseignez la valeur 0 ou 1 prise par un capteur à l'état ON
//jeu couleurs 1
var couleursON=['ff851b','0f0','0f0','0f0','0f0','0f0','0f0','0f0','0f0','0f0','ff0'];
var couleursOFF=['f00','666','666','666','666','666','666','666','666','666','666'];
//jeu couleurs 2
//var couleursON=['ff851b','3fb740','3fb740','3fb740','3fb740','3fb740','3fb740','3fb740','3fb740','ff0'];
//var couleursOFF=['f00','222','222','222','222','222','222','222','222','222'];
//jeu couleurs 3
//var couleursON=['000033','000066','000066','000099','000099','000099','0000cc','0000cc','0000ff','3300ff'];
//var couleursOFF=['f00','222','222','222','222','222','222','222','222','222'];
//ne pas modifier ci-dessous
var rang=0;
var i;
//test entrées digitales avec capteurs
for (i=0;i<=(btn.length-1);i++){
if(datasources["STATUS"]["response"]["btn" + btn[i]] == statusON) {
rang=rang + 1;}
}
//calcul volume Eau / volume total mini et utile
var ve=hauteurs[rang] * Math.pow(diametreInterieur/2,2) * Math.PI;
var vt=hauteurs[hauteurs.length - 1] * Math.pow(diametreInterieur/2,2) * Math.PI;
var vm=hauteurs[1]* Math.pow(diametreInterieur/2,2) * Math.PI;
var vu=ve-vm;
if (ve<=0){vu=0;}
return `
<style>
.box2{
height: 152px;
width: 40px;
position: absolute;
top: 5px;
left: 10px;
background: #333;
border-radius:1%;
overflow: hidden;
}
.led{
position: absolute;
left: 10px;
width: 20px;
height: 8px;
}
</style>
<div class="box2">
<div class="led" style="top:95px;background:#${ rang>=1 ? couleursON[0] : couleursOFF[0]};"></div>
<div class="led" style="top:85px;background:#${ rang>=2 ? couleursON[1] : couleursOFF[1]};"></div>
<div class="led" style="top:75px;background: #${ rang>=3 ? couleursON[2] : couleursOFF[2]};"></div>
<div class="led" style="top:65px;background: #${ rang>=4 ? couleursON[3] : couleursOFF[3]};"></div>
<div class="led" style="top:55px;background: #${ rang>=5 ? couleursON[4] : couleursOFF[4]};"></div>
<div class="led" style="top:45px;background: #${ rang>=6 ? couleursON[5] : couleursOFF[5]};"></div>
<div class="led" style="top:35px;background: #${ rang>=7 ? couleursON[6] : couleursOFF[6]};"></div>
<div class="led" style="top:25px;background: #${ rang>=8 ? couleursON[7] : couleursOFF[7]};"></div>
<div class="led" style="top:15px;background: #${ rang>=9 ? couleursON[8] : couleursOFF[8]};"></div>
<div class="led" style="top:5px;background: #${ rang>=10 ? couleursON[9] : couleursOFF[9]};"></div>
</div>
<div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;">
<br>
<span >Contenance cuve: ${(vt/1000).toFixed(0)}</span> litres<br>
<span >Hauteur Eau : ${hauteurs[rang]}</span> cm<br>
<span style="font-weight:bold;">Volume total Eau : ${(ve/1000).toFixed(0)} litres</span><br>
<span style="font-weight:bold;">Volume mini : ${(vm/1000).toFixed(0)} litres</span><br><br>
<span style="font-weight:bold;background:#666">Volume utile Eau : ${(vu/1000).toFixed(0)} litres</span><br>
</div>
`;
Autres formes de cuve
Il est tout à fait possible d'appliquer le principe des interrupteurs à flotteurs aux autres formes de cuves vues dans le chapitre précédent.
A vous de jouer.