Aller au contenu
jjacques68

Filtrer les devices via l'API

Recommended Posts

Bonjour à tous, 

 

Je commence ce topic afin de recenser les différentes manières de filtrer les device de nos box.

Je suis entrain de tester cela depuis une HC3, donc je ne peux pas confirmer que cela fonctionne sur une HC2...

 

Pour se faire, on utilise : 

MaListe = fibaro.getDevicesID({filter})

on aura donc la liste des ID des device trouvés.

 

il existe une autre méthode avec :

MaListe = api.get(/devices/?...)

dans ce cas, on aura un retour JSON avec tout le contenu des propriétés des device.

On choisira l'un ou l'autre suivant l'usage.

 

Dans mon cas, je me suis rendu compte que j'utilisais très souvent api.get(), juste pour avoir la liste des ID !

Donc pas du tout cohérent, vu qu'on a pas besoin de récupérer la totalité des propriétés !

 

Pour les exemples suivant, je me sers de l'API d'un device, que j'ai copié dans NotePad++ afin de visualiser le JSON plus facilement (voir les captures futures)

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Donc je me lance

 

un exemple tout simple :

 

lister les device visible :

 

dans l'API on trouve la propriété "visible" : 

 

image.png.33613391f20c5f141000041019494db5.png

 

 

donc : 

MaListe = fibaro.getDevicesID({visible=true})

me retourne la liste des ID de TOUS les device visible

 

on peut cumuler des filtres :

 

par exemple je veux les visibles de type lumières :

ListeDevice = fibaro.getDevicesID({visible=true, properties={isLight=true}})

là, la syntaxe est étrange car on descend dans l’arborescence des propriété des device :

 

image.png.4994ba7c43dc880df1398ef2bd392f73.png

 

Modifié par jjacques68
  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

On peut également filtrer sur le type d'interface

377374604_Sanstitre.png.48ff639afa17996a03778d54532b5733.png

 

ListeDevice = fibaro.getDevicesID({interfaces ={"light"}})

 

Ici la syntaxe change encore, car on filtre sur un élément d'une sous-table : "interfaces".

 

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

question : comment fait-on pour filtrer sur cette rubrique "categories", qui est un tableau 

 

image.png.8ad53a1e497fe58ced21883e4de9824c.png

 

j'ai essayé sans succès

ListeDevice = fibaro.getDevicesID({properties={categories={"lights"}}})
ListeDevice = fibaro.getDevicesID({properties={categories,"lights"}})
ListeDevice = fibaro.getDevicesID({properties={categories="lights"}})
ListeDevice = fibaro.getDevicesID({properties={categories[1]="lights"}})

 

 

?????

 

Modifié par jjacques68

Partager ce message


Lien à poster
Partager sur d’autres sites

Déjà pour tester tu pourrais mettre uniquement l'URL de l'API dans ton navigateur, plutôt que de passer par le code LUA

En plus ça faciliterait la lecture, parce que là, "listeDevice = fibaro.getDevicesID(...." je suis désolé mais c'est inutile et illisible en l'état.

 

Exemple :

/api/devices?interface=quickApp

Là c'est clair, et on peut directement l'utiliser dans un navigateur ou dans un code LUA avec api.get()

 

Enfin ce n'est que mon avis... :)

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

pas bête, mais y a des subtilité entre l'URL et la fonction : 

 

"properties" devient "property"

"interfaces" devient "interface"

 

ils ont tout mis au singulier on dirait...

 

Ducoup je suis resté sur les fonctions pour avoir le même "texte" que ce que l'on voit dans le JSON !

Modifié par jjacques68

Partager ce message


Lien à poster
Partager sur d’autres sites

Le souci c'est que tu utilises getDevicesID () et non pas api.get() qui elle, utilise bien la même syntaxe

 

Tu devrais déjà utiliser la "vraie" API officielle(*), et ensuite quand ton filtre fonctionnera, t'attaquer à la conversion en langage accepté par getDevicesID, ça me semblerait plus cohérent comme démarche

 

(*) même si elle n'a d'officielle que le nom, tellement est la mal documentée

Partager ce message


Lien à poster
Partager sur d’autres sites

À bon tu es sur. Je vais regarder cela en rentrant

PS@lazer à répondu entre temps

Oui pour l'api c'est bien api.get qu'il faut utiliser

 

Envoyé avec Tapatalk

 

 

 

 

Partager ce message


Lien à poster
Partager sur d’autres sites

ben j'essaye de faire ça avec api.get() :

 

/api/devices?property={category="lights"}}}

retour : rien :( 

Modifié par jjacques68

Partager ce message


Lien à poster
Partager sur d’autres sites

Et bien voilà, bel exemple, tu as réussi à t’embrouiller à cause de getDevicesID() et ses accolades ;)

 

Je t'avais donné des exemples sur l'autre topic, les revoici, pour t'inspirer de la syntaxe, donc avec des crochets dans ton cas :

 

/api/devices?visible=true                          returns devices with visible equal to 'true'
/api/devices?property=[batteryLevel,100]           returns devices with property batteryLevel equal to 100
/api/devices?property=[unit,%CE%BCg/m3]            returns devices with unit equal to µg/m3
/api/devices?interface=light                       returns devices with light interface
/api/devices?type=com.fibaro.netatmoWeatherStation returns Netatmo Weather Station
/api/devices?baseType=com.fibaro.weather           returns Weather plugins
/api/devices/?property=isLight
/api/devices?interface=zwave&parentId=1

 

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Il doit avoir des liens de parenté avec@nico
Comme je t'ai déjà dis il faut être méthodique
Ça ne sert à rien de mettre la charrues avant les bœuf
J'ai l'impression que tu foncés et que tu réfléchis après

