4 #include <spdlog/spdlog.h>
43 std::unique_ptr<app_workspace> app_workspace::instance;
46 if (!instance.get()) {
47 spdlog::debug(
"app_workspace.cpp - Instantiating app_workspace");
48 instance = std::unique_ptr<app_workspace>(
new app_workspace());
95 HX711::Rate rate = HX711::Rate::HZ_80;
97 rate = HX711::Rate::HZ_80;
99 rate = HX711::Rate::HZ_10;
101 rate = HX711::Rate::OTHER;
107 this->main_config->hx_conf.clock_pin,
108 this->main_config->hx_conf.ref_unit,
109 this->main_config->hx_conf.offset,
114 }
catch (HX711::GpioException &ex) {
115 std::string what = ex.what();
116 std::string err =
"app_workspace.cpp - hx711 initialization failed. Reason: " + what;
117 spdlog::critical(err);
131 this->calib_thread->detach();
141 this->calib_thread->detach();
161 spdlog::error(
"app_workspace.cpp - samples_in: {0}", this->
samples_in);
162 this->clear_s2_buffers();
169 spdlog::error(
"app_workspace.cpp - timeout_in: {0}", this->
timeout_in);
170 this->clear_s2_buffers();
188 this->measuring_thread->detach();
214 this->measuring_thread->detach();
221 spdlog::info(
"app_workspace.cpp - Starting HX711 measuring for {0} samples.", samples);
224 bool measuring =
true;
225 std::vector<HX711::Value> *watcher =
nullptr;
230 spdlog::debug(
"STARTING measuring");
233 m_start = std::chrono::high_resolution_clock::now();
236 std::vector<HX711::Value> res =
hx711_controller->getValues(samples, &watcher);
238 m_end = std::chrono::high_resolution_clock::now();
245 this->measuring_watchdog->join();
247 spdlog::debug(
"ENDING measuring");
253 spdlog::info(
"app_workspace.cpp - Starting HX711 measuring for {0} seconds.", seconds);
256 bool measuring =
true;
257 std::vector<HX711::Value> *watcher =
nullptr;
262 spdlog::debug(
"STARTING measuring");
265 m_start = std::chrono::high_resolution_clock::now();
268 std::vector<HX711::Value> res =
hx711_controller->getValues(std::chrono::seconds(seconds), &watcher);
270 m_end = std::chrono::high_resolution_clock::now();
277 this->measuring_watchdog->join();
279 spdlog::debug(
"ENDING measuring");
287 return this->scr_mgr;
299 this->scr_mgr = scr_mgr;
317 return this->cur_font_size;
321 spdlog::info(
"app_workspace.cpp - Loading font with size {0}", size_px);
323 ImGuiIO &io = ImGui::GetIO();
325 ImFont* font = io.Fonts->AddFontFromFileTTF(font_path.c_str(), size_px);
329 spdlog::error(
"app_workspace.cpp - Failed to load font size {0}!" , size_px);
342 spdlog::info(
"app_workspace.cpp - Loging in user through RFID. Querrying DB...");
346 spdlog::error(
"app_workspace.cpp - Failed to login user. db_driver log should provide more information.");
351 rv =
db_conn->query_measurement_headers(usr);
353 spdlog::error(
"app_workspace.cpp - Failed to retrieve user measurement headers.");
360 spdlog::error(
"app_workspace.cpp - Cannot login \"subuser\", because user workspace isn't initialized."
361 " User isn't logged in? flag: user_logged: {0}",
user_logged);
375 spdlog::info(
"app_workspace.cpp - Finished logging in subuser through RFID.");
385 spdlog::info(
"app_workspace.cpp - Finished logging in user through RFID.");
426 spdlog::error(
"app_workspace.cpp - User login. Failed to verify credentials");
436 spdlog::error(
"app_workspace.cpp - Failed to login user. db_driver log should provide more information.");
441 rv =
db_conn->query_measurement_headers(usr);
443 spdlog::error(
"app_workspace.cpp - Failed to retrieve user measurement headers.");
470 }
else if (rv == 3) {
485 spdlog::error(
"app_workspace.cpp - Failed to login user. db_driver log should provide more information.");
489 rv =
db_conn->query_measurement_headers(usr);
491 spdlog::error(
"app_workspace.cpp - Failed to retrieve user measurement headers.");
537 std::unique_ptr<user_cont> usr(usr_tmp);
545 spdlog::error(
"screen_definitions.cpp - Failed to verify username availability");
550 spdlog::debug(
"screen_definitions.cpp - Username is available.");
554 rv = this->
db_conn->is_rfid_serial_available(this->
s6_rfid_tag->serial, this->s6_rfid_tag->serial_size);
561 spdlog::error(
"screen_definitions.cpp - Failed to verify username availability");
566 spdlog::debug(
"screen_definitions.cpp - RFID is available.");
567 memcpy(usr->rfid_serial_bin, this->s6_rfid_tag->serial, this->s6_rfid_tag->serial_size);
568 usr->rfid_ser_len = this->
s6_rfid_tag->serial_size;
572 std::time_t ct_tmp = std::time(
nullptr);
573 std::tm *current_time = std::localtime(&ct_tmp);
576 if (this->
s6_year_in > (current_time->tm_year + 1900) || this->s6_year_in <
YEAR_MIN) {
584 spdlog::error(
"screen_definitions.cpp - Year out of range");
594 memset(&dob, 0,
sizeof(std::tm));
595 strptime(buf,
"%Y-%m-%d", &dob);
604 usr->date_of_birth = dob;
606 rv = this->
db_conn->insert_user(usr.get(), this->s6_passwd_in);
608 spdlog::error(
"screen_definitions.cpp - Failed to execute user insert.");
613 this->clear_s6_buffers();
614 spdlog::info(
"screen_definitions.cpp - Successfully added new user.");
639 return db_conn->is_open() ? 0 : 1;
642 void app_workspace::clear_s1_buffers() {
648 void app_workspace::clear_s2_buffers() {
653 void app_workspace::clear_s6_buffers() {
674 std::vector<double> res;
676 for (
size_t i = 0; i < raw_vals.size(); i++) {
689 spdlog::debug(
"========== (debug) config file start ==========");
690 spdlog::debug(
"general settings:");
691 spdlog::debug(
"\tdebug_screens: {0}",
main_config->debug_screens);
692 spdlog::debug(
"\tfonts_path: {0}",
main_config->fonts_path);
694 spdlog::debug(
"\tlang_path: {0}",
main_config->lang_path);
695 spdlog::debug(
"\tavailable_langs:");
696 for (
size_t i = 0; i <
main_config->lang_options.size(); i++) {
697 spdlog::debug(
"\t\topt {0}: {1}", i,
main_config->lang_options[i]);
700 spdlog::debug(
"\tdefault_lang: {0}",
main_config->lang_default);
701 spdlog::debug(
"\tcurrent_lang: {0}",
main_config->lang_current);
702 spdlog::debug(
"spi keyboard settings:");
703 spdlog::debug(
"\tdev: {0}",
main_config->keyb_conf.dev);
704 spdlog::debug(
"\tmode: {0}",
main_config->keyb_conf.config->mode);
705 spdlog::debug(
"\tbits: {0}",
main_config->keyb_conf.config->bits_per_word);
706 spdlog::debug(
"\tspeed: {0}",
main_config->keyb_conf.config->speed);
707 spdlog::debug(
"\tdelay: {0}",
main_config->keyb_conf.config->delay);
708 spdlog::debug(
"spi rfid settings:");
709 spdlog::debug(
"\tdev: {0}",
main_config->rfid_conf.dev);
710 spdlog::debug(
"\tmode: {0}",
main_config->rfid_conf.config->mode);
711 spdlog::debug(
"\tbits: {0}",
main_config->rfid_conf.config->bits_per_word);
712 spdlog::debug(
"\tspeed: {0}",
main_config->rfid_conf.config->speed);
713 spdlog::debug(
"\tdelay: {0}",
main_config->rfid_conf.config->delay);
714 spdlog::debug(
"database settings:");
715 spdlog::debug(
"\thost: {0}",
main_config->db_conf.host);
716 spdlog::debug(
"\tuser: {0}",
main_config->db_conf.user);
717 spdlog::debug(
"\tpassword: {0}",
main_config->db_conf.passwd);
718 spdlog::debug(
"\tdatabase: {0}",
main_config->db_conf.db);
719 spdlog::debug(
"\tport: {0}",
main_config->db_conf.port);
720 spdlog::debug(
"\tsocket: {0}",
main_config->db_conf.socket);
721 spdlog::debug(
"\tclientflags: {0}",
main_config->db_conf.clientflags);
722 spdlog::debug(
"hx711 settings:");
723 spdlog::debug(
"\tdata pin: {0}",
main_config->hx_conf.data_pin);
724 spdlog::debug(
"\tclock pin: {0}",
main_config->hx_conf.clock_pin);
725 spdlog::debug(
"\trate: {0}",
main_config->hx_conf.rate);
726 spdlog::debug(
"\tref unit: {0}",
main_config->hx_conf.ref_unit);
727 spdlog::debug(
"\toffset: {0}",
main_config->hx_conf.offset);
728 spdlog::debug(
"========== (debug) config file end ==========");
748 this->measuring_thread.reset(
new std::thread([]() {
756 auto res = std::chrono::duration_cast<std::chrono::milliseconds>(app_wrk->
m_end - app_wrk->
m_start).count();
765 auto res = std::chrono::duration_cast<std::chrono::milliseconds>(app_wrk->
m_end - app_wrk->
m_start).count();
768 "Smps: " + std::to_string(
HX_TEST_SAMP_COUNT * (i + 1)) +
" - " + std::to_string(res) +
" ms";
777 this->measuring_thread->detach();
799 this->measuring_thread.reset(
new std::thread([]() {
809 "In: " + std::to_string(
HX_TEST_TIME_COUNT) +
"s - " + std::to_string(res.size()) +
" samples";
817 "In: " + std::to_string(
HX_TEST_TIME_COUNT * (i + 1)) +
"s - " + std::to_string(res.size())+
" samples";
826 this->measuring_thread->detach();
846 std::vector<HX711::Value> res;
869 if (res.size() <= 0) {
875 unsigned long m_len =
876 std::chrono::duration_cast<std::chrono::microseconds>(app_wrk->
m_end - app_wrk->
m_start).count();
877 std::time_t start_timet = std::chrono::system_clock::to_time_t(app_wrk->
m_start);
878 std::time_t end_timet = std::chrono::system_clock::to_time_t(app_wrk->
m_end);
879 std::tm start_tm, end_tm;
880 localtime_r(&start_timet, &start_tm);
881 localtime_r(&end_timet, &end_tm);
884 app_wrk->
userspace->init_measured(values, &start_tm, &end_tm, m_len);
885 app_wrk->
userspace->get_last_hx_measuring()->log_measurement_to_debug();
888 int rv = app_wrk->
db_conn->insert_measurement(app_wrk->
userspace->measured.get());
890 spdlog::error(
"app_workspace.cpp - hx711_measurement: failet to insert measurement to DB.");
892 rv = app_wrk->
db_conn->increment_user_measurement_count(app_wrk->
userspace->get_measured_id());
894 spdlog::error(
"app_workspace.cpp - hx711_measurement: Successfully inserted measurement but"
895 " failed to increment user measurement_count.");
898 app_wrk->
userspace->get_measured_user()->measure_count++;
901 rv = app_wrk->
db_conn->query_measurement_headers(app_wrk->
userspace->get_measured_user());
903 spdlog::error(
"app_workspace.cpp - hx711_measurement: Failed to retrieve (update)"
904 " user measurement headers.");
911 rv = app_wrk->
db_conn->query_username(uname, app_wrk->
userspace->measured->measurer_id);
913 spdlog::error(
"app_workspace.cpp - hx711_measurement: Failed to retrieve measurer username.");
915 if (app_wrk->
userspace->measured->measurer_id != app_wrk->
userspace->measured->measuree_id) {
916 std::string sub_uname;
917 rv = app_wrk->
db_conn->query_username(sub_uname, app_wrk->
userspace->measured->measuree_id);
920 spdlog::error(
"app_workspace.cpp - hx711_measurement: Failed to retrieve measuree username.");
922 app_wrk->
userspace->measured->init_convinience_vars(uname.c_str(), sub_uname.c_str());
925 app_wrk->
userspace->measured->init_convinience_vars(uname.c_str(), uname.c_str());
952 std::vector<HX711::Value> res;
957 spdlog::info(
"app_workspace.cpp - Starting taring");
967 }
catch (std::exception &ex) {
968 spdlog::error(
"app_workspace.cpp - Caught exception while taring HX711");
982 }
catch (std::exception &ex) {
983 spdlog::error(
"app_workspace.cpp - Caught exception while cleaning after HX711 calibration");
992 spdlog::info(
"app_workspace.cpp - Successfully finished calibrating");
1002 std::vector<HX711::Value> res;
1007 spdlog::info(
"app_workspace.cpp - Starting calibration");
1011 HX711::Value orig_ref_unit = app_wrk->
hx711_controller->getReferenceUnit();
1016 }
catch (std::exception &ex) {
1017 spdlog::error(
"app_workspace.cpp - Caught exception while preparing for HX711 calibration");
1029 const double raw = app_wrk->
hx711_controller->read(HX711::Options(samples));
1030 const double ref_unit_float = (raw - app_wrk->
zero_value) / known_weight;
1031 app_wrk->
ref_unit =
static_cast<HX711::Value
>(round(ref_unit_float));
1046 }
catch (std::exception &ex) {
1047 spdlog::error(
"app_workspace.cpp - Caught exception while cleaning after HX711 calibration");
1057 spdlog::info(
"app_workspace.cpp - Successfully finished calibrating");
1068 long failed_measures = 0, failed_inserts = 0;
1069 unsigned long measure_count = 1;
1070 int consec_fm = 0, consec_fi = 0;
1072 std::vector<HX711::Value> res;
1073 std::unique_ptr<measurement> measr;
1086 spdlog::error(
"app_workspace.cpp - countinous measuring failed. Reason is because of consecutive"
1087 "measuring or insert failures. Failed measures: {0} (limit: {1}), failed inserts: {2} (limit: {3})",
1109 if (res.size() <= 0) {
1117 unsigned long m_len =
1118 std::chrono::duration_cast<std::chrono::microseconds>(app_wrk->
m_end - app_wrk->
m_start).count();
1119 std::time_t start_timet = std::chrono::system_clock::to_time_t(app_wrk->
m_start);
1120 std::time_t end_timet = std::chrono::system_clock::to_time_t(app_wrk->
m_end);
1121 std::tm start_tm, end_tm;
1122 localtime_r(&start_timet, &start_tm);
1123 localtime_r(&end_timet, &end_tm);
1128 measr->measurement_part = measure_count;
1132 auto i_start = std::chrono::steady_clock::now();
1133 rv = app_wrk->
db_conn->insert_measurement(measr.get());
1134 auto i_end = std::chrono::steady_clock::now();
1135 spdlog::debug(
"app_workspace.cpp - hx711_continuous_measurement: inserting measurement to DB"
1136 " took {0}ms ({1} us)", std::chrono::duration_cast<std::chrono::milliseconds>(i_end - i_start).count(),
1137 std::chrono::duration_cast<std::chrono::microseconds>(i_end - i_start).count());
1139 spdlog::error(
"app_workspace.cpp - hx711_continuous_measurement: failed to insert measurement to DB.");
1149 if ((measure_count - failed_inserts) > 1) {
1150 rv = app_wrk->
db_conn->increment_user_measurement_count(app_wrk->
userspace->get_measured_id());
1152 spdlog::error(
"app_workspace.cpp - hx711_measurement: Successfully inserted measurement but"
1153 " FAILED to increment user measurement_count.");
1156 app_wrk->
userspace->get_measured_user()->measure_count++;
1159 rv = app_wrk->
db_conn->query_measurement_headers(app_wrk->
userspace->get_measured_user());
1161 spdlog::error(
"app_workspace.cpp - hx711_measurement: Failed to retrieve (update)"
1162 " user measurement headers.");
1169 app_wrk->
userspace->measured = std::unique_ptr(std::move(measr));
1172 rv = app_wrk->
db_conn->query_username(uname, app_wrk->
userspace->measured->measurer_id);
1174 spdlog::error(
"app_workspace.cpp - hx711_measurement: Failed to retrieve measurer username.");
1176 if (app_wrk->
userspace->measured->measurer_id != app_wrk->
userspace->measured->measuree_id) {
1177 std::string sub_uname;
1178 rv = app_wrk->
db_conn->query_username(sub_uname, app_wrk->
userspace->measured->measuree_id);
1181 spdlog::error(
"app_workspace.cpp - hx711_measurement: Failed to retrieve measuree username.");
1183 app_wrk->
userspace->measured->init_convinience_vars(uname.c_str(), sub_uname.c_str());
1186 app_wrk->
userspace->measured->init_convinience_vars(uname.c_str(), uname.c_str());
1209 spdlog::debug(
"STARTING measuring watchdog");
1213 if (!(*msring))
break;
1215 if (*watcher !=
nullptr && ((*watcher)->size() - val_len) > 50) {
1222 if (val_len < (*watcher)->size()) {
1223 std::vector<HX711::Value> tmp;
1224 for (
size_t i = val_len; i < (*watcher)->size(); i++) {
1225 tmp.push_back((*watcher)->at(i));
1227 val_len = (*watcher)->size();
1236 if (fail_cnt == 20) {
1237 printf(
"breaking on fail_cnt\n");
1244 std::this_thread::sleep_for(std::chrono::milliseconds(50));
1247 spdlog::debug(
"ENDING measuring watchdog");
void threaded_values_read()
This function is started in a new thread for reading HX711 values.
void threaded_values_read_looped()
This function is started in a new thread for reading HX711 values in a loop. This reading is done in ...
void threaded_tare()
This function is started in a new thread for taring HX711.
void threaded_measuring_watchdog(bool *msring, std::vector< HX711::Value > **watcher)
When an HX711 reading is started, when creating new thread, this thread is created as well....
void threaded_calibration()
This function is started in a new thread for calibrating HX711.
#define S2_MAX_SAMPLES_IN
#define DEF_BUFF_SIZE_EXTRA
#define DEF_BUFF_SIZE_SMALL
#define S2_MIN_TIMEOUT_IN
#define S2_MIN_SAMPLES_IN
#define HX_TEST_TIME_COUNT
#define S6_MIN_SAMPLES_IN
#define HX_TEST_CONST_IT_COUNT
#define HX_TEST_INC_IT_COUNT
#define HX_CONT_MAX_CONSEC_FAIL_FI
#define HX_CONT_MAX_CONSEC_FAIL_FM
#define S2_MAX_TIMEOUT_IN
#define HX_TEST_SAMP_COUNT
One of the most importat classes in the whole project. Holds variables that define the state of the a...
int hx711_measure()
Performs hx711 measuring with set values of either samples or timeout. The results is saved to the da...
std::chrono::time_point< std::chrono::high_resolution_clock > m_start
std::vector< HX711::Value > hx711_values_samples(int samples)
Reads the HX711 sensor until @samples is collected. Also starts new thread which is used to monitor o...
std::unique_ptr< custom_hx711 > hx711_controller
HX711 controller. This is an instance of custom_hx711 which extends library's AdvancedHX711.
void logoff_user()
Logs out user and subuser if logged in.
static std::unique_ptr< app_workspace > & get_instance()
Get the instance app_workspace which is a singleton.
bool s6_calibration_finished
user_workspace * get_userspace()
void use_font_size(app_workspace_ns::font_size font_size)
When this is called following gui elements will use selected font_size until next call of this or fon...
std::chrono::time_point< std::chrono::high_resolution_clock > m_end
void set_err_screen_and_activate(const char *title, const char *label)
Set the err screen and activate the screen on next frame.
void init_labels()
This is called after localisation dictionary is loaded. After the dict is loaded arrays defined in ap...
void hx711_tare()
Function that performs taring on the hx711 controller.
const char * s6_month_labels[S6_MONTH_CNT]
std::unique_ptr< db_driver > db_conn
Database driver holder.
std::unique_ptr< app_config > main_config
Application config loaded from app_config.conf (main config file).
int register_new_user()
This function validets screen 6 buffers and if everything checks out then inserts new user into the D...
const char * s6_role_labels[S6_ROLE_CNT]
int log_in_user_rfid(rfid_reader::rfid_tag *tag, bool loading_sub=false)
Logs in user through scanned RFID tag. Initializes user_workspace if loading_sub is false.
std::pair< long, std::string > test_hx_samples_times[HX_TEST_CONST_IT_COUNT+HX_TEST_INC_IT_COUNT]
int open_db_connection()
Tries to open the database connection and init db_driver.
int load_font_size(app_workspace_ns::font_size key, float size_px)
Initializes font into the map.
std::vector< double > normalize_raw_values(std::vector< HX711::Value > &raw_vals)
Takes raw values and normalizes them using HX offset and reference unit. Resulting values are in Gram...
char s6_passwd_in[DEF_BUFF_SIZE_SMALL]
char usr_passwd[DEF_BUFF_SIZE_SMALL]
void logout_subuser()
Logs out subuser.
std::unique_ptr< measurement > observed_measurement
This variable is used to observe measuring.
const char * s3_filter_opt_labels[S3_FILTER_OPT_CNT]
app_workspace()
Construct a new app workspace object.
void hx711_calibrate()
Function that performs calibration on the hx711 controller.
int hx711_continuous_measure()
Starts hx711 measuring that will run until its stopped by user.
app_workspace_ns::font_size get_font_size()
Get the font size.
bool is_debug_screens()
Retruns flag is.
int font_push_cnt
Whenever a font is used, it is pushed to the font stack of ImGui library. All pushed fonts need to be...
std::pair< long, std::string > test_hx_timeout_collected[HX_TEST_CONST_IT_COUNT+HX_TEST_INC_IT_COUNT]
char s6_name_in[DEF_BUFF_SIZE]
char s6_lastname_in[DEF_BUFF_SIZE_SMALL]
const char * unit_sel_labels[UNIT_SEL_CNT]
bool has_user()
Checks if user is logged in. This is determined by user_space being initialized and having the user_l...
std::vector< HX711::Value > hx711_values_timeout(int seconds)
Reads the HX711 sensor until @timeout is reached. Also starts new thread which is used to monitor ong...
int selected_hx_measure_opt
int verify_user_cred()
Tests if user entered correct credentials.
screen_manager * get_scr_mgr()
Get the screen manager instance. This instance is kind of singleton. Is initalized only once on start...
std::map< app_workspace_ns::font_size, ImFont * > loaded_fonts
Map of loaded fonts.
char subusr_name[DEF_BUFF_SIZE]
void set_kb_testing(bool val)
void set_scr_mgr(screen_manager *scr_mgr)
Set the screen manager instancte. This should only be called once, when the application is starting u...
std::unique_ptr< rfid_reader::rfid_tag > s6_rfid_tag
char usr_name[DEF_BUFF_SIZE]
void login_subuser()
When a user is already logged in and their role is employee or admin, they can log in another user as...
const char * s6_unit_sel_labels[S6_UNIT_SEL_CNT]
bool refresh_current_screen
When this is set to true, elements of current screen will be reinitialized for next frame.
int init_hx711_controller()
Initializes the hx711 controller.
bool user_logged
Flag to indicate if a user is logged in.
char s6_uname_in[DEF_BUFF_SIZE_SMALL]
std::unique_ptr< user_workspace > userspace
User's workspace. Serves similar function as app_workspace but for user data.
void log_in_user_cred()
Logs in user using credentials. Credentials are gained from screen_1 buffers.
int s6_selected_unit_option
char s6_desc_in[DEF_BUFF_SIZE_EXTRA]
const char * hx_measure_opts[S2_MEASURE_OTPS_CNT]
Handles database querries.
This is a wrapper for ImGui Text which serves as unchangeble label.
void set_label(const char *label)
Container for measurement data and (convenience) variables, that are used to show measurement in GUI.
static void init_simple_measuring(measurement *m, std::vector< double > &values)
static void init_measuring(measurement *m, user_workspace *uspace, std::vector< double > &values, std::tm *start_tm, std::tm *end_tm, unsigned long m_length)
void clear_previous_screen_stack()
void set_selected_screen(uint8_t screen)
void refresh_all_screns()
void refresh_screen_elements(uint8_t screen)
Class used as a container for user data, that are selected from database. (and also for insert,...
Container that servers for storing users data and manipulating them.
const char * get_localized_text(const char *key)
Get the localized text object.
font_size
This enum defines sizes of corresponding fonts. E.g.: SMALL_FONT is 12px.
void set_kb_testing_inner(bool val)
bool get_kb_testing_inner()
#define ADMIN_CTRL_SCREEN
RFID tag structure. Stores data read from SPI.
Struct used to contain username, password and user status until credentials are verified.