or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

entry-interface.mdindex.mdinstance-management.mdintegration-utilities.mdlisteners-events.mdpersistence-data.mdtable-operations.md

listeners-events.mddocs/

0

# Listeners and Events

1

2

Real-time notification system for NetworkTable changes including entry modifications, connection status, and table updates. Essential for responsive robotics applications that need to react immediately to data changes.

3

4

## Capabilities

5

6

### Entry Listeners

7

8

Listen for changes to NetworkTable entries at various scopes.

9

10

```python { .api }

11

def addEntryListener(listener: Callable, immediateNotify: bool = True, localNotify: bool = True):

12

"""

13

Add a global entry listener for all NetworkTable changes.

14

15

Parameters:

16

- listener: Callable. Function called on entry changes with signature:

17

listener(key, value, isNew) or listener(entry, key, value, isNew)

18

- immediateNotify: bool. Call listener immediately with current values

19

- localNotify: bool. Whether to notify on local changes

20

21

Returns:

22

int: Listener ID for removal

23

"""

24

25

def removeEntryListener(listener):

26

"""

27

Remove an entry listener.

28

29

Parameters:

30

- listener: Callable or int. Listener function or ID to remove

31

"""

32

```

33

34

### Connection Listeners

35

36

Listen for NetworkTables connection status changes.

37

38

```python { .api }

39

def addConnectionListener(listener: Callable, immediateNotify: bool = False):

40

"""

41

Add a connection status listener.

42

43

Parameters:

44

- listener: Callable. Function called on connection changes with signature:

45

listener(connected, info) where:

46

- connected: bool, current connection status

47

- info: dict, connection information

48

- immediateNotify: bool. Call listener immediately with current status

49

50

Returns:

51

int: Listener ID for removal

52

"""

53

54

def removeConnectionListener(listener):

55

"""

56

Remove a connection listener.

57

58

Parameters:

59

- listener: Callable or int. Listener function or ID to remove

60

"""

61

```

62

63

### Table-Level Entry Listeners

64

65

Add listeners to specific tables for scoped notifications.

66

67

```python { .api }

68

class NetworkTable:

69

def addEntryListener(listener: Callable, immediateNotify: bool = False,

70

key: str = None, localNotify: bool = False):

71

"""

72

Add an entry listener for this table.

73

74

Parameters:

75

- listener: Callable. Function called on entry changes

76

- immediateNotify: bool. Call listener immediately with current values

77

- key: str, optional. Specific key to watch (None for all keys in table)

78

- localNotify: bool. Whether to notify on local changes

79

"""

80

81

def addEntryListenerEx(listener: Callable, flags: int, key: str = None,

82

paramIsNew: bool = True):

83

"""

84

Add an entry listener with extended options.

85

86

Parameters:

87

- listener: Callable. Function called on entry changes

88

- flags: int. Bitmask of notification flags

89

- key: str, optional. Specific key to watch

90

- paramIsNew: bool. Whether to pass isNew parameter to listener

91

"""

92

93

def removeEntryListener(listener):

94

"""

95

Remove an entry listener from this table.

96

97

Parameters:

98

- listener: Callable. Previously added listener function

99

"""

100

101

def addSubTableListener(listener: Callable, localNotify: bool = False):

102

"""

103

Add a listener for subtable creation/deletion.

104

105

Parameters:

106

- listener: Callable. Function called when subtables change

107

- localNotify: bool. Whether to notify on local changes

108

"""

109

```

110

111

### Entry-Level Listeners

112

113

Add listeners to specific entries for maximum efficiency.

114

115

```python { .api }

116

class NetworkTableEntry:

117

def addListener(listener: Callable, flags: int, paramIsNew: bool = True) -> int:

118

"""

119

Add a listener for changes to this specific entry.

120

121

Parameters:

122

- listener: Callable. Function called when entry changes with signature:

123

listener(entry, value, isNew) if paramIsNew=True

124

listener(entry, value) if paramIsNew=False

125

- flags: int. Bitmask of notification flags

126

- paramIsNew: bool. Whether to pass isNew parameter to listener

127

128

Returns:

129

int: Listener ID for removal

130

"""

131

132

def removeListener(listener_id: int):

133

"""

134

Remove a listener by ID.

135

136

Parameters:

137

- listener_id: int. ID returned from addListener

138

"""

139

```

