Skip to content

Commit

Permalink
fix: better handling of system timer closes #522
Browse files Browse the repository at this point in the history
  • Loading branch information
slipx06 committed Oct 14, 2024
1 parent 21178aa commit ac3a52c
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 40 deletions.
4 changes: 2 additions & 2 deletions dist/sunsynk-power-flow-card.js

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": "5.0.0",
"version": "5.0.1",
"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
132 changes: 95 additions & 37 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,6 @@ export class SunsynkPowerFlowCard extends LitElement {
entityID: '',
};


switch (true) {
case stateUseTimer.state === 'off':
case !enableTimer:
Expand All @@ -531,50 +530,109 @@ export class SunsynkPowerFlowCard extends LitElement {
case !config.entities.prog6_time:
inverterProg.show = false;
break;

default: {
inverterProg.show = true;

const timer_now = new Date(); // Create a new Date object representing the current time

const progTimes: Date[] = [];

[prog1, prog2, prog3, prog4, prog5, prog6].forEach((prog, index) => {
const [hours, minutes] = prog.time.state.split(':').map(item => parseInt(item, 10));
progTimes[index] = new Date(timer_now.getTime());
progTimes[index].setHours(hours);
progTimes[index].setMinutes(minutes);
});

const [prog_time1, prog_time2, prog_time3, prog_time4, prog_time5, prog_time6] = progTimes;

if (timer_now >= prog_time6 || timer_now < prog_time1) {
assignInverterProgValues(prog6, config.entities.prog6_charge);
} else if (timer_now >= prog_time1 && timer_now < prog_time2) {
assignInverterProgValues(prog1, config.entities.prog1_charge);
} else if (timer_now >= prog_time2 && timer_now < prog_time3) {
assignInverterProgValues(prog2, config.entities.prog2_charge);
} else if (timer_now >= prog_time3 && timer_now < prog_time4) {
assignInverterProgValues(prog3, config.entities.prog3_charge);
} else if (timer_now >= prog_time4 && timer_now < prog_time5) {
assignInverterProgValues(prog4, config.entities.prog4_charge);
} else if (timer_now >= prog_time5 && timer_now < prog_time6) {
assignInverterProgValues(prog5, config.entities.prog5_charge);
//console.log(`Current date and time: ${timer_now.toLocaleString()}`);

assignInverterProgramBasedOnTime(timer_now);

function assignInverterProgramBasedOnTime(timer_now: Date) {
const progTimes: { start: Date; end: Date }[] = [];

// Populate the progTimes array with Date objects based on the current time
[prog1, prog2, prog3, prog4, prog5, prog6].forEach((prog, index) => {
if (!prog || !prog.time || !prog.time.state) {
console.error(`Program ${index + 1} is not defined or has no valid time.`);
return; // Skip this program
}

const [hours, minutes] = prog.time.state.split(':').map(item => parseInt(item, 10));
const progStartTime = new Date(timer_now.getTime());
progStartTime.setHours(hours);
progStartTime.setMinutes(minutes);

// Determine the end time for each program (next program's start time)
const nextIndex = (index + 1) % [prog1, prog2, prog3, prog4, prog5, prog6].length;
const nextProg = [prog1, prog2, prog3, prog4, prog5, prog6][nextIndex];
const progEndTime = nextProg && nextProg.time && nextProg.time.state ?
new Date(timer_now.getTime()) :
new Date(timer_now.getTime());

if (nextProg && nextProg.time && nextProg.time.state) {
const [nextHours, nextMinutes] = nextProg.time.state.split(':').map(item => parseInt(item, 10));
progEndTime.setHours(nextHours);
progEndTime.setMinutes(nextMinutes);
} else {
console.warn(`Next program ${nextIndex + 1} is not defined or has no valid time.`);
}

//console.log(`Program ${index + 1} time (before adjustment): Start: ${progStartTime.toLocaleString()}, End: ${progEndTime.toLocaleString()}`);

// Add to the progTimes array
progTimes[index] = { start: progStartTime, end: progEndTime };
});

// Adjust times for the next day if necessary
adjustProgramTimes(progTimes, timer_now);

//console.log("Adjusted Program Times:");
//progTimes.forEach((progTime, index) => {
// console.log(`Prog ${index + 1}: Start: ${progTime.start.toLocaleString()}, End: ${progTime.end.toLocaleString()}`);
//});

// Time comparison logic to determine the active program
for (let i = 0; i < progTimes.length; i++) {
const { start: currentProgStartTime, end: currentProgEndTime } = progTimes[i];

// Check for normal case (start < end)
if (currentProgStartTime <= timer_now && timer_now < currentProgEndTime) {
//console.log(`Assigning Program ${i + 1}`);
assignInverterProgValues([prog1, prog2, prog3, prog4, prog5, prog6][i], config.entities[`prog${i + 1}_charge`]);
break; // Exit once the correct program is assigned
}
// Check for wrap-around case (start > end)
else if (currentProgStartTime > currentProgEndTime) {
if (timer_now >= currentProgStartTime || timer_now < currentProgEndTime) {
//console.log(`Assigning Program ${i + 1} (wrap-around)`);
assignInverterProgValues([prog1, prog2, prog3, prog4, prog5, prog6][i], config.entities[`prog${i + 1}_charge`]);
break; // Exit once the correct program is assigned
}
}
}
}

function assignInverterProgValues(prog, entityID) {
if (prog.charge.state === 'No Grid or Gen' || prog.charge.state === '0' || prog.charge.state === 'off') {
inverterProg.charge = 'none';
} else {
inverterProg.charge = 'both';

function adjustProgramTimes(progTimes: { start: Date; end: Date }[], timer_now: Date) {
const currentTime = timer_now.getTime();
// Adjust for times that roll over into the next day
progTimes.forEach((progTime) => {
// If the start time is before current time and the end time is after the current time, adjust to the next day
if (progTime.start.getTime() < currentTime && progTime.end.getTime() < currentTime) {
progTime.start.setDate(progTime.start.getDate() + 1);
progTime.end.setDate(progTime.end.getDate() + 1);
//console.log(`Adjusted Program ${index + 1} to next day: Start: ${progTime.start.toLocaleString()}, End: ${progTime.end.toLocaleString()}`);
}
});
return progTimes;
}
inverterProg.capacity = parseInt(prog.capacity.state);
inverterProg.entityID = entityID;
}


function assignInverterProgValues(prog, entityID) {
if (prog.charge.state === 'No Grid or Gen' || prog.charge.state === '0' || prog.charge.state === 'off') {
inverterProg.charge = 'none';
} else {
inverterProg.charge = 'both';
}

inverterProg.capacity = parseInt(prog.capacity.state);
inverterProg.entityID = entityID;
}

break;
}
}

if (gridVoltage != null && !Number.isNaN(gridVoltage) && inverterModel == InverterModel.Solis) {
// the grid voltage can sometimes read decimals like 0.1, in cases where there is power trickled back.
gridStatus = gridVoltage > 50 ? 'on' : 'off';
Expand Down

0 comments on commit ac3a52c

Please sign in to comment.