> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mertani.co.id/llms.txt
> Use this file to discover all available pages before exploring further.

# Kalibrasi Sensor

Menu **Kalibrasi Sensor** digunakan untuk menyesuaikan hasil pembacaan sensor agar sesuai dengan kondisi referensi di lapangan. Hasil kalibrasi disebut **Sintetik Data**, inilah yang digunakan di seluruh sistem untuk dashboard, grafik, tabel, laporan, dan export data.

***

## Konsep Dasar

| Istilah           | Penjelasan                                                                |
| ----------------- | ------------------------------------------------------------------------- |
| `x`               | Nilai asli dari sensor (**Raw Data**) -> input dari semua rumus kalibrasi |
| **Sintetik Data** | Hasil kalibrasi dari `x` -> digunakan di seluruh tampilan sistem          |
| **Raw Data**      | Nilai mentah sensor -> disimpan sebagai referensi, tidak berubah          |

**Hal penting yang perlu diketahui:**

* Kalibrasi **hanya berlaku untuk data baru**, data historis tidak akan berubah
* Jika tidak ada kalibrasi yang dikonfigurasi, sistem menggunakan nilai default: `x` (raw = sintetik)
* Perubahan unit (misalnya dari `cm` ke `meter`) hanya mengubah **label**, nilai berubah hanya jika rumus kalibrasi diubah

***

## Metode Kalibrasi

<CardGroup cols={2}>
  <Card title="Berbasis Rumus" icon="1" href="./kalibrasi-sensor#1-kalibrasi-berbasis-rumus">
    Transformasi matematis langsung menggunakan nilai sensor `x`
  </Card>

  <Card title="Berbasis Parameter" icon="2" href="./kalibrasi-sensor#2-kalibrasi-berbasis-parameter">
    Menggunakan nilai sensor lain dalam satu device sebagai referensi
  </Card>

  <Card title="Berbasis Dataset" icon="3" href="./kalibrasi-sensor#3-kalibrasi-berbasis-dataset">
    Konversi non-linear menggunakan tabel lookup
  </Card>

  <Card title="Berbasis Kondisi (Conditional)" icon="4" href="./kalibrasi-sensor#4-kalibrasi-berbasis-kondisi-conditional">
    Percabangan logika untuk membedakan range nilai dengan rumus berbeda
  </Card>
</CardGroup>

***

## 1. Kalibrasi Berbasis Rumus

Metode paling umum menggunakan rumus matematika dengan `x` sebagai nilai sensor.

**Contoh rumus:**

```
‣ x - 212
‣ (x + 100) / 100
‣ 3.6156 * ((302 - x) ** 1.7461)
```

**Contoh Visualisasi Kalibrasi:**

<Frame>
  <div>
    <img src="https://mintcdn.com/mertani/vd3A9dvPMbENrLnT/assets/dashboard-guides/configs/kalibrasi-light.webp?fit=max&auto=format&n=vd3A9dvPMbENrLnT&q=85&s=3d3bc49e87ebf189fed526ca2946dc11" alt="Contoh kalibrasi sensor" className="dark:hidden" noZoom={true} width="4108" height="2416" data-path="assets/dashboard-guides/configs/kalibrasi-light.webp" />

    <img src="https://mintcdn.com/mertani/vd3A9dvPMbENrLnT/assets/dashboard-guides/configs/kalibrasi-dark.webp?fit=max&auto=format&n=vd3A9dvPMbENrLnT&q=85&s=79a0a738e2a442a65d589fc1034141f9" alt="Contoh kalibrasi sensor" className="hidden dark:block" noZoom={true} width="4108" height="2416" data-path="assets/dashboard-guides/configs/kalibrasi-dark.webp" />
  </div>
</Frame>

TMA = tinggi instalasi ke dasar sungai - sensor record

Hasil = `200 - x`

|                | Nilai            |
| -------------- | ---------------- |
| Raw Data (`x`) | `120`            |
| Sintetik Data  | `200 - 120 = 80` |

***

## 2. Kalibrasi Berbasis Parameter

Menggunakan nilai sensor **lain dalam device yang sama** sebagai bagian dari rumus kalibrasi. Format: `[id_sensor]`

```
‣ [RYG8-flLev] / 100
‣ [RYG8-flVel] * [RYG8-flLev]
```

Metode ini memungkinkan pembuatan **virtual sensor** (parameter turunan), sensor yang tidak secara fisik ada di perangkat, tetapi nilainya dihitung dari kombinasi sensor yang ada.

**Studi kasus - Menghitung Debit dari Water Level:**

Device hanya memiliki sensor water level (cm), tetapi ingin ditampilkan juga nilai dalam meter dan nilai debit.

| Parameter        | ID Sensor    | Rumus Kalibrasi                             | Keterangan                    |
| ---------------- | ------------ | ------------------------------------------- | ----------------------------- |
| Water Level (cm) | `RYG8-flLev` | `x`                                         | Nilai asli, tanpa perubahan   |
| Water Level (m)  | `RYG8-flLev` | `x / 100`                                   | Konversi cm → m               |
| Debit (m³/s)     | `RYG8-flw`   | `3.6156 * ((302 - [RYG8-flLev]) ** 1.7461)` | Rating curve dari water level |

**Hasil dengan Raw Data `x = 200 cm`:**

| Parameter                 | Nilai | Satuan |
| ------------------------- | ----- | ------ |
| Raw Data                  | 200   | cm     |
| Water Level (dikalibrasi) | 2     | m      |
| Debit                     | 12.13 | m³/s   |

<Warning>
  Parameter turunan (virtual sensor) **tidak dapat digunakan kembali** sebagai referensi `[parameter]` untuk kalibrasi sensor lain. Gunakan sensor fisik asli sebagai referensi.

  **Contoh yang tidak diperbolehkan:**

  ```
  ‣ [Debit] ← virtual = [water_level] * [velocity]
  ‣ [Virtual lain]    = [debit] * 10  ← akan error
  ```
</Warning>

***

## 3. Kalibrasi Berbasis Dataset

Digunakan untuk konversi **non-linear** berdasarkan tabel referensi (lookup table). Cocok untuk hubungan antara dua parameter yang tidak dapat direpresentasikan dengan rumus matematika sederhana.

**Fungsi:**

```
DATASET("slug_dataset", nilai_input, "kolom_output")
```

| Argumen          | Keterangan                                                        |
| ---------------- | ----------------------------------------------------------------- |
| `"slug_dataset"` | Identitas dataset yang telah diunggah                             |
| `nilai_input`    | Nilai yang akan dicari di kolom referensi (kolom pertama dataset) |
| `"kolom_output"` | Nama kolom hasil yang ingin diambil                               |

**Contoh dataset (penampang\_basah):**

| water\_level | area |
| ------------ | ---- |
| 4.0          | 40.4 |
| 3.9          | 39.0 |
| 3.8          | 37.7 |
| 3.7          | 36.5 |
| …            | …    |
| 0.0          | 1.1  |

**Contoh implementasi - Menghitung Debit dengan Dataset:**

```
[RYG8-flVel] * DATASET("penampang_basah", [RYG8-flLev] / 100, "area")
```

| Bagian Rumus         | Keterangan                                          |
| -------------------- | --------------------------------------------------- |
| `[RYG8-flVel]`       | Nilai kecepatan aliran dari sensor                  |
| `[RYG8-flLev] / 100` | Tinggi air dalam meter (dikonversi dari cm)         |
| `DATASET(...)`       | Mencari luas penampang basah berdasarkan tinggi air |
| **Hasil**            | Debit = kecepatan × luas penampang (m³/s)           |

<Note>
  Pastikan nilai input berada dalam range yang tercakup oleh dataset. Nilai di luar range dapat menghasilkan output kosong atau tidak akurat. Lihat panduan lengkap di [Manajemen Dataset](../devices/dataset-calibration).
</Note>

***

## 4. Kalibrasi Berbasis Kondisi (Conditional)

Metode ini memungkinkan **percabangan logika**, membedakan range nilai sensor dan menerapkan rumus yang berbeda untuk masing-masing kondisi. Sangat berguna untuk data sensor yang memiliki karakteristik berbeda pada rentang nilai tertentu.

**Format:**

```
(kondisi) ? (rumus_jika_benar) : (rumus_jika_salah)
```

| Simbol | Keterangan                        |
| ------ | --------------------------------- |
| `?`    | Tanda "jika kondisi benar"        |
| `:`    | Tanda "jika kondisi salah" (else) |

**Nesting (percabangan bersarang):**
Kondisi dapat ditumpuk untuk lebih dari 2 range:

```
(kondisi_1) ? (rumus_1) : ((kondisi_2) ? (rumus_2) : (rumus_3))
```

***

### Contoh: Rating Curve dengan Multi-Range

Sebuah sensor water level mengukur ketinggian air dalam `cm`. Hubungan antara ketinggian dan debit berbeda pada range rendah, menengah, dan tinggi:

**Rumus:**

```
(x < 50) ? (0.0023 * (x ** 1.85)) 
: ((x <= 120) ? ((1 - ((x - 50) / 70)) * (0.0023 * (x ** 1.85)) + ((x - 50) / 70) * (0.000089 * (x ** 2.94))) 
: (0.000089 * (x ** 2.94)))
```

| Range    | Kondisi        | Rumus                        | Keterangan        |
| -------- | -------------- | ---------------------------- | ----------------- |
| Rendah   | `x < 50`       | `0.0023 * (x ** 1.85)`       | Aliran laminar    |
| Transisi | `50 ≤ x ≤ 120` | Interpolasi antara dua rumus | Perubahan gradual |
| Tinggi   | `x > 120`      | `0.000089 * (x ** 2.94)`     | Aliran turbulen   |

**Contoh Perhitungan:**

| Raw Data (`x`) | Kondisi                                 | Rumus yang Digunakan       | Sintetik Data |
| -------------- | --------------------------------------- | -------------------------- | ------------- |
| 30 cm          | `30 < 50` → benar                       | `0.0023 * (30 ** 1.85)`    | 1.42          |
| 80 cm          | `80 < 50` → salah, `80 ≤ 120` → benar   | Interpolasi                | 8.75          |
| 150 cm         | `150 < 50` → salah, `150 ≤ 120` → salah | `0.000089 * (150 ** 2.94)` | 28.34         |

***

### Contoh Lain: Konversi Suhu dengan Threshold

Sensor suhu mentah dalam Fahrenheit, perlu dikonversi ke Celsius dengan koreksi berbeda pada range ekstrem:

**Rumus:**

```
(x > 200) ? ((x - 32) * 5/9 - 2.5) 
: ((x < 0) ? ((x - 32) * 5/9 + 1.8) 
: ((x - 32) * 5/9))
```

| Range          | Kondisi       | Rumus              | Keterangan                           |
| -------------- | ------------- | ------------------ | ------------------------------------ |
| Ekstrem tinggi | `x > 200`     | `(x-32)*5/9 - 2.5` | Koreksi negatif untuk panas ekstrem  |
| Normal         | `0 ≤ x ≤ 200` | `(x-32)*5/9`       | Konversi standar                     |
| Ekstrem rendah | `x < 0`       | `(x-32)*5/9 + 1.8` | Koreksi positif untuk dingin ekstrem |

**Hasil:**

| Raw Data (`x`) | Suhu Asli (°F) | Kondisi        | Sintetik Data (°C) |
| -------------- | -------------- | -------------- | ------------------ |
| -10            | -10°F          | Ekstrem rendah | -21.7              |
| 72             | 72°F           | Normal         | 22.2               |
| 250            | 250°F          | Ekstrem tinggi | 116.6              |

***

### Kombinasi dengan Metode Lain

Kalibrasi kondisi **dapat dikombinasikan** dengan metode lain:

**Kombinasi dengan Parameter (`[id_sensor]`):**

```
([RYG8-temp] > 30) ? (x * 1.05) : (x * 0.98)
```

> Debit dikalikan faktor 1.05 jika suhu > 30°C, atau 0.98 jika ≤ 30°C

**Kombinasi dengan Dataset (`DATASET()`):**

```
(x < 100) ? (DATASET("kurva_rendah", x, "output")) 
: (DATASET("kurva_tinggi", x, "output"))
```

> Lookup ke dataset berbeda tergantung range nilai

**Kombinasi Rumus + Parameter + Kondisi:**

```
(x < 50) ? ([RYG8-flVel] * x * 0.8) 
: (([RYG8-flVel] * x * 1.2) + [RYG8-temp] * 0.1)
```

<Callout type="info">
  Metode kondisi menggunakan **operator ternary** (`? :`). Pastikan setiap kondisi menghasilkan nilai `true` atau `false`. Gunakan parentheses `()` untuk mengelompokan kondisi dan rumus dengan benar.
</Callout>

<Warning>
  Saat menggunakan nesting (percabangan bersarang), pastikan setiap kondisi dan rumus dibungkus dengan parentheses yang benar untuk menghindari error parsing.
</Warning>

***

## Operator yang Didukung

| Operator          | Simbol    | Contoh                           |
| ----------------- | --------- | -------------------------------- |
| Penjumlahan       | `+`       | `x + 10`                         |
| Pengurangan       | `-`       | `x - 5`                          |
| Perkalian         | `*`       | `x * 2`                          |
| Pembagian         | `/`       | `x / 100`                        |
| Pangkat           | `**`      | `x ** 2`                         |
| Kondisi (ternary) | `? :`     | `(x > 10) ? (x * 2) : (x * 0.5)` |
| Akar kuadrat      | `sqrt(n)` | `sqrt(x)`                        |
| Eksponensial      | `exp(n)`  | `exp(x)`                         |
| Nilai absolut     | `abs(n)`  | `abs(x)`                         |
| Sinus             | `sin(n)`  | `sin(x)` atau `sin(torad(90))`   |
| Kosinus           | `cos(n)`  | `cos(x)` atau `cos(torad(90))`   |
| Tangen            | `tan(n)`  | `tan(x)` atau `tan(torad(90))`   |

> Fungsi trigonometri (`sin`, `cos`, `tan`) menggunakan **radian** secara default. Jika nilai input dalam **derajat**, gunakan `torad()` untuk konversi: `sin(torad(90))`.

***

## Cara Mengatur Kalibrasi

Kalibrasi sensor dapat diakses melalui dua jalur:

<Tabs>
  <Tab title="Dari Manajemen Device">
    <Steps>
      <Step title="Buka halaman Manajemen Device">
        Masuk ke menu **Manajemen Device**.
      </Step>

      <Step title="Buka detail device">
        Pilih device yang sensornya ingin dikalibrasi, lalu buka halaman detail device.
      </Step>

      <Step title="Buka daftar sensor">
        Masuk ke tab atau menu **Sensor Device** untuk melihat semua sensor pada device tersebut.
      </Step>

      <Step title="Buka pengaturan kalibrasi">
        Klik badge **kalibrasi** pada sensor yang ingin dikonfigurasi. Panel kalibrasi akan terbuka.
      </Step>

      <Step title="Input rumus kalibrasi">
        Panel kalibrasi terdiri dari dua bagian:

        * **Tabel kiri** -> menampilkan referensi data raw vs sintetik untuk validasi
        * **Form kanan** -> tempat menginput rumus kalibrasi

        Ketik `=` untuk membuka daftar sensor dan dataset yang tersedia. Pilih sensor atau dataset untuk menyisipkan ID-nya ke dalam rumus secara otomatis.
      </Step>

      <Step title="Atur unit output (opsional)">
        Jika kalibrasi mengubah satuan (misalnya `cm` → `meter`), perbarui field **Unit** sesuai satuan hasil kalibrasi.

        Ingat: mengubah unit **tidak mengubah nilai**, perubahan nilai hanya terjadi melalui rumus kalibrasi.
      </Step>

      <Step title="Simpan kalibrasi">
        Klik **"Simpan"**. Rumus akan diterapkan pada data baru yang masuk setelah penyimpanan.

        <Frame>
          <video src="https://mintcdn.com/mertani/s_1RXp64XZSqMTTx/assets/dashboard-guides/configs/kalibrasi-devicesensor.webm?fit=max&auto=format&n=s_1RXp64XZSqMTTx&q=85&s=b6da94e1b72f10cbfa6106cb18776c73" controls autoPlay loop playsInline muted data-path="assets/dashboard-guides/configs/kalibrasi-devicesensor.webm" />
        </Frame>
      </Step>
    </Steps>
  </Tab>

  <Tab title="Dari Manajemen Sensor">
    <Steps>
      <Step title="Buka halaman Manajemen Sensor">
        Masuk ke menu **Manajemen Sensor** untuk melihat semua sensor lintas device.
      </Step>

      <Step title="Cari sensor yang ingin dikalibrasi">
        Gunakan kolom pencarian untuk menyaring berdasarkan:

        * Nama Device atau ID Device
        * Nama Sensor atau ID Sensor
      </Step>

      <Step title="Buka pengaturan kalibrasi">
        Klik badge **kalibrasi** pada baris sensor yang dituju.
      </Step>

      <Step title="Input rumus dan simpan">
        Input rumus kalibrasi pada form yang tersedia. Ketik `=` untuk memilih sensor atau dataset dari daftar.

        Klik **"Simpan"** untuk menerapkan kalibrasi.

        <Frame>
          <video src="https://mintcdn.com/mertani/s_1RXp64XZSqMTTx/assets/dashboard-guides/configs/kalibrasi-sensor.webm?fit=max&auto=format&n=s_1RXp64XZSqMTTx&q=85&s=1bf1d997b663dc18c9dc231cf5216ce5" controls autoPlay loop playsInline muted data-path="assets/dashboard-guides/configs/kalibrasi-sensor.webm" />
        </Frame>
      </Step>
    </Steps>
  </Tab>
</Tabs>

***

## Memilih Metode yang Tepat

| Kondisi                                          | Metode yang Direkomendasikan |
| ------------------------------------------------ | ---------------------------- |
| Koreksi offset atau perubahan skala sederhana    | Rumus (`x`)                  |
| Konversi unit (cm → m, °F → °C)                  | Rumus (`x`)                  |
| Menghitung parameter dari kombinasi sensor lain  | Parameter (`[id_sensor]`)    |
| Membuat virtual sensor (debit, dll.)             | Parameter (`[id_sensor]`)    |
| Hubungan non-linear yang tidak bisa dirumuskan   | Dataset (`DATASET()`)        |
| Lookup tabel penampang, kurva rating, dll.       | Dataset (`DATASET()`)        |
| Data memiliki range dengan karakteristik berbeda | Kondisi (`? :`)              |
| Perlu interpolasi antara beberapa rumus          | Kondisi (`? :`)              |
| Kombinasi metode dengan threshold tertentu       | Kondisi + metode lain        |
