Aller au contenu
vravolta

Comment créer un child device de type IP camera

Recommended Posts

Histoire de me familiariser avec la question des child devices dans les quick apps, je me suis dit qu'un bon sujet de travail serait ma camera Netatmo Presence. A ce jour, elle est d'un coté déclarée sur ma HC3 comme une camera IP et de l'autre, comme une lumière vu que je peux en piloter l'allumage du projecteur.

J'avais pour idée de créer une quick app pour un device parent à qui je fournis l'adresse IP de la camera et mon username/password Netatmo et que ce dernier me crée en device child, le device de type lumière (qui lui même est une quick app que j'ai déjà développée) et le device de type camera avec les bons paramètres remplis grace au travail du quick app parent qui irait chercher dans l'API Netatmo les bonnes valeurs. 

Sauf que voila, j'ai beau chercher de partout, je ne trouve à aucun moment d'exemple de code qui ajouterait une camera IP en device child d'une quick app. J'ai des exemples pour des sondes de température, des switches, mais jamais de camera. Quelque a t il une idée de comment faire?

Partager ce message


Lien à poster
Partager sur d’autres sites

Pour te "familiariser", tu as choisi un sujet bien complexe... le chalenge est élevé !

 

Déjà le type ipcamera ne fait pas partie des types officiellement supportés pour les QuickApps :

/api/quickApp/availableTypes

Mais ça ne veut pas dire que c'est impossible... on a déjà réussi à créer des enfants d'un type qui n'étaient pas dans la liste.

 

Dans la hiérarchie des devices, on retrouve bien le type ipcamera :

/api/devices/hierarchy

Donc tu peux toujours tenter de forcer le type ipcamera pour ton child.

 

Mais après... comment créer le visuel de la caméra, afficher l'image, etc... alors là je n'en ai aucune idée.
 

Partager ce message


Lien à poster
Partager sur d’autres sites

OK, donc concrètement, il n'est pas juste possible de faire qu'une quick app parent puisse générer un enfant d'un type fibaro pourtant proposé dans la liste des devices et de juste en paramétrer correctement les variables pour qu'il fonctionne? Car mon but n'est pas de réécrire une quick app qui réplique le type ipcamera de fibaro, juste de réutiliser ce type en lui remplissant les paramètre pour que ca fonctionne, paramètre qui eux même sont communs avec la lumière. Autre possibilité: est ce que je pourrais avoir une ipcamera en parent et créer une device de type lumière qui serait son enfant et hériterait de ses paramètres?

Partager ce message


Lien à poster
Partager sur d’autres sites

Je me suis mal exprimé.

Lorsque tu crées un child device depuis un QuickApp parent, en théorie tu dois utiliser les types officiellement listés dans /api/quickApp/availableTypes
En pratique, tu peux utiliser le type que tu veux parmi l'ensemble de ceux disponibles dans /api/devices/hierarchy

 

Cependant, après c'est à toi de coder (en LUA) toute la logique de fonctionnement.

 

Du coup... je ne comprends pas la suite de ta demande.

Si tu veux réutiliser un type donné, il faut quand même que tu codes toute la logique, tu ne peux pas juste "réutiliser" le code existant d'un module proposé par défaut dans le système.

 

Partager ce message


Lien à poster
Partager sur d’autres sites

Alors l'idée, c'est de créer un QA qui va attaquer l'API Netatmo pour récupérer les infos de connexion = le token d'accès à la camera. A partir de là, le QA saurait générer l'adresse d'accès à la camera tant pour les images que pour la commande de la lumière. Et il aurait en fils 2 devices: une camera IP dont il aurait juste rempli automatiquement les paramètres et une QA que j'ai déjà codé, qui est de type lumière et se comporte en pratique exactement comme n'importe quelle lumière pilotée par un module Fibaro. Je ne veux en aucun cas toucher ou répliquer un code de device standard qui existe déjà, juste créer ce device et lui fixer les bons paramètres. Pour le dire autrement, aujourd'hui, j'ai un device IP camera avec des paramètres inintelligibles et un device QA qui se comporte comme une lumière, avec les mêmes paramètres inintelligibles que la camera IP. Et demain, je voudrais arriver à une situation où j'ai un QA parent à qui je donne des paramètres compréhensibles d'un humain = concrètement, un username et un password. Et lui il fait tout le job fastidieux d'attaquer l'API pour obtenir les paramètres inintelligibles et les passe à un QA fils et un device IP camera fils.

 

Autre manière de voir la chose, il me faudrait trouver comment créer avec du code LUA un device IP camera (pas grave s'il n'est pas fils) et une fois créé, lui fixer ses paramètres (= la valeur de certaines de ses variables, son nom, sa pièce, etc.). Si j'ai ca, je comprends que faire de ma QA qui gère la lumière une QA fille de la QA qui va chercher les paramètres inintelligibles ne devrait pas poser de soucis et donc que j'aurai atteint mon but.

Partager ce message


Lien à poster
Partager sur d’autres sites
il y a 39 minutes, vravolta a dit :

une camera IP dont il aurait juste rempli automatiquement les paramètres

c'est ça qui ne va pas.
C'est à toi de coder le device enfant.
Comme dit, tu ne peux pas "cloner" un device existant.

 

Partager ce message


Lien à poster
Partager sur d’autres sites

Et si on oublie le coté parent enfant et qu'on parle d'un QA qui créerait un device standard avec du code LUA, c'est impossible? 

Et si c'est possible, est ce qu'il est possible depuis un QA de modifier les variables d'un device existant?

Partager ce message


Lien à poster
Partager sur d’autres sites

Si c'est le principe, ton QA parent crée un QA enfant, avec du code LUA.
 

Depuis un QA, une scène, ou depuis l'extérieur de la box même, tu peux modifier les variables de n'importe quel QuickApp, car tout passe par l'API HTTP REST.

Il y a plusieurs discussion à ce sujet sur le forum; par exemple :

 

 

 

Partager ce message


Lien à poster
Partager sur d’autres sites

Oui, mais vu qu'en pratique il est très hors de ma portée de créer un QA qui réplique le device IP camera, le fait de pouvoir modifier des variables d'un autre QA n'a du coup pas vraiment d'intérêt. Donc cette piste doit être abandonnée. Et du coup la question, c'est de savoir si du LUA peut créer des devices (qui donc ne sont pas des QA) au même titre qu'il est possible de le faire manuellement dans la box en cliquant sur ajouter un appareil puis en choisissant IP camera comme type d'appareil (et donc pas QA). Dans la liste qui apparait, on voit que camera IP est à coté de QuickApp = c'est de nature différente, ca j'ai compris désormais. Mais est ce qu'un QA peut créer autre chose que des QA, c'est la question que je me pose.

Partager ce message


Lien à poster
Partager sur d’autres sites

Je pense que oui, encore une fois tout passe par l'API HTTP, donc il "suffit" de regarder comment fait l'interface Web pour reproduire avec du LUA.

Utiliser pour cela les outils de développement du navigateur Web, accessibles avec F12.

Partager ce message


Lien à poster
Partager sur d’autres sites

Donc si je comprends bien, l'idée c'est de mettre en place une manière de "sniffer" ce que fait le navigateur quand je crée manuellement une quickapp ipcamera puis lui set ses variables. Je vais obtenir des calls à l'API HTTP de ma HC3 et donc en répliquant ces calls via net.HTTPclient en lua, je devrais obtenir du code lua de création d'une ipcamera ainsi que de set de ses valeurs.

 

En tout cas, j'en profite pour te dire un grand merci pour tes réponses: je découvre le monde de la domotique qui m'a l'air vraiment prometteur car un nombre affolant de choses peuvent y être intégrées et une fois qu'on a tout concentré sur une seule plateforme, c'est que du bonheur à faire interagir. Certes, il faut tâtonner car c'est loin d'être 100% plug & play, mais ca ouvre un paquet de possibilités.

 

J'ai en parallèle plein de projets dont le plus lourd sera certainement le fait de ne pas juste monitorer mon onduleur via son API mais d'en modifier les paramètres, ce qui se fait via modbus tcp et donc un layer plus bas que le HTTP où on se retrouve à aller lire directement des octets dans des registres pour créer en lua la couche supplémentaire qui manque.

Partager ce message


Lien à poster
Partager sur d’autres sites

Voilà, tu as compris le principe :)

 

Oui la domotique c'est fantastique, tout ce qu'on peut faire avec :D

 

Pour Modbus, je n'ai jamais touché à ce protocole; mais ce sera surement en forgeant les paquets en TCP (ou UDP ?).

Il y a des fonctions LUA pour ça, mais c'est encore plus délicat à manipuler, car c'est une succession d'appels de fonctions asynchrones.

Il vaut mieux se familiariser avec des QuickApps faciles avant d'attaquer des sujets aussi complexes.

Partager ce message


Lien à poster
Partager sur d’autres sites

Alors j'arrive désormais bien à communiquer via le Modbus TCP de ma batterie et donc j'attaque la partie interface maintenant que le code de communication TCP fonctionne. Et je bute sur 2 types de soucis:

- je n'arrive pas à faire un bêtre truc = un bouton sur lequel il est écrit initialement "Connect" et qui quand je clique dessus me connecte puis affiche "Disconnect" pour que le prochain appui lance non pas une connexion mais une déconnexion. J'ai essayé naivement le code suivant, mais ca ne fonctionne pas:

function QuickApp:BtnConnectClick(event)
    local btnName = event.elementName
    if btnName.text =="Connect" then
       self:connect()
        self:updateView(btnName, "text""Disconnect")
    else -- Disconnect
       self:disconnect()
       self:updateView(btnName, "text""Connect")
    end
end
 
