lzq 2025-11-13 17:08:25 +08:00
parent d4c76462fa
commit 97b4e8a36b
13 changed files with 83 additions and 131 deletions

View File

@ -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
)

View File

@ -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": ""

View File

@ -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<std::istream> imageFileStream = std::make_shared<std::istringstream>(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(&currentTime);
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

View File

@ -1,8 +1,8 @@
#include "daily_and_size_sink.h"
#include <charconv>
#include <regex>
#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());

View File

@ -1,5 +1,7 @@
#include "date_util.h"
#include "HCNetSDK.h"
namespace zsy
{
std::string DateUtil::format(const std::string &pattern, const TimePoint dt)

View File

@ -2,27 +2,42 @@
#include "application.h"
#include "common/date_util.h"
#include "common/snowflake.h"
#include <fmt/core.h>
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"({
res.set_content( fmt::format(
R"({{
"code": 0,
"msg": "",
"data": {
"data": {{
"car_number": "",
"type": 2,
"type": {},
"order_no": "",
"err_msg": "",
"scene": "",
"no_weight": false
}
})";
res.set_content(data, "application/json");
}}
}})", type), "application/json");
});
Application::httpSvr->postEndpoint("/api/site/report-v2", [this](const httplib::Request &req, httplib::Response &res)
{

View File

@ -1,11 +1,13 @@
#ifndef TEST_H
#define TEST_H
#include <cstdint>
namespace zsy
{
class Test
{
int type;
public:
Test();
};

View File

@ -23,13 +23,14 @@ namespace zsy
// 0-->不可用、1-->可用
uint8_t status;
std::shared_mutex status_mtx;
std::unique_ptr<httplib::Server> svr;
std::unique_ptr<std::thread> svrThread;
public:
std::unique_ptr<httplib::Server> svr;
explicit HttpSvr(const nlohmann::json &config);
template<typename Func>
requires std::invocable<Func, const httplib::Request&, httplib::Response&>
void postEndpoint(std::string path, Func &&handler)
{
std::shared_lock lock(status_mtx);

View File

@ -13,7 +13,7 @@ namespace zsy
{
try
{
LOGGER_ERROR("MQTT{} 正在连接...", config.clientId);
LOGGER_INFO("MQTT{} 正在连接...", config.clientId);
ioc = std::make_shared<boost::asio::io_context>();
cli = MQTT_NS::make_sync_client(*ioc, config.server, config.port);
cli->set_keep_alive_sec(30);

View File

@ -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<GenericPlatformScaleProcessor *>(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)
{

View File

@ -20,8 +20,8 @@ namespace zsy
{
Application::deviceHolder->getSoundColumn(sn)->play("欢迎光临");
});
}
t.detach();
}
// 上报 1
auto reportPassResult = Application::reportSvr->reportPass(license, sn);

20
z-doc/test.http 100644
View File

@ -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

11
z-doc/test.json 100644
View File

@ -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"
}
}
}
}