diff --git a/public/locales/en/common.json b/public/locales/en/common.json
index 51259046..79138cad 100755
--- a/public/locales/en/common.json
+++ b/public/locales/en/common.json
@@ -514,6 +514,16 @@
"origin_ip": "Origin IP",
"status": "Status"
},
+ "pfsense": {
+ "load": "Load Avg",
+ "memory": "Mem Usage",
+ "wanStatus": "WAN Status",
+ "up": "Up",
+ "down": "Down",
+ "temp": "Temp",
+ "disk": "Disk Usage",
+ "wanIP": "WAN IP"
+ },
"proxmoxbackupserver": {
"datastore_usage": "Datastore",
"failed_tasks_24h": "Failed Tasks 24h",
diff --git a/src/utils/config/service-helpers.js b/src/utils/config/service-helpers.js
index c38fe47c..4942aeae 100644
--- a/src/utils/config/service-helpers.js
+++ b/src/utils/config/service-helpers.js
@@ -267,7 +267,7 @@ export function cleanServiceGroups(groups) {
namespace, // kubernetes widget
app,
podSelector,
- wan, // opnsense widget,
+ wan, // opnsense widget, pfsense widget
enableBlocks, // emby/jellyfin
enableNowPlaying,
volume, // diskstation widget
@@ -299,10 +299,10 @@ export function cleanServiceGroups(groups) {
if (app) cleanedService.widget.app = app;
if (podSelector) cleanedService.widget.podSelector = podSelector;
}
- if (type === "opnsense") {
+ if (["opnsense", "pfsense"].includes(type)) {
if (wan) cleanedService.widget.wan = wan;
}
- if (type === "emby" || type === "jellyfin") {
+ if (["emby", "jellyfin"].includes(type)) {
if (enableBlocks !== undefined) cleanedService.widget.enableBlocks = JSON.parse(enableBlocks);
if (enableNowPlaying !== undefined) cleanedService.widget.enableNowPlaying = JSON.parse(enableNowPlaying);
}
diff --git a/src/widgets/components.js b/src/widgets/components.js
index 7aeb8b45..754898bf 100644
--- a/src/widgets/components.js
+++ b/src/widgets/components.js
@@ -52,6 +52,7 @@ const components = {
opnsense: dynamic(() => import("./opnsense/component")),
overseerr: dynamic(() => import("./overseerr/component")),
paperlessngx: dynamic(() => import("./paperlessngx/component")),
+ pfsense: dynamic(() => import("./pfsense/component")),
photoprism: dynamic(() => import("./photoprism/component")),
proxmoxbackupserver: dynamic(() => import("./proxmoxbackupserver/component")),
pihole: dynamic(() => import("./pihole/component")),
diff --git a/src/widgets/pfsense/component.jsx b/src/widgets/pfsense/component.jsx
new file mode 100644
index 00000000..803f0307
--- /dev/null
+++ b/src/widgets/pfsense/component.jsx
@@ -0,0 +1,51 @@
+import { useTranslation } from "next-i18next";
+
+import Container from "components/services/widget/container";
+import Block from "components/services/widget/block";
+import useWidgetAPI from "utils/proxy/use-widget-api";
+
+export default function Component({ service }) {
+ const { t } = useTranslation();
+
+ const { widget } = service;
+
+ const { data: systemData, error: systemError } = useWidgetAPI(widget, "system");
+ const { data: interfaceData, error: interfaceError } = useWidgetAPI(widget, "interface");
+
+ const showWanIP = widget.fields?.filter(f => f !== 'wanIP').length <= 4 && widget.fields?.includes('wanIP');
+ const showDiskUsage = widget.fields?.filter(f => f !== 'disk').length <= 4 && widget.fields?.includes('disk');
+
+ if (systemError || interfaceError) {
+ const finalError = systemError ?? interfaceError;
+ return ;
+ }
+
+ if (!systemData || !interfaceData) {
+ return (
+
+
+
+
+
+ {showWanIP && }
+ {showDiskUsage && }
+
+ );
+ }
+
+ const wan = interfaceData.data.filter(l => l.hwif === widget.wan)[0];
+
+ return (
+
+
+
+
+ {t("pfsense.up")}:
+ {t("pfsense.down")}}
+ />
+ {showWanIP && }
+ {showDiskUsage && }
+
+ );
+}
diff --git a/src/widgets/pfsense/widget.js b/src/widgets/pfsense/widget.js
new file mode 100644
index 00000000..88aa44fd
--- /dev/null
+++ b/src/widgets/pfsense/widget.js
@@ -0,0 +1,24 @@
+
+import genericProxyHandler from "utils/proxy/handlers/generic";
+
+const widget = {
+ api: "{url}/api/v1/{endpoint}",
+ proxyHandler: genericProxyHandler,
+
+ mappings: {
+ system: {
+ endpoint: "status/system",
+ validate: [
+ "data"
+ ]
+ },
+ interface: {
+ endpoint: "status/interface",
+ validate: [
+ "data"
+ ]
+ }
+ },
+};
+
+export default widget;
diff --git a/src/widgets/widgets.js b/src/widgets/widgets.js
index 85fb62f8..f7b07a96 100644
--- a/src/widgets/widgets.js
+++ b/src/widgets/widgets.js
@@ -46,6 +46,7 @@ import ombi from "./ombi/widget";
import opnsense from "./opnsense/widget";
import overseerr from "./overseerr/widget";
import paperlessngx from "./paperlessngx/widget";
+import pfsense from "./pfsense/widget";
import photoprism from "./photoprism/widget";
import proxmoxbackupserver from "./proxmoxbackupserver/widget";
import pihole from "./pihole/widget";
@@ -130,6 +131,7 @@ const widgets = {
opnsense,
overseerr,
paperlessngx,
+ pfsense,
photoprism,
proxmoxbackupserver,
pihole,