fancontrol

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello

I writhed for my fun a fancontrol in C. Currently is do only managing speed fan and detect startup value and stop value for fans (for example, my cpu fan is stoping at 18 and start at value 30 set in pwm file).
In the future I want to implement:
- control fan reading hdd temp (currently is using only fans that are visible in /sys/class/hwmon/*)
- detect fan controlers
- detect GPU temp (this is a plan for far far away time)
- save settings in files
- use multiple temp sensors (for example, use mb sensors...for normal operations, but if CPU temp si jumping a trigger value...speed all case fans - usefull if cpu heat sink is good, but you need and a good airflow in case) - a nice gui for fans/sensors (this is a plan to start in october-november...) If lm-sensors team are interested about this, please announce me. To know if is worth to make some cosmetics for apps etc.

The current code is working almost...without erros.
I attached a older version (currently, the new version is not on my laptop..)

Ioan Rusan

#include "main.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(int argc, char **argv){
    char *config_file;
    int i;
    int autoload = 0;
    int autodetect = 0;
    int ii = 0;
    config_file = NULL;
    if(argc < 2){
	printf("Usage: fanmanager --config full_path_to_config_file\n");
	exit(-1);
    }
    for(i = 0; i < argc; i++){
	if(strstr(argv[i], "--config") != 0)
	    config_file = argv[i+1];
	if(strstr(argv[i], "--autoload") != 0)
	    autoload = atoi(argv[i+1]);
	if(strstr(argv[i], "--autodetect") != 0)
	    autodetect = 1;
	if(strstr(argv[i], "--detect_startup") !=0)
	  autodetect = 2;
    }
    if(config_file == NULL){
      printf("There are no config file!\n");
      exit(0);
    }
    if(load_fan_settings(config_file) !=0){
      printf("Error loading config file");
      exit(0);
    }
    printf("Enable fan control for %d fans...\n", number_of_fans);
    enable_fan_control();
    if(autodetect == 1){
	autodetect_fan_range();
	exit(0);
    }
    if(autodetect == 2){
      detect_startup_value();
      exit(0);
    }
    for(;;){
	system("clear");
	if(autoload !=0){
	    ii++;
	    if(ii == autoload){
		load_fan_settings(config_file);
	        ii = 0;
	    }
	}

	for(i = 0; i <= number_of_fans; i++){
	    load_fan_status(i);
	}
	calc_fan_speed();
	for(i = 0; i <= number_of_fans; i++){
	    printf("Temp: %d, min_speed: %d, start_speed: %d, max_temp = %d, current_fan_speed %d, current_fan_rpm %d, \noutput_fan_speed %s, input_temp_sensor %s, input_fan_speed %s\n", fan[i].current_temp, fan[i].min_speed, fan[i].start_temp, fan[i].max_temp, fan[i].current_fan_speed, fan[i].fan_rpm, fan[i].output_fan_speed, fan[i].input_temp_sensor, fan[i].input_fan_speed);
	}
	for(i = 0; i <= number_of_fans; i++)
	    set_fan_speed(i);
        usleep(300000);
    }
    return 0;
}

int autodetect_fan_range(){
  int i;
  int found = 0;
  int half, last_min, min;
  for (i = 0;  number_of_fans >= i; i++){
    last_min = 255;
    fan[i].current_fan_speed = 255;
    fan[i].min_speed = 255;
    set_fan_speed(i);
	printf("SpeedUp fan %d\n", i);
    sleep(5);
    min = 255;
    do{
	fan[i].current_fan_speed--;
	if(set_fan_speed(i) != 0){
	  printf("Error setting new speed\n");
	  break;
	}
	sleep(1);
	load_fan_status(i);
	printf("rpm: %d, fan_speed %d\n", fan[i].fan_rpm, fan[i].current_fan_speed);
	if(fan[i].fan_rpm == 0){
	    found = 1;
	    fan[i].min_speed = fan[i].current_fan_speed+1;
	}else
	    found = 0;
    }while(found == 0);
  }
}

int detect_startup_value(){
  int i,ii;
  for(i = 0; number_of_fans >= i; i++){
    fan[i].current_fan_speed = 0;
    set_fan_speed(i);
    printf("Wait for fans to stop");
    sleep(5);
    for(ii = 0; ii < 255; ii++){
      	printf("rpm: %d, fan_speed %d\n", fan[i].fan_rpm, fan[i].current_fan_speed);
      fan[i].current_fan_speed = ii;
      set_fan_speed(i);
      sleep(1);
      load_fan_status(i);
      if(fan[i].fan_rpm > 0){
	fan[i].min_speed = ii;
	printf("Fan %d is starting at value %d", i, ii);
	ii = 255;
      }
    }
  }
}

int enable_fan_control(){
  FILE *fp;
  char *file_name, *int_point;
  int i;
  file_name = (char *) malloc(1024);
  printf("%d\n", number_of_fans);
  for(i = 0; number_of_fans >= i; i++){
    memcpy(file_name, fan[i].output_fan_speed, strlen(fan[i].output_fan_speed));
    int_point = file_name+strlen(fan[i].output_fan_speed);
    memcpy(int_point, "_enable", 8);
    printf("Enable for %s\n", file_name);
    fp = fopen(file_name, "w");
    if(fp == NULL){
      printf("Enable fan %d failed\n", i);
    }
    fwrite("1", 1, 1, fp);
    fclose(fp);
  }
  free(file_name);
  return 0;
  
}
char *extract_value(char *string){
    char *buffer;
    char *buffer1;
    char *val;
    int first = 0;
    buffer1 = (char *) malloc(1024);
    buffer = (char *) malloc(1024);
    memcpy(buffer1, string, 1023);
    strtok(buffer1, "=");
    while (buffer != NULL){
	val = strtok(NULL, "=");
	if(strlen(val) < 1023)
	    memcpy(buffer, val, strlen(val));
	else
	    memcpy(buffer, val, 1023);
	free(buffer1);
	return buffer;
    }
    free(buffer1);
}

int load_fan_settings(char *file_config){
    FILE *fp;
    char *line;
    char *buffer;
    int fan_number = 0;
    int check = 7;
    fp = fopen(file_config, "r");
    line = (char *) malloc(1024);
    number_of_fans = -1;
    while(!feof(fp)){
      memset(line, 0, 1023);
      fgets(line, 1023, fp);
      buffer = extract_value(line);
      if(strstr(line, "SENSOR=") != 0){
	if(check < 7){
	  prinf("configuration file with erros for sensor %d", number_of_fans);
	  exit(-1);
	}
	check = 7;
	number_of_fans++;
	fan_number = (atoi(buffer)-1);
	if(fan_number < 0)
	    exit(-2);
	if(number_of_fans > 0)
	    fan = (fans *) realloc(fan, (number_of_fans + 1) * sizeof(fans));
	else
	    fan = (fans *) calloc((number_of_fans + 1), sizeof(fans));
	fan[fan_number].fan_id = fan_number;
      }
      fan[fan_number].max_temp = 50;
      fan[fan_number].min_temp = 30;
      fan[fan_number].min_speed = 255;
	if(strstr(line, "MAX_TEMP") != NULL){
	  if(atoi(buffer) < 255){
	    fan[fan_number].max_temp = atoi(buffer);
	    check++;
	  }else{
	    printf("for MAX_TEMP range is 0 to 255\n");
	    exit(-1);
	  }
	}
	if(strstr(line, "MIN_TEMP") != NULL){
	  if(atoi(buffer) < 255){
	    fan[fan_number].start_temp = atoi(buffer);
	    check++;
	  }else{
	    printf("for MIN_TEMP range is 0 to 255\n");
	    exit(-1);
	  }
	}
	if(strstr(line, "MIN_SPEED") != NULL){
	  if(atoi(buffer) < 255){
	    fan[fan_number].min_speed = atoi(buffer);
	    check++;
	  }else{
	    printf("for MIN_SPEED range is 0 to 255\n");
	    exit(-1);
	  }
	}
	if(strstr(line, "TEMP_INPUT") != NULL){
	    memcpy(fan[fan_number].input_temp_sensor, buffer, strlen(buffer) - 1);
	    check++;
	}
	if(strstr(line, "OUTPUT_FAN") != NULL){
	    memcpy(fan[fan_number].output_fan_speed, buffer, strlen(buffer) - 1);
	    check++;
	}
	if(strstr(line, "INPUT_FAN") != NULL){
	    memcpy(fan[fan_number].input_fan_speed, buffer, strlen(buffer) - 1);
	    check++;
	}
	if(strstr(line, "LINIAR_FAN") != NULL){
	    fan[fan_number].liniar_fan = atoi(buffer);
	    check++;
	}
    }
    if(check < 7){
      printf("error in config file\n");
      exit(-1);
    }
    free(line);
    return 0;
}

int set_fan_speed(int fan_number){
    FILE *fp;
    char *mem_zone;
    mem_zone = (char *) calloc(255, 1);
    sprintf(mem_zone, "%d", fan[fan_number].current_fan_speed);
    fp = fopen(fan[fan_number].output_fan_speed, "w");
    if(fp != NULL)
	fwrite(mem_zone, sizeof(mem_zone), 1, fp);
    else{
	printf("Error opening fan device %s \n",fan[fan_number].output_fan_speed);
	return -1;
    }

    fclose(fp);
    return 0;
}

int load_fan_status(int fan_number){
    FILE *fp;
    char *buffer;
    buffer = (char *) calloc(32,1);
    fp = fopen(fan[fan_number].output_fan_speed, "r");
    if(fp == NULL){
	printf("Error opening %s\n", fan[fan_number].output_fan_speed);
    }else{
        fscanf(fp, "%s", buffer);
        fan[fan_number].current_fan_speed = atoi(buffer);
        fclose(fp);
    }

    fp = fopen(fan[fan_number].input_temp_sensor, "r");
    if(fp == NULL){
	printf("Error opening %s\n", fan[fan_number].input_temp_sensor);
    }else{
        memset(buffer, 0, 31);
        fscanf(fp, "%s", buffer);
	if((atoi(buffer)/1000) < 255)
	  fan[fan_number].current_temp = (atoi(buffer)/1000);
	else
	  fan[fan_number].current_temp = 255;
        fclose(fp);
    }
    fp = fopen(fan[fan_number].input_fan_speed, "r");
    if(fp == NULL){
    	printf("Error opening %s\n", fan[fan_number].input_fan_speed);
    }else{
        memset(buffer, 0, 31);
        fscanf(fp, "%s", buffer);
	if((atoi(buffer) < 65355))
	  fan[fan_number].fan_rpm = atoi(buffer);
	else
	  fan[fan_number].fan_rpm = 65355;
        fclose(fp);
    }

    free(buffer);
    if(fp == NULL)
	return -1;
    return 0;
}
int full_speed(){
  return 0;
}

int calc_fan_speed(){
  unsigned int i = 0;
  unsigned int diviziune, temp_diff, current_need_speed;

  for(i = 0; i <= number_of_fans; i++){
    if(fan[i].current_temp >= fan[i].max_temp){
 	fan[i].current_fan_speed = 255;
    }else{
	temp_diff = fan[i].max_temp - fan[i].start_temp;
	if((temp_diff < 0) || (temp_diff > 255) || (fan[i].min_speed < 0))
	  diviziune = 1;
	else
	  diviziune = (255 - fan[i].min_speed)/temp_diff;
	if(fan[i].current_temp >= fan[i].start_temp)
    	    current_need_speed = (fan[i].current_temp - fan[i].start_temp) * diviziune;
    	else
    	    current_need_speed = 0;
	if((current_need_speed > 255) || (current_need_speed < 0))
	  current_need_speed = 255;
	printf("diviziune: %d, current_need_speed %d\n", diviziune, current_need_speed);
	if(current_need_speed < fan[i].min_speed)
          fan[i].current_fan_speed = fan[i].min_speed;
	else{
	    if(fan[i].liniar_fan == 0){
		fan[i].current_fan_speed = current_need_speed * current_need_speed;
	    }else
		fan[i].current_fan_speed = current_need_speed;
	}
    }
  }

  return 0;
}
typedef struct fans{
    int fan_id;
    char input_temp_sensor[255];
    char input_fan_speed[255];
    char output_fan_speed[255];
    unsigned char current_fan_speed;
    unsigned int fan_rpm;
    int current_temp;
    unsigned int min_speed;
    int start_temp;
    int max_temp;
    char liniar_fan;
    char intermediar_step;
}fans;


fans *fan;
int number_of_fans;
int load_fan_settings(char *file_config);
int load_fan_status(int fan_number);
int set_fan_speed(int fan_number);
int full_speed();
int calc_fan_speed();
int get_value_setting(char *source, char *store);
char *extract_value(char *string);
int autodetect_range();
int detect_startup_value();
int enable_fan_control();
_______________________________________________
lm-sensors mailing list
lm-sensors@xxxxxxxxxxxxxx
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux