Background
At my new $dayjob
, we’re undergoing a migration/refresh to Juniper Mist which will encompass over 13K APs when the dust settles. If you’re reading this, you already know that just performing a 1:1 swap for that many APs requires a lot of planning and resources. And depending on the size of your team, things may move faster or slower, or you may opt to contract out some of the work that’s required. Now, some organizations with large deployments choose to refresh portions of their network on a yearly cycle, let’s say 20% per year over 5 years. For us, that would have been a pretty manageable 2600 APs per year. However, given the variables listed below, we’re having to move fast (I mean like Jimmy Johns fast), but our team is small so we’re also having to pull in more resources, including external ones which can result in inconsistencies if left unchecked.
- Timeline – Our healthcare deployment which consists of approximately half of our total APs must be swapped by Sep 1st. The remaining University APs must be swapped by NLT Jan 2027 if not sooner
- New Wi-Fi vendor – Means new ways of doing things, from design to configuration to installation to monitoring. Almost everything is new in terms of process, documentation, etc which can slow things down as you work through the kinks
- Hired help – Having to leverage a number of different contractors just to get the APs installed due to the sheer number of them and the aggressive timeline. We have to onboard all contractors into our processes and expectations which includes showing them how to use the Mist installer app, how we want our APs installed and labeled, and then work to validate things are done correctly
More on how we’ve worked to automate the validation of our installs in a future blog post…
The problem
Like a lot of organizations, there’s some tech debt that has creeped in over time. Most of our plans with AP locations were kept in the vendor’s NMS and over time, they have become outdated. It’s also a bit tedious to try and export those plans from the NMS, especially in mass. Even then, after performing pre-swap walkthroughs, we’ve found that some of the APs weren’t installed where originally intended and in some cases, weren’t installed at all! My goal is to have an offline repository that is independent of whatever vendor we are using, that can be leveraged to identify undocumented changes over time and also be updated dynamically on the fly based on real-time information from the Mist dashboard.
Possible solutions
Now, maybe you are lucky enough to already have an accurate and up-to-date offline repository of all your buildings’ floorplans with AP locations marked on them. If you are, my hats off to you! Keep doing what you’re doing.
Or maybe you have all your floorplans and the accompanying AP locations located inside of your NMS which may or may not be tied to your current wireless vendor of choice. If this is the case, what happens if you one day decide to move away from that vendor? Can you export all of the floorplans with the AP locations identified? Is it easy? Can it be done programmatically if you have many buildings and/or many floors? And more importantly, have you tested it?
Lastly, maybe you are leveraging youre Wi-Fi design software to keep track of your floor plans and AP locations. I’m not as familiar with Ekahau these days, but I do know you can import/export to/from Hamina. What happens if the Hamina walrus up and decides to retire one day and Hamina goes away? I certainly hope that never happens, but we cannot predict the future. What if you or your company can no longer afford to license such a software?
I realize I’m not covering every single situation and that my solution may not apply or work for you… This was just something that as intermediate level coder, I wondered if it was possible to do and if it was, it could serve as a good backup solution to keeping track of our floor plans and more importantly, where and how they are located on those floor plans.
Leveraging automation
By leveraging the Mist API and a couple of Python modules (requests, pillow), I was able to write a script that for a given site does a few things that I will list below:
- Downloads any and all floor plans
- Downloads uploaded pictures for all APs inside the site
- Informs you if an AP hasn’t been placed on any map
- Records the height, map, mounting method, orientation, and x/y coordinates for each AP
- Based on the x,y coordinates, generates a new image of the floor plan with the AP locations identified
- Creates a CSV that records all of those values in case you ever need them in the future perhaps for redesigns or placing APs back on a map in Mist if they’ve been accidentally moved or removed.
Armed with this info, you could do that either manually or programattically using the same Mist API that was used to obtain it.
Here’s a sample of what it looks like…






As you can see, the screenshots are essentially spitting images of each other, except now I have an offline version of all of the original maps, maps with AP locations, and within a single that done for my by running script and it took less than 5 mins to run which could probably be sped up by adding some concurrency into the mix.
Lessons learned
Here are some lessons learned after continuing to build the script and work through different sites…
- Use requests sessions whenever possible to make downloads of maps and pictures as efficient as possible. This limits the number of new connections that need to be opened
- Check to see if the files already exist before downloading them. This saves bandwidth and a little time. Thinking about scale here
- Depending on the image, you may have to convert it to “RGB” mode in order to get colors to appear
- Find a good font that is legible, most likely the bold version of the font you want to use. Google fonts is a good starting point.
Next steps
At my former employer, they put a legend on every map created and I love that concept. The legend includes things like the last time the map was updated, the models and number of APs installed, and different models or APs serving different purposes are color coded. (I’d love to see Hamina add this capability to their reporting)
While my script is still a work in progress, I’d like to take this same concept and use pillow to generate a legend that lists the number of APs installed, the models of those APs, and also indicate what each color means. For example, an indoor AP is green, an outdoor AP is red, a BT11 is blue.
Additionally, as I alluded to before, I want to write another script that is capable of doing the reverse by taking the information in the CSV and placing an AP back on the map if it ever goes missing, especially if this happens at scale. For instance, what if your floors for the site get deleted or the maps replaced.
Final thoughts and feedback
While this post wasn’t meant to be a how-to with step by step instructions on how to accomplish this, it was meant to provoke thought and discussion. I was also genuinely curious on whether something like this was even possible and come to find out, it is. At this point, there’s still some work to be done to polish it all up and I need to figure out if this method is the most optimal way of backing up and storing our floor plans.
But what about you? Is this something that would be useful to you? Are you handling this type of problem in a different way? How can I make this better? I’d love to engage with you on LinkedIn or X, hit me up! What about you? Is this something that would be useful to you? Are you handling this type of problem in a different way? How can I make this better? I’d love to engage with you on LinkedIn or X, hit me up!
Update #1
By request (thank you Richard Herwig), I cleaned up the script and placed it on my GitHub here: https://github.com/kmillerusaf/mist_backup_maps
I tested the process on my machine to make sure everything worked and it does, as long as the instructions are followed. If doesn’t work for you, feel free to reach out to me on LinkedIn, Slack, or X.
My friend Josh Schmelzle also recommended that I add a video to showcase the script running so I added that to the media section above.
If you have ideas or want to collaborate on making this better, find me!