Adding Bristol Water quality to Home Assistant
Recently, I was looking up the water quality for my area, and I noticed that it pulls the data from an API within their CMS. This makes the data perfect to pull into Home Assistant.
I've used the rest
integration a lot previously, and it allows for great integration with APIs and data, without needing a full custom integration.
The API URL has a base of https://www.bristolwater.co.uk/_hcms/api/getWQHubdbDataInfo
and takes a query parameter of the postcode (e.g. ?q=BS1
).
The data is returned with numeric key names, so using something like a single sensor with attributes via json_attributes
would be unclean, and hard to know what the attribute is.
{
"1": "Shipton Moyne",
"2": 403,
"3": "Sherston, Marshfield and Pucklechurch",
"4": "Your water supply comes primarily from groundwater (boreholes) though at times this is supplemented with surface water (river)",
"5": "Your drinking water supply is classed as hard.",
"6": 91,
"7": 9.5,
"8": "266",
"9": 19,
"10": 27,
"11": 16,
"12": "...",
"13": "0.41",
"14": "209",
"15": "255",
"16": "41",
"17": "13",
"18": "1.2",
"19": "43",
"20": "55",
"21": "635",
"22": "7.52",
"24": "...",
"25": "..."
}
The values within the API response can be mapped to the values from the code of the water quality checker.
The mapping is as follows:
- 4: This is a message relating to the source of the water (e.g. from ground water, boreholes, etc.)
- 5: This is a message relating to the classification of the water (e.g. hard or soft)
- 6: This is the level of calcium (in mg/L)
- 7: This is the level of magnesium (in mg/L)
- 8: This is the level of water hardness from calcium carbonate (in mg/L)
- 13: This is the level of flouride (in mg/L)
- 14: This is the level of water alkalinity from calcium carbonate (in mg/L)
- 15: This is the level of water alkalinity from bicarbonate (in mg/L)
- 16: This is the level of chloride (in mg/L)
- 17: This is the level of nitrate (in mg/L)
- 18: This is the level of phosphate (in mg/L)
- 19: This is the level of sulphate (in mg/L)
- 20: This is the level of sodium (in mg/L)
Creating the sensors
By mapping these into sensors under a REST integration, I ended up with the following YAML:
rest:
- resource: 'https://www.bristolwater.co.uk/_hcms/api/getWQHubdbDataInfo'
params:
q: !secret postcode
scan_interval: 86400
sensor:
- name: Water Source
unique_id: bristol_water_source
value_template: "{{ value_json['objects'][0]['values']['4'] }}"
- name: Water Classification
unique_id: bristol_water_classification
value_template: "{{ value_json['objects'][0]['values']['5'] }}"
- name: Water Calcium
unique_id: bristol_water_calcium
value_template: "{{ value_json['objects'][0]['values']['6'] }}"
unit_of_measurement: mg/L
- name: Water Magnesium
unique_id: bristol_water_magnesium
value_template: "{{ value_json['objects'][0]['values']['7'] }}"
unit_of_measurement: mg/L
- name: Water Hardness (CaCO3)
unique_id: bristol_water_hardness
value_template: "{{ value_json['objects'][0]['values']['8'] }}"
unit_of_measurement: mg/L
- name: Water Flouride
unique_id: bristol_water_flouride
value_template: "{{ value_json['objects'][0]['values']['13'] }}"
unit_of_measurement: mg/L
- name: Water Alkalinity (CaCO3)
unique_id: bristol_water_alkalinity_caco3
value_template: "{{ value_json['objects'][0]['values']['14'] }}"
unit_of_measurement: mg/L
- name: Water Alkalinity (HCO3)
unique_id: bristol_water_alkalinity_hco3
value_template: "{{ value_json['objects'][0]['values']['15'] }}"
unit_of_measurement: mg/L
- name: Water Chloride
unique_id: bristol_water_chloride
value_template: "{{ value_json['objects'][0]['values']['16'] }}"
unit_of_measurement: mg/L
- name: Water Nitrate
unique_id: bristol_water_nitrate
value_template: "{{ value_json['objects'][0]['values']['17'] }}"
unit_of_measurement: mg/L
- name: Water Phosphate
unique_id: bristol_water_phosphate
value_template: "{{ value_json['objects'][0]['values']['18'] }}"
unit_of_measurement: mg/L
- name: Water Sodium
unique_id: bristol_water_sodium
value_template: "{{ value_json['objects'][0]['values']['19'] }}"
unit_of_measurement: mg/L
- name: Water Sulphate
unique_id: bristol_water_sulphate
value_template: "{{ value_json['objects'][0]['values']['20'] }}"
unit_of_measurement: mg/L
Displaying it on the dashboard
I then created a dashboard page using this with the following YAML:
Summary
type: markdown
title: Bristol Water
content: |-
**Classification**
{{ states('sensor.water_classification') }}
**Source**
{{ states('sensor.water_source') }}
Contents
type: vertical-stack
cards:
- type: horizontal-stack
cards:
- type: custom:mushroom-entity-card
entity: sensor.water_calcium
icon_type: none
name: Calcium
layout: vertical
fill_container: true
- type: custom:mushroom-entity-card
entity: sensor.water_magnesium
icon_type: none
name: Magnesium
layout: vertical
fill_container: true
- type: custom:mushroom-entity-card
name: Fluoride
icon_type: none
fill_container: true
layout: vertical
entity: sensor.water_flouride
- type: horizontal-stack
cards:
- type: custom:mushroom-entity-card
icon_type: none
layout: vertical
fill_container: true
entity: sensor.water_chloride
name: Chloride
- type: custom:mushroom-entity-card
icon_type: none
layout: vertical
fill_container: true
entity: sensor.water_nitrate
name: Nitrate
- type: custom:mushroom-entity-card
icon_type: none
fill_container: true
layout: vertical
entity: sensor.water_phosphate
name: Phosphate
- type: horizontal-stack
cards:
- type: custom:mushroom-entity-card
icon_type: none
layout: vertical
fill_container: true
entity: sensor.water_sulphate
name: Sulphate
- type: custom:mushroom-entity-card
icon_type: none
layout: vertical
fill_container: true
entity: sensor.water_sodium
name: Sodium
- type: custom:mushroom-entity-card
entity: sensor.water_hardness
icon_type: none
fill_container: true
layout: vertical
name: Hardness
Alkalinity
type: vertical-stack
cards:
- type: horizontal-stack
cards:
- type: custom:mushroom-entity-card
icon_type: none
layout: vertical
fill_container: true
entity: sensor.water_alkalinity_caco3
name: Alkalinity (CaCO3)
- type: custom:mushroom-entity-card
icon_type: none
layout: vertical
fill_container: true
entity: sensor.water_alkalinity_hco3
name: Alkalinity (HCO3)