{"record":{"id":"cfffa7bc413bd097","repo":"ruvnet/RuView","slug":"failed-to-parse-esp32-data-e","errorCode":null,"errorMessage":"Failed to parse ESP32 data: {e}","messagePattern":"Failed to parse ESP32 data: (.+?)","errorType":"exception","errorClass":"CSIParseError","httpStatus":null,"severity":"error","filePath":"archive/v1/src/hardware/csi_extractor.py","lineNumber":130,"sourceCode":"\n            all_values = np.array(float_values)\n            amplitude = all_values[:num_antennas * num_subcarriers].reshape(num_antennas, num_subcarriers)\n            phase = all_values[num_antennas * num_subcarriers:].reshape(num_antennas, num_subcarriers)\n            \n            return CSIData(\n                timestamp=datetime.fromtimestamp(timestamp_ms / 1000, tz=timezone.utc),\n                amplitude=amplitude,\n                phase=phase,\n                frequency=frequency,\n                bandwidth=bandwidth,\n                num_subcarriers=num_subcarriers,\n                num_antennas=num_antennas,\n                snr=snr,\n                metadata={'source': 'esp32', 'raw_length': len(raw_data)}\n            )\n            \n        except (ValueError, IndexError) as e:\n            raise CSIParseError(f\"Failed to parse ESP32 data: {e}\")\n\n\nclass ESP32BinaryParser:\n    \"\"\"Parser for ADR-018 binary CSI frames from ESP32 nodes.\n\n    Binary frame format:\n        Offset  Size  Field\n        0       4     Magic: 0xC5110001 (LE)\n        4       1     Node ID\n        5       1     Number of antennas\n        6       2     Number of subcarriers (LE u16)\n        8       4     Frequency MHz (LE u32)\n        12      4     Sequence number (LE u32)\n        16      1     RSSI (i8)\n        17      1     Noise floor (i8)\n        18      1     PPDU type (ADR-110): 0=HT/legacy, 1=HE-SU, 2=HE-MU,\n                       3=HE-TB, 0xFF=unknown. Pre-ADR-110 firmware sends 0.\n        19      1     Flags (ADR-110): bit 0 = bw40, bit 2 = STBC,","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/archive/v1/src/hardware/csi_extractor.py#L112-L148","documentation":"Catch-all at the end of ESP32CSIParser.parse: any ValueError or IndexError raised while reading the six header fields (timestamp, antennas, subcarriers, frequency, bandwidth, snr) is re-raised as CSIParseError('Failed to parse ESP32 data: ...'). IndexError means the line had fewer than seven comma-separated fields; ValueError means a header field failed int()/float().","triggerScenarios":"'CSI_DATA:123' or 'CSI_DATA:123,1,52' (IndexError: <7 fields); a non-numeric header field like 'CSI_DATA:ts,1,52,2437,20,31,...' (ValueError on int('ts')); a partial line delivered by a fixed-size chunked read.","commonSituations":"Reading the stream in fixed-size chunks instead of newline-delimited lines, so parse receives a line cut in half; header layout changes between firmware versions; CR/LF artifacts producing empty header fields.","solutions":["Read newline-delimited lines (readline / splitlines) so parse always receives a complete row","Pre-validate the header: split(',') must yield at least 7 fields and fields 0-5 must be numeric (see validationCode)","Keep firmware and pipeline versions in lockstep so the CSI_DATA header layout matches"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"def looks_like_esp32_header(line: bytes) -> bool:\n    parts = line.strip().split(b',')\n    if len(parts) < 7 or not line.startswith(b'CSI_DATA:'):\n        return False\n    try:\n        [int(parts[0]), int(parts[1]), int(parts[2])]\n        [float(parts[3]), float(parts[4]), float(parts[5])]\n    except ValueError:\n        return False\n    return True","typeGuard":null,"tryCatchPattern":"try:\n    data = parser.parse(raw)\nexcept CSIParseError as e:\n    logger.debug('dropping partial/malformed CSI line: %s (raw=%r)', e, raw[:80])","preventionTips":["Read the stream line-by-line (newline-delimited) instead of fixed-size chunks so partial lines never reach the parser","Validate the six header fields are present and numeric before parsing when ingesting untrusted captures","Upgrade firmware and pipeline together — header layout changes surface here as 'Failed to parse ESP32 data'"],"tags":["esp32","parsing","stream","protocol"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}