Aller au contenu
jjacques68

Gestion complète des plantes avec Mi-Flora

Recommended Posts

Bonjour à tous,

 

Voici un petit tuto qui explique mon installation pour contrôler l'état des plantes vertes de la maison.

 

EDIT : Scène en Version 2 (téléchargeable à la fin du tuto).

correction d'un bug dans l'affichage du debug lors de la création des VG.

 

HC2.png.cdb46ca2c6ea448bf2e238ef95f12123.png

 

Je précise tout de suite que je n'ai pas les pouces verts :P, et que je suis du genre à oublier d'arroser nos belles plantes (ou de trop les arroser).

Ce n'est pas vital, mais ça me rend quand même service. Et j'ose dire que mes plantes ne se portent pas si mal que ça…

 

J'utilise les capteurs XIAOMI Mi Flora en vente sur amazon, aliexpress, … à des prix allant du simple au triple !

 

miflora-3.thumb.jpg.91552c8b324b89ddc07300c9e213b228.jpg

 

J'en ai déjà eu à 9 € et d'autre à 20 € !!! Faut surveiller les offres du moment…

Attention aux capteurs version chinois !!! (impossible de les mettre à jour, mais fonctionne sous BLEA).

!!! Il faut prendre des versions internationales !!!

Ils semblent plutôt bien fonctionner (même à l'extérieur).

La précision des mesures restent à confirmer...

Surtout qu'aucune plante ne se comporte de la même manière.

 

J'ai utilisé l'application Flower Care (iPhone) pour mettre à jour les capteurs (actuellement : 3.1.8).

 

Ces capteurs sont en Bluetooth, donc il faut une box compatible. Dans mon cas j'ai une Jeedom Smart.

 

Sommaire :

 

  1. Configuration Jeedom
  2. VD HC2
  3. La Scène Mi-Flora
  4. Conclusion

 

1. Configuration Jeedom

 

Je passe la partie installation Jeedom.

J'utilise le plungin BLEA de @sarakha63 (merci pour son travail) qui fonctionne à merveille avec les objets bluetooth.

J'ai également ajouté une antenne bluetooth supplémentaire pour avoir une meilleur portée (raspberry avec raspbian installé et une clé Bluetooth de type SENA)

Tout est bien expliqué sur le blog de @sarakha63. Je vous invite à fouillé un peu chez lui.

 

Voilà le résultat dans Jeedom :

jeedom.thumb.png.e919c7bad6aadf081ed0fb2719937cbd.png

 

On y voit les 12 plantes avec leurs données (humidité, température, batterie...)

Je remonte certaines de ces données vers la HC2 :

L'humidité (surtout cela qui m'intéresse) ; Le fertilisant ; L'ensoleillement ; La température ; La batterie

 

Cette remontée d'info se fait grâce à un script :

 

EDIT : il faut installer le plugin script disponible dans le market

 

scipt.thumb.png.93ac5d3d2d1cca614c5a390e69909063.png

 

Voilà le script au complet (sans retour à la ligne ni espace) :

 

http://192.168.xx.xx/api/callAction?deviceID=363&name=setProperty&arg1=ui.FromJeedom.value&arg2={Tmp:"#[Maison][Sanse Gd][Température]# °C",Hum:"#[Maison][Sanse Gd][Humidité]# %25",Frt:"#[Maison][Sanse Gd][Fertilisant]# uS/cm",Lum:"#[Maison][Sanse Gd][Luminosité]# Lux",Bat:"#[Maison][Sanse Gd][Batterie]# %25"}

 

On voit dans ce script que j'écris dans un label nommé "FromJeedom" d'un VD (ici ID = 363) les données voulues de ma plante (nommée  Sanse Gd)

Je duplique ce script autant de fois que j'ai de plante en passant à changer le N° du VD (car un VD par plante) et bien sûr le nom de la plante.

Ce qui fait que mon script contient 12 requêtes l'une en dessous de l'autre.

192.168.xx.xx est l'adresse IP sur le réseau local de la HC2.

 

Il est exécuté toutes les 29 minutes grâce à Auto-actualisation (CRON)  : */29 * * * *

(google sera mieux que moi vous expliquer ce CRON… c'est pas mal le système :))

 

EDIT : Le temps de rafraichissement de chaque Mi-Flora est fixé à 2 heures (suffisent à mon avis... à voir à l'usage)

 

2. VD HC2 :

 

Voici le VD d'une plante :

 

VD.png.a05fb3f392821e3e53817f7d078b2c84.png

 

On y voit comme prévu, les données voulues.

Le nom du VD est simplement le nom de la plante (pas forcément identique à celui renseigné dans Jeedom)

L'icône présente un point d'exclamation rouge car justement l'humidité est plus basse que la consigne :huh:

Sinon celle-ci serait sans le point d'exclamation. (Donc j'ai 2 icones par plante…)

 

Il y a en plus :

  • Un label consigne avec 2 boutons +/- pour sélectionner la consigne d'alerte pour l'arrosage.
  • Un label Up pour savoir quand a été faite la dernière mise à jour
  • Un label data qui reçoit le contenu de la requête Jeedom.

Vous aurez compris que ce label a pour ID : FromJeedom (voir chapitre 1)

 

Pour les labels, il est important du coup de les identifier avec cette logique : (la scène utilisera ces ID de label)

Humidité = Hum ; Température = Tmp ; Lumière = Lum ; Fertilisant = Frt ; Batterie = Bat

 

Code du bouton + :

local id = fibaro:getSelfId()
local cons = tonumber(fibaro:getGlobalValue("HumPlante"..id))
local val = string.match(fibaro:getValue(id, "ui.Hum.value"), "[0-9.]+")

--INC la consigne
cons=cons+1
if cons > 100 then cons = 100 end

--set la VG
fibaro:setGlobal("HumPlante"..id, cons)

--affiche dans le label consigne
fibaro:call(id, "setProperty", "ui.HumCons.value", cons.." %")

--test la valeur et la consigne pour avoir la bonne icone
if tonumber(val) >= cons then
  fibaro:call(id, "setProperty", "currentIcon", 1083)
else
  fibaro:call(id, "setProperty", "currentIcon", 1084)
end

Code du bouton - :

local id = fibaro:getSelfId()
local cons = tonumber(fibaro:getGlobalValue("HumPlante"..id))
local val = string.match(fibaro:getValue(id, "ui.Hum.value"), "[0-9.]+")

--DEC la consigne
cons=cons-1
if cons < 0 then cons = 0 end

--set la VG
fibaro:setGlobal("HumPlante"..id, cons)

--affiche dans le label consigne
fibaro:call(id, "setProperty", "ui.HumCons.value", cons.." %")

--test la valeur et la consigne pour la bone icone
if tonumber(val) >= cons then
  fibaro:call(id, "setProperty", "currentIcon", 1083)
else
  fibaro:call(id, "setProperty", "currentIcon", 1084)
end

On constate dans ces codes qu'une variable globale "HumPlanteXXX" est utilisée pour mémoriser la consigne. Celle –ci est créée par la scène (voir chapitre3).

On retrouve également l'ID des 2 icones pour cette plante.

 

Code de la mainLoop : (rien de bien compliqué, c'est juste pour que tout soit propre lors d'un reboot de la HC2)

local id = fibaro:getSelfId()
local cons = tonumber(fibaro:getGlobalValue("HumPlante"..id))
local val = string.match(fibaro:getValue(id, "ui.Hum.value"), "[0-9.]+")

--affiche de la consigne
fibaro:call(id, "setProperty", "ui.HumCons.value", fibaro:getGlobal("HumPlante"..id).." %")

--test la valeur et la consigne pour l'icone
if tonumber(val) >= cons then
  fibaro:call(id, "setProperty", "currentIcon", 1083)
else
  fibaro:call(id, "setProperty", "currentIcon", 1084)
end

fibaro:abort()

3. La scène Mi-Flora : (attention c'est lourd…)

 

--[[
%% autostart
%% properties
353 ui.FromJeedom.value
352 ui.FromJeedom.value
357 ui.FromJeedom.value
358 ui.FromJeedom.value
359 ui.FromJeedom.value
361 ui.FromJeedom.value
362 ui.FromJeedom.value
363 ui.FromJeedom.value
366 ui.FromJeedom.value
367 ui.FromJeedom.value
368 ui.FromJeedom.value
385 ui.FromJeedom.value
%% events
%% globals
--]]

--[[
Version 2

- se déclenche sur changement de valeur du label FromJeedom des VD des plantes
- a besoin de 2 VG par plante (testées et crées par la fonction TestGlobal) :
		HumPlante = consigne pour les tests d'humidité
		DatePlante = date à laquelle l'alerte mail a été envoyé (pour pas en avoir plusieurs)
- récupère la chaine de caractère du label FromJeedom du VD (table json)
- pour chaque item du json, update des label correspondant du VD
- pour le label "Hum", appel de la fonction Alerte pour tester l'humidité
- la fonction alerte change l'icone du VD et envoi notif si pas déjà fait
- si le param "active" = 0 c'est que la plante/capteur n'est plus utilisé
--]]


--Déclarations******************************************************************

local Trigger = fibaro:getSourceTrigger()
local NameID
local Liste = { --liste des plantes (VD)
	[352] = {id = 352, IcoOK=1061, IcoNOK=1062, active=1},
  	[353] = {id = 353, IcoOK=1059, IcoNOK=1060, active=1},  		
  	[357] = {id = 357, IcoOK=1063, IcoNOK=1064, active=1},
  	[358] = {id = 358, IcoOK=1071, IcoNOK=1072, active=1},
  	[359] = {id = 359, IcoOK=1067, IcoNOK=1068, active=1},
  	[361] = {id = 361, IcoOK=1069, IcoNOK=1070, active=1},
  	[362] = {id = 362, IcoOK=1077, IcoNOK=1078, active=1},
  	[363] = {id = 363, IcoOK=1075, IcoNOK=1076, active=1},
  	[366] = {id = 366, IcoOK=1079, IcoNOK=1080, active=1},
    [367] = {id = 367, IcoOK=1081, IcoNOK=1082, active=1},
    [368] = {id = 368, IcoOK=1083, IcoNOK=1084, active=1},
    [385] = {id = 385, IcoOK=1091, IcoNOK=1092, active=1},
}

--TestGlobal****************************************************************
-- teste si la VG existe. La créée le cas échéant

function TestGlobal(id)
  local listeVG = {"HumPlante", "DatePlante"} --liste des VG à tester/créer
   
  for k,v in ipairs(listeVG) do --pour chaque VG de la liste
    if fibaro:getGlobal(v..id) == nil then --si pas de VG
	  
      newVar = {}
        --détermine son nom
        newVar.name = v..id
        --détermine sa valeur
        if v == "HumPlante" then
          newVar.value = "20"
        elseif v == "DatePlante" then
          newVar.value = ""
        end

      --crée la VG	  
	  api.post("/globalVariables", newVar)
      print("VG "..newVar.name.." créée.")
    end
  end
end

--UpdateVD********************************************************************
--met à jour les label du VD et appel la fonction alerte

function UpdateVD(id, name, IcoOK, IcoNOK)
  --récupère le tableau Json
  local MaChaine = fibaro:getValue(id, "ui.FromJeedom.value")
  --print(MaChaine)
  print("<font color='green'>"..os.date("%d/%m/%Y").." - Update "..name.."</font>") 
  
  --test si le label est pas vide
  if MaChaine == "" or MaChaine == nil then 
    print("Label vide. fin")
    return false --sort de la function donc fin à la scène
  end  

  --pour chaque élément du tableau Json
  for label,valeur in pairs(json.decode(MaChaine)) do
    fibaro:call(id, "setProperty", "ui."..label..".value", valeur) --met à jour le VD
    if label == "Hum" then Alerte(id, valeur, name, IcoOK, IcoNOK) end
  end
  
  --met à jour la date updated
  fibaro:call(id, "setProperty", "ui.Up.value", os.date("%d/%m/%Y - %H:%M"))
  fibaro:call(id, "setProperty", "log", os.date("%d/%m/%Y - %H:%M"))
  fibaro:call(id, "setProperty", "logTemp", "TxtGreen")
end

--Alerte**********************************************************************
--alerte en cas d'humidité trop basse

function Alerte(id, valeur, name, IcoOK, IcoNOK)
  local CurrentDate = os.date("%d/%m/%Y")

  --reformate la valeur pour extraire que le chiffre  
   valeur = string.match(valeur, "[0-9.]+")

  --si la valeur est < consigne
  if tonumber(valeur) < tonumber(fibaro:getGlobalValue("HumPlante"..id)) then
    
    -- change icone en alerte
    fibaro:call(id, "setProperty", "currentIcon", IcoNOK)
      
    --si la date de la variable est différente
    if fibaro:getGlobal("DatePlante"..id) ~= CurrentDate then
      print("<font color='red'>".."Arroser "..name.."</font>")    
      --  envoi mail
      fibaro:call(2, "sendEmail", "Alerte plante "..name, "Arroser "..name)  
      -- met à jour la variable DateAlerte
      fibaro:setGlobal("DatePlante"..id, CurrentDate)        
    else --déjà notifié
      print("<font color='yellow'>"..name.." : déjà notifié".."</font>")
    end
      
  else -- Hum est ok = icone OK
    fibaro:call(id, "setProperty", "currentIcon", IcoOK)
  end    
end

-- NotUsed********************************************************************
-- utlisé quand un capteur/plante n'est plus actif

function NotUsed(id)
  fibaro:call(id, "setProperty", "ui.Up.value", "Not Used")
  fibaro:call(id, "setProperty", "log", "Not Used")
  fibaro:call(id, "setProperty", "logTemp", "TxtGreen")
  fibaro:call(id, "setProperty", "currentIcon", 1)
end

--MAIN**********************************************************************

if Trigger.type == "property" then
  --trouve le nom du VD déclencheur
  NameID = api.get("/devices/"..Trigger.deviceID).name
  
  --test la présence de la VG (créé si pas le cas)
  TestGlobal(Trigger.deviceID)
  
  --si plante active on met à jour le VD
  if Liste[Trigger.deviceID].active == 1 then -- si la plante/capteur est actif
    UpdateVD(Trigger.deviceID, NameID, Liste[Trigger.deviceID].IcoOK, Liste[Trigger.deviceID].IcoNOK)
  else --sinon (capteur pas utilisé)
	NotUsed(Trigger.deviceID)
  end  

elseif Trigger.type == "other" or Trigger.type == "autostart" then  
  --pour chaque élément de la liste
  for id, _ in pairs(Liste) do
    NameID = api.get("/devices/"..Liste[id].id).name --trouve le nom du VD
    TestGlobal(Liste[id].id)
  
    if Liste[id].active == 1 then -- si la plante/capteur est actif
      UpdateVD(Liste[id].id, NameID, Liste[id].IcoOK, Liste[id].IcoNOK) --appel de la fonction avec l'ID et le nom   	
    else --sinon (capteur pas utilisé)
	  NotUsed(Liste[id].id)
    end  	
  end

end

Voici le debug : :60:

 

debug.png.4c57b650a8afa1e149b9557c49af94eb.png

 

Explication :

 

Cette scène est lancée à chaque changement d'un label d'un VD (Déclaré dans les Trigger). Donc lorsque le script Jeedom est exécuté (toutes les 29 minutes).

Bien entendu si les données de la plante ont changé !!

Elle est aussi lancée au démarrage de la HC2 (%%autostart) avec son bout de code qui va bien dans la section Main.

 

Je passe par une variable "liste" sous forme de tableau pour faciliter l'écriture du code.

Cette variable, contient l'ID des VD des plantes, l'ID des icônes OK / NOK ainsi que le paramètre "active" (voir fonction NotUsed).

 

Après avoir récupéré le nom de la plante (nom du VD – section Main), je teste l'existence des VG nécessaires.

 

Fonction TestGlobal() :

 

VG HumPlante = consigne d'humidité

VG DatePlante = date de la dernière notification d'alerte (pour avoir qu'une seule alerte par jour en cas de besoin d'arrosage, et non à chaque mise à jour du label du VD)

 

Si les 2 variables, HumPlanteXXX et DatePlanteXXX (où XXX est l'ID du VD), n'existent pas, elles sont créées avec comme valeur par défaut : 20 pour HumPlante et "" DatePlante.

Donc en tout ça fait 2 VG par plantes (soit pour moi actuellement 24 VG…)

 

Fonction UpdateVD() :

 

Rien de particulier sur cette fonction.

Elle décode le contenu Json du label "FromJeedom" et envoie les données dans chaque label du VD.

D'où l'importance d'avoir nommé les labels (Hum, Frt, Bat, …).

Quand la fonction arrive au label "Hum", une fonction Alerte est appelée.

 

Fonction Alerte() :

 

Simple, si le taux d'humidité est inférieur à la consigne, alors  je change l'icône du VD (ID mémorisé dans la variable "Liste") et je vérifie le VG DatePlanteXXX.

Si j'ai la même date qu'aujourd'hui dans la VG, c'est que l'alerte a déjà été faite.

Sinon je créé l'alerte par mail et met à jour la date dans la VG.

Vous aurez compris que les alertes tombent la nuit essentiellement ^_^

 

Fonction NotUsed() :

 

Cette fonction permet de désactiver un VD (plante qui meurt, ou capteur HS).

Il suffit de mettre 0 dans le paramètre "active" de la variable Liste.

 

4. Conclusion :

 

Ce système fonctionne très bien depuis plusieurs mois.

L'interaction Jeedom->HC2 ne pose pas de problème.

On connait la stabilité de la HC2... je dois dire que Jeedom est assez stable aussi.

De temps en temps, une antenne (local ou supplémentaire) bluetooth perd la boule, alors un petit reboot de la Jeedom est nécessaire.

 

Lors de j'ajout d'une plante :

  • Je commence par intégrer le capteur dans Jeedom.
  • Ensuite j'ajoute le requête au script.
  • Ensuite je crée les icones :13:
  • Puis je crée le VD dans la HC2 (je duplique simplement un existant en modifiant les icones)

(le VD ne fonctionnera pas tout de suite car les VG ne sont pas encore crées...)

  • Et pour finir j'ajoute dans la variable "liste" de la scène une ligne identique aux autres avec le nouvel ID du nouveau VD et les nouvelles icones.
  • et c'est parti...:60:

 

A cause du nombre de plantes, donc de requêtes effectuées par le script Jeedom, j'ai de temps en temps une alerte sur la HC2 qui me dit "Too many instance" de la scène Mi-Flora (pourtant réglé avec le nombre d'instance max soit 10).

Cela est normal car si j'ai 11 plantes qui changent leurs données en même temps, cela fait 11 lancements de scène !!!!

Pour régler ce problème, je vais diviser mon script Jeedom en 2 (le lancement différé de la requête (paramètre Timeout) ne semble pas fonctionné).

Soit 6 requêtes par script et décaler le moment exécution vers la HC2.

De cette manière jamais j'aurai plus de 10 requêtes envoyées en une fois à la HC2, donc jamais plus de 10 scènes exécutées simultanément.

 

Je n'exploite pas les autres données (Fertilisant, Température, …)

 

Attention aux plantes dans les grands pots (le capteur ne plonge pas jusqu'en bas !!!).

Du coup, je règle la consigne d'humidité dans les VD à l'usage (entre 20 et 25%).

Cela m'a permis de me rendre compte qu'une plante était en excès d'eau (80 % d'humidité).

Je ne l'ai plus arrosé depuis des semaines… le taux baisse petit à petit, et la plante se porte de mieux en mieux.

 

EDIT :

Pour les intéressés :

  • voici le VD à télécharger : (il suffit de renommer son nom et de mettre les bons ID des icones.)  :   Bambou.vfib
  • et la scène : (mettre à jour l'ID du VD et des icones)   :  Scene-36-ID199-MiFLora.txt

 

  • Les icones de mes plantes sont dans une galerie    :    Galerie Plantes Vertes (je la compléterai petit à petit)
Modifié par jjacques68
voir les EDIT
  • Upvote 5

Partager ce message


Lien à poster
Partager sur d’autres sites

Yop nickels, ça il me le faut et vite. Mais semaine dernière, quand j'ai cherché ces capteurs, j'ai pas trouvé la version internationale de dispo... tu as qques liens ?

Partager ce message


Lien à poster
Partager sur d’autres sites

D'ailleurs faudra que je passe sur Cernay voir ça chez toi directement :)

Partager ce message


Lien à poster
Partager sur d’autres sites

cela fonctionne pour des plants de canabis ?
je déconne bon travail au moins un alsacien qui joue avec le lua pas comme@nico

Envoyé de mon SM-G901F en utilisant Tapatalk

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Sacré Lorrain :)

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

@Nico avec plaisir si tu passes dans le coin :) 

 

voilà oú j'ai acheté mes derniers : 

 

https://www.aliexpress.com/item/Original-Xiaomi-Mi-Flora-Monitor-Digital-Plants-Grass-Flowers-Soil-Water-Light-Smart-Tester-Sensor-with/32741431283.html

 

compter quand même trois semaine...

mais c'est le meilleur tarif ces derniers temps.

 

une fois j'ai pu en commander 4 sur Amazon à 9 € :) mais c'est plus jamais arrivé...

 

Partager ce message


Lien à poster
Partager sur d’autres sites

Bon bah voilà, j'ai pris sur ton lien :)

Maintenant il me faut ta clef Bluetooth, tu conseilles laquelle par exemple ?

Partager ce message


Lien à poster
Partager sur d’autres sites

Et pour me simplifier la vie, il y a moyen qu'en fin de topic tu nous mettes directement le VD en téléchargement en exportant un des tiens et si possible aussi tes icônes de plantes, j'en ai plusieurs communes avec toi :)

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Pour les icônes je pense mettre ça dans une galerie... c'est possible ou il faut des droits spécifiques ?

Partager ce message


Lien à poster
Partager sur d’autres sites

Non, tu peux, et tu mets le lien en bas du premier post ci dessous avec l'export du VD, comme sur les autres tutos.

 

Clef aussi commandé chez Lextronic :) Bon, va falloir que je regarde comment intégrer tout ça dans mon Jeedom de test...

Partager ce message


Lien à poster
Partager sur d’autres sites

Je pensais mettre Jeedom sur mon NAS mais faut une version 64bits. Snif.

Partager ce message


Lien à poster
Partager sur d’autres sites

Ou la je ne pourrais pas t'aidé la-dessus.

Moi la jeedom smart ne me sert que pour le bluetooth.

 

je n'y connais pas grand chose de cette box. Je préfère la HC2...

j'ai jamais mis vraiment les mains dedans...

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Oui mais 250€ pour arroser mes plantes bof bof.

Quoi d autres en Bluetooth ?

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Bah moi j'ai aussi mon Jeedom sur un NAS pour le moment... Mais bon c'est un docker, pas sûr la clef fonctionne, je verrai bien. Sinon il faudra que je presque le truc de barbu, un rasp pfffff....... :)

Partager ce message


Lien à poster
Partager sur d’autres sites

Du gros gros boulot !!!! Felicitations. Ça me donne envie de mettre plein de plante :-)
Pour la clé sena je crois qu'il y en a aussi sur ebay mais elle a l'air dur a trouver.
La différence de prix des mi-flora est juste incroyable :-) .
Ça conforte jeedom en passerelle :-)


Envoyé de mon Nexus 5X en utilisant Tapatalk

Partager ce message


Lien à poster
Partager sur d’autres sites

@Nico tu n'as pas un vieux portable que tu pourrais recycler pour Jeedom ? Sur le nas tu vois les usb depuis le docker?

Envoyé de mon Nexus 5X en utilisant Tapatalk

Partager ce message


Lien à poster
Partager sur d’autres sites

Aucune idée, j'ai jamais regardé, je verrai bien, cela m'arrangerai.

Sinon si j'ai des vieux portables, mais si je peux éviter de démultiplier les trucs...

Partager ce message


Lien à poster
Partager sur d’autres sites

×