Skip to content

Commit 7709f83

Browse files
Rename can_logger/player.py to canlogger/player
Move can_logger.py to module can.io.logger Move can_player.py to module can.io.player Make entry points canplayer and canlogger Move Logger and LogReader classes to logger.py and player.py
1 parent 1629ebc commit 7709f83

5 files changed

Lines changed: 144 additions & 96 deletions

File tree

can/io/__init__.py

Lines changed: 2 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3,74 +3,10 @@
33
and Writers based off the file extension.
44
"""
55

6+
from .logger import Logger
7+
from .player import LogReader
68
from .asc import ASCWriter
79
from .blf import BLFReader, BLFWriter
810
from .csv import CSVWriter
911
from .sqlite import SqlReader, SqliteWriter
1012
from .stdout import Printer
11-
12-
13-
class Logger(object):
14-
"""
15-
Logs CAN messages to a file.
16-
17-
The format is determined from the file format which can be one of:
18-
* .asc: :class:`can.ASCWriter`
19-
* .blf :class:`can.BLFWriter`
20-
* .csv: :class:`can.CSVWriter`
21-
* .db: :class:`can.SqliteWriter`
22-
* other: :class:`can.Printer`
23-
24-
Note this class itself is just a dispatcher,
25-
an object that inherits from Listener will
26-
be created when instantiating this class.
27-
"""
28-
29-
@classmethod
30-
def __new__(cls, other, filename):
31-
if not filename:
32-
return Printer()
33-
elif filename.endswith(".asc"):
34-
return ASCWriter(filename)
35-
elif filename.endswith(".blf"):
36-
return BLFWriter(filename)
37-
elif filename.endswith(".csv"):
38-
return CSVWriter(filename)
39-
elif filename.endswith(".db"):
40-
return SqliteWriter(filename)
41-
else:
42-
return Printer(filename)
43-
44-
45-
class LogReader(object):
46-
"""
47-
Replay logged CAN messages from a file.
48-
49-
The format is determined from the file format which can be one of:
50-
* .asc
51-
* .blf
52-
* .csv
53-
* .db
54-
55-
Exposes a simple iterator interface, to use simply:
56-
57-
>>> for m in LogReader(my_file):
58-
... print(m)
59-
60-
Note there are no time delays, if you want to reproduce
61-
the measured delays between messages look at the
62-
:class:`can.util.MessageSync` class.
63-
"""
64-
65-
@classmethod
66-
def __new__(cls, other, filename):
67-
if filename.endswith(".asc"):
68-
raise NotImplemented
69-
# return ASCReader(filename)
70-
if filename.endswith(".blf"):
71-
return BLFReader(filename)
72-
if filename.endswith(".csv"):
73-
raise NotImplemented
74-
# return CSVReader(filename)
75-
if filename.endswith(".db"):
76-
return SqlReader(filename)
Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
#!/usr/bin/env python
22
"""
3-
can_logger.py logs CAN traffic to the terminal and to a file on disk.
3+
logger.py logs CAN traffic to the terminal and to a file on disk.
44
5-
can_logger.py can0
5+
logger.py can0
66
77
See candump in the can-utils package for a C implementation.
88
Efficient filtering has been implemented for the socketcan backend.
99
For example the command
1010
11-
can_logger.py can0 F03000:FFF000
11+
logger.py can0 F03000:FFF000
1212
1313
Will filter for can frames with a can_id containing XXF03XXX.
1414
@@ -22,8 +22,46 @@
2222

2323
import can
2424

25-
if __name__ == "__main__":
26-
25+
from .asc import ASCWriter
26+
from .blf import BLFWriter
27+
from .csv import CSVWriter
28+
from .sqlite import SqliteWriter
29+
from .stdout import Printer
30+
31+
32+
class Logger(object):
33+
"""
34+
Logs CAN messages to a file.
35+
36+
The format is determined from the file format which can be one of:
37+
* .asc: :class:`can.ASCWriter`
38+
* .blf :class:`can.BLFWriter`
39+
* .csv: :class:`can.CSVWriter`
40+
* .db: :class:`can.SqliteWriter`
41+
* other: :class:`can.Printer`
42+
43+
Note this class itself is just a dispatcher,
44+
an object that inherits from Listener will
45+
be created when instantiating this class.
46+
"""
47+
48+
@classmethod
49+
def __new__(cls, other, filename):
50+
if not filename:
51+
return Printer()
52+
elif filename.endswith(".asc"):
53+
return ASCWriter(filename)
54+
elif filename.endswith(".blf"):
55+
return BLFWriter(filename)
56+
elif filename.endswith(".csv"):
57+
return CSVWriter(filename)
58+
elif filename.endswith(".db"):
59+
return SqliteWriter(filename)
60+
else:
61+
return Printer(filename)
62+
63+
64+
def main():
2765
parser = argparse.ArgumentParser(description="Log CAN traffic, printing messages to stdout or to a given file")
2866

