Skip to content

Commit f1dbfef

Browse files
committed
Add end count to send periodic in BCM
1 parent 63c60af commit f1dbfef

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

can/broadcastmanager.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def __init__(
104104
messages: Union[Sequence[Message], Message],
105105
period: float,
106106
duration: Optional[float],
107+
count: Optional[int],
107108
):
108109
"""Message send task with a defined duration and period.
109110
@@ -113,9 +114,13 @@ def __init__(
113114
:param duration:
114115
Approximate duration in seconds to continue sending messages. If
115116
no duration is provided, the task will continue indefinitely.
117+
:param count:
118+
The number of messages to send before stopping. If
119+
no count is provided, the task will continue indefinitely.
116120
"""
117121
super().__init__(messages, period)
118122
self.duration = duration
123+
self.count = count
119124

120125

121126
class RestartableCyclicTaskABC(CyclicSendTaskABC):
@@ -207,6 +212,7 @@ def __init__(
207212
messages: Union[Sequence[Message], Message],
208213
period: float,
209214
duration: Optional[float] = None,
215+
count: Optional[int] = None,
210216
on_error: Optional[Callable[[Exception], bool]] = None,
211217
):
212218
"""Transmits `messages` with a `period` seconds for `duration` seconds on a `bus`.
@@ -222,12 +228,13 @@ def __init__(
222228
it shall return either ``True`` or ``False`` depending
223229
on desired behaviour of `ThreadBasedCyclicSendTask`.
224230
"""
225-
super().__init__(messages, period, duration)
231+
super().__init__(messages, period, duration, count)
226232
self.bus = bus
227233
self.send_lock = lock
228234
self.stopped = True
229235
self.thread = None
230236
self.end_time = time.perf_counter() + duration if duration else None
237+
self.end_count = count if count else None
231238
self.on_error = on_error
232239

233240
if HAS_EVENTS:
@@ -257,6 +264,7 @@ def start(self):
257264

258265
def _run(self):
259266
msg_index = 0
267+
count = 0
260268
while not self.stopped:
261269
# Prevent calling bus.send from multiple threads
262270
with self.send_lock:
@@ -272,7 +280,10 @@ def _run(self):
272280
break
273281
if self.end_time is not None and time.perf_counter() >= self.end_time:
274282
break
283+
if self.end_count is not None and count >= self.end_count:
284+
break
275285
msg_index = (msg_index + 1) % len(self.messages)
286+
count += 1
276287

277288
if HAS_EVENTS:
278289
win32event.WaitForSingleObject(self.event.handle, self.period_ms)

can/bus.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ def send_periodic(
175175
msgs: Union[Sequence[Message], Message],
176176
period: float,
177177
duration: Optional[float] = None,
178+
count: Optional[int] = None,
178179
store_task: bool = True,
179180
) -> can.broadcastmanager.CyclicSendTaskABC:
180181
"""Start sending messages at a given period on this bus.
@@ -194,6 +195,9 @@ def send_periodic(
194195
:param duration:
195196
Approximate duration in seconds to continue sending messages. If
196197
no duration is provided, the task will continue indefinitely.
198+
:param count:
199+
The number of messages to send before stopping. If
200+
no count is provided, the task will continue indefinitely.
197201
:param store_task:
198202
If True (the default) the task will be attached to this Bus instance.
199203
Disable to instead manage tasks manually.
@@ -222,7 +226,7 @@ def send_periodic(
222226
raise ValueError("Must be either a list, tuple, or a Message")
223227
if not msgs:
224228
raise ValueError("Must be at least a list or tuple of length 1")
225-
task = self._send_periodic_internal(msgs, period, duration)
229+
task = self._send_periodic_internal(msgs, period, duration, count)
226230
# we wrap the task's stop method to also remove it from the Bus's list of tasks
227231
original_stop_method = task.stop
228232

@@ -246,6 +250,7 @@ def _send_periodic_internal(
246250
msgs: Union[Sequence[Message], Message],
247251
period: float,
248252
duration: Optional[float] = None,
253+
count: Optional[int] = None,
249254
) -> can.broadcastmanager.CyclicSendTaskABC:
250255
"""Default implementation of periodic message sending using threading.
251256
@@ -258,6 +263,9 @@ def _send_periodic_internal(
258263
:param duration:
259264
The duration between sending each message at the given rate. If
260265
no duration is provided, the task will continue indefinitely.
266+
:param count:
267+
The number of messages to send before stopping. If
268+
no count is provided, the task will continue indefinitely.
261269
:return:
262270
A started task instance. Note the task can be stopped (and
263271
depending on the backend modified) by calling the :meth:`stop`
@@ -269,7 +277,7 @@ def _send_periodic_internal(
269277
threading.Lock()
270278
) # pylint: disable=attribute-defined-outside-init
271279
task = ThreadBasedCyclicSendTask(
272-
self, self._lock_send_periodic, msgs, period, duration
280+
self, self._lock_send_periodic, msgs, period, duration, count
273281
)
274282
return task
275283

0 commit comments

Comments
 (0)