or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bit-timing.mdbus-operations.mdcli-tools.mdevent-system.mdfile-io.mdhardware-interfaces.mdindex.mdmessage-handling.mdperiodic-transmission.md

message-handling.mddocs/

0

# Message Handling

1

2

CAN message creation, manipulation, and validation with comprehensive support for all CAN message types including standard and extended arbitration IDs, remote frames, error frames, and CAN FD messages with flexible data rates.

3

4

## Capabilities

5

6

### Message Creation

7

8

Create CAN messages with full control over all message properties and automatic validation.

9

10

```python { .api }

11

class Message:

12

def __init__(self, timestamp=0.0, arbitration_id=0, is_extended_id=True,

13

is_remote_frame=False, is_error_frame=False, channel=None,

14

dlc=None, data=None, is_fd=False, is_rx=True,

15

bitrate_switch=False, error_state_indicator=False, check=False):

16

"""

17

Create a CAN message object.

18

19

Parameters:

20

- timestamp: Message timestamp in seconds (float)

21

- arbitration_id: CAN arbitration ID (0-0x1FFFFFFF for extended, 0-0x7FF for standard)

22

- is_extended_id: True for 29-bit extended ID, False for 11-bit standard ID

23

- is_remote_frame: True for remote transmission request frames

24

- is_error_frame: True for error frames

25

- channel: Channel identifier (backend specific)

26

- dlc: Data Length Code (0-8 for CAN 2.0, 0-64 for CAN FD)

27

- data: Message data as bytes, bytearray, or list of integers

28

- is_fd: True for CAN FD frames

29

- is_rx: True for received messages, False for transmitted

30

- bitrate_switch: True for CAN FD bitrate switching

31

- error_state_indicator: True for CAN FD error state indicator

32

- check: If True, validate message parameters (raises ValueError on invalid)

33

34

Raises:

35

- ValueError: Invalid message parameters (only if check=True)

36

- TypeError: Invalid data type

37

"""

38

```

39

40

### Message Properties

41

42

Access and modify message properties with automatic type conversion and validation.

43

44

```python { .api }

45

# Message properties (all read/write)

46

timestamp: float # Message timestamp in seconds

47

arbitration_id: int # CAN arbitration ID

48

is_extended_id: bool # Extended (29-bit) vs standard (11-bit) ID

49

is_remote_frame: bool # Remote transmission request

50

is_error_frame: bool # Error frame indicator

51

channel: Any # Channel identifier

52

dlc: int # Data Length Code

53

data: bytearray # Message data bytes

54

is_fd: bool # CAN FD frame

55

is_rx: bool # Receive (True) vs transmit (False)

56

bitrate_switch: bool # CAN FD bitrate switching

57

error_state_indicator: bool # CAN FD error state indicator

58

```

59

60

### Message Comparison

61

62

Compare messages with configurable tolerance and optional field exclusions.

63

64

```python { .api }

65

def equals(self, other: Message, timestamp_delta=1e-6, check_channel=True,

66

check_direction=True) -> bool:

67

"""

68

Compare this message with another message.

69

70

Parameters:

71

- other: Message to compare with

72

- timestamp_delta: Maximum timestamp difference in seconds (None to ignore)

73

- check_channel: Whether to compare message channels

74

- check_direction: Whether to compare message directions (Rx/Tx)

75

76

Returns:

77

True if messages are equal within specified tolerances

78

"""

79

```

80

81

### Message Validation

82

83

Validate message parameters and detect invalid configurations.

84

85

```python { .api }

86

def _check(self) -> None:

87

"""

88

Check if message parameters are valid.

89

90

Validates:

91

- Timestamp is not negative, infinite, or NaN

92

- Remote and error frames are mutually exclusive

93

- CAN FD compatibility with remote frames

94

- Arbitration ID ranges (11-bit: 0-0x7FF, 29-bit: 0-0x1FFFFFFF)

95

- DLC ranges (CAN 2.0: 0-8, CAN FD: 0-64)

96

- Data consistency with DLC and frame type

97

- CAN FD specific flags only used with CAN FD frames

98

99

Raises:

100

- ValueError: Invalid message parameters

101

"""

102

```

103

104

### String Representation

105

106

Convert messages to human-readable string formats with comprehensive information display.

107

108

```python { .api }

109

def __str__(self) -> str:

110

"""

111

Return human-readable string representation.

112

113

Format: Timestamp ID Flags DL Data ASCII Channel

114

Example: " 12.345678 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08 'test'"

115

"""

116

117

def __repr__(self) -> str:

118

"""

119

Return unambiguous string representation suitable for recreating the message.

120

121

Example: "can.Message(timestamp=12.345, arbitration_id=0x123, ...)"

122

"""

123

124

def __format__(self, format_spec: str) -> str:

125

"""Format message using format specification (empty spec uses __str__)."""

126

```

127

128

### Data Access

129

130

Access message data through multiple interfaces for different use cases.

131

132

```python { .api }

133

def __len__(self) -> int:

134

"""Return the DLC (works for remote frames)."""

135

136

def __bytes__(self) -> bytes:

137

"""Return message data as bytes."""

138

139

def __bool__(self) -> bool:

140

"""Messages are always truthy."""

141

```

142

143

### Message Copying

144

145

Create copies of messages with full or shallow copying support.

146

147

```python { .api }

148

def __copy__(self) -> Message:

149

"""Create a shallow copy of the message."""

150

151

def __deepcopy__(self, memo) -> Message:

152

"""Create a deep copy of the message with all referenced objects copied."""

153

```

154

155

## Usage Examples

156

157

### Basic Message Creation

158

159

```python

160

import can

161

162

# Standard 11-bit ID message

163

msg1 = can.Message(

164

arbitration_id=0x123,

165

data=[0x11, 0x22, 0x33, 0x44],

166

is_extended_id=False

167

)

168

169

# Extended 29-bit ID message

170

msg2 = can.Message(

171

arbitration_id=0x18FF1234,

172

data=b'\x01\x02\x03\x04\x05\x06\x07\x08',

173

is_extended_id=True

174

)

175

176

# Remote frame

177

remote_msg = can.Message(

178

arbitration_id=0x456,

179

is_remote_frame=True,

180

dlc=8, # Request 8 bytes

181

is_extended_id=False

182

)

183

184

print(f"Standard message: {msg1}")

185

print(f"Extended message: {msg2}")

186

print(f"Remote frame: {remote_msg}")

187

```

188

189

### CAN FD Messages

190

191

```python

192

import can

193

194

# CAN FD message with up to 64 bytes

195

fd_msg = can.Message(

196

arbitration_id=0x123,

197

data=list(range(64)), # 64 bytes of data

198

is_fd=True,

199

bitrate_switch=True,

200

is_extended_id=False

201

)

202

203

print(f"CAN FD message length: {len(fd_msg)}")

204

print(f"CAN FD data: {fd_msg.data[:10]}...") # First 10 bytes

205

```

206

207

### Message Validation

208

209

```python

210

import can

211

212

try:

213

# This will raise ValueError because remote frames can't carry data

214

invalid_msg = can.Message(

215

arbitration_id=0x123,

216

data=[1, 2, 3, 4],

217

is_remote_frame=True,

218

check=True # Enable validation

219

)

220

except ValueError as e:

221

print(f"Validation error: {e}")

222

223

# Valid message creation

224

valid_msg = can.Message(

225

arbitration_id=0x123,

226

data=[1, 2, 3, 4],

227

check=True

228

)

229

```

230

231

### Message Comparison

232

233

```python

234

import can

235

import time

236

237

# Create two similar messages

238

msg1 = can.Message(

239

timestamp=time.time(),

240

arbitration_id=0x123,

241

data=[1, 2, 3, 4]

242

)

243

244

time.sleep(0.001) # Small delay

245

246

msg2 = can.Message(

247

timestamp=time.time(),

248

arbitration_id=0x123,

249

data=[1, 2, 3, 4]

250

)

251

252

# Compare with default timestamp tolerance (1µs)

253

if msg1.equals(msg2):

254

print("Messages are equal (within timestamp tolerance)")

255

256

# Compare ignoring timestamps

257

if msg1.equals(msg2, timestamp_delta=None):

258

print("Messages have identical content")

259

260

# Strict comparison (identity)

261

if msg1 is msg2:

262

print("Same message object")

263

else:

264

print("Different message objects")

265

```

266

267

### Working with Message Data

268

269

```python

270

import can

271

272

msg = can.Message(

273

arbitration_id=0x123,

274

data=[0x48, 0x65, 0x6C, 0x6C, 0x6F] # "Hello" in ASCII

275

)

276

277

# Access data in different ways

278

print(f"Data as list: {list(msg.data)}")

279

print(f"Data as bytes: {bytes(msg)}")

280

print(f"Data as hex: {msg.data.hex()}")

281

print(f"Data length: {len(msg)}")

282

283

# Modify data

284

msg.data[0] = 0x48 # Set first byte

285

msg.data.extend([0x21]) # Add exclamation mark

286

msg.dlc = len(msg.data) # Update DLC

287

288

print(f"Modified message: {msg}")

289

```

290

291

### Message Copying

292

293

```python

294

import can

295

import copy

296

297

original = can.Message(

298

arbitration_id=0x123,

299

data=[1, 2, 3, 4],

300

channel="can0"

301

)

302

303

# Shallow copy

304

shallow_copy = copy.copy(original)

305

shallow_copy.arbitration_id = 0x456

306

307

# Deep copy

308

deep_copy = copy.deepcopy(original)

309

deep_copy.data[0] = 99

310

311

print(f"Original: {original}")

312

print(f"Shallow copy: {shallow_copy}")

313

print(f"Deep copy: {deep_copy}")

314

```

315

316

## Types

317

318

```python { .api }

319

from typing import Union, Optional, Any

320

from collections.abc import Sequence

321

322

# Type aliases for message data

323

CanData = Union[bytes, bytearray, Sequence[int]]

324

Channel = Union[str, int, Any]

325

326

class Message:

327

"""CAN message representation with support for all CAN variants."""

328

329

# Slots for memory efficiency

330

__slots__ = (

331

"__weakref__",

332

"arbitration_id", "bitrate_switch", "channel", "data", "dlc",

333

"error_state_indicator", "is_error_frame", "is_extended_id",

334

"is_fd", "is_remote_frame", "is_rx", "timestamp"

335

)

336

```