Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 0 additions & 96 deletions can/io/logger.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,3 @@
#!/usr/bin/env python
"""
logger.py logs CAN traffic to the terminal and to a file on disk.

logger.py can0

See candump in the can-utils package for a C implementation.
Efficient filtering has been implemented for the socketcan backend.
For example the command

logger.py can0 F03000:FFF000

Will filter for can frames with a can_id containing XXF03XXX.

Dynamic Controls 2010
"""
from __future__ import print_function
import datetime
import argparse
import time
import socket

import can

from .asc import ASCWriter
from .blf import BLFWriter
from .csv import CSVWriter
Expand Down Expand Up @@ -59,75 +35,3 @@ def __new__(cls, other, filename):
return SqliteWriter(filename)
else:
return Printer(filename)


def main():
parser = argparse.ArgumentParser(description="Log CAN traffic, printing messages to stdout or to a given file")

parser.add_argument("-f", "--file_name", dest="log_file",
help="""Path and base log filename, extension can be .txt, .asc, .csv, .db, .npz""",
default=None)

parser.add_argument("-v", action="count", dest="verbosity",
help='''How much information do you want to see at the command line?
You can add several of these e.g., -vv is DEBUG''', default=2)

parser.add_argument('-c', '--channel', help='''Most backend interfaces require some sort of channel.
For example with the serial interface the channel might be a rfcomm device: "/dev/rfcomm0"
With the socketcan interfaces valid channel examples include: "can0", "vcan0"''')

parser.add_argument('-i', '--interface', dest="interface",
help='''Specify the backend CAN interface to use. If left blank,
fall back to reading from configuration files.''',
choices=can.VALID_INTERFACES)

parser.add_argument('--filter', help='''Comma separated filters can be specified for the given CAN interface:
<can_id>:<can_mask> (matches when <received_can_id> & mask == can_id & mask)
<can_id>~<can_mask> (matches when <received_can_id> & mask != can_id & mask)
''', nargs=argparse.REMAINDER, default='')

parser.add_argument('-b', '--bitrate', type=int,
help='''Bitrate to use for the CAN bus.''')

results = parser.parse_args()

verbosity = results.verbosity

logging_level_name = ['critical', 'error', 'warning', 'info', 'debug', 'subdebug'][min(5, verbosity)]
can.set_logging_level(logging_level_name)

can_filters = []
if len(results.filter) > 0:
print('Adding filter/s', results.filter)
for filt in results.filter:
if ':' in filt:
_ = filt.split(":")
can_id, can_mask = int(_[0], base=16), int(_[1], base=16)
elif "~" in filt:
can_id, can_mask = filt.split("~")
can_id = int(can_id, base=16) | 0x20000000 # CAN_INV_FILTER
can_mask = int(can_mask, base=16) & socket.CAN_ERR_FLAG
can_filters.append({"can_id": can_id, "can_mask": can_mask})

config = {"can_filters": can_filters}
if results.interface:
config["bustype"] = results.interface
if results.bitrate:
config["bitrate"] = results.bitrate
bus = can.interface.Bus(results.channel, **config)
print('Can Logger (Started on {})\n'.format(datetime.datetime.now()))
logger = Logger(results.log_file)

try:
while True:
msg = bus.recv(1)
if msg is not None:
logger(msg)
except KeyboardInterrupt:
pass
finally:
bus.shutdown()
logger.stop()

if __name__ == "__main__":
main()
82 changes: 0 additions & 82 deletions can/io/player.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
#!/usr/bin/env python
"""
player.py replays CAN traffic saved with logger.py back
to a CAN bus.

Similar to canplayer in the can-utils package.
"""
from __future__ import print_function
import datetime
import time
import argparse
import logging

import can
from .blf import BLFReader
from .sqlite import SqlReader

Expand Down Expand Up @@ -84,75 +74,3 @@ def __iter__(self):

time.sleep(sleep_period)
yield m


def main():
parser = argparse.ArgumentParser(description="Replay CAN traffic")

parser.add_argument("-f", "--file_name", dest="log_file",
help="""Path and base log filename, extension can be .txt, .asc, .csv, .db, .npz""",
default=None)

parser.add_argument("-v", action="count", dest="verbosity",
help='''Also print can frames to stdout.
You can add several of these to enable debugging''', default=2)

parser.add_argument('-c', '--channel',
help='''Most backend interfaces require some sort of channel.
For example with the serial interface the channel might be a rfcomm device: "/dev/rfcomm0"
With the socketcan interfaces valid channel examples include: "can0", "vcan0"''')

parser.add_argument('-i', '--interface', dest="interface",
help='''Specify the backend CAN interface to use. If left blank,
fall back to reading from configuration files.''',
choices=can.VALID_INTERFACES)

parser.add_argument('-b', '--bitrate', type=int,
help='''Bitrate to use for the CAN bus.''')

parser.add_argument('--ignore-timestamps', dest='timestamps',
help='''Ignore timestamps (send all frames immediately with minimum gap between
frames)''', action='store_false')

parser.add_argument('-g', '--gap', type=float, help='''<ms> minimum time between replayed frames''')
parser.add_argument('-s', '--skip', type=float, default=60*60*24,
help='''<s> skip gaps greater than 's' seconds''')

parser.add_argument('infile', metavar='input-file', type=str,
help='The file to replay. Supported types: .db, .blf')

results = parser.parse_args()

verbosity = results.verbosity
gap = 0.0001 if results.gap is None else results.gap

logging_level_name = ['critical', 'error', 'warning', 'info', 'debug', 'subdebug'][min(5, verbosity)]
can.set_logging_level(logging_level_name)

config = {}
if results.interface:
config["bustype"] = results.interface
if results.bitrate:
config["bitrate"] = results.bitrate
bus = can.interface.Bus(results.channel, **config)

player = LogReader(results.infile)

in_sync = MessageSync(player, timestamps=True, skip=results.skip)

print('Can LogReader (Started on {})'.format(
datetime.datetime.now()))

try:
for m in in_sync:
if verbosity >= 3:
print(m)
bus.send(m)
except KeyboardInterrupt:
pass
finally:
bus.shutdown()


if __name__ == "__main__":
main()
95 changes: 95 additions & 0 deletions can/logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/env python
"""
logger.py logs CAN traffic to the terminal and to a file on disk.

logger.py can0

See candump in the can-utils package for a C implementation.
Efficient filtering has been implemented for the socketcan backend.
For example the command

logger.py can0 F03000:FFF000

Will filter for can frames with a can_id containing XXF03XXX.

Dynamic Controls 2010
"""
from __future__ import print_function
import datetime
import argparse
import socket

import can
from can.io.logger import Logger


def main():
parser = argparse.ArgumentParser(description="Log CAN traffic, printing messages to stdout or to a given file")

parser.add_argument("-f", "--file_name", dest="log_file",
help="""Path and base log filename, extension can be .txt, .asc, .csv, .db, .npz""",
default=None)

parser.add_argument("-v", action="count", dest="verbosity",
help='''How much information do you want to see at the command line?
You can add several of these e.g., -vv is DEBUG''', default=2)

parser.add_argument('-c', '--channel', help='''Most backend interfaces require some sort of channel.
For example with the serial interface the channel might be a rfcomm device: "/dev/rfcomm0"
With the socketcan interfaces valid channel examples include: "can0", "vcan0"''')

parser.add_argument('-i', '--interface', dest="interface",
help='''Specify the backend CAN interface to use. If left blank,
fall back to reading from configuration files.''',
choices=can.VALID_INTERFACES)

parser.add_argument('--filter', help='''Comma separated filters can be specified for the given CAN interface:
<can_id>:<can_mask> (matches when <received_can_id> & mask == can_id & mask)
<can_id>~<can_mask> (matches when <received_can_id> & mask != can_id & mask)
''', nargs=argparse.REMAINDER, default='')

parser.add_argument('-b', '--bitrate', type=int,
help='''Bitrate to use for the CAN bus.''')

results = parser.parse_args()

verbosity = results.verbosity

logging_level_name = ['critical', 'error', 'warning', 'info', 'debug', 'subdebug'][min(5, verbosity)]
can.set_logging_level(logging_level_name)

can_filters = []
if len(results.filter) > 0:
print('Adding filter/s', results.filter)
for filt in results.filter:
if ':' in filt:
_ = filt.split(":")
can_id, can_mask = int(_[0], base=16), int(_[1], base=16)
elif "~" in filt:
can_id, can_mask = filt.split("~")
can_id = int(can_id, base=16) | 0x20000000 # CAN_INV_FILTER
can_mask = int(can_mask, base=16) & socket.CAN_ERR_FLAG
can_filters.append({"can_id": can_id, "can_mask": can_mask})

config = {"can_filters": can_filters}
if results.interface:
config["bustype"] = results.interface
if results.bitrate:
config["bitrate"] = results.bitrate
bus = can.interface.Bus(results.channel, **config)
print('Can Logger (Started on {})\n'.format(datetime.datetime.now()))
logger = Logger(results.log_file)

try:
while True:
msg = bus.recv(1)
if msg is not None:
logger(msg)
except KeyboardInterrupt:
pass
finally:
bus.shutdown()
logger.stop()

if __name__ == "__main__":
main()
85 changes: 85 additions & 0 deletions can/player.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/usr/bin/env python
"""
Replays CAN traffic saved with can.logger back
to a CAN bus.

Similar to canplayer in the can-utils package.
"""
from __future__ import print_function
import argparse
import datetime

import can
from can.io.player import LogReader, MessageSync


def main():
parser = argparse.ArgumentParser(description="Replay CAN traffic")

parser.add_argument("-f", "--file_name", dest="log_file",
help="""Path and base log filename, extension can be .txt, .asc, .csv, .db, .npz""",
default=None)

parser.add_argument("-v", action="count", dest="verbosity",
help='''Also print can frames to stdout.
You can add several of these to enable debugging''', default=2)

parser.add_argument('-c', '--channel',
help='''Most backend interfaces require some sort of channel.
For example with the serial interface the channel might be a rfcomm device: "/dev/rfcomm0"
With the socketcan interfaces valid channel examples include: "can0", "vcan0"''')

parser.add_argument('-i', '--interface', dest="interface",
help='''Specify the backend CAN interface to use. If left blank,
fall back to reading from configuration files.''',
choices=can.VALID_INTERFACES)

parser.add_argument('-b', '--bitrate', type=int,
help='''Bitrate to use for the CAN bus.''')

parser.add_argument('--ignore-timestamps', dest='timestamps',
help='''Ignore timestamps (send all frames immediately with minimum gap between
frames)''', action='store_false')

parser.add_argument('-g', '--gap', type=float, help='''<ms> minimum time between replayed frames''')
parser.add_argument('-s', '--skip', type=float, default=60*60*24,
help='''<s> skip gaps greater than 's' seconds''')

parser.add_argument('infile', metavar='input-file', type=str,
help='The file to replay. Supported types: .db, .blf')

results = parser.parse_args()

verbosity = results.verbosity
gap = 0.0001 if results.gap is None else results.gap

logging_level_name = ['critical', 'error', 'warning', 'info', 'debug', 'subdebug'][min(5, verbosity)]
can.set_logging_level(logging_level_name)

config = {}
if results.interface:
config["bustype"] = results.interface
if results.bitrate:
config["bitrate"] = results.bitrate
bus = can.interface.Bus(results.channel, **config)

player = LogReader(results.infile)

in_sync = MessageSync(player, timestamps=True, skip=results.skip)

print('Can LogReader (Started on {})'.format(
datetime.datetime.now()))

try:
for m in in_sync:
if verbosity >= 3:
print(m)
bus.send(m)
except KeyboardInterrupt:
pass
finally:
bus.shutdown()


if __name__ == "__main__":
main()
File renamed without changes.
Loading