<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Danke Hidayat</title><description>Junior software developer and DevOps engineer in Bandung. Full-stack IoT systems, embedded firmware, real-time dashboards, and the containers that keep them reliable in production.</description><link>https://dankehidayat.my.id/</link><language>en-us</language><item><title>Automating Calibration and Report Generation with Google Colab</title><link>https://dankehidayat.my.id/notes/2025-10-17-automating-calibration-and-report-generation-with-google-colab/</link><guid isPermaLink="true">https://dankehidayat.my.id/notes/2025-10-17-automating-calibration-and-report-generation-with-google-colab/</guid><description>A repeatable pipeline for comparing DHT11 and HTC-1 sensors, calibrating them with data-driven methods, classifying thermal comfort with fuzzy logic, and generating a LaTeX report, all inside Google Colab.</description><pubDate>Fri, 17 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Comparing a low-cost sensor against a reference and writing up the result by hand is repetitive work. This note describes a workflow that does the whole thing inside Google Colab: extract paired readings from Google Sheets, calibrate the DHT11 against an HTC-1 reference, evaluate agreement with regression and Bland-Altman analysis, classify thermal comfort with a Mamdani fuzzy model, and generate a complete scientific-style report as a PDF, all from a single notebook.&lt;/p&gt;
&lt;h2&gt;Objective&lt;/h2&gt;
&lt;p&gt;Temperature and humidity matter in tropical workspaces, where natural ventilation carries most of the thermal load. Low-cost sensors such as the DHT11 are widely used, but their readings drift. The goal was to quantify the offset against an HTC-1, correct it with a data-driven calibration, and produce a report that could be regenerated whenever new data arrived.&lt;/p&gt;
&lt;h2&gt;Data Collection&lt;/h2&gt;
&lt;p&gt;The DHT11 and the HTC-1 sat side by side in a naturally ventilated office in Indonesia. Two datasets were recorded:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Before calibration, to establish the baseline error&lt;/li&gt;
&lt;li&gt;After calibration, to verify the correction&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each dataset spanned several hours of normal office activity, so the comparison covered realistic changes in temperature and humidity rather than a single static condition.&lt;/p&gt;
&lt;h2&gt;Analysis in Colab&lt;/h2&gt;
&lt;p&gt;The notebook loads the paired readings from Google Sheets using gspread, then computes error metrics for the raw and the calibrated series. Mean absolute error and standard deviation summarize how far the DHT11 sits from the reference. A linear regression quantifies the relationship between the two sensors, and a Bland-Altman comparison checks bias and agreement across the measurement range instead of collapsing everything into one number.&lt;/p&gt;
&lt;p&gt;The key metric is the mean absolute error:&lt;/p&gt;
&lt;p&gt;$$
\mathrm{MAE} = \frac{1}{n}\sum_{i=1}^{n}\left|\hat{y}_i - y_i\right|
$$&lt;/p&gt;
&lt;h2&gt;Calibration Results&lt;/h2&gt;
&lt;p&gt;After calibration, the DHT11 tracked the reference much more closely. The mean error and its spread both shrank, and the fitted regression line moved toward the line of identity. For a low-cost sensor, the improvement was substantial enough to make the readings usable for further analysis.&lt;/p&gt;
&lt;h2&gt;Fuzzy Mamdani Classification&lt;/h2&gt;
&lt;p&gt;Raw numbers are hard to interpret, so a Mamdani fuzzy model converted each reading into a thermal comfort category. Membership functions over temperature and humidity produced states from COLD through COMFORTABLE to HOT, which read naturally when compared with how the room actually felt.&lt;/p&gt;
&lt;p&gt;The classified readings were then checked against the ASHRAE 55-2020 comfort range for naturally ventilated spaces in tropical climates, 23 to 28 degrees Celsius. The analysis reported the share of readings inside that band:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When less than 70% of readings were comfortable, it recommended specific actions: optimize natural ventilation during the hottest hours, add fans to improve air circulation, and review internal heat loads from equipment and lighting.&lt;/li&gt;
&lt;li&gt;When at least 70% were comfortable, it recommended keeping the existing ventilation pattern and monitoring periodically to catch drift early.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Automated LaTeX Report&lt;/h2&gt;
&lt;p&gt;Once the analysis finished, the notebook assembled the report with pylatex: sections for the methodology and results, plus figures inserted directly from the analysis. The document compiled to a PDF and was saved to Google Drive so it could be shared immediately after each run.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;from pylatex import Document, Section

doc = Document(&amp;quot;Scientific_Thermal_Comfort_Report&amp;quot;)

with doc.create(Section(&amp;quot;Results and Discussion&amp;quot;)):
    doc.append(&amp;quot;This section presents the calibration outcomes and fuzzy logic analysis performed in Colab.&amp;quot;)

doc.generate_pdf(clean_tex=False)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Why Automate&lt;/h2&gt;
&lt;p&gt;The notebook turned a one-off comparison into a repeatable pipeline. New data can be added to the sheet and the report regenerated in a single run, which makes it practical to re-validate the calibration as the sensors age or the environment changes. It also showed that an inexpensive sensor like the DHT11 becomes far more reliable once its readings are corrected against a proper reference.&lt;/p&gt;
&lt;h2&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GitHub Gist:&lt;/strong&gt; DHT11 &amp;amp; HTC-1 Calibration Script
&lt;a href=&quot;https://gist.github.com/dankehidayat/1e7b296543a7aef27e711bea51d5cdd6&quot;&gt;https://gist.github.com/dankehidayat/1e7b296543a7aef27e711bea51d5cdd6&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Generated PDF Report:&lt;/strong&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1Z6PtvuDW63F5cUrvonf1WnnZPhWKushy/view&quot;&gt;https://drive.google.com/file/d/1Z6PtvuDW63F5cUrvonf1WnnZPhWKushy/view&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Original Post:&lt;/strong&gt;
&lt;a href=&quot;https://dankehidayat.my.id/blog/2025-10-17-automating-calibration-report-generation&quot;&gt;https://dankehidayat.my.id/blog/2025-10-17-automating-calibration-report-generation&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Energy Monitoring System Calibration: Linear Regression Approach for Sensor Accuracy</title><link>https://dankehidayat.my.id/notes/2025-10-14-energy-monitoring-system-calibration-linear-regression-approach/</link><guid isPermaLink="true">https://dankehidayat.my.id/notes/2025-10-14-energy-monitoring-system-calibration-linear-regression-approach/</guid><description>How an ESP32 energy monitoring system calibrates DHT11 temperature and humidity readings with linear regression, and how the fitted model runs in production firmware.</description><pubDate>Tue, 14 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;An energy monitoring system is only as trustworthy as the data it collects. When the readings feed HVAC control, small sensor errors compound into real misallocation of energy. This note describes how the Eco Office monitor, an ESP32-based system, calibrates its DHT11 temperature and humidity sensors against a reference instrument using ordinary least squares regression, and how the fitted model is deployed directly in the firmware.&lt;/p&gt;
&lt;p&gt;The DHT11 is inexpensive and easy to interface, but its accuracy is limited. Compared against a calibrated HTC-1 reference, the raw readings showed a mean absolute error of 3.84 degrees Celsius in temperature and 14.18% in relative humidity. Those offsets are too large for a system that uses environmental data to regulate cooling and heating.&lt;/p&gt;
&lt;h2&gt;Why Calibration Was Needed&lt;/h2&gt;
&lt;p&gt;Before calibration, the raw DHT11 readings diverged from the reference across the whole measurement range:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Temperature: mean absolute error around 3.84 degrees Celsius, with maximum errors approaching 5 degrees&lt;/li&gt;
&lt;li&gt;Humidity: mean absolute error around 14.18%, with large spikes at the extremes&lt;/li&gt;
&lt;li&gt;A consistent negative bias in temperature and a positive bias in humidity&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Errors of this size would distort any downstream calculation, from thermal comfort classification to energy consumption analysis. The readings had to be corrected before they could be used.&lt;/p&gt;
&lt;h2&gt;Measurement Setup and Data Collection&lt;/h2&gt;
&lt;p&gt;The DHT11 and the HTC-1 were placed side by side in a naturally ventilated office in Indonesia and logged concurrently for about nine hours. Logging spanned warm and cool parts of the day so that the model would see realistic variation.&lt;/p&gt;
&lt;p&gt;In total, 19 paired readings were collected. Temperature ranged from the mid-20s to the upper-20s degrees Celsius and relative humidity from around 46% to the low 70s. That spread is sufficient to fit a first-order model and to check how the correction behaves across the operating range.&lt;/p&gt;
&lt;h2&gt;Calibration Model&lt;/h2&gt;
&lt;p&gt;For each variable, a first-order model maps a raw reading $x$ onto a corrected value $\hat{y}$:&lt;/p&gt;
&lt;p&gt;$$
\hat{y} = a x + b
$$&lt;/p&gt;
&lt;p&gt;where $a$ is the slope and $b$ is the intercept, fitted separately for temperature and humidity. The coefficients fitted from the paired data and later embedded in the firmware are:&lt;/p&gt;
&lt;p&gt;$$
\begin{aligned}
\hat{T} &amp;amp;= 0.923,T_{\text{raw}} - 1.618 \
\hat{H} &amp;amp;= 0.926,H_{\text{raw}} + 18.052
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;The quality of the correction is reported as the mean absolute error (MAE) against the reference:&lt;/p&gt;
&lt;p&gt;$$
\mathrm{MAE} = \frac{1}{n}\sum_{i=1}^{n}\left|\hat{y}_i - y_i\right|
$$&lt;/p&gt;
&lt;h2&gt;Model Deployment in Firmware&lt;/h2&gt;
&lt;p&gt;The firmware stores the four fitted coefficients as constants and applies them on every DHT11 read, so each measurement is corrected before it is used or published:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;const float TEMP_SLOPE = 0.923;
const float TEMP_INTERCEPT = -1.618;
const float HUM_SLOPE = 0.926;
const float HUM_INTERCEPT = 18.052;

float calibrateTemperature(float rawTemp) { return (TEMP_SLOPE * rawTemp) + TEMP_INTERCEPT; }
float calibrateHumidity(float rawHum) { return (HUM_SLOPE * rawHum) + HUM_INTERCEPT; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A multiply-add per reading is negligible on the ESP32, which is one of the reasons a linear model was chosen over a heavier approach.&lt;/p&gt;
&lt;p&gt;The firmware also keeps a ring buffer of the last 10 per-sample errors and reports a running mean absolute error. That value is converted into an accuracy figure over the measurement range:&lt;/p&gt;
&lt;p&gt;$$
\mathrm{accuracy} = \max\left(0,; 100 - \frac{\mathrm{MAE}}{\mathrm{range}} \times 100\right)
$$&lt;/p&gt;
&lt;p&gt;This gives the dashboard a single percentage that summarizes how close the calibrated readings are to the reference.&lt;/p&gt;
&lt;h2&gt;Results&lt;/h2&gt;
&lt;p&gt;After applying the fitted models, the error metrics improved substantially:&lt;/p&gt;
&lt;h3&gt;Temperature&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Mean absolute error dropped from 3.84 degrees Celsius to 0.80 degrees Celsius&lt;/li&gt;
&lt;li&gt;Maximum error dropped from roughly 5 degrees to about 1.4 degrees&lt;/li&gt;
&lt;li&gt;The negative bias disappeared and the residuals scattered evenly around zero&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Humidity&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Mean absolute error dropped from 14.18% to 1.15%&lt;/li&gt;
&lt;li&gt;Maximum error shrank to roughly 2%&lt;/li&gt;
&lt;li&gt;Consistency across the range improved noticeably&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Overall, temperature accuracy improved by about 80% and humidity accuracy by more than 90%. For a low-cost sensor, that brings the readings within a useful range for energy analysis.&lt;/p&gt;
&lt;h2&gt;The Analysis Code&lt;/h2&gt;
&lt;p&gt;The regression was fit with a small Python class. The coefficients below match the values deployed in the firmware:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, r2_score

class SensorCalibrator:
    def __init__(self):
        self.temp_model = LinearRegression()
        self.humidity_model = LinearRegression()

        # Coefficients from the regression analysis
        self.temp_coef = 0.923
        self.temp_intercept = -1.618
        self.humidity_coef = 0.926
        self.humidity_intercept = 18.052

    def calibrate_temperature(self, raw_temp):
        return self.temp_coef * raw_temp + self.temp_intercept

    def calibrate_humidity(self, raw_humidity):
        return self.humidity_coef * raw_humidity + self.humidity_intercept

    def evaluate_calibration(self, raw_readings, reference_readings):
        calibrated = [self.calibrate_temperature(t) for t in raw_readings]

        mae = mean_absolute_error(reference_readings, calibrated)
        r2 = r2_score(reference_readings, calibrated)

        return {
            &amp;#39;mae&amp;#39;: mae,
            &amp;#39;r2&amp;#39;: r2,
            &amp;#39;calibrated_readings&amp;#39;: calibrated
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A quick example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;calibrator = SensorCalibrator()
raw_temp = 25.0
calibrated_temp = calibrator.calibrate_temperature(raw_temp)
print(f&amp;quot;Raw: {raw_temp} C -&amp;gt; Calibrated: {calibrated_temp:.2f} C&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Downstream Use in the System&lt;/h2&gt;
&lt;p&gt;Calibrated values feed several consumers inside the Eco Office monitor:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A fuzzy Mamdani engine classifies thermal comfort into COLD, COOL, COMFORTABLE, WARM, and HOT states from temperature and humidity.&lt;/li&gt;
&lt;li&gt;A second fuzzy engine classifies energy consumption into ECONOMICAL, NORMAL, and WASTEFUL states using voltage, active power, power factor, and reactive power from the PZEM-004T.&lt;/li&gt;
&lt;li&gt;MQTT telemetry publishes the corrected readings every 30 seconds to the Selene platform.&lt;/li&gt;
&lt;li&gt;The on-device LCD and the Blynk widgets display the calibrated values and the fuzzy states.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The PZEM-004T measures voltage, current, active power, power factor, frequency, and cumulative energy. One unit note matters here: the library method &lt;code&gt;PZEM004Tv30::energy()&lt;/code&gt; returns kilowatt-hours directly, while the underlying register is stored in watt-hours and divided by 1000. The MQTT field, the Blynk widget, and the LCD all use kWh consistently.&lt;/p&gt;
&lt;h2&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;Linear regression turned out to be a simple and effective way to calibrate low-cost sensors:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It reduced temperature and humidity errors to a fraction of their original values&lt;/li&gt;
&lt;li&gt;A multiply-add per reading is cheap enough for embedded hardware&lt;/li&gt;
&lt;li&gt;The resulting coefficients are easy to inspect, test, and update in the firmware&lt;/li&gt;
&lt;li&gt;Corrected readings made the downstream fuzzy classification and telemetry substantially more reliable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The next step is to explore non-linear calibration and automatic recalibration, particularly to handle sensor aging and slow changes in environmental conditions.&lt;/p&gt;
</content:encoded></item><item><title>Japanese Input with Mozc + Fcitx5 on Arch Linux (Wayland + Hyprland)</title><link>https://dankehidayat.my.id/notes/2025-04-18-japanese-input-with-mozc-fcitx5-arch-linux/</link><guid isPermaLink="true">https://dankehidayat.my.id/notes/2025-04-18-japanese-input-with-mozc-fcitx5-arch-linux/</guid><description>A simple guide to setting up Japanese input on Arch Linux using Fcitx5 and Mozc. Good for anyone who needs reliable Japanese typing for study, work, or communication.</description><pubDate>Fri, 18 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Setting up Japanese input on Linux can feel a bit confusing at first, especially if you’re new to the ecosystem. When I first tried writing Japanese on Arch Linux, I bounced between different input managers and configurations before finding a setup that “just works.” So in this guide, I’ll walk you through how to get &lt;strong&gt;Mozc + Fcitx5&lt;/strong&gt; working smoothly on &lt;strong&gt;Arch Linux with Wayland (Hyprland)&lt;/strong&gt; — the same setup I use daily.&lt;/p&gt;
&lt;p&gt;While these steps are for Arch (and distros that use pacman, like EndeavourOS or Manjaro), you can still apply the general idea on other distributions. The only part that changes is the package manager:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Debian/Ubuntu:&lt;/strong&gt; &lt;code&gt;apt install fcitx5-mozc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fedora:&lt;/strong&gt; &lt;code&gt;dnf install fcitx5-mozc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;openSUSE:&lt;/strong&gt; &lt;code&gt;zypper install fcitx5-mozc&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Everything else — configuration, environment variables, and Mozc settings — works similarly.&lt;/p&gt;
&lt;h2&gt;1. Install the Required Packages&lt;/h2&gt;
&lt;p&gt;Let’s start with the essentials. Install Fcitx5, Mozc, and the config tools:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman -S fcitx5 fcitx5-configtool fcitx5-qt fcitx5-mozc-ut
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gives you the input manager (Fcitx5), the Japanese engine (Mozc), plus the UI tools to configure everything.&lt;/p&gt;
&lt;h2&gt;2. Set Up Environment Variables&lt;/h2&gt;
&lt;p&gt;Next, your system needs to know that Fcitx5 is the input method framework you’ll be using. Add these lines to your shell config (&lt;code&gt;~/.zshrc&lt;/code&gt;, &lt;code&gt;~/.bashrc&lt;/code&gt;, or &lt;code&gt;~/.profile&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export GTK_IM_MODULE=&amp;quot;fcitx&amp;quot;
export QT_IM_MODULE=&amp;quot;fcitx&amp;quot;
export XMODIFIERS=@im=fcitx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then apply the changes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source ~/.zshrc   # or source ~/.bashrc / ~/.profile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A quick log-out and log-in will ensure everything loads properly.&lt;/p&gt;
&lt;h2&gt;3. Configure Fcitx5&lt;/h2&gt;
&lt;p&gt;Now that Fcitx5 is installed, it’s time to make Mozc your Japanese input method.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open &lt;strong&gt;fcitx5-configtool&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;+&lt;/strong&gt; to add a new input method.&lt;/li&gt;
&lt;li&gt;Uncheck &lt;strong&gt;“Only Show Current Language”&lt;/strong&gt; so Japanese engines appear.&lt;/li&gt;
&lt;li&gt;Search for &lt;strong&gt;Mozc&lt;/strong&gt; and add it.&lt;/li&gt;
&lt;li&gt;Remove any input methods you don’t want, like “Keyboard - English.”&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;At this point, Fcitx5 should appear in your system tray or panel.&lt;/p&gt;
&lt;h2&gt;4. Enable Japanese Input&lt;/h2&gt;
&lt;p&gt;Here’s the fun part — switching languages.&lt;/p&gt;
&lt;p&gt;By default, you can toggle between English and Japanese using:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Ctrl + Space&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Try typing &lt;em&gt;nihongo&lt;/em&gt; and you should see:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;にほんご&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If that works, you’re officially ready to type Japanese anywhere on your system.&lt;/p&gt;
&lt;h2&gt;5. Optional: Install Themes for Fcitx5&lt;/h2&gt;
&lt;p&gt;If you want your input menu to look a bit nicer (especially if you use Hyprland with a themed setup), there are some great community skins.&lt;/p&gt;
&lt;p&gt;With &lt;code&gt;yay&lt;/code&gt; installed, you can grab them like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Dark theme
yay -S fcitx5-skin-fluentdark-git

# Light theme
yay -S fcitx5-skin-fluentlight-git

# Material Color theme
yay -S fcitx5-material-color
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then apply the theme:&lt;/p&gt;
&lt;p&gt;Right-click the Fcitx5 tray icon → &lt;strong&gt;Configure&lt;/strong&gt; → &lt;strong&gt;Addons&lt;/strong&gt; → &lt;strong&gt;Classic UI&lt;/strong&gt; → Choose your skin.&lt;/p&gt;
&lt;h2&gt;6. Customize Mozc&lt;/h2&gt;
&lt;p&gt;Mozc itself has plenty of customization options. You can access them by:&lt;/p&gt;
&lt;p&gt;Right-click Fcitx5 tray icon → &lt;strong&gt;Mozc Settings&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;From here, you can tweak:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;your input mode&lt;/li&gt;
&lt;li&gt;key mappings&lt;/li&gt;
&lt;li&gt;dictionary behavior&lt;/li&gt;
&lt;li&gt;suggestion style&lt;/li&gt;
&lt;li&gt;punctuation preferences&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Make it feel natural for your workflow.&lt;/p&gt;
&lt;h2&gt;Troubleshooting Tips&lt;/h2&gt;
&lt;p&gt;Here are a few common issues you might run into:&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Fcitx5 isn’t starting&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Add it to autostart in your DE/WM.
For Hyprland users, you can add:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec-once = fcitx5 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;strong&gt;Input doesn’t work in some apps&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Some Electron apps (like VS Code or Discord) need Wayland flags enabled:&lt;/p&gt;
&lt;p&gt;Add these flags to their &lt;code&gt;.desktop&lt;/code&gt; file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;--enable-features=UseOzonePlatform --ozone-platform=wayland
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After that, Japanese input should work normally.&lt;/p&gt;
&lt;h2&gt;All Set!&lt;/h2&gt;
&lt;p&gt;Once everything is installed, configured, and themed the way you like, you’ll have a smooth and reliable Japanese input experience on Arch Linux. Whether you&amp;#39;re studying Japanese, chatting with friends, or writing notes, this setup is dependable and lightweight — perfect for daily use.&lt;/p&gt;
&lt;p&gt;If you want me to prepare the frontmatter + content together in a single file, just say &lt;strong&gt;“assemble it”&lt;/strong&gt; and I’ll package the whole blog post neatly.&lt;/p&gt;
</content:encoded></item><item><title>Beneath the Masks: A Personal Anime Review of BanG Dream! Ave Mujica</title><link>https://dankehidayat.my.id/notes/2025-04-15-beneath-the-masks-ave-mujica-review/</link><guid isPermaLink="true">https://dankehidayat.my.id/notes/2025-04-15-beneath-the-masks-ave-mujica-review/</guid><description>My honest take on BanG Dream! Ave Mujica, a dark and emotional music anime about identity, ambition, trauma, and what it means to create art when everything inside you feels broken.</description><pubDate>Tue, 15 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/images/blog/ave-mujica/thumbnail.jpeg&quot; alt=&quot;Ave Mujica thumbnail&quot;&gt;&lt;/p&gt;
&lt;p&gt;When I heard there was going to be an Ave Mujica anime, I wasn’t sure what to expect. It’s part of the BanG Dream universe, but it doesn’t follow the usual upbeat path. This one leans into a gothic metal tone with characters who wear emotional armor and try to sound louder than their own fears.&lt;/p&gt;
&lt;p&gt;This is a review from someone who watched not just the music, but the people behind it. The show is as much about psychology as it is about guitar riffs and set pieces.&lt;/p&gt;
&lt;h2&gt;What Ave Mujica Actually Is&lt;/h2&gt;
&lt;p&gt;Ave Mujica isn’t just another band in the franchise. They’re a strange mix of masked performance and emotional unraveling.&lt;/p&gt;
&lt;p&gt;Sakiko, known on stage as Oblivionis, forms the band after her old group CRYCHIC collapses. She brings in four other girls, each with their own contradictions, and asks them to become something greater than themselves. And heavier.&lt;/p&gt;
&lt;p&gt;Instead of typical band anime energy, their sound goes for gothic symphonic metal. Dramatic. Brooding. Their whole style feels like a metaphor for how every member carries some version of a cracked identity.&lt;/p&gt;
&lt;h2&gt;Getting to Know the Characters&lt;/h2&gt;
&lt;p&gt;The thing that surprised me most is how much the show cares about who these characters are. It doesn’t rely on tropes. It slows down and lets you feel what they’re struggling with.&lt;/p&gt;
&lt;h3&gt;Sakiko Togawa (Oblivionis)&lt;/h3&gt;
&lt;p&gt;Sakiko’s story is the one that keeps pulling me back. She watched CRYCHIC fall apart and watched her old friends move forward without her. Starting Ave Mujica almost feels like a shield.&lt;/p&gt;
&lt;p&gt;Her stage persona means “to forget,” but the show makes it clear she never really forgets anything. She buries it under control, perfection, and a need to rewrite her own history.&lt;/p&gt;
&lt;p&gt;There are scenes where she looks like she’s keeping the entire band together through sheer willpower, even while she’s falling apart inside. It’s hard not to feel for her.&lt;/p&gt;
&lt;h3&gt;Mutsumi Wakaba (Mortis)&lt;/h3&gt;
&lt;p&gt;Mutsumi’s story hurts in a very human way. Her relationship with Mortis isn’t a gimmick. It feels like a person trying to survive by splitting off the parts of themselves that can take the hits.&lt;/p&gt;
&lt;p&gt;When Mortis appears, it’s not an edgy moment. It’s a cry for help. And the show treats it that way.&lt;/p&gt;
&lt;p&gt;Their back and forth makes up the emotional center of the series for me. It’s identity laid bare in the most dramatic and painful way.&lt;/p&gt;
&lt;h3&gt;Nyamu Yutenji (Amoris)&lt;/h3&gt;
&lt;p&gt;Nyamu is that chaotic presence you can’t look away from. She’s loud, charming, and unpredictable. She wants attention and isn’t shy about it.&lt;/p&gt;
&lt;p&gt;Her persona means “of love,” which fits because she chases affection like it’s her life force. At first she looks like comic relief, but she becomes a foil to Sakiko’s rigid world view.&lt;/p&gt;
&lt;p&gt;She forces the band to confront their own strictness. And she makes the group feel alive.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/images/blog/ave-mujica/hachibousei_dance.jpg&quot; alt=&quot;Hachibousei Dance&quot;&gt;&lt;/p&gt;
&lt;h3&gt;Uika Misumi (Doloris)&lt;/h3&gt;
&lt;p&gt;Uika holds herself in a way that always looks composed. That calm hides a lot of pressure though.&lt;/p&gt;
&lt;p&gt;She has experience in another idol unit, and it gives her a strange duality. Bright idol on one side, dark metal guitarist on the other. She’s always aware of both worlds and you can feel the weight on her.&lt;/p&gt;
&lt;h3&gt;Umiri Yahata (Timoris)&lt;/h3&gt;
&lt;p&gt;Umiri is quiet but extremely precise. Everything she does is measured. Her persona means “fear,” and it reflects her perfectionism well.&lt;/p&gt;
&lt;p&gt;What I like about her arc is that it never turns her into someone she’s not. She doesn’t suddenly become loose or carefree. She learns how to move forward without erasing the parts of herself that still worry.&lt;/p&gt;
&lt;h2&gt;Why the Show Works&lt;/h2&gt;
&lt;p&gt;The gothic visuals aren’t just there for style. They mirror the themes. Masks hide truths we don’t want to face. Personas become shields. Every member of the band is trying to figure out who they are under the makeup and the costumes.&lt;/p&gt;
&lt;p&gt;The animation leans into this. Shadowed stages. Sharp highlights. Close-up shots that feel like confessions. The music doesn’t act as background either. It feels like the only language these characters can use to say what they can’t put into words.&lt;/p&gt;
&lt;h2&gt;Some Flaws, But Nothing Deal-Breaking&lt;/h2&gt;
&lt;p&gt;The show has a few rough edges.&lt;/p&gt;
&lt;p&gt;Some symbolic moments lean a bit too dramatic. A few scenes assume you already know the emotional weight they’re referencing. And this isn’t a gentle entry into music anime. It starts heavy and stays that way.&lt;/p&gt;
&lt;p&gt;Even with those flaws, the series never wastes the emotion it builds.&lt;/p&gt;
&lt;h2&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;For me, Ave Mujica feels like watching people pour themselves onto a stage and trying to make something beautiful out of the mess.&lt;/p&gt;
&lt;p&gt;It isn’t just a band story. It’s a story about people trying to pull themselves together, even when they already expect to break again. Somewhere in that chaos, they find moments of harmony.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rating: ★★★★★ (5/5)&lt;/strong&gt;
Not just for the music, but for how deeply I felt every beat of these characters’ hearts.&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/BanG_Dream%21_Ave_Mujica&quot;&gt;https://en.wikipedia.org/wiki/BanG_Dream%21_Ave_Mujica&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Ave_Mujica&quot;&gt;https://en.wikipedia.org/wiki/Ave_Mujica&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://anibase.net/en/character/mPen1/Uika-Misumi&quot;&gt;https://anibase.net/en/character/mPen1/Uika-Misumi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Computers Were Faster When They Were Slower</title><link>https://dankehidayat.my.id/notes/2024-11-30-computers-were-faster-when-they-were-slower/</link><guid isPermaLink="true">https://dankehidayat.my.id/notes/2024-11-30-computers-were-faster-when-they-were-slower/</guid><description>A look at why modern machines feel slower despite powerful hardware, and how bloated software and careless coding practices are dragging us down.</description><pubDate>Sat, 30 Nov 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/images/blog/computers-slower/moore_hu.jpeg&quot; alt=&quot;Illustration of old vs modern computer performance&quot;&gt;&lt;/p&gt;
&lt;p&gt;There’s a strange truth about modern computing. Machines today are faster, lighter, and capable of doing far more than the ones we grew up with. Yet they often feel slower when you open an app, load a website, or try to do something simple.&lt;/p&gt;
&lt;p&gt;The problem isn’t the hardware. It’s the software we run on top of it.&lt;/p&gt;
&lt;h2&gt;The Promise of Moore’s Law&lt;/h2&gt;
&lt;p&gt;Moore’s Law predicted that transistor counts on integrated circuits would double about every two years. For decades, that meant computers would get faster and more capable at a steady, almost predictable pace.&lt;/p&gt;
&lt;p&gt;And for the most part, this held up. Hardware has become absurdly powerful compared to what we had in the past. Even a budget phone today can run circles around high-end desktops from the early 2000s.&lt;/p&gt;
&lt;p&gt;But while the hardware raced ahead, software development took a different path.&lt;/p&gt;
&lt;h2&gt;The Reality of Modern Software&lt;/h2&gt;
&lt;p&gt;In the early days, developers wrote programs like every byte mattered. Memory was limited. Storage was tiny. CPUs crawled. You had to be careful and intentional.&lt;/p&gt;
&lt;p&gt;Today the mindset is different. Hardware is “good enough,” so efficiency is treated like an optional bonus. The result is software that’s larger, slower, and full of features most people never touch.&lt;/p&gt;
&lt;p&gt;A simple example is the text editor. Years ago, it opened instantly and used a tiny amount of memory. Today, many editors load entire frameworks, sync accounts, run background processes, and ship with plugins you never asked for.&lt;/p&gt;
&lt;p&gt;The tool is the same, but the experience is slower.&lt;/p&gt;
&lt;h2&gt;The Bandwidth vs Processing Paradox&lt;/h2&gt;
&lt;p&gt;We have faster internet, quicker storage, and stronger CPUs. Websites should load instantly. Web apps should feel snappy. Most don’t.&lt;/p&gt;
&lt;p&gt;Modern sites stack frameworks on top of frameworks. They load megabytes of scripts to display a few paragraphs of text. The speed we gain from better hardware gets erased by layers of complexity.&lt;/p&gt;
&lt;p&gt;A faster connection doesn’t help much when a site insists on loading twelve analytics trackers and half a megabyte of CSS.&lt;/p&gt;
&lt;h2&gt;A Small but Embarrassing Example&lt;/h2&gt;
&lt;p&gt;A developer once needed to number the lines in a text file. Instead of using the built-in Unix command &lt;code&gt;nl&lt;/code&gt;, which does this instantly, they wrote a Python script that looped through the file line by line. It was slower, more complicated, and solved a problem the system already handled.&lt;/p&gt;
&lt;p&gt;This isn’t rare. Many developers simply don’t know what tools already exist. They default to writing new code, often without thinking about performance, because writing feels easier than learning.&lt;/p&gt;
&lt;h2&gt;The Weight of Abstraction&lt;/h2&gt;
&lt;p&gt;Modern software leans heavily on abstraction layers. Frameworks on top of frameworks. Libraries wrapped inside other libraries.&lt;/p&gt;
&lt;p&gt;Abstraction helps developers build things faster, but every extra layer adds cost. A small web app might load dozens of dependencies just to show a few buttons. Each library adds memory use, CPU time, and maintenance overhead.&lt;/p&gt;
&lt;p&gt;None of this is visible to the user. They just feel the lag.&lt;/p&gt;
&lt;h2&gt;The Snowball Effect&lt;/h2&gt;
&lt;p&gt;One slow tool is manageable. A hundred slow tools running at once is a different story.&lt;/p&gt;
&lt;p&gt;That’s where we are now. Even with hardware that is thousands of times more capable than what we had in the past, the software stack is so heavy that the performance gain gets eaten alive.&lt;/p&gt;
&lt;p&gt;You can see this in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;browsers that use gigabytes of RAM&lt;/li&gt;
&lt;li&gt;operating systems that launch dozens of background processes&lt;/li&gt;
&lt;li&gt;games that rely on upscaling to compensate for inefficient rendering pipelines&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The hardware is strong. The software is what’s slowing us down.&lt;/p&gt;
&lt;h2&gt;The Path Forward&lt;/h2&gt;
&lt;p&gt;We don’t need to abandon modern tools. They’ve made development more accessible and allowed people to create things that would have been impossible a decade ago.&lt;/p&gt;
&lt;p&gt;But we do need a shift in mindset. Developers should:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;learn the system tools that already exist&lt;/li&gt;
&lt;li&gt;write code with performance in mind&lt;/li&gt;
&lt;li&gt;avoid dependencies that don’t add real value&lt;/li&gt;
&lt;li&gt;build with intention instead of convenience&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Minimalism isn’t about doing less. It’s about doing what matters and doing it well.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Computers are faster than ever, but they rarely feel that way. Moore’s Law keeps pushing hardware forward, but software often pulls the experience back.&lt;/p&gt;
&lt;p&gt;If we want machines to feel fast again, we need to treat efficiency as a priority instead of an afterthought. Otherwise we’ll stay stuck in a strange loop where better hardware gives us slower programs.&lt;/p&gt;
</content:encoded></item><item><title>Social Media and the Mechanics of Behavioral Influence</title><link>https://dankehidayat.my.id/notes/2021-08-08-social-media-and-the-mechanics-of-behavioral-influence/</link><guid isPermaLink="true">https://dankehidayat.my.id/notes/2021-08-08-social-media-and-the-mechanics-of-behavioral-influence/</guid><description>A reflection on how modern social media platforms mirror the principles of B.F. Skinner’s behavioral conditioning, shaping how we act, think, and interact online.</description><pubDate>Sun, 08 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/images/blog/skinner-box/thumbnail.webp&quot; alt=&quot;Baby inside skinner box&quot;&gt;&lt;/p&gt;
&lt;p&gt;An American psychologist named B. F. Skinner (1904–1990) became widely known for the &lt;em&gt;Skinner Box&lt;/em&gt;, a device used in animal behavior experiments. In his research, he placed rats inside a box equipped with lights, levers, and other mechanisms. He programmed the box so that when a rat stood on a lever or pressed it at a certain moment, it might receive a reward, such as a food pellet, or a mild electric shock. Although the experiments involved animals, the ideas behind them were aimed at understanding human behavior.&lt;/p&gt;
&lt;p&gt;Skinner later wrote a book titled &lt;em&gt;Beyond Freedom and Dignity&lt;/em&gt;, where he explained how he viewed the world. His vision was a kind of behavioral utopia in which every human action is shaped by stimulus and response, much like what happened inside his experimental box.&lt;/p&gt;
&lt;p&gt;In this view, people do good social things because those behaviors are rewarded, and they avoid unwanted actions because those behaviors are punished. Skinner believed that “freedom” and “dignity” were abstract ideas, almost illusions. They were metaphysical concepts, not actual goals of society. Social engineers, he argued, could design a system that shapes people to behave as expected.&lt;/p&gt;
&lt;p&gt;This feels relevant today because, in many ways, we live inside a modern “Skinner Box,” especially when we think about social media.&lt;/p&gt;
&lt;p&gt;Social media is a form of social control. Every platform—Facebook, Twitter, Reddit—functions like a giant Skinner Box. In the early days, these platforms were more open, decentralized, and free. But over time, the people running them realized they could act like social engineers.&lt;/p&gt;
&lt;p&gt;What’s striking is that social control on these platforms doesn’t require much effort. They almost run themselves. You can steer people to behave in certain ways simply by shaping how they interact. Even basic tools like banning users are enough. Platforms don’t need to ban many accounts—just enough to create a chilling effect that influences everyone else.&lt;/p&gt;
&lt;p&gt;Privacy isn’t the only concern. The deeper issue is how your behavior becomes metadata. The people making decisions might not know you personally, but the metadata is used to train new AI models designed for cognitive influence. These systems can tag content automatically, spread certain messages, trigger hashtags, or push specific recommendations to shape what people see.&lt;/p&gt;
&lt;p&gt;We can probably agree that with all this information at our fingertips, it’s becoming harder to “single-task” or devote serious thought to anything that requires sustained attention. A student might deactivate Facebook or ask a friend to hide their phone just so they can finish a lab report in the next four hours.&lt;/p&gt;
&lt;p&gt;Sharing has become the norm, and sharing itself isn’t a problem. The issue is that most shared content isn’t meaningful persuasion or thoughtful argument. It simply distracts us from deeper thinking.&lt;/p&gt;
&lt;p&gt;As social media and personal technology become even more embedded in the lives of younger generations, the problem will only grow. Small social habits once seen as trivial are increasingly normalized, while the social push toward slow, reflective thinking fades into the background.&lt;/p&gt;
&lt;p&gt;Many people believe social media gives them a new voice for revolution and social change. But those who look closer understand that this technological revolution is not like the social revolutions of the past.&lt;/p&gt;
&lt;p&gt;I enjoy social media. Being able to connect with others so easily is a real gift to our natural need for friendship and understanding. But we should ask where our time is best spent. Instead of waiting for change after seeing it on your feed, how can what you see translate into your own life? Why is this information shown to me? What purpose does this photo, story, or tweet serve?&lt;/p&gt;
&lt;p&gt;Rather than treating social media as the answer to every question in our daily interactions, it’s healthier to treat it as just one more tool for examining the larger issues we face.&lt;/p&gt;
&lt;p&gt;Don’t let society or social media bury you under the weight of endless information. Question what you see. Don’t settle into complacency and drift away from the deeper, more demanding forms of thought that make us fully human.&lt;/p&gt;
</content:encoded></item></channel></rss>