Garbage Collection

Bildschirmfoto von 2021-01-20 21-47-20

This widget will show you the upcoming garbage collection dates. Badges are shown the day before a garbage collection (in yellow) and on the day of garbage collection (in red). Note that I changed the code a bit to fake the badges in the screenshot for demonstration purposes. I read all the collection date values from my nextcloud calendar with the iCalendar binding. The text in the widget is in German but I think you get the idea. The badges ‘Heute’ and ‘Morgen’ mean ‘Today’ and ‘Tomorrow’.

Configuaration parameters:

  1. Title: Will be displayed as card title, leave emtpy for none.
  2. Footer: Will be displayed as card footer, leave emtpy for none. I use the following footer value to display the date of the next collection (might require some simple translation on your end):
="Nächste Abholung: " + ((dayjs(items.garbage_collection.state).diff(dayjs().startOf("day"), "days")) == 0 ? "Heute" : (dayjs(items.garbage_collection.state).diff(dayjs().startOf("day"), "days")) == 1 ? "Morgen" : "In " + (dayjs(items.garbage_collection.state).diff(dayjs().startOf("day"), "days")) + " Tagen")
  1. & 4. Put your localized strings for “Today” (3.) and “Tomorrow” (4.) here.
  2. Date Array: Requires a string of the format as shown in the following example:
"Restmüll","black","f7:trash","garbage_collection_restmuell"|"Bioabfall","teal","f7:trash","garbage_collection_bioabfall"|"Gelbe Tonne","yellow","f7:trash","garbage_collection_gelb"|"Blaue Tonne","blue","f7:trash","garbage_collection_blue"|"Sperrmüll","gray","f7:trash","garbage_collection_bulk"|"Weihnachtsbäume","green","f7:trash","garbage_collection_christmas"

The logic behind this is:

"<Type of garbage collection>","<color>","<icon>","<name of DateTime item providing the next collection date>"

Multiple types of garbage collections are divided by a pipe symbol: |

DateTime items with an undefined state will not be shown in the widget.

Screenshots

None so far

Changelog

Version 0.2

  • fixed: complete overhaul to make the widget more easy to use and reduce amount of code significantly

Version 0.1

  • initial release

Resources

uid: garbage_list_v1
tags: []
props:
  parameters:
    - description: Title of the card
      label: Title
      name: title
      required: false
      type: TEXT
    - description: The card footer
      label: Footer
      name: footer
      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: Feb 3, 2021, 7:17:40 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: =loop.listitem.split("\"")[1]
                          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'
    - component: f7-card-footer
      slots:
        default:
          - component: Label
            config:
              text: =props.footer
14 Likes

That’s really cool and exactly what I’m looking for (in the near future). I’m still in the process to migrate/rebuild/streamline all my OH2.5 stuff. I’m not yet in the layout stuff. But seems your sample will be my first learning and implementation.

I’m happy to provide feedback once I started.

Cheers
thefechner

Awesome! I will give it a try when my migration to OH3 is completed.
Thanks for sharing :grinning:

Thanks for sharing your thoughts on this. I just added the missing visibility configuration (when the next collection date is unknown the corresponding item will not be shown in the widget):

uid: garbage_cell_v4
tags: []
props:
  parameterGroups: []
timestamp: Jan 21, 2021, 11:21:27 AM
component: f7-card
config:
  title: ="Abfuhrtermine:"
