Metadata-Version: 2.4
Name: python-can-canpal
Version: 0.1.0rc2
Summary: CANPAL USB and TCP backend for python-can
License-Expression: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Topic :: System :: Hardware :: Hardware Drivers
Requires-Python: <3.13,>=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: python-can==4.6.1
Requires-Dist: pyserial==3.5
Provides-Extra: test
Requires-Dist: pytest<10,>=8; extra == "test"
Requires-Dist: build<2,>=1; extra == "test"
Requires-Dist: twine<8,>=6; extra == "test"
Dynamic: license-file

# python-can-canpal

CANPAL USB and TCP client backend for [python-can](https://python-can.readthedocs.io/).

**0.1.0rc2 is an experimental preview. Full hardware release acceptance is incomplete.**
Use it for evaluation on an isolated test bench. It is not the qualified 0.1.0 release.

## Install

Requires Python 3.12, python-can 4.6.1, pySerial 3.5, and a separately supplied
64-bit CANPAL native SDK with the fixes described below.

```text
python -m pip install python-can-canpal==0.1.0rc2
```

The Python package does **not** include the CANPAL SDK, firmware, device drivers,
Qt/MinGW runtime, or fake binaries. Obtain compatible native components from your
CANPAL supplier before attempting hardware access. The MIT license applies to
the new Python plugin, tests and documentation; native components have separate licenses.

## What has been verified

| Environment | Preview evidence |
| --- | --- |
| Windows 11 x64 | X5 classic CAN/RTR and X6 classic CAN/RTR/ISO FD over USB and explicit-IP WLAN TCP |
| Windows, multiple devices | Two USB devices, X5 USB + X6 WLAN, X5 WLAN + X6 USB; five reopen cycles per device/transport |
| Ubuntu 24.04 x86_64 in Hyper-V | Native Linux SDK with two USB devices through USB/IP; ttyACM number swap with UID selection; TCP checks through temporary SSH forwarding via Windows WLAN |

Both devices had CAN1 wired to their own CAN2 on separate physical buses.
These checks do not use an independent reference CAN interface. Classic checks
covered standard/extended frames and RTR DLC 0–8 in both directions. X6 FD checks
covered lengths 0–64 and BRS off/on. The current SDK checks verified 19,680 frames
and 20 Windows reopen cycles. Of these, 4,384 frames were verified on Linux USB
using usbipd-win 5.3.0 and Linux CDC ACM. Reversing attachment order swapped
ttyACM0/ttyACM1 while UID selection still found the correct X5 and X6.

SDK software regressions passed 170 assertions on each of Windows x64, Windows
x86, and Ubuntu x86_64, plus two Linux ThreadSanitizer checks. Windows x86 SDK
checks do not qualify a 32-bit Python plugin configuration.

**Not yet qualified:** independent-reference CAN/CAN FD interoperability, physical
Linux host USB controllers, direct Linux WLAN, two simultaneous WLAN devices,
full repeated physical renumbering/disconnection acceptance, rated-load/endurance
runs, and native resource stability. Formal 0.1.0 retains the complete release
acceptance requirements.

## Native SDK and firmware requirements

Request **CANPAL native SDK build `663eda8`** from your CANPAL supplier through
the existing supplier channel. Windows x64 and Ubuntu 24.04 x86_64 runtime bundles
are supplied on request, separately from PyPI. Match the binary SHA256 below and
the bundle manifest before use; updating this Python package alone does not
update your installed native SDK.

The pinned source revision is `663eda823be0533754123695405033b38e115489`. It adds
stricter CAN ACK validation, TCP buffered-read handling, immediate OBD write-error
propagation, UDS source filtering, and synchronized command handoff. It also
includes cooperative worker shutdown and the Qt serial buffered-read fix.
The firmware protocol has no transaction sequence, so a delayed ACK for an
identical earlier request cannot be distinguished by the echoed fields alone.

| Runtime file | SHA256 |
| --- | --- |
| Windows x64 CANPAL.dll | `c5bf185e71d06171302163d47f9c709b791306ecddf911de464d5b432daa943a` |
| Ubuntu x86_64 libCANPAL.so | `a7b5d46e50bdb1fa5a580f59f43498fa78a05b959dd2d0c2bd01f9eba242c70d` |

Matching exported function names or the SDK version string alone does not identify
this fixed build. rc2 updates the SDK baseline, validation tooling and documentation;
its Python runtime behavior is unchanged from rc1.

Classic RTR also requires firmware that preserves the received DLC. The original
X5 firmware reporting `0x0332` and X6 firmware reporting `0x0127` cleared RTR DLC
to zero. Supplier-signed diagnostic builds fixed this on the two test devices.
Those builds still report the same version numbers: ask your supplier to identify
the actual fixed build. The plugin cannot recover DLC that firmware has discarded.

Set `CANPAL_LIBRARY` to the absolute DLL/SO path, or pass `library_path`.
On Windows, `CANPAL_DEPENDENCY_DIRS` may list Qt/MinGW runtime directories,
separated by semicolons. On Linux, install the matching Qt 5 runtime and grant
serial-port access through udev or the dialout group.

## Connect by UID or IP

```python
import can

with can.Bus(interface="canpal", ignore_config=True,
             transport="usb", device_id="YOUR_24_HEX_DIGIT_UID",
             channel=0, bitrate=500_000) as bus:
    message = bus.recv(timeout=1)
```

The device UID remains the selector when a COM/ttyACM number changes. After a
reconnection, close and recreate the Bus using the same UID; automatic reconnect
is not implemented. A Linux USB/IP enumeration-order swap has been verified;
the full repeated physical renumbering acceptance remains pending.

Use `transport="wlan", host="192.0.2.10", port=8000` for TCP direct connection.
The IP and port must match the actual device; no network discovery is attempted.
Keep `device_id` to verify identity at that endpoint. X6 CAN FD additionally uses
`fd=True, data_bitrate=2_000_000`.

Different physical devices use independent Bus objects. A device can have one
Bus and one selected CAN channel at a time. Use one Notifier per device for
independent fault handling. UDP, server mode, transmit echo and concurrent
channels on one device are not implemented.

A successful `send()` means the native queue accepted the frame, not that the
CAN bus acknowledged it. Use a single receiver per Bus, stop its Notifier before
shutdown, and handle python-can exceptions. Timestamp alignment is approximate
per device and does not provide precise synchronization between devices.

The source distribution includes Chinese installation, testing and release notes.
