Skip to content

Conversation

@pantherale0
Copy link
Contributor

@pantherale0 pantherale0 commented Nov 10, 2025

Proposed change

Adds a new integration for Anglian Water (UK only, east of england) - anglianwater.co.uk

This creates two sensors that display the latest water meter information, yesterdays total water usage in litres and the latest meter reading in cubic meters.

This does validate that an account has a smart meter associated with it during the config flow. Only basic tests have been added for now.

I have not yet completed this, so the quality scale has not been filled in yet.

This does rely on Microsoft B2C authentication to login, the whole end to end process of login has been implemented without the need for a web browser.

This does scrape some configuration settings from the authentication web page which you can see in this function, but this is the only scraping the integration does, the rest is standard get/post requests and header inspection:

https://github.com/pantherale0/pyanglianwater/blob/c7a2c9d515397c5496a0c42031abcc7263706be9/pyanglianwater/auth.py#L130

Brands: home-assistant/brands#8402

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

Checklist

  • I understand the code I am submitting and can explain how it works.
  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • I have followed the perfect PR recommendations
  • The code has been formatted using Ruff (ruff format homeassistant tests)
  • Tests have been added to verify that the new code works.
  • Any generated code has been carefully reviewed for correctness and compliance with project standards.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description.

To help with the load of incoming pull requests:

@pantherale0 pantherale0 marked this pull request as ready for review November 10, 2025 13:28
@pantherale0

This comment was marked as resolved.

vol.Required(CONF_PASSWORD): selector.TextSelector(
selector.TextSelectorConfig(type=selector.TextSelectorType.PASSWORD)
),
vol.Optional(CONF_ACCOUNT_NUMBER): selector.TextSelector(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did we have this again?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Account number? If you move house, your old account is still associated with your account and sometimes AW don't actually update the primary account number.

Basically the account number is a unique identifier for the specific user and property combination.

If you have a 2nd home for example, you would have two account numbers representing different properties (despite being under the same name / login).

For most users, we can rely on the default account number as the smart meter rollout is still ongoing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we fetch a list of all numbers?

Copy link
Contributor Author

@pantherale0 pantherale0 Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have another look at the API, I know it does display a list of accounts somehow, but I'm honestly not 100% certain where that comes from (my account only has one account number).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, it grabs it by the "business partner number" which is returned in the JWT token.

['getAssociatedAccounts'](_0x3ea7ac, _0x139fc9 = false) {
                        ;
                        return this.context.associated_accounts && !_0x139fc9 ? (0, _0x4811b8.of)(this.context.associated_accounts) : this.http.get(_0x348da9.c.config.apiUrl + '/v1/businesspartners/' + this.utilsService.encryptAES256AsHex(_0x3ea7ac) + '/associatedaccounts').pipe((0, _0x31186f.M)(_0x5d1478 => {
                            ;
                            this.context.update(_0x506a78.o.SET_ASSOCIATED_ACCOUNTS, _0x5d1478.result);
                        }), (0, _0x4afb98.T)(_0x3f281e => _0x3f281e.result));
                    }
this.businessPartnerService.getAssociatedAccounts(this.authService.activeUser.businessPartnerNumber);

If I'm thinking what you are thinking, would you prefer a drop down list or radio controls?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would either expect we add all houses at once, unless there's a good reason not to do it

Copy link
Contributor Author

@pantherale0 pantherale0 Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not all houses have a smart meter and therefore won't work with this integration (AW are still slowly completing the rollout), plus some houses have a completely different type of "smart meter" (also not supported as they require someone to come round and wave a stick over the top of the meter), none of that can be figured out in the API without probing each one.

Plus if you are a landlord for a HMO or similar, you might not be interested in your tenants water usage in your personal Home Assistant.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a crack at implementing a dropdown / list using the SelectSelector, I'm not sure if I've hit a bug in core though because if I return a list of SelectOptionDict then the new step never loads and instead I'm greeted with an "Unknown error occurred" message. Nothing is logged in the logs and the only error I can see is a 400 bad request response from HA, I will stash these changes for now.

imo, I think the text box is plenty suitable though, the account number can be found in multiple places (latest bill, account statement, when you sign into their apps, over the phone, via whatsapp). There is quite a bit of history with that:

pantherale0/haanglianwater#66
pantherale0/haanglianwater#106 (comment)

You will then see in 106, that actually I had to revert the changes I made because I then found that their backend system and MSO B2C claims and user management aren't quite in sync and therefore actually manually entering the account number is the only reliable way to select the correct property (against ones you no longer live in / own, because they are all still included), I would take a guess that 70% of users will be fine with the automatic detection from the access token however so the field is optional, but just there in case we select the wrong one.

There is some further complexities, the library itself can only interact with one account at a time due to the need for some encryption (https://github.com/pantherale0/pyanglianwater/blob/f5f1e608361a0544f462c43b3249b693ba676d5f/pyanglianwater/utils.py#L118) on API requests - basically the integration actually mimics how the website functionally behaves when it comes to multiple accounts.

@home-assistant home-assistant bot marked this pull request as draft November 10, 2025 14:24
@home-assistant
Copy link

Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍

Learn more about our pull request process.

@pantherale0 pantherale0 marked this pull request as ready for review November 10, 2025 17:49
@home-assistant home-assistant bot requested a review from joostlek November 10, 2025 17:49
@pantherale0 pantherale0 marked this pull request as draft November 11, 2025 00:21
@pantherale0

This comment was marked as outdated.

@pantherale0 pantherale0 marked this pull request as ready for review November 11, 2025 12:19
Comment on lines 60 to 75
AnglianWaterSensorEntityDescription(
key=AnglianWaterSensor.YESTERDAY_WATER_COST,
native_unit_of_measurement="GBP",
device_class=SensorDeviceClass.MONETARY,
value_fn=lambda entity: entity.yesterday_water_cost,
state_class=SensorStateClass.TOTAL,
translation_key=AnglianWaterSensor.YESTERDAY_WATER_COST,
),
AnglianWaterSensorEntityDescription(
key=AnglianWaterSensor.YESTERDAY_SEWERAGE_COST,
native_unit_of_measurement="GBP",
device_class=SensorDeviceClass.MONETARY,
value_fn=lambda entity: entity.yesterday_sewerage_cost,
state_class=SensorStateClass.TOTAL,
translation_key=AnglianWaterSensor.YESTERDAY_SEWERAGE_COST,
),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would argue that a device class is not fitting here

Copy link
Contributor Author

@pantherale0 pantherale0 Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May I ask why?

The monetary device class would correctly display the costs in the UI, whereas without it will just show "GBP" at the end which is incorrect for the UK:

image

(Note: this screenshot is from the custom integration which hasn't been updated for a while)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, but more like, monetary + total is used for a balance, not for yesterdays cost.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall I use measurement instead? The value can only represent yesterdays total cost (the data from the meter is only updated once every 24~ hours, and the API itself will only return the cost for a full day, not per hour costs etc).

My thinking was that this could be used in the energy dashboard.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't have measurement with monetary, as the unit of measurement is always wrong in that case. This is a discussion that has been done several times, I can link you to those, but should we remove the state classes for now so we can merge this and add it later?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, yeah I'll remove it for now, its not 100% accurate anyway because Anglian Water don't include the daily standing charge in this cost (yet).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed state_class from these 2 sensors.

@home-assistant home-assistant bot marked this pull request as draft November 13, 2025 19:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants