diff --git a/README.md b/README.md
index c6bbb6d30..adefb6eed 100644
--- a/README.md
+++ b/README.md
@@ -166,6 +166,7 @@ Currently the following service providers are supported:
- [Peterborough City Council - peterborough.gov.uk](./doc/source/peterborough_gov_uk.md)
- [South Cambridgeshire District Council - scambs.gov.uk](./doc/source/scambs_gov_uk.md)
- [City of York Council - york.gov.uk](./doc/source/york_gov_uk.md)
+- [West Berkshire Council - westberks.gov.uk](./doc/source/westberks_gov_uk.md)
- [Wiltshire Council - wiltshire.gov.uk](./doc/source/wiltshire_gov_uk.md)
## Installation
diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/source/westberks_gov_uk.py b/custom_components/waste_collection_schedule/waste_collection_schedule/source/westberks_gov_uk.py
new file mode 100644
index 000000000..9a24b47de
--- /dev/null
+++ b/custom_components/waste_collection_schedule/waste_collection_schedule/source/westberks_gov_uk.py
@@ -0,0 +1,113 @@
+from datetime import date, datetime
+
+import time
+import json
+import requests
+
+from waste_collection_schedule import Collection
+
+TITLE = "West Berkshire Council, UK"
+DESCRIPTION = "Source for westberks.gov.uk services for West Berkshire Council"
+URL = "westberks.gov.uk"
+
+TEST_CASES = {
+ "known_uprn": {"uprn": "100080241094"},
+ "unknown_uprn_by_name": {"postcode": "RG7 6NZ", "housenumberorname": "PARROG HOUSE"},
+ "unknown_uprn_by_number": {"postcode": "RG18 4QU", "housenumberorname": "6"},
+ "unknown_uprn_business": {"postcode": "RG18 4GE", "housenumberorname": "3"}
+}
+
+ICONS = {
+ "RUBBISH": "mdi:trash-can",
+ "RECYCLING": "mdi:recycle",
+}
+
+SEARCH_URLS = {
+ "uprn_search": "https://www.westberks.gov.uk/apiserver/ajaxlibrary",
+ "collection_search": "https://www.westberks.gov.uk/apiserver/ajaxlibrary",
+}
+
+COLLECTIONS = {"Rubbish", "Recycling"}
+
+class Source:
+ def __init__(
+ self, uprn=None, postcode=None, housenumberorname=None
+ ): # argX correspond to the args dict in the source configuration
+ self._uprn = uprn
+ self._postcode = postcode
+ self._housenumberorname = housenumberorname
+
+ def fetch(self):
+ entries = []
+ session = requests.Session()
+
+ # Find the UPRN based on the postcode and the property name/number
+ if self._uprn is None:
+ self._postcode = self._postcode.strip()
+ jsonrpc = {"id": str(int(time.time())),"method": "location.westberks.echoPostcodeFinder","params": {"provider": "", "postcode": self._postcode}}
+ args = { "callback": "HomeAssistant", "jsonrpc": json.dumps(jsonrpc), "_": 0 }
+ r = requests.get(SEARCH_URLS["uprn_search"], params = args)
+
+ # I don't really know python so there *must* be a better way to do these four lines!
+ response_str = r.content.decode("utf-8")
+ data_length = len(response_str) -1
+ response_sub = response_str[14:data_length]
+ address_data = json.loads(response_sub)
+
+ propertyUprns = address_data['result']
+ for match in propertyUprns:
+ if match['line1'].startswith(self._housenumberorname):
+ self._uprn = match["udprn"]
+ if match['buildingnumber'].startswith(self._housenumberorname): # no evidence (yet) that their database uses this
+ self._uprn = match["udprn"]
+
+ entries = []
+
+ # Get the collection days based on the UPRN (either supplied through arguments or searched for above)
+ if self._uprn is not None:
+
+ # POST request - one for each type as it is a separate method in the api
+ rubbish_args = {"jsonrpc":"2.0","id":str(int(time.time())) ,"method":"goss.echo.westberks.forms.getNextRubbishCollectionDate","params":{"uprn":self._uprn}}
+ recycling_args = {"jsonrpc":"2.0","id":str(int(time.time())),"method":"goss.echo.westberks.forms.getNextRecyclingCollectionDate","params":{"uprn":self._uprn}}
+ r = session.post(SEARCH_URLS["collection_search"], json = rubbish_args)
+ rubbish_data = json.loads(r.content)
+ r = session.post(SEARCH_URLS["collection_search"], json = recycling_args)
+ recycling_data = json.loads(r.content)
+
+ # if subtext is empty, use datetext
+ # if both have values, use subtext
+
+ # Extract dates from json
+ waste_type = "Rubbish"
+ if not rubbish_data['result']['nextRubbishDateSubText']:
+ dt_str = rubbish_data['result']['nextRubbishDateText'] + " " + str(date.today().year)
+ else:
+ if len(rubbish_data['result']['nextRubbishDateText'])<12:
+ dt_str = rubbish_data['result']['nextRubbishDateSubText'] + " " + str(date.today().year)
+ dt_zulu = datetime.strptime(dt_str, '%A %d %B %Y')
+ dt_local = dt_zulu.astimezone(None)
+ entries.append(
+ Collection(
+ date=dt_local.date(),
+ t=waste_type,
+ icon=ICONS.get(waste_type.upper()),
+ )
+ )
+
+ waste_type = "Recycling"
+ if not recycling_data['result']['nextRecyclingDateSubText']:
+ dt_str = recycling_data['result']['nextRecyclingDateText'] + " " + str(date.today().year)
+ else:
+ if len(recycling_data['result']['nextRecyclingDateText'])<12:
+ dt_str = recycling_data['result']['nextRecyclingDateSubText'] + " " + str(date.today().year)
+ dt_zulu = datetime.strptime(dt_str, '%A %d %B %Y')
+ dt_local = dt_zulu.astimezone(None)
+ entries.append(
+ Collection(
+ date=dt_local.date(),
+ t=waste_type,
+ icon=ICONS.get(waste_type.upper()),
+ )
+ )
+
+ return entries
diff --git a/doc/source/westberks_gov_uk.md b/doc/source/westberks_gov_uk.md
new file mode 100644
index 000000000..3e39be4c5
--- /dev/null
+++ b/doc/source/westberks_gov_uk.md
@@ -0,0 +1,52 @@
+# West Berkshire Council
+
+Support for schedules provided by [West Berkshire Council](https://www.westberks.gov.uk/).
+
+If collection data is available for the address provided, it will return rubbish and recycling waste collection dates.
+
+## Configuration via configuration.yaml
+
+```yaml
+waste_collection_schedule:
+ sources:
+ - name: westberks_gov_uk
+ args:
+ postcode: POSTCODE
+ uprn: UPRN
+```
+
+### Configuration Variables
+
+**postcode**
+_(string) (optional)_
+
+**hournameornumber**
+_(string) (optional)_
+
+**uprn**
+_(string) (optional)_
+
+Either the postcode _and_ housenameornumber or the UPRN should be supplied in the arguments
+
+## Examples
+
+```yaml
+waste_collection_schedule:
+ sources:
+ - name: westberks_gov_uk
+ args:
+ uprn: "100080241094"
+```
+
+```yaml
+waste_collection_schedule:
+ sources:
+ - name: westberks_gov_uk
+ args:
+ postcode: "RG18 4QU"
+ housenameornumber: "6"
+```
+
+## How to find your UPRN
+
+An easy way to discover your Unique Property Reference Number (UPRN) is by going to [Find My Address](https://www.findmyaddress.co.uk/) and providing your address details.
diff --git a/info.md b/info.md
index 1527d80a5..6ad02b588 100644
--- a/info.md
+++ b/info.md
@@ -152,4 +152,5 @@ Currently the following service providers are supported:
- [Peterborough City Council - peterborough.gov.uk](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/peterborough_gov_uk.md)
- [South Cambridgeshire District Council - scambs.gov.uk](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/scambs_gov_uk.md)
- [City of York Council - york.gov.uk](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/york_gov_uk.md)
-- [Wiltshire Council - wiltshire.gov.uk](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/wiltshire_gov_uk.md)
\ No newline at end of file
+- [West Berkshire Council - westberks.gov.uk](./doc/source/westberks_gov_uk.md)
+- [Wiltshire Council - wiltshire.gov.uk](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/wiltshire_gov_uk.md)