work on ui
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
venv
|
venv
|
||||||
|
*.pyc
|
||||||
@@ -1,18 +1,21 @@
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
from bleak import BLEDevice, BleakScanner
|
from bleak import BLEDevice, BleakScanner, BleakClient
|
||||||
|
|
||||||
NODE_BLUETOOTH_SERVICE_UUID = "E1898FF7-5063-4441-a6eb-526073B00001"
|
NODE_BLUETOOTH_SERVICE_UUID = "E1898FF7-5063-4441-a6eb-526073B00001"
|
||||||
|
|
||||||
|
|
||||||
class MeshNode:
|
class MeshNode:
|
||||||
def __init__(self, ble_device: BLEDevice):
|
def __init__(self, client: BleakClient):
|
||||||
self.ble_device = ble_device
|
self.client = client
|
||||||
|
|
||||||
async def discover():
|
async def discover():
|
||||||
"""Find a mesh node via Bluetooth
|
"""Find a mesh node via Bluetooth
|
||||||
"""
|
"""
|
||||||
devices = await BleakScanner(service_uuids=[NODE_BLUETOOTH_SERVICE_UUID], scanning_mode="pasive")
|
devices = await BleakScanner.discover(service_uuids=[NODE_BLUETOOTH_SERVICE_UUID], timeout=5)
|
||||||
|
|
||||||
# no device was found
|
# no device was found
|
||||||
if len(devices) == 0:
|
if len(devices) == 0:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
device = await BleakScanner.find_device_by_address(devices[0].address, timeout=5)
|
||||||
|
return MeshNode(BleakClient(device))
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
from api.node import MeshNode
|
from api.node import MeshNode
|
||||||
|
from ui.app import Hive
|
||||||
|
|
||||||
|
|
||||||
print(MeshNode.discover())
|
if __name__ == "__main__":
|
||||||
|
app = Hive()
|
||||||
|
app.run()
|
||||||
11
desktop_app/ui/app.py
Normal file
11
desktop_app/ui/app.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from textual.app import App, ComposeResult
|
||||||
|
from textual.widgets import Header, Footer
|
||||||
|
from ui.screens.pair_screen import PairScreen
|
||||||
|
|
||||||
|
|
||||||
|
class Hive(App):
|
||||||
|
theme = "rose-pine"
|
||||||
|
ENABLE_COMMAND_PALETTE = False
|
||||||
|
|
||||||
|
def on_ready(self):
|
||||||
|
self.push_screen(PairScreen())
|
||||||
7
desktop_app/ui/assets/banner.txt
Normal file
7
desktop_app/ui/assets/banner.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
_
|
||||||
|
| |
|
||||||
|
_ __ ___ ___ ___| |__
|
||||||
|
| '_ ` _ \ / _ \/ __| '_ \
|
||||||
|
| | | | | | __/\__ \ | | |
|
||||||
|
|_| |_| |_|\___||___/_| |_|
|
||||||
39
desktop_app/ui/assets/pair_screen.tcss
Normal file
39
desktop_app/ui/assets/pair_screen.tcss
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
PairScreen {
|
||||||
|
align: center middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
EffectLabel {
|
||||||
|
min-width: 50;
|
||||||
|
text-align: center;
|
||||||
|
text-style: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#middle {
|
||||||
|
border: $success ascii;
|
||||||
|
width: 50;
|
||||||
|
height: 28;
|
||||||
|
|
||||||
|
padding: 0 1 1 1;
|
||||||
|
|
||||||
|
Static {
|
||||||
|
min-width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataTable {
|
||||||
|
margin-top: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadingIndicator {
|
||||||
|
height: 1;
|
||||||
|
margin-top: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataTable {
|
||||||
|
height: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
margin: 2 0 0 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
32
desktop_app/ui/screens/pair_screen.py
Normal file
32
desktop_app/ui/screens/pair_screen.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
from textual.screen import Screen
|
||||||
|
from textual.containers import VerticalScroll, Vertical
|
||||||
|
from textual.widgets import Static, Button, LoadingIndicator, DataTable
|
||||||
|
from textualeffects.widgets import EffectLabel
|
||||||
|
|
||||||
|
|
||||||
|
class PairScreen(Screen):
|
||||||
|
CSS_PATH = "../assets/pair_screen.tcss"
|
||||||
|
|
||||||
|
def compose(self):
|
||||||
|
|
||||||
|
with Vertical(id="middle") as center_window:
|
||||||
|
center_window.border_title = "Pair a Node"
|
||||||
|
|
||||||
|
with open("ui/assets/banner.txt", "r") as f:
|
||||||
|
yield EffectLabel(f.read(), effect="Print")
|
||||||
|
|
||||||
|
yield Static("Make sure your mesh network node is powered and ready to pair. When you're ready, click the \"Pair\" button to connect to the mesh!")
|
||||||
|
|
||||||
|
table = DataTable()
|
||||||
|
table.add_columns("[b]Address", "RSSI")
|
||||||
|
yield table
|
||||||
|
|
||||||
|
table.add_row("hi", "[green][/] -34 dBm")
|
||||||
|
table.add_row("hi", "[green][/] -52 dBm")
|
||||||
|
table.add_row("hi", "[yellow][/] -64 dBm")
|
||||||
|
table.add_row("hi", "[red][/] -98 dBm")
|
||||||
|
table.add_row("hi", "[red][/] -101 dBm")
|
||||||
|
|
||||||
|
yield LoadingIndicator()
|
||||||
|
|
||||||
|
yield Button("Pair", disabled=True, variant="success", id="pair-btn")
|
||||||
Reference in New Issue
Block a user