// control charging of battery on apple M1 // tested on macbook pro 2021 model // works on linux #include #include #include #include #include #include #include #include #include int main(int argc, char **argv) { int i; int option; int limit = 90; while ((option = getopt(argc, argv, "l:uh")) != -1) { switch (option) { case 'h': puts("help"); puts("-l limit capacity"); break; case 'l': limit = atoi(optarg); printf("limit: %d\n", limit); break; default: /* '?' */ puts("unknown option"); } } pid_t pid, sid; pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } if (pid > 0) { exit(EXIT_SUCCESS); } umask(0); sid = setsid(); if (sid < 0) { exit(EXIT_FAILURE); } if ((chdir("/")) < 0) { exit(EXIT_FAILURE); } close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); FILE * cb; FILE * capfile; char cbeh[20]; char cap[6]; int icap; char LOGNAME[] = "charge-ctl"; char aut[] = "auto"; char inh[] = "inhibit-charge"; char dis[] = "force-discharge"; void change (char *what) { char buf[1024]; ssize_t len; int fd; char *filename; fd = open("/sys/class/power_supply/macsmc-battery/charge_behaviour", O_RDONLY); len = read(fd, buf, sizeof(buf)-1); close(fd); buf[len-1] = 0; if (strcmp(buf, what) == 0) { openlog(LOGNAME, LOG_PID, LOG_USER); syslog(LOG_USER | LOG_INFO, "no change"); return; } cb = fopen("/sys/class/power_supply/macsmc-battery/charge_behaviour", "w"); if (cb == NULL) { printf("problem with open\n"); exit(EXIT_FAILURE); } fprintf(cb, "%s", what); fclose(cb); openlog(LOGNAME, LOG_PID, LOG_USER); syslog(LOG_USER | LOG_INFO, what); } while (1) { capfile = fopen("/sys/class/power_supply/macsmc-battery/capacity", "r"); fgets(cap, 5, capfile); fclose(capfile); icap = atoi(cap); if (icap < 85) { change(aut); } else if (icap > 90) { change(dis); } else { change(inh); } sleep(60); } exit(EXIT_SUCCESS); }