Files
usbserial-dw/main.cpp
2021-08-28 15:09:31 +02:00

243 lines
7.7 KiB
C++
Executable File

/*
* File: main.cpp
* Author: fede.tft
*
* Created on September 10, 2009, 10:50 AM
*/
#include <iostream>
#include <boost/log/sinks/debug_output_backend.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/sinks/event_log_backend.hpp>
#include <boost/thread/future.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/core.hpp>
#include <boost/log/common.hpp>
#include <boost/log/sinks.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/log/detail/config.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/program_options.hpp>
#include "TimeoutSerial.h"
#include "YmodemFileReceive.h"
#include <exception>
using namespace std;
using namespace boost;
namespace po = boost::program_options;
typedef vector< string > split_vector_type;
static void init_log(void)
{
/* init boost log
* 1. Add common attributes
* 2. set log filter to trace
*/
boost::log::add_common_attributes();
boost::log::core::get()->add_global_attribute("Scope",
boost::log::attributes::named_scope());
boost::log::core::get()->set_filter(
boost::log::trivial::severity >= boost::log::trivial::trace
);
/* log formatter:
* [TimeStamp] [ThreadId] [Severity Level] [Scope] Log message
*/
auto fmtTimeStamp = boost::log::expressions::
format_date_time<boost::posix_time::ptime>("TimeStamp", "%Y-%m-%d %H:%M:%S.%f");
auto fmtThreadId = boost::log::expressions::
attr<boost::log::attributes::current_thread_id::value_type>("ThreadID");
auto fmtSeverity = boost::log::expressions::
attr<boost::log::trivial::severity_level>("Severity");
auto fmtScope = boost::log::expressions::format_named_scope("Scope",
boost::log::keywords::format = "%n(%f:%l)",
boost::log::keywords::iteration = boost::log::expressions::reverse,
boost::log::keywords::depth = 2);
boost::log::formatter logFmt =
boost::log::expressions::format("[%1%] (%2%) [%3%] [%4%] %5%")
% fmtTimeStamp % fmtThreadId % fmtSeverity % fmtScope
% boost::log::expressions::smessage;
/* console sink */
auto consoleSink = boost::log::add_console_log(std::clog);
consoleSink->set_formatter(logFmt);
consoleSink->set_filter(
boost::log::trivial::severity >= boost::log::trivial::warning
);
/* fs sink */
auto fsSink = boost::log::add_file_log(
// boost::log::keywords::file_name = "serial-dw_%Y-%m-%d_%H-%M-%S.%N.log",
boost::log::keywords::file_name = "serial-downloader.log",
boost::log::keywords::rotation_size = 10 * 1024 * 1024,
boost::log::keywords::min_free_space = 30 * 1024 * 1024,
boost::log::keywords::open_mode = std::ios_base::app);
fsSink->set_formatter(logFmt);
fsSink->locked_backend()->auto_flush(true);
}
void showProgress(int num)
{
cout << "Downloading: (" << num << "/100) %" ;
cout.put('\r');
cout << flush;
}
int main(int argc, char* argv[])
{
string line;
YmodemFileReceive modem;
float temperature = NAN;
float humidity= NAN;
float pressure = NAN;
po::variables_map vm;
std::string port,path,filename;
int speed;
init_log();
po::options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("measure", "get and print values")
("verbose", po::value<string>()->implicit_value("0"), "verbosity level")
("file", po::value<string>(&filename)->default_value("camera.jpg"),"filename of capture filename")
("path", po::value<string>(&path)->default_value("/tmp"),"directory for file of capture")
("capture", "capture photo of camera")
("port", po::value<string>(&port)->default_value("/dev/ttyUSB0"), "port to read from")
("speed", po::value<int>(&speed)->default_value(115200), "speed read from port")
("temperature", "get and print temprature")
("humidity", "get and print humidity")
("pressure", "get and print pressure")
;
try {
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
if (vm.count("help")) {
cout << desc << "\n";
return 0;
}
} catch(std::exception& e) {
cerr << "error: " << e.what() << "\n";
return 1;
}
catch(...) {
cerr << "Exception of unknown type!\n";
return 1;
}
try {
BOOST_LOG_TRIVIAL(debug) << "Starting Program on " << port ;
TimeoutSerial serial(port,speed);
serial.setTimeout(posix_time::seconds(5));
serial.setDTR(false);
serial.setRTS(false);
boost::this_thread::sleep(posix_time::milliseconds(5000));
line = serial.readStringUntil("\n");
trim(line);
BOOST_LOG_TRIVIAL(debug) << line;
if (vm.count("measure") || vm.count("temperature") || vm.count("pressure") || vm.count("humidity")) {
serial.writeString("measure\r\n");
for (;;) {
line = serial.readStringUntil("\n");
trim(line);
if (line == "") continue;
split_vector_type SplitVec;
split( SplitVec, line, is_any_of(" "), token_compress_on );
for (vector<string>::iterator t=SplitVec.begin(); t!=SplitVec.end(); ++t) {
split_vector_type kv;
split(kv, *t, is_any_of("="), token_compress_on);
if (kv[0] == "temperature") temperature = stof(kv[1]);
if (kv[0] == "humidity") humidity = stof(kv[1]);
if (kv[0] == "pressure") pressure = stof(kv[1]);
}
if (pressure > 0.0) break;
}
if (vm.count("measure")) {
cout << "teplota = " << temperature << endl;
cout << "vlhkost = " << humidity << endl;
cout << "tlak = " << pressure << endl;
}
if (vm.count("temperature")) {
cout << temperature << endl;
}
if (vm.count("humidity")) {
cout << humidity << endl;
}
if (vm.count("pressure")) {
cout << pressure << endl;
}
return 0;
}
if (vm.count("capture")) {
serial.writeString("capture\r\n");
boost::this_thread::sleep(posix_time::milliseconds(100));
serial.setTimeout(posix_time::milliseconds(500));
try {
for (;;) {
line = serial.readStringUntil("\r\n");
if (line.rfind("[OK]",0) == 0)
cout << line;
}
} catch (...) {
}
serial.writeString("rb\r\n");
boost::this_thread::sleep(posix_time::milliseconds(100));
serial.readChar(1);
serial.readChar(1);
modem.setSerialPort(&serial);
modem.setFilePath(path);
modem.setDefaultFileName(filename);
modem.receiveProgress.connect(showProgress);
modem.startReceive();
boost::this_thread::sleep(posix_time::seconds(1));
serial.writeString("free\r\n");
}
serial.close();
} catch(boost::system::system_error& e)
{
cout<<"Error: "<<e.what()<<endl;
return 1;
}
}