|
| 1 | +### Configuration Management |
| 2 | + |
| 3 | +#### Loading Configuration |
| 4 | + |
| 5 | +Configuration is loaded at startup in the following priority order: |
| 6 | + |
| 7 | +1. **SD Card**: `config.json` file on the SD card |
| 8 | +2. **Default**: Built-in default configuration if SD file not found |
| 9 | + |
| 10 | +#### Updating Configuration |
| 11 | + |
| 12 | +Configuration can be updated through: |
| 13 | + |
| 14 | +1. **Cloud Function**: `updateConfig` Particle function |
| 15 | + - copy the intended config.json and paste it as and argument into updateConfig |
| 16 | + - If successful, the device will restart without returning any value. |
| 17 | + - verify that the first metadata packet after reset matches your configuration |
| 18 | + - See below for other types of responses. |
| 19 | +3. **SD Card**: Replace `config.json` file and restart system |
| 20 | + |
| 21 | +#### updateConfig Function Details |
| 22 | + |
| 23 | +The `updateConfig` Particle cloud function accepts a JSON configuration string and applies it to the system. The function provides detailed feedback about the configuration update process. |
| 24 | + |
| 25 | +##### Usage |
| 26 | + |
| 27 | +```bash |
| 28 | +# Using Particle CLI |
| 29 | +particle call <device_name> updateConfig '{"config":{"system":{"logPeriod":600}}}' |
| 30 | + |
| 31 | +# Using Particle Console |
| 32 | +# Paste the JSON configuration directly into the function argument field |
| 33 | + |
| 34 | +# Remove configuration (revert to defaults) |
| 35 | +particle call <device_name> updateConfig 'remove' |
| 36 | +``` |
| 37 | + |
| 38 | +##### Response Types |
| 39 | + |
| 40 | +The `updateConfig` function returns different responses based on the outcome: |
| 41 | + |
| 42 | +**Success Responses:** |
| 43 | +- **Return 1**: Configuration updated successfully, device will restart automatically |
| 44 | +- **Return 0**: Configuration removed successfully (when using "remove" command) |
| 45 | +- Verify success by checking the first metadata packet after reset matches your configuration |
| 46 | +- New configuration UIDs will be available via `getSystemConfig` and `getSensorConfig` |
| 47 | + |
| 48 | +**Error Responses:** |
| 49 | +The function returns specific error codes when configuration updates fail: |
| 50 | + |
| 51 | +| Error Code | Description | Troubleshooting | |
| 52 | +|------------|-------------|-----------------| |
| 53 | +| `0` | Success - Configuration removed from SD card | | |
| 54 | +| `1` | Success - Configuration updated, system restarting | | |
| 55 | +| `-1` | Failed to remove configuration from SD card | | |
| 56 | +| `-2` | Invalid configuration format - Missing 'config' element | | |
| 57 | +| `-3` | Invalid configuration format - Missing 'system' element | | |
| 58 | +| `-4` | Invalid configuration format - Missing 'sensors' element | | |
| 59 | +| `-5` | Failed to write test file to SD card | | |
| 60 | +| `-6` | Failed to remove current configuration from SD card | | |
| 61 | +| `-7` | Failed to write new configuration to SD card | | |
| 62 | + |
| 63 | +##### Configuration Validation Rules |
| 64 | + |
| 65 | +The system performs several validation checks: |
| 66 | + |
| 67 | +1. **JSON Structure Validation** |
| 68 | + - Must contain "config" root element (checked by string search) |
| 69 | + - Must contain "system" section within config (checked by string search) |
| 70 | + - Must contain "sensors" section within config (checked by string search) |
| 71 | + - All whitespace, newlines, carriage returns, and tabs are automatically stripped |
| 72 | + |
| 73 | +2. **SD Card Validation** |
| 74 | + - SD card must be accessible for writing |
| 75 | + - System tests write capability before attempting configuration update |
| 76 | + - Current configuration must be removable before writing new configuration |
| 77 | + |
| 78 | +3. **Special Commands** |
| 79 | + - Use "remove" as the configuration string to delete config.json and revert to defaults |
| 80 | + |
| 81 | +##### Example Error Scenarios |
| 82 | + |
| 83 | +###### Missing Configuration Elements |
| 84 | +```bash |
| 85 | +particle call device_name updateConfig '{"system":{"logPeriod":300}}' # Missing "config" wrapper |
| 86 | +# Returns: -2 |
| 87 | + |
| 88 | +particle call device_name updateConfig '{"config":{"sensors":{"numSoil":3}}}' # Missing "system" section |
| 89 | +# Returns: -3 |
| 90 | + |
| 91 | +particle call device_name updateConfig '{"config":{"system":{"logPeriod":300}}}' # Missing "sensors" section |
| 92 | +# Returns: -4 |
| 93 | +``` |
| 94 | + |
| 95 | +###### SD Card Issues |
| 96 | +```bash |
| 97 | +# If SD card is not available or full |
| 98 | +particle call device_name updateConfig '{"config":{"system":{"logPeriod":300},"sensors":{}}}' |
| 99 | +# May return: -5, -6, or -7 depending on the specific SD card failure point |
| 100 | +``` |
| 101 | + |
| 102 | +###### Configuration Removal |
| 103 | +```bash |
| 104 | +particle call device_name updateConfig 'remove' |
| 105 | +# Returns: 0 (success) or -1 (failed to remove) |
| 106 | +``` |
| 107 | + |
| 108 | +##### Best Practices |
| 109 | + |
| 110 | +1. **Validate JSON First**: Use a JSON validator before sending to the device |
| 111 | +2. **Check Parameter Ranges**: Verify all values are within acceptable ranges |
| 112 | +3. **Plan Hardware Requirements**: Ensure sufficient Talons for sensor configuration |
| 113 | +4. **Monitor Device Status**: Watch for restart after successful configuration |
| 114 | +5. **Verify Configuration**: Check UIDs after restart to confirm changes applied |
| 115 | + |
| 116 | +#### Configuration UIDs |
| 117 | + |
| 118 | +The system generates unique identifiers for configuration tracking: |
| 119 | + |
| 120 | +- **System Configuration UID**: Changes when system parameters are modified |
| 121 | +- **Sensor Configuration UID**: Changes when sensor counts are modified |
| 122 | + |
| 123 | +These UIDs can be retrieved via cloud functions: |
| 124 | +- `getSystemConfig`: Returns system configuration UID |
| 125 | +- `getSensorConfig`: Returns sensor configuration UID |
| 126 | + |
| 127 | +##### UID Encoding Format |
| 128 | + |
| 129 | +The Configuration UIDs are encoded as 32-bit integers using bit-packing to efficiently store multiple configuration parameters in a single value. |
| 130 | + |
| 131 | +###### System Configuration UID Encoding |
| 132 | + |
| 133 | +The System Configuration UID is constructed using the following bit layout: |
| 134 | + |
| 135 | +``` |
| 136 | +Bits: 31-16 15-12 11-10 9-8 7-6 5-4 3-2 1-0 |
| 137 | +Field: logPeriod backhaul powerSave logMode numAux numI2C numSDI12 reserved |
| 138 | +``` |
| 139 | + |
| 140 | +| Field | Bits | Description | Range | |
| 141 | +|-------|------|-------------|-------| |
| 142 | +| `logPeriod` | 31-16 | Logging period in seconds | 0-65535 | |
| 143 | +| `backhaulCount` | 15-12 | Number of logs before backhaul | 0-15 | |
| 144 | +| `powerSaveMode` | 11-10 | Power management mode | 0-3 | |
| 145 | +| `loggingMode` | 9-8 | Logging behavior mode | 0-3 | |
| 146 | +| `numAuxTalons` | 7-6 | Number of Auxiliary Talons | 0-3 | |
| 147 | +| `numI2CTalons` | 5-4 | Number of I2C Talons | 0-3 | |
| 148 | +| `numSDI12Talons` | 3-2 | Number of SDI-12 Talons | 0-3 | |
| 149 | +| Reserved | 1-0 | Reserved for future use | 0-3 | |
| 150 | + |
| 151 | +**Encoding Formula:** |
| 152 | +```cpp |
| 153 | +int systemUID = (logPeriod << 16) | |
| 154 | + (backhaulCount << 12) | |
| 155 | + (powerSaveMode << 10) | |
| 156 | + (loggingMode << 8) | |
| 157 | + (numAuxTalons << 6) | |
| 158 | + (numI2CTalons << 4) | |
| 159 | + (numSDI12Talons << 2); |
| 160 | +``` |
| 161 | + |
| 162 | +###### Sensor Configuration UID Encoding |
| 163 | + |
| 164 | +The Sensor Configuration UID uses the following bit layout: |
| 165 | + |
| 166 | +``` |
| 167 | +Bits: 31-28 27-24 23-20 19-16 15-12 11-8 7-4 3-0 |
| 168 | +Field: numET numHaar numSoil numApogee numCO2 numO2 numPress reserved |
| 169 | +``` |
| 170 | + |
| 171 | +| Field | Bits | Description | Range | |
| 172 | +|-------|------|-------------|-------| |
| 173 | +| `numET` | 31-28 | Number of ET sensors (LI-710) | 0-15 | |
| 174 | +| `numHaar` | 27-24 | Number of Haar atmospheric sensors | 0-15 | |
| 175 | +| `numSoil` | 23-20 | Number of soil sensors (TDR315H) | 0-15 | |
| 176 | +| `numApogeeSolar` | 19-16 | Number of Apogee solar sensors | 0-15 | |
| 177 | +| `numCO2` | 15-12 | Number of CO2 sensors (Hedorah) | 0-15 | |
| 178 | +| `numO2` | 11-8 | Number of O2 sensors (SO421) | 0-15 | |
| 179 | +| `numPressure` | 7-4 | Number of pressure sensors | 0-15 | |
| 180 | +| Reserved | 3-0 | Reserved for future use | 0-15 | |
| 181 | + |
| 182 | +**Encoding Formula:** |
| 183 | +```cpp |
| 184 | +int sensorUID = (numET << 28) | |
| 185 | + (numHaar << 24) | |
| 186 | + (numSoil << 20) | |
| 187 | + (numApogeeSolar << 16) | |
| 188 | + (numCO2 << 12) | |
| 189 | + (numO2 << 8) | |
| 190 | + (numPressure << 4); |
| 191 | +``` |
| 192 | + |
| 193 | +##### UID Decoding Examples |
| 194 | + |
| 195 | +###### Decoding System Configuration UID |
| 196 | + |
| 197 | +To extract individual values from a System Configuration UID: |
| 198 | + |
| 199 | +```cpp |
| 200 | +// Example UID: 1234567890 (decimal) = 0x499602D2 (hex) |
| 201 | +int systemUID = 1234567890; |
| 202 | + |
| 203 | +// Extract each field |
| 204 | +int logPeriod = (systemUID >> 16) & 0xFFFF; // Bits 31-16 |
| 205 | +int backhaulCount = (systemUID >> 12) & 0xF; // Bits 15-12 |
| 206 | +int powerSaveMode = (systemUID >> 10) & 0x3; // Bits 11-10 |
| 207 | +int loggingMode = (systemUID >> 8) & 0x3; // Bits 9-8 |
| 208 | +int numAuxTalons = (systemUID >> 6) & 0x3; // Bits 7-6 |
| 209 | +int numI2CTalons = (systemUID >> 4) & 0x3; // Bits 5-4 |
| 210 | +int numSDI12Talons = (systemUID >> 2) & 0x3; // Bits 3-2 |
| 211 | +``` |
| 212 | + |
| 213 | +###### Decoding Sensor Configuration UID |
| 214 | + |
| 215 | +```cpp |
| 216 | +// Example UID: 305419896 (decimal) = 0x12345678 (hex) |
| 217 | +int sensorUID = 305419896; |
| 218 | + |
| 219 | +// Extract each field |
| 220 | +int numET = (sensorUID >> 28) & 0xF; // Bits 31-28 |
| 221 | +int numHaar = (sensorUID >> 24) & 0xF; // Bits 27-24 |
| 222 | +int numSoil = (sensorUID >> 20) & 0xF; // Bits 23-20 |
| 223 | +int numApogeeSolar = (sensorUID >> 16) & 0xF; // Bits 19-16 |
| 224 | +int numCO2 = (sensorUID >> 12) & 0xF; // Bits 15-12 |
| 225 | +int numO2 = (sensorUID >> 8) & 0xF; // Bits 11-8 |
| 226 | +int numPressure = (sensorUID >> 4) & 0xF; // Bits 7-4 |
| 227 | +``` |
| 228 | + |
| 229 | +A tool has been developed to help parse this UID and make sense of it, found [in RTGS_Lab gems_sensing_db_tools](https://github.com/RTGS-Lab/gems_sensing_db_tools) |
| 230 | + |
| 231 | +##### Practical Examples |
| 232 | + |
| 233 | +###### Example 1: Default Configuration |
| 234 | +```json |
| 235 | +{ |
| 236 | + "system": { |
| 237 | + "logPeriod": 300, |
| 238 | + "backhaulCount": 4, |
| 239 | + "powerSaveMode": 1, |
| 240 | + "loggingMode": 0, |
| 241 | + "numAuxTalons": 1, |
| 242 | + "numI2CTalons": 1, |
| 243 | + "numSDI12Talons": 1 |
| 244 | + } |
| 245 | +} |
| 246 | +``` |
| 247 | + |
| 248 | +**System UID Calculation:** |
| 249 | +- logPeriod (300) << 16 = 19660800 |
| 250 | +- backhaulCount (4) << 12 = 16384 |
| 251 | +- powerSaveMode (1) << 10 = 1024 |
| 252 | +- loggingMode (0) << 8 = 0 |
| 253 | +- numAuxTalons (1) << 6 = 64 |
| 254 | +- numI2CTalons (1) << 4 = 16 |
| 255 | +- numSDI12Talons (1) << 2 = 4 |
| 256 | + |
| 257 | +**System UID = 19678292** (decimal) or **0x12C4154** (hex) |
| 258 | + |
| 259 | +###### Example 2: Sensor Configuration |
| 260 | +```json |
| 261 | +{ |
| 262 | + "sensors": { |
| 263 | + "numET": 1, |
| 264 | + "numHaar": 2, |
| 265 | + "numSoil": 3, |
| 266 | + "numApogeeSolar": 1, |
| 267 | + "numCO2": 1, |
| 268 | + "numO2": 1, |
| 269 | + "numPressure": 1 |
| 270 | + } |
| 271 | +} |
| 272 | +``` |
| 273 | + |
| 274 | +**Sensor UID Calculation:** |
| 275 | +- numET (1) << 28 = 268435456 |
| 276 | +- numHaar (2) << 24 = 33554432 |
| 277 | +- numSoil (3) << 20 = 3145728 |
| 278 | +- numApogeeSolar (1) << 16 = 65536 |
| 279 | +- numCO2 (1) << 12 = 4096 |
| 280 | +- numO2 (1) << 8 = 256 |
| 281 | +- numPressure (1) << 4 = 16 |
| 282 | + |
| 283 | +**Sensor UID = 305205520** (decimal) or **0x12311110** (hex) |
| 284 | + |
| 285 | +##### UID Usage |
| 286 | + |
| 287 | +Configuration UIDs are used for: |
| 288 | + |
| 289 | +1. **Change Detection**: Compare current UID with stored UID to detect configuration changes |
| 290 | +2. **Remote Monitoring**: Cloud functions return UIDs for remote configuration verification |
| 291 | +3. **Debugging**: Quick identification of active configuration without full JSON parsing |
| 292 | +4. **Optimization**: Fast configuration comparison without string operations |
0 commit comments