1 /*--------------------------------------------------------------------------*/
4 // This file is part of ruwai.
6 // If you use ruwai_parser in any program or publication, please inform and
7 // acknowledge its author Stefan Mertl (stefan@mertl-research.at).
9 // ruwai is free software: you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 3 of the License, or
12 // (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
19 // You should have received a copy of the GNU General Public License
20 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 /*--------------------------------------------------------------------------*/
24 #include "log_temperature.h"
26 Root::Root(std::string config_file
)
28 boost::property_tree::ptree pt
;
29 double c1_gain
, c2_gain
, c3_gain
, c4_gain
;
32 display
= new LCDDisplay(66, 67, 45, 23, 47, 27);
36 display
->print("Hello, Ruwai", "is speaking.");
39 boost::property_tree::ini_parser::read_ini(config_file
, pt
);
41 // ---------------------------------------------------------
42 // Parse the arduino stack section.
43 dev_name
= pt
.get
<std::string
>("arduino_stack.serial_port");
44 n_channels
= pt
.get
<unsigned int>("arduino_stack.n_channels");
46 channel1_active
= pt
.get
<bool>("arduino_stack.channel1_active");
47 channel2_active
= pt
.get
<bool>("arduino_stack.channel2_active");
48 channel3_active
= pt
.get
<bool>("arduino_stack.channel3_active");
49 channel4_active
= pt
.get
<bool>("arduino_stack.channel4_active");
53 record_channels
.push_back(1);
58 record_channels
.push_back(2);
63 record_channels
.push_back(3);
68 record_channels
.push_back(4);
71 c1_gain
= pt
.get
<double>("arduino_stack.channel1_pga");
72 channel1_gain
= translate_pga_gain(c1_gain
);
73 if (channel1_gain
== PGA_GAIN_UNKNOWN
)
75 syslog(LOG_ERR
, "[ERROR][root] Unknown gain setting for channel 1: %f.", c1_gain
);
76 std::exit(EXIT_FAILURE
);
79 c2_gain
= pt
.get
<double>("arduino_stack.channel2_pga");
80 channel2_gain
= translate_pga_gain(c2_gain
);
81 if (channel2_gain
== PGA_GAIN_UNKNOWN
)
83 syslog(LOG_ERR
, "[ERROR][root] Unknown gain setting for channel 4: %f.", c2_gain
);
84 std::exit(EXIT_FAILURE
);
87 c3_gain
= pt
.get
<double>("arduino_stack.channel3_pga");
88 channel3_gain
= translate_pga_gain(c3_gain
);
89 if (channel3_gain
== PGA_GAIN_UNKNOWN
)
91 syslog(LOG_ERR
, "[ERROR][root] Unknown gain setting for channel 4: %f.", c3_gain
);
92 std::exit(EXIT_FAILURE
);
95 c4_gain
= pt
.get
<double>("arduino_stack.channel4_pga");
96 channel4_gain
= translate_pga_gain(c4_gain
);
97 if (channel4_gain
== PGA_GAIN_UNKNOWN
)
99 syslog(LOG_ERR
, "[ERROR][root] Unknown gain setting for channel 4: %f.", c4_gain
);
100 std::exit(EXIT_FAILURE
);
103 sps_raw
= pt
.get
<uint16_t>("arduino_stack.sps");
104 sps
= translate_adc_sps(sps_raw
);
105 if (sps
== ADC_SPS_UNKNOWN
)
107 syslog(LOG_ERR
, "[ERROR][root] Not supported sps setting: %d.", sps_raw
);
108 std::exit(EXIT_FAILURE
);
112 // ------------------------------------------------------------------------
113 // Parse the record section.
114 storage_mode
= pt
.get
<std::string
>("record.storage_mode");
115 tmp_dir
= pt
.get
<std::string
>("record.tmp_dir");
116 ruwai_serial_file
= pt
.get
<std::string
>("record.ruwai_serial_file");
117 file_length
= pt
.get
<unsigned int>("record.file_length");
118 //record_channels = to_array<unsigned int>(pt.get<std::string>("record.record_channels"));
121 // ------------------------------------------------------------------------
122 // Parse the gps section.
123 gps_usb_active
= pt
.get
<bool>("gps.usb_active");
126 // ------------------------------------------------------------------------
127 // Depending on the selected storage mode, parse the sd or hdd section.
128 if (storage_mode
== "sd")
130 sd_dev_label
= pt
.get
<std::string
>("sd.dev_label");
131 sd_dev_1
= pt
.get
<std::string
>("sd.dev_1");
132 sd_dev_2
= pt
.get
<std::string
>("sd.dev_2");
133 sd_mnt_point
= pt
.get
<std::string
>("sd.mnt_point");
134 } else if (storage_mode
== "hdd")
136 hdd_mseed_dir
= pt
.get
<std::string
>("hdd.mseed_dir");
139 // ------------------------------------------------------------------------
140 rts_start_server
= pt
.get
<bool>("rt_server.start_server");
141 rts_port
= pt
.get
<unsigned int>("rt_server.port");
142 rts_max_clients
= pt
.get
<unsigned int>("rt_server.max_clients");
144 catch (const boost::property_tree::ptree_bad_path
& e
) {
145 syslog(LOG_ERR
, "[ERROR][root] Couldn't read the config file %s. Error message: %s.", config_file
.c_str(), e
.what());
151 //const std::string serial_filename = "/etc/ruwai_serial";
153 std::ifstream
myfile(ruwai_serial_file
);
154 if (myfile
.is_open())
156 std::getline(myfile
, line
);
157 boost::trim_left(line
);
158 boost::trim_right(line
);
159 serial_number
= line
;
160 syslog(LOG_NOTICE
, "[root] Ruwai serial number: %s.", serial_number
.c_str());
165 syslog(LOG_ERR
, "[ERROR][root] Unable to open the file %s to read the serial number.", ruwai_serial_file
.c_str());
166 std::exit(EXIT_FAILURE
);
170 syslog(LOG_ERR
, "[ERROR][root] Couldn't read the serial number from %s. Unknown error.", ruwai_serial_file
.c_str());
175 std::string rec_channels_string
= "";
176 for (unsigned int k
= 0; k
< record_channels
.size(); k
++)
178 rec_channels_string
+= std::to_string(record_channels
[k
]);
180 if (k
< record_channels
.size() - 1)
182 rec_channels_string
+= ",";
186 syslog(LOG_NOTICE
, "------- read configuration --------");
187 syslog(LOG_NOTICE
, "arduino_stack");
188 syslog(LOG_NOTICE
, "serial_port: %s", dev_name
.c_str());
189 syslog(LOG_NOTICE
, "n_channels: %d", n_channels
);
190 syslog(LOG_NOTICE
, "channel1_active: %d", channel1_active
);
191 syslog(LOG_NOTICE
, "channel2_active: %d", channel2_active
);
192 syslog(LOG_NOTICE
, "channel3_active: %d", channel3_active
);
193 syslog(LOG_NOTICE
, "channel4_active: %d", channel4_active
);
194 syslog(LOG_NOTICE
, "channel1_gain: %.3f (%d)", c1_gain
, channel1_gain
);
195 syslog(LOG_NOTICE
, "channel2_gain: %.3f (%d)", c2_gain
, channel2_gain
);
196 syslog(LOG_NOTICE
, "channel3_gain: %.3f (%d)", c3_gain
, channel3_gain
);
197 syslog(LOG_NOTICE
, "channel4_gain: %.3f (%d)", c4_gain
, channel4_gain
);
198 syslog(LOG_NOTICE
, "sps: %d (%d)", sps_raw
, sps
);
199 syslog(LOG_NOTICE
, "record");
200 syslog(LOG_NOTICE
, "storage_mode: %s", storage_mode
.c_str());
201 syslog(LOG_NOTICE
, "tmp_dir: %s", tmp_dir
.c_str());
202 syslog(LOG_NOTICE
, "record_channels: %s", rec_channels_string
.c_str());
203 syslog(LOG_NOTICE
, "file_length: %d", file_length
);
204 if (storage_mode
== "sd")
206 syslog(LOG_NOTICE
, "sd");
207 syslog(LOG_NOTICE
, "dev_label: %s", sd_dev_label
.c_str());
208 syslog(LOG_NOTICE
, "dev_1: %s", sd_dev_1
.c_str());
209 syslog(LOG_NOTICE
, "dev_2: %s", sd_dev_2
.c_str());
210 syslog(LOG_NOTICE
, "mnt_point: %s", sd_mnt_point
.c_str());
211 } else if (storage_mode
== "hdd")
213 syslog(LOG_NOTICE
, "hdd");
214 syslog(LOG_NOTICE
, "mseed_dir: %s", hdd_mseed_dir
.c_str());
216 syslog(LOG_NOTICE
, "gps");
217 syslog(LOG_NOTICE
, "usb_active: %d", gps_usb_active
);
218 syslog(LOG_NOTICE
, "rt_server");
219 syslog(LOG_NOTICE
, "start_server: %d", rts_start_server
);
220 syslog(LOG_NOTICE
, "port: %d", rts_port
);
221 syslog(LOG_NOTICE
, "max_clients: %d", rts_max_clients
);
222 syslog(LOG_NOTICE
, "-----------------------------------");
224 // Create the temporary data directory.
225 if (!boost::filesystem::exists(tmp_dir
))
227 if (!boost::filesystem::create_directory(tmp_dir
))
229 syslog(LOG_ERR
, "[ERROR][root] Can't create the tmp_dir: %s. This is mandatory. Exiting.", tmp_dir
.c_str());
230 std::exit(EXIT_FAILURE
);
234 std::string mseed_dir
;
235 if (storage_mode
== "sd")
236 mseed_dir
= sd_mnt_point
;
237 else if (storage_mode
== "hdd")
238 mseed_dir
= hdd_mseed_dir
;
239 recorder
= new Recorder(serial_number
, n_channels
, record_channels
, sps
, mseed_dir
, tmp_dir
, file_length
);
240 rt_server
= new RealTimeServer(rts_port
, rts_max_clients
);
247 bool is_ready
= true;
249 // Check the output directory structure. If it doesn't exist, it's created.
250 if(!recorder
->check_output_dir_structure())
252 syslog(LOG_ERR
, "[ERROR][root] The output directory structure couldn't be created. Can't start the recorder.");
256 if (storage_mode
== "sd" && !is_sd_mounted())
265 Root::is_sd_dev_available(void)
267 bool dev_available
= false;
270 if (stat(sd_dev_label
.c_str(), &sb
) != -1)
272 switch (sb
.st_mode
& S_IFMT
) {
274 syslog(LOG_NOTICE
, "[root] SD card block device found at %s.", sd_dev_label
.c_str());
275 dev_available
= true;
278 syslog(LOG_ERR
, "[ERROR][root] SD card device file %s is not a block device.", sd_dev_label
.c_str());
284 syslog(LOG_WARNING
, "[WARNING][root] SD card block device file %s not found.", sd_dev_label
.c_str());
287 return dev_available
;
291 Root::is_sd_mounted(void)
294 struct mntent
*part
= NULL
;
295 bool is_mounted
= false;
297 if ((mtab
= setmntent("/etc/mtab", "r")) != NULL
)
299 while ((part
= getmntent(mtab
)) != NULL
)
301 if((part
->mnt_fsname
!= NULL
) && ((strcmp(part
->mnt_fsname
, sd_dev_1
.c_str())) == 0 || (strcmp(part
->mnt_fsname
, sd_dev_2
.c_str())) == 0) && (strcmp(part
->mnt_dir
, sd_mnt_point
.c_str()) == 0) )
310 syslog(LOG_NOTICE
, "[root] The SD card is correctly mounted at %s.", sd_mnt_point
.c_str());
314 syslog(LOG_WARNING
, "[WARNING][root] The SD card is NOT mounted. Couldn't find an entry for %s or %s mounted at %s in /etc/mtab.", sd_dev_1
.c_str(), sd_dev_2
.c_str(), sd_mnt_point
.c_str());
323 bool mount_success
= false;
326 // TODO: Use the mount function instead of calling mount using the system
327 // command. Using the mount function didn't work because of missing
328 // permissions when running as a normal user. Also the mtab entry is not
329 // written automatically. I think I would have to add an entry to mtab.
330 //ret_val = mount(sd_dev_label.c_str(), sd_mnt_point.c_str(), "ext4", MS_NOSUID | MS_NOEXEC | MS_NODEV, NULL);
332 std::string cmd
= "mount " + sd_mnt_point
;
333 ret_val
= system(cmd
.c_str());
337 syslog(LOG_NOTICE
, "[root] Successfully mounted the sd card on %s.", sd_mnt_point
.c_str());
338 mount_success
= true;
342 syslog(LOG_ERR
, "[ERROR][root] Troubles when mounting the SD card: %s.", strerror(errno
));
344 return mount_success
;
351 bool port_open
= false;
352 bool config_confirmed
= false;
355 display
->print("Starting...", "");
357 // Start the temperature logging thread.
358 syslog(LOG_NOTICE
, "[root] Starting the temperature logging thread.");
359 std::thread
t_temp_log(log_temperature
);
362 // Check the output directory structure. If it doesn't exist, it's created.
363 if(!recorder
->check_output_dir_structure())
365 syslog(LOG_ERR
, "[ERROR][root] The output directory structure couldn't be created. Can't start the recorder.");
369 port_open
= open_port();
374 // Test the chrono measurement.
376 syslog(LOG_DEBUG, "Testing the chrono measurement with usleep(1000).");
377 auto start = std::chrono::high_resolution_clock::now();
379 auto end = std::chrono::high_resolution_clock::now();
380 auto diff = end - start;
381 syslog(LOG_DEBUG, "Measured time: %d nanoseconds", (int)std::chrono::duration_cast<std::chrono::nanoseconds>(diff).count());
384 // Start the real time server if activated.
385 if (rts_start_server
)
387 syslog(LOG_NOTICE
, "[root] Starting the realtime server thread.");
388 std::thread
t_rts([&] (RealTimeServer
* rt_server
) {rt_server
->start_listen();}, rt_server
);
393 parser
= new SerialParser(serial_port
, recorder
);
394 std::thread
t_read_and_parse([&] (SerialParser
* parser
) {parser
->read_and_parse();}, parser
);
396 // Wait for handshaking.
397 display
->print("Handshaking...", "");
398 syslog(LOG_NOTICE
, "[root] Handshaking with Arduino stack....");
400 for (int k
= 0; k
< max_try
; k
++)
402 syslog(LOG_NOTICE
, "[root] Waiting for handshake with Arduino stack...");
403 parser
->start_handshake();
405 if (parser
->is_synced())
410 if (!parser
->is_synced())
412 syslog(LOG_ERR
, "[ERROR][root] ...tried handshake for %d times. Got no answer. Giving up.", max_try
);
413 std::exit(EXIT_FAILURE
);
417 syslog(LOG_NOTICE
, "[root] ...handshake was successful.");
421 display
->print("Configuring...", "");
422 syslog(LOG_NOTICE
, "[root] Setting the Arduino stack to control mode.");
423 success
= parser
->set_control_mode();
426 syslog(LOG_NOTICE
, "[root] Confirmed control mode configuration by the Arduino stack.");
430 syslog(LOG_ERR
, "[ERROR][root] No confirmation of the control mode configuration.");
433 // Configure the Arduino stack.
434 // TODO: Restart the configuration if no confirmation was received.
435 syslog(LOG_NOTICE
, "[root] Configuring the Arduino stack....");
437 for (int k
= 0; k
< max_try
; k
++)
439 config_confirmed
= true;
440 syslog(LOG_NOTICE
, "[root] Setting the sps to %d.", sps
);
441 success
= parser
->set_sps((uint16_t)sps
);
444 syslog(LOG_NOTICE
, "[root] Confirmed sps configuration by the Arduino stack.");
448 syslog(LOG_ERR
, "[ERROR][root] No confirmation of the sps configuration. Start again.");
449 config_confirmed
= false;
453 syslog(LOG_NOTICE
, "[root] Activating the channels.");
454 success
= parser
->set_channels(channel1_active
, channel2_active
, channel3_active
, channel4_active
, channel1_gain
, channel2_gain
, channel3_gain
, channel4_gain
);
457 syslog(LOG_NOTICE
, "[root] Confirmed channel configuration by the Arduino stack.");
461 syslog(LOG_ERR
, "[ERROR][root] No confirmation of the channel configuration. Start again.");
462 config_confirmed
= false;
466 syslog(LOG_NOTICE
, "[root] Sending the GPS configuration.");
467 success
= parser
->set_gps(gps_usb_active
);
470 syslog(LOG_NOTICE
, "[root] Confirmed gps configuration by the Arduino stack.");
474 syslog(LOG_ERR
, "[ERROR][root] No confirmation of the gps configuration. Start again.");
475 config_confirmed
= false;
480 if (config_confirmed
)
486 if (!config_confirmed
)
488 syslog(LOG_ERR
, "[ERROR][root] Couldn't configure the Arduino Stack. Tried it %d times.", max_try
);
489 std::exit(EXIT_FAILURE
);
492 syslog(LOG_NOTICE
, "[root] Stack configured successfully.");
494 syslog(LOG_NOTICE
, "[root] Set to record mode.");
495 success
= parser
->set_record_mode();
498 syslog(LOG_NOTICE
, "[root] Confirmed record mode configuration by the Arduino stack.");
499 display
->print("Recording...", "");
503 syslog(LOG_ERR
, "[ERROR][root] No confirmation of the record mode configuration.");
506 //std::thread t_lcd_status([&] (Root* this) {this->lcd_status();}, this);
507 std::thread
t_lcd_status(&Root::lcd_status
, this);
509 t_read_and_parse
.join();
511 // Close the serial port.
519 Root::open_port(void)
521 serial_port
= open(dev_name
.c_str(), O_RDWR
| O_NOCTTY
);
522 if(serial_port
== -1)
524 // Couldn't open the serial port.
525 syslog(LOG_ERR
, "[ERROR][root] Unable to open the Arduino stack serial port %s", dev_name
.c_str());
530 //fcntl(serial_port, F_SETFL, 0);
531 syslog(LOG_NOTICE
, "[root] Serial port %s to Arduino stack opened.", dev_name
.c_str());
537 Root::close_port(void)
544 Root::configure_port(void)
546 struct termios port_options
; // struct to hold the port settings
548 // Fetch the current port settings
549 tcgetattr(serial_port
, &port_options
);
551 // Flush the port's buffers (in and out) before we start using it
552 tcflush(serial_port
, TCIOFLUSH
);
554 // Input flags - Turn off input processing
556 // convert break to null byte, no CR to NL translation,
557 // no NL to CR translation, don't mark parity errors or breaks
558 // no input parity check, don't strip high bit off,
559 // no XON/XOFF software flow control
561 // port_options.c_iflag &= ~(IGNBRK | BRKINT | ICRNL |
562 // INLCR | PARMRK | INPCK | ISTRIP | IXON);
563 port_options
.c_iflag
= 0;
565 // Output flags - Turn off output processing
567 // no CR to NL translation, no NL to CR-NL translation,
568 // no NL to CR translation, no column 0 CR suppression,
569 // no Ctrl-D suppression, no fill characters, no case mapping,
570 // no local output processing
572 // port_options.c_oflag &= ~(OCRNL | ONLCR | ONLRET |
573 // ONOCR | ONOEOT| OFILL | OLCUC | OPOST);
574 port_options
.c_oflag
= 0;
576 // Turn off line processing
578 // echo off, echo newline off, canonical mode on,
579 // extended input processing off, signal chars off
580 // port_options.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
582 // In non-blocking mode, the infinite loop in the serial parser causes a
583 // large CPU load which significantly increases the power consumption of
585 port_options
.c_lflag
= 0;
586 port_options
.c_lflag
&= ~ICANON
; // Set to non-canonical (blocking) mode.
587 port_options
.c_cc
[VMIN
] = 0; // Minimum number of bytes read.
588 port_options
.c_cc
[VTIME
] = 10; // timeout in deci-seconds
590 // Set the input and output baud rates
591 cfsetispeed(&port_options
, B1000000
);
592 cfsetospeed(&port_options
, B1000000
);
593 //cfsetispeed(&port_options, B500000);
594 //cfsetospeed(&port_options, B500000);
595 //cfsetispeed(&port_options, B1152000);
596 //cfsetospeed(&port_options, B1152000);
598 // c_cflag contains a few important things- CLOCAL and CREAD, to prevent
599 // this program from "owning" the port and to enable receipt of data.
600 // Also, it holds the settings for number of data bits, parity, stop bits,
601 // and hardware flow control.
602 port_options
.c_cflag
|= CLOCAL
;
603 port_options
.c_cflag
|= CREAD
;
604 // Set up the frame information.
605 port_options
.c_cflag
&= ~CSIZE
; // clear frame size info
606 port_options
.c_cflag
|= CS8
; // 8 bit frames
607 port_options
.c_cflag
&= ~PARENB
;// no parity
608 port_options
.c_cflag
&= ~CSTOPB
;// one stop bit
610 // Now that we've populated our options structure, let's push it back to the
612 tcsetattr(serial_port
, TCSANOW
, &port_options
);
614 syslog(LOG_DEBUG
, "Configured the serial port:");
615 syslog(LOG_DEBUG
, "port_options.c_cflag: %d - %s", port_options
.c_cflag
, std::bitset
<16>(port_options
.c_cflag
).to_string().c_str());
616 syslog(LOG_DEBUG
, "port_options.c_iflag: %d - %s", port_options
.c_iflag
, std::bitset
<16>(port_options
.c_iflag
).to_string().c_str());
617 syslog(LOG_DEBUG
, "port_options.c_oflag: %d - %s", port_options
.c_oflag
, std::bitset
<16>(port_options
.c_oflag
).to_string().c_str());
618 syslog(LOG_DEBUG
, "port_options.c_lflag: %d - %s", port_options
.c_lflag
, std::bitset
<16>(port_options
.c_lflag
).to_string().c_str());
620 // Flush the buffer one more time.
621 tcflush(serial_port
, TCIOFLUSH
);
623 //fcntl(serial_port, F_SETFL, 0);
628 Root::clear_tmp_dir(void)
630 // Check for forgotten files in the tmp directory.
631 syslog(LOG_NOTICE
, "[root] Cleaning the tmp directory.");
633 std::vector
<std::string
> file_list
;
634 boost::filesystem::path
search_dir(tmp_dir
);
635 boost::filesystem::directory_iterator end_itr
;
637 if (boost::filesystem::exists(search_dir
) && boost::filesystem::is_directory(search_dir
))
639 for (boost::filesystem::directory_iterator
dir_itr(search_dir
); dir_itr
!= end_itr
; dir_itr
++)
641 //syslog(LOG_NOTICE, "Moving file %s from tmp directory to mseed_dir.", dir_itr->path().filename().string().c_str());
642 file_list
.push_back(dir_itr
->path().filename().string());
646 if (file_list
.size() == 0)
648 syslog(LOG_NOTICE
, "[root] No data files found in the tmp directory: %s.", search_dir
.c_str());
652 recorder
->copy_files(file_list
);
659 Root::translate_pga_gain(double gain)
661 pga_gain_t ret = PGA_GAIN_UNKNOWN;
662 if (gain == 0.125 || gain == 0.172 || gain == 0.25 || gain == 0.344 || \
663 gain == 0.5 || gain == 0.688 || gain == 1 || gain == 1.375 || \
664 gain == 2 || gain == 2.75 || gain == 4 || gain == 5.5 || gain == 8 || \
665 gain == 11 || gain == 16 || gain == 22 || gain == 32 || gain == 44 || \
666 gain == 64 || gain == 88 || gain == 128 || gain == 176)
668 ret = (pga_gain_t) gain;
676 Root::translate_pga_gain(double gain
)
678 pga_gain_t ret
= PGA_GAIN_UNKNOWN
;
680 ret
= PGA_GAIN_0_125
;
681 else if (gain
== 0.172)
682 ret
= PGA_GAIN_0_172
;
683 else if (gain
== 0.25)
685 else if (gain
== 0.344)
686 ret
= PGA_GAIN_0_344
;
687 else if (gain
== 0.5)
689 else if (gain
== 0.688)
690 ret
= PGA_GAIN_0_688
;
693 else if (gain
== 1.375)
694 ret
= PGA_GAIN_1_375
;
697 else if (gain
== 2.75)
701 else if (gain
== 5.5)
719 else if (gain
== 128)
721 else if (gain
== 176)
730 Root::translate_adc_sps(uint16_t sps
)
732 adc_sps_t ret
= ADC_SPS_UNKNOWN
;
733 if (sps
== 100 || sps
== 200 || sps
== 400 || sps
== 500 || \
736 ret
= (adc_sps_t
) sps
;
743 Root::lcd_status(void)
745 char c_time_string
[27];
746 std::string time_string
;
747 timestamp_t last_timestamp
;
751 std::stringstream stream
;
755 last_timestamp
= recorder
->get_last_timestamp();
756 ms_hptime2isotimestr(last_timestamp
.time
, c_time_string
, true);
757 time_string
= std::string(c_time_string
);
758 display
->print(time_string
.substr(0, 10), time_string
.substr(11));
759 std::this_thread::sleep_for(std::chrono::seconds(5));
762 stream
<< "GPS F:" << last_timestamp
.gps_fix
<< " OK:" << last_timestamp
.gps_fix_ok
;
765 stream
<< "SLTS:" << last_timestamp
.sec_slts
;
767 display
->print(msg1
, msg2
);
768 std::this_thread::sleep_for(std::chrono::seconds(5));
771 std::vector
<int> tmp_file_size(recorder
->tmp_file_size
);
773 stream
<< "Recording";
777 stream
<< tmp_file_size
.size() << " files";
779 display
->print(msg1
, msg2
);
780 std::this_thread::sleep_for(std::chrono::seconds(2));
783 for (unsigned int k
= 0; k
< tmp_file_size
.size(); k
++)
786 stream
<< "Size file " << k
+ 1;
790 stream
<< recorder
->tmp_file_size
[k
] << " kB";
792 display
->print(msg1
, msg2
);
793 std::this_thread::sleep_for(std::chrono::seconds(2));
796 /* TODO: Getting the file size is blocking the program somehow.
797 std::string tmp_dir = recorder->get_tmp_dir();
798 std::vector<std::string> rec_files = get_file_list(tmp_dir);
799 std::sort(rec_files.begin(), rec_files.end());
801 stream << rec_files.size() << " files";
805 for (std::vector<std::string>::iterator it = rec_files.begin(); it != rec_files.end(); it++)
807 std::string file_path = tmp_dir + "/" + *it;
808 stream << boost::filesystem::file_size(file_path) / 1024 << "; ";
816 std::vector
<std::string
>
817 Root::get_file_list(const std::string path
)
819 std::vector
<std::string
> m_file_list
;
822 boost::filesystem::path
apk_path(path
);
824 for (auto& entry
: boost::make_iterator_range(boost::filesystem::directory_iterator(apk_path
), {}))
826 m_file_list
.push_back(entry
.path().string());