Envoyé avec Tapatalk

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

:2::2::2:C'est l'hôpital qui se fout de la charité :2::2::2:

  • Like 2
  • Haha 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Pfff moi je suis pas comme cela

Envoyé avec Tapatalk

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

nan mais les gars, je suis pas allé trop vite !

vous avez lu le premier post ?

 

je cherche à filtrer les device dans une simple liste !

pas à obtenir tout leur contenu JSON !

 

api.get() = tu récupères toutes les propriété des device selon ton filtre

fibaro.getDeviceID() = tu récupères que la liste des ID selon ton filtre

 

@Lazer : les [] fonctionnent bien, mais pas sur la proriété "category", suis entrain de me demander si on est pas limiter dans l'arborescence...

le problème c'est qu'on descend un cran plus bas...

 

 

Partager ce message


Lien à poster
Partager sur d’autres sites

Tiens, c'est cadeau :D

/api/devices?property=[categories,["lights"]]

Donc on peut descendre assez profondément dans le filtre.

 

Je te laisse convertir ça à la sauce getDeviceID() :)

Partager ce message


Lien à poster
Partager sur d’autres sites

Remarque, dans ce cas précis pour filtrer les lumières, il serait plus rapide d'utiliser le filtre suivant qui donne le même résultat, mais plus simplement :

/api/devices?property=isLight

 

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

nan mais je rève ! 

 

Je l'avais cette put... de syntaxe de m..., mais au lieu d'utiliser les " je mettais %27 !

 

et en fait %27 c'est pas les " mais '.

les " c'est %22 !

et en plus on est pas obligé de se faire chier avec les code ascii visiblement dans l'URL

nan mais quel boulet je suis !

 

merci tout plein !

 

  • Like 1

Partager ce message


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

Remarque, dans ce cas précis pour filtrer les lumières, il serait plus rapide d'utiliser le filtre suivant qui donne le même résultat, mais plus simplement :

oui on est tout à fait d'accord !

 

c'était pour l'exercice ! ;) 

 

attend maintenant je vais le transposer pour le getDeviceID(), va être marrant ça...

Partager ce message


Lien à poster
Partager sur d’autres sites

Voici le code de la fonction fibaro.getDevicesId() sur HC2 pour mieux comprendre ce qui se passe à l'intérieur :

 

fibaro.getDevicesId = function(self, filter)
    if type(filter) ~= 'table' or
        (type(filter) == 'table' and next(filter) == nil)
    then
        return fibaro:getIds(fibaro:getAllDeviceIds())
    end

    local args = '/?'
    for c, d in pairs(filter) do
        if c == 'properties' and d ~= nil and type(d) == 'table' then
            for a, b in pairs(d) do
                if b == "nil" then
                    args = args .. 'property=' .. tostring(a) .. '&'
                else
                    args = args .. 'property=[' .. tostring(a) .. ',' .. tostring(b) .. ']&'
                end
            end
        elseif c == 'interfaces' and d ~= nil and type(d) == 'table' then
            for a, b in pairs(d) do
                args = args .. 'interface=' .. tostring(b) .. '&'
            end
        else
            args = args .. tostring(c) .. "=" .. tostring(d) .. '&'
        end
    end

    args = string.sub(args, 1, -2)
    return fibaro:getIds(api.get('/devices' .. args))
end

 

et fibaro.getIds() dont elle dépend :

fibaro.getIds = function(self, devices)
    local ids = {}
    for _, a in pairs(devices) do
        if a ~= nil and type(a) == 'table' and a['id'] ~= nil and a['id'] > 3 then
            table.insert(ids, a['id'])
        end
    end
    return ids
end

Ainsi que fibaro.getAllDeviceIds() :

fibaro.getAllDeviceIds = function(self)
    return api.get('/devices/')
end

 

Leur code n'est pas vraiment optimisé car de toute façon il récupère bien le JSON complet des devices.

Je serais toi, j'utiliserais api.get() et je recoderais fibaro.getIds() directement dans mon code, ça ira plus vite :)

Avec quelques optimisations comme virer ce table.insert() monstrueux (comme discuté sur un autre topic, c'est l'une des instructions les plus lentes en LUA)

cf : https://springrts.com/wiki/Lua_Performance#TEST_12:_Adding_Table_Items_.28table.insert_vs._.5B_.5D.29

 

Modifié par Lazer
  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

et voici la propriété "categories" avec getDeviceID() :

 

ListeDevice = fibaro.getDevicesID({visible=true, properties={categories='["lights"]'}})

oui @Lazer, je suis d'accord avec toi, ça fait mal aux yeux :P

 

Mais là j'ai que les ID ;) 

Partager ce message


Lien à poster
Partager sur d’autres sites

Regarde mon post au dessus, et surtout la fin, j'ai édité entre-temps.

Moi je referais le code complet, je suis certain que tu peux gagner en performance.

Partager ce message


Lien à poster
Partager sur d’autres sites

tu parles de la fonction sur HC2 ?

 

parce que c'est ce que semble faire le getDeviceID() sur la HC3 !

 

on peut pas refaire son code !? si ?

Partager ce message


Lien à poster
Partager sur d’autres sites

Tu fais le code que tu veux....

Moi je reprendrais leur code, et je l'améliorerai (virer ce qui est inutile, et optimiser les instructions trop lentes)

 

Après tu as le choix, soit tu surcharges fibaro.getDeviceID() (suffit d'appeler ta fonction pareil), ou alors te créer une autre fonction dans ton toolbox (très pratique en plus maintenant avec les fichiers dans les Quickapps)

Partager ce message


Lien à poster
Partager sur d’autres sites

×