added temperature monitor
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
- **Авто-монтирование**: Автоматически монтирует `/dev/mmcblk1p1` в `/media`
|
||||
- **Поддержка больших файлов**: Загрузка файлов до 200 MB
|
||||
- **Перезагрузка системы**: Кнопка безопасной перезагрузки с корректным отмонтированием
|
||||
- **Мониторинг температуры**: Отображение температуры CPU с цветовой индикацией
|
||||
|
||||
## Структура проекта
|
||||
|
||||
@@ -86,6 +87,7 @@ sudo ./up
|
||||
| `/api/extlinux` | POST | Запись extlinux.conf |
|
||||
| `/api/progress` | GET | Статус загрузки |
|
||||
| `/api/mount` | GET | Статус монтирования |
|
||||
| `/api/temperature` | GET | Температура CPU |
|
||||
| `/api/reboot` | POST | Перезагрузка системы |
|
||||
|
||||
## Параметры загрузки
|
||||
|
||||
+114
@@ -282,6 +282,118 @@ static void handle_mount_status(struct mg_connection *c) {
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
|
||||
// Handle temperature read
|
||||
static void handle_temperature(struct mg_connection *c) {
|
||||
float temperature = 0.0f;
|
||||
int success = 0;
|
||||
char path[256];
|
||||
|
||||
// Try all thermal zones (0-3)
|
||||
for (int i = 0; i < 4 && !success; i++) {
|
||||
snprintf(path, sizeof(path), "/sys/class/thermal/thermal_zone%d/temp", i);
|
||||
FILE *f = fopen(path, "r");
|
||||
if (f) {
|
||||
// Check zone type if available
|
||||
char type_path[256];
|
||||
snprintf(type_path, sizeof(type_path), "/sys/class/thermal/thermal_zone%d/type", i);
|
||||
FILE *type_f = fopen(type_path, "r");
|
||||
if (type_f) {
|
||||
char type[32] = {0};
|
||||
if (fscanf(type_f, "%31s", type) == 1) {
|
||||
// Prefer CPU or soc zones
|
||||
int is_cpu = (strstr(type, "cpu") != NULL ||
|
||||
strstr(type, "soc") != NULL ||
|
||||
strstr(type, "CPU") != NULL);
|
||||
|
||||
int temp_raw;
|
||||
if (fscanf(f, "%d", &temp_raw) == 1) {
|
||||
temperature = temp_raw / 1000.0f;
|
||||
success = 1;
|
||||
// If this is a CPU zone, use it immediately
|
||||
if (is_cpu) {
|
||||
fclose(f);
|
||||
fclose(type_f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(type_f);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
// If thermal zones failed, try hwmon (0-3)
|
||||
if (!success) {
|
||||
for (int i = 0; i < 4 && !success; i++) {
|
||||
snprintf(path, sizeof(path), "/sys/class/hwmon/hwmon%d/temp1_input", i);
|
||||
FILE *f = fopen(path, "r");
|
||||
if (f) {
|
||||
// Check sensor name
|
||||
char name_path[256];
|
||||
snprintf(name_path, sizeof(name_path), "/sys/class/hwmon/hwmon%d/name", i);
|
||||
FILE *name_f = fopen(name_path, "r");
|
||||
if (name_f) {
|
||||
char name[32] = {0};
|
||||
if (fscanf(name_f, "%31s", name) == 1) {
|
||||
// Prefer CPU or sunxi sensors
|
||||
int is_cpu = (strstr(name, "cpu") != NULL ||
|
||||
strstr(name, "sunxi") != NULL ||
|
||||
strstr(name, "CPU") != NULL ||
|
||||
strstr(name, "acpitz") != NULL);
|
||||
|
||||
int temp_raw;
|
||||
if (fscanf(f, "%d", &temp_raw) == 1) {
|
||||
temperature = temp_raw / 1000.0f;
|
||||
success = 1;
|
||||
if (is_cpu) {
|
||||
fclose(f);
|
||||
fclose(name_f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(name_f);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Last resort: try any temp1_input
|
||||
if (!success) {
|
||||
const char *fallback_paths[] = {
|
||||
"/sys/class/hwmon/hwmon0/temp1_input",
|
||||
"/sys/class/hwmon/hwmon1/temp1_input",
|
||||
"/sys/class/hwmon/hwmon2/temp1_input",
|
||||
"/sys/class/hwmon/hwmon3/temp1_input",
|
||||
NULL
|
||||
};
|
||||
|
||||
for (int i = 0; fallback_paths[i] != NULL && !success; i++) {
|
||||
FILE *f = fopen(fallback_paths[i], "r");
|
||||
if (f) {
|
||||
int temp_raw;
|
||||
if (fscanf(f, "%d", &temp_raw) == 1) {
|
||||
temperature = temp_raw / 1000.0f;
|
||||
success = 1;
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *root = cJSON_CreateObject();
|
||||
cJSON_AddBoolToObject(root, "success", success);
|
||||
cJSON_AddNumberToObject(root, "temperature", temperature);
|
||||
cJSON_AddStringToObject(root, "unit", "Celsius");
|
||||
|
||||
char *json = cJSON_PrintUnformatted(root);
|
||||
mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s\n", json);
|
||||
free(json);
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
|
||||
// Handle system reboot
|
||||
static void handle_reboot(struct mg_connection *c) {
|
||||
cJSON *root = cJSON_CreateObject();
|
||||
@@ -417,6 +529,8 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) {
|
||||
handle_progress(c);
|
||||
} else if (mg_match_uri(hm->uri, "/api/mount")) {
|
||||
handle_mount_status(c);
|
||||
} else if (mg_match_uri(hm->uri, "/api/temperature")) {
|
||||
handle_temperature(c);
|
||||
} else if (mg_match_uri(hm->uri, "/api/reboot")) {
|
||||
handle_reboot(c);
|
||||
} else if (mg_match_uri(hm->uri, "/")) {
|
||||
|
||||
+35
@@ -21,7 +21,9 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
// Initialize
|
||||
checkMountStatus();
|
||||
checkTemperature();
|
||||
setInterval(checkMountStatus, 10000); // Check every 10 seconds
|
||||
setInterval(checkTemperature, 5000); // Check temperature every 5 seconds
|
||||
|
||||
// Tab switching
|
||||
tabBtns.forEach((btn) => {
|
||||
@@ -306,4 +308,37 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
|
||||
}
|
||||
|
||||
// Temperature functions
|
||||
const temperatureStatus = document.getElementById("temperature-status");
|
||||
const tempValue = temperatureStatus
|
||||
? temperatureStatus.querySelector(".temp-value")
|
||||
: null;
|
||||
|
||||
async function checkTemperature() {
|
||||
if (!tempValue) return;
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/temperature");
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
tempValue.textContent = data.temperature.toFixed(1);
|
||||
tempValue.style.color = getTempColor(data.temperature);
|
||||
} else {
|
||||
tempValue.textContent = "N/A";
|
||||
tempValue.style.color = "#888";
|
||||
}
|
||||
} catch (error) {
|
||||
tempValue.textContent = "Error";
|
||||
tempValue.style.color = "#ff4757";
|
||||
}
|
||||
}
|
||||
|
||||
function getTempColor(temp) {
|
||||
if (temp < 50) return "#00ff88"; // Green - cool
|
||||
if (temp < 70) return "#00d9ff"; // Blue - normal
|
||||
if (temp < 80) return "#ffa500"; // Orange - warm
|
||||
return "#ff4757"; // Red - hot
|
||||
}
|
||||
});
|
||||
|
||||
@@ -33,6 +33,14 @@
|
||||
<span class="status-text">Checking...</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="status-item">
|
||||
<span class="label">CPU Temperature:</span>
|
||||
<span class="value" id="temperature-status">
|
||||
<span class="temp-icon">🌡️</span>
|
||||
<span class="temp-value">--</span>
|
||||
<span class="temp-unit">°C</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -98,6 +98,21 @@ h2 {
|
||||
box-shadow: 0 0 10px #ff4757;
|
||||
}
|
||||
|
||||
/* Temperature Display */
|
||||
.temp-icon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.temp-value {
|
||||
color: #00d9ff;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
.temp-unit {
|
||||
color: #888;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
/* Upload Section */
|
||||
.upload-tabs {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user