diff --git a/CMakeLists.txt b/CMakeLists.txt index f630592..699cf12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,6 @@ find_package(HCNet CONFIG REQUIRED) find_package(ICU REQUIRED COMPONENTS uc) find_path(CPP_HTTPLIB_INCLUDE_DIRS "httplib.h") # 使用时要先于 windows.h 包含 find_path(CPPCODEC_INCLUDE_DIRS "cppcodec/base32_crockford.hpp") -#find_library(WS2_32_LIB NAMES ws2_32) set(SOURCE_DIRS src/common src/vidicon @@ -45,7 +44,6 @@ set(LINK_DIRS src ) set(LIBRARIES -# ${WS2_32_LIB} openssl::libssl openssl::libcrypto mqtt_cpp_iface::mqtt_cpp_iface @@ -78,5 +76,5 @@ target_compile_definitions(${PROJECT_NAME} PUBLIC SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_INFO # 启用日志宏 CPPHTTPLIB_OPENSSL_SUPPORT # httplib 支持 openssl MQTT_STD_VARIANT - _WIN32_WINNT=0x0601 + _WIN32_WINNT=0x0A00 ) diff --git a/config/config.json b/config/config.json index efb890d..efbc3a6 100644 --- a/config/config.json +++ b/config/config.json @@ -2,6 +2,7 @@ "name": "测试", "delay": 0, "daemon": false, + "embedMqtt": true, "httpSvr": { "port": 11000 }, @@ -94,7 +95,10 @@ { "sn": "1", "name": "地磅", + "delay": 5, "sample": 20, + "retries": 30, + "weight": 200.0, "port": "COM2", "baudRate": 9600, "byteSize": 8, @@ -114,7 +118,7 @@ { "sn": "1", "name": "摄像头", - "ip": "", + "ip": "127.0.0.1", "port": 8000, "username": "", "passwd": "" diff --git a/src/barrier/generic_barrier.cpp b/src/barrier/generic_barrier.cpp index 6572304..49c500f 100644 --- a/src/barrier/generic_barrier.cpp +++ b/src/barrier/generic_barrier.cpp @@ -52,17 +52,11 @@ namespace zsy { std::jthread t([recognizeResult,name,sn] { - LOGGER_INFO("正在处理车牌识别结果:{} {}", name, sn); + LOGGER_INFO("正在处理车牌识别结果:{}、{}、{}", recognizeResult->license, name, sn); RecognizeProcessor::process(recognizeResult); LOGGER_INFO("车牌识别结果处理完成"); }); t.detach(); - /*Application::threadPool->submit([recognizeResult,name,sn] - { - LOGGER_INFO("正在处理车牌识别结果:{} {}", name, sn); - RecognizeProcessor::process(recognizeResult); - LOGGER_INFO("车牌识别结果处理完成"); - });*/ } } catch (std::exception &e) { @@ -177,77 +171,4 @@ namespace zsy return std::make_tuple(false, nullptr, "", ""); } } - - /*void GenericBarrier::resolveRecognizeResult(const std::string &license, const std::string &imageFile) - { - try - { - LOGGER_INFO("车牌识别结果处理中,设备名称:{}", config.name); - // 播放语音 1 - std::thread t1([sn = config.sn,name = config.name] - { - size_t found = name.find("前置"); - - if (found != std::string::npos) - { - Application::deviceHolder->getSoundColumn(sn)->play("欢迎光临"); - } - }); - // 上传车头照 - auto imageFileDecode = SysUtil::base64_decode(imageFile); - const std::shared_ptr imageFileStream = std::make_shared(imageFileDecode, std::ios_base::in | std::ios_base::binary); - auto photoId = Snowflake::genIdStr(); - auto now = std::chrono::system_clock::now(); - std::time_t currentTime = std::chrono::system_clock::to_time_t(now); - - std::tm *localTime = std::localtime(¤tTime); - - std::stringstream ss; - ss << std::put_time(localTime, "%Y%m%d"); - - std::string date = ss.str(); - auto [carFrontUrlSucc,carFrontUrl] = Application::oss->upload(date + "/" + "front_" + photoId + ".jpg", *imageFileStream); - // 上报 1 - auto reportPassResult = Application::reportSvr->reportPass(license, config.sn, carFrontUrl); - if (!(reportPassResult.code == 0 && (reportPassResult.data.type == 1 || reportPassResult.data.type == 2))) - { - LOGGER_INFO("不处理:{}", config.name); - t1.join(); - return; - } - - // 上报结果不为 0,播放语音 2 并读地磅,拍车斗并上传 - std::thread t2([sn = config.sn] - { - Application::deviceHolder->getSoundColumn(sn)->play("正在称重,请稍后"); - }); - double weight = Application::deviceHolder->getPlatformScale(config.sn)->reading(); - auto photographPath = Application::deviceHolder->getVidicon(config.sn)->photograph(); - auto [carBodyUrlSucc,carBodyUrl] = Application::oss->upload(date + "/" + "body_" + photoId + ".jpg", photographPath); - if (!photographPath.empty()) - { - auto pathPtr = SysUtil::ch_vlt(photographPath.c_str()); - if (std::remove(pathPtr.get()) != 0) - { - auto [_,code,msg] = SysUtil::getError(); - LOGGER_ERROR("临时照片删除失败:{},错误码:{},错误信息:{}", photographPath, code, msg); - } else - { - LOGGER_ERROR("临时照片删除成功:{}", photographPath); - } - } - - // 上报 2 - Application::reportSvr->report(license, config.sn, weight, carFrontUrl, carBodyUrl, reportPassResult.data.orderNo); - t1.join(); - t2.join(); - } catch (std::exception &e) - { - LOGGER_ERROR("车牌识别结果处理失败: {}", e.what()); - } - catch (...) - { - LOGGER_ERROR("未知异常,车牌识别结果处理失败"); - } - }*/ } // zsy diff --git a/src/common/daily_and_size_sink.cpp b/src/common/daily_and_size_sink.cpp index 1f3934a..4ba6e05 100644 --- a/src/common/daily_and_size_sink.cpp +++ b/src/common/daily_and_size_sink.cpp @@ -1,8 +1,8 @@ #include "daily_and_size_sink.h" - #include #include -#include "utils/date_util.h" + +#include "date_util.h" namespace zsy { @@ -70,25 +70,9 @@ namespace zsy if (std::regex_match(filename, match, file_pattern)) { std::string date_str = match[1].str(); + std::chrono::sys_days date; std::istringstream tstr(date_str); - int year, month, day; - char dash1, dash2; - - // 解析字符串(格式:YYYY-MM-DD) - std::istringstream iss(date_str); - if (!(iss >> year >> dash1 >> month >> dash2 >> day) || dash1 != '-' || dash2 != '-') - { - throw std::invalid_argument("无效的日期格式,需为 YYYY-MM-DD"); - } - - std::chrono::year_month_day ymd(std::chrono::year{year}, - std::chrono::month{(unsigned) month}, std::chrono::day{(unsigned) day}); - if (!ymd.ok()) - { - throw std::invalid_argument("无效的日期"); - } - std::chrono::sys_days date{ymd}; - + tstr >> std::chrono::parse("%F", date); if (date < cutoff_time) { std::filesystem::remove(entry.path()); @@ -153,4 +137,4 @@ namespace zsy } return size; } -} \ No newline at end of file +} diff --git a/src/common/date_util.cpp b/src/common/date_util.cpp index a7a8a39..f16da84 100644 --- a/src/common/date_util.cpp +++ b/src/common/date_util.cpp @@ -1,5 +1,7 @@ #include "date_util.h" +#include "HCNetSDK.h" + namespace zsy { std::string DateUtil::format(const std::string &pattern, const TimePoint dt) diff --git a/src/controller/test.cpp b/src/controller/test.cpp index 581e5ec..f55790d 100644 --- a/src/controller/test.cpp +++ b/src/controller/test.cpp @@ -2,27 +2,42 @@ #include "application.h" #include "common/date_util.h" #include "common/snowflake.h" +#include namespace zsy { - Test::Test() + Test::Test() : type(0) { + Application::httpSvr->getEndpoint("/type", [this](const httplib::Request &req, httplib::Response &res) + { + std::string type = req.get_param_value("type"); + if (type.empty()) + { + res.set_content("未指定类型:0-->前置、1-->进、2-->出", "application/json"); + return; + } + this->type = std::stoi(type); + + res.set_content("已改为" + type, "application/json"); + }); + Application::httpSvr->postEndpoint("/api/site/report-car-pass", [this](const httplib::Request &req, httplib::Response &res) { + auto type = this->type; std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - std::string data = R"({ - "code": 0, - "msg": "", - "data": { - "car_number": "", - "type": 2, - "order_no": "", - "err_msg": "", - "scene": "", - "no_weight": false - } - })"; - res.set_content(data, "application/json"); + res.set_content( fmt::format( + R"({{ + "code": 0, + "msg": "", + "data": {{ + "car_number": "", + "type": {}, + "order_no": "", + "err_msg": "", + "scene": "", + "no_weight": false + }} + }})", type), "application/json"); }); Application::httpSvr->postEndpoint("/api/site/report-v2", [this](const httplib::Request &req, httplib::Response &res) { diff --git a/src/controller/test.h b/src/controller/test.h index 7e8efe5..7bf1a6d 100644 --- a/src/controller/test.h +++ b/src/controller/test.h @@ -1,11 +1,13 @@ #ifndef TEST_H #define TEST_H +#include namespace zsy { class Test { + int type; public: Test(); }; diff --git a/src/http/http_svr.h b/src/http/http_svr.h index f49814a..4c20f4d 100644 --- a/src/http/http_svr.h +++ b/src/http/http_svr.h @@ -23,13 +23,14 @@ namespace zsy // 0-->不可用、1-->可用 uint8_t status; std::shared_mutex status_mtx; - std::unique_ptr svr; std::unique_ptr svrThread; public: + std::unique_ptr svr; explicit HttpSvr(const nlohmann::json &config); template + requires std::invocable void postEndpoint(std::string path, Func &&handler) { std::shared_lock lock(status_mtx); diff --git a/src/mqtt/mqtt_cli.cpp b/src/mqtt/mqtt_cli.cpp index b4e3635..1b7efb0 100644 --- a/src/mqtt/mqtt_cli.cpp +++ b/src/mqtt/mqtt_cli.cpp @@ -13,7 +13,7 @@ namespace zsy { try { - LOGGER_ERROR("MQTT:{} 正在连接...", config.clientId); + LOGGER_INFO("MQTT:{} 正在连接...", config.clientId); ioc = std::make_shared(); cli = MQTT_NS::make_sync_client(*ioc, config.server, config.port); cli->set_keep_alive_sec(30); diff --git a/src/platform_scale/generic_platform_scale.cpp b/src/platform_scale/generic_platform_scale.cpp index 0204e87..c4a8b41 100644 --- a/src/platform_scale/generic_platform_scale.cpp +++ b/src/platform_scale/generic_platform_scale.cpp @@ -94,11 +94,6 @@ namespace zsy try { LOGGER_INFO("正在读取地磅数据,设备名称:{}", config.name); - /*if (status != 1) - { - LOGGER_INFO("无法称重,地磅状态:{}", status); - return 0.0; - }*/ int retry_count = 0; while ((serialPort->status.load() == 3 || serialPort->readStatus.load() == 3) && retry_count < 10) @@ -113,11 +108,9 @@ namespace zsy if (serialPort->status.load() == 3 || serialPort->readStatus.load() == 3) { LOGGER_ERROR("无法称重,串口异常,重试失败"); - /*status = 1;*/ return 0.0; } - /*status = 2;*/ LOGGER_INFO("正在称重..."); if (config.delay > 0) std::this_thread::sleep_for(std::chrono::milliseconds(config.delay * 1000)); auto processor = static_cast(serialPort->processor); @@ -125,17 +118,18 @@ namespace zsy while (processor->steady.load() < config.sample || processor->weight.load() <= config.weight) { count++; + + LOGGER_INFO("第 {} 次称重", count); + if (count >= config.retries) { LOGGER_ERROR("称重失败,连续 {} 次未稳定或磅重低于阈值 {} KG,当前磅重:{} KG", count, config.weight, processor->weight.load()); - /*status = 1;*/ return 0.0; } std::this_thread::sleep_for(std::chrono::milliseconds(3000)); } auto res = processor->weight.load(); LOGGER_INFO("称重完成:{} KG", res); - /*status = 1;*/ return res; } catch (std::exception &e) { diff --git a/src/recognize_processor.cpp b/src/recognize_processor.cpp index fb6d050..18a85ce 100644 --- a/src/recognize_processor.cpp +++ b/src/recognize_processor.cpp @@ -20,8 +20,8 @@ namespace zsy { Application::deviceHolder->getSoundColumn(sn)->play("欢迎光临"); }); + t.detach(); } - t.detach(); // 上报 1 auto reportPassResult = Application::reportSvr->reportPass(license, sn); diff --git a/z-doc/test.http b/z-doc/test.http new file mode 100644 index 0000000..d97835e --- /dev/null +++ b/z-doc/test.http @@ -0,0 +1,20 @@ +### 车牌识别上报 +POST http://localhost:11000/plateRecognize +Content-Type: application/json + +< ./test.json + +### 修改进出场 +GET http://localhost:11000/type?type=2 + +### 开门 +GET http://localhost:11000/opendoor?sn=1 + +### 称重 +GET http://localhost:11000/weight?sn=1 + +### 播放语音 +GET http://localhost:11000/play?sn=1 + +### 拍照 +GET http://localhost:11000/photo?sn=1 diff --git a/z-doc/test.json b/z-doc/test.json new file mode 100644 index 0000000..4429576 --- /dev/null +++ b/z-doc/test.json @@ -0,0 +1,11 @@ +{ + "AlarmInfoPlate": { + "serialno": "4", + "result": { + "PlateResult": { + "imageFile": "iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAIAAADwlwNsAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAEXRFWHRTb2Z0d2FyZQBTbmlwYXN0ZV0Xzt0AAAAXdEVYdFVzZXIgQ29tbWVudABTY3JlZW5zaG9093UNRwAAAMhJREFUGJVj/P//PwNewIRfGknF29PrFu2+g00FC5T+++vnj2+fP33+jCTHzMnLxQpXwcDAwPDy3Ia1F5H40pYJrqooKqQs4ny0MWxh3L5tOwMDA8Pv909f/OSVleCDinMpWNtp8DEwMDCwCMhIcTEwMDBISSnCtX17dP7+2x8MDBAVirp64ugGv/x85T6Gb3EDlo2zZmET54U7mRF7qP/69ZeNjRliywcGhjt7Fuy+ycDA8PfGtrkbL/5iYPh2ddeyVUdeQhQDABokQPRTGLjWAAAAAElFTkSuQmCC", + "license": "皖F25510" + } + } + } +} \ No newline at end of file