diff --git a/public/locales/es/common.json b/public/locales/es/common.json
index a680a695..827b6cc4 100644
--- a/public/locales/es/common.json
+++ b/public/locales/es/common.json
@@ -18,13 +18,13 @@
"load": "Carga",
"cpu": "CPU",
"mem": "MEM",
- "temp": "TEMP",
- "max": "Max",
- "uptime": "UP",
- "months": "mo",
- "days": "d",
- "hours": "h",
- "minutes": "m"
+ "temp": "TEMPORAL",
+ "max": "Máximo",
+ "uptime": "ARRIBA",
+ "months": "Meses",
+ "days": "Días",
+ "hours": "Horas",
+ "minutes": "Minutos"
},
"docker": {
"rx": "Recibido",
@@ -234,10 +234,10 @@
"cpu": "Procesador",
"mem": "Memoria",
"wait": "Espere por favor",
- "temp": "TEMP",
- "uptime": "UP",
- "days": "d",
- "hours": "h"
+ "temp": "TEMPORAL",
+ "uptime": "ARRIBA",
+ "days": "Días",
+ "hours": "Horas"
},
"changedetectionio": {
"totalObserved": "Total Observados",
diff --git a/public/locales/ko/common.json b/public/locales/ko/common.json
index 1293ce9c..ebafd10b 100644
--- a/public/locales/ko/common.json
+++ b/public/locales/ko/common.json
@@ -42,13 +42,13 @@
"free": "남음",
"used": "사용",
"load": "부하",
- "temp": "TEMP",
- "max": "Max",
- "uptime": "UP",
- "months": "mo",
- "days": "d",
- "hours": "h",
- "minutes": "m"
+ "temp": "온도",
+ "max": "최대",
+ "uptime": "가동",
+ "months": "달",
+ "days": "일",
+ "hours": "시간",
+ "minutes": "분"
},
"unifi": {
"users": "사용자",
diff --git a/public/locales/uk/common.json b/public/locales/uk/common.json
index b3394925..0cdf4d7b 100644
--- a/public/locales/uk/common.json
+++ b/public/locales/uk/common.json
@@ -131,11 +131,11 @@
"mem": "Пам'ять",
"temp": "TEMP",
"max": "Max",
- "uptime": "UP",
- "months": "mo",
- "days": "d",
- "hours": "h",
- "minutes": "m"
+ "uptime": "Відправка",
+ "months": "міс",
+ "days": "д",
+ "hours": "г",
+ "minutes": "хв"
},
"unifi": {
"users": "Користувачі",
@@ -359,9 +359,9 @@
"mem": "Пам'ять",
"wait": "Будь ласка, зачекайте",
"temp": "TEMP",
- "uptime": "UP",
- "days": "d",
- "hours": "h"
+ "uptime": "Відправка",
+ "days": "д",
+ "hours": "г"
},
"quicklaunch": {
"bookmark": "Закладка",
diff --git a/public/locales/zh-CN/common.json b/public/locales/zh-CN/common.json
index 1d646d6d..6d65f709 100644
--- a/public/locales/zh-CN/common.json
+++ b/public/locales/zh-CN/common.json
@@ -18,13 +18,13 @@
"load": "负载",
"cpu": "处理器",
"mem": "内存",
- "temp": "TEMP",
- "max": "Max",
- "uptime": "UP",
- "months": "mo",
- "days": "d",
- "hours": "h",
- "minutes": "m"
+ "temp": "温度",
+ "max": "最大",
+ "uptime": "运行时间",
+ "months": "月",
+ "days": "天",
+ "hours": "时",
+ "minutes": "分"
},
"docker": {
"rx": "接收",
@@ -236,8 +236,8 @@
"wait": "请稍等",
"temp": "TEMP",
"uptime": "UP",
- "days": "d",
- "hours": "h"
+ "days": "天",
+ "hours": "时"
},
"changedetectionio": {
"totalObserved": "观察到的总数",
diff --git a/src/components/widgets/glances/glances.jsx b/src/components/widgets/glances/glances.jsx
index b0acdaa0..a6f4dfa8 100644
--- a/src/components/widgets/glances/glances.jsx
+++ b/src/components/widgets/glances/glances.jsx
@@ -6,6 +6,12 @@ import { useTranslation } from "next-i18next";
import UsageBar from "../resources/usage-bar";
+const cpuSensorLabels = ["cpu_thermal", "Core"];
+
+function convertToFahrenheit(t) {
+ return t * 9/5 + 32
+}
+
export default function Widget({ options }) {
const { t, i18n } = useTranslation();
@@ -65,10 +71,22 @@ export default function Widget({ options }) {
}
const unit = options.units === "imperial" ? "fahrenheit" : "celsius";
- let mainTemp;
- if (options.cputemp && data.sensors) {
- mainTemp = unit === "celsius" ? data.sensors.find(s => s.label.includes("cpu_thermal")).value : data.sensors.find(s => s.label.includes("cpu_thermal")).value * 5/9 + 32;
+ let mainTemp = 0;
+ let maxTemp = 80;
+ const cpuSensors = data.sensors?.filter(s => cpuSensorLabels.some(label => s.label.startsWith(label)) && s.type === "temperature_core");
+ if (options.cputemp && cpuSensors) {
+ try {
+ mainTemp = cpuSensors.reduce((acc, s) => acc + s.value, 0) / cpuSensors.length;
+ maxTemp = Math.max(cpuSensors.reduce((acc, s) => acc + s.warning, 0) / cpuSensors.length, maxTemp);
+ if (unit === "fahrenheit") {
+ mainTemp = convertToFahrenheit(mainTemp);
+ maxTemp = convertToFahrenheit(maxTemp);
+ }
+ } catch (e) {
+ // cpu sensor retrieval failed
+ }
}
+ const tempPercent = Math.round((mainTemp / maxTemp) * 100);
return (
@@ -107,7 +125,7 @@ export default function Widget({ options }) {
- {options.cputemp && mainTemp &&
+ {options.cputemp && mainTemp > 0 &&
(
@@ -122,6 +140,7 @@ export default function Widget({ options }) {
{t("glances.temp")}
+
)}
{options.uptime && data.uptime &&
@@ -134,6 +153,7 @@ export default function Widget({ options }) {
{t("glances.uptime")}
+
)}
diff --git a/src/components/widgets/resources/cputemp.jsx b/src/components/widgets/resources/cputemp.jsx
index d5cb6100..92c684e5 100644
--- a/src/components/widgets/resources/cputemp.jsx
+++ b/src/components/widgets/resources/cputemp.jsx
@@ -3,6 +3,12 @@ import { FaThermometerHalf } from "react-icons/fa";
import { BiError } from "react-icons/bi";
import { useTranslation } from "next-i18next";
+import UsageBar from "./usage-bar";
+
+function convertToFahrenheit(t) {
+ return t * 9/5 + 32
+}
+
export default function CpuTemp({ expanded, units }) {
const { t } = useTranslation();
@@ -21,7 +27,7 @@ export default function CpuTemp({ expanded, units }) {
);
}
- if (!data) {
+ if (!data || !data.cputemp) {
return (
@@ -41,9 +47,16 @@ export default function CpuTemp({ expanded, units }) {
);
}
+ let minTemp = 0;
+ let mainTemp = data.cputemp.main;
+ if (data.cputemp.cores?.length) {
+ mainTemp = data.cputemp.cores.reduce((a, b) => a + b) / data.cputemp.cores.length;
+ minTemp = Math.min(...data.cputemp.cores);
+ }
const unit = units === "imperial" ? "fahrenheit" : "celsius";
- const mainTemp = (unit === "celsius") ? data.cputemp.main : data.cputemp.main * 5/9 + 32;
- const maxTemp = (unit === "celsius") ? data.cputemp.max : data.cputemp.max * 5/9 + 32;
+ mainTemp = (unit === "celsius") ? mainTemp : convertToFahrenheit(mainTemp);
+ const maxTemp = (unit === "celsius") ? data.cputemp.max : convertToFahrenheit(data.cputemp.max);
+ const percent = Math.round(((mainTemp - minTemp) / (maxTemp - minTemp)) * 100);
return (
@@ -73,6 +86,7 @@ export default function CpuTemp({ expanded, units }) {
{t("resources.max")}
)}
+
);
diff --git a/src/components/widgets/resources/disk.jsx b/src/components/widgets/resources/disk.jsx
index dbc41b1c..ca09c095 100644
--- a/src/components/widgets/resources/disk.jsx
+++ b/src/components/widgets/resources/disk.jsx
@@ -44,7 +44,8 @@ export default function Disk({ options, expanded }) {
);
}
- const percent = Math.round((data.drive.used / data.drive.size) * 100);
+ // data.drive.used not accurate?
+ const percent = Math.round(((data.drive.size - data.drive.available) / data.drive.size) * 100);
return (
diff --git a/src/components/widgets/resources/memory.jsx b/src/components/widgets/resources/memory.jsx
index 2ee0a15e..30b7c8eb 100644
--- a/src/components/widgets/resources/memory.jsx
+++ b/src/components/widgets/resources/memory.jsx
@@ -44,7 +44,7 @@ export default function Memory({ expanded }) {
);
}
- const percent = Math.round((data.memory.used / data.memory.total) * 100);
+ const percent = Math.round((data.memory.active / data.memory.total) * 100);
return (
@@ -52,7 +52,7 @@ export default function Memory({ expanded }) {
- {t("common.bytes", { value: data.memory.free, maximumFractionDigits: 1, binary: true })}
+ {t("common.bytes", { value: data.memory.available, maximumFractionDigits: 1, binary: true })}
{t("resources.free")}
diff --git a/src/components/widgets/resources/uptime.jsx b/src/components/widgets/resources/uptime.jsx
index 2624bef1..3bf785b1 100644
--- a/src/components/widgets/resources/uptime.jsx
+++ b/src/components/widgets/resources/uptime.jsx
@@ -3,6 +3,8 @@ import { FaRegClock } from "react-icons/fa";
import { BiError } from "react-icons/bi";
import { useTranslation } from "next-i18next";
+import UsageBar from "./usage-bar";
+
export default function Uptime() {
const { t } = useTranslation();
@@ -45,6 +47,8 @@ export default function Uptime() {
else if (d > 0) uptime = `${d}${t("resources.days")} ${h}${t("resources.hours")}`;
else uptime = `${h}${t("resources.hours")} ${m}${t("resources.minutes")}`;
+ const percent = Math.round((new Date().getSeconds() / 60) * 100);
+
return (
@@ -55,6 +59,7 @@ export default function Uptime() {
{t("resources.uptime")}
+
);
diff --git a/src/pages/api/docker/stats/[...service].js b/src/pages/api/docker/stats/[...service].js
index 0ca30f00..e27cd35c 100644
--- a/src/pages/api/docker/stats/[...service].js
+++ b/src/pages/api/docker/stats/[...service].js
@@ -30,7 +30,7 @@ export default async function handler(req, res) {
});
}
- const containerNames = containers.map((container) => container.Names[0].replace(/^\//, ""));
+ const containerNames = containers.map((container) => container.Names[0]?.replace(/^\//, ""));
const containerExists = containerNames.includes(containerName);
if (containerExists) {
@@ -75,7 +75,7 @@ export default async function handler(req, res) {
}
}
- return res.status(200).send({
+ return res.status(404).send({
error: "not found",
});
} catch (e) {
diff --git a/src/pages/api/docker/status/[...service].js b/src/pages/api/docker/status/[...service].js
index 2bcc0a8a..bb03a637 100644
--- a/src/pages/api/docker/status/[...service].js
+++ b/src/pages/api/docker/status/[...service].js
@@ -30,7 +30,7 @@ export default async function handler(req, res) {
});
}
- const containerNames = containers.map((container) => container.Names[0].replace(/^\//, ""));
+ const containerNames = containers.map((container) => container.Names[0]?.replace(/^\//, ""));
const containerExists = containerNames.includes(containerName);
if (containerExists) {
diff --git a/src/utils/config/service-helpers.js b/src/utils/config/service-helpers.js
index 317c0f3c..f739f05f 100644
--- a/src/utils/config/service-helpers.js
+++ b/src/utils/config/service-helpers.js
@@ -249,7 +249,8 @@ export function cleanServiceGroups(groups) {
podSelector,
wan, // opnsense widget,
enableBlocks, // emby/jellyfin
- enableNowPlaying
+ enableNowPlaying,
+ volume // diskstation widget
} = cleanedService.widget;
const fieldsList = typeof fields === 'string' ? JSON.parse(fields) : fields;
@@ -281,8 +282,11 @@ export function cleanServiceGroups(groups) {
if (wan) cleanedService.widget.wan = wan;
}
if (type === "emby" || type === "jellyfin") {
- if (enableBlocks) cleanedService.widget.enableBlocks = enableBlocks === 'true';
- if (enableNowPlaying) cleanedService.widget.enableNowPlaying = enableNowPlaying === 'true';
+ if (enableBlocks) cleanedService.widget.enableBlocks = enableBlocks;
+ if (enableNowPlaying) cleanedService.widget.enableNowPlaying = enableNowPlaying;
+ }
+ if (type === "diskstation") {
+ if (volume) cleanedService.widget.volume = volume;
}
}
diff --git a/src/widgets/diskstation/component.jsx b/src/widgets/diskstation/component.jsx
index 3195a62d..afc41ae4 100644
--- a/src/widgets/diskstation/component.jsx
+++ b/src/widgets/diskstation/component.jsx
@@ -33,8 +33,7 @@ export default function Component({ service }) {
const uptime = `${ t("common.number", { value: days }) } ${ t("diskstation.days") }`;
// storage info
- // TODO: figure out how to display info for more than one volume
- const volume = storageData.data.vol_info?.[0];
+ const volume = widget.volume ? storageData.data.vol_info?.find(vol => vol.name === widget.volume) : storageData.data.vol_info?.[0];
const usedBytes = parseFloat(volume?.used_size);
const totalBytes = parseFloat(volume?.total_size);
const freeBytes = totalBytes - usedBytes;