2012-06-09 14:25:28 +00:00
|
|
|
/**
|
|
|
|
* mbpfan.c - automatically control fan for MacBook Pro
|
|
|
|
* Copyright (C) 2010 Allan McRae <allan@archlinux.org>
|
|
|
|
* Modifications by Rafael Vega <rvega@elsoftwarehamuerto.org>
|
2014-06-22 14:48:44 +00:00
|
|
|
* Modifications (2012) by Daniel Graziotin <daniel@ineed.coffee>
|
2012-07-04 23:22:48 +00:00
|
|
|
* Modifications (2012) by Ismail Khatib <ikhatib@gmail.com>
|
2012-06-09 14:25:28 +00:00
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
2014-06-22 16:35:14 +00:00
|
|
|
* 2014-06-22 - v1.7.0
|
2012-06-09 14:25:28 +00:00
|
|
|
*
|
|
|
|
* Notes:
|
|
|
|
* Assumes any number of processors and fans (max. 10)
|
2012-06-15 19:07:11 +00:00
|
|
|
* It uses only the temperatures from the processors as input.
|
2012-06-09 14:25:28 +00:00
|
|
|
* Requires coretemp and applesmc kernel modules to be loaded.
|
|
|
|
* Requires root use
|
|
|
|
*
|
|
|
|
* Tested models:
|
|
|
|
* MacBook Pro 8.1 13" (Intel i7 - Linux 3.2)
|
2012-07-04 23:22:48 +00:00
|
|
|
* MacBook Pro 6,2 15" (Intel i7 - Linux 3.2)
|
|
|
|
* MacBook Pro 2,2 15" (Intel Core 2 Duo - Linux 3.4.4)
|
2012-06-09 14:25:28 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
2012-06-11 19:43:53 +00:00
|
|
|
#include <math.h>
|
|
|
|
#include <syslog.h>
|
2014-06-22 14:48:44 +00:00
|
|
|
#include <sys/utsname.h>
|
|
|
|
#include <sys/errno.h>
|
2012-06-09 14:25:28 +00:00
|
|
|
#include "mbpfan.h"
|
2012-06-11 19:43:53 +00:00
|
|
|
#include "global.h"
|
2012-07-04 23:22:48 +00:00
|
|
|
#include "settings.h"
|
2012-06-09 14:25:28 +00:00
|
|
|
|
|
|
|
/* lazy min/max... */
|
|
|
|
#define min(a,b) a < b ? a : b
|
|
|
|
#define max(a,b) a > b ? a : b
|
|
|
|
|
2012-06-09 17:07:25 +00:00
|
|
|
int min_fan_speed = 2000;
|
|
|
|
int max_fan_speed = 6200;
|
2012-06-09 14:25:28 +00:00
|
|
|
|
|
|
|
/* temperature thresholds
|
|
|
|
* low_temp - temperature below which fan speed will be at minimum
|
|
|
|
* high_temp - fan will increase speed when higher than this temperature
|
|
|
|
* max_temp - fan will run at full speed above this temperature */
|
2012-06-09 17:07:25 +00:00
|
|
|
int low_temp = 63; // try ranges 55-63
|
|
|
|
int high_temp = 66; // try ranges 58-66
|
|
|
|
int max_temp = 86; // do not set it > 90
|
2012-06-09 14:25:28 +00:00
|
|
|
|
2012-06-15 19:47:23 +00:00
|
|
|
int polling_interval = 7;
|
2012-06-09 14:25:28 +00:00
|
|
|
|
2014-07-21 21:43:39 +00:00
|
|
|
t_sensors* sensors = NULL;
|
|
|
|
t_fans* fans = NULL;
|
|
|
|
|
2012-06-09 14:25:28 +00:00
|
|
|
|
2014-06-22 14:48:44 +00:00
|
|
|
bool is_legacy_kernel()
|
|
|
|
{
|
|
|
|
struct utsname kernel;
|
|
|
|
uname(&kernel);
|
|
|
|
|
|
|
|
char *str_kernel_version;
|
2014-06-23 08:24:03 +00:00
|
|
|
str_kernel_version = strtok(kernel.release, ".");
|
|
|
|
|
2015-03-28 02:38:48 +00:00
|
|
|
if (atoi(str_kernel_version) < 3){
|
|
|
|
syslog(LOG_INFO, "mbpfan detected a pre-3.x.x linux kernel. Detected version: %s. Exiting.\n", kernel.release);
|
|
|
|
printf("mbpfan detected a pre-3.x.x linux kernel. Detected version: %s. Exiting.\n", kernel.release);
|
2014-06-29 10:42:52 +00:00
|
|
|
exit(EXIT_FAILURE);
|
2014-06-23 08:24:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
str_kernel_version = strtok(NULL, ".");
|
|
|
|
int kernel_version = atoi(str_kernel_version);
|
2014-06-22 14:48:44 +00:00
|
|
|
|
|
|
|
if(verbose) {
|
|
|
|
printf("Detected kernel version: %s\n", kernel.release);
|
|
|
|
printf("Detected kernel minor revision: %s\n", str_kernel_version);
|
|
|
|
|
|
|
|
if(daemonize) {
|
|
|
|
syslog(LOG_INFO, "Kernel version: %s", kernel.release);
|
2014-06-23 08:24:03 +00:00
|
|
|
syslog(LOG_INFO, "Detected kernel minor revision: %s", str_kernel_version);
|
2014-06-22 14:48:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-28 02:38:48 +00:00
|
|
|
return (atoi(kernel.release) == 3 && kernel_version < 15);
|
2014-06-22 14:48:44 +00:00
|
|
|
}
|
|
|
|
|
2014-06-22 15:07:24 +00:00
|
|
|
|
2012-06-11 19:43:53 +00:00
|
|
|
t_sensors *retrieve_sensors()
|
2012-06-09 14:25:28 +00:00
|
|
|
{
|
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
t_sensors *sensors_head = NULL;
|
|
|
|
t_sensors *s = NULL;
|
|
|
|
|
|
|
|
char *path = NULL;
|
2014-06-22 14:48:44 +00:00
|
|
|
char *path_begin = NULL;
|
|
|
|
|
|
|
|
if (is_legacy_kernel()) {
|
|
|
|
if(verbose) {
|
|
|
|
printf("Using legacy sensor path for kernel < 3.15.0\n");
|
|
|
|
|
|
|
|
if(daemonize) {
|
|
|
|
syslog(LOG_INFO, "Using legacy path for kernel < 3.15.0");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-22 15:07:24 +00:00
|
|
|
path_begin = (char *) "/sys/devices/platform/coretemp.0/temp";
|
2014-06-22 14:48:44 +00:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if(verbose) {
|
|
|
|
printf("Using new sensor path for kernel >= 3.0.15\n");
|
|
|
|
|
|
|
|
if(daemonize) {
|
|
|
|
syslog(LOG_INFO, "Using new sensor path for kernel >= 3.0.15");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-22 15:07:24 +00:00
|
|
|
path_begin = (char *) "/sys/devices/platform/coretemp.0/hwmon/hwmon";
|
2014-06-22 14:48:44 +00:00
|
|
|
|
|
|
|
int counter;
|
|
|
|
for (counter = 0; counter < 10; counter++) {
|
|
|
|
|
2016-03-17 12:03:02 +00:00
|
|
|
char hwmon_path[strlen(path_begin)+2];
|
2014-06-22 14:48:44 +00:00
|
|
|
|
|
|
|
sprintf(hwmon_path, "%s%d", path_begin, counter);
|
|
|
|
|
|
|
|
// thanks http://stackoverflow.com/questions/18192998/plain-c-opening-a-directory-with-fopen
|
|
|
|
fopen(hwmon_path, "wb");
|
|
|
|
|
|
|
|
if (errno == EISDIR) {
|
|
|
|
|
|
|
|
path_begin = (char*) malloc(sizeof( char ) * (strlen(hwmon_path) + strlen("/temp") + 1));
|
|
|
|
strcpy(path_begin, hwmon_path);
|
|
|
|
strcat(path_begin, "/temp");
|
|
|
|
|
|
|
|
if(verbose) {
|
|
|
|
printf("Found hwmon path at %s\n", path_begin);
|
|
|
|
|
|
|
|
if(daemonize) {
|
|
|
|
syslog(LOG_INFO, "Found hwmon path at %s\n", path_begin);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
const char *path_end = "_input";
|
|
|
|
|
|
|
|
int path_size = strlen(path_begin) + strlen(path_end) + 2;
|
2012-08-22 13:53:07 +00:00
|
|
|
char number[2];
|
2012-08-22 13:05:52 +00:00
|
|
|
sprintf(number,"%d",0);
|
|
|
|
|
2012-10-24 09:13:25 +00:00
|
|
|
int sensors_found = 0;
|
2012-11-12 10:48:05 +00:00
|
|
|
|
2014-06-22 15:07:24 +00:00
|
|
|
int counter = 0;
|
2012-10-24 09:13:25 +00:00
|
|
|
for(counter = 0; counter<10; counter++) {
|
2012-08-22 13:05:52 +00:00
|
|
|
path = (char*) malloc(sizeof( char ) * path_size);
|
|
|
|
|
2012-10-24 09:13:25 +00:00
|
|
|
sprintf(number,"%d",counter);
|
2012-08-22 13:05:52 +00:00
|
|
|
path[0] = '\0';
|
|
|
|
strncat( path, path_begin, strlen(path_begin) );
|
|
|
|
strncat( path, number, strlen(number) );
|
|
|
|
strncat( path, path_end, strlen(path_begin) );
|
|
|
|
|
|
|
|
FILE *file = fopen(path, "r");
|
|
|
|
|
|
|
|
if(file != NULL) {
|
|
|
|
s = (t_sensors *) malloc( sizeof( t_sensors ) );
|
|
|
|
s->path = (char *) malloc(sizeof( char ) * path_size);
|
|
|
|
strcpy(s->path, path);
|
|
|
|
fscanf(file, "%d", &s->temperature);
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if (sensors_head == NULL) {
|
|
|
|
sensors_head = s;
|
|
|
|
sensors_head->next = NULL;
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
} else {
|
|
|
|
t_sensors *tmp = sensors_head;
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
while (tmp->next != NULL) {
|
|
|
|
tmp = tmp->next;
|
2012-06-09 14:25:28 +00:00
|
|
|
}
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
tmp->next = s;
|
|
|
|
tmp->next->next = NULL;
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
fclose(file);
|
2012-10-24 09:13:25 +00:00
|
|
|
sensors_found++;
|
2012-06-09 14:25:28 +00:00
|
|
|
}
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
free(path);
|
|
|
|
path = NULL;
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-10-24 09:13:25 +00:00
|
|
|
if(verbose) {
|
|
|
|
printf("Found %d sensors\n", sensors_found);
|
|
|
|
|
|
|
|
if(daemonize) {
|
|
|
|
syslog(LOG_INFO, "Found %d sensors", sensors_found);
|
|
|
|
}
|
2012-08-23 20:32:49 +00:00
|
|
|
}
|
|
|
|
|
2014-06-29 10:52:55 +00:00
|
|
|
if (!sensors_found > 0){
|
2014-06-29 10:58:53 +00:00
|
|
|
syslog(LOG_CRIT, "mbpfan could not detect any temp sensor. Please contact the developer.\n");
|
2014-06-29 10:52:55 +00:00
|
|
|
printf("mbpfan could not detect any temp sensor. Please contact the developer.\n");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
return sensors_head;
|
2012-06-09 14:25:28 +00:00
|
|
|
}
|
|
|
|
|
2014-06-22 15:07:24 +00:00
|
|
|
|
2012-10-24 09:13:25 +00:00
|
|
|
t_fans *retrieve_fans()
|
2012-06-09 17:07:25 +00:00
|
|
|
{
|
2012-10-24 09:13:25 +00:00
|
|
|
|
|
|
|
t_fans *fans_head = NULL;
|
|
|
|
t_fans *fan = NULL;
|
2012-06-16 09:02:48 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
char *path_output = NULL;
|
|
|
|
char *path_manual = NULL;
|
2012-06-16 09:02:48 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
const char *path_begin = "/sys/devices/platform/applesmc.768/fan";
|
|
|
|
const char *path_output_end = "_output";
|
|
|
|
const char *path_man_end = "_manual";
|
2012-11-12 10:48:05 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
int path_min_size = strlen(path_begin) + strlen(path_output_end) + 2;
|
|
|
|
int path_man_size = strlen(path_begin) + strlen(path_man_end) + 2;
|
2012-08-22 13:53:07 +00:00
|
|
|
char number[2];
|
2012-08-22 13:05:52 +00:00
|
|
|
sprintf(number,"%d",0);
|
2012-06-16 09:02:48 +00:00
|
|
|
|
2012-08-22 14:02:03 +00:00
|
|
|
int counter = 0;
|
2012-10-24 09:13:25 +00:00
|
|
|
int fans_found = 0;
|
2012-06-16 09:02:48 +00:00
|
|
|
|
2014-07-21 21:43:02 +00:00
|
|
|
for(counter = 0; counter<10; counter++) {
|
2012-11-12 10:48:05 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
path_output = (char*) malloc(sizeof( char ) * path_min_size);
|
|
|
|
path_output[0] = '\0';
|
|
|
|
path_manual = (char*) malloc(sizeof( char ) * path_man_size);
|
|
|
|
path_manual[0] = '\0';
|
2012-08-22 14:02:03 +00:00
|
|
|
sprintf(number,"%d",counter);
|
2012-06-16 09:02:48 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
strncat( path_output, path_begin, strlen(path_begin) );
|
|
|
|
strncat( path_output, number, strlen(number) );
|
|
|
|
strncat( path_output, path_output_end, strlen(path_begin) );
|
2012-06-16 09:02:48 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
strncat( path_manual, path_begin, strlen(path_begin) );
|
|
|
|
strncat( path_manual, number, strlen(number) );
|
|
|
|
strncat( path_manual, path_man_end, strlen(path_begin) );
|
2012-06-16 09:02:48 +00:00
|
|
|
|
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
FILE *file = fopen(path_output, "r");
|
2012-06-16 09:02:48 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(file != NULL) {
|
2012-10-24 09:13:25 +00:00
|
|
|
fan = (t_fans *) malloc( sizeof( t_fans ) );
|
|
|
|
fan->fan_output_path = (char *) malloc(sizeof( char ) * path_min_size);
|
|
|
|
fan->fan_manual_path = (char *) malloc(sizeof( char ) * path_man_size);
|
|
|
|
strcpy(fan->fan_output_path, path_output);
|
|
|
|
strcpy(fan->fan_manual_path, path_manual);
|
|
|
|
|
|
|
|
if (fans_head == NULL) {
|
|
|
|
fans_head = fan;
|
|
|
|
fans_head->next = NULL;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
t_fans *tmp = fans_head;
|
|
|
|
|
|
|
|
while (tmp->next != NULL) {
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp->next = fan;
|
|
|
|
tmp->next->next = NULL;
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
fclose(file);
|
2012-10-24 09:13:25 +00:00
|
|
|
fans_found++;
|
2012-06-09 17:07:25 +00:00
|
|
|
}
|
2012-10-24 09:13:25 +00:00
|
|
|
|
|
|
|
free(path_output);
|
|
|
|
path_output = NULL;
|
|
|
|
free(path_manual);
|
|
|
|
path_manual = NULL;
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(verbose) {
|
2012-10-24 09:13:25 +00:00
|
|
|
printf("Found %d fans\n", fans_found);
|
2012-11-12 10:48:05 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(daemonize) {
|
2012-10-24 09:13:25 +00:00
|
|
|
syslog(LOG_INFO, "Found %d fans", fans_found);
|
2012-06-11 19:43:53 +00:00
|
|
|
}
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-06-11 19:43:53 +00:00
|
|
|
|
2014-06-29 10:52:55 +00:00
|
|
|
if (!fans_found > 0){
|
2014-06-29 10:58:53 +00:00
|
|
|
syslog(LOG_CRIT, "mbpfan could not detect any fan. Please contact the developer.\n");
|
2014-06-29 10:52:55 +00:00
|
|
|
printf("mbpfan could not detect any fan. Please contact the developer.\n");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
2012-10-24 09:13:25 +00:00
|
|
|
|
|
|
|
return fans_head;
|
2012-06-09 17:07:25 +00:00
|
|
|
}
|
|
|
|
|
2012-10-24 09:13:25 +00:00
|
|
|
|
2014-07-21 21:44:13 +00:00
|
|
|
static void set_fans_mode(t_fans *fans, int mode)
|
2012-06-09 17:07:25 +00:00
|
|
|
{
|
|
|
|
|
2012-10-24 09:13:25 +00:00
|
|
|
t_fans *tmp = fans;
|
2012-08-22 13:05:52 +00:00
|
|
|
FILE *file;
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
while(tmp != NULL) {
|
|
|
|
file = fopen(tmp->fan_manual_path, "rw+");
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(file != NULL) {
|
2014-07-21 21:44:13 +00:00
|
|
|
fprintf(file, "%d", mode);
|
2012-08-22 13:05:52 +00:00
|
|
|
fclose(file);
|
2012-06-09 17:07:25 +00:00
|
|
|
}
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
tmp = tmp->next;
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-06-09 17:07:25 +00:00
|
|
|
}
|
|
|
|
|
2014-07-21 21:44:13 +00:00
|
|
|
void set_fans_man(t_fans *fans)
|
|
|
|
{
|
|
|
|
|
|
|
|
set_fans_mode(fans, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_fans_auto(t_fans *fans)
|
|
|
|
{
|
|
|
|
|
|
|
|
set_fans_mode(fans, 0);
|
|
|
|
}
|
|
|
|
|
2012-06-09 14:25:28 +00:00
|
|
|
t_sensors *refresh_sensors(t_sensors *sensors)
|
|
|
|
{
|
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
t_sensors *tmp = sensors;
|
2012-06-09 14:25:28 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
while(tmp != NULL) {
|
|
|
|
FILE *file = fopen(tmp->path, "r");
|
2012-06-09 14:25:28 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(file != NULL) {
|
|
|
|
fscanf(file, "%d", &tmp->temperature);
|
|
|
|
fclose(file);
|
2012-06-09 14:25:28 +00:00
|
|
|
}
|
2012-06-16 09:02:48 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
tmp = tmp->next;
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
return sensors;
|
2012-06-09 14:25:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Controls the speed of the fan */
|
2012-10-24 09:13:25 +00:00
|
|
|
void set_fan_speed(t_fans* fans, int speed)
|
2012-06-09 14:25:28 +00:00
|
|
|
{
|
2012-10-24 09:13:25 +00:00
|
|
|
t_fans *tmp = fans;
|
2012-08-22 13:05:52 +00:00
|
|
|
FILE *file;
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
while(tmp != NULL) {
|
|
|
|
file = fopen(tmp->fan_output_path, "rw+");
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(file != NULL) {
|
|
|
|
fprintf(file, "%d", speed);
|
|
|
|
fclose(file);
|
2012-06-09 14:25:28 +00:00
|
|
|
}
|
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
tmp = tmp->next;
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
|
|
|
|
2012-06-09 14:25:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned short get_temp(t_sensors* sensors)
|
|
|
|
{
|
2012-08-22 13:05:52 +00:00
|
|
|
sensors = refresh_sensors(sensors);
|
|
|
|
int sum_temp = 0;
|
|
|
|
unsigned short temp = 0;
|
|
|
|
|
|
|
|
t_sensors* tmp = sensors;
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-10-24 12:18:11 +00:00
|
|
|
int number_sensors = 0;
|
2012-11-12 10:48:05 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
while(tmp != NULL) {
|
|
|
|
sum_temp += tmp->temperature;
|
|
|
|
tmp = tmp->next;
|
2012-10-24 12:18:11 +00:00
|
|
|
number_sensors++;
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-10-24 12:18:11 +00:00
|
|
|
// just to be safe
|
2012-11-12 10:48:05 +00:00
|
|
|
if (number_sensors == 0) {
|
2012-10-24 12:18:11 +00:00
|
|
|
number_sensors++;
|
2012-11-12 10:48:05 +00:00
|
|
|
}
|
2012-10-24 12:18:11 +00:00
|
|
|
|
|
|
|
temp = (unsigned short)( ceil( (float)( sum_temp ) / (number_sensors * 1000) ) );
|
2012-08-22 13:05:52 +00:00
|
|
|
return temp;
|
2012-06-09 14:25:28 +00:00
|
|
|
}
|
|
|
|
|
2014-06-22 15:07:24 +00:00
|
|
|
|
2012-11-18 21:16:49 +00:00
|
|
|
void retrieve_settings(const char* settings_path)
|
2012-06-09 14:25:28 +00:00
|
|
|
{
|
2012-08-22 13:05:52 +00:00
|
|
|
Settings *settings = NULL;
|
|
|
|
int result = 0;
|
|
|
|
FILE *f = NULL;
|
2012-11-18 21:16:49 +00:00
|
|
|
|
|
|
|
if (settings_path == NULL) {
|
|
|
|
f = fopen("/etc/mbpfan.conf", "r");
|
|
|
|
|
|
|
|
} else {
|
|
|
|
f = fopen(settings_path, "r");
|
|
|
|
}
|
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
|
|
|
|
if (f == NULL) {
|
|
|
|
/* Could not open configfile */
|
|
|
|
if(verbose) {
|
|
|
|
printf("Couldn't open configfile, using defaults\n");
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(daemonize) {
|
|
|
|
syslog(LOG_INFO, "Couldn't open configfile, using defaults");
|
2012-07-04 23:22:48 +00:00
|
|
|
}
|
|
|
|
}
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
} else {
|
|
|
|
settings = settings_open(f);
|
|
|
|
fclose(f);
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if (settings == NULL) {
|
|
|
|
/* Could not read configfile */
|
|
|
|
if(verbose) {
|
|
|
|
printf("Couldn't read configfile\n");
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(daemonize) {
|
2014-06-29 10:58:53 +00:00
|
|
|
syslog(LOG_WARNING, "Couldn't read configfile");
|
2012-07-04 23:22:48 +00:00
|
|
|
}
|
|
|
|
}
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
} else {
|
|
|
|
/* Read configfile values */
|
|
|
|
result = settings_get_int(settings, "general", "min_fan_speed");
|
2012-08-23 20:32:49 +00:00
|
|
|
|
|
|
|
if (result != 0) {
|
|
|
|
min_fan_speed = result;
|
|
|
|
}
|
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
result = settings_get_int(settings, "general", "max_fan_speed");
|
2012-08-23 20:32:49 +00:00
|
|
|
|
|
|
|
if (result != 0) {
|
|
|
|
max_fan_speed = result;
|
|
|
|
}
|
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
result = settings_get_int(settings, "general", "low_temp");
|
2012-08-23 20:32:49 +00:00
|
|
|
|
|
|
|
if (result != 0) {
|
|
|
|
low_temp = result;
|
|
|
|
}
|
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
result = settings_get_int(settings, "general", "high_temp");
|
2012-08-23 20:32:49 +00:00
|
|
|
|
|
|
|
if (result != 0) {
|
|
|
|
high_temp = result;
|
|
|
|
}
|
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
result = settings_get_int(settings, "general", "max_temp");
|
2012-08-23 20:32:49 +00:00
|
|
|
|
|
|
|
if (result != 0) {
|
|
|
|
max_temp = result;
|
|
|
|
}
|
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
result = settings_get_int(settings, "general", "polling_interval");
|
2012-08-23 20:32:49 +00:00
|
|
|
|
|
|
|
if (result != 0) {
|
|
|
|
polling_interval = result;
|
|
|
|
}
|
2012-08-22 13:05:52 +00:00
|
|
|
|
|
|
|
/* Destroy the settings object */
|
|
|
|
settings_delete(settings);
|
2012-07-04 23:22:48 +00:00
|
|
|
}
|
|
|
|
}
|
2012-08-22 13:05:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void mbpfan()
|
|
|
|
{
|
|
|
|
int old_temp, new_temp, fan_speed, steps;
|
|
|
|
int temp_change;
|
|
|
|
int step_up, step_down;
|
|
|
|
|
2012-11-18 21:16:49 +00:00
|
|
|
retrieve_settings(NULL);
|
2012-08-22 13:05:52 +00:00
|
|
|
|
2014-07-21 21:43:39 +00:00
|
|
|
sensors = retrieve_sensors();
|
|
|
|
fans = retrieve_fans();
|
2012-10-24 09:13:25 +00:00
|
|
|
set_fans_man(fans);
|
2014-07-27 17:44:00 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
new_temp = get_temp(sensors);
|
2014-07-27 17:44:00 +00:00
|
|
|
|
|
|
|
fan_speed = min_fan_speed;
|
2012-10-24 09:13:25 +00:00
|
|
|
set_fan_speed(fans, fan_speed);
|
2012-08-22 13:05:52 +00:00
|
|
|
|
|
|
|
if(verbose) {
|
2014-07-27 17:44:00 +00:00
|
|
|
printf("Sleeping for 2 seconds to get first temp delta\n");
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(daemonize) {
|
2014-07-27 17:44:00 +00:00
|
|
|
syslog(LOG_INFO, "Sleeping for 2 seconds to get first temp delta");
|
2012-06-11 19:43:53 +00:00
|
|
|
}
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2014-07-27 17:44:00 +00:00
|
|
|
sleep(2);
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
step_up = (float)( max_fan_speed - min_fan_speed ) /
|
|
|
|
(float)( ( max_temp - high_temp ) * ( max_temp - high_temp + 1 ) / 2 );
|
2012-06-09 14:25:28 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
step_down = (float)( max_fan_speed - min_fan_speed ) /
|
|
|
|
(float)( ( max_temp - low_temp ) * ( max_temp - low_temp + 1 ) / 2 );
|
2012-06-09 14:25:28 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
while(1) {
|
|
|
|
old_temp = new_temp;
|
|
|
|
new_temp = get_temp(sensors);
|
2012-06-09 14:25:28 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(new_temp >= max_temp && fan_speed != max_fan_speed) {
|
|
|
|
fan_speed = max_fan_speed;
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-06-09 14:25:28 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(new_temp <= low_temp && fan_speed != min_fan_speed) {
|
|
|
|
fan_speed = min_fan_speed;
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-06-09 14:25:28 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
temp_change = new_temp - old_temp;
|
2012-06-09 14:25:28 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(temp_change > 0 && new_temp > high_temp && new_temp < max_temp) {
|
|
|
|
steps = ( new_temp - high_temp ) * ( new_temp - high_temp + 1 ) / 2;
|
|
|
|
fan_speed = max( fan_speed, ceil(min_fan_speed + steps * step_up) );
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-06-09 14:25:28 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(temp_change < 0 && new_temp > low_temp && new_temp < max_temp) {
|
|
|
|
steps = ( max_temp - new_temp ) * ( max_temp - new_temp + 1 ) / 2;
|
|
|
|
fan_speed = min( fan_speed, floor(max_fan_speed - steps * step_down) );
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-06-09 14:25:28 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(verbose) {
|
|
|
|
printf("Old Temp %d: New Temp: %d, Fan Speed: %d\n", old_temp, new_temp, fan_speed);
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(daemonize) {
|
|
|
|
syslog(LOG_INFO, "Old Temp %d: New Temp: %d, Fan Speed: %d", old_temp, new_temp, fan_speed);
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
|
|
|
}
|
2012-06-11 19:43:53 +00:00
|
|
|
|
2012-10-24 09:13:25 +00:00
|
|
|
set_fan_speed(fans, fan_speed);
|
2012-06-09 14:25:28 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(verbose) {
|
|
|
|
printf("Sleeping for %d seconds\n", polling_interval);
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(daemonize) {
|
|
|
|
syslog(LOG_INFO, "Sleeping for %d seconds", polling_interval);
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-06-09 14:25:28 +00:00
|
|
|
}
|
2012-08-23 20:32:49 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
sleep(polling_interval);
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-06-09 14:25:28 +00:00
|
|
|
}
|