checking a value across lots of Constants

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
User avatar
philwilkinson40
Posts: 63
Joined: Tue Nov 14, 2017 3:11 am
Location: Perth, Australia

checking a value across lots of Constants

Post by philwilkinson40 » Sat May 22, 2021 11:55 am

I am trying to solve a problem, which probably has a very simple answer.

The use case is a set of remote microcontrollers sending data to a central 'broker' microcontroller using the excellent ESP-Now module written by @Glenn20.

Each remote microcontroller and the broker contain a config file containing lots of Constants that define the sensor and actuator types by IPSO code. This is a very small subset:

Code: Select all

TEMP_SENSOR = 3303
HUMIDITY_SENSOR = 3304
ACCELEROMETER_SENSOR = 3313
BAROMETER_SENSOR = 3315
VOLTAGE_SENSOR = 3316
CURRENT_SENSOR = 3317
ALTITUDE_SENSOR = 3321
BUZZER_ACTUATOR = 3338
LIGHT_ACTUATOR = 3311
ILLUMINANCE_SENSOR = 3301
PRESENCE_SENSOR = 3302
Each remote microcontroller sends a small packet of data periodically to the central broker. Due to size constraints and efficiency the IPSO and associated sensor data is sequentially combined using ustruct.pack. Note that the message is limited to a string or byte-string less than 250 bytes

Code: Select all

from esp import espnow

# A WLAN interface must be active to send()/recv()
w0 = network.WLAN(network.STA_IF)
w0.active(True)

e = espnow.ESPNow()
e.init()
peer = config.broker   # MAC address of broker's wifi interface
e.add_peer(peer)

#ESP-now publisher
message = (ustruct.pack('IIIIII',config.TEMP_SENSOR, temp_data, config.HUMIDITY_SENSOR, humidity_data, config.VOLTAGE_SENSOR, battery_data))
e.send(peer, message, True)
After the broker unpacks the payload I would then like the broker to efficiently look up which IPSO data type has being sent.
Typically, I would do this sort of thing with enumerate, which is not available in Micropython.
Is there a way to quickly search for which constant has the value without putting all the constants in a list and iterating across it?

I assume you will have realised by now I am not a programmer so I apologise in advance if this question is nonsense.

SpotlightKid
Posts: 463
Joined: Wed Apr 08, 2015 5:19 am

Re: checking a value across lots of Constants

Post by SpotlightKid » Sat May 22, 2021 1:39 pm

It depends a bit on what you want to do when you have matched a constant, but usually in Python you'd have a dictionary mapping constants as keys to functions as values:

Code: Select all

COMMANDS = {
    _CMD_WRITE: do_write,
    _CMD_READ: do_read,
    _CMD_DELETE: do_delete,
} # etc.

cmd = read_command()
func = COMMANDS.get(cmd)

if func:
    func(*args)
else:
    raise ValueError("Unknown command")

User avatar
philwilkinson40
Posts: 63
Joined: Tue Nov 14, 2017 3:11 am
Location: Perth, Australia

Re: checking a value across lots of Constants

Post by philwilkinson40 » Sun May 23, 2021 5:00 am

Thanks for responding @Spotlightkid

I had hoped to try and keep the config file independent of the functions and also wanted to avoid repeating the Constants within a list or dict.
However, perhaps I can't !

so I will progress with your approach and create a dict with keys corresponding with the Constants and values that take the subsequent binary object and do something with it (analyse it, store it in a file etc).

thanks again for the help.

johanson
Posts: 8
Joined: Sat May 22, 2021 1:04 pm

Re: checking a value across lots of Constants

Post by johanson » Tue May 25, 2021 7:08 pm

Typically, I would do this sort of thing with enumerate, which is not available in Micropython
Enumerate is a part of MicroPython, maybe the typical way you mention is actually possible.

Post Reply