I couldn't stand that I was not able to get this working nicely so did some more testing and found that the crippled Json is in a part of the result that is not relevant. So I used the regex as posted earlier to only select the proper "ophaaldagen" Json object from the result.
Now - building on your latest version - this is how I got it working:
Code: Select all
--[[ getGarbageDates.lua for [ dzVents >= 2.4 ]
this script is only useful in those areas of the Netherlands where the household garbage collector is connected to afvalwijzer.nl
Enter your zipcode and housenumber in the appropriate place between the lines starting with --++++
Next is to set your virtual text and or virtual alert device.
the text device will contain the most nearby collectdates for the four types of household garbage
the alert device will contain the date and type for the garbagecollecion that will arrive first
]]--
return {
on = { timer = { "at 00:05","at 08:00" }, -- daily run twice
devices = { "Garbage" }, -- Only for test purposes can be ignored
httpResponses = { "getGarbage_Response" } -- Trigger the handle Json part
},
logging = { level = domoticz.LOG_DEBUG,
marker = "collectGarbage" },
data = { garbage = { initial = {} }, -- Keep a copy of last json just in case
lastStartline = { initial = 1 },
lastEndline = { initial = 1000 },
},
execute = function(dz, triggerObject)
--++++--------------------- Mandatory: Set your values and device names below this Line --------------------------------------
local myZipcode = "3065KA" -- Your zipcode like "3085RA"
local myHousenumber = 193 -- Your housenumber like 38
local myTextDevice = "GarbageText" -- Name with quotes or idx without when created as virtual text device
local myAlertDevice = "GarbageAlert" -- Name with quotes or idx without when created as virtual alert device
--++++---------------------------- Set your values and device names above this Line --------------------------------------------
local myYear = os.date("%Y")
garbageTypes = {"restafval","gft","papier","plastic"}
local function collectGarbageDates(secondsFromNow)
local getGarbage_url = "http://json.mijnafvalwijzer.nl/?method=postcodecheck&postcode=" ..
myZipcode .. "&street=&huisnummer=" ..
myHousenumber .. "&toevoeging"
dz.openURL ({ url = getGarbage_url ,
method = "GET",
callback = "getGarbage_Response" }).afterSec(secondsFromNow)
end
-- Add entry to log and notify to all subsystems
local function errorMessage(message)
dz.log(message,dz.LOG_ERROR)
dz.notify(message)
end
local function string2Epoch(dateString) -- seconds from epoch based on stringdate (used by string2Date)
-- Assuming a date pattern like: yyyy-mm-dd
local pattern = "(%d+)-(%d+)-(%d+)"
local runyear, runmonth, runday= dateString:match(pattern)
local convertedTimestamp = os.time({year = runyear, month = runmonth, day = runday})
return convertedTimestamp
end
local function string2Date(str,fmt) -- convert string from json into datevalue
if fmt then return os.date(fmt,string2Epoch(str)) end
return os.date(" %A %d %B, %Y",string2Epoch(str))
end
local function alertLevel(delta)
if delta < 2 then return dz.ALERTLEVEL_RED end
if delta < 3 then return dz.ALERTLEVEL_YELLOW end
if delta < 4 then return dz.ALERTLEVEL_ORANGE end
return dz.ALERTLEVEL_GREEN
end
local function setGarbageAlertDevice(alertDevice,alertText,alertDate)
local delta = tonumber(string2Date(alertDate,"%d")) - tonumber(os.date("%d")) -- delta in days between today and first garbage collection date
dz.devices(alertDevice).updateAlertSensor(alertLevel(delta),alertText)
dz.log("\nalertLevel: " .. alertLevel(delta) .. ", alertText: " .. alertText,dz.LOG_DEBUG)
return (delta == 0)
end
local function longGarbageName(str) -- Use descriptive strings
str = tostring(str)
str = str:gsub("plastic"," Plastic verpakkingen, blik en drinkpakken ")
str = str:gsub("gft"," Groente-, fruit- en tuin afval ")
str = str:gsub("papier"," Papier en kartonnen verpakkingen ")
str = str:gsub("restafval" ," Restafval ")
return str
end
local function handleResponse()
json = "{"..triggerObject.data:match('(\"ophaaldagen\":{.*),\"ophaaldagenNext\":').."}"
-- dz.log('JSON RESULT: '..json,dz.LOG_ERROR)
triggerObject.json = dz.utils.fromJSON(json)
-- json is now a Lua table
if type(triggerObject.json) == 'table' then
dz.data.garbage = triggerObject.json.ophaaldagen.data -- Store this part in dz.data
rt = triggerObject.json.ophaaldagen.data -- and in table
else
errorMessage("Problem with response (no data) using data from earlier run")
rt = dz.data.garbage -- json empty. Get last valid from dz.data
if #rt < 1 then -- No valid data in dz.data either
errorMessage("No previous data. are zipcode and housenumber ok and in afvalkalender ?")
return false
end
end
-- dz.utils.dumpTable(rt)
local garbageLines = ""
local typeEarliestDate
local overallEarliestDate = "2999-12-31" -- Hopefully we will have a different garbage collection system by then
local garbageToday = false
local today = os.date("%Y-%m-%d")
local garbage = {}
for i = 1,#garbageTypes do --walk the the type Table
typeEarliestDate = "2999-12-31"
for j = 1, math.min(#rt, #dz.data.garbage) do -- walk the response table
if rt[j].date >= today and rt[j].date < typeEarliestDate and rt[j].type == garbageTypes[i] then -- Keep date closest to today per type
typeEarliestDate = rt[j].date
if typeEarliestDate < overallEarliestDate then -- date closest to today overall ?
overallEarliestDate = typeEarliestDate -- keep date
overallEarliestType = garbageTypes[i] -- keep type
dz.data.lastStartline = j
end
garbage[string2Epoch(typeEarliestDate,"%a %e %b" )] = string2Date(typeEarliestDate,"%a %e %b" ) .. longGarbageName(rt[j].type)
typeEarliestDate = rt[j].date -- Keep date closest to today
end
end
end
-- Order the lines based on dates
local keyTable = {}
local garbageLines = ''
for key in pairs(garbage) do
table.insert(keyTable, key)
end
table.sort(keyTable)
for _, key in ipairs(keyTable) do
garbageLines = garbageLines .. garbage[key] .. '\n'
end
-- Update the devices
if myAlertDevice then -- Update AlertDevice with nearby date / type
garbageToday = setGarbageAlertDevice( myAlertDevice,
longGarbageName(overallEarliestType) .. "\n" ..
string2Date(overallEarliestDate),
overallEarliestDate)
end
if myTextDevice then -- Update defined virtual text device with dates / types
dz.devices(myTextDevice).updateText(garbageLines)
dz.log("\n" .. garbageLines,dz.LOG_DEBUG)
end
if dz.time.matchesRule("at 08:00-17:00") and garbageToday then
dz.notify(longGarbageName(overallEarliestType) .. " will be collected today")
end
end
-- Main
if triggerObject.isHTTPResponse then
if triggerObject.ok then
handleResponse()
else
errorMessage("Problem with response from hvcgroep (not ok)")
--collectGarbageDates(600) -- response not OK, try again after 10 minutes
end
else
collectGarbageDates(1)
end
end
}