140

141

## Notification Flags

142

143

Control when listeners are called with notification flag constants.

144

145

```python { .api }

146

# Notification timing flags

147

NT_NOTIFY_IMMEDIATE = 0x01 # Notify immediately with current values

148

NT_NOTIFY_LOCAL = 0x02 # Notify on local changes

149

150

# Notification event flags

151

NT_NOTIFY_NEW = 0x04 # Notify when entries are created

152

NT_NOTIFY_DELETE = 0x08 # Notify when entries are deleted

153

NT_NOTIFY_UPDATE = 0x10 # Notify when entry values change

154

NT_NOTIFY_FLAGS = 0x20 # Notify when entry flags change

155

156

# Common combinations

157

NOTIFY_ALL = NT_NOTIFY_NEW | NT_NOTIFY_DELETE | NT_NOTIFY_UPDATE | NT_NOTIFY_FLAGS

158

NOTIFY_CHANGES = NT_NOTIFY_UPDATE | NT_NOTIFY_FLAGS

159

```

160

161

## Usage Examples

162

163

### Global Entry Listener

164

165

```python

166

from networktables import NetworkTables

167

168

def on_entry_change(key, value, isNew):

169

"""Called whenever any NetworkTable entry changes."""

170

status = "NEW" if isNew else "UPDATED"

171

print(f"Entry {status}: {key} = {value}")

172

173

# Add global listener

174

NetworkTables.addEntryListener(on_entry_change, immediateNotify=True)

175

176

# The listener will be called for all entry changes across all tables

177

```

178

179

### Connection Status Monitoring

180

181

```python

182

from networktables import NetworkTables

183

184

def on_connection_change(connected, info):

185

"""Called when connection status changes."""

186

if connected:

187

print(f"Connected to {info.get('remote_ip', 'unknown')}")

188

else:

189

print("Disconnected from NetworkTables")

190

191

# Monitor connection status

192

NetworkTables.addConnectionListener(on_connection_change, immediateNotify=True)

193

194

# Start client connection

195

NetworkTables.initialize(server='roborio-1234-frc.local')

196

```

197

198

### Table-Specific Listeners

199

200

```python

201

from networktables import NetworkTables

202

203

def on_smartdashboard_change(key, value, isNew):

204

"""Called when SmartDashboard entries change."""

205

print(f"SmartDashboard update: {key} = {value}")

206

207

def on_vision_target_change(key, value, isNew):

208

"""Called only when vision target data changes."""

209

print(f"Vision target updated: {value}")

210

211

# Listen to entire SmartDashboard table

212

sd = NetworkTables.getTable('SmartDashboard')

213

sd.addEntryListener(on_smartdashboard_change)

214

215

# Listen to specific key in Vision table

216

vision = NetworkTables.getTable('Vision')

217

vision.addEntryListener(on_vision_target_change, key='targetDistance')

218

```

219

220

### Entry-Specific Listeners

221

222

```python

223

from networktables import NetworkTables

224

225

def on_speed_change(entry, value, isNew):

226

"""Called when drive speed changes."""

227

print(f"Drive speed: {value} m/s")

228

229

# Validate speed limits

230

if value > 5.0:

231

print("WARNING: Speed exceeds safe limit!")

232

233

# Listen to specific entry for maximum efficiency

234

speed_entry = NetworkTables.getEntry('/SmartDashboard/driveSpeed')

235

listener_id = speed_entry.addListener(

236

on_speed_change,

237

NetworkTables.NotifyFlags.UPDATE | NetworkTables.NotifyFlags.NEW

238

)

239

240

# Remove listener when done

241

speed_entry.removeListener(listener_id)

242

```

243

244

### Advanced Listener Configuration

245

246

