python-j1939
python-j1939 copied to clipboard
Periodic message using send_periodic() gives error message
I observed that although the send() command from the python-can library handles the 'pdu' message from the python-J1939 library fine, the send_periodic() command is gives the following error message:
File "C:\Program Files\Python37\lib\site-packages\can\broadcastmanager.py", line 125, in start
name = "Cyclic send task for 0x%X" % (self.message.arbitration_id)
TypeError: %X format: an integer is required, not ArbitrationID
Which is understandable as the arbitration_id argument which is found in the can.Message object is done differently in the python-j1939 way. However, I don't understand why the normal send() function seems to work fine.
Is this intended (maybe there is another way to send periodic messages with python-j1939?) or am I missing something?
Code for error reproduction:
import time
import j1939
if __name__ == "__main__":
channel = 0
bustype = 'kvaser'
sourceaddr = 0xFE
destaddr = 0xF1
bus = j1939.Bus(channel=channel, bustype=bustype, timeout=0.01, broadcast=True)
data = [0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF]
pgn = j1939.PGN()
pgn.value = 0xFECA # DM1
aid = j1939.ArbitrationID(pgn=pgn, source_address=sourceaddr, destination_address=destaddr)
pdu = j1939.PDU(timestamp=0.0, arbitration_id=aid, data=data, info_strings=None)
bus.send_periodic(pdu, 0.5, duration=10.0)
#bus.send(pdu)
I ran into this same issue recently.
I believe that send
is overridden by j1939.Bus
but send_periodic
is not.
I ended up writing a function that polls for received messages using something along the lines of:
MSG_POLL_TIMEOUT_SEC = 0.025
def update(bus):
"""
Messages are read via polling with timeout MSG_POLL_TIMEOUT_SEC.
"""
assert isinstance(bus, j1939.Bus)
recv_msg = lambda: bus.recv(MSG_POLL_TIMEOUT_SEC)
msg = recv_msg()
while msg:
logging.debug(f"Received message:\n\t{str(msg)}")
msg = recv_msg()
It's a bodge, but it worked for me. ¯\_(ツ)_/¯