Skip to content

Instantly share code, notes, and snippets.

@knoguchi
Last active June 4, 2017 16:32
Show Gist options
  • Save knoguchi/4fc486a0cc39c1fd256d2fb6f619ee98 to your computer and use it in GitHub Desktop.
Save knoguchi/4fc486a0cc39c1fd256d2fb6f619ee98 to your computer and use it in GitHub Desktop.
import re
import argparse
from collections import namedtuple
class Record:
def __init__(self, crtime=0.00000, ch=1, hexid=0x000, dir="Rx", stat="d", data=None, length=0, bitcount=0, decid=0):
self.crtime = crtime
self.ch = ch
self.hexid = hexid
self.dir = dir
self.stat = stat
self.data = data or []
self.length = length
self.bitcount = bitcount
self.decid = decid
@property
def dlc(self):
return len(self.data)
@classmethod
def parse_from_file(cls, input_file):
"""
The log format is fixed header fields, variable length data, ordered key-value pairs
header fields: crtime, ch, hexid, dir, stat, dlc
variable data: byte * dlc
"""
HEADER_TYPES = (
('crtime', float),
('ch', int),
('hexid', lambda s: int(s, 16)),
('dir', str),
('stat', str),
('dlc', int),
)
HEADER_LENGTH = len(HEADER_TYPES)
Header = namedtuple("Header", [field for field, _ in HEADER_TYPES])
for line in input_file:
fields = line.split()
if not re.match("1|2", fields[1]):
# ignore non-data rows
continue
# extract header
header_values = fields[:HEADER_LENGTH]
header_values = [func(value) for (field, func), value in zip(HEADER_TYPES, header_values)]
header = Header(*header_values)
# extract data
data = map(lambda x: int(x, 16), fields[HEADER_LENGTH:][:header.dlc])
# extract trailer
length = fields[-7]
bitcount = fields[-4]
decid = fields[-1]
yield cls(
crtime=header.crtime,
ch=header.ch,
hexid=header.hexid,
dir=header.dir,
stat=header.stat,
data=data,
length=length,
bitcount=bitcount,
decid=decid
)
def __str__(self):
return '%f %d %03X %s %d %s' % (
self.crtime, self.ch, self.hexid, self.dir, self.dlc,
' '.join(["%02X" % byte for byte in self.data])
)
def main():
parser = argparse.ArgumentParser(description='CanlogFilter')
parser.add_argument('inputFile', help='Input file path')
parser.add_argument('--difftime', '-d', action='store_const', const=True, default=False, help='Print with difftime')
group = parser.add_mutually_exclusive_group()
group.add_argument('--pickup', '-u', nargs='*', type=lambda x: int(x, 16), help='pick up records')
group.add_argument('--dropoff', '-o', nargs='*', type=lambda x: int(x, 16), help='drop off records')
args = parser.parse_args()
with open(args.inputFile) as input_file:
canlog = Record.parse_from_file(input_file)
if args.pickup:
canlog = pick_log(canlog, args.pickup)
elif args.dropoff:
canlog = drop_log(canlog, args.dropoff)
if args.difftime:
printlog_with_diff_time(canlog)
else:
printlog(canlog)
def pick_log(canlog, ids):
return filter(lambda rec: rec.hexid in ids, canlog)
def drop_log(canlog, ids):
return filter(lambda rec: rec.hexid not in ids, canlog)
def printlog(canlog):
for rec in canlog:
print rec
def printlog_with_diff_time(canlog):
prevtime = 0
for rec in canlog:
difftime = rec.crtime - prevtime
print '%f %s' % (difftime, rec)
prevtime = rec.crtime
if __name__ == '__main__': main()
@knoguchi
Copy link
Author

knoguchi commented Jun 4, 2017

48行目はPython2でしか動かない。Python3では入れ子のタプルの展開ができなくなったため。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment