summaryrefslogtreecommitdiff
path: root/src/modules/battery.c
blob: 02379c8de355907d9687e1c6279bf9466d776d6b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include "battery.h"

#include <stdlib.h>
#include <string.h>
#include <tgmath.h>
#include <stdbool.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

#define VALUE_SIZE 16
#define BATTERY_PATH "/sys/class/power_supply/BAT1/"

struct battery {
    int status;
    int capacity;
    time_t last_updated;
    char value[VALUE_SIZE];
};

static int
open_battery_file(const char * name)
{
    char path[128];
    snprintf(path, 128, "%s%s", BATTERY_PATH, name);
    return open(path, O_RDONLY);
}

static int
battery_value(int file)
{
    const size_t buf_size = 4;
    int val = 0;
    char buf[buf_size];

    memset(&buf, '\0', buf_size);
    lseek(file, 0, SEEK_SET);
    read(file, &buf, sizeof(char) * buf_size);
    sscanf(buf, "%d", &val);

    return val;
}

static bool
battery_status_discharging(int file)
{
    const size_t buf_size = 16;
    char buf[buf_size];

    memset(&buf, '\0', buf_size);
    lseek(file, 0, SEEK_SET);
    read(file, &buf, sizeof(char) * buf_size);

    return strncmp(buf, "Discharging\n", buf_size) == 0;
}

struct battery *
battery_new()
{
    struct battery * b = malloc(sizeof(struct battery));
    b->last_updated = 0;
    b->capacity = open_battery_file("capacity");
    b->status = open_battery_file("status");
    return b;
}

void
battery_free(struct battery * b)
{
    close(b->status);
    close(b->capacity);
    free(b);
}

void battery_update(struct battery * b)
{
    int cap = battery_value(b->capacity);
    bool discharge = battery_status_discharging(b->status);
    snprintf(
        b->value, VALUE_SIZE,
        "%s% 4d%%",
        discharge ? "\uf241" : "\uf0e7",
        cap);
}

const char *
battery_get_val(struct battery * b)
{
    return b->value;
}

bool
battery_should_update(struct battery * b, time_t now, unsigned short limit)
{
    double time_diff = difftime(now, b->last_updated);
    if(time_diff >= limit) {
        b->last_updated = now;
        return true;
    }
    return false;
}