> For the complete documentation index, see [llms.txt](https://navixy.com/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://navixy.com/docs/analytics/id/iot-query/schema-overview/transformation-layer/common-transformations/sensor-data-aggregation.md).

# Agregasi data sensor

Proses pembacaan sensor IoT mentah menjadi catatan per jam dengan keranjang waktu, kalibrasi terdekode, perhitungan volume bahan bakar, dan agregasi tingkat perangkat

Transformasi agregasi data sensor melakukan resampling pembacaan sensor mentah menjadi catatan ringkasan berbasis bucket waktu. Setiap baris dalam `processed_common_data.sensors_data_by_hours` merepresentasikan satu sensor pada satu perangkat untuk satu bucket: nilai terdekode rata-rata, minimum, dan maksimum, serta, untuk sensor bahan bakar, volume terkalibrasi pada masing-masing titik tersebut.

Transformasi bawaan berjalan setiap jam dan mengagregasi data sensor mentah dari jam terakhir dari `raw_telematics_data.inputs` ke dalam bucket satu jam. Setiap proses menambahkan seperangkat catatan per jam yang baru ke tabel.

{% hint style="info" %}
Data dalam tabel ini mungkin berusia hingga 1 jam, yang mencerminkan proses yang paling baru selesai.\
Semua stempel waktu disimpan dalam UTC.\
Hanya nilai sensor numerik yang ikut dalam agregasi. Status teks, bilangan negatif, dan notasi ilmiah difilter di sumber.
{% endhint %}

### Tabel output: processed\_common\_data.sensors\_data\_by\_hours

Setiap baris merepresentasikan satu bucket pembacaan teragregasi untuk satu sensor pada satu perangkat. Dalam transformasi bawaan, setiap bucket mencakup satu jam. Kunci alami adalah `hour_bucket`, `device_id`, `sensor_name`, dan `event_id`.

<table><thead><tr><th width="245">Bidang</th><th width="115">Tipe</th><th>Deskripsi</th></tr></thead><tbody><tr><td><code>hour_bucket</code></td><td>timestamp</td><td>Awal bucket waktu yang diagregasikan oleh baris. Dalam transformasi bawaan, selalu disejajarkan dengan batas jam dalam UTC. Dalam transformasi kustom dengan ukuran bucket yang berbeda, ini adalah awal bucket pada granularitas yang dipilih (misalnya, awal jendela 5 menit).</td></tr><tr><td><code>device_id</code></td><td>integer</td><td>Pengidentifikasi perangkat. Untuk mendapatkan label Pelacak tanpa penggandaan baris, gabungkan ke <code>raw_business_data.objects</code> on <code>device_id</code> where <code>is_deleted = false</code>.</td></tr><tr><td><code>sensor_name</code></td><td>text</td><td>Pengidentifikasi input mentah dari <code>raw_telematics_data.inputs</code>. Sesuai dengan <code>sensor_description.input_label</code> saat sensor dikonfigurasi.</td></tr><tr><td><code>event_id</code></td><td>integer</td><td>Pengidentifikasi jenis peristiwa untuk pembacaan sensor.</td></tr><tr><td><code>sensor_id</code></td><td>integer</td><td>Pengidentifikasi entitas sensor dari <code>raw_business_data.sensor_description</code>. Null jika sensor tidak dikonfigurasi.</td></tr><tr><td><code>input_label</code></td><td>text</td><td>Label input yang dikonfigurasi dari <code>sensor_description</code>. Sesuai dengan <code>sensor_name</code> jika tersedia.</td></tr><tr><td><code>sensor_label</code></td><td>text</td><td>Nama sensor yang dapat dibaca manusia yang ditetapkan oleh pengguna.</td></tr><tr><td><code>jenis_sensor</code></td><td>text</td><td>Jenis sensor, misalnya <code>level Bahan bakar</code>, <code>suhu</code>, <code>Pengapian</code>.</td></tr><tr><td><code>satuan_sensor</code></td><td>text</td><td>String satuan yang dimasukkan pengguna saat <code>jenis_satuan</code> disetel ke kustom. Kosong jika tidak.</td></tr><tr><td><code>jenis_satuan</code></td><td>integer</td><td>Kode numerik untuk kategori unit. Diuraikan menjadi string yang dapat dibaca manusia dalam <code>sensor_deskripsi_satuan_tipe</code>.</td></tr><tr><td><code>tipe_kelompok</code></td><td>integer</td><td>Kode aturan agregasi untuk sensor yang dikelompokkan: 0 untuk jumlah, 1 untuk rata-rata. Diselesaikan di <code>sensor_deskripsi_Kelompok_tipe</code>.</td></tr><tr><td><code>value_avg</code></td><td>bilangan pecahan</td><td>Rata-rata nilai sensor yang telah didekode di seluruh pembacaan dalam bucket.</td></tr><tr><td><code>value_min</code></td><td>bilangan pecahan</td><td>Nilai minimum yang didekode di dalam bucket.</td></tr><tr><td><code>value_max</code></td><td>bilangan pecahan</td><td>Nilai maksimum hasil dekode di bucket.</td></tr><tr><td><code>val_low_avg</code>, <code>val_high_avg</code>, <code>vol_low_avg</code>, <code>vol_high_avg</code></td><td>numeric</td><td>Titik batas kalibrasi yang digunakan saat interpolasi <code>calibrated_volume_avg</code>. Hanya sensor bahan bakar; selain itu null.</td></tr><tr><td><code>calibrated_volume_avg</code></td><td>numeric</td><td>Volume terkalibrasi yang sesuai dengan <code>value_avg</code>dihitung dengan interpolasi linear antara titik-titik batas. Untuk sensor non-Bahan bakar, ini sama dengan <code>value_avg</code>.</td></tr><tr><td><code>val_low_min</code>, <code>val_high_min</code>, <code>vol_low_min</code>, <code>vol_high_min</code>, <code>calibrated_volume_min</code></td><td>numeric</td><td>Titik-titik batas kalibrasi dan volume terinterpolasi untuk <code>value_min</code>.</td></tr><tr><td><code>val_low_max</code>, <code>val_high_max</code>, <code>vol_low_max</code>, <code>vol_high_max</code>, <code>calibrated_volume_max</code></td><td>numeric</td><td>Titik-titik batas kalibrasi dan volume terinterpolasi untuk <code>value_max</code>.</td></tr><tr><td><code>label Pelacak</code></td><td>text</td><td>Label Pelacak dari <code>raw_business_data.objects</code>. Dapat muncul beberapa kali untuk bucket yang sama jika sebuah perangkat pernah dialihkan antarobjek secara historis.</td></tr><tr><td><code>sensor_deskripsi_satuan_tipe</code></td><td>text</td><td>Kategori unit yang dapat dibaca manusia ditentukan dari <code>jenis_satuan</code>.</td></tr><tr><td><code>sensor_deskripsi_Kelompok_tipe</code></td><td>text</td><td>Aturan pengelompokan yang dapat dibaca manusia yang diturunkan dari <code>tipe_kelompok</code>.</td></tr><tr><td><code>unit sensor akhir</code></td><td>text</td><td>String satuan yang ditampilkan. Sama dengan <code>satuan_sensor</code> ketika disetel, jika tidak akan kembali ke <code>sensor_deskripsi_satuan_tipe</code>.</td></tr><tr><td><code>value_title</code></td><td>text</td><td>Label yang dapat dibaca manusia untuk sensor diskret, diambil dari <code>parameters.value_titles</code> menggunakan <code>value_max</code> sebagai kunci. Null untuk sensor pengukuran.</td></tr></tbody></table>

Contoh di bawah menunjukkan pola kueri umum. Yang pertama mengembalikan agregat per jam untuk 7 hari terakhir. Yang kedua melakukan join ke `raw_business_data.objects` untuk menyertakan label pelacak tanpa penggandaan baris. Yang ketiga berfokus pada sensor bahan bakar dan menggunakan kolom volume terkalibrasi.

{% tabs %}
{% tab title="Kueri per jam dasar" %}
{% code overflow="wrap" expandable="true" %}

```sql
SELECT
    device_id,
    hour_bucket,
    sensor_label,
    sensor_type,
    value_avg,
    value_min,
    value_max,
    unit sensor akhir
FROM processed_common_data.sensors_data_by_hours
WHERE hour_bucket >= CURRENT_DATE - INTERVAL '7 days'
ORDER BY device_id, hour_bucket, sensor_label;
```

{% endcode %}
{% endtab %}

{% tab title="Dengan label Pelacak" %}
{% code overflow="wrap" expandable="true" %}

```sql
SELECT
    s.device_id,
    o.pelacak_label,
    s.hour_bucket,
    s.sensor_label,
    s.value_avg,
    s.sensor_units_final
FROM processed_common_data.sensors_data_by_hours s
LEFT JOIN raw_business_data.objects o
    ON o.device_id = s.device_id
   AND o.is_deleted = false
WHERE s.hour_bucket >= CURRENT_DATE - INTERVAL '7 days'
ORDER BY s.device_id, s.hour_bucket, s.sensor_label;
```

{% endcode %}
{% endtab %}

{% tab title="Sensor bahan bakar dengan volume terkalibrasi" %}
{% code overflow="wrap" expandable="true" %}

```sql
SELECT
    device_id,
    hour_bucket,
    sensor_label,
    value_avg AS raw_avg,
    calibrated_volume_avg AS volume_avg_litres,
    calibrated_volume_min AS volume_min_litres,
    calibrated_volume_max AS volume_max_litres
FROM processed_common_data.sensors_data_by_hours
DI MANA sensor_type = 'fuel_level'
  AND hour_bucket >= CURRENT_DATE - INTERVAL '24 hours'
ORDER BY device_id, hour_bucket;
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Bagaimana agregat sensor dibuat

Sebuah baris dalam tabel ini bukan pembacaan perangkat mentah, melainkan entitas turunan yang disusun dari banyak pembacaan sensor individual. Transformasi ini bekerja melalui data mentah secara bertahap: menentukan pembacaan mana yang dapat digunakan, menggabungkan konfigurasi sensor, mendekode nilai, mengelompokkan ke dalam jendela waktu, mengagregasi, menerapkan kalibrasi bahan bakar, dan akhirnya memperkaya dengan label yang dapat dibaca manusia. Memahami proses ini membantu Anda menafsirkan hasil dengan benar dan mengenali kapan perilaku bawaan perlu disesuaikan dengan kasus penggunaan Anda.

Berikut adalah langkah-langkah algoritma yang membentuk baris agregat sensor:

{% stepper %}
{% step %}

#### **Membaca dan memfilter masukan mentah**

Transformasi ini membaca irisan data terbaru dari `raw_telematics_data.inputs`. Panjang irisan sesuai dengan interval yang dikonfigurasi: proses bawaan membaca 1 jam terakhir; proses kustom dengan interval 5 menit membaca 5 menit terakhir. Pembacaan disaring sebelum pemrosesan lebih lanjut:

* Hanya nilai yang cocok dengan ekspresi reguler `^[0-9]+\.?[0-9]*$` yang lolos. Ini menerima bilangan bulat non-negatif dan desimal.
* Teks menyatakan, angka negatif, notasi ilmiah, dan nilai null dikecualikan.
* Sensor yang hanya mengeluarkan data non-numerik tidak muncul di tabel keluaran.

Penyaring beroperasi pada data mentah `Nilai` Kolom dalam `Masukan`, Sebelum penguraian apa pun diterapkan.
{% endstep %}

{% step %}

#### **Konfigurasi penggabungan sensor**

Setiap pembacaan yang tersisa dicocokkan dengan `raw_business_data.sensor_description` Menggunakan sebuah `LEFT JOIN` on `device_id` dan `input_label = sensor_name`. Gabungan ini membawa `sensor_id`, `sensor_label`, `jenis_sensor`, `jenis_satuan`, `tipe_kelompok`, `pembagi`, `pengali`, `calibration_data`, dan `parameter`. Karena join ini bertipe kiri, pembacaan dari sensor yang tidak dikonfigurasi tetap diteruskan dengan metadata sensor bernilai null.
{% endstep %}

{% step %}

#### **Mendekode nilai mentah**

Setiap pembacaan diubah dari representasi tersimpannya menjadi nilai numerik yang dapat digunakan. Aturan dekode berasal dari `sensor_description.parameters.calc_method`:

* `bit_index` mengekstrak satu bit dari nilai integer menggunakan pergeseran bit dan mask: `((raw_value::bigint >> bit_index) & 1)`. Digunakan untuk flag status yang dikemas dalam integer.
* `identitas` menggunakan nilai numerik mentah tanpa perubahan.
* Jika tidak, fungsi menerapkan `(raw_value / divider) * multiplier`, yang merupakan rumus standar untuk Sensor pengukuran. Pembagi bernilai null memicu `COALESCE` fallback ke nilai mentah.
  {% endstep %}

{% step %}

#### **Pengelompokan ke bucket dan agregasi**

Nilai yang telah didekode dikelompokkan ke dalam bucket waktu dengan memotong `device_time` ke batas bucket. Di dalam setiap bucket, fungsi menghitung `AVG`, `MIN`, dan `MAX` dari nilai yang telah didekode. Pengelompokan juga mencakup kolom metadata sensor, sehingga agregat dihitung per sensor per perangkat per bucket.

Dalam transformasi bawaan, bucket adalah satu jam. Transformasi kustom dapat menggunakan interval positif apa pun. Lihat [Menyesuaikan transformasi](https://claude.ai/chat/32cacafe-fe34-476d-b7d0-c93b4ce82da6#customizing-the-transformation) di bawah.
{% endstep %}

{% step %}

#### **Kalibrasi untuk sensor Bahan bakar**

Sensor dengan `calibration_data` array (biasanya sensor level Bahan bakar) diberikan interpolasi linear pada setiap agregat. Untuk `value_avg`, `value_min`, dan `value_max` secara terpisah, fungsi menemukan titik batas kalibrasi tepat di bawah dan tepat di atas nilai tersebut, lalu melakukan interpolasi linear untuk menghasilkan `calibrated_volume_avg`, `calibrated_volume_min`, dan `calibrated_volume_max`. Untuk sensor tanpa data kalibrasi, volume terkalibrasi sama dengan agregat mentah.

Kolom titik batas (`val_low_*`, `val_high_*`, `vol_low_*`, `vol_high_*`) dipertahankan dalam output demi transparansi.
{% endstep %}

{% step %}

#### **Pengayaan dengan label**

Baris yang diagregasi digabungkan dengan `raw_business_data.objects` on `device_id` untuk menambahkan `label Pelacak`, dan dengan `raw_business_data.description_parameters` dua kali untuk menyelesaikan `jenis_satuan` dan `tipe_kelompok` ke string deskripsi yang dapat dibaca manusia. Fungsi juga menghitung `unit sensor akhir`, yang lebih memilih `satuan_sensor` dan kembali ke string deskripsi.

Untuk sensor diskret dengan `parameters.value_titles` pemetaan, fungsi mencari judul yang dapat dibaca manusia yang sesuai dengan `value_max` dan mengembalikannya sebagai `value_title`. Sensor pengukuran memiliki `value_title` diatur ke null.
{% endstep %}
{% endstepper %}

Dua bagian referensi berikut berisi parameter interval yang dapat dikonfigurasi dan aturan penguraian yang diterapkan transformasi secara internal.

<details>

<summary>Parameter interval</summary>

Transformasi ini dikendalikan oleh satu parameter, `p_interval`, yang mengontrol baik ukuran bucket maupun jendela penelusuran ke belakang. Keduanya selalu sama: eksekusi dengan `p_interval = '5 minutes'` membaca 5 menit terakhir data mentah dan menghasilkan bucket 5 menit.

| Pengaturan                      | Transformasi bawaan                           | Transformasi kustom                                                                   |
| ------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------- |
| Ukuran bucket                   | 1 jam                                         | Interval positif apa pun yang ditetapkan di node SQL Kustom                           |
| Jendela penelusuran ke belakang | 1 jam                                         | Sama dengan ukuran bucket                                                             |
| Frekuensi penjadwalan           | Setiap jam (disesuaikan dengan ukuran bucket) | Disesuaikan dengan ukuran bucket yang dipilih untuk cakupan berkelanjutan tanpa celah |

Lihat [Menyesuaikan transformasi](#customizing-the-transformation) untuk petunjuk cara mengubah interval.

</details>

<details>

<summary>Aturan penguraian nilai</summary>

Nilai sensor mentah datang sebagai teks di `raw_telematics_data.inputs.value`. Transformasi menerapkan aturan penguraian berdasarkan konfigurasi setiap sensor sebelum dilakukan agregasi.

| `calc_method`        | Perilaku penguraian                                                                                             |
| -------------------- | --------------------------------------------------------------------------------------------------------------- |
| `bit_index`          | Mengekstrak satu bit: `((value::bigint >> bit_index) & 1)`. `bit_index` dibaca dari `parameter`.                |
| `identitas`          | Menggunakan nilai mentah sebagai float, tanpa perubahan.                                                        |
| (bawaan / tidak ada) | Menerapkan `(raw_value / divider) * multiplier`. Pembagi null memicu suatu `COALESCE` fallback ke nilai mentah. |

Interpolasi kalibrasi, yang diterapkan setelah agregasi untuk sensor dengan data kalibrasi, bekerja dengan menemukan titik batas dalam `calibration_data` (sebuah array JSONB berisi `{in, out}` entri) yang paling dekat dengan nilai agregat dan melakukan interpolasi linear di antaranya. Hasilnya disimpan di `calibrated_volume_*` kolom.

</details>

### Menyesuaikan transformasi

Agregasi data sensor bawaan mencerminkan agregasi per jam serbaguna milik Navixy. Jika skenario operasional Anda memerlukan granularitas yang berbeda, seperti resolusi yang lebih halus untuk dasbor diagnostik atau interval yang lebih kasar untuk pelaporan jangka panjang, Anda dapat membangun transformasi kustom yang memanggil `select_timeperiod_sensor_data` dengan interval yang berbeda dan menulis hasilnya ke tabel Anda sendiri di `processed_custom_data`.

Penyesuaian adalah perubahan satu baris di dalam node Custom SQL:

```sql
SELECT * FROM processed_common_data.select_timeperiod_sensor_data('5 minutes')
```

Ubah literal interval untuk mengontrol ukuran bucket dan jendela tinjau ke belakang sekaligus. Fungsi ini mengembalikan bentuk kolom yang sama apa pun intervalnya, sehingga konfigurasi node Output di hilir tetap sederhana.

{% hint style="warning" %}
Nilai interval mengontrol ukuran bucket dan tinjau ke belakang secara bersamaan. Keduanya tidak dapat diatur secara terpisah. Jadwal alur kerja harus berjalan setidaknya sesering interval, jika tidak, beberapa pembacaan tidak akan diagregasi.
{% endhint %}

#### Bentuk alur kerja

Alur kerja minimal terdiri dari dua node:

<figure><img src="https://1696125515-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoFNFEIINiGFbhi3Px3dE%2Fuploads%2Fgit-blob-2160d1986b61ca2e36061e3889caf87b1a905d59%2FSensor-data-aggregation-custom-timeframe.png?alt=media" alt=""><figcaption></figcaption></figure>

Tidak `Data mentah: Telematics` Node sumber diperlukan. Fungsi membaca dari `raw_telematics_data.inputs` dan `raw_business_data` tabel secara internal. Node Custom SQL berisi seluruh pipeline, dan node Output mewujudkan hasil ke tabel target Anda.

#### Contoh kustomisasi

Luaskan bagian di bawah untuk melihat contoh kustomisasi berbasis kasus.

<details>

<summary>Mengubah ukuran bucket</summary>

Gunakan ini ketika granularitas per jam terlalu kasar untuk kebutuhan pelaporan Anda. Kasus umum mencakup dasbor yang menampilkan tren Bahan bakar dengan resolusi 5 menit, diagnostik detik demi detik untuk test drive singkat, dan rekap harian untuk pelaporan jangka panjang.

Untuk mengubah ukuran bucket, edit literal interval di node Custom SQL dan perbarui jadwal agar sesuai.

* **Bucket 5 menit**, dengan jadwal `*/5 * * * *` (setiap 5 menit):

```sql
SELECT * FROM processed_common_data.select_timeperiod_sensor_data('5 minutes')
```

* **Bucket 15 menit**, dengan jadwal `*/15 * * * *` (setiap 15 menit):

```sql
SELECT * FROM processed_common_data.select_timeperiod_sensor_data('15 minutes')
```

* **Bucket harian**, dengan jadwal `5 0 * * *` (setiap hari pukul 00.05 UTC):

```sql
SELECT * FROM processed_common_data.select_timeperiod_sensor_data('1 day')
```

Kolom keluaran masih disebut `hour_bucket` terlepas dari intervalnya. Jika Anda menginginkan nama yang lebih jelas di tabel kustom Anda, beri alias di SQL Kustom:

```sql
SELECT
    hour_bucket AS bucket_time,
    ID perangkat, nama sensor, ID kejadian,
    ID sensor, label input, label sensor,
    Jenis sensor, satuan sensor, jenis satuan, jenis Kelompok,
    Nilai rata-rata, nilai minimum, nilai maksimum,
    Label Pelacak, satuan sensor akhir
FROM processed_common_data.select_timeperiod_sensor_data('5 minutes')
```

Atur node Output **Kolom waktu** ke `bucket_time` jika Anda memberi alias, atau ke `hour_bucket` Jika Anda mempertahankan nama aslinya.

</details>

<details>

<summary>Pembatasan pada sensor tertentu</summary>

Gunakan ini ketika Anda hanya memerlukan agregat untuk sebagian sensor, misalnya hanya level bahan bakar dan suhu mesin, untuk mengurangi ukuran tabel dan biaya kueri.

Bungkus pemanggilan fungsi dalam penyaringan `SELECT` di dalam node Custom SQL:

```sql
SELECT *
FROM processed_common_data.select_timeperiod_sensor_data('15 minutes')
DI MANA sensor_type DALAM ('fuel_level', 'temperature')
```

Anda dapat memfilter berdasarkan kolom apa pun yang dikembalikan fungsi, termasuk `sensor_label`, `sensor_name`, atau `sensor_id`. Untuk menemukan nilai yang tersedia dalam data Anda, kueri tabel sumber:

```sql
SELECT DISTINCT sensor_name FROM raw_telematics_data.inputs LIMIT 100;
```

</details>

<details>

<summary>Mengurangi output menjadi kolom esensial</summary>

Gunakan ini saat Anda tidak memerlukan breakpoint kalibrasi atau sensor diskret `value_title` Kolom, dan Anda ingin tabel keluaran yang lebih ramping. Ini sangat berguna terutama ketika Armada Anda tidak memiliki sensor level bahan bakar, dalam hal ini 15 kolom terkait kalibrasi semuanya bernilai null atau duplikat dari agregat mentah.

Proyeksikan hanya kolom yang Anda perlukan:

```sql
SELECT
    hour_bucket,
    device_id,
    nama sensor,
    event_id,
    sensor_label,
    sensor_type,
    value_avg,
    value_min,
    value_max,
    Label pelacak,
    unit sensor akhir
FROM processed_common_data.select_timeperiod_sensor_data('15 minutes')
```

Konfigurasi node Output tetap sama; tabel tujuan hanya akan memiliki lebih sedikit kolom.

</details>

#### Konfigurasi node Output

Setelah node Custom SQL disiapkan, hubungkan node tersebut ke node Output dan konfigurasikan tabel tujuan.

<table><thead><tr><th width="180">Parameter</th><th>Nilai</th></tr></thead><tbody><tr><td><strong>Nama tabel</strong></td><td>Nama deskriptif, misalnya <code>sensors_data_by_5min</code></td></tr><tr><td><strong>Kolom waktu</strong></td><td><code>hour_bucket</code> (atau alias Anda jika Anda menggantinya)</td></tr><tr><td><strong>Kunci utama</strong></td><td><code>device_id</code>, <code>hour_bucket</code>, <code>sensor_name</code>, <code>event_id</code></td></tr><tr><td><strong>Partisi berdasarkan</strong></td><td><code>DATE(hour_bucket)</code></td></tr><tr><td><strong>Mode penulisan</strong></td><td><code>tambahkan</code></td></tr></tbody></table>

Kunci primer harus mencakup keempat kolom dari kunci alami fungsi. Menggunakan hanya `device_id` dan `hour_bucket` akan menyebabkan pelanggaran kunci primer, karena setiap perangkat memiliki beberapa sensor yang menghasilkan data dalam bucket yang sama. `tambahkan` adalah mode penulisan yang benar ketika Penjadwalan cocok dengan ukuran bucket, karena setiap eksekusi menghasilkan bucket baru yang belum pernah ditulis sebelumnya. Gunakan `upsert` hanya jika eksekusi Anda tumpang tindih (misalnya, interval 15 menit yang dijadwalkan setiap 5 menit).

#### Penjadwalan

Frekuensi penjadwalan harus sama dengan nilai interval. Setiap eksekusi kemudian membaca data persis sebanyak satu bucket, tanpa tumpang tindih dan tanpa celah.

| Ukuran bucket | Ekspresi jadwal | Arti                        |
| ------------- | --------------- | --------------------------- |
| 1 menit       | `* * * * *`     | Setiap menit                |
| 5 menit       | `*/5 * * * *`   | Setiap 5 menit              |
| 15 menit      | `*/15 * * * *`  | Setiap 15 menit             |
| 1 jam         | `0 * * * *`     | Setiap jam pada menit 00    |
| 1 hari        | `5 0 * * *`     | Setiap hari pukul 00:05 UTC |

Waktunya menggunakan UTC. Sesuaikan frekuensi cron dengan interval Anda; menjalankannya lebih jarang daripada interval akan meninggalkan celah di tabel output, dan menjalankannya lebih sering akan menyebabkan konflik kunci primer duplikat di `tambahkan` mode.

#### Menggunakan templat alur kerja

Navixy menyediakan templat alur kerja siap pakai yang dapat Anda muat ke Transformation Builder sebagai titik awal. Templat ini dilengkapi dengan node Custom SQL yang telah dikonfigurasi sebelumnya untuk bucket 5 menit.

Lihat [Templat](/docs/analytics/id/iot-query/schema-overview/transformation-layer/transformation-builder/templates.md) halaman untuk unduhan, petunjuk impor, dan konfigurasi node Output untuk transformasi ini.

### Langkah selanjutnya

* [**Transformasi umum**](/docs/analytics/id/iot-query/schema-overview/transformation-layer/common-transformations.md): Kembali ke indeks transformasi.
* [**Templat**](/docs/analytics/id/iot-query/schema-overview/transformation-layer/transformation-builder/templates.md): Unduh templat alur kerja agregasi data sensor dan impor ke Pembuat transformasi.
* [**Pembuat transformasi**](/docs/analytics/id/iot-query/schema-overview/transformation-layer/transformation-builder.md): Pelajari cara menggunakan editor alur kerja visual, menambahkan node, dan melihat pratinjau hasil.
* [**Lapisan data mentah**](/docs/analytics/id/iot-query/schema-overview/bronze-layer.md): Jelajahi tabel sumber yang menjadi input bagi agregasi data sensor: `raw_telematics_data.inputs`, `raw_business_data.sensor_description`, dan `raw_business_data.objects`.
* [**Perjalanan**](/docs/analytics/id/iot-query/schema-overview/transformation-layer/common-transformations/trips.md): Transformasi saudara yang menghasilkan catatan perjalanan kendaraan dari data telematika mentah.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://navixy.com/docs/analytics/id/iot-query/schema-overview/transformation-layer/common-transformations/sensor-data-aggregation.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
