Skip to content

Commit 046fe0b

Browse files
committed
Rewriting the broadcast manager to use bus instead of channel
1 parent 573ee3b commit 046fe0b

4 files changed

Lines changed: 107 additions & 85 deletions

File tree

can/broadcastmanager.py

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,10 @@
1212
log.debug("Loading base broadcast manager functionality")
1313

1414

15-
class CyclicTask(object):
15+
class CyclicSendTaskABC(object):
1616

17-
def stop(self):
18-
"""Cancel the periodic task"""
19-
raise NotImplementedError()
20-
21-
def start(self):
22-
"""Once stopped a task can be restarted"""
23-
raise NotImplementedError()
24-
25-
26-
class CyclicSendTaskABC(CyclicTask):
27-
28-
def __init__(self, channel, message, period):
17+
def __init__(self, message, period):
2918
"""
30-
:param str channel: The name of the CAN channel to connect to.
3119
:param message: The :class:`can.Message` to be sent periodically.
3220
:param float period: The rate in seconds at which to send the message.
3321
"""
@@ -36,24 +24,28 @@ def __init__(self, channel, message, period):
3624

3725
@abc.abstractmethod
3826
def stop(self):
39-
"""Send a TX_DELETE message to the broadcast manager to cancel this task.
27+
"""Cancel this periodic task.
28+
"""
4029

41-
This will delete the entry for the transmission of the CAN message
42-
specified.
30+
@abc.abstractmethod
31+
def start(self):
32+
"""Restart a stopped periodic task.
4333
"""
4434

35+
36+
class ModifiableCyclicTaskABC(CyclicSendTaskABC):
37+
"""Adds support for modifying a periodic message"""
38+
4539
@abc.abstractmethod
4640
def modify_data(self, message):
4741
"""Update the contents of this periodically sent message without altering
4842
the timing.
4943
5044
:param message: The :class:`~can.Message` with new :attr:`Message.data`.
51-
Note it must have the same :attr:`~can.Message.arbitration_id`.
5245
"""
5346

5447

5548
class MultiRateCyclicSendTaskABC(CyclicSendTaskABC):
56-
5749
"""Exposes more of the full power of the TX_SETUP opcode.
5850
5951
Transmits a message `count` times at `initial_period` then
@@ -64,9 +56,9 @@ def __init__(self, channel, message, count, initial_period, subsequent_period):
6456
super(MultiRateCyclicSendTaskABC, self).__init__(channel, message, subsequent_period)
6557

6658

67-
def send_periodic(channel, message, period):
59+
def send_periodic(bus, message, period):
6860
"""
6961
Send a message every `period` seconds on the given channel.
7062
7163
"""
72-
return can.interface.CyclicSendTask(channel, message, period)
64+
return can.interface.CyclicSendTask(bus, message, period)

can/bus.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ def send(self, msg):
6262
"""
6363
raise NotImplementedError("Trying to write to a readonly bus?")
6464

65+
def send_periodic(self, msg, period, duration=None):
66+
"""Start sending a message at a given period on this bus.
67+
68+
:param msg:
69+
:param period:
70+
:param float duration:
71+
The duration to keep sending this message at given rate. If
72+
no duration is provided, the task will continue indefinitely.
73+
:return: A started :class:`can.CyclicTask` instance
74+
"""
75+
raise NotImplementedError("TODO")
76+
6577
def __iter__(self):
6678
"""Allow iteration on messages as they are received.
6779

can/interfaces/interface.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def __new__(cls, other, channel=None, *args, **kwargs):
8181
class CyclicSendTask(CyclicSendTaskABC):
8282

8383
@classmethod
84-
def __new__(cls, other, channel, *args, **kwargs):
84+
def __new__(cls, other, bus, *args, **kwargs):
8585

8686
# If can.rc doesn't look valid: load default
8787
if 'interface' not in can.rc or 'channel' not in can.rc:
@@ -108,7 +108,7 @@ def __new__(cls, other, channel, *args, **kwargs):
108108
else:
109109
can.log.info("Current CAN interface doesn't support CyclicSendTask")
110110

111-
return cls(channel, *args, **kwargs)
111+
return cls(bus, *args, **kwargs)
112112

113113

114114
class MultiRateCyclicSendTask(MultiRateCyclicSendTaskABC):

examples/cyclic.py

100644100755
Lines changed: 80 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -14,86 +14,104 @@
1414
import can
1515
logging.basicConfig(level=logging.INFO)
1616

17-
channel = 'vcan0'
1817

19-
20-
def test_simple_periodic_send():
21-
print("Starting to send a message every 200ms. Initial data is zeros")
22-
msg = can.Message(arbitration_id=0x123, data=[0, 0, 0, 0, 0, 0], extended_id=False)
23-
task = can.send_periodic('vcan0', msg, 0.20)
18+
def simple_periodic_send(bus):
19+
"""
20+
Sends a message every 20ms with no explicit timeout
21+
Sleeps for 2 seconds then stops the task.
22+
"""
23+
print("Starting to send a message every 200ms for 2s")
24+
msg = can.Message(arbitration_id=0x123, data=[1, 2, 3, 4, 5, 6], extended_id=False)
25+
task = bus.send_periodic(msg, 0.20)
2426
time.sleep(2)
2527
task.stop()
2628
print("stopped cyclic send")
2729

2830

29-
def test_extended_periodic_send():
30-
print("Starting to send a message every 200ms. Initial data is zeros")
31+
def limited_periodic_send(bus):
32+
print("Starting to send a message every 200ms for 1s")
3133
msg = can.Message(arbitration_id=0x12345678, data=[0, 0, 0, 0, 0, 0], extended_id=True)
32-
task = can.send_periodic('vcan0', msg, 0.20)
33-
time.sleep(2)
34-
task.stop()
35-
print("stopped cyclic send")
34+
bus.send_periodic(msg, 0.20, 1)
35+
time.sleep(3)
36+
# task.stop()
37+
# print("stopped cyclic send")
38+
39+
40+
# def test_periodic_send_with_modifying_data():
41+
# print("Starting to send a message every 200ms. Initial data is ones")
42+
# msg = can.Message(arbitration_id=0x0cf02200, data=[1, 1, 1, 1])
43+
# task = can.send_periodic('vcan0', msg, 0.20)
44+
# time.sleep(2)
45+
# print("Changing data of running task to begin with 99")
46+
# msg.data[0] = 0x99
47+
# task.modify_data(msg)
48+
# time.sleep(2)
49+
#
50+
# task.stop()
51+
# print("stopped cyclic send")
52+
# print("Changing data of stopped task to single ff byte")
53+
# msg.data = bytearray([0xff])
54+
# task.modify_data(msg)
55+
# time.sleep(1)
56+
# print("starting again")
57+
# task.start()
58+
# time.sleep(1)
59+
# task.stop()
60+
# print("done")
61+
#
62+
#
63+
# def test_dual_rate_periodic_send():
64+
# """Send a message 10 times at 1ms intervals, then continue to send every 500ms"""
65+
# msg = can.Message(arbitration_id=0x123, data=[0, 1, 2, 3, 4, 5])
66+
# print("Creating cyclic task to send message 10 times at 1ms, then every 500ms")
67+
# task = can.interface.MultiRateCyclicSendTask('vcan0', msg, 10, 0.001, 0.50)
68+
# time.sleep(2)
69+
#
70+
# print("Changing data[0] = 0x42")
71+
# msg.data[0] = 0x42
72+
# task.modify_data(msg)
73+
# time.sleep(2)
74+
#
75+
# task.stop()
76+
# print("stopped cyclic send")
77+
#
78+
# time.sleep(2)
79+
#
80+
# task.start()
81+
# print("starting again")
82+
# time.sleep(2)
83+
# task.stop()
84+
# print("done")
3685

3786

38-
def test_periodic_send_with_modifying_data():
39-
print("Starting to send a message every 200ms. Initial data is ones")
40-
msg = can.Message(arbitration_id=0x0cf02200, data=[1, 1, 1, 1])
41-
task = can.send_periodic('vcan0', msg, 0.20)
42-
time.sleep(2)
43-
print("Changing data of running task to begin with 99")
44-
msg.data[0] = 0x99
45-
task.modify_data(msg)
46-
time.sleep(2)
47-
48-
task.stop()
49-
print("stopped cyclic send")
50-
print("Changing data of stopped task to single ff byte")
51-
msg.data = bytearray([0xff])
52-
task.modify_data(msg)
53-
time.sleep(1)
54-
print("starting again")
55-
task.start()
56-
time.sleep(1)
57-
task.stop()
58-
print("done")
59-
87+
if __name__ == "__main__":
6088

61-
def test_dual_rate_periodic_send():
62-
"""Send a message 10 times at 1ms intervals, then continue to send every 500ms"""
63-
msg = can.Message(arbitration_id=0x123, data=[0, 1, 2, 3, 4, 5])
64-
print("Creating cyclic task to send message 10 times at 1ms, then every 500ms")
65-
task = can.interface.MultiRateCyclicSendTask('vcan0', msg, 10, 0.001, 0.50)
66-
time.sleep(2)
89+
reset_msg = can.Message(arbitration_id=0x00, data=[0, 0, 0, 0, 0, 0], extended_id=False)
6790

68-
print("Changing data[0] = 0x42")
69-
msg.data[0] = 0x42
70-
task.modify_data(msg)
71-
time.sleep(2)
7291

73-
task.stop()
74-
print("stopped cyclic send")
7592

76-
time.sleep(2)
93+
for interface in {
94+
'socketcan_ctypes',
95+
#'socketcan_native'
96+
}:
97+
print("Carrying out cyclic tests with {} interface".format(interface))
98+
can.rc['interface'] = interface
7799

78-
task.start()
79-
print("starting again")
80-
time.sleep(2)
81-
task.stop()
82-
print("done")
100+
channel = 'vcan0'
101+
bus = can.interface.Bus(channel=channel)
102+
bus.send(reset_msg)
83103

104+
simple_periodic_send(bus)
84105

85-
if __name__ == "__main__":
106+
bus.send(reset_msg)
86107

87-
for interface in {'socketcan_ctypes', 'socketcan_native'}:
88-
print("Carrying out cyclic tests with {} interface".format(interface))
89-
can.rc['interface'] = interface
108+
limited_periodic_send(bus)
90109

91-
test_simple_periodic_send()
110+
#test_periodic_send_with_modifying_data()
92111

93-
test_extended_periodic_send()
112+
#print("Carrying out multirate cyclic test for {} interface".format(interface))
113+
#can.rc['interface'] = interface
114+
#test_dual_rate_periodic_send()
94115

95-
test_periodic_send_with_modifying_data()
96116

97-
print("Carrying out multirate cyclic test for {} interface".format(interface))
98-
can.rc['interface'] = interface
99-
test_dual_rate_periodic_send()
117+
time.sleep(2)

0 commit comments

Comments
 (0)