Prototype cleanup 2

This commit is contained in:
Agie Ashwood 2024-11-26 11:34:29 -07:00
parent 46a9cc3ee9
commit bda89ca795
5 changed files with 55 additions and 39 deletions

View File

@ -266,17 +266,17 @@ PierMesh has two main events loops to learn about: the TUI and the service.
## TUI ## TUI
[🔗 Docs](https://git.utopic.work/PierMesh/piermesh/src/branch/main/docs/ui.md) [🔗 Docs](https://git.utopic.work/PierMesh/piermesh/src/branch/main/docs/tlog.md)
[🔗 Source](https://git.utopic.work/PierMesh/piermesh/src/branch/main/src/ui.py) [🔗 Source](https://git.utopic.work/PierMesh/piermesh/src/branch/main/src/tlog.py)
The TUI is provided via [Textual's](https://textual.textualize.io/) library. It's a relatively simple application that gives us a quick overview of system statistics in the way of memory and cpu usage as well as scrollable logs. You can toggle full screen logs with f and close the TUI and service with q. The TUI is provided via [curses](https://docs.python.org/3/howto/curses.html) library. It's a relatively simple application that gives us a quick overview of system statistics in the way of memory and cpu usage as well as logs you can scroll with the directional keys
## The Service ## The Service
PierMesh runs a number of loops under the hood. These are primarily initialized in the main loop of run with a special logging loop outside of that. PierMesh runs a number of loops under the hood. These are primarily initialized in the main loop of run with a special logging loop outside of that.
Note that we make heavy use of [Meshtastic's Python API](https://github.com/meshtastic/python). Note that we make use of [Meshtastic's Python API](https://github.com/meshtastic/python).
### run ### run
@ -288,18 +288,18 @@ Note that we make heavy use of [Meshtastic's Python API](https://github.com/mesh
In run.main we (in order) In run.main we (in order)
1. Initialize the `Node` class to a global `nodeOb`. 1. Initialize the `Node` class to a global `nodeOb`.
2. Wait for x seconds determined by command line arguments (see the falin and marcille scripts in scripts) 2. Wait for x seconds determined by command line arguments (see the falin script in scripts)
3. Initialize our `Transceiver` class (and the corresponding hardware) 3. Initialize our `Transceiver` class (and the corresponding hardware)
4. Initialize our `Server` class 4. Initialize our `Server` class
5. Create an async task running the `Node.spongeListen` method which looks for updates from the filter system 5. Create an async task running the `Node.spongeListen` method which looks for updates from the filter system
6. Kick the loop on with `await asyncio.sleep(1)` (we do this to kick on all async loops so I will omit this step going forward) 6. Kick the loop on with `await asyncio.sleep(1)` (we do this to kick on all async loops so I will omit this step going forward)
7. Create an async task running the `Transceiver.checkProgress` method which checks for packet reception progress and resends packets if necessary 7. Create an async task running the `Transceiver.checkProgress` method which checks for packet reception progress and resends packets if necessary (currently not in use)
8. Create an async task running `Node.monitor` which checks and reports system usage 8. Create an async task running `Node.monitor` which checks and reports system usage
9. Create an async task running the `Transceiver.announce` method which broadcasts a `Packets.Message` containing network mapping information 9. Create an async task running the `Transceiver.announce` method which broadcasts a `Packets.Message` containing network mapping information
10. Last we start the `Microdot` server loop 10. Last we start the `Microdot` server loop
### .. ### ..
Travelling out of the run.main thread to the primary ____main____ code we see the other two threads: one running the `logPassLoop` loop which is created in the same way as the main thread: `lplThread = threading.Thread(target=asyncio.run, args=(logPassLoop(),))` and one running the TUI loop which has it's own system we just kick on by instantiating the TUI class and calling .run() on. Travelling out of the run.main thread to the primary ____main____ code we see the other thread running the TUI loop which has it's own system we just kick on by running .runLogUI
## Packet lifecycle ## Packet lifecycle
@ -342,4 +342,4 @@ To avoid unnecessary manual documentation labor for future devs I will not list
# Fin # Fin
Well not really, there's more to learn but these are the basics. There's more in the docs above and you can always submit an issue or reach me at info@piermesh.net or on Tumblr at utopicwork. Well not really, there's more to learn but these are the basics. There's more in the docs above and you can always submit an issue or reach me at info@piermesh.net or on Tumblr at utopicwork.

View File

@ -2,8 +2,6 @@
# PierMesh # PierMesh
## A new internet, a fresh start ## A new internet, a fresh start
This is the monorepo for PierMesh.
# Docs # Docs
You can find the full docs here: [docs/](https://git.utopic.work/PierMesh/piermesh/src/branch/main/docs) You can find the full docs here: [docs/](https://git.utopic.work/PierMesh/piermesh/src/branch/main/docs)
@ -15,24 +13,25 @@ Note: these instructions will probably only work on Linux at the moment
Note: check the scripts to make sure they'll work with your system, and in general I recommend checking scripts before you run them Note: check the scripts to make sure they'll work with your system, and in general I recommend checking scripts before you run them
Follow Meshtastic's guide on setting up your device: [https://meshtastic.org/docs/getting-started/](https://meshtastic.org/docs/getting-started/) Follow Meshtastic's guide on setting up your device: [https://meshtastic.org/docs/getting-started/](https://meshtastic.org/docs/getting-started/)
Make sure you have the latest Python installed Make sure you have the latest Python installed
Make sure you have pip and venv installed
``` ```
git clone https://git.utopic.work/PierMesh/piermesh git clone https://git.utopic.work/PierMesh/piermesh
cd piermesh cd piermesh
python -m venv . python -m venv .venv
source bin/activate source .venv/bin/activate
pip install -r requirements.txt pip install -r requirements.txt
cd src cd src
chmod a+x ./scripts/falin python run.py
./scripts/falin
``` ```
# License text # License text

View File

@ -3,7 +3,7 @@
Nickname = node1 Nickname = node1
StartupDelay = 0 StartupDelay = 0
WebUIPort = 5000 WebUIPort = 5000
ShowTUI = False ShowTUI = True
[OPERATOR_REQUIRED] [OPERATOR_REQUIRED]
TransceiverPort = /dev/ttyACM0 TransceiverPort = /dev/ttyACM0

View File

@ -4,17 +4,17 @@ PierMesh has two main events loops to learn about: the TUI and the service.
## TUI ## TUI
[🔗 Docs](https://git.utopic.work/PierMesh/piermesh/src/branch/main/docs/ui.md) [🔗 Docs](https://git.utopic.work/PierMesh/piermesh/src/branch/main/docs/tlog.md)
[🔗 Source](https://git.utopic.work/PierMesh/piermesh/src/branch/main/src/ui.py) [🔗 Source](https://git.utopic.work/PierMesh/piermesh/src/branch/main/src/tlog.py)
The TUI is provided via [Textual's](https://textual.textualize.io/) library. It's a relatively simple application that gives us a quick overview of system statistics in the way of memory and cpu usage as well as scrollable logs. You can toggle full screen logs with f and close the TUI and service with q. The TUI is provided via [curses](https://docs.python.org/3/howto/curses.html) library. It's a relatively simple application that gives us a quick overview of system statistics in the way of memory and cpu usage as well as logs you can scroll with the directional keys
## The Service ## The Service
PierMesh runs a number of loops under the hood. These are primarily initialized in the main loop of run with a special logging loop outside of that. PierMesh runs a number of loops under the hood. These are primarily initialized in the main loop of run with a special logging loop outside of that.
Note that we make heavy use of [Meshtastic's Python API](https://github.com/meshtastic/python). Note that we make use of [Meshtastic's Python API](https://github.com/meshtastic/python).
### run ### run
@ -26,18 +26,18 @@ Note that we make heavy use of [Meshtastic's Python API](https://github.com/mesh
In run.main we (in order) In run.main we (in order)
1. Initialize the `Node` class to a global `nodeOb`. 1. Initialize the `Node` class to a global `nodeOb`.
2. Wait for x seconds determined by command line arguments (see the falin and marcille scripts in scripts) 2. Wait for x seconds determined by command line arguments (see the falin script in scripts)
3. Initialize our `Transceiver` class (and the corresponding hardware) 3. Initialize our `Transceiver` class (and the corresponding hardware)
4. Initialize our `Server` class 4. Initialize our `Server` class
5. Create an async task running the `Node.spongeListen` method which looks for updates from the filter system 5. Create an async task running the `Node.spongeListen` method which looks for updates from the filter system
6. Kick the loop on with `await asyncio.sleep(1)` (we do this to kick on all async loops so I will omit this step going forward) 6. Kick the loop on with `await asyncio.sleep(1)` (we do this to kick on all async loops so I will omit this step going forward)
7. Create an async task running the `Transceiver.checkProgress` method which checks for packet reception progress and resends packets if necessary 7. Create an async task running the `Transceiver.checkProgress` method which checks for packet reception progress and resends packets if necessary (currently not in use)
8. Create an async task running `Node.monitor` which checks and reports system usage 8. Create an async task running `Node.monitor` which checks and reports system usage
9. Create an async task running the `Transceiver.announce` method which broadcasts a `Packets.Message` containing network mapping information 9. Create an async task running the `Transceiver.announce` method which broadcasts a `Packets.Message` containing network mapping information
10. Last we start the `Microdot` server loop 10. Last we start the `Microdot` server loop
### .. ### ..
Travelling out of the run.main thread to the primary ____main____ code we see the other two threads: one running the `logPassLoop` loop which is created in the same way as the main thread: `lplThread = threading.Thread(target=asyncio.run, args=(logPassLoop(),))` and one running the TUI loop which has it's own system we just kick on by instantiating the TUI class and calling .run() on. Travelling out of the run.main thread to the primary ____main____ code we see the other thread running the TUI loop which has it's own system we just kick on by running .runLogUI
## Packet lifecycle ## Packet lifecycle
@ -80,4 +80,4 @@ To avoid unnecessary manual documentation labor for future devs I will not list
# Fin # Fin
Well not really, there's more to learn but these are the basics. There's more in the docs above and you can always submit an issue or reach me at info@piermesh.net or on Tumblr at utopicwork. Well not really, there's more to learn but these are the basics. There's more in the docs above and you can always submit an issue or reach me at info@piermesh.net or on Tumblr at utopicwork.

View File

@ -129,7 +129,7 @@ if __name__ == "__main__":
else: else:
if "ShowTUI" in config["OPERATOR_OVERRIDES"]: if "ShowTUI" in config["OPERATOR_OVERRIDES"]:
showTUI = config["OPERATOR_OVERRIDES"]["ShowTUI"] showTUI = config["OPERATOR_OVERRIDES"]["ShowTUI"]
showTUI = bool(showTUI) showTUI = showTUI == "True"
psk = False psk = False
if argConfig.override: if argConfig.override:
if not argConfig.PSK: if not argConfig.PSK:
@ -274,15 +274,14 @@ class Node:
""" """
Monitor and log ram and cpu usage Monitor and log ram and cpu usage
""" """
global tuiOb global tuiOb, logger
while True: while True:
if tuiOb != None: if tuiOb is not None and showTUI:
await asyncio.sleep(10) await asyncio.sleep(10)
memmb = self.proc.memory_info().rss / (1024 * 1024) memmb = self.proc.memory_info().rss / (1024 * 1024)
memmb = round(memmb, 2) memmb = round(memmb, 2)
cpup = self.proc.cpu_percent(interval=1) cpup = self.proc.cpu_percent(interval=1)
logger.log( logger.info(
10,
" MEM: {0} mB | CPU: {1} %".format( " MEM: {0} mB | CPU: {1} %".format(
memmb, memmb,
cpup, cpup,
@ -290,6 +289,17 @@ class Node:
) )
tuiOb.do_set_cpu_percent(float(cpup)) tuiOb.do_set_cpu_percent(float(cpup))
tuiOb.do_set_mem(memmb) tuiOb.do_set_mem(memmb)
elif not showTUI:
await asyncio.sleep(10)
memmb = self.proc.memory_info().rss / (1024 * 1024)
memmb = round(memmb, 2)
cpup = self.proc.cpu_percent(interval=1)
logger.info(
" MEM: {0} mB | CPU: {1} %".format(
memmb,
cpup,
),
)
else: else:
logger.log(20, "No TUI object, waiting 5 seconds...") logger.log(20, "No TUI object, waiting 5 seconds...")
await asyncio.sleep(5) await asyncio.sleep(5)
@ -306,6 +316,7 @@ class Node:
----- -----
We use a common technique here that calls the function from our preloaded actions via dictionary entry We use a common technique here that calls the function from our preloaded actions via dictionary entry
""" """
global logger
while True: while True:
while (len(self.todo) >= 1): while (len(self.todo) >= 1):
try: try:
@ -484,17 +495,23 @@ def initLogger(nodeName, tolog, tui=True):
""" """
global logger global logger
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
logger.propagate = not tui logger.propagate = False
logger.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)
vh = VHandler(logging.DEBUG, tolog)
formatter = logging.Formatter( formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s') '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
vh.setFormatter(formatter) if tui:
vh = VHandler(logging.DEBUG, tolog)
logger.addHandler(vh) vh.setFormatter(formatter)
logger.addHandler(vh)
else:
sh = logging.StreamHandler()
sh.setLevel(logging.DEBUG)
sh.setFormatter(formatter)
logger.addHandler(sh)
dt = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") dt = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
@ -507,14 +524,14 @@ def initLogger(nodeName, tolog, tui=True):
if __name__ == "__main__": if __name__ == "__main__":
try: try:
tolog = queue.Queue() tolog = queue.Queue()
initLogger(nodeNickname, tolog) initLogger(nodeNickname, tolog, tui=showTUI)
mainThread = threading.Thread(target=uvloop.run, args=(main(),)) mainThread = threading.Thread(target=uvloop.run, args=(main(),))
mainThread.start() mainThread.start()
# TODO: Waiting for this to finish when no tui
# TODO: Logging to screen when no tui
if showTUI: if showTUI:
tlog.runLogUI(tolog, nodeNickname) tlog.runLogUI(tolog, nodeNickname)
# else: else:
# TODO: Resource logging
print("No TUI")
except Exception: except Exception:
print(traceback.format_exc()) print(traceback.format_exc())
os._exit(1) os._exit(1)