dzVents get garbage collection dates (various)

User avatar
waaren
Posts: 1051
Joined: Tuesday 03 January 2017 15:18
Target OS: Raspberry Pi
Domoticz version: Beta
Location: Netherlands
Contact:

Re: dzVents get garbage collection dates from inzamelkalender.hvcgroep.nl

Post by waaren » Friday 14 September 2018 17:28

Huntback wrote:
Friday 14 September 2018 12:36
waaren wrote:
Tuesday 11 September 2018 21:24
Superpjeter wrote:
Tuesday 11 September 2018 19:42
Thanks for your offer but I already figured it out
Good to read. Can you please share your solution for the benefit of other forum users ?
Thx
.. So would you please, if you have time for it, take a to look at the script so that this can also work for https://afvalkalender.circulus-berkel.nl?
Will do but still traveling so please don't expect anything until late next week
Raspberry (debian stretch via berryboot on Synology DS916+) , Domoticz (almost) latest Beta, , dzVents 2.6, RFLink, RFXtrx433e, P1, Youless, Harmony, Hue, Yeelight, Xiaomi, HomeWizard, Zwave, Amazon echo

User avatar
waaren
Posts: 1051
Joined: Tuesday 03 January 2017 15:18
Target OS: Raspberry Pi
Domoticz version: Beta
Location: Netherlands
Contact:

Re: dzVents get garbage collection dates from inzamelkalender.hvcgroep.nl

Post by waaren » Tuesday 18 September 2018 8:14

Huntback wrote:
Friday 14 September 2018 12:36
So would you please, if you have time for it, take a to look at the script so that this can also work for https://afvalkalender.circulus-berkel.nl?
Some adjustments were needed to the original script because circulus-berkel return a JSON that must be reformatted before it can be used as a Lua table with consecutive record numbers.
Also introduced an extra initial step to get the bagId automatically based on zipCode / houseNumber

Could you please test this and report your findings ?

Code: Select all

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

this script is only useful in those  areas of the Netherlands where circulus-berkel is the garbage collector

Enter your zipcode and housenumber and your virtual text and or virtual alert device in the 
appropriate place between the lines starting with --++++

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 garbagecollection that will arrive first
]]--

local prefix        = "getGarbageDates"
local httpresponse  = prefix .. "Response"
local triggerDevice = prefix .. "Trigger"
local logMarker     = prefix .. "Marker"

return 
        {
     on      =  {   devices        =   { triggerDevice },            -- Just for development and test ; ignored when live
                    timer          =   { "at 00:05","at 08:00" },    -- daily run twice
                    httpResponses  =  { httpresponse }               -- Trigger the handle Json part
                },

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

    data    =   {   garbage     = { initial = {} },                  -- Keep a copy of last json just in case
                    bagID       = { initial = "Not set yet" },           
                    ZipCode     = { initial = "not set yet" },
                    HouseNumber = { initial = "not set yet" },
                },

    execute = function(dz, triggerObject)

        --++++--------------------- Mandatory: Set your values and device names below this Line --------------------------------------
        local myZipCode     = "7328CK"
        local myHouseNumber = 46
        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 myProvider    = "https://afvalkalender.circulus-berkel.nl" 
        local myYear        = os.date("%Y")

        garbageTypes  = {13,7,8,10}                -- Valid for circulus-berkelfor but these numbers vary per garbageCollector; Why ??
         -- ("13","  Boeken, Elektrische apparaten, Speelgoed en Textiel  ")
         -- ("7","  Groente-, fruit- en tuin afval            ")
         --  ("10","  Papier en kartonnen verpakkingen          ")
         --  ("8","  Restafval                                ")

        -- get BagId based on Zipcode / Housenumber 
        local function collectBagId(secondsFromNow)
            local getBagId_url  = myProvider .. "/rest/adressen/" .. myZipCode .."-" .. myHouseNumber
            dz.openURL  ({  url         = getBagId_url ,
                            method      = "GET",
                            callback    = httpresponse}).afterSec(secondsFromNow)
        end
        
        -- get garbage collect Year calendar 
        local function collectGarbageDates(secondsFromNow)
            local getGarbage_url  = myProvider .. "/rest/adressen/" .. dz.data.bagID .. "/kalender/" .. myYear
            dz.openURL  ({  url         = getGarbage_url ,
                            method      = "GET",
                            callback    = httpresponse}).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("13","  Boeken, Elektrische apparaten, Speelgoed en Textiel  ")
            str = str:gsub("7","  Groente-, fruit- en tuin afval            ")
            str = str:gsub("10","  Papier en kartonnen verpakkingen          ")
            str = str:gsub("8","  Restafval                                ")
            return str
        end
        
        -- extract bafId from json and store in persistent data
        local function getBagID()
            rt = dz.utils.fromJSON(triggerObject.data)
            dz.data.bagID = rt[1].bagId
            collectGarbageDates(1)
        end
        
        -- 
        local function handleResponse()
            dz.log(dz.data.bagID,dz.LOG_DEBUG)
            
            if dz.data.bagID == "Not set yet"  then
               getBagID()
               return
            end   
            rt , rtRaw = {}
            rtRaw = dz.utils.fromJSON(triggerObject.data)         -- dzVents does nor recognize the response as pure JSON so conversion is required
            
            if rtRaw["1"] ~=  nil then
                for k, v in pairs(rtRaw) do                        -- Extra step is necessary because json is not standard and some records are missing 
                    table.insert( rt, { ophaaldatum = v.ophaaldatum , afvalstroom_id = v.afvalstroom_id })
                end    
                dz.data.garbage = rt
            else
                errorMessage("Problem with response from  (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 circulus-berkel area?")
                    return false
                end
            end
            
            local garbageLines = ""
            local typeEarliestDate
            local typeEarliestKind
            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
                 dz.log("Checking " .. garbageTypes[i],dz.LOG_DEBUG)
                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
                        typeEarliestKind =  rt[j].afvalstroom_id
                        if  typeEarliestDate < overallEarliestDate then  -- date closest to today overall ?
                            overallEarliestDate = typeEarliestDate      -- keep date
                            overallEarliestType =  garbageTypes[i]            -- keep type
                        end
                    end
                end
                garbageLines = garbageLines .. string2Date(typeEarliestDate,"%a %e %b" ) .. longGarbageName(typeEarliestKind) .. " " .. "\n"
            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 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 " .. myProvider .. " (not ok)")
                collectGarbageDates(600)                            -- response not OK, try again after 10 minutes
            end
        else
            if dz.data.bagID == "Not set yet"  or dz.data.ZipCode ~= myZipCode or dz.data.HouseNumber ~= myHouseNumber then
            -- Initial or something changed in zipCode / HouseNumebr
                dz.data.ZipCode     = myZipCode  
                dz.data.HouseNumber = myHouseNumber
                dz.data.bagID       = "Not set yet"
                collectBagId(1)
            else
                collectGarbageDates(1)
            end
        end
    end
}
Raspberry (debian stretch via berryboot on Synology DS916+) , Domoticz (almost) latest Beta, , dzVents 2.6, RFLink, RFXtrx433e, P1, Youless, Harmony, Hue, Yeelight, Xiaomi, HomeWizard, Zwave, Amazon echo

Huntback
Posts: 3
Joined: Monday 02 January 2017 15:35
Target OS: NAS (Synology & others)
Domoticz version: 4.9700
Location: Apeldoorn
Contact:

Re: dzVents get garbage collection dates (various)

Post by Huntback » Tuesday 18 September 2018 21:26

hello waaren,

The script is now working :)
'myTextDevice' and 'myAlertDevice' were updated immediately.
First garbage collection day is here next Thursday, on that day also the notification in the 'myAlertDevice' must be updated with "will be collected today".
I now assume that this also works.
If not or with other problems with the script then I report again.
For now thank you very much for the quick response and the modification of the script.
Synology - DS918+
RFXCOM - RFXtrx433
TFA - Weatherstation
Some KAKU, etc.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest