Skip to main content
Data sources supply the underlying data for Building BI dashboards. Each data source defines the columns, metrics, and calculations available to your charts and widgets.

In this guide

Choose a source

Compare physical, virtual, and key time-series sources.

Inspect schema

Preview columns, samples, and toolbar actions.

Add calculations

Create columns, metrics, and URL fields.

Optimize and validate

Optimize sources, check usage, and apply point bounds.
Navigate to Building BI and select Data Sources in the left navigation panel.
Data Sources page showing a table of data sources with columns for Name, Type (Physical or Virtual), Database Type (CLICKHOUSE, POSTGRES, or BIG_QUERY), Description, and Date Added, with a Search bar and Add Data Sources button

Data Sources page showing all available data sources with their type, database type, and description

Changes to data sources, calculated columns, and metrics are portfolio-wide. Any modification affects all dashboards across the entire portfolio, not just a single building.

Data source types

Building BI supports two data source types:
  • Physical — Maps directly to a database table managed by the backend. Physical data sources reflect the raw data stored in your connected database.
  • Virtual — Built from SQL queries (views) on top of physical tables. Virtual data sources give you flexibility to create custom datasets without modifying the underlying database. You can edit a virtual table’s SQL by clicking the three-dot menu on its row.
Both types expose columns and metrics that you can use when building dashboard charts. When you select a chart in edit mode, the Chart Configuration panel lets you pick a data source and drag its metrics into the X-Axis, Y-Axis, and Legend fields.
Dashboard in edit mode showing the Chart Configuration panel with Setup and Style tabs, a Charts section with chart type icons and search, a Data Source dropdown set to Timeseries Last Va, a Metrics list including Total Count, One Metric, Cooling Request Pe, Heating Request P, Percent Running St, Device ID, Zone Temp Inside, and more with fx buttons, X-Axis set to Area Name, and Legend and Y-Axis drop zones

Chart Configuration panel showing a selected data source and its available metrics

The Data Sources page provides two tabs: All Datasources lists every data source in your portfolio, and Favorites shows only data sources you have starred. Select the star icon on any row to add it to your favorites.
Data Sources page showing the Favorites tab with a single starred data source RTU Details of type Virtual and CLICKHOUSE database type added 3 minutes ago

Favorites tab showing starred data sources for quick access

Select the three-dot menu on any row in the data sources list to access Edit Details or Delete.
Data Sources list showing the All Datasources tab with a three-dot menu open on a row displaying Edit Details and Delete options, with RTU Details starred as a favorite

Row-level three-dot menu with Edit Details and Delete options

Never delete a data source unless you are certain no dashboards rely on it. Deleting a data source instantly breaks every dashboard and chart that references it across the entire portfolio.

Virtual table considerations

Virtual tables recompute on every query. Use them for light, real-time reshapes. Prefer physical tables when historical trending or heavy aggregation must stay fast.
  • You can create virtual tables on ClickHouse and PostgreSQL data sources.
  • You cannot create virtual tables on BigQuery.

Database types

Building BI connects to three database engines. Each stores a specific category of data, and each requires its own SQL dialect for calculated columns and metrics.
Tables do not join across database types. You cannot combine a ClickHouse table with a BigQuery table in a single query.
When writing calculated columns or metrics, use the SQL syntax that matches the database type of the data source. ClickHouse, PostgreSQL, and BigQuery each follow different SQL dialects.

Key data sources

While many tables exist, two primary sources cover the majority of sensor-related use cases:

Point Time Series Real-Time

The core sensor table where every reading creates a new row. This is the source of truth for building sensor data. Slight variants exist that poll less frequently — use those only when loading time is a concern. Point Time Series Real-Time runs on ClickHouse, so all calculated columns and metrics on this table must use ClickHouse SQL syntax.

Point Time Series Last Value

Returns only the most recent recorded value per sensor. Search Last Value in the data sources list to find this table.
Last Value rows are not a synchronized snapshot. Each row is the most recent reading for that sensor, regardless of timestamp. Do not use them for time-sensitive math that assumes every sensor sampled at once.

Aggregated tables

Some data sources aggregate readings at fixed intervals (15-minute, hourly, daily, or monthly). Aggregated tables return summary values (average, sum, maximum, minimum, count, or delta) for each point during the polling period. Aggregation is valuable for some sensor types. Hourly average air temperature shows how a space generally felt, while an hourly average of elevator floor level is less meaningful.

Polling and data structure

Each point time series table contains one row per data point at a given time period, along with context columns identifying the device, area, and building. You may see multiple rows from the same device at the same timestamp if they come from different points. Prefer ID columns over name columns for filters and calculations. Names are editable and not guaranteed unique. Each row carries nested layers of context around the data point, from the building level down to the individual sensor value: Two common polling patterns exist:
  • Change of value (COV) — A new row is created only when the value changes beyond the COV threshold, with a maximum interval of one hour between rows.
  • Structured polling — A new row is created at every polling interval (every 1, 2, 5, 10, or 15 minutes) regardless of whether the value changed.
Check the Point page and Device page in the left navigation bar to understand which points and devices exist in the building before building queries against point time series tables.

Data source schema

Selecting any data source name opens its schema view. The schema reveals the building blocks available for your dashboards across five tabs: Columns, Calculated, Metrics, URLs, and Actions.
Edit RTU Details schema view showing Virtual and Not Optimized badges, Schema and Samples tabs, a warning about changes affecting all charts, and columns tab with a table of columns including building_id, building_name, building_timezone, building_region, building_type, building_sqft, building_brand, building_phone_number, area_id, area_name, datasource_id, and datasource_name with their display names, descriptions, data types, hidden status, and sensitive value flags

Data source schema view showing columns with their display names, data types, and visibility settings

Schema toolbar actions

From the top of the schema view, you can:
  • Sync Datasource — Pull in the latest columns if the underlying KODE table was updated.
  • + Add Column — Create a new calculated column, metric, or URL.
  • Three-dot menu — Access Check Column Usage to see which dashboards reference specific columns, Check Optimization to review virtual table performance, or Edit Details to change basic parameters.
Data source schema view three-dot menu showing Check Column Usage, Check Optimization, and Edit Details options

Three-dot menu showing Check Column Usage, Check Optimization, and Edit Details options

Samples tab

The Samples tab previews a subset of records from the data source before you build charts. Use it to validate fields, confirm virtual table SQL, and inspect example values without creating a report first.
1

Open a data source

Navigate to Building BI > Data Sources and select a data source name.
2

Open Samples

Next to the Schema tab, select Samples.
3

Review the preview

The table shows available columns and example values. The preview is read-only and limited to approximately 20 rows for performance. Changes you make to the data source are reflected automatically when you return to Samples.Native columns and calculated columns appear together in the preview. Calculated columns show an i icon in the column header. Select the icon to open the column’s query. Use that when you are writing other calculated columns or metrics from the same source.
Edit Point Timeseries Samples tab showing a Physical data source with an info banner stating this is a preview with a maximum of 20 rows visible, and a table with columns for Connector ID, Building ID, Building TZ, Device ID, Field, Kind, Measurement, and Unit

Samples tab showing a preview of 20 rows from a physical data source

Both physical and virtual data sources support sample preview across ClickHouse, PostgreSQL, and BigQuery dialects.
Calculated columns appear at the end of the sample table. Look for the i icon in the header to confirm a column is calculated, then select it to inspect the expression.
Sample preview is for validation, not full data exploration. Use dashboards and charts for analysis workflows.

Calculated columns, metrics, and URLs

Calculated columns, calculated metrics, and URLs extend your data sources beyond raw columns. Use this section for SQL patterns and examples. For create steps, field options, data-type limits, and columns-versus-metrics graphics, see Calculated fields.
Editing a calculated column, metric, or URL affects all dashboards portfolio-wide. Always validate your logic before saving. Changing a calculation can break multiple live dashboards.

Calculated columns

Calculated columns apply row-level logic to produce a new value for each row independently, similar to a spreadsheet formula. Each calculated column contains a single SQL expression. Use calculated columns to:
  • Extract time components for filtering (for example, toHour(date_time_local) returns the hour as an integer).
  • Isolate a specific sensor’s values using conditional logic (for example, return number_value only when ontology_point_field matches a target, otherwise return null).
  • Plot multiple sensor readings side-by-side in a single chart.
The examples below use the Point Time Series Real-Time table, which runs on ClickHouse. All calculated columns and metrics on this table must follow ClickHouse SQL syntax. Match the dialect of your source: PostgreSQL, ClickHouse, or BigQuery.

Column rules

  • Each calculated column must have a unique name within the data source.
  • Column names must use the exact database field names (for example, building_name, not “Building Name”).
  • You cannot edit a calculated column’s SQL expression from the chart fx editor. Edit it in Data Sources directly.

Metadata syntax on Real-Time tables

When referencing metadata fields (such as building_name, device_name, or ontology_point_field) on the Point Time Series Real-Time table, you must wrap them in the dictGetString pattern:
Real-Time metadata example
Replace discharge_air_pressure_setpoint with any ontology_point_field value. Use the appropriate payload column (number_value, string_value, or boolean_value) depending on the point’s data type.

Simplified syntax on Last Value tables

The Last Value table is pre-processed, so you can reference metadata columns directly without dictGetString:
Last Value metadata example

Calculated metrics

Calculated metrics perform aggregate calculations across multiple rows. Unlike columns, metrics dynamically recalculate based on your chart’s grouping. If a chart is grouped by hour, the metric produces one value per hour. If grouped by device, it produces one value per device. Use aggregate functions like sumIf, countIf, or avgIf to filter rows before aggregating. You can combine multiple functions to build complex logic. Example: net occupancy metric This metric calculates occupancy by subtracting people leaving from people entering:
Net occupancy (Real-Time table)
Columns operate on a single row. Metrics aggregate across multiple rows. Use a column when you need a per-row value (for dimensions or filters). Use a metric when you need an aggregated result (for chart values).

URLs

URL columns turn data into navigation actions in your dashboards.

Internal URLs

Internal URLs follow the pattern /buildings/{building_id} and navigate within Cloud BMS on both desktop and mobile. Building BI validates the IDs automatically.
Add a Device URL to table widgets for a quality-of-life improvement. In the widget style settings, set the URL option on the device name column to Device URL. Each device name cell becomes a hyperlink to that device’s page, letting users jump directly from a dashboard finding to the relevant device.

External URLs

External URLs open in a new browser tab, allowing users to navigate to resources outside KODE OS such as a CMMS system or a specific work order. For URL behavior on chart widgets, data-type limits on metrics, and Hidden or Sensitive Values options, see Calculated fields.

Add a data source

1

Open the data sources page

Navigate to Building BI > Data Sources.
2

Start a new data source

Select + Add Data Sources and choose Physical or Virtual.
3

Configure the data source

On the Details tab, complete the required fields:
Add Data Source dialog with Virtual selected, Details tab active, showing Database Type set to CLICKHOUSE, Database set to point_time_series, Name set to rtu_details, Display Name set to RTU Details, a Description field, and Cancel and Save buttons

Add Data Source dialog showing the Details tab for a virtual data source

For virtual tables, switch to the SQL Expression tab to define the query. The Source Tables field lists the tables referenced in your SQL. Write the SQL expression using the syntax that matches the selected database type (PostgreSQL or ClickHouse).
Review existing virtual tables for SQL syntax examples. You can also consult the database engine documentation or use an LLM for query construction. LLMs handle standard ClickHouse and PostgreSQL syntax well, though they may not know KODE OS-specific table structures.
Add Data Source dialog with Virtual selected, SQL Expression tab active, showing Source Tables listing connector_time_series, device_time_series, and point_time_series aggregated_last_values, and a SQL Expression editor with a query using dictGetString on point_time_series metadata_dictionary

Add Data Source dialog showing the SQL Expression tab with source tables and query editor

4

Save the data source

Select Save to add the data source to your list. A confirmation toast appears.
Datasource created successfully confirmation toast

Confirmation toast after creating a data source

Creating new data sources is uncommon. Try to solve problems with existing data sources first. If a table exists at another client but is missing from yours, add it using the same connection details.

Optimize virtual data sources

Unoptimized virtual data sources load slower and can produce errors with large datasets. A warning banner reading “Not Optimized” appears at the top of any unoptimized data source. See dashboard performance for broader optimization guidance.

Optimize from the data source page

1

Open the data source

Navigate to Data Sources and select the virtual data source you want to optimize.
2

Edit the SQL expression

Select the three-dot menu and choose Edit Details. Switch to the SQL Expression tab to review and modify the query. An Optimize your Virtual Datasource section appears at the bottom with suggestions.
Edit RTU Details dialog with Virtual selected, SQL Expression tab showing Source Tables and SQL code editor with ClickHouse query, and an Optimize your Virtual Datasource expandable section at the bottom

Edit Details dialog showing the SQL Expression tab with optimization suggestions

3

Apply optimization suggestions

