Files
bambuddy/backend/tests
maziggy 7e5eff14d8 feat(humidity): per-filament humidity threshold for auto-drying + alarms (#1605)
Reporter @thenewguy runs an engineering farm with one AMS per material
      (PLA, ASA, Nylon, PVB, HIPS) — Bambuddy's single global ams_humidity_fair
      threshold (default 60%) was driving both the queue / ambient auto-drying
      trigger AND the hourly humidity alarm uniformly, which is wrong for
      multi-material setups where Nylon wants <10% and PLA is fine at 60%.

      Drying RUN parameters were already per-filament via drying_presets;
      this commit adds the missing per-filament TRIGGER.

      New setting ams_humidity_thresholds — JSON map of filament-type to
      threshold percent with a "default" key for unknown / unmapped types.
      Empty / unset → both consumers fall back to ams_humidity_fair so the
      upgrade is silent.

      Resolver lives in PrintScheduler.resolve_humidity_threshold(trays,
      thresholds, fallback) — picks the lowest (most-restrictive) threshold
      across all loaded tray types, matching the conservative-params strategy
      _get_conservative_drying_params already uses for temp / hours. Empty
      tray slots contribute no constraint; all-empty AMS falls through to the
      "default" key. Filament names normalized to uppercase base (so
      "PLA Basic" / "pla basic" both map to PLA).

      Two consumer sites rewired through the same resolver so the scheduler
      and the alarm path can never disagree about whether an AMS is "too
      humid":
        - print_scheduler.py::_check_auto_drying — per-AMS humidity comparison
          for start / stop / skip decisions.
        - main.py AMS sensor / alarm worker — hourly humidity alarm notifier.

      UI: new table in Settings → Workflow → Auto-Drying, below the existing
      Drying Presets table. Default row + 8 default filament types
      (PLA / PETG / TPU / ABS / ASA / PA / PC / PVA) pre-filled from the
      current ams_humidity_fair value so the editor starts sensibly.

      Input pattern: draft-on-edit / commit-on-blur (transient humidityDrafts
      state per row). onChange only updates the draft; onBlur (and Enter)
      parses + clamps to [5, 95] + commits. Empty value on blur clears the
      override and falls back to default. Caught mid-PR via a typing test:
      the naive per-keystroke clamp snapped "3" → 5 before the user could
      type the second digit of "30".

      Setting is in the public _UI_PREFERENCE_FIELDS allowlist (same rationale
      as drying_presets and ams_humidity_fair — non-sensitive integer map,
      no SETTINGS_READ permission required for badge-color rendering).
2026-06-28 12:40:40 +02:00
..