Skip to content

Commit

Permalink
feat: display extra load information on compact card when additional …
Browse files Browse the repository at this point in the history
…loads = 3 and 4 closes #472

feat: customise the grid icons. See `import_icon:`, `export_icon:`, and `disconnected_icon:` under grid section. Specify mdi or sensor that returns an mdi:icon closes #475 and closes #469
fix: position of grid provider name when Daily Grid Buy is hidden
  • Loading branch information
slipx06 committed Jun 5, 2024
1 parent 9f4dc85 commit ae6eab5
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 15 deletions.
14 changes: 7 additions & 7 deletions dist/sunsynk-power-flow-card.js

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ These attributes are only needed if `show_solar` is set to `true`
| auto_scale: | Optional | `true` | If set to `true` the card will use the entities `unit_of_measurement` attribute to perform the correct scaling (i,e, power values greater than 999W will be displayed as kW e.g. 1.23kW) and display the correct unit. The number of decimal places can be changed using the `decimal_places` card attribute apart from the daily energy values which are set using the `decimal_places_energy` attribute |
| energy_cost_decimals: | Optional | `2` | Sets the number of decimal places to display the buy and sell energy costs |
| off_threshold: | Optional | `0` | When power falls below this value the load will be considered off and colour will change to grey. Requires `dynamic_colour` to be enabled. Can also be set to `-1` to disable. |
| import_icon: | Optional | | Set the grid connected/import image using any mdi icon e.g. `mdi:transmission-tower-import`. You can also provide a sensor that returns the mdi icon. If defined overrides the card default icon. |
| export_icon: | Optional | | Set the grid export image using any mdi icon e.g. `mdi:transmission-tower-export`. You can also provide a sensor that returns the mdi icon. If defined overrides the card default icon. |
| disconnected_icon: | Optional | | Set the grid disconnected image using any mdi icon e.g. `mdi:transmission-tower-off`. You can also provide a sensor that returns the mdi icon. If defined overrides the card default icon. |

