diff --git a/plugins/lime-plugin-rx/src/icons/gearIcon.tsx b/plugins/lime-plugin-rx/src/icons/gearIcon.tsx
new file mode 100644
index 000000000..e35514260
--- /dev/null
+++ b/plugins/lime-plugin-rx/src/icons/gearIcon.tsx
@@ -0,0 +1,7 @@
+import { IconProps, SvgIcon } from "components/icons/SvgIcon";
+
+export const GearIcon = ({ ...props }: IconProps) => (
+
+
+
+);
diff --git a/plugins/lime-plugin-rx/src/rxPage.tsx b/plugins/lime-plugin-rx/src/rxPage.tsx
index 355243d25..196218b41 100644
--- a/plugins/lime-plugin-rx/src/rxPage.tsx
+++ b/plugins/lime-plugin-rx/src/rxPage.tsx
@@ -3,6 +3,7 @@ import { Fragment } from "preact";
import { Footer } from "plugins/lime-plugin-rx/src/components/footer";
import { Alignment } from "plugins/lime-plugin-rx/src/sections/alignment";
import { InternetPath } from "plugins/lime-plugin-rx/src/sections/internetPath";
+import { System } from "plugins/lime-plugin-rx/src/sections/system";
import { Wired } from "plugins/lime-plugin-rx/src/sections/wired";
const Page = ({}) => {
@@ -16,6 +17,7 @@ const Page = ({}) => {
+
diff --git a/plugins/lime-plugin-rx/src/sections/system.tsx b/plugins/lime-plugin-rx/src/sections/system.tsx
new file mode 100644
index 000000000..25315e304
--- /dev/null
+++ b/plugins/lime-plugin-rx/src/sections/system.tsx
@@ -0,0 +1,85 @@
+import { Trans, plural, t } from "@lingui/macro";
+import { Fragment } from "preact";
+
+import {
+ IconsClassName,
+ Section,
+ SectionTitle,
+} from "plugins/lime-plugin-rx/src/components/components";
+import { GearIcon } from "plugins/lime-plugin-rx/src/icons/gearIcon";
+import { useNodeStatus } from "plugins/lime-plugin-rx/src/rxQueries";
+
+import { useBoardData } from "utils/queries";
+import { IGetBoardDataResponse } from "utils/types";
+
+const toHHMMSS = (seconds: string, plus: number) => {
+ const secNum = parseInt(seconds, 10) + plus;
+ const days = Math.floor(secNum / 86400);
+ const hours = Math.floor(secNum / 3600) % 24;
+ const mins = Math.floor(secNum / 60) % 60;
+ const secs = secNum % 60;
+ const daysText = days
+ ? plural(days, { one: "# day", other: "# days" })
+ : null;
+ const hoursText = hours
+ ? plural(hours, { one: "# hour", other: "# hours" })
+ : null;
+ const minsText = mins
+ ? plural(mins, { one: "# minute", other: "# minutes" })
+ : null;
+ const secsText = secs
+ ? plural(secs, { one: "# second", other: "# seconds" })
+ : null;
+ const allTexts = [daysText, hoursText, minsText, secsText];
+ return allTexts.filter((x) => x !== null).join(", ");
+};
+
+const SystemInfo = () => {
+ const { data: node } = useNodeStatus();
+ const { data: bd } = useBoardData();
+
+ const boardData = bd as IGetBoardDataResponse;
+ const secNum = parseInt(node?.uptime, 10);
+ const attributes = [
+ {
+ label: t`Uptime`,
+ value: toHHMMSS(node?.uptime, 0),
+ },
+ { label: t`Device`, value: boardData.board_name },
+ { label: t`Firmware`, value: boardData.release.description },
+ ];
+ return (
+
+
+ {attributes.map((attribute, i) => (
+
+
+ {attribute.label}:
+
+
+ {attribute.value}
+
+
+ ))}
+
+
+ );
+};
+
+export const System = () => {
+ const { isLoading: isLoadingNodeStatus } = useNodeStatus();
+ const { isLoading: isLoadingBoardData } = useBoardData();
+
+ const isLoading = isLoadingBoardData || isLoadingNodeStatus;
+
+ return (
+
+ }>
+ System
+
+
+ {isLoading ? Loading... : }
+
+
+ );
+};
diff --git a/src/utils/types.ts b/src/utils/types.ts
new file mode 100644
index 000000000..3e9094aa7
--- /dev/null
+++ b/src/utils/types.ts
@@ -0,0 +1,15 @@
+export interface IGetBoardDataResponse {
+ kernel: string;
+ hostname: string;
+ system: string;
+ model: string;
+ board_name: string;
+ rootfs_type: string;
+ release: {
+ distribution: string;
+ version: string;
+ revision: string;
+ target: string;
+ description: string;
+ };
+}