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 from inzamelkalender.hvcgroep.nl

Post by waaren »

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
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
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 from inzamelkalender.hvcgroep.nl

Post by waaren »

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
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
Huntback
Posts: 28
Joined: Monday 02 January 2017 14:35
Target OS: NAS (Synology & others)
Domoticz version: 2024.2
Location: Apeldoorn
Contact:

Re: dzVents get garbage collection dates (various)

Post by Huntback »

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 - DS411+II
Synology - DS918+
RFXCOM - RFXtrx433XL (LAN)
Oregon - Weatherstation
Some KAKU, Impuls, TFA, etc.
delcara
Posts: 11
Joined: Wednesday 07 November 2018 10:48
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.10171
Location: Netherlands
Contact:

Re: dzVents get garbage collection dates (various)

Post by delcara »

Hello Waaren,

I'm trying to create a script to get garbage collection dates from ROVA. I've discovered how to get the dates through a curl command. But I've no idea how to translate this to a dzVents script. I've just started with DzVents and have now translated all my blockly to DzVents (relatively simple scripts to control lights etc.). Can you help to translate this curl command to a DzVents script?

Code: Select all

curl -v --cookie "RovaLc_inwoners={\"Id\":160267,\"ZipCode\":\"8103JB\",\"HouseNumber\":\"15\",\"HouseAddition\":null,\"Municipality\":\"Raalte\",\"Province\":null,\"Firstname\":null,\"Lastname\":null,\"UserAgent\":\"\",\"School\":null,\"Street\":null,\"Country\":null,\"Portal\":null,\"AreaLevel\":5,\"City\":\"Raalte\",\"Ip\":null}" https://www.rova.nl/api/TrashCalendar/GetCalendarItems?portal=inwoners


Then the output lookes like this:

Code: Select all

