Use python to naively find an Arduino's IP address from another PC on the local network

Question:

I have a ESP8266 Nodemcu device running a local HTTP server. I followed the quick-start instructions here.

My goal is to have a large number of these devices running in sync. To do that, I wrote this script:

#!/usr/bin/env python
import time
import sys
import socket
import requests

def myFunction():
    #This is what I have right now...
    ipAddresses = ["192.168.1.43", "192.168.1.44"]

    #
    #Instead, I need to search the local network for all the arduinos [ESP8266s] and append their address to the array.
    #

    for address in ipAddresses:
        TurnOnLED(address)

def TurnOnLED(address):
    try:
        r = requests.post('http://' + address + '/LedON')
        r.close()
    except requests.exceptions.ConnectionError:
        pass

#Main
def Main():
    try:
        print("Press CTRL-C to stop.")
        while ON:
            myFunction()
            time.sleep(60)
    except KeyboardInterrupt:
        sys.exit(0)

if __name__ == "__main__":
    Main()

This works, and allows me to control all of my devices from my desktop PC. My difficulty is with finding each IP address dynamically. I considered assigning a static IP address, but I would like them to be retail-optimized, so I cannot guarantee any particular IP address being unused out-of-the-box.

For the same reason, I want to be able to install the same arduino code on all of them. This is what I mean by naive. I want my python script to find the IP address of each device over the local network without any [unique] ‘help’ from the devices themselves. I want to install the same code on each device, and have my script find them all without any additional set up.

My first attempt was using the socket python module and looking for every hostname that began with "ESP-" since those are the first four characters of the factory hostname on all the boards. My query consistently turned up nothing, though.

This answer here has some good information, but my solution runs on a Macintosh, and I will not have the full host name, only "ESP-".

Asked By: JeremiahDuane

||

Answers:

So, now that I know what are the constraints, and what is just what is in the tutorial, here are my 2 cents (keep in mind that I too, am just a hobbyist about everything that has "voltage". And not even a good one).

1st strategy : PC is server

So, if I assume that your devices are, for example, temperature sensors, and you want to frequently grab all the temperatures, then, one strategy could be that those devices all connect, every minute, to the server, report the temperature, and disconnect. For example, using a HTTPS request to do so.

So host the server on your PC, and have your devices behave as clients

# Example request from micropython
import urequests
rep = urequests.get(URL)
print(rep.text)
response.close()

2nd strategy : a third party is server

A variant of that strategy is to have a sort of central data repository, that acts as a server. So, I mean, your PC is not the server, nor any ESP, but another machine (which could be one ESP, a rasppi, or even a droplet or EC2 instance in the cloud, doesn’t matter. As long as you can host a backend on it).
So, ESP8266 are clients of that server. And so is your PC. So that server has to be able to answer to request "set value from client", and "get value for the PC".

The drawback of those first 2 strategies, is that they are ok when the devices are the one sending data. It fits less if they are (as in your led example, but I surmise that was just an example) the ones receiving mostly the data. Because then, you would have to wait for the ESP to connect to have it get the message "you need to switch on the led".

3rd strategy : central registry

Or you can have it both way. That is keep your current architecture. When your PC wants something from the ESP8266, it has to connect to them, that are servers, and send it request.
But, in parallel to that, ESP8266 also behave as clients to register themselves in a central directory, which could be on the PC, or on a 3rd party. The objective of that central directory is not to gather the data from the ESP8266. Just to gather a uptodate list of them. Each minute they, in parallel with their server activity, the ESP8266 send a message "I am alive" to this central dircetory. And then the PC (that could be, or not, hosting that central directory) just need to get all IP associated with a not too old "I am alive" message, to get a list of IP.

4th strategy : ARP

Once your PC is on, it could scan the network, using an ARP request, with scapy. Search for "scanning local network with scapy".
For example here is a tutorial

From there, you get a list of IP. Associated with MAC address. And now, you need to know which ones are the ESP8266. You can here also apply several ideas. For example, you may use the MAC address to find guess which one are the ESP8266. Or you may simply try a dummy request on all found IP, to check which one are the ESP8266 (using a specific API of the server code of the ESP8266 you wrote)

Or you may decide to host the server on each ESP8266 on a specific port, like 8123, so that you can quickly rule out devices whose port 8123 is not listening.

5th strategy : don’t reinvent the wheel

The best strategy is clearly a mix between my second and my third. Having a directory, and a 3rd party handling messages. But that is reinventing message brokers.

There is one well known middleware, fitted for ESP8266 (I mean, for IoT low profile devices), that is MQTT.

That needs some more tutorial reading and long trial and error on your behalf. You can start here for example. But that is just the 1st example I found on Google searching "MQTT ESP8266 micropython". There are zillions resources on that.

It may seem to be not the easiest way (compared to just copy and paste some code that list all the alive IP on a network). But in the long run, I you intend to have many ESP8266, so many of them that you can’t afford to assign them static IP and simply list their IP, you probably really need a message broker like that, a preferably, not one that your reinvent

Answered By: chrslg