-
Notifications
You must be signed in to change notification settings - Fork 0
/
BattTracker.cpp
137 lines (118 loc) · 3.33 KB
/
BattTracker.cpp
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "BattStats.h"
void BattTracker::start(int MIN, bool clean){
auto t = time(nullptr);
auto tm = *localtime(&t);
if(isRunning()){ //already running
cout<<"Already running"<<endl;
exit(1);
}
ofstream flock("battstats.lock");
if(!flock){
cout<<"Error creating lock file"<<endl;
exit(1);
}
flock<<batteryLevel()<<endl;
fstream ff;
if(clean){
remove("battstats.log");
}
ff.open("battstats.log", ios::out|ios::app);
if(!ff){
cerr<<"Error opening log file"<<endl;
unlock();
exit(1);
}
ff.seekg(0, ios_base::end);
ff<<put_time(&tm, "%d-%m-%Y %H:%M:%S")<<'\t'<<"Battstats starting"<<endl;
bool status; //0 - charging, 1 - discharging
bool lastStatus = 0;
int h = 0;
int min = -MIN;
//condition will be modified by other istances
while(isRunning()){
status = isDischarging();
if(status!=lastStatus){
lastStatus = !lastStatus;
t = time(nullptr);
tm = *localtime(&t);
ff<<endl<<put_time(&tm, "%d-%m-%Y %H:%M:%S")<<'\t'<<"Status: "<< (status ? "discharging" : "charging")<<endl;
min = -MIN;
h = 0;
if(status){
flock.close();
remove("battstats.lock");
flock.open("battstats.lock");
flock<<batteryLevel()<<endl;
}
}
min += MIN;
if(min>59){
h++;
min -= 60;
}
ff<<setw(2)<<setfill('0')<<h<<':'<<setw(2)<<setfill('0')<<min<<"\t"<<batteryLevel()<<endl;
ff.flush(); //salva i cambiamenti
flock<<h*60+min<<endl;
flock.flush();
sleep(MIN*60);
}
t = time(nullptr);
tm = *localtime(&t);
ff<<endl<<put_time(&tm, "%d-%m-%Y %H:%M:%S")<<'\t'<<"Battstats exiting"<<endl<<endl;
ff.close();
flock.close();
unlock();
}
void BattTracker::unlock(){
remove("battstats.lock");
}
bool BattTracker::isRunning(){
ifstream flock("battstats.lock");
return flock.good();
}
//This function display status when app is run without args
void BattTracker::status(){
cout<<"Status: \t\t\t"<< (isRunning() ? "Running" : "Not Running") << endl;
int startingPercentage;
int min;
if(isRunning()){
ifstream flock("battstats.lock");
flock>>startingPercentage;
cout<<"Starting battery percentage: \t"<<startingPercentage<<endl;
while(flock){
flock>>min;
}
cout<<"Time elapsed: \t\t\t"<<setw(2)<<setfill('0')<<min/60<<':'<<setw(2)<<setfill('0')<<min%60<<endl;
}
cout<<"Current battery percentage: \t"<<batteryLevel()<<endl;
if(isRunning() && isDischarging()){
int currentPercentage = batteryLevel();
cout<<"Estimated time remaining: \t";
if(startingPercentage == currentPercentage || min == 0){
cout<<"Insufficient data"<<endl;
} else {
int eta = ((float)min/(startingPercentage - currentPercentage))*currentPercentage;
cout<<eta/60<<" hour(s) and "<<eta%60<<" minute(s)"<<endl;
}
}
}
void BattTracker::kill(){
//kill battstats
//exception for "battstats stop" is made excluding parent pid from kill
if(system("kill $(pgrep battstats | grep -v $PPID ) 2>/dev/null")){
cout<<"Error stopping or not running"<<endl;
}
}
int BattTracker::batteryLevel(){
ifstream fcapacity("/sys/class/power_supply/BAT1/capacity");
int percentage;
fcapacity>>percentage;
return percentage;
}
bool BattTracker::isDischarging(){
//(system("if [ `cat /sys/class/power_supply/BAT1/status` == 'Discharging' ]; then exit 1; fi; exit 0"))
ifstream fstatus("/sys/class/power_supply/BAT1/status");
char c;
fstatus>>c;
return (c=='D' ? true : false); //D for "Discharging" (reads only first char)
}