Files
usbserial-dw/main.cpp
2021-10-15 21:18:39 +02:00

298 lines
9.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 <boost/format.hpp>
#include "TimeoutSerial.h"
#include "YmodemFileReceive.h"
#include <exception>
using namespace std;
using namespace boost;
using boost::format;
namespace po = boost::program_options;
typedef vector< string > split_vector_type;
static void init_log(bool debug = false)
{
/* 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);
if (!debug)
fsSink->set_filter(
boost::log::trivial::severity >= boost::log::trivial::warning
);
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,brightness,saturation,contrast;
po::options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("measure", "get and print values")
("debug", "debug output to file")
("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(460800), "speed read from port")
("brightness", po::value<int>(&brightness)->default_value(0), "set brightness")
("saturation", po::value<int>(&saturation)->default_value(0), "set saturation")
("contrast", po::value<int>(&contrast)->default_value(0), "set contrast")
("temperature", "get and print temprature")
("humidity", "get and print humidity")
("pressure", "get and print pressure")
("reboot", "reboot ESP32 CAM")
("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;
}
init_log(vm.count("debug"));
} 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();
}
if (vm.count("reset")) {
serial.setDTR(true);
serial.setRTS(true);
serial.writeString("reboot\r\n");
boost::this_thread::sleep(posix_time::milliseconds(1000));
serial.setDTR(false);
serial.setRTS(false);
}
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("brightness")) {
string s = str(format("bright %d\r\n") % brightness);
BOOST_LOG_TRIVIAL(debug) << "SET " << s ;
serial.writeString(s);
boost::this_thread::sleep(posix_time::milliseconds(100));
}
if (vm.count("saturation")) {
string s = str(format("satur %d\r\n") % saturation);
BOOST_LOG_TRIVIAL(debug) << "SET " << s ;
serial.writeString(s);
boost::this_thread::sleep(posix_time::milliseconds(100));
}
if (vm.count("contrast")) {
string s = str(format("contr %d\r\n") % contrast);
BOOST_LOG_TRIVIAL(debug) << "SET " << s ;
serial.writeString(s);
boost::this_thread::sleep(posix_time::milliseconds(100));
}
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));
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;
}
}