Script coût électricité ne fonctionne plus suite à MAJ

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 <\>.
val
Messages : 27
Inscription : 29 déc. 2021, 02:49

Script coût électricité ne fonctionne plus suite à MAJ

Message par val »

Bonjour à tous, je besoin de votre aide concernant un petit problème suite à une grosse MAJ de mon installation :

- Premièrement MAJ de Domoticz de la V2021.1 vers la V2024.7
- Ensuite MAJ de Buster vers Bookworm
- Migration de OZW vers Z-Wave-js-ui

J'ai eu quelques soucis avec la migration du Zwave mais dans l'ensemble tout s'est bien passé sauf un script que j'avais qui ne fonctionne plus malgré qu j'ai remplacé les appels API vers la nouvelle version, ce script sert à calculer le coût électrique journalier.

La version initiale de ce script ici :

Code : Tout sélectionner

--[[
            put today's electricity and / or today's Gas usage costs in custom virtual sensor
            Collect information from a P1 device and /or a Gas device
            electricity takes different tariffs and returns (from solarpanels or the likes) into account.
            
]]--

local scriptVar = "dailyEnergyCost"

return  {
            on = { timer = { "every 6 minutes" },           -- using 6 minutes because Stroom and Gas are updated very frequently
                   httpResponses = { scriptVar .. "*" },
        },

        logging = { level   =   domoticz.LOG_DEBUG,    -- change to LOG_ERROR when script executes OK
                    marker  =   sciptVar},

        data =  { energyCosts = { initial = {} }
                },

    execute = function(dz, item)
        --  ********************************************************************* Your changes below this line *************
        -- input Devices
        local electricity = dz.devices("Power") -- P1 device or comment this line
        local gas = dz.devices("Gas") -- Gas meter or comment this line
        
        -- outPut Devices
        local electricityCost = dz.devices("electricityCost today") -- define this virtual sensor as Custom sensor or comment this line when not used
        local gasCost = dz.devices("gasCost today")   -- define this virtual sensor as Custom sensor or comment this line when not used
        
        -- fixed Transport + contract costs per month in Euro's
        local electricityFixedMonth = 6.31 
        local gasFixedMonth = 6.31 
        --      ********************************************************************** No changes below this line **************

        local function getDaysForMonth(month, year)       -- Returns number of days in given or current month
            if month == nil then month = dz.time.month end
            if year == nil then year = dz.time.year end
            return os.date('*t',os.time{year=year,month=month+1,day=0}).day
        end

        local function triggerJSON(url, response, delay)
            local delay = delay or 0
            dz.openURL({    url = url,
                            method = "GET",
                            callback = response}).afterSec(delay)
        end
        
        local function getCosts(id) -- these costs should be set in domoticz settings
            if next(dz.data.energyCosts) == nil  or dz.data.energyCosts.creationTime < ( dz.time.dDate - dz.time.secondsSinceMidnight ) then
                local costURL = dz.settings['Domoticz url'] .. "/json.htm?param=getcosts&type=command&idx=" .. id
                triggerJSON(costURL, scriptVar .. "_cost")
            end
            return ( next(dz.data.energyCosts) ~= nil )
        end
        
        local function makeCostTable(t) -- (re)Create costTable if not existing yet; Refreshed at least once a day
            if next( dz.data.energyCosts ) == nil or dz.data.energyCosts.creationTime < ( dz.time.dDate - dz.time.secondsSinceMidnight ) then
                dz.data.energyCosts = t
                dz.data.energyCosts.electricityFixedDay  = (electricityFixedMonth or 0 ) / getDaysForMonth()
                dz.data.energyCosts.gasFixedDay  = (gasFixedMonth or 0 ) / getDaysForMonth()
                dz.data.energyCosts.creationTime = dz.time.dDate
                dz.data.energyCosts.humanReadableCreationTime = dz.time.raw
            end
        end
        
        local function updateCustomSensor(device, value) 
            local currentValue = device.rawData[1]
            if value ~= tonumber(currentValue) then              -- Update only needed when new value is different fom previous one 
                dz.log(device.name .. " ==>> previous value: " .. currentValue .. " ; new value " .. value,dz.LOG_DEBUG)
                device.updateCustomSensor(value) 
            end
        end
        
        local function getEnergy(id)
            local energyURL = dz.settings['Domoticz url'] .. "/json.htm?range=month&sensor=counter&type=graph" ..
                                "&actmonth=" .. dz.time.month ..
                                "&idx=" .. id
                triggerJSON(energyURL, scriptVar .. "_energy")
        end
        
        local function makeTodaysGasCosts()
            local gasTodayCost
            if gasCost then
                gasTodaysCost = dz.data.energyCosts.gasFixedDay * 10000
                gasTodaysCost = gasTodaysCost + gas.counterToday * dz.data.energyCosts.CostGas
            end
           return dz.utils.round(gasTodaysCost / 10000, 2)
        end
        
        local function makeTodaysElectricityCosts(t)
            local today
            for i, record in ipairs(t) do
                if record.d == dz.time.rawDate then
                    today = i
                end
            end
            
            local electricityTodaysCost
            if electricityCost then 
                electricityTodaysCost = dz.data.energyCosts.electricityFixedDay * 10000
                if today then 
                    electricityTodaysCost = electricityTodaysCost + t[today].v * dz.data.energyCosts.CostEnergy
                    electricityTodaysCost = electricityTodaysCost + t[today].v2 * dz.data.energyCosts.CostEnergyT2
                    electricityTodaysCost = electricityTodaysCost - t[today].r1 * dz.data.energyCosts.CostEnergyR1
                    electricityTodaysCost = electricityTodaysCost - t[today].r2 * dz.data.energyCosts.CostEnergyR2
                end
            end
           
           return dz.utils.round(electricityTodaysCost / 10000,2) 
        end
        
        local function updateCustomSensor(device, value)
            if device == nil or value == nil then
                return 
            end
            local currentValue = device.rawData[1]
            if value ~= tonumber(currentValue) then              -- Update only needed when new value is different fom previous one 
                dz.log(device.name .. " ==>> previous value: " .. currentValue .. " ; new value " .. value,dz.LOG_DEBUG)
                device.updateCustomSensor(value) 
            end
        end
        
        if not ( item.isHTTPResponse ) then
            if not ( getCosts(electricity.id) ) then 
                -- logWrite("No or outdated costs. Next time the costs will be there")
                return 
            end 
            -- logWrite("-- costs are there; get energy data")
            getEnergy(electricity.id)
        elseif item.trigger == ( scriptVar .. "_energy" ) then
            updateCustomSensor( electricityCost, makeTodaysElectricityCosts(item.json.result))
            updateCustomSensor( gasCost, makeTodaysGasCosts())
        else
            makeCostTable(item.json)
        end
    end
}
Le mien modifié avec les nouveaux appels API :

Code : Tout sélectionner

--[[
            put today's electricity and / or today's Gas usage costs in custom virtual sensor
            Collect information from a P1 device and /or a Gas device
            electricity takes different tariffs and returns (from solarpanels or the likes) into account.
            
]]--

local scriptVar = "dailyEnergyCost"

return  {
            on = { timer = { "every minute" },           -- using 6 minutes because Stroom and Gas are updated very frequently
                   httpResponses = { scriptVar .. "*" },
        },

        logging = { level   =   domoticz.LOG_DEBUG,    -- change to LOG_ERROR when script executes OK
                    marker  =   sciptVar},

        data =  { energyCosts = { initial = {} }
                },

    execute = function(dz, item)
        --  ********************************************************************* Your changes below this line *************
        -- input Devices
        local electricity = dz.devices("Puissance Instantanée") -- P1 device or comment this line
        --local gas = dz.devices("Gas") -- Gas meter or comment this line
        
        -- outPut Devices
        local electricityCost = dz.devices("Tarif Journalier") -- define this virtual sensor as Custom sensor or comment this line when not used
        --local gasCost = dz.devices("gasCost today")   -- define this virtual sensor as Custom sensor or comment this line when not used
        
        -- fixed Transport + contract costs per month in Euro's
        local electricityFixedMonth = 17.27 
        --local gasFixedMonth = 6.31 
        --      ********************************************************************** No changes below this line **************

        local function getDaysForMonth(month, year)       -- Returns number of days in given or current month
            if month == nil then month = dz.time.month end
            if year == nil then year = dz.time.year end
            return os.date('*t',os.time{year=year,month=month+1,day=0}).day
        end

        local function triggerJSON(url, response, delay)
            local delay = delay or 0
            dz.openURL({    url = url,
                            method = "GET",
                            callback = response}).afterSec(delay)
        end
        
        local function getCosts(id) -- these costs should be set in domoticz settings
            if next(dz.data.energyCosts) == nil  or dz.data.energyCosts.creationTime < ( dz.time.dDate - dz.time.secondsSinceMidnight ) then
                local costURL = dz.settings['Domoticz url'] .. "/json.htm?param=getcosts&type=command&param=idx=" .. id
                triggerJSON(costURL, scriptVar .. "_cost")
            end
            return ( next(dz.data.energyCosts) ~= nil )
        end
        
        local function makeCostTable(t) -- (re)Create costTable if not existing yet; Refreshed at least once a day
            if next( dz.data.energyCosts ) == nil or dz.data.energyCosts.creationTime < ( dz.time.dDate - dz.time.secondsSinceMidnight ) then
                dz.data.energyCosts = t
                dz.data.energyCosts.electricityFixedDay  = (electricityFixedMonth or 0 ) / getDaysForMonth()
                dz.data.energyCosts.gasFixedDay  = (gasFixedMonth or 0 ) / getDaysForMonth()
                dz.data.energyCosts.creationTime = dz.time.dDate
                dz.data.energyCosts.humanReadableCreationTime = dz.time.raw
            end
        end
        
        local function updateCustomSensor(device, value) 
            local currentValue = device.rawData[1]
            if value ~= tonumber(currentValue) then              -- Update only needed when new value is different fom previous one 
                dz.log(device.name .. " ==>> previous value: " .. currentValue .. " ; new value " .. value,dz.LOG_DEBUG)
                device.updateCustomSensor(value) 
            end
        end
        
        local function getEnergy(id)
            local energyURL = dz.settings['Domoticz url'] .. "/json.htm?range=month&sensor=counter&type=command&param=graph" ..
                                "&actmonth=" .. dz.time.month ..
                                "&idx=" .. id
                triggerJSON(energyURL, scriptVar .. "_energy")
        end
        
        local function makeTodaysGasCosts()
            local gasTodayCost
            if gasCost then
                gasTodaysCost = dz.data.energyCosts.gasFixedDay * 10000
                gasTodaysCost = gasTodaysCost + gas.counterToday * dz.data.energyCosts.CostGas
            end
           return dz.utils.round(gasTodaysCost / 10000, 2)
        end
        
        local function makeTodaysElectricityCosts(t)
            local today
            for i, record in ipairs(t) do
                if record.d == dz.time.rawDate then
                    today = i
                end
            end
            
            local electricityTodaysCost
            if electricityCost then 
                electricityTodaysCost = dz.data.energyCosts.electricityFixedDay * 10000
                if today then 
                    electricityTodaysCost = electricityTodaysCost + t[today].v * dz.data.energyCosts.CostEnergy
                    electricityTodaysCost = electricityTodaysCost + t[today].v2 * dz.data.energyCosts.CostEnergyT2
                    electricityTodaysCost = electricityTodaysCost - t[today].r1 * dz.data.energyCosts.CostEnergyR1
                    electricityTodaysCost = electricityTodaysCost - t[today].r2 * dz.data.energyCosts.CostEnergyR2
                end
            end
           
           return dz.utils.round(electricityTodaysCost / 10000,2) 
        end
        
        local function updateCustomSensor(device, value)
            if device == nil or value == nil then
                return 
            end
            local currentValue = device.rawData[1]
            if value ~= tonumber(currentValue) then              -- Update only needed when new value is different fom previous one 
                dz.log(device.name .. " ==>> previous value: " .. currentValue .. " ; new value " .. value,dz.LOG_DEBUG)
                device.updateCustomSensor(value) 
            end
        end
        
        if not ( item.isHTTPResponse ) then
            if not ( getCosts(electricity.id) ) then 
                -- logWrite("No or outdated costs. Next time the costs will be there")
                return 
            end 
            -- logWrite("-- costs are there; get energy data")
            getEnergy(electricity.id)
        elseif item.trigger == ( scriptVar .. "_energy" ) then
            updateCustomSensor( electricityCost, makeTodaysElectricityCosts(item.json.result))
            updateCustomSensor( gasCost, makeTodaysGasCosts())
        else
            makeCostTable(item.json)
        end
    end
}
Et le message d'erreur dans les logs de Domoticz :
2025-04-27 01:09:00.418 dzVents: ------ Start internal script: Coût electricité journalier:, trigger: "every minute"
2025-04-27 01:09:00.446 dzVents: Debug: Processing device-adapter for Puissance Instantanée: P1 smart meter energy device adapter
2025-04-27 01:09:00.449 dzVents: Debug: Processing device-adapter for Tarif Journalier: Custom sensor device adapter
2025-04-27 01:09:00.449 dzVents: Debug: OpenURL: url = http://127.0.0.1:8080/json.htm?range=mo ... h=4&idx=67
2025-04-27 01:09:00.449 dzVents: Debug: OpenURL: method = GET
2025-04-27 01:09:00.449 dzVents: Debug: OpenURL: post data = nil
2025-04-27 01:09:00.449 dzVents: Debug: OpenURL: headers = nil
2025-04-27 01:09:00.449 dzVents: Debug: OpenURL: callback = dailyEnergyCost_energy
2025-04-27 01:09:00.451 dzVents: ------ Finished Coût electricité journalier
2025-04-27 01:09:01.091 dzVents: ------ Start internal script: Coût electricité journalier: HTTPResponse: "dailyEnergyCost_energy"
2025-04-27 01:09:01.109 dzVents: Debug: Processing device-adapter for Tarif Journalier: Custom sensor device adapter
2025-04-27 01:09:01.109 Error: dzVents: An error occurred when calling event handler Coût electricité journalier
2025-04-27 01:09:01.110 Error: dzVents: ...ents/generated_scripts/Coût electricité journalier.lua:103: attempt to perform arithmetic on a nil value (field 'v')
2025-04-27 01:09:01.110 dzVents: ------ Finished Coût electricité journalier
Si quelqu'un peut m'aider à régler ce problême ou un autre script proposant la même fonction, je suis preneur.

Merci
Dernière modification par Keros le 27 avr. 2025, 13:38, modifié 1 fois.
Raison : Modification des balises pour le code
gaston
Messages : 155
Inscription : 16 avr. 2019, 20:30

Re: Script coût électricité ne fonctionne plus suite à MAJ

Message par gaston »

Elo,

En effet, un sacré bond en monté de version, ce qui a induit pour ton script des modifs au niveau de tes commandes, mais je pense à autre truc qui a changé sur les versions "récentes" c'est la notion de réseau de confiance dans l'onglet "sécurité" des paramètres.
Certains "trucs" fonctionnent mal si ce champ n'est pas renseigné. Il faudrait, au minimum, ajouter l’hôte local, dans mon cas, j'ai aussi indiqué mon réseau local, ce qui donne ceci:

Code : Tout sélectionner

127.0.0.1;192.168.25.*
Le symbole "*" à la fin n'est pas pour cacher une adresse mais pour prendre toutes les adresses de la plage réseau.
higgins91
Messages : 668
Inscription : 17 nov. 2016, 11:06

Re: Script coût électricité ne fonctionne plus suite à MAJ

Message par higgins91 »

2025-04-27 01:09:01.110 Error: dzVents: ...ents/generated_scripts/Coût electricité journalier.lua:103: attempt to perform arithmetic on a nil value (field 'v')
à la ligne 103, tu as un calcul avec une valeur nulle. Regarde ta formule et affiche les valeurs avant calcul dans les logs pour débugguer...
Dz version : 2023.2
Rpi 4 avec dongle téléinfo, RFXCom, sondes 1-wire et GPIO
gaston
Messages : 155
Inscription : 16 avr. 2019, 20:30

Re: Script coût électricité ne fonctionne plus suite à MAJ

Message par gaston »

2025-04-27 01:09:00.449 dzVents: Debug: OpenURL: url = http://127.0.0.1:8080/json.htm?range=mo ... h=4&idx=67
Comme j'ai vu ça, je me suis dis que le script n'est pas autorisé à lire un truc donc "nil value" et ça fout le bordel pour la suite du calcul => faire un tour du coté sécurité, ça coûte rien.
val
Messages : 27
Inscription : 29 déc. 2021, 02:49

Re: Script coût électricité ne fonctionne plus suite à MAJ

Message par val »

gaston a écrit : 27 avr. 2025, 10:17 Elo,

En effet, un sacré bond en monté de version, ce qui a induit pour ton script des modifs au niveau de tes commandes, mais je pense à autre truc qui a changé sur les versions "récentes" c'est la notion de réseau de confiance dans l'onglet "sécurité" des paramètres.
Certains "trucs" fonctionnent mal si ce champ n'est pas renseigné. Il faudrait, au minimum, ajouter l’hôte local, dans mon cas, j'ai aussi indiqué mon réseau local, ce qui donne ceci:

Code : Tout sélectionner

127.0.0.1;192.168.25.*
Le symbole "*" à la fin n'est pas pour cacher une adresse mais pour prendre toutes les adresses de la plage réseau.
Bonjour, de ce coté la tout est bon
higgins91 a écrit : 27 avr. 2025, 13:23
2025-04-27 01:09:01.110 Error: dzVents: ...ents/generated_scripts/Coût electricité journalier.lua:103: attempt to perform arithmetic on a nil value (field 'v')
à la ligne 103, tu as un calcul avec une valeur nulle. Regarde ta formule et affiche les valeurs avant calcul dans les logs pour débugguer...
Bonjour, j'avais bien vu que le problème venait de la ligne 103. Je pense qu'avec la nouvelle version de Domoticz le script n'arrive plus à récupérer le prix du kWh dans les paramètres.
Seulement voilà, j'ai toujours utilisé des scripts tout prêt et je suis incapable de déboguer ça tout seul, c'est pour ça que je viens solliciter votre aide.

Merci de vos réponses
val
Messages : 27
Inscription : 29 déc. 2021, 02:49

Re: Script coût électricité ne fonctionne plus suite à MAJ

Message par val »

Toujours le même problème avec la V2025.1, personne n'a d'idées ?

Merci
Répondre