diff --git a/README.md b/README.md index a57abc6..8c55497 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # tesla-style-solar-power-card +> **⚠ WARNING: BREAKING CONFIG CHANGE** + +> **You have to define the bubbles/icons AND the FLOWS!!** +> Without defining each flow no line will show, read the usage part carefully + This is a [home-assistant](home-assistant.io) card for solar installations. It provides a tesla style graphic to see the flows of energy ((k)W). ### Table of contents diff --git a/package.json b/package.json index 4437a52..d1f5e0e 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "module": "dist/index.js", "scripts": { "start": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wds\"", - "build": "rimraf dist && tsc && rollup -c rollup.config.js", + "build": "rimraf dist && tsc && rollup -c rollup.config.js && cp tesla-style-solar-power-card.js ../homeassistant/config/www", "prepublish": "tsc", "lint": "eslint --ext .ts,.html . --ignore-path .gitignore && prettier \"**/*.ts\" --check --ignore-path .gitignore", "format": "eslint --ext .ts,.html . --fix --ignore-path .gitignore && prettier \"**/*.ts\" --write --ignore-path .gitignore", diff --git a/src/services/HtmlResizeForPowerCard.ts b/src/services/HtmlResizeForPowerCard.ts index 376d94f..2904f51 100644 --- a/src/services/HtmlResizeForPowerCard.ts +++ b/src/services/HtmlResizeForPowerCard.ts @@ -268,6 +268,23 @@ export class HtmlResizeForPowerCard { ); } }); + const gridElement = ( + teslaCardElement.querySelector('.grid_consumption_entity') + ); + if (gridElement === null) { + changeSelectorStyle('.generation_yield_entity', 'margin', '0px'); + changeSelectorStyle('.battery_consumption_entity', 'margin', '0px'); + changeSelectorStyle('.power_lines', 'width', 30 * pxRate + 'px'); + selectorElement = ( + teslaCardElement.querySelector('.power_lines svg') + ); + if (selectorElement !== null) + selectorElement.setAttribute( + 'viewBox', + 12 * pxRate + ' 0 ' + 42 * pxRate + ' ' + 42 * pxRate + ); + } + changeSelectorStyle('.acc_appliance1', 'top', 10 + 'px'); changeSelectorStyle('.acc_appliance1_line', 'top', 23 * pxRate + 'px'); changeSelectorStyle('.acc_appliance2', 'bottom', 10 + 'px'); diff --git a/tesla-style-solar-power-card.js b/tesla-style-solar-power-card.js index 89d9111..1718545 100644 --- a/tesla-style-solar-power-card.js +++ b/tesla-style-solar-power-card.js @@ -232,7 +232,7 @@ const Z=(t,e)=>"method"===e.kind&&e.descriptor&&!("value"in e.descriptor)?Object id="${t+"_circle"}" > - `}_handleClick(t){const e=new Event("hass-more-info",{bubbles:!0,cancelable:!0,composed:!0});e.detail={entityId:t.entity_id},null!=this.teslaCard.shadowRoot&&this.teslaCard.shadowRoot.dispatchEvent(e)}}class at{static changeStylesDependingOnWidth(t,e,i,s){if("complete"!==document.readyState||s===i)return s;if(null==t.shadowRoot)return s;const n=t.shadowRoot.querySelector("#tesla-style-solar-power-card");if(null==n)return s;const r=i/100,o=function(t,e,i){const s=n.querySelector(t);null!==s&&(s.style[e]=i)};o(".acc_left","top",12*r+"px"),o(".acc_right","top",12*r+"px"),void 0===e.get("battery_consumption_entity")&&void 0!==e.get("appliance2_consumption_entity")&&o(".acc_center_container","margin-bottom",15*r+"px"),n.querySelectorAll(".acc_container").forEach(((t,e,i)=>{const s=i[e];s.style.height=9*r+"px",s.style.width=9*r+"px",s.style.padding=5*r+"px"})),n.querySelectorAll("ha-icon").forEach(((t,e,i)=>{var s;const n=null===(s=i[e].shadowRoot)||void 0===s?void 0:s.querySelector("ha-svg-icon");null!=n&&(n.style.height=9*r+"px",n.style.width=9*r+"px")})),n.querySelectorAll(".acc_text").forEach((t=>{t.style["font-size"]=3*r+"px",t.style["margin-top"]=-.5*r+"px"})),n.querySelectorAll(".acc_text_extra").forEach((t=>{t.style["font-size"]=3*r+"px",t.style.top=1*r+"px",t.style.width=10*r+"px"})),o(".power_lines","height",42*r+"px"),o(".power_lines","width",42*r+"px"),o(".power_lines","top",21*r+"px"),o(".power_lines","left",21*r+"px"),o(".power_lines svg","width",42*r+"px"),o(".power_lines svg","height",42*r+"px"),o(".power_lines svg","viewBox","0 0 "+42*r+" "+42*r);let a=n.querySelector(".power_lines svg");null!==a&&a.setAttribute("viewBox","0 0 "+42*r+" "+42*r);const l=22*r;return o("#generation_to_house_entity_line","d","M"+l+",0 C"+l+","+l+" "+l+","+l+" "+2*l+","+l),o("#grid_feed_in_entity_line","d","M"+l+",0 C"+l+","+l+" "+l+","+l+" 0,"+l),o("#grid_to_house_entity_line","d","M0,"+l+" C"+l+","+l+" "+l+","+l+" "+2*l+","+l),o("#grid_to_battery_entity_line","d","M0,"+l+" C"+l+","+l+" "+l+","+l+" "+l+","+2*l),o("#battery_to_house_entity_line","d","M"+l+","+2*l+" C"+l+","+l+" "+l+","+l+" "+2*l+","+l),o("#generation_to_battery_entity_line","d","M"+l+",0 C"+l+",0 "+l+","+2*l+" "+l+","+2*l),[1,2].forEach((t=>{o(".acc_appliance"+t+"_line svg","viewBox","0 0 "+26*r+" "+26*r),o(".acc_appliance"+t+"_line","right",10*r+"px"),o(".acc_appliance"+t+"_line","width",4*r+"px"),o(".acc_appliance"+t+"_line","height",18*r+"px"),o(".acc_appliance"+t+"_line svg","width",4*r+"px"),o(".acc_appliance"+t+"_line svg","height",18*r+"px"),a=n.querySelector(".acc_appliance"+t+"_line_svg"),null!==a&&a.setAttribute("viewBox","0 0 "+26*r+" "+26*r);null===n.querySelector(".generation_yield_entity")&&1===t&&null!==a&&o(".acc_center_container","margin-top",19*r+"px");null===n.querySelector(".battery_consumption_entity")&&2===t&&null!==a&&o(".acc_center_container","margin-bottom",19*r+"px")})),o(".acc_appliance1","top","10px"),o(".acc_appliance1_line","top",23*r+"px"),o(".acc_appliance2","bottom","10px"),o(".acc_appliance2_line","bottom",15*r+"px"),i}}window.customCards=window.customCards||[],window.customCards.push({type:"tesla-style-solar-power-card",name:"Tesla Style Solar Power Card",description:"A Solar Power Visualization with svg paths that mimmicks the powerwall app of tesla 2"});class lt extends nt{constructor(){super(...arguments),this.solarCardElements=new Map,this.oldWidth=100,this.pxRate=30,this.htmlWriter=new ot(this,this.hass),this.title="Hey there",this.counter=5}__increment(){this.counter+=1}setConfig(t){let e;t.test_gui,this.config={...t},null==this.config.grid_icon&&(this.config.grid_icon="mdi:transmission-tower"),null==this.config.generation_icon&&(this.config.generation_icon="mdi:solar-panel-large"),null==this.config.house_icon&&(this.config.house_icon="mdi:home"),null==this.config.battery_icon&&(this.config.battery_icon="mdi:battery-medium"),null==this.config.appliance1_icon&&(this.config.appliance1_icon="mdi:car-sports"),null==this.config.appliance2_icon&&(this.config.appliance2_icon="mdi:air-filter"),this.createSolarCardElements(),e=this,setInterval(this.animateCircles,15,e),e=this}createSolarCardElements(){Object.keys(this.config).forEach((t=>{if(null!=this.config[t]&&t.indexOf("_entity")>5){const e=this.config[t].toString();this.solarCardElements.set(t,new rt(e,t))}}))}getCardSize(){return 5}static getStubConfig(){return{}}async firstUpdated(){await new Promise((t=>setTimeout(t,0))),this.oldWidth=at.changeStylesDependingOnWidth(this,this.solarCardElements,this.clientWidth,this.oldWidth)}connectedCallback(){super.connectedCallback(),this.redraw=this.redraw.bind(this),window.addEventListener("resize",this.redraw)}shouldUpdate(t){let e;e=this,requestAnimationFrame((t=>{e.updateAllCircles(t)})),e=this;let i=!0;return Array.from(t.keys()).some((e=>{const s=t.get(e);return"hass"===e&&s&&(i=i&&this.sensorChangeDetected(s)),!i})),i}sensorChangeDetected(t){let e=!1;return this.solarCardElements.forEach(((i,s)=>{void 0!==this.hass.states[this.config[s]]&&this.hass.states[this.config[s]].state!==t.states[this.config[s]].state&&(e=!0)})),e}async performUpdate(){this.solarCardElements.forEach((t=>{t.setValueAndUnitOfMeasurement(this.hass.states[t.entity].state,this.config.show_w_not_kw,this.hass.states[t.entity].attributes.unit_of_measurement),t.setSpeed(this.config.show_w_not_kw)})),super.performUpdate()}render(){if(this.config.show_error)return this._showError("common.show_error");this.pxRate=this.clientWidth/100;const t=22*this.pxRate;return I` + `}_handleClick(t){const e=new Event("hass-more-info",{bubbles:!0,cancelable:!0,composed:!0});e.detail={entityId:t.entity_id},null!=this.teslaCard.shadowRoot&&this.teslaCard.shadowRoot.dispatchEvent(e)}}class at{static changeStylesDependingOnWidth(t,e,i,s){if("complete"!==document.readyState||s===i)return s;if(null==t.shadowRoot)return s;const n=t.shadowRoot.querySelector("#tesla-style-solar-power-card");if(null==n)return s;const r=i/100,o=function(t,e,i){const s=n.querySelector(t);null!==s&&(s.style[e]=i)};o(".acc_left","top",12*r+"px"),o(".acc_right","top",12*r+"px"),void 0===e.get("battery_consumption_entity")&&void 0!==e.get("appliance2_consumption_entity")&&o(".acc_center_container","margin-bottom",15*r+"px"),n.querySelectorAll(".acc_container").forEach(((t,e,i)=>{const s=i[e];s.style.height=9*r+"px",s.style.width=9*r+"px",s.style.padding=5*r+"px"})),n.querySelectorAll("ha-icon").forEach(((t,e,i)=>{var s;const n=null===(s=i[e].shadowRoot)||void 0===s?void 0:s.querySelector("ha-svg-icon");null!=n&&(n.style.height=9*r+"px",n.style.width=9*r+"px")})),n.querySelectorAll(".acc_text").forEach((t=>{t.style["font-size"]=3*r+"px",t.style["margin-top"]=-.5*r+"px"})),n.querySelectorAll(".acc_text_extra").forEach((t=>{t.style["font-size"]=3*r+"px",t.style.top=1*r+"px",t.style.width=10*r+"px"})),o(".power_lines","height",42*r+"px"),o(".power_lines","width",42*r+"px"),o(".power_lines","top",21*r+"px"),o(".power_lines","left",21*r+"px"),o(".power_lines svg","width",42*r+"px"),o(".power_lines svg","height",42*r+"px"),o(".power_lines svg","viewBox","0 0 "+42*r+" "+42*r);let a=n.querySelector(".power_lines svg");null!==a&&a.setAttribute("viewBox","0 0 "+42*r+" "+42*r);const l=22*r;o("#generation_to_house_entity_line","d","M"+l+",0 C"+l+","+l+" "+l+","+l+" "+2*l+","+l),o("#grid_feed_in_entity_line","d","M"+l+",0 C"+l+","+l+" "+l+","+l+" 0,"+l),o("#grid_to_house_entity_line","d","M0,"+l+" C"+l+","+l+" "+l+","+l+" "+2*l+","+l),o("#grid_to_battery_entity_line","d","M0,"+l+" C"+l+","+l+" "+l+","+l+" "+l+","+2*l),o("#battery_to_house_entity_line","d","M"+l+","+2*l+" C"+l+","+l+" "+l+","+l+" "+2*l+","+l),o("#generation_to_battery_entity_line","d","M"+l+",0 C"+l+",0 "+l+","+2*l+" "+l+","+2*l),[1,2].forEach((t=>{o(".acc_appliance"+t+"_line svg","viewBox","0 0 "+26*r+" "+26*r),o(".acc_appliance"+t+"_line","right",10*r+"px"),o(".acc_appliance"+t+"_line","width",4*r+"px"),o(".acc_appliance"+t+"_line","height",18*r+"px"),o(".acc_appliance"+t+"_line svg","width",4*r+"px"),o(".acc_appliance"+t+"_line svg","height",18*r+"px"),a=n.querySelector(".acc_appliance"+t+"_line_svg"),null!==a&&a.setAttribute("viewBox","0 0 "+26*r+" "+26*r);null===n.querySelector(".generation_yield_entity")&&1===t&&null!==a&&o(".acc_center_container","margin-top",19*r+"px");null===n.querySelector(".battery_consumption_entity")&&2===t&&null!==a&&o(".acc_center_container","margin-bottom",19*r+"px")}));return null===n.querySelector(".grid_consumption_entity")&&(o(".generation_yield_entity","margin","0px"),o(".battery_consumption_entity","margin","0px"),o(".power_lines","width",30*r+"px"),a=n.querySelector(".power_lines svg"),null!==a&&a.setAttribute("viewBox",12*r+" 0 "+42*r+" "+42*r)),o(".acc_appliance1","top","10px"),o(".acc_appliance1_line","top",23*r+"px"),o(".acc_appliance2","bottom","10px"),o(".acc_appliance2_line","bottom",15*r+"px"),i}}window.customCards=window.customCards||[],window.customCards.push({type:"tesla-style-solar-power-card",name:"Tesla Style Solar Power Card",description:"A Solar Power Visualization with svg paths that mimmicks the powerwall app of tesla 2"});class lt extends nt{constructor(){super(...arguments),this.solarCardElements=new Map,this.oldWidth=100,this.pxRate=30,this.htmlWriter=new ot(this,this.hass),this.title="Hey there",this.counter=5}__increment(){this.counter+=1}setConfig(t){let e;t.test_gui,this.config={...t},null==this.config.grid_icon&&(this.config.grid_icon="mdi:transmission-tower"),null==this.config.generation_icon&&(this.config.generation_icon="mdi:solar-panel-large"),null==this.config.house_icon&&(this.config.house_icon="mdi:home"),null==this.config.battery_icon&&(this.config.battery_icon="mdi:battery-medium"),null==this.config.appliance1_icon&&(this.config.appliance1_icon="mdi:car-sports"),null==this.config.appliance2_icon&&(this.config.appliance2_icon="mdi:air-filter"),this.createSolarCardElements(),e=this,setInterval(this.animateCircles,15,e),e=this}createSolarCardElements(){Object.keys(this.config).forEach((t=>{if(null!=this.config[t]&&t.indexOf("_entity")>5){const e=this.config[t].toString();this.solarCardElements.set(t,new rt(e,t))}}))}getCardSize(){return 5}static getStubConfig(){return{}}async firstUpdated(){await new Promise((t=>setTimeout(t,0))),this.oldWidth=at.changeStylesDependingOnWidth(this,this.solarCardElements,this.clientWidth,this.oldWidth)}connectedCallback(){super.connectedCallback(),this.redraw=this.redraw.bind(this),window.addEventListener("resize",this.redraw)}shouldUpdate(t){let e;e=this,requestAnimationFrame((t=>{e.updateAllCircles(t)})),e=this;let i=!0;return Array.from(t.keys()).some((e=>{const s=t.get(e);return"hass"===e&&s&&(i=i&&this.sensorChangeDetected(s)),!i})),i}sensorChangeDetected(t){let e=!1;return this.solarCardElements.forEach(((i,s)=>{void 0!==this.hass.states[this.config[s]]&&this.hass.states[this.config[s]].state!==t.states[this.config[s]].state&&(e=!0)})),e}async performUpdate(){this.solarCardElements.forEach((t=>{t.setValueAndUnitOfMeasurement(this.hass.states[t.entity].state,this.config.show_w_not_kw,this.hass.states[t.entity].attributes.unit_of_measurement),t.setSpeed(this.config.show_w_not_kw)})),super.performUpdate()}render(){if(this.config.show_error)return this._showError("common.show_error");this.pxRate=this.clientWidth/100;const t=22*this.pxRate;return I`
${this.writeGenerationIconBubble()} @@ -357,7 +357,9 @@ const Z=(t,e)=>"method"===e.kind&&e.descriptor&&!("value"in e.descriptor)?Object .generation_yield_entity{ color: var(--warning-color); } - .house_consumption_entity, + .house_consumption_entity{ + border: 1px solid var(--info-color); + } .appliance1_consumption_entity, .appliance2_consumption_entity { border: 1px solid var(--info-color);