*   Trying 141.138.194.225...
* TCP_NODELAY set
* Connected to www.rova.nl (141.138.194.225) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: CN=www.rova.nl
*  start date: Oct 30 06:51:49 2018 GMT
*  expire date: Jan 28 06:51:49 2019 GMT
*  subjectAltName: host "www.rova.nl" matched cert's "www.rova.nl"
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
> GET /api/TrashCalendar/GetCalendarItems?portal=inwoners HTTP/1.1
> Host: www.rova.nl
> User-Agent: curl/7.52.1
> Accept: */*
> Cookie: RovaLc_inwoners={"Id":160267,"ZipCode":"8103JB","HouseNumber":"15","HouseAddition":null,"Municipality":"Raalte","Province":null,"Firstname":null,"Lastname":null,"UserAgent":"","School":null,"Street":null,"Country":null,"Portal":null,"AreaLevel":5,"City":"Raalte","Ip":null}
>
< HTTP/1.1 200 OK
< Cache-Control: no-cache
< Pragma: no-cache
< Content-Type: application/json; charset=utf-8
< Expires: -1
< Server: Microsoft-IIS/8.5
< X-AspNet-Version: 4.0.30319
< X-Powered-By: ASP.NET
< Date: Wed, 07 Nov 2018 10:20:55 GMT
< Content-Length: 286
<
* Curl_http_done: called premature == 0
* Connection #0 to host www.rova.nl left intact
[{"GarbageTypeCode":"GFT","GarbageType":"GFT","Date":"2018-11-12T00:00:00","Regular":true},{"GarbageTypeCode":"REST","GarbageType":"Restafval","Date":"2018-11-16T00:00:00","Regular":true},{"GarbageTypeCode":"PLASTICPLUS","GarbageType":"PMD","Date":"2018-11-19T00:00:00","Regular":true}]
The ID can be everything doesn't matter if I change this, I still got the correct dates for my address.
Raspberry pi 3, Domoticz Beta, Nginx, dzVents 2.7.4, RFXtrx433e, P1 smart meter, Harmony, Hue, Zwave, Amazon echo, Sonos, Synology DS413, HomeBridge, HA Bridge, Ubiquiti.
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 »

Just sent a PM
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
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 »

delcara wrote: Wednesday 07 November 2018 11:24 I'm trying to create a script to get garbage collection dates from ROVA. I've discovered how to get the dates through a curl command. But I've no idea how to translate this to a dzVents script. I've just started with DzVents and have now translated all my blockly to DzVents (relatively simple scripts to control lights etc.). Can you help to translate this curl command to a DzVents script?
Please have a look at the script below.
I tried to translate the curl command into a domoticz.openUrl but I failed in finding the working syntax (the cookie table seems to mess up the openUrl internally). If someone else has found a solution for this I would be much obliged if that solution could be shared here.
So had to use the curl command itself. To ensure that a wait time for the JSON return would not stall the event thread, the command is processed in the background and the script will come back every couple of seconds to check if it is already there.
(In practice I have not seen that the return have taken more then 2 seconds, but just to be sure)

Code: Select all

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

    this script is only useful in those  areas of the Netherlands where the household garbage collector is rova
    Tested on debian stretch but probably also working on other Linux variants.

    needs curl command 
    needs to be able to process commands in the background ( by using leading &)

    Enter your zipcode, housenumber and garbageID in the appropriate places 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 types of household garbage
    the alert device will contain the date and type for the garbagecollection that will arrive first
    notification system will be called when collect will be today

]]-- 
 return {
         on =   {   timer           =   { "at 00:05","at 08:00" },    -- daily run twice
                    devices         =   { "getGarbage"          },    -- Ignore just for test  
                    httpResponses   =   { "delay_Response"      },    -- (re)triggers the script
                },
                
    logging =   {   level   = domoticz.LOG_DEBUG ,              -- Change to ERROR when script is behaving as expected  
                    marker  = ""},                              -- Will be set in execute = function block 
            
    data    =   {   delay           =  { initial = 0 },
                },

    execute = function(dz, item, info)

    -- ************************* Mandatory: Set your values and device names below this Line 
        
        local myZipcode     = "0000AA"            -- Your zipcode like "3085RA"
        local myHousenumber = "99"                -- Your housenumber like 38
        local myGarbageID   = "9999999"            -- Your GarbageID
        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
        
    -- **************************************************************** No changes required below this  
       local initialDelay           = 2 
       local repeatDelay            = 10
       local maxDelay               = 60
       local outFile                = "/tmp/garbageCollectionDates.json"
       local catCommand             = "cat"
       local garbageToday           = false
       
        _G.logMarker                = info.scriptName     -- sets the logmarker for dz.log
       
        local function logWrite(str,level)
            dz.log(str,level or dz.LOG_DEBUG)
        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, delta)
            dz.devices(alertDevice).updateAlertSensor(alertLevel(delta),alertText)
            return (delta == 0)
        end

        local function longGarbageName(str)                                        -- Use descriptive strings
            str = tostring(str)
            str = str:gsub("PMD","  Plastic verpakkingen, blik en drinkpakken ")
            str = str:gsub("GFT","  Groente-, fruit- en tuin afval ")
            str = str:gsub("Restafval" ,"  Restafval ")
            return str
        end
        
        local function retriggerAfterSec(seconds)
            dz.openURL({
                url =  dz.settings['Domoticz url'] .. "/json.htm?type=command&param=getversion",
                method = "GET",
                callback = "delay_Response" }).afterSec(seconds)
        end  
        
        local function osCommand(cmd)
            local fileHandle     = assert(io.popen(cmd, 'r'))
            local commandOutput  = assert(fileHandle:read('*a'))
            local returnTable    = {fileHandle:close()}
            return commandOutput,returnTable[3]            -- rc[3] contains returnCode
        end
       
        function makeTimeStamp(dateString)
            local pattern = "(%d+)%-(%d+)%-(%d+)T(%d+):(%d+):(%d+)"
            local xyear, xmonth, xday, xhour, xminute, xseconds = dateString:match(pattern)
            local convertedTimestamp  = os.time({year = xyear, month = xmonth, day = xday, hour = xhour, min = xminute, sec = xseconds})
            return convertedTimestamp 
        end
       
        local function procesJSON(resultJSON)
            keep    = {}
            rt      = dz.utils.fromJSON(resultJSON)
            
            local today = os.date("%Y-%m-%d")
            local garbageLines =  "" 
            local earliestDate   = "2999-12-31"       -- Hopefully we will have a different garbage collection system by then
            
            for i = 1,#rt do
                local fmtDate                 = os.date(" %A %d %B, %Y", makeTimeStamp(rt[i].Date))
                if  rt[i].Date >= today and rt[i].Date < earliestDate then
                    fmtDate             = os.date(" %A %d %B, %Y", makeTimeStamp(rt[i].Date))
                    keep.Date           = rt[i].Date
                    keep.fmtDate        = fmtDate
                    keep.GarbageType    = longGarbageName(rt[i].GarbageType)
                    earliestDate        = rt[i].Date
                end
                garbageLines = garbageLines .. fmtDate .. longGarbageName(rt[i].GarbageType) .. " " .. "\n"
            end

            if myTextDevice then       -- Update defined virtual text device with dates / types
                dz.devices(myTextDevice).updateText(garbageLines)
            end
            
            if myAlertDevice then   -- Update AlertDevice with nearby date / type
                local delta  = os.date("%d",tonumber(makeTimeStamp(keep.Date))) - os.date("%d") 
                garbageToday = setGarbageAlertDevice(  myAlertDevice, keep.GarbageType .. "\n" .. keep.fmtDate, delta )
            end  
            
            if dz.time.matchesRule("at 08:00-17:00") and garbageToday then
                dz.notify(keep.GarbageType .. "will be collected today")
            end
        end

        local function triggerCurlInBackGround()
            local curlCommand  = "curl -v --cookie" 
            local curlCookie  =  'RovaLc_inwoners={' ..
                                 '\\"Id\\":' ..             myGarbageID .. ',' .. 
                                 '\\"ZipCode\\":\\"' ..     myZipcode .. '\\",' .. 
                                 '\\"HouseNumber\\":\\"' .. myHousenumber .. '\\"}' 
            local curlHTTP    = "https://www.rova.nl/api/TrashCalendar/GetCalendarItems?portal=inwoners"
            local backGround  = " & "  -- We don't want the script to wait for the result so process curl in background

            getGarbageCollectionDatesCommand = curlCommand .. " " .. curlCookie  .. " " .. curlHTTP .. " > " .. outFile .. backGround 
            osCommand(getGarbageCollectionDatesCommand)
        end
        
        local function waitForAndProcessResult()
            local result, returnCode = osCommand(catCommand .. " " .. outFile) -- is the output there ?
            if returnCode == 0 then                                 -- Yes
                -- logWrite(result) 
                osCommand("rm " .. outFile)
                procesJSON(result)
            else                                                    -- Not yet. Come back in repeatDelay seconds 
                logWrite("No result yet")
                dz.data.delay = dz.data.delay + repeatDelay                    -- Keep track of the delays 
                if dz.data.delay > maxDelay then
                    logWrite("We are waiting > maxDelay seconds for the result. Giving up now",dz.LOG_ERROR)
                else
                    retriggerAfterSec(repeatDelay)
                end
            end 
        end
        
        -- main 
        if item.isDevice or item.isTimer then
            triggerCurlInBackGround()
            retriggerAfterSec(initialDelay) -- We will come back in initialDelay seconds to check if output has already arrived
            dz.data.delay = initialDelay 
        else
            waitForAndProcessResult()
        end
    end
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
delcara
Posts: 11
Joined: Wednesday 07 November 2018 10:48
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.10171
Location: Netherlands
Contact:

Re: dzVents get garbage collection dates (various)

Post by delcara »

Thnx! Just read your PM and you're answer is already here. I'm going to try the script when i'm home tonight. Nice thinking and a creative solution!
Raspberry pi 3, Domoticz Beta, Nginx, dzVents 2.7.4, RFXtrx433e, P1 smart meter, Harmony, Hue, Zwave, Amazon echo, Sonos, Synology DS413, HomeBridge, HA Bridge, Ubiquiti.
akamming
Posts: 338
Joined: Friday 17 August 2018 14:03
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: dzVents get garbage collection dates (various)

Post by akamming »

delcara wrote: Wednesday 07 November 2018 11:24 Hello Waaren,

I'm trying to create a script to get garbage collection dates from ROVA. I've discovered how to get the dates through a curl command. But I've no idea how to translate this to a dzVents script. I've just started with DzVents and have now translated all my blockly to DzVents (relatively simple scripts to control lights etc.). Can you help to translate this curl command to a DzVents script?

Code: Select all

curl -v --cookie "RovaLc_inwoners={\"Id\":160267,\"ZipCode\":\"8103JB\",\"HouseNumber\":\"15\",\"HouseAddition\":null,\"Municipality\":\"Raalte\",\"Province\":null,\"Firstname\":null,\"Lastname\":null,\"UserAgent\":\"\",\"School\":null,\"Street\":null,\"Country\":null,\"Portal\":null,\"AreaLevel\":5,\"City\":\"Raalte\",\"Ip\":null}" https://www.rova.nl/api/TrashCalendar/GetCalendarItems?portal=inwoners

Hi,

i was working on the same thing. a few weeks ago i created my own dzvents script for the ROVA afvalkalender. This one hopefully works for you!

Code: Select all

return {
	on = {
		timer = {
		    'at 20:00',                -- The notification will be sent at this time on the day before ROVA arrives
		    'every 8 hours' ,           -- Update frequency of the  virtual device  
	    }
    },
    logging = {
	        level = domoticz.LOG_DEBUG,  -- adjust to your needs
	        marker = "Rova"
    },
	execute = function(domoticz, item)
	    -- The name of your virtual text device which will contain the Afvalkalender
	    local DeviceName="Rova Afvalkalender" 
	    
	    -- Adress vars
	    local ZipCode="8103JB"  
	    local HouseNumber="15"
	    local HouseAddition="null"
	    local Municipality="Raalte"
	    
	    -- Notification params
	    local NotifyTitle="Rova"
	    local NotifyLine1="Zet container bij de weg, "
	    local NotifyLine2=" wordt opgehaald op "
	    
	    
		-- Get ROVA kalender by accessing the API using  curl 
	    local command = 'curl --cookie "RovaLc_inwoners={\\"Id\\":160266,\\"ZipCode\\":\\"'..ZipCode..'\\",\\"HouseNumber\\":\\"'..HouseNumber..'\\",\\"HouseAddition\\":'..HouseAddition..',\\"Municipality\\":\\"'..Municipality..'\\",\\"Province\\":null,\\"Firstname\\":null,\\"Lastname\\":null,\\"UserAgent\\":\\"\\",\\"School\\":null,\\"Street\\":null,\\"Country\\":null,\\"Portal\\":null,\\"AreaLevel\\":5,\\"City\\":\\"Zwolle\\",\\"Ip\\":null}" https://www.rova.nl/api/TrashCalendar/GetCalendarItems?portal=inwoners'
	    domoticz.log("Command is ["..command.."]",domoticz.LOG_DEBUG)
	    local handle=io.popen(command..' || echo error')
        local result = handle:read("*a")
        handle:close()

        -- For debugging purposes: Log result
        domoticz.log ("JSON output Rova is "..result, domoticz.LOG_DEBUG)
        
        if(result ~= 'error\n') then
            -- convert JSON object to readable format
    	    local json = domoticz.utils.fromJSON(result)

            -- convert dates
    	    local RovaDate=string.sub(json[1].Date,1,-10)
    	    local RovaDate2=string.sub(json[2].Date,1,-10)
    	    local RovaDate3=string.sub(json[3].Date,1,-10)

            -- log result
    	    domoticz.log("Next Garbage Collection: ["..json[1].GarbageTypeCode..' at '..RovaDate..']',domoticz.LOG_FORCE)
    	    
    	    -- update device
    	    domoticz.devices(DeviceName).updateText(json[1].GarbageTypeCode.." "..RovaDate..", "..json[2].GarbageTypeCode.." "..RovaDate2..", "..json[3].GarbageTypeCode.." "..RovaDate3)
    	    
    	    -- check if we have to send notification
    	    if (item.isTimer) then
    	        local twoletters = string.sub(item.trigger,1,2)
    	        domoticz.log("1st to trigger letters are ["..twoletters.."]",domoticz.LOG_DEBUG)
    	        domoticz.log("Item is timer ("..item.trigger..")",domoticz.LOG_DEBUG)
    	        
        	    if (twoletters=="at") then -- we are at the notification timestamp
        	        -- prepare time comparison
            	    local Time = require('Time')
                    local t = Time(RovaDate..' 00:00:00')
                    domoticz.log("Secondsago = "..t.secondsAgo..", minutesAgo="..t.minutesAgo..", hoursago="..t.hoursAgo..", daysago="..t.daysAgo,domoticz.LOG_DEBUG)
                    
                    -- check if we have to notify
                    if (t.daysAgo==0 and t.secondsAgo<0) then -- timestamp is within 1 day
                        -- Yes we do: notify
                        domoticz.log("Rova will be there within 1 day, sending notification", domoticz.LOG_DEBUG) 
                        domoticz.notify(NotifyTitle,NotifyLine1..json[1].GarbageTypeCode..NotifyLine2..RovaDate,domoticz.PRIORITY_NORMAL)
                    else
                        -- no we don't 
                        domoticz.log("no need to notify",domoticz.LOG_DEBUG)
                    end
                end
            end
	    else
	        domoticz.log("some kind of error accessing the Rova data API",domoticz.LOG_ERROR)
	    end
	end
}
Make sure you create a virtual text sensor with the name "Rova Afvalkalender" before you run the script!

I am still testing this script. It seems to work fine for me now, so i would be happy to hear your findings ...
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 »

akamming wrote: Thursday 08 November 2018 16:13 i was working on the same thing. a few weeks ago i created my own dzvents script for the ROVA afvalkalender. This one hopefully works for you!
@akamming, we took more or less the same approach. The main difference is that in your script the event thread (which is single threaded) must wait until the curl command has finished. Potentially this could stall the event system.
I worked around this risk by executing curl in the background and retrigger the script to check every couple of seconds if the result has arrived. Another approach could be to use the option --connect-timeout <seconds> or -m, --max-time <seconds> in the curl command.
In my opinion the best way would be to use domoticz.openURL but I have not found a way to use this with the required cookie table/JSON.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
akamming
Posts: 338
Joined: Friday 17 August 2018 14:03
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: dzVents get garbage collection dates (various)

Post by akamming »

waaren wrote: Thursday 08 November 2018 16:59 In my opinion the best way would be to use domoticz.openURL but I have not found a way to use this with the required cookie table/JSON.
Totally agree. This is why i tried to make a suggestion in the suggestion thread: viewtopic.php?f=31&t=25454&p=195745#p195745. So far no response.

Since this script is run only every 8 hours, i think it is a small risk. I have the same risk for another script where i run an os.execute statement. I like your workaround. maybe i'll implemented if this becomes a problem.


KR Arnold
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 »

akamming wrote: Friday 09 November 2018 9:16 Totally agree. This is why i tried to make a suggestion in the suggestion thread:
Maybe we need to look at the optional "headers =" in domoticz.openURL
So far I found that when you have the cookie generated by www.rova.nl already in chrome, the url
https://www.rova.nl/api/TrashCalendar/G ... %2215%22} , does return the requested JSON. So if there is a way to get this cookie on the domoticz system we might be a step further in the right direction
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
delcara
Posts: 11
Joined: Wednesday 07 November 2018 10:48
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.10171
Location: Netherlands
Contact:

Re: dzVents get garbage collection dates (various)

Post by delcara »

Already usesd the script from Waaren. So far it's working nice, adjusted the run times and notifications a little bit. I now receive a notification the evening before collection day and some nice notifications through google TTS on my Sonos speakers :D .

Strange thing is that i can't save the script when copy/paste in the domoticz web editor, checked it for weird characters or empty spaces. No problem with other scripts. And it runs fine when i copy it to the scripts folder. Didn't bother to look further for the cause of this issue. Running domoticz beta 4.10171.
Raspberry pi 3, Domoticz Beta, Nginx, dzVents 2.7.4, RFXtrx433e, P1 smart meter, Harmony, Hue, Zwave, Amazon echo, Sonos, Synology DS413, HomeBridge, HA Bridge, Ubiquiti.
delcara
Posts: 11
Joined: Wednesday 07 November 2018 10:48
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.10171
Location: Netherlands
Contact:

Re: dzVents get garbage collection dates (various)

Post by delcara »

Discovered why saving in the webeditor didn't work! I've got a reverse proxy (nginx) on the PI and it was a limitations in the HTTP GET request in my proxy config.
Raspberry pi 3, Domoticz Beta, Nginx, dzVents 2.7.4, RFXtrx433e, P1 smart meter, Harmony, Hue, Zwave, Amazon echo, Sonos, Synology DS413, HomeBridge, HA Bridge, Ubiquiti.
martijn333
Posts: 3
Joined: Tuesday 18 December 2018 22:18
Target OS: OS X
Domoticz version:
Contact:

Re: dzVents get garbage collection dates (various)

Post by martijn333 »

I tried the Circulus-Berkel script but what am i doing wrong.
The zipcode and housenumber are set correctly.
I activated debug to get more information.
Can someone help me?

2018-12-18 22:13:00.253 Status: dzVents: Debug: getGarbageDatesMarker: OpenURL: url = https://afvalkalender.circulus-berkel.n ... ender/2018
2018-12-18 22:13:00.253 Status: dzVents: Debug: getGarbageDatesMarker: OpenURL: method = GET
2018-12-18 22:13:00.253 Status: dzVents: Debug: getGarbageDatesMarker: OpenURL: post data = nil
2018-12-18 22:13:00.253 Status: dzVents: Debug: getGarbageDatesMarker: OpenURL: headers = nil
2018-12-18 22:13:00.253 Status: dzVents: Debug: getGarbageDatesMarker: OpenURL: callback = getGarbageDatesResponse
2018-12-18 22:13:00.254 Status: dzVents: Info: getGarbageDatesMarker: ------ Finished Script #1
2018-12-18 22:13:00.414 Status: EventSystem: Script event triggered: /home/pi/domoticz/dzVents/runtime/dzVents.lua
2018-12-18 22:13:02.603 Status: dzVents: Info: Handling httpResponse-events for: "getGarbageDatesResponse
2018-12-18 22:13:02.603 Status: dzVents: Info: getGarbageDatesMarker: ------ Start internal script: Script #1: HTTPResponse: "getGarbageDatesResponse"
2018-12-18 22:13:02.614 Status: dzVents: Debug: getGarbageDatesMarker: 0200200000011954
2018-12-18 22:13:02.618 Status: dzVents: Error (2.4.9): getGarbageDatesMarker: Problem with response from (no data) using data from earlier run
2018-12-18 22:13:02.618 Status: dzVents: Error (2.4.9): getGarbageDatesMarker: No previous data. are zipcode and housenumber ok and in circulus-berkel area?
2018-12-18 22:13:02.619 Status: dzVents: Info: getGarbageDatesMarker: ------ Finished Script #1
2018-12-18 22:13:02.619 Status: EventSystem: Script event triggered: /home/pi/domoticz/dzVents/runtime/dzVents.lua
2018-12-18 22:13:02.644 Status: Notification: Problem with response from (no data) using data from earlier run
2018-12-18 22:13:02.645 Status: Notification: No previous data. are zipcode and housenumber ok and in circulus-berkel area?
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 »

martijn333 wrote: Tuesday 18 December 2018 22:23 I tried the Circulus-Berkel script but what am i doing wrong.
Can someone help me?
For some reason the script does not like the data that came back from circulus-berkel
Can you try to enter https://afvalkalender.circulus-berkel.n ... ender/2018 in your browser and show the results. If that look more or less OK please add the line

Code: Select all

dz.log(triggerObject.data,dz.LOG_FORCE)
right after the line

Code: Select all

rtRaw = dz.utils.fromJSON(triggerObject.data)         -- dzVents does nor recognize the response as pure JSON so conversion is required
      
.
and show the relevant loglines
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
martijn333
Posts: 3
Joined: Tuesday 18 December 2018 22:18
Target OS: OS X
Domoticz version:
Contact:

Re: dzVents get garbage collection dates (various)

Post by martijn333 »

I added the line this are the results:

Code: Select all

2018-12-19 11:58:00.423 Status: dzVents: Info: getGarbageDatesMarker: ------ Start internal script: Script #1:, trigger: at 11:58
2018-12-19 11:58:00.455 Status: dzVents: Debug: getGarbageDatesMarker: OpenURL: url = https://afvalkalender.circulus-berkel.nl/rest/adressen/0200200000011954/kalender/2018
2018-12-19 11:58:00.455 Status: dzVents: Debug: getGarbageDatesMarker: OpenURL: method = GET
2018-12-19 11:58:00.455 Status: dzVents: Debug: getGarbageDatesMarker: OpenURL: post data = nil
2018-12-19 11:58:00.455 Status: dzVents: Debug: getGarbageDatesMarker: OpenURL: headers = nil
2018-12-19 11:58:00.455 Status: dzVents: Debug: getGarbageDatesMarker: OpenURL: callback = getGarbageDatesResponse
2018-12-19 11:58:00.456 Status: dzVents: Info: getGarbageDatesMarker: ------ Finished Script #1
2018-12-19 11:58:00.598 Status: EventSystem: Script event triggered: /home/pi/domoticz/dzVents/runtime/dzVents.lua
2018-12-19 11:58:02.869 Status: dzVents: Info: Handling httpResponse-events for: "getGarbageDatesResponse
2018-12-19 11:58:02.869 Status: dzVents: Info: getGarbageDatesMarker: ------ Start internal script: Script #1: HTTPResponse: "getGarbageDatesResponse"
2018-12-19 11:58:02.879 Status: dzVents: Debug: getGarbageDatesMarker: 0200200000011954
2018-12-19 11:58:02.883 Status: dzVents: !Info: getGarbageDatesMarker: [{"afvalstroom_id":4,"ophaaldatum":"2018-01-04"},{"afvalstroom_id":55,"ophaaldatum":"2018-01-06"},{"afvalstroom_id":55,"ophaaldatum":"2018-01-15"},{"afvalstroom_id":55,"ophaaldatum":"2018-01-29"},{"afvalstroom_id":4,"ophaaldatum":"2018-02-01"},{"afvalstroom_id":55,"ophaaldatum":"2018-02-12"},{"afvalstroom_id":55,"ophaaldatum":"2018-02-26"},{"afvalstroom_id":4,"ophaaldatum":"2018-03-01"},{"afvalstroom_id":55,"ophaaldatum":"2018-03-12"},{"afvalstroom_id":55,"ophaaldatum":"2018-03-26"},{"afvalstroom_id":12,"ophaaldatum":"2018-04-04"},{"afvalstroom_id":4,"ophaaldatum":"2018-04-05"},{"afvalstroom_id":55,"ophaaldatum":"2018-04-09"},{"afvalstroom_id":55,"ophaaldatum":"2018-04-23"},{"afvalstroom_id":4,"ophaaldatum":"2018-05-03"},{"afvalstroom_id":55,"ophaaldatum":"2018-05-07"},{"afvalstroom_id":55,"ophaaldatum":"2018-05-19"},{"afvalstroom_id":55,"ophaaldatum":"2018-06-04"},{"afvalstroom_id":4,"ophaaldatum":"2018-06-07"},{"afvalstroom_id":55,"ophaaldatum":"2018-06-18"},{"afvalstroom_id":55,"ophaaldatum":"2018-07-02"},{"afvalstroom_id":4,"ophaaldatum":"2018-07-05"},{"afvalstroom_id":55,"ophaaldatum":"2018-07-16"},{"afvalstroom_id":55,"ophaaldatum":"2018-07-30"},{"afvalstroom_id":12,"ophaaldatum":"2018-08-01"},{"afvalstroom_id":4,"ophaaldatum":"2018-08-02"},{"afvalstroom_id":55,"ophaaldatum":"2018-08-13"},{"afvalstroom_id":55,"ophaaldatum":"2018-08-27"},{"afvalstroom_id":4,"ophaaldatum":"2018-09-06"},{"afvalstroom_id":55,"ophaaldatum":"2018-09-10"},{"afvalstroom_id":55,"ophaaldatum":"2018-09-24"},{"afvalstroom_id":4,"ophaaldatum":"2018-10-04"},{"afvalstroom_id":55,"ophaaldatum":"2018-10-08"},{"afvalstroom_id":55,"ophaaldatum":"2018-10-22"},{"afvalstroom_id":4,"ophaaldatum":"2018-11-01"},{"afvalstroom_id":55,"ophaaldatum":"2018-11-05"},{"afvalstroom_id":55,"ophaaldatum":"2018-11-19"},{"afvalstroom_id":55,"ophaaldatum":"2018-12-03"},{"afvalstroom_id":12,"ophaaldatum":"2018-12-05"},{"afvalstroom_id":4,"ophaaldatum":"2018-12-06"},{"afvalstroom_id":11,"ophaaldatum":"2018-12-11"},{"afvalstroom_id":55,"ophaaldatum":"2018-12-17"},{"afvalstroom_id":11,"ophaaldatum":"2018-12-22"},{"afvalstroom_id":55,"ophaaldatum":"2018-12-31"}]
2018-12-19 11:58:02.883 Status: dzVents: Error (2.4.9): getGarbageDatesMarker: Problem with response from (no data) using data from earlier run
2018-12-19 11:58:02.884 Status: dzVents: Error (2.4.9): getGarbageDatesMarker: No previous data. are zipcode and housenumber ok and in circulus-berkel area?
2018-12-19 11:58:02.884 Status: dzVents: Info: getGarbageDatesMarker: ------ Finished Script #1
2018-12-19 11:58:02.884 Status: EventSystem: Script event triggered: /home/pi/domoticz/dzVents/runtime/dzVents.lua
2018-12-19 11:58:02.924 Status: Notification: Problem with response from (no data) using data from earlier run
2018-12-19 11:58:02.925 Status: Notification: No previous data. are zipcode and housenumber ok and in circulus-berkel area?
Thank you for helping!
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 »

martijn333 wrote: Wednesday 19 December 2018 12:04 Thank you for helping!
Response from your provider again differs a bit from others.

script below should do it for you.

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  = {1,4,11,12,55}                -- Valid for circulus-berkelfor but these numbers vary per garbageCollector; Why ??
         -- ("55","  Groente-, fruit- en tuin afval            ")
         -- ("4", "  Papier en kartonnen verpakkingen          ")
         -- ("11","  Plastic, blik drankpakken                 ")
         -- ("12","  Boeken, speelgoed en textiel              ") 
         -- ("1", "  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)
            dz.log(str,dz.LOG_DEBUG)
            str = str:gsub("12","  Boeken, Elektrische apparaten, Speelgoed en Textiel")
            str = str:gsub("55","  Groente-, fruit- en tuin afval     ")
            str = str:gsub("4", "  Papier en kartonnen verpakkingen    ")
            str = str:gsub("11","  Plastic, blik drankpakken          ")
            str = str:gsub("1", "  Rest afval                          ")
            
            dz.log(str,dz.LOG_DEBUG)
            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 dumpTable(t, level)
            for attr, value in pairs(t) do
                if (type(value) ~= 'function') then
                    if (type(value) == 'table') then
                        io.write(level .. attr .. ':\n')
                        print(level .. attr )
                        dumpTable(value, level .. '    ')
                    else
                        io.write(level .. attr .. ': ' .. tostring(value) .. "\n")
                        print(level .. attr .. ': ' .. tostring(value) )
                    end
                else
                    io.write(level .. attr .. '()\n')
                    print(level .. attr .. '()')
                end
            end
        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")
            local foundFirst = false
            
            for i = 1,#garbageTypes do --walk the the type Table
                 dz.log("Checking " .. garbageTypes[i],dz.LOG_DEBUG)
                typeEarliestDate      = "2999-12-31"
                local foundOne = false
                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
                        foundOne = true
                        typeEarliestDate =  rt[j].ophaaldatum
                        typeEarliestKind =  rt[j].afvalstroom_id
                        if  typeEarliestDate < overallEarliestDate then  -- date closest to today overall ?
                            foundFirst = true
                            overallEarliestDate = typeEarliestDate      -- keep date
                            overallEarliestType =  garbageTypes[i]            -- keep type
                        end
                    end
                    
                end
                if foundOne then 
                    garbageLines = garbageLines .. string2Date(typeEarliestDate,"%a %e %b" ) .. longGarbageName(typeEarliestKind) .. " " .. "\n"
                end    
            end

            if myAlertDevice and foundFirst 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
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
martijn333
Posts: 3
Joined: Tuesday 18 December 2018 22:18
Target OS: OS X
Domoticz version:
Contact:

Re: dzVents get garbage collection dates (various)

Post by martijn333 »

Thanks it is working!
imdos
Posts: 34
Joined: Thursday 03 August 2017 21:50
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Contact:

Re: dzVents get garbage collection dates (various)

Post by imdos »

Great work. I got the script working on rmn. However I don't understand the logics for the notification of the alert. Could someone help me with that. I would like to receive a modification on the day itself in the morning, around 8 or something.

Sent from my MI 6 using Tapatalk

Making use of: Raspbian(SSD), dz Beta, Woonveilig, Z-Wave(alarm+multi-sensor), RFLink(blinds), P1, Yeelight, Xiaomi temp sensors, Tasmota(SonoFF, Blitzwolf SHP2, Shelly1)
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 »

imdos wrote: Monday 04 February 2019 22:37 Great work. I got the script working on rmn. However I don't understand the logics for the notification of the alert. Could someone help me with that. I would like to receive a modification on the day itself in the morning, around 8 or something.

Sent from my MI 6 using Tapatalk
If you can send me the script via PM as you use it now 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
Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests