Hi, I tried this script with an older script that you have written, but it isn't working.
Code: Select all
local scriptVar = 'myCustomTimer'
return
{
on =
{
timer =
{
'every minute',
},
customEvents =
{
scriptVar .. '*', -- event triggered by emitEvent
},
},
logging =
{
level = domoticz.LOG_DEBUG, -- change to domoticz.LOG_ERROR when all is OK
marker = scriptVar,
},
execute = function(dz, item)
local every = 30 -- Frequency ==>> the script should execute every nn seconds (min 1, max 30)
if item.isCustomEvent then
dz.log('Triggered by customEvent ' .. item.trigger, dz.log_DEBUG)
else
dz.log('Triggered by timer',dz.LOG_DEBUG)
for i = every, (60 - every), every do
dz.emitEvent(scriptVar .. ' after ' .. i .. ' seconds' ).afterSec(i)
end
end
--[[
TWC control script based on surplus of own (solar) generated power.
the script uses for the TWC schedule function 3 variables
scheduledAmpEndTime en scheduledAmpStartTime -- type time e.g. 23:00 and 07:00
activeScheduledDays -- type string e.g. 0,1,1,1,1,1,0 (In this example Sunday and Saturday off, other days On)
For control 4 virtual On/Off switches
TWC_Active -- systeem active / Off
TWC_UserControlled -- dzVents controlled ==>> The script will ensure that UserControlled and Scheduler are mutual exclusive
TWC_Scheduler -- TWC scheduler controle
TWC_fastload -- set Amps fixed at maxAmp
and (optional) one setPoint device
TWC_RestUsage -- virtual Thermostat setpoint to have the possibility to have a variable level of restusage (amount to reserve for other incidental usage)
Input device is of type: P1 Smart meter
Display device is type: Electric (instant + counter)
versie 201905262100
]]--
local scriptVar = 'TWC'
return {
on = { timer = {'every minute between sunrise and sunset', 'at 3:17'}, -- at 3:17 to reset to default
devices = {'TWC_*'},
httpResponse = { scriptVar .. '_callback'}
},
logging = { level = domoticz.LOG_DEBUG,
marker = scriptVar },
data = { lastSendAmps = { initial = 6 },
lastSendScheduleTime = { initial = 0 },
fastloadSwitchedOn = { initial = 0 },
lastLogLine = { initial = "" },
},
execute = function(dz, item)
-- Your Changes below this line
local P1 = dz.devices('Power') -- Change to "name" or idx of your P1 meter
local grid = dz.devices(33) -- Change to "name" or idx of your (display) output device
local usageDelivered = dz.devices(26) -- Change to "name" or idx of your usage delivered
local defaultAmp = 6 -- Start value
local maxAmp = 16 -- Maximum load Amperage
local minAmp = 5 -- Minimum load Amperage
local restUsage = 0 -- How much do you want to keep for own ( additional ) usage
local urlTWC = '192.168.1.43' -- IP or DNS of your TWC
local fastloadMaxHours = 8 -- Max hours for fastload
local debug2File = true -- Ehh
local debugFile = '/var/log/domoticz_debug.log'
local schedule = -- defaults for TWC internal scheduler
{
scheduledAmpsMax = -1, -- -1 is deactivate
scheduledAmpsStartTime = '10:30',
scheduledAmpsEndTime = '15:30',
scheduledAmpsDay = {1,1,1,1,1,1,1,1}, -- All days
resumeTrackGreenEnergyTime = '-1:00', -- -1:00 is deactivate
}
-- No Changes required below this line
local userControlled = dz.devices('TWC_UserControlled')
local scheduleControlled = dz.devices('TWC_Scheduler')
local activeDevice = dz.devices('TWC_Active')
local fastloadDevice = dz.devices('TWC_fastload')
if dz.devices('TWC_RestUsage') then restUsage = dz.devices('TWC_RestUsage').setPoint end
local isActive = activeDevice.state == 'On'
local isDisabled = not isActive
local isUserControlled = isActive and userControlled.state == 'On'
local isSchedulerControlled = isActive and ( not userControlled ) and scheduleControlled.state == 'On'
local toGrid = usageDelivered.WhActual
local function logWrite2File(str)
out = io.open(debugFile,'a')
local origin = 'timer'
if item.isDevice then origin = item.name elseif item.isHTTPResponse then origin = 'Response' end
out:write(origin .. ":" .. dz.time.rawDate .. ' - ' ..dz.time.rawTime .. ' ; ' .. str .. "\n")
out:close()
end
local function logWrite(str, level )
dz.log(tostring(str), level or dz.LOG_DEBUG)
if debug2File then
if str ~= dz.data.lastLogLine then
logWrite2File("dzVents TWC: " .. str)
dz.data.lastLogLine = str
end
end
end
local function urlEncoded(url) -- not sure if we can't just use the dzVents std urlEncode method (to be checked)
--This function converts only the special chars [,] and : to hex. Other chars are not touched
local function char2Hex(c) -- internal helper function
return string.format("%%%02X", string.byte(c))
end
if url == nil then return end
url = url:gsub("\n", "\r\n") --convert Linefeed to Linefeed + return
url = url:gsub("[%[%]%:]", char2Hex) -- Convert [, ] and : to hexCode
url = url:gsub(" ", "+") -- convert space to +
return url
end
local function sendURL(amps, schedule)
local TWCCommand =
'scheduledAmpsMax=' .. schedule.scheduledAmpsMax .. -- disable scheduled AmpsMax
'&scheduledAmpStartTime='.. schedule.scheduledAmpsStartTime ..
'&scheduledAmpsEndTime=' .. schedule.scheduledAmpsEndTime ..-- only considered when scheduled AmpsMax active
'&scheduledAmpsDay[0]=' .. schedule.scheduledAmpsDay[1] .. --Sunday
'&scheduledAmpsDay[1]=' .. schedule.scheduledAmpsDay[2] ..
'&scheduledAmpsDay[2]=' .. schedule.scheduledAmpsDay[3] ..
'&scheduledAmpsDay[3]=' .. schedule.scheduledAmpsDay[4] ..
'&scheduledAmpsDay[4]=' .. schedule.scheduledAmpsDay[5] ..
'&scheduledAmpsDay[5]=' .. schedule.scheduledAmpsDay[6] .. -- Friday
'&scheduledAmpsDay[6]=' .. schedule.scheduledAmpsDay[7] .. -- All days(only when scheduled AmpsMax active)
'&resumeTrackGreenEnergyTime=' .. schedule.resumeTrackGreenEnergyTime .. -- (de)activate internal
'&submit=Save' ..
'&nonScheduledAmpsMax=' .. amps -- User controlled
local url = 'http://'.. urlTWC .. '/index.php?' .. urlEncoded(TWCCommand)
dz.openURL( {
url = url,
method = 'GET',
callback = scriptVar .. '_callback',
})
logWrite('url encoded send: ' .. url )
end
local function toggleControlers(master) -- Make these switches mutual exclusive
logWrite("in function toggleControllers ")
userControlled.opposite = scheduleControlled
scheduleControlled.opposite = userControlled
if master.active then
master.opposite.switchOff().checkFirst().silent()
else
master.opposite.switchOn().checkFirst().silent()
end
end
local function createSchedule(activeDays)
logWrite("in function createSchedule ")
schedule.scheduledAmpsEndTime = dz.variables('scheduledAmpsEndTime').value
schedule.scheduledAmpsStartTime = dz.variables('scheduledAmpsStartTime').value
schedule.scheduledAmpsMax = maxAmp
local days = dz.utils.stringSplit(activeDays,",")
for i, v in ipairs(days) do
schedule.scheduledAmpsDay[i] = v
end
end
local function controlURL(amps, schedule)
logWrite("in function controlURL ")
sendURL(amps, schedule)
dz.data.lastSendAmps = amps
end
local function controlFastload()
logWrite("in function controlFastload ")
if item.active then
if dz.data.fastloadSwitchedOn == 0 then dz.data.fastloadSwitchedOn = dz.time.dDate end
if dz.time.dDate < ( dz.data.fastloadSwitchedOn + fastloadMaxHours * 3600 ) then
fastloadDevice.switchOn().afterMin(10) -- trigger script every 10 minutes until switched Off
controlURL( maxAmp, schedule) -- Full power
else
fastloadDevice.switchOff().silent()
dz.data.fastloadSwitchedOn = 0
end
else
fastloadDevice.cancelQueuedCommands() -- Switched off manual so prevent retriggering
end
end
logWrite("restUsage: " .. restUsage)
if item.isDevice then
logWrite("managing controler " .. item.name .. " is " .. item.state )
if item == activeDevice and item.state == 'Off' then
logWrite("in main 1 ")
controlURL( 0, schedule)
logWrite('Switched to inactive' )
elseif item == fastloadDevice then
logWrite("in main 2 ")
activeDevice.switchOn().checkFirst().silent()
controlFastload()
elseif item == activeDevice then
logWrite("in main 3 ")
toggleControlers(scheduleControlled) -- When system is activated, it needs at least one control-type active
else
logWrite("in main 4 ")
toggleControlers(item) -- if userControlled is On then scheduleControlled must be off and vice versa
end
elseif isDisabled then
logWrite('inactive' )
elseif item.isTimer and fastloadDevice.active then
logWrite("in main 5 ")
if fastloadDevice.lastUpdate.minutesAgo > 10 then controlURL( maxAmp, schedule) end -- Full power
elseif isSchedulerControlled and dz.data.lastSendScheduleTime == 0 then -- Only Send this once to set TWC to internal scheduler
logWrite("in main 6 ")
logWrite("scheduler active")
controlURL( maxAmp, createSchedule( dz.variables('activeScheduledDays').value ))
dz.data.lastSendScheduleTime = dz.time.dDate
elseif item.isTimer and (not scheduler) then
logWrite("in main 7 ")
logWrite("timer active")
dz.data.lastSendScheduleTime = 0 -- reset
if ( dz.time.hour < 4 ) or (not ( dz.data.lastSendAmps ) ) then -- initialize or reset
logWrite("in main 8 ")
dz.data.lastSendAmps = defaultAmp
return
end
logWrite('Return to the grid: ' .. toGrid .. ' Watt' )
grid.updateElectricity(toGrid) -- update virtual sensor (display only)
if toGrid > restUsage then -- we ( still ) have some spare
logWrite("in main 9 ")
if dz.data.lastSendAmps < maxAmp then
logWrite("in main 10 ")
controlURL(math.min( dz.data.lastSendAmps + 1, maxAmp ), schedule) -- one step up
end
else
logWrite("in main 11 ")
if dz.data.lastSendAmps > minAmp then
logWrite("in main 12 ")
controlURL( math.max( dz.data.lastSendAmps - 1 , minAmp ), schedule) -- one step back
end
end
elseif item.ok then -- return from TWC
logWrite("in main 13 ")
logWrite("HTTP callback OK")
elseif item.isHTTPResponse then -- return was not OK !
logWrite("in main 14 ")
local status = item.statusCode
if item.protocol then -- available in dzVents >= 2.4.19
logWrite("in main 15 ")
status = item.protocol .. ' (' .. status .. ') ' .. statusText
end
logWrite('something went wrong with sending new amps to TWC. ( status: ' .. status .. ' )', dz.LOG_ERROR)
end
end
}
end
}