Domoberry wrote: Thursday 19 October 2023 10:10
BTW is there a Domoticz device possible related to exceeding the max usage set?
At the time, there is nothing. Even the power-meter devices curves max figures are mostly false/underestimated: Only samples every 5mn make their way in DB records & so graphs, so you must be very lucky to sample a real max for the 5mn time slice!
On a single phase contract, I have a script that drives a virtual power-meter that records real max on a 10mn slice base (+ also a mean that's doing discrete power samples integration over time, as the device does not compute mean values itself ; that's IMO a better representation of real power drain over time). That's the only way I found to be able to monitor real max power figures, to avoid going over my 9kW contract & risk a power cut from electricity provider metering device.
You already have a script that warns you, if that's enough keep it. If you want to also record each phase true maximums (& get rid of means if not needed) you may triple my setup!
Single phase power meter is to change in devSmartMeterPwr string name for yours.
Script needs creating virtual meters devMeanPwrVrtSen for mean, devPeakPwrVrtSen for max and associated user variables that stores some data between this device type script calls (resp. varPwrSum/varPwrLast).
You can also see there is a max handling here: maxPeakPwr, that's here set for 13kW in my case (that's over my 9kW contrcat but there may be a delay in overconsumption management that shuts heavy consumers automatically & there is a overpower tolerance of 10% and some time tolerance as well to allow controlled devices shutdowns).
If this max (independant from domoticz setup) is reached, value is not recorded (considered a bad/spurious one) and a line is printed in logs (but you may send a notification/mail...).
Code: Select all
-- Smart-Meter Mean : Per 10mn/600s "targetted" time slice mean power consumption
-- Only use slices > 5mn Domoticz log/graph record time in DB or some values
-- will be overwritten! Time slice is a target value that may be exceeded by
-- last measurement delay that may be minimised by increasing device reports.
devSmartMeterPwr='SmartMeter W' -- Real PWR consumtion measurement device name.
devMeanPwrVrtSen='Puissance MOY' -- Virtual sensor type "usage/electricity" name.
varPwrSum='pwrSum' -- User variable, decimal/float type, storing current time slice power ~integral.
varPwrLast='pwrLast' -- User variable, decimal/float type, storing last pwr watt value.
maxLastUpdateVrt=600 -- Virtual sensor update rate.
maxPeakPwr=13000 -- Device limit is 63A, measures exceeding are filtered.
-- Smart-Meter Peak : Per 10mn/600s time slice max peak power consumption recorder.
-- Only use slices > 5mn (see above).
-- Max update always done immediately (i.e. before current time slice end) so
-- the virtual sensor fed by this script may be used to switch some devices off
-- to prevent overloads.
devPeakPwrVrtSen='Puissance MAX' -- Virtual sensor type "electricity" name
--
-- END : User editabe settings.
--
commandArray = {}
--
-- Internal fct :
-- Get current script exec time & compute last 'device' or 'uservariable' update time.
--
local function timeLastUpdate(devOrVar, isUserVar)
t1 = os.time()
if (isUserVar == true) then
sT0 = uservariables_lastupdate[devOrVar]
else
sT0 = otherdevices_lastupdate[devOrVar]
end
-- Returns a date time like 2016-12-02 15:30:10
-- => Format as os.time & compute diff :
year = string.sub(sT0, 1, 4)
month = string.sub(sT0, 6, 7)
day = string.sub(sT0, 9, 10)
hour = string.sub(sT0, 12, 13)
minutes = string.sub(sT0, 15, 16)
seconds = string.sub(sT0, 18, 19)
t0 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
tDiff = os.difftime(t1, t0)
return(tDiff)
end
--
-- Update virtual sensor
--
local function updateNum(dev, value1)
local cmd = string.format("%d|0|%d", otherdevices_idx[dev], math.floor(value1))
table.insert (commandArray, { ['UpdateDevice'] = cmd } )
end
--
-- MAIN
--
-- Smart-Meter Mean/Peak :
if (devicechanged[devSmartMeterPwr]) then
curPwr = tonumber(devicechanged[devSmartMeterPwr])
-- Immediately log & return on bad pwr figures...
if (curPwr > maxPeakPwr) then
print('WARNING : '..devSmartMeterPwr..' reports '..curPwr..'W !!!')
return commandArray
end
-----------------------
-- Update Peak power --
-----------------------
pkPwr = tonumber(otherdevices[devPeakPwrVrtSen])
tLastPk= timeLastUpdate(devPeakPwrVrtSen, false)
-- Debug :
--print(devSmartMeterPwr..': P='..curPwr..'W ('..type(curPwr)..')')
--print(devPeakPwrVrtSen..': P='..pkPwr..'W ('..type(pkPwr)..') ; Last : '..tLastPk..'s')
-- Peak Pwr is stored rounded...
if (curPwr > (pkPwr + 1)) or (tLastPk > maxLastUpdateVrt) then
--Log update if time slice reached :
if (tLastPk > maxLastUpdateVrt) then
print(string.format('%s : New time slice (since %ds) => Got Pmax=%.2fW', devPeakPwrVrtSen, tLastPk, math.max(pkPwr, curPwr)))
end
updateNum(devPeakPwrVrtSen, curPwr)
end
-----------------------
-- Update Mean power --
-----------------------
tLastMean = timeLastUpdate(devMeanPwrVrtSen, false)
-- Debug :
--print(devSmartMeterPwr..': P='..curPwr..'W ; Last : '..tLastMean..'s')
pwrLast = uservariables[varPwrLast]
pwrSum = uservariables[varPwrSum]
sumDeltaT = timeLastUpdate(varPwrSum, true)
-- Calc pwr sum + store. Set current mean pwr if time slice exceeded & reset user vars.
if (tLastMean > maxLastUpdateVrt) then
meanPwr = (pwrSum + pwrLast*sumDeltaT) / tLastMean
--Log update :
print(string.format('%s : New time slice (after %ds) => Record Pmean=%.2fW', devMeanPwrVrtSen, tLastMean, meanPwr))
updateNum(devMeanPwrVrtSen, meanPwr)
commandArray['Variable:'..varPwrSum] = '0'
commandArray['Variable:'..varPwrLast] = tostring(curPwr)
else
pwrSum = pwrSum + pwrLast*sumDeltaT
--Debug :
--print('Update current Psum='..pwrSum..'Ws ; deltaT='..sumDeltaT..'s')
commandArray['Variable:'..varPwrLast] = tostring(curPwr)
commandArray['Variable:'..varPwrSum] = tostring(pwrSum)
end
end
return commandArray
That's pure Lua, so should be quite straightforward to triple for a 3 phase setup. Max value update is by script design done instantly inside a record time slice, so virtual max device may be used directly to manage heavy consumers automatic shutdown in other scripts if needed.
10mn (600s, in maxLastUpdateVrt) time slice is just a target (that's a Lua time script! You may tune your power device reports frequency/power change % triggering a report, to get closer to this target if needed ; logs shows real slices durations) & configurable, but don't put less than 5mn or you'll fall in the domoticz core 5mn samples resolution & miss values!