Python 3.7.1 ANT + TKinter - отображение текущих данных с устройства ANT + в Tkinter - PullRequest
0 голосов
/ 12 декабря 2018

Относительно моего вопроса на вчерашний день ( здесь ), я пытался реализовать репозиторий python-ant с помощью форка, созданного Bissont .Я попытался использовать его демонстрацию силы для интеллектуального тренажера Tacx Bushido, так как это то же устройство, которое я использую.Я немного изменил код, чтобы он соответствовал моему приемнику Suunto ANT +, и, запустив его в консоли, код работал.Теперь я попытался реализовать его в среде TKinter для отображения оперативных данных, полученных с устройства ANT +, но в итоге получил следующий код ошибки, и окно Tkinter больше не открывается:

Traceback(последний вызов был последним): файл "/usr/local/lib/python3.5/dist-packages/ant-0.1.1-py3.5.egg/ant/core/node.py", строка 212, в началеФайл self.reset (wait) "/usr/local/lib/python3.5/dist-packages/ant-0.1.1-py3.5.egg/ant/core/node.py", строка 197, в файле сброса evmФайл .waitForMessage (message.StartupMessage) "/usr/local/lib/python3.5/dist-packages/ant-0.1.1-py3.5.egg/ant/core/event.py", строка 163, в waitForMessageвернуть файл self.msg.waitFor (class_, timeout) "/usr/local/lib/python3.5/dist-packages/ant-0.1.1-py3.5.egg/ant/core/event.py", строка114, в ожидании повышения

Traceback (большинствоПоследний вызов ecent): файл "/home/pi/python-ant/demos/ant.core/ANT+ power.py", строка 47, в файле antnode.start () "/usr/local/lib/python3.5/dist-packages / ant-0.1.1-py3.5.egg / ant / core / node.py ", строка 217, в начале повышения NodeError (err) ant.core.exceptions.NodeError:: timeout

Итак, вот что (финальная программа) должна делать:

  • Получение и сохранение данных ANT
  • Округление чисел до 2-3 десятичных знаков (макс.)
  • Считать общую выходную мощность из файла
  • Записать данные о мощности в файл (приложение)
  • Суммировать общую выходную мощность
  • отобразить текущую скорость,частота вращения педалей, мощность и общая мощность

Вот мой код на данный момент:

# imports
import random
import time
from tkinter import *

from ant.core import driver
from ant.core.node import Node, Network, ChannelID
from ant.core.constants import NETWORK_KEY_ANT_PLUS, NETWORK_NUMBER_PUBLIC
from ant.plus.power import *

from config import *

# creating root tkinter Window
root = Tk()
root.title("TacX Bushido ANT+ Live Data")

# defining text variables
running = 0
SAVE_FILE = "power_doc.txt"
HEADLINE_TEXT = StringVar()
HEADLINE_TEXT.set('Headline')
HEADLINE_M= StringVar()
HEADLINE_M.set('M')
power_display = StringVar()
power_display.set('0')
cadence_display = StringVar()
cadence_display.set('0')
speed_display = StringVar()
speed_display.set('0')
powertotal_display = StringVar()
powertotal_display.set('0')

# defining ANT variables
device = driver.USB2Driver(log=LOG, debug=DEBUG, idProduct=0x1008)
antnode = Node(device)
antnode.start()
network = Network(key=NETWORK_KEY_ANT_PLUS, name='N:ANT+')
antnode.setNetworkKey(NETWORK_NUMBER_PUBLIC, network)



# defining Window Size
root.geometry("800x600")

# creating Label Frame to wrap labels
frame = LabelFrame(root)
frame.pack(padx=20, pady=20)

# creating labels, Headline 1
Mlabel = Label(root, font = ("Helvetica",48) ,textvariable = HEADLINE_M, justify=CENTER, bg="#FFFFFF", fg = '#000000')
Mlabel.pack(fill=BOTH, padx=20, pady=10)

# headline 2
headLine = Label(root, font=("Helvetica", 26), textvariable= HEADLINE_TEXT, justify=CENTER, bg="#FFFFFF", fg = '#000000')
headLine.pack(fill=BOTH, pady=5)

# power
l1 = Label(root, font = ("Helvetica",20) ,textvariable = power_display, justify=CENTER, bg="#190000", fg = '#B0C4C2')
l1.pack(fill=BOTH)

# cadence
l2 = Label(root, font = ("Helvetica",20), textvariable = cadence_display, justify=CENTER, bg="#190000", fg = '#B0C4C2')
l2.pack(fill=BOTH)

# speed
l3 = Label(root, font = ("Helvetica",20), textvariable = speed_display, justify=CENTER, bg="#190000", fg = '#B0C4C2')
l3.pack(fill=BOTH)

# total Power
l4 = Label(root, font = ("Helvetica",20), textvariable = powertotal_display, justify=CENTER, bg="#190000", fg = '#B0C4C2')
l4.pack(fill=BOTH)


# function to read total power values out of a file
def get_power_total(SAVE_FILE):
    power_total = 0
    with open(SAVE_FILE, 'r') as inp:
        for line in inp:
            try:
                num = float(line)
                power_total += num
            except ValueError:
                print('{} is not a number!'.format(line))
    power_total = round_number(power_total)
    return power_total

# rounds numbers to 2 decimals
def round_number(inputNumber):
    inputNumber = round(inputNumber, 2)
    return inputNumber


# use formula for a 28" Wheel to determine Speed using cadence
def determine_speed(cadence):
    speed = float(cadence)*0.356
    speed = round_number(speed)
    return speed


# write in document to determine total power output
def write_file(SAVE_FILE, power):
    f = open(SAVE_FILE, "a+")
    f.write(str(power) + '\n')
    f.close()

# updates label
def update_label(power, cadence):
    power_total = get_power_total(SAVE_FILE)
    speed = determine_speed(cadence)
    power_total += power
    write_file(SAVE_FILE, power)
    power_display.set("Power: {} W".format(power))
    cadence_display.set("Cadence: {}".format(cadence))
    speed_display.set("Speed : {} Km/h".format(speed))
    powertotal_display.set("Total Power Output: {} W".format(power_total))
    root.after(1000, power_data)
    root.update_idletasks()

# find device
def device_found(self, device_number, transmission_type):
    print("Detect monitor device number: %d, transmission type: %d" % (device_number, transmission_type))

# determine power
def power_data(eventCount, pedalDiff, pedalPowerRatio, cadence, accumPower, instantPower):
    update_label(instantPower, cadence)

power  = BicyclePower(antnode, network, callbacks = {'onDevicePaired': device_found,
                                              'onPowerData': power_data})

# Unpaired, search:
power.open()


monitor = None
while True:
    try:
        time.sleep(1)
    except KeyboardInterrupt:
        break

power.close()
antnode.stop()
# mainloop to display the window
root.after(1000, power_data)
root.mainloop()

Я уже знаю, что оператор while True будет блокировать открытие моего окна Tkinter до появления устройствабыл найден, что является неудовлетворительным, но я не придумал лучшего подхода, чтобы оставить все как есть.

Любые предложения, помощь или все, что высоко ценится.

Заранее спасибо!

Редактировать (для тех, кто заинтересован или застрял в той же теме): После дальнейшего изучения библиотеки я понял, что power.open () создает бесконечный циклобратных вызовов, что приводит к недоступности root.mainloop ().Мне еще предстоит найти способ вмешиваться в цикл обратного вызова, чтобы захватывать данные, отображать их в основном цикле и продолжать цикл обратного вызова.Я постараюсь предоставить больше информации и возможного решения, как только я его найду.Не стесняйтесь вносить свой вклад, если у вас есть идея или другой подход к этому:)

Редактировать 2: Поскольку модуль ANT + считывает и записывает данные как таковые, одним из подходов может быть запись в файл и создание другого сценария.читать данные из файла.Тем не менее, я не знаю, возможно ли это в python (что-то вроде readonly-mode без блокировки доступа из других источников).

Редактировать 3: Проблема решена: разбить скрипт на 2 части (отдельные скрипты).1-й сценарий: чтение данных ANT + и запись в файл, подобный следующему:

def write_file(SAVE_FILE, power):
        f = open(SAVE_FILE, "w")
        f.write(str(power) + '\n')
        f.close()

2-й сценарий: данные только для чтения и присвоение значений, например:

def readFile():
    file = open("ultimateFile.txt", "r")
    VALUE = file.readline()
    file.close()
    return VALUE

Я обновлюкод / ​​скрипты в 2019 году и загрузить обновленный код / ​​скрипты в github.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...