Skip to content

Commit 91b5920

Browse files
authored
Update version and enhance inverter settings
Updated version number and modified battery polarity settings for Victron and Solis inverters. Added support for a second solar input and adjusted the display logic for solar power.
1 parent e0b5fbd commit 91b5920

1 file changed

Lines changed: 32 additions & 14 deletions

File tree

‎xpower-flow-card.js‎

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// xPower Flow Card — Modern power flow card for solar hybrid inverters
22
// Copyright (C) 2025 BTNBx — MIT License
3-
const V='1.2.5';
3+
const V='1.2.6';
44

55
/* ═══════════════════════════════════════
66
xPower Flow Card — i18n
@@ -163,7 +163,7 @@ const PRESETS={
163163
},
164164
victron:{
165165
label:'Victron (Venus OS)',inverter_name:'VICTRON',
166-
bat_polarity:'negative',grid_polarity:'positive',
166+
bat_polarity:'positive',grid_polarity:'positive',
167167
e:{solar:'sensor.pv_power',battery:'sensor.battery_power',soc:'sensor.battery_soc',
168168
grid:'sensor.grid_power',load:'sensor.ac_consumption',grid_voltage:'sensor.grid_voltage',
169169
battery_voltage:'sensor.battery_voltage',pv_voltage:'sensor.pv_voltage',
@@ -185,6 +185,18 @@ const PRESETS={
185185
daily_export:'',daily_load:'',daily_charge:'',daily_discharge:'',
186186
battery_temperature:''}
187187
},
188+
solis:{
189+
label:'Solis (SolisCloud)',inverter_name:'SOLIS',
190+
bat_polarity:'positive',grid_polarity:'positive',
191+
e:{solar:'sensor.solis_pv_power',battery:'sensor.solis_battery_power',soc:'sensor.solis_battery_soc',
192+
grid:'sensor.solis_grid_power',load:'sensor.solis_house_load',grid_voltage:'sensor.solis_grid_voltage',
193+
battery_voltage:'sensor.solis_battery_voltage',pv_voltage:'sensor.solis_pv_voltage',
194+
temperature:'sensor.solis_inverter_temperature',frequency:'sensor.solis_grid_frequency',
195+
grid_status:'',daily_solar:'sensor.solis_today_energy_generation',daily_import:'sensor.solis_today_grid_import',
196+
daily_export:'sensor.solis_today_grid_export',daily_load:'sensor.solis_today_load_consumption',
197+
daily_charge:'sensor.solis_today_battery_charge',daily_discharge:'sensor.solis_today_battery_discharge',
198+
battery_temperature:'sensor.solis_battery_temperature'}
199+
},
188200
custom:{
189201
label:'Custom',inverter_name:'Inverter',
190202
bat_polarity:'negative',grid_polarity:'positive',
@@ -197,6 +209,7 @@ const PRESETS={
197209
const DEFAULTS={
198210
preset:'deye',
199211
...PRESETS.deye.e,
212+
solar2:'',pv_voltage2:'',
200213
bat_polarity:'negative',grid_polarity:'positive',
201214
shutdown_soc:20,battery_capacity:5120,language:'pt',
202215
inverter_name:'DEYE',
@@ -207,12 +220,14 @@ const DEFAULTS={
207220
};
208221

209222
const ENTITY_FIELDS=[
210-
{key:'solar',label:'Solar Power'},{key:'battery',label:'Battery Power'},
223+
{key:'solar',label:'Solar Power (MPPT1)'},{key:'solar2',label:'Solar Power (MPPT2)'},
224+
{key:'battery',label:'Battery Power'},
211225
{key:'soc',label:'Battery SOC'},{key:'grid',label:'Grid Power'},
212226
{key:'load',label:'Load Power'},{key:'grid_voltage',label:'Grid Voltage'},
213-
{key:'battery_voltage',label:'Battery Voltage'},{key:'pv_voltage',label:'PV Voltage'},
227+
{key:'battery_voltage',label:'Battery Voltage'},
214228
{key:'temperature',label:'Inverter Temp.'},{key:'battery_temperature',label:'Battery Temp.'},
215229
{key:'frequency',label:'Grid Frequency'},{key:'grid_status',label:'Grid Status'},
230+
{key:'pv_voltage',label:'PV Voltage (MPPT1)'},{key:'pv_voltage2',label:'PV Voltage (MPPT2)'},
216231
{key:'daily_solar',label:'Daily Solar'},{key:'daily_import',label:'Daily Import'},
217232
{key:'daily_export',label:'Daily Export'},{key:'daily_load',label:'Daily Load'},
218233
{key:'daily_charge',label:'Daily Charge'},{key:'daily_discharge',label:'Daily Discharge'},
@@ -336,8 +351,8 @@ class XPowerFlowCardEditor extends HTMLElement{
336351
<div class="field">
337352
<label>${L.editor_bat_pol}</label>
338353
<select id="ed-bpol" style="${selStyle}">
339-
<option value="negative" ${c.bat_polarity==='negative'?'selected':''}>${L.charging} (Deye, Sunsynk, Victron)</option>
340-
<option value="positive" ${c.bat_polarity==='positive'?'selected':''}>${L.charging} (Huawei, Fronius, SolarEdge)</option>
354+
<option value="negative" ${c.bat_polarity==='negative'?'selected':''}>${L.charging} (Deye, Sunsynk, Growatt)</option>
355+
<option value="positive" ${c.bat_polarity==='positive'?'selected':''}>${L.charging} (Huawei, Fronius, SolarEdge, Victron, Solis)</option>
341356
</select>
342357
</div>
343358
<div class="field">
@@ -492,7 +507,7 @@ svg{width:100%;height:auto;display:block}
492507
.ss #hs{fill:none;stroke:rgba(102,187,106,0.7);stroke-width:1.2}.sc #hl{fill:none;stroke:rgba(38,198,218,0.7);stroke-width:1.2}.sg #hg{fill:none;stroke:rgba(66,165,245,0.7);stroke-width:1.2}.sbt #hb2{fill:none;stroke:rgba(124,77,255,0.7);stroke-width:1.2}
493508
.ss #hsa{fill:rgba(102,187,106,0.12);stroke:none}.sc #hla{fill:rgba(38,198,218,0.12);stroke:none}.sg #hga{fill:rgba(66,165,245,0.12);stroke:none}.sbt #hb2a{fill:rgba(124,77,255,0.12);stroke:none}
494509
</style>
495-
<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)">
510+
<ha-card><svg viewBox="0 0 526 510"><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)">
496511
<g id="wicons" style="display:none" transform="translate(-20,0)">
497512
<rect class="wb" x="-2" y="-4" width="86" height="20"/>
498513
<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>
@@ -508,7 +523,7 @@ svg{width:100%;height:auto;display:block}
508523
<g id="nGrid" class="ct"><g id="gridIcon" 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><circle id="gsd" cx="92" cy="189" r="4" fill="rgba(255,255,255,0.12)"/><text x="66" y="300" class="vd" id="dg"></text></g>
509524
<g id="nLoad" class="ct"><g id="loadIcon" 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>
510525
<g id="nBat" class="ct"><g id="batIcon" 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>
511-
<rect id="ap" x="185" y="512" width="130" height="16" class="au-pill" fill="var(--green)"/><text x="250" y="521" class="au" id="va"></text>
526+
<defs><clipPath id="au-clip"><rect x="452" y="414" width="70" height="96" rx="9"/></clipPath></defs><rect x="452" y="414" width="70" height="96" rx="9" fill="rgba(12,14,24,0.92)"/><rect x="452" y="414" width="70" height="96" rx="9" fill="none" id="au-border" stroke="var(--green)" stroke-width="2.5"/><text x="487" y="458" id="va" font-family="-apple-system,sans-serif" font-size="30" font-weight="800" fill="white" text-anchor="middle" dominant-baseline="middle"></text><g clip-path="url(#au-clip)"><rect x="452" y="478" width="70" height="32" id="au-bar" fill="var(--green)"/><text x="487" y="494" font-family="-apple-system,sans-serif" font-size="7" font-weight="700" fill="white" text-anchor="middle" dominant-baseline="middle" letter-spacing="0.04em">AUTOSSUFICIÊNCIA</text></g>
512527
</g></svg>
513528
<div class="sr">
514529
<div class="sb sg"><div class="sb-header"><span class="sl">${L.grid24}</span><span class="sv" id="hz"></span></div><svg viewBox="0 0 200 55" preserveAspectRatio="none"><path id="hga"/><path id="hg"/><line class="cursor" id="cg" x1="0" y1="0" x2="0" y2="55"/><circle class="cursor-dot" id="dg2" cx="0" cy="0" r="3"/></svg><span class="sb-tip" id="tg"></span></div>
@@ -561,7 +576,9 @@ _drawSparks(){this._spark('hs','hsa',this._hist.solar);this._spark('hl','hla',th
561576
_update(){if(!this._h||!this.shadowRoot.getElementById('vs'))return;
562577
const c=this._c,L=this._lang;
563578

564-
const sol=this._gv(c.solar);
579+
const sol1=this._gv(c.solar);
580+
const sol2=this._gv(c.solar2);
581+
const sol=sol1!==null&&sol2!==null?sol1+sol2:sol1!==null?sol1:sol2;
565582
const bat=this._norm(this._gv(c.battery),'bat');
566583
const soc=this._gv(c.soc);
567584
const grid=this._norm(this._gv(c.grid),'grid');
@@ -570,6 +587,7 @@ const temp=this._gv(c.temperature);
570587
const gv=this._gv(c.grid_voltage);
571588
const bv=this._gv(c.battery_voltage);
572589
const pvv=this._gv(c.pv_voltage);
590+
const pvv2=this._gv(c.pv_voltage2);
573591
const freq=this._gv(c.frequency);
574592

575593
const p=this._prev;
@@ -585,8 +603,8 @@ this._$('bl').setAttribute('width',(26*(socVal/100)).toFixed(1));
585603
const blEl=this._$('bl');if(blEl){if(bat!==null&&bat<-10){blEl.setAttribute('fill','#4CD964');blEl.setAttribute('class','bat-charge');}else{blEl.setAttribute('fill','var(--battery)');blEl.removeAttribute('class');}}
586604

587605
if(temp!==null)this._$('tp').textContent=temp.toFixed(0)+'\u00B0C';else this._$('tp').textContent='';
588-
if(pvv!==null)this._$('pv').textContent=pvv.toFixed(0)+'V';else this._$('pv').textContent='';
589-
if(gv!==null&&freq!==null)this._$('gv').textContent=gv.toFixed(0)+'V \u00B7 '+freq.toFixed(1)+'Hz';else this._$('gv').textContent='';
606+
if(pvv!==null&&pvv2!==null)this._$('pv').textContent=pvv.toFixed(0)+'V / '+pvv2.toFixed(0)+'V';else if(pvv!==null)this._$('pv').textContent=pvv.toFixed(0)+'V';else if(pvv2!==null)this._$('pv').textContent=pvv2.toFixed(0)+'V';else this._$('pv').textContent='';
607+
if(gv!==null&&freq!==null)this._$('gv').textContent=gv.toFixed(0)+'V \u00B7 '+freq.toFixed(1)+'Hz';else if(gv!==null)this._$('gv').textContent=gv.toFixed(0)+'V';else if(freq!==null)this._$('gv').textContent=freq.toFixed(1)+'Hz';else this._$('gv').textContent='';
590608
if(bv!==null)this._$('bv').textContent=bv.toFixed(1)+'V';else this._$('bv').textContent='';
591609
const bt=this._gv(c.battery_temperature);if(bt!==null)this._$('bt').textContent=bt.toFixed(0)+'\u00B0C';else this._$('bt').textContent='';
592610

@@ -618,8 +636,8 @@ if(batF>RUNTIME_MIN_W&&socVal>shuSoc){
618636

619637
const gridImp=gridF>0?gridF:0;
620638
const au=loadF>0?Math.max(0,Math.min(100,((loadF-gridImp)/loadF)*100)):0;
621-
this._$('va').textContent=L.autarky+': '+au.toFixed(0)+'%';
622-
const ap=this._$('ap');if(ap){let pc;if(au>=80)pc='#66BB6A';else if(au>=50)pc='#FFA726';else if(au>=25)pc='#FF7043';else pc='#EF5350';ap.setAttribute('fill',pc);}
639+
this._$('va').textContent=au.toFixed(0)+'%';
640+
let auC;if(au>=80)auC='#66BB6A';else if(au>=50)auC='#FFA726';else if(au>=25)auC='#FF7043';else auC='#EF5350';const auBar=this._$('au-bar');if(auBar)auBar.setAttribute('fill',auC);const auBorder=this._$('au-border');if(auBorder)auBorder.setAttribute('stroke',auC);
623641

624642
const wtv=this._gv(c.weather_temp);const whv=this._gv(c.weather_humidity);
625643
const wicons=this._$('wicons');const wdrop=this._$('wdrop');const wdiv=this._$('wdiv');
@@ -672,7 +690,7 @@ const lcd=this._$('lcd');if(lcd){const total=solF+Math.abs(batF)+Math.abs(gridF)
672690
const a=Math.abs(total);lcd.textContent=a>=1000?(a/1000).toFixed(1)+'kW':a.toFixed(0)+'W';}
673691

674692
// #3 Pill glow — autarky >90%
675-
const apEl=this._$('ap');if(apEl){if(au>=90){apEl.style.filter='drop-shadow(0 0 6px rgba(255,215,0,0.6))';apEl.setAttribute('class','au-pill au-glow');}else{apEl.style.filter='';apEl.setAttribute('class','au-pill');}}
693+
const auBorderEl=this._$('au-border');if(auBorderEl&&au>=90){auBorderEl.style.filter='drop-shadow(0 0 4px rgba(255,215,0,0.6))';}else if(auBorderEl){auBorderEl.style.filter='';}
676694
}
677695

678696
getCardSize(){return this._c.compact?4:6;}

0 commit comments

Comments
 (0)