From 55e9edf8ed682bdd79b9b231283432dad7f5192c Mon Sep 17 00:00:00 2001 From: Alessandro Mauri Date: Wed, 9 Oct 2024 17:35:05 +0200 Subject: [PATCH] quick rewrite in C --- ambientd.c | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 ambientd.c diff --git a/ambientd.c b/ambientd.c new file mode 100644 index 0000000..4826e08 --- /dev/null +++ b/ambientd.c @@ -0,0 +1,163 @@ +#include +#include +#include +#include +#include +#include + +#define MAX(x, y) ((x) > (y) ? (x) : (y)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#define ABS(x) ((x) < 0 ? -(x) : (x)) +#define MEDIAN_SAMPLES 4 + +const char *LUMINANCE_DEV = "/sys/bus/iio/devices/iio:device0/in_illuminance_raw"; +const char *MAX_BRIGHTNESS_DEV = "/sys/class/backlight/intel_backlight/max_brightness"; +const char *BRIGHTNESS_DEV = "/sys/class/backlight/intel_backlight/brightness"; +const char *ACTUAL_BRIGHTNESS_DEV = "/sys/class/backlight/intel_backlight/actual_brightness"; + +char STR_BUFFER[128] = {0}; + +// file pointer to the luminance device +FILE *luminance_fp = NULL; + +// max luminance that the display can output +int max_luminance = 400; + +// minimum display brightness in percent +float min_brightness_percent = 0.05; + +// retturns the luminance value in percentage between 0 and 1 +int get_luminance_raw (void) +{ + const char *x = fgets(STR_BUFFER, sizeof(STR_BUFFER), luminance_fp); + if (x == NULL) { + fprintf(stderr, "Could not read luminance value: %s\n", strerror(errno)); + return 1.0; + } + int luminance = strtol(STR_BUFFER, NULL, 10); + rewind(luminance_fp); + + return luminance; +} + +int read_int(FILE *fp) +{ + fflush(fp); + const char *p = fgets(STR_BUFFER, sizeof(STR_BUFFER), fp); + if (p == NULL) { + return -1; + } + long r = strtol(STR_BUFFER, NULL, 10); + if (r == LONG_MIN || r == LONG_MAX) { + return -1; + } + rewind(fp); + return r; +} + +int main (void) +{ + // open the luminance device + luminance_fp = fopen(LUMINANCE_DEV, "r"); + if (luminance_fp == NULL) { + fprintf(stderr, "Could not open luminance device '%s': %s\n", + LUMINANCE_DEV, strerror(errno)); + return 1; + } + + // get max and min brightness + FILE *fp = fopen(MAX_BRIGHTNESS_DEV, "r"); + if (fp == NULL) { + fprintf(stderr, "Could not open max_brightness file '%s': %s\n", + MAX_BRIGHTNESS_DEV, strerror(errno)); + return 1; + } + int max_brightness = read_int(fp); + if (max_brightness < 0) { + fprintf(stderr, "Could not read max brightness value: %s\n", strerror(errno)); + return 1; + } + int min_brightness = max_brightness * min_brightness_percent; + fclose(fp); + + + // open brightness device + FILE *brightness_fp = fopen(BRIGHTNESS_DEV, "w"); + if (brightness_fp == NULL) { + fprintf(stderr, "Could not open brightness device '%s': %s\n", + BRIGHTNESS_DEV, strerror(errno)); + return 1; + } + + // open actual brightness device + FILE *actual_brightness_fp = fopen(ACTUAL_BRIGHTNESS_DEV, "r"); + if (brightness_fp == NULL) { + fprintf(stderr, "Could not open actual brightness device '%s': %s\n", + ACTUAL_BRIGHTNESS_DEV, strerror(errno)); + return 1; + } + + int x = get_luminance_raw(); + int luminance_samples[MEDIAN_SAMPLES] = {x, x, x, x}; + int idx = 0; + int user_offset = 0; + int brightness_target = min_brightness; + int brightness_old = min_brightness; + int brightness_adjusted = min_brightness; + int brightness_delta = 0; + while (1) { + static float luminance; + static float luminance_percent; + + luminance_samples[idx] = get_luminance_raw(); + idx = (idx + 1) % MEDIAN_SAMPLES; + + luminance = 0; + for (int i = 0; i < MEDIAN_SAMPLES; i++) { + luminance += luminance_samples[i] / MEDIAN_SAMPLES; + } + luminance_percent = MIN(luminance/max_luminance, 1.0); + + brightness_old = brightness_target; + brightness_target = MAX((int)(luminance_percent * max_brightness), min_brightness); + brightness_delta = ABS((float)(brightness_target - brightness_old)/brightness_old); + + // if the brightness changes by more than 10% reduce the user offset, scaling + // with the delta, this accounts for large changes in brightness no longer + // corresponding to the adjustments that the user made to the brightness + if (brightness_delta > 0.1) { + user_offset = user_offset * MAX(MIN(1-(brightness_delta*1.2), 1), 0); + } + + brightness_adjusted = MIN(MAX(brightness_target + user_offset, min_brightness), max_brightness); + x = snprintf(STR_BUFFER, sizeof(STR_BUFFER), "%d", brightness_adjusted); + if (x <= 0) { + fprintf(stderr, "Error in snprintf(): %s\n", strerror(errno)); + } + if (fputs(STR_BUFFER, brightness_fp) == EOF) { + fprintf(stderr, "error writing brightness: %s\n", strerror(errno)); + } + rewind(brightness_fp); + + sleep(3); + + // read actual brightness to get the user offset + int actual_brightness = 0; + int off = 0; + actual_brightness = read_int(actual_brightness_fp); + if (actual_brightness < 0) { + fprintf(stderr, "error reading actual brightness: %s\n", strerror(errno)); + actual_brightness = brightness_target; + } + + off = actual_brightness - brightness_target; + if (brightness_target != max_brightness || off < 0){ + user_offset = off; + } + + printf("brightness target: %d; user offset: %d; brightness adjusted: %d\n\n", brightness_target, user_offset, brightness_adjusted); + + } + + return 0; +}