将三个脚本合二为一

时间:2015-03-08 01:58:44

标签: python multithreading sqlite wxpython pyserial

我有三个脚本,在我看来它们代表了程序必须做的三件事。

第一个脚本不断读取传入的串行端口,并将所有信息写入文件,我这样做是因为我不确定部署设备中串行缓冲区的大小,因此收集每一个部分至关重要来自串口的信息。为了将其组合成一个单独的文件,我简要介绍了pythons线程功能,但我还没有研究过python方面的线程,但是部署设备现在只是一个单核心设备,如果这对于python线程来说很重要

第二段代码用于验证和解析第一个脚本创建的文件,并将其放入SQLite数据库。

第三个文件是用python编写的,带有wxPython扩展。它(不完全完整)从文件中读取信息并更新wxPython显示小部件。

虽然我确信其中很多都是效率低下的,但实际上并不是我想要的方式,但我一直在尝试从python论坛获得帮助,而且帮助有点不存在。

首要任务是确保从串口收集所有数据,然后将其存储在数据库中,进行数据记录,我宁愿同时在显示器上显示数据将它存储在数据库中,但我认为会产生太多的延迟,这样代码就可以将显示放在定时器上,每隔250ms,我就可以从数据库的下一个信息中更新显示。

现在你有了这里的信息是问题,我如何组合我制作一个脚本的部分。我可以在写入文件时读取文件,例如串行集合文件和SQLite数据库吗?

我应该研究的方法指针和直接答案一样受欢迎,我真的非常感谢提前任何帮助!

Serial Scrape Code:

import serial

ser = serial.Serial('/dev/pts/7', 19200, timeout=0)
print ser.name          # check which port was really used

ScratchFile = open('Data/Scratch.scr', 'a')

x = 1
while True:
 SData = ser.readline()
 Valid = bool(SData)
 if Valid == True:
  #SData = (SData + "\n")
  ScratchFile.write(SData)
 #print(b)

ser.close()

验证并存储代码:

#GKPCM Database Test


#outline open database, read serial,write string, repeat

import sqlite3
db = sqlite3.connect('Data/telemetry.gkpcm')
cursor = db.cursor()

InsertQuery ="""INSERT INTO vehicletelemetry (date,time,cyclecount,rpm,speed,odometer,oiltemp,airtemp,fuellevel,enginetemp,ind1,ind2,ind3,ind4,ind5,ind6,ind7,ind8) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"""

tablename="vehicletelemetry"
cursor.execute(""" SELECT COUNT(*) FROM sqlite_master WHERE name = ?  """, (tablename, ))
QUERY = cursor.fetchone()
print bool(QUERY[0]) # True if exists
if bool(QUERY[0]) !=1:
 print('not in DB')
 cursor.execute('''CREATE TABLE vehicletelemetry(id INTEGER PRIMARY KEY, date INTEGER,time INTEGER, cyclecount INTEGER, rpm INTEGER, speed INTEGER, odometer INTEGER, oiltemp INTEGER, airtemp INTEGER, fuellevel INTEGER, enginetemp INTEGER, ind1 BOOL, ind2 BOOL, ind3 BOOL, ind4 BOOL, ind5 BOOL, ind6 BOOL, ind7 BOOL, ind8 BOOL)''')
 cursor.execute('INSERT INTO vehicletelemetry (date,time,cyclecount,rpm,speed,odometer,oiltemp,airtemp,fuellevel,enginetemp,ind1,ind2,ind3,ind4,ind5,ind6,ind7,ind8) VALUES (031514,013030,18960,3000,22,192768,210,72,98,210,0,0,0,0,0,0,0,0)')
 db.commit()
else:
 print('DB Table Exists')

#openfile to read
with open('Data/Scratch.scr') as ScratchFile:
 for DataLine in ScratchFile:
  #Read Database for last record date
  LastEntry = cursor.execute('SELECT * FROM vehicletelemetry ORDER BY id DESC LIMIT 1')
  for Records in LastEntry:
    LastLogDate = Records[1]
    LastLogTime = Records[2]
    LastLogCycles = Records[3]
  DataLine1 = DataLine.strip()
  DataLine2 = DataLine1.split(',')
#Check Packet for Correct Length
  if len(DataLine2) - 2 != 18:
   print ("Invalid Data Length")
  else:
#Check Packet DataQualifiers to ensure proper package introduction and termination
   if DataLine2[0] != "7887" and DataLine2[18] != "0420":
    print ("Invalid Data Qulifier")
   else:
#Remove Qualifiers So data can be stored
    PiP = 1
    DataLine3 = []
    for Packet in DataLine2:
     if PiP >= 1 and PiP <= 18:
      DataLine3.append(DataLine2[PiP])
      PiP = PiP + 1
#Compare Date Time and Cycle Count to Current Record
    #print(DataLine3)
    if int(DataLine2[1]) >= int(LastLogDate): 
     if int(DataLine2[2]) >= int(LastLogTime): 
      if int(DataLine2[3]) > int(LastLogCycles):
       cursor.execute(InsertQuery,DataLine3)
       db.commit()
       print(Records,DataLine2[3],LastLogCycles,"Data Valid")

db.close()
#todo

显示代码:

import wx
import os
import wx.lib.agw.speedmeter as SM
import sys
import math
import wx.gizmos as gizmos
from wx.lib.colourdb import getColourList
import wx.lib.buttons
from math import pi, sqrt
import time


#GUI--------------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------------------


class MyFrame(wx.Frame):

    def __init__(self,parent):
        wx.Frame.__init__(self,parent,-1,"test",pos=(3, 3),size=(480, 320))

        SPEEDOpanel = wx.Panel(self, -1,style=wx.NO_BORDER, pos=(240, 0), size=(240, 240))
        TACHpanel = wx.Panel(self, -1, pos=(0, 0), size=(240, 240))
        ODOpanel = wx.Panel(self, -1, pos=(125, 200), size=(125, 30), style=wx.NO_BORDER)
        AIRpanel = wx.Panel(self, -1, pos=(0, 240), size=(80, 80), style=wx.NO_BORDER)
        OILpanel = wx.Panel(self, -1, pos=(120, 240), size=(80, 80), style=wx.NO_BORDER)
        FUELpanel = wx.Panel(self, -1, pos=(240, 240), size=(80, 80), style=wx.NO_BORDER)
        ENGpanel = wx.Panel(self, -1, pos=(360, 240), size=(80, 80), style=wx.NO_BORDER)

        INDpanel1 = wx.Panel(self, -1, pos=(80, 240), size=(40, 40), style=wx.NO_BORDER)
        INDpanel2 = wx.Panel(self, -1, pos=(80, 280), size=(40, 40), style=wx.NO_BORDER)
        INDpanel3 = wx.Panel(self, -1, pos=(200, 240), size=(40, 40), style=wx.NO_BORDER)
        INDpanel4 = wx.Panel(self, -1, pos=(200, 280), size=(40, 40), style=wx.NO_BORDER)
        INDpanel5 = wx.Panel(self, -1, pos=(320, 240), size=(40, 40), style=wx.NO_BORDER)
        INDpanel6 = wx.Panel(self, -1, pos=(320, 280), size=(40, 40), style=wx.NO_BORDER)
        INDpanel7 = wx.Panel(self, -1, pos=(440, 240), size=(40, 40), style=wx.NO_BORDER)
        INDpanel8 = wx.Panel(self, -1, pos=(440, 280), size=(40, 40), style=wx.NO_BORDER)


        SPEEDOpanel.SetBackgroundColour(wx.BLACK)
        TACHpanel.SetBackgroundColour(wx.BLUE)
        ODOpanel.SetBackgroundColour(wx.RED)
        AIRpanel.SetBackgroundColour(wx.BLUE)
        OILpanel.SetBackgroundColour(wx.CYAN)
        FUELpanel.SetBackgroundColour(wx.BLACK)
        ENGpanel.SetBackgroundColour(wx.BLUE)

        INDpanel1.SetBackgroundColour(wx.BLUE)
        INDpanel2.SetBackgroundColour(wx.RED)
        INDpanel3.SetBackgroundColour(wx.BLUE)
        INDpanel4.SetBackgroundColour(wx.RED)
        INDpanel5.SetBackgroundColour(wx.BLUE)
        INDpanel6.SetBackgroundColour(wx.RED)
        INDpanel7.SetBackgroundColour(wx.BLUE)
        INDpanel8.SetBackgroundColour(wx.RED)


#SPEEDOMETER----------------------------------------------------------------------------------------------------------

        SPEEDO = SM.SpeedMeter(SPEEDOpanel, agwStyle=SM.SM_DRAW_HAND|SM.SM_DRAW_SECTORS|SM.SM_DRAW_MIDDLE_TEXT|SM.SM_DRAW_SECONDARY_TICKS, pos=(0, 0), size=(240, 240))

        # Set The Region Of Existence Of SpeedMeter 
        SPEEDO.SetAngleRange(-7.25, -2)

        # SpeedMeter In Sectors
        intervals = range(0, 260, 20)
        SPEEDO.SetIntervals(intervals)

        # Assign The Same Colours To All Sectors 
        # Usually This Is Black
        colours = [wx.BLACK]*12
        SPEEDO.SetIntervalColours(colours)

        # Assign The Ticks
        ticks = [str(interval) for interval in intervals]
        SPEEDO.SetTicks(ticks)
        # Set The Ticks/Tick Markers Colour
        SPEEDO.SetTicksColour(wx.RED)
        # We Want To Draw 5 Secondary Ticks Between The Principal Ticks
        SPEEDO.SetNumberOfSecondaryTicks(10)

        # Set The Font For The Ticks Markers
        SPEEDO.SetTicksFont(wx.Font(7, wx.SWISS, wx.NORMAL, wx.NORMAL))

        # Set The Text In The Center Of SpeedMeter
        SPEEDO.SetMiddleText("MPH")
        # Assign The Colour To The Center Text
        SPEEDO.SetMiddleTextColour(wx.WHITE)
        # Assign A Font To The Center Text
        SPEEDO.SetMiddleTextFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD))

        # Set The Colour For The Hand Indicator
        SPEEDO.SetHandColour(wx.Colour(255, 255, 0))

        # Set The Colour For The Gauge Background
        SPEEDO.SetSpeedBackground(wx.BLACK)

        # Do Not Draw The External (CONTAINER) Arc
        SPEEDO.DrawExternalArc(False)
        SPEEDO.SetSpeedValue(0)

#TACHOMETER----------------------------------------------------------------------------------------------------------

        TACH = SM.SpeedMeter(TACHpanel, agwStyle=SM.SM_DRAW_HAND|SM.SM_DRAW_PARTIAL_SECTORS|SM.SM_DRAW_MIDDLE_TEXT|SM.SM_DRAW_SECONDARY_TICKS, pos=(0, 0), size=(240, 240))

        # Set The Region Of Existence Of SpeedMeter 
        TACH.SetAngleRange(-6, -2)

        # SpeedMeter In Sectors
        intervals = range(0, 15, 1)
        TACH.SetIntervals(intervals)

        # Assign The Same Colours To All Sectors 
        # Usually This Is Black
        colours = [wx.BLACK]*10
        colours.append(wx.Colour(255, 255, 0))
        colours.append(wx.Colour(255, 255, 0))
        colours.append(wx.Colour(255, 255, 0))
        colours.append(wx.RED)
        TACH.SetIntervalColours(colours)

        # Assign The Ticks
        ticks = [str(interval) for interval in intervals]
        TACH.SetTicks(ticks)
        # Set The Ticks/Tick Markers Colour
        TACH.SetTicksColour(wx.RED)
        # We Want To Draw 5 Secondary Ticks Between The Principal Ticks
        TACH.SetNumberOfSecondaryTicks(1)

        # Set The Font For The Ticks Markers
        TACH.SetTicksFont(wx.Font(7, wx.SWISS, wx.NORMAL, wx.NORMAL))

        # Set The Text In The Center Of SpeedMeter
        TACH.SetMiddleText("RPM")
        # Assign The Colour To The Center Text
        TACH.SetMiddleTextColour(wx.WHITE)
        # Assign A Font To The Center Text
        TACH.SetMiddleTextFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD))

        # Set The Colour For The Hand Indicator
        TACH.SetHandColour(wx.Colour(255, 255, 0))

        # Set The Colour For The Gauge Background
        TACH.SetSpeedBackground(wx.BLACK)

        # Do Not Draw The External (CONTAINER) Arc
        TACH.DrawExternalArc(False)
        TACH.SetSpeedValue(0)
#ODOMETER--------------------------------------------------------------------------------------------------------------
        DECIMAL1=wx.gizmos.LEDNumberCtrl(ODOpanel,-1, pos=wx.Point(0, 0), size=wx.Size(125, 30), style=wx.gizmos.LED_ALIGN_LEFT)
        DECIMAL1.SetBackgroundColour("BLACK")
        DECIMAL1.SetForegroundColour("RED")
        DECIMAL1.SetValue("192768")
#AIRTEMP---------------------------------------------------------------------------------------------------------------
        AIR = SM.SpeedMeter(AIRpanel, agwStyle=SM.SM_DRAW_HAND|SM.SM_DRAW_PARTIAL_SECTORS,bufferedstyle=SM.SM_BUFFERED_DC, pos=(0, 0), size=(80, 80))

        # Air Temp Control
        AIR.SetAngleRange(5,7.25)

        intervals = range(0, 5)
        AIR.SetIntervals(intervals)

        colours = [wx.BLACK]*3
        colours.append(wx.RED)
        AIR.SetIntervalColours(colours)

        ticks = ["140", "", "210", "", "280"]
        AIR.SetTicks(ticks)
        AIR.SetTicksColour(wx.RED)
        AIR.SetHandColour(wx.Colour(255, 255, 0))
        AIR.SetSpeedBackground(wx.BLACK)        
        #AIR.SetArcColour(wx.RED)
        AIR.SetTicksFont(wx.Font(7, wx.SWISS, wx.NORMAL, wx.NORMAL))
        AIR.SetSpeedValue(0)
        AIR.SetDirection("Reverse")


#OILTEMP---------------------------------------------------------------------------------------------------------------
        OIL = SM.SpeedMeter(OILpanel, agwStyle=SM.SM_DRAW_HAND|SM.SM_DRAW_PARTIAL_SECTORS,bufferedstyle=SM.SM_BUFFERED_DC, pos=(0, 0), size=(80, 80))

        # Air Temp Control
        OIL.SetAngleRange(5,7.25)

        intervals = range(0, 5)
        OIL.SetIntervals(intervals)

        colours = [wx.BLACK]*3
        colours.append(wx.RED)
        OIL.SetIntervalColours(colours)

        ticks = ["140", "", "210", "", "280"]
        OIL.SetTicks(ticks)
        OIL.SetTicksColour(wx.RED)

        OIL.SetHandColour(wx.Colour(255, 255, 0))
        OIL.SetSpeedBackground(wx.BLACK)        
        #OIL.SetArcColour(wx.RED)
        OIL.SetTicksFont(wx.Font(7, wx.SWISS, wx.NORMAL, wx.NORMAL))        
        OIL.SetSpeedValue(0)
        OIL.SetDirection("Reverse")
#FUELLEVEL---------------------------------------------------------------------------------------------------------------
        FUEL = SM.SpeedMeter(FUELpanel, agwStyle=SM.SM_DRAW_HAND|SM.SM_DRAW_SECTORS,bufferedstyle=SM.SM_BUFFERED_DC, pos=(0, 0), size=(80, 80))

        # Air Temp Control
        FUEL.SetAngleRange(5,7.25)

        intervals = range(0, 5)
        FUEL.SetIntervals(intervals)

        colours = [wx.BLACK]*4
        FUEL.SetIntervalColours(colours)

        ticks = ["E", "", "1/2", "", "F"]
        FUEL.SetTicks(ticks)
        FUEL.SetTicksColour(wx.RED)

        FUEL.SetHandColour(wx.Colour(255, 255, 0))
        FUEL.SetSpeedBackground(wx.BLACK)        
        #FUEL.SetArcColour(wx.RED)
        FUEL.SetTicksFont(wx.Font(7, wx.SWISS, wx.NORMAL, wx.NORMAL))        
        FUEL.SetSpeedValue(0)
        FUEL.SetDirection("Reverse")

#ENGTEMP---------------------------------------------------------------------------------------------------------------
        ENG = SM.SpeedMeter(ENGpanel, agwStyle=SM.SM_DRAW_HAND|SM.SM_DRAW_PARTIAL_SECTORS,bufferedstyle=SM.SM_BUFFERED_DC, pos=(0, 0), size=(80, 80))

        # Air Temp Control
        ENG.SetAngleRange(5,7.25)

        intervals = range(0, 5)
        ENG.SetIntervals(intervals)

        colours = [wx.BLACK]*3
        colours.append(wx.RED)
        ENG.SetIntervalColours(colours)

        ticks = ["140", "", "210", "", "280"]
        ENG.SetTicks(ticks)
        ENG.SetTicksColour(wx.RED)

        ENG.SetHandColour(wx.Colour(255, 255, 0))
        ENG.SetSpeedBackground(wx.BLACK)        
        #ENG.SetArcColour(wx.RED)
        ENG.SetTicksFont(wx.Font(7, wx.SWISS, wx.NORMAL, wx.NORMAL))        
        ENG.SetSpeedValue(0)
        ENG.SetDirection("Reverse")
