flacon030 Posté(e) le 12 mai 2023 Signaler Posté(e) le 12 mai 2023 (modifié) Bonjour a tous Sur le marketplace il y a un QA pour la gestion des onduleurs fronius Il est plutôt complet mais perso il me manque une information essentiel La gestion de la charge ou décharge de la batterie Cette information est disponible mais le child n'a pas été créer Comment l'ajouter? c'est cette info que je voudrais récupérer pour créer le child if self.P_Akku ~= json.null() then self:updateView("akku", "text", "Batterie: - Charge / + Decharge: " .. string.format("%.3f", self.P_Akku) .. " W") end J'ai bien réussi a ajouter un child avec cela, mais ma valeur reste a zéro -- Current Akku power (w) self.P_Akku.currentGridChild = self:initChildDevice("currentAkkuChild", "Akku", "com.fibaro.powerMeter", PowerSensor) voici le code Ci joint l'API de l'onduleur, et a titre d'information ma batterie est une BYD -- comment the line below to activate trace logs fibaro.trace = function() end function QuickApp:onInit() self:debug('onInit') self.E_Total_Consumed = 0 self.E_Total_Produced = 0 if (not self:checkConfiguration()) then self:updateProperty("log", "Not configured") self:warning("Quick app not configured. Please go to the quick app variables configuration, and set ip of your Fronius device.") else self:updateProperty("log", "") self:trace("initFields") self:initFields() self:trace("createChildDevices") self:createChildDevices() self:trace("fetchGeneralData") self:fetchGeneralData() self:trace("fetchMeterData") self:fetchMeterData() end end function QuickApp:checkConfiguration() if self:getVariable("ip") ~= "" and self:getVariable("port") ~= "" and self:getVariable("timeout") ~= "" then return true end return false end function QuickApp:initFields() self.http = net.HTTPClient({ timeout = 3000 }) self.ip = self:getVariable("ip") self.port = self:getVariable("port") self.timeout = tonumber(self:getVariable("timeout")) self.childs = {} self:updateProperty("configured", true) end -- check if provided device id is a child of this quick app function QuickApp:childDeviceExist(deviceId) if deviceId == nil then return false end local dev = api.get('/devices/' .. tostring(deviceId)) if dev == nil then return false end return dev.parentId == self.id end -- init child devices or create if not exist function QuickApp:initChildDevice(variableName, deviceName, type, class) local childId = self:getVariable(variableName) if(self:childDeviceExist(childId) == false) then local child = self:createChildDevice({ name = deviceName, type = type }, class) childId = child.id self:setVariable(variableName, childId) self:trace(deviceName, "created:", child.id) end return self.childDevices[childId] end function QuickApp:createChildDevices() self:initChildDevices({ ["com.fibaro.electricMeter"] = Meter, ["com.fibaro.energyMeter"] = Meter, ["com.fibaro.powerMeter"] = PowerSensor, }) -- data from: /solar_api/v1/GetMeterRealtimeData.cgi?Scope=System endpoint self.childs.totalEnergyConsumedChild = self:initChildDevice("totalEnergyConsumedChild", "Total energy consumed", "com.fibaro.energyMeter", Meter) self.childs.totalEnergyConsumedChild:updateProperty("rateType", "consumption") -- data from: /solar_api/v1/GetPowerFlowRealtimeData.fcgi endpoint -- total energy produced (kWh) self.childs.totalEnergyChild = self:initChildDevice("totalEnergyChild", "Total energy produced", "com.fibaro.energyMeter", Meter) self.childs.totalEnergyChild:updateProperty("rateType", "production") -- total energy produced in a day (kWh) -- self.childs.totalEnergyDayChild = self:initChildDevice("totalEnergyDayChild", "Day Consumption", "com.fibaro.electricMeter", Meter) -- current production (W) self.childs.currentPowerChild = self:initChildDevice("currentPowerChild", "Production", "com.fibaro.powerMeter", PowerSensor) self.childs.currentPowerChild:updateProperty("rateType", "production") -- current grid power (W) -- from docs: value is null if no meter is enabled ( + from grid , - to grid ) self.childs.currentGridChild = self:initChildDevice("currentGridChild", "Grid", "com.fibaro.powerMeter", PowerSensor) -- self.childs.grid = self:initChildDevice("totalEnergyDayHouseC", "Total energy house day", "com.fibaro.electricMeter", Meter) end function QuickApp:setChildVisibility(childName, visible) local child = self.childs[childName] if child == nil then self:warning(string.format("Child %s not found", childName)) return end local previousVisible = child:getVariable("visible") if previousVisible ~= visible then child:setVisible(visible) child:setVariable("visible", visible) self:debug(string.format("Changing visibility of the child device (id:%d). Visible value: %s", child.id, visible)) end end -- fetch general data function QuickApp:fetchGeneralData() local requestUrl = string.format("http://%s:%s/solar_api/v1/GetPowerFlowRealtimeData.fcgi", self.ip, self.port) self:trace("Sending request:", requestUrl) self.http:request(requestUrl, { options = { method = "GET", headers = { ["Accept"] = "application/json" } }, success = function(response) if (response.status == 200) then self:updateProperty("log", "") self:parseGeneralData(response.data) end -- loop the request fibaro.setTimeout(tonumber(self.timeout) * 1000, function () self:fetchGeneralData() end) end, error = function(err) self:error(tostring(err)) self:updateProperty("log", "Connection error") fibaro.setTimeout(tonumber(self.timeout) * 1000, function () self:fetchGeneralData() end) end }) end function QuickApp:parseGeneralData(data) local fronius = json.decode(data) self:trace(data) self.E_Total = fronius.Body.Data.Site.E_Total or 0 -- total energy produced self.P_PV = fronius.Body.Data.Site.P_PV or 0 -- current power self.P_Grid = fronius.Body.Data.Site.P_Grid or 0 self.P_Load = fronius.Body.Data.Site.P_Load or 0 self.P_Akku = fronius.Body.Data.Site.P_Akku or 0 self:updateView("mode", "text", "Mode: " .. fronius.Body.Data.Site.Mode) if self.P_Grid ~= json.null() then self:setChildVisibility("currentGridChild", true) self.childs.currentGridChild:updateProperty("log", "") local gridValue = string.format("%.0f", self.P_Grid) self:updateView("grid", "text", "Linky: - Injection / + Conso: " .. gridValue .. " W") self.childs.currentGridChild:setValue(gridValue) if self.P_Grid < 0 then self.childs.currentGridChild:updateProperty("log", "Injection linky") else self.childs.currentGridChild:updateProperty("log", "Conso linky") end else self.childs.currentGridChild:updateProperty("log", "Meter not connected") self:setChildVisibility("currentGridChild", false) -- hiding unused device end if self.P_Load ~= json.null() then self:updateView("load", "text", "Conso maison: " .. string.format("%.3f", self.P_Load) .. " W") end if self.P_Akku ~= json.null() then self:updateView("akku", "text", "Batterie: - Charge / + Decharge: " .. string.format("%.3f", self.P_Akku) .. " W") end if self.P_PV ~= json.null() then self:updateView("current", "text", "Fronius: " .. string.format("%.3f",self.P_PV) .. " W") self.childs.currentPowerChild:updateProperty("value", self.P_PV) end self:updateView("total", "text", "Index Total: " .. string.format("%.3f",self.E_Total / 1000) .. " kWh") self.childs.totalEnergyChild:setValue((self.E_Total) / 1000) self:updateView("day", "text", "Index Journaliere: " .. string.format("%.3f",fronius.Body.Data.Site.E_Day / 1000) .. " kWh") --self.childs.totalEnergyDayChild:setValue(fronius.Body.Data.Site.E_Day / 1000) self:updateView("year", "text", "Index Annuel: " .. string.format("%.3f", fronius.Body.Data.Site.E_Year / 1000) .. " kWh") end -- fetch meter data -> not used for now function QuickApp:fetchMeterData() self.http:request("http://" .. self.ip .. ":" .. self.port .. "/solar_api/v1/GetMeterRealtimeData.cgi?Scope=System", { options = { method = "GET", timeout = 10000, headers = { ["Accept"] = "application/json" } }, success = function(response) if (response.status == 200) then self:parseMeterData(response.data) end fibaro.setTimeout(tonumber(self.timeout) * 1000, function () self:fetchMeterData() end) end, error = function(err) self:error(tostring(err)) fibaro.setTimeout(tonumber(self.timeout) * 1000, function () self:fetchMeterData() end) end }) end function QuickApp:parseMeterData(data) local fronius = json.decode(data) if fronius == nil or fronius.Body == nil or fronius.Body.Data["0"] == nil then self:trace("Unable to download meter data.") self.childs.totalEnergyConsumedChild:updateProperty("log", "Meter not connected") self:setChildVisibility("totalEnergyConsumedChild", false) -- hiding unused device return end self.childs.totalEnergyConsumedChild:updateProperty("log", "") self:setChildVisibility("totalEnergyConsumedChild", true) self.E_Total_Consumed = fronius.Body.Data["0"].EnergyReal_WAC_Sum_Consumed or 0 -- total energy consumed if self.E_Total_Consumed ~= json.null() then self:updateView("totalConsumption", "text", "Index Conso Linky Annuel: " .. string.format("%.3f",self.E_Total_Consumed / 1000) .. " kWh") self.childs.totalEnergyConsumedChild:setValue((self.E_Total_Consumed) / 1000) end self.E_Total_Produced = fronius.Body.Data["0"].EnergyReal_WAC_Sum_Produced or 0 -- total energy exported (not used for now) end API Fronius.pdf Modifié le 13 mai 2023 par flacon030
flacon030 Posté(e) le 13 mai 2023 Auteur Signaler Posté(e) le 13 mai 2023 Bon je me répond a moi même Après pas mal d'essais je viens de trouver Il faut ajouter deux lignes pour ce QA et avoir un nouveau child (celui de la puissance qui entre ou sort de la batterie) if self.P_Akku ~= json.null() then self:updateView("akku", "text", "Batterie: - Charge / + Decharge: " .. string.format("%.3f", self.P_Akku) .. " W") self.childs.currentAkkuChild:updateProperty("value", self.P_Akku) -- Ligne ajouté Akku end -- Current Akku power (w) self.childs.currentAkkuChild = self:initChildDevice("currentAkkuChild", "Akku", "com.fibaro.powerMeter", PowerSensor) -- ligne ajouter Akku
flacon030 Posté(e) le 13 mai 2023 Auteur Signaler Posté(e) le 13 mai 2023 Quel type de chilld créer pour un % d'autonomie de l'habitation selon vous? Merci
Lazer Posté(e) le 13 mai 2023 Signaler Posté(e) le 13 mai 2023 Un multilevelsensor avec la propriété unit configurée sur % par exemple Ou alors, tu exploites la propriété batterylevel de l'un des QA existants (parent ou enfant), mais ça ne sera pas très juste, puisque cette propriété, bien que contenant un pourcentage, est censée contenir un niveau de batterie, pas d'autre chose.
flacon030 Posté(e) le 13 mai 2023 Auteur Signaler Posté(e) le 13 mai 2023 Je pense que je vais essayer un multilevelsensor Car ce n'est pas une batterie effectivement C'est le pourcentage d’autoconsommation des PV, rien a voir avec une batterie Merci pour ton aide
Lazer Posté(e) le 13 mai 2023 Signaler Posté(e) le 13 mai 2023 Oui OK. Sinon c'est un détail ici, mais en PV, le taux d'autoconsommation et le taux d'autonomie sont 2 statistiques bien distinctes.
flacon030 Posté(e) le 13 mai 2023 Auteur Signaler Posté(e) le 13 mai 2023 (modifié) Oui je vais essayer de remonter ces deux information dans le QA J'ai vu dans le code json que ces informations sont disponibles En faite j’essaie de remonter tous les info du code json de l'onduleur et des batteries pour avoir un QA le plus complet possible Body Data Inverters 1 Battery_Mode "normal" DT 99 E_Day 3682 E_Total 3896556 E_Year 1760809.25 P 699 SOC 48.79999923706055 Site BatteryStandby false E_Day 3682 E_Total 3896556 E_Year 1760809.2000000002 Meter_Location "grid" Mode "bidirectional" P_Akku 76.86 P_Grid 10.7 P_Load -709.7 P_PV 670 rel_Autonomy 98.49232069888684 rel_SelfConsumption 100 Version "12" Head RequestArguments {} Status Code 0 Reason "" UserMessage "" Timestamp "2023-05-13T12:04:39+02:00" Il reste un point que j’essaierais de régler plus tard c'est que les child de puissance puissent afficher les puissances comme le child du linky avec la mention "injection" ou "consommation" sous la puissance dans la tuile Modifié le 13 mai 2023 par flacon030
flacon030 Posté(e) le 13 mai 2023 Auteur Signaler Posté(e) le 13 mai 2023 (modifié) J'ai la consommation de mon habitation qui remonte en négatif dans la tuile de mon child et donc invisible sous domocharts est il possible de la convertir en positif? if self.P_Load ~= json.null() then self:updateView("load", "text", "Conso maison: " .. string.format("%.3f", self.P_Load) .. " W") self.childs.currentLoadChild:updateProperty("value", self.P_Load) end Modifié le 13 mai 2023 par flacon030
mprinfo Posté(e) le 13 mai 2023 Signaler Posté(e) le 13 mai 2023 Ou alors en multipliant par -1Envoyé de mon BLA-L29 en utilisant Tapatalk
Lazer Posté(e) le 13 mai 2023 Signaler Posté(e) le 13 mai 2023 Si tu veux faire une opération mathématique, il y a plus simple, il suffit de mettre le signe - devant, encore plus efficace que la multiplication. Mais ces 2 solutions ne sont pas bonnes, car si le nombre est positif, ça donnera un nombre négatif en sortie. C'est donc bien math.abs() qui renvoie la valeur absolue, donc un nombre positif, en toutes circonstances. Ou bien si on ne veut pas appeler une fonction externe, on peut le faire avec un simple if pour tester si le nombre est négatif, alors renvoyer -nombre, else renvoyer nombre. 1
flacon030 Posté(e) le 13 mai 2023 Auteur Signaler Posté(e) le 13 mai 2023 (modifié) Effectivement cela fonction en ajoutant * -1 et cela ne posera pas de problème pour cette fonctionnalité vu que la consommation de la maison ne peut pas être négative Mais pour ma culture personnel, je la place ou celle fonction dans mon code? Merci fonction math.abs() code du child if self.P_Load ~= json.null() then self:updateView("load", "text", "Conso maison: " .. string.format("%.3f", self.P_Load * -1) .. " W") self.childs.currentLoadChild:updateProperty("value", self.P_Load * -1) end Modifié le 13 mai 2023 par flacon030
mprinfo Posté(e) le 13 mai 2023 Signaler Posté(e) le 13 mai 2023 C'est très simple math.abs(-100) Tu peux remplacer -100 par une variable math.abs(self.P_Load) Envoyé de mon BLA-L29 en utilisant Tapatalk
flacon030 Posté(e) le 13 mai 2023 Auteur Signaler Posté(e) le 13 mai 2023 (modifié) Merci Voici ce que j'obtiens a présent avec ce QA modifier Reste a réussir a faire fonctionner les deux child "autoconsommation" et "autonomie" Modifié le 13 mai 2023 par flacon030
flacon030 Posté(e) le 19 mai 2023 Auteur Signaler Posté(e) le 19 mai 2023 (modifié) bonjour j'essaie de créer mes deux derniers child mais je n'ai aucune valeur qui remonte, elles reste a 0, or elles remonte bien dans mon panneau du QA (voir image ci dessus) J'ai mis un multilevelSensor avec une propriété en "unit" "%" mais je suis pas sur de faire se qu'il faut function QuickApp:createChildDevices() self:initChildDevices({ ["com.fibaro.multilevelSensor"] = sensor, }) self.childs.rel_AutonomyChild = self:initChildDevice("rel_AutonomyChild", "rel_Autonomy", "com.fibaro.multilevelSensor", sensor) self.childs.rel_AutonomyChild:updateProperty("unit", "%") self.childs.rel_SelfConsumptionChild = self:initChildDevice("rel_SelfConsumption", "rel_SelfConsumption", "com.fibaro.multilevelSensor", sensor) self.childs.rel_SelfConsumptionChild:updateProperty("unit", "%") function QuickApp:parseGeneralData(data) local fronius = json.decode(data) self:trace(data) self.rel_Autonomy = fronius.Body.Data.Site.rel_Autonomy or 0 self.rel_SelfConsumption = fronius.Body.Data.Site.rel_SelfConsumption or 0 self:updateView("mode", "text", "Mode: " .. fronius.Body.Data.Site.Mode) -- ----rel_SelfConsumption--- self:updateView("rel_SelfConsumption", "text", "Autoconsommation: " .. string.format("%.3f",fronius.Body.Data.Site.rel_SelfConsumption) .. " %") self.childs.rel_SelfConsumption:setValue(fronius.Body.Data.Site.rel_SelfConsumption) -- ----rel_Autonomy--- self:updateView("rel_Autonomy", "text", "Autonomy: " .. string.format("%.3f",fronius.Body.Data.Site.rel_Autonomy) .. " %") self.childs.rel_AutonomyChild:setValue(fronius.Body.Data.Site.rel_Autonomy) Modifié le 19 mai 2023 par flacon030
Lazer Posté(e) le 19 mai 2023 Signaler Posté(e) le 19 mai 2023 Je vois que tu fais un updateView, pourquoi, tu as un label ? Si tu veux mettre à jour la propriété value du module, c'est avec updateProperty("value", ma_nouvelle_valeur)
vravolta Posté(e) le 28 juin 2023 Signaler Posté(e) le 28 juin 2023 My 2 cents sur ce sujet: j'ai aussi du fronius à la maison et arrivera un moment où tu voudras non seulement lire sur ton onduleur mais aussi écrire pour modifier son comportement. Et là, l'API ne pourra rien pour toi car elle ne peut que lire. Tu devras alors passer via Modbus qui a en plus le mérite d'être bien plus complet et rapide. J'ai déjà écrit une QA avec toutes les briques pour exploiter le Modbus Fronius, mais je ne l'ai pas encore publiée car il faut que je la rende plus compréhensible pour les autres. Mais si tu veux partir dans cette voie, je t'aide volontiers car comme le modbus est un protocole super bas niveau (on envoie des messages en hexa, il faut se gaffer avec les conversions de type qu'on recoit en retour et la gestion des nombres négatifs est un grand moment de solitude).
flacon030 Posté(e) le 30 juin 2023 Auteur Signaler Posté(e) le 30 juin 2023 interessant je suis intéressè par ta proposition
vravolta Posté(e) le 1 juillet 2023 Signaler Posté(e) le 1 juillet 2023 OK, je vais poser mon QA modbus Fronius ce matin sur Marketplace. Il faut alors bien lire la doc Fronius sur le Modbus (de mémoire, elle n'est pas dispo en téléchargement sur leur site et il faut leur envoyer un mail pour l'obtenir) car des fois, il faut bouger des paramètres obscurs avant que des modifs soient prises en compte, mais la doc a le mérite d'être bien faite. Toute la couche technique de communication a été écrite, l'entier du paramétrage de mon registre y est (= il existe une sorte de structure standardisée pour les onduleurs modbus de toutes marques, mais selon les modèles, tous les registres ne sont pas exploités).
flacon030 Posté(e) le 1 juillet 2023 Auteur Signaler Posté(e) le 1 juillet 2023 (modifié) super merci tiens nous au courant quant elle sera en ligne Car personnellement se qui me manque est qui n'est pas dans les API c'est le pourcentage de charge batterie Modifié le 1 juillet 2023 par flacon030
flacon030 Posté(e) le 3 juillet 2023 Auteur Signaler Posté(e) le 3 juillet 2023 (modifié) Bonjour Je viens de mettre en place ton QA Merci pour ce dernier Par contre se que je trouve étrange c'est cette valeur MaxChargingPower: 10240.0 W Cela correspond a quoi? Se qui serait bien a présent c'est qu'il y est un module enfant pour avoir le % de charge batterie (SOC) afin de pouvoir l'exploiter dans les scenarios de la HC3 Et un retour d'info sur la température de la batterie Modifié le 3 juillet 2023 par flacon030
vravolta Posté(e) le 4 juillet 2023 Signaler Posté(e) le 4 juillet 2023 Concernant le max charging power (et discharge) cela permet de forcer la vitesse de charge/décharge de la batterie stationnaire Fronius, comme dans l’onglet de la gestion de l’énergie, sauf qu’ici, on peut le piloter finement depuis la HC3. Dans mon cas, mon onduleur a une puissance d’ondulation (AC) max de 5.2kW mais mes panneaux peuvent produire jusqu'à 8.2kW (DC). Donc les jours de plein soleil, j’ai intérêt à vider ma batterie sur le réseau en début de journée pour que quand la puissance des panneaux dépasse 5.2kW, l’excédent soit injecté directement dans la batterie qui elle se charge en DC. Sinon, ils sont perdus. Quand je veux forcer la décharge, je fixe une puissance mini de décharge. Et quand je veux éviter que ma batterie ne se charge trop vite (et ne puisse plus encaisser le surplus de production), je mets une puissance max de charge. Ceci est valable les jours de plein soleil car quand il fait gris, j’ai intérêt à maintenir la batterie totalement chargée. Ca, c’est ce à quoi je veux arriver, ce qui implique d’intégrer dans ma QA non seulement la partie Fronius mais aussi les prévisions météo couplées avec mon capteur de luminosité. Et effectivement, il faudra que je me penche sur la création des enfants pour créer ce qui manque dans le QA Fronius qui utilise l’API et pas le Modbus. Un autre avantage de Modbus, c’est qu’il est possible en un seul appel de récupérer l’entier des paramètres là où via l’API, il faut faire une requête par paramètre. Mais au final, je manque de temps en ce moment pour terminer totalement mon projet. En le rendant public, au moins le boulot de debug (les message d’erreur Modbus sont quasi inutilisables car en gros, il répond juste : « j’ai pas compris » dans le meilleur des cas, voire rien du tout tant que tout n’est pas parfaitement formaté. Pour la température de la batterie, je n'ai rien trouvé dans les registres de mon onduleur, mais peut être que selon les modèles, c'est dispo. La seul température que j'ai, c'est celle de l'onduleur qui est dans le bloc I160, adresse absolue de registre 42290.
flacon030 Posté(e) le 5 juillet 2023 Auteur Signaler Posté(e) le 5 juillet 2023 (modifié) Merci pour toutes ces informations Vivement le suite Pour info personnellement je suis en batterie BYD HVM de 11,6Kw avec 3Kwc de panneaux et avec un onduleur de 5Kw (fronius Symo hybride) Je pense que je vais rajouter 1Kwc de panneaux pour avoir la possibilité en été de climatiser la maison, car pour le moment je sui a 93% en autoconsommation et 89% en autosufisance avec le SPA l'eau chaude sanitaire et toute la maison, et les très belle journées avec la climatisation quant la production dépasse les 20Kw/h par jour Modifié le 5 juillet 2023 par flacon030
Messages recommandés