Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,13 @@ This project adheres to [Semantic Versioning](https://semver.org/).

*Unreleased* versions radiate potential—-and dread. Once you merge an infernal PR, move its bullet under a new version heading with the actual release date.*



-->
## [1.2.2] = 2026-09-30
### Changed
- ⚡ `probe_data` table now has `value_float` and `value_jsonb` columns instead of one `value` (jsonb type) column.

## [1.2.1] - 2026-07-08
### Fixed
- 🩹 Addressed CVEs by updating minimum package versions for urllib3 2.7.0, pillow 12.3.0, mako 1.3.12, starlette 1.3.1, fastapi 0.139.0, idna 3.18, pytest 9.1.1, python-dotenv 1.2.2, fonttools 4.63.0, requests 2.34.2, markdown 3.10.2, pymdown-extensions 10.21.3, pygments 2.20.0, and python-multipart 0.0.32.
Expand Down
5 changes: 4 additions & 1 deletion opensampl/db/orm.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,10 @@ class ProbeData(Base):
primary_key=True,
comment="Foreign key to the metric type being measured",
)
value = Column(JSONB, comment="Measurement value stored as JSON; value's expected type defined via metric")
value_float = Column(Float, nullable=True, comment="Float type value; value's expected type defined via metric")
value_jsonb = Column(
JSONB, nullable=True, comment="Measurement value stored as JSON; value's expected type defined via metric"
)


