This guide shows how to invoke PyPNM PNM capture endpoints using curl. Each example
sends a POST request with a JSON body that mirrors the common FastAPI request models.
Downstream OFDM Capture Endpoints
- Downstream OFDM RxMER
- Downstream OFDM Channel Estimation
- Downstream OFDM FEC Summary
- Downstream OFDM Modulation Profile
- Downstream OFDM Constellation Display
- Downstream Spectrum Analysis
Upstream OFDMA Capture Endpoints
PNM capture endpoints in PyPNM are all POST operations that accept a JSON body based
on a shared request model (for example, CommonRequest / PnmSingleCaptureRequest).
Representative routers and services:
CmDsOfdmRxMerServiceCmDsOfdmChanEstimateCoefCmDsOfdmFecSummaryCmDsOfdmModulationProfileCmSpectrumAnalysisCmUsOfdmaPreEq
The examples focus on how to structure the JSON and how to invoke the endpoints
with curl. Response payloads are typically JSON containing PNM metadata and capture
file information. Archive/plot outputs follow the same request shape but use a different
analysis.output.type value.
For all examples below, generic addresses are used:
- Example CM MAC address:
aa:bb:cc:dd:ee:ff - Example CM IP address:
192.168.0.100 - Example TFTP server (IPv4):
192.168.0.200 - Example TFTP server (IPv6):
::1(dummy placeholder)
Most PNM capture endpoints accept a request with this common structure (simplified).
Key details for the current implementation:
analysis.output.typeuses lowercase strings ("json","archive", etc.).analysis.plotis required for single-capture analysis routes; RxMER needs at leastplot.ui.theme.pnm_parameters.tftp.ipv6can safely use a dummy address::1if IPv6 is not otherwise used.
curl -X POST "http://127.0.0.1:8000/<endpoint>" -H "Content-Type: application/json" -d @- << 'JSON'
{
"cable_modem": {
"mac_address": "aa:bb:cc:dd:ee:ff",
"ip_address": "192.168.0.100",
"snmp": {
"snmp_v2c": {
"community": "private"
}
},
"pnm_parameters": {
"tftp": {
"ipv4": "192.168.0.200",
"ipv6": "::1",
"dest_dir": ""
},
"capture": {
"channel_ids": []
}
}
},
"analysis": {
"output": {
"type": "json"
},
"plot": {
"ui": {
"theme": "dark"
}
}
}
}
JSONYou can reuse this block and only change the <endpoint> path for each PNM capture.
Endpoint:
POST /docs/pnm/ds/ofdm/rxMer/getCapture
This is a validated RxMER pattern using the generic MAC/IP/TFTP and the required
analysis.plot.ui.theme field:
curl -X POST "http://127.0.0.1:8000/docs/pnm/ds/ofdm/rxMer/getCapture" -H "Content-Type: application/json" -d @- << 'JSON'
{
"cable_modem": {
"mac_address": "aa:bb:cc:dd:ee:ff",
"ip_address": "192.168.0.100",
"snmp": {
"snmp_v2c": {
"community": "private"
}
},
"pnm_parameters": {
"tftp": {
"ipv4": "192.168.0.200",
"ipv6": "::1",
"dest_dir": ""
},
"capture": {
"channel_ids": []
}
}
},
"analysis": {
"output": {
"type": "json"
},
"plot": {
"ui": {
"theme": "dark"
}
}
}
}
JSONThe response payload corresponds to the RxMER analysis model returned by your
Analysis(AnalysisType.BASIC, msg_rsp) path, combined with RxMER measurement stats.
Endpoint:
POST /docs/pnm/ds/ofdm/chanEstimate/getCapture
Channel estimation uses the same overall request shape. If the underlying route uses the
same CommonAnalysisRequest, this template should validate:
curl -X POST "http://127.0.0.1:8000/docs/pnm/ds/ofdm/chanEstimate/getCapture" -H "Content-Type: application/json" -d @- << 'JSON'
{
"cable_modem": {
"mac_address": "aa:bb:cc:dd:ee:ff",
"ip_address": "192.168.0.100",
"snmp": {
"snmp_v2c": {
"community": "private"
}
},
"pnm_parameters": {
"tftp": {
"ipv4": "192.168.0.200",
"ipv6": "::1",
"dest_dir": ""
},
"capture": {
"channel_ids": []
}
}
},
"analysis": {
"output": {
"type": "json"
},
"plot": {
"ui": {
"theme": "dark"
}
}
}
}
JSONThe JSON response will contain channel-estimation taps and related metadata, aligned with
your CmDsOfdmChanEstimateCoef / analysis models.
Endpoint:
POST /docs/pnm/ds/ofdm/fecSummary/getCapture
Example:
curl -X POST "http://127.0.0.1:8000/docs/pnm/ds/ofdm/fecSummary/getCapture" -H "Content-Type: application/json" -d @- << 'JSON'
{
"cable_modem": {
"mac_address": "aa:bb:cc:dd:ee:ff",
"ip_address": "192.168.0.100",
"snmp": {
"snmp_v2c": {
"community": "private"
}
},
"pnm_parameters": {
"tftp": {
"ipv4": "192.168.0.200",
"ipv6": "::1",
"dest_dir": ""
},
"capture": {
"channel_ids": []
}
}
},
"analysis": {
"output": {
"type": "json"
},
"plot": {
"ui": {
"theme": "dark"
}
}
}
}
JSONThe response payload typically includes per-profile and per-subcarrier summary counters (total codewords, corrected, uncorrectable, etc.).
Endpoint:
POST /docs/pnm/ds/ofdm/modulationProfile/getCapture
Example:
curl -X POST "http://127.0.0.1:8000/docs/pnm/ds/ofdm/modulationProfile/getCapture" -H "Content-Type: application/json" -d @- << 'JSON'
{
"cable_modem": {
"mac_address": "aa:bb:cc:dd:ee:ff",
"ip_address": "192.168.0.100",
"snmp": {
"snmp_v2c": {
"community": "private"
}
},
"pnm_parameters": {
"tftp": {
"ipv4": "192.168.0.200",
"ipv6": "::1",
"dest_dir": ""
}
}
},
"analysis": {
"output": {
"type": "json"
},
"plot": {
"ui": {
"theme": "dark"
}
}
}
}
JSONEndpoint:
POST /docs/pnm/ds/ofdm/constellationDisplay/getCapture
Constellation Display extends the same analysis block with additional plot options
(such as display_cross_hair). The example below matches your UI fields:
curl -X POST "http://127.0.0.1:8000/docs/pnm/ds/ofdm/constellationDisplay/getCapture" -H "Content-Type: application/json" -d @- << 'JSON'
{
"cable_modem": {
"mac_address": "aa:bb:cc:dd:ee:ff",
"ip_address": "192.168.0.100",
"snmp": {
"snmp_v2c": {
"community": "private"
}
},
"pnm_parameters": {
"tftp": {
"ipv4": "192.168.0.200",
"ipv6": "::1",
"dest_dir": ""
}
}
},
"analysis": {
"type": "basic",
"output": {
"type": "json"
},
"plot": {
"ui": {
"theme": "dark"
},
"options": {
"display_cross_hair": true
}
}
},
"capture_settings": {
"modulation_order_offset": 0,
"number_sample_symbol": 8192
}
}
JSONIf you switch the output type to a plot/archive-oriented value in your OutputType enum,
you can have this endpoint generate MatPlot reports instead of pure JSON.
Endpoint:
POST /docs/pnm/ds/spectrumAnalysis/getCapture
Example:
curl -X POST "http://127.0.0.1:8000/docs/pnm/ds/spectrumAnalysis/getCapture" -H "Content-Type: application/json" -d @- << 'JSON'
{
"cable_modem": {
"mac_address": "aa:bb:cc:dd:ee:ff",
"ip_address": "192.168.0.100",
"snmp": {
"snmp_v2c": {
"community": "private"
}
},
"pnm_parameters": {
"tftp": {
"ipv4": "192.168.0.200",
"ipv6": "::1",
"dest_dir": ""
}
}
},
"analysis": {
"type": "basic",
"output": {
"type": "json"
},
"plot": {
"ui": {
"theme": "dark"
}
},
"spectrum_analysis": {
"moving_average": {
"points": 10
}
}
},
"capture_parameters": {
"inactivity_timeout": 60,
"first_segment_center_freq": 300000000,
"last_segment_center_freq": 900000000,
"segment_freq_span": 1000000,
"num_bins_per_segment": 256,
"noise_bw": 150,
"window_function": 1,
"num_averages": 1,
"spectrum_retrieval_type": 1
}
}
JSONThe JSON response will contain spectrum sweep configuration and amplitude bins that map
directly onto the CmSpectrumAnalysis / CmSpectrumAnalysisSnmp models.
Endpoint:
POST /docs/pnm/us/ofdma/preEqualization/getCapture
Example:
curl -X POST "http://127.0.0.1:8000/docs/pnm/us/ofdma/preEqualization/getCapture" -H "Content-Type: application/json" -d @- << 'JSON'
{
"cable_modem": {
"mac_address": "aa:bb:cc:dd:ee:ff",
"ip_address": "192.168.0.100",
"snmp": {
"snmp_v2c": {
"community": "private"
}
},
"pnm_parameters": {
"tftp": {
"ipv4": "192.168.0.200",
"ipv6": "::1",
"dest_dir": ""
}
}
},
"analysis": {
"output": {
"type": "json"
},
"plot": {
"ui": {
"theme": "dark"
}
}
}
}
JSONThe response will include decoded upstream pre-equalizer taps which correspond to the
CmUsOfdmaPreEqModel used by the parser examples.
- When scripting against these endpoints, it is often convenient to template the common request body and just substitute MAC/IP/TFTP values.
- The same JSON payloads shown here can be used directly in Postman, Python
requests, or any other HTTP client. - For automation, you can combine these
curlinvocations with the parser examples insrc/pypnm/examples/python/parsers/to build end-to-end workflows:- Trigger capture via FastAPI.
- Download or reference the PNM binary.
- Parse with a
Cm*parser and feed into additional analysis utilities.