mirror of
https://github.com/henrygd/beszel.git
synced 2025-12-17 10:46:16 +01:00
add battery charge monitoring
This commit is contained in:
@@ -18,6 +18,7 @@ export default function AreaChartDefault({
|
||||
tickFormatter,
|
||||
contentFormatter,
|
||||
dataPoints,
|
||||
domain,
|
||||
}: // logRender = false,
|
||||
{
|
||||
chartData: ChartData
|
||||
@@ -26,6 +27,7 @@ export default function AreaChartDefault({
|
||||
tickFormatter: (value: number, index: number) => string
|
||||
contentFormatter: ({ value, payload }: { value: number; payload: SystemStatsRecord }) => string
|
||||
dataPoints?: DataPoint[]
|
||||
domain?: [number, number]
|
||||
// logRender?: boolean
|
||||
}) {
|
||||
const { yAxisWidth, updateYAxisWidth } = useYAxisWidth()
|
||||
@@ -51,7 +53,7 @@ export default function AreaChartDefault({
|
||||
orientation={chartData.orientation}
|
||||
className="tracking-tighter"
|
||||
width={yAxisWidth}
|
||||
domain={[0, max ?? "auto"]}
|
||||
domain={domain ?? [0, max ?? "auto"]}
|
||||
tickFormatter={(value, index) => updateYAxisWidth(tickFormatter(value, index))}
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
|
||||
@@ -41,6 +41,7 @@ import { timeTicks } from "d3-time"
|
||||
import { useLingui } from "@lingui/react/macro"
|
||||
import { $router, navigate } from "../router"
|
||||
import { getPagePath } from "@nanostores/router"
|
||||
import { batteryStateTranslations } from "@/lib/i18n"
|
||||
|
||||
const AreaChartDefault = lazy(() => import("../charts/area-chart"))
|
||||
const ContainerChart = lazy(() => import("../charts/container-chart"))
|
||||
@@ -668,6 +669,35 @@ export default function SystemDetail({ name }: { name: string }) {
|
||||
</ChartCard>
|
||||
)}
|
||||
|
||||
{/* Battery chart */}
|
||||
{systemStats.at(-1)?.stats.bat && (
|
||||
<ChartCard
|
||||
empty={dataEmpty}
|
||||
grid={grid}
|
||||
title={t`Battery`}
|
||||
description={`${t({
|
||||
message: "Current state",
|
||||
comment: "Context: Battery state",
|
||||
})}: ${batteryStateTranslations[systemStats.at(-1)?.stats.bat![1] ?? 0]()}`}
|
||||
>
|
||||
<AreaChartDefault
|
||||
chartData={chartData}
|
||||
maxToggled={maxValues}
|
||||
dataPoints={[
|
||||
{
|
||||
label: t`Charge`,
|
||||
dataKey: ({ stats }) => stats?.bat?.[0],
|
||||
color: "1",
|
||||
opacity: 0.35,
|
||||
},
|
||||
]}
|
||||
domain={[0, 100]}
|
||||
tickFormatter={(val) => `${val}%`}
|
||||
contentFormatter={({ value }) => `${value}%`}
|
||||
/>
|
||||
</ChartCard>
|
||||
)}
|
||||
|
||||
{/* GPU power draw chart */}
|
||||
{hasGpuPowerData && (
|
||||
<ChartCard
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as RechartsPrimitive from "recharts"
|
||||
import { chartTimeData, cn } from "@/lib/utils"
|
||||
import { ChartData } from "@/types"
|
||||
|
||||
import type { JSX } from "react";
|
||||
import type { JSX } from "react"
|
||||
|
||||
// Format: { THEME_NAME: CSS_SELECTOR }
|
||||
const THEMES = { light: "", dark: ".dark" } as const
|
||||
@@ -43,9 +43,9 @@ const ChartContainer = React.forwardRef<
|
||||
const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`
|
||||
|
||||
return (
|
||||
//<ChartContext.Provider value={{ config }}>
|
||||
//</ChartContext.Provider>
|
||||
<div
|
||||
//<ChartContext.Provider value={{ config }}>
|
||||
//</ChartContext.Provider>
|
||||
<div
|
||||
data-chart={chartId}
|
||||
ref={ref}
|
||||
className={cn(
|
||||
@@ -54,10 +54,10 @@ const ChartContainer = React.forwardRef<
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{/* <ChartStyle id={chartId} config={config} /> */}
|
||||
<RechartsPrimitive.ResponsiveContainer>{children}</RechartsPrimitive.ResponsiveContainer>
|
||||
</div>
|
||||
);
|
||||
{/* <ChartStyle id={chartId} config={config} /> */}
|
||||
<RechartsPrimitive.ResponsiveContainer>{children}</RechartsPrimitive.ResponsiveContainer>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
ChartContainer.displayName = "Chart"
|
||||
|
||||
@@ -228,7 +228,7 @@ const ChartTooltipContent = React.forwardRef<
|
||||
{itemConfig?.label || item.name}
|
||||
</span>
|
||||
{item.value !== undefined && (
|
||||
<span className="font-medium tabular-nums text-foreground">
|
||||
<span className="font-medium text-foreground">
|
||||
{content && typeof content === "function"
|
||||
? content(item, key)
|
||||
: item.value.toLocaleString() + (unit ? unit : "")}
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
|
||||
.recharts-tooltip-wrapper {
|
||||
z-index: 1;
|
||||
@apply tabular-nums;
|
||||
}
|
||||
|
||||
.recharts-yAxis {
|
||||
|
||||
@@ -36,3 +36,13 @@ export enum SystemStatus {
|
||||
Pending = "pending",
|
||||
Paused = "paused",
|
||||
}
|
||||
|
||||
/** Battery state */
|
||||
export enum BatteryState {
|
||||
Unknown,
|
||||
Empty,
|
||||
Full,
|
||||
Charging,
|
||||
Discharging,
|
||||
Idle,
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import type { Messages } from "@lingui/core"
|
||||
import languages from "@/lib/languages"
|
||||
import { detect, fromStorage, fromNavigator } from "@lingui/detect-locale"
|
||||
import { messages as enMessages } from "@/locales/en/en"
|
||||
import { BatteryState } from "./enums"
|
||||
import { t } from "@lingui/core/macro"
|
||||
|
||||
// activates locale
|
||||
function activateLocale(locale: string, messages: Messages = enMessages) {
|
||||
@@ -54,3 +56,14 @@ export function getLocale() {
|
||||
}
|
||||
return locale
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
export const batteryStateTranslations = {
|
||||
[BatteryState.Unknown]: () => t({ message: "Unknown", comment: "Context: Battery state" }),
|
||||
[BatteryState.Empty]: () => t({ message: "Empty", comment: "Context: Battery state" }),
|
||||
[BatteryState.Full]: () => t({ message: "Full", comment: "Context: Battery state" }),
|
||||
[BatteryState.Charging]: () => t({ message: "Charging", comment: "Context: Battery state" }),
|
||||
[BatteryState.Discharging]: () => t({ message: "Discharging", comment: "Context: Battery state" }),
|
||||
[BatteryState.Idle]: () => t({ message: "Idle", comment: "Context: Battery state" }),
|
||||
} as const
|
||||
|
||||
4
beszel/site/src/types.d.ts
vendored
4
beszel/site/src/types.d.ts
vendored
@@ -1,5 +1,5 @@
|
||||
import { RecordModel } from "pocketbase"
|
||||
import { Unit, Os } from "./lib/enums"
|
||||
import { Unit, Os, BatteryState } from "./lib/enums"
|
||||
|
||||
// global window properties
|
||||
declare global {
|
||||
@@ -136,6 +136,8 @@ export interface SystemStats {
|
||||
efs?: Record<string, ExtraFsStats>
|
||||
/** GPU data */
|
||||
g?: Record<string, GPUData>
|
||||
/** battery percent and state */
|
||||
bat?: [number, BatteryState]
|
||||
}
|
||||
|
||||
export interface GPUData {
|
||||
|
||||
Reference in New Issue
Block a user