diff --git a/docs/project-state.md b/docs/project-state.md index a822ab6..2a408f4 100644 --- a/docs/project-state.md +++ b/docs/project-state.md @@ -163,4 +163,4 @@ Examples: 5. Add config backup/restore. 6. Improve BMS out-of-range behavior without changing NimBLE connect timeout. -- Fixed WebUI temperature probe scan by registering `/temps/scan`, `/temps/assign`, and `/temps/clear` firmware routes.\n\n- Added per-temperature-sensor `weather` flag and WebUI outside temperature badge with emoji thresholds: below 50°F ice, 50-74°F happy, 75-84°F sun, and 85°F+ fire.\n\n- Improved WebUI temperature sensor config checkbox layout with compact On/Weather controls.\n\n- Temperature probe assignment now enforces one logical slot per physical DS18B20 address; assigning a probe to a new slot clears the old slot mapping.\n\n- Added per-slot WebUI Clear buttons for temperature probe assignments using the existing `/temps/clear` API.\n\n- Fixed weather temp checkbox persistence by saving the `weather` flag from WebUI temp config and auto-saving checkbox changes.\n\n- Fixed temperature assignment clearing so Clear removes the stored DS18B20 address, disables the slot, clears weather flag, and resets cached temp state.\n\n- Hardened `/temps/clear` so clearing a temp slot removes the persisted DS18B20 address, disables the slot, clears weather flag, resets cached temp state, and supports clearing all slots with an empty POST body.\n\n- Removed legacy physical-scan-order fallback for unassigned DS18B20 slots; enabled slots now require an explicit assigned address before reporting a value.\n\n- Filtered DS18B20 scan results so already-assigned probe addresses are hidden until cleared from their configured temp slot.\n\n- Moved WebUI Temperature Assignment card directly above Temperature Sensor Config for better setup flow.\n\n- Added read-only assigned DS18B20 address display under each WebUI temperature config slot.\n \ No newline at end of file +- Fixed WebUI temperature probe scan by registering `/temps/scan`, `/temps/assign`, and `/temps/clear` firmware routes.\n\n- Added per-temperature-sensor `weather` flag and WebUI outside temperature badge with emoji thresholds: below 50°F ice, 50-74°F happy, 75-84°F sun, and 85°F+ fire.\n\n- Improved WebUI temperature sensor config checkbox layout with compact On/Weather controls.\n\n- Temperature probe assignment now enforces one logical slot per physical DS18B20 address; assigning a probe to a new slot clears the old slot mapping.\n\n- Added per-slot WebUI Clear buttons for temperature probe assignments using the existing `/temps/clear` API.\n\n- Fixed weather temp checkbox persistence by saving the `weather` flag from WebUI temp config and auto-saving checkbox changes.\n\n- Fixed temperature assignment clearing so Clear removes the stored DS18B20 address, disables the slot, clears weather flag, and resets cached temp state.\n\n- Hardened `/temps/clear` so clearing a temp slot removes the persisted DS18B20 address, disables the slot, clears weather flag, resets cached temp state, and supports clearing all slots with an empty POST body.\n\n- Removed legacy physical-scan-order fallback for unassigned DS18B20 slots; enabled slots now require an explicit assigned address before reporting a value.\n\n- Filtered DS18B20 scan results so already-assigned probe addresses are hidden until cleared from their configured temp slot.\n\n- Moved WebUI Temperature Assignment card directly above Temperature Sensor Config for better setup flow.\n\n- Added read-only assigned DS18B20 address display under each WebUI temperature config slot.\n\n- Fixed DS18B20 scan filtering so assigned probes are hidden from assignment results without removing them from runtime polling.\n \ No newline at end of file diff --git a/firmware/esp32/overland-controller/sensors.cpp b/firmware/esp32/overland-controller/sensors.cpp index e1e7a71..e426e64 100644 --- a/firmware/esp32/overland-controller/sensors.cpp +++ b/firmware/esp32/overland-controller/sensors.cpp @@ -15,6 +15,9 @@ DeviceAddress sensorAddresses[MAX_TEMP_SENSORS]; String sensorAddressStrings[MAX_TEMP_SENSORS]; int sensorCount = 0; +int tempScanResultIndexes[MAX_TEMP_SENSORS]; +int tempScanResultCount = 0; + float cToF(float c) { return (c * 9.0 / 5.0) + 32.0; } @@ -88,45 +91,48 @@ int scanTempSensors() { sensorCount = MAX_TEMP_SENSORS; } + tempScanResultCount = 0; + for (int i = 0; i < MAX_TEMP_SENSORS; i++) { sensorAddressStrings[i] = ""; + tempScanResultIndexes[i] = -1; } - int availableCount = 0; - for (int i = 0; i < sensorCount; i++) { - DeviceAddress address; - - if (!ds18b20.getAddress(address, i)) { + if (!ds18b20.getAddress(sensorAddresses[i], i)) { continue; } - String addressString = addressToString(address); + String addressString = addressToString(sensorAddresses[i]); + sensorAddressStrings[i] = addressString; if (isTempAddressAssigned(addressString)) { continue; } - memcpy(sensorAddresses[availableCount], address, 8); - sensorAddressStrings[availableCount] = addressString; - availableCount++; + tempScanResultIndexes[tempScanResultCount] = i; + tempScanResultCount++; } - sensorCount = availableCount; - - return sensorCount; + return tempScanResultCount; } int getTempScanResultCount() { - return sensorCount; + return tempScanResultCount; } String getTempScanResultAddress(int index) { - if (index < 0 || index >= sensorCount) { + if (index < 0 || index >= tempScanResultCount) { return ""; } - return sensorAddressStrings[index]; + int physicalIndex = tempScanResultIndexes[index]; + + if (physicalIndex < 0 || physicalIndex >= sensorCount) { + return ""; + } + + return sensorAddressStrings[physicalIndex]; } void printSensorAddresses() { @@ -191,11 +197,17 @@ bool assignTempSensorByIndex(int configIndex, int scanIndex) { return false; } - if (scanIndex < 0 || scanIndex >= sensorCount) { + if (scanIndex < 0 || scanIndex >= tempScanResultCount) { return false; } - String selectedAddress = sensorAddressStrings[scanIndex]; + int physicalIndex = tempScanResultIndexes[scanIndex]; + + if (physicalIndex < 0 || physicalIndex >= sensorCount) { + return false; + } + + String selectedAddress = sensorAddressStrings[physicalIndex]; for (int i = 0; i < MAX_TEMP_SENSORS; i++) { if (i == configIndex) {