2016-10-08 4 views
0

Работая над проектом мониторинга, мне нужно подсчитать импульсы от счетчиков импульсов. Я уже нашел некоторые решения, которые я пытался адаптировать к моим потребностям.Python, получающий последнюю строку

Вот питон скрипт, работающий на Raspberry Pi:

#!/usr/bin/env python 

import RPi.GPIO as GPIO 
import datetime 
import sys 
import signal 
from subprocess import check_output 

#verbose = True  # global variable 

############################################################################################################ 
############################################################################################################ 

def printusage(progname): 
     print progname + ' <gpio-pin-number> <filename> [debug]' 
     print 'Example usage: ' 
    print progname + ' 23 /path/to/mylogfile' 
     print progname + ' 23 /path/to/mylogfile debug' 
    sys.exit(-1) 

def signal_handler(signal, frame): 
     if verbose: 
     print('You pressed Ctrl+C, so exiting') 
    GPIO.cleanup() 
     sys.exit(0) 


def readvalue(myworkfile): 
    try: 
     f = open(myworkfile, 'ab+')  # open for reading. If it does not exist, create it 
     line=subprocess.check_output(['tail','-f','-1',f]) 
     elmts=line.split(" ") 
     value = int(elmts[2]) 
    except: 
     value = 0    # if something went wrong, reset to 0 
    #print "old value is", value 
    f.close() # close for reading 
    return value 


def writevalue(myworkfile,value): 
    f = open(myworkfile, 'a') 
    f.write((str(datetime.datetime.now())+' '+str(value)+'\r\n')) # timestamp 
    f.close() 

############################################################################################################ 
############################################################################################################ 

######### Initialization 


#### get input parameters: 

try: 
    mygpiopin = int(sys.argv[1]) 
    logfile = sys.argv[2] 
except: 
    printusage(sys.argv[0]) 

verbose = False 
try: 
    if sys.argv[3] == 'debug': 
     verbose = True 
     print "Verbose is On" 
    else: 
     printusage(sys.argv[0]) 
except: 
    pass 

#### if verbose, print some info to stdout 

if verbose: 
    print "GPIO is " + str(mygpiopin) 
    print "Logfile is " + logfile 
    print "Current value is " + str(readvalue(logfile)) 


#### setup 

GPIO.setmode(GPIO.BCM) 
GPIO.setup(mygpiopin, GPIO.IN, pull_up_down = GPIO.PUD_DOWN) 

signal.signal(signal.SIGINT, signal_handler) # SIGINT = interrupt by CTRL-C 


########## Main Loop 

while True: 
    # wait for pin going up 
    GPIO.wait_for_edge(mygpiopin, GPIO.RISING) 

    # read value from file 
    counter=readvalue(logfile) + 1 
    if verbose: 
     print "New value is", counter 

    # write value to file 
    writevalue(logfile,counter) 

    # and wait for pin going down 
    GPIO.wait_for_edge(mygpiopin, GPIO.FALLING) 

############################################################################################################ 
############################################################################################################ 

Я хочу, чтобы получить последний индекс зарегистрирован, и увеличить его, но все, что я опробованный до сих пор оставляет петлю наклеенную на index of 1.

Я не могу использовать «более тяжелый» метод для поиска последней строки, например, просмотра всего файла, потому что с течением времени он будет становиться все тяжелее и тяжелее, и я не могу пропустить пульс.

Я довольно новичок в программировании, поэтому благодарим за помощь!

EDIT: файл результат выглядит следующим образом:

2016-10-08 16:54:23.072469 1 
2016-10-08 16:54:23.462465 1 
2016-10-08 16:54:23.777977 1 
2016-10-08 16:54:24.010045 1 
2016-10-08 16:54:24.194032 1 
2016-10-08 16:54:24.388120 1 
2016-10-08 16:54:24.549389 1 
2016-10-08 16:54:24.737994 1 
2016-10-08 16:54:24.959462 1 
2016-10-08 16:54:25.164638 1 
2016-10-08 16:54:25.351850 1 
2016-10-08 16:54:25.536655 1 
2016-10-08 16:54:25.716214 1 
2016-10-08 16:54:25.794152 1 
2016-10-08 17:06:13.506531 1 
2016-10-08 17:06:14.097642 1 
2016-10-08 17:06:14.211579 1 
2016-10-08 17:06:15.237852 1 
2016-10-08 17:06:15.752239 1 
2016-10-08 17:06:16.320419 1 
2016-10-08 17:06:16.842906 1 
2016-10-08 17:06:17.391121 1 
2016-10-08 17:06:17.851521 1 
2016-10-08 17:06:18.444486 1 
2016-10-08 17:06:18.858358 1 
+0

Почему вы используете подпроцесс для чтения файла? Хуже того, почему вы передаете ему файл-объект? –

+0

Вы смешиваете вкладки и пробелы. Вероятно, это не причина ваших текущих проблем, но определенно причина ваших будущих проблем. Не делай этого. Используйте только пробелы. Настройте свой редактор, чтобы вставить 4 пробела, когда вы нажимаете вкладку. – zvone

+0

Также почему вы 'line.split (" ")' и получаете третий элемент? Все, что вы пишете, это 'str (datetime.datetime.now()) + '' + str (value) + '\ r \ n')' поэтому не более двух элементов –

ответ

0

Чтобы прочитать последнюю строку большого файла, выбрать позицию ближе к концу файла и читать. Если там нет новых строк, вернитесь немного и прочитайте снова.

Затем найдите последнюю строку новой строки, а остальная часть - ваша последняя строка.

EXPECTED_MAX_LINE_SIZE = 500 # this should be both small enough and big enough 

def get_last_line(f): 
    end = f.seek(0, os.SEEK_END) # detect file size 
    pos = end-EXPECTED_MAX_LINE_SIZE 
    if pos < 0: pos = 0 
    f.seek(pos, os.SEEK_SET) 
    end_of_file = f.read(EXPECTED_MAX_LINE_SIZE) 

    # TODO: check if '\n' is not there and read some more 

    return end_of_file.splitlines()[-1] 
0

Ваша логика путь более сложная, если вы будете запускать скрипт в разное время просто сохранить последний индекс в отдельном файл постоянно перезаписана:

def next_index(index): 
    with open(index, 'a+') as f: # open for reading. If it does not exist, create it 
     val = int(next(f, -1)) + 1 # first run value will be 0 
    open(index,"w").write(str(val)) # overwrite 
    return val 

если значение создаются в другом месте просто сделать написав там, просто убедитесь, что вы перезаписали предыдущее значение с w.

0

Я не думаю, что это то, что имел в виду Padraic Cunningham, но мне удалось решить мою проблему с помощью двух файлов, один для входа обновленное значение индекса, и один для хранения значений:

#!/usr/bin/env python 

import RPi.GPIO as GPIO 
import datetime 
import sys 
import signal 

#verbose = True  # global debug variable 

############################################################################################################ 

def printusage(progname): #show how to use the script 
    print progname + ' <gpio-pin-number> <index file> <store file> [debug]' 
    print 'Example usage: ' 
    print progname + ' 23 /path/to/mylogfile /path/to/storefile' 
    print progname + ' 23 /path/to/mylogfile /path/to/storefile debug' 
    sys.exit(-1) 

def signal_handler(signal, frame): #exiting the script 
    if verbose: 
     print('You pressed Ctrl+C, so exiting') 
    GPIO.cleanup() 
    sys.exit(0) 


def readvalue(myworkfile): 
    try: 
     f = open(myworkfile, 'ab+')  # open for reading. If it does not exist, create it 
     line=f.readline() #read the first and only line of the file 
     elmts=line.split(" ") # the format is <yyyy-mm-dd hh:mm:ss.ssssss indexvalue> 
     value = int(elmts[2]) #get the index value 
    except: 
     value = 0    # if something went wrong, reset to 0 
    #print "old value is", value 
    f.close() # close for reading 
    return value 


def writevalue(myworkfile,value): 
    f = open(myworkfile, 'w') #overwrite the value 
    f.write((str(datetime.datetime.now())+' '+str(value))) # timestamp + data 
    f.close() 

def store_value(index_file,index_value): 
    f=open(index_file, 'a+') 
    f.write(str(datetime.datetime.now())+' '+str(index_value)+'\r\n') #store timestamp + data 
    f.close() 

############################################################################################################ 

######### Initialization 
#### get input parameters 
try: 
    mygpiopin = int(sys.argv[1]) 
    logfile = sys.argv[2] 
    storefile=sys.argv[3] 
except: 
    printusage(sys.argv[0]) 

verbose = False 
try: 
    if sys.argv[4] == 'debug': 
     verbose = True 
     print "Verbose is On" 
    else: 
     printusage(sys.argv[0]) 
except: 
    pass 

if verbose: #### if verbose, print some info to stdout 
    print "GPIO is " + str(mygpiopin) 
    print "Logfile is " + logfile 
    print "Storefile is " + storefile 
    print "Current value is " + str(readvalue(logfile)) 

#### SETUP 
GPIO.setmode(GPIO.BCM) 
GPIO.setup(mygpiopin, GPIO.IN, pull_up_down = GPIO.PUD_DOWN) 
signal.signal(signal.SIGINT, signal_handler) # SIGINT = interrupt by CTRL-C 

########## Main Loop ##### 

while True: 
    GPIO.wait_for_edge(mygpiopin, GPIO.RISING) # wait for pin going up 
    counter=readvalue(logfile) + 1 # read value from file and increment index 
    if verbose: 
     print "New value is", counter 
    writevalue(logfile,counter) # write value to logfile 
    store_value(storefile,counter) # store value in storefile 
    GPIO.wait_for_edge(mygpiopin, GPIO.FALLING) # and wait for pin going down 
############################################################################################################ 

Спасибо за помощь!

+0

* Я не думаю, что это было что Padraic Cunningham означало, что это именно то, что я имел в виду. ** сохранить последний индекс в отдельном файле ** –

+0

Не уверен, что я понял вас правильно, спасибо еще раз! – NyuengBo

Смежные вопросы