AT&T measurement catalogue

Every measurement_id the rXg produces, every protobuf ID the webhook accepts, and the gap between the two.

Scope: this is the off-rXg contract only. Everything below concerns what leaves the rXg for AT&T. The same ingested data separately drives the rXg's own view of its fleet — AP online/offline state, client counts, radio state, health notices — through entirely different code, and that on-rXg path uses none of these protobuf IDs. See §1 of the project context before concluding that a metric "is not collected" because it is absent here.
How this was built. Producer IDs extracted from every measurement_id: literal under console/app/lib/telemetry/{cisco,ruckus} on rgnets/rxg@32c0dfea95 (branch hbh/kpi-update). Protobuf IDs extracted from ATT_PROTOBUF_MEASUREMENT_TYPES in notifications.yaml on rgnets/att-templates@0e44313f27 (branch hbh/combined-new-schema). The three tables below are set operations over those two lists, so they are exhaustive as of 2026-09-17 — not a curated selection.
SetCountMeaning
Map entries71Keys in ATT_PROTOBUF_MEASUREMENT_TYPES (69 distinct ints — two are double-assigned).
Delivered31Produced by a vendor and mapped. This is what AT&T actually receives.
Dropped in transit12Produced by a vendor, absent from the map, silently discarded by the webhook's select.
Reserved40Mapped, but no code emits them. Aspirational or awaiting a producer.

1  Delivered — reaches AT&T today

Accessor columns name the method on Telemetry::Cisco::Grpc::Grpc / Telemetry::Ruckus::Mqtt::Mqtt that supplies the value, so you can trace any number back to its computation. Radio metrics carry source_subtype 0 and a band source_subcategory; switch and port metrics carry source_subtype 1.

IDmeasurement_idCiscoRuckusBacking accessorNotes
Radio — phase 1 — source_subtype 0, extra = radio slot ID
111client_count_per_apYYclient_countsDistinct client MACs per radio. Ruckus gates the whole client-derived block on this being non-zero.
112channel_utilization_avgYYchannel_utilizationsRuckus source field is airtime.
113throughput_per_client_avgYYap_to_client_throughput_avgsDownstream only, despite the name. Webhook divides by 10⁶ → Mbps.
114aggregate_throughput_avgYYap_to_client_ + client_to_ap_throughput_avgsSum of both directions. Webhook divides by 10⁶ → Mbps.
115rssi_avgYYrssi_avgsRuckus reads receiveSignalStrength. See the SNR/RSSI caveat below.
116snr_avgYYsnr_avgsRuckus reads client["rssi"] — the vendor's field names are crossed. See caveat.
117mcs_avgYYmcs_avgsDerived, not reported: StatsTask::McsComputation back-solves an index from rate + PHY + NSS + width. Computed last because it depends on the others.
122noise_avgYYnoise_floorsCisco falls back to a second source: noise_floors || noise_floors2.
123radio_band_primary_channelYYcurrent_channels
124radio_channel_widthYYchannel_width_avgsAn average width is sent, not the configured one.
126radio_power_levelYYtx_powersShares 126 with radio_gain — deliberate, commented in the map as "Map radio_gain to RADIO_POWER_LEVEL".
126radio_gainYYgainsSame int as above. AT&T cannot distinguish the two without measurement_id.
Switch — phase 2 — source_subtype 1, switch-level, Cisco only
4000switch_versionY—svalue: versionString metric — travels in svalue.
4001switch_poe_budgetY—poe_budgetCollides with the reserved temperature key, also 4001. Almost certainly meant 4002.
4003switch_poe_usageY—poe_usage
4005switch_stp_modeY—stp_modee.g. stp-mode-rapid-pvst.
4006switch_routesY—routesList metric — repeated Route message in the proto.
4007switch_vlan_stp_statesY—vlan_stp_statesRepeated VlanStpState. The webhook's map_stp_state helper folds blk/lis/lrn/fwd/dis into the port-status enum.
4008switch_vty_linesY—vty_linesRepeated VtyLine.
4009switch_cpu_loadY—cpu_loads
4010switch_memory_usageY—memory_usage
Port — phase 2 — source_subtype 1, extra = port BIA MAC, Cisco only
5000port_rx_packetsY—unicast_pkts_ins + multicast + broadcastSummed in Ruby from three separate counters.
5001port_tx_packetsY—unicast_pkts_outs + multicast + broadcastLikewise.
5002port_rx_discardsY—discards_ins
5003port_tx_discardsY—discards_outs
5004port_duplexY—duplexes
5005port_uptimeY—port_uptimes
5006port_poe_usageY—port_poe_usages
5007port_tagged_vlansY—svalue: tagged_vlansString metric. Keyed with bia_address: nil, unlike its neighbours.
5008port_access_vlanY—access_vlansSame nil-BIA keying.
5009port_native_vlanY—native_vlansSame nil-BIA keying.

