From b1c3cc767c22e21900cc9839a4d21465eecd7fec Mon Sep 17 00:00:00 2001 From: liamcottle Date: Sun, 15 Dec 2024 20:14:26 +1300 Subject: [PATCH 1/5] add bleak as python dependency for rnode ble connections --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 84ce612..624380a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ aiohttp>=3.9.5 +bleak>=0.22.3 cx_freeze>=7.0.0 lxmf>=0.5.8 peewee>=3.17.3 From 7c5235845a42f9a2c41cc6d3e0ec8f9bc38b1a98 Mon Sep 17 00:00:00 2001 From: liamcottle Date: Sun, 15 Dec 2024 20:51:52 +1300 Subject: [PATCH 2/5] add api to scan for ble devices --- meshchat.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/meshchat.py b/meshchat.py index d8e31f0..88e27f1 100644 --- a/meshchat.py +++ b/meshchat.py @@ -13,11 +13,13 @@ import RNS import RNS.vendor.umsgpack as msgpack import LXMF from LXMF import LXMRouter +from RNS.Interfaces.RNodeInterface import BLEConnection from aiohttp import web, WSMessage, WSMsgType, WSCloseCode import asyncio import base64 import webbrowser +from bleak import BleakScanner from peewee import SqliteDatabase from serial.tools import list_ports @@ -317,6 +319,45 @@ class ReticulumMeshChat: "comports": comports, }) + # scan for rnodes available via ble + @routes.get("/api/v1/rnodes/ble-scan") + async def index(request): + + # determine how long we should scan for + scan_duration_seconds = int(request.query.get("scan_duration_seconds", 3)) + + # discover ble devices + ble_scan_results = await BleakScanner.discover( + timeout=scan_duration_seconds, + return_adv=True, + cb=dict(use_bdaddr=True), + service_uuids=[ + BLEConnection.UART_SERVICE_UUID, + ], + ) + + # format scan results + rnodes = [] + for ble_address in ble_scan_results: + + # get device and advertisement data from scan result + device, advertisement_data = ble_scan_results[ble_address] + + # skip this result if advertisement data is unavailable + if advertisement_data is None: + continue + + rnodes.append({ + "name": device.name, + "local_name": advertisement_data.local_name, + "ble_address": device.address, + "port": "ble://" + advertisement_data.local_name, + }) + + return web.json_response({ + "rnodes": rnodes, + }) + # fetch reticulum interfaces @routes.get("/api/v1/reticulum/interfaces") async def index(request): From 4970d5088f5faef41d46c7d18c3dde3f09be9076 Mon Sep 17 00:00:00 2001 From: liamcottle Date: Sun, 15 Dec 2024 20:59:52 +1300 Subject: [PATCH 3/5] discover ble rnodes when adding or editing an interface --- .../interfaces/AddInterfacePage.vue | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/frontend/components/interfaces/AddInterfacePage.vue b/src/frontend/components/interfaces/AddInterfacePage.vue index 51afc03..ef1ec91 100644 --- a/src/frontend/components/interfaces/AddInterfacePage.vue +++ b/src/frontend/components/interfaces/AddInterfacePage.vue @@ -118,7 +118,12 @@ +
+ Discovering Bluetooth RNodes... + Discover Bluetooth RNodes +
@@ -184,6 +189,9 @@ export default { config: null, comports: [], + rnodes: [], + + isLoadingRnodes: false, newInterfaceName: null, newInterfaceType: null, @@ -243,6 +251,7 @@ export default { this.getConfig(); this.loadComports(); + this.loadRnodes(); // check if we are editing an interface const interfaceName = this.$route.query.interface_name; @@ -276,9 +285,30 @@ export default { const response = await window.axios.get(`/api/v1/comports`); this.comports = response.data.comports; } catch(e) { - // do nothing if failed to load interfaces + // do nothing if failed to load comports } }, + async loadRnodes() { + + // do nothing if already loading + if(this.isLoadingRnodes){ + return; + } + + // show loading + this.isLoadingRnodes = true; + + try { + const response = await window.axios.get(`/api/v1/rnodes/ble-scan`); + this.rnodes = response.data.rnodes; + } catch(e) { + // do nothing if failed to load rnodes + } finally { + // no longer loading + this.isLoadingRnodes = false; + } + + }, async loadInterfaceToEdit(interfaceName) { try { From 3aaebfccbad9f3d83b25b4557125ce5cf1bb18c7 Mon Sep 17 00:00:00 2001 From: liamcottle Date: Sun, 15 Dec 2024 21:08:55 +1300 Subject: [PATCH 4/5] add section titles to interface port list --- src/frontend/components/interfaces/AddInterfacePage.vue | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/frontend/components/interfaces/AddInterfacePage.vue b/src/frontend/components/interfaces/AddInterfacePage.vue index ef1ec91..fe516a9 100644 --- a/src/frontend/components/interfaces/AddInterfacePage.vue +++ b/src/frontend/components/interfaces/AddInterfacePage.vue @@ -117,7 +117,9 @@
From 6100a3bdff32c454a98c1c8e9d48c83ea4fb7a9a Mon Sep 17 00:00:00 2001 From: liamcottle Date: Sun, 15 Dec 2024 21:09:53 +1300 Subject: [PATCH 5/5] show ble address --- src/frontend/components/interfaces/AddInterfacePage.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/components/interfaces/AddInterfacePage.vue b/src/frontend/components/interfaces/AddInterfacePage.vue index fe516a9..db6f6e5 100644 --- a/src/frontend/components/interfaces/AddInterfacePage.vue +++ b/src/frontend/components/interfaces/AddInterfacePage.vue @@ -120,7 +120,7 @@ - +
Discovering Bluetooth RNodes...