Autre problème sans doute hyper basique: autant, quand je suis dans le contexte de la lecture des messages Modbus, c'est simple d'afficher les valeurs lues dans un "Label", autant, je n'ai pas trouvé de manière de récupérer ces valeurs en dehors du contexte. Donc typiquement, je vais chercher des paramètres comme le niveau de charge max toléré par la batterie, je les affiche dans un label, c'est tout OK. Autant, si après, lors d'une autre connexion, je veux calculer 80% de cette valeur pour mettre à jour les paramètres de charge de ma batterie, je n'ai rien trouvé de raisonnable pour récupérer cette valeur à part déclarer une variable globale dans l'onglet variable de ma QuickApp, la remplir puis la lire. C'est moche car on parle de données hypertechniques que l'utilisateur ne devrait pas avoir à voir dans sa liste de variables et encore moins pouvoir éditer ou changer. Donc en gros, ce dont j'aurais besoin, c'est d'un variable globale accessible depuis n'importe quel contexte de mon main mais qui n'apparaisse pas dans l'onglet variables.
 
Et à terme, il me faudrait la possibilité de faire que depuis une autre QA, je puisse récupérer ces variables et les mettre à jour pour que depuis toute QA, je puisse savoir quel est le courant de charge de la batterie et le modifier s'il ne me plait pas. Donc en quelque sorte, faire l'équivalent d'une API pour mon QA.

Partager ce message


Lien à poster
Partager sur d’autres sites

I've kind of workarrounded the thing by using a global value to bypass my incapacity to get the caption value of my button with this. I find this dirty, but at least, it works. And don't ask me why, but the first code was not actually updating the caption on my screen, the second one is. That's really a mystery to me:

function QuickApp:BtnConnect(event)
    local btnName = event.elementName
    if self.ConnectStatus == "Disconnected" then
        self:connect()
        self.ConnectStatus = "Connected"
        self:updateView(btnName, "text""Disconnect")
    else -- Disconnect
        self:disconnect()
        self.ConnectStatus = "Disconnected"
        self:updateView(btnName, "text""Connect")
    end
end

Partager ce message


Lien à poster
Partager sur d’autres sites

Et je continue de me répondre à moi même: je pense qu'il y avait un souci avec ma box en connexion à distance car en me connectant en local dessus, ca fonctionne sans souci avec les variables globales. J'ai au passage découvert que je pouvais me passer le contexte parent quand j'exécute une sous fonction et que je pouvais alors updater les variables globales du parent plutot que celles du "self" dans lequel je me trouve. En fait, il faut faire attention à ne pas se mélanger les pédales entre tous les self qui sont le contexte le plus bas dans lequel on se trouve, mais il est possible de faire référence, pour peu qu'on s'en soit transmis les valeurs, aux selfs parent.

Partager ce message


Lien à poster
Partager sur d’autres sites

Tellement de questions... sans raccord avec le sujet du topic.

Difficile de suivre ;)

Tu devrais ouvrir un nouveau sujet pour chaque thème abordé... ou poser tes questions sur des topics déjà existants, car tous ces sujets ont déjà été traités.

 

En vrac :

 

Un label c'est fait pour afficher une info pour l'utilisateur, mais pas pour stocker une information (car le label est non persistant = sa valeur est perdue en cas de redémarrage du QA). Partant de là, lire un label n'a aucun sens (même si c'est quand même possible)

Pour stocker une info en mémoire non persistante, tu as les variables LUA (local, globale, membre d'une table self, etc), ou bien les variables du QA (dans l'onglet dédié), ou encore les propriétés du QA (exemples : value, power, energy, batterylevel, etc). Enfin il existe les variables globales de la HC3, assez peu utilisées depuis qu'on peut stocker des variables au niveau des QA directement.

 

La portée des variables en LUA, ou plus généralement dans n'importe quel langage de programmation, est un concept à bien maitriser pour ne pas avoir de mauvaise surprise
Il y a déjà 1 ou 2 topics à ce sujet sur le forum.

 

Pour enchainer les connect/transmit/receive/disconnect, il faut manier les appels asynchrones de fonction. Pas évident à appréhender, et certainement l'un des aspects les plus complexes de la programmation LUA sur HC3.

 

Partager ce message


Lien à poster
Partager sur d’autres sites

Alors en fait, j'avais bien compris le fonctionnement des variables et de l'histoire du contexte, mais pour une raison que j'ignore, ca ne fonctionnait pas comme ca devait en théorie. C'est pour ca que j'ai essayé de passer par les labels. Pui en me reconnectant en local plutot qu'à distance, le même code non modifié, qui ne fonctionnait pas, s'est mis à marcher, me confirmant que ma compréhension initiale des contextes était la bonne.

Je dois avoir un truc sur ma configuration car de même, quand j'ai tenté la mise à jour de ce weekend, ca a tout planté et j'ai du restaurer depuis ma sauvegarde.. Après, vu toutes mes bidouilles de dev en ce moment où je ne suis pas certain que tous les sockets que j'ouvre sont fermés, etc., je pense que ca peut expliquer des comportements anormaux.

Partager ce message


Lien à poster
Partager sur d’autres sites

Attention aux mises à jour en beta, surtout celle de ce week-end, elle est bien buguée et a été retirée par Fibaro.

 

Partager ce message


Lien à poster
Partager sur d’autres sites

×