Skip to content

Commit

Permalink
Added DLI calculation and display
Browse files Browse the repository at this point in the history
  • Loading branch information
maziggy committed Nov 2, 2024
1 parent 0e52779 commit da598d1
Showing 1 changed file with 155 additions and 140 deletions.
295 changes: 155 additions & 140 deletions dist/ppfdChart.min.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,145 +15,133 @@ class PPFDCustomCard extends LitElement {
this.title = 'PPFD Chart';
this.refresh_interval = 60;
this.lastUpdateTimestamp = new Date();
this.dli = null;
this.lhd = null;
}

// Define styles
static styles = css`
ha-card {
padding: 15px; /* Reduced padding */
box-sizing: border-box;
}
.main-container {
display: flex;
align-items: center;
width: 100%;
color: #ffffff;
background-color: #2c2c2e;
border-radius: 10px;
padding: 10px 10px; /* Reduced top and bottom padding */
box-shadow: 2px 4px 10px rgba(0, 0, 0, 0.2);
position: relative;
box-sizing: border-box;
}
.main-container::before {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
border-radius: 16px;
border: 2px solid rgba(100, 100, 255, 0.5);
pointer-events: none;
box-sizing: border-box;
}
.update-container {
font-size: 0.8em;
color: #ccc;
padding-right: 10px;
flex-shrink: 0;
min-width: 90px;
text-align: left;
}
.chart-container {
text-align: center;
position: relative;
width: 100%;
padding: 0 10px;
margin: 0 auto;
box-sizing: border-box;
}
.section-names {
display: flex;
justify-content: space-between;
width: 100%;
font-size: 0.9em;
color: #ffffff;
padding: 0 10px;
box-sizing: border-box;
position: relative;
}
.section-seeding {
flex: 1;
text-align: left;
padding-left: 5%;
}
.section-vegetation {
position: absolute;
left: 54%;
transform: translateX(-50%);
font-size: 0.9em;
color: #ffffff;
}
.section-flowering {
flex: 1;
text-align: right;
padding-right: 5%;
}
.chart-bar {
width: 100%;
height: 40px;
position: relative;
background: linear-gradient(to right, rgba(0, 9, 255, 1), rgba(4, 219, 190, 1), rgba(11, 230, 91, 1), rgba(255, 179, 0, 1), rgba(255, 3, 3, 1));
border-radius: 20px;
overflow: hidden;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.2);
margin-bottom: 10px;
}
.separator {
position: absolute;
top: 0;
bottom: 0;
width: 2px;
background-color: #333;
opacity: 0.7;
z-index: 10;
}
.separator:nth-child(1) { left: calc((600 - 100) / 1100 * 100%); }
.separator:nth-child(2) { left: calc((800 - 100) / 1100 * 100%); }
.marker {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
width: 32px;
height: 32px;
background: radial-gradient(circle at center, #f1c40f 0%, #f39c12 70%);
color: #222;
font-weight: bold;
font-size: 0.9em;
border: 3px solid rgba(255, 235, 59, 0.8);
border-radius: 50%;
box-shadow: 0 0 10px rgba(255, 223, 0, 0.8), 0 0 6px rgba(0, 0, 0, 0.3);
transform: translateX(-50%);
text-align: center;
}
.scales {
position: relative;
font-size: 0.8em;
color: #ffffff;
width: 100%;
box-sizing: border-box;
display: flex;
justify-content: space-between;
padding-top: 4px;
}
.scale-tick {
position: absolute;
width: 1px;
height: 10px;
background-color: #ffffff;
top: -10px;
left: 50%;
transform: translateX(-50%);
}
.scale-tick-label {
position: absolute;
transform: translateX(-50%);
margin-top: 2px;
font-size: 0.7em;
color: #ccc;
}
static styles = css`
ha-card {
padding: 15px;
box-sizing: border-box;
}
.main-container {
display: flex;
align-items: center;
width: 100%;
color: #ffffff;
background-color: #2c2c2e;
border-radius: 10px;
padding: 10px 10px;
box-shadow: 2px 4px 10px rgba(0, 0, 0, 0.2);
position: relative;
box-sizing: border-box;
}
.update-container {
font-size: 0.8em;
color: #ccc;
padding-right: 10px;
flex-shrink: 0;
min-width: 90px;
text-align: left;
}
.dli-display {
font-size: 1em;
color: #4CAF50;
background: rgba(0, 0, 0, 0.7);
padding: 5px 10px;
border-radius: 5px;
margin-top: 10px;
box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.3);
}
.chart-container {
text-align: center;
position: relative;
width: 100%;
padding: 0 10px;
margin: 0 auto;
box-sizing: border-box;
}
.section-names {
display: flex;
justify-content: space-between;
width: 100%;
font-size: 0.9em;
color: #ffffff;
padding: 0 10px;
box-sizing: border-box;
position: relative;
}
.chart-bar {
width: 100%;
height: 40px;
position: relative;
background: linear-gradient(to right, rgba(0, 9, 255, 1), rgba(4, 219, 190, 1), rgba(11, 230, 91, 1), rgba(255, 179, 0, 1), rgba(255, 3, 3, 1));
border-radius: 20px;
overflow: hidden;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.2);
margin-bottom: 10px;
}
.separator {
position: absolute;
top: 0;
bottom: 0;
width: 2px;
background-color: #333;
opacity: 0.7;
z-index: 10;
}
.separator:nth-child(1) { left: calc((600 - 100) / 1100 * 100%); }
.separator:nth-child(2) { left: calc((800 - 100) / 1100 * 100%); }
.marker {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
width: 32px;
height: 32px;
background: radial-gradient(circle at center, #f1c40f 0%, #f39c12 70%);
color: #222;
font-weight: bold;
font-size: 0.9em;
border: 3px solid rgba(255, 235, 59, 0.8);
border-radius: 50%;
box-shadow: 0 0 10px rgba(255, 223, 0, 0.8), 0 0 6px rgba(0, 0, 0, 0.3);
transform: translateX(-50%);
text-align: center;
}
.scales {
position: relative;
font-size: 0.8em;
color: #ffffff;
width: 100%;
box-sizing: border-box;
display: flex;
justify-content: space-between;
padding-top: 4px;
}
.scale-tick {
position: absolute;
width: 1px;
height: 10px;
background-color: #ffffff;
top: -10px;
left: 50%;
transform: translateX(-50%);
}
.scale-tick-label {
position: absolute;
transform: translateX(-50%);
margin-top: 2px;
font-size: 0.7em;
color: #ccc;
}
.section-vegetation {
position: absolute;
left: 54%; /* Adjusted rightward */
transform: translateX(-50%);
font-size: 0.9em;
color: #ffffff;
}
`;

setConfig(config) {
Expand All @@ -167,7 +155,6 @@ class PPFDCustomCard extends LitElement {

set hass(hass) {
this._hass = hass;

const entityId = this.entity;
if (!entityId) {
console.error("Entity ID is missing in the configuration.");
Expand All @@ -187,6 +174,8 @@ class PPFDCustomCard extends LitElement {
this.updateCurrentPPFD(currentPPFD);
this.updateLastUpdated(lastUpdated);
this.lastUpdateTimestamp = lastUpdated;

this.calculateDLI(currentPPFD);
} else {
console.warn("ShadowRoot or entity state is not available.");
}
Expand Down Expand Up @@ -245,14 +234,40 @@ class PPFDCustomCard extends LitElement {
}
}

calculateDLI(currentPPFD) {
const onTimeEntity = this._hass.states['time.growbox_light_scheduled_on_time'];
const offTimeEntity = this._hass.states['time.growbox_light_scheduled_off_time'];

if (onTimeEntity && offTimeEntity) {
const onTime = new Date(`1970-01-01T${onTimeEntity.state}`);
let offTime = new Date(`1970-01-01T${offTimeEntity.state}`);

if (offTime <= onTime) {
offTime.setHours(offTime.getHours() + 24);
}

const lightDurationMs = offTime - onTime;
this.lhd = Math.round(lightDurationMs / (1000 * 60 * 60));

this.dli = Math.round((currentPPFD * this.lhd * 3600) / 1000000);

const dliDisplayElement = this.shadowRoot.querySelector("#dli-display");
if (dliDisplayElement) {
dliDisplayElement.innerText = `DLI ${this.dli} @${this.lhd}h`;
}
} else {
console.warn("Scheduled light-on or light-off time entity is missing.");
}
}

render() {
return html`
<ha-card>
<div class="main-container">
<div class="update-container">
<div><a href="https://github.com/maziggy/ppfdChart/" target=_blank style="text-decoration: none; color: inherit;"><u><b>ppfdChart</u></b></a></div>
<div><br>Last Changed:<br><span id="update-time">Just now</span></div>
<div><br>PPFD in µmol/m²s</div>
<div>Last Changed:<br><span id="update-time">Just now</span></div>
<div class="dli-display" id="dli-display">Calculating...</div>
</div>
<div class="chart-container">
<div class="section-names">
Expand Down

0 comments on commit da598d1

Please sign in to comment.