Skip to content

Commit 6686393

Browse files
authored
Bump version from 1.1.5 to 1.1.6
## v1.1.6 ### Synchronized Flow Animation - Flow dots now animate **in sequence**: energy arrives at the inverter first, then exits to home or battery - Outgoing flows (inverter → home, inverter → battery charging) have a calculated delay based on the fastest incoming flow speed - Creates a realistic "energy flowing through the inverter" visual effect ### Inverter Lightning Bolt - Bolt glow now **only activates when receiving solar energy** - When solar is off, the bolt reverts to a dim neutral appearance - Glow uses solar yellow color with soft blur filter ### Weather Widget - Widened the border box to prevent humidity text from being clipped
1 parent e928c8b commit 6686393

1 file changed

Lines changed: 17 additions & 5 deletions

File tree

‎xpower-flow-card.js‎

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// xPower Flow Card — Modern power flow card for solar hybrid inverters
22
// Copyright (C) 2025 BTNBx
33
// Licensed under GPL-3.0 — see LICENSE file
4-
const V='1.1.5';
4+
const V='1.1.6';
55

66
/* ═══════════════════════════════════════
77
xPower Flow Card — i18n
@@ -491,7 +491,7 @@ svg{width:100%;height:auto;display:block}
491491
</style>
492492
<ha-card><svg viewBox="0 0 526 520"><defs><filter id="glow" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur in="SourceGraphic" stdDeviation="2.5" result="blur"/><feMerge><feMergeNode in="blur"/><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge></filter></defs><g transform="translate(25.5,10) scale(0.95)">
493493
<g id="wicons" style="display:none" transform="translate(-20,0)">
494-
<rect class="wb" x="-2" y="-4" width="72" height="20"/>
494+
<rect class="wb" x="-2" y="-4" width="82" height="20"/>
495495
<g transform="translate(0,1)"><rect x="6" y="0" width="2.5" height="7" rx="1.2" fill="none" stroke="var(--t3)" stroke-width="0.7"/><circle cx="7.2" cy="9" r="2.5" fill="none" stroke="var(--t3)" stroke-width="0.7"/><line x1="7.2" y1="3" x2="7.2" y2="7" stroke="var(--red)" stroke-width="1" stroke-linecap="round"/><circle cx="7.2" cy="9" r="1.2" fill="var(--red)"/></g>
496496
<text x="14" y="8" class="wt" id="wt"></text>
497497
<line id="wdiv" x1="42" y1="2" x2="42" y2="12" stroke="var(--t3)" stroke-width="0.5" opacity="0.4" style="display:none"/>
@@ -501,7 +501,7 @@ svg{width:100%;height:auto;display:block}
501501
<path class="fl" d="M250,96 L250,178"/><path class="fl" d="M250,272 L250,364"/><path class="fl" d="M90,225 L215,225"/><path class="fl" d="M285,225 L395,225"/>
502502
<path id="fs" class="fa" d="M250,96 L250,178" pathLength="100" opacity="0"/><path id="fb" class="fa" d="M250,272 L250,364" pathLength="100" opacity="0"/><path id="fg" class="fa" d="M90,225 L215,225" pathLength="100" opacity="0"/><path id="fh" class="fa" d="M285,225 L395,225" pathLength="100" opacity="0"/>
503503
<g><g transform="translate(250,38) scale(1.65) translate(-250,-38)"><circle cx="250" cy="38" r="9" fill="var(--solar)" opacity="0.85"/><line x1="250" y1="25" x2="250" y2="21" stroke="var(--solar)" stroke-width="2" stroke-linecap="round" opacity="0.6"/><line x1="250" y1="51" x2="250" y2="55" stroke="var(--solar)" stroke-width="2" stroke-linecap="round" opacity="0.6"/><line x1="237" y1="38" x2="233" y2="38" stroke="var(--solar)" stroke-width="2" stroke-linecap="round" opacity="0.6"/><line x1="263" y1="38" x2="267" y2="38" stroke="var(--solar)" stroke-width="2" stroke-linecap="round" opacity="0.6"/><line x1="240.8" y1="28.8" x2="238" y2="26" stroke="var(--solar)" stroke-width="2" stroke-linecap="round" opacity="0.5"/><line x1="259.2" y1="47.2" x2="262" y2="50" stroke="var(--solar)" stroke-width="2" stroke-linecap="round" opacity="0.5"/><line x1="259.2" y1="28.8" x2="262" y2="26" stroke="var(--solar)" stroke-width="2" stroke-linecap="round" opacity="0.5"/><line x1="240.8" y1="47.2" x2="238" y2="50" stroke="var(--solar)" stroke-width="2" stroke-linecap="round" opacity="0.5"/></g><text x="250" y="82" class="vm" style="fill:var(--green)" id="vs"></text><text x="250" y="-2" class="vl">${L.solar}</text><text x="310" y="30" class="vc" id="ds" text-anchor="start"></text><text x="320" y="44" class="vc" id="pv" text-anchor="start"></text></g>
504-
<g><g transform="translate(250,225) scale(1.65)"><rect x="-18" y="-24" width="36" height="48" rx="2" fill="rgba(255,255,255,0.08)" stroke="rgba(255,255,255,0.25)" stroke-width="1"/><rect x="-18" y="-24" width="36" height="5" rx="2" fill="rgba(255,255,255,0.12)"/><rect x="-12" y="-15" width="24" height="12" rx="1.5" fill="rgba(255,255,255,0.05)" stroke="rgba(255,255,255,0.2)" stroke-width="0.7"/><rect x="-8" y="-12" width="16" height="6" rx="1" fill="rgba(102,187,106,0.4)"/><circle id="led1" cx="-6" cy="2" r="1.2" fill="rgba(255,255,255,0.12)"/><circle id="led2" cx="-2" cy="2" r="1.2" fill="rgba(255,255,255,0.12)"/><circle id="led3" cx="2" cy="2" r="1.2" fill="rgba(255,255,255,0.12)"/><circle id="led4" cx="6" cy="2" r="1.2" fill="rgba(255,255,255,0.12)"/><path d="M-6,9 L-8,15 L-4,15 L-6,21" fill="var(--solar)" stroke="var(--solar)" stroke-width="0.8" opacity="0.9" filter="url(#glow)"/><rect x="2" y="12" width="10" height="3" rx="0.5" fill="rgba(255,255,255,0.1)"/><rect x="2" y="17" width="10" height="3" rx="0.5" fill="rgba(255,255,255,0.1)"/></g>${INV?'<text x="250" y="272" class="il">'+INV+'</text>':''}<text x="296" y="264" class="vc" id="tp" text-anchor="start"></text></g>
504+
<g><g transform="translate(250,225) scale(1.65)"><rect x="-18" y="-24" width="36" height="48" rx="2" fill="rgba(255,255,255,0.08)" stroke="rgba(255,255,255,0.25)" stroke-width="1"/><rect x="-18" y="-24" width="36" height="5" rx="2" fill="rgba(255,255,255,0.12)"/><rect x="-12" y="-15" width="24" height="12" rx="1.5" fill="rgba(255,255,255,0.05)" stroke="rgba(255,255,255,0.2)" stroke-width="0.7"/><rect x="-8" y="-12" width="16" height="6" rx="1" fill="rgba(102,187,106,0.4)"/><circle id="led1" cx="-6" cy="2" r="1.2" fill="rgba(255,255,255,0.12)"/><circle id="led2" cx="-2" cy="2" r="1.2" fill="rgba(255,255,255,0.12)"/><circle id="led3" cx="2" cy="2" r="1.2" fill="rgba(255,255,255,0.12)"/><circle id="led4" cx="6" cy="2" r="1.2" fill="rgba(255,255,255,0.12)"/><path id="bolt" d="M-6,9 L-8,15 L-4,15 L-6,21" fill="rgba(255,255,255,0.15)" stroke="rgba(255,255,255,0.3)" stroke-width="0.5"/><rect x="2" y="12" width="10" height="3" rx="0.5" fill="rgba(255,255,255,0.1)"/><rect x="2" y="17" width="10" height="3" rx="0.5" fill="rgba(255,255,255,0.1)"/></g>${INV?'<text x="250" y="272" class="il">'+INV+'</text>':''}<text x="296" y="264" class="vc" id="tp" text-anchor="start"></text></g>
505505
<g><g transform="translate(66,225) scale(1.65) translate(-66,-196)"><rect x="64" y="181" width="4" height="30" rx="1" fill="var(--red)" opacity="0.7"/><rect x="54" y="183" width="24" height="3" rx="1" fill="var(--red)" opacity="0.6"/><rect x="57" y="192" width="18" height="2.5" rx="1" fill="var(--red)" opacity="0.5"/><path d="M60,211 L64,199 L68,199 L72,211" fill="var(--red)" opacity="0.4"/><circle cx="56" cy="184" r="1.5" fill="var(--red)" opacity="0.8"/><circle cx="76" cy="184" r="1.5" fill="var(--red)" opacity="0.8"/><circle cx="58" cy="193" r="1.2" fill="var(--red)" opacity="0.7"/><circle cx="74" cy="193" r="1.2" fill="var(--red)" opacity="0.7"/><line x1="54" y1="184" x2="46" y2="181" stroke="var(--red)" stroke-width="0.8" opacity="0.3"/><line x1="78" y1="184" x2="86" y2="181" stroke="var(--red)" stroke-width="0.8" opacity="0.3"/></g><text x="66" y="268" class="vm" style="fill:var(--red)" id="vg"></text><text x="66" y="190" class="vl">${L.grid}</text><text x="66" y="286" class="vc" id="gv"></text><text x="66" y="300" class="vd" id="dg"></text></g>
506506
<g><g transform="translate(434,225) scale(1.65) translate(-434,-188)"><path d="M416,188 L434,174 L452,188 Z" fill="var(--load)" opacity="0.8"/><rect x="420" y="187" width="28" height="18" rx="1" fill="var(--load)" opacity="0.6"/><rect x="430" y="195" width="8" height="10" rx="1" fill="rgba(0,0,0,0.3)"/><rect x="422" y="190" width="6" height="5" rx="0.5" fill="rgba(255,255,255,0.15)"/><rect x="440" y="190" width="6" height="5" rx="0.5" fill="rgba(255,255,255,0.15)"/><rect x="441" y="176" width="5" height="8" rx="1" fill="var(--load)" opacity="0.5"/></g><text x="434" y="268" class="vm" style="fill:var(--load)" id="vl"></text><text x="434" y="190" class="vl">${L.load}</text><text x="434" y="288" class="vd" id="dl"></text></g>
507507
<g><g transform="translate(250,400) scale(1.70) translate(-250,-351)"><rect x="232" y="341" width="32" height="20" rx="3" fill="var(--battery)" opacity="0.75"/><rect x="264" y="345.5" width="6" height="11" rx="2" fill="var(--battery)" opacity="0.9"/><rect x="235" y="344" width="26" height="14" rx="1.5" fill="rgba(0,0,0,0.35)"/><rect id="bl" x="235" y="344" width="26" height="14" rx="1.5" fill="var(--battery)" opacity="0.45"/></g><text x="250" y="440" class="vm" style="fill:var(--solar)" id="vb"></text><text x="250" y="462" class="vs" id="vc"></text><text x="250" y="372" class="vl">${L.battery}</text><text x="310" y="394" class="vc" id="bv" text-anchor="start"></text><text x="310" y="406" class="vc" id="bt" text-anchor="start"></text><text x="250" y="483" class="vd" id="db"></text><text x="250" y="498" class="vc" id="br" style="fill:var(--t1)"></text></g>
@@ -593,14 +593,23 @@ this._$('db').textContent=L.charge+' '+this._fmtE(dC)+' '+L.discharge+' '+this._
593593

594594
// Flow animations (normalized: bat>0=discharging, grid>0=import)
595595
const solF=sol??0,batF=bat??0,gridF=grid??0,loadF=load??0;
596+
// Incoming flows (no delay): solar→inv, grid→inv, battery discharge→inv
596597
this._sf(this._$('fs'),'s',solF,'fd','var(--green)','0.8');
597-
if(Math.abs(batF)>10)this._sf(this._$('fb'),'b',batF,batF<0?'fd':'fu',batF<0?'var(--green)':'var(--battery)','0.75');else this._$('fb').style.display='none';
598598
if(Math.abs(gridF)>10)this._sf(this._$('fg'),'g',gridF,gridF>0?'fr':'fL',gridF>0?'var(--red)':'var(--green)','0.7');else this._$('fg').style.display='none';
599-
// Home flow color: dominant source → green(solar), red(grid), purple(battery)
599+
// Determine fastest incoming speed for sync delay
600+
const inSpds=[];if(solF>10)inSpds.push(this._spd(solF));if(gridF>10)inSpds.push(this._spd(Math.abs(gridF)));if(batF>10)inSpds.push(this._spd(batF));
601+
const syncDelay=inSpds.length>0?Math.min(...inSpds)/2:0;
602+
// Battery: charging=outgoing(delay), discharging=incoming(no delay)
603+
if(Math.abs(batF)>10){this._sf(this._$('fb'),'b',batF,batF<0?'fd':'fu',batF<0?'var(--green)':'var(--battery)','0.75');this._$('fb').style.animationDelay=batF<0?syncDelay.toFixed(2)+'s':'0s';}else{this._$('fb').style.display='none';}
604+
// Home flow: outgoing (delay), color by dominant source
600605
const solContrib=solF>0?solF:0;const batContrib=batF>0?batF:0;const gridContrib=gridF>0?gridF:0;
601606
let homeColor='var(--green)';
602607
if(loadF>10){if(gridContrib>=solContrib&&gridContrib>=batContrib&&gridContrib>0)homeColor='var(--red)';else if(batContrib>=solContrib&&batContrib>0)homeColor='var(--battery)';else homeColor='var(--green)';}
603608
this._sf(this._$('fh'),'h',loadF,'fr',homeColor,'0.75');
609+
this._$('fh').style.animationDelay=syncDelay>0?syncDelay.toFixed(2)+'s':'0s';
610+
// Incoming flows: no delay
611+
this._$('fs').style.animationDelay='0s';
612+
this._$('fg').style.animationDelay='0s';
604613

605614
// Battery runtime (with flicker threshold)
606615
const batCap=c.battery_capacity??5120;const shuSoc=c.shutdown_soc??20;
@@ -638,6 +647,9 @@ _led('led2',batF>10,'#FFA726');
638647
_led('led3',gridF>10,'#EF5350');
639648
_led('led4',loadF>10,'#26C6DA');
640649

650+
// Bolt glow — only when receiving solar
651+
const bolt=this._$('bolt');if(bolt){if(solF>10){bolt.setAttribute('fill','var(--solar)');bolt.setAttribute('stroke','var(--solar)');bolt.setAttribute('stroke-width','0.8');bolt.setAttribute('opacity','0.9');bolt.setAttribute('filter','url(#glow)');}else{bolt.setAttribute('fill','rgba(255,255,255,0.15)');bolt.setAttribute('stroke','rgba(255,255,255,0.3)');bolt.setAttribute('stroke-width','0.5');bolt.setAttribute('opacity','1');bolt.removeAttribute('filter');}}
652+
641653
// Sparkline values
642654
this._$('hv').textContent=this._fmt(sol)+' / '+this._fmtE(dS);
643655
this._$('hx').textContent=this._fmt(load)+' / '+this._fmtE(dL);

0 commit comments

Comments
 (0)