2  Dropped in transit — produced, then discarded

The rXg computes all twelve of these and hands them to the webhook, which drops them because ATT_PROTOBUF_MEASUREMENT_TYPES has no matching key. No log line, no error — the select just narrows the array. Note that this includes every byte counter and every port speed/status value, three of which schema_notes.md documents as already having assigned protobuf IDs from the old scheme.

measurement_idCiscoRuckusWhy it is missing
switch_temperatureY—Pure name mismatch. The map's key is temperature; the producer emits switch_temperature. One string away from working.
bytes_rxY—schema_notes.md assigns RX_BYTES = 108. Never added to the map.
bytes_txY—TX_BYTES = 109. Same.
speedY—IF_SPEED = 87. Same.
connection_statusY—IF_OPER_STATUS = 83. Same. (Producer name differs from the notes' status.)
radio_channel_listYYMap entry exists but is commented out: #'radio_channel_list' => 125. Cisco sends it as svalue.
ap_to_client_total_transferYYMap has a placeholder #'…' => ? — protobuf ID never assigned.
client_to_ap_total_transferYYSame placeholder.
ap_to_client_total_throughputYYSame placeholder. Computed as transfer × 8 ÷ window.
client_to_ap_total_throughputYYSame placeholder.
radio_oper_stateY—No protobuf ID proposed anywhere. Cisco-only, sent as svalue.
device_uptimeY—Intentional. schema_notes.md: "internal use only in rXg, not mapped to a protobuf ID".

The four *_total_transfer / *_total_throughput elements are the volumetric ones — they are also the metrics that the missing SUM() in the continuous aggregates would affect. Assigning them protobuf IDs and fixing the rollup are the same piece of work viewed from two ends.

3  Reserved — mapped, no producer

40 keys in the map that no code emits. These are commitments, not capabilities. schema_notes.md is candid about it, marking both large blocks "not yet implemented in the rXg repository".

Gateway, 3000–3020  20 IDs

Whole-rXg metrics: no per-device source_id. schema_notes.md proposes source_subtype 14 (GATEWAY) but flags it uncertain. 3002 is unassigned. att-templates!20 (ldd/gateway_metrics) is the intended producer, and it targets hbh/combined-new-schema rather than master.

GroupIDsKeys
DHCP3000–3001gateway_dhcp_succ_num, gateway_dhcp_fail_num
Social-media tonnage3003–3004gateway_soc_media_tonnage_ds, …_us
Total tonnage3005–3006gateway_total_tonnage_dl, …_ul
Passpoint3007–3009gateway_passpt_tonnage_dl, …_ul, gateway_passpt_clients
Non-Passpoint3010–3012gateway_non_passpoint_tonnage_dl, …_ul, gateway_non_passpoint_clients
AAA (internal)3013–3016gateway_aaa_auth_time_avg, …_time_max, …_succ_num, …_fail_num
AAA (external)3017–3020gateway_external_aaa_auth_time_avg, …_time_max, …_succ_num, …_fail_num

The notes' original names were period-scoped (PASSPT_TONNAGE_24HR / 30DAY / 365DAY); the map replaced those with direction-scoped names (_dl / _ul) and no period. Whoever implements the producer has to settle what window a gateway tonnage value covers — the webhook asserts collection_interval: 300 for everything it sends.

WLAN sensor, 2000–2016  17 IDs

The absorbed phase-1 radio IDs. schema_notes.md lists PACKET_RETRANSMIT_AVG 118, LATENCY_AVG 119, JITTER_AVG 120 and PACKET_LOSS_AVG 121 as radio measurements, but none of 118–121 appear in the map — they were re-scoped into this sensor block instead. Worth confirming with AT&T that 118–121 are genuinely retired. We do have the underlying data: sensor ping jitter/loss/RTT already exist in the rXg as SensorMetric.

GroupIDsKeys
Link quality2000–2004wlan_sensor_packet_retransmit_avg, …_latency_avg, …_jitter_avg, …_packet_loss_avg, …_mos_score
Onboarding2005–2007wlan_sensor_dhcp_time, …_capport_time_avg, …_capport_time_max
Services2008–2010wlan_sensor_dns_average, …_avg_download, …_avg_upload
Client attributes2011–2016wlan_sensor_ssid, …_rssi, …_client_to_ap_mcs, …_primary_channel, …_channel_width, …_phyrate

No AAA block here, although the notes ask for five WLAN_SENSOR_AAA_* measurements. Those look to have become the gateway 3013–3020 range.

Three orphans

IDKeyStatus
4001temperatureName mismatch with the producer's switch_temperature and an int collision with switch_poe_budget. Two bugs in one entry.
4004switch_descriptionNotes say "intended but not currently implemented in rXg".
5010port_descriptionA descriptions KPI exists on the Cisco class but is excluded from PORT_KPIS_FOR_REPORT, so nothing emits it.

4  Identity fields

How AT&T tells one measurement apart from another. Set once per element by the producer, then stamped by the webhook.

FieldSet byValue
measurement_idproducerSnake-case name; the webhook rewrites underscores to spaces before sending.
measurement_typewebhookThe protobuf int from the map.
source_idproducerAP ethernet MAC, or switch primary MAC. source_id_type 1 = MAC.
extraproducerRadio slot ID (AP) or port BIA MAC (switch).
source_subtypeproducer0 AP, 1 switch. The proto enum also defines CONTROLLER 2, UPS 3, ONT 4, CELL 5, SERVER 6, CLIENT 7, DB 8, APPLIANCE 9, LB 10, GSLB 11, SAAS 12, HA 13, GATEWAY 14 — none of which we emit yet.
source_subcategoryproducerBand: 0 2.4G, 1 5G, 2 6G. Radio metrics only; nil elsewhere.
reporter_idwebhookThe rXg's own FQDN, from DeviceOption.active.domain_name. Sent with reporter_id_type 1 (MAC) even though it is a domain name.
customer_id / venue_idwebhookFrom the att_venue_info CustomDataSet. If that record is absent, both silently become "".
collection_intervalwebhookHard-coded 300 for every measurement, with the comment "time in seconds?". The Ruckus report window is actually 15 minutes.
timestampeitherProducer's value if present, else Time.now.to_i at send time.

5  Caveats to carry into any analysis

  1. Ruckus SNR and RSSI come from crossed vendor fields. EXTRACT_SNR reads client["rssi"] and EXTRACT_RSSI reads client["receiveSignalStrength"], annotated in the source as "ruckus messed this up on their end". IDs 115 and 116 are therefore not comparable between a Cisco venue and a Ruckus venue without knowing this.
  2. mcs_avg is inferred, not measured. Both vendors back-solve an MCS index from rate, PHY, NSS and channel width. Any gap in the PHY or width tables yields no value at all rather than a wrong one — which is the safer failure, but means missing data is expected for new PHYs.
  3. Ruckus client-derived metrics vanish when a radio is idle. to_kpi_report only appends SNR, RSSI, MCS and the throughput family when client_count.nonzero?. An idle radio still reports noise, utilisation, channel and power — so a missing 115 means "no clients", not "no data".
  4. Radio metrics are per radio; the ID says "per AP". client_count_per_ap (111) is emitted once per radio with the slot in extra. Summing it across an AP is the caller's job.
  5. Nothing here comes from OpenWiFi. Our own APs feed ClientMetric / RadioMetric / ThroughputMetric and never reach this webhook. A venue on our own hardware reports nothing to AT&T today.
  6. Ruckus values are bounded by a 20-minute cache TTL on the payload body, which is the only place the raw JSON exists. See the project context page.

Generated 2026-09-17 from the SHAs named at the top. Re-run the extraction before trusting the counts after either branch moves.  ← Project context