### Entities

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sunsynk-power-flow-card",
"version": "4.41.2",
"version": "4.42.0",
"description": "A customizable Home Assistant card to emulate the Sunsynk System flow that's displayed on the Inverter screen.",
"main": "sunsynk-power-flow-card.js",
"scripts": {
Expand Down
22 changes: 19 additions & 3 deletions src/cards/compact-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ export const compactCard = (config: sunsynkPowerFlowCardConfig, inverterImg: str
color: ${data.dynamicColourEssentialLoad4} !important;
--mdc-icon-size: 20px;
}
.grid-icon {
color: ${data.customGridIconColour} !important;
--mdc-icon-size: 64px;
}
</style>
<div class="container card">
${config.title ? html`<h1
Expand Down Expand Up @@ -773,23 +778,34 @@ export const compactCard = (config: sunsynkPowerFlowCardConfig, inverterImg: str
width="64.5" height="64.5" viewBox="0 0 24 24">
<path class="${validGridDisconnected.includes(data.gridStatus.toLowerCase()) ? 'st12' : ''}"
fill="${data.gridColour}"
display="${!config.show_grid || data.totalGridPower < 0 ? 'none' : ''}"
display="${!config.show_grid || data.totalGridPower < 0 || config.grid.import_icon ? 'none' : ''}"
d="${icons.gridOn}"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" id="transmission_off" x="-0.5" y="187.5"
width="64.5" height="64.5" viewBox="0 0 24 24">
<path class="${validGridConnected.includes(data.gridStatus.toLowerCase()) ? 'st12' : ''}"
fill="${data.gridOffColour}" display="${!config.show_grid ? 'none' : ''}"
fill="${data.gridOffColour}" display="${!config.show_grid || config.grid.disconnected_icon ? 'none' : ''}"
d="${icons.gridOff}"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" id="grid_export" x="-0.5" y="187.5"
width="64.5" height="64.5" viewBox="0 0 24 24">
<path class="${validGridDisconnected.includes(data.gridStatus.toLowerCase()) ? 'st12' : ''}"
fill="${data.gridColour}"
display="${!config.show_grid || data.totalGridPower >= 0 ? 'none' : ''}"
display="${!config.show_grid || data.totalGridPower >= 0 || config.grid.export_icon ? 'none' : ''}"
d="${icons.gridExportCompact}"/>
</svg>
</a>
<a href="#" @click=${(e) => Utils.handlePopup(e, config.entities.grid_connected_status_194)}>
<g display="${config.show_grid || config.grid.import_icon || config.grid.disconnected_icon || config.grid.export_icon ? '' : 'none'}">
<foreignObject x="-0.5" y="187.5" width="70" height="70" style="position: fixed; ">
<body xmlns="http://www.w3.org/1999/xhtml">
<div style="position: fixed; ">
<ha-icon icon="${data.customGridIcon}" class="grid-icon"></ha-icon>
</div>
</body>
</foreignObject>
</g>
</a>
<svg xmlns="http://www.w3.org/2000/svg" id="essen" x="${data.essIconSize === 1 ? "405" : "402"}"
y="${data.essIconSize === 1 ? "186" : "177.5"}" width="${data.essIconSize === 1 ? "75" : "79"}"
height="${data.essIconSize === 1 ? "75" : "79"}"
Expand Down
30 changes: 27 additions & 3 deletions src/cards/full-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@ export const fullCard = (config: sunsynkPowerFlowCardConfig, inverterImg: string
color: ${data.gridColour} !important;
--mdc-icon-size: 70px;
}
.grid-icon {
color: ${data.customGridIconColour} !important;
--mdc-icon-size: 64px;
}
.grid-icon-small {
color: ${data.customGridIconColour} !important;
--mdc-icon-size: 32px;
}
</style>
<div class="container card">
${config.title ? html`<h1
Expand Down Expand Up @@ -883,7 +893,7 @@ export const fullCard = (config: sunsynkPowerFlowCardConfig, inverterImg: string
height="${config.inverter.three_phase ? '34' : '65'}" viewBox="0 0 24 24">
<path class="${validGridDisconnected.includes(data.gridStatus.toLowerCase()) ? 'st12' : ''}"
fill="${data.gridColour}"
display="${!config.show_grid || data.totalGridPower < 0 ? 'none' : ''}"
display="${!config.show_grid || data.totalGridPower < 0 || config.grid.import_icon ? 'none' : ''}"
d="${icons.gridOn}"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" id="transmission_off"
Expand All @@ -892,7 +902,7 @@ export const fullCard = (config: sunsynkPowerFlowCardConfig, inverterImg: string
width="${config.inverter.three_phase ? '34' : '65'}"
height="${config.inverter.three_phase ? '34' : '65'}" viewBox="0 0 24 24">
<path class="${validGridConnected.includes(data.gridStatus.toLowerCase()) ? 'st12' : ''}"
fill="${data.gridOffColour}" display="${!config.show_grid ? 'none' : ''}"
fill="${data.gridOffColour}" display="${!config.show_grid || config.grid.disconnected_icon ? 'none' : ''}"
d="${icons.gridOff}"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" id="grid_export"
Expand All @@ -902,10 +912,24 @@ export const fullCard = (config: sunsynkPowerFlowCardConfig, inverterImg: string
height="${config.inverter.three_phase ? '34' : '65'}" viewBox="0 0 24 24">
<path class="${validGridDisconnected.includes(data.gridStatus.toLowerCase()) ? 'st12' : ''}"
fill="${data.gridColour}"
display="${!config.show_grid || data.totalGridPower >= 0 ? 'none' : ''}"
display="${!config.show_grid || data.totalGridPower >= 0 || config.grid.export_icon ? 'none' : ''}"
d="${icons.gridExport}"/>
</svg>
</a>
<a href="#" @click=${(e) => Utils.handlePopup(e, config.entities.grid_connected_status_194)}>
<g display="${config.show_grid || config.grid.import_icon || config.grid.disconnected_icon || config.grid.export_icon ? '' : 'none'}">
<foreignObject x="${config.inverter.three_phase ? '404' : '389'}"
y="${config.inverter.three_phase ? '339' : '308'}"
width="${config.inverter.three_phase ? '34' : '65'}"
height="${config.inverter.three_phase ? '34' : '65'}" style="position: fixed; ">
<body xmlns="http://www.w3.org/1999/xhtml">
<div style="position: fixed; ">
<ha-icon icon="${data.customGridIcon}" class="${config.inverter.three_phase ? 'grid-icon-small' : 'grid-icon'}"></ha-icon>
</div>
</body>
</foreignObject>
</g>
</a>
<!-- Nonessential Icon -->
<svg xmlns="http://www.w3.org/2000/svg" id="noness_default" x="303.5" y="305.5" width="70"
Expand Down
6 changes: 6 additions & 0 deletions src/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ export class SunSynkCardEditor extends LitElement implements LovelaceCardEditor
{name: 'animation_speed', selector: {number: {}}},
{name: 'max_power', selector: {number: {}}},
{name: 'off_threshold', selector: {number: {}}},
{name: 'import_icon', selector: {icon: {}}},
{name: 'export_icon', selector: {icon: {}}},
{name: 'disconnected_icon', selector: {icon: {}}},
]
}, {
type: "expandable",
Expand All @@ -313,6 +316,9 @@ export class SunSynkCardEditor extends LitElement implements LovelaceCardEditor
{name: 'load2_icon', selector: {entity: {}}},
{name: 'load3_icon', selector: {entity: {}}},
{name: 'max_power', selector: {entity: {}}},
{name: 'import_icon', selector: {entity: {}}},
{name: 'export_icon', selector: {entity: {}}},
{name: 'disconnected_icon', selector: {entity: {}}},
]
}]
}]
Expand Down
29 changes: 28 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,9 @@ export class SunsynkPowerFlowCard extends LitElement {
const iconNonessentialLoad1 = this.getEntity('grid.load1_icon', {state: config.grid?.load1_icon?.toString() ?? ''}).state;
const iconNonessentialLoad2 = this.getEntity('grid.load2_icon', {state: config.grid?.load2_icon?.toString() ?? ''}).state;
const iconNonessentialLoad3 = this.getEntity('grid.load3_icon', {state: config.grid?.load3_icon?.toString() ?? ''}).state;
const iconGridImport = this.getEntity('grid.import_icon', {state: config.grid?.import_icon?.toString() ?? ''}).state;
const iconGridDisconnected = this.getEntity('grid.disconnected_icon', {state: config.grid?.disconnected_icon?.toString() ?? ''}).state;
const iconGridExport = this.getEntity('grid.export_icon', {state: config.grid?.export_icon?.toString() ?? ''}).state;

let remainingSolar = config.entities.remaining_solar ? Utils.convertValueNew(stateRemainingSolar.state, stateRemainingSolar.attributes?.unit_of_measurement, decimalPlaces) : false;
let totalSolarGeneration = config.entities.total_pv_generation ? Utils.convertValueNew(stateTotalPVGeneration.state, stateTotalPVGeneration.attributes?.unit_of_measurement, 2) : false;
Expand Down Expand Up @@ -1016,6 +1019,28 @@ export class SunsynkPowerFlowCard extends LitElement {
const PV2Efficiency = (!config.solar.pv2_max_power || config.solar.efficiency === 0) ? 100 : Utils.toNum(Math.min((pv2PowerWatts / pv2MaxPower.toNum()) * 100, 200), 0);
const PV3Efficiency = (!config.solar.pv3_max_power || config.solar.efficiency === 0) ? 100 : Utils.toNum(Math.min((pv3PowerWatts / pv3MaxPower.toNum()) * 100, 200), 0);
const PV4Efficiency = (!config.solar.pv4_max_power || config.solar.efficiency === 0) ? 100 : Utils.toNum(Math.min((pv4PowerWatts / pv4MaxPower.toNum()) * 100, 200), 0);

let customGridIcon: string;
let customGridIconColour: string;
switch (true) {
case totalGridPower < 0 && validGridConnected.includes(gridStatus.toLowerCase()):
customGridIcon = iconGridExport;
customGridIconColour = gridColour;
break;
case totalGridPower >= 0 && validGridConnected.includes(gridStatus.toLowerCase()):
customGridIcon = iconGridImport;
customGridIconColour = gridColour;
break;
case totalGridPower === 0 && validGridDisconnected.includes(gridStatus.toLowerCase()):
customGridIcon = iconGridDisconnected;
customGridIconColour = gridOffColour;
break;
default:
customGridIcon = iconGridImport;
customGridIconColour = gridColour;
break;
}

/**
* The current structure of this data object is intentional, but it is considered temporary.
* There is a need to evaluate the data being passed, as there might be duplication.
Expand Down Expand Up @@ -1203,7 +1228,9 @@ export class SunsynkPowerFlowCard extends LitElement {
dynamicColourNonEssentialLoad1,
dynamicColourNonEssentialLoad2,
dynamicColourNonEssentialLoad3,
stateBatterySOH
stateBatterySOH,
customGridIcon,
customGridIconColour
};

if (this.isFullCard) {
Expand Down
5 changes: 5 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ export interface sunsynkPowerFlowCardConfig extends LovelaceCardConfig {
energy_cost_decimals: number;
show_absolute: boolean;
off_threshold: number;
import_icon: string;
export_icon: string;
disconnected_icon: string;
}
entities: CardConfigEntities
}
Expand Down Expand Up @@ -465,4 +468,6 @@ export interface DataDto {
dynamicColourNonEssentialLoad2,
dynamicColourNonEssentialLoad3,
stateBatterySOH: CustomEntity,
customGridIcon,
customGridIconColour
}

0 comments on commit ae6eab5

Please sign in to comment.