/****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */ function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; /** * @license * Copyright 2019 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ const t$2=globalThis,e$2=t$2.ShadowRoot&&(void 0===t$2.ShadyCSS||t$2.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,s$2=Symbol(),o$4=new WeakMap;let n$3 = class n{constructor(t,e,o){if(this._$cssResult$=true,o!==s$2)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e;}get styleSheet(){let t=this.o;const s=this.t;if(e$2&&void 0===t){const e=void 0!==s&&1===s.length;e&&(t=o$4.get(s)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),e&&o$4.set(s,t));}return t}toString(){return this.cssText}};const r$3=t=>new n$3("string"==typeof t?t:t+"",void 0,s$2),i$3=(t,...e)=>{const o=1===t.length?t[0]:e.reduce((e,s,o)=>e+(t=>{if(true===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(s)+t[o+1],t[0]);return new n$3(o,t,s$2)},S$1=(s,o)=>{if(e$2)s.adoptedStyleSheets=o.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(const e of o){const o=document.createElement("style"),n=t$2.litNonce;void 0!==n&&o.setAttribute("nonce",n),o.textContent=e.cssText,s.appendChild(o);}},c$2=e$2?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const s of t.cssRules)e+=s.cssText;return r$3(e)})(t):t; /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */const{is:i$2,defineProperty:e$1,getOwnPropertyDescriptor:h$1,getOwnPropertyNames:r$2,getOwnPropertySymbols:o$3,getPrototypeOf:n$2}=Object,a$1=globalThis,c$1=a$1.trustedTypes,l$1=c$1?c$1.emptyScript:"",p$1=a$1.reactiveElementPolyfillSupport,d$1=(t,s)=>t,u$1={toAttribute(t,s){switch(s){case Boolean:t=t?l$1:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t);}return t},fromAttribute(t,s){let i=t;switch(s){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t);}catch(t){i=null;}}return i}},f$1=(t,s)=>!i$2(t,s),b$1={attribute:true,type:String,converter:u$1,reflect:false,useDefault:false,hasChanged:f$1};Symbol.metadata??=Symbol("metadata"),a$1.litPropertyMetadata??=new WeakMap;let y$1 = class y extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t);}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,s=b$1){if(s.state&&(s.attribute=false),this._$Ei(),this.prototype.hasOwnProperty(t)&&((s=Object.create(s)).wrapped=true),this.elementProperties.set(t,s),!s.noAccessor){const i=Symbol(),h=this.getPropertyDescriptor(t,i,s);void 0!==h&&e$1(this.prototype,t,h);}}static getPropertyDescriptor(t,s,i){const{get:e,set:r}=h$1(this.prototype,t)??{get(){return this[s]},set(t){this[s]=t;}};return {get:e,set(s){const h=e?.call(this);r?.call(this,s),this.requestUpdate(t,h,i);},configurable:true,enumerable:true}}static getPropertyOptions(t){return this.elementProperties.get(t)??b$1}static _$Ei(){if(this.hasOwnProperty(d$1("elementProperties")))return;const t=n$2(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties);}static finalize(){if(this.hasOwnProperty(d$1("finalized")))return;if(this.finalized=true,this._$Ei(),this.hasOwnProperty(d$1("properties"))){const t=this.properties,s=[...r$2(t),...o$3(t)];for(const i of s)this.createProperty(i,t[i]);}const t=this[Symbol.metadata];if(null!==t){const s=litPropertyMetadata.get(t);if(void 0!==s)for(const[t,i]of s)this.elementProperties.set(t,i);}this._$Eh=new Map;for(const[t,s]of this.elementProperties){const i=this._$Eu(t,s);void 0!==i&&this._$Eh.set(i,t);}this.elementStyles=this.finalizeStyles(this.styles);}static finalizeStyles(s){const i=[];if(Array.isArray(s)){const e=new Set(s.flat(1/0).reverse());for(const s of e)i.unshift(c$2(s));}else void 0!==s&&i.push(c$2(s));return i}static _$Eu(t,s){const i=s.attribute;return false===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=false,this.hasUpdated=false,this._$Em=null,this._$Ev();}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this));}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.();}removeController(t){this._$EO?.delete(t);}_$E_(){const t=new Map,s=this.constructor.elementProperties;for(const i of s.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t);}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return S$1(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(true),this._$EO?.forEach(t=>t.hostConnected?.());}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.());}attributeChangedCallback(t,s,i){this._$AK(t,i);}_$ET(t,s){const i=this.constructor.elementProperties.get(t),e=this.constructor._$Eu(t,i);if(void 0!==e&&true===i.reflect){const h=(void 0!==i.converter?.toAttribute?i.converter:u$1).toAttribute(s,i.type);this._$Em=t,null==h?this.removeAttribute(e):this.setAttribute(e,h),this._$Em=null;}}_$AK(t,s){const i=this.constructor,e=i._$Eh.get(t);if(void 0!==e&&this._$Em!==e){const t=i.getPropertyOptions(e),h="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:u$1;this._$Em=e;const r=h.fromAttribute(s,t.type);this[e]=r??this._$Ej?.get(e)??r,this._$Em=null;}}requestUpdate(t,s,i,e=false,h){if(void 0!==t){const r=this.constructor;if(false===e&&(h=this[t]),i??=r.getPropertyOptions(t),!((i.hasChanged??f$1)(h,s)||i.useDefault&&i.reflect&&h===this._$Ej?.get(t)&&!this.hasAttribute(r._$Eu(t,i))))return;this.C(t,s,i);} false===this.isUpdatePending&&(this._$ES=this._$EP());}C(t,s,{useDefault:i,reflect:e,wrapped:h},r){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,r??s??this[t]),true!==h||void 0!==r)||(this._$AL.has(t)||(this.hasUpdated||i||(s=void 0),this._$AL.set(t,s)),true===e&&this._$Em!==t&&(this._$Eq??=new Set).add(t));}async _$EP(){this.isUpdatePending=true;try{await this._$ES;}catch(t){Promise.reject(t);}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,s]of this._$Ep)this[t]=s;this._$Ep=void 0;}const t=this.constructor.elementProperties;if(t.size>0)for(const[s,i]of t){const{wrapped:t}=i,e=this[s];true!==t||this._$AL.has(s)||void 0===e||this.C(s,void 0,i,e);}}let t=false;const s=this._$AL;try{t=this.shouldUpdate(s),t?(this.willUpdate(s),this._$EO?.forEach(t=>t.hostUpdate?.()),this.update(s)):this._$EM();}catch(s){throw t=false,this._$EM(),s}t&&this._$AE(s);}willUpdate(t){}_$AE(t){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=true,this.firstUpdated(t)),this.updated(t);}_$EM(){this._$AL=new Map,this.isUpdatePending=false;}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return true}update(t){this._$Eq&&=this._$Eq.forEach(t=>this._$ET(t,this[t])),this._$EM();}updated(t){}firstUpdated(t){}};y$1.elementStyles=[],y$1.shadowRootOptions={mode:"open"},y$1[d$1("elementProperties")]=new Map,y$1[d$1("finalized")]=new Map,p$1?.({ReactiveElement:y$1}),(a$1.reactiveElementVersions??=[]).push("2.1.2"); /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ const t$1=globalThis,i$1=t=>t,s$1=t$1.trustedTypes,e=s$1?s$1.createPolicy("lit-html",{createHTML:t=>t}):void 0,h="$lit$",o$2=`lit$${Math.random().toFixed(9).slice(2)}$`,n$1="?"+o$2,r$1=`<${n$1}>`,l=document,c=()=>l.createComment(""),a=t=>null===t||"object"!=typeof t&&"function"!=typeof t,u=Array.isArray,d=t=>u(t)||"function"==typeof t?.[Symbol.iterator],f="[ \t\n\f\r]",v=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,_=/-->/g,m=/>/g,p=RegExp(`>|${f}(?:([^\\s"'>=/]+)(${f}*=${f}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),g=/'/g,$=/"/g,y=/^(?:script|style|textarea|title)$/i,x=t=>(i,...s)=>({_$litType$:t,strings:i,values:s}),b=x(1),E=Symbol.for("lit-noChange"),A=Symbol.for("lit-nothing"),C=new WeakMap,P=l.createTreeWalker(l,129);function V(t,i){if(!u(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==e?e.createHTML(i):i}const N=(t,i)=>{const s=t.length-1,e=[];let n,l=2===i?"":3===i?"":"",c=v;for(let i=0;i"===u[0]?(c=n??v,d=-1):void 0===u[1]?d=-2:(d=c.lastIndex-u[2].length,a=u[1],c=void 0===u[3]?p:'"'===u[3]?$:g):c===$||c===g?c=p:c===_||c===m?c=v:(c=p,n=void 0);const x=c===p&&t[i+1].startsWith("/>")?" ":"";l+=c===v?s+r$1:d>=0?(e.push(a),s.slice(0,d)+h+s.slice(d)+o$2+x):s+o$2+(-2===d?i:x);}return [V(t,l+(t[s]||"")+(2===i?"":3===i?"":"")),e]};class S{constructor({strings:t,_$litType$:i},e){let r;this.parts=[];let l=0,a=0;const u=t.length-1,d=this.parts,[f,v]=N(t,i);if(this.el=S.createElement(f,e),P.currentNode=this.el.content,2===i||3===i){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes);}for(;null!==(r=P.nextNode())&&d.length0){r.textContent=s$1?s$1.emptyScript:"";for(let s=0;s2||""!==s[0]||""!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=A;}_$AI(t,i=this,s,e){const h=this.strings;let o=false;if(void 0===h)t=M(this,t,i,0),o=!a(t)||t!==this._$AH&&t!==E,o&&(this._$AH=t);else {const e=t;let n,r;for(t=h[0],n=0;n{const e=s?.renderBefore??i;let h=e._$litPart$;if(void 0===h){const t=s?.renderBefore??null;e._$litPart$=h=new k(i.insertBefore(c(),t),t,void 0,s??{});}return h._$AI(t),h}; /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */const s=globalThis;class i extends y$1{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0;}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const r=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=D(r,this.renderRoot,this.renderOptions);}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(true);}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(false);}render(){return E}}i._$litElement$=true,i["finalized"]=true,s.litElementHydrateSupport?.({LitElement:i});const o$1=s.litElementPolyfillSupport;o$1?.({LitElement:i});(s.litElementVersions??=[]).push("4.2.2"); /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ const t=t=>(e,o)=>{ void 0!==o?o.addInitializer(()=>{customElements.define(t,e);}):customElements.define(t,e);}; /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */const o={attribute:true,type:String,converter:u$1,reflect:false,hasChanged:f$1},r=(t=o,e,r)=>{const{kind:n,metadata:i}=r;let s=globalThis.litPropertyMetadata.get(i);if(void 0===s&&globalThis.litPropertyMetadata.set(i,s=new Map),"setter"===n&&((t=Object.create(t)).wrapped=true),s.set(r.name,t),"accessor"===n){const{name:o}=r;return {set(r){const n=e.get.call(this);e.set.call(this,r),this.requestUpdate(o,n,t,true,r);},init(e){return void 0!==e&&this.C(o,void 0,t,e),e}}}if("setter"===n){const{name:o}=r;return function(r){const n=this[o];e.call(this,r),this.requestUpdate(o,n,t,true,r);}}throw Error("Unsupported decorator location: "+n)};function n(t){return (e,o)=>"object"==typeof o?r(t,e,o):((t,e,o)=>{const r=e.hasOwnProperty(o);return e.constructor.createProperty(o,t),r?Object.getOwnPropertyDescriptor(e,o):void 0})(t,e,o)} // Climate Entity Feature Enum (matching Home Assistant) const ClimateEntityFeature = { TARGET_TEMPERATURE: 1, TARGET_TEMPERATURE_RANGE: 2, TARGET_HUMIDITY: 4, FAN_MODE: 8, PRESET_MODE: 16, SWING_MODE: 32, AUX_HEAT: 64, TURN_OFF: 128, TURN_ON: 256, SWING_HORIZONTAL_MODE: 512, }; // Helper function to check if a feature is supported function supportsFeature(stateObj, feature) { return (stateObj.attributes.supported_features & feature) !== 0; } let ClimateControlDialog = class ClimateControlDialog extends i { constructor() { super(...arguments); this.stateObj = null; } // Helper to capitalize mode text _capitalize(text) { // Special case for heat_cool if (text === 'heat_cool') { return 'Heat/Cool'; } return text.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' '); } render() { if (!this.stateObj) { return b `
No climate entity data
`; } return b ` ${this._renderModeRow()} ${this._renderNoTemperatureChangeToggle()} ${this._renderTargetTemperature()} ${this._renderTargetTemperatureRange()} ${this._renderTargetHumidity()} ${this._renderFanSwingRow()} ${this._renderAuxHeat()} `; } _renderModeRow() { const hasPresetMode = supportsFeature(this.stateObj, ClimateEntityFeature.PRESET_MODE); if (!hasPresetMode) { return this._renderHvacModes(); } return b `
${this._renderHvacModes()} ${this._renderPresetModes()}
`; } _renderHvacModes() { if (!this.stateObj) return ''; return b `
HVAC Mode
`; } _renderTargetTemperature() { if (!this.stateObj || !supportsFeature(this.stateObj, ClimateEntityFeature.TARGET_TEMPERATURE)) { return ''; } const isNoTempChange = this._isNoTemperatureChangeEnabled(); const temperatureStep = this._getTemperatureStep(); const { min_temp, max_temp, temperature } = this.stateObj.attributes; const range = max_temp - min_temp; const tempPercent = ((temperature - min_temp) / range) * 100; // Use the currently selected HVAC mode to determine styling const currentMode = this.stateObj.state; // Determine class, track fill, and label based on current mode let inputClass = ''; let trackFill = tempPercent; let label = 'Set to'; if (currentMode === 'heat_cool') { inputClass = 'heat-cool'; } else if (currentMode === 'cool') { inputClass = 'cooling'; trackFill = 100 - tempPercent; label = 'Cool to'; } else if (currentMode === 'heat') { inputClass = 'heating'; label = 'Heat to'; } return b `
Target Temperature
${label} ${temperature}°
`; } _renderTargetTemperatureRange() { if (!this.stateObj || !supportsFeature(this.stateObj, ClimateEntityFeature.TARGET_TEMPERATURE_RANGE)) { return ''; } const isNoTempChange = this._isNoTemperatureChangeEnabled(); const temperatureStep = this._getTemperatureStep(); const { min_temp, max_temp, target_temp_low, target_temp_high } = this.stateObj.attributes; const range = max_temp - min_temp; const lowPercent = ((target_temp_low - min_temp) / range) * 100; const highPercent = ((target_temp_high - min_temp) / range) * 100; // Use the currently selected HVAC mode to determine layout const currentMode = this.stateObj.state; // Determine if we need dual range or single based on current mode const heatOnly = currentMode === 'heat'; const coolOnly = currentMode === 'cool'; const isOffOrAuto = currentMode === 'off' || currentMode === 'auto'; // Render heat only (single input with red track) if (heatOnly) { return b `
Target Temperature
Heat to ${target_temp_low}°
`; } // Render cool only (single input with blue track) if (coolOnly) { return b `
Target Temperature
Cool to ${target_temp_high}°
`; } // Render dual range (both heat and cool, heat_cool, auto, or off) return b `
Temperature Range
Heat to ${target_temp_low}°
Cool to ${target_temp_high}°
${!isOffOrAuto ? b `
` : ''}
`; } _renderTargetHumidity() { if (!this.stateObj || !supportsFeature(this.stateObj, ClimateEntityFeature.TARGET_HUMIDITY)) { return ''; } const humidityStep = this._getHumidityStep(); const { min_humidity, max_humidity, target_humidity } = this.stateObj.attributes; const range = max_humidity - min_humidity; const humidityPercent = ((target_humidity - min_humidity) / range) * 100; return b `
Target Humidity
Set to ${target_humidity}%
`; } _renderFanSwingRow() { const hasFanMode = supportsFeature(this.stateObj, ClimateEntityFeature.FAN_MODE); const hasSwingMode = supportsFeature(this.stateObj, ClimateEntityFeature.SWING_MODE); const hasSwingHorizontal = supportsFeature(this.stateObj, ClimateEntityFeature.SWING_HORIZONTAL_MODE); // If none are present, return nothing if (!hasFanMode && !hasSwingMode && !hasSwingHorizontal) { return ''; } // If only one is present, show it full width if (hasFanMode && !hasSwingMode && !hasSwingHorizontal) { return this._renderFanModes(); } if (!hasFanMode && hasSwingMode && !hasSwingHorizontal) { return this._renderSwingModes(); } if (!hasFanMode && !hasSwingMode && hasSwingHorizontal) { return this._renderSwingHorizontalModes(); } // Show all present modes in a row return b `
${hasFanMode ? this._renderFanModes() : ''} ${hasSwingMode ? this._renderSwingModes() : ''} ${hasSwingHorizontal ? this._renderSwingHorizontalModes() : ''}
`; } _renderFanModes() { if (!this.stateObj) return ''; return b `
Fan Mode
`; } _renderPresetModes() { if (!this.stateObj) return ''; return b `
Thermostat Preset
`; } _renderSwingModes() { if (!this.stateObj) return ''; return b `
Swing (Vertical)
`; } _renderSwingHorizontalModes() { if (!this.stateObj) return ''; return b `
Swing (Horizontal)
`; } _renderAuxHeat() { if (!this.stateObj || !supportsFeature(this.stateObj, ClimateEntityFeature.AUX_HEAT)) { return ''; } return b `
Auxiliary Heat
Aux Heat
`; } _isNoTemperatureChangeEnabled() { return Boolean(this.stateObj?.attributes.noChange); } _getTemperatureStep() { const configuredStep = this.stateObj?.attributes.temperature_step; if (typeof configuredStep === 'number' && Number.isFinite(configuredStep) && configuredStep > 0) { return configuredStep; } return 0.5; } _getHumidityStep() { const configuredStep = this.stateObj?.attributes.humidity_step; if (typeof configuredStep === 'number' && Number.isFinite(configuredStep) && configuredStep > 0) { return configuredStep; } return 1; } _normalizeToStep(value, step) { const snapped = step > 0 ? Math.round(value / step) * step : value; const precision = this._getStepPrecision(step); const factor = 10 ** precision; return Math.round((snapped + Number.EPSILON) * factor) / factor; } _getStepPrecision(step) { if (!Number.isFinite(step) || step <= 0) { return 3; } const stepString = step.toString().toLowerCase(); if (stepString.includes('e-')) { const exponent = Number(stepString.split('e-')[1]); return Number.isFinite(exponent) ? exponent : 3; } const decimalPart = stepString.split('.')[1]; return decimalPart ? decimalPart.length : 0; } _renderNoTemperatureChangeToggle() { if (!this.stateObj) return ''; const supportsTemperature = supportsFeature(this.stateObj, ClimateEntityFeature.TARGET_TEMPERATURE) || supportsFeature(this.stateObj, ClimateEntityFeature.TARGET_TEMPERATURE_RANGE); if (!supportsTemperature) { return ''; } return b `
No Temperature Change
`; } // Event handlers that dispatch custom events for parent to handle _handleHvacModeChange(e) { const value = e.target.value; if (this.stateObj) { this.stateObj = { ...this.stateObj, state: value }; } this.dispatchEvent(new CustomEvent('hvac-mode-changed', { detail: { mode: value }, bubbles: true, composed: true })); } _handleTempSlider(e) { const rawValue = parseFloat(e.target.value); const value = this._normalizeToStep(rawValue, this._getTemperatureStep()); // Update stateObj to trigger re-render with new track fill if (this.stateObj) { this.stateObj = { ...this.stateObj, attributes: { ...this.stateObj.attributes, temperature: value } }; } this.dispatchEvent(new CustomEvent('temperature-changed', { detail: { temperature: value }, bubbles: true, composed: true })); } _handleTempSliderChange(e) { const rawValue = parseFloat(e.target.value); const value = this._normalizeToStep(rawValue, this._getTemperatureStep()); this.dispatchEvent(new CustomEvent('temperature-change-committed', { detail: { temperature: value }, bubbles: true, composed: true })); } _handleTempLowSlider(e) { const rawValue = parseFloat(e.target.value); const value = this._normalizeToStep(rawValue, this._getTemperatureStep()); // Update stateObj to trigger re-render with new track fill if (this.stateObj) { this.stateObj = { ...this.stateObj, attributes: { ...this.stateObj.attributes, target_temp_low: value } }; } this.dispatchEvent(new CustomEvent('target-temp-low-changed', { detail: { temperature: value }, bubbles: true, composed: true })); } _handleTempLowSliderChange(e) { const rawValue = parseFloat(e.target.value); const value = this._normalizeToStep(rawValue, this._getTemperatureStep()); this.dispatchEvent(new CustomEvent('target-temp-low-committed', { detail: { temperature: value }, bubbles: true, composed: true })); } _handleTempHighSlider(e) { const rawValue = parseFloat(e.target.value); const value = this._normalizeToStep(rawValue, this._getTemperatureStep()); // Update stateObj to trigger re-render with new track fill if (this.stateObj) { this.stateObj = { ...this.stateObj, attributes: { ...this.stateObj.attributes, target_temp_high: value } }; } this.dispatchEvent(new CustomEvent('target-temp-high-changed', { detail: { temperature: value }, bubbles: true, composed: true })); } _handleTempHighSliderChange(e) { const rawValue = parseFloat(e.target.value); const value = this._normalizeToStep(rawValue, this._getTemperatureStep()); this.dispatchEvent(new CustomEvent('target-temp-high-committed', { detail: { temperature: value }, bubbles: true, composed: true })); } _handleHumiditySlider(e) { const rawValue = parseFloat(e.target.value); const value = this._normalizeToStep(rawValue, this._getHumidityStep()); // Update stateObj to trigger re-render with new track fill if (this.stateObj) { this.stateObj = { ...this.stateObj, attributes: { ...this.stateObj.attributes, target_humidity: value } }; } this.dispatchEvent(new CustomEvent('humidity-changed', { detail: { humidity: value }, bubbles: true, composed: true })); } _handleHumiditySliderChange(e) { const rawValue = parseFloat(e.target.value); const value = this._normalizeToStep(rawValue, this._getHumidityStep()); this.dispatchEvent(new CustomEvent('humidity-committed', { detail: { humidity: value }, bubbles: true, composed: true })); } _handleFanModeChange(e) { const value = e.target.value; this.dispatchEvent(new CustomEvent('fan-mode-changed', { detail: { mode: value }, bubbles: true, composed: true })); } _handlePresetModeChange(e) { const value = e.target.value; this.dispatchEvent(new CustomEvent('preset-mode-changed', { detail: { mode: value }, bubbles: true, composed: true })); } _handleSwingModeChange(e) { const value = e.target.value; this.dispatchEvent(new CustomEvent('swing-mode-changed', { detail: { mode: value }, bubbles: true, composed: true })); } _handleSwingHorizontalModeChange(e) { const value = e.target.value; this.dispatchEvent(new CustomEvent('swing-horizontal-mode-changed', { detail: { mode: value }, bubbles: true, composed: true })); } _handleAuxHeatToggle(e) { const checked = e.target.checked; this.dispatchEvent(new CustomEvent('aux-heat-changed', { detail: { enabled: checked }, bubbles: true, composed: true })); } _handleNoTemperatureChangeToggle(e) { const checked = e.target.checked; if (this.stateObj) { this.stateObj = { ...this.stateObj, attributes: { ...this.stateObj.attributes, noChange: checked } }; } this.dispatchEvent(new CustomEvent('no-temp-change-changed', { detail: { enabled: checked }, bubbles: true, composed: true })); } }; ClimateControlDialog.styles = i$3 ` :host { display: block; background: transparent; border-radius: var(--ha-card-border-radius, 8px); padding: 0; } .dialog-header { font-size: 20px; font-weight: 500; color: var(--primary-text-color, #333); margin-bottom: 20px; display: flex; align-items: center; gap: 12px; } .entity-icon { font-size: 28px; } .section { margin-bottom: 20px; } .section-title { font-size: 14px; font-weight: 600; color: var(--secondary-text-color, #666); margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; } .mode-row { display: flex; gap: 12px; } .mode-row .section { flex: 1; } .mode-select { width: 100%; padding: 10px 12px; border: 1px solid var(--divider-color, #ddd); border-radius: 4px; background: var(--card-background-color, white); font-size: 14px; color: var(--primary-text-color, #333); cursor: pointer; outline: none; transition: border-color 0.2s; } .mode-select:hover { border-color: #999; } .mode-select:focus { border-color: var(--primary-color, #03a9f4); box-shadow: 0 0 0 2px rgba(3, 169, 244, 0.1); } .temp-range-control { position: relative; } .dual-range-container { position: relative; margin: 0 0; padding: 0; } .dual-range-input { position: absolute; width: 100%; left: 0; pointer-events: none; -webkit-appearance: none; background: transparent; margin: 0; height: 20px; } .dual-range-input::-webkit-slider-runnable-track { background: transparent; height: 8px; border-radius: 4px; } .dual-range-input::-webkit-slider-thumb { -webkit-appearance: none; pointer-events: all; width: 20px !important; height: 20px !important; border-radius: 10px; background: linear-gradient(to bottom, white, #f8f8f8); cursor: grab; border: 2px solid var(--primary-color, #03a9f4); box-shadow: 0 2px 8px rgba(0,0,0,0.15), inset 0 1px 0 rgba(255,255,255,0.8); margin-top: -6px !important; transition: transform 0.15s, box-shadow 0.15s; } .dual-range-input::-webkit-slider-thumb:hover { transform: scale(1.1); box-shadow: 0 4px 12px rgba(0,0,0,0.2), inset 0 1px 0 rgba(255,255,255,0.8); } .dual-range-input::-moz-range-track { background: transparent; height: 8px; border-radius: 4px; } .dual-range-input::-moz-range-thumb { pointer-events: all; border: none; width: 20px !important; height: 20px !important; border-radius: 10px; background: linear-gradient(to bottom, white, #f8f8f8); cursor: grab; border: 2px solid var(--primary-color, #03a9f4); box-shadow: 0 2px 8px rgba(0,0,0,0.15), inset 0 1px 0 rgba(255,255,255,0.8); margin-top: -6px !important; transition: transform 0.15s, box-shadow 0.15s; } .dual-range-input::-moz-range-thumb:hover { transform: scale(1.1); box-shadow: 0 4px 12px rgba(0,0,0,0.2), inset 0 1px 0 rgba(255,255,255,0.8); } .dual-range-input:focus::-webkit-slider-thumb { box-shadow: 0 0 0 4px rgba(3, 169, 244, 0.2), 0 2px 8px rgba(0,0,0,0.15), inset 0 1px 0 rgba(255,255,255,0.8); } .dual-range-input:focus::-moz-range-thumb { box-shadow: 0 0 0 4px rgba(3, 169, 244, 0.2), 0 2px 8px rgba(0,0,0,0.15), inset 0 1px 0 rgba(255,255,255,0.8); } /* Heating input - red from left to thumb */ .dual-range-input.heating::-webkit-slider-runnable-track { background: linear-gradient(to right, #f44336 0%, #f44336 var(--track-fill, 50%), transparent var(--track-fill, 50%)); height: 8px; border-radius: 4px; position: relative; z-index: 5; } .dual-range-input.heating::-moz-range-track { background: transparent; height: 8px; border-radius: 4px; } .dual-range-input.heating::-moz-range-progress { background: #f44336; height: 8px; border-radius: 4px 0 0 4px; } /* Cooling input - blue from right to thumb */ .dual-range-input.cooling::-webkit-slider-runnable-track { background: linear-gradient(to left, #2196f3 0%, #2196f3 var(--track-fill, 50%), transparent var(--track-fill, 50%)); height: 8px; border-radius: 4px; position: relative; z-index: 5; } .dual-range-input.cooling::-moz-range-track { background: transparent; height: 8px; border-radius: 4px; } .dual-range-input.cooling::-moz-range-progress { background: #2196f3; height: 8px; border-radius: 0 4px 4px 0; transform: scaleX(-1); transform-origin: center; } /* Heat/Cool input - orange full track */ .dual-range-input.heat-cool::-webkit-slider-runnable-track { background: #ff9800; height: 8px; border-radius: 4px; position: relative; z-index: 5; } .dual-range-input.heat-cool::-moz-range-track { background: #ff9800; height: 8px; border-radius: 4px; } .temp-range-labels { display: flex; justify-content: space-between; margin-top: 12px; padding: 0 10px; } .temp-range-value { display: flex; flex-direction: column; align-items: center; } .temp-range-label { font-size: 11px; color: var(--secondary-text-color, #666); margin-bottom: 4px; text-transform: uppercase; letter-spacing: 0.5px; } .temp-range-number { font-size: 24px; font-weight: 600; color: var(--primary-text-color, #333); } .dual-range-fill { position: absolute; height: 8px; background: linear-gradient(90deg, rgba(244, 67, 54, 0.3), rgba(33, 150, 243, 0.3)); border-radius: 4px; top: 50%; transform: translateY(-50%); pointer-events: none; z-index: 1; } .toggle-row { display: flex; align-items: center; justify-content: space-between; padding: 12px 0; } .toggle-label { font-size: 14px; color: var(--primary-text-color, #333); } .toggle-switch { position: relative; display: inline-block; width: 48px; height: 26px; } .toggle-switch input { opacity: 0; width: 0; height: 0; } .toggle-slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; transition: .4s; border-radius: 26px; } .toggle-slider:before { position: absolute; content: ""; height: 18px; width: 18px; left: 4px; bottom: 4px; background-color: white; transition: .4s; border-radius: 50%; } input:checked + .toggle-slider { background-color: var(--primary-color, #03a9f4); } input:checked + .toggle-slider:before { transform: translateX(22px); } `; __decorate([ n({ type: Object }) ], ClimateControlDialog.prototype, "stateObj", void 0); ClimateControlDialog = __decorate([ t('climate-control-dialog') ], ClimateControlDialog); export { ClimateControlDialog, ClimateEntityFeature, supportsFeature }; //# sourceMappingURL=climate-dialog.js.map