Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New app: Battery monitor #1147

Merged
merged 6 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,5 @@ src/**/easter
!easter/
src/**/axp
!axp/
src/**/batteryMonitorUI
!batteryMonitorUI/
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ core: $(CACHE)/.setup

apps: $(CACHE)/.setup
@$(ECHO) $(PRINT_RECIPE)
@cd $(SRC_DIR)/batteryMonitorUI && BUILD_DIR="$(PACKAGES_APP_DEST)/Battery monitor tool/App/BatteryMonitorUI" make
@find $(SRC_DIR)/batteryMonitorUI -depth -type d -name res -exec cp -r {}/. "$(PACKAGES_APP_DEST)/Battery monitor tool/App/BatteryMonitorUI/res/" \;
@cd $(SRC_DIR)/playActivityUI && BUILD_DIR="$(PACKAGES_APP_DEST)/Activity Tracker/App/PlayActivity" make
@find $(SRC_DIR)/playActivityUI -depth -type d -name res -exec cp -r {}/. "$(PACKAGES_APP_DEST)/Activity Tracker/App/PlayActivity/res/" \;
@find $(SRC_DIR)/packageManager -depth -type d -name res -exec cp -r {}/. $(BUILD_DIR)/App/PackageManager/res/ \;
Expand Down
2 changes: 1 addition & 1 deletion src/batmon/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ INCLUDE_SHMVAR=1
include ../common/config.mk

TARGET = batmon
LDFLAGS := $(LDFLAGS) -pthread
LDFLAGS := $(LDFLAGS) -pthread -lsqlite3

include ../common/commands.mk
include ../common/recipes.mk
207 changes: 195 additions & 12 deletions src/batmon/batmon.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@
#include <stdlib.h>
#include <string.h>

int battery_current_state_duration = 0;
int best_session_time = 0;

int main(int argc, char *argv[])
{
log_setName("batmon");
getDeviceModel();
getDeviceSerial();
best_session_time = get_best_session_time();

FILE *fp;
int old_percentage = -1, current_percentage, warn_at = 15;
int old_percentage = -1, current_percentage, warn_at = 15, last_logged_percentage = -1;

atexit(cleanup);
signal(SIGINT, sigHandler);
Expand All @@ -17,25 +24,45 @@ int main(int argc, char *argv[])
signal(SIGCONT, sigHandler);

display_init();

int ticks = CHECK_BATTERY_TIMEOUT_S;

bool is_charging = false;

while (!quit) {
if (battery_isCharging()) {
if (!is_charging) {
// Charging just started
is_charging = true;
if (DEVICE_ID == MIYOO354) {
current_percentage = getBatPercMMP();
// To solve : Sometimes getBatPercMMP returns 1735289191
current_percentage = (current_percentage > 100) ? old_percentage : current_percentage;
}
else {
current_percentage = 500;
saveFakeAxpResult(current_percentage);
}
is_charging = true;
update_current_duration();

int session_time = get_current_session_time();
printf_debug("Charging detected - Previous session duration = %d\n", session_time);

if (session_time > best_session_time) {
printf_debug("Best session duration\n", 1);
set_best_session_time(session_time);
best_session_time = session_time;
}
log_new_percentage(current_percentage, is_charging);
}
}
else if (is_charging) {
// Charging just stopped
is_charging = false;

printf_debug(
"Charging stopped: suspended = %d, perc = %d, warn = %d\n",
is_suspended, current_percentage, warn_at);

if (DEVICE_ID == MIYOO283) {
adc_value_g = updateADCValue(0);
current_percentage = batteryPercentage(adc_value_g);
Expand All @@ -44,9 +71,8 @@ int main(int argc, char *argv[])
else if (DEVICE_ID == MIYOO354) {
current_percentage = getBatPercMMP();
}
printf_debug(
"charging stopped: suspended = %d, perc = %d, warn = %d\n",
is_suspended, current_percentage, warn_at);
update_current_duration();
log_new_percentage(current_percentage, is_charging);
}

if (!is_suspended) {
Expand All @@ -59,19 +85,33 @@ int main(int argc, char *argv[])
}
else if (DEVICE_ID == MIYOO354) {
current_percentage = getBatPercMMP();
// To solve : Sometimes getBatPercMMP returns 1735289191
current_percentage = (current_percentage > 100) ? old_percentage : current_percentage;
}
printf_debug(
"battery check: suspended = %d, perc = %d, warn = %d\n",
is_suspended, current_percentage, warn_at);

ticks = -1;
}

if (current_percentage != old_percentage) {
// This statement is not englobed in the previous one
// in order to be launched once when batmon starts
printf_debug(
"saving percBat: suspended = %d, perc = %d, warn = %d\n",
is_suspended, current_percentage, warn_at);
old_percentage = current_percentage;
file_put_sync(fp, "/tmp/percBat", "%d", current_percentage);

if (abs(last_logged_percentage - current_percentage) >= BATTERY_LOG_THRESHOLD) {
// Current battery state duration addition
update_current_duration();
// New battery percentage entry
log_new_percentage(current_percentage, is_charging);
last_logged_percentage = current_percentage;
}

if (DEVICE_ID == MIYOO283) {
saveFakeAxpResult(current_percentage);
}
Expand All @@ -90,11 +130,16 @@ int main(int argc, char *argv[])
else
batteryWarning_hide();
#endif
if (battery_current_state_duration > MAX_DURATION_BEFORE_UPDATE)
update_current_duration();

ticks++;
sleep(1);
battery_current_state_duration++;
ticks++;
}

// Current battery state duration addition
update_current_duration();
return EXIT_SUCCESS;
}

Expand Down Expand Up @@ -127,6 +172,148 @@ void cleanup(void)
close(sar_fd);
}

void update_current_duration(void)
{
if (open_battery_log_db() == 1) {
if (bat_log_db != NULL) {
const char *sql = "SELECT * FROM bat_activity WHERE device_serial = ? ORDER BY id DESC LIMIT 1;";
sqlite3_stmt *stmt;
int rc = sqlite3_prepare_v2(bat_log_db, sql, -1, &stmt, 0);

if (rc == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, DEVICE_SN, -1, SQLITE_STATIC);
rc = sqlite3_step(stmt);
if (rc == SQLITE_ROW) {
int current_duration = sqlite3_column_int(stmt, 3);
int new_duration = current_duration + battery_current_state_duration;

const char *update_sql = "UPDATE bat_activity SET duration = ? WHERE id = ?";

sqlite3_stmt *update_stmt;
rc = sqlite3_prepare_v2(bat_log_db, update_sql, -1, &update_stmt, 0);

if (rc == SQLITE_OK) {
sqlite3_bind_int(update_stmt, 1, new_duration);
sqlite3_bind_int(update_stmt, 2, sqlite3_column_int(stmt, 0));

// Exécuter la mise à jour
rc = sqlite3_step(update_stmt);

battery_current_state_duration = 0;
sqlite3_finalize(stmt);
sqlite3_finalize(update_stmt);
}
}
}
close_battery_log_db();
}
}
}

void log_new_percentage(int new_bat_value, int is_charging)
{
if (open_battery_log_db() == 1) {
if (bat_log_db != NULL) {
char *sql = sqlite3_mprintf("INSERT INTO bat_activity(device_serial, bat_level, duration, is_charging) VALUES(%Q, %d, %d, %d);", DEVICE_SN, new_bat_value, 0, is_charging);
sqlite3_exec(bat_log_db, sql, NULL, NULL, NULL);
sqlite3_free(sql);

// FILO logic
sqlite3_stmt *stmt;
const char *count_sql = "SELECT COUNT(id) FROM bat_activity";

int count = 0;

if (sqlite3_prepare_v2(bat_log_db, count_sql, -1, &stmt, NULL) == SQLITE_OK) {
if (sqlite3_step(stmt) == SQLITE_ROW) {
count = sqlite3_column_int(stmt, 0);
}
sqlite3_finalize(stmt);
}

if (count > FILO_MIN_SIZE) {
// Deletion of the 1st entry
const char *delete_sql = "DELETE FROM bat_activity WHERE id = (SELECT MIN(id) FROM bat_activity);";
sqlite3_prepare_v2(bat_log_db, delete_sql, -1, &stmt, 0);
sqlite3_step(stmt);
}
}
close_battery_log_db();
}
}

int get_current_session_time(void)
{
int current_session_duration = 0;
if (open_battery_log_db() == 1) {
if (bat_log_db != NULL) {
const char *sql = "SELECT * FROM bat_activity WHERE device_serial = ? AND is_charging = 1 ORDER BY id DESC LIMIT 1;";
sqlite3_stmt *stmt;
int rc = sqlite3_prepare_v2(bat_log_db, sql, -1, &stmt, 0);

if (rc == SQLITE_OK) {

sqlite3_bind_text(stmt, 1, DEVICE_SN, -1, SQLITE_STATIC);
rc = sqlite3_step(stmt);
if (rc == SQLITE_ROW) {

sqlite3_stmt *stmt_sum;
const char *query_sum = "SELECT SUM(duration) FROM bat_activity WHERE device_serial = ? AND id > ?;";
rc = sqlite3_prepare_v2(bat_log_db, query_sum, -1, &stmt_sum, NULL);
if (rc == SQLITE_OK) {
sqlite3_bind_text(stmt_sum, 1, DEVICE_SN, -1, SQLITE_STATIC);
sqlite3_bind_int(stmt_sum, 2, sqlite3_column_int(stmt, 0));
while ((rc = sqlite3_step(stmt_sum)) == SQLITE_ROW) {
current_session_duration = sqlite3_column_int(stmt_sum, 0);
}
}
sqlite3_finalize(stmt_sum);
}
}
sqlite3_finalize(stmt);
}
close_battery_log_db();
}
return current_session_duration;
}

int set_best_session_time(int best_session)
{
int is_success = 0;
if (open_battery_log_db() == 1) {
if (bat_log_db != NULL) {
const char *sql = "SELECT * FROM device_specifics WHERE device_serial = ? ORDER BY id LIMIT 1;";
sqlite3_stmt *stmt;
int rc = sqlite3_prepare_v2(bat_log_db, sql, -1, &stmt, 0);

if (rc == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, DEVICE_SN, -1, SQLITE_STATIC);
rc = sqlite3_step(stmt);
if (rc == SQLITE_ROW) {
const char *update_sql = "UPDATE device_specifics SET best_session = ? WHERE id = ?";

sqlite3_stmt *update_stmt;
rc = sqlite3_prepare_v2(bat_log_db, update_sql, -1, &update_stmt, 0);

if (rc == SQLITE_OK) {
sqlite3_bind_int(update_stmt, 1, best_session);
sqlite3_bind_int(update_stmt, 2, sqlite3_column_int(stmt, 0));

// Exécuter la mise à jour
rc = sqlite3_step(update_stmt);

sqlite3_finalize(stmt);
sqlite3_finalize(update_stmt);
is_success = 1;
}
}
}
close_battery_log_db();
}
}
return is_success;
}

void saveFakeAxpResult(int current_percentage)
{
FILE *fp;
Expand Down Expand Up @@ -161,7 +348,7 @@ int updateADCValue(int value)
return value;
}

int getBatPercMMP()
int getBatPercMMP(void)
{
char buf[100] = "";
int battery_number;
Expand Down Expand Up @@ -190,9 +377,6 @@ int batteryPercentage(int value)
return 0;
}

//
// Draw Battery warning thread
//
static void *batteryWarning_thread(void *param)
{
while (1) {
Expand All @@ -217,6 +401,5 @@ void batteryWarning_hide(void)
return;
pthread_cancel(adc_pt);
pthread_join(adc_pt, NULL);
display_drawFrame(0); // erase red frame
adcthread_active = false;
}
14 changes: 14 additions & 0 deletions src/batmon/batmon.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <sqlite3/sqlite3.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
Expand All @@ -25,12 +26,20 @@
#include "utils/flags.h"
#include "utils/log.h"

#include "batmonDB.h"

#define CHECK_BATTERY_TIMEOUT_S 15 // s - check battery percentage every 15s

// Battery logs
#define BATTERY_LOG_THRESHOLD 2 // Define when a new battery entry is logged
#define FILO_MIN_SIZE 1000
#define MAX_DURATION_BEFORE_UPDATE 600

// for reading battery
#define SARADC_IOC_MAGIC 'a'
#define IOCTL_SAR_INIT _IO(SARADC_IOC_MAGIC, 0)
#define IOCTL_SAR_SET_CHANNEL_READ_VALUE _IO(SARADC_IOC_MAGIC, 1)

typedef struct {
int channel_value;
int adc_value;
Expand All @@ -44,6 +53,11 @@ static bool is_suspended = false;

static void sigHandler(int sig);
void cleanup(void);

void update_current_duration(void);
void log_new_percentage(int new_bat_value, int is_charging);
int get_current_session_time(void);
int set_best_session_time(int best_session);
void saveFakeAxpResult(int current_percentage);
bool isCharging(void);
int updateADCValue(int);
Expand Down