Загрузка данных
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/input.h>
#include <sys/select.h>
#include <sys/time.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>
#include <time.h>
#include <sys/stat.h>
// Константы
#define SIGNAL_FILE "/tmp/signalS" // Файл сигнала для управления программой
#define SENSOR_FILE "/tmp/mySensors" // Файл с данными датчиков
#define SCRIPT_PATH "/home/diver/Скрипты/sensors.sh" // Скрипт для получения данных датчиков
#define IDLE_TIMEOUT 60 // Время бездействия перед переходом в спящий режим (секунды)
#define TIMEOUT 1 // Таймаут проверки активности устройств (секунды)
#define TEMP_CHECK_INTERVAL 5 // Интервал проверки температуры при превышении (секунды)
#define BRIGHTNESS_LOW 60 // Минимальная яркость экрана
#define BRIGHTNESS_OFF 0 // Выключенная яркость экрана
#define TEMP_THRESHOLD 60 // Пороговая температура для изменения частоты процессора
#define FREQ_LOW "1100MHz" // Низкая частота процессора
#define FREQ_HIGH "3.0GHz" // Высокая частота процессора
char *MOUSE_DEVICE = NULL;
char *KEYBOARD_DEVICE = NULL;
// Функция для выполнения внешних команд
void run_command(const char *command) {
FILE *fp = popen(command, "r");
if (!fp) {
fprintf(stderr, "Не удалось выполнить команду: %s\n", command);
return;
}
char buffer[128];
while (fgets(buffer, sizeof(buffer), fp)) {
printf("%s", buffer);
}
pclose(fp);
}
// Функция для проверки активности устройства
int check_device_activity(const char *device_path, int timeout) {
int fd = open(device_path, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
perror("Не удалось открыть устройство");
return 0;
}
fd_set fds;
FD_ZERO(&fds);
FD_SET(fd, &fds);
struct timeval tv = {timeout, 0};
int ret = select(fd + 1, &fds, NULL, NULL, &tv);
close(fd);
if (ret > 0) {
return 1; // Есть активность
}
return 0; // Нет активности
}
// Функция для проверки работы mpv
int is_mpv_running() {
DIR *dir = opendir("/proc");
if (!dir) {
perror("Не удалось открыть /proc");
return 0;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR) {
char path[256];
snprintf(path, sizeof(path), "/proc/%s/comm", entry->d_name);
FILE *fp = fopen(path, "r");
if (fp) {
char comm[16];
if (fgets(comm, sizeof(comm), fp)) {
if (strncmp(comm, "mpv", 3) == 0) {
fclose(fp);
closedir(dir);
return 1;
}
}
fclose(fp);
}
}
}
closedir(dir);
return 0;
}
// Функция для установки яркости экрана
void set_screen_brightness(int level) {
char command[64];
snprintf(command, sizeof(command), "xbacklight -set %d", level);
run_command(command);
}
// Получение текущей частоты процессора
void get_current_cpu_frequency() {
printf("Текущая частота процессора:\n");
run_command("cpupower frequency-info | grep 'current CPU freq'");
}
// Функция для автоматического поиска устройств ввода через libinput
char* find_input_device(const char* capability_keyword, const char* name_keyword) {
FILE *fp = popen("libinput list-devices", "r");
if (!fp) {
perror("Не удалось выполнить libinput list-devices");
return NULL;
}
char line[512];
char name[256] = {0};
char kernel[256] = {0};
char scroll_methods[256] = {0};
int has_capability = 0;
int is_excluded = 0;
while (fgets(line, sizeof(line), fp)) {
// Начало новой секции устройства — сброс всех флагов
if (strncmp(line, "Device:", 7) == 0) {
// Сброс флагов
memset(name, 0, sizeof(name));
memset(kernel, 0, sizeof(kernel));
memset(scroll_methods, 0, sizeof(scroll_methods));
has_capability = 0;
is_excluded = 0;
// Парсим имя устройства
sscanf(line, "Device: %[^\n]", name);
// Исключаем устройства с "Keyboard" в имени для мыши
if (strcmp(capability_keyword, "pointer") == 0 && strstr(name, "Keyboard")) {
is_excluded = 1;
}
}
// Парсинг пути устройства
else if (strncmp(line, "Kernel:", 7) == 0) {
sscanf(line, "Kernel: %s", kernel);
}
// Проверка возможностей
else if (strstr(line, "Capabilities:") && strstr(line, capability_keyword)) {
has_capability = 1;
}
// Проверка методов прокрутки (признак мыши)
else if (strstr(line, "Scroll methods:")) {
sscanf(line, "Scroll methods: %[^\n]", scroll_methods);
}
// Конец секции устройства — проверка условий
else if (line[0] == '\n') {
// Для мыши: требуется Scroll methods = button
if (strcmp(capability_keyword, "pointer") == 0) {
if (has_capability && !is_excluded &&
strstr(scroll_methods, "button") && kernel[0] != '\0') {
char *device_path = strdup(kernel);
pclose(fp);
return device_path;
}
}
// Для клавиатуры: исключаем системные устройства
else if (strcmp(capability_keyword, "keyboard") == 0) {
if (has_capability && !is_excluded && kernel[0] != '\0') {
if ((name_keyword == NULL) || (strstr(name, name_keyword))) {
char *device_path = strdup(kernel);
pclose(fp);
return device_path;
}
}
}
}
}
pclose(fp);
return NULL;
}
// Основная функция
int main() {
// Автоматическое определение устройств
KEYBOARD_DEVICE = find_input_device("keyboard", "Keyboard");
MOUSE_DEVICE = find_input_device("pointer", "Mouse|TouchPad");
if (!MOUSE_DEVICE || !KEYBOARD_DEVICE) {
fprintf(stderr, "Не удалось найти устройства ввода\n");
free(MOUSE_DEVICE);
free(KEYBOARD_DEVICE);
return 1;
}
printf("Найдена клавиатура: %s\n", KEYBOARD_DEVICE);
printf("Найдена мышь: %s\n", MOUSE_DEVICE);
// Проверка и создание сигнального файла
if (access(SIGNAL_FILE, F_OK) == 0) {
remove(SIGNAL_FILE);
printf("Сигнальный файл удален. Выход.\n");
free(MOUSE_DEVICE);
free(KEYBOARD_DEVICE);
return 0;
}
FILE *file = fopen(SIGNAL_FILE, "w");
if (!file) {
perror("Не удалось создать сигнальный файл");
free(MOUSE_DEVICE);
free(KEYBOARD_DEVICE);
return 1;
}
fclose(file);
// Проверка доступности устройств
if (access(MOUSE_DEVICE, F_OK) != 0) {
printf("Устройство мыши не найдено!\n");
free(MOUSE_DEVICE);
free(KEYBOARD_DEVICE);
return 1;
}
if (access(KEYBOARD_DEVICE, F_OK) != 0) {
printf("Устройство клавиатуры не найдено!\n");
free(MOUSE_DEVICE);
free(KEYBOARD_DEVICE);
return 1;
}
// Основной цикл
time_t last_activity_time = time(NULL); // Время последней активности
int in_sleep_mode = 0; // Флаг спящего режима
int in_game_mode = 0; // Флаг игрового режима
int temp_throttle_active = 0; // Флаг активного режима снижения частоты из-за температуры
int current_interval = TIMEOUT; // Текущий интервал проверки
while (access(SIGNAL_FILE, F_OK) == 0) {
printf("\n--- Новая итерация ---\n");
// Проверка активности
int mouse_active = check_device_activity(MOUSE_DEVICE, TIMEOUT);
int keyboard_active = check_device_activity(KEYBOARD_DEVICE, TIMEOUT);
int mpv_active = is_mpv_running();
// Обновление времени последней активности
if (mouse_active || keyboard_active || mpv_active) {
last_activity_time = time(NULL);
if (in_sleep_mode) {
printf("Активность обнаружена. Возобновление нормального режима.\n");
in_sleep_mode = 0;
set_screen_brightness(BRIGHTNESS_LOW);
// Если выходим из спящего режима, восстанавливаем частоту процессора
printf("Восстановление частоты процессора до стандартных значений...\n");
run_command("cpupower frequency-set -g powersave -d 800MHz -u 4.0GHz");
get_current_cpu_frequency();
temp_throttle_active = 0;
current_interval = TIMEOUT;
}
}
// Проверка времени бездействия
if (!in_sleep_mode && (time(NULL) - last_activity_time) >= IDLE_TIMEOUT) {
printf("Нет активности более %d секунд. Переход в спящий режим...\n", IDLE_TIMEOUT);
in_sleep_mode = 1;
set_screen_brightness(BRIGHTNESS_OFF);
// В спящем режиме принудительно устанавливаем частоту процессора на 800 МГц
printf("Принудительное снижение частоты процессора до 800 МГц...\n");
run_command("cpupower frequency-set -g powersave -d 800MHz -u 800MHz");
get_current_cpu_frequency();
temp_throttle_active = 0;
current_interval = TIMEOUT;
}
// Проверка игрового режима
if (mpv_active) {
if (!in_game_mode) {
printf("Обнаружен игровой режим (mpv запущен).\n");
in_game_mode = 1;
}
} else {
if (in_game_mode) {
printf("Игровой режим завершен (mpv остановлен).\n");
in_game_mode = 0;
// При выходе из игрового режима восстанавливаем частоту процессора
printf("Восстановление частоты процессора после игрового режима...\n");
run_command("cpupower frequency-set -g powersave -d 800MHz -u 4.0GHz");
get_current_cpu_frequency();
temp_throttle_active = 0;
current_interval = TIMEOUT;
}
}
// Проверка температуры
if (!in_sleep_mode) {
system("sensors | grep 'Core 0:' | awk '{print $3}' | sed 's/[+°C]//g' > /tmp/mySensors");
FILE *sensor_file = fopen(SENSOR_FILE, "r");
if (sensor_file) {
char buffer[32];
if (fgets(buffer, sizeof(buffer), sensor_file)) {
float temperature = atof(buffer);
printf("Текущая температура: %.2f°C\n", temperature);
// Проверка на превышение порога
if (temperature >= TEMP_THRESHOLD) {
printf("Температура %.2f°C превышает порог %d°C! Снижение частоты до %s...\n",
temperature, TEMP_THRESHOLD, FREQ_LOW);
// Снижаем частоту
char command[128];
snprintf(command, sizeof(command),
"cpupower frequency-set -g powersave -d 800MHz -u %s", FREQ_LOW);
run_command(command);
get_current_cpu_frequency();
temp_throttle_active = 1;
current_interval = TEMP_CHECK_INTERVAL;
printf("Таймер увеличен до %d секунд\n", TEMP_CHECK_INTERVAL);
} else if (temp_throttle_active) {
// Температура нормализовалась после троттлинга
printf("Температура нормализовалась (%.2f°C). Восстановление частоты до %s...\n",
temperature, FREQ_HIGH);
char command[128];
snprintf(command, sizeof(command),
"cpupower frequency-set -g powersave -d 800MHz -u %s", FREQ_HIGH);
run_command(command);
get_current_cpu_frequency();
temp_throttle_active = 0;
current_interval = TIMEOUT;
printf("Таймер возвращен на %d секунду\n", TIMEOUT);
} else {
printf("Температура %.2f°C в пределах нормы.\n", temperature);
}
} else {
printf("Не удалось прочитать данные из файла сенсоров.\n");
}
fclose(sensor_file);
} else {
printf("Не удалось открыть файл сенсоров.\n");
}
}
// Спим нужный интервал
sleep(current_interval);
}
printf("Сигнальный файл удален. Выход.\n");
// Очистка памяти
free(MOUSE_DEVICE);
free(KEYBOARD_DEVICE);
return 0;
}