Garbage Collection

I haven’t though about that option. Thank you very much for the hint, I’ll give it a try :slight_smile:

Hello, maybe somebody can help me here.

I’m trying to get the garbage calendar from the BSR (in Berlin). The URL is: abfuhrkalender

There you type in you location and get a link to a php script generating an iCal for you.
The URL looks something like this (not my address, by the way):

https://www.bsr.de/abfuhrkalender_ajax.php?script=dynamic_iCal_ajax&abf_strasse=Bahnhofstr.,%2012555%20Berlin%20(Treptow-K%C3%B6penick)&abf_hausnr=47&tab_control=Liste&abf_config_weihnachtsbaeume=&abf_config_restmuell=on&abf_config_biogut=on&abf_config_wertstoffe=on&abf_config_laubtonne=on&abf_selectmonth=11%202024&listitems=14

With firefox or other browsers this works fine. But if I try the same with wget/curl I always get “internal server error” (500). I tried different format, with quotation marks in different places, with %28%29 instead of ().

Nothing works.

Does anyone have an idea how to solve this?

Looks like someone thought it to be a brilliant idea to use a regular expression CODE_MARKUP_PATTERN hard-coded to <pre(?: data-code-wrap=\"[a-z]+\")?><code class=\"lang-(?<lang>[a-z]+)\">(?<content>.*?)</code></pre>" to find the code in this forum post rendered as HTML (a context free language!) by discourse, which probably got updated somewhen in the last 3 years and changed its rendering and now inserts some extra class attributes and extra buttons:

<pre data-code-wrap="yaml" class="codeblock-buttons">
  <div class="codeblock-button-wrapper" style="right: 0px;">
    <button class="btn nohighlight copy-cmd" aria-label="copy code to clipboard"><svg class="fa d-icon d-icon-copy svg-icon svg-string" xmlns="http://www.w3.org/2000/svg"><use href="#copy"></use></svg></button>
    <button class="btn nohighlight fullscreen-cmd" aria-label="show code in full screen"><svg class="fa d-icon d-icon-discourse-expand svg-icon svg-string" xmlns="http://www.w3.org/2000/svg"><use href="#discourse-expand"></use></svg></button>
  </div>
  <code class="lang-yaml hljs language-yaml" data-highlighted="yes">
…
  </code>
</pre>

So the regexp will find nothing and properties["YAML_CONTENT_PROPERTY"] remains NULL and CommunityUIWidgetAddonHandler.install throws the error:

2024-11-10 17:00:43.015 [ERROR] [munity.CommunityUIWidgetAddonHandler] - Widget from marketplace is invalid: Couldn’t find the widget in the add-on entry. The starting code fence may not be marked as ```yaml

You might be better of to put the code into some external URL ending on .yaml and put the link after your first post; see http :// github.com /openhab/openhab-core/blob/main/bundles/org.openhab.core.addon.marketplace/src/main/java/org/openhab/core/addon/marketplace/internal/community/CommunityMarketplaceAddonService.java#L420

Hey David,

the selection of BSR is a bit more complex, because you need a active session and the right cockies: hacs_waste_collection_schedule/custom_components/waste_collection_schedule/waste_collection_schedule/source/bsr_de.py at master · mampfes/hacs_waste_collection_schedule · GitHub I try to integrate it into müll.io for easy API access today, but no success today. Perhaps I will try it at the end of the week again.

Regards,
Tim

@timl That would be wonderful, Thank you.

@timl Did you make it work?

Edit:
I got it to work manually:

#1
curl -c cookie.txt https://www.bsr.de/abfuhrkalender-20520.php

#2
curl -b cookie.txt "https://www.bsr.de/abfuhrkalender_ajax.php?script=dynamic_search&step=1&q=Streetname.,"
=> 
[
{"value": "FullStreetName1",
 "streetkey": "0123456789"
},
{"value": "FullStreetName2",
 "streetkey": "0123456789"}...
]

#3
curl -b cookie.txt "https://www.bsr.de/abfuhrkalender_ajax.php?script=dynamic_search&step=2&q=FullStreeName"
=>
{
"123456789012345678910": {
"HouseNo": "1",
"Street": "Streetname.",
"FullStreet": "FullStreeNameWithNumber"
},
"123456789012345678920": {
"HouseNo": "2",
"Street": "Streetname.",
"FullStreet": "FullStreeNameWithNumber"
},
...
}

#4
curl -b cookie.txt "https://www.bsr.de/abfuhrkalender_ajax.php?script=dynamic_kalender_ajax&abf_strasse=Streetname.&abf_hausnr=Number&tab_control=Monat&abf_config_restmuell=on&abf_selectmonth=1%202025"
(note: if you skip this the next step will produce an empty iCal and any abf_config_ works EXCEPT weihnachtsbaeume)
=>
some html snippet <li> <div> ...

#5
curl -b cookie.txt "https://www.bsr.de/abfuhrkalender_ajax.php?script=dynamic_iCal_ajax&abf_strasse=FullStreetNameX&abf_hausnr=Number&tab_control=Monat&abf_config_restmuell=on&abf_config_biogut=on&abf_config_wertstoffe=on&abf_config_laubtonne=on&abf_selectmonth=01%202025"
(notes: 
- abf_config_weihnachtsbaeume doesn't do anything
- with tab_control=Monat and abf_selectmonth=01%202025" you get ALL events for that month [this is good, so you only need to pull once per month lets say two week before])
=>
the desired iCal

:grin:

You have to go through all steps, if you skip just one the iCal at the end will be empty. :face_with_raised_eyebrow:

Okay, I did it. Without using third party services.
The documentation for OH is very very very poor. So I will post here how I did it. And I have a question too.
0 Precondition:
You have to change the paths to you needs.
I run OH in docker, where curl is installed.
I use the iCalendar binding to get the dates into OH.

1 script:
/openhab/scripts/bsr.sh (since I want the BSR garbage collection [Berlin]):

#!/bin/bash

curl -c /tmp/bsr.txt https://www.bsr.de/abfuhrkalender-20520.php
curl -b /tmp/bsr.txt "https://www.bsr.de/abfuhrkalender_ajax.php?script=dynamic_search&step=1&q=<streetname>,"
curl -b /tmp/bsr.txt "https://www.bsr.de/abfuhrkalender_ajax.php?script=dynamic_search&step=2&q=<full streetname>"
curl -b /tmp/bsr.txt "https://www.bsr.de/abfuhrkalender_ajax.php?script=dynamic_kalender_ajax&abf_strasse=<streetname>&abf_hausnr=<#>&tab_control=Liste&abf_config_restmuell=on&abf_config_biogut=on&abf_config_wertstoffe=on"
curl -b /tmp/bsr.txt "https://www.bsr.de/abfuhrkalender_ajax.php?script=dynamic_iCal_ajax&abf_strasse=<full streetname>&abf_hausnr=<#>&tab_control=Liste&abf_config_restmuell=on&abf_config_biogut=on&abf_config_wertstoffe=on" > /openhab/conf/html/bsr.ics

To find the needed values go to “Abfuhrkalender | BSR” enter your street and number search and go to “Termine herunterladen” the link behind “Termindatei herunterladen” gibes you all you need.
some Explanations:

  • “” is your streetname up to and including “,”
  • “<#>” is your house number
  • “< full streetname>” is your full streetname in the abf_strasse parameter from the link above.
  • the streetnames need “HTML URL Encoding Reference” (like space > %20), BUT within sh-scripts the % needs a % as escape character. so %20 becomes %%20 and ä become %%C3%%A4.
  • files in /openhab/conf/html/ can be accessed via http://localhost:8080/static/

If you can get the collection date in an ics format the rest will be the same from here on.

2 things file:
/openhab/things/bsr.things:

Bridge icalendar:calendar:garb   "Müll"    @ "Internet" [ url="http://localhost:8080/static/bsr.ics", refreshTime=60 ]
Thing  icalendar:eventfilter:wert  "Wertstoffe" (icalendar:calendar:garb) [ maxEvents=2, textEventField="SUMMARY", textEventValue="Abholung Wertstoffe (Abholung durch ALBA)" ]
Thing  icalendar:eventfilter:rest  "Restmüll"   (icalendar:calendar:garb) [ maxEvents=2, textEventField="SUMMARY", textEventValue="Abholung Hausmüll" ]
Thing  icalendar:eventfilter:bio   "Biomüll"    (icalendar:calendar:garb) [ maxEvents=2, textEventField="SUMMARY", textEventValue="Abholung Biogut" ]

some Explanations:
I only want the next two dates so maxEvents is 2.
Question: What/How do I insert metadata here to add the icon colour?

3 items file:
/openhab/items/bsr.items:

String   Garb_Bio_1_event_name        "nächster Termin [%s]"                    <calendar> { channel="icalendar:eventfilter:bio:result_0#title" }
DateTime Garb_Bio_1_event_at          "nächster Termin [%1$td.%1$tm.%1$tY]"     <calendar> { channel="icalendar:eventfilter:bio:result_0#begin" }
String   Garb_Bio_2_event_name        "übernächster Termin [%s]"                <calendar> { channel="icalendar:eventfilter:bio:result_1#title" }
DateTime Garb_Bio_2_event_at          "übernächster Termin [%1$td.%1$tm.%1$tY]" <calendar> { channel="icalendar:eventfilter:bio:result_1#begin" }

String   Garb_Rest_1_event_name       "nächster Termin [%s]"                    <calendar> { channel="icalendar:eventfilter:rest:result_0#title" }
DateTime Garb_Rest_1_event_at         "nächster Termin [%1$td.%1$tm.%1$tY]"     <calendar> { channel="icalendar:eventfilter:rest:result_0#begin" }
String   Garb_Rest_2_event_name       "übernächster Termin [%s]"                <calendar> { channel="icalendar:eventfilter:rest:result_1#title" }
DateTime Garb_Rest_2_event_at         "übernächster Termin [%1$td.%1$tm.%1$tY]" <calendar> { channel="icalendar:eventfilter:rest:result_1#begin" }

String   Garb_Wert_1_event_name       "nächster Termin [%s]"                    <calendar> { channel="icalendar:eventfilter:wert:result_0#title" }
DateTime Garb_Wert_1_event_at         "nächster Termin [%1$td.%1$tm.%1$tY]"     <calendar> { channel="icalendar:eventfilter:wert:result_0#begin" }
String   Garb_Wert_2_event_name       "übernächster Termin [%s]"                <calendar> { channel="icalendar:eventfilter:wert:result_1#title" }
DateTime Garb_Wert_2_event_at         "übernächster Termin [%1$td.%1$tm.%1$tY]" <calendar> { channel="icalendar:eventfilter:wert:result_1#begin" }

some Explanations:
Add the needed items and link them to the things.
Question: Or do I insert metadata here?

4 the widget:

uid: garbage_list_v1
tags: []
props:
  parameters:
    - description: Title of the card
      label: Title
      name: title
      required: false
      type: TEXT
    - description: Your local translation for <tomorrow>
      label: Tomorrow translation
      name: tomorrow
      required: true
      type: TEXT
    - description: Your local translation for <today>
      label: Today translation
      name: today
      required: true
      type: TEXT
    - description: Date items
      label: Date items
      name: datearray
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Nov 29, 2024, 4:24:36 PM
component: f7-card
config:
  title: =props.title
slots:
  default:
    - component: f7-card-content
      slots:
        default:
          - component: f7-list
            config:
              mediaList: true
            slots:
              default:
                - component: oh-repeater
                  config:
                    for: listitem
                    in: =props.datearray.split("|")
                    fragment: true
                  slots:
                    default:
                      - component: oh-list-item
                        config:
                          title: =items[loop.listitem.split("\"")[1]].state
                          icon: =loop.listitem.split("\"")[5]
                          iconColor: =loop.listitem.split("\"")[3]
                          badge: '=((dayjs(items[loop.listitem.split("\"")[7]].state).diff(dayjs().startOf("day"),
                            "days")) == 0 ? (props.today) :
                            (dayjs(items[loop.listitem.split("\"")[7]].state).diff(dayjs().startOf("day"),
                            "days")) == 1 ? (props.tomorrow) : false)'
                          badgeColor: '=((dayjs(items[loop.listitem.split("\"")[7]].state).diff(dayjs().startOf("day"),
                            "days")) == 0 ? "red" : "yellow")'
                          footer: =items[loop.listitem.split("\"")[7]].displayState
                          visible: '=items[loop.listitem.split("\"")[7]].state == "UNDEF" ? false : true'

some Explanations:
The datearray links the items: “Garb_Bio_1_event_name”,“green”,“f7:trash”,“Garb_Bio_1_event_at”|“Garb_Rest_1_event_name”,“red”,“f7:trash”,“Garb_Rest_1_event_at”|“Garb_Wert_1_event_name”,“gray”,“f7:trash”,“Garb_Wert_1_event_at”|“Garb_Bio_2_event_name”,“green”,“f7:trash”,“Garb_Bio_2_event_at”|“Garb_Rest_2_event_name”,“red”,“f7:trash”,“Garb_Rest_2_event_at”|“Garb_Wert_2_event_name”,“gray”,“f7:trash”,“Garb_Wert_2_event_at”
Question: Here the colours are hard coded. How to I add the metadata here?

5 updating automatically once per day:
/openhab/rules/bsr.rules:

rule "Update bsr calendar once per day"
when
  Time cron "0 1 * * * *"
then
  executeCommandLine('../conf/scripts/bsr.sh')
end

some Explanations:
The Time cron means every day at 1 o clock. Look here for more info: https://crontab-generator.org/

That’s it. :wink:


–EDIT–

Can anybody help me with berlin-recycling.de ?
Like for bsr I looked at hacs_waste_collection_schedule but I can’t make it work.

Thanks a lot

Hey David, I added Berlin as Provder and add BSR & Abfall.io. If you (someone else) need it, feel free to send me feedback, if there are open issues/problems.

Hello and thanks to Thomas Lauterbach for programming the Widget!

For this i have a question - how can I bind the iCalendar to the widget?
Widget is displayed, but don´t show any Dates.
I thinK I don´t find my mistake for myself…

Thanks and regards,
André

I think you have to install the iCalender-Binding to address your Carbage-Calender.

Yes you need a source for your pickup dates and then use datetime items to store the next pickup dates. I showed an example how to set up the iCalendar binding here: Garbage Collection - #36 by DrRSatzteil