add peanut info widget
This commit is contained in:
parent
d3cabec07b
commit
8c64b3f28a
60
src/components/widgets/peanut/peanut.jsx
Normal file
60
src/components/widgets/peanut/peanut.jsx
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import useSWR from "swr";
|
||||||
|
import { FaCarBattery } from "react-icons/fa";
|
||||||
|
import { useTranslation } from "next-i18next";
|
||||||
|
|
||||||
|
import Error from "../widget/error";
|
||||||
|
import Resource from "../widget/resource";
|
||||||
|
|
||||||
|
export default function Widget({ options }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { expanded } = options;
|
||||||
|
let { refresh } = options;
|
||||||
|
if (!refresh) refresh = 1500;
|
||||||
|
|
||||||
|
const { data, error } = useSWR(
|
||||||
|
`/api/widgets/peanut?${new URLSearchParams({ ...options }).toString()}`,
|
||||||
|
{
|
||||||
|
refreshInterval: refresh,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error || data?.error) {
|
||||||
|
return <Error options={options} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return (
|
||||||
|
<Resource
|
||||||
|
icon={FaCarBattery}
|
||||||
|
value="-"
|
||||||
|
label="Load"
|
||||||
|
expandedValue="-"
|
||||||
|
expandedLabel="Battery"
|
||||||
|
expanded={expanded}
|
||||||
|
percentage="0"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Resource
|
||||||
|
icon={FaCarBattery}
|
||||||
|
value={t("common.number", {
|
||||||
|
value: data['ups.load'],
|
||||||
|
style: "unit",
|
||||||
|
unit: "percent",
|
||||||
|
maximumFractionDigits: 0,
|
||||||
|
})}
|
||||||
|
label="Load"
|
||||||
|
expandedValue={t("common.number", {
|
||||||
|
value: data['battery.charge'],
|
||||||
|
style: "unit",
|
||||||
|
unit: "percent",
|
||||||
|
maximumFractionDigits: 0,
|
||||||
|
})}
|
||||||
|
expandedLabel="Battery"
|
||||||
|
percentage={data['ups.load']}
|
||||||
|
expanded={expanded}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -12,6 +12,7 @@ const widgetMappings = {
|
|||||||
logo: dynamic(() => import("components/widgets/logo/logo"), { ssr: false }),
|
logo: dynamic(() => import("components/widgets/logo/logo"), { ssr: false }),
|
||||||
unifi_console: dynamic(() => import("components/widgets/unifi_console/unifi_console")),
|
unifi_console: dynamic(() => import("components/widgets/unifi_console/unifi_console")),
|
||||||
glances: dynamic(() => import("components/widgets/glances/glances")),
|
glances: dynamic(() => import("components/widgets/glances/glances")),
|
||||||
|
peanut: dynamic(() => import("components/widgets/peanut/peanut")),
|
||||||
openmeteo: dynamic(() => import("components/widgets/openmeteo/openmeteo")),
|
openmeteo: dynamic(() => import("components/widgets/openmeteo/openmeteo")),
|
||||||
longhorn: dynamic(() => import("components/widgets/longhorn/longhorn")),
|
longhorn: dynamic(() => import("components/widgets/longhorn/longhorn")),
|
||||||
kubernetes: dynamic(() => import("components/widgets/kubernetes/kubernetes")),
|
kubernetes: dynamic(() => import("components/widgets/kubernetes/kubernetes")),
|
||||||
|
|||||||
55
src/pages/api/widgets/peanut.js
Normal file
55
src/pages/api/widgets/peanut.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { httpProxy } from "utils/proxy/http";
|
||||||
|
import createLogger from "utils/logger";
|
||||||
|
import { getPrivateWidgetOptions } from "utils/config/widget-helpers";
|
||||||
|
|
||||||
|
const logger = createLogger("peanut");
|
||||||
|
|
||||||
|
async function retrieveFromPeanutAPI(privateWidgetOptions, ups) {
|
||||||
|
let errorMessage;
|
||||||
|
const url = privateWidgetOptions?.options?.url;
|
||||||
|
if (!url) {
|
||||||
|
errorMessage = "Missing PeaNUT URL";
|
||||||
|
logger.error(errorMessage);
|
||||||
|
throw new Error(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
const apiUrl = `${url}/api/v1/devices/${ups || privateWidgetOptions?.options?.key}`;
|
||||||
|
const headers = {
|
||||||
|
"Accept-Encoding": "application/json",
|
||||||
|
};
|
||||||
|
const params = { method: "GET", headers };
|
||||||
|
|
||||||
|
const [status, , data] = await httpProxy(apiUrl, params);
|
||||||
|
|
||||||
|
if (status === 401) {
|
||||||
|
errorMessage = `Authorization failure getting data from peanut API. Data: ${data.toString()}`;
|
||||||
|
logger.error(errorMessage);
|
||||||
|
throw new Error(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status !== 200) {
|
||||||
|
errorMessage = `HTTP ${status} getting data from peanut API. Data: ${data.toString()}`;
|
||||||
|
logger.error(errorMessage);
|
||||||
|
throw new Error(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.parse(Buffer.from(data).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function handler(req, res) {
|
||||||
|
const { key } = req.query;
|
||||||
|
|
||||||
|
const privateWidgets = await getPrivateWidgetOptions();
|
||||||
|
const privateWidgetOptions = privateWidgets.find((o) => o.type === "peanut");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const upsData = await retrieveFromPeanutAPI(privateWidgetOptions, key);
|
||||||
|
const data = {
|
||||||
|
...upsData
|
||||||
|
};
|
||||||
|
|
||||||
|
return res.status(200).send(data);
|
||||||
|
} catch (e) {
|
||||||
|
return res.status(400).json({ error: e.message });
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user