{"id":37227778,"url":"https://github.com/ajimaru/octoprint-tempeta","last_synced_at":"2026-05-20T22:18:09.034Z","repository":{"id":331595648,"uuid":"1131285019","full_name":"Ajimaru/OctoPrint-TempETA","owner":"Ajimaru","description":"„OctoPrint plugin that shows an ETA countdown while bed/hotend/chamber heats up or cools down.","archived":false,"fork":false,"pushed_at":"2026-01-15T06:12:41.000Z","size":2231,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-15T07:58:41.381Z","etag":null,"topics":["bed","chamber","eta","heating","hotend","octoprint","octoprint-plugin","temperature"],"latest_commit_sha":null,"homepage":"https://github.com/Ajimaru/OctoPrint-TempETA/releases","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Ajimaru.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.md","dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-09T18:55:21.000Z","updated_at":"2026-01-14T22:34:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Ajimaru/OctoPrint-TempETA","commit_stats":null,"previous_names":["ajimaru/octoprint-tempeta"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/Ajimaru/OctoPrint-TempETA","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ajimaru%2FOctoPrint-TempETA","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ajimaru%2FOctoPrint-TempETA/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ajimaru%2FOctoPrint-TempETA/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ajimaru%2FOctoPrint-TempETA/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ajimaru","download_url":"https://codeload.github.com/Ajimaru/OctoPrint-TempETA/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ajimaru%2FOctoPrint-TempETA/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28538868,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T14:59:57.589Z","status":"ssl_error","status_checked_at":"2026-01-18T14:59:46.540Z","response_time":98,"last_error":"SSL_read: 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":["bed","chamber","eta","heating","hotend","octoprint","octoprint-plugin","temperature"],"created_at":"2026-01-15T03:23:59.834Z","updated_at":"2026-05-20T22:18:09.025Z","avatar_url":"https://github.com/Ajimaru.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- markdownlint-disable MD041 MD033--\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"octoprint_temp_eta/static/img/temp_eta.svg\" alt=\"Temperature ETA Logo\" width=\"96\" /\u003e\n\u003c/p\u003e\n\u003ch1 align=\"center\"\u003eOctoPrint Temperature ETA Plugin\u003c/h1\u003e\n\u003c!-- markdownlint-enable MD041 MD033--\u003e\n\n[![License](https://img.shields.io/github/license/Ajimaru/OctoPrint-TempETA)](https://github.com/Ajimaru/OctoPrint-TempETA#license)\n[![Python](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://python.org)\n![Top Language](https://img.shields.io/github/languages/top/Ajimaru/OctoPrint-TempETA)\n[![OctoPrint](https://img.shields.io/badge/OctoPrint-1.10.2%2B-blue.svg)](https://octoprint.org)\n[![Latest Release](https://img.shields.io/github/v/release/Ajimaru/OctoPrint-TempETA?sort=semver)](https://github.com/Ajimaru/OctoPrint-TempETA/releases/latest)\n![Downloads](https://img.shields.io/github/downloads/Ajimaru/OctoPrint-TempETA/total.svg)\n![Maintenance](https://img.shields.io/maintenance/yes/2026)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Ajimaru/OctoPrint-TempETA/pulls)\n\n![Stars](https://img.shields.io/github/stars/Ajimaru/OctoPrint-TempETA?style=social)\n![Forks](https://img.shields.io/github/forks/Ajimaru/OctoPrint-TempETA?style=social)\n![Watchers](https://img.shields.io/github/watchers/Ajimaru/OctoPrint-TempETA?style=social)\n\n---\n\n### Heat Up and Cool Down with Confidence\n\n\u003c!-- markdownlint-disable MD033--\u003e\n\u003cstrong\u003e\n  Display real-time countdown/ETA when your 3D printer's bed, hotend, or chamber is heating up or cooling down.\u003cbr /\u003e\n  No more guessing how long until your print starts or is ready for maintenance!\n\u003c/strong\u003e\n\n#### Heating\n\n\u003cimg src=\"assets/img/Temperature_ETA_heating.png\" alt=\"Heating ETA\" width=\"666\" /\u003e\n\n#### Cooling\n\n\u003cimg src=\"assets/img/Temperature_ETA_cooling.png\" alt=\"Cooling ETA\" width=\"666\" /\u003e\n\u003c!-- markdownlint-enable MD033--\u003e\n\n## Table of Contents\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdetails\u003e\n\n- [Table of Contents](#table-of-contents)\n- [Features](#features)\n- [Installation](#installation)\n  - [Via Plugin Manager (Recommended)](#via-plugin-manager-recommended)\n  - [Manual Installation](#manual-installation)\n- [Configuration](#configuration)\n  - [General](#general)\n  - [Heating ETA](#heating-eta)\n  - [Cool-down ETA](#cool-down-eta)\n  - [MQTT](#mqtt)\n  - [Maintenance](#maintenance)\n  - [Help](#help)\n  - [Settings Defaults](#settings-defaults)\n- [How It Works](#how-it-works)\n- [MQTT Message Format](#mqtt-message-format)\n- [FAQ](#faq)\n- [Contributing](#contributing)\n- [License](#license)\n- [Support](#support)\n- [Credits](#credits)\n\n\u003c/details\u003e\n\u003c!-- markdownlint-enable MD033 --\u003e\n\n## Features\n\n- ⏱️ **Real-time ETA countdown** for bed, hotend and chamber heating or cooling\n- 🌡️ **Smart calculation algorithms**: Linear (default) and exponential models\n- 📊 **Flexible display**: Show ETA in navbar, sidebar, and/or a dedicated tab\n- 📈 **Progress bars**: Show progress to target in the sidebar and tab views\n- 📉 **Historical temperature graphs**: A dedicated history view in the tab with a configurable time window\n- ⏳ **Heating ETA**: Estimates time remaining until target temperature is reached\n- 🧊 **Cool-down ETA**: Estimates time remaining until cool-down target is reached (target set to 0), with two modes: threshold-based and ambient-based\n- 🎛️ **Configurable thresholds**: Start countdown when within a configurable delta to target\n- 🎨 **Status colors**: Optional color bands for heating/cooling/idle states\n- 🔔 **Sound alerts**: Play a sound when target is reached or cool-down finishes\n- 🖥️ **Browser toast notifications**: Small top-right notifications for key events (default off)\n- 📡 **MQTT integration**: Publish ETA data and state changes to an MQTT broker for home automation\n- 🔁 **Reset history**: One-click reset deletes persisted history files for all printer profiles\n- 🧰 **Multiple heaters**: Supports tools, bed and chamber (as reported by OctoPrint/printer)\n- 🌍 **Internationalization**: English and German included, easily extensible\n- 🧮 **Supports °C and °F** based on OctoPrint settings\n- ⚙️ **Highly configurable**: Many settings to tailor behavior and display to your needs\n- 🚀 **Lightweight**: Minimal performance impact (~2Hz monitoring)\n\n## Installation\n\n### Via Plugin Manager (Recommended)\n\n1. Open OctoPrint web interface\n2. Navigate to **Settings** → **Plugin Manager**\n3. Click **Get More...**\n4. Click **Install from URL** and enter:\n   `https://github.com/Ajimaru/OctoPrint-TempETA/releases/latest/download/octoprint_tempeta-latest.zip`\n5. Click **Install**\n6. Restart OctoPrint\n\n### Manual Installation\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdetails\u003e\n\u003csummary\u003eManual pip install (advanced users)\u003c/summary\u003e\n\n```bash\npip install https://github.com/Ajimaru/OctoPrint-TempETA/releases/latest/download/octoprint_tempeta-latest.zip\n```\n\nThe `releases/latest` URL always points to the newest stable release.\n\n\u003c/details\u003e\n\u003c!-- markdownlint-enable MD033 --\u003e\n\n## Configuration\n\nConfigure the plugin in **Settings** → **Temperature ETA**:\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\n\u003cimg\n  src=\"assets/img/Temperature_ETA_settings.png\"\n  alt=\"Temperature ETA settings\"\n  width=\"666\"\n/\u003e\n\n\u003c!-- markdownlint-enable MD033 --\u003e\n\nThe settings UI is organized into multiple tabs:\n\n### General\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eGeneral Settings\u003c/strong\u003e (click to expand)\u003c/summary\u003e\n\n- **Enable Temperature ETA**: Master switch for the plugin\n- **Hide ETA while printing**: Optionally suppress ETA during active print jobs\n- **Show in sidebar / navbar / tab**: Independently enable the UI placements\n- **Show progress bars**: Show progress bars in sidebar and tab\n- **Show historical graph** + **Historical graph window (seconds)**: Configure the history graph in the tab\n- **Temperature display**: Use OctoPrint's preference or override it\n- **Status colors**: Configure time-based bands or fixed status colors (heating/cooling/idle)\n- **Update \u0026 Logging**:\n  - **Update interval** + **Temperature history size**: Control refresh rate and retained samples\n  - **Debug logging** (optional): Enables additional log output (may be noisy)\n- **Sound alerts** (optional): Enable per-event sounds, volume, rate limit, and a test button\n- **Browser notifications** (optional): Enable per-event toasts, timeout, and rate limit\n\nNote: Numeric settings inputs are validated (min/max/range) and saving is blocked until invalid values are fixed.\n\n\u003c/details\u003e\n\u003c!-- markdownlint-enable MD033 --\u003e\n\n## How It Works\n\n1. **Temperature Monitoring**: Plugin registers for temperature callbacks (~2Hz frequency)\n2. **Rate Calculation**: Analyzes temperature history to determine heating rate (°C/second)\n3. **ETA Estimation**: Uses selected algorithm (linear/exponential) to predict time to target\n4. **Display Update**: Sends countdown to frontend via WebSocket (1Hz default)\n5. **Smart Thresholds**: Only shows ETA when heating or cooling and within configured threshold\n\n### Heating ETA\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eHeating ETA Settings\u003c/strong\u003e (click to expand)\u003c/summary\u003e\n\n- **Enable heating ETA**: Controls whether heating ETAs are shown/calculated\n- **Heating threshold** + **Threshold unit**: Start ETA when within a configured delta to the target\n- **Calculation algorithm**: Linear (default) or exponential\n\n\u003c/details\u003e\n\u003c!-- markdownlint-enable MD033 --\u003e\n\n### Cool-down ETA\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eCool-down ETA Settings\u003c/strong\u003e (click to expand)\u003c/summary\u003e\n\n- **Enable cool-down ETA**: Turn cool-down ETA on/off\n- **Mode**:\n  - **Threshold target (default)**: Estimate time until a fixed, per-heater target is reached\n  - **Ambient-based target**: Estimate time until near ambient temperature (best-effort)\n- **Cool-down targets**: Configure per-heater targets (tool0/bed/chamber) for threshold mode\n- **Ambient temperature** (optional): Provide a fixed ambient value for ambient mode\n- **Hysteresis / fit window**: Controls when cool-down ETA disappears and how much recent data is used\n\n\u003c/details\u003e\n\u003c!-- markdownlint-enable MD033 --\u003e\n\n### MQTT\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eMQTT Settings\u003c/strong\u003e (click to expand)\u003c/summary\u003e\n\n- **Enable MQTT**: Master switch for MQTT integration (publishes ETA data to external broker)\n- **Broker Host**: MQTT broker hostname or IP address (e.g., `localhost`, `192.168.1.100`)\n- **Broker Port**: MQTT broker port (default: `1883`, TLS typically uses `8883`)\n- **Username/Password**: Optional authentication credentials for the MQTT broker\n- **Use TLS/SSL**: Enable encrypted connection to the broker\n- **Skip TLS certificate verification**: For self-signed certificates (not recommended for production)\n- **Base Topic**: Root MQTT topic for publishing messages (default: `octoprint/temp_eta`)\n  - ETA updates are published to: `{base_topic}/{heater}/eta`\n  - State changes are published to: `{base_topic}/{heater}/state_change`\n- **QoS**: MQTT Quality of Service level (0=At most once, 1=At least once, 2=Exactly once)\n- **Retain Messages**: Enable MQTT retain flag (new subscribers receive the last message)\n- **Publish Interval**: Minimum seconds between MQTT publishes (default: `1.0`)\n\n\u003c/details\u003e\n\u003c!-- markdownlint-enable MD033 --\u003e\n\n### Maintenance\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eMaintenance Actions\u003c/strong\u003e (click to expand)\u003c/summary\u003e\n\n- **Reset profile history**: Deletes all persisted ETA history JSON files for all printer profiles (stored in OctoPrint's plugin data folder)\n- **Restore defaults**: Resets only this plugin's settings back to defaults (does not delete history files)\n\n\u003c/details\u003e\n\u003c!-- markdownlint-enable MD033 --\u003e\n\n### Help\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eHow is ETA calculated?\u003c/strong\u003e (click to expand)\u003c/summary\u003e\n\n**ETA Logic Overview**\nThe plugin estimates how long it will take for each heater (bed, hotend, chamber) to reach its target temperature (heating) or cool down to a set value (cooling). It does this by analyzing recent temperature history and applying a calculation algorithm.\n\n#### Algorithms Used\n\n- **Linear ETA (default):**\n  Calculates the rate of temperature change (°C/s) using the last 10 seconds of data. ETA is the remaining temperature difference divided by this rate.\n  This method is fast and stable for most printers.\n\n- **Exponential ETA (advanced):**\n  Models heating/cooling as an exponential curve, which can be more accurate for some hardware.\n  This option can be enabled in the settings.\n\n#### Key Points\n\n- ETA is only shown when the heater is actively heating/cooling and within a configurable threshold of the target.\n- The plugin automatically handles multiple heaters and adapts to target changes.\n- All calculations are optimized for performance and run in a background thread.\n\n\u003c/details\u003e\n\u003c!-- markdownlint-enable MD033 --\u003e\n\n### Settings Defaults\n\n\u003c!-- markdownlint-disable MD033 MD040 --\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eDefault Plugin Settings\u003c/strong\u003e (click to expand)\u003c/summary\u003e\n\nThe following defaults apply to the user-editable plugin settings:\n\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eSetting\u003c/th\u003e\n\u003cth\u003eKey\u003c/th\u003e\n\u003cth\u003eDefault\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\u003ctd\u003eEnable Temperature ETA\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eenabled\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eEnable heating ETA\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eenable_heating_eta\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eHide ETA while printing\u003c/td\u003e\u003ctd\u003e\u003ccode\u003esuppress_while_printing\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eShow in sidebar\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eshow_in_sidebar\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eShow in navbar\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eshow_in_navbar\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eShow in tab\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eshow_in_tab\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eShow progress bars\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eshow_progress_bars\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eShow historical graph\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eshow_historical_graph\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eGraph window (seconds)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003ehistorical_graph_window_seconds\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e180\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eTemperature display\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etemp_display\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eoctoprint\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eHeating threshold\u003c/td\u003e\u003ctd\u003e\u003ccode\u003ethreshold_start\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e5.0 °C\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eThreshold unit\u003c/td\u003e\u003ctd\u003e\u003ccode\u003ethreshold_unit\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eoctoprint\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eAlgorithm\u003c/td\u003e\u003ctd\u003e\u003ccode\u003ealgorithm\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003elinear\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eUpdate Interval\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eupdate_interval\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e1.0 s\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eHistory Size\u003c/td\u003e\u003ctd\u003e\u003ccode\u003ehistory_size\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e60\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eEnable cool-down ETA\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eenable_cooldown_eta\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eCool-down mode\u003c/td\u003e\u003ctd\u003e\u003ccode\u003ecooldown_mode\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003ethreshold\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eEnable debug logging\u003c/td\u003e\u003ctd\u003e\u003ccode\u003edebug_logging\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eColor mode\u003c/td\u003e\u003ctd\u003e\u003ccode\u003ecolor_mode\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003ebands\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eHeating color\u003c/td\u003e\u003ctd\u003e\u003ccode\u003ecolor_heating\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e#5cb85c\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eCooling color\u003c/td\u003e\u003ctd\u003e\u003ccode\u003ecolor_cooling\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e#337ab7\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eIdle color\u003c/td\u003e\u003ctd\u003e\u003ccode\u003ecolor_idle\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e#777777\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eEnable sound alerts\u003c/td\u003e\u003ctd\u003e\u003ccode\u003esound_enabled\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eSound: target reached\u003c/td\u003e\u003ctd\u003e\u003ccode\u003esound_target_reached\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eSound: cool-down done\u003c/td\u003e\u003ctd\u003e\u003ccode\u003esound_cooldown_finished\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eSound volume\u003c/td\u003e\u003ctd\u003e\u003ccode\u003esound_volume\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e0.5\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eSound min interval\u003c/td\u003e\u003ctd\u003e\u003ccode\u003esound_min_interval_s\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e10.0 s\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eEnable notifications\u003c/td\u003e\u003ctd\u003e\u003ccode\u003enotification_enabled\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eNotify: target reached\u003c/td\u003e\u003ctd\u003e\u003ccode\u003enotification_target_reached\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eNotify: cool-down done\u003c/td\u003e\u003ctd\u003e\u003ccode\u003enotification_cooldown_finished\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eNotification timeout\u003c/td\u003e\u003ctd\u003e\u003ccode\u003enotification_timeout_s\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e6.0 s\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eNotification min interval\u003c/td\u003e\u003ctd\u003e\u003ccode\u003enotification_min_interval_s\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e10.0 s\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eEnable MQTT\u003c/td\u003e\u003ctd\u003e\u003ccode\u003emqtt_enabled\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eMQTT broker host\u003c/td\u003e\u003ctd\u003e\u003ccode\u003emqtt_broker_host\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e\"\"\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eMQTT broker port\u003c/td\u003e\u003ctd\u003e\u003ccode\u003emqtt_broker_port\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e1883\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eMQTT username\u003c/td\u003e\u003ctd\u003e\u003ccode\u003emqtt_username\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e\"\"\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eMQTT password\u003c/td\u003e\u003ctd\u003e\u003ccode\u003emqtt_password\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e\"\"\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eMQTT use TLS\u003c/td\u003e\u003ctd\u003e\u003ccode\u003emqtt_use_tls\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eMQTT TLS insecure\u003c/td\u003e\u003ctd\u003e\u003ccode\u003emqtt_tls_insecure\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eMQTT base topic\u003c/td\u003e\u003ctd\u003e\u003ccode\u003emqtt_base_topic\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eoctoprint/temp_eta\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eMQTT QoS\u003c/td\u003e\u003ctd\u003e\u003ccode\u003emqtt_qos\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e0\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eMQTT retain\u003c/td\u003e\u003ctd\u003e\u003ccode\u003emqtt_retain\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eMQTT publish interval\u003c/td\u003e\u003ctd\u003e\u003ccode\u003emqtt_publish_interval\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003e1.0 s\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003c/details\u003e\n\u003c!-- markdownlint-enable MD033 MD040 --\u003e\n\n## MQTT Message Format\n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eMQTT Message Format Details\u003c/strong\u003e (click to expand)\u003c/summary\u003e\n\n**ETA Updates** (`{base_topic}/{heater}/eta`):\n\n```json\n{\n  \"heater\": \"bed\",\n  \"eta_seconds\": 120.5,\n  \"eta_kind\": \"heating\",\n  \"target\": 60.0,\n  \"actual\": 40.2,\n  \"cooldown_target\": null,\n  \"timestamp\": 1234567890.123,\n  \"state\": \"heating\"\n}\n```\n\n**State Changes** (`{base_topic}/{heater}/state_change`):\n\n```json\n{\n  \"heater\": \"bed\",\n  \"state\": \"at_target\",\n  \"previous_state\": \"heating\",\n  \"timestamp\": 1234567890.456,\n  \"actual\": 60.0,\n  \"target\": 60.0\n}\n```\n\n\u003c/details\u003e\n\u003c!-- markdownlint-enable MD033 --\u003e\n\n## FAQ\n\n**Q: Why does the ETA jump around?**\nA: Temperature changes aren't perfectly linear. The plugin uses recent data to calculate rate. Longer threshold values provide more stable estimates.\n\n**Q: Can I use this with multiple hotends?**\nA: Yes. The UI registers heaters dynamically as OctoPrint reports them (e.g. tool0, tool1, ...).\n\n**Q: Does this work with chamber heaters?**\nA: Yes! Enable chamber in settings if your printer has a chamber heater.\n\n**Q: Will this slow down my prints?**\nA: No. The plugin uses efficient algorithms and runs in a separate thread. Impact is negligible.\n\n**Q: Can I hide the ETA during an active print?**\nA: Yes. If you enable \"Hide ETA while printing\", the plugin will only show ETA when no print job is active. If the option is disabled (default), ETA is shown whenever the target temperature is at least the configured heating threshold above the current temperature.\n\n## Contributing\n\nContributions welcome! Please:\n\n1. Fork the repository\n2. Create a feature branch: `git checkout -b wip/my-feature`\n3. Write tests for new features\n4. Submit a pull request\n5. For local development scripts (setup, restart helper, post-commit build hook, performance monitor), see [.development/README.md](.development/README.md).\n6. See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.\n7. Please follow our [Code of Conduct](CODE_OF_CONDUCT.md).\n\nNote: `main` is protected on GitHub, so changes go through PRs.\n\n[![Open Issues](https://img.shields.io/github/issues/Ajimaru/OctoPrint-TempETA)](https://github.com/Ajimaru/OctoPrint-TempETA/issues?q=is%3Aissue%20state%3Aopen)\n[![Closed Issues](https://img.shields.io/github/issues-closed-raw/Ajimaru/OctoPrint-TempETA)](https://github.com/Ajimaru/OctoPrint-TempETA/issues?q=is%3Aissue%20state%3Aclosed)\n[![Open PRs](https://img.shields.io/github/issues-pr/Ajimaru/OctoPrint-TempETA)](https://github.com/Ajimaru/OctoPrint-TempETA/pulls?q=is%3Aopen+is%3Apr)\n[![Closed PRs](https://img.shields.io/github/issues-pr-closed/Ajimaru/OctoPrint-TempETA)](https://github.com/Ajimaru/OctoPrint-TempETA/pulls?q=is%3Apr+is%3Aclosed)\n\n[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit\u0026logoColor=white)](https://pre-commit.com/)\n![Commit Activity (year)](https://img.shields.io/github/commit-activity/y/Ajimaru/OctoPrint-TempETA)\n![Last Commit](https://img.shields.io/github/last-commit/Ajimaru/OctoPrint-TempETA)\n\n![Build Status](https://img.shields.io/github/actions/workflow/status/Ajimaru/OctoPrint-TempETA/ci.yml)\n[![Coverage](https://codecov.io/gh/Ajimaru/OctoPrint-TempETA/graph/badge.svg?branch=main)](https://codecov.io/gh/Ajimaru/OctoPrint-TempETA)\n[![CI](https://github.com/Ajimaru/OctoPrint-TempETA/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/Ajimaru/OctoPrint-TempETA/actions/workflows/ci.yml?query=branch%3Amain)\n[![i18n](https://github.com/Ajimaru/OctoPrint-TempETA/actions/workflows/i18n.yml/badge.svg?branch=main)](https://github.com/Ajimaru/OctoPrint-TempETA/actions/workflows/i18n.yml?query=branch%3Amain)\n![Release Date](https://img.shields.io/github/release-date/Ajimaru/OctoPrint-TempETA)\n\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![Code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)\n![Languages Count](https://img.shields.io/github/languages/count/Ajimaru/OctoPrint-TempETA)\n\n## License\n\nAGPLv3 - See [LICENSE](LICENSE) for details.\n\n## Support\n\n- 🐛 **Bug Reports**: [GitHub Issues](https://github.com/Ajimaru/OctoPrint-TempETA/issues)\n- 💬 **Discussion**: [Github Discussions](https://github.com/Ajimaru/OctoPrint-TempETA/discussions)\n\nNote: For logs and troubleshooting, enable \"debug logging\" in the plugin settings.\n\n## Credits\n\n- **Original Request**: [Issue #469](https://github.com/OctoPrint/OctoPrint/issues/469) by [@CptanPanic](https://github.com/CptanPanic) (2014)\n- **Development**: Built following [OctoPrint Plugin Guidelines](https://docs.octoprint.org/en/main/plugins/index.html)\n- **Contributors**: See [AUTHORS.md](AUTHORS.md)\n\n---\n\n**Like this plugin?** ⭐ Star the repo and share it with the OctoPrint community!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fajimaru%2Foctoprint-tempeta","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fajimaru%2Foctoprint-tempeta","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fajimaru%2Foctoprint-tempeta/lists"}