Calcul d'un pourcentage (autoconsommation) sur la base de deux devices

Forum dédié aux problématiques concernant les scripts pour DomoticZ.
Entourez votre code et les logs avec les balises nommées code grâce au bouton <\>.
Ayep
Messages : 4
Inscription : 06 août 2019, 15:50

Calcul d'un pourcentage (autoconsommation) sur la base de deux devices

Message par Ayep »

Bonjour,

Je sollicite votre aide pour calculer mon taux d'autoconsommation. J'ai :
- Ma conso "linky"
- Ma conso "photovoltaique"
- un cumul des deux (trouvé un script lua pour cela)

Mais je n'arrive pas à trouver une solution pour calculer mon pourcentage. Que me conseillez-vous? DZvents, lua, python, ou meme blocky?

Si quelqu'un à des pistes je suis preneur.

Merci par avance
Pièces jointes
Capture.PNG
Capture.PNG (41.25 Kio) Consulté 1855 fois
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

Re: Calcul d'un pourcentage (autoconsommation) sur la base de deux devices

Message par Keros »

Bonjour Ayep et bienvenu sur le forum ;)

Pour des calculs mathématiques, oublie tout de suite Blocky. Les scripts graphiques fonctionne pour faire des condition Oui / Non mais c'est très vite limité.

Après le Lua et le Dzvents sont similaires car, en fait, le DzVents est du LUA modifié en programmation orientée objet pour DomoticZ.
Python, c'est aussi possible mais c'est à l'extérieur de DomoticZ : il faudra faire des appels d'info et des envois d'infos.

Si tu as un script avec le cumul des deux, ce ne sera pas super compliquer de calculer le pourcentage. Détermine la formule en le faisant sur un papier et ensuite tu pourras modifier ton code en conséquence.

Si tu n'y arrives pas, regarde les liens dans ma signature : j'ai écrit des petits guides dont un a propos du débogage. Et si tu es bloqué, partage nous ton code et les logs d'erreurs que tu as.
Comment bien utiliser le forum : Poser une question, Mettre un script, un fichier, une image ou des logs
Mes petits guides : Débuter en programmation, Le débogage, Le choix de matériel, Les sauvegardes
Ma présentation - Mes Tutos
Ayep
Messages : 4
Inscription : 06 août 2019, 15:50

Re: Calcul d'un pourcentage (autoconsommation) sur la base de deux devices

Message par Ayep »

Bonjour,

Et merci! En effet, c'était en fait mon premier post sur le forum, en dépit d'une inscription plus ancienne :D

Alors, déjà je n'avais pas du tout pensé à recycler le lua actuel, et y intégrer le calcul de %. Merci, c'est un super début !

J'ai donc le code suivant :

Code : Tout sélectionner

-- Autoconsommation
-- Power consumption device script - SunnyBoy 20180523
--
-- Smart meters only measure net electricity consumption/production, i.e. 
-- Electricity consumption - Electricity production. This script subtracts 
-- electricity production from smart meter readings to get electricity 
-- consumption. It's triggered each time the smart meter or PV meter update.
--
-- 1. Create dummy hardware and device
-- 1.1 Go to Setup -> Hardware 
--     Name: anything, e.g. "Ele_Consumption" (this name is only used internally)
--     Type: "Dummy (does nothing, use for virtual switches only)"
-- 1.2 Click on 'Add'
-- 1.3 Click on 'Create Virtual Sensors' from the table of hardware above
--     Name: anything, e.g. "Power Consumption" (this name is displayed on the dashboard etc.)
--     Sensor type: "Electric (Instant+Counter)"
-- 1.4 Click 'Ok'
-- 2. Get name/id of relevant sensors
-- 2.1. Note down the name of your smart meter and solar meter devices (not hardware)
-- 2.2. Note the name and ID of your virtual sensor
-- 3. Update and copy the script below
-- 3.1. Update meter / sensor names
-- 3.2. Go to Setup -> More Options -> Events
-- 3.3. Enter name (e.g. PowerConsumption), Select 'Lua' and 'Device'
-- 3.4. Toggle event active, save
-- 4. Update utility/dashboard accordingly

commandArray = {}
debug = false

-- for debugging, use this file
if (debug) then
    file = io.open("/home/pi/lua_test.log", "a") -- append
end

-- Update these lines before use
smartmeter = "Linky" -- name of smart meter device
solarmeter = "Solar" -- name of solar meter device
dummymeter = "Power" -- name of virtual sensor
dummyautoconso = "Autoconsommation" --Dummy sensor to get the % Autoconsommation
dummymeter_id = 192 -- ID of virtual sensor
dummyautoconso_id = 191
dummymeter_trigger = solarmeter -- name of the meter to trigger the dummy meter update. Use the slowest meter here: if your smart meter updates every 10 sec and PV every 100 sec, you get 9 values using potentially outdated PV data. In my case cloudy days gave negative consumption because of this.


function Round1(num, dec)
    return tonumber(string.format("%." ..(dec or 0).. "f", num or 0))
end

-- debug to check what devices are named (but better use 'Show current states' in
-- online editor)
if (debug) then
    file:write('other devices states:\n')
    for i, v in pairs(otherdevices) do file:write(i, v) end
    file:write("\n")
    file:write('other devices svalues:\n')
    for i, v in pairs(otherdevices_svalues) do file:write(i, v) end
    file:write("\n")
end

-- loop through all the changed devices, only update during day if solar meter
-- is triggered, or during the night if smart meter is triggered.
for deviceName,deviceValue in pairs(devicechanged) do
    if (debug) then
        file:write("Device based event fired on '"..deviceName.."', value '"..tostring(deviceValue).."'\n");
    end
    
    -- Looks like: Device based event fired on 'Power (net)', value '2058750;1175597;790812;1911744;251;0'
    -- Syntax: USAGE1;USAGE2;RETURN1;RETURN2;CONS;PROD https://www.domoticz.com/wiki/Domoticz_API/JSON_URL's#Electricity_P1_smart_meter
    -- Counter: T1: 2058.750, T2: 1175.671
    -- Counter Return: R1: 790.812, R2: 1911.744
    -- Or: Device based event fired on 'Solar Power', value '0.000;3755165.000'
    -- Counter: 3755.165
    -- Time of script consumption counter: 2058.750 + 1175.671 + 3755.165 - 790.812 - 1911.744
    if (deviceName == solarmeter and timeofday['Daytime']) or (deviceName == smartmeter and timeofday['Nighttime']) then
        -- Smart meter: Match six integers separated by semicolum
        -- first four are energy meters, last two are power meters?
        smart_e1, smart_e2, smart_e3, smart_e4, smart_p1, smart_p2 = otherdevices_svalues[smartmeter]:match("([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);([^;]+)")
        -- Solar meter power;counter: 0.000;3755165.000
        solar_p, solar_e = otherdevices_svalues[solarmeter]:match("([^;]+);([^;]+)")
        
        -- Calculate power consumption and update dummy device. Consumption is 
        -- always positive, so we add our solar power to the smart meter power
        -- if solar generates 1kW, smart meter shows -0.5kW, real consumption is 0.5kW (=solar - return)
        -- if solar generates 1kW, smart meter shows 0.5kW, real consumption is 1.5kW (=solar + consumption)
        consumption_p = smart_p1 + solar_p - smart_p2
        consumption_e = smart_e1 + smart_e2 + solar_e - smart_e3 - smart_e4
        autoconso = solar_e / consumption_e * 100  --ratio = device 164/192 
        
        -- Populate commandArray with update command
        commandArray[1] = {['UpdateDevice'] = dummymeter_id .. "|0|" .. Round1(consumption_p,0) .. ";" .. Round1(consumption_e,1)}
        commandArray[1] = {['UpdateDevice'] = dummyautoconso_id .. "|0|" .. Round1(autoconso,0)}
        if (debug) then
            file:write("Update device".. dummymeter_id .. "|0|" .. consumption_p .. ";" .. consumption_e .. "\n");
        end
    end
end

if (debug) then
    file:close()
end

return commandArray
Mais j'obtiens pour le moment :

Code : Tout sélectionner

2022-02-24 16:17:32.956 Error: EventSystem: in Power_consumption: [string "-- Autoconsommation..."]:63: bad argument #1 to 'pairs' (table expected, got nil)
J'ai cassé le script d'origine :D

Merci des conseils !
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

Re: Calcul d'un pourcentage (autoconsommation) sur la base de deux devices

Message par Keros »

J'ai du mal à lire ton script, car il y a des espaces utilisés dans le nom des variables : ça fonctionne peut-être (je n'ai jamais testé) mais cela ne rend pas la lecture facile. Généralement, je mets des - ou des _

En LUA, tu ne peux avoir deux commandArray[] identique. Pour ta deuxième ligne que tu as ajoutée, il faut que tu change le 1 par un 2 par exemple)

Est-ce que ton widget dummyautoconso est du même type que le widget dummymeter ? Si oui, tu devrais avoir une commande avec les mêmes infos. J'ai l'impression qu'il en manque.

Il faudrait que tu fasses du débogage pour vérifier les différentes étapes de ton programme. Regarde les liens dans ma signature, j'ai écrit des petits guides dont un à propos du débogage. Vérifie en premier que ton programme s'exécute et calcul le bon pourcentage et, dans un deuxième temps, attaque-toi à envoyer cette valeur dans le widget.
Comment bien utiliser le forum : Poser une question, Mettre un script, un fichier, une image ou des logs
Mes petits guides : Débuter en programmation, Le débogage, Le choix de matériel, Les sauvegardes
Ma présentation - Mes Tutos
denis_brasseur
Messages : 898
Inscription : 24 déc. 2018, 17:05
Localisation : (26)

Re: Calcul d'un pourcentage (autoconsommation) sur la base de deux devices

Message par denis_brasseur »

Quel est le type de ton script ? device ou time ? Pour utiliser deviceChanged, le script doit être de type device.
Pi3 + DD PiDrive - RFXtrx433 - AEON Labs ZW090
Ayep
Messages : 4
Inscription : 06 août 2019, 15:50

Re: Calcul d'un pourcentage (autoconsommation) sur la base de deux devices

Message par Ayep »

Bonjour,
Merci des réponses.
J'ai du mal à lire ton script, car il y a des espaces utilisés dans le nom des variables : ça fonctionne peut-être (je n'ai jamais testé) mais cela ne rend pas la lecture facile. Généralement, je mets des - ou des _
Je n'ai pas trouvé ces variables, il me semble qu'elles ont justement un "_" ; en tout cas totalement d'accord, tout comme les minuscules, j'essaie de rester sur ces bases. Après ce script à la base vient d'ici :
https://www.domoticz.com/wiki/Virtual_meter

En LUA, tu ne peux avoir deux commandArray[] identique. Pour ta deuxième ligne que tu as ajoutée, il faut que tu change le 1 par un 2 par exemple)
Merci! En effet, première boulette :D
Est-ce que ton widget dummyautoconso est du même type que le widget dummymeter ? Si oui, tu devrais avoir une commande avec les mêmes infos. J'ai l'impression qu'il en manque.
Tu as raison ; le device "Power" est un device de type (Electric: Instant+Counter). Le device "Autoconsommation" est pour le moment de type "Percentage". Du coup à voir ce qui est inadapté ici, soit mon code, soit mon type de device.
Il faudrait que tu fasses du débogage pour vérifier les différentes étapes de ton programme. Regarde les liens dans ma signature, j'ai écrit des petits guides dont un à propos du débogage. Vérifie en premier que ton programme s'exécute et calcul le bon pourcentage et, dans un deuxième temps, attaque-toi à envoyer cette valeur dans le widget.
Merci, c'est de très bons conseils. Je vais prendre le temps de commencer à apprendre à débogger cet après-midi.
Quel est le type de ton script ? device ou time ? Pour utiliser deviceChanged, le script doit être de type device.
@denis_brasseur : merci, initialement de type "Trigger" = Device, j'ai du faire une fausse manip, ce matin il était en "All"... Ca n'a peut-être pas aidé.

Désolé pour les termes en anglais, mon installation est ainsi :D

Merci encore à vous pour vos idées, je vous tiens informés.
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

Re: Calcul d'un pourcentage (autoconsommation) sur la base de deux devices

Message par Keros »

Ayep a écrit : 25 févr. 2022, 12:35 Tu as raison ; le device "Power" est un device de type (Electric: Instant+Counter). Le device "Autoconsommation" est pour le moment de type "Percentage". Du coup à voir ce qui est inadapté ici, soit mon code, soit mon type de device.
Non, non c'est bon, reste sur le type pourcentage. Avec le débogage, tu devrais pourvoir vérifier que le calcul est correct et ensuite vérifier que ta fonction pour mettre à jour le device pourcentage est bonne.
Comment bien utiliser le forum : Poser une question, Mettre un script, un fichier, une image ou des logs
Mes petits guides : Débuter en programmation, Le débogage, Le choix de matériel, Les sauvegardes
Ma présentation - Mes Tutos
Ayep
Messages : 4
Inscription : 06 août 2019, 15:50

Re: Calcul d'un pourcentage (autoconsommation) sur la base de deux devices

Message par Ayep »

Alors, les news :

- la fonction de mise à jour semblait bien fonctionner. J'ai enlevé la fonction "round", et là on voyait bien le taux qui évoluait, mais trèees légèrement/lentement. Me suis donc dis qu'il s'agissait d'un problème de variable "cumulative", et non d'un taux à un instant t.

Bingo, en fouinant dans le code, j'avais pris les variables "energie" et non "puissance" pour mes calculs... D'où les évolutions très lentes.

Voici donc ce que ça donne, pour ceux que ça intéresse :
Capture.PNG
Capture.PNG (34.18 Kio) Consulté 1764 fois

Code : Tout sélectionner

-- Autoconsommation
-- Power consumption device script - SunnyBoy 20180523
--
-- Smart meters only measure net electricity consumption/production, i.e. 
-- Electricity consumption - Electricity production. This script subtracts 
-- electricity production from smart meter readings to get electricity 
-- consumption. It's triggered each time the smart meter or PV meter update.
--
-- 1. Create dummy hardware and device
-- 1.1 Go to Setup -> Hardware 
--     Name: anything, e.g. "Ele_Consumption" (this name is only used internally)
--     Type: "Dummy (does nothing, use for virtual switches only)"
-- 1.2 Click on 'Add'
-- 1.3 Click on 'Create Virtual Sensors' from the table of hardware above
--     Name: anything, e.g. "Power Consumption" (this name is displayed on the dashboard etc.)
--     Sensor type: "Electric (Instant+Counter)"
-- 1.4 Click 'Ok'
-- 2. Get name/id of relevant sensors
-- 2.1. Note down the name of your smart meter and solar meter devices (not hardware)
-- 2.2. Note the name and ID of your virtual sensor
-- 3. Update and copy the script below
-- 3.1. Update meter / sensor names
-- 3.2. Go to Setup -> More Options -> Events
-- 3.3. Enter name (e.g. PowerConsumption), Select 'Lua' and 'Device'
-- 3.4. Toggle event active, save
-- 4. Update utility/dashboard accordingly

commandArray = {}
debug = false

-- for debugging, use this file
if (debug) then
    file = io.open("/home/pi/lua_test.log", "a") -- append
end

-- Update these lines before use
smartmeter = "Linky" -- name of smart meter device
solarmeter = "Solar" -- name of solar meter device
dummymeter = "Power" -- name of virtual sensor
dummyautoconso = "Autoconsommation" --Dummy sensor to get the % Autoconsommation
dummymeter_id = 192 -- ID of virtual sensor
dummyautoconso_id = 191
dummymeter_trigger = solarmeter -- name of the meter to trigger the dummy meter update. Use the slowest meter here: if your smart meter updates every 10 sec and PV every 100 sec, you get 9 values using potentially outdated PV data. In my case cloudy days gave negative consumption because of this.


function Round1(num, dec)
    return tonumber(string.format("%." ..(dec or 0).. "f", num or 0))
end

-- debug to check what devices are named (but better use 'Show current states' in
-- online editor)
if (debug) then
    file:write('other devices states:\n')
    for i, v in pairs(otherdevices) do file:write(i, v) end
    file:write("\n")
    file:write('other devices svalues:\n')
    for i, v in pairs(otherdevices_svalues) do file:write(i, v) end
    file:write("\n")
end

-- loop through all the changed devices, only update during day if solar meter
-- is triggered, or during the night if smart meter is triggered.
for deviceName,deviceValue in pairs(devicechanged) do
    if (debug) then
        file:write("Device based event fired on '"..deviceName.."', value '"..tostring(deviceValue).."'\n");
    end
    
    -- Looks like: Device based event fired on 'Power (net)', value '2058750;1175597;790812;1911744;251;0'
    -- Syntax: USAGE1;USAGE2;RETURN1;RETURN2;CONS;PROD https://www.domoticz.com/wiki/Domoticz_API/JSON_URL's#Electricity_P1_smart_meter
    -- Counter: T1: 2058.750, T2: 1175.671
    -- Counter Return: R1: 790.812, R2: 1911.744
    -- Or: Device based event fired on 'Solar Power', value '0.000;3755165.000'
    -- Counter: 3755.165
    -- Time of script consumption counter: 2058.750 + 1175.671 + 3755.165 - 790.812 - 1911.744
    if (deviceName == solarmeter and timeofday['Daytime']) or (deviceName == smartmeter and timeofday['Nighttime']) then
        -- Smart meter: Match six integers separated by semicolum
        -- first four are energy meters, last two are power meters?
        smart_e1, smart_e2, smart_e3, smart_e4, smart_p1, smart_p2 = otherdevices_svalues[smartmeter]:match("([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);([^;]+)")
        -- Solar meter power;counter: 0.000;3755165.000
        solar_p, solar_e = otherdevices_svalues[solarmeter]:match("([^;]+);([^;]+)")
        
        -- Calculate power consumption and update dummy device. Consumption is 
        -- always positive, so we add our solar power to the smart meter power
        -- if solar generates 1kW, smart meter shows -0.5kW, real consumption is 0.5kW (=solar - return)
        -- if solar generates 1kW, smart meter shows 0.5kW, real consumption is 1.5kW (=solar + consumption)
        consumption_p = smart_p1 + solar_p - smart_p2
        consumption_e = smart_e1 + smart_e2 + solar_e - smart_e3 - smart_e4
        autoconso = solar_p / consumption_p * 100  --ratio = device 164/192 
        
        -- Populate commandArray with update command
        commandArray[1] = {['UpdateDevice'] = dummymeter_id .. "|0|" .. Round1(consumption_p,0) .. ";" .. Round1(consumption_e,1)}
        --commandArray[2] = {['UpdateDevice'] = dummyautoconso_id .. "|0|" .. autoconso}
        commandArray[2] = {['UpdateDevice'] = dummyautoconso_id .. "|0|" .. Round1(autoconso,0)}
        if (debug) then
            file:write("Update device".. dummymeter_id .. "|0|" .. consumption_p .. ";" .. consumption_e .. "\n");
        end
    end
end

if (debug) then
    file:close()
end

return commandArray
Donc là, j'ai mon % en temps réel. En revanche des idées pour avoir un suivi quotidien qui s'affiche en plus? Un peu comme le compteur energie, qui a le nombre de kWh de la journée en dessous? Cela pourrait etre une moyenne du % journalier qui évolue...

Merci à vous !
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

Re: Calcul d'un pourcentage (autoconsommation) sur la base de deux devices

Message par Keros »

Bravo tu y es arrivé !!

Tu peux essayer un type General Custom Sensor. Tu auras les valeurs par palier de 5 minutes sur les 7 derniers jours, Le mini + moyenne + maxi journalier jour le mois en cours et l'année en cours. Par contre, pas historique plus loin (année précédente).
Comment bien utiliser le forum : Poser une question, Mettre un script, un fichier, une image ou des logs
Mes petits guides : Débuter en programmation, Le débogage, Le choix de matériel, Les sauvegardes
Ma présentation - Mes Tutos
Répondre