```python

247

from networktables import NetworkTables

248

249

def robot_state_listener(key, value, isNew):

250

"""Monitor critical robot state changes."""

251

print(f"Robot state change: {key} = {value}")

252

253

def config_listener(key, value, isNew):

254

"""Monitor configuration changes that should persist."""

255

print(f"Config updated: {key} = {value}")

256

# Could trigger config save here

257

258

# Listen only to new entries and updates, not flag changes

259

flags = NetworkTables.NotifyFlags.NEW | NetworkTables.NotifyFlags.UPDATE

260

261

robot_table = NetworkTables.getTable('Robot')

262

robot_table.addEntryListenerEx(robot_state_listener, flags)

263

264

# Listen to configuration with immediate notification

265

config_table = NetworkTables.getTable('Config')

266

config_table.addEntryListenerEx(

267

config_listener,

268

flags | NetworkTables.NotifyFlags.IMMEDIATE

269

)

270

```

271

272

### Subtable Monitoring

273

274

```python

275

from networktables import NetworkTables

276

277

def on_camera_added(table, key, subtable, isNew):

278

"""Called when new camera subtables are created."""

279

if isNew:

280

print(f"New camera detected: {key}")

281

# Could set up camera-specific listeners here

282

283

vision_table = NetworkTables.getTable('Vision')

284

vision_table.addSubTableListener(on_camera_added)

285

```

286

287

### Listener Cleanup Patterns

288

289

```python

290

from networktables import NetworkTables

291

292

class RobotDataMonitor:

293

def __init__(self):

294

self.listeners = []

295

296

def start_monitoring(self):

297

"""Start all listeners and track them for cleanup."""

298

# Connection monitoring

299

conn_listener = NetworkTables.addConnectionListener(self.on_connection)

300

self.listeners.append(('connection', conn_listener))

301

302

# Entry monitoring

303

entry_listener = NetworkTables.addEntryListener(self.on_entry_change)

304

self.listeners.append(('entry', entry_listener))

305

306

# Specific entry monitoring

307

speed_entry = NetworkTables.getEntry('/SmartDashboard/speed')

308

speed_listener = speed_entry.addListener(

309

self.on_speed_change,

310

NetworkTables.NotifyFlags.UPDATE

311

)

312

self.listeners.append(('speed_entry', speed_entry, speed_listener))

313

314

def stop_monitoring(self):

315

"""Clean up all listeners."""

316

for listener_info in self.listeners:

317

if listener_info[0] == 'connection':

318

NetworkTables.removeConnectionListener(listener_info[1])

319

elif listener_info[0] == 'entry':

320

NetworkTables.removeEntryListener(listener_info[1])

321

elif listener_info[0] == 'speed_entry':

322

entry, listener_id = listener_info[1], listener_info[2]

323

entry.removeListener(listener_id)

324

325

self.listeners.clear()

326

327

def on_connection(self, connected, info):

328

print(f"Connection: {connected}")

329

330

def on_entry_change(self, key, value, isNew):

331

print(f"Entry: {key} = {value}")

332

333

def on_speed_change(self, entry, value, isNew):

334

print(f"Speed: {value}")

335

336

# Usage

337

monitor = RobotDataMonitor()

338

monitor.start_monitoring()

339

340

# Later cleanup

341

monitor.stop_monitoring()

342

```

343

344

## Error Handling

345

346

```python

347

from networktables import NetworkTables

348

349

def safe_listener(key, value, isNew):

350

"""Listener with error handling to prevent crashes."""

351

try:

352

# Process the change

353

process_value_change(key, value)

354

except Exception as e:

355

print(f"Error processing {key}: {e}")

356

# Continue execution despite errors

357

358

def process_value_change(key, value):

359

"""Your actual processing logic here."""

360

pass

361

362

# Add listener with error handling

363

NetworkTables.addEntryListener(safe_listener)

364

```

365

366

## Listener Performance Tips

367

368

1. **Use specific listeners**: Entry-level listeners are more efficient than global listeners

369

2. **Filter notifications**: Use notification flags to only receive relevant events

370

3. **Avoid heavy processing**: Keep listener functions lightweight to avoid blocking

371

4. **Handle errors**: Always include error handling to prevent listener crashes

372

5. **Clean up listeners**: Remove listeners when no longer needed to prevent memory leaks