// // Created by pengx on 2025/3/18. // #include "methane_serial_port.hpp" #include "tcp_service.hpp" #include "config.hpp" #include "utils.hpp" #include <iomanip> #include <iostream> #include <boost/beast/core.hpp> #include <boost/beast/http.hpp> #include <boost/beast/version.hpp> #include <boost/asio/connect.hpp> #include <boost/asio/ip/tcp.hpp> namespace beast = boost::beast; namespace http = beast::http; namespace net = boost::asio; using tcp = net::ip::tcp; void upload_to_server(const int value) { net::io_context ioc; tcp::resolver resolver{ioc}; auto const results = resolver.resolve(Config::REMOTE_SERVICE_IP, Config::HTTP_PORT); tcp::socket socket{ioc}; try { net::connect(socket, results.begin(), results.end()); // 构建HTTP请求 http::request<http::string_body> req{http::verb::post, Config::API_RECEIVE_DATA, 11}; req.set(http::field::host, Config::REMOTE_SERVICE_IP); req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING); req.set(http::field::content_type, "application/json"); req.set(http::field::connection, "keep-alive"); //{"type":6,"devcode":"1212","data":{"gas":"20"}} std::ostringstream oss; oss << R"({"type":6,"devcode":")" << Config::DOG_CODE << R"(","data":{"gas":")" << value << R"("}})"; std::string body = oss.str(); req.body() = body; req.prepare_payload(); // 发送HTTP请求 http::write(socket, req); } catch (std::exception const &e) { std::cerr << "Error: " << e.what() << std::endl; if (socket.is_open()) { socket.shutdown(tcp::socket::shutdown_both); socket.close(); } } } void MethaneSerialPort::upload_to_server_async(const int value) { post(io_service_, [this, value] { upload_to_server(value); }); } void MethaneSerialPort::handle_response(const std::vector<uint8_t> &buffer) { const auto x = buffer[2]; const auto y = buffer[3]; const auto z = buffer[4]; const auto w = buffer[5]; const auto result = x * (1 << 24) + y * (1 << 16) + z * (1 << 8) + w; TcpService::getInstance().update_gas_value(result); // 上传服务器 if (Utils::is_network_reachable(Config::REMOTE_SERVICE_IP, Config::HTTP_PORT)) { upload_to_server_async(result); } } MethaneSerialPort::MethaneSerialPort( boost::asio::io_service &io_service, const std::string &port_name, const int baud_rate ): io_service_(io_service), port_(io_service, port_name), timer_(io_service) { port_.set_option(serial_port_base::baud_rate(baud_rate)); port_.set_option(serial_port_base::character_size(8)); port_.set_option(serial_port_base::parity(serial_port_base::parity::none)); port_.set_option(serial_port_base::stop_bits(serial_port_base::stop_bits::one)); std::cout << "\033[1;92m" << "MethaneSerialPort init success" << "\033[0m" << std::endl; start_timer(); } void MethaneSerialPort::start_timer() { timer_.expires_from_now(boost::posix_time::seconds(1)); timer_.async_wait([this](const boost::system::error_code &error) { if (!error) { read_from_port(); } }); } //CC 05 00 00 00 00 0D 77 void MethaneSerialPort::read_from_port() { async_read( port_, buffer_, boost::asio::transfer_at_least(8), [this](const boost::system::error_code &error, const size_t) mutable { if (!error) { if (buffer_.size() >= 8) { std::istream is(&buffer_); std::vector<uint8_t> response(8); is.read(reinterpret_cast<char *>(response.data()), 8); if (response[0] == 0xCC && response[7] == 0x77) { handle_response(response); // 处理最新的一帧 } } // 丢弃所有缓存数据 buffer_.consume(buffer_.size()); // 继续下一次读取 read_from_port(); } else { start_timer(); } } ); }