dzVents get garbage collection dates (various)  [SOLVED]

Moderator: leecollings

User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: dzVents get garbage collection dates (various)

Post by waaren »

riko wrote: Saturday 22 August 2020 13:48 .. I'm also looking to customize the notification timing. I would like to have a notification the night before the garbage collection day.
Try changing the part

Code: Select all

            -- Update text device
            if myTextDevice then
                local garbageLines = ''
                for _, key in ipairs(sortedKeys) do
                    garbageLines = garbageLines .. string2Date(garbage[key][1], '%a %e %b' ) .. ':  '  .. longGarbageName(garbage[key][2]) .. '\n'
                end
                dz.devices(myTextDevice).updateText(garbageLines)
            end
from the version posted 14 June 2020 to

Code: Select all

             -- Update text device / Notify for tomorrow
             local garbageLines = ''
             for _, key in ipairs(sortedKeys) do
                 garbageLines = garbageLines .. string2Date(garbage[key][1], '%a %e %b' ) .. ':  '  .. longGarbageName(garbage[key][2]) .. '\n'
                 if dz.time.addHours(24).rawDate == garbage[key][1] and dz.time.matchesRule("at 18:00-22:00") then
                     dz.notify('Huisafval',longGarbageName(garbage[key][2]) .. ' wordt morgen opgehaald',dz.PRIORITY_NORMAL,dz.SOUND_DEFAULT, "" , myNotificationTable)
                 end
             end
             if myTextDevice then dz.devices(myTextDevice).updateText(garbageLines) end
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
ronaldbro
Posts: 327
Joined: Thursday 15 November 2018 21:38
Target OS: Raspberry Pi / ODroid
Domoticz version: 2020.2
Location: Netherlands
Contact:

Re: dzVents get garbage collection dates (various)

Post by ronaldbro »

I had the same on my wish list. Already did a change to get the message a day before but I noticed that when I have two pickups in two days that I don't have the message for the second day.

To make it work I'm think of splitting the alert widget into 3 widgets, 1 for each container I have.

Just need a few hours of spare time...
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: dzVents get garbage collection dates (various)

Post by waaren »

ronaldbro wrote: Saturday 22 August 2020 21:46 I had the same on my wish list. Already did a change to get the message a day before but I noticed that when I have two pickups in two days that I don't have the message for the second day.
Can you try the change I proposed earlier today? It should also work for your requirement.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
ronaldbro
Posts: 327
Joined: Thursday 15 November 2018 21:38
Target OS: Raspberry Pi / ODroid
Domoticz version: 2020.2
Location: Netherlands
Contact:

Re: dzVents get garbage collection dates (various)

Post by ronaldbro »

Thanks waaren, just changed the code and will see in the coming days. Got a plastics pickup on Monday and paper on Tuesday so should get a notification tomorrow and Monday.
plugge

Re: dzVents get garbage collection dates (various)

Post by plugge »

Hm, the script gives an error. See the last two lines.
Any ideas?

Version: 2020.2 (build 12252)
Build Hash: ce7f13306
Compile Date: 2020-08-20 15:38:42
dzVents Version: 3.0.11
Python Version: 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 bit (Intel)]

Code: Select all

2020-08-23 00:43:00.115 Status: dzVents: Info: collectGarbage: ------ Start internal script: GetGarbageDates:, trigger: "at 00:43"
2020-08-23 00:43:00.116 Status: dzVents: Debug: collectGarbage: OpenURL: url = http://json.mijnafvalwijzer.nl/?method=postcodecheck&postcode [removed for privacy reasons]
2020-08-23 00:43:00.116 Status: dzVents: Debug: collectGarbage: OpenURL: method = GET
2020-08-23 00:43:00.116 Status: dzVents: Debug: collectGarbage: OpenURL: post data = nil
2020-08-23 00:43:00.116 Status: dzVents: Debug: collectGarbage: OpenURL: headers = nil
2020-08-23 00:43:00.116 Status: dzVents: Debug: collectGarbage: OpenURL: callback = getGarbage_Response
2020-08-23 00:43:00.117 Status: dzVents: Info: collectGarbage: ------ Finished GetGarbageDates
2020-08-23 00:43:00.117 Status: EventSystem: Script event triggered: D:\Program Files (x86)\Domoticz\dzVents\runtime\dzVents.lua
2020-08-23 00:43:01.438 Status: dzVents: Info: collectGarbage: ------ Start internal script: GetGarbageDates: HTTPResponse: "getGarbage_Response"
2020-08-23 00:43:01.488 Status: dzVents: Info: collectGarbage: 2020-08-28
2020-08-23 00:43:01.489 Status: dzVents: Info: collectGarbage: 2020-09-03
2020-08-23 00:43:01.489 Status: dzVents: Info: collectGarbage: 2020-08-28
2020-08-23 00:43:01.489 Status: dzVents: Debug: collectGarbage: Papier en kartonnen verpakkingen
2020-08-23 00:43:01.489 Friday 28 August, 2020
2020-08-23 00:43:01.489 Status: dzVents: Info: collectGarbage: 2020-08-28
2020-08-23 00:43:01.507 Status: dzVents: Debug: collectGarbage: Processing device-adapter for GarbageAlert: Alert sensor adapter
2020-08-23 00:43:01.508 Status: dzVents: Debug: collectGarbage:
2020-08-23 00:43:01.508 alertLevel: 1, alertText: Papier en kartonnen verpakkingen
2020-08-23 00:43:01.508 Friday 28 August, 2020
2020-08-23 00:43:01.508 Status: dzVents: Info: collectGarbage: 2020-08-28
2020-08-23 00:43:01.508 Status: dzVents: Info: collectGarbage: ------ Finished GetGarbageDates
2020-08-23 00:43:01.508 Status: EventSystem: Script event triggered: D:\Program Files (x86)\Domoticz\dzVents\runtime\dzVents.lua
2020-08-23 00:43:01.508 Error: dzVents: Error: (3.0.11) collectGarbage: An error occurred when calling event handler GetGarbageDates
2020-08-23 00:43:01.508 Error: dzVents: Error: (3.0.11) collectGarbage: ...cz\scripts\dzVents\generated_scripts/GetGarbageDates.lua:117: bad argument #1 to 'date' (invalid conversion specifier '%e %b')
Somewhere in

Code: Select all

        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
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: dzVents get garbage collection dates (various)

Post by waaren »

plugge wrote: Sunday 23 August 2020 0:53 Hm, the script gives an error. See the last two lines.
Any ideas?
Lua os.date behaves a little bit different on windows systems.

Try changing

Code: Select all

garbageLines = garbageLines .. string2Date(garbage[key][1], '%a %e %b' ) .. ':  '  .. longGarbageName(garbage[key][2]) .. '\n'
to

Code: Select all

garbageLines = garbageLines .. string2Date(garbage[key][1], '%a %d %b' ) .. ':  '  .. longGarbageName(garbage[key][2]) .. '\n'
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
plugge

Re: dzVents get garbage collection dates (various)

Post by plugge »

Thanks waaren! It works fine now.
And thanks for the heads-up that Lua os.date behaves different on Windows systems. :o
plugge

Re: dzVents get garbage collection dates (various)

Post by plugge »

@waaren does this difference with Windows occurs elsewhere in the script, because it misses a date (27 august), but lists 03 september.

Code: Select all

2020-08-23 01:32:01.927 Status: dzVents: Info: collectGarbage: ------ Start internal script: GetGarbageDates: HTTPResponse: "getGarbage_Response"
2020-08-23 01:32:01.983 Status: dzVents: Info: collectGarbage: 2020-08-28
2020-08-23 01:32:01.983 Status: dzVents: Info: collectGarbage: 2020-09-03
2020-08-23 01:32:01.984 Status: dzVents: Info: collectGarbage: 2020-08-28
2020-08-23 01:32:01.984 Status: dzVents: Debug: collectGarbage: Papier en kartonnen verpakkingen
2020-08-23 01:32:01.984 Friday 28 August, 2020
2020-08-23 01:32:01.984 Status: dzVents: Info: collectGarbage: 2020-08-28
2020-08-23 01:32:02.002 Status: dzVents: Debug: collectGarbage: Processing device-adapter for GarbageAlert: Alert sensor adapter
2020-08-23 01:32:02.002 Status: dzVents: Debug: collectGarbage:
2020-08-23 01:32:02.002 alertLevel: 1, alertText: Papier en kartonnen verpakkingen
2020-08-23 01:32:02.002 Friday 28 August, 2020
2020-08-23 01:32:02.002 Status: dzVents: Info: collectGarbage: 2020-08-28
2020-08-23 01:32:02.002 Status: dzVents: Info: collectGarbage: 2020-09-03
2020-08-23 01:32:02.003 Status: dzVents: Debug: collectGarbage: Processing device-adapter for GarbageText: Text device
2020-08-23 01:32:02.005 Status: dzVents: Info: collectGarbage: ------ Finished GetGarbageDates
plugge

Re: dzVents get garbage collection dates (various)

Post by plugge »

plugge wrote: Sunday 23 August 2020 1:33 @waaren does this difference with Windows occurs elsewhere in the script, because it misses a date (27 august), but lists 03 september.
Found the culprit. :oops: The keyword is different for my community: "restgft" (kliko with two sections) instead of "restafval", plus some other keywords "kerstbomen", "textiel".
riko
Posts: 90
Joined: Saturday 22 August 2020 13:36
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: dzVents get garbage collection dates (various)

Post by riko »

Thanks, I now realise that I use an older script which one enabled me to make use of the RMN.nl schedule. I just tried to adjust the newest 14 June version to be able to load the RMN data. As my town doesn't support MijnAfvalwijzer. This older script made use of the BagId in the following REST call: https://inzamelschema.rmn.nl/rest/adressen/" ..myBagId .. "/kalender/" .. myYear (check https://inzamelschema.rmn.nl/rest/adres ... ender/2020 for an example of the response, which has possible another structure than Mijnafvalwijzer)

This is the adjusted part of the script that I tried:

Code: Select all

    execute = function(dz, item)

        --++++--------------------- Mandatory: Set your values and device names below this Line --------------------------------------
--        local myZipcode     = '3085RA'          -- Your zipcode like '3085RA'
--        local myHousenumber = 38                -- Your housenumber like 38
        local myBagId       = "0312200000006752"
        local myTextDevice  = 'GarbageText2'     -- Name with quotes or idx without when created as virtual text device
        local myAlertDevice = 'GarbageAlert2'    -- Name with quotes or idx without when created as virtual alert device
        local myYear = os.date("%Y")             -- Rik: weet niet zeker of deze er ook uit kan met dit nieuwe script?

        local myNotificationTable =
        {
             -- table with one or more notification systems.
             -- uncomment the notification systems that you want to be used
             -- Can be one or more of

             -- dz.NSS_FIREBASE_CLOUD_MESSAGING,
             -- dz.NSS_PUSHOVER,
             -- dz.NSS_HTTP,
             -- dz.NSS_KODI,
             -- dz.NSS_LOGITECH_MEDIASERVER,
             -- dz.NSS_NMA,
             -- dz.NSS_PROWL,
             -- dz.NSS_PUSHALOT,
             -- dz.NSS_PUSHBULLET,
             -- dz.NSS_PUSHOVER,
             -- dz.NSS_PUSHSAFER,
             dz.NSS_TELEGRAM,
        }
        --++++---------------------------- No changes required below this line --------------------------------------------

        local debug = ( dz.utils.LOG_MODULE_EXEC_INFO == dz.LOG_DEBUG )
        local garbageTypes  = {100,3,87,1}



        local function collectGarbageDates(secondsFromNow)
            local getGarbage_url = "https://inzamelschema.rmn.nl/rest/adressen/" ..myBagId .. "/kalender/" .. myYear
            dz.openURL ({ url = getGarbage_url ,
                          method = "GET",
                          callback = "getGarbage_Response" }).afterSec(secondsFromNow)
        end

This didn't work :(

Do you know a way how I can get the notification part working for the older script? Which worked fine for me till now. The notification on the day of collection used to work with the following code:

Code: Select all

if dz.time.matchesRule("at 06:00-17:00") and garbageToday then
dz.notify(longGarbageName(overallEarliestType) .. "wordt vandaag opgehaald")
end
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: dzVents get garbage collection dates (various)

Post by waaren »

riko wrote: Sunday 23 August 2020 14:16 Do you know a way how I can get the notification part working for the older script? Which worked fine for me till now. The notification on the day of collection used to work with the following code:
If you share the older script you use and still gives you a warning on the garbage collection day itself, I will have a look.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
riko
Posts: 90
Joined: Saturday 22 August 2020 13:36
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: dzVents get garbage collection dates (various)

Post by riko »

Thanks. I'll test it first myself on Thursday (Friday is the next collection day ;)). I'll let you know the result
waaren wrote: Sunday 23 August 2020 18:23
riko wrote: Sunday 23 August 2020 14:16 Do you know a way how I can get the notification part working for the older script? Which worked fine for me till now. The notification on the day of collection used to work with the following code:
If you share the older script you use and still gives you a warning on the garbage collection day itself, I will have a look.
ronaldbro
Posts: 327
Joined: Thursday 15 November 2018 21:38
Target OS: Raspberry Pi / ODroid
Domoticz version: 2020.2
Location: Netherlands
Contact:

Re: dzVents get garbage collection dates (various)

Post by ronaldbro »

ronaldbro wrote: Saturday 22 August 2020 23:06 Thanks waaren, just changed the code and will see in the coming days. Got a plastics pickup on Monday and paper on Tuesday so should get a notification tomorrow and Monday.
Thanks waaren, the change worked perfectly :)
riko
Posts: 90
Joined: Saturday 22 August 2020 13:36
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: dzVents get garbage collection dates (various)

Post by riko »

Last Friday's garbage collection proofed my adjustments didn't work :(

This is the full code of the script I use. As you see I've adjusted the garbage types according to my local situation:

Code: Select all

--[[ getGarbageDates.lua for [ dzVents >= 2.4 ]

This script is only useful in those areas of the Netherlands where the HVC group collects household garbage

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

Ga naar de volgende url in de browser, waarbij je de juiste url voor jouw afvalverwerker kiest, en postcode en huisnummer wijzigd.
https://apps.hvcgroep.nl/rest/adressen/3328LN-35
de output die je krijgt te zien bevat een bagID wat je later nodig hebt.

Dit bagId wordt gebruikt in de volgende URLs:
Ophaaldagen: https://apps.hvcgroep.nl/rest/adressen/BagID/kalender/2018 <<replace BagID
De ophaaldagen gebruiken ID's om aan te geven welk afvaltype het betreft.
Informatie over deze afvaltypes kan opgehaald worden via:
https://apps.hvcgroep.nl/rest/adressen/BagID/afvalstromen <<replace BagID

]]--

return {
active = true,
on = { timer = { "at 20:00","at 07:00" }, -- daily run twice
-- { timer = {'every 1 minutes'},
httpResponses = { "getGarbage_Response" } -- Trigger the handle Json part
},

logging = { level = domoticz.LOG_INFO, -- Remove the "-- at the beginning of this and next line for debugging the script
marker = "collectGarbage" },

data = { garbage = {initial = {} }, -- Keep a copy of last json just in case
},

execute = function(dz, triggerObject)

--++++--------------------- Mandatory: Set your values and device names below this Line --------------------------------------
local myTextDevice = "Garbage" -- 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
local myBagId = "0312200000006752"
local myYear = os.date("%Y")

-- it can happen that other examples then HVC uses other numbers, change them at line
garbageTypes = {100,3,87,1}

--++++---------------------------- Set your values and device names above this Line --------------------------------------------

local function collectGarbageDates(secondsFromNow)
local getGarbage_url = "https://inzamelschema.rmn.nl/rest/adressen/" ..myBagId .. "/kalender/" .. myYear
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)
return (delta == 0)
end

local function longGarbageName(str) -- Use descriptive strings
str = tostring(str)
str = str:gsub("100"," Plastic ")
str = str:gsub("3"," GFT afval (bruin) ")
str = str:gsub("87"," Oud papier en kartonnen (blauw) ")
str = str:gsub("1"," Restafval (grijs) ")
return str
end

local function handleResponse()
if #triggerObject.json > 0 then
dz.data.garbage = triggerObject.json
rt = triggerObject.json
else
errorMessage("Problem with response from hvcgroep (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 HVC group area ?")
return false
end
end
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")

for i = 1,#garbageTypes do --walk the the type Table
typeEarliestDate = "2999-12-31"
for j = 1,#rt do -- walk the result Table
-- walk the response table
if rt[j].ophaaldatum >= today and rt[j].ophaaldatum < typeEarliestDate and
rt[j].afvalstroom_id == garbageTypes[i] then -- Keep date closest to today per type
typeEarliestDate = rt[j].ophaaldatum
if typeEarliestDate < overallEarliestDate then -- date closest to today overall ?
overallEarliestDate = typeEarliestDate -- keep date
overallEarliestType = garbageTypes[i] -- keep type
end
garbageLines = garbageLines .. string2Date(typeEarliestDate,"%a %e %b" ) .. longGarbageName(rt[j].afvalstroom_id) .. " " .. "\n"
typeEarliestDate = rt[j].ophaaldatum -- Keep date closest to today

end
end
end

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)
end

if dz.time.matchesRule("at 06:00-17:00") and garbageToday then
dz.notify(longGarbageName(overallEarliestType) .. "wordt vandaag opgehaald")
end


if (dz.time.addHours(24).rawDate == garbage) and dz.time.matchesRule("at 18:00-22:00") then
dz.notify(longGarbageName(overallEarliestType) .. "wordt morgen opgehaald")
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
}
I tried to create a line myself, but it doesn't work (see one of the latest lines in the script):

Code: Select all

if (dz.time.addHours(24).rawDate == garbage) and dz.time.matchesRule("at 18:00-22:00") then
dz.notify(longGarbageName(overallEarliestType) .. "wordt morgen opgehaald")
end
Could you help me in fixing this? Or even better: if it is easy for you to enable the RMN schedule in your latest release of the script it is even better. I think it was there in earlier versions. I also like your new feature of the sorting on date, which is neither there in the old script.
waaren wrote: Sunday 23 August 2020 18:23
riko wrote: Sunday 23 August 2020 14:16 Do you know a way how I can get the notification part working for the older script? Which worked fine for me till now. The notification on the day of collection used to work with the following code:
If you share the older script you use and still gives you a warning on the garbage collection day itself, I will have a look.
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: dzVents get garbage collection dates (various)

Post by waaren »

riko wrote: Monday 31 August 2020 14:58 Could you help me in fixing this? Or even better: if it is easy for you to enable the RMN schedule in your latest release of the script it is even better. I think it was there in earlier versions. I also like your new feature of the sorting on date, which is neither there in the old script.
Can you try this?

Code: Select all

--[[ getGarbageDates.lua for [ dzVents >= 2.4.28 ]
--

Enter your bagid 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 20:00',
                'at 07:00'
            },

            devices =
            {
               -- 'getGarbage',                -- Only for test purposes can be ignored
            },

            httpResponses =
            {
                'getGarbage_Response' -- Trigger to handle Json part
            },
        },

        logging =
        {
            level = domoticz.LOG_ERROR, -- set to LOG_DEBUG when something does not work as expected
            marker = 'collectGarbage',
        },

        data =
        {
            garbage =
            {
                initial = {},              -- Keep a copy of last json just in case
            },
        },

    execute = function(dz, item)

        --++++--------------------- Mandatory: Set your values and device names below this Line --------------------------------------
        local myBagId = "0312200000006752"
        local myYear = os.date("%Y")
        local myTextDevice = "Garbage" -- 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
        
        local myNotificationTable =
        {
             -- table with one or more notification systems.
             -- uncomment the notification systems that you want to be used
             -- Can be one or more of

             -- dz.NSS_FIREBASE_CLOUD_MESSAGING,
             dz.NSS_PUSHOVER,
             -- dz.NSS_HTTP,
             -- dz.NSS_KODI,
             -- dz.NSS_LOGITECH_MEDIASERVER,
             -- dz.NSS_NMA,
             -- dz.NSS_PROWL,
             -- dz.NSS_PUSHALOT,
             -- dz.NSS_PUSHBULLET,
             -- dz.NSS_PUSHOVER,
             -- dz.NSS_PUSHSAFER,
             -- dz.NSS_TELEGRAM,
        }

        local longGarbageName =
        {
            [100] = "Plastic",
            [3] = "GFT afval (bruin)",
            [87] = "Oud papier en kartonnen (blauw)",
            [1] = "Restafval (grijs)"
        }

        --++++---------------------------- No changes required below this line --------------------------------------------

        local function collectGarbageDates(secondsFromNow)
            local getGarbage_url = "https://inzamelschema.rmn.nl/rest/adressen/" ..myBagId .. "/kalender/" .. myYear
                dz.openURL ({ url = getGarbage_url ,
                callback = "getGarbage_Response" }).afterSec(secondsFromNow)
        end

        -- Add entry to log and notify to set subsystems
        local function errorMessage(message)
            dz.log(message,dz.LOG_ERROR)
            dz.notify('Garbage',message, dz.PRIORITY_HIGH, dz.SOUND_DEFAULT, "" , myNotificationTable)
        end

        local function convertDateFormat(dateString, fromPattern, toFormat)
            local fromPattern = fromPattern or '(%d+)-(%d+)-(%d+)'
            local toFormat = toFormat or '%a %d %b'
            local runyear, runmonth, runday= dateString:match(fromPattern)
            return os.date(toFormat, os.time({year = runyear, month = runmonth, day = runday}) )
        end

        local function text(lines)
            if dz.utils.deviceExists(myTextDevice) then
               dz.devices(myTextDevice).updateText( table.concat(lines, '\n') )
            end
        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 alert(lines)
            if dz.utils.deviceExists(myAlertDevice) then
                dz.devices(myAlertDevice).updateAlertSensor(alertLevel(lines.delta), lines[1])
            end

            if dz.time.matchesRule('at 05:00-09:00') and lines.delta == 0  then
                dz.notify('Huisafval',lines[1]:match('%: (.*)')  .. ' will be collected today', dz.PRIORITY_NORMAL,dz.SOUND_DEFAULT, "" , myNotificationTable)
            elseif dz.time.matchesRule('at 17:00-22:00') and lines.delta == 1 then
                dz.notify('Huisafval',lines[1]:match('%: (.*)')  .. ' will be collected tomorrow', dz.PRIORITY_NORMAL,dz.SOUND_DEFAULT, "" , myNotificationTable)
            end
        end

        local function selectRecords(t)
            dateRecords = {}
            for _, garbage in ipairs(t) do
                if garbage.ophaaldatum >= dz.time.rawDate then
                    if dateRecords[garbage.ophaaldatum] then
                         table.insert(dateRecords[garbage.ophaaldatum], longGarbageName[garbage.afvalstroom_id] )
                    else
                        dateRecords[garbage.ophaaldatum] = { longGarbageName[garbage.afvalstroom_id] }
                    end
                    dz.log(garbage.ophaaldatum .. ' = ' .. longGarbageName[garbage.afvalstroom_id], dz.LOG_DEBUG)
                end
            end
            return dateRecords
        end

        local function makeLines(t)
            local startDate = dz.time
            local futureDay = 0
            local lineCounter = 1
            local textLines = {}

            while lineCounter < 5 and futureDay < 60 do
                local traverseDate = startDate.addDays(futureDay).rawDate
                if t[traverseDate] then
                    local textLine = convertDateFormat(traverseDate) .. ': ' .. table.concat(t[traverseDate], ' plus ')
                    if lineCounter == 1 then textLines.delta = futureDay end
                    textLines[lineCounter] = textLine
                    lineCounter = lineCounter + 1
                end
                futureDay = futureDay + 1
            end

            return textLines
        end

       local function handleResponse()

            if not(item.ok and item.json) then
                errorMessage('Problem with response (no data). Try 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. is bagnumber ok?')
                    return false
                end
            else
                rt = selectRecords(item.json)

                textLines = makeLines(rt)
                alert(textLines)
                text(textLines)
            end
        end

        -- Main
        if item.isHTTPResponse then
            if item.ok then
                handleResponse()
            else
                errorMessage('Problem with response (not ok)')
                collectGarbageDates(600)                                           -- response not OK, try again after 10 minutes
            end
        else
            collectGarbageDates(1)
        end
    end
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
riko
Posts: 90
Joined: Saturday 22 August 2020 13:36
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: dzVents get garbage collection dates (various)

Post by riko »

waaren wrote: Monday 31 August 2020 17:19 Can you try this?
Thanks, waaren. The script is working so far: devices are updated, and sorted(!), no errors :D

I'll have to test the notifications this weekend again. I'll let you know about the result
riko
Posts: 90
Joined: Saturday 22 August 2020 13:36
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: dzVents get garbage collection dates (various)

Post by riko »

It is working, thanks a lot waaren!

For all others who want to use RMN.nl as the data source (for certain Dutch municipalities). This is the script that works. Simply fill-in the bag ID field with the number you can find on: https://inzamelschema.rmn.nl/rest/adressen/0000aa-99 (0000aa = zip code - 00 = house number)

Code: Select all

--[[ getGarbageDates.lua for [ dzVents >= 2.4.28 ]
--

Enter your bagid 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 20:00',
                'at 07:00'
            },

            devices =
            {
               -- 'getGarbage',                -- Only for test purposes can be ignored
            },

            httpResponses =
            {
                'getGarbage_Response' -- Trigger to handle Json part
            },
        },

        logging =
        {
            level = domoticz.LOG_DEBUG, -- set to LOG_DEBUG when something does not work as expected
            marker = 'collectGarbage',
        },

        data =
        {
            garbage =
            {
                initial = {},              -- Keep a copy of last json just in case
            },
        },

    execute = function(dz, item)

        --++++--------------------- Mandatory: Set your values and device names below this Line --------------------------------------
        local myBagId = "XXXXXXXX" -- Find bagid at https://inzamelschema.rmn.nl/rest/adressen/0000aa-99 (zip code - house number)
        local myYear = os.date("%Y")
        local myTextDevice = "Garbage" -- 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
        
        local myNotificationTable =
        {
             -- table with one or more notification systems.
             -- uncomment the notification systems that you want to be used
             -- Can be one or more of

             -- dz.NSS_FIREBASE_CLOUD_MESSAGING,
             -- dz.NSS_PUSHOVER,
             -- dz.NSS_HTTP,
             -- dz.NSS_KODI,
             -- dz.NSS_LOGITECH_MEDIASERVER,
             -- dz.NSS_NMA,
             -- dz.NSS_PROWL,
             -- dz.NSS_PUSHALOT,
             -- dz.NSS_PUSHBULLET,
             -- dz.NSS_PUSHOVER,
             -- dz.NSS_PUSHSAFER,
             dz.NSS_TELEGRAM,
        }

        local longGarbageName =
        {
            [100] = "Plastic",
            [3] = "GFT afval (bruin)",
            [87] = "Oud papier en kartonnen (blauw)",
            [1] = "Restafval (grijs)"
        }

        --++++---------------------------- No changes required below this line --------------------------------------------

        local function collectGarbageDates(secondsFromNow)
            local getGarbage_url = "https://inzamelschema.rmn.nl/rest/adressen/" ..myBagId .. "/kalender/" .. myYear
                dz.openURL ({ url = getGarbage_url ,
                callback = "getGarbage_Response" }).afterSec(secondsFromNow)
        end

        -- Add entry to log and notify to set subsystems
        local function errorMessage(message)
            dz.log(message,dz.LOG_ERROR)
            dz.notify('Garbage',message, dz.PRIORITY_HIGH, dz.SOUND_DEFAULT, "" , myNotificationTable)
        end

        local function convertDateFormat(dateString, fromPattern, toFormat)
            local fromPattern = fromPattern or '(%d+)-(%d+)-(%d+)'
            local toFormat = toFormat or '%a %d %b'
            local runyear, runmonth, runday= dateString:match(fromPattern)
            return os.date(toFormat, os.time({year = runyear, month = runmonth, day = runday}) )
        end

        local function text(lines)
            if dz.utils.deviceExists(myTextDevice) then
               dz.devices(myTextDevice).updateText( table.concat(lines, '\n') )
            end
        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 alert(lines)
            if dz.utils.deviceExists(myAlertDevice) then
                dz.devices(myAlertDevice).updateAlertSensor(alertLevel(lines.delta), lines[1])
            end

            if dz.time.matchesRule('at 05:00-09:00') and lines.delta == 0  then
                dz.notify('Huisafval',lines[1]:match('%: (.*)')  .. ' will be collected today', dz.PRIORITY_NORMAL,dz.SOUND_DEFAULT, "" , myNotificationTable)
            elseif dz.time.matchesRule('at 17:00-22:00') and lines.delta == 1 then
                dz.notify('Huisafval',lines[1]:match('%: (.*)')  .. ' will be collected tomorrow', dz.PRIORITY_NORMAL,dz.SOUND_DEFAULT, "" , myNotificationTable)
            end
        end

        local function selectRecords(t)
            dateRecords = {}
            for _, garbage in ipairs(t) do
                if garbage.ophaaldatum >= dz.time.rawDate then
                    if dateRecords[garbage.ophaaldatum] then
                         table.insert(dateRecords[garbage.ophaaldatum], longGarbageName[garbage.afvalstroom_id] )
                    else
                        dateRecords[garbage.ophaaldatum] = { longGarbageName[garbage.afvalstroom_id] }
                    end
                    dz.log(garbage.ophaaldatum .. ' = ' .. longGarbageName[garbage.afvalstroom_id], dz.LOG_DEBUG)
                end
            end
            return dateRecords
        end

        local function makeLines(t)
            local startDate = dz.time
            local futureDay = 0
            local lineCounter = 1
            local textLines = {}

            while lineCounter < 5 and futureDay < 60 do
                local traverseDate = startDate.addDays(futureDay).rawDate
                if t[traverseDate] then
                    local textLine = convertDateFormat(traverseDate) .. ': ' .. table.concat(t[traverseDate], ' plus ')
                    if lineCounter == 1 then textLines.delta = futureDay end
                    textLines[lineCounter] = textLine
                    lineCounter = lineCounter + 1
                end
                futureDay = futureDay + 1
            end

            return textLines
        end

       local function handleResponse()

            if not(item.ok and item.json) then
                errorMessage('Problem with response (no data). Try 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. is bagnumber ok?')
                    return false
                end
            else
                rt = selectRecords(item.json)

                textLines = makeLines(rt)
                alert(textLines)
                text(textLines)
            end
        end

        -- Main
        if item.isHTTPResponse then
            if item.ok then
                handleResponse()
            else
                errorMessage('Problem with response (not ok)')
                collectGarbageDates(600)                                           -- response not OK, try again after 10 minutes
            end
        else
            collectGarbageDates(1)
        end
    end
}
riko
Posts: 90
Joined: Saturday 22 August 2020 13:36
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: dzVents get garbage collection dates (various)

Post by riko »

Unfortunately one more bug to report with the script above.
The 'tomorrow notification' works correctly in normal cases, but doesn't work when there is also garbage to be collected today (and tomorrow again)
I don't recognise this problem in the script, anyone knows how to fix this?
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: dzVents get garbage collection dates (various)

Post by waaren »

riko wrote: Saturday 05 September 2020 19:56 Unfortunately one more bug to report with the script above.
The 'tomorrow notification' works correctly in normal cases, but doesn't work when there is also garbage to be collected today (and tomorrow again)
I don't recognise this problem in the script, anyone knows how to fix this?
Can you try with this? Idea is that you will get a notification in the morning for a collection today and a notification in the evening for a collection tomorrow.

Code: Select all

--[[ getGarbageDates.lua for [ dzVents >= 2.4.28 ]
--

Enter your bagid 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

]]--

local eveningRun = 'at 20:00'
local morningRun = 'at 07:00'

return
{
        on =
        {
            timer =
            {
                morningRun,
                eveningRun,
            },

            devices =
            {
               -- 'getGarbage',                -- Only for test purposes can be ignored
            },

            httpResponses =
            {
                'getGarbage_Response' -- Trigger to handle Json part
            },
        },

        logging =
        {
            level = domoticz.LOG_DEBUG, -- set to LOG_DEBUG when something does not work as expected
            marker = 'collectGarbage',
        },

        data =
        {
            garbage =
            {
                initial = {},              -- Keep a copy of last json just in case
            },
        },

    execute = function(dz, item)

        --++++--------------------- Mandatory: Set your values and device names below this Line --------------------------------------
        local myBagId = "XXXXXXXX" -- Find bagid at https://inzamelschema.rmn.nl/rest/adressen/0000aa-99 (zip code - house number)
        local myYear = os.date("%Y")
        local myTextDevice = "Garbage" -- 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

        local myNotificationTable =
        {
             -- table with one or more notification systems.
             -- uncomment the notification systems that you want to be used
             -- Can be one or more of

             -- dz.NSS_FIREBASE_CLOUD_MESSAGING,
             -- dz.NSS_PUSHOVER,
             -- dz.NSS_HTTP,
             -- dz.NSS_KODI,
             -- dz.NSS_LOGITECH_MEDIASERVER,
             -- dz.NSS_NMA,
             -- dz.NSS_PROWL,
             -- dz.NSS_PUSHALOT,
             -- dz.NSS_PUSHBULLET,
             -- dz.NSS_PUSHOVER,
             -- dz.NSS_PUSHSAFER,
             dz.NSS_TELEGRAM,
        }

        local longGarbageName =
        {
            [100] = "Plastic",
            [3] = "GFT afval (bruin)",
            [87] = "Oud papier en kartonnen (blauw)",
            [1] = "Restafval (grijs)"
        }

        --++++---------------------------- No changes required below this line --------------------------------------------

        local function collectGarbageDates(secondsFromNow)
            local getGarbage_url = "https://inzamelschema.rmn.nl/rest/adressen/" ..myBagId .. "/kalender/" .. myYear
                dz.openURL ({ url = getGarbage_url ,
                callback = "getGarbage_Response" }).afterSec(secondsFromNow)
        end

        -- Add entry to log and notify to set subsystems
        local function errorMessage(message)
            dz.log(message,dz.LOG_ERROR)
            dz.notify('Garbage',message, dz.PRIORITY_HIGH, dz.SOUND_DEFAULT, "" , myNotificationTable)
        end

        local function convertDateFormat(dateString, fromPattern, toFormat)
            local fromPattern = fromPattern or '(%d+)-(%d+)-(%d+)'
            local toFormat = toFormat or '%a %d %b'
            local runyear, runmonth, runday= dateString:match(fromPattern)
            return os.date(toFormat, os.time({year = runyear, month = runmonth, day = runday}) )
        end

        local function text(lines)
            if dz.utils.deviceExists(myTextDevice) then
               dz.devices(myTextDevice).updateText( table.concat(lines, '\n') )
            end
        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 alert(lines)
            if dz.utils.deviceExists(myAlertDevice) then
                dz.devices(myAlertDevice).updateAlertSensor(alertLevel(lines.delta), lines[1])
            end

            if dz.time.matchesRule('at 05:00-09:00') and lines.delta == 0  then
                dz.notify('Huisafval',lines[1]:match('%: (.*)')  .. ' will be collected today', dz.PRIORITY_NORMAL,dz.SOUND_DEFAULT, "" , myNotificationTable)
            elseif dz.time.matchesRule('at 17:00-22:00') and lines.delta == 1 then
                dz.notify('Huisafval',lines[1]:match('%: (.*)')  .. ' will be collected tomorrow', dz.PRIORITY_NORMAL,dz.SOUND_DEFAULT, "" , myNotificationTable)
            end
        end

        local function selectRecords(t)
            dateRecords = {}
            for _, garbage in ipairs(t) do
                if garbage.ophaaldatum >= dz.time.rawDate then
                    if dateRecords[garbage.ophaaldatum] then
                         table.insert(dateRecords[garbage.ophaaldatum], longGarbageName[garbage.afvalstroom_id] )
                    else
                        dateRecords[garbage.ophaaldatum] = { longGarbageName[garbage.afvalstroom_id] }
                    end
                    dz.log(garbage.ophaaldatum .. ' = ' .. longGarbageName[garbage.afvalstroom_id], dz.LOG_DEBUG)
                end
            end
            return dateRecords
        end

        local function makeLines(t)
            local startDate = dz.time
            local futureDay = 0
            local lineCounter = 1
            local textLines = {}

            if dz.time.matchesRule(eveningRun) then futureDay = 1 end

            while lineCounter < 5 and futureDay < 60 do
                local traverseDate = startDate.addDays(futureDay).rawDate
                if t[traverseDate] then
                    local textLine = convertDateFormat(traverseDate) .. ': ' .. table.concat(t[traverseDate], ' plus ')
                    if lineCounter == 1 then textLines.delta = futureDay end
                    textLines[lineCounter] = textLine
                    lineCounter = lineCounter + 1
                end
                futureDay = futureDay + 1
            end

            return textLines
        end

       local function handleResponse()

            if not(item.ok and item.json) then
                errorMessage('Problem with response (no data). Try 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. is bagnumber ok?')
                    return false
                end
            else
                rt = selectRecords(item.json)

                textLines = makeLines(rt)
                alert(textLines)
                text(textLines)
            end
        end

        -- Main
        if item.isHTTPResponse then
            if item.ok then
                handleResponse()
            else
                errorMessage('Problem with response (not ok)')
                collectGarbageDates(600)                                           -- response not OK, try again after 10 minutes
            end
        else
            collectGarbageDates(1)
        end
    end
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
riko
Posts: 90
Joined: Saturday 22 August 2020 13:36
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: dzVents get garbage collection dates (various)

Post by riko »

Yes, this one seems to be working, thanks!!
Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests