SkillAgentSearch skills...

jetson-customize-fan

Use when you need to add, remove, edit, list, or change the boot default of an nvfancontrol fan profile on a Jetson/Tegra (Orin, Thor) target. Triggers: edit fan profile, tune fan curve.

Install / Use

npx skills add NVIDIA/skills --skill jetson-customize-fan

Installs into whichever agent you are using.

About this skill
📄

SKILL.md

Installable skill definition

Quality Score

95/100

Supported Platforms

Universal

Tags

Our assessment of jetson-customize-fan

jetson-customize-fan scores 95/100 on our quality scale, 360th of 3,356 Development & Engineering skills we index (top 11%).

Its SKILL.md is 17 KB long, well organised into 18 sections with 8 code examples: a thorough specification that gives an agent plenty to work with.

With 3,421 GitHub stars, it is one of the more widely adopted skills in the catalogue.

Substance
30/30
Structure
20/20
Description
15/15
Adoption
15/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated 5 days ago, so jetson-customize-fan is actively maintained.
  • It is released under the Apache-2.0 license, a permissive license that allows use, modification and commercial use with attribution.
  • Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

Safety scan

No issues found

Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands.

Automated pattern scan on 2026-09-29. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.

jetson-customize-fan compared with similar skills

All 4 of these similar skills score higher than jetson-customize-fan; compare them before choosing.

SkillScoreStarsUpdatedFormat
jetson-customize-fan (this skill)by NVIDIA953.4k5d agoSKILL.md
ai-job-searchby MadsLorentzen10044.4ktodayCLAUDE.md
claude-howtoby luongnv8910041.7k2d agoCLAUDE.md
algorithmic-artby anthropics100177.9k6d agoSKILL.md
pptxby anthropics100177.9k6d agoSKILL.md

Frequently asked questions

How do I install jetson-customize-fan?
Run npx skills add NVIDIA/skills --skill jetson-customize-fan. The install tabs above show the steps for each supported agent.
Which AI agents does jetson-customize-fan work with?
It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
Is jetson-customize-fan safe to use?
Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. It is Apache-2.0-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is jetson-customize-fan still maintained?
The repository was last updated 5 days ago, so jetson-customize-fan is actively maintained.

name: jetson-customize-fan description: >- Use when you need to add, remove, edit, list, or change the boot default of an nvfancontrol fan profile on a Jetson/Tegra (Orin, Thor) target. Triggers: edit fan profile, tune fan curve. version: 0.0.1 license: "Apache-2.0" metadata: data-classification: public author: "Jetson Team" tags: - thermal - fan - nvfancontrol - profile domain: thermal

Modify nvfancontrol Fan Profile (BSP-side)

Purpose

Edit the per-board nvfancontrol configuration so the device boots with the desired fan curve / control mode / governor / default profile. BSP-side only — all writes land in the overlay tracker, the upstream bsp_image copy is read-only.

This skill handles BSP-side edits to the per-board nvfancontrol configuration file: adding profiles, removing profiles, editing the temp → PWM / RPM curves, changing the boot default profile / control mode / governor, and listing defined profiles. Applies on Jetson / Tegra platforms (T234 Orin, T264 Thor).

File format (canonical, per the BSP file header)

POLLING_INTERVAL <seconds>

<FAN <index>>
    TMARGIN <ENABLED|DISABLED>
    FAN_GOVERNOR <type> {
        STEP_SIZE <int>
    }
    FAN_CONTROL <close_loop|open_loop> {
        RPM_TOLERANCE <rpm>
    }
    FAN_PROFILE <name> {
        # TEMP HYST PWM RPM
        <T0> <H0> <P0> <R0>
        ...
    }
    FAN_PROFILE <name> { ... }       # one or more profiles
    THERMAL_GROUP <id> {
        GROUP_MAX_TEMP <C>
        # zone-name <coeffs csv> <max-temp>
        <zone> <coeffs> <max-temp>
        ...
    }
    FAN_DEFAULT_CONTROL  <close_loop|open_loop>
    FAN_DEFAULT_PROFILE  <name>
    FAN_DEFAULT_GOVERNOR <type>
    KICKSTART_PWM <0..255>

Rules:

  • Profile curve tuples are 4-column: TEMP HYST PWM RPM. Sort points by ascending TEMP; the daemon interpolates between them.
  • PWM is 0..255 (8-bit duty cycle); RPM is the close-loop target speed. A trailing 0 0 row at the high end pins the fan off above GROUP_MAX_TEMP.
  • HYST is hysteresis (°C) at that point — the controller waits HYST degrees of cooling before stepping the curve down.
  • FAN_DEFAULT_PROFILE must reference an existing FAN_PROFILE block in the same <FAN N>. nvfancontrol fails to start if the default names a missing profile.
  • FAN_DEFAULT_CONTROL = close_loop (drives toward target RPM, requires tach) or open_loop (writes PWM directly).
  • FAN_DEFAULT_GOVERNOR = cont (continuous interpolation) and other family-specific values; copy verbatim from existing per-board files when introducing one.
  • THERMAL_GROUP maps thermal zones to the controller's input. Coefficients are a 20-element CSV — copy verbatim from existing entries; values vary by chip family and zone.
  • <FAN N> is one block per fan index (typical: <FAN 1>). Block boundaries <...> and {...} are strict; preserve indentation matching neighboring lines.
  • Curves are characterised, not invented. Add or edit curves from real thermal-acoustic data for the platform; do not interpolate from neighbouring profiles or copy across chip families.

Prerequisites

Resolve the active profile per ../../context/target-platform-contract.md. Refuse and route in these cases:

| Condition | Refuse with | |---|---| | No active profile, or active: NA | Route to /jetson-set-target or /jetson-init-target. | | Profile lacks bsp_image: block | Route to /jetson-init-image. | | <bsp_image.root_path>/Linux_for_Tegra/ missing | Route to /jetson-init-image. | | <source.root_path>/Linux_for_Tegra/ missing or not a git repo | Route to /jetson-init-source. |

Resolve paths:

  • <bsp_image.root_path> from bsp_image.root_path: if present, else <workspace>/Image.
  • <source.root_path> from source.root_path: if present, else <workspace>/Source.

<bsp_image.root_path> is read-only for this skill; every write lands under <source.root_path> (the overlay tracker). This is the workflow invariant in ../../context/bsp-customization-workflow.md#workflow-invariants — hand-editing upstream silently destroys the diff trail and makes /jetson-promote-image a noop.

The per-board file

The conf this skill edits has the relative path:

Linux_for_Tegra/rootfs/etc/nvpower/nvfancontrol/nvfancontrol_<active-sku>.conf

It lives in two roots; the skill walks both:

| Role | Location | Skill writes? | |---|---|---| | Detection + pristine source | <bsp_image.root_path>/Linux_for_Tegra/rootfs/etc/nvpower/nvfancontrol/ | no — read-only | | Overlay edit target + git commit | <source.root_path>/Linux_for_Tegra/rootfs/etc/nvpower/nvfancontrol/ | yes |

Subsequent sections refer to the per-board file to mean the overlay copy under <source.root_path>. Operations 1–4 all read, edit, and save against that overlay copy. The <bsp_image.root_path> copy is read once during the "Resolving <active-sku>" detection step and once during the Overlay edit recipe's pristine-import step, then never touched again.

Resolving <active-sku> — which file to edit

Filename conventions vary per product family:

  • nvfancontrol_<module.id>_<module.sku>.conf — most Orin parts (e.g. nvfancontrol_p3767_0000.conf, nvfancontrol_p3701_0008.conf).
  • nvfancontrol_<module.id>_<module.sku>_<carrier.id>_<carrier.sku>.conf — Thor variants where the carrier disambiguates (e.g. nvfancontrol_p3834_0008_p4071_0000.conf).
  • nvfancontrol_<carrier>_<sku>_<rev>.conf — IGX revision variants (e.g. nvfancontrol_p3740_0002_b01.conf).

The nvfancontrol daemon resolves the right file at startup based on the booted hardware's DT compatible plus board IDs (no helper script — it's done inside the binary). To map BSP-side without a running target, against <bsp_image.root_path>:

  1. List <bsp_image.root_path>/Linux_for_Tegra/rootfs/etc/nvpower/nvfancontrol/.
  2. Filter to filenames that contain <module.id>_<module.sku> from the active profile.
  3. If multiple candidates remain, refine with <carrier.id>_<carrier.sku> and (when relevant) the carrier revision tag.
  4. If still ambiguous, run the per-board flash conf dispatch chain to read the kernel DTB's compatible and pick the file whose name aligns with the resolved board / carrier.
  5. Verify the chosen file actually exists under <bsp_image.root_path>/Linux_for_Tegra/rootfs/etc/nvpower/nvfancontrol/.

Don't blindly compose a filename — the naming convention varies by product family.

Propagation set — confs to keep in sync

The active-SKU file is rarely the only conf that should carry a customization. After editing it, apply the same edit to every sibling in the propagation set so the change survives regardless of which module / baseboard SKU is booted:

  • The reference platform's nvfancontrol conf — the upstream conf the active file was forked from (resolve via reference_devkit in the active profile, or jetson-derive-carrier fork ancestry). For a BSP that contains only the reference (no derived carriers), this is the same file as the active and the rule reduces to a no-op.
  • Every carrier-derived nvfancontrol conf — each nvfancontrol_*.conf produced by jetson-derive-carrier for a custom carrier on top of the same module SKU.

"Apply the same edit" ≠ blanket file copy. Port the changed FAN_PROFILE / control lines into each sibling; preserve every other line. Sibling confs often hold carrier-specific deltas (different THERMAL_GROUP coefficients for a different thermal solution, different tach RPM ceilings) that must stay intact — a blanket overwrite would mis-tune the fan on those carriers. Blanket-copying is safe only when both confs were byte-identical before the edit.

Overlay edit recipe (apply before any Operation)

Follow the canonical Off-skill edits recipe in the workflow doc — pristine import + customization commit pair, both gated by the preview gate. Apply once per run, covering every per-board file the run touches (the active conf plus every sibling in the Propagation set).

Concrete substitutions for this skill:

  • <rel>/<file> is rootfs/etc/nvpower/nvfancontrol/<conf>.
  • Suggested pristine-import message: import pristine: <comma-separated rel paths of imported confs>, body Source: <bsp_image.root_path>/Linux_for_Tegra/ (BSP <bsp_image.version>).
  • Suggested customization-commit header: jetson-customize-fan: <summary>, body lines like nvfancontrol_p3767_0000.conf: added FAN_PROFILE static (open-loop, PWM=255 flat), FAN_DEFAULT_CONTROL close_loop -> open_loop, FAN_DEFAULT_PROFILE quiet -> static.

Instructions

Pick the operation that matches the user's intent and follow the matching subsection. All write-side operations (1–4) must first apply the Overlay edit recipe.

  • Operation 1 — Add a new fan profile.
  • Operation 2 — Remove a fan profile.
  • Operation 3 — Edit an existing fan profile (curve, hysteresis).
  • Operation 4 — Change the boot default (control / profile / governor).
  • Operation 5 — List defined fan profiles (read-only).

After any write-side operation, run the Deploy chain (## Deploy) to land the change on the device.

Examples

Add an aggressive profile to a P3767-0000 (Orin Nano dev kit) target and pin it as the boot default:

/jetson-customize-fan
> add a profile called "aggressive" with the curve {0:255, 40:150, 80:0}
> set FAN_DEFAULT_PROFILE to aggressive

Soften the fan ramp on the existing quiet profile (raise HYST, lower mid-PWM):

/jetson-customize-fan
> edit FAN_PROFILE quiet — raise HYST to 5 from 30 °C up, drop PWM at 60 °C to 80

List which profiles the active SKU currently defines and which is the boot default:

/jetson-customize-fan
> list defined fan profiles

Operation 1 — Add a new fan profile

Apply the Overlay edit recipe first.

  1. In the per-board file, inside the <FAN N> block, add a new FAN_PROFILE <name> { ... } between existing profiles. Daemon parse order doesn't matter, but grouping with siblings keeps the file scannable.
  2. Pick <name> lowercase, no whitespace (e.g. quiet, cool, aggressive).
  3. Fill the curve table — 4-column TEMP HYST PWM RPM tuples, ascending TEMP. End with at least one row above GROUP_MAX_TEMP so behavior at over-temp is defined.

Example skeleton:

FAN_PROFILE aggressive {
    #TEMP HYST PWM RPM
    0    0    255 6000
    20   2    255 6000
    40   2    150 3500
    60   2    50  1500
    80   0    0   0
    105  0    0   0
}

Validate (see Rules):

  • Every TEMP lies within 0..GROUP_MAX_TEMP of the THERMAL_GROUP.
  • PWM ∈ [0, 255]; RPM ≤ the platform's tach-reported max (varies by fan part).
  • Tuples are sorted ascending by TEMP.

If you intend the new profile to be the boot default, follow Operation 4.

Operation 2 — Remove a fan profile

Apply the Overlay edit recipe first.

  1. In the per-board file, delete the entire FAN_PROFILE <name> { ... } block including all curve rows and the closing }.
  2. If the deleted <name> matches the trailing FAN_DEFAULT_PROFILE, point FAN_DEFAULT_PROFILE at a remaining profile — otherwise the daemon fails to start.
  3. Search for hard-coded references in the rootfs before declaring the change safe:
    grep -rn "nvfancontrol.*profile\|FAN_PROFILE" \
      Linux_for_Tegra/rootfs/etc 2>/dev/null
    

The remaining profiles do not need renaming.

Operation 3 — Edit an existing fan profile

Apply the Overlay edit recipe first.

  1. In the

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars3.4k
CategoryDevelopment
Updated5d ago
Forks412

Languages

Python

Trust signals

100/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

No cautions