Files
usbserial-dw/main.cpp
2021-09-01 08:05:36 +02:00

253 lines
8.0 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")
("noraw", "do not set raw mode")
("noreset", "do not set zero on lines DTR a RST")
;
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));
if (! vm.count("noreset")) {
serial.setDTR(false);
serial.setRTS(false);
}
if (! vm.count("noraw")) {
serial.setRAW();
}
boost::this_thread::sleep(posix_time::milliseconds(5000));
if (! vm.count("noreset")) {
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 << endl;
}
} 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;
}
}