Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"uplot": "^1.6.32"
},
"devDependencies": {
"@types/react": "^18.2.43",
Expand Down
113 changes: 83 additions & 30 deletions web/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ body {
.value-success {
font-weight: 600;
color: var(--color-success);
font-size: 0.875rem;
font-size: 0.65rem;
}

.value-warning {
Expand All @@ -162,7 +162,7 @@ body {
.value-error {
font-weight: 600;
color: var(--color-error);
font-size: 0.875rem;
font-size: 0.65rem;
}

.miners-list {
Expand Down Expand Up @@ -239,7 +239,7 @@ body {
right: 0;
bottom: 0;
background-image: url("../assets/ems.png");
background-size: cover;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
z-index: 0;
Expand All @@ -252,6 +252,8 @@ body {
justify-content: center;
align-items: center;
min-height: 250px;
width: 100%;
height: 100%;
}

.pv-power-display {
Expand Down Expand Up @@ -392,26 +394,38 @@ body {
.mpc-table {
width: 100%;
border-collapse: collapse;
font-size: 0.875rem;
font-size: 0.7rem;
table-layout: fixed;
}

.mpc-table thead {
background-color: rgba(51, 65, 85, 0.7);
}

.mpc-table th {
padding: 0.75rem 1rem;
padding: 0.4rem 0.5rem;
text-align: left;
font-weight: 600;
color: var(--color-text);
border-bottom: 2px solid var(--color-border);
text-transform: uppercase;
font-size: 0.75rem;
letter-spacing: 0.05em;
font-size: 0.65rem;
letter-spacing: 0.03em;
}

.mpc-table th:first-child,
.mpc-table td:first-child {
width: 120px;
}

.mpc-table th:not(:first-child),
.mpc-table td:not(:first-child) {
width: 25px;
text-align: center;
}

.mpc-table td {
padding: 0.75rem 1rem;
padding: 0.4rem 0.5rem;
border-bottom: 1px solid var(--color-border);
color: var(--color-text);
}
Expand All @@ -428,29 +442,15 @@ body {
border-bottom: none;
}

/* Prevent wrapping in forecast and profit columns */
.mpc-table th:nth-child(5),
.mpc-table th:nth-child(6),
.mpc-table th:nth-child(7),
.mpc-table th:nth-child(8),
.mpc-table th:nth-child(9),
.mpc-table td:nth-child(5),
.mpc-table td:nth-child(6),
.mpc-table td:nth-child(7),
.mpc-table td:nth-child(8),
.mpc-table td:nth-child(9) {
white-space: nowrap;
}

/* Forecast data header styling */
.mpc-table thead tr:first-child th {
vertical-align: middle;
}

.mpc-table thead tr:nth-child(2) th {
padding-top: 0.5rem;
padding-bottom: 0.75rem;
font-size: 0.7rem;
padding-top: 0.3rem;
padding-bottom: 0.4rem;
font-size: 0.6rem;
}

.action-charge,
Expand Down Expand Up @@ -513,19 +513,72 @@ body {
}

.devices-section {
min-height: 200px;
min-height: auto;
padding: 1rem;
}

.devices-section::before {
/* Hide background image on mobile */
display: none;
}

.devices-content {
min-height: 150px;
min-height: auto;
flex-direction: column;
gap: 1rem;
padding: 0;
position: static !important;
}

/* Wrapper for power displays with mobile labels */
.devices-content .power-display-wrapper {
position: static !important;
margin: 0 auto;
width: 100%;
max-width: 280px;
display: flex;
flex-direction: column;
align-items: center;
}

/* Show label from data attribute on mobile */
.devices-content .power-display-wrapper::before {
content: attr(data-mobile-label);
font-size: 0.875rem;
font-weight: 600;
color: var(--color-text-secondary);
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: 0.5rem;
text-align: center;
}

/* Convert absolute positioned PowerDisplay components to static flow on mobile */
.devices-content .power-display-wrapper .pv-power-display {
position: static !important;
margin: 0 auto;
width: 100%;
padding: 1rem 1.5rem;
display: flex;
flex-direction: column;
align-items: center;
}

.pv-power-display {
padding: 1.5rem 2rem;
.devices-content .solar-info {
position: static !important;
width: 100% !important;
max-width: 280px;
margin: 0 auto;
}

.pv-power-value {
font-size: 2rem;
font-size: 1.5rem;
}

.pv-power-label {
font-size: 0.875rem;
margin-bottom: 0.5rem;
margin-top: 0 !important;
}

.mpc-summary {
Expand Down
101 changes: 67 additions & 34 deletions web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,48 +129,81 @@ function App() {
<section className="card devices-section">
<h2>Devices</h2>
<div className="devices-content" style={{ position: "relative" }}>
<PowerDisplay
value={health?.ems?.current_pv_power}
style={{ position: "absolute", top: "202px", right: "170px" }}
/>
<div
className="power-display-wrapper"
data-mobile-label="Solar Power"
>
<PowerDisplay
value={health?.ems?.current_pv_power}
style={{ position: "absolute", top: "202px", right: "170px" }}
/>
</div>

<PowerDisplay
value={health?.ems?.ess_power}
invertColors={true}
label={
<div
className="power-display-wrapper"
data-mobile-label={
health?.ems?.ess_soc !== undefined
? `${health.ems.ess_soc.toFixed(1)}%`
: "N/A"
? `Battery (${health.ems.ess_soc.toFixed(1)}%)`
: "Battery"
}
style={{ position: "absolute", top: "643px", right: "622px" }}
/>
>
<PowerDisplay
value={health?.ems?.ess_power}
invertColors={true}
label={
health?.ems?.ess_soc !== undefined
? `${health.ems.ess_soc.toFixed(1)}%`
: "N/A"
}
style={{ position: "absolute", top: "643px", right: "622px" }}
/>
</div>

<PowerDisplay
value={
health?.ems?.grid_sensor_status === 1
? health?.ems?.grid_sensor_active_power
: undefined
}
style={{ position: "absolute", top: "556px", left: "220px" }}
/>
<div
className="power-display-wrapper"
data-mobile-label="Grid Power"
>
<PowerDisplay
value={
health?.ems?.grid_sensor_status === 1
? health?.ems?.grid_sensor_active_power
: undefined
}
style={{ position: "absolute", top: "556px", left: "220px" }}
/>
</div>

<PowerDisplay
value={health?.ems?.plant_active_power}
label="Active Power"
invertColors={true}
showLabel={true}
style={{ position: "absolute", top: "194px", left: "223px" }}
/>
<div
className="power-display-wrapper"
data-mobile-label="Plant Active Power"
>
<PowerDisplay
value={health?.ems?.plant_active_power}
label="Active Power"
invertColors={true}
showLabel={true}
style={{ position: "absolute", top: "194px", left: "223px" }}
/>
</div>

<PowerDisplay
value={health?.ems?.dc_charger_output_power}
label={
<div
className="power-display-wrapper"
data-mobile-label={
health?.ems?.dc_charger_vehicle_soc !== undefined
? `${health.ems.dc_charger_vehicle_soc.toFixed(1)}%`
: "N/A"
? `EV Charger (${health.ems.dc_charger_vehicle_soc.toFixed(1)}%)`
: "EV Charger"
}
style={{ position: "absolute", top: "428px", right: "162px" }}
/>
>
<PowerDisplay
value={health?.ems?.dc_charger_output_power}
label={
health?.ems?.dc_charger_vehicle_soc !== undefined
? `${health.ems.dc_charger_vehicle_soc.toFixed(1)}%`
: "N/A"
}
style={{ position: "absolute", top: "428px", right: "162px" }}
/>
</div>

<SolarInfo
solarAngle={health?.sun?.solar_angle}
Expand Down
Loading