Closed AmirHmZz closed 1 year ago
The ESPNow.peers_table
is a python dict, which doesn't have an intrinsic notion of order. Since 3.7, python guarantees that insertion order is preserved in dictionaries (eg. when calling dict.items()
), but I don't think that micropython makes such guarantees.
So, the peers_table
dict is indexed by peer MAC address and the values are a list: [rssi, timestamp]
. Only the very latest rssi and timestamp for each peer is saved - ie. each new message from a peer overwrites the [rssi, timestamp]
values.
If you have a specific use case that is not well-supported by this mechanism, let me know and I'll look at supporting that in future versions.
I envisaged several possible modes for using the rssi values:
(NOTE: the peers_table dict is also handy for monitoring when you last heard from a peer as it includes the timestamp for the last received message.)
def rssi_check(e, period):
now = time.ticks_ms()
for peer, (rssi, rssi_ms) in e.peers_table.items():
if time.ticks_diff(now, rssi_ms) < period and rssi < rssi_threshold:
print(f"Warning: Signal strength ({rssi}) is below threshold for peer {peer}.")
then call rssi_check(e, period)
every period milliseconds from your app loop (or from a periodic async task). You would read the actual messages in some other part of your app workflow.
for peer, msg in e.irecv():
rssi, rssi_ms = e.peers_table[peer]
# process message
...
# process rssi
if rssi < rssi_threshold:
print(f"Warning: Signal strength ({rssi}) is below threshold for peer {peer}.")
If you want to store and monitor changes in rssi values over time (eg. graph changes over time or analyse movements within a network), you need to store the rssi values into some other data structure.
@glenn20 Sorry for the delay. Do you have any statistics about how much RAM does peers_table
takes? Does peers_table
has any size limitation? There's also another recommendation: peers_table
name is not much suitable as long as it contains broadcast message senders too.
I haven't measured it precisely, but it should be about (1 mp_obj_str_t object + 6 bytes + 1 mp_obj_list_t + 2 x mp_obj_t = 16 + 6 + 16 + 8 = 46 bytes) per entry in the dict and there is one entry for each peer from whom we have received a message (remember, it only stores rssi for the last message received from each peer). The use of the peers table also saves some memory elsewhere because recv() returns a reference to the bytes object containing the MAC address in the dict keys instead of allocating a new MAC address bytes object for each packet received from the peer.
@AmirHmZz Regarding the name, I'm very open to suggestions. It is a table of data (rssi and timestamp of last received message) about all the peers from whom we have received a message.
If you have a specific use case that is not well-supported by this mechanism, let me know and I'll look at supporting that in future versions.
I use peers_table
in order to find nearby devices. I've developed a MESH network on top of ESP-NOW
and each device sends something like ping messages to broadcast address. So each device finds nearby devices by iterating over peers_table
and filtering them by two parameters:
RSSI
>= _MIN_RSSILIMITLatest message timestamp
>= time.time()
- _PINGSTIMEOUTWhen I opened this issue, I needed peers_table
to be sorted by RSSI. But after that I've decided to change my algorithm and after you described other use cases of peers_table
, I think it's one of the best choices for its implementation.
The reason that I insist on renaming peers_table
is not only peers are included in that table. I mean device A
will be found in device B
's peers_table
if device A
sends a message to broadcast MAC address even If device B
has not added device A
as a peer. What about renaming it to table
? Or maybe nopeers_table
(Inspired by NoSQL
, just kiddin)! Anyway, I'll keep thinking about it to suggest better names and I will share them with you.
I think it's better to update documentation and mention that broadcast message senders are also included in peers_table
. I remember that I've done a test to discover this ability because I needed it In my project.
I think it's better to update documentation and mention that broadcast message senders are also included in
peers_table
. I remember that I've done a test to discover this ability because I needed it In my project.
Ah - I get where the ambiguity is now :). I think of a peer as any ESP-NOW capable device operating on the same channel (ie. any device which can send me a message), rather than just those that we have registered with add_peer()
(which I think of as "add the peer to the list of peers to whom we will send messages", rather than "make this device a new peer"). By my interpretation, the docs are pretty clear, but I see that peer
is not a well defined term (the Espressif API docs are not explicit on this either). According to my implicit definition, the name makes sense, but not according to yours. I'll look at clarifying that in the docs.
My feature request comes with two questions:
ESPNOW.peers_table
records sorted by any parameter like latest message timestamp or rssi?