{"id":36990071,"url":"https://github.com/chiptoma/shelly-fridge-controller","last_synced_at":"2026-01-13T23:33:36.677Z","repository":{"id":328506281,"uuid":"1101224172","full_name":"chiptoma/shelly-fridge-controller","owner":"chiptoma","description":"Adaptive thermostat controller for Shelly Plus 1PM – compressor protection, fault detection, MQTT reporting","archived":false,"fork":false,"pushed_at":"2026-01-08T22:59:26.000Z","size":1941,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-13T19:44:53.102Z","etag":null,"topics":["embedded","iot","refrigeration","shelly","smart-home","thermostat"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chiptoma.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-21T11:20:08.000Z","updated_at":"2025-12-18T22:41:23.000Z","dependencies_parsed_at":"2025-12-15T09:04:11.174Z","dependency_job_id":null,"html_url":"https://github.com/chiptoma/shelly-fridge-controller","commit_stats":null,"previous_names":["chiptoma/shelly-fridge-controller"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/chiptoma/shelly-fridge-controller","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chiptoma%2Fshelly-fridge-controller","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chiptoma%2Fshelly-fridge-controller/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chiptoma%2Fshelly-fridge-controller/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chiptoma%2Fshelly-fridge-controller/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chiptoma","download_url":"https://codeload.github.com/chiptoma/shelly-fridge-controller/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chiptoma%2Fshelly-fridge-controller/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28405302,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-13T21:51:37.118Z","status":"ssl_error","status_checked_at":"2026-01-13T21:45:14.585Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["embedded","iot","refrigeration","shelly","smart-home","thermostat"],"created_at":"2026-01-13T23:33:36.033Z","updated_at":"2026-01-13T23:33:36.671Z","avatar_url":"https://github.com/chiptoma.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Shelly Fridge Controller\n\n[![CI](https://github.com/chiptoma/shelly-fridge-controller/actions/workflows/ci.yml/badge.svg)](https://github.com/chiptoma/shelly-fridge-controller/actions/workflows/ci.yml)\n[![Security](https://github.com/chiptoma/shelly-fridge-controller/actions/workflows/security.yml/badge.svg)](https://github.com/chiptoma/shelly-fridge-controller/actions/workflows/security.yml)\n[![Coverage](https://img.shields.io/badge/coverage-98%25-brightgreen)](https://github.com/chiptoma/shelly-fridge-controller)\n[![License](https://img.shields.io/badge/license-PolyForm%20Noncommercial-blue)](LICENSE)\n[![Version](https://img.shields.io/github/v/release/chiptoma/shelly-fridge-controller)](https://github.com/chiptoma/shelly-fridge-controller/releases/latest)\n\n**Stop defrosting your fridge manually. Get precise temperature control.**\n\nA smart controller that monitors your evaporator coil, triggers defrost automatically, and replaces your 1-5 dial with actual °C control.\n\n![Console debug demo](docs/assets/console.gif)\n\n---\n\n## The Problem\n\nEvery fridge has this cycle:\n\n```\nCompressor runs → Evaporator gets cold → Moisture freezes on coil → Ice builds up\n                                                                          ↓\nAirflow blocked ← Ice layer thickens ← More moisture freezes ← Coil stays cold\n       ↓\nCompressor runs forever trying to cool air that can't circulate\n```\n\n**The thermostat can't see this happening.** It only measures air temperature - by the time the air warms up, you've got an ice block.\n\nMy drinks fridge needed manual defrost every 10 days. I'd have to turn it off and wait for the ice to melt. Plus, the 1-5 rotary thermostat gave me no real control over the actual temperature.\n\n---\n\n## The Solution\n\n**Put a sensor on the evaporator coil.** Now you can see ice forming.\n\n```\nNormal operation:    Evaporator at -8°C to -12°C ✓\nIce forming:         Evaporator drops below -16°C ⚠️\n                              ↓\n               Controller stops cooling\n                              ↓\n               Evaporator warms to -5°C\n                              ↓\n               Hold for 5 minutes (ice melts)\n                              ↓\n               Resume normal cooling ✓\n```\n\nNo more ice blocks. No more manual defrost. The controller catches it early, every time.\n\n---\n\n## Features\n\n### Smart Defrost\n\nTwo systems ensure ice never builds up:\n\n| System | Trigger | Action |\n|--------|---------|--------|\n| **Dynamic** | Evaporator hits -16°C | Stop cooling → warm to -5°C → hold 5 min |\n| **Scheduled** | Daily at 1 AM | Backup defrost window (up to 1 hour) |\n\nDynamic defrost is the workhorse - it catches ice as it forms. Scheduled defrost is the safety net.\n\n### Precise Temperature Control\n\nReplace your vague 1-5 dial with actual degrees:\n\n- **Set exact target**: 4.0°C, 3.5°C, whatever you want\n- **Smoothed readings**: EMA filter eliminates noise and door-open spikes\n- **Adaptive hysteresis**: Auto-adjusts to achieve 10-20 min cycles (optimal for compressor)\n\n### Compressor Protection\n\nEvery decision passes through safety checks:\n\n| Guard | Purpose |\n|-------|---------|\n| **Min Run** (3 min) | Prevents incomplete cooling cycles |\n| **Min Off** (5 min) | Lets refrigerant pressures equalize |\n| **Max Run** (2 hr) | Forces stop if something's wrong |\n| **Freeze Cut** (0.5°C) | Emergency stop if air too cold |\n\n### Fault Detection\n\n| Fault | Detection | Response |\n|-------|-----------|----------|\n| **Relay Weld** | Temp drops while \"off\" | FATAL alarm |\n| **Locked Rotor** | Power \u003e 400W | FATAL alarm |\n| **Ghost Run** | Power \u003c 10W while \"on\" | Warning → FATAL |\n| **Sensor Fail** | Null readings | Enters Limp Mode |\n\n### Limp Mode (Never Gives Up)\n\nWhen sensors fail, the controller keeps your food cold anyway:\n\n```\nBlind cycling: 30 min ON → 15 min OFF → repeat (66% duty)\n```\n\nAuto-recovers when sensors come back.\n\n---\n\n## Quick Start\n\n```bash\ngit clone https://github.com/chiptoma/shelly-fridge-controller.git\ncd shelly-fridge-controller\nnpm install\n\ncp .env.example .env\n# Edit .env: SHELLY_IP=192.168.1.xxx\n\nnpm run deploy:monitor\n```\n\n---\n\n## Hardware\n\n| Component | Purpose |\n|-----------|---------|\n| **Shelly Plus 1 or 1PM** | Controller with power monitoring |\n| **Shelly Plus Add-On** | Connects temperature sensors |\n| **DS18B20 (x2)** | Air sensor + evaporator sensor |\n\n### Sensor Placement\n\n| Sensor | Location | Why |\n|--------|----------|-----|\n| **Air** (ID: 101) | Middle of fridge, away from walls | Measures actual food temperature |\n| **Evaporator** (ID: 100) | Clamped to evaporator coil | **Detects ice formation** - this is the critical one |\n\n### Wiring\n\n```\nMains                    Shelly Plus 1PM                   Compressor\n─────                    ───────────────                   ──────────\n\n                      ┌─────────────────┐\nL (Live) ─────────────┤ L           O ├─────────────────► L (Live)\n                      │                 │\nN (Neutral) ──────────┤ N    [Add-On]  │\n      │               │     100: Evap  │◄── DS18B20 on evaporator coil\n      │               │     101: Air   │◄── DS18B20 in fridge air\n      │               └─────────────────┘\n      │\n      └────────────────────────────────────────────────► N (Neutral)\n```\n\n---\n\n## MQTT\n\n\u003e **Security Note:** MQTT communication has no authentication by design. This is standard for local IoT deployments where the MQTT broker is on a trusted home network. For internet-exposed setups, configure TLS and authentication on your MQTT broker.\n\n### Status (every 5s to `fridge/status`)\n\n```json\n{\n  \"tAirRaw\": 4.3,\n  \"tAirSmt\": 4.2,\n  \"tEvap\": -8.5,\n  \"tDev\": 32.1,\n  \"status\": \"COOLING\",\n  \"reason\": \"TEMP\",\n  \"alarm\": \"NONE\",\n  \"relayOn\": 1,\n  \"dutyHr\": 45.2,\n  \"dutyDay\": 42.8,\n  \"dutyLife\": 41.5,\n  \"hoursLife\": 1247,\n  \"hyst\": 1.2,\n  \"avgOnSec\": 720,\n  \"avgOffSec\": 480,\n  \"defrostOn\": 0,\n  \"doorOpen\": 0,\n  \"turboOn\": 0,\n  \"health\": 0.25,\n  \"watts\": 85\n}\n```\n\n| Field | Description |\n|-------|-------------|\n| `tAirRaw` | Raw air temperature (°C) |\n| `tAirSmt` | Smoothed air temperature (°C) |\n| `tEvap` | Evaporator temperature (°C) |\n| `tDev` | Shelly device temperature (°C) |\n| `status` | Current state (IDLE, COOLING, DEFROST, LIMP, etc.) |\n| `reason` | Why in this state (TEMP, TIMER, PROTECT, etc.) |\n| `alarm` | Active alarm (NONE, TEMP, SENSOR, WELD, etc.) |\n| `relayOn` | Compressor running (0/1) |\n| `dutyHr` | Duty cycle this hour (%) |\n| `dutyDay` | Average duty cycle 24h (%) |\n| `dutyLife` | Lifetime duty cycle (%) |\n| `hoursLife` | Total compressor run hours |\n| `hyst` | Current hysteresis band (°C) |\n| `avgOnSec` | Average ON cycle length (seconds) |\n| `avgOffSec` | Average OFF cycle length (seconds) |\n| `defrostOn` | Defrost active (0/1) |\n| `doorOpen` | Door open detected (0/1) |\n| `turboOn` | Turbo mode active (0/1) |\n| `health` | Cooling efficiency (°C/min) |\n| `watts` | Current power draw (W, null if no PM) |\n\n### Commands (`fridge/command`)\n\n```json\n{\"cmd\": \"setpoint\", \"value\": 3.5}\n{\"cmd\": \"turbo_on\"}\n{\"cmd\": \"turbo_off\"}\n{\"cmd\": \"reset_alarms\"}\n```\n\n### Home Assistant\n\n```yaml\nsensor:\n  - platform: mqtt\n    name: \"Fridge Temperature\"\n    state_topic: \"fridge/status\"\n    value_template: \"{{ value_json.tAirSmt }}\"\n    unit_of_measurement: \"°C\"\n\n  - platform: mqtt\n    name: \"Evaporator Temperature\"\n    state_topic: \"fridge/status\"\n    value_template: \"{{ value_json.tEvap }}\"\n    unit_of_measurement: \"°C\"\n\nbinary_sensor:\n  - platform: mqtt\n    name: \"Fridge Defrost Active\"\n    state_topic: \"fridge/status\"\n    value_template: \"{{ value_json.defrostOn }}\"\n    payload_on: 1\n    payload_off: 0\n```\n\n---\n\n## Configuration\n\n| Setting | Default | Description |\n|---------|---------|-------------|\n| `ctl_targetDeg` | 4.0°C | Target temperature |\n| `defr_dynTrigDeg` | -16°C | Evap temp that triggers defrost |\n| `defr_dynEndDeg` | -5°C | Evap temp that ends defrost |\n| `defr_schedHour` | 1 | Hour for scheduled defrost (1 AM) |\n\n**50+ settings available** - See [CONFIGURATION.md](docs/CONFIGURATION.md)\n\n---\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `npm run deploy` | Build and deploy |\n| `npm run deploy:monitor` | Deploy + live logs |\n| `npm run shelly:status` | Device status |\n| `npm run shelly:monitor` | Live debug output |\n| `npm test` | Run tests |\n\n---\n\n## Documentation\n\n| Doc | Description |\n|-----|-------------|\n| **[ALGORITHM.md](docs/ALGORITHM.md)** | Control loop, defrost logic, state machines |\n| **[CONFIGURATION.md](docs/CONFIGURATION.md)** | All 50+ settings |\n| **[DEPLOYMENT.md](docs/DEPLOYMENT.md)** | Build and deploy tools |\n| **[TESTING.md](docs/TESTING.md)** | 866 tests |\n\n---\n\n## Specs\n\n| | |\n|---|---|\n| **Runtime** | Shelly mJS (ES5) |\n| **Memory** | ~25KB heap |\n| **Bundle** | \u003c32KB |\n| **Tests** | 866 |\n\n---\n\n## License\n\n**PolyForm Noncommercial 1.0.0** - Free for personal use.\n\nSee [LICENSE](LICENSE) for full terms.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchiptoma%2Fshelly-fridge-controller","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchiptoma%2Fshelly-fridge-controller","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchiptoma%2Fshelly-fridge-controller/lists"}