Phyn integration - Water leak detector

Thank you.

Changing my home’s name in the Phyn app appears to have corrected the error. My “Home name” field didn’t appear to be empty (although I don’t remember naming it), but it did have a space in the name. I renamed it to something without a space and was then able to add the integration into HA.

1 Like

Their promise to open it up via HomeKit is getting stale…

Indeed. As is the release of the 1.5" version. Early 2022 the product page said coming later in 2022. Now the page just says in development. Not much I can do besides wait since I have a 1.25" water main.

Glad to see the the integration, thanks @MizterB !

1 Like

First of all, excellent work @MizterB, this is just what I’ve been missing! In the past I’ve had to use ifttt for closing down the valve when leaving home and opening the valve when coming back home. Now I’m able to dump ifttt (as I’m not using it for anything else).

I’ve done a small update in sensor.py by including option for average water flow rate by allowing to select unit of measurement (did include device class and native unit of measurment). With this one can change the metric units just like with other existing sensors. It is working with my local setup, thus I made a pull request towards your main repository. After this all known sensor units can be adjusted basis of individual preference.

2 Likes

@MizterB Thanks so much for your work on this. This integration is a huge help. I have been running without issue. I have been searching for a long time for a way to get this info into HA.

Yes, this is awesome, kudos!

Logged a small issue - make sure you enter your username correctly as it is case sensitive. I had accidentally capitalized the first letter of my email and couldn’t get everything to authenticate.

Hi @MizterB and anyone else that might have any insight, will this integration work with the Kohler H2Wise+ thats powered by Phynn? Reviews on Phynn on their own site seem mixed I came across the Kohler product line. See link below. I have not yet purchased any device so I cannot unfortunately test anything. this device works with Kohler Konnect but I haven’t found a single integration for that either.
https://www.kohler.com/en/products/smart-home/shop-water-monitoring/h2wise-smart-home-water-monitor-and-automatic-shutoff-valve-33604

Impossible to know without trying it out. If you do buy & try, please share your results. At the same time, please don’t base your buying decision on the availability of an unofficial, reverse-engineered HA integration. Things could change at any time.

Million thanks MizterB! I’ve been using Phyn for 3 years and always been p*ssed off lack of API. You made my day, finally I can integrate water usage to my Energy dashboard. Thumbs up!

I’m getting an error when I try to log into my Phyn device. Here’s the error from the logs, any thoughts?

Logger: aiohttp.server
Source: custom_components/phyn/config_flow.py:31
Integration: Phyn
First occurred: 9:47:30 PM (1 occurrences)
Last logged: 9:47:30 PM

Error handling request
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/aiohttp/web_protocol.py", line 433, in _handle_request
    resp = await request_handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/aiohttp/web_app.py", line 504, in _handle
    resp = await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/aiohttp/web_middlewares.py", line 117, in impl
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/security_filter.py", line 85, in security_filter_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/forwarded.py", line 100, in forwarded_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/request_context.py", line 28, in request_context_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/ban.py", line 80, in ban_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/auth.py", line 236, in auth_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/view.py", line 148, in handle
    result = await handler(request, **request.match_info)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/config/config_entries.py", line 181, in post
    return await super().post(request, flow_id)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/data_validator.py", line 72, in wrapper
    result = await method(view, request, data, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/data_entry_flow.py", line 110, in post
    result = await self._flow_mgr.async_configure(flow_id, data)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 271, in async_configure
    result = await self._async_handle_step(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 367, in _async_handle_step
    result: FlowResult = await getattr(flow, method)(user_input)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/phyn/config_flow.py", line 46, in async_step_user
    info = await validate_input(self.hass, user_input)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/phyn/config_flow.py", line 31, in validate_input
    return {"title": homes[0]["alias_name"]}
                     ~~~~~~~~^^^^^^^^^^^^^^
KeyError: 'alias_name'

It looks like you added the Away Mode api call into the aiophyn API, but I’m not seeing it incorporated into the HA add-on.

I’ve never tried developing an add-on and willing to try to contribute if possible (assuming its not there that I’m missing). I’m inferring it would be optimally defined as a switch much like the Shutoff control?

1 Like

I submitted a feature request to allow to view and change the Away Mode

I created a new pull request (in both the aiophyn library and the homeassistant-phyn custom integration to add a new away mode switch to the Phyn device in HA.

I’ve so far been testing this with both of my Phyn devices and its working correctly. I did notice that when changing the away mode in HA the change doesn’t reflect in the app (on iOS) until I closed the app or changed homes (so it forced the app to reload the device details).

Example of the new switch in the UX here:

2 Likes

I’ve been looking into the Kohler device and I’ve been able to get the aiophyn module to work with it. However, I’ve had to manually scrape the JWT token and pass that to the aiophyn module. It looks like Kohler uses Azure B2C for login then passes a username/password to AWS cognito for the phyn “partner” login. I’m unable to ascertain what password is passed, but was wondering if anyone else might have some ideas.

Kohler devices reach out to the phyn api /partner-user-setup/token to get a token, which I’m assuming allows authentication to the phyn API, and then goes to AWS cognito, but I’m not sure how to make sense of that token at this point.

1 Like

Ok, with a slight modification to aiophyn (different API key/pool id/client id) I have the H2Wise+ integrated into home assistant. Unfortunately, I don’t expect anyone else to be able to get it to work at this time as there’s a secondary password that you have to dump through the app and it’s a complex. I haven’t been able to reverse engineer the code enough to figure out how the app gets that password but will keep trying occasionally to see if there’s a way to figure it out.

2 Likes

I finally figured it out. If you wouldn’t mind trying it, follow the same instructions but use the following repo: GitHub - jordanruthe/homeassistant-phyn

When you add the device via the integration, be sure to choose Kohler instead of Phyn. If you could let me know whether you have success or not, it would be appreciated.

2 Likes

Dumb question here (HA newbie):

What’s the difference between a “Home Assistant custom component” and an “integration”? I.e. why isn’t this just a normal integration like so many others?

My initial thinking was that the answer would be something like “Well, this is reverse-engineered, unofficial, etc.” But that seems to also be the case for many of the most popular integrations!

Thanks in advance.

I was not able to get this to work. When I try to add the device I only have the Phyn device option, Kohler waterwise does not show up. Any ideas?

I grabed the beta version and see the Kohler radio button now but I get unknown error occurred when I try to login. I verified my un and pw are currect by logging into the app with no issues. Not sure what the issue is.

I’ll try to take a look in the next day or two. Any additional logging information you have would be helpful (feel free to dm it if you prefer).

You can get automation detail by the following configuration in your ha config file:

logging:
  logs:
    custom_component.phyn: debug
    aiophyn: debug
1 Like

I apologize, not very familiar with the setup. Not sure how to DM you or what file to add the logging in. I tried to add it to the configuration.yaml file but I was not able to restart the system after that. Just started using HA yesterday but I was able to get everything installed, connected to smartthings, homekit, and get this integration installed. So, got a little ways but not to where I want to be. Really want this integration so I can auto stop water flow when I need to. Really appreciate the help!

Here are some logs:

2023-11-05 13:42:36.939 ERROR (MainThread) [aiohttp.server] Error handling request
Traceback (most recent call last):
File “/usr/local/lib/python3.11/site-packages/aiohttp/web_protocol.py”, line 433, in _handle_request
resp = await request_handler(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/usr/local/lib/python3.11/site-packages/aiohttp/web_app.py”, line 504, in _handle
resp = await handler(request)
^^^^^^^^^^^^^^^^^^^^^^
File “/usr/local/lib/python3.11/site-packages/aiohttp/web_middlewares.py”, line 117, in impl
return await handler(request)
^^^^^^^^^^^^^^^^^^^^^^
File “/usr/src/homeassistant/homeassistant/components/http/security_filter.py”, line 85, in security_filter_middleware
return await handler(request)
^^^^^^^^^^^^^^^^^^^^^^
File “/usr/src/homeassistant/homeassistant/components/http/forwarded.py”, line 100, in forwarded_middleware
return await handler(request)
^^^^^^^^^^^^^^^^^^^^^^
File “/usr/src/homeassistant/homeassistant/components/http/request_context.py”, line 28, in request_context_middleware
return await handler(request)
^^^^^^^^^^^^^^^^^^^^^^
File “/usr/src/homeassistant/homeassistant/components/http/ban.py”, line 80, in ban_middleware
return await handler(request)
^^^^^^^^^^^^^^^^^^^^^^
File “/usr/src/homeassistant/homeassistant/components/http/auth.py”, line 236, in auth_middleware
return await handler(request)
^^^^^^^^^^^^^^^^^^^^^^
File “/usr/src/homeassistant/homeassistant/components/http/headers.py”, line 31, in headers_middleware
response = await handler(request)
^^^^^^^^^^^^^^^^^^^^^^
File “/usr/src/homeassistant/homeassistant/components/http/view.py”, line 148, in handle
result = await handler(request, **request.match_info)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/usr/src/homeassistant/homeassistant/components/http/decorators.py”, line 63, in with_admin
return await func(self, request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/usr/src/homeassistant/homeassistant/components/config/config_entries.py”, line 177, in post
return await super().post(request, flow_id)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/usr/src/homeassistant/homeassistant/components/http/data_validator.py”, line 72, in wrapper
result = await method(view, request, data, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/usr/src/homeassistant/homeassistant/helpers/data_entry_flow.py”, line 110, in post
result = await self._flow_mgr.async_configure(flow_id, data)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/usr/src/homeassistant/homeassistant/data_entry_flow.py”, line 293, in async_configure
result = await self._async_handle_step(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/usr/src/homeassistant/homeassistant/data_entry_flow.py”, line 389, in _async_handle_step
result: FlowResult = await getattr(flow, method)(user_input)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/config/custom_components/phyn/config_flow.py”, line 52, in async_step_user
info = await validate_input(self.hass, user_input)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/config/custom_components/phyn/config_flow.py”, line 29, in validate_input
api = await async_get_api(
^^^^^^^^^^^^^^^^^^^^
File “/usr/local/lib/python3.11/site-packages/aiophyn/api.py”, line 192, in async_get_api
await api.async_authenticate()
File “/usr/local/lib/python3.11/site-packages/aiophyn/api.py”, line 142, in async_authenticate
await self._partner_api.authenticate()
File “/usr/local/lib/python3.11/site-packages/aiophyn/partners/kohler.py”, line 59, in authenticate
self._phyn_password = await self.token_to_password(token)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/usr/local/lib/python3.11/site-packages/aiophyn/partners/kohler.py”, line 198, in token_to_password
return unpad(cipher.decrypt(bytearray.fromhex(ct)), AES.block_size).decode()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/usr/local/lib/python3.11/site-packages/Crypto/Util/Padding.py”, line 92, in unpad
raise ValueError(“Padding is incorrect.”)
ValueError: Padding is incorrect.