I’ve got a Node-Red flow for anyone using Cheshire East. You will need to replace the UPRN in the http request node, you can find yours using UPRN search, address & postcode finder - FindMyAddress.
Might not be perfectly elegant, however it works for me
[{"id":"cae57bf.8eb5988","type":"inject","z":"40d22550.6e2dcc","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"43200","crontab":"","once":true,"onceDelay":"5","topic":"","payloadType":"date","x":100,"y":40,"wires":[["812b22c7.db831"]]},{"id":"812b22c7.db831","type":"http request","z":"40d22550.6e2dcc","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"https://online.cheshireeast.gov.uk/MyCollectionDay/SearchByAjax/GetBartecJobList?uprn=xxxxxxxxx","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":190,"y":100,"wires":[["c61cbb09.69fd68"]]},{"id":"c61cbb09.69fd68","type":"html","z":"40d22550.6e2dcc","name":"Table","property":"payload","outproperty":"payload","tag":"div.inner-results-contains-table > div > table > tbody > tr > td ","ret":"text","as":"single","x":270,"y":160,"wires":[["f0338d6d.f83b1"]]},{"id":"f0338d6d.f83b1","type":"function","z":"40d22550.6e2dcc","name":"","func":"dayjs.extend(duration);\ndayjs.extend(customParseFormat);\n\nlet upcomingBins = [];\nlet gardenDone = false;\nlet mixedDone = false;\nlet generalDone = false;\n\nmsg.payload.forEach((i) => {\n if (i.length > 0) {\n const item = i.split(\"\\n\");\n const items = item.map((s) => s.trim());\n\n if (items.includes(\"Empty Standard Garden Waste\") && !gardenDone) {\n gardenDone = true;\n upcomingBins.push(populatePayload(items, \"sensor.garden_waste\"));\n }\n if (items.includes(\"Empty Standard Mixed Recycling\") && !mixedDone) {\n mixedDone = true;\n upcomingBins.push(populatePayload(items, \"sensor.recycling_waste\"));\n }\n if (items.includes(\"Empty Standard General Waste\") && !generalDone) {\n generalDone = true;\n upcomingBins.push(populatePayload(items, \"sensor.general_waste\"));\n }\n }\n});\n\nfunction populatePayload(items, id) {\n let binItem = {\n payload: {\n data: {\n state: null,\n attributes: {}\n }\n }\n };\n\n const date = dayjs(items[2], \"DD/MM/YYYY\");\n const today = dayjs();\n\n let hours = date.diff(today, \"hours\");\n binItem.entity_id = id;\n binItem.payload.data.attributes.day = items[1];\n binItem.payload.data.attributes.date = date;\n binItem.payload.data.state = date;\n binItem.payload.data.attributes.daysUntil = hoursToDays(hours);\n\n return binItem;\n}\n\nfunction toString(h) {\n if (h < 0) return \"Today\";\n else if (h > 0 && h < 24) return \"Tomorrow\";\n else return `${hoursToDays(h)} days time`;\n}\n\nfunction hoursToDays(h) {\n return Math.ceil(dayjs.duration({ hours: h }).asDays());\n}\n\nconst slicedArray = upcomingBins.slice(0, 3);\nmsg.payload = slicedArray;\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[{"var":"dayjs","module":"dayjs"},{"var":"customParseFormat","module":"dayjs/plugin/customParseFormat"},{"var":"duration","module":"dayjs/plugin/duration"}],"x":340,"y":220,"wires":[["2805aa44.d14236"]]},{"id":"2805aa44.d14236","type":"split","z":"40d22550.6e2dcc","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":470,"y":260,"wires":[["14df8c02.bdabd4"]]},{"id":"14df8c02.bdabd4","type":"ha-api","z":"40d22550.6e2dcc","name":"","server":"68b1f3b6.69c6ac","version":1,"debugenabled":false,"protocol":"http","method":"post","path":"/api/states/{{payload.entity_id}}","data":"payload.payload.data\t","dataType":"jsonata","responseType":"json","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"results"}],"x":590,"y":260,"wires":[[]]},{"id":"68b1f3b6.69c6ac","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":"30"}]
I then have the following template sensors to tell me how many days until collection
template:
sensor:
- unique_id: garden_bin
state: >
{% set t = states('sensor.garden_waste') | as_datetime %}
{% if t %}
{% set delta = t - now() %}
{% set days = delta.days + 1 %}
{% if days == 1 %}
Tomorrow
{% elif days == 0 %}
Today
{% else %}
{{ days }} days time
{% endif %}
{% endif %}
- unique_id: general_bin
state: >
{% set t = states('sensor.general_waste') | as_datetime %}
{% if t %}
{% set delta = t - now() %}
{% set days = delta.days + 1 %}
{% if days == 1 %}
Tomorrow
{% elif days == 0 %}
Today
{% else %}
{{ days }} days time
{% endif %}
{% endif %}
- unique_id: recycling_bin
state: >
{% set t = states('sensor.recycling_waste') | as_datetime %}
{% if t %}
{% set delta = t - now() %}
{% set days = delta.days + 1 %}
{% if days == 1 %}
Tomorrow
{% elif days == 0 %}
Today
{% else %}
{{ days }} days time
{% endif %}
{% endif %}
I might work on turning this into a web api if anyone is interested?
EDIT: Web API is now available. Repo available here: GitHub - greghesp/bin-collection-api
Temporary web API endpoint: https://bin-collection-api.vercel.app/api/council/cheshire_east?uprn=XXXXXXX