diff --git a/README.md b/README.md
index 91463b17..7175521b 100644
--- a/README.md
+++ b/README.md
@@ -117,6 +117,7 @@ Currently the following service providers are supported:
### United Kingdom
- [York.gov.uk](./doc/source/york_gov_uk.md)
+- [Cambridge.gov.uk](./doc/source/cambridge_gov_uk.md)
## Installation
diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/source/cambridge_gov_uk.py b/custom_components/waste_collection_schedule/waste_collection_schedule/source/cambridge_gov_uk.py
new file mode 100644
index 00000000..6f58c4ad
--- /dev/null
+++ b/custom_components/waste_collection_schedule/waste_collection_schedule/source/cambridge_gov_uk.py
@@ -0,0 +1,70 @@
+import logging
+from datetime import datetime
+
+import requests
+from waste_collection_schedule import Collection
+
+TITLE = "Cambridge.gov.uk"
+DESCRIPTION = (
+ "Source for cambridge.gov.uk services for Cambridge and part of Cambridgeshire"
+)
+URL = "cambridge.gov.uk"
+TEST_CASES = {
+ "houseNumber": {"post_code": "CB13JD", "number": 37},
+ "houseName": {"post_code": "cb215hd", "number": "ROSEMARY HOUSE"},
+}
+
+API_URLS = {
+ "address_search": "https://servicelayer3c.azure-api.net/wastecalendar/address/search/",
+ "collection": "https://servicelayer3c.azure-api.net/wastecalendar/collection/search/{}/",
+}
+
+ICONS = {
+ "DOMESTIC": "mdi:trash-can",
+ "RECYCLE": "mdi:recycle",
+ "ORGANIC": "mdi:leaf",
+}
+
+_LOGGER = logging.getLogger(__name__)
+
+
+class Source:
+ def __init__(self, post_code: str, number: str):
+ self._post_code = post_code
+ self._number = str(number).capitalize()
+
+ def fetch(self):
+ # fetch location id
+ r = requests.get(
+ API_URLS["address_search"], params={"postCode": self._post_code}
+ )
+ r.raise_for_status()
+ addresses = r.json()
+
+ address_ids = [
+ x["id"] for x in addresses if x["houseNumber"].capitalize() == self._number
+ ]
+
+ if len(address_ids) == 0:
+ raise Exception(f"Could not find address {self._post_code} {self._number}")
+
+ q = str(API_URLS["collection"]).format(address_ids[0])
+ r = requests.get(q)
+ r.raise_for_status()
+
+ collections = r.json()["collections"]
+ entries = []
+
+ for collection in collections:
+ for round_type in collection["roundTypes"]:
+ entries.append(
+ Collection(
+ date=datetime.strptime(
+ collection["date"], "%Y-%m-%dT%H:%M:%SZ"
+ ).date(),
+ t=round_type.title(),
+ icon=ICONS[round_type],
+ )
+ )
+
+ return entries
diff --git a/doc/source/cambridge_gov_uk.md b/doc/source/cambridge_gov_uk.md
new file mode 100644
index 00000000..3fe67289
--- /dev/null
+++ b/doc/source/cambridge_gov_uk.md
@@ -0,0 +1,35 @@
+# Cambridge City Council
+
+Support for schedules provided by [Cambridge City Council](https://www.cambridge.gov.uk/check-when-your-bin-will-be-emptied), serving Cambridge (UK) and part of Cambridgeshire.
+
+## Configuration via configuration.yaml
+
+```yaml
+waste_collection_schedule:
+ sources:
+ - name: cambridge_gov_uk
+ args:
+ post_code: POST_CODE
+ number: NUMBER
+
+```
+
+### Configuration Variables
+
+**POST_CODE**
+*(string) (required)*
+
+**NUMBER**
+*(string) (required)*
+
+
+## Example
+
+```yaml
+waste_collection_schedule:
+ sources:
+ - name: cambridge_gov_uk
+ args:
+ post_code: "CB13JD"
+ number: "37"
+```