0
# Persistence and Data Management
1
2
Data persistence across restarts, entry management, and bulk operations. Critical for maintaining configuration and state information between robot sessions, enabling seamless transitions and preserving important settings.
3
4
## Capabilities
5
6
### Persistent Entry Management
7
8
Control which entries persist across NetworkTables restarts.
9
10
```python { .api }
11
def setPersistent(key: str):
12
"""
13
Make an entry persistent across NetworkTables restarts.
14
15
Parameters:
16
- key: str. Entry key to make persistent
17
"""
18
19
def clearPersistent(key: str):
20
"""
21
Remove persistence from an entry.
22
23
Parameters:
24
- key: str. Entry key to make non-persistent
25
"""
26
27
def isPersistent(key: str) -> bool:
28
"""
29
Check if an entry is persistent.
30
31
Parameters:
32
- key: str. Entry key to check
33
34
Returns:
35
bool: True if entry is persistent, False otherwise
36
"""
37
```
38
39
### File-Based Persistence
40
41
Save and load NetworkTables data to/from files.
42
43
```python { .api }
44
def savePersistent(filename: str):
45
"""
46
Save all persistent entries to a file.
47
48
Parameters:
49
- filename: str. File path to save persistent data to
50
"""
51
52
def loadPersistent(filename: str):
53
"""
54
Load persistent entries from a file.
55
56
Parameters:
57
- filename: str. File path to load persistent data from
58
"""
59
60
def saveEntries(filename: str, prefix: str):
61
"""
62
Save entries matching a prefix to a file.
63
64
Parameters:
65
- filename: str. File path to save entries to
66
- prefix: str. Entry prefix to match (e.g., "/SmartDashboard/")
67
"""
68
69
def loadEntries(filename: str, prefix: str):
70
"""
71
Load entries from a file with a specific prefix.
72
73
Parameters:
74
- filename: str. File path to load entries from
75
- prefix: str. Prefix to prepend to loaded entries
76
"""
77
```
78
79
### Entry Flag Management
80
81
Manage entry flags for various behaviors including persistence.
82
83
```python { .api }
84
def setFlags(key: str, flags: int):
85
"""
86
Set flags for an entry.
87
88
Parameters:
89
- key: str. Entry key
90
- flags: int. Bitmask of flags to set (e.g., NT_PERSISTENT)
91
"""
92
93
def clearFlags(key: str, flags: int):
94
"""
95
Clear flags for an entry.
96
97
Parameters:
98
- key: str. Entry key
99
- flags: int. Bitmask of flags to clear
100
"""
101
102
def getFlags(key: str) -> int:
103
"""
104
Get flags for an entry.
105
106
Parameters:
107
- key: str. Entry key
108
109
Returns:
110
int: Bitmask of entry flags
111
"""
112
```
113
114
### Bulk Entry Operations
115
116
Perform operations on multiple entries at once.
117
118
```python { .api }
119
def deleteAllEntries():
120
"""Delete all entries in this NetworkTables instance."""
121
122
def getEntries(prefix: str, types: int = 0) -> List[NetworkTableEntry]:
123
"""
124
Get all entries with names starting with the given prefix.
125
126
Parameters:
127
- prefix: str. Path prefix to match (e.g., "/Config/")
128
- types: int. Bitmask of entry types to include (default: 0 for all types)
129
130
Returns:
131
List[NetworkTableEntry]: List of matching entries
132
"""
133
134
def getEntryInfo(prefix: str, types: int = 0) -> List[tuple]:
135
"""
136
Get information about entries matching the prefix.
137
138
Parameters:
139
- prefix: str. Path prefix to match
140
- types: int. Bitmask of entry types to include (default: 0 for all types)
141
142
Returns:
143
List[tuple]: List of (name, type, flags) tuples for matching entries
144
"""
145
```
146
147
### Entry Deletion
148
149
Delete individual entries from NetworkTables.
150
151
```python { .api }
152
class NetworkTable:
153
def delete(key: str):
154
"""
155
Delete an entry from the table.
156
157
Parameters:
158
- key: str. Entry key to delete
159
"""
160
161
class NetworkTableEntry:
162
def delete() -> bool:
163
"""
164
Delete this entry from NetworkTables.
165
166
Returns:
167
bool: True if entry was deleted, False if it didn't exist
168
"""
169
```
170
171
## Entry Flag Constants
172
173
```python { .api }
174
# Entry flag constants
175
NT_PERSISTENT = 0x01 # Entry persists across restarts
176
177
# Usage in setFlags/clearFlags
178
entry.setFlags(NT_PERSISTENT) # Make persistent
179
entry.clearFlags(NT_PERSISTENT) # Remove persistence
180
```
181
182
## Usage Examples
183
184
### Basic Persistence Configuration
185
186
```python
187
from networktables import NetworkTables
188
189
# Initialize connection
190
NetworkTables.initialize(server='roborio-1234-frc.local')
191
sd = NetworkTables.getTable('SmartDashboard')
192
193
# Set configuration values and make them persistent
194
sd.putNumber('maxSpeed', 2.5)
195
sd.setPersistent('maxSpeed')
196
197
sd.putString('autonomousMode', 'defense')
198
sd.setPersistent('autonomousMode')
199
200
sd.putBoolean('compressorEnabled', True)
201
sd.setPersistent('compressorEnabled')
202
203
# Check persistence status
204
if sd.isPersistent('maxSpeed'):
205
print("Max speed will survive robot restart")
206
```
207
208
### File-Based Persistence
209
210
```python
211
from networktables import NetworkTables
212
213
# Save all persistent values to file
214
try:
215
NetworkTables.savePersistent('robot_config.ini')
216
print("Configuration saved successfully")
217
except Exception as e:
218
print(f"Failed to save configuration: {e}")
219
220
# Load persistent values from file on startup
221
try:
222
NetworkTables.loadPersistent('robot_config.ini')
223
print("Configuration loaded successfully")
224
except Exception as e:
225
print(f"Failed to load configuration: {e}")
226
```
227
228
### Selective Data Export/Import
229
230
```python
231
from networktables import NetworkTables
232
233
# Save only SmartDashboard data
234
NetworkTables.saveEntries('dashboard_data.ini', '/SmartDashboard/')
235
236
# Save only Vision processing data
237
NetworkTables.saveEntries('vision_config.ini', '/Vision/')
238
239
# Load data with different prefix (data migration)
240
NetworkTables.loadEntries('old_config.ini', '/LegacyConfig/')
241
```
242
243
### Configuration Management Class
244
245
```python
246
from networktables import NetworkTables
247
248
class RobotConfig:
249
def __init__(self, config_file='robot_config.ini'):
250
self.config_file = config_file
251
self.config_table = NetworkTables.getTable('Config')
252
253
def load_defaults(self):
254
"""Load default configuration values."""
255
defaults = {
256
'maxSpeed': 1.0,
257
'autonomousMode': 'defense',
258
'compressorEnabled': True,
259
'visionProcessingEnabled': False,
260
'pidGains': [0.1, 0.0, 0.01]
261
}
262
263
for key, value in defaults.items():
264
# Set defaults without overwriting existing values
265
if isinstance(value, bool):
266
self.config_table.setDefaultBoolean(key, value)
267
elif isinstance(value, (int, float)):
268
self.config_table.setDefaultNumber(key, value)
269
elif isinstance(value, str):
270
self.config_table.setDefaultString(key, value)
271
elif isinstance(value, list):
272
self.config_table.setDefaultValue(key, value)
273
274
# Make all config values persistent
275
self.config_table.setPersistent(key)
276
277
def save_config(self):
278
"""Save configuration to file."""
279
try:
280
NetworkTables.saveEntries(self.config_file, '/Config/')
281
print(f"Configuration saved to {self.config_file}")
282
return True
283
except Exception as e:
284
print(f"Failed to save config: {e}")
285
return False
286
287
def load_config(self):
288
"""Load configuration from file."""
289
try:
290
NetworkTables.loadEntries(self.config_file, '/Config/')
291
print(f"Configuration loaded from {self.config_file}")
292
return True
293
except Exception as e:
294
print(f"Failed to load config: {e}")
295
return False
296
297
def get_config_value(self, key, default=None):
298
"""Get a configuration value with type detection."""
299
entry = self.config_table.getEntry(key)
300
if not entry.exists():
301
return default
302
303
entry_type = entry.getType()
304
if entry_type == NetworkTables.EntryTypes.BOOLEAN:
305
return entry.getBoolean(default)
306
elif entry_type == NetworkTables.EntryTypes.DOUBLE:
307
return entry.getDouble(default)
308
elif entry_type == NetworkTables.EntryTypes.STRING:
309
return entry.getString(default)
310
else:
311
return entry.value
312
313
# Usage
314
config = RobotConfig()
315
config.load_defaults()
316
config.load_config() # Load saved values
317
318
# Access configuration
319
max_speed = config.get_config_value('maxSpeed', 1.0)
320
auto_mode = config.get_config_value('autonomousMode', 'defense')
321
```
322
323
### Entry Cleanup and Management
324
325
```python
326
from networktables import NetworkTables
327
328
def cleanup_old_entries():
329
"""Remove old or temporary entries."""
330
# Get all entries with "temp" prefix
331
temp_entries = NetworkTables.getEntries('/temp/')
332
333
print(f"Cleaning up {len(temp_entries)} temporary entries")
334
for entry in temp_entries:
335
entry.delete()
336
337
# Remove specific old entries
338
old_keys = ['/SmartDashboard/oldValue1', '/SmartDashboard/oldValue2']
339
for key in old_keys:
340
entry = NetworkTables.getEntry(key)
341
if entry.exists():
342
entry.delete()
343
print(f"Deleted old entry: {key}")
344
345
def list_persistent_entries():
346
"""List all persistent entries for debugging."""
347
all_entries = NetworkTables.getEntries('/')
348
persistent_entries = []
349
350
for entry in all_entries:
351
if entry.isPersistent():
352
persistent_entries.append(entry.getName())
353
354
print("Persistent entries:")
355
for name in sorted(persistent_entries):
356
print(f" {name}")
357
358
return persistent_entries
359
360
# Usage
361
cleanup_old_entries()
362
list_persistent_entries()
363
```
364
365
### Advanced Flag Management
366
367
```python
368
from networktables import NetworkTables
369
370
# Direct flag management using NetworkTable
371
sd = NetworkTables.getTable('SmartDashboard')
372
373
# Set multiple flags at once
374
flags = NetworkTables.EntryFlags.PERSISTENT
375
sd.setFlags('importantValue', flags)
376
377
# Check current flags
378
current_flags = sd.getFlags('importantValue')
379
if current_flags & NetworkTables.EntryFlags.PERSISTENT:
380
print("Value is persistent")
381
382
# Clear specific flags
383
sd.clearFlags('importantValue', NetworkTables.EntryFlags.PERSISTENT)
384
385
# Using entry-level flag management
386
entry = NetworkTables.getEntry('/SmartDashboard/criticalData')
387
entry.setFlags(NetworkTables.EntryFlags.PERSISTENT)
388
389
if entry.isPersistent():
390
print("Entry is persistent")
391
```
392
393
### Bulk Data Operations
394
395
```python
396
from networktables import NetworkTables
397
398
def backup_all_data(backup_file='nt_backup.ini'):
399
"""Backup all NetworkTables data."""
400
try:
401
# Save everything by using root prefix
402
NetworkTables.saveEntries(backup_file, '/')
403
print(f"All data backed up to {backup_file}")
404
return True
405
except Exception as e:
406
print(f"Backup failed: {e}")
407
return False
408
409
def restore_from_backup(backup_file='nt_backup.ini'):
410
"""Restore data from backup file."""
411
try:
412
# Clear existing data first (optional)
413
NetworkTables.deleteAllEntries()
414
415
# Load from backup
416
NetworkTables.loadEntries(backup_file, '/')
417
print(f"Data restored from {backup_file}")
418
return True
419
except Exception as e:
420
print(f"Restore failed: {e}")
421
return False
422
423
def migrate_data_structure():
424
"""Migrate data from old structure to new structure."""
425
# Get old entries
426
old_entries = NetworkTables.getEntries('/OldConfig/')
427
428
# Migrate to new location
429
for entry in old_entries:
430
old_name = entry.getName()
431
new_name = old_name.replace('/OldConfig/', '/Config/')
432
433
# Copy value to new location
434
new_entry = NetworkTables.getEntry(new_name)
435
new_entry.setValue(entry.value)
436
437
# Copy persistence
438
if entry.isPersistent():
439
new_entry.setPersistent()
440
441
# Delete old entry
442
entry.delete()
443
444
print(f"Migrated {old_name} -> {new_name}")
445
446
# Usage
447
backup_all_data()
448
migrate_data_structure()
449
restore_from_backup()
450
```
451
452
## Best Practices
453
454
1. **Use persistence sparingly**: Only make truly configuration-related values persistent
455
2. **Regular backups**: Save important data periodically, not just on shutdown
456
3. **Error handling**: Always handle file I/O errors gracefully
457
4. **Data validation**: Validate loaded data before using it
458
5. **Cleanup**: Remove temporary entries to keep NetworkTables clean
459
6. **Migration support**: Plan for data structure changes over time