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. Provide the metadata namespace where you store the color, label and icon information for your collection items. Add custom namespaces to your collection date items with the corresponding name. Icon metadata is optional and defaults to the trash can.

  2. Put your localized strings for “Today” and “Tomorrow” here.

  3. Date Items: Requires a group item which is parent to all collection dates that should be shown in the widget.

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

Screenshots

image

Changelog

Version 0.4

  • Added optional icon metadata property. Can be omitted to get the default trash icon. Can be used on all collection dates or only selected collection dates. Wil always default to the trash can if not set for a collection date.

Version 0.3

!!! Note that this version contains breaking changes. Please read the setup instructions again !!!

  • List is now sorted from earliest to latest collection date
  • Use a group of collection items instead of a string to define collection items
  • Use metadata to retrieve labels and colors for the collection list items

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
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: Metadata namespace for collection color
      label: Color metadata
      name: collectioncolor
      required: true
      type: TEXT
    - description: Metadata namespace for collection labels
      label: Label metadata
      name: collectionlabel
      required: true
      type: TEXT
    - description: Metadata namespace for collection icon
      label: Icon metadata
      name: collectionicon
      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
    - context: item
      label: Date items
      name: dategroup
      required: true
      type: TEXT
  parameterGroups: []
timestamp: Aug 31, 2024, 1:30:49 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:
                    fetchMetadata: =[props.collectionlabel, props.collectioncolor,
                      props.collectionicon]
                    for: item
                    groupItem: =[props.dategroup]
                    map: "loop.item_source.sort((x,y) => (x.state).localeCompare(y.state, undefined,
                      { numeric: true }))[loop.item_idx]"
                    sourceType: itemsInGroup
                  slots:
                    default:
                      - component: oh-list-item
                        config:
                          badge: '=((dayjs(loop.item.state).diff(dayjs().startOf("day"), "days")) == 0 ?
                            (props.today) :
                            (dayjs(loop.item.state).diff(dayjs().startOf("day"),
                            "days")) == 1 ? (props.tomorrow) : false)'
                          badgeColor: '=((dayjs(loop.item.state).diff(dayjs().startOf("day"), "days")) ==
                            0 ? "red" : "yellow")'
                          footer: =items[loop.item.name].displayState
                          icon: '=loop.item.metadata[props.collectionicon] == null ? "f7:trash" :
                            loop.item.metadata[props.collectionicon].value'
                          iconColor: =loop.item.metadata[props.collectioncolor].value
                          title: =loop.item.metadata[props.collectionlabel].value
                          visible: =loop.item.state != "UNDEF"
    - component: f7-card-footer
      slots:
        default:
          - component: Label
            config:
              text: =props.footer
16 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