-
Compteur de contenus
351 -
Inscription
-
Dernière visite
-
Jours gagnés
20
Tout ce qui a été posté par Barelle
-
Scène pour afficher l'utilisation des variables globales Références croisées (xref) Lorsque les développements prennent une certaine ampleur, et en absence d'atelier de développement logiciel, il est utile de de pouvoir rapidement identifier quel morceau de code utilise telle variable (globale dans le cas de la HC2). Ce sujet avait déjà été abordé il y a maintenant quelque temps : Je vous en propose une nouvelle version qui permet : D'obtenir pour chaque variable globale les scènes et VD qui en font usage ; Pour chaque scène et pour chaque VD d'avoir la liste des variables globales utilisées (c'est cela qui est nouveau). Voici un exemple des résultats affichés dans le fenêtre de debug : La scène est un peu longue lors de son exécution, je suis preneur d'idées d'algorithmes plus optimisés. Le code de la scène : --[[ This scene is used to list all the global variables and where they are used. It's a kind of xref. -- 07/02/2017: creation -- 24/10/2019: add scene and virtual devices --]] local startTime = os.time(); local globalVariables = api.get("/globalVariables"); -- Get all globals variables local scenes = api.get("/scenes?type=com.fibaro.luaScene&isLua=true"); -- all the scenes local devices = api.get("/devices?type=virtual_device"); -- and all the virtual devices since for others types there is no lua code function round(num, numDecimalPlaces) return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", num)); end -- round function progressBar(progressPct, length) if length ~= nil or length == 0 then length = 20; end progressPct = math.abs(progressPct); progressPct = math.min(progressPct, length); return ' [' .. string.rep("*", progressPct) .. string.rep("_", length - progressPct) .. '] '; end -- progressBar fibaro:debug('<font color="Gold">Analyzing lua code for ' .. #globalVariables .. ' global variables, ' .. #scenes .. ' scenes, ' .. #devices .. ' virtual devices, this may take a while.</font>'); -- Where each global variable is used local txt = '<BR><font color="yellow">'.. string.rep('=', 80) .. '<BR>Globals variables ' .. os.date("%d/%m/%y %X") .. '</font><BR>'; local cnt = 0; for _, glob in pairs(globalVariables) do -- For each global variable txt = txt .. '<BR><font color="Orange">Global variable "' .. glob.name .. '":</font>'; cnt = cnt + 1; local used = false; for _, s in pairs(scenes) do -- For each scene local scene = api.get("/scenes/" .. s.id); if scene.triggers.globals ~= nil then for _, g in pairs(scene.triggers.globals) do -- We look each trigger if (g ~= nil) and (g == glob.name) then txt = txt .. '<BR><font color="lightgreen">   - trigger in scene "' .. scene.name .. '" (id:' .. scene.id .. ')</font>'; used = true; end end end -- Lua code inspection if (scene.lua ~= nil) and (string.find(scene.lua, glob.name) ~= nil) then txt = txt .. '<BR><font color="Chartreuse">   - used in scene "' .. scene.name .. '" (id:' .. scene.id .. ')</font>'; used = true; end end -- for _, s in pairs(scenes) for _,device in pairs(devices) do -- For each virtual device if (device.properties.mainLoop ~= nil) and (string.find(device.properties.mainLoop, glob.name) ~= nil) then -- look in mainloop txt = txt .. '<BR><font color="DeepSkyBlue">   - used in VD "' .. device.name .. '" mainloop</font>'; used = true; end local rows = device.properties.rows; -- look in buttons for _, row in pairs(rows) do if (row.type ~= nil) and (row.type == "button") and (row.elements ~= nil) then for _,element in pairs(row.elements) do if (element.lua ~= nil) and (element.lua == true) then if (element.msg ~= nil) and (string.find(element.msg, glob.name) ~= nil) then txt = txt .. '<BR><font color="LightSkyBlue">   - used in "' .. element.name .. '" btn (id: ' .. element.id .. ') of "' .. device.name .. '" VD (' .. device.id .. ')</font>'; used = true; end end end end end end -- for _,d in pairs(devices) if not used then txt = txt .. "<font color='Magenta'> unused</font>"; end local progress = round((cnt / #globalVariables) * 100) if (progress % 5) == 0 then fibaro:debug('<font color="gray">working,' .. progressBar(progress/5, 20) .. tostring(progress) .. '% done in ' .. (os.time()-startTime) .. ' secondes.</font>'); end end txt = txt .. '<BR><font color="gray">Total memory in use by Lua (version '.._VERSION..'): ' .. string.format("%.2f", collectgarbage("count")) .. ' KB</font>'; txt = txt .. '<BR><font color="gray">Time for global variables: ' .. (os.time()-startTime) .. ' secondes.</font><BR>'; -- Global variables used by scenes local sceneTime = os.time(); txt = txt .. '<BR><font color="yellow">'.. string.rep('=', 80) .. '<BR>Global variables used by scene ' .. os.date("%d/%m/%y %X") .. '</font><BR>'; for _, s in pairs(scenes) do -- For each scene txt = txt .. '<BR><font color="lightgreen">Scene "' .. s.name .. '" (id:'.. s.id .. '):</font>'; local used = false; local scene = api.get("/scenes/" .. s.id); if scene.triggers.globals ~= nil then for _, g in pairs(scene.triggers.globals) do -- We look each trigger for _, glob in pairs(globalVariables) do -- For each global variable if (g == glob.name) then txt = txt .. '<BR><font color="Orange">   - global "' .. glob.name .. ' used as a trigger"</font>'; used = true; end end -- for _, glob end end -- Lua code inspection if (scene.lua ~= nil) then for _, glob in pairs(globalVariables) do -- For each global variable if (string.find(scene.lua, glob.name) ~= nil) then txt = txt .. '<BR><font color="Coral">   - global "' .. glob.name .. '" used</font>'; used = true; end end -- for _, glob end if not used then txt = txt .. "<font color='Magenta'> no global variable used</font>"; end end -- for _, s in pairs(scenes) txt = txt .. '<BR><font color="gray">Total memory in use by Lua (version '.._VERSION..'): ' .. string.format("%.2f", collectgarbage("count")) .. ' KB</font>'; txt = txt .. '<BR><font color="gray">Time for scenes: ' .. (os.time()-sceneTime) .. ' secondes.</font><BR>'; -- Global variables used by virtual devices local deviceTime = os.time(); txt = txt .. '<BR><font color="yellow">'.. string.rep('=', 80) .. '<BR>Global variables used by virtual devices ' .. os.date("%d/%m/%y %X") .. '</font><BR>'; for _,device in pairs(devices) do -- For each virtual device txt = txt .. '<BR><font color="DeepSkyBlue">Virtual device "' .. device.name .. '" (id:'.. device.id .. '):</font>'; local used = false; if (device.properties.mainLoop ~= nil) then -- look in mainloop for _, glob in pairs(globalVariables) do -- For each global variable if (string.find(device.properties.mainLoop, glob.name) ~= nil) then txt = txt .. '<BR><font color="Orange">   - global "' .. glob.name .. '" used in mainloop</font>'; used = true; end end end local rows = device.properties.rows; -- look in buttons for _, row in pairs(rows) do if (row.type ~= nil) and (row.type == "button") and (row.elements ~= nil) then for _,element in pairs(row.elements) do for _, glob in pairs(globalVariables) do -- For each global variable if (element.lua ~= nil) and (element.lua == true) then if (element.msg ~= nil) and (string.find(element.msg, glob.name) ~= nil) then txt = txt .. '<BR><font color="Coral">   - global "' .. glob.name .. '" used in btn "' .. element.name .. '" (id:' .. element.id .. ')</font>'; used = true; end end end end end end if not used then txt = txt .. "<font color='Magenta'> no global variable used</font>"; end end -- for _,device txt = txt .. '<BR><font color="gray">Total memory in use by Lua (version '.._VERSION..'): ' .. string.format("%.2f", collectgarbage("count")) .. ' KB</font>'; txt = txt .. '<BR><font color="gray">Time for virtual devices: ' .. (os.time()-deviceTime) .. ' secondes.</font>'; txt = txt .. '<BR><font color="gray">Total elapsed time: ' .. (os.time()-startTime) .. ' secondes.</font><BR>'; fibaro:debug(txt); Je vous propose l'icône que j'utilise et suis preneur d'une qui serait plus "artistique". A l'approche des frimas, je ne puis que conclure par un... Chaleureusement.
-
C'est le nœud Input http, paramétré Peut-être : if (msg.payload === "banana") { msg.payload = "53=ON"; return [ null, msg ]; } else { return [ msg, null ]; } Mais cela n'a rien avoir avec Node-red, c'est de la programmation toute bébête...
-
Pour compléter, voici un exemple de scène envoyant une donnée à la gauge, il ne reste qu'à l'adapter à tes besoins, notamment en changeant l'adresse du serveur Node-RED : --[[ %% autostart %% properties %% events %% globals --]] local urlNodeRed = "http://192.168.0.26:1880/HC2/Data/ModuleX"; -- Node-RED serveur local HTTPClientTimeout = 15000; function sendValueToNodeRed(payload) local nodeRed = net.HTTPClient(); nodeRed:request(urlNodeRed, { options = {method = 'PUT', data = payload, headers = {["content-type"] = "text/plain"}, timeout = HTTPClientTimeout}, success = function(response) fibaro:debug("sendValueToNodeRed>>>success, payload="..payload); end, error = function (err) fibaro:debug("sendValueToNodeRed>>>error:" .. err .. ", payload=" .. payload); if string.lower(err) == "operation cancelled" then HTTPClientTimeout = HTTPClientTimeout + 1000; fibaro:debug("sendValueToNodeRed>>>error:operation cancelled, increasing HTTPClientTimeout to " .. HTTPClientTimeout .. ", payload=" .. payload); else fibaro:debug("sendValueToNodeRed>>>error:" .. err .. ", payload=" .. payload); end end }); end -- sendValueToNodeRed value = tostring(5); sendValueToNodeRed(value);
-
Pour la gauge, il faut savoir d'où viennent les données, est-ce Node-Red qui interroge périodiquement la HC2 ou est-ce la HC2 qui envoie les données vers Node-Red. Pour activer le bouton, il faudra dans un VD ou une scène de la HC2 l'envoi des données vers Node-Red. Cela pourrait ressembler au schéma ci-après dans le cas ou la HC2 est à l'initiative des échanges.
-
Avec ce schéma cela fonctionne : Si après le changement d'état, aucun message n'est envoyé au bouton, il restera comme avant. L'important est le retour de Off vers Portail N°x.
-
Compare les paramètres du bouton.
-
Avec le bouton X de test cela fonctionne t-il ?
-
Je suppose que l'on devrait avoir le même résultat on { "oid": "1.3.6.1.4.1.42505.9.2.2.3.0", "type": "Integer", "value": 1 } off { "oid": "1.3.6.1.4.1.42505.9.2.2.3.0", "type": "Integer", "value": 0 }
-
Cela devra revenir au même : on { "oid": "1.3.6.1.4.1.42505.9.2.2.3.0", "type": "Integer", "value": msg.payload.indexOf("ON") != -1 ? 1 : 0 } off { "oid": "1.3.6.1.4.1.42505.9.2.2.3.0", "type": "Integer", "value": msg.payload.indexOf("OFF") != -1 ? 1 : 0 } Mais où est donc créé la variable msg.payload.indexOf ?
-
Donc cela progresse...
-
Ce que je veux dire c'est que le code "oid": "1.3.6.1.4.1.42505.9.2.2.3.0", produira le même effet, les deux valeurs sont égales quelle que soit le résultat du test msg.payload.indexOf("53") != -1
-
Le test msg.payload.indexOf("53") != -1 est inutile, les valeurs retournées sont identiques. Où est créé la variable msg.payload.indexOf ?
-
J'avais compris que le sujet concerne le Portail N° 1... Il me semble ne pas avoir été bien lu. Dans la fonction Port 2, il y a un return [p52]; or p52 n'y est pas défini. Donc j'ignore il y aura une erreur, par ailleurs je suppose que syntaxiquement, dans les fonctions p2 à p5 (celles de gauche), il faudrait écrire : var tmp = (flow.get("tmpVar")) + 1; flow.set("tmpVar", tmp); var msg1 = {}; msg1.payload = {payload:msg.payload.value === 0 ? "52=OFF" : "52=ON"} return msg1; Ci-après un script de test implémentant un timer de 2 secondes : test.json
-
Bon, je ne comprends pas tout, surtout que je n'ai pas exploré les fonctions de dashboard : Déjà dans la fonction Port 2 : var tmp = (flow.get("tmpVar")) + 1; flow.set("tmpVar", tmp); var p53 = {payload:msg.payload.value === 0 ? "52=OFF" : "52=ON"} ///msg = {icon: '<font color = "white" i class="fa fa-book fa-2x"></i>'}; return [p52]; j'aurais plutôt vu un var p52 = ... ou alors un return [p53]... Ensuite, avec la fonction resend every 5s, le message sera envoyé toutes les 5 secondes, ce qui me parait curieux. Pour ma part, j'aurais plutôt prévu en sortie de la fonction Port 2, un lien direct vers Portail N° 1 et un second lien vers une fonction delay de 2 secondes dont la sortie est une fonction avec le code var msg1 = {}; msg1.payload = "52=OFF"; return msg1; La sortie de cette fonction étant reliée à l'entrée de portail N° 1. Cela répond-il à la question ? ou je n'ai vraiment rien compris...
-
J'utilise Node-RED, mais ne lis pas de question...
-
Aide LUA : Tri des données d'une matrice
Barelle a répondu à un(e) sujet de BenjyNet dans Le bistrot
Alors ceci devrait faire l'affaire : local str = "1571436000 - 1572822000 | Vacances de la Toussaint" local date1 = string.match(str, "(%d+)%s"); local date2 = string.match(str, "-%s(%d+)%s"); local libelle = string.match(str, "|%s(.+)"); fibaro:debug(os.date("%d-%m-%Y", date1) .. " " .. os.date("%d-%m-%Y", date2) .. " " .. libelle); -
Aide LUA : Tri des données d'une matrice
Barelle a répondu à un(e) sujet de BenjyNet dans Le bistrot
Cela répond-il à la question ? function formatDate(sdate) -- Transforme une date en string en date exploitable year, month, day = sdate:match("(%d+)-(%d+)-(%d+)"); if (year == nil) or (month == nil) or (day == nil) then return "???"; else return day.."-"..month.."-"..year; end end -- formatDate -
Dans une scène, local user = api.get("/loginStatus"); permet de connaître l'utilisateur qui a lancé la scène. A essayer dans un VD.
-
topic unique Fibaro Switch 2 - FGS-213 / FGS-223
Barelle a répondu à un(e) sujet de BenjyNet dans Modules Fibaro
On est d'accord, même si ma remarque initiale était erronée. -
topic unique Fibaro Switch 2 - FGS-213 / FGS-223
Barelle a répondu à un(e) sujet de BenjyNet dans Modules Fibaro
Dans ce cas, ok, mais elle n'a rien à faire sur ce schéma, ou alors en la rejetant au delà du fil connectée à la borne N, juste pour montrer qu'une ampoule z-wave est alimentée par le secteur. -
topic unique Fibaro Switch 2 - FGS-213 / FGS-223
Barelle a répondu à un(e) sujet de BenjyNet dans Modules Fibaro
Avec le schéma précédent, l'ampoule sera toujours allumée. Elle doit être branchée entre le neutre et la borne Q du FGS... -
Aide LUA : Tri des données d'une matrice
Barelle a répondu à un(e) sujet de BenjyNet dans Le bistrot
table.sort(nomDeLaTable, function(a, b) return a.Start < b.Start; end); -
Oups, j'avais mal lu... Et en s'inspirant de : Pour une scène les actions pouvant être : start, stop, enable ou disable.
-
Fonctions de contrôle des scènes : fibaro:abort() fibaro:getSourceTrigger() fibaro:getSourceTriggerType() fibaro:startScene(sceneID) fibaro:killScenes(sceneID) fibaro:setSceneEnabled(sceneID, enabled) fibaro:isSceneEnabled(sceneID) fibaro:countScenes(sceneID)