class MetricType(Base):
Expand Down
28 changes: 19 additions & 9 deletions opensampl/load_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,18 +138,28 @@ def load_time_data(
df["probe_uuid"] = data_definition.probe.uuid # ty: ignore[possibly-unbound-attribute]
df["reference_uuid"] = data_definition.reference.uuid # ty: ignore[possibly-unbound-attribute]
df["metric_type_uuid"] = data_definition.metric.uuid # ty: ignore[possibly-unbound-attribute]
logger.debug(df.head())
# Ensure correct dtypes

# Ensure correct time dtypes
df["time"] = pd.to_datetime(df["time"], format="mixed", utc=True, errors="raise")
df["value"] = df["value"].apply(json.dumps)

if data_definition.metric.is_numeric():
df["value_float"] = pd.to_numeric(df["value"], errors="raise")
df["value_jsonb"] = None
else:
df["value_float"] = None
df["value_jsonb"] = df["value"].apply(json.dumps)

df = df.drop(columns=["value"]) # Drop original value column, as we now have value_float and value_jsonb
logger.debug(df.head())

records = df.to_dict(orient="records")
insert_stmt = text(f"""
INSERT INTO {ProbeData.__table__.schema}.{ProbeData.__tablename__}
(time, probe_uuid, reference_uuid, metric_type_uuid, value)
VALUES (:time, :probe_uuid, :reference_uuid, :metric_type_uuid, :value)
ON CONFLICT (time, probe_uuid, reference_uuid, metric_type_uuid)
DO NOTHING
""") # noqa: S608
INSERT INTO {ProbeData.__table__.schema}.{ProbeData.__tablename__}
(time, probe_uuid, reference_uuid, metric_type_uuid, value_float, value_jsonb)
VALUES (:time, :probe_uuid, :reference_uuid, :metric_type_uuid, :value_float, :value_jsonb)
ON CONFLICT (time, probe_uuid, reference_uuid, metric_type_uuid)
DO NOTHING
""") # noqa: S608

try:
result = session.execute(insert_stmt, records)
Expand Down
4 changes: 4 additions & 0 deletions opensampl/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ def convert_to_type(self, value: Any) -> Any:
"""Convert a given value to the expected type for the Metric"""
return self.value_type(value)

def is_numeric(self) -> bool:
"""Return True if the metric's value_type is numeric (int or float)"""
return self.value_type in [int, float]

@field_serializer("value_type")
def serialize_type(self, value: type):
"""Return the name of value_type for serializing"""
Expand Down
2 changes: 1 addition & 1 deletion opensampl/server/grafana/grafana-dashboards/ntp_dash.json
Original file line number Diff line number Diff line change
Expand Up @@ -1313,7 +1313,7 @@
"editorMode": "code",
"format": "table",
"rawQuery": true,
"rawSql": "WITH probe_ref AS (\n SELECT\n uuid,\n COALESCE(pm.name, CONCAT(pm.ip_address, ' ', pm.probe_id)) AS probe_name\n FROM castdb.probe_metadata pm\n)\nSELECT\n time_bucket('1 minute'::interval, pd.time AT TIME ZONE 'UTC') AS time,\n pd.probe_uuid,\n pr.probe_name,\n pd.reference_uuid,\n AVG(pd.value::float * 1e9) FILTER (WHERE lower(m.name) = 'phase offset') AS phase_offset,\n AVG(pd.value::float * 1e9) FILTER (WHERE lower(m.name) = 'jitter') AS jitter,\n AVG((pd.value)::float) FILTER (WHERE lower(m.name) = 'stratum') AS stratum,\n AVG((pd.value)::float) FILTER (WHERE lower(m.name) = 'sync health') AS sync_health\nFROM castdb.probe_data pd\nJOIN probe_ref pr\n ON pd.probe_uuid = pr.uuid\nJOIN castdb.metric_type m\n ON pd.metric_type_uuid = m.uuid\nWHERE pd.probe_uuid = ANY(ARRAY[${ntp_probe:sqlstring}]::text[]) AND $__timeFilter(pd.time)\nGROUP BY 1, 2, 3, 4\nORDER BY\n 1, 3;",
"rawSql": "WITH probe_ref AS (\n SELECT\n uuid,\n COALESCE(pm.name, CONCAT(pm.ip_address, ' ', pm.probe_id)) AS probe_name\n FROM castdb.probe_metadata pm\n)\nSELECT\n time_bucket('1 minute'::interval, pd.time AT TIME ZONE 'UTC') AS time,\n pd.probe_uuid,\n pr.probe_name,\n pd.reference_uuid,\n AVG(pd.value_float * 1e9) FILTER (WHERE lower(m.name) = 'phase offset') AS phase_offset,\n AVG(pd.value_float * 1e9) FILTER (WHERE lower(m.name) = 'jitter') AS jitter,\n AVG((pd.value)::float) FILTER (WHERE lower(m.name) = 'stratum') AS stratum,\n AVG((pd.value)::float) FILTER (WHERE lower(m.name) = 'sync health') AS sync_health\nFROM castdb.probe_data pd\nJOIN probe_ref pr\n ON pd.probe_uuid = pr.uuid\nJOIN castdb.metric_type m\n ON pd.metric_type_uuid = m.uuid\nWHERE pd.probe_uuid = ANY(ARRAY[${ntp_probe:sqlstring}]::text[]) AND $__timeFilter(pd.time)\nGROUP BY 1, 2, 3, 4\nORDER BY\n 1, 3;",
"refId": "A",
"sql": {
"columns": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@
"editorMode": "code",
"format": "time_series",
"rawQuery": true,
"rawSql": "SELECT \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n coalesce(pm.name, concat(pm.ip_address, ' Interface ', pm.probe_id)),\n AVG(pd.value::FLOAT) * 1e9 AS value\nFROM castdb.probe_data pd JOIN castdb.probe_metadata pm ON pd.probe_uuid = pm.uuid\nWHERE\n $__timeFilter(pd.time)\n AND pm.vendor IN ('ADVA', 'MicrochipTP4100', 'NTP')\n AND coalesce(pm.public, true)\n AND (trim('${clock_name:csv}') = '' OR pd.probe_uuid = ANY(string_to_array(trim('${clock_name:csv}'), ',')))\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pd.probe_uuid,\n pm.name,\n pm.ip_address,\n pm.probe_id\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')\n",
"rawSql": "SELECT \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n coalesce(pm.name, concat(pm.ip_address, ' Interface ', pm.probe_id)),\n AVG(pd.value_float) * 1e9 AS value\nFROM castdb.probe_data pd JOIN castdb.probe_metadata pm ON pd.probe_uuid = pm.uuid\nWHERE\n $__timeFilter(pd.time)\n AND pm.vendor IN ('ADVA', 'MicrochipTP4100', 'NTP')\n AND coalesce(pm.public, true)\n AND (trim('${clock_name:csv}') = '' OR pd.probe_uuid = ANY(string_to_array(trim('${clock_name:csv}'), ',')))\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pd.probe_uuid,\n pm.name,\n pm.ip_address,\n pm.probe_id\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')\n",
"refId": "A",
"sql": {
"columns": [
Expand Down Expand Up @@ -776,7 +776,7 @@
"editorMode": "code",
"format": "time_series",
"rawQuery": true,
"rawSql": "SELECT \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n COALESCE(pm.name, CONCAT(pm.ip_address, ' Interface ', pm.probe_id)),\n (MAX(pd.value::FLOAT) - MIN(pd.value::FLOAT)) * 1e9 AS value\nFROM castdb.probe_data pd JOIN castdb.probe_metadata pm ON pd.probe_uuid = pm.uuid\nWHERE\n $__timeFilter(pd.time)\n AND pm.vendor IN ('ADVA', 'MicrochipTP4100', 'NTP')\n AND coalesce(pm.public, true)\n AND (trim('${clock_name:csv}') = '' OR pd.probe_uuid = ANY(string_to_array(trim('${clock_name:csv}'), ',')))\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pd.probe_uuid,\n pm.name,\n pm.ip_address,\n pm.probe_id\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')\n",
"rawSql": "SELECT \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n COALESCE(pm.name, CONCAT(pm.ip_address, ' Interface ', pm.probe_id)),\n (MAX(pd.value_float) - MIN(pd.value_float)) * 1e9 AS value\nFROM castdb.probe_data pd JOIN castdb.probe_metadata pm ON pd.probe_uuid = pm.uuid\nWHERE\n $__timeFilter(pd.time)\n AND pm.vendor IN ('ADVA', 'MicrochipTP4100', 'NTP')\n AND coalesce(pm.public, true)\n AND (trim('${clock_name:csv}') = '' OR pd.probe_uuid = ANY(string_to_array(trim('${clock_name:csv}'), ',')))\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pd.probe_uuid,\n pm.name,\n pm.ip_address,\n pm.probe_id\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')\n",
"refId": "A",
"sql": {
"columns": [
Expand Down Expand Up @@ -916,7 +916,7 @@
"editorMode": "code",
"format": "time_series",
"rawQuery": true,
"rawSql": "SELECT \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n AVG(pd.value::FLOAT) * 1e9 AS value\nFROM castdb.probe_data pd\nWHERE\n $__timeFilter(pd.time)\n AND pd.probe_uuid = ${clock_name:sqlstring}\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pd.probe_uuid\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')\n",
"rawSql": "SELECT \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n AVG(pd.value_float) * 1e9 AS value\nFROM castdb.probe_data pd\nWHERE\n $__timeFilter(pd.time)\n AND pd.probe_uuid = ${clock_name:sqlstring}\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pd.probe_uuid\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')\n",
"refId": "A",
"sql": {
"columns": [
Expand Down Expand Up @@ -1027,7 +1027,7 @@
"editorMode": "code",
"format": "time_series",
"rawQuery": true,
"rawSql": "SELECT \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n (MAX(pd.value::FLOAT) - MIN(pd.value::FLOAT)) * 1e9 AS value\nFROM castdb.probe_data pd\nWHERE\n $__timeFilter(pd.time)\n AND pd.probe_uuid = ${clock_name:sqlstring}\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pd.probe_uuid\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')\n",
"rawSql": "SELECT \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n (MAX(pd.value_float) - MIN(pd.value_float)) * 1e9 AS value\nFROM castdb.probe_data pd\nWHERE\n $__timeFilter(pd.time)\n AND pd.probe_uuid = ${clock_name:sqlstring}\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pd.probe_uuid\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')\n",
"refId": "A",
"sql": {
"columns": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@
"format": "table",
"hide": false,
"rawQuery": true,
"rawSql": "SELECT \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n coalesce(pm.name, pm.probe_id) AS channel,\n AVG(pd.value::FLOAT) AS value\nFROM \n get_probe_data_by_probe_and_metric(${modem:sqlstring}, ${ebno_uuid:sqlstring}) pd\nJOIN \n castdb.reference r ON pd.reference_uuid = r.uuid\nJOIN \n castdb.probe_metadata pm ON r.compound_reference_uuid = pm.uuid\nWHERE \n $__timeFilter(pd.time)\n and r.compound_reference_uuid in (${compound_ref:sqlstring})\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pm.name,\n pm.probe_id\nORDER BY \n time\n",
"rawSql": "SELECT \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n coalesce(pm.name, pm.probe_id) AS channel,\n AVG(pd.value_float) AS value\nFROM \n get_probe_data_by_probe_and_metric(${modem:sqlstring}, ${ebno_uuid:sqlstring}) pd\nJOIN \n castdb.reference r ON pd.reference_uuid = r.uuid\nJOIN \n castdb.probe_metadata pm ON r.compound_reference_uuid = pm.uuid\nWHERE \n $__timeFilter(pd.time)\n and r.compound_reference_uuid in (${compound_ref:sqlstring})\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pm.name,\n pm.probe_id\nORDER BY \n time\n",
"refId": "B",
"sql": {
"columns": [
Expand Down Expand Up @@ -628,7 +628,7 @@
"format": "table",
"hide": false,
"rawQuery": true,
"rawSql": "select \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n COALESCE(pm.name, pm.probe_id) as name,\n AVG(pd.value::FLOAT) * 1e9 AS value\nFROM \n get_probe_data_by_probe_and_metric(${modem:sqlstring}, ${phase_offset_uuid:sqlstring}) pd\njoin castdb.reference r on pd.reference_uuid = r.uuid\nJOIN \n castdb.probe_metadata pm ON r.compound_reference_uuid = pm.uuid\nwhere \n $__timeFilter(pd.time)\n and r.compound_reference_uuid in (${compound_ref:sqlstring})\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pm.uuid\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')",
"rawSql": "select \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n COALESCE(pm.name, pm.probe_id) as name,\n AVG(pd.value_float) * 1e9 AS value\nFROM \n get_probe_data_by_probe_and_metric(${modem:sqlstring}, ${phase_offset_uuid:sqlstring}) pd\njoin castdb.reference r on pd.reference_uuid = r.uuid\nJOIN \n castdb.probe_metadata pm ON r.compound_reference_uuid = pm.uuid\nwhere \n $__timeFilter(pd.time)\n and r.compound_reference_uuid in (${compound_ref:sqlstring})\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pm.uuid\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')",
"refId": "B",
"sql": {
"columns": [
Expand Down Expand Up @@ -763,7 +763,7 @@
"format": "table",
"hide": false,
"rawQuery": true,
"rawSql": "select \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n COALESCE(pm.name, pm.probe_id) as name,\n (MAX(pd.value::FLOAT) - MIN(pd.value::FLOAT)) * 1e9 AS value\nFROM \n get_probe_data_by_probe_and_metric(${modem:sqlstring}, ${phase_offset_uuid:sqlstring}) pd\njoin castdb.reference r on pd.reference_uuid = r.uuid\nJOIN \n castdb.probe_metadata pm ON r.compound_reference_uuid = pm.uuid\nwhere \n $__timeFilter(pd.time)\n and r.compound_reference_uuid in (${compound_ref:sqlstring})\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pm.uuid\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')",
"rawSql": "select \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n COALESCE(pm.name, pm.probe_id) as name,\n (MAX(pd.value_float) - MIN(pd.value_float)) * 1e9 AS value\nFROM \n get_probe_data_by_probe_and_metric(${modem:sqlstring}, ${phase_offset_uuid:sqlstring}) pd\njoin castdb.reference r on pd.reference_uuid = r.uuid\nJOIN \n castdb.probe_metadata pm ON r.compound_reference_uuid = pm.uuid\nwhere \n $__timeFilter(pd.time)\n and r.compound_reference_uuid in (${compound_ref:sqlstring})\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pm.uuid\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')",
"refId": "B",
"sql": {
"columns": [
Expand Down Expand Up @@ -1246,7 +1246,7 @@
"format": "table",
"hide": false,
"rawQuery": true,
"rawSql": "select \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n AVG(pd.value::FLOAT) AS value\nFROM \n get_probe_data_by_probe_and_metric(${modem:sqlstring}, ${ebno_uuid:sqlstring}) pd\njoin castdb.reference r on pd.reference_uuid = r.uuid\nwhere \n $__timeFilter(pd.time)\n AND r.compound_reference_uuid = ${compound_ref:sqlstring}\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pd.probe_uuid\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')",
"rawSql": "select \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n AVG(pd.value_float) AS value\nFROM \n get_probe_data_by_probe_and_metric(${modem:sqlstring}, ${ebno_uuid:sqlstring}) pd\njoin castdb.reference r on pd.reference_uuid = r.uuid\nwhere \n $__timeFilter(pd.time)\n AND r.compound_reference_uuid = ${compound_ref:sqlstring}\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pd.probe_uuid\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')",
"refId": "B",
"sql": {
"columns": [
Expand Down Expand Up @@ -1367,7 +1367,7 @@
"format": "table",
"hide": false,
"rawQuery": true,
"rawSql": "select \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n AVG(pd.value::FLOAT) * 1e9 AS value\nFROM \n get_probe_data_by_probe_and_metric(${modem:sqlstring}, ${phase_offset_uuid:sqlstring}) pd\njoin castdb.reference r on pd.reference_uuid = r.uuid\nwhere \n $__timeFilter(pd.time)\n AND r.compound_reference_uuid = ${compound_ref:sqlstring}\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pd.probe_uuid\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')",
"rawSql": "select \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n AVG(pd.value_float) * 1e9 AS value\nFROM \n get_probe_data_by_probe_and_metric(${modem:sqlstring}, ${phase_offset_uuid:sqlstring}) pd\njoin castdb.reference r on pd.reference_uuid = r.uuid\nwhere \n $__timeFilter(pd.time)\n AND r.compound_reference_uuid = ${compound_ref:sqlstring}\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pd.probe_uuid\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')",
"refId": "B",
"sql": {
"columns": [
Expand Down Expand Up @@ -1488,7 +1488,7 @@
"format": "table",
"hide": false,
"rawQuery": true,
"rawSql": "select \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n (MAX(pd.value::FLOAT) - MIN(pd.value::FLOAT)) * 1e9 AS value\nFROM \n get_probe_data_by_probe_and_metric(${modem:sqlstring}, ${phase_offset_uuid:sqlstring}) pd\njoin castdb.reference r on pd.reference_uuid = r.uuid\nwhere \n $__timeFilter(pd.time)\n AND r.compound_reference_uuid = ${compound_ref:sqlstring}\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pd.probe_uuid\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')",
"rawSql": "select \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC') AS time,\n (MAX(pd.value_float) - MIN(pd.value_float)) * 1e9 AS value\nFROM \n get_probe_data_by_probe_and_metric(${modem:sqlstring}, ${phase_offset_uuid:sqlstring}) pd\njoin castdb.reference r on pd.reference_uuid = r.uuid\nwhere \n $__timeFilter(pd.time)\n AND r.compound_reference_uuid = ${compound_ref:sqlstring}\nGROUP BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC'),\n pd.probe_uuid\nORDER BY \n time_bucket(${resolution:sqlstring}, pd.time AT TIME ZONE 'UTC')",
"refId": "B",
"sql": {
"columns": [
Expand Down
Loading
Loading