OJC Posté(e) le 16 novembre 2017 Auteur Signaler Posté(e) le 16 novembre 2017 Oui, juste ça. Pas besoin de mettre localP et local si tu utilise les valeurs par défaut. Pour fixer ces valeurs par défaut, c'est dans le VD Controller que ça se passe.
OJC Posté(e) le 16 novembre 2017 Auteur Signaler Posté(e) le 16 novembre 2017 Ps : j'ai omis de préciser que les coefficients sont désormais à multiplier par 100 : donc la ou tu avais 0.6 tu mets 60 et 1 pour 0.01
pepite Posté(e) le 16 novembre 2017 Signaler Posté(e) le 16 novembre 2017 il y a 46 minutes, OJC a dit : sont désormais à multiplier par 100 hihi ca sent la modif du 1er post ;-)
OJC Posté(e) le 16 novembre 2017 Auteur Signaler Posté(e) le 16 novembre 2017 Non il est ok mais j'ai pas pensé à faire un tuto mise à jour. My bad. 1
OJC Posté(e) le 25 novembre 2017 Auteur Signaler Posté(e) le 25 novembre 2017 Publication de la v. 3.0 avec de grosses modifications sur le fonctionnement et la configuration. Heating Manager peut toujours fonctionner sur un mode classique de planification, mais il est désormais pensé pour fonctionner sur un mode événementiel, sans aucune planification mais uniquement en fonction de l'état de la maison, avec un nouveau VD Thermostat pour contrôler manuellement le chauffage dans chaque pièce. Désolé pour le code que je n'ai pas mis en spoiler puisqu'il n'y a manifestement plus de spoiler, et que ce serait trop long directement dans le post.
pepite Posté(e) le 26 novembre 2017 Signaler Posté(e) le 26 novembre 2017 @OJC, du gros gros boulot :-)Felicutations pour les thermostats VIRTUELS, ton Heating MANAGER devient tres tres complet. Merci beaucoup. Je n ai pas vu s il etait possible de tout mettre à OFF ou mettre à OFF une seule pièce. Et un grand merci pour le tuto très complet. Envoyé de mon Nexus 5X en utilisant Tapatalk
OJC Posté(e) le 26 novembre 2017 Auteur Signaler Posté(e) le 26 novembre 2017 @pepite Merci Pour l'arrêt total du chauffage ou dans une pièce seulement, c'est un événement à paramétrer (via une variable globale alimentée par GEA par exemple, ou un VD par exemple) en mettant une consigne à 0 °C ou 8 °C (hors-gel). Un arrêt total hors période de chauffe, qui revient à arrêter la scène, n'est pas géré en interne, il faut le faire manuellement ou via GEA par exemple. Perso je n'ai jamais coupé totalement mon script de chauffage (époque openHAB), l'évolution de la température à l'intérieur de la maison se suffisant à elle-même pour ne pas déclencher la chauffe. Au fait, elle est à jour ta signature ??
pepite Posté(e) le 26 novembre 2017 Signaler Posté(e) le 26 novembre 2017 @OJC : Ok pour l'arret, c'est effectivement facilement faisable comme tu l'indiques. mais pourquoi pas l'implémenter, tu as déja fait tellement sur ton Heating Manager ;-) Juste une remarque sur le "popupWarnErrLog" n'est pas adapté pour les WARNING qui pourraient être importants du fait du fonctionnement des Popups. En fait les Popups n'apparaissent que lorsque l’application est ouverte, ce qui enlève de l'interet à l'usage des popups. Peut-etre qe pour avoir 2 types de notification, le plus judicieux serait de couplet PUSH + SMS plutôt que PUSH +POPUP. Ce n'est évidemment qu'une suggestion, étant incapable d'écrire ce genre de code comme tu le fais ;-) Ma signature ? A quel sujet ?
OJC Posté(e) le 26 novembre 2017 Auteur Signaler Posté(e) le 26 novembre 2017 (modifié) @pepite Au départ, je n'avais mis que le popup ne sachant qu'il était possible de faire un push. Puis j'ai vu comment faire, donc je l'ai ajouté, sans supprimer l'autre partie puisqu'elle existait. Sachant qu'en pratique, vu que le programme contrôle de manière très approfondie la configuration au démarrage, ce n'est que pendant la phase de configuration que ça présente un intérêt. En pratique, en régime de croisière, il n'est pas censé y avoir d'erreurs ou de warning (sauf si on s'amuse à supprimer des pièces ou des modules avec la scène en train de tourner). Pour le SMS, cela implique d'avoir une passerelle que je n'ai pas, je ne peux donc pas tester. J'avais hésité à intégrer le support pour le Notification Center de Krikroff, mais il n'a plus l'air maintenu ? Pour l'arrêt, ça m'embête qd même un peu de laisser la scène se "suicider" puisque, dans ce cas, si les conditions d'arrêt de la chauffe ne sont pas réunies, elle ne pourra pas redémarrer toute seule. Du coup, je vois pas bien comment faire pour que ce soit pertinent. Pour ta signature, c'est par rapport à l'équipement domotique qui a l'air inversement proportionnel à l'intérêt que tu portes à la question Modifié le 26 novembre 2017 par OJC Correction des fautes d'orthographe, je suis fatigué :)
OJC Posté(e) le 27 novembre 2017 Auteur Signaler Posté(e) le 27 novembre 2017 (modifié) Bon, voilà... Roadmap remplie J'ai donc ajouté le paramètre persistent qui permet de faire en sorte que le programme continue de considérer qu'un événement est réalisé alors que ses conditions ne sont plus remplies, et de faire comme s'il n'avait jamais cessé d'être réalisé si les conditions sont de nouveau remplies dans le délai défini. Concrètement, j'ai configuré mon chauffage pour que la température passe à 18 °C quand la variable SleepState est à true (variable qui se met toute seule à cette valeur en fonction de diverses conditions) et qu'aucun mouvement n'est détecté depuis 30 minutes. Comme la température baisse graduellement pendant une heure, pour éviter que la chauffe ne redémarre alors que le mouvement était juste mon fils qui va aux toilettes (plié en trois minutes), j'ai défini un délai de persistance à 5 minutes : comme ça, sauf à ce que le mouvement dure plus longtemps, le chauffage ne redémarre pas et reste à 18 °C. J'ai aussi ajouté la possibilité de viser plusieurs pièces dans la fonction self:addEvent, et ajouté la fonction self:addGlobalEvent qui, comme son intitulé le suggère, permet de définir un événement s'appliquant à toutes les pièces. Enfin, les conditions de réalisation des événements ne se limitent plus à vérifier si telle variable ou propriété est égale à telle valeur, mais accepte désormais tous les opérateurs de comparaison disponibles (==, ~=, >=, <=, > et <). Je crois que je suis bon pour le chauffage maintenant, je vais m'attaquer à mes éclairages ^^ Modifié le 27 novembre 2017 par OJC 1
Dgille Posté(e) le 8 décembre 2017 Signaler Posté(e) le 8 décembre 2017 La beta 4.151 corrige le probleme des panneaux de chauffage pour info. 1
iman Posté(e) le 9 décembre 2017 Signaler Posté(e) le 9 décembre 2017 OJC, j'ai voulu rajouter 4 radiateurs supplémentaires soit 8 au total et j'ai ce message d'erreur avec le heating manager 1.3: [DEBUG] 15:16:01: [INFO] Checking notre chambre...[DEBUG] 15:16:01: line 154: bad argument #1 to 'match' (string expected, got nil)
OJC Posté(e) le 9 décembre 2017 Auteur Signaler Posté(e) le 9 décembre 2017 Tu peux mettre ta conf stp ?
iman Posté(e) le 9 décembre 2017 Signaler Posté(e) le 9 décembre 2017 la voici: --[[ %% autostart %% properties 1078 ui.lbldressing.value 1078 ui.lblsalle.value 1078 ui.lblbureau.value 1078 ui.lblsalledebains.value 1078 ui.lblchambre.value 1078 ui.lblenfant.value 1078 ui.lblclara.value 1078 ui.lblmatheo.value %% globals --]] --[[ Heating Manager v. 1.3.0 (2017) by OJC This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. --]] --[[ Versions Notes 1.3.0 Add the possibility of using virtual device as heater controller Add the possibilité of using virtual device or global variable as setpoint provider 1.2.0 New regulation code, inspired by eedomus box Add the possibility of using virtual temperature sondes Configuration simplification for both Manager and Panel 1.1.0 Add motion sensor management Improve door/window sensor management Code Optimization 1.0.0 Initial release --]] ---------------------------------------------------------------------------------- -- GENERIC CODE -- ---------------------------------------------------------------------------------- logColor = {"YellowGreen", "SkyBlue", "NavajoWhite", "Tomato"} lib = {} function lib:iif(a,b,c) if (a) then return b else return c end end function lib:log(m,l) if ((l or 1) >= logLevel) then print('<span style="color:' .. logColor[l or 1] .. ';">' .. m .. '</span>') end end f = {"Ç","ç","[-èéêë']+","[-ÈÉÊË']+","[-àáâãäå']+","[-@ÀÁÂÃÄÅ']+","[-ìíîï']+","[-ÌÍÎÏ']+","[-ðòóôõö']+","[-ÒÓÔÕÖ']+","[-ùúûü']+","[-ÙÚÛÜ']+","[-ýÿ']+","Ý","%W"} r = {"C","c","e","E","a","A","i","I","o","O","u","U","y","Y",""} format = {} function format:ddigit(n) if (n < 10) then return "0"..n else return n end end function format:replace(s) local s = s for i, j in ipairs(f) do s = string.gsub(s, j, r) end return s end function getDeviceIDbyName(name) local devices = api.get("/devices?name=" .. name) if (devices[1] ~= nil) then return devices[1].id end end function getInstanceAuthorization(max) local t = os.time() local max = tonumber(max) or 1 while (fibaro:countScenes() > max) do fibaro:sleep(500) if (os.time() - t) > 30 then return false end end return true end --DEPENDENCIES = lib:log; getDeviceIDbyName function getPanelID() local p = panel local v = fibaro:getGlobalValue(p.global) if (fibaro:getValue(v, p.label) == nil) then local ID = getDeviceIDbyName(p.name) if (ID ~= nil) then fibaro:setGlobal(p.global, ID) return ID else lib:log("[CRITICAL ERROR] " .. p.name .. " was not found !", 4) fibaro:abort() end else return v end end --DEPENDENCIES = format:ddgit function getReadableTime(t) local d = "" local h = math.floor(t/3600) local m = math.floor(t/60 - (h * 60)) local s = math.floor(t - h * 3600 - m * 60) if (h > 0) then d = d .. format:ddigit(h) .. " h " end if (m > 0) then d = d .. lib:iif(h ~= 0, format:ddigit(m), m) .. " m " end if (s > 0) then d = d .. lib:iif(m ~= 0, format:ddigit(s), s) .. " s" end return d end function getTemperatureSonde(ID) local r = api.get("/rooms?id=" .. ID) return r.defaultSensors.temperature end function setGlobalVariables(...) for _, v in ipairs{...} do if (fibaro:getGlobalValue(v) == nil) then api.post("/globalVariables", {name = v, isEnum = 0}) end end end ---------------------------------------------------------------------------------- -- SPECIFIC CODE -- ---------------------------------------------------------------------------------- collection = {} HeatingManager = {} --DEPENDENCIES = GetTemperatureSonde; format:replace function HeatingManager:addHeater(idHeater, idSonde, localP, localT) local heater, on, off if type(idHeater) == "table" then heater, on, off = idHeater[1], idHeater[2], idHeater[3] else heater, on, off = idHeater, 0, 0 end table.insert(collection, { heater = heater, OnOff = lib:iif(on ~= 0, {on, off}, 0), sonde = idSonde or getTemperatureSonde(fibaro:getRoomID(heater)), kP = localP or default.kP, kT = localT or default.kT, panel = "lbl" .. format:replace(fibaro:getRoomNameByDeviceID(heater)) }) end --DEPENDENCIES = getPanelID function HeatingManager:getTemperatures(item) local c, s, e = 0, 0, 0 if (type(item.sonde) == "number") then c = fibaro:getValue(item.sonde, "value") elseif (type(item.sonde) == "table") then c = string.match(fibaro:getValue(item.sonde[1], "ui." .. item.sonde[2] .. ".value"), "[0-9]+[,.][0-9]+") or string.match(fibaro:getValue(item.sonde[1], "ui." .. item.sonde[2] .. ".value"), "[0-9]+") end s = string.match(fibaro:getValue(getPanelID(), "ui." .. item.panel .. ".value"), "[0-]+9[,.][0-9]+") or string.match(fibaro:getValue(getPanelID(), "ui." .. item.panel .. ".value"), "[0-9]+") if (outdoorSonde == nil) then o = api.get("/weather").Temperature elseif (type(outdoorSonde) == "number") then o = fibaro:getValue(outdoorSonde, "value") elseif (type(outdoorSonde) == "table") then o = string.match(fibaro:getValue(outdoorSonde[1], "ui." .. outdoorSonde[2] .. ".value"), "[0-9]+[,.][0-9]+") or string.match(fibaro:getValue(outdoorSonde[1], "ui." .. outdoorSonde[2] .. ".value"), "[0-9]+") end return c, s, o or s end function HeatingManager:setOutdoorSonde(idSonde) outdoorSonde = idSonde end ---------------------------------------------------------------------------------- -- MAIN CODE -- ---------------------------------------------------------------------------------- --DEPENDENCIES = lib:log; getReadableTime ; -- HeatingManager:getTemperatures function SceneRun() local collection = collection for _, item in ipairs(collection) do local current, setpoint, C, T, P = 0, 0, 0, 0, 0 lib:log("[INFO] Checking " .. fibaro:getRoomNameByDeviceID(item.heater) .. "...") current, setpoint, outdoor = HeatingManager:getTemperatures(item) if (current == nil) then lib:log("[ERROR] " .. fibaro:getRoomNameByDeviceID(item.heater) .. " have no Temperature Sonde !",4) fibaro:call(item.heater, "turnOff") break end lib:log("[INFO] Current = " .. current .. " °C - Setpoint = " .. setpoint .." °C - Outdoor = " .. outdoor .. " °C") P = math.min((item.kP * (setpoint - current)) + (item.kT * (setpoint - outdoor)),1) if (P > 0) then lib:log("[ACTION] Start heating in " .. fibaro:getRoomNameByDeviceID(item.heater) .. " for " .. getReadableTime(P * heatingCycle * 60), 2) if type(item.OnOff) == "number" then fibaro:call(item.heater, "turnOn") if (P < 1) then setTimeout(function() fibaro:call(item.heater, "turnOff") end, P * heatingCycle * 60 * 1000) end else fibaro:call(item.heater, "pressButton", item.OnOff[1]) if (P < 1) then setTimeout(function() fibaro:call(item.heater, "pressButton", item.OnOff[2]) end, P * heatingCycle * 60 * 1000) end end else lib:log("[INFO] Heating is not required in ".. fibaro:getRoomNameByDeviceID(item.heater)) if type(item.OnOff) == "number" then fibaro:call(item.heater, "turnOff") else fibaro:call(item.heater, "pressButton", item.OnOff[2]) end end end setTimeout(SceneRun, heatingCycle * 60 * 1000) end ---------------------------------------------------------------------------------- -- CONFIGURATION -- ---------------------------------------------------------------------------------- -- 1. Default Parameters default = {} default.kP = 3.1 default.kT = 0.02 -- For more information, see https://doc.eedomus.com/view/Algorithme_Chauffage -- 2. General Parameters heatingCycle = 10 logLevel = 1 -- 3. Collection Definition --[[ HeatingManager:addHeater(idHeater, [idSonde], [localP], [localT]) + idHeater = ID of heater control device or {ID of heater virtuel device, order number of the ON button, order number of the OFF button} + idSonde = ID of temperature sonde or {ID of temperature virtual device, ID of temperature label} - Optional : if not set, room temperature sonde is used + localP = Optional : if not set, default.kP is used + localT = Optional : if not set, default.kT is used --]] HeatingManager:addHeater({437, 1, 2}, 1053, localP, localT) HeatingManager:addHeater({511, 1, 2}, 453, 0.6, 0.01) HeatingManager:addHeater({438, 1, 2}, 1059, 2.6, localT) HeatingManager:addHeater({439, 1, 2}, 415, 1.2, 0.01) HeatingManager:addHeater({1076, 1, 2}, 1073, localP, localT) HeatingManager:addHeater({943, 1, 2}, 1070, 0.6, 0.01) HeatingManager:addHeater({1075, 1, 2}, 457, 2.6, localT) HeatingManager:addHeater({1077, 1, 2}, 450, 1.2, 0.01) --HeatingManager:setOutdoorSonde(ID Device or {ID VirtualDevice, ID Label}) --idSonde = ID Device or {ID VirtualDevice, ID Label} - Optional : If not set, weather plugin is used HeatingManager:setOutdoorSonde(1045) ------------------------------------------------------------------------- -- START CODE -- ------------------------------------------------------------------------- --DEPENDENCIES = lib:log; getInstanceAuthorization; -- HeatingManager:checkGlobalVariables; -- SceneRun trigger = fibaro:getSourceTrigger() if not (getInstanceAuthorization(lib:iif(trigger.type == "property", 9, 1))) then lib.log("[CRITICAL ERROR] Too many instances are running !", 4) fibaro:abort() end panel = {name = "Heating Panel", label = "ui.lblHeatingPanel.value", global = "HeatingPanelID"} setGlobalVariables("HeatingPanelID") if (trigger.type == "property") then for _, item in ipairs(collection) do if item.panel == string.match(trigger.propertyName,"ui.(%a+).value") then local current = 0 local setPoint = 0 current, setPoint = HeatingManager:getTemperatures(item) if (current == nil) then lib:log("[ERROR] " .. fibaro:getRoomNameByDeviceID(item.heater) .. " have no Temperature Sonde !",4) fibaro:call(item.heater, "turnOff") fibaro:abort() end if (current < setPoint) then lib.log("[OVERRIDE] Start heating in " .. fibaro:getRoomNameByDeviceID(item.heater), 4) fibaro:call(item.heater,"turnOn") elseif (current >= setPoint) then lib.log("[OVERRIDE] Heating is not required in " .. fibaro:getRoomNameByDeviceID(item.heater), 4) fibaro:call(item.heater,"turnOff") end end end else lib:log("Heating Manager v. 1.3.0 (2017) by OJC", 3) SceneRun() end et avec le panneau le déboguer est OK par contre message erreur avec la scène sur le rajout à partir de chambre
OJC Posté(e) le 9 décembre 2017 Auteur Signaler Posté(e) le 9 décembre 2017 Ta pièce semble s'appeler «notre chambre» or je ne vois pas de label «ui.lblnotrechambre.value» dans les triggers
OJC Posté(e) le 9 décembre 2017 Auteur Signaler Posté(e) le 9 décembre 2017 Tu es sur du nom de ton label dans le VD ?
iman Posté(e) le 9 décembre 2017 Signaler Posté(e) le 9 décembre 2017 entre temps temps j'ai rectifier et mis tous avec le label chambre ainsi que le nom de la pièce
iman Posté(e) le 9 décembre 2017 Signaler Posté(e) le 9 décembre 2017 dans le VD les labels sont identique et voici la scène et message erreur: --[[ %% autostart %% properties 1078 ui.lbldressing.value 1078 ui.lblsalle.value 1078 ui.lblbureau.value 1078 ui.lblsalledebains.value 1078 ui.lblchambre.value 1078 ui.lblenfant.value 1078 ui.lblclara.value 1078 ui.lblmatheo.value %% globals --]] --[[ Heating Manager v. 1.3.0 (2017) by OJC This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. --]] --[[ Versions Notes 1.3.0 Add the possibility of using virtual device as heater controller Add the possibilité of using virtual device or global variable as setpoint provider 1.2.0 New regulation code, inspired by eedomus box Add the possibility of using virtual temperature sondes Configuration simplification for both Manager and Panel 1.1.0 Add motion sensor management Improve door/window sensor management Code Optimization 1.0.0 Initial release --]] ---------------------------------------------------------------------------------- -- GENERIC CODE -- ---------------------------------------------------------------------------------- logColor = {"YellowGreen", "SkyBlue", "NavajoWhite", "Tomato"} lib = {} function lib:iif(a,b,c) if (a) then return b else return c end end function lib:log(m,l) if ((l or 1) >= logLevel) then print('<span style="color:' .. logColor[l or 1] .. ';">' .. m .. '</span>') end end f = {"Ç","ç","[-èéêë']+","[-ÈÉÊË']+","[-àáâãäå']+","[-@ÀÁÂÃÄÅ']+","[-ìíîï']+","[-ÌÍÎÏ']+","[-ðòóôõö']+","[-ÒÓÔÕÖ']+","[-ùúûü']+","[-ÙÚÛÜ']+","[-ýÿ']+","Ý","%W"} r = {"C","c","e","E","a","A","i","I","o","O","u","U","y","Y",""} format = {} function format:ddigit(n) if (n < 10) then return "0"..n else return n end end function format:replace(s) local s = s for i, j in ipairs(f) do s = string.gsub(s, j, r) end return s end function getDeviceIDbyName(name) local devices = api.get("/devices?name=" .. name) if (devices[1] ~= nil) then return devices[1].id end end function getInstanceAuthorization(max) local t = os.time() local max = tonumber(max) or 1 while (fibaro:countScenes() > max) do fibaro:sleep(500) if (os.time() - t) > 30 then return false end end return true end --DEPENDENCIES = lib:log; getDeviceIDbyName function getPanelID() local p = panel local v = fibaro:getGlobalValue(p.global) if (fibaro:getValue(v, p.label) == nil) then local ID = getDeviceIDbyName(p.name) if (ID ~= nil) then fibaro:setGlobal(p.global, ID) return ID else lib:log("[CRITICAL ERROR] " .. p.name .. " was not found !", 4) fibaro:abort() end else return v end end --DEPENDENCIES = format:ddgit function getReadableTime(t) local d = "" local h = math.floor(t/3600) local m = math.floor(t/60 - (h * 60)) local s = math.floor(t - h * 3600 - m * 60) if (h > 0) then d = d .. format:ddigit(h) .. " h " end if (m > 0) then d = d .. lib:iif(h ~= 0, format:ddigit(m), m) .. " m " end if (s > 0) then d = d .. lib:iif(m ~= 0, format:ddigit(s), s) .. " s" end return d end function getTemperatureSonde(ID) local r = api.get("/rooms?id=" .. ID) return r.defaultSensors.temperature end function setGlobalVariables(...) for _, v in ipairs{...} do if (fibaro:getGlobalValue(v) == nil) then api.post("/globalVariables", {name = v, isEnum = 0}) end end end ---------------------------------------------------------------------------------- -- SPECIFIC CODE -- ---------------------------------------------------------------------------------- collection = {} HeatingManager = {} --DEPENDENCIES = GetTemperatureSonde; format:replace function HeatingManager:addHeater(idHeater, idSonde, localP, localT) local heater, on, off if type(idHeater) == "table" then heater, on, off = idHeater[1], idHeater[2], idHeater[3] else heater, on, off = idHeater, 0, 0 end table.insert(collection, { heater = heater, OnOff = lib:iif(on ~= 0, {on, off}, 0), sonde = idSonde or getTemperatureSonde(fibaro:getRoomID(heater)), kP = localP or default.kP, kT = localT or default.kT, panel = "lbl" .. format:replace(fibaro:getRoomNameByDeviceID(heater)) }) end --DEPENDENCIES = getPanelID function HeatingManager:getTemperatures(item) local c, s, e = 0, 0, 0 if (type(item.sonde) == "number") then c = fibaro:getValue(item.sonde, "value") elseif (type(item.sonde) == "table") then c = string.match(fibaro:getValue(item.sonde[1], "ui." .. item.sonde[2] .. ".value"), "[0-13]+[,.][0-13]+") or string.match(fibaro:getValue(item.sonde[1], "ui." .. item.sonde[2] .. ".value"), "[0-13]+") end s = string.match(fibaro:getValue(getPanelID(), "ui." .. item.panel .. ".value"), "[0-]+13[,.][0-13]+") or string.match(fibaro:getValue(getPanelID(), "ui." .. item.panel .. ".value"), "[0-13]+") if (outdoorSonde == nil) then o = api.get("/weather").Temperature elseif (type(outdoorSonde) == "number") then o = fibaro:getValue(outdoorSonde, "value") elseif (type(outdoorSonde) == "table") then o = string.match(fibaro:getValue(outdoorSonde[1], "ui." .. outdoorSonde[2] .. ".value"), "[0-9]+[,.][0-9]+") or string.match(fibaro:getValue(outdoorSonde[1], "ui." .. outdoorSonde[2] .. ".value"), "[0-9]+") end return c, s, o or s end function HeatingManager:setOutdoorSonde(idSonde) outdoorSonde = idSonde end ---------------------------------------------------------------------------------- -- MAIN CODE -- ---------------------------------------------------------------------------------- --DEPENDENCIES = lib:log; getReadableTime ; -- HeatingManager:getTemperatures function SceneRun() local collection = collection for _, item in ipairs(collection) do local current, setpoint, C, T, P = 0, 0, 0, 0, 0 lib:log("[INFO] Checking " .. fibaro:getRoomNameByDeviceID(item.heater) .. "...") current, setpoint, outdoor = HeatingManager:getTemperatures(item) if (current == nil) then lib:log("[ERROR] " .. fibaro:getRoomNameByDeviceID(item.heater) .. " have no Temperature Sonde !",4) fibaro:call(item.heater, "turnOff") break end lib:log("[INFO] Current = " .. current .. " °C - Setpoint = " .. setpoint .." °C - Outdoor = " .. outdoor .. " °C") P = math.min((item.kP * (setpoint - current)) + (item.kT * (setpoint - outdoor)),1) if (P > 0) then lib:log("[ACTION] Start heating in " .. fibaro:getRoomNameByDeviceID(item.heater) .. " for " .. getReadableTime(P * heatingCycle * 60), 2) if type(item.OnOff) == "number" then fibaro:call(item.heater, "turnOn") if (P < 1) then setTimeout(function() fibaro:call(item.heater, "turnOff") end, P * heatingCycle * 60 * 1000) end else fibaro:call(item.heater, "pressButton", item.OnOff[1]) if (P < 1) then setTimeout(function() fibaro:call(item.heater, "pressButton", item.OnOff[2]) end, P * heatingCycle * 60 * 1000) end end else lib:log("[INFO] Heating is not required in ".. fibaro:getRoomNameByDeviceID(item.heater)) if type(item.OnOff) == "number" then fibaro:call(item.heater, "turnOff") else fibaro:call(item.heater, "pressButton", item.OnOff[2]) end end end setTimeout(SceneRun, heatingCycle * 60 * 1000) end ---------------------------------------------------------------------------------- -- CONFIGURATION -- ---------------------------------------------------------------------------------- -- 1. Default Parameters default = {} default.kP = 3.1 default.kT = 0.02 -- For more information, see https://doc.eedomus.com/view/Algorithme_Chauffage -- 2. General Parameters heatingCycle = 10 logLevel = 1 -- 3. Collection Definition --[[ HeatingManager:addHeater(idHeater, [idSonde], [localP], [localT]) + idHeater = ID of heater control device or {ID of heater virtuel device, order number of the ON button, order number of the OFF button} + idSonde = ID of temperature sonde or {ID of temperature virtual device, ID of temperature label} - Optional : if not set, room temperature sonde is used + localP = Optional : if not set, default.kP is used + localT = Optional : if not set, default.kT is used --]] HeatingManager:addHeater({437, 1, 2}, 1053, localP, localT) HeatingManager:addHeater({511, 1, 2}, 453, 0.6, 0.01) HeatingManager:addHeater({438, 1, 2}, 1059, 2.6, localT) HeatingManager:addHeater({439, 1, 2}, 415, 1.2, 0.01) HeatingManager:addHeater({1076, 1, 2}, 1073, 0.6, 0.01) HeatingManager:addHeater({943, 1, 2}, 1070, 0.6, 0.01) HeatingManager:addHeater({1075, 1, 2}, 457, 0.6, 0.01) HeatingManager:addHeater({1077, 1, 2}, 450, 0.6, 0.01) --HeatingManager:setOutdoorSonde(ID Device or {ID VirtualDevice, ID Label}) --idSonde = ID Device or {ID VirtualDevice, ID Label} - Optional : If not set, weather plugin is used HeatingManager:setOutdoorSonde(1045) ------------------------------------------------------------------------- -- START CODE -- ------------------------------------------------------------------------- --DEPENDENCIES = lib:log; getInstanceAuthorization; -- HeatingManager:checkGlobalVariables; -- SceneRun trigger = fibaro:getSourceTrigger() if not (getInstanceAuthorization(lib:iif(trigger.type == "property", 9, 1))) then lib.log("[CRITICAL ERROR] Too many instances are running !", 4) fibaro:abort() end panel = {name = "Heating Panel", label = "ui.lblHeatingPanel.value", global = "HeatingPanelID"} setGlobalVariables("HeatingPanelID") if (trigger.type == "property") then for _, item in ipairs(collection) do if item.panel == string.match(trigger.propertyName,"ui.(%a+).value") then local current = 0 local setPoint = 0 current, setPoint = HeatingManager:getTemperatures(item) if (current == nil) then lib:log("[ERROR] " .. fibaro:getRoomNameByDeviceID(item.heater) .. " have no Temperature Sonde !",4) fibaro:call(item.heater, "turnOff") fibaro:abort() end if (current < setPoint) then lib.log("[OVERRIDE] Start heating in " .. fibaro:getRoomNameByDeviceID(item.heater), 4) fibaro:call(item.heater,"turnOn") elseif (current >= setPoint) then lib.log("[OVERRIDE] Heating is not required in " .. fibaro:getRoomNameByDeviceID(item.heater), 4) fibaro:call(item.heater,"turnOff") end end end else lib:log("Heating Manager v. 1.3.0 (2017) by OJC", 3) SceneRun() end [DEBUG] 17:54:32: [INFO] Checking chambre...[DEBUG] 17:54:32: line 153: bad argument #1 to 'match' (string expected, got nil)
OJC Posté(e) le 9 décembre 2017 Auteur Signaler Posté(e) le 9 décembre 2017 Ok. Je suis sur mon smartphone, tu peux me mettre juste la ligne 153 qui génère l'erreur stp ?
iman Posté(e) le 9 décembre 2017 Signaler Posté(e) le 9 décembre 2017 honte à moi, je viens de trouver j'ai 2 VD et je change la variable suivant la cheminée si elle est en route et j'ai modifier qu'un seul des VD et évidemment le mauvais merci encore pour ton aide OJC sinon pour la régule c top
OJC Posté(e) le 9 décembre 2017 Auteur Signaler Posté(e) le 9 décembre 2017 Cool Je suis content que ça marche bien.
iman Posté(e) le 9 décembre 2017 Signaler Posté(e) le 9 décembre 2017 OJC, ma scène fonctionne mais le setpoint=1 °c il ne prend pas la consigne du VD?
Messages recommandés