slots:
  default:
    - component: f7-card-content
      slots:
        default:
          - component: f7-list
            config:
              mediaList: true
            slots:
              default:
                - component: oh-list-item
                  config:
                    title: Restmüll
                    icon: f7:trash
                    iconColor: black
                    badge: '=((items.garbage_collection_restmuell.displayState == items.local_dateweekday.displayState) ? "Heute" : (items.garbage_collection_restmuell.displayState == items.local_dateweekday_tomorrow.displayState) ? "Morgen" : false)'
                    badgeColor: '=((items.garbage_collection_restmuell.displayState == items.local_dateweekday.displayState) ? "red" : "yellow")'
                    footer: =items.garbage_collection_restmuell.displayState
                    visible: '=items.garbage_collection_restmuell.state == "UNDEF" ? false : true'
                - component: oh-list-item
                  config:
                    title: Bioabfall
                    icon: f7:trash
                    iconColor: teal
                    badge: '=((items.garbage_collection_bioabfall.displayState == items.local_dateweekday.displayState) ? "Heute" : (items.garbage_collection_bioabfall.displayState == items.local_dateweekday_tomorrow.displayState) ? "Morgen" : false)'
                    badgeColor: '=((items.garbage_collection_bioabfall.displayState == items.local_dateweekday.displayState) ? "red" : "yellow")'
                    footer: =items.garbage_collection_bioabfall.displayState
                    visible: '=items.garbage_collection_bioabfall.state == "UNDEF" ? false : true'
                - component: oh-list-item
                  config:
                    title: Gelbe Tonne
                    icon: f7:trash
                    iconColor: yellow
                    badge: '=((items.garbage_collection_gelb.displayState == items.local_dateweekday.displayState) ? "Heute" : (items.garbage_collection_gelb.displayState == items.local_dateweekday_tomorrow.displayState) ? "Morgen" : false)'
                    badgeColor: '=((items.garbage_collection_gelb.displayState == items.local_dateweekday.displayState) ? "red" : "yellow")'
                    footer: =items.garbage_collection_gelb.displayState
                    visible: '=items.garbage_collection_gelb.state == "UNDEF" ? false : true'
                - component: oh-list-item
                  config:
                    title: Blaue Tonne
                    icon: f7:trash
                    iconColor: blue
                    badge: '=((items.garbage_collection_blue.displayState == items.local_dateweekday.displayState) ? "Heute" : (items.garbage_collection_blue.displayState == items.local_dateweekday_tomorrow.displayState) ? "Morgen" : false)'
                    badgeColor: '=((items.garbage_collection_blue.displayState == items.local_dateweekday.displayState) ? "red" : "yellow")'
                    footer: =items.garbage_collection_blue.displayState
                    visible: '=items.garbage_collection_blue.state == "UNDEF" ? false : true'
                - component: oh-list-item
                  config:
                    title: Sperrmüll
                    icon: f7:trash
                    iconColor: gray
                    badge: '=((items.garbage_collection_bulk.displayState == items.local_dateweekday.displayState) ? "Heute" : (items.garbage_collection_bulk.displayState == items.local_dateweekday_tomorrow.displayState) ? "Morgen" : false)'
                    badgeColor: '=((items.garbage_collection_bulk.displayState == items.local_dateweekday.displayState) ? "red" : "yellow")'
                    footer: =items.garbage_collection_bulk.displayState
                    visible: '=items.garbage_collection_bulk.state == "UNDEF" ? false : true'
                - component: oh-list-item
                  config:
                    title: Weihnachtsbäume
                    icon: f7:trash
                    iconColor: green
                    badge: '=((items.garbage_collection_christmas.displayState == items.local_dateweekday.displayState) ? "Heute" : (items.garbage_collection_christmas.displayState == items.local_dateweekday_tomorrow.displayState) ? "Morgen" : false)'
                    badgeColor: '=((items.garbage_collection_christmas.displayState == items.local_dateweekday.displayState) ? "red" : "yellow")'
                    footer: =items.garbage_collection_christmas.displayState
                    visible: '=items.garbage_collection_christmas.state == "UNDEF" ? false : true'
    - component: f7-card-footer
      slots:
        default:
          - component: Label
            config:
              text: '="Nächste Abholung: " + items.garbage_collection.displayState'

Since I really did not like the repetitions in the code and the inflexible usage of the code I improved it a bit today. It will still look the same but is now fully configurable so that it may be even used for any other type of events:

