Below is the code. Sorry for mixed language and not perfect scripting structure. I removed outcommented code for debugging and personal information.
Code: Select all
return {
on = {
timer = { 'every minute' },
httpResponses = { 'energyRetrievedSolarWatt' }
},
data = {
PowerIn = { history = true, maxItems = 20 },
PowerOut = { history = true, maxItems = 20 },
PowerWP = { history = true, maxItems = 1440 },
WorkTimeWP = { history = true, maxItems = 50 },
PowerEKZ = { history = true, maxItems = 20 }, --positiv: Bezug / negativ: Einspeisung
LockWP = { initial = 19 }, --Counter for locking WP
LastPowerWP = { initial = 0 },
LimitOn = { initial = -6000 },
LimitOff = { initial = 1000}, --Strom Bezug
Counter = { initial = 0 },
'DelayWP',
'CounterMail'
},
execute = function(domoticz, item)
if (item.isTimer) then
domoticz.log('Timer!!!', domoticz.LOG_INFO)
domoticz.openURL({
url = 'http://192.168.xx.xx/rest/kiwigrid/wizard/devices',
method = 'GET',
callback = 'energyRetrievedSolarWatt'
})
elseif (item.isHTTPResponse) then
if (item.ok) then -- statusCode == 2xx
domoticz.log('HTTP Solarwatt Responnse received...', domoticz.LOG_INFO)
local Time = require('Time')
local t = Time()
local PowerWP = -99999
local PowerIn = -99999
local PowerOut = -99999
local PowerPool = -99999
local PowerHausPool = -99999
local PowerForecast = 0
local PowerHaus = 0
local PowerEKZ = 0
domoticz.data.initialize('LimitOn')
domoticz.data.initialize('LimitOff')
if (CounterMail == nil or CounterMail < 0 or CounterMail > 60) then CounterMail = 0 end
-- Werte aus Solarwatt (Kiwigrid) Energiemanager auslesen
for i,v in ipairs(item.json['result']['items']) do
if (v['tagValues']['IdName']['value'] == 'Wärmepumpe') then
PowerWP = v['tagValues']['PowerIn']['value']
elseif (v['tagValues']['IdName']['value'] == 'Standort Guldener') then
PowerIn = v['tagValues']['PowerIn']['value']
PowerOut = v['tagValues']['PowerOut']['value']
PowerEKZ = PowerIn - PowerOut
PowerForecast = 0;
for iforecast=1,96,1 do
PowerForecast = PowerForecast + v['tagValues']['PowerProductionForecastValues']['value'][iforecast]
end
PowerForecast = PowerForecast / 4
elseif (v['tagValues']['IdName']['value'] == 'Pool' or v['tagValues']['IdName']['value'] == 'S0-Energiezähler 1 (0d16ffff0b0bffff1312ffff10ffff)') then --Pool
PowerPool = v['tagValues']['PowerIn']['value']
elseif (v['tagValues']['IdName']['value'] == 'S0-Energiezähler 1 (ERC04-100005801)') then --Pool
PowerHausPool = v['tagValues']['PowerIn']['value']
end
end
PowerHaus = PowerHausPool - PowerPool
if (CounterMail == 0) then
if (PowerWP == -99999) then
domoticz.email('Domoticz capture error!','Keine Werte für Wärmepumpezähler erhalten!','[email protected]')
CounterMail = 60
end
if (PowerIn == -99999) then
domoticz.email('Domoticz capture error!','Keine Werte für Standortzähler (PowerIn) erhalten!','[email protected]')
CounterMail = 60
end
if (PowerOut == -99999) then
domoticz.email('Domoticz capture error!','Keine Werte für Standortzähler (PowerOut) erhalten!','[email protected]')
CounterMail = 60
end
if (PowerForecast == 0) then
domoticz.email('Domoticz capture error!','Keine Werte für Standortzähler (PowerForecast) erhalten!','[email protected]')
CounterMail = 60
end
if (PowerPool == -99999) then
domoticz.email('Domoticz capture error!','Keine Werte für Poolzähler erhalten!','[email protected]')
CounterMail = 60
end
if (PowerHausPool == -99999) then
domoticz.email('Domoticz capture error!','Keine Werte für Hauszähler erhalten!','[email protected]')
CounterMail = 60
end
else
CounterMail = CounterMail - 1
end
--Werte in Zähler von Domoticz schreiben
domoticz.devices('Pool').updateEnergy(domoticz.utils.round(PowerPool,0))
domoticz.devices('Wärmepumpe').updateEnergy(domoticz.utils.round(PowerWP,0))
domoticz.devices('Haushalt').updateEnergy(domoticz.utils.round(PowerHaus,0))
domoticz.devices('Bezug').updateEnergy(domoticz.utils.round(PowerIn,0))
domoticz.devices('Einspeisung').updateEnergy(domoticz.utils.round(PowerOut,0))
if (t.matchesRule('at 04:45-04:50')) then
if (PowerForecast > 0) then
domoticz.devices('Vorhersage').updateCustomSensor(domoticz.utils.round(PowerForecast/1000,1))
else
domoticz.log('HTTP Forcast.Solar send...', domoticz.LOG_ERROR)
domoticz.openURL({
url = 'https://api.forecast.solar/estimate/47.266549/8.734622/45/-31/17.4',
method = 'GET',
callback = 'solarForecast'
})
end
end
--History für AVG anlegen
domoticz.data.PowerIn.add(PowerIn)
domoticz.data.PowerOut.add(PowerOut)
domoticz.data.PowerWP.add(PowerWP)
domoticz.data.PowerEKZ.add(PowerEKZ)
if (domoticz.data.LastPowerWP > 1000 and PowerWP < 1000) then
domoticz.data.initialize('LockWP')
domoticz.log('WP swiched off -> initialize LockWP', domoticz.LOG_ERROR)
if ((domoticz.devices('Freigabe WP').active) and t.matchesRule('at 06:55-20:05')) then
domoticz.devices('Freigabe WP').switchOff()
end
end
domoticz.data.LastPowerWP = PowerWP
if (domoticz.data.LockWP > 0) then
domoticz.data.LockWP = domoticz.data.LockWP - 1
end
--Count working WP Compressors and Time
domoticz.data.Counter = domoticz.data.Counter + 1
if (PowerWP < 2500) then
if (domoticz.devices('Wärmepumpe Kompressor').level ~= 0) then
domoticz.devices('Wärmepumpe Kompressor').switchSelector(0)
domoticz.data.WorkTimeWP.add(domoticz.data.Counter)
domoticz.log('WP worked for '..domoticz.data.Counter..' minutes. AVG: '..domoticz.utils.round(domoticz.data.WorkTimeWP.avgSince('24:00:00'),0)..' minutes...', domoticz.LOG_ERROR)
domoticz.devices('Arbeitszeit WP').updateText(domoticz.data.Counter..' Minuten ('..domoticz.utils.round(domoticz.data.WorkTimeWP.avgSince('24:00:00'),0)..')')
domoticz.data.DelayWP = domoticz.utils.round(domoticz.data.WorkTimeWP.avgSince('24:00:00'),0) * 0.8
if (domoticz.data.DelayWP < 0) then domoticz.data.DelayWP = 0 end
end
end
if (PowerWP > 2500 and PowerWP < 7250) then
if (domoticz.devices('Wärmepumpe Kompressor').level == 0) then
domoticz.devices('Wärmepumpe Kompressor').switchSelector(10)
domoticz.data.initialize('Counter')
end
end
if (PowerWP > 7250 and PowerWP < 12500) then
if (domoticz.devices('Wärmepumpe Kompressor').level == 10) then domoticz.devices('Wärmepumpe Kompressor').switchSelector(20) end
end
if (PowerWP > 12500) then
if (domoticz.devices('Wärmepumpe Kompressor').level == 20) then domoticz.devices('Wärmepumpe Kompressor').switchSelector(30) end
end
-- Energie Otimierer
if (domoticz.devices('Energie Optimierer').active) then
--Switch control
--Ausschalt - Limit
local limitLow = 0;
limitLow = domoticz.data.LimitOn + 1500 + domoticz.data.PowerWP.avgSince('00:05:00');
if ((tonumber(domoticz.devices('Wärmepumpe Kompressor').level) > 0) or (limitLow > domoticz.data.LimitOff)) then
limitLow = domoticz.data.LimitOff
end
domoticz.devices('LimitLow').updateTemperature(-limitLow);
--Einschalte - Limit
local limitHigh = 0
if (tonumber(domoticz.devices('Wärmepumpe Kompressor').level) > 0) then
limitHigh = limitLow;
elseif ((domoticz.data.LimitOn + domoticz.data.PowerWP.avgSince('00:05:00') )<0) then limitHigh = domoticz.data.LimitOn + domoticz.data.PowerWP.avgSince('00:05:00') end
domoticz.devices('LimitHight').updateTemperature(-limitHigh);
domoticz.devices('Limitten').updateCurrent(-limitHigh,-limitLow,-domoticz.data.PowerEKZ.avgSince('00:05:00'));
domoticz.devices('PowerEKZ').updateTemperature(-domoticz.data.PowerEKZ.avgSince('00:05:00'));
-- Zeitschaltuhr
if (t.matchesRule('at 20:05-06:55') and (domoticz.devices('Wärmepumpe Sommerbetrieb').active == false or tonumber(domoticz.devices('Vorhersage')._state) < 60) or domoticz.devices('Wärmepumpe Sommerbetrieb').active == true and t.matchesRule('at 20:05-05:00')) then
if (domoticz.devices('Freigabe WP').active == false) then
domoticz.log('Im Zeitfenster Niedertarif!!!', domoticz.LOG_ERROR)
domoticz.devices('Freigabe WP').switchOn()
domoticz.devices('Status Optimierer').updateText('Niedertarif -> On')
end
else
-- Verbrauchsoptimierer
--Ausschalten
if (domoticz.devices('Freigabe WP').active) then
if (domoticz.data.PowerEKZ.avgSince('00:05:00') > limitLow) then
domoticz.devices('Freigabe WP').switchOff()
domoticz.log('Freigabe WP ausgeschaltet! PowerEKZ(' .. domoticz.utils.round(domoticz.data.PowerEKZ.avgSince('00:05:00'),0) .. ') > '..domoticz.utils.round(limitLow,0), domoticz.LOG_ERROR)
domoticz.devices('Status Optimierer').updateText('Aus: PowerEKZ avg('..domoticz.utils.round(domoticz.data.PowerEKZ.avgSince('00:05:00'),0) .. ') > Limit('..domoticz.utils.round(limitLow,0)..')')
end
else
--Einschalten
if (domoticz.data.PowerEKZ.avgSince('00:05:00') < limitHigh) then
if ((domoticz.data.DelayWP < domoticz.data.Counter or domoticz.devices('Wärmepumpe Kompressor').level == 0 or t.matchesRule('at 10:59-12:01')) and domoticz.data.LockWP == 0) then
--Einschaltbedingung erfüllt
domoticz.devices('Freigabe WP').switchOn()
domoticz.log('Freigabe WP eingeschaltet! PowerEKZ AVG(' .. domoticz.utils.round(domoticz.data.PowerEKZ.avgSince('00:05:00'),0) .. ') <min('..domoticz.data.LimitOn..' + WP (' .. domoticz.utils.round(domoticz.data.PowerWP.avgSince('00:05:00'),0) .. '),0) Limit:'..domoticz.utils.round(limitHigh,0)..'!', domoticz.LOG_ERROR)
domoticz.devices('Status Optimierer').updateText('On: PowerEKZ avg(' .. domoticz.utils.round(domoticz.data.PowerEKZ.avgSince('00:05:00'),0) .. ') < Limit('..domoticz.utils.round(limitHigh,0)..')')
elseif (domoticz.data.LockWP > 0) then --WP is in 15min block
--Einschaltbedingung NICHT erfüllt
domoticz.devices('Status Optimierer').updateText('WP Locked: PowerEKZ avg(' .. domoticz.utils.round(domoticz.data.PowerEKZ.avgSince('00:05:00'),0) .. ') < Limit('..domoticz.utils.round(limitHigh,0)..')')
else
--Einschaltbedingung NICHT erfüllt
domoticz.devices('Status Optimierer').updateText('Delayed: PowerEKZ avg(' .. domoticz.utils.round(domoticz.data.PowerEKZ.avgSince('00:05:00'),0) .. ') < Limit('..domoticz.utils.round(limitHigh,0)..')')
end
end
end
end
else --Optimierer Ausgeschalten
domoticz.log(domoticz.devices('Status Optimierer').text, domoticz.LOG_ERROR)
if (domoticz.devices('Status Optimierer').text ~= 'Optimierer deaktiviert!') then domoticz.devices('Status Optimierer').updateText('Optimierer deaktiviert!') end
end
if (domoticz.devices('Freigabe WP').active) then domoticz.devices('WPFreigabe').updateTemperature(10000); else domoticz.devices('WPFreigabe').updateTemperature(0); end
end
end
end
}