2967
parser.add_argument("-f", "--file_name", dest="log_file",
@@ -70,7 +108,7 @@
70108

71109
bus = can.interface.Bus(results.channel, bustype=results.interface, can_filters=can_filters)
72110
print('Can Logger (Started on {})\n'.format(datetime.datetime.now()))
73-
logger = can.Logger(results.log_file)
111+
logger = Logger(results.log_file)
74112
notifier = can.Notifier(bus, [logger], timeout=0.1)
75113

76114
try:
@@ -79,3 +117,6 @@
79117
except KeyboardInterrupt:
80118
bus.shutdown()
81119
notifier.stop()
120+
121+
if __name__ == "__main__":
122+
main()
Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python
22
"""
3-
can_player.py replays CAN traffic saved with can_logger.py back
3+
player.py replays CAN traffic saved with logger.py back
44
to a CAN bus.
55
66
Similar to canplayer in the can-utils package.
@@ -11,9 +11,40 @@
1111

1212
import can
1313
from can.util import MessageSync
14+
from .blf import BLFReader
15+
from .sqlite import SqlReader
1416

15-
if __name__ == "__main__":
1617

18+
class LogReader(object):
19+
"""
20+
Replay logged CAN messages from a file.
21+
22+
The format is determined from the file format which can be one of:
23+
* .asc
24+
* .blf
25+
* .csv
26+
* .db
27+
28+
Exposes a simple iterator interface, to use simply:
29+
30+
>>> for m in LogReader(my_file):
31+
... print(m)
32+
33+
Note there are no time delays, if you want to reproduce
34+
the measured delays between messages look at the
35+
:class:`can.util.MessageSync` class.
36+
"""
37+
38+
@classmethod
39+
def __new__(cls, other, filename):
40+
if filename.endswith(".blf"):
41+
return BLFReader(filename)
42+
if filename.endswith(".db"):
43+
return SqlReader(filename)
44+
raise NotImplementedError("No read support for this log format")
45+
46+
47+
def main():
1748
parser = argparse.ArgumentParser(description="Replay CAN traffic")
1849

1950
parser.add_argument("-f", "--file_name", dest="log_file",
@@ -55,7 +86,7 @@
5586

5687
bus = can.interface.Bus(results.channel, bustype=results.interface)
5788

58-
player = can.LogReader(results.infile)
89+
player = LogReader(results.infile)
5990

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

@@ -70,3 +101,6 @@
70101
finally:
71102
bus.shutdown()
72103

104+
105+
if __name__ == "__main__":
106+
main()

doc/bin.rst

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,82 @@ Scripts
33

44
The following scripts are installed along with python-can.
55

6-
can_logger.py
7-
-------------
6+
canlogger
7+
---------
88

9-
Command line help (``--help``)::
9+
Command line help (``canlogger --help`` or ``python -m can.io.logger --help``)::
1010

11-
usage: can_logger.py [-h] [-f LOG_FILE] [-v] [-i {socketcan,kvaser,serial,ixxat}]
12-
channel ...
11+
usage: canlogger [-h] [-f LOG_FILE] [-v] [-c CHANNEL]
12+
[-i {pcan,remote,ixxat,socketcan_ctypes,virtual,usb2can,nican,serial,kvaser,socketcan,socketcan_native}]
13+
[--filter ...]
1314

1415
Log CAN traffic, printing messages to stdout or to a given file
1516

16-
positional arguments:
17-
channel Most backend interfaces require some sort of channel.
17+
optional arguments:
18+
-h, --help show this help message and exit
19+
-f LOG_FILE, --file_name LOG_FILE
20+
Path and base log filename, extension can be .txt,
21+
.asc, .csv, .db, .npz
22+
-v How much information do you want to see at the command
23+
line? You can add several of these e.g., -vv is DEBUG
24+
-c CHANNEL, --channel CHANNEL
25+
Most backend interfaces require some sort of channel.
1826
For example with the serial interface the channel
19-
might be a rfcomm device: /dev/rfcomm0 Other channel
20-
examples are: can0, vcan0
21-
filter Comma separated filters can be specified for the given
27+
might be a rfcomm device: "/dev/rfcomm0" With the
28+
socketcan interfaces valid channel examples include:
29+
"can0", "vcan0"
30+
-i {pcan,remote,ixxat,socketcan_ctypes,virtual,usb2can,nican,serial,kvaser,socketcan,socketcan_native}, --interface {pcan,remote,ixxat,socketcan_ctypes,virtual,usb2can,nican,serial,kvaser,socketcan,socketcan_native}
31+
Specify the backend CAN interface to use. If left
32+
blank, fall back to reading from configuration files.
33+
--filter ... Comma separated filters can be specified for the given
2234
CAN interface: <can_id>:<can_mask> (matches when
2335
<received_can_id> & mask == can_id & mask)
2436
<can_id>~<can_mask> (matches when <received_can_id> &
2537
mask != can_id & mask)
2638

39+
40+
canplayer
41+
---------
42+
43+
Command line help (``canplayer --help`` or ``python -m can.io.player --help``)::
44+
45+
usage: canplayer [-h] [-f LOG_FILE] [-v] [-c CHANNEL]
46+
[-i {pcan,remote,ixxat,socketcan_ctypes,virtual,usb2can,nican,serial,kvaser,socketcan,socketcan_native}]
47+
[--ignore-timestamps] [-g GAP] [-s SKIP]
48+
input-file
49+
50+
Replay CAN traffic
51+
52+
positional arguments:
53+
input-file The file to replay. Supported types: .db
54+
2755
optional arguments:
2856
-h, --help show this help message and exit
2957
-f LOG_FILE, --file_name LOG_FILE
3058
Path and base log filename, extension can be .txt,
31-
.csv, .db, .npz
32-
-v How much information do you want to see at the command
33-
line? You can add several of these e.g., -vv is DEBUG
34-
-i {socketcan,kvaser,serial,ixxat}, --interface {socketcan,kvaser,serial,ixxat}
35-
Which backend do you want to use?
59+
.asc, .csv, .db, .npz
60+
-v Also print can frames to stdout. You can add several
61+
of these to enable debugging
62+
-c CHANNEL, --channel CHANNEL
63+
Most backend interfaces require some sort of channel.
64+
For example with the serial interface the channel
65+
might be a rfcomm device: "/dev/rfcomm0" With the
66+
socketcan interfaces valid channel examples include:
67+
"can0", "vcan0"
68+
-i {pcan,remote,ixxat,socketcan_ctypes,virtual,usb2can,nican,serial,kvaser,socketcan,socketcan_native}, --interface {pcan,remote,ixxat,socketcan_ctypes,virtual,usb2can,nican,serial,kvaser,socketcan,socketcan_native}
69+
Specify the backend CAN interface to use. If left
70+
blank, fall back to reading from configuration files.
71+
--ignore-timestamps Ignore timestamps (send all frames immediately with
72+
minimum gap between frames)
73+
-g GAP, --gap GAP <ms> minimum time between replayed frames
74+
-s SKIP, --skip SKIP <s> skip gaps greater than 's' seconds
75+
3676

3777

3878
canserver
3979
---------
4080

41-
Command line help (``--help``)::
81+
Command line help (``canserver --help`` or ``python -m can.interfaces.remote --help``)::
4282

4383
usage: canserver [-h] [-v] [-c CHANNEL]
4484
[-i {pcan,remote,ixxat,socketcan_ctypes,virtual,usb2can,nican,serial,kvaser,socketcan,socketcan_native}]

setup.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,9 @@
2323
"": ["CONTRIBUTORS.txt", "LICENSE.txt"],
2424
"doc": ["*.*"]
2525
},
26-
27-
scripts=[
28-
"./bin/can_logger.py",
29-
"./bin/can_player.py"
30-
],
3126
entry_points={"console_scripts": [
27+
"canlogger = can.io.logger:main",
28+
"canplayer = can.io.player:main",
3229
"canserver = can.interfaces.remote.__main__:main"
3330
]},
3431

0 commit comments

Comments
 (0)