mirror of
https://github.com/liamcottle/reticulum-meshchat.git
synced 2026-04-28 00:20:48 +00:00
collect rssi, snr and link quality for announces and add snr to announces ui
This commit is contained in:
parent
7ea306003e
commit
5a1bd889b7
4 changed files with 52 additions and 13 deletions
13
database.py
13
database.py
|
|
@ -3,7 +3,7 @@ from datetime import datetime, timezone
|
|||
from peewee import *
|
||||
from playhouse.migrate import migrate as migrate_database, SqliteMigrator
|
||||
|
||||
latest_version = 4 # increment each time new database migrations are added
|
||||
latest_version = 5 # increment each time new database migrations are added
|
||||
database = DatabaseProxy() # use a proxy object, as we will init real db client inside meshchat.py
|
||||
migrator = SqliteMigrator(database)
|
||||
|
||||
|
|
@ -32,6 +32,14 @@ def migrate(current_version):
|
|||
migrator.add_column("lxmf_messages", 'method', LxmfMessage.method),
|
||||
)
|
||||
|
||||
# migrate to version 5
|
||||
if current_version < 5:
|
||||
migrate_database(
|
||||
migrator.add_column("announces", 'rssi', Announce.rssi),
|
||||
migrator.add_column("announces", 'snr', Announce.snr),
|
||||
migrator.add_column("announces", 'quality', Announce.quality),
|
||||
)
|
||||
|
||||
return latest_version
|
||||
|
||||
|
||||
|
|
@ -61,6 +69,9 @@ class Announce(BaseModel):
|
|||
identity_hash = CharField(index=True) # identity hash that announced the destination
|
||||
identity_public_key = CharField() # base64 encoded public key, incase we want to recreate the identity manually
|
||||
app_data = TextField(null=True) # base64 encoded app data bytes
|
||||
rssi = IntegerField(null=True)
|
||||
snr = FloatField(null=True)
|
||||
quality = FloatField(null=True)
|
||||
|
||||
created_at = DateTimeField(default=lambda: datetime.now(timezone.utc))
|
||||
updated_at = DateTimeField(default=lambda: datetime.now(timezone.utc))
|
||||
|
|
|
|||
33
meshchat.py
33
meshchat.py
|
|
@ -2019,6 +2019,9 @@ class ReticulumMeshChat:
|
|||
"background_colour": db_lxmf_user_icon.background_colour,
|
||||
}
|
||||
|
||||
# get current hops away
|
||||
hops = RNS.Transport.hops_to(bytes.fromhex(announce.destination_hash))
|
||||
|
||||
return {
|
||||
"id": announce.id,
|
||||
"destination_hash": announce.destination_hash,
|
||||
|
|
@ -2026,6 +2029,10 @@ class ReticulumMeshChat:
|
|||
"identity_hash": announce.identity_hash,
|
||||
"identity_public_key": announce.identity_public_key,
|
||||
"app_data": announce.app_data,
|
||||
"hops": hops,
|
||||
"rssi": announce.rssi,
|
||||
"snr": announce.snr,
|
||||
"quality": announce.quality,
|
||||
"display_name": display_name,
|
||||
"custom_display_name": self.get_custom_destination_display_name(announce.destination_hash),
|
||||
"lxmf_user_icon": lxmf_user_icon,
|
||||
|
|
@ -2186,7 +2193,12 @@ class ReticulumMeshChat:
|
|||
query.execute()
|
||||
|
||||
# upserts the provided announce to the database
|
||||
def db_upsert_announce(self, identity: RNS.Identity, destination_hash: bytes, aspect: str, app_data: bytes):
|
||||
def db_upsert_announce(self, identity: RNS.Identity, destination_hash: bytes, aspect: str, app_data: bytes, announce_packet_hash: bytes):
|
||||
|
||||
# get rssi, snr and signal quality if available
|
||||
rssi = self.reticulum.get_packet_rssi(announce_packet_hash)
|
||||
snr = self.reticulum.get_packet_snr(announce_packet_hash)
|
||||
quality = self.reticulum.get_packet_q(announce_packet_hash)
|
||||
|
||||
# prepare data to insert or update
|
||||
data = {
|
||||
|
|
@ -2194,6 +2206,9 @@ class ReticulumMeshChat:
|
|||
"aspect": aspect,
|
||||
"identity_hash": identity.hash.hex(),
|
||||
"identity_public_key": base64.b64encode(identity.get_public_key()).decode("utf-8"),
|
||||
"rssi": rssi,
|
||||
"snr": snr,
|
||||
"quality": quality,
|
||||
"updated_at": datetime.now(timezone.utc),
|
||||
}
|
||||
|
||||
|
|
@ -2377,13 +2392,13 @@ class ReticulumMeshChat:
|
|||
|
||||
# handle an announce received from reticulum, for an audio call address
|
||||
# NOTE: cant be async, as Reticulum doesn't await it
|
||||
def on_audio_call_announce_received(self, aspect, destination_hash, announced_identity, app_data):
|
||||
def on_audio_call_announce_received(self, aspect, destination_hash, announced_identity, app_data, announce_packet_hash):
|
||||
|
||||
# log received announce
|
||||
print("Received an announce from " + RNS.prettyhexrep(destination_hash) + " for [call.audio]")
|
||||
|
||||
# upsert announce to database
|
||||
self.db_upsert_announce(announced_identity, destination_hash, aspect, app_data)
|
||||
self.db_upsert_announce(announced_identity, destination_hash, aspect, app_data, announce_packet_hash)
|
||||
|
||||
# find announce from database
|
||||
announce = database.Announce.get_or_none(database.Announce.destination_hash == destination_hash.hex())
|
||||
|
|
@ -2398,13 +2413,13 @@ class ReticulumMeshChat:
|
|||
|
||||
# handle an announce received from reticulum, for an lxmf address
|
||||
# NOTE: cant be async, as Reticulum doesn't await it
|
||||
def on_lxmf_announce_received(self, aspect, destination_hash, announced_identity, app_data):
|
||||
def on_lxmf_announce_received(self, aspect, destination_hash, announced_identity, app_data, announce_packet_hash):
|
||||
|
||||
# log received announce
|
||||
print("Received an announce from " + RNS.prettyhexrep(destination_hash) + " for [lxmf.delivery]")
|
||||
|
||||
# upsert announce to database
|
||||
self.db_upsert_announce(announced_identity, destination_hash, aspect, app_data)
|
||||
self.db_upsert_announce(announced_identity, destination_hash, aspect, app_data, announce_packet_hash)
|
||||
|
||||
# find announce from database
|
||||
announce = database.Announce.get_or_none(database.Announce.destination_hash == destination_hash.hex())
|
||||
|
|
@ -2423,13 +2438,13 @@ class ReticulumMeshChat:
|
|||
|
||||
# handle an announce received from reticulum, for an lxmf propagation node address
|
||||
# NOTE: cant be async, as Reticulum doesn't await it
|
||||
def on_lxmf_propagation_announce_received(self, aspect, destination_hash, announced_identity, app_data):
|
||||
def on_lxmf_propagation_announce_received(self, aspect, destination_hash, announced_identity, app_data, announce_packet_hash):
|
||||
|
||||
# log received announce
|
||||
print("Received an announce from " + RNS.prettyhexrep(destination_hash) + " for [lxmf.propagation]")
|
||||
|
||||
# upsert announce to database
|
||||
self.db_upsert_announce(announced_identity, destination_hash, aspect, app_data)
|
||||
self.db_upsert_announce(announced_identity, destination_hash, aspect, app_data, announce_packet_hash)
|
||||
|
||||
# find announce from database
|
||||
announce = database.Announce.get_or_none(database.Announce.destination_hash == destination_hash.hex())
|
||||
|
|
@ -2507,13 +2522,13 @@ class ReticulumMeshChat:
|
|||
|
||||
# handle an announce received from reticulum, for a nomadnet node
|
||||
# NOTE: cant be async, as Reticulum doesn't await it
|
||||
def on_nomadnet_node_announce_received(self, aspect, destination_hash, announced_identity, app_data):
|
||||
def on_nomadnet_node_announce_received(self, aspect, destination_hash, announced_identity, app_data, announce_packet_hash):
|
||||
|
||||
# log received announce
|
||||
print("Received an announce from " + RNS.prettyhexrep(destination_hash) + " for [nomadnetwork.node]")
|
||||
|
||||
# upsert announce to database
|
||||
self.db_upsert_announce(announced_identity, destination_hash, aspect, app_data)
|
||||
self.db_upsert_announce(announced_identity, destination_hash, aspect, app_data, announce_packet_hash)
|
||||
|
||||
# find announce from database
|
||||
announce = database.Announce.get_or_none(database.Announce.destination_hash == destination_hash.hex())
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ class AnnounceHandler:
|
|||
self.received_announce_callback = received_announce_callback
|
||||
|
||||
# we will just pass the received announce back to the provided callback
|
||||
def received_announce(self, destination_hash, announced_identity, app_data):
|
||||
def received_announce(self, destination_hash, announced_identity, app_data, announce_packet_hash):
|
||||
try:
|
||||
# handle received announce
|
||||
self.received_announce_callback(self.aspect_filter, destination_hash, announced_identity, app_data)
|
||||
self.received_announce_callback(self.aspect_filter, destination_hash, announced_identity, app_data, announce_packet_hash)
|
||||
except:
|
||||
# ignore failure to handle received announce
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -90,7 +90,20 @@
|
|||
</div>
|
||||
<div>
|
||||
<div class="text-gray-900 dark:text-gray-100">{{ peer.custom_display_name ?? peer.display_name }}</div>
|
||||
<div class="text-gray-500 dark:text-gray-400 text-sm">{{ formatTimeAgo(peer.updated_at) }}</div>
|
||||
<div class="flex space-x-1 text-gray-500 dark:text-gray-400 text-sm">
|
||||
|
||||
<!-- time ago -->
|
||||
<span class="flex my-auto space-x-1">
|
||||
{{ formatTimeAgo(peer.updated_at) }}
|
||||
</span>
|
||||
|
||||
<!-- snr (only shown for peers directly heard on rf) -->
|
||||
<span v-if="peer.snr != null && (peer.hops === 0 || peer.hops === 1)" class="flex my-auto space-x-1">
|
||||
<span>•</span>
|
||||
<span>SNR {{ peer.snr }}dB</span>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue