Hi Jos,
I’m a big fan of your waste collection project and have been using it for quite some time. However, since updating Domoticz (Windows), I can no longer use the script.
I’m getting the well-known error regarding io.popen, which is no longer supported in Domoticz (Windows):
2026-08-19 08:53:00.454 Error: EventSystem: in C:\Program Files (x86)\Domoticz\scripts\lua\script_time_garbagecalendar.lua: ...86)\Domoticz\scripts\lua\script_time_garbagecalendar.lua:348: 'popen' not supported
With the help of AI, I modified some functions in gc_generalfuncs.lua and gc_main.lua.
io.popen has been replaced with os.execute, io.open, and os.remove. Instead of keeping the output in memory, it is now written to a temporary file, which is then read afterwards.
Perhaps this is something you could consider incorporating into a future version, so I wanted to share these modifications with you.
gc_generalfuncs.lua
Code: Select all
-- addlogmessage function sends messages to Domoticz log
function genfuncs.domo_api_query(url, uploadfile)
if not url then
return nil, 1, nil
end
-- GEWIJZIGD VOOR WINDOWS: io.popen omzeild via een tijdelijk bestand
local tmp_api_log = (datafilepath or '') .. 'domo_api_tmp.json'
local sQuery = 'curl --silent --connect-timeout 2 '
if uploadfile and uploadfile ~= '' then
sQuery = sQuery .. ' -F file="@' .. uploadfile .. '" '
end
-- Schrijf output direct naar een tijdelijk bestand in plaats van popen te gebruiken
sQuery = sQuery .. '"' .. url .. '" > "' .. tmp_api_log .. '"'
Print_logfile('-> domo_api_query (Windows Exec):' .. (sQuery or 'NIL'))
os.execute(sQuery) -- Veilige aanroep op Windows
-- Lees het resultaat uit met het toegestane io.open
local f = io.open(tmp_api_log, 'r')
local Web_Data = nil
if f then
Web_Data = f:read('*all')
f:close()
os.remove(tmp_api_log) -- Netjes opruimen
end
if not Web_Data or Web_Data == '' then
Print_logfile('-< domo_api_query failed, temporary file empty or missing.')
return nil, 2
end
Print_logfile('Web_Data:' .. (Web_Data or 'NIL'))
local JSON_Web_Data = JSON:decode(Web_Data or '')
if (JSON_Web_Data == nil) then
-- No data returned so API must have failed
Print_logfile('-< domo_api_query failed, no json returned:' .. (Web_Data or '?'))
return nil, 2
end
if (JSON_Web_Data['status'] ~= 'OK') then
-- No data returned so API must have failed
Print_logfile('-< domo_api_query failed, status not OK:' .. (Web_Data or '?'))
return JSON_Web_Data, 3
end
Print_logfile('-< domo_api_query successful.')
return JSON_Web_Data, 0
end
Code: Select all
--------------------------------------------------------------------------
-- Do the actual webquery, retrieving data from the website
--------------------------------------------------------------------------
function genfuncs.perform_webquery(url)
-- Paden Windows-vriendelijk maken met backslashes en correcte aanhalingstekens
local base_path = (datafilepath or ((GC_scriptpath or '/') .. 'data/')):gsub('/', '\\')
if not base_path:match('\\$') then base_path = base_path .. '\\' end
local errlogfile = base_path .. 'webquery_err.log'
local tmp_web_out = base_path .. 'webquery_out.txt'
-- Zorg dat de URL geen dubbele aanhalingstekens bevat vanuit de aanroepende module
local clean_url = url:gsub('"', '')
-- Bouw de Windows Query op. We schrijven direct de output EN de -w metadata naar het bestand.
-- Let op: Geen geneste dubbele aanhalingstekens voor cmd.exe!
local sQuery = 'curl -L -k --silent -w "\\n#@#httprc:%{http_code}#@#\\n#@#endurl:%{url_effective}#@#" "' .. clean_url .. '" > "' .. tmp_web_out .. '" 2>"' .. errlogfile .. '"'
Print_logfile('sQuery (Windows Exec)=' .. sQuery)
os.execute(sQuery)
-- Lees het resultaat uit met io.open
local f = io.open(tmp_web_out, 'r')
local Web_Data = ""
if f then
Web_Data = f:read('*all')
f:close()
os.remove(tmp_web_out) -- Netjes opruimen
end
-- Get effective url and http response code from the output and strip it from the result output
local httprc = Web_Data:match('#@#httprc:([^#]*)#@#') or '?'
local redirecturl = (Web_Data:match('#@#endurl:([^#]*)#@#') or '?')
if Web_Data:find('(.*)\n#@#httprc:') then
Web_Data = Web_Data:match('(.*)\n#@#httprc:')
end
-- Show Webdata retrieved
Print_logfile('--- url: ' .. redirecturl .. ' rc:' .. (httprc or '?') .. ' web data: --------')
Print_logfile(Web_Data)
-- Check for 301 Moved Permanently
if (httprc == '301' or Web_Data:find('Moved Permanently')) then
Print_logfile('### Error: Site Moved Permanently: check your hostname for changes!',1)
local lWeb_Data = Web_Data:gsub('.-<body>(.-)</body>.*', '%1')
lWeb_Data = lWeb_Data:gsub('[\r\n]', '')
Print_logfile(lWeb_Data,1)
return ''
end
-- Check redirection to warn
if (not clean_url:find(redirecturl, 1, true)) then
Print_logfile('### warning: Site redirected from : #' .. clean_url .. '# to : #' .. redirecturl .. '#' .. (clean_url:find(redirecturl, 1, true) or '?'),1)
end
-- Check for Web request errors when seperate file is defined, else all output is in Web_Data
local Web_Error = ''
local ifile, ierr = io.open(errlogfile, 'r')
Web_Error = ierr or ''
if ifile then
Web_Error = ifile:read('*all')
ifile:close()
end
if Web_Error ~= '' then
Print_logfile('---- web err ------------------------------------------------------------------------')
Print_logfile('Web_Err=' .. Web_Error)
end
--os.remove(errlogfile)
Print_logfile('---- end web data ------------------------------------------------------------------------')
if (Web_Error:find('unsupported protocol')) then
Print_logfile('### Error: unsupported protocol.')
Print_logfile('### This website still uses tls 1.0 and Debian Buster (and up) has set the minssl to tls 1.2 so will fail.')
Print_logfile('### To fix: Set /etc/ssl/openssl.cnf; goto section [system_default_sect]; Change-> MinProtocol = TLSv1.0 ; and reboot')
return ''
end
if (Web_Data == '') then
Print_logfile('### Error: Empty result from curl command')
return ''
end
return Web_Data
end
gc_main.lua i updated the first few lines from
function Perform_Data_check()
Code: Select all
----------------------------------------------------------------------------------------------------------------
-- Do the actual update retrieving data from the website and processing it
function Perform_Data_check()
-- ensure the access is set correctly for data
Print_logfile('-> Action starting, First check access to required files:')
-- GEWIJZIGD VOOR WINDOWS: io.popen en ls volledig verwijderd om 'popen not supported' te voorkomen
local function ListAccess()
local files_to_check = {
{path = Datafile, label = "Datafile"},
{path = RunLogfile, label = "RunLogfile"},
{path = icalfile, label = "Icalfile"}
}
for _, file_info in ipairs(files_to_check) do
if file_info.path and file_info.path ~= '' then
local f = io.open(file_info.path, "r")
if f then
Print_logfile(' Access OK (Windows Native Check) - ' .. file_info.label .. ': ' .. file_info.path)
f:close()
else
Print_logfile(' File not found or unreadable - ' .. file_info.label .. ': ' .. file_info.path)
end
end
end
end
-- show access info when debugging
if testrun then
ListAccess() -- Aanroep aangepast zonder argumenten omdat wildcards (*) niet werken in io.open
end
-- Check for access to data & logfiles
if not Perform_Rights_check(Datafile) then
return
end
if not Perform_Rights_check(RunLogfile) then
return
end
local missingrecords = ''
...
...
...
I hope you appreciate the effort I’ve put into this, even though I’m not a programmer.
Best,
Sander