Domotisation de la VMC

Publié sur: Domotisation de la VMC – Jeedom – Le Blog

Cet article va être très court, car il a pour but de vous donner des idées au vu de la simplicité du scénario qui en découle. Il y a quelques mois j’ai enfin réussi à me motiver et à tirer le câble pour domotiser la vitesse de ma VMC. IMPORTANT : il ne faut JAMAIS…

6 « J'aime »

Merci Loïc pour ce partage.

Il faut que je me motive également à le faire !

Petite question câblage, tu pilote ta VMC directement par l’IPX (je présume par un relay Outpout, borne 3-4-5 par exemple, ou 3-4 est petite vitesse et 4-5 grande vitesse) ou passes-tu par un contacteur / relais ?
Je viens de me poser la question en lisant ton billet, vis-à-vis de la capacité des relais de l’IPX (bien que la puissance d’une VMC ne doit pas chercher loin … faut que je penses à regarder la puissance de la mienne tiens) à permuter sur une charge inductive.

Bonjour
Je pilote la Vmc directement avec les relais de l’ipx. La petite vitesse est toujours alimenté en direct par le tableau électrique et la grande vitesse par l’ipx quand le relais est fermée.

Pour la puissance pas trop d’inquiétude le disjoncteur d’une Vmc est normalement un 2 ampères, l’ipx peut piloter jusqu’à 10A.

Top :), perso j’ai également domotisé la mienne (double flux). En me basant sur la doc technique et le retour des températures, j’ai fait une vitesse lente en abs ou alors si température extérieur trop basse, une vitesse normal en présence.
Par contre pas encore le Netatmo pour la qualité de l’air.

Merci @Loic, pour l’info qualité de l’air, je vais en tenir compte pour le PV/GV de ma VMC double flux ! Pour l’instant je ciblé l’hygrométrie extérieur au plus faible et la température extérieur au plus chaud l’hiver et au plus frais l’été (pentes temp/hygro + tranche horaire dites hors pollution), en parallèle je déclenche aussi la GV sur seuil Hygro des salles de bain.
J’utilise des sondes du Mobile Alerte qui donne Temp/hygro qualité de l’air.
image

Hello Loic et les Autres,
Automaticien de base, la régulation de temp est souvent au cœur de ce métier.
Coté éléc, il y a plein de solution et comme d’hab, si vous prenez une VMC très « simple », c’est plus « simple » de faire se que vous voulez.
J’ai pris une Double flux avec un bon rendement mais pas dutout technique électriquement.
Ce qui permet de faire du Arret-PV-GV et RécupChaleur/ByPass.

En therme de model mathématique thermique, les erreurs sont très compliquer à rattraper.
Par exemple, il fait 40°c dehors mais je n’ai pas mis en place un relai qui permet de tous couper, thermiquement, la température va vite monter et là, c’est « chaud » pour évacuer les calories.
C’est le même équilibre à trouver comme quand on écrit un bon bout de programme, ça peut être très complet mais si c’est pas adapté à l’utilisateur, c’est purement « inutile ».

Globalement, ne pas laisser échapper de la chaleur qu’on à créer en Hiver et ne pas laisser échapper la fraicheur qu’on veux conserver et été.

  • Mode été qui coupe tout quand il fait plus chaud dehors que dedans.

  • Mode été en PV à 1°c sous la temp extérieur, GV à 2°c en dessous.

  • Mode été qui fait tourner 2h au plus frais de la nuit même s’il faut plus chaut. (souvent vers 7h)

  • Mode Hiver quand une pièces passe au dessus d’une humidité choisi

  • Mode Hiver quand le poel à granule est en fonctionnement (répartition de sa chaleur accru)

  • Annexe : Mode Manu pour plein de petit cas (maintenance, grosse canicule, raclette qui pue… :slight_smile: )

  • Annexe : Mode silence qui reduit GV vers PV

  • Annexe : Mode hotte (via conso sur le prise de la hotte)

Et évidement, on peux faire plein de déco dans un design mais dans le fond, c’est pas utile si la prog est bien faite, c’est autonome. bon, j’avoue, quand j’ouvre le scenario, c’est un peu lent…mais ça fonctionne très bien.
pour JC

Attention, mettez bien des hystérésis aux consignes, l’usure d’un moteur se compte souvent en nombre de démarrage.

Attention, pour un moteur, l’intensité au démarrage, c’est « 7 x l’intensité nominal ». Il ne faut pas faire l’amalgame entre un disjoncteur et un relais, ils n’ont pas le même rôle.
Pour un disjoncteur, le circuit est déjà fermé et il est là que pour protéger les lignes éléc alors qu’un relais à un pouvoir de coupure puisqu’il ouvre/ferme un circuit sous puissance de démarrage. De plus, un disjoncteur est fait pour ne pas sauté rapidement, (type AM ou DM normalement pour les VMC Hotte, pompe de relevage, ect…) pour justement « encaisser » les quelques secondes au démarrage (les fabricants estime que les fils n’ont pas le temps de chauffer).
Ne pas lésiner à bien calculer le Courant maxi pour ne pas user les relais de l’IPX, vu le prix…

3 « J'aime »

Hello @mick37, Tu utilises des données de Mobile alerte? Celles de LaCrossTechnologie?
Si Oui, comment tu fais? Je galère un peu…

voir le post de @laurent.da-col
que j’ai mis à ma sauce

ex php extraction Mobile Alerts

il faut que tu renseigne les id de ton virtuel, les labels servent à l’affichage debug du scénario (setLog)
utilise le selecteur jquery google pour pointer ou il faut dans la page HTML de ton Mobile
Alerts

"/html/body/div[2]/div[1]/div/div/div[".$n."]/h4"

nth-child(3)
3 est le n° d’enregistrement (ligne de la premiere donnée)
nth-child(5)
5 est l’emplacement de la donnée dans la ligne (il peut y avoir plusieurs données dans la meme ligne)

installer et utiliser le plugin jQuery dans Chrome pour récupérer les sélecteurs dans la page HTML de Mobile Alerts.
jquery

Attention : cette page est triée par nom de capteurs, capteurs qui ne sont repérables dans la feuille que par leur positions, donc si tu renomme ou ajoute un capteur il faudra recupérer à nouveau l’emplacement avec jQuery.


$stream = stream_context_create(Array("http" => Array("method" => "GET", "header" => "User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0", "timeout" => 120)));
$html = file_get_contents("https://measurements.mobile-alerts.eu/Home/SensorsOverview?phoneid=xxxxxxxxxxx",false,$stream); 
$sonde = 1;

// ----------------- Controle Reception longueur de trame Html ----------- Si trame à zéro abandon -----------------------
$lenhtml = strlen($html);
if ($lenhtml<1) $sonde=0;
$scenario->setLog("taille html=".$lenhtml." Sonde=".$sonde);
cmd::byId(4340)->event($sonde);
if ($lenhtml<1) goto end;

// ------------------------------------------------------------------------------------------------------------------------
$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXpath($dom);

// ------------------------------------------------------------------------------------------------------------------------
$id = array(5752, 2128, 2129, 4189, 1946);
$label = array("heure",	"temp SDB",	"hygro SDB", "air SDB", "temp Chambre");
$scenario->setLog("Etage SDB Chambre");
foreach ($id as $cle => $val) {
    $n=$cle+3;
   	$value[$cle]=$xpath->query("/html/body/div[2]/div[1]/div/div/div[".$n."]/h4")[0]->childNodes[0]->nodeValue;
  	$value[$cle] = substr($value[$cle], 0, -1);
  	$scenario->setLog($id[$cle]." ".$label[$cle]."=".$value[$cle]);
    if ($value[$cle]!="---" && $value[$cle]!="0") cmd::byId($id[$cle])->event($value[$cle]);
};

// ------------------------------------------------------------------------------------------------------------------------
$id = array(5754, 2724);
$label = array("heure",	"temp Frigo");
$scenario->setLog("Frigo");
foreach ($id as $cle => $val) {
    $n=$cle+3;
   	$value[$cle]=$xpath->query("/html/body/div[2]/div[2]/div/div/div[".$n."]/h4")[0]->childNodes[0]->nodeValue;
  	$value[$cle] = substr($value[$cle], 0, -1);
  	$scenario->setLog($id[$cle]." ".$label[$cle]."=".$value[$cle]);
    if ($value[$cle]!="---" && $value[$cle]!="0") cmd::byId($id[$cle])->event($value[$cle]);
};

// ------------------------------------------------------------------------------------------------------------------------
$id = array(5756, 2112);
$label = array("heure",	"Pluie");
$scenario->setLog("Pluie");
foreach ($id as $cle => $val) {
    $n=$cle+3;
   	$value[$cle]=$xpath->query("/html/body/div[2]/div[4]/div/div/div[".$n."]/h4")[0]->childNodes[0]->nodeValue;
  	$value[$cle] = substr($value[$cle], 0, -2);
    if ($cle==1) $value[$cle]=($value[$cle])*3;
  	$scenario->setLog($id[$cle]." ".$label[$cle]."=".$value[$cle]);
    if ($value[$cle]!="---" && $value[$cle]!="0") cmd::byId($id[$cle])->event($value[$cle]);
};

// ------------------------------------------------------------------------------------------------------------------------
$id = array(5739, 2106, 2107);
$label = array("heure",	"temp Terrasse", "hygro Terrasse");
$scenario->setLog("Terrasse");
foreach ($id as $cle => $val) {
    $n=$cle+3;
   	$value[$cle]=$xpath->query("/html/body/div[2]/div[5]/div/div/div[".$n."]/h4")[0]->childNodes[0]->nodeValue;
  	$value[$cle] = substr($value[$cle], 0, -1);
  	$scenario->setLog($id[$cle]." ".$label[$cle]."=".$value[$cle]);
    if ($value[$cle]!="---" && $value[$cle]!="0") cmd::byId($id[$cle])->event($value[$cle]);
};

// ------------------------------------------------------------------------------------------------------------------------
$id = array(5756, 2114, 2113, 2116);
$label = array("heure",	"Vent",	"Rafale", "Orientation");
$scenario->setLog("Vent");
foreach ($id as $cle => $val) {
    $n=$cle+3;
   	$value[$cle]=$xpath->query("/html/body/div[2]/div[6]/div/div/div[".$n."]/h4")[0]->childNodes[0]->nodeValue;
  	if ($cle < 3) $value[$cle] = substr($value[$cle], 0, -4);
  	$scenario->setLog($id[$cle]." ".$label[$cle]."=".$value[$cle]);
    if ($value[$cle]!="---" && $value[$cle]!="0") cmd::byId($id[$cle])->event($value[$cle]);
};

Log du scénario avec les id des virtuels

[2022-03-13 23:56:04][SCENARIO] Start : Scenario execute automatiquement sur programmation.
[2022-03-13 23:56:04][SCENARIO] Exécution du sous-élément de type [action] : code
[2022-03-13 23:56:04][SCENARIO] Exécution d'un bloc code
[2022-03-13 23:56:32][SCENARIO] taille html=9867 Sonde=1
[2022-03-13 23:56:32][SCENARIO] Etage SDB Chambre
[2022-03-13 23:56:32][SCENARIO] 5752 heure=13/03/2022 23:54:2
[2022-03-13 23:56:32][SCENARIO] 2128 temp SDB=18,0
[2022-03-13 23:56:32][SCENARIO] 2129 hygro SDB=51
[2022-03-13 23:56:33][SCENARIO] 4189 air SDB=750 pp
[2022-03-13 23:56:33][SCENARIO] 1946 temp Chambre=19,2
[2022-03-13 23:56:33][SCENARIO] Frigo
[2022-03-13 23:56:33][SCENARIO] 5754 heure=13/03/2022 23:54:1
[2022-03-13 23:56:33][SCENARIO] 2724 temp Frigo=5,2
[2022-03-13 23:56:33][SCENARIO] Pluie
[2022-03-13 23:56:33][SCENARIO] 5756 heure=
[2022-03-13 23:56:33][SCENARIO] 2112 Pluie=0
[2022-03-13 23:56:33][SCENARIO] Terrasse
[2022-03-13 23:56:33][SCENARIO] 5739 heure=13/03/2022 23:51:4
[2022-03-13 23:56:33][SCENARIO] 2106 temp Terrasse=10,2
[2022-03-13 23:56:33][SCENARIO] 2107 hygro Terrasse=90
[2022-03-13 23:56:33][SCENARIO] Vent
[2022-03-13 23:56:33][SCENARIO] 5756 heure=13/03/2022 23:4
[2022-03-13 23:56:33][SCENARIO] 2114 Vent=0.4
[2022-03-13 23:56:33][SCENARIO] 2113 Rafale=3.2
[2022-03-13 23:56:33][SCENARIO] 2116 Orientation=Nord- Nord Est
[2022-03-13 23:56:33][SCENARIO] x Rdc
[2022-03-13 23:56:33][SCENARIO] 5741 heure=13/03/2022 23:50:4
[2022-03-13 23:56:33][SCENARIO] 2120 temp Chambre=19,5
[2022-03-13 23:56:33][SCENARIO] 2121 hygro Chambre=64
[2022-03-13 23:56:33][SCENARIO] 1938 temp SDB=20,3
[2022-03-13 23:56:33][SCENARIO] 1939 hygro SDB=64
[2022-03-13 23:56:33][SCENARIO] 2124 temp Séjour=17,5
[2022-03-13 23:56:34][SCENARIO] 2125 hygro Séjour=70
[2022-03-13 23:56:34][SCENARIO] 5722 temp Buanderie=17,5
[2022-03-13 23:56:34][SCENARIO] 5723 hygro Buanderie=69
[2022-03-13 23:56:34][SCENARIO] x Rdc2
[2022-03-13 23:56:34][SCENARIO] 5750 heure=13/03/2022 23:54:4
[2022-03-13 23:56:34][SCENARIO] 5748 temp Salon=21,3
[2022-03-13 23:56:34][SCENARIO] 5749 hygro Salon=58
[2022-03-13 23:56:34][SCENARIO] 4788 temp Bureau=19,6
[2022-03-13 23:56:34][SCENARIO] 4789 hygro Bureau=63
[2022-03-13 23:56:34][SCENARIO] 5725 temp Garage=10,7
[2022-03-13 23:56:34][SCENARIO] 5726 hygro Garage=84
[2022-03-13 23:56:34][SCENARIO] 5383 temp Etage=18,3
[2022-03-13 23:56:34][SCENARIO] 5386 hygro Etage=55
[2022-03-13 23:56:34][SCENARIO] Fin correcte du scénario

Bonjour,

Si jamais voici la dernière version de mon code PHP :

$phoneid="PHONE ID";

$tabmodules = [
    ["Cave","/html/body/div[2]/div[1]/div/div/div[1]/h3/a","/html/body/div[2]/div[1]/div/div/div[3]/h4",[//Titre du capteur, Chemin xpath du titre, Chemin xpath de la date/heure du relevé
		["/html/body/div[2]/div[1]/div/div/div[4]/h4",3011],//Chemin xpath de la mesure, Id. de la commande
		["/html/body/div[2]/div[1]/div/div/div[6]/h4",3012]]],
    ["Piscine","/html/body/div[2]/div[5]/div/div/div[1]/h3/a","/html/body/div[2]/div[5]/div/div/div[3]/h4",[
		["/html/body/div[2]/div[5]/div/div/div[4]/h4",2996],
		["/html/body/div[2]/div[5]/div/div/div[6]/h4",2998]]],
    ["Piscine 2","/html/body/div[2]/div[6]/div/div/div[1]/h3/a","/html/body/div[2]/div[6]/div/div/div[3]/h4",[
		["/html/body/div[2]/div[6]/div/div/div[5]/h4",2934]]],
    ["Maison","/html/body/div[2]/div[4]/div/div/div[1]/h3/a","/html/body/div[2]/div[4]/div/div/div[3]/h4",[
		["/html/body/div[2]/div[4]/div/div/div[5]/h4",3003],
		["/html/body/div[2]/div[4]/div/div/div[6]/h4",3005],
		["/html/body/div[2]/div[4]/div/div/div[4]/h4",3015],
		["/html/body/div[2]/div[4]/div/div/div[7]/h4",3000]]],
    ["Etage","/html/body/div[2]/div[3]/div/div/div[1]/h3/a","/html/body/div[2]/div[3]/div/div/div[3]/h4",[
		["/html/body/div[2]/div[3]/div/div/div[4]/h4",3007]]]
];

$stream = stream_context_create(Array("http" => Array("method"  => "GET",
                                                      "header"  => "User-agent: PHP",
                                ))); 
$html = file_get_contents("https://measurements.mobile-alerts.eu/Home/SensorsOverview?phoneid=".$phoneid,false,$stream); 
$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXpath($dom);

$now_timestamp=time();

foreach ($tabmodules as list($module_titre,$module_titre_xpath,$module_dateheure_xpath,$tabcapteurs)) {

  $module_timestamp=date_format(date_create_from_format("d/m/Y H:i:s",$xpath->query($module_dateheure_xpath)[0]->childNodes[0]->nodeValue),'U');
  
  if (( $xpath->query($module_titre_xpath)[0]->childNodes[0]->nodeValue == $module_titre ) && ($now_timestamp-$module_timestamp<900)) {
  
  	foreach ($tabcapteurs as list($capteur_xpath,$capteur_cmdid)) {
    
       	$value=$xpath->query($capteur_xpath)[0]->childNodes[0]->nodeValue;
    	if ($value!="---" && $value!="OFL") {

          cmd::byId($capteur_cmdid)->event($value);
          
          $scenario->setLog($module_titre." (".($now_timestamp-$module_timestamp).") "."->".$value);
          
        };
  	};
  
  };
  
};

Il suffit d’y renseigner son PHONE ID dans la variable $honeid et les éléments suivant dans le tableau $tabmodules :

  • Titre du capteur dans la page http : pour contrôle,
  • Chemin xpath du titre précisé précédemment,
  • Chemin xpath de la date/heure du dernier relevé pour le capteur,
  • Tableau des sondes à extraire pour le capteur :
    - Chemin xpath de la mesure,
    - Id. de la commande Jeedom où enregistrer la mesure.

La mise à jour des commandes ne se fait que si la date/heure de la mesure à moins de 15 minutes.

Cependant je n’utilise plus cette méthode je passe par jMQTT/MQTT/maserver qui a le mérite entre autre de n’être plus dépendant du cloud car l’interception des mesures s’y fait sur le réseau local.