“These ARE the devices you are looking for” – a MAC based identifier in Python, Micropython and C++

TLDR: Code for MAC address in (Micro)Python and C++ for D1 Mini, Raspberry devices and NodeMCU.

I was looking for a unique static identifier to handle my IoT devices without baking the mqtt publish topics, name and location into the code. The code on identical devices should be the same, the the individual configuration should be pulled from the mqtt server. The devices should be kept as simple and dumb as possible and get their data from a central source. For simplicity I wanted to use the same mqtt server they also will be publishing to and created sustained topics with the required settings saved in a JSON object. As Node-Red was already in use, this proofed to be very simple and comfortable. This way the devices are interchangeable and replacable without having to change the code and flash them for specific locations.
The devices will still need the IP of the mqtt broker, the topic prefix where the settings will be stored and the credentials of the WiFi.

Below you find the code for MicroPython, Python and C++ as I use a mixture of devices like D1 mini, Raspberry Pi 4, Raspberry Pi Zero, Raspberry Pico W and NodeMCU.

# https://docs.micropython.org/en/latest/library/network.WLAN.html
# https://docs.micropython.org/en/latest/library/binascii.html

import ubinascii
import network

wlan = network.WLAN(network.STA_IF) # create a WiFi client network

print(ubinascii.hexlify(wlan.config('mac'), ":").decode().upper())
# https://www.tutorialspoint.com/extracting-mac-address-using-python

import uuid

# after each 2 digits, join elements of getnode().
print (':'.join(['{:02x}'.format((uuid.getnode() >> elements) & 0xff).upper()
for elements in range(0,2*6,2)][::-1]))

When using the Python code in a script started at boot by cron uuid.getnode() can’t find the mac address and returns a random uuid. The problem did not occur when the system was running and the network interface already up. As a workaround I used a constant like “PIZERO_01” as id in the microcontroller and the same in Node-RED to assign it further.
You could also do some magic with the module subprocess.check_output() and parse the output of ifconfig or use another identifier lie this one (https://stackoverflow.com/questions/36235807/fixed-identifier-for-a-machine-uuid-getnode): subprocess.check_output([‘cat’, ‘/var/lib/dbus/machine-id’]).decode(‘utf-8’).
For now I stay with the workaround and will update this post with any changes.

# MAC Address from Wifi module 
# https://www.arduino.cc/reference/en/libraries/wifi/wifi.macaddress/

#include <WiFi.h>

println(String(WiFi.macAddress()))

Similar Posts

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.