fan-control: presence-aware IPMI fan curve for the R730 PVE host
The iDRAC stock curve runs the CPU at ~72°C on the 7080 RPM floor even under load (optimises for quiet, not cool). Add a bash daemon + systemd unit that drives the chassis fans from CPU temp on two curves, picked by garage occupancy (the server is in the garage): COOL when empty (measured ~58-65°C under load), QUIET near the silent floor when the ha-sofia garage door shows someone is there (open, or <15min since last activity). Manual fan mode is backstopped: bash EXIT trap + systemd ExecStopPost hand fans back to Dell auto on stop/crash; CPU>=83°C or repeated IPMI failures do the same. Pushgateway metrics (job=fan_control). 36 unit tests cover the pure curve/hysteresis/presence/parse logic; DRY_RUN + RUN_ONCE for integration checks. Deployed and verified on 192.168.1.127 (CPU 70->58°C in cool mode, hysteresis stepping confirmed). Design: docs/plans/2026-06-04-pve-fan-control-design.md Runbook: docs/runbooks/fan-control.md [ci skip] Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
c6f27fa172
commit
90ad6b9125
60 changed files with 640 additions and 9563 deletions
|
|
@ -1,75 +0,0 @@
|
|||
"""Demo extractor - returns hardcoded test streams for framework testing.
|
||||
|
||||
This extractor exists purely for testing the extraction pipeline end-to-end.
|
||||
It does NOT connect to any real streaming site. Disable it in production by
|
||||
removing its registration from __init__.py or setting DEMO_EXTRACTOR_ENABLED=false.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
from backend.extractors.base import BaseExtractor
|
||||
from backend.extractors.models import ExtractedStream
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Set DEMO_EXTRACTOR_ENABLED=false to disable this extractor
|
||||
DEMO_ENABLED = os.getenv("DEMO_EXTRACTOR_ENABLED", "true").lower() in ("true", "1", "yes")
|
||||
|
||||
|
||||
class DemoExtractor(BaseExtractor):
|
||||
"""Demo extractor that returns hardcoded test streams.
|
||||
|
||||
Use this to verify the extraction framework works end-to-end without
|
||||
needing a real streaming site. The streams are publicly available HLS
|
||||
test streams from Apple and others.
|
||||
"""
|
||||
|
||||
@property
|
||||
def site_key(self) -> str:
|
||||
return "demo"
|
||||
|
||||
@property
|
||||
def site_name(self) -> str:
|
||||
return "Demo (Test Streams)"
|
||||
|
||||
async def extract(self) -> list[ExtractedStream]:
|
||||
"""Return hardcoded test streams for framework testing."""
|
||||
if not DEMO_ENABLED:
|
||||
logger.info("[demo] Demo extractor is disabled via DEMO_EXTRACTOR_ENABLED")
|
||||
return []
|
||||
|
||||
logger.info("[demo] Returning demo test streams")
|
||||
|
||||
streams = [
|
||||
ExtractedStream(
|
||||
url="https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8",
|
||||
site_key=self.site_key,
|
||||
site_name=self.site_name,
|
||||
quality="720p",
|
||||
title="Big Buck Bunny (Test Stream)",
|
||||
is_live=False,
|
||||
),
|
||||
ExtractedStream(
|
||||
url="https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8",
|
||||
site_key=self.site_key,
|
||||
site_name=self.site_name,
|
||||
quality="1080p",
|
||||
title="Apple Bipbop (Test Stream)",
|
||||
is_live=False,
|
||||
),
|
||||
ExtractedStream(
|
||||
url="https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8",
|
||||
site_key=self.site_key,
|
||||
site_name=self.site_name,
|
||||
quality="1080p",
|
||||
title="Tears of Steel (Test Stream)",
|
||||
is_live=False,
|
||||
),
|
||||
]
|
||||
|
||||
# Optionally run health checks on the demo streams
|
||||
for stream in streams:
|
||||
stream.is_live = await self.health_check(stream.url)
|
||||
|
||||
return streams
|
||||
Loading…
Add table
Add a link
Reference in a new issue