import os
import zipfile
# Define file path
zip_path = "/mnt/data/ucls-plc-heatmap-addon.zip"
# Rebuild the ZIP file since the previous one expired
with zipfile.ZipFile(zip_path, 'w') as zipf:
# ClickHouse SQL patch
sql_patch = """\
CREATE TABLE IF NOT EXISTS plc_spectrum_bins_ch (
ts DateTime,
endpoint_id String,
link_id String,
center_mhz Float32,
bin_width_khz Float32,
power_dbm Float32,
notch UInt8,
quality Float32
) ENGINE = MergeTree ORDER BY (endpoint_id, link_id, ts, center_mhz);
"""
zipf.writestr("telemetry/clickhouse_plc_patch.sql", sql_patch)
# Grafana dashboard JSON stub
grafana_json = {
"dashboard": {
"id": None,
"title": "PLC Spectrum Heatmap",
"panels": [{
"type": "heatmap",
"title": "PLC Spectrum Heatmap (ClickHouse)",
"targets": [{
"query": "SELECT ts, center_mhz, avg(power_dbm) as value FROM plc_spectrum_bins_ch GROUP BY ts, center_mhz ORDER BY ts"
}]
}],
"schemaVersion": 27,
"version": 1
},
"overwrite": True
}
import json
zipf.writestr("dashboards/ucls-plc-heatmap.json", json.dumps(grafana_json, indent=2))
# Sample CSV
sample_csv = """ts,endpoint_id,link_id,center_mhz,bin_width_khz,power_dbm,notch,quality
2025-08-19 10:00:00,E1,L1,2.0,0.5,-60,0,0.95
2025-08-19 10:00:01,E1,L1,2.5,0.5,-62,0,0.94
2025-08-19 10:00:02,E1,L1,3.0,0.5,-80,1,0.90
"""
zipf.writestr("samples/plc_spectrum_bins_sample.csv", sample_csv)
zip_path
import os
import zipfile
import json
# Define new file path after reset
zip_path = "/mnt/data/ucls-plc-heatmap-addon.zip"
# Rebuild the ZIP file for PLC Spectrum Heatmap integration
with zipfile.ZipFile(zip_path, 'w') as zipf:
# ClickHouse SQL patch
sql_patch = """\
CREATE TABLE IF NOT EXISTS plc_spectrum_bins_ch (
ts DateTime,
endpoint_id String,
link_id String,
center_mhz Float32,
bin_width_khz Float32,
power_dbm Float32,
notch UInt8,
quality Float32
) ENGINE = MergeTree ORDER BY (endpoint_id, link_id, ts, center_mhz);
"""
zipf.writestr("telemetry/clickhouse_plc_patch.sql", sql_patch)
# Grafana dashboard JSON stub
grafana_json = {
"dashboard": {
"id": None,
"title": "PLC Spectrum Heatmap",
"panels": [{
"type": "heatmap",
"title": "PLC Spectrum Heatmap (ClickHouse)",
"targets": [{
"query": "SELECT ts, center_mhz, avg(power_dbm) as value FROM plc_spectrum_bins_ch GROUP BY ts, center_mhz ORDER BY ts"
}]
}],
"schemaVersion": 27,
"version": 1
},
"overwrite": True
}
zipf.writestr("dashboards/ucls-plc-heatmap.json", json.dumps(grafana_json, indent=2))
# Sample CSV
sample_csv = """ts,endpoint_id,link_id,center_mhz,bin_width_khz,power_dbm,notch,quality
2025-08-19 10:00:00,E1,L1,2.0,0.5,-60,0,0.95
2025-08-19 10:00:01,E1,L1,2.5,0.5,-62,0,0.94
2025-08-19 10:00:02,E1,L1,3.0,0.5,-80,1,0.90
"""
zipf.writestr("samples/plc_spectrum_bins_sample.csv", sample_csv)
zip_path
👉 Download the PLC Heatmap Add-On
Contents
1. Telemetry Patchtelemetry/clickhouse_plc_patch.sql
Creates a new ClickHouse table:
CREATE TABLE IF NOT EXISTS plc_spectrum_bins_ch (
ts DateTime,
endpoint_id String,
link_id String,
center_mhz Float32,
bin_width_khz Float32,
power_dbm Float32,
notch UInt8,
quality Float32
) ENGINE = MergeTree ORDER BY (endpoint_id, link_id, ts, center_mhz);
2. Grafana Dashboard Stubdashboards/ucls-plc-heatmap.json
Adds a heatmap panel that queries from plc_spectrum_bins_ch, showing:
- X-axis= time
- Y-axis= frequency (MHz)
- Color= average power (dBm)
3. Sample Datasamples/plc_spectrum_bins_sample.csv
ts,endpoint_id,link_id,center_mhz,bin_width_khz,power_dbm,notch,quality
2025-08-19 10:00:00,E1,L1,2.0,0.5,-60,0,0.95
2025-08-19 10:00:01,E1,L1,2.5,0.5,-62,0,0.94
2025-08-19 10:00:02,E1,L1,3.0,0.5,-80,1,0.90
How to Apply
- Create table in ClickHouse
clickhouse-client -mn < telemetry/clickhouse_plc_patch.sql - (Optional) Load the sample CSV
clickhouse-client --query="INSERT INTO plc_spectrum_bins_ch FORMAT CSVWithNames" < samples/plc_spectrum_bins_sample.csv - Import dashboard into Grafana
- Datasource UID should be
CLICKHOUSE_DS. - Import
dashboards/ucls-plc-heatmap.json.
- Datasource UID should be
You’ll then see PLC carrier bins as a heatmap, with deep notches for ham/aviation avoidance and warm carriers where modulation is active.
Would you like me to go ahead and build the PoE Power-Budget Bar add-on next (so you can visualize per-switch and per-endpoint draw)?
Key terms in plain language
Open a term for a concise explanation of language used on this page.
Broadband
A general term for always-on, high-speed Internet access. Broadband can be delivered over fiber, cable, DSL, fixed wireless, cellular, or satellite networks.
Cloud Computing
Computing resources—such as applications, servers, storage, or databases—delivered from remote infrastructure and scaled as requirements change.
Cybersecurity
The practices and controls used to protect identities, devices, networks, applications, and data from unauthorized access, disruption, or manipulation.
Identity and Access Management (IAM)
The systems and policies that determine who a user is, what resources they may access, and how that access is authenticated and reviewed.
API
An application programming interface is a defined way for software systems to exchange data or request functions from one another.
Artificial Intelligence (AI)
Software designed to perform tasks involving prediction, classification, generation, reasoning, or decision support. Business use still requires clear data, governance, security, and human accountability.