Fixes power net TGUI BSOD if console isn't connected to a grid (#14985)

This commit is contained in:
dearmochi
2020-11-25 19:41:06 +00:00
committed by GitHub
parent 0d53f4a964
commit 730060ee56
3 changed files with 168 additions and 143 deletions
+9 -5
View File
@@ -29,14 +29,18 @@
data["select_monitor"] = TRUE
data["powermonitors"] = GLOB.powermonitor_repository.powermonitor_data()
if(powermonitor && !isnull(powermonitor.powernet))
if(powermonitor)
if(select_monitor && (powermonitor.stat & (NOPOWER|BROKEN)))
powermonitor = null
return
data["poweravail"] = DisplayPower(powermonitor.powernet.viewavail)
data["powerdemand"] = DisplayPower(powermonitor.powernet.viewload)
data["history"] = powermonitor.history
data["apcs"] = GLOB.apc_repository.apc_data(powermonitor.powernet)
if(powermonitor.powernet)
data["poweravail"] = DisplayPower(powermonitor.powernet.viewavail)
data["powerdemand"] = DisplayPower(powermonitor.powernet.viewload)
data["history"] = powermonitor.history
data["apcs"] = GLOB.apc_repository.apc_data(powermonitor.powernet)
data["no_powernet"] = FALSE
else
data["no_powernet"] = TRUE
return data
+158 -137
View File
@@ -2,11 +2,11 @@ import { map, sortBy } from 'common/collections';
import { flow } from 'common/fp';
import { toFixed } from 'common/math';
import { pureComponentHooks } from 'common/react';
import { Component, Fragment } from 'inferno';
import { decodeHtmlEntities } from 'common/string';
import { Section, Box, Button, Flex, LabeledList, ProgressBar, ColorBox, Chart, Table, Icon } from "../components";
import { Window } from "../layouts";
import { Fragment } from 'inferno';
import { useBackend, useLocalState } from "../backend";
import { Box, Button, Chart, ColorBox, Flex, Icon, LabeledList, ProgressBar, Section, Table } from "../components";
import { Window } from "../layouts";
const PEAK_DRAW = 600000;
export const PowerMonitor = (props, context) => {
@@ -70,31 +70,162 @@ const DataView = (props, context) => {
history,
apcs,
select_monitor,
no_powernet,
} = data;
const [
sortByField,
setSortByField,
] = useLocalState(context, 'sortByField', null);
const supply = history.supply[history.supply.length - 1] || 0;
const demand = history.demand[history.demand.length - 1] || 0;
const supplyData = history.supply.map((value, i) => [i, value]);
const demandData = history.demand.map((value, i) => [i, value]);
const maxValue = Math.max(
PEAK_DRAW,
...history.supply,
...history.demand);
// Process area data
const parsedApcs = flow([
map((apc, i) => ({
...apc,
// Generate a unique id
id: apc.name + i,
})),
sortByField === 'name' && sortBy(apc => apc.Name),
sortByField === 'charge' && sortBy(apc => -apc.CellPct),
sortByField === 'draw' && sortBy(apc => -apc.Load),
])(apcs);
let body;
if (no_powernet) {
body = (
<Box color="bad" textAlign="center">
<Icon
name="exclamation-triangle"
size="2"
my="0.5rem"
/><br />
Warning: The monitor is not connected to power grid via cable!
</Box>
);
} else {
const [
sortByField,
setSortByField,
] = useLocalState(context, 'sortByField', null);
const supply = history.supply[history.supply.length - 1] || 0;
const demand = history.demand[history.demand.length - 1] || 0;
const supplyData = history.supply.map((value, i) => [i, value]);
const demandData = history.demand.map((value, i) => [i, value]);
const maxValue = Math.max(
PEAK_DRAW,
...history.supply,
...history.demand);
// Process area data
const parsedApcs = flow([
map((apc, i) => ({
...apc,
// Generate a unique id
id: apc.name + i,
})),
sortByField === 'name' && sortBy(apc => apc.Name),
sortByField === 'charge' && sortBy(apc => -apc.CellPct),
sortByField === 'draw' && sortBy(apc => -apc.Load),
])(apcs);
body = (
<Fragment>
<Flex spacing={1}>
<Flex.Item width="200px">
<Section>
<LabeledList>
<LabeledList.Item label="Supply">
<ProgressBar
value={supply}
minValue={0}
maxValue={maxValue}
color="green">
{toFixed(supply / 1000) + ' kW'}
</ProgressBar>
</LabeledList.Item>
<LabeledList.Item label="Draw">
<ProgressBar
value={demand}
minValue={0}
maxValue={maxValue}
color="red">
{toFixed(demand / 1000) + ' kW'}
</ProgressBar>
</LabeledList.Item>
</LabeledList>
</Section>
</Flex.Item>
<Flex.Item grow={1}>
<Section position="relative" height="100%">
<Chart.Line
fillPositionedParent
data={supplyData}
rangeX={[0, supplyData.length - 1]}
rangeY={[0, maxValue]}
strokeColor="rgba(32, 177, 66, 1)"
fillColor="rgba(32, 177, 66, 0.25)" />
<Chart.Line
fillPositionedParent
data={demandData}
rangeX={[0, demandData.length - 1]}
rangeY={[0, maxValue]}
strokeColor="rgba(219, 40, 40, 1)"
fillColor="rgba(219, 40, 40, 0.25)" />
</Section>
</Flex.Item>
</Flex>
<Box mb={1}>
<Box inline mr={2} color="label">
Sort by:
</Box>
<Button.Checkbox
checked={sortByField === 'name'}
content="Name"
onClick={() => setSortByField(sortByField !== 'name' && 'name')} />
<Button.Checkbox
checked={sortByField === 'charge'}
content="Charge"
onClick={() => setSortByField(
sortByField !== 'charge' && 'charge'
)} />
<Button.Checkbox
checked={sortByField === 'draw'}
content="Draw"
onClick={() => setSortByField(sortByField !== 'draw' && 'draw')} />
</Box>
<Table>
<Table.Row header>
<Table.Cell>
Area
</Table.Cell>
<Table.Cell collapsing>
Charge
</Table.Cell>
<Table.Cell textAlign="right">
Draw
</Table.Cell>
<Table.Cell collapsing title="Equipment">
Eqp
</Table.Cell>
<Table.Cell collapsing title="Lighting">
Lgt
</Table.Cell>
<Table.Cell collapsing title="Environment">
Env
</Table.Cell>
</Table.Row>
{parsedApcs.map((area, i) => (
<Table.Row
key={area.id}
className="Table__row candystripe">
<Table.Cell>
{decodeHtmlEntities(area.Name)}
</Table.Cell>
<Table.Cell className="Table__cell text-right text-nowrap">
<AreaCharge
charging={area.CellStatus}
charge={area.CellPct} />
</Table.Cell>
<Table.Cell className="Table__cell text-right text-nowrap">
{area.Load}
</Table.Cell>
<Table.Cell className="Table__cell text-center text-nowrap">
<AreaStatusColorBox status={area.Equipment} />
</Table.Cell>
<Table.Cell className="Table__cell text-center text-nowrap">
<AreaStatusColorBox status={area.Lights} />
</Table.Cell>
<Table.Cell className="Table__cell text-center text-nowrap">
<AreaStatusColorBox status={area.Environment} />
</Table.Cell>
</Table.Row>
))}
</Table>
</Fragment>
);
}
return (
<Section title={powermonitor}
@@ -109,117 +240,7 @@ const DataView = (props, context) => {
)}
</Box>
}>
<Flex spacing={1}>
<Flex.Item width="200px">
<Section>
<LabeledList>
<LabeledList.Item label="Supply">
<ProgressBar
value={supply}
minValue={0}
maxValue={maxValue}
color="green">
{toFixed(supply / 1000) + ' kW'}
</ProgressBar>
</LabeledList.Item>
<LabeledList.Item label="Draw">
<ProgressBar
value={demand}
minValue={0}
maxValue={maxValue}
color="red">
{toFixed(demand / 1000) + ' kW'}
</ProgressBar>
</LabeledList.Item>
</LabeledList>
</Section>
</Flex.Item>
<Flex.Item grow={1}>
<Section position="relative" height="100%">
<Chart.Line
fillPositionedParent
data={supplyData}
rangeX={[0, supplyData.length - 1]}
rangeY={[0, maxValue]}
strokeColor="rgba(32, 177, 66, 1)"
fillColor="rgba(32, 177, 66, 0.25)" />
<Chart.Line
fillPositionedParent
data={demandData}
rangeX={[0, demandData.length - 1]}
rangeY={[0, maxValue]}
strokeColor="rgba(219, 40, 40, 1)"
fillColor="rgba(219, 40, 40, 0.25)" />
</Section>
</Flex.Item>
</Flex>
<Box mb={1}>
<Box inline mr={2} color="label">
Sort by:
</Box>
<Button.Checkbox
checked={sortByField === 'name'}
content="Name"
onClick={() => setSortByField(sortByField !== 'name' && 'name')} />
<Button.Checkbox
checked={sortByField === 'charge'}
content="Charge"
onClick={() => setSortByField(
sortByField !== 'charge' && 'charge'
)} />
<Button.Checkbox
checked={sortByField === 'draw'}
content="Draw"
onClick={() => setSortByField(sortByField !== 'draw' && 'draw')} />
</Box>
<Table>
<Table.Row header>
<Table.Cell>
Area
</Table.Cell>
<Table.Cell collapsing>
Charge
</Table.Cell>
<Table.Cell textAlign="right">
Draw
</Table.Cell>
<Table.Cell collapsing title="Equipment">
Eqp
</Table.Cell>
<Table.Cell collapsing title="Lighting">
Lgt
</Table.Cell>
<Table.Cell collapsing title="Environment">
Env
</Table.Cell>
</Table.Row>
{parsedApcs.map((area, i) => (
<Table.Row
key={area.id}
className="Table__row candystripe">
<Table.Cell>
{decodeHtmlEntities(area.Name)}
</Table.Cell>
<Table.Cell className="Table__cell text-right text-nowrap">
<AreaCharge
charging={area.CellStatus}
charge={area.CellPct} />
</Table.Cell>
<Table.Cell className="Table__cell text-right text-nowrap">
{area.Load}
</Table.Cell>
<Table.Cell className="Table__cell text-center text-nowrap">
<AreaStatusColorBox status={area.Equipment} />
</Table.Cell>
<Table.Cell className="Table__cell text-center text-nowrap">
<AreaStatusColorBox status={area.Lights} />
</Table.Cell>
<Table.Cell className="Table__cell text-center text-nowrap">
<AreaStatusColorBox status={area.Environment} />
</Table.Cell>
</Table.Row>
))}
</Table>
{body}
</Section>
);
};
File diff suppressed because one or more lines are too long