Add min and max temp and humid screen
This commit is contained in:
parent
d368d1f71d
commit
961179db27
@ -148,7 +148,7 @@ static bool stats_screen_dispatch(StatsScreen *screen, SensorState *state) {
|
|||||||
lcd_clear(state->lcd);
|
lcd_clear(state->lcd);
|
||||||
lcd_write_string(state->lcd, "temp humi time");
|
lcd_write_string(state->lcd, "temp humi time");
|
||||||
char buff[17];
|
char buff[17];
|
||||||
int cur_len = snprintf(buff, sizeof(buff), "%.1f%c %3" PRIu32 "%% ",
|
int cur_len = snprintf(buff, sizeof(buff), "%-4.1f%c %3" PRIu32 "%% ",
|
||||||
convert_temperature(state->temp),
|
convert_temperature(state->temp),
|
||||||
GLOBAL_OPTS.temp_unit, state->humid);
|
GLOBAL_OPTS.temp_unit, state->humid);
|
||||||
struct tm lt;
|
struct tm lt;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "statrange.h"
|
#include "statrange.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
@ -92,6 +93,10 @@ static void stat_range_show_data(StatRangeScreen *screen, SensorState *state) {
|
|||||||
screen->stage = STAT_RANGE_START_DATE;
|
screen->stage = STAT_RANGE_START_DATE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (state->sel_down) {
|
||||||
|
screen->need_redraw = true;
|
||||||
|
screen->view = (screen->view + 1) % STAT_RANGE_NVIEW;
|
||||||
|
}
|
||||||
if (screen->need_redraw) {
|
if (screen->need_redraw) {
|
||||||
screen->need_redraw = false;
|
screen->need_redraw = false;
|
||||||
uint64_t start = to_uts_timestamp(&screen->sds, &screen->sts);
|
uint64_t start = to_uts_timestamp(&screen->sds, &screen->sts);
|
||||||
@ -108,17 +113,45 @@ static void stat_range_show_data(StatRangeScreen *screen, SensorState *state) {
|
|||||||
--screen->stage;
|
--screen->stage;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
char desc_line[17];
|
||||||
|
char data_line[17];
|
||||||
|
char humid_str[6];
|
||||||
|
switch (screen->view) {
|
||||||
|
case STAT_RANGE_AVG:
|
||||||
|
snprintf(desc_line, 17, "%" PRIi64 "pts:", data.npoints);
|
||||||
|
if (data.npoints) { // prevent UB
|
||||||
|
snprintf(data_line, 17, "%.1f%c %d%%",
|
||||||
|
convert_temperature(data.avgtemp),
|
||||||
|
GLOBAL_OPTS.temp_unit, data.avghumid);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case STAT_RANGE_TEMP:
|
||||||
|
strcpy(desc_line, "Max Min");
|
||||||
|
if (data.npoints) { // prevent UB
|
||||||
|
snprintf(data_line, 17, "%-4.1f%c %.1f%c",
|
||||||
|
convert_temperature(data.maxtemp), GLOBAL_OPTS.temp_unit,
|
||||||
|
convert_temperature(data.mintemp), GLOBAL_OPTS.temp_unit);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case STAT_RANGE_HUMID:
|
||||||
|
strcpy(desc_line, "Max Min");
|
||||||
|
if (data.npoints) { // prevent UB
|
||||||
|
snprintf(data_line, 17, "%s %d%%",
|
||||||
|
pad_humid_str(data.maxhumid, humid_str, 6),
|
||||||
|
data.minhumid);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warnx("attempt to draw bad stat range view");
|
||||||
|
--screen->stage;
|
||||||
|
screen->need_redraw = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
lcd_clear(state->lcd);
|
lcd_clear(state->lcd);
|
||||||
lcd_move_to(state->lcd, 0, 0);
|
lcd_move_to(state->lcd, 0, 0);
|
||||||
char points_line[17];
|
lcd_write_string(state->lcd, desc_line);
|
||||||
snprintf(points_line, 17, "%" PRIi64 "pts:", data.npoints);
|
|
||||||
lcd_write_string(state->lcd, points_line);
|
|
||||||
lcd_move_to(state->lcd, 1, 0);
|
lcd_move_to(state->lcd, 1, 0);
|
||||||
if (data.npoints) {
|
if (data.npoints) {
|
||||||
char data_line[17];
|
|
||||||
snprintf(data_line, 17, "%.1f%c %d%%",
|
|
||||||
convert_temperature(data.temp),
|
|
||||||
GLOBAL_OPTS.temp_unit, data.humid);
|
|
||||||
lcd_write_string(state->lcd, data_line);
|
lcd_write_string(state->lcd, data_line);
|
||||||
} else {
|
} else {
|
||||||
lcd_write_string(state->lcd, "No data!");
|
lcd_write_string(state->lcd, "No data!");
|
||||||
@ -134,6 +167,7 @@ static bool stat_range_screen_dispatch(StatRangeScreen *screen,
|
|||||||
switch (screen->stage) {
|
switch (screen->stage) {
|
||||||
case STAT_RANGE_START_DATE:
|
case STAT_RANGE_START_DATE:
|
||||||
if(stat_range_handle_date(screen, &screen->sds, state, "Start Date:")) {
|
if(stat_range_handle_date(screen, &screen->sds, state, "Start Date:")) {
|
||||||
|
screen->view = STAT_RANGE_AVG;
|
||||||
date_sel_reset(&screen->sds);
|
date_sel_reset(&screen->sds);
|
||||||
time_sel_reset(&screen->sts);
|
time_sel_reset(&screen->sts);
|
||||||
date_sel_reset(&screen->eds);
|
date_sel_reset(&screen->eds);
|
||||||
@ -166,6 +200,7 @@ StatRangeScreen *stat_range_screen_new(void) {
|
|||||||
(ScreenCleanupFunc) free);
|
(ScreenCleanupFunc) free);
|
||||||
s->need_redraw = true;
|
s->need_redraw = true;
|
||||||
s->stage = STAT_RANGE_START_DATE;
|
s->stage = STAT_RANGE_START_DATE;
|
||||||
|
s->view = STAT_RANGE_AVG;
|
||||||
date_sel_init(&s->sds, PERIOD_DAY);
|
date_sel_init(&s->sds, PERIOD_DAY);
|
||||||
time_sel_init(&s->sts, &s->sds, true);
|
time_sel_init(&s->sts, &s->sds, true);
|
||||||
date_sel_init(&s->eds, PERIOD_DAY);
|
date_sel_init(&s->eds, PERIOD_DAY);
|
||||||
|
@ -22,6 +22,12 @@ typedef struct {
|
|||||||
STAT_RANGE_END_TIME,
|
STAT_RANGE_END_TIME,
|
||||||
STAT_RANGE_SHOW
|
STAT_RANGE_SHOW
|
||||||
} stage;
|
} stage;
|
||||||
|
enum {
|
||||||
|
STAT_RANGE_AVG = 0,
|
||||||
|
STAT_RANGE_TEMP,
|
||||||
|
STAT_RANGE_HUMID,
|
||||||
|
STAT_RANGE_NVIEW
|
||||||
|
} view;
|
||||||
bool need_redraw;
|
bool need_redraw;
|
||||||
DateSelection sds;
|
DateSelection sds;
|
||||||
TimeSelection sts;
|
TimeSelection sts;
|
||||||
|
114
src/ui/statsby.c
114
src/ui/statsby.c
@ -10,6 +10,7 @@
|
|||||||
#include "statsby.h"
|
#include "statsby.h"
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static void stats_by_select_period(StatsByScreen *screen, SensorState *state) {
|
static void stats_by_select_period(StatsByScreen *screen, SensorState *state) {
|
||||||
if (state->up_down) {
|
if (state->up_down) {
|
||||||
@ -67,17 +68,91 @@ static void stats_by_select_start(StatsByScreen *screen, SensorState *state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void stats_by_draw_current_view (StatsByScreen *screen,
|
||||||
|
SensorState *state,
|
||||||
|
UtilAveragePeriod *data) {
|
||||||
|
char desc_string[17];
|
||||||
|
char data_string[17];
|
||||||
|
char humid_str[6];
|
||||||
|
switch (screen->view) {
|
||||||
|
case STATS_BY_AVG:
|
||||||
|
// switch-ception
|
||||||
|
switch (screen->period) {
|
||||||
|
case PERIOD_YEAR:
|
||||||
|
snprintf(desc_string, 17, "Year>%d", data->year);
|
||||||
|
break;
|
||||||
|
case PERIOD_MONTH:
|
||||||
|
snprintf(desc_string, 17, "Month>%d-%d", data->year,
|
||||||
|
data->month);
|
||||||
|
break;
|
||||||
|
case PERIOD_WEEK:
|
||||||
|
snprintf(desc_string, 17, "Week>%d-%d-%d", data->year,
|
||||||
|
data->month, data->day);
|
||||||
|
break;
|
||||||
|
case PERIOD_DAY:
|
||||||
|
snprintf(desc_string, 17, "Day>%d-%d-%d", data->year,
|
||||||
|
data->month, data->day);
|
||||||
|
break;
|
||||||
|
case PERIOD_HOUR:
|
||||||
|
snprintf(desc_string, 17, "Hour>%d-%d %d:00", data->month,
|
||||||
|
data->day, data->hour);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (data->npoints) { // prevent UB
|
||||||
|
snprintf(data_string, 17, "T:%.1f%c H:%d%%",
|
||||||
|
convert_temperature(data->avgtemp), GLOBAL_OPTS.temp_unit,
|
||||||
|
data->avghumid);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case STATS_BY_TEMP:
|
||||||
|
strcpy(desc_string, "Max Min");
|
||||||
|
if (data->npoints) { // prevent UB
|
||||||
|
snprintf(data_string, 17, "%-4.1f%c %.1f%c",
|
||||||
|
convert_temperature(data->maxtemp), GLOBAL_OPTS.temp_unit,
|
||||||
|
convert_temperature(data->mintemp), GLOBAL_OPTS.temp_unit);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case STATS_BY_HUMID:
|
||||||
|
if (data->npoints) { // prevent UB
|
||||||
|
strcpy(desc_string, "Max Min");
|
||||||
|
snprintf(data_string, 17, "%s %d%%",
|
||||||
|
pad_humid_str(data->maxhumid, humid_str, 6),
|
||||||
|
data->minhumid);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warnx("attempt to draw bad stats-by view");
|
||||||
|
--screen->stage;
|
||||||
|
screen->need_redraw = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lcd_move_to(state->lcd, 0, 0);
|
||||||
|
lcd_write_string(state->lcd, desc_string);
|
||||||
|
lcd_move_to(state->lcd, 1, 0);
|
||||||
|
if (data->npoints) {
|
||||||
|
lcd_write_string(state->lcd, data_string);
|
||||||
|
} else {
|
||||||
|
lcd_write_string(state->lcd, "No data!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void stats_by_show_stats(StatsByScreen *screen, SensorState *state) {
|
static void stats_by_show_stats(StatsByScreen *screen, SensorState *state) {
|
||||||
if (state->back_down) {
|
if (state->back_down) {
|
||||||
screen->stage = STATS_BY_SELECT_PERIOD;
|
screen->stage = STATS_BY_SELECT_PERIOD;
|
||||||
screen->need_redraw = true;
|
screen->need_redraw = true;
|
||||||
screen->ds.stage = DATE_SEL_YEAR;
|
screen->ds.stage = DATE_SEL_YEAR;
|
||||||
} else if (screen->need_redraw) {
|
screen->view = STATS_BY_AVG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (state->sel_down) {
|
||||||
|
screen->view = (screen->view + 1) % STATS_BY_NVIEW;
|
||||||
|
screen->need_redraw = true;
|
||||||
|
}
|
||||||
|
if (screen->need_redraw) {
|
||||||
screen->need_redraw = false;
|
screen->need_redraw = false;
|
||||||
lcd_display_control(state->lcd, LCD_CURSOR_NO_BLINK, LCD_CURSOR_OFF,
|
lcd_display_control(state->lcd, LCD_CURSOR_NO_BLINK, LCD_CURSOR_OFF,
|
||||||
LCD_DISPLAY_ON);
|
LCD_DISPLAY_ON);
|
||||||
lcd_clear(state->lcd);
|
lcd_clear(state->lcd);
|
||||||
lcd_move_to(state->lcd, 0, 0);
|
|
||||||
if (screen->period == PERIOD_HOUR &&
|
if (screen->period == PERIOD_HOUR &&
|
||||||
screen->offset_scale == 0 &&
|
screen->offset_scale == 0 &&
|
||||||
screen->ds.year == screen->ds.start_time.local_year &&
|
screen->ds.year == screen->ds.start_time.local_year &&
|
||||||
@ -95,39 +170,7 @@ static void stats_by_show_stats(StatsByScreen *screen, SensorState *state) {
|
|||||||
}
|
}
|
||||||
screen->ulimit_reached = data.upper_bound;
|
screen->ulimit_reached = data.upper_bound;
|
||||||
screen->blimit_reached = data.lower_bound;
|
screen->blimit_reached = data.lower_bound;
|
||||||
char period_string[17];
|
stats_by_draw_current_view(screen, state, &data);
|
||||||
switch (screen->period) {
|
|
||||||
case PERIOD_YEAR:
|
|
||||||
snprintf(period_string, 17, "Year>%d", data.year);
|
|
||||||
break;
|
|
||||||
case PERIOD_MONTH:
|
|
||||||
snprintf(period_string, 17, "Month>%d-%d", data.year,
|
|
||||||
data.month);
|
|
||||||
break;
|
|
||||||
case PERIOD_WEEK:
|
|
||||||
snprintf(period_string, 17, "Week>%d-%d-%d", data.year,
|
|
||||||
data.month, data.day);
|
|
||||||
break;
|
|
||||||
case PERIOD_DAY:
|
|
||||||
snprintf(period_string, 17, "Day>%d-%d-%d", data.year,
|
|
||||||
data.month, data.day);
|
|
||||||
break;
|
|
||||||
case PERIOD_HOUR:
|
|
||||||
snprintf(period_string, 17, "Hour>%d-%d %d:00", data.month,
|
|
||||||
data.day, data.hour);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
lcd_write_string(state->lcd, period_string);
|
|
||||||
lcd_move_to(state->lcd, 1, 0);
|
|
||||||
if (data.npoints) {
|
|
||||||
char data_string[17];
|
|
||||||
snprintf(data_string, 17, "T:%.1f%c H:%d%%",
|
|
||||||
convert_temperature(data.temp), GLOBAL_OPTS.temp_unit,
|
|
||||||
data.humid);
|
|
||||||
lcd_write_string(state->lcd, data_string);
|
|
||||||
} else {
|
|
||||||
lcd_write_string(state->lcd, "No data!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!screen->ulimit_reached && state->up_down) {
|
if (!screen->ulimit_reached && state->up_down) {
|
||||||
++screen->offset_scale;
|
++screen->offset_scale;
|
||||||
@ -178,6 +221,7 @@ StatsByScreen *stats_by_screen_new() {
|
|||||||
s->need_redraw = true;
|
s->need_redraw = true;
|
||||||
s->stage = STATS_BY_SELECT_PERIOD;
|
s->stage = STATS_BY_SELECT_PERIOD;
|
||||||
s->period = PERIOD_HOUR;
|
s->period = PERIOD_HOUR;
|
||||||
|
s->view = STATS_BY_AVG;
|
||||||
date_sel_init(&s->ds, PERIOD_DAY);
|
date_sel_init(&s->ds, PERIOD_DAY);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,12 @@ typedef struct {
|
|||||||
STATS_BY_SELECT_START,
|
STATS_BY_SELECT_START,
|
||||||
STATS_BY_SHOWING,
|
STATS_BY_SHOWING,
|
||||||
} stage;
|
} stage;
|
||||||
|
enum {
|
||||||
|
STATS_BY_AVG = 0,
|
||||||
|
STATS_BY_TEMP,
|
||||||
|
STATS_BY_HUMID,
|
||||||
|
STATS_BY_NVIEW,
|
||||||
|
} view;
|
||||||
bool need_redraw;
|
bool need_redraw;
|
||||||
UtilPeriod period;
|
UtilPeriod period;
|
||||||
DateSelection ds;
|
DateSelection ds;
|
||||||
|
43
src/util.c
43
src/util.c
@ -129,13 +129,21 @@ static const char *AVG_FOR_PERIOD_QUERY_STR =
|
|||||||
"etime >= (select max(time) from env_data) as ulimit,\n"
|
"etime >= (select max(time) from env_data) as ulimit,\n"
|
||||||
"stime <= (select min(time) from env_data) as blimit,\n"
|
"stime <= (select min(time) from env_data) as blimit,\n"
|
||||||
"atemp,\n"
|
"atemp,\n"
|
||||||
"ahumid\n"
|
"ahumid,\n"
|
||||||
|
"maxtemp,\n"
|
||||||
|
"mintemp,\n"
|
||||||
|
"maxhumid,\n"
|
||||||
|
"minhumid\n"
|
||||||
"FROM (SELECT\n"
|
"FROM (SELECT\n"
|
||||||
"unixepoch(printf('%04d-%02d-%02d', ?1, ?2, ?3), 'utc', printf('%d %s', ?4 * ?6, ?5)) as stime,\n"
|
"unixepoch(printf('%04d-%02d-%02d', ?1, ?2, ?3), 'utc', printf('%d %s', ?4 * ?6, ?5)) as stime,\n"
|
||||||
"unixepoch(printf('%04d-%02d-%02d', ?1, ?2, ?3), 'utc', printf('%d %s', (?4 + 1) * ?6, ?5)) as etime,\n"
|
"unixepoch(printf('%04d-%02d-%02d', ?1, ?2, ?3), 'utc', printf('%d %s', (?4 + 1) * ?6, ?5)) as etime,\n"
|
||||||
"count(time) AS ndata,\n"
|
"count(time) AS ndata,\n"
|
||||||
"round(avg(temp)) AS atemp,\n"
|
"round(avg(temp)) AS atemp,\n"
|
||||||
"round(avg(humid)) AS ahumid\n"
|
"round(avg(humid)) AS ahumid,\n"
|
||||||
|
"max(temp) AS maxtemp,\n"
|
||||||
|
"min(temp) AS mintemp,\n"
|
||||||
|
"max(humid) AS maxhumid,\n"
|
||||||
|
"min(humid) AS minhumid\n"
|
||||||
"FROM env_data\n"
|
"FROM env_data\n"
|
||||||
"WHERE time >= stime\n"
|
"WHERE time >= stime\n"
|
||||||
"AND time <= etime);\n";
|
"AND time <= etime);\n";
|
||||||
@ -145,10 +153,11 @@ static const char *DATA_POINT_QUERY_STR =
|
|||||||
"UNION ALL\n"
|
"UNION ALL\n"
|
||||||
"SELECT min(time) IS NULL, min(time), temp, humid FROM env_data WHERE time > ?1\n"
|
"SELECT min(time) IS NULL, min(time), temp, humid FROM env_data WHERE time > ?1\n"
|
||||||
"UNION ALL\n"
|
"UNION ALL\n"
|
||||||
"SELECT false, * FROM env_data WHERE time == ?1;";
|
"SELECT false, time, temp, humid FROM env_data WHERE time == ?1;";
|
||||||
static sqlite3_stmt *DATA_POINT_QUERY;
|
static sqlite3_stmt *DATA_POINT_QUERY;
|
||||||
static const char *AVG_FOR_RANGE_QUERY_STR =
|
static const char *AVG_FOR_RANGE_QUERY_STR =
|
||||||
"SELECT count(time), round(avg(temp)), round(avg(humid)) FROM env_data\n"
|
"SELECT count(time), round(avg(temp)), round(avg(humid)),\n"
|
||||||
|
" max(temp), min(temp), max(humid), min(humid) FROM env_data\n"
|
||||||
"WHERE time >= ?1 AND time <= ?2;";
|
"WHERE time >= ?1 AND time <= ?2;";
|
||||||
static sqlite3_stmt *AVG_FOR_RANGE_QUERY;
|
static sqlite3_stmt *AVG_FOR_RANGE_QUERY;
|
||||||
void initialize_util_queries(sqlite3 *db) {
|
void initialize_util_queries(sqlite3 *db) {
|
||||||
@ -257,8 +266,12 @@ bool get_average_for_period(sqlite3 *db, int year, int month, int day,
|
|||||||
data->npoints = sqlite3_column_int64(AVG_FOR_PERIOD_QUERY, 4);
|
data->npoints = sqlite3_column_int64(AVG_FOR_PERIOD_QUERY, 4);
|
||||||
data->upper_bound = sqlite3_column_int64(AVG_FOR_PERIOD_QUERY, 5);
|
data->upper_bound = sqlite3_column_int64(AVG_FOR_PERIOD_QUERY, 5);
|
||||||
data->lower_bound = sqlite3_column_int64(AVG_FOR_PERIOD_QUERY, 6);
|
data->lower_bound = sqlite3_column_int64(AVG_FOR_PERIOD_QUERY, 6);
|
||||||
data->temp = sqlite3_column_int(AVG_FOR_PERIOD_QUERY, 7);
|
data->avgtemp = sqlite3_column_int(AVG_FOR_PERIOD_QUERY, 7);
|
||||||
data->humid = sqlite3_column_int(AVG_FOR_PERIOD_QUERY, 8);
|
data->avghumid = sqlite3_column_int(AVG_FOR_PERIOD_QUERY, 8);
|
||||||
|
data->maxtemp = sqlite3_column_int(AVG_FOR_PERIOD_QUERY, 9);
|
||||||
|
data->mintemp = sqlite3_column_int(AVG_FOR_PERIOD_QUERY, 10);
|
||||||
|
data->maxhumid = sqlite3_column_int(AVG_FOR_PERIOD_QUERY, 11);
|
||||||
|
data->minhumid = sqlite3_column_int(AVG_FOR_PERIOD_QUERY, 12);
|
||||||
}
|
}
|
||||||
sqlite3_reset(AVG_FOR_PERIOD_QUERY);
|
sqlite3_reset(AVG_FOR_PERIOD_QUERY);
|
||||||
return success;
|
return success;
|
||||||
@ -325,8 +338,12 @@ bool get_average_for_range(sqlite3 *db, uint64_t start, uint64_t end,
|
|||||||
success = false;
|
success = false;
|
||||||
} else if (data) {
|
} else if (data) {
|
||||||
data->npoints = sqlite3_column_int64(AVG_FOR_RANGE_QUERY, 0);
|
data->npoints = sqlite3_column_int64(AVG_FOR_RANGE_QUERY, 0);
|
||||||
data->temp = sqlite3_column_int(AVG_FOR_RANGE_QUERY, 1);
|
data->avgtemp = sqlite3_column_int(AVG_FOR_RANGE_QUERY, 1);
|
||||||
data->humid = sqlite3_column_int(AVG_FOR_RANGE_QUERY, 2);
|
data->avghumid = sqlite3_column_int(AVG_FOR_RANGE_QUERY, 2);
|
||||||
|
data->maxtemp = sqlite3_column_int(AVG_FOR_RANGE_QUERY, 3);
|
||||||
|
data->mintemp = sqlite3_column_int(AVG_FOR_RANGE_QUERY, 4);
|
||||||
|
data->maxhumid = sqlite3_column_int(AVG_FOR_RANGE_QUERY, 5);
|
||||||
|
data->minhumid = sqlite3_column_int(AVG_FOR_RANGE_QUERY, 6);
|
||||||
}
|
}
|
||||||
sqlite3_reset(AVG_FOR_RANGE_QUERY);
|
sqlite3_reset(AVG_FOR_RANGE_QUERY);
|
||||||
return success;
|
return success;
|
||||||
@ -352,3 +369,13 @@ float convert_temperature(int dk) {
|
|||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *pad_humid_str(int humid, char *buf, size_t buf_size) {
|
||||||
|
int fmt_len = snprintf(buf, buf_size, "%d%%", humid);
|
||||||
|
ssize_t remaining = buf_size - fmt_len - 1;
|
||||||
|
if (remaining > 0) {
|
||||||
|
memset(buf + fmt_len, ' ', remaining);
|
||||||
|
buf[buf_size - 1] = '\0';
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
26
src/util.h
26
src/util.h
@ -138,8 +138,12 @@ bool get_database_limits(sqlite3 *db, UtilPeriod period, UtilDate *start,
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int64_t npoints;
|
int64_t npoints;
|
||||||
int temp;
|
int avgtemp;
|
||||||
int humid;
|
int avghumid;
|
||||||
|
int maxtemp;
|
||||||
|
int maxhumid;
|
||||||
|
int mintemp;
|
||||||
|
int minhumid;
|
||||||
int year;
|
int year;
|
||||||
int month;
|
int month;
|
||||||
int day;
|
int day;
|
||||||
@ -154,8 +158,8 @@ typedef struct {
|
|||||||
* Return: false if an error occurred, true otherwise.
|
* Return: false if an error occurred, true otherwise.
|
||||||
*/
|
*/
|
||||||
bool get_average_for_period(sqlite3 *db, int year, int month, int day,
|
bool get_average_for_period(sqlite3 *db, int year, int month, int day,
|
||||||
int64_t count, UtilPeriod period,
|
int64_t count, UtilPeriod period,
|
||||||
UtilAveragePeriod *data);
|
UtilAveragePeriod *data);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int64_t time;
|
int64_t time;
|
||||||
@ -180,8 +184,12 @@ bool get_data_point_info(sqlite3 *db, int64_t time, UtilDataPointInfo *info);
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int64_t npoints;
|
int64_t npoints;
|
||||||
int temp;
|
int avgtemp;
|
||||||
int humid;
|
int avghumid;
|
||||||
|
int maxtemp;
|
||||||
|
int mintemp;
|
||||||
|
int maxhumid;
|
||||||
|
int minhumid;
|
||||||
} UtilAverageRange;
|
} UtilAverageRange;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -196,4 +204,10 @@ bool get_average_for_range(sqlite3 *db, uint64_t start, uint64_t end,
|
|||||||
*/
|
*/
|
||||||
float convert_temperature(int dk);
|
float convert_temperature(int dk);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fill BUF with at most BUF_SIZE characters (including the null byte), by
|
||||||
|
* padding "HUMID%" to BUF_SIZE - 1 characters.
|
||||||
|
*/
|
||||||
|
char *pad_humid_str(int humid, char *buf, size_t buf_size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user