Python 将三个脚本合并为一个脚本

Python 将三个脚本合并为一个脚本,python,multithreading,sqlite,wxpython,pyserial,Python,Multithreading,Sqlite,Wxpython,Pyserial,我制作了三个脚本,在我看来,它们代表了程序必须完成的三件事 第一个脚本不断读取传入的串行端口,并将所有信息写入一个文件,我这样做是因为我不确定部署设备中串行缓冲区的大小,从串行端口收集每一条信息是至关重要的。为了将其合并到一个单独的文件中,我简要地阅读了pythons线程功能,但我没有研究python线程是什么,但是部署设备目前只是一个单核心设备,如果这对python线程来说很重要的话 第二段代码用于验证和解析由第一个脚本创建的文件,并将其放入SQLite数据库 第三个文件是用python编写的

我制作了三个脚本,在我看来,它们代表了程序必须完成的三件事

第一个脚本不断读取传入的串行端口,并将所有信息写入一个文件,我这样做是因为我不确定部署设备中串行缓冲区的大小,从串行端口收集每一条信息是至关重要的。为了将其合并到一个单独的文件中,我简要地阅读了pythons线程功能,但我没有研究python线程是什么,但是部署设备目前只是一个单核心设备,如果这对python线程来说很重要的话

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

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

虽然我确信很多这样做是低效的,但这也不是我真正想要的方式,但我一直在尝试从python论坛获得帮助,而且这种帮助有点不存在

首要任务是确保所有数据都是从串行端口收集的,然后需要存储在数据库中,用于数据记录,我更希望在将数据存储在数据库中的同时在显示器上显示数据,但我认为这会造成太多的延迟,通过这种方式使用代码,我可以将显示放在计时器上,每隔250ms我可以根据数据库中的下一个信息更新显示

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

指向我应该研究的方法的建议和直接的回答一样受欢迎,我真的非常感谢所有的帮助

串行刮码:

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

您可以在GUI启动的线程中运行串行代码。我怀疑串行代码会阻止UI的主循环。如果您这样做,则需要使用线程安全方法将结果传回wxPython,例如
wx.CallAfter
wx.PostEvent
。以下是几个链接,展示了如何在wxPython中使用线程:

无论调用什么方法来更新UI,都可以使用它来更新SQLite数据库。我将使用此方法插入从串行代码接收的任何数据。您可以向UI的
\uuuu init\uuuu
中添加一个不同的方法,该方法检查数据库是否已创建,如果未创建,则为您创建数据库

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

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


你为什么要否决这个问题?它的合法性受到质疑了吗?我很感谢你的回复,关于线程的信息很可能正是我想要的,我会尝试一些代码,看看它是否有效,
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()