#INDICATORS-------------------------------------------------------------------------------------------------------------

        CEL_ON = wx.Image('Images/cel_on.gif', wx.BITMAP_TYPE_ANY)
        CEL_OFF = wx.Image('Images/cel_off.ico', wx.BITMAP_TYPE_ANY)
        LOWFUEL_ON = wx.Image('Images/fuel_on.gif', wx.BITMAP_TYPE_ANY)
        LOWFUEL_OFF = wx.Image('Images/fuel_off.ico', wx.BITMAP_TYPE_ANY)
        BATTERY_ON = wx.Image('Images/battery_on.gif', wx.BITMAP_TYPE_ANY)
        BATTERY_OFF = wx.Image('Images/battery_off.ico', wx.BITMAP_TYPE_ANY)
        SEATBELT_ON = wx.Image('Images/seatbelt_on.gif', wx.BITMAP_TYPE_ANY)
        SEATBELT_OFF = wx.Image('Images/seatbelt_off.ico', wx.BITMAP_TYPE_ANY)
        UPSHIFT_ON = wx.Image('Images/upshift_on.gif', wx.BITMAP_TYPE_ANY)
        UPSHIFT_OFF = wx.Image('Images/upshift_off.ico', wx.BITMAP_TYPE_ANY)
        TEMP_ON = wx.Image('Images/temp_on.gif', wx.BITMAP_TYPE_ANY)
        TEMP_OFF = wx.Image('Images/temp_off.ico', wx.BITMAP_TYPE_ANY)
        PBRAKE_ON = wx.Image('Images/brake_on.gif', wx.BITMAP_TYPE_ANY)
        PBRAKE_OFF = wx.Image('Images/brake_off.ico', wx.BITMAP_TYPE_ANY)
        LIGHTS_ON = wx.Image('Images/light_on.gif', wx.BITMAP_TYPE_ANY)
        LIGHTS_OFF = wx.Image('Images/light_off.ico', wx.BITMAP_TYPE_ANY)

        imageBitmap = wx.StaticBitmap(INDpanel1, wx.ID_ANY, wx.BitmapFromImage(CEL_ON))
        imageBitmap = wx.StaticBitmap(INDpanel2, wx.ID_ANY, wx.BitmapFromImage(LOWFUEL_ON))
        imageBitmap = wx.StaticBitmap(INDpanel3, wx.ID_ANY, wx.BitmapFromImage(BATTERY_ON))
        imageBitmap = wx.StaticBitmap(INDpanel4, wx.ID_ANY, wx.BitmapFromImage(SEATBELT_ON))
        imageBitmap = wx.StaticBitmap(INDpanel5, wx.ID_ANY, wx.BitmapFromImage(UPSHIFT_ON))
        imageBitmap = wx.StaticBitmap(INDpanel6, wx.ID_ANY, wx.BitmapFromImage(TEMP_ON))
        imageBitmap = wx.StaticBitmap(INDpanel7, wx.ID_ANY, wx.BitmapFromImage(PBRAKE_ON))
        imageBitmap = wx.StaticBitmap(INDpanel8, wx.ID_ANY, wx.BitmapFromImage(LIGHTS_ON))


        imageBitmap = wx.StaticBitmap(INDpanel1, wx.ID_ANY, wx.BitmapFromImage(CEL_OFF))
        imageBitmap = wx.StaticBitmap(INDpanel2, wx.ID_ANY, wx.BitmapFromImage(LOWFUEL_OFF))
        imageBitmap = wx.StaticBitmap(INDpanel3, wx.ID_ANY, wx.BitmapFromImage(BATTERY_OFF))
        imageBitmap = wx.StaticBitmap(INDpanel4, wx.ID_ANY, wx.BitmapFromImage(SEATBELT_OFF))
        imageBitmap = wx.StaticBitmap(INDpanel5, wx.ID_ANY, wx.BitmapFromImage(UPSHIFT_OFF))
        imageBitmap = wx.StaticBitmap(INDpanel6, wx.ID_ANY, wx.BitmapFromImage(TEMP_OFF))
        imageBitmap = wx.StaticBitmap(INDpanel7, wx.ID_ANY, wx.BitmapFromImage(PBRAKE_OFF))
        imageBitmap = wx.StaticBitmap(INDpanel8, wx.ID_ANY, wx.BitmapFromImage(LIGHTS_OFF))







APP=wx.App(0)

frame=MyFrame(None)
APP.SetTopWindow(frame)
frame.Show()
APP.MainLoop() 

1 个答案:

答案 0 :(得分:1)

您可以在GUI启动的线程中运行序列代码。我怀疑串行代码会阻止UI的主循环。如果你走这条路,那么你需要使用线程安全的方法将结果传回wxPython,例如wx.CallAfterwx.PostEvent。以下是一些显示如何在wxPython中使用线程的链接:

无论您调用哪种方法来更新UI,您都可以使用它来更新SQLite数据库。我会使用此方法插入从串行代码中收到的任何数据。您可以向UI __init__添加一个不同的方法来检查数据库是否已创建,如果没有,则为您创建。

以下文章可以帮助您将SQLite集成到您的wx应用程序中:

您可以从数据库中查询并在SQLite规范的限制内写入。我不确定您为什么要读取和写入打开的文件,但我发现此链接可能有所帮助: