Отправка сообщения CAN J1939

Я хотел бы получить пример кода для отправки простого сообщения CAN со стеком J1939 с использованием Python.

На следующем веб-сайте есть простой пример получения сообщения J1939: https://justkding.me/gotits/python-sae-j1939-socket-support

Код на этой странице отлично подходит для получения:

    import socket

def main():
    with socket.socket(
        family=socket.PF_CAN, type=socket.SOCK_DGRAM, proto=socket.CAN_J1939
    ) as s:
        s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        addr = "vcan0", socket.J1939_NO_NAME, socket.J1939_NO_PGN, socket.J1939_NO_ADDR
        s.bind(addr)

        while True:
            data, addr = s.recvfrom(128)
            print("{:02x} {:05x}:".format(addr[3], addr[2]), end="")

            for j in range(len(data)):
                if j % 8 == 0 and j != 0:
                    print("\n{:05x}    ".format(j), end="")
                print(" {:02x}".format(data[j]), end="")
            print("\n", end="")

if __name__ == "__main__":
    main()

Я читал документы, но не могу найти простого способа отправить сообщение J1939 на Python.

Вот ссылка на документацию ядра: https://www.kernel.org/doc/html/latest/networking/j1939.html

Вот код утилиты C testj1939, который может быть полезен: https://github.com/linux-can/can-utils/blob/master/testj1939.c

Может ли кто-нибудь опубликовать простой код для отправки сообщения с использованием протокола J1939 в Python? Любая документация, показывающая, как это правильно сделать, будет принята с благодарностью.

Спасибо.


person rickthehope    schedule 14.01.2021    source источник


Ответы (1)


Решением было использовать sendto () вместо send (). В J1939 байты, указанные в качестве аргумента send (), представляют собой только полезную нагрузку. Следовательно, sendto () необходим для указания адреса назначения.

import socket

def main():

    s = socket.socket(socket.PF_CAN, socket.SOCK_DGRAM, socket.CAN_J1939) 
    s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    
    addr_source = "vcan0", socket.J1939_NO_NAME, socket.J1939_NO_PGN, 0x20
    addr_destination = "vcan0", socket.J1939_NO_NAME, 0x12300, 0x30
    s.bind(addr_source)

    data = b'\x01\x02\x03\x04\x05\x06\x07\x08'
    s.sendto(data, addr_destination)

if __name__ == "__main__":
    main()
person rickthehope    schedule 14.01.2021