Expand the Optimize your Virtual Datasource section. The system generates AI-powered filter suggestions to limit the data retrieved from the source. Review the suggestion and apply it to improve query performance.
Optimize your Virtual Datasource section showing an AI-generated note about applying filters, a suggested filter template with column_name_filter placeholder, and expandable sections for point_time_series.aggregated_last_values and point_time_series.metadata source tables

Optimization suggestions with AI-generated filters for source tables

4

Save your changes

Select Save to apply the optimization.

Identify unoptimized sources from a dashboard

You can also check optimization status while editing a dashboard. Click Edit Dashboard, select a chart, and open the Setup panel. The Data Source dropdown flags any unoptimized sources so you can address them directly.

Check column usage

Unused columns add overhead to your data sources. Use the column usage check to identify and remove them.
1

Open column usage

From the data source schema view, select the three-dot menu and choose Check Column Usage.
2

Select what to check

Choose which categories to scan: Check Columns, Check Calculated, and Check Metrics. Each category shows the total number of items. Select Check to run the scan.
Check Usage dialog stating You are about to check usage of columns in this Data Source, with checkboxes for Check Columns with 51 Total Columns, Check Calculated with 0 Total Columns, and Check Metrics with 1 Total Columns, and Cancel and Check buttons

Check Usage dialog showing column, calculated, and metrics categories to scan

3

Remove unused columns

Review the results. Columns marked “Unused” can be safely deleted to reduce source overhead.

Point bounds and unit conversion

KODE OS stores point high/low bounds and a unit conversion foundation in the platform data model. These capabilities support analytics and diagnostics workflows in Building BI. They do not change displayed point values or trend charts by default.
Bounds and unit conversion are foundation capabilities. End-user value comes from dashboards, metrics, and filters your team builds on top of the platform data.

Point high/low bounds

The platform applies default minimum and maximum bounds per ontology field based on sensor or measurement type. Admins can review and adjust bounds per point in Point modeling. When an incoming value exceeds configured bounds, the platform flags the reading with an Out of Range state. Use this in Building BI to:
  • Filter point time series data to exclude bad readings from KPIs and rollups
  • Build sensor health dashboards that list points currently out of range
  • Group counts by device, system, floor, or area for calibration prioritization
  • Replace dashboards that rely on static ontology bounds with platform bounds logic
After bounds are enabled for your portfolio, run Sync Datasource on affected tables to pull the latest columns into Building BI.

Unit conversion foundation

The unit conversion layer normalizes compatible units within the same measurement type in the background. Use it in calculated columns and metrics when you aggregate data across buildings where the same point field may report in different units (for example, °C vs °F).
Dynamic units in widget Style settings control chart label formatting. They are separate from the platform unit conversion foundation used in data and metrics logic.

Build cleaner metrics

Use bounds and unit conversion together for more reliable KPIs:
  1. Normalize units in calculated metrics when rolling up the same ontology field across sites with different point_unit values.
  2. Exclude out-of-range readings so a small set of failing sensors does not skew portfolio averages or space-level rollups.
  3. Filter dashboards on Out of Range in cur_state or related status fields to surface sensors that need calibration or replacement.
Check the Data Quality global template in Templates as a starting point for sensor health dashboards, then extend it with bounds-aware filters and metrics.

Limitations

Calculated columns and metrics do not support window functions or aggregations of aggregations (nesting aggregate functions). This is a calculated field limit, not a ClickHouse limit. Two workarounds exist:
  • Virtual tables — Perform a window function or one level of aggregation in the virtual table SQL, then use the result as a regular column in your charts.
SQL dialect differs per database type. A ClickHouse expression does not work on a PostgreSQL or BigQuery data source without modification. Always verify the database type before writing or copying SQL expressions.
Thousands of calculations have been written across KODE deployments. If you are stuck, review existing calculated columns and metrics in other data sources for working examples, or ask your team for help.

Column reference

The Point Time Series tables (Real-Time and Last Value) share a common column structure. Use this reference when building calculated columns, metrics, or filters.

Physical vs virtual data sources

Compare direct tables with derived virtual sources.

Key data sources

Choose Real-Time or Last Value Point Time Series sources.

Database types

Understand ClickHouse, PostgreSQL, and BigQuery trade-offs.

Column reference

Look up column names for calculations and filters.

Next steps

Dashboards

Create and configure interactive dashboards with charts, tables, and widgets.

Widget customization

Customize chart styles, colors, and layouts for your dashboard widgets.
Last modified on August 18, 2026