How to migrate esps to new ip range

Hello all,

Title is a bit confusing. I need to change my local network ip from the very common 192.168.1.x to something less common to avoid network clashes when I connect my wireguard vpn. I am running proxmox and all my services that I host are easy to switch. I nearly did it yesterday but I had to revert because of the 6 ESP devices I have in my house i various hard to reach places.

My question is: how can I change the IPs of these devices to the new IP range?

I have tried to first create a larger mask on the original network and changed their ask to match he larger mask. Then I switched HA to the new range (that is within the larger mask). The new HA ip and the original ESP ips could communicate fine. But then I cannot understand how to change the IP of the ESPs. I tried flashing a new IP on a test ESP and it got lost. It didn’t receive the new IP but the old one worked again after switching HA back to the original IP.

I am really confused. I searched for a DHCP mode because I figured when the new IP range is active, ESPs will just get new IPs there. But that doesn’t exist (it kinda makes sense it doesn’t).

What should I do?

Show your yaml to see how you configured it. Do the esp’s have fixed ip? If so, use the use_address setting to flash during the change (OTA will use use_address and not the new static IP to do the flash), after which the static IP should take hold when flash is done.

thank you for your reply. all of them have something like this at the beginning. I am not sure how up to standard this is because I have set them up more than 3 years ago, probably earlier.

esphome:
  name: entrance
  project:
    name: esphome.entrance
    version: "1.0"

esp32:
  board: lolin32
  framework:
    type: esp-idf
    version: recommended
    # Custom sdkconfig options
    sdkconfig_options:
      CONFIG_COMPILER_OPTIMIZATION_SIZE: y
    # Advanced tweaking options
    advanced:
      ignore_efuse_mac_crc: false

api:
  encryption:
    key: "xxxxxxxxxxxxxxxx"

ota:
  - platform: esphome
    password: "xxxxxxxxxxxxxxxxxxx"

wifi:
  networks:
    - ssid: "Mjolnir"
      password: "xxxxxxxxxxxxx"
      manual_ip:
        static_ip: 192.168.1.14
        gateway: 192.168.1.1
        subnet: 255.255.0.0
      priority: 1
    - ssid: "MjolnirGarden"
      password: "xxxxxxxxxxxxxxx"
      manual_ip:
        static_ip: 192.168.1.14
        gateway: 192.168.1.1
        subnet: 255.255.0.0
      priority: 0
  min_auth_mode: WPA2
  power_save_mode: none

# Enable logging
logger:
  level: INFO
  baud_rate: 0

# at some point there was an error with one of the updates and the solution was to comment the `ap`. so i have no emergency ap for them.

# Enable fallback hotspot (captive portal) in case wifi connection fails
#  ap:
#    ssid: "Entrance Fallback Hotspot"
#    password: "xxxxxxxxx"

#captive_portal:

If these are the old static ips then you change them to the new value. But if you do only that, OTA will fail because it will try to reach them at the new address to flash, but it isn’t there yet.

So you also need to add the use_address field with the old ip as per the documentation. OTA will connect to the address in use_address to flash. When flashed the ESP’s start using the new static IP (the esp’s themselves do not look at the use_address field, it is just for ESPHome).

When the ESP’s have sucessfully connected using the new static IP, then you need to remove the use_address field (or set it to the new ip too) so you can flash using the new IP.

What happens if the gateway is different though?

use_address only works if the gateway is the same for the old and new static ip. And they are talking about moving to a whole new subnet.

I think serial flashing is the only way to go in that case.

If you flash on the old network, it should not matter what you flash it to, should it? After flashing it will connect to a new network. Or will it rollback if it cannot immediately connect to the new IP? Is that what you are worried about?

I’m worried that they are changing from 192.168.1.x to something like 10.1.1.x

The use_address will need the old 192.168.1.1 gateway but the new config will have something like 10.1.1.1 as the gateway. e.g. this won’t work:

wifi:
  networks:
    - ssid: "Mjolnir"
      password: "xxxxxxxxxxxxx"
      manual_ip:
        use_address: 192.168.1.14  ### <- remove after flashing
        static_ip: 10.1.1.14
        gateway: 10.1.1.1
        subnet: 255.255.0.0
      priority: 1

If the gateways are the same then sure this will work:

Flash them once OTA like this:

wifi:
  networks:
    - ssid: "Mjolnir"
      password: "xxxxxxxxxxxxx"
      manual_ip:
        use_address: 192.168.1.14  ### <- remove after flashing once
        static_ip: # new ip address here, must be in 192.168.x.x
        gateway: 192.168.1.1
        subnet: 255.255.0.0
      priority: 1
    - ssid: "MjolnirGarden"
      password: "xxxxxxxxxxxxxxx"
      manual_ip:
        use_address: 192.168.1.14 ### <- remove after flashing once
        static_ip:  # new ip address here, must be in 192.168.x.x
        gateway: 192.168.1.1
        subnet: 255.255.0.0
      priority: 0
  min_auth_mode: WPA2
  power_save_mode: none

Then remove the two use_address lines and flash them again.

Maybe a workaround could be to define a third network with the new connection details and different SSID temporarily? It is a bit of a hack, but if you can prevent it from reaching the old networks by changing SSID after boot it will be forced to pick the new one. Then from there you can change it to the definitive yaml and restore the original SSID.

Or do one SSID at a time and temporarily disable the network you do not want it to use.

That’s a good idea. Though you wouldn’t need a third.

Just change one of the two existing SSIDs at a time. You wouldn’t even need use_address.

Oh wow! This exploded!

A little bit more detail:

I want to change from 192.168.1.x with 192.168.1.1 gateway to a less common 192.168.124.x with a /22 mask (to include 124-127 range) and the gateway 192.168.125.1.

From this discussion I don’t understand how to move over to the new gateway. It seems that all should be well with the ip change with a /16 mask until the gateway change. or did I misunderstand?

Can all your ESPs see both ā€œMjolnirā€ and ā€œMjolnirGardenā€ networks?

If so it will be very simple. Change one SSID to the new IP range at a time.

e.g.

Change your ā€œMjolnirā€ access point to use the new IP range.

Reboot all your ESPs so they connect to ā€œMjolnirGardenā€. ā€œMjolnirā€ will be inaccessible as the ESPs have old wifi config for this.

Flash all the ESPs with the new wifi config for ā€œMjolnirā€. They won’t yet be contactable on this new network but they will still be contactable via ā€œMjolnirGardenā€.

Once they reboot they can join to ā€œMjolnirā€.

Once they are all done. Change your ā€œMjolnirGardenā€ access point to the new range.

Reboot all your ESPs so they are definitely connected to ā€œMjolnirā€. ā€œMjolnirGardenā€ will be inaccessible as the ESPs have old wifi config for this.

Then flash all your ESPs again with the new wifi config for ā€œMjolnirGardenā€. They will be contactable via ā€œMjolnirā€.

If any of your ESPs can only see one SSID then those ESPs will have to be flashed serially.

Mjolnir is the network I have inside the house. Some ESPs are connected to that. MjolnirGarden is a network for the garden. I have added Mjolnir too just in case the garden network (for which I use two wifi powerline adapters) goes down.

You gave me an idea to use another AP with the old network and move like you said. I will give it a try when I find another home alone window!

Thank you all!

By default esphome does use DHCP so you should be fine doing just nothing and with the next renewal the nodes should get the new IP :raised_hands:

If you want to force the renewal you can also restart the nodes (often quickest solution is to flip some breakers in your distribution panel) :bulb:

When migrating the IP address range the simplest way is to run both ranges simultaneously on the same interface. Configure your router with a second IP and netmask. There should be no need to have multiple SSIDS.

I’d also recommend that rather than hard-coding static addresses in the ESPHome devices, it’s better to use fixed DHCP address assignments in the router if you need stable IPs - that makes this kind of migration so much easier.

static or non static if mdns is working you should be able to comment out the static IP and flash.

MDNS should give esphome the correct IP

wifi doesnt care about IP. If builder can access device via mdns it will flash. only after flash and reboot is there some possibilty builder will lose connection if mdns doesnt work. You may need to remove and readd to HA but it should not create any issue and all entities should remain.

in the end you should just need to disable the use address or static IP >> let dhcp take over address >> builder will find device by mdns and allow you to flash new wifi credentials.

static IP should be set at router to prevent this problem.

Just to suggest an alternative approach.

I’d re-configure esphome for DHCP, ideally combined with DHCP reservations matching the old static IPs and a relatively short DHCP lifetime. Once that’s all working smoothly, change the IP ranges/ DHCP reservations - either wait for the new DHCP requests to update your esphome clients or ā€˜encourage’ them by switching off the AP for a bit (so they need to re-establish the connection) or rebooting them. If you really want static IPs (instead of ā€˜just’ static DHCP reservations) again, that would be the final step.

I’m reading: I don’t trust that I can configure new IP addresses and it will work first time.

You have made a conscious decision to reconfigure your network. Your yaml includes static IP Addresses.

Write it down in a chart. Device, MAC address, old IP Address, new IP Address, DNS, WiFi SSID, fallback Access Point SSID, etc

Print it out and cross them off as you update them. One by one. Cut and paste can be used to prevent transcription fumbles.

Reconfigure your router last, the DHCP section being most important.

Restart everything and it should work together in glorious harmony…

Your fallback/failoverfor any device (I think this is the ā€˜third network’ concept some are suggesting) is the Access Point mode where it can’t connect to a network, so goes into Access Point mode, where you can connect directly to it and try again. A good idea is to make sure the SSID’S are unique so you can find them later. You shouldn’t need to break out your serial adapter to reflash - that is what that Access Point functionality is there for. I strongly recommend you allocate a password for this, especially once you recognise what a serious security loophole this can pose if your router becomes unavailable, even for short lengths of time.

The official ESPHome instructions seem to cover exactly your situation quite clearly, especially the section on Connecting to Multiple Networks see WiFi Component - ESPHome - Smart Home Made Simple

I also quote from there
ā€œIt’s recommended to provide a static IP for your node, as it can dramatically improve connection times.ā€

I’m a big fan of static IP addresses so I know where to expect to find a device on my network, no clashes, no surprises, so I plan it carefully.

Control, planning, not guesswork and hope.

Update: on reading again, seems you got most of it right, and those 6 errant devices should be able to be seen and fixed using the Access Point route. Then go back and systematically assign everything so it corresponds to that list you should meticulously maintain as you add/change/remove devices.

Further update: I see you commented out the Access Point in your yaml. In which case you will have to revert to your old network IP range, connect to those devices, and update them. Most routers support backup and restore of configurations, so this should be fairly painless. Don’t forget to go back and add the Access Point with passwords to all your other devices so you aren’t caught out again.

2 Likes