1#include "core/aqm_db.h"
2#include "core/aqm_paths.h"
3#include "core/aqm_platform.h"
4#include "core/globals.h"
5#include "sensor/sensor_info.h"
6#include "sensor/sensor_detector.h"
13void check_alerts(
void);
14void export_to_csv(
void);
15void configure_limits(
void);
16void generate_statistics(
void);
17void backup_database(
void);
18void cleanup_old_data(
void);
19void interval_collection(
void);
20void generate_pdf_report(
void);
22void save_config(
void);
23static void show_menu(
void);
24static void configure_sensor_runtime(
void);
25static void configure_multi_sensor(
void);
26static void wait_for_menu_return(
void);
30 init_sensor_configs();
31 srand((
unsigned)time(NULL));
34 printf(
"Configuration file not found. Please configure the settings.\n");
38 printf(
"Configuration loaded successfully.\n");
41 if (aqm_db_init() != 0) {
42 fprintf(stderr,
"Database initialization failed.\n");
50static void show_menu(
void) {
55 printf(
"\n=== Air Quality Monitor ===\n");
56 printf(
"1. Start data collection\n");
57 printf(
"2. Fetch data\n");
58 printf(
"3. Check alerts\n");
59 printf(
"4. Export to CSV\n");
60 printf(
"5. Generate statistics\n");
61 printf(
"6. Backup database\n");
62 printf(
"7. Cleanup old data\n");
63 printf(
"8. Generate PDF report\n");
64 printf(
"9. Configure limits and settings\n");
65 printf(
"10. Show sensor runtime info\n");
66 printf(
"11. Configure sensor/plugin runtime\n");
67 printf(
"12. Auto-detect sensors\n");
68 printf(
"13. Configure multi-sensor setup\n");
70 printf(
"Select an option: ");
72 if (!fgets(input,
sizeof(input), stdin) || !aqm_parse_int(input, &option)) {
73 printf(
"Invalid input.\n");
79 interval_collection();
91 generate_statistics();
100 generate_pdf_report();
107 show_sensor_runtime_info();
110 configure_sensor_runtime();
114 run_auto_detection_and_prompt();
118 configure_multi_sensor();
122 printf(
"Exiting program...\n");
125 printf(
"Invalid option. Try again.\n");
129 wait_for_menu_return();
130 }
while (option != 0);
133static void wait_for_menu_return(
void) {
135 printf(
"\nPress Enter to return to the menu...");
136 (void)fgets(input,
sizeof(input), stdin);
139static void configure_sensor_runtime(
void) {
140 const char *allowed_modes[] = {
"mock",
"dht22",
"bme680",
"pms5003",
"mh-z19",
"mhz19"};
141 const size_t allowed_count =
sizeof(allowed_modes) /
sizeof(allowed_modes[0]);
144 printf(
"\nSensor/plugin runtime configuration:\n");
145 printf(
"Current mode: %s\n", sensor_mode);
146 printf(
"Plugins enabled: %s\n", sensor_plugins_enabled ?
"yes" :
"no");
147 printf(
"Custom plugin path: %s\n", sensor_plugin_path[0] ? sensor_plugin_path :
"(none)");
149 printf(
"Enable plugins? (1=yes, 0=no, Enter=keep): ");
150 if (fgets(input,
sizeof(input), stdin) && input[0] !=
'\n') {
152 if (aqm_parse_int(input, &enabled))
153 sensor_plugins_enabled = enabled ? 1 : 0;
156 printf(
"Sensor mode [mock|dht22|bme680|pms5003|mh-z19] (Enter=keep): ");
157 if (fgets(input,
sizeof(input), stdin) && input[0] !=
'\n') {
158 aqm_trim_crlf(input);
161 for (
size_t i = 0; i < allowed_count; i++) {
162 if (strcmp(input, allowed_modes[i]) == 0) {
168 size_t n = strlen(input);
169 if (n >=
sizeof(sensor_mode))
170 n =
sizeof(sensor_mode) - 1;
171 memcpy(sensor_mode, input, n);
172 sensor_mode[n] =
'\0';
174 printf(
"Invalid sensor mode. Keeping current mode.\n");
179 printf(
"Custom plugin path (Enter=keep, '-'=clear): ");
180 if (fgets(input,
sizeof(input), stdin) && input[0] !=
'\n') {
181 aqm_trim_crlf(input);
182 if (strcmp(input,
"-") == 0) {
183 sensor_plugin_path[0] =
'\0';
184 }
else if (input[0]) {
185 snprintf(sensor_plugin_path,
sizeof(sensor_plugin_path),
"%s", input);
189 printf(
"Runtime sensor settings updated.\n");
192static void configure_multi_sensor(
void) {
193 const char *allowed_modes[] = {
"dht22",
"bme680",
"pms5003",
"mhz19"};
194 const size_t allowed_count =
sizeof(allowed_modes) /
sizeof(allowed_modes[0]);
197 printf(
"\n=== Multi-Sensor Configuration ===\n");
198 printf(
"Currently configured sensors: %d\n", active_sensor_count);
200 for (
int i = 0; i < active_sensor_count; i++) {
201 printf(
" %d. Mode: %s, Path: %s, Enabled: %s\n",
203 sensor_configs[i].mode,
204 sensor_configs[i].plugin_path[0] ? sensor_configs[i].plugin_path :
"(default)",
205 sensor_configs[i].enabled ?
"yes" :
"no");
208 printf(
"\nOptions:\n");
209 printf(
"1. Add a new sensor\n");
210 printf(
"2. Remove a sensor\n");
211 printf(
"3. Enable/Disable a sensor\n");
212 printf(
"4. Clear all sensors\n");
213 printf(
"0. Back to main menu\n");
214 printf(
"Select an option: ");
217 if (!fgets(input,
sizeof(input), stdin) || !aqm_parse_int(input, &option)) {
218 printf(
"Invalid input.\n");
224 if (active_sensor_count >= MAX_SENSORS) {
225 printf(
"Maximum number of sensors (%d) reached.\n", MAX_SENSORS);
229 printf(
"\nAvailable sensor modes:\n");
230 for (
size_t i = 0; i < allowed_count; i++) {
231 printf(
" - %s\n", allowed_modes[i]);
234 printf(
"\nEnter sensor mode: ");
235 if (fgets(input,
sizeof(input), stdin)) {
236 aqm_trim_crlf(input);
238 for (
size_t i = 0; i < allowed_count; i++) {
239 if (strcmp(input, allowed_modes[i]) == 0) {
246 SensorConfig *config = &sensor_configs[active_sensor_count];
248 strncpy(config->
mode, input,
sizeof(config->
mode) - 1);
249 config->
mode[
sizeof(config->
mode) - 1] =
'\0';
252 active_sensor_count++;
253 printf(
"Sensor %s added successfully.\n", input);
255 printf(
"Invalid sensor mode.\n");
261 if (active_sensor_count == 0) {
262 printf(
"No sensors configured.\n");
266 printf(
"\nEnter sensor number to remove (1-%d): ", active_sensor_count);
268 if (fgets(input,
sizeof(input), stdin) && aqm_parse_int(input, &idx) && idx >= 1 && idx <= active_sensor_count) {
269 for (
int i = idx - 1; i < active_sensor_count - 1; i++) {
270 sensor_configs[i] = sensor_configs[i + 1];
272 sensor_configs[active_sensor_count - 1].
mode[0] =
'\0';
273 sensor_configs[active_sensor_count - 1].
plugin_path[0] =
'\0';
274 sensor_configs[active_sensor_count - 1].
enabled = 0;
275 active_sensor_count--;
276 printf(
"Sensor removed successfully.\n");
278 printf(
"Invalid sensor number.\n");
283 if (active_sensor_count == 0) {
284 printf(
"No sensors configured.\n");
288 printf(
"\nEnter sensor number to toggle (1-%d): ", active_sensor_count);
290 if (fgets(input,
sizeof(input), stdin) && aqm_parse_int(input, &toggle_idx) && toggle_idx >= 1 && toggle_idx <= active_sensor_count) {
291 sensor_configs[toggle_idx - 1].
enabled = !sensor_configs[toggle_idx - 1].
enabled;
292 printf(
"Sensor %s is now %s.\n",
293 sensor_configs[toggle_idx - 1].mode,
294 sensor_configs[toggle_idx - 1].enabled ?
"enabled" :
"disabled");
296 printf(
"Invalid sensor number.\n");
301 printf(
"\nAre you sure you want to clear all sensors? (y/n): ");
302 if (fgets(input,
sizeof(input), stdin) && (input[0] ==
'y' || input[0] ==
'Y')) {
303 init_sensor_configs();
304 printf(
"All sensors cleared.\n");
306 printf(
"Operation canceled.\n");
314 printf(
"Invalid option.\n");
Configuration for one sensor slot in multi-sensor mode.
char mode[32]
Sensor mode identifier, e.g.
char plugin_path[256]
Path to the plugin library; empty string means use the default resolved by resolve_default_plugin_pat...
int enabled
Non-zero if this sensor slot is active for data collection.