uid: garbage_list_v1
tags: []
props:
  parameters:
    - description: Title of the card
      label: Title
      name: title
      required: false
      type: TEXT
    - description: The card footer
      label: Footer
      name: footer
      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: Jan 26, 2021, 9:02:52 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: =loop.listitem.split("\"")[1]
                          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'
    - component: f7-card-footer
      slots:
        default:
          - component: Label
            config:
              text: =props.footer

The only configuration option that requires a bit of explanation I guess is the “Date Items” property. I use the same format like the universal toggle widget (Universal Toggle Widget - #2 by DrRSatzteil) but with more parameters:
It requires a String in the following format:

"<Label 1>","<Color 1>","<Icon 1>","<Item Name 1>"|"<Label 2>","<Color 2>","<Icon 2>","<Item Name 2>"... and so on for more items

See here for available colors: Color Themes | Framework7 Documentation
See here for available icons: Framework7 Icons

1 Like

Thank you for this. It’s nice and helpful.
The next improvement could be sorting the list ascending from the nearest date :wink:

I already thought about that but I have no clue whether it could be done… It would be definitely nice but I don’t intend to go any deeper to investigate if it would be possible right now.

I use the following footer that tells me at least in how many days the next collection will take place. It’s not as good as a sorted list but good enough for me right now:

="Next collection: " + ((dayjs(items.garbage_collection.state).diff(dayjs().startOf("day"), "days")) == 0 ? "Today" : (dayjs(items.garbage_collection.state).diff(dayjs().startOf("day"), "days")) == 1 ? "Tomorrow" : "In " + (dayjs(items.garbage_collection.state).diff(dayjs().startOf("day"), "days")) + " days") 
1 Like

You could actually use an item representing the config string and calculate the string in a rule. Then use the value of this item in the widget config :grinning:

I would like to use your example. But am struggling with the setup. I am not very experienced but with a little nudge here and there I made it to setting most things up.

Could you explain what is needed to successfully see the content in the widget? Or in another words: Some granularity for “BTW: I read all the collection date values from my nextcloud calendar with the iCalendar binding.” would help.

I have a calendar bridge and the eventfilter thing. Text and schedule set up. Not created items from the channels yet. Now do I have to name the items in a special way? How does the widget know which calendar thing to display?

Hi Tim,

If you have the eventfilters already setup you’re almost there. You can create the date items with whatever name you like and connect them to the eventfilter channels. When you have all your items setup you can configure the widget via the Date Items property (make sure you are using the latest version of the widget I posted in this thread and not the one from my initial post):

The syntax is:

"<Label 1>","<Color 1>","<Icon 1>","<Item1>"|"<Label 2>","<Color 2>","<Icon 2>","<Item 2>"...

A concrete example would be:

"Waste","blue","f7:trash","name_of_my_waste_item"

Please let me know if that works for you!

understood, thanks. But I have to step back once again because it is also the first time I deal with the ical-binding: If I want to filter green, blue, grey and yellow collection date - do I create four eventfilter-things and the item to it?

In short: yes, exactly!

You could also retrieve all of them with one eventfilter but then it would be up to you to check what type of event you get on each channel. So I would recommend to do it exactly as you suggested.

Ok. Start with one EventFilter. Got three items: Biotonne_Start, Biotonne_Ende and Biotonne_Titel. all filled.
DateItem-String: “Waste”,“green”,“f7:trash”,“Biotonne_Titel”
The widget shows the green icon and “Biotonne”, but no dates?

Use the Biotonne_Start item. You don’t need the Titel. That should do the trick!

unfortunately it doesn’t. Now the widget displays the green icon and says “Waste”.
Ok, the “waste” is easy, changed it to “Biotonne”. But still no date.

I assume the date item shows the correct date?

2021-02-08T06:00:00.000+0100

could be that I have to transform or format the value? or configure the eventfilter in a different way?

Oh yes good point! You need to set the state description metadata for your item to make it work!

good, works now!
only your footer still shows NaN

If you want to use my footer you need to add all your garbage date items to a group with aggregation “earliest”.

Then use this group item as items.garbage_collection.state in my footer