Skip to content

Commit

Permalink
fix: solar eficiency can exceed 100% (limited to 200%) closes #437
Browse files Browse the repository at this point in the history
fix: update visual editor.
  • Loading branch information
slipx06 committed May 19, 2024
1 parent ee6f908 commit 0e4644e
Show file tree
Hide file tree
Showing 18 changed files with 191 additions and 117 deletions.
18 changes: 9 additions & 9 deletions dist/sunsynk-power-flow-card.js

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions docs/configuration.md

Large diffs are not rendered by default.

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.37.1",
"version": "4.37.2",
"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
80 changes: 69 additions & 11 deletions src/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,17 @@ export class SunSynkCardEditor extends ScopedRegistryHost(LitElement) implements
{name: "max_line_width", selector: {number: {}}},
{name: "min_line_width", selector: {number: {}}},
]
}]
}, {
type: "expandable",
title: this._title('sensor'),
schema: [{
type: "grid",
schema: [
{name: 'card_height', selector: {entity: {}}},
{name: 'card_width', selector: {entity: {}}},
]
}]
}]
},
{
type: "expandable",
Expand Down Expand Up @@ -123,14 +133,24 @@ export class SunSynkCardEditor extends ScopedRegistryHost(LitElement) implements
{name: 'colour', selector: {color_rgb: {}}},
{name: 'dynamic_colour', selector: {boolean: {}}},
{name: 'animation_speed', selector: {number: {}}},
{name: 'max_power', selector: {number: {}}},
{name: 'max_power', selector: {number: {}}},
{name: 'pv1_max_power', selector: {number: {}}},
{name: 'pv2_max_power', selector: {number: {}}},
{name: 'pv3_max_power', selector: {number: {}}},
{name: 'pv4_max_power', selector: {number: {}}},
{name: 'efficiency', selector: {number: {mode: 'box', min: 0, max: 3,}}},
]
}]
}, {
type: "expandable",
title: this._title('sensor'),
schema: [{
name: "solar",
type: "grid",
schema: [
{name: 'max_power', selector: {entity: {}}},
]
}]
}]
}, {
type: "expandable",
title: this._title('battery'),
Expand All @@ -139,11 +159,8 @@ export class SunSynkCardEditor extends ScopedRegistryHost(LitElement) implements
type: "grid",
schema: [
{name: 'energy', selector: {number: {min: 0,}}},
{name: "energy", selector: {entity: {}}},
{name: 'shutdown_soc', selector: {number: {mode: 'box', min: 0, max: 100,}}},
{name: 'shutdown_soc', selector: {entity: {}}},
{name: 'shutdown_soc', selector: {number: {mode: 'box', min: 0, max: 100,}}},
{name: 'shutdown_soc_offgrid', selector: {number: {mode: 'box', min: 0, max: 100,}}},
{name: 'shutdown_soc_offgrid', selector: {entity: {}}},
{name: 'show_daily', selector: {boolean: {}}},
{name: 'auto_scale', selector: {boolean: {}}},
{name: 'invert_power', selector: {boolean: {}}},
Expand All @@ -156,10 +173,22 @@ export class SunSynkCardEditor extends ScopedRegistryHost(LitElement) implements
{name: 'hide_soc', selector: {boolean: {}}},
{name: 'show_remaining_energy', selector: {boolean: {}}},
{name: 'animation_speed', selector: {number: {}}},
{name: 'max_power', selector: {number: {}}},
{name: 'max_power', selector: {entity: {}}},
{name: 'max_power', selector: {number: {}}},
]
}]
}, {
type: "expandable",
title: this._title('sensor'),
schema: [{
name: "battery",
type: "grid",
schema: [
{name: "energy", selector: {entity: {}}},
{name: 'shutdown_soc', selector: {entity: {}}},
{name: 'shutdown_soc_offgrid', selector: {entity: {}}},
{name: 'max_power', selector: {entity: {}}},
]
}]
}]
},
{
type: "expandable",
Expand Down Expand Up @@ -211,6 +240,22 @@ export class SunSynkCardEditor extends ScopedRegistryHost(LitElement) implements
{name: 'show_daily_aux', selector: {boolean: {}}},
]
}]
}, {
type: "expandable",
title: this._title('sensor'),
schema: [{
name: "load",
type: "grid",
schema: [
{name: 'load1_icon', selector: {entity: {}}},
{name: 'load2_icon', selector: {entity: {}}},
{name: 'load3_icon', selector: {entity: {}}},
{name: 'load4_icon', selector: {entity: {}}},
{name: 'aux_load1_icon', selector: {entity: {}}},
{name: 'aux_load2_icon', selector: {entity: {}}},
{name: 'max_power', selector: {entity: {}}},
]
}]
}]
},
{
Expand Down Expand Up @@ -244,7 +289,20 @@ export class SunSynkCardEditor extends ScopedRegistryHost(LitElement) implements
{name: 'animation_speed', selector: {number: {}}},
{name: 'max_power', selector: {number: {}}},
]
}]
}, {
type: "expandable",
title: this._title('sensor'),
schema: [{
name: "grid",
type: "grid",
schema: [
{name: 'load1_icon', selector: {entity: {}}},
{name: 'load2_icon', selector: {entity: {}}},
{name: 'load3_icon', selector: {entity: {}}},
{name: 'max_power', selector: {entity: {}}},
]
}]
}]
}, {
type: "expandable",
title: this._title('entities'),
Expand Down
57 changes: 30 additions & 27 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -738,82 +738,85 @@ export class SunsynkPowerFlowCard extends LitElement {
let maxLineWidth = (Utils.toNum(config.max_line_width) < 1 ? 1 : config.max_line_width) - 1;
let minLineWidth = Utils.toNum(config.min_line_width) || 1;

const BatteryMaxPower = this.getEntity('battery.max_power', {state: config.battery.max_power?.toString() ?? ''});
let BattMaxPower = BatteryMaxPower.toNum();
const batteryMaxPower = this.getEntity('battery.max_power', {state: config.battery.max_power?.toString() ?? ''});
let BattMaxPower = batteryMaxPower.toNum(0);
const solarMaxPower = this.getEntity('solar.max_power', {state: config.solar.max_power?.toString() ?? ''});
const loadMaxPower = this.getEntity('load.max_power', {state: config.load.max_power?.toString() ?? ''});
const gridMaxPower = this.getEntity('grid.max_power', {state: config.grid.max_power?.toString() ?? ''});

//Calculate line width depending on power usage
let pv1LineWidth = !config.solar.max_power ? minLineWidth : this.dynamicLineWidth(pv1PowerWatts, (config.solar.max_power || pv1PowerWatts), maxLineWidth, minLineWidth);
let pv2LineWidth = !config.solar.max_power ? minLineWidth : this.dynamicLineWidth(pv2PowerWatts, (config.solar.max_power || pv2PowerWatts), maxLineWidth, minLineWidth);
let pv3LineWidth = !config.solar.max_power ? minLineWidth : this.dynamicLineWidth(pv3PowerWatts, (config.solar.max_power || pv3PowerWatts), maxLineWidth, minLineWidth);
let pv4LineWidth = !config.solar.max_power ? minLineWidth : this.dynamicLineWidth(pv4PowerWatts, (config.solar.max_power || pv4PowerWatts), maxLineWidth, minLineWidth);
let pv1LineWidth = !config.solar.max_power ? minLineWidth : this.dynamicLineWidth(pv1PowerWatts, (solarMaxPower.toNum() || pv1PowerWatts), maxLineWidth, minLineWidth);
let pv2LineWidth = !config.solar.max_power ? minLineWidth : this.dynamicLineWidth(pv2PowerWatts, (solarMaxPower.toNum() || pv2PowerWatts), maxLineWidth, minLineWidth);
let pv3LineWidth = !config.solar.max_power ? minLineWidth : this.dynamicLineWidth(pv3PowerWatts, (solarMaxPower.toNum() || pv3PowerWatts), maxLineWidth, minLineWidth);
let pv4LineWidth = !config.solar.max_power ? minLineWidth : this.dynamicLineWidth(pv4PowerWatts, (solarMaxPower.toNum() || pv4PowerWatts), maxLineWidth, minLineWidth);
let batLineWidth = !config.battery.max_power ? minLineWidth : this.dynamicLineWidth(Math.abs(batteryPower), (BattMaxPower || Math.abs(batteryPower)), maxLineWidth, minLineWidth);
let loadLineWidth = !config.load.max_power ? minLineWidth : this.dynamicLineWidth(Math.abs(essentialPower), (config.load.max_power || Math.abs(essentialPower)), maxLineWidth, minLineWidth);
let auxLineWidth = !config.load.max_power ? minLineWidth : this.dynamicLineWidth(Math.abs(auxPower), (config.load.max_power || Math.abs(auxPower)), maxLineWidth, minLineWidth);
let gridLineWidth = !config.grid.max_power ? minLineWidth : this.dynamicLineWidth(Math.abs(totalGridPower), (config.grid.max_power || Math.abs(totalGridPower)), maxLineWidth, minLineWidth);
let grid169LineWidth = !config.grid.max_power ? minLineWidth : this.dynamicLineWidth(Math.abs(autoScaledGridPower), (config.grid.max_power || Math.abs(autoScaledGridPower)), maxLineWidth, minLineWidth);
let nonessLineWidth = !config.grid.max_power ? minLineWidth : this.dynamicLineWidth(Math.abs(nonessentialPower), (config.grid.max_power || Math.abs(nonessentialPower)), maxLineWidth, minLineWidth);
let solarLineWidth = !config.solar.max_power ? minLineWidth : this.dynamicLineWidth(totalPV, (config.solar.max_power || totalPV), maxLineWidth, minLineWidth);
let loadLineWidth = !config.load.max_power ? minLineWidth : this.dynamicLineWidth(Math.abs(essentialPower), (loadMaxPower.toNum() || Math.abs(essentialPower)), maxLineWidth, minLineWidth);
let auxLineWidth = !config.load.max_power ? minLineWidth : this.dynamicLineWidth(Math.abs(auxPower), (loadMaxPower.toNum() || Math.abs(auxPower)), maxLineWidth, minLineWidth);
let gridLineWidth = !config.grid.max_power ? minLineWidth : this.dynamicLineWidth(Math.abs(totalGridPower), (gridMaxPower.toNum() || Math.abs(totalGridPower)), maxLineWidth, minLineWidth);
let grid169LineWidth = !config.grid.max_power ? minLineWidth : this.dynamicLineWidth(Math.abs(autoScaledGridPower), (gridMaxPower.toNum() || Math.abs(autoScaledGridPower)), maxLineWidth, minLineWidth);
let nonessLineWidth = !config.grid.max_power ? minLineWidth : this.dynamicLineWidth(Math.abs(nonessentialPower), (gridMaxPower.toNum() || Math.abs(nonessentialPower)), maxLineWidth, minLineWidth);
let solarLineWidth = !config.solar.max_power ? minLineWidth : this.dynamicLineWidth(totalPV, (solarMaxPower.toNum() || totalPV), maxLineWidth, minLineWidth);

//Calculate power use animation speeds depending on Inverter size
if (config && config.solar && config.solar.animation_speed) {
const speed =
config.solar.animation_speed -
(config.solar.animation_speed - 1) * (totalPV / (config.solar.max_power || totalPV));
(config.solar.animation_speed - 1) * (totalPV / (solarMaxPower.toNum() || totalPV));
this.changeAnimationSpeed(`solar`, speed);
}

if (config && config.solar && config.solar.animation_speed) {
const speed =
config.solar.animation_speed -
(config.solar.animation_speed - 1) *
(pv1PowerWatts / (config.solar.max_power || pv1PowerWatts));
(pv1PowerWatts / (solarMaxPower.toNum() || pv1PowerWatts));
this.changeAnimationSpeed(`pv1`, speed);
}

if (config && config.solar && config.solar.animation_speed) {
const speed =
config.solar.animation_speed -
(config.solar.animation_speed - 1) *
(pv2PowerWatts / (config.solar.max_power || pv2PowerWatts));
(pv2PowerWatts / (solarMaxPower.toNum() || pv2PowerWatts));
this.changeAnimationSpeed(`pv2`, speed);
}

if (config && config.solar && config.solar.animation_speed) {
const speed =
config.solar.animation_speed -
(config.solar.animation_speed - 1) *
(pv3PowerWatts / (config.solar.max_power || pv3PowerWatts));
(pv3PowerWatts / (solarMaxPower.toNum() || pv3PowerWatts));
this.changeAnimationSpeed(`pv3`, speed);
}

if (config && config.solar && config.solar.animation_speed) {
const speed =
config.solar.animation_speed -
(config.solar.animation_speed - 1) *
(pv4PowerWatts / (config.solar.max_power || pv4PowerWatts));
(pv4PowerWatts / (solarMaxPower.toNum() || pv4PowerWatts));
this.changeAnimationSpeed(`pv4`, speed);
}

if (config && config.battery && config.battery.animation_speed) {
const speed =
config.battery.animation_speed -
(config.battery.animation_speed - 1) *
(Math.abs(batteryPower) / (config.battery.max_power || Math.abs(batteryPower)));
(Math.abs(batteryPower) / (BattMaxPower || Math.abs(batteryPower)));
this.changeAnimationSpeed(`battery`, speed);
}

if (config && config.load && config.load.animation_speed) {
const speed =
config.load.animation_speed -
(config.load.animation_speed - 1) * (Math.abs(essentialPower) / (config.load.max_power || Math.abs(essentialPower)));
(config.load.animation_speed - 1) * (Math.abs(essentialPower) / (loadMaxPower.toNum() || Math.abs(essentialPower)));
this.changeAnimationSpeed(`load`, speed);
this.changeAnimationSpeed(`load1`, speed);
}

if (config && config.load && config.load.animation_speed) {
const speed =
config.load.animation_speed -
(config.load.animation_speed - 1) * (Math.abs(auxPower) / (config.load.max_power || Math.abs(auxPower)));
(config.load.animation_speed - 1) * (Math.abs(auxPower) / (loadMaxPower.toNum() || Math.abs(auxPower)));
this.changeAnimationSpeed(`aux`, speed);
this.changeAnimationSpeed(`aux1`, speed);
}
Expand All @@ -822,7 +825,7 @@ export class SunsynkPowerFlowCard extends LitElement {
const speed =
config.grid.animation_speed -
(config.grid.animation_speed - 1) *
(Math.abs(totalGridPower) / (config.grid.max_power || Math.abs(totalGridPower)));
(Math.abs(totalGridPower) / (gridMaxPower.toNum() || Math.abs(totalGridPower)));
this.changeAnimationSpeed(`grid1`, speed);
this.changeAnimationSpeed(`grid`, speed);
this.changeAnimationSpeed(`grid2`, speed);
Expand All @@ -832,7 +835,7 @@ export class SunsynkPowerFlowCard extends LitElement {
const speed =
config.grid.animation_speed -
(config.grid.animation_speed - 1) *
(Math.abs(nonessentialPower) / (config.grid.max_power || Math.abs(nonessentialPower)));
(Math.abs(nonessentialPower) / (gridMaxPower.toNum() || Math.abs(nonessentialPower)));
this.changeAnimationSpeed(`ne`, speed);
}

Expand Down Expand Up @@ -927,11 +930,11 @@ export class SunsynkPowerFlowCard extends LitElement {
const {batteryIcon, batteryCharge, stopColour, battery0} = BatteryIconManager.convert(stateBatterySoc)

//Calculate pv efficiency
const totalPVEfficiency = (!config.solar.max_power || config.solar.efficiency === 0) ? 100 : Utils.toNum(Math.min((totalPV / config.solar.max_power) * 100, 100) ,0);
const PV1Efficiency = (!config.solar.pv1_max_power || config.solar.efficiency === 0) ? 100 : Utils.toNum(Math.min((pv1PowerWatts / config.solar.pv1_max_power) * 100, 100) ,0);
const PV2Efficiency = (!config.solar.pv2_max_power || config.solar.efficiency === 0) ? 100 : Utils.toNum(Math.min((pv2PowerWatts / config.solar.pv2_max_power) * 100, 100) ,0);
const PV3Efficiency = (!config.solar.pv3_max_power || config.solar.efficiency === 0) ? 100 : Utils.toNum(Math.min((pv3PowerWatts / config.solar.pv3_max_power) * 100, 100) ,0);
const PV4Efficiency = (!config.solar.pv4_max_power || config.solar.efficiency === 0) ? 100 : Utils.toNum(Math.min((pv4PowerWatts / config.solar.pv4_max_power) * 100, 100) ,0);
const totalPVEfficiency = (!config.solar.max_power || config.solar.efficiency === 0) ? 100 : Utils.toNum(Math.min((totalPV / solarMaxPower.toNum()) * 100, 200) ,0);
const PV1Efficiency = (!config.solar.pv1_max_power || config.solar.efficiency === 0) ? 100 : Utils.toNum(Math.min((pv1PowerWatts / config.solar.pv1_max_power) * 100, 200) ,0);
const PV2Efficiency = (!config.solar.pv2_max_power || config.solar.efficiency === 0) ? 100 : Utils.toNum(Math.min((pv2PowerWatts / config.solar.pv2_max_power) * 100, 200) ,0);
const PV3Efficiency = (!config.solar.pv3_max_power || config.solar.efficiency === 0) ? 100 : Utils.toNum(Math.min((pv3PowerWatts / config.solar.pv3_max_power) * 100, 200) ,0);
const PV4Efficiency = (!config.solar.pv4_max_power || config.solar.efficiency === 0) ? 100 : Utils.toNum(Math.min((pv4PowerWatts / config.solar.pv4_max_power) * 100, 200) ,0);
/**
* 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
Loading

0 comments on commit 0e4644e

Please sign in to comment.