PLTS Status Pagi Hari Ini

Baterai PLTS semalem tidak sampai pagi, karena kemarin hujan penuh dari jam 12 siang. Bisa dilihat pada grafik di bawah. Inverter aktif mulai jam sekitar 11 siang kemarin sampai jam 4 pagi tadi.

Pada grafik diatas, pada jam 4 pagi, voltase pada Load AC PLTS, naik tajam dan memiliki karakteristik grafis yang sama dengan voltage pada Load AC PLN. Pada waktu ini inverter mulai mengaktifkan sistem bypass PLN, sehingga sistem kelistrikan menggunakan jaringan PLN karena baterai sudah tidak sanggup menyuplai kebutuhan energi.

Voltase yang dikeluarkan oleh inverter juga terlihat lebih stabil di angka 220 volt. Berbeda dengan voltase dari PLN yang berfluktuasi naik turun. Hal ini bisa dipahami karena memang yang menggunakan listrik PLN ada banyak rumah yang pemakaiannya juga berfluktuasi.

Analogi yang sama juga pada air PDAM, kadang kenceng tapi kadang juga lemah tergantung waktu pemakaian. Pagi hari biasanya air lemah karena banyak yang pakai. Sedangkan malam atau siang hari kencang karena jarang orang yang pakai air.

Kediri, 22 Okt 2025

Struktur Direktori Ci4 Docker

Sekarang saya pakai docker dalam pengembangan web dengan framework Ci4. Sebelumnya saya sering pakai environment lengkap seperti xampp ataupun Laragon. Tetapi karena saya memiliki beberapa project legacy yang masih pakai dependency lama, seperti php 7 atau yang lain, sehingga kadang kesulitan menyesuaikan atau mengganti dependency jika pakai Xampp atau Laragon. Apalagi kalau ada project paralel yang harus pakai dua versi php yang berbeda.

Dengan pengembangan berbasis kontainer seperti Docker, kita bisa mengatur lingkungan yang berbeda setiap project. Lingkungan pengembangan satu project bisa kita buat independen terhadap project lain. Kita juga bisa jalankan dua project itu secara bersamaan tanpa mengganggu project yang lain.

Untuk kasus Ci4 dan bisa juga untuk framework lain sejenis, kita bisa pisahkan direktori untuk public dan private. Tujuannya diantaranya untuk keamanan dan konsistensi git workflow.

Misalhnya kita bisa buat struktur direktori seperti berikut:

project_directory
|- docker-compose.yml
|- Dockerfile
|- src
|-- private
|-- public

Kita bisa masukkan semua code ci4 di direktori private. Kemudian copy isi dari direktori public dalam ci4 ke src/public. Kemudian kita mapping src/public ke document root dalam kontainer. Kita map juga direktori private ke server.

Berikut docker compose nya:

name: 'ci4zuriah'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: zuriah_app
    ports:
      - "8080:80"
    volumes:
      - ./src/public:/var/www/html
      - ./src/private:/var/www/private
      - ./docker/php.ini:/usr/local/etc/php/php.ini
    depends_on:
      - db
    networks:
      - ci4net

  db:
    image: arm64v8/mysql:9.4.0-oracle
    container_name: zuriah_db
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: ci4db
      MYSQL_USER: ci4user
      MYSQL_PASSWORD: ci4pass
    ports:
      - "3356:3306"
    volumes:
      - dbdata:/var/lib/mysql
    networks:
      - ci4net

  phpmyadmin:
    image: arm64v8/phpmyadmin:5.2
    container_name: zuriah_myadmin
    restart: always
    ports:
      - "8051:80"
    environment:
      PMA_HOST: db
      MYSQL_ROOT_PASSWORD: rootpass
      UPLOAD_LIMIT: 10M
    depends_on:
      - db
    networks:
      - ci4net

volumes:
  dbdata:

networks:
  ci4net:

Dockerfile

FROM php:8.3-apache

# Install dependencies
RUN apt-get update && apt-get install -y \
    libicu-dev \
    libpq-dev \
    libpng-dev \
    libjpeg-dev \
    libfreetype6-dev \
    unzip \
    curl \
    zip 

# Install Composer
RUN curl -sS https://getcomposer.org/installer | php -- \
    && mv composer.phar /usr/local/bin/composer

# Aktifkan ekstensi PHP
RUN docker-php-ext-configure gd \
    --with-freetype \
    --with-jpeg \
    && docker-php-ext-install \
    gd \
    intl \
    mysqli \
    pdo \
    pdo_mysql

# Aktifkan mod_rewrite Apache
RUN a2enmod rewrite

# Restart Apache agar perubahan berlaku
RUN service apache2 restart

Kediri, 20 oct 2025

Dockerfile untuk Ci4 dengan Composer

Dengan case ingin menjalankan composer didalam container php dengan apache

FROM php:8.1-apache

# Install dependencies
RUN apt-get update && apt-get install -y \
    libicu-dev \
    libpq-dev \
    unzip \
    curl \
    zip \

# Install Composer
RUN curl -sS https://getcomposer.org/installer | php -- \
    && mv composer.phar /usr/local/bin/composer

# Aktifkan ekstensi PHP Intl 
RUN docker-php-ext-install intl mysqli pdo pdo_mysql

# Aktifkan mod_rewrite Apache
RUN a2enmod rewrite

# Restart Apache agar perubahan berlaku
RUN service apache2 restart

p9, 2 Oct 2025

Migrasi Android dari API 28 ke API 35: Menghadapi Dependency yang Saling Menggantung

Saya menghadapi sesuatu proses pekerjaan yang mesti dilakukan tapi cukup malas dan menunda untuk dikerjakan. Agak malas karena ngerjain satu hal tapi harus mengerjakan yang lain juga. Kesalahan di satu hal bisa merembet ke yang lain, begitu juga sebaliknya. Proses ini adalah upgrade API level android dan gradle.

Google kini mewajibkan minimal target API level 35 untuk aplikasi yang ingin dirilis atau di-update di Play Store. Bagi banyak developer yang masih bertahan di API 28, migrasi ini bukan sekadar ganti angka—tapi sebuah proses kompleks yang melibatkan dependency, build system, dan refactor kode besar-besaran.

⚠️ Kenapa Migrasi Ini Mendesak?

  • Google Play Policy: Mulai 2025, aplikasi baru dan update harus menargetkan API 35.
  • Banyak aplikasi lama masih di API 28, karena tidak pernah di-update sejak 2019–2020.
  • Perubahan besar di dependency seperti AndroidX, Jetpack, AGP, dan Gradle membuat migrasi tidak bisa dilakukan parsial.

🔄 Tantangan Migrasi: Dependency yang Saling Menggantung

  • Update satu dependency sering memicu error di dependency lain.
  • Banyak library yang sudah deprecated atau tidak kompatibel dengan AGP terbaru.
  • Proses migrasi bisa jadi loop tak berujung kalau tidak dilakukan secara menyeluruh.

🧱 Komponen yang Harus Diupdate Bersamaan

Untuk migrasi yang sukses, kamu harus menyentuh hampir semua lapisan build system:

🔧 File Terkait Gradle & Build System

FileFungsi
build.gradle (project)Versi Gradle Plugin & Kotlin DSL
build.gradle (app)Target SDK, compile SDK, dependency
gradle-wrapper.propertiesVersi Gradle minimum
gradle.propertiesFlag konfigurasi build
libs.versions.tomlManajemen dependency versi modern
settings.gradleKonfigurasi modul dan plugin
AndroidManifest.xmlTarget SDK dan permission yang deprecated
proguard-rules.proPenyesuaian obfuscation untuk library baru

🧹 Refactor Kode: Hadapi Deprecated API

  • Banyak API lama (seperti AsyncTask, getExternalStorageDirectory(), dll) sudah deprecated.
  • Perlu migrasi ke API modern seperti WorkManager, Storage Access Framework, dan ActivityResult API.
  • Gunakan lint dan IDE inspection untuk mendeteksi deprecated usage.

📦 Strategi Migrasi Modular

  1. Audit dependency: Cek versi dan kompatibilitas dengan AGP terbaru.
  2. Update Gradle wrapper dan AGP dulu: Pastikan build system stabil.
  3. Migrasi ke libs.versions.toml: Untuk manajemen versi yang lebih maintainable.
  4. Refactor kode deprecated: Gunakan IDE dan dokumentasi resmi.
  5. Testing bertahap: Gunakan emulator API 35 dan unit test untuk validasi.

🧪 Studi Kasus & Strategi Praktis Migrasi

Untuk menghindari migrasi yang membingungkan dan penuh error, lakukan pendekatan berikut:

  1. Install Android Studio terbaru Pastikan kamu menggunakan versi terbaru agar kompatibel dengan AGP dan SDK level 35.
  2. Buat proyek baru dari template bawaan Gunakan template “Empty Compose Activity” atau “Basic Views” untuk melihat struktur modern.
  3. Review struktur proyek baru Perhatikan versi Gradle, AGP, libs.versions.toml, settings.gradle, dan konfigurasi build.gradle.
  4. Bandingkan dengan proyek lama Identifikasi perbedaan versi, plugin, dan struktur dependency.
  5. Terapkan secara bertahap ke proyek lama Mulai dari update Gradle wrapper, lalu AGP, lalu dependency, lalu refactor kode deprecated.
  6. Gunakan version catalog (libs.versions.toml) Ini akan memudahkan tracking versi dan menghindari konflik antar modul.

Dengan pendekatan ini, kamu bisa belajar dari proyek baru yang sudah sesuai standar modern, lalu menerapkannya ke proyek lama secara sistematis dan minim risiko.

✅ Penutup: Migrasi Bukan Sekadar Update, Tapi Rebirth

Migrasi dari API 28 ke 35 bukan hanya soal memenuhi kebijakan Google, tapi juga kesempatan untuk membersihkan, merapikan, dan memodernisasi proyekmu. Dengan pendekatan modular dan dokumentasi yang rapi, kamu bisa mengubah proses yang menyakitkan jadi investasi jangka panjang.

Kediri, 8 Sep 2025

Belajar Flutter bagi Pengembang Native

Sebagai developer yang sudah terbiasa dengan Java, Kotlin, dan Swift, kamu mungkin sudah sangat akrab dengan XML layout di Android dan Storyboard di iOS. Tapi ketika harus membangun aplikasi lintas platform, muncul pertanyaan besar: Haruskah saya belajar Flutter? Jawabannya: ya, jika kamu ingin efisiensi, modularitas, dan satu codebase untuk dua platform utama.

Blog ini adalah roadmap belajar Flutter yang dirancang khusus untuk kamu yang berasal dari dunia native. Kita akan transisi secara bertahap, tanpa membuang keahlian yang sudah kamu miliki.

🧠 Tahap 1: Memahami Paradigma UI Baru

Flutter menggunakan pendekatan declarative UI berbasis Widget Tree. Ini mirip dengan View Hierarchy di Android atau Scene Graph di iOS.

  • Container = View
  • Text = TextView / UILabel
  • Column = LinearLayout (vertical)
  • Row = LinearLayout (horizontal)
  • Stack = FrameLayout / ZStack

Mulailah dengan membangun layout sederhana menggunakan Scaffold, AppBar, dan BottomNavigationBar. Anggap saja ini seperti membuat Activity atau ViewController.

📐 Tahap 2: Layout & Responsivitas

Kalau kamu terbiasa dengan match_parent, wrap_content, dan AutoLayout, Flutter punya padanannya:

  • Gunakan Expanded, Flexible, dan SizedBox untuk kontrol ukuran.
  • MediaQuery dan LayoutBuilder membantu membuat UI yang adaptif.
  • Hindari dulu animasi atau gesture kompleks—fokus pada layout yang familiar.

Tips: Buat layout nested seperti XML-style agar transisi terasa lebih natural.

🔄 Tahap 3: Navigasi & Lifecycle

Navigasi di Flutter menggunakan Navigator.push() dan pop(), mirip dengan Intent di Android atau segue di iOS.

Lifecycle-nya juga punya padanan:

  • initState() = onCreate() / viewDidLoad()
  • dispose() = onDestroy() / deinit
  • didChangeDependencies() = mirip onResume() atau viewWillAppear()

Dokumentasikan perbandingan lifecycle ini untuk referensi pribadi—sangat membantu saat debugging.

🔥 Tahap 4: Integrasi Firebase & Plugin

Flutter punya ekosistem plugin yang matang, terutama untuk Firebase:

  • firebase_core, firebase_auth, cloud_firestore, firebase_analytics
  • Setup-nya mirip dengan build.gradle dan Info.plist, tapi lewat pubspec.yaml
  • Modularisasi setup agar bisa reuse di proyek lain

Tips: Bandingkan setup Firebase di Flutter vs native untuk insight tambahan.

🧮 Tahap 5: State Management Bertahap

Mulai dari yang paling sederhana:

  • setState() → cocok untuk state lokal
  • Provider → untuk state global yang ringan
  • Riverpod atau Bloc → untuk aplikasi kompleks dan scalable

Jangan langsung lompat ke Bloc atau Redux—biar nggak over-engineered di awal.

🧱 Tahap 6: Modularisasi & Struktur Proyek

Karena kamu suka arsitektur modular, Flutter bisa disusun seperti ini:

Kode

lib/
├── core/
├── shared/
├── features/
│   ├── auth/
│   ├── dashboard/
│   └── settings/

Gunakan pubspec.yaml seperti kamu pakai libs.versions.toml di Gradle. Buat komponen reusable seperti CustomButton, AppTextField, dll.

🔌 Tahap 7: Native Bridge & Optimasi

Kalau kamu butuh akses ke fitur native (sensor, BLE, dll), gunakan Platform Channels:

  • Flutter → Kotlin/Swift → native API
  • Bisa modularisasi channel agar tetap maintainable

Optimasi ukuran APK/IPA:

  • flutter build apk --split-per-abi
  • Deferred loading untuk fitur jarang dipakai
  • Kompres asset dan gunakan tree-shaking

🎯 Kesimpulan: Flutter Bukan Pengganti, Tapi Pelengkap

Flutter bukan berarti meninggalkan Java, Kotlin, atau Swift. Justru, kamu bisa memanfaatkan semua keahlian native untuk membangun aplikasi lintas platform yang efisien dan scalable. Dengan satu codebase, kamu bisa hemat waktu, biaya, dan tenaga—tanpa mengorbankan kualitas.

Kediri, 8 Sep 2025