-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlog.c
118 lines (100 loc) · 3.67 KB
/
log.c
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "main.h"
void state_to_string(state_t state, char *string) {
switch (state) {
case CHARGING:
strncpy(string, "charging", MAX_BUFFER_SIZE);
break;
case DISCHARGING:
strncpy(string, "discharging", MAX_BUFFER_SIZE);
break;
default:
perror("Unable to convert state to string");
exit(EXIT_FAILURE);
}
}
static void update_sleep_count(time_t prev_time, int *sum, int *count) {
struct tm *prev = localtime(&prev_time);
// tm_isdst returns -1 if information not available
// accounts for daylight saving
if (prev->tm_isdst >= 0) {
prev->tm_hour -= prev->tm_isdst;
}
// converts prev to minutes past midnight
(*sum) += prev->tm_hour * 60 + prev->tm_min;
(*count)++;
}
void monitor_sleep_time(time_t current_time, battery_t *battery, FILE *analysis_file) {
// sum of 7 days previous sleep times stored in minutes past midnight
int sum_sleep_time = 0;
int number_of_sleeps = 0;
char buff[MAX_BUFFER_SIZE + 1];
// stores time of previous line in csv file
time_t prev_time = current_time;
while (fgets(buff, MAX_BUFFER_SIZE, analysis_file)) {
time_t temp_time = atol(buff);
// only stores if within 7 days
if (temp_time > (current_time - 7 * DAY_IN_SECONDS)) {
// only stores if there is a difference in 4 hours to prev
// this means that prev was the sleep time
if (prev_time < (temp_time - 4 * HOUR_IN_SECONDS)) {
update_sleep_count(prev_time, &sum_sleep_time, &number_of_sleeps);
}
prev_time = temp_time;
}
}
// checks if final line of csv is also a sleep time
if (prev_time < (current_time - 4 * HOUR_IN_SECONDS)) {
update_sleep_count(prev_time, &sum_sleep_time, &number_of_sleeps);
}
if (number_of_sleeps > 0) {
int average_sleep_time = sum_sleep_time / number_of_sleeps;
battery->data->average_sleep_time = average_sleep_time;
//printf("Average sleep time = %d in minutes past midnight.\n",average_sleep_time);
struct tm *current = localtime(¤t_time);
// checks if current time is within 30 minute window
if (average_sleep_time - (current->tm_hour * 60 + current->tm_min) < 30) {
battery->data->pre_sleep = true;
}
}
}
void write_to_files(battery_t *battery, FILE *log_file, FILE *analysis_file, time_t current_time) {
char state_string[MAX_BUFFER_SIZE];
state_to_string(battery->state, state_string);
struct tm *current = localtime(¤t_time);
// tm_isdst returns -1 if information not available
// accounts for daylight saving
if (current->tm_isdst >= 0) {
current->tm_hour -= current->tm_isdst;
}
// writes to text log
fprintf(log_file, "State: %s, Percentage: %d, Time: %s", state_string, battery->percentage, asctime(current));
// writes to csv log
fprintf(analysis_file, "%ld,%s,%d\n", current_time, state_string, battery->percentage);
}
void log_battery_info(battery_t *battery) {
FILE *log_file = fopen(BATTERY_LOG_PATH, "a");
if (log_file == NULL) {
perror("Failed to open battery logfile");
exit(EXIT_FAILURE);
}
FILE *analysis_file = fopen(BATTERY_ANALYSIS_PATH, "a+");
if (analysis_file == NULL) {
perror("Failed to open battery analysis file");
exit(EXIT_FAILURE);
}
// calculates current time in seconds past 01/01/1970
time_t current_time = time(NULL);
monitor_sleep_time(current_time, battery, analysis_file);
write_to_files(battery, log_file, analysis_file, current_time);
if (fclose(log_file) != 0) {
perror("Failed to close battery log file");
exit(EXIT_FAILURE);
}
if (fclose(analysis_file) != 0) {
perror("Failed to close battery analysis file");
exit(EXIT_FAILURE);
}
}