Posts: 17
Threads: 7
Joined: May 2023
Hello,
at the moment my program show an GUI in a thread and in the other thread i get some data via BLE in an array. Now i want to display the data in my GUI. First i want to safe them into an svg, then display. Next step is to send it into influx DB oder mySQL. Can anyone help me to creat the svg and display them in my tkinter windows? I need first to creat the svg in my BLE thread and then writ into to svg above my print from the data? Right?
Here is my code:
import asyncio
import threading
from tkinter import *
from bleak import BleakClient
import numpy
import svgwrite
address = "CC:50:E3:9C:15:02"
MODEL_NBR_UUID = "beb5483e-36e1-4688-b7f5-ea07361b26a8"
class BLEThread(threading.Thread):
def __init__(self, address):
threading.Thread.__init__(self)
self.address = address
async def handle_uuid1_notify(self, sender, data):
spo2_value = numpy.frombuffer(data, dtype=numpy.uint32)
print("Red: {0}".format(spo2_value))
async def handle_uuid2_notify(self, sender, data):
ir_value = numpy.frombuffer(data, dtype=numpy.uint32)
print("IR: {0}".format(ir_value))
async def read_data(self):
UUID1 = "beb5483e-36e1-4688-b7f5-ea07361b26a8"
UUID2 = "beb5483e-36e1-4688-b7f5-ea07361b26a9"
async with BleakClient(self.address) as client:
await client.start_notify(UUID1, self.handle_uuid1_notify)
await client.start_notify(UUID2, self.handle_uuid2_notify)
while True:
await asyncio.sleep(1)
def run(self):
asyncio.run(self.read_data())
class TkinterThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
tkFenster = Tk()
tkFenster.title('BLE MAX30102')
tkFenster.mainloop()
def start_threads():
ble_thread = BLEThread(address)
tkinter_thread = TkinterThread()
ble_thread.start()
tkinter_thread.start()
if __name__ == '__main__':
start_threads()
Posts: 17
Threads: 7
Joined: May 2023
May-03-2023, 01:39 PM
(This post was last modified: May-03-2023, 01:40 PM by Nietzsche.)
I think excel is better?
At the moment this is my code, i save in in txt, but not right formated:
import asyncio
import threading
from tkinter import *
from bleak import BleakClient
import numpy
from prettytable import PrettyTable
import datetime
address = "CC:50:E3:9C:15:02"
MODEL_NBR_UUID = "beb5483e-36e1-4688-b7f5-ea07361b26a8"
table = PrettyTable()
table.field_names = ["Wert 1", "Wert 2"]
def print_table():
print(table)
class BLEThread(threading.Thread):
def __init__(self, address):
threading.Thread.__init__(self)
self.address = address
async def handle_uuid1_notify(self, sender, data):
spo2_values = numpy.frombuffer(data, dtype=numpy.uint32)
print("Red: {0}".format(spo2_values))
for spo2_value in spo2_values:
table.add_row([spo2_value, ""])
print_table()
async def handle_uuid2_notify(self, sender, data):
ir_values = numpy.frombuffer(data, dtype=numpy.uint32)
print("IR: {0}".format(ir_values))
for ir_value in ir_values:
table.add_row(["", ir_value])
print_table()
async def read_data(self):
UUID1 = "beb5483e-36e1-4688-b7f5-ea07361b26a8"
UUID2 = "beb5483e-36e1-4688-b7f5-ea07361b26a9"
async with BleakClient(self.address) as client:
await client.start_notify(UUID1, self.handle_uuid1_notify)
await client.start_notify(UUID2, self.handle_uuid2_notify)
while True:
await asyncio.sleep(1)
def run(self):
asyncio.run(self.read_data())
class TkinterThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
tkFenster = Tk()
tkFenster.title('BLE MAX30102')
tkFenster.mainloop()
def save_table():
now = datetime.datetime.now()
filename = "table_{}.txt".format(now.strftime("%Y-%m-%d_%H-%M-%S"))
with open(filename, 'w') as file:
file.write(str(table))
def start_threads():
ble_thread = BLEThread(address)
tkinter_thread = TkinterThread()
ble_thread.start()
tkinter_thread.start()
threading.Timer(60.0, save_table).start()
if __name__ == '__main__':
start_threads() I get this:
+--------+--------+
| Wert 1 | Wert 2 |
+--------+--------+
| 555 | |
| 554 | |
| 558 | |
| 557 | |
| 556 | |
| 553 | |
| 553 | |
| 548 | |
| 544 | |
| 556 | |
| 560 | |
| 554 | |
| | 3528 |
| | 3518 |
| | 3523 |
| | 3524 |
| | 3529 |
| | 3528 |
| | 3531 |
| | 3537 |
| | 3528 |
| | 3531 |
| | 3531 |
| | 3524 |
| | 3524 |
| | 3526 |
| | 3531 |
| | 3531 |
| | 3524 |
| | 3531 |
| | 3527 |
| | 3525 |
But i want this
+--------+--------+
| Wert 1 | Wert 2 |
+--------+--------+
| 555 | 3324 |
| 554 | 234 |
| 558 | 324 |
Posts: 6,800
Threads: 20
Joined: Feb 2020
So no more tkinter? If you want to write a spreadsheet I would use pandas. First verify that you are getting values.
import asyncio
import threading
from tkinter import *
from bleak import BleakClient
import numpy as np
import pandas as pd
class BLEThread(threading.Thread):
def __init__(self, address):
threading.Thread.__init__(self)
self.address = address
self.table = pd.DataFrame()
async def update_table(self, column, data):
print(f"update_table({column})")
self.table[column] = np.frombuffer(data, dtype=np.uint32)
print(self.table)
async def read_data(self):
async with BleakClient(self.address) as client:
client.start_notify(
"beb5483e-36e1-4688-b7f5-ea07361b26a8",
lambda uuid, data: self.update_table("Wert 1", data)
)
client.start_notify(
"beb5483e-36e1-4688-b7f5-ea07361b26a9",
lambda uuid, data: self.update_table("Wert 2", data)
)
while True:
await asyncio.sleep(1)
def run(self):
asyncio.run(self.read_data())
def start_threads(address):
ble_thread = BLEThread(address)
ble_thread.start()
if __name__ == '__main__':
start_threads("CC:50:E3:9C:15:02")
Nietzsche likes this post
Posts: 17
Threads: 7
Joined: May 2023
(May-03-2023, 03:55 PM)deanhystad Wrote: So no more tkinter? If you want to write a spreadsheet I would use pandas. First verify that you are getting values.
Hi! First i want to safe my data in a file, then i want to dispay them in tkinter, so step by step. :)
Thanks for the tipp with pandas, i have installed them and implement them into my code:
import pandas as pd
import asyncio
import threading
from tkinter import *
from bleak import BleakClient
import numpy
from prettytable import PrettyTable
import openpyxl
from datetime import datetime
address = "CC:50:E3:9C:15:02"
MODEL_NBR_UUID = "beb5483e-36e1-4688-b7f5-ea07361b26a8"
table = PrettyTable()
table.field_names = ["Wert 1", "Wert 2"]
wb = openpyxl.Workbook() # Workbook-Objekt erzeugen
ws = wb.active #Arbeitsblatt auswählen
now = datetime.now()
dt_string = now.strftime("%d-%m-%Y_%H-%M-%S") # Variable mit Datum und Uhrzeit erzeugen
filename = f"{dt_string}.xlsx" #Datei mit Name und Datum erzeugen
ws["A1"] = "Red"
ws["B1"] = "IR" #Überschriften hinzufügen
last_red_row = 1 # Die erste Zeile ist bereits mit Überschriften belegt
last_ir_row = 1
spo2_list = []
ir_list = []
def print_table():
print(table)
class BLEThread(threading.Thread):
def __init__(self, address):
threading.Thread.__init__(self)
self.address = address
async def handle_uuid1_notify(self, sender, data):
spo2_values = numpy.frombuffer(data, dtype=numpy.uint32)
print("Red: {0}".format(spo2_values))
for spo2_value in spo2_values:
table.add_row([spo2_value, ""])
ws.append([spo2_value, ""]) # Zeile hinzufügen
spo2_list.append(spo2_value) # füge den empfangenen Wert der Liste hinzu
# wenn alle Werte empfangen wurden, erstelle einen Pandas DataFrame und gib ihn aus
if len(spo2_list) == 100:
pythonDaten = pd.DataFrame(spo2_list)
print(pythonDaten.head())
wb.save(filename)
async def handle_uuid2_notify(self, sender, data):
ir_values = numpy.frombuffer(data, dtype=numpy.uint32)
print("IR: {0}".format(ir_values))
for ir_value in ir_values:
if ir_value:
table.add_row(["", ir_value])
ws.append(["", ir_value]) # Zeile hinzufügen
ir_list.append(ir_value) # füge den empfangenen Wert der Liste hinzu
# wenn alle Werte empfangen wurden, erstelle einen Pandas DataFrame und gib ihn aus
if len(ir_list) == 100:
pythonDaten2 = pd.DataFrame(ir_list)
print(pythonDaten2.head())
wb.save(filename)
async def read_data(self):
UUID1 = "beb5483e-36e1-4688-b7f5-ea07361b26a8"
UUID2 = "beb5483e-36e1-4688-b7f5-ea07361b26a9"
async with BleakClient(self.address) as client:
await client.start_notify(UUID1, self.handle_uuid1_notify)
await client.start_notify(UUID2, self.handle_uuid2_notify)
while True:
await asyncio.sleep(1)
def run(self):
asyncio.run(self.read_data())
class TkinterThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
tkFenster = Tk()
tkFenster.title('BLE MAX30102')
tkFenster.mainloop()
def start_threads():
ble_thread = BLEThread(address)
tkinter_thread = TkinterThread()
ble_thread.start()
tkinter_thread.start()
if __name__ == '__main__':
start_threads()
wb.save(filename) But at the moment i also need to synchonizat them, the data are not side by side.
Posts: 6,800
Threads: 20
Joined: Feb 2020
May-05-2023, 04:03 PM
(This post was last modified: May-05-2023, 04:03 PM by deanhystad.)
Get rid of the pretty table. It doesn't have the right temperament for adding columns piecemeal and is causing most of your problems. Use pandas to display the data. It is pretty enough for your purposes. Eventually you plan to display the data in a tkinter table, right?
You only need one handle function like I showed in my last example. The lambda expression used to bind the handler will pass the column name associated with the data. When you get data from "beb5483e-36e1-4688-b7f5-ea07361b26a8" it will place it in the "Wert 1" column, and data from "beb5483e-36e1-4688-b7f5-ea07361b26a9" will be placed in the "Wert 2" column. Whenever you look at the table it will have the most recent values for each column.
Do not use openpyxl to write an excel spreadsheet. Use pandas. It has a function for directly writing a dataframe to an excel spreadsheet.
Currently you are doing nothing with tkinter. Leave that out until you have the other parts working. I would start by getting the data into a DataFrame and printing. From there it is simple to write the DataFrame to a spreadsheet. When that is all working it will be easier to write the tkinter app. Since pandas and tkinter are so widely used I'm sure someone has documented a way to connect a dataframe to the data model for a tkinter table.
Posts: 17
Threads: 7
Joined: May 2023
(May-05-2023, 04:03 PM)deanhystad Wrote: Get rid of the pretty table. It doesn't have the right temperament for adding columns piecemeal and is causing most of your problems. Use pandas to display the data. I followed your tip and got it now, thanks!
|