kongo09 / philips-airpurifier-coap

💨 Philips AirPurifier custom component for Home Assistant. Supports local CoAP protocol.
172 stars 27 forks source link

How change IP address of existing purifier? #112

Closed rstolpe closed 7 months ago

rstolpe commented 8 months ago

Hi, I have changed IP address for existing purifier how can I change the IP adress for that one without needing to remove it from HA?

kongo09 commented 8 months ago

There is no way to change the IP address. You need to remove it and then install it again. But don't worry, this shouldn't break anything, all your entities and automations should still work.

I agree that this is a shortcoming of practically every HA integration. I haven't looked into ways to change it once setup, so I'll leave this issue open until I understand this better. But don't expect me to work on this anytime soon.

tjorim commented 8 months ago

Don't we rely on the Mac address as a unique identifier? That's also how the purifier gets discovered.

kongo09 commented 8 months ago

The devices do have a unique identifier independent of the IP, which is why you can delete it and recreate it and everything should still be there. Still I understand that simply having an options flow to change the IP would be more convenient.

tjorim commented 8 months ago

I know this integration (https://github.com/petretiandrea/home-assistant-tapo-p100) is trying to do the same. Not sure if there's an official HA way to do it.

kongo09 commented 8 months ago

The way to do it is probably to either pick-up a change automatically through the autodiscovery, or use an options flow:

https://developers.home-assistant.io/docs/config_entries_options_flow_handler

kongo09 commented 8 months ago

I looked a bit into this and there are two ways I could do this:

It feels the second approach is easier, as you wouldn't have to know which device in HA is exactly which new IP address. It's enough to just type in a new address and the integration does the rest. This could also be extended to auto-discovery, which unfortunately doesn't work all the time. But if it works, it could auto-discover the devices under the new IP address and fix itself.

Any thoughts that would speak against approach 2 and favour more approach 1?

rstolpe commented 8 months ago

I looked a bit into this and there are two ways I could do this:

  • implement an options dialog through the flow handler. If the IP address of a device changes, you need to know which device has received which new IP address, then go to that devices, start the options flow and enter the new IP. The integration would then try to establish contact to the device, get the device details, verify that it is indeed the same device and if so, update the internal data in Home Assistant.

  • alternatively, I could simply change the "add device" flow where you can manually enter an IP address of a new device. If the integration then establishes contact and gets the device details, it anyhow checks if that devices already exists. If so, it could simply update the existing device with the new details and stop the adding process

It feels the second approach is easier, as you wouldn't have to know which device in HA is exactly which new IP address. It's enough to just type in a new address and the integration does the rest. This could also be extended to auto-discovery, which unfortunately doesn't work all the time. But if it works, it could auto-discover the devices under the new IP address and fix itself.

Any thoughts that would speak against approach 2 and favour more approach 1?

Option two is best I think

tjorim commented 8 months ago

Sounds good, I think this is what you are looking for? registered_devices https://developers.home-assistant.io/docs/creating_integration_manifest?_highlight=macaddress#dhcp

However, I think we would need to use the device_registry from what I understand. Not sure we currently do that (and we definitely don't seem to save the MAC address at the moment).

kongo09 commented 8 months ago

I'm using the device ID as identifier: https://github.com/kongo09/philips-airpurifier-coap/blob/0e7b904ddf5857b885fcbfeb47f071c16de500b9/custom_components/philips_airpurifier_coap/config_flow.py#L271

This should be very doable as the mechanics for that are already provided by the HA classes. I'll take a look over the weekend.

tjorim commented 8 months ago

That probably explains why my nmap device_tracker entity is not in the same device. Nmap does not know about that unique_id. Is there a way to add the MAC address as well?

kongo09 commented 8 months ago

There is only one unique ID. However, if it is best practice to use the MAC, I could switch that over. Not sure if that will create a migration problem for everyone, though, as the devices would not be recognized anymore.

tjorim commented 8 months ago

Just thinking out loud after reading the developer docs: the unique ID and identifiers don't need to be the same. Identifiers are a set so a device can have multiple identifiers. I don't think switching to MAC as a unique (entity?) ID is recommended.

Identifiers: Set of (DOMAIN, identifier) tuples. Identifiers identify the device in the outside world. An example is a serial number. Each item in the set uniquely defines a device entry, meaning another device can't have the same identifier.

But to be fair, I think we're getting off track of the original issue of simply detecting IP address changes. I'm more than happy as it is simply working at the moment. I'm trying to grasp the HA architecture but just the difference between a device registry and entity registry is already confusing me. I just noticed that with the beta and switching my Tapo smart switches from the custom integration to core that the nmap device tracker entities were neatly moved in the new devices from tplink.

kongo09 commented 8 months ago

Would you know how to retrieve the MAC? It's not part of the device information the device shares.

tjorim commented 8 months ago

Looks to be part of the config flow during discovery. I think that's when/where we should save or pass it along.

async def async_step_dhcp(self, discovery_info: dhcp.DhcpServiceInfo) -> FlowResult: (from https://github.com/kongo09/philips-airpurifier-coap/blob/master/custom_components%2Fphilips_airpurifier_coap%2Fconfig_flow.py#L54)

I remember seeing it earlier when we were troubleshooting the discovery of model AMF765:

2024-01-10 15:52:54.167 DEBUG (MainThread) [custom_components.philips_airpurifier_coap.config_flow] async_step_dhcp: called, found: DhcpServiceInfo(ip='192.168.0.114', hostname='mxchip', macaddress='849dc27a6c6e')
2024-01-10 15:52:54.169 DEBUG (MainThread) [custom_components.philips_airpurifier_coap.config_flow] trying to configure host: 192.168.0.114

Edit: checked some random integrations, they seem to set it only 1 identifier as you said. However, they put the MAC address as a connection. Like connections={(dr.CONNECTION_NETWORK_MAC, device.mac)}, or connections={("mac", attributes["mac"])},.

kongo09 commented 7 months ago

I checked but couldn't find any system call to give me the MAC address in case the user registers the devices manually. It's also not part of the data the device reports itself. I'll leve the device ID what it is for now.

However, I've fixed the original request of enabling a change of the IP address using approach 2:

please try v0.18.3

kongo09 commented 7 months ago

This can probably be improved by using registered_devices as described here https://developers.home-assistant.io/docs/creating_integration_manifest#dhcp

However, this would require storing the MAC - will keep this open to figure out how to do this.

kongo09 commented 7 months ago

Maybe this shows how it works: https://github.com/kongo09/core/blob/72e908f6cca95251b6a08e38d71cfdefb071d300/homeassistant/components/upnp/device.py#L52

kongo09 commented 7 months ago

added in v0.18.5-beta.1

tjorim commented 7 months ago

The device matching with MAC address (nmap entity) works for me. Haven't tested changing the IP address yet. One warning but I've also seen it happen before:

This error originated from a custom integration.

Logger: custom_components.philips_airpurifier_coap.config_flow
Source: custom_components/philips_airpurifier_coap/config_flow.py:84
Integration: Philips AirPurifier (with CoAP) (documentation, issues)
First occurred: 00:53:17 (1 occurrences)
Last logged: 00:53:17

Timeout, host 192.168.0.114 looks like a Philips AirPurifier but doesn't answer, aborting
kongo09 commented 7 months ago

That's great. The MAC address is indeed stored independently from the unique ID. But the way to get it is tricky and on my system actually doesn't work due to network topology, I assume. Anyhow, glad to hear it's working for others.