I haven’t though about that option. Thank you very much for the hint, I’ll give it a try
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
You have to go through all steps, if you skip just one the iCal at the end will be empty.
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.
—
–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