custom-components / grocy

Custom Grocy integration for Home Assistant
Apache License 2.0
156 stars 47 forks source link

[Question] Pull chore data for daily notification #256

Closed dinki closed 1 year ago

dinki commented 1 year ago

Hi. Thanks again for this great integration. My family and I have been using it for chore tracking and what a difference it has made in our home.

I am writing to ask if someone can tell me a way to pull data from this integration for use in a daily notification to each member of my household. I'd like to pull all chores due today and overdue that I can then push via a notification. I'm fine with templating this but it is beyond my skill level. Any help would be most appreciated

OvernightPancake commented 1 year ago

Try an automation like this one:

I've also added my slightly modified version below:

alias: Notify daily chore reminder
description: ""
trigger:
  - platform: sun
    event: sunrise
    offset: 0
condition: []
action:
  - service: notify.notify
    data:
      message: >-
        Chores: {% for chore in
        state_attr('sensor.grocy_chores','chores') if
        strptime(chore.next_estimated_execution_time,
        '%Y-%m-%dT%H:%M:%S')|as_local <= today_at('23:59:59') %} {{chore.name}}
        {% else %} None! {% endfor %}

This will send a daily reminder at [trigger] sunrise and will use the [service] notify.notify to notify all available devices. I have not yet expanded on this to clean up the notification or only show chores for certain users, if anyone is able to update this I would appreciate it.

dinki commented 1 year ago

@JonSp8 Wow! This is almost exactly what I'm looking for! Can I tax you just a bit more to tell me how I might and another condition to the template that will also look for the user it is assigned to so that I can use it for all members of my family? What you provided shows all chores for the day. I certainly don't want to accidentally do my wife's chores! haha

I'm sure this is just an AND condition in the if statement above but I don't know how to format that condition. Again, thank you for helping with this!

- id: 1
  name: Kitchen - Wipe Counters
  description: ''
  period_type: daily
  period_config: ''
  period_days: 0
  track_date_only: false
  rollover: false
  assignment_type: in-alphabetical-order
  assignment_config: 2,3,4,5
  next_execution_assigned_to_user_id: 3
  userfields: null
  last_tracked_time: '2022-12-03T07:13:52'
  next_estimated_execution_time: '2022-12-04T14:38:55'
  last_done_by:
    id: 4
    username: mrsdinki
    first_name: mrsdinki
    last_name: ''
    display_name: dinki
  track_count: 0
  next_execution_assigned_user:
    id: 3
    username: dinki
    first_name: dinki
    last_name: ''
    display_name: dinki

Not sure which of these is the current assigned user

hillbicks commented 1 year ago

Not OP, but here is my template sensor

  - name: "Chores "
      state: >
         {% for chore in
         state_attr('sensor.grocy_chores','chores')
         if (chore.next_execution_assigned_to_user_id) == 1
         if strptime(chore.next_estimated_execution_time,'%Y-%m-%dT%H:%M:%S')|as_local <= today_at('23:59:59')%}
         {{chore.name}},
         {% endfor %}

Replace the 1 for next_execution_assigned_to_user_id with the relevant user_id.

Hope this helps.

OvernightPancake commented 1 year ago

Thanks for this @hillbicks!

I was struggling to get the formatting correct on my end and was just about to give it another go.

hillbicks commented 1 year ago

Another code snippet. This time to send a notification via node red when a chore is finished. Tasks are different it seems, you can't get information about an individual task from the grocy api.

I use node red for this automation, I haven't looked into home assistant for automation, but should be possible as well.

image

1) Event node that listens for the event call_service 2) change node to check whether payload.event.service == execute_chore 3) http request to grocy api http://GROCY_IP/api/chores/{{{payload.event.service_data.chore_id}}} //this will get the details for the chore that was just marked as done. 4) change node to check which user completed the task payload.last_done_by.username == A and payload.last_done_by.username == B 5) send a notification to the smartphone of the other user to inform him

{
    "message": "{{{payload.last_done_by.username}}} just finished the task {{{payload.chore.name}}} ",
    "title": "Chores",
    "data": {
        "channel": "channel_chore",
        "tag": "chore",
        "actions": [
            {
                "action": "thanks",
                "title": "Thanks"
            },
            {
                "action": "about_time",
                "title": "About time"
            }
        ]
    }
}

With the tag/channel set, you can then also send another notification to the user who finished the task, informing him about the answer, or anything else.

If you have any questions let me know.

kernel610 commented 1 year ago

@hillbicks Can you share the Node Red extract for this flow? This is exactly what I've been looking for and struggling with building. I can't get my flow to pull from the http request correctly so want to troubleshoot what you have versus what I'm trying.

hillbicks commented 1 year ago

@hillbicks Can you share the Node Red extract for this flow? This is exactly what I've been looking for and struggling with building. I can't get my flow to pull from the http request correctly so want to troubleshoot what you have versus what I'm trying.

Sure thing.

[{"id":"30cd453c820cf859","type":"switch","z":"38c9b265.61ce5e","name":"grocy execute chore","property":"payload.event.service","propertyType":"msg","rules":[{"t":"eq","v":"execute_chore","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":420,"y":3580,"wires":[["c6ee7d5f487124a9","a5d22b077c6b27b1"]]},{"id":"c6ee7d5f487124a9","type":"http request","z":"38c9b265.61ce5e","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"http://portainer.local:8080/api/chores/{{{payload.event.service_data.chore_id}}}","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"headers":[{"keyType":"other","keyValue":"accept","valueType":"other","valueValue":"application/json"},{"keyType":"other","keyValue":"GROCY-API-KEY","valueType":"other","valueValue":"j6NPWaEYuQmBVf0vhrAt0vbh47mpE9IlPpLgR30cCUB9maq2Du"}],"x":690,"y":3580,"wires":[["8e178831af80b70a","a5d22b077c6b27b1","a703bfb2711bbe9f"]]},{"id":"cd9c46181d5b3161","type":"api-call-service","z":"38c9b265.61ce5e","name":"smartphone z chore done","server":"c52db6a3.01673","version":5,"debugenabled":false,"domain":"notify","service":"group_notify_smartphone_z","areaId":[],"deviceId":[],"entityId":[],"data":"{\"message\":\"{{{payload.last_done_by.username}}} hat grade {{{payload.chore.name}}} erledigt\",\"title\":\"Hausarbeit \",\"data\":{\"channel\":\"die Hausarbeit\",\"tag\":\"chore\",\"actions\":[{\"action\":\"danke\",\"title\":\"Danke\"},{\"action\":\"wurde_auch_zeit\",\"title\":\"Wurde auch Zeit\"}]}}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1210,"y":3620,"wires":[[]]},{"id":"8e178831af80b70a","type":"switch","z":"38c9b265.61ce5e","name":"grocy execute chore who?","property":"payload.last_done_by.username","propertyType":"msg","rules":[{"t":"eq","v":"Z","vt":"str"},{"t":"eq","v":"meier","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":930,"y":3580,"wires":[["f65d10c9c36d2403","a5d22b077c6b27b1","d64dc7b8a49bd71a"],["cd9c46181d5b3161","d64dc7b8a49bd71a"]]},{"id":"f65d10c9c36d2403","type":"api-call-service","z":"38c9b265.61ce5e","name":"smartphone m chore done","server":"c52db6a3.01673","version":5,"debugenabled":false,"domain":"notify","service":"group_notify_smartphone_meier","areaId":[],"deviceId":[],"entityId":[],"data":"{\"message\":\"{{{payload.last_done_by.username}}} hat grade {{{payload.chore.name}}} erledigt\",\"title\":\"Hausarbeit \",\"data\":{\"channel\":\"die Hausarbeit\",\"tag\":\"chore\",\"actions\":[{\"action\":\"danke\",\"title\":\"Danke\"},{\"action\":\"wurde_auch_zeit\",\"title\":\"Wurde auch Zeit\"}]}}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1210,"y":3540,"wires":[[]]},{"id":"29850005da0a58ca","type":"server-events","z":"38c9b265.61ce5e","name":"call_service for grocy","server":"c52db6a3.01673","version":2,"eventType":"call_service","exposeToHomeAssistant":false,"eventData":"","haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"$outputData(\"eventData\").event_type","valueType":"jsonata"}],"event_type":"","x":200,"y":3580,"wires":[["30cd453c820cf859"]]},{"id":"c52db6a3.01673","type":"server","name":"homeassistant","version":5,"addon":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":true,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"id","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

The channels have german names though, but the flow shouldn't be complicated to understand. I use these to send replies when one user clicks done. Let me know if you have questions.

kernel610 commented 1 year ago

@hillbicks Can you share the Node Red extract for this flow? This is exactly what I've been looking for and struggling with building. I can't get my flow to pull from the http request correctly so want to troubleshoot what you have versus what I'm trying.

Sure thing.

[{"id":"30cd453c820cf859","type":"switch","z":"38c9b265.61ce5e","name":"grocy execute chore","property":"payload.event.service","propertyType":"msg","rules":[{"t":"eq","v":"execute_chore","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":420,"y":3580,"wires":[["c6ee7d5f487124a9","a5d22b077c6b27b1"]]},{"id":"c6ee7d5f487124a9","type":"http request","z":"38c9b265.61ce5e","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"http://portainer.local:8080/api/chores/{{{payload.event.service_data.chore_id}}}","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"headers":[{"keyType":"other","keyValue":"accept","valueType":"other","valueValue":"application/json"},{"keyType":"other","keyValue":"GROCY-API-KEY","valueType":"other","valueValue":"j6NPWaEYuQmBVf0vhrAt0vbh47mpE9IlPpLgR30cCUB9maq2Du"}],"x":690,"y":3580,"wires":[["8e178831af80b70a","a5d22b077c6b27b1","a703bfb2711bbe9f"]]},{"id":"cd9c46181d5b3161","type":"api-call-service","z":"38c9b265.61ce5e","name":"smartphone z chore done","server":"c52db6a3.01673","version":5,"debugenabled":false,"domain":"notify","service":"group_notify_smartphone_z","areaId":[],"deviceId":[],"entityId":[],"data":"{\"message\":\"{{{payload.last_done_by.username}}} hat grade {{{payload.chore.name}}} erledigt\",\"title\":\"Hausarbeit \",\"data\":{\"channel\":\"die Hausarbeit\",\"tag\":\"chore\",\"actions\":[{\"action\":\"danke\",\"title\":\"Danke\"},{\"action\":\"wurde_auch_zeit\",\"title\":\"Wurde auch Zeit\"}]}}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1210,"y":3620,"wires":[[]]},{"id":"8e178831af80b70a","type":"switch","z":"38c9b265.61ce5e","name":"grocy execute chore who?","property":"payload.last_done_by.username","propertyType":"msg","rules":[{"t":"eq","v":"Z","vt":"str"},{"t":"eq","v":"meier","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":930,"y":3580,"wires":[["f65d10c9c36d2403","a5d22b077c6b27b1","d64dc7b8a49bd71a"],["cd9c46181d5b3161","d64dc7b8a49bd71a"]]},{"id":"f65d10c9c36d2403","type":"api-call-service","z":"38c9b265.61ce5e","name":"smartphone m chore done","server":"c52db6a3.01673","version":5,"debugenabled":false,"domain":"notify","service":"group_notify_smartphone_meier","areaId":[],"deviceId":[],"entityId":[],"data":"{\"message\":\"{{{payload.last_done_by.username}}} hat grade {{{payload.chore.name}}} erledigt\",\"title\":\"Hausarbeit \",\"data\":{\"channel\":\"die Hausarbeit\",\"tag\":\"chore\",\"actions\":[{\"action\":\"danke\",\"title\":\"Danke\"},{\"action\":\"wurde_auch_zeit\",\"title\":\"Wurde auch Zeit\"}]}}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1210,"y":3540,"wires":[[]]},{"id":"29850005da0a58ca","type":"server-events","z":"38c9b265.61ce5e","name":"call_service for grocy","server":"c52db6a3.01673","version":2,"eventType":"call_service","exposeToHomeAssistant":false,"eventData":"","haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"$outputData(\"eventData\").event_type","valueType":"jsonata"}],"event_type":"","x":200,"y":3580,"wires":[["30cd453c820cf859"]]},{"id":"c52db6a3.01673","type":"server","name":"homeassistant","version":5,"addon":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":true,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"id","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

The channels have german names though, but the flow shouldn't be complicated to understand. I use these to send replies when one user clicks done. Let me know if you have questions.

Got it working! Thank you for sharing. It was the headers piece of the http request that I had incorrect.