From 48afdbf662078c012a14c5635c1dd303f875cdff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=A4=E7=9F=A5=E6=99=BA=E8=83=BD?= <2386089024@qq.com> Date: Tue, 10 Jun 2025 16:39:51 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=20src/6.10main.cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/6.10main.cpp | 1822 ---------------------------------------------- 1 file changed, 1822 deletions(-) delete mode 100644 src/6.10main.cpp diff --git a/src/6.10main.cpp b/src/6.10main.cpp deleted file mode 100644 index e401421..0000000 --- a/src/6.10main.cpp +++ /dev/null @@ -1,1822 +0,0 @@ -#include "main.h" -//4 13 22 31 -#include -#include -#include -#include"yolov5_detect.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include "jlinux_uart.h" - -#include -#include - -#include -#include - -#define MSS_TEST_BUS_NAME "yolov5test" -static jbus_hdl_t g_jbus; -static jmss_hdl_t g_jmss; -static jisp_hdl_t g_jisp; -static bool g_running; -jmss_stm_t* g_stm[5]; -static jbas_hdl_t jbas_handle; - -#define modelpath_fire "/demo/bin/fire2025_pre.rknn" -#define DOWNLOAD_VERSION_PATH "/tmp/version" -#define ID_FILE_PWD "/etc/DeviceID" -std::string DeviceID; -std::string response_controllerId = "NULL"; - -static char labels_fire[2][20] = { "fire", "any" }; -static char labels_smog[2][20] = { "smog", "any" }; - -#define SERIAL_PORT_INFRARED_SENSOR "/dev/ttyS4" -#define SERIAL_PORT_SOLENOID "/dev/ttyS5" -#define BAUD_RATE B115200 -static int serialPortInfraredSensor; -static int serialPortSolenoid; -float temperature_img[24][32]; -unsigned char buffer[1544]; - -std::mutex mtx; -std::vector ControlInstructions(16, 0x00); - - -#define BAS_TEST_BUS_NAME "bastest" -jbas_hdl_t g_jbas; - -#define PRSTR(val) printf("%s: %s\n", #val, (val) ? (val) : "(null)") - -using namespace cv; -using namespace std; -using json = nlohmann::json; - - -// 定义GPIO控制引脚(假设GPIO2_B0已经设置好) -#define RELAY_GPIO_PIN 116 // 使用GPIO 72控制继电器 - - - - -void hexdump(const char *buf, int len) -{ - //printf("hexdump: len:%d \n", len); - for (int i = 0; i < len; i++) - { - printf("\033[0m\033[1;33m%02X \033[0m", buf[i], buf[i]); - } - printf("\n"); -} - - -// 控制继电器复位的函数 -void reset_relay() { - // 导出GPIO引脚 - system("echo 116 > /sys/class/gpio/export"); - - // 设置GPIO引脚为输出 - system("echo out > /sys/class/gpio/gpio116/direction"); - - // 复位继电器 - system("echo 1 > /sys/class/gpio/gpio116/value"); // 设置高电平 - usleep(1000000); // 等待1秒 - system("echo 0 > /sys/class/gpio/gpio116/value"); // 设置低电平 - std::cout << "Relay reset!" << std::endl; -} - -// 播放音频的函数 -void play_audio(const std::string& file_path, jspk_hdl_t jspk) { - JES_SPK_PlayFile(jspk, file_path.c_str()); - while (JES_SPK_IsBusy(jspk)) { - sleep(1); - } - std::cout << "Audio played: " << file_path << std::endl; -} - -constexpr auto CONFIG_FILE = "/demo/bin/jh.json"; -constexpr auto ID_FILE_PATH = "/etc/DeviceID"; -constexpr auto LICENSE_FILE = "/demo/bin/activation.lic"; -constexpr auto ENCRYPT_KEY = "YourSecretKey1234567890ABCDEF"; // 24字节密钥 - -// RSA公钥(PEM格式) -const string PUBLIC_KEY = R"( ------BEGIN PUBLIC KEY----- -MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAK+UGGqE+K12kd5F5AH3GQNMSKZjq0l+IBTzF28YWTz+CWtRQ78eKOp3/fXZ8UBRQc2/nRT9Us24l9kPGJ2qUYECAwEAAQ== ------END PUBLIC KEY----- -)"; - -// 全局变量 -mutex activation_mutex; - -class Config { -public: - static string getActivationUrl() { - try { - ifstream file(CONFIG_FILE); - if (!file) { - throw runtime_error("Config file not found"); - } - - json config = json::parse(file); - if (config.contains("activation_url")) { - string url = config["activation_url"]; - cout << "[INFO] Using activation URL from JSON config: " << url << endl; - return url; - } - throw runtime_error("activation_url not found in config"); - - } - catch (const exception& e) { - cerr << "[WARN] " << e.what() << " - Using default URL" << endl; - return "http://183.238.1.242:8889/api/label/security"; - } - } -}; - -class CryptoUtil { -public: - - // 异或加密(保留原有逻辑) - static string xorEncrypt(const string& plaintext) { - string encrypted = xorCipher(plaintext, ENCRYPT_KEY); - return base64Encode(encrypted); - } - - static string xorDecrypt(const string& ciphertext) { - string decoded = base64Decode(ciphertext); - return xorCipher(decoded, ENCRYPT_KEY); - } - - // URL编码 - static string urlEncode(const string& value) { - ostringstream escaped; - escaped.fill('0'); - escaped << hex; - for (char c : value) { - if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') { - escaped << c; - } - else { - escaped << '%' << setw(2) << int((unsigned char)c); - } - } - return escaped.str(); - } - - // 新增RSA加密 - static string rsaEncrypt(const string& plaintext) { - RSA* rsa = nullptr; - BIO* bio = nullptr; - string result; - - try { - bio = BIO_new_mem_buf(PUBLIC_KEY.c_str(), -1); - // rsa = PEM_read_bio_RSA_PUBKEY(bio, nullptr, nullptr, nullptr); - rsa = PEM_read_bio_RSA_PUBKEY(bio, nullptr, nullptr, nullptr); - if (!rsa) throw runtime_error("PEM_read_bio_RSA_PUBKEY failed"); - - int keySize = RSA_size(rsa); - vector encrypted(keySize); - - int len = RSA_public_encrypt( - plaintext.size(), - reinterpret_cast(plaintext.c_str()), - encrypted.data(), - rsa, - RSA_PKCS1_PADDING - ); - - if (len == -1) throw runtime_error("RSA encryption failed"); - - result = base64Encode(encrypted.data(), len); - - } - catch (const exception& e) { - cerr << "[ERROR] RSA encryption failed: " << e.what() << endl; - ERR_print_errors_fp(stderr); - result.clear(); - } - - if (rsa) RSA_free(rsa); - if (bio) BIO_free_all(bio); - return result; - } - -private: - static string xorCipher(const string& data, const string& key) { - string result; - for (size_t i = 0; i < data.size(); ++i) { - result += data[i] ^ key[i % key.size()]; - } - return result; - } - - static string base64Encode(const string& data) { - BIO* bio, * b64; - BUF_MEM* bufferPtr; - - b64 = BIO_new(BIO_f_base64()); - bio = BIO_new(BIO_s_mem()); - bio = BIO_push(b64, bio); - - BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); - BIO_write(bio, data.c_str(), data.size()); - BIO_flush(bio); - BIO_get_mem_ptr(bio, &bufferPtr); - BIO_set_close(bio, BIO_NOCLOSE); - BIO_free_all(bio); - - return string(bufferPtr->data, bufferPtr->length); - } - - static string base64Encode(const unsigned char* data, size_t len) { - BIO* b64 = BIO_new(BIO_f_base64()); - BIO* mem = BIO_new(BIO_s_mem()); - BIO_push(b64, mem); - - BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); - BIO_write(b64, data, len); - BIO_flush(b64); - - char* ptr; - long size = BIO_get_mem_data(mem, &ptr); - string result(ptr, size); - - BIO_free_all(b64); - return result; - } - - static string base64Decode(const string& encoded) { - BIO* bio, * b64; - char* buffer = (char*)malloc(encoded.size()); - memset(buffer, 0, encoded.size()); - - bio = BIO_new_mem_buf(encoded.c_str(), -1); - b64 = BIO_new(BIO_f_base64()); - bio = BIO_push(b64, bio); - - BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); - int len = BIO_read(bio, buffer, encoded.size()); - BIO_free_all(bio); - - string result(buffer, len); - free(buffer); - return result; - } -}; - -class NetworkUtil { -public: - static int postRequest(const string& url, const string& postData, string& response) { - CURL* curl = curl_easy_init(); - if (!curl) return CURLE_FAILED_INIT; - - // 使用RSA加密数据 - string encryptedData = CryptoUtil::rsaEncrypt(postData); - string urlEncodedData = CryptoUtil::urlEncode(encryptedData); - - struct curl_slist* headers = nullptr; - headers = curl_slist_append(headers, "Accept: application/json"); // 修改Content-Type - - const string full_url = url + "?id=" + urlEncodedData; - // cout << "[DEBUG] full_url: " << full_url << endl; - - curl_easy_setopt(curl, CURLOPT_URL, full_url.c_str()); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); - - CURLcode res = curl_easy_perform(curl); - curl_easy_cleanup(curl); - curl_slist_free_all(headers); - return res; - } - -private: - static size_t writeCallback(void* contents, size_t size, size_t nmemb, string* output) { - output->append(static_cast(contents), size * nmemb); - return size * nmemb; - } -}; - -class ActivationManager { -public: - explicit ActivationManager(string device_id, string mac) - : device_id_(move(device_id)), mac_(move(mac)) {} - - bool checkActivation() { - lock_guard lock(activation_mutex); - - if (checkLocalLicense()) { - cout << "[INFO] Device already activated" << endl; - return true; - } - return processOnlineActivation(); - } - -private: - string device_id_; - string mac_; - - bool checkLocalLicense() { - ifstream file(LICENSE_FILE, ios::binary); - if (!file) return false; - - string encrypted((istreambuf_iterator(file)), istreambuf_iterator()); - return validateLicense(encrypted); - } - - bool validateLicense(const string& encrypted) { - // 修改为使用xorDecrypt - string decrypted = CryptoUtil::xorDecrypt(encrypted); - auto pos = decrypted.find('|'); - if (pos == string::npos) return false; - - string storedId = decrypted.substr(0, pos); - string storedMac = decrypted.substr(pos + 1); - - return (storedId == device_id_ && storedMac == mac_); - } - - bool processOnlineActivation(int retry_count = 3) { - string activation_url = Config::getActivationUrl(); - const string post_data = device_id_ + "|" + mac_; - cout << "[DEBUG] Original POST data: " << post_data << endl; - - for (int i = 0; i < retry_count; ++i) { - string response; - int curl_code = NetworkUtil::postRequest(activation_url, post_data, response); - - if (curl_code != CURLE_OK) { - cerr << "[ERROR] Network error: " << curl_easy_strerror((CURLcode)curl_code) << endl; - continue; - } - - try { - auto json_resp = json::parse(response); - int code = json_resp["code"].get(); - - if (code == 0) { - generateLicenseFile(device_id_ + "|" + mac_); - return true; - } - - if (code == 60001 || code == 60002) { - cerr << "[FATAL] Activation failed: " << json_resp["msg"].get() << endl; - return false; - } - - if (code == 60003 && i < retry_count - 1) { - cout << "[WARN] Retrying... (" << i + 1 << "/" << retry_count << ")" << endl; - this_thread::sleep_for(chrono::seconds(1)); - continue; - } - return false; - - } - catch (const json::exception& e) { - cerr << "[ERROR] JSON parse error: " << e.what() << endl; - } - } - return false; - } - - void generateLicenseFile(const string& data) { - ofstream file(LICENSE_FILE, ios::binary); - // 修改为使用xorEncrypt - string encrypted = CryptoUtil::xorEncrypt(data); - file.write(encrypted.data(), encrypted.size()); - cout << "[INFO] License file created successfully" << endl; - } -}; - -string getDeviceID() { - ifstream file(ID_FILE_PATH); - string id; - if (!getline(file, id)) throw runtime_error("Failed to read device ID"); - return id; -} - -string getMACAddress() { - const vector interfaces = { "eth0", "eth1", "enp0s3", "wlan0" }; - - for (const auto& iface : interfaces) { - ifstream file("/sys/class/net/" + iface + "/address"); - if (file) { - string mac; - getline(file, mac); - mac.erase(remove(mac.begin(), mac.end(), '\n'), mac.end()); - - if (mac.length() == 17 && count(mac.begin(), mac.end(), ':') == 5) { - return mac; - } - } - } - throw runtime_error("No valid MAC address found"); -} - - -// 获取设备信息 -int g_camera_number = 1; - -std::string generateIndices(char result[4], Alarm* Alarm) { - std::string indices(16, '0'); - - int CA_ID = g_camera_number; - - int start = (CA_ID - 1) * 4; - - for (int i = 0; i < 4; ++i) { - if (result[i] == '1') { - indices[start + i] = '1'; - Alarm->ifalarm = 1; - } - } - - return indices; -} - - - - -int ALARM_TEMPERATURE; -int WARN_TEMPERATURE; -int MOVE_THRESHOLD; -int IGNORE_TEMPERATURE; -double Confidence_Threshold; - -vector> last_result; -auto last_result_time = std::chrono::high_resolution_clock::now();// 时间 -vector> now_result; - -int width = 1920, height = 1080; -JMediaRawFrameType_e type = JMEDIA_RAWFRAMETYPE_NV12; - - -bool check_whether_in_last_result(vector>& last_result, vector& now, std::ofstream& temperature_log) { - if (last_result.empty()) return true; - //查找now的框坐标是否有出现在上一帧 - for (auto i : last_result) { - //范围5像素以内都视为不变 - if (abs(i[0] - now[0]) <= MOVE_THRESHOLD && abs(i[1] - now[1]) <= MOVE_THRESHOLD && abs(i[2] - now[2]) <= MOVE_THRESHOLD && abs(i[3] - now[3]) <= MOVE_THRESHOLD) { - temperature_log << "有重复 此帧结果:(" << now[0] << " " << now[1] << ") (" << now[2] << " " << now[3] << ")" - << " 上帧结果:(" << i[0] << " " << i[1] << ") (" << i[2] << " " << i[3] << ")" << endl; - cout << "上帧结果:(" << i[0] << " " << i[1] << ") (" << i[2] << " " << i[3] << ")" << endl; - cout << "此帧结果:(" << now[0] << " " << now[1] << ") (" << now[2] << " " << now[3] << ")" << endl; - return true; - } - } - cout << "无重复 此帧结果:(" << now[0] << " " << now[1] << ") (" << now[2] << " " << now[3] << ")" << endl; - temperature_log << "无重复 此帧结果:(" << now[0] << " " << now[1] << ") (" << now[2] << " " << now[3] << ")" << endl; - return false; -} - - -string Get_Time(int input) { - // 获取当前系统时间 - std::time_t alarmTime_std = std::time(nullptr); - // 将时间转换为本地时间 - std::tm* localTime = std::localtime(&alarmTime_std); - // 从本地时间结构中获取时间信息 - int year = localTime->tm_year + 1900; - int month = localTime->tm_mon + 1; - int day = localTime->tm_mday; - int hour = localTime->tm_hour; - int minute = localTime->tm_min; - int second = localTime->tm_sec; - // 拼接成字符串 - std::ostringstream oss_alarmTime; - if (input == 1) { - oss_alarmTime << std::setfill('0') - << std::setw(4) << year << "-" - << std::setw(2) << month << "-" - << std::setw(2) << day << " " - << std::setw(2) << hour << ":" - << std::setw(2) << minute << ":" - << std::setw(2) << second; - } - else { - oss_alarmTime << std::setfill('0') - << std::setw(2) << month << "_" - << std::setw(2) << day << "_" - << std::setw(2) << hour << "_" - << std::setw(2) << minute << "_" - << std::setw(2) << second; - } - // 获取拼接后的字符串 - std::string formattedTime = oss_alarmTime.str(); - return formattedTime; -} - - - -double calibration(double x) { - double p1 = -9.052e-08; - double p2 = 8.313e-05; - double p3 = -0.02813; - double p4 = 4.16; - double p5 = -219.7; - double res = p1 * pow(x, 4) + p2 * pow(x, 3) + p3 * pow(x, 2) + p4 * x + p5; - return res; -} - - -size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* response) { - size_t totalSize = size * nmemb; - response->append(static_cast(contents), totalSize); - return totalSize; -} - - -bool _geturlFromfile(const char* filepath, char* url, int maxLength) { - if (filepath == NULL) { - printf("getrulVersion is error, url == null.\n"); - return false; - } - FILE* fp = fopen(filepath, "r"); - if (fp == NULL) { - printf("open %s failed, error is %s.\n", filepath, strerror(errno)); - return false; - } - int iffind = 0; - char* line = NULL; - size_t len = 0; - size_t read; - while ((read = getline(&line, &len, fp)) != -1) { - if (read == 0 || line[0] == '#') { - continue; - } - char* pline = strstr(line, "upload_url"); - if (pline != NULL && (pline = strstr(pline, "=")) != NULL) { - pline++; //过滤掉等于号 - //过滤掉空格 - while (*pline == ' ') { - pline++; - } - int pline_len = strlen(pline) - 1; - int version_len = (pline_len > maxLength ? maxLength : pline_len); - memcpy(url, pline, version_len); - printf("upload_url = %s\n", url); - iffind = 1; - break; - } - } - if (iffind == 0) { - printf("Can not find upload_url\n"); - return false; - } - free(line); - fclose(fp); - return true; -} - - -// 函数用于读取文件并将其内容保存在全局字符串变量中 -void readFileAndStoreInGlobal(const std::string& filename) { - std::ifstream file(filename); - if (file.is_open()) { - std::getline(file, DeviceID); // 读取一行并存储在全局字符串中 - file.close(); - } - else { - std::cerr << "无法打开文件: " << filename << std::endl; - } -} - - -// std::string generateIndices(char result[4],Alarm* Alarm) { -// std::string indices; -// for (int i = 0; i < 4; ++i) { -// if (result[i] == '1') { -// // 将索引值加入到生成的字符串中 -// indices += std::to_string(i + 1); -// Alarm->ifalarm = 1; -// } -// } -// return indices; -// } - - - - - -void checkCoverage(int x1, int x2, int width, char result[4]) { - // 初始化为 '1',表示覆盖 - // std::string resultString1(result, 4); - // std::cout << "result in: " << resultString1 << std::endl; - char result_now[4] = { '1','1','1','1' }; - int line1 = width * 7 / 32; - int line2 = width / 2; - int line3 = width * 25 / 32; - if (x1 > line1) { - result_now[3] = '0'; - } - if (x1 > line2) { - result_now[3] = '0'; - result_now[2] = '0'; - } - if (x1 > line3) { - result_now[3] = '0'; - result_now[2] = '0'; - result_now[1] = '0'; - } - - if (x2 < line3) { - result_now[0] = '0'; - } - if (x2 < line2) { - result_now[0] = '0'; - result_now[1] = '0'; - } - if (x2 < line1) { - result_now[0] = '0'; - result_now[1] = '0'; - result_now[2] = '0'; - } - result[0] = result[0] | result_now[0]; - result[1] = result[1] | result_now[1]; - result[2] = result[2] | result_now[2]; - result[3] = result[3] | result_now[3]; -} - - -//用于resul_warn和result_fire的与操作。 -void and_result(char result1[4], char result2[4]) { - result1[0] = result1[0] & result2[0]; - result1[1] = result1[1] & result2[1]; - result1[2] = result1[2] & result2[2]; - result1[3] = result1[3] & result2[3]; - std::string resultString(result1, 4); - // 打印结果字符串 - std::cout << "与后结果: " << resultString << std::endl; -} - - -//用于resul_warn和result_fire的与操作。 -void or_result(char result1[4], char result2[4]) { - result1[0] = result1[0] | result2[0]; - result1[1] = result1[1] | result2[1]; - result1[2] = result1[2] | result2[2]; - result1[3] = result1[3] | result2[3]; - std::string resultString(result1, 4); - // 打印结果字符串 - std::cout << "或后结果: " << resultString << std::endl; -} - - -void getLabels(const char* path, char labels[2][20]) { - if (strcmp(path, modelpath_fire) == 0) { - std::cout << "Labels for fire model" << std::endl; - strcpy(labels[0], labels_fire[0]); - strcpy(labels[1], labels_fire[1]); - } - else { - std::cout << "Null labels" << std::endl; - strcpy(labels[0], "null"); - strcpy(labels[1], "null"); - } -} - - -static Scalar colorArray[10] = { - Scalar(255, 0, 0, 255), - Scalar(0, 255, 0, 255), - Scalar(0,0,139,255), - Scalar(0,100,0,255), - Scalar(139,139,0,255), - Scalar(209,206,0,255), - Scalar(0,127,255,255), - Scalar(139,61,72,255), - Scalar(0,255,0,255), - Scalar(255,0,0,255), -}; - - -int plot_one_box(Mat src, int x1, int x2, int y1, int y2, char* label, char colour) -{ - int tl = round(0.002 * (src.rows + src.cols) / 2) + 1; - rectangle(src, cv::Point(x1, y1), cv::Point(x2, y2), colorArray[colour], 3); - int tf = max(tl - 1, 1); - int base_line = 0; - cv::Size t_size = getTextSize(label, FONT_HERSHEY_SIMPLEX, (float)tl / 3, tf, &base_line); - int x3 = x1 + t_size.width; - int y3 = y1 - t_size.height - 3; - rectangle(src, cv::Point(x1, y1), cv::Point(x3, y3), colorArray[colour], -1); - putText(src, label, cv::Point(x1, y1 - 2), FONT_HERSHEY_SIMPLEX, (float)tl / 3, cv::Scalar(255, 255, 255, 255), tf, 8); - return 0; -} - - -bool directoryExists(const std::string& path) { - struct stat info; - if (stat(path.c_str(), &info) != 0) { - return false; // 文件夹不存在 - } - else if (info.st_mode & S_IFDIR) { - return true; // 文件夹存在 - } - return false; // 存在但不是文件夹 -} - - -bool createDirectory(const std::string& path) { - if (!directoryExists(path)) { - if (mkdir(path.c_str(), 0755) == 0) { - std::cout << "文件夹创建成功: " << path << std::endl; - return true; - } - else { - std::cerr << "文件夹创建失败: " << strerror(errno) << std::endl; - return false; - } - } - else { - std::cout << "文件夹已存在: " << path << std::endl; - return true; - } -} - - -//计算校验和 -uint8_t calculateChecksum(const std::vector& data) { - uint16_t sum = 0; - for (size_t i = 0; i < data.size() - 1; ++i) { - sum += data[i]; - } - return static_cast(sum & 0xFF); -} - - -void printVector(const std::vector& vec) { - std::cout << "Vector contents: "; - for (const auto& byte : vec) { - std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte) << " "; - } - std::cout << std::dec << std::endl; // 切换回十进制 -} - - -int main(int argc, char** argv) -{ - std::string folderPath = "/demo/pic"; - if (!createDirectory(folderPath)) { - return 0; - } - - - - // 获取设备信息 - jbus_hdl_t jbus = jbus_init("devinfo_test_app"); - if (!jbus) { - fprintf(stderr, "Error: jbus_init() failed.\n"); - return EXIT_FAILURE; - } - - jbas_handle = JES_BAS_Init(jbus); - if (!jbas_handle) { - fprintf(stderr, "Error: JES_BAS_Init() failed.\n"); - jbus_cleanup(jbus); - return EXIT_FAILURE; - } - - JBASDevInfo_t devinfo; - int results = JES_BAS_GetDevInfo(jbas_handle, &devinfo, JFALSE); - - if (results == 0) { - printf("Successfully retrieved device information:\n"); - PRSTR(devinfo.devname); - string CA_ID = devinfo.devname; - PRSTR(devinfo.language); - - //获取设备 - // 提取设备名称中的摄像头编号 - if (!CA_ID.empty()) { - char lastChar = CA_ID.back(); // 获取最后一个字符 - if (isdigit(lastChar) && lastChar >= '1' && lastChar <= '4') { - g_camera_number = lastChar - '0'; // 转换为整数,例如 '2' -> 2 - } - else { - g_camera_number = 1; // 默认值 - fprintf(stderr, "Warning: Invalid device name format: %s\n", CA_ID.c_str()); - } - } - else { - g_camera_number = 1; // 默认值 - fprintf(stderr, "Warning: Device name is empty\n"); - } - - // 打印验证 - printf("Camera number: %d\n", g_camera_number); - } - - - // 打开 JSON 文件 - cout << "解析JSON文件" << endl; - std::ifstream file("/demo/bin/config.json"); - - // 检查文件是否成功打开 - if (!file.is_open()) { - std::cerr << "Failed to open json file" << std::endl; - return 1; - } - - try { - // 解析 JSON 文件 - json Config_jsonData; - file >> Config_jsonData; - // 关闭文件 - - // 赋值给全局常量 - WARN_TEMPERATURE = Config_jsonData["WARN_TEMPERATURE"]; - ALARM_TEMPERATURE = Config_jsonData["ALARM_TEMPERATURE"]; - MOVE_THRESHOLD = Config_jsonData["MOVE_THRESHOLD"]; - IGNORE_TEMPERATURE = Config_jsonData["IGNORE_TEMPERATURE"]; - Confidence_Threshold = Config_jsonData["Confidence_Threshold"]; - } - catch (const json::parse_error& e) - { - std::cerr << "JSON parsing error: " << e.what() << std::endl; - return 0; - } - file.close(); - - cout << "配置 WARN_TEMPERATURE :" << WARN_TEMPERATURE << endl; - cout << "配置 ALARM_TEMPERATURE :" << ALARM_TEMPERATURE << endl; - cout << "配置 MOVE_THRESHOLD :" << MOVE_THRESHOLD << endl; - cout << "配置 IGNORE_TEMPERATURE :" << IGNORE_TEMPERATURE << endl; - cout << "配置 Confidence_Threshold :" << Confidence_Threshold << endl; - cout << SERIAL_PORT_INFRARED_SENSOR << endl; - cout << SERIAL_PORT_SOLENOID << endl; - - try { - const string device_id = getDeviceID(); - const string mac = getMACAddress(); - - cout << "Device ID: " << device_id << "\nMAC: " << mac << endl; - - // 验证RSA加密 - // cout << "\n--- RSA Encryption Test ---" << endl; - // string test_data = device_id + "|" + mac; - // cout << "[TEST] Original data: " << test_data << endl; - - // string encrypted = CryptoUtil::rsaEncrypt(test_data); - // cout << "[TEST] Encrypted data (Base64): " << encrypted << endl; - // cout << "[TEST] URL Encoded data: " << CryptoUtil::urlEncode(encrypted) << endl; - - - // 执行激活流程 - cout << "\n--- Activation Process ---" << endl; - ActivationManager activator(device_id, mac); - if (!activator.checkActivation()) { - cerr << "[FATAL] Activation failed" << endl; - return EXIT_FAILURE; - } - - cout << "\nStarting algorithm..." << endl; - // 主程序逻辑 - - - g_jbus = jbus_init(MSS_TEST_BUS_NAME); - printf("jbus_init success\n"); - g_jmss = JES_MSS_Init(g_jbus); - printf("JES_MSS_Init success\n"); - g_jisp = JES_ISP_Init(g_jbus); - printf("JES_ISP_Init success\n"); - char ispver[128] = {}; - JES_ISP_GetVersion(g_jisp, 0, ispver, sizeof(ispver)); - printf("ispver: %s\n", ispver); - sleep(1); - - - JMediaRawFrameType_e type = argc >= 2 ? (JMediaRawFrameType_e)atoi(argv[1]) : JMEDIA_RAWFRAMETYPE_NV12; - int width = 1920, height = 1080; - jmss_raw_t* rawchn = JES_MSS_RawOpen(g_jmss, 0, width, height, type); - if (rawchn == NULL) { - printf("==============>>>: %s:%d open rawchn failed\n", strrchr(__FILE__, '/'), __LINE__); - return -1; - } - int ret; - - - readFileAndStoreInGlobal((char*)ID_FILE_PWD); - // 打印全局字符串变量 - std::cout << "ID内容:" << DeviceID << std::endl; - char model_fire[] = modelpath_fire; - pthread_t rtsp_tidp; - pthread_t fire_rknn_tidp; - pthread_t smog_rknn_tidp; - pthread_t heart_beat_tidp; - - pthread_t storage_serial; - pthread_create(&storage_serial, NULL, storage_serial_thread, NULL); - - pthread_create(&fire_rknn_tidp, NULL, rkmedia_rknn_thread, model_fire); - // pthread_create(&heart_beat_tidp, NULL, heart_beat, NULL); - //串口读数据线程 - pthread_t read_serial; - pthread_create(&read_serial, NULL, read_serial_thread, NULL); - printf("%s initial finish\n", __func__); - - - while (!quit) - { - usleep(500000); - } - - JES_MSS_Deinit(g_jmss); - JES_ISP_Deinit(g_jisp); - jbus_cleanup(g_jbus); - - } - catch (const exception& e) { - cerr << "[FATAL] " << e.what() << endl; - return EXIT_FAILURE; - } - return EXIT_SUCCESS; -} - -void* rkmedia_rknn_thread(void* args) -{ - pthread_detach(pthread_self()); - - - //初始化协议信息 - // ControlInstructions[0] = 0xCA; //协议头 - // ControlInstructions[1] = 0x14; //总长度 - // ControlInstructions[2] = 0x01; //操作指令 - - //打开JES的通道 - jmss_raw_t* rawchn = JES_MSS_RawOpen(g_jmss, 0, width, height, type); - if (rawchn == NULL) { - printf("==============>>>: %s:%d open rawchn failed\n", strrchr(__FILE__, '/'), __LINE__); - } - //日志相关内容 - std::string filename = "/demo/bin/temperature_log.txt"; - std::ofstream temperature_log(filename, std::ios::out | std::ios::trunc); - temperature_log << "配置 WARN_TEMPERATURE :" << WARN_TEMPERATURE << endl; - temperature_log << "配置 ALARM_TEMPERATURE :" << ALARM_TEMPERATURE << endl; - temperature_log << "配置 MOVE_THRESHOLD :" << MOVE_THRESHOLD << endl; - temperature_log << "配置 IGNORE_TEMPERATURE :" << IGNORE_TEMPERATURE << endl; - temperature_log << "配置 Confidence_Threshold :" << Confidence_Threshold << endl; - //环境温度 - double temp_env = 0; - - auto last_time = std::chrono::high_resolution_clock::now();// 记录开始时间 - // 创建一个 Alarm 结构体对象 - Alarm Alarm; - // 调用初始化函数来初始化结构体成员 - initializeAlarm(&Alarm); - //用于从全局buffer中复制数据 - unsigned char copyBuffer[1544]; - - /* 参数初始化 */ - int output_nboxes_left = 0; - yolov5_detect_result_group_t detect_result_group; - - /* 算法模型初始化 */ - char* path = reinterpret_cast(args); - printf("loading model %s\n", path); - rknn_context ctx; - yolov5_detect_init(&ctx, path); - // yolov5_detect_init(&ctx, "./fire_rv1126.rknn"); - - //配置label - char labels[2][20]; - getLabels(path, labels); - // 设置压缩质量 - std::vector compression_params; - compression_params.push_back(cv::IMWRITE_JPEG_QUALITY); - compression_params.push_back(30); // 设置压缩质量,范围为 0-100 - int overtem_cnt = 0; - std::vector over_tmp_deque(10, 0); - - - /* 算法运行 */ - while (!quit) { - int time2run = 1; - // auto current_time = std::chrono::high_resolution_clock::now(); - // auto elapsed_time = std::chrono::duration_cast(current_time - last_time);// 计算距离开始时间的时间差 - - // if (elapsed_time.count() - 1000 > 0) { - // last_time = current_time; - // time2run = 1; - // } - sleep(2); - //获取摄像头buffer - JVMediaFrame_t frm; - if (JES_MSS_RawGetFrame(rawchn, &frm) < 0) { - sleep(1); - continue; - } - int overtmp_falg = 0; - Alarm.ifalarm = 0; - Alarm.ifwarn = 0; - - // // int JES_MCS_GetLinkageList(jmcs_hdl_t hdl, JMCSLinkageList_t *list); - // JBOOL reverse = JTRUE; - // JBASDevInfo_t devinfo; - // JES_BAS_GetDevInfo(g_jbas, &devinfo, JTRUE); - // PRSTR(devinfo.devname); - // PRSTR(devinfo.language); - - Mat src; - NV12ToRGB(width, height, frm.buffer, src); - //裁剪 - cv::Rect roi(220, 130, 1480, 570); - src = src(roi); - //固定时间间隔去处理红外参数 - char result[4] = { '0','0','0','0' }; - char result_warn[4] = { '0','0','0','0' }; - char result_fire_rknn[4] = { '0','0','0','0' }; - //初始化ControlInstructions - // ControlInstructions[3]=0x00; - // ControlInstructions[4]=0x00; - // ControlInstructions[5]=0x00; - // ControlInstructions[6]=0x00; - // ControlInstructions[7]=0x00; - // ControlInstructions[8]=0x00; - // ControlInstructions[9]=0x00; - // ControlInstructions[10]=0x00; - // ControlInstructions[11]=0x00; - // ControlInstructions[12]=0x00; - // ControlInstructions[13]=0x00; - // ControlInstructions[14]=0x00; - // ControlInstructions[15]=0x00; - // ControlInstructions[16]=0x00; - // ControlInstructions[17]=0x00; - // ControlInstructions[18]=0x00; - - if (time2run) { - cout << "run ." << endl; - mtx.lock(); - memcpy(copyBuffer, buffer, sizeof(buffer)); - mtx.unlock(); - //计算温度 - double temperature; - int Col, Row; - int j = 0; - double max_temperature = 0; - for (int i = 4; i < 1540; i += 2) { - // temperature = calibration((buffer[i+1]*256+buffer[i])/100.0); - temperature = (buffer[i + 1] * 256 + buffer[i]) / 100.0 + 6; - // cout << (buffer[i+1]*256+buffer[i])/100.0 << " " << temperature << endl; - - //按视觉顺序存入数组 - Col = 31 - (j) % 32; - Row = (j) / 32; - temperature_img[Row][Col] = temperature; - j++; - } - temp_env = (buffer[1541] * 256 + buffer[1540]) / 100.0; - WARN_TEMPERATURE = (temp_env * 2) > WARN_TEMPERATURE ? (temp_env * 2) : WARN_TEMPERATURE; - // ALARM_TEMPERATURE = WARN_TEMPERATURE + 20; - //截去上下5行数据 - for (int i = 5; i < 19; i++) { - for (j = 0; j < 32; j++) { - if (temperature_img[i][j] > IGNORE_TEMPERATURE) continue; - if (temperature_img[i][j] > max_temperature) max_temperature = temperature_img[i][j]; - - if (temperature_img[i][j] > ALARM_TEMPERATURE) { - overtmp_falg = 1; - if (0 <= j && j <= 6) - result[0] = '1'; - else if (6 < j && j <= 15) - result[1] = '1'; - else if (15 < j && j <= 24) - result[2] = '1'; - else if (24 < j && j <= 31) - result[3] = '1'; - } - - if (temperature_img[i][j] > WARN_TEMPERATURE) { - Alarm.ifwarn = 1; - if (0 < j && j <= 6) - result_warn[0] = '1'; - else if (6 < j && j <= 15) - result_warn[1] = '1'; - else if (13 < j && j <= 24) - result_warn[2] = '1'; - else if (24 < j && j <= 31) - result_warn[3] = '1'; - } - } - } - - int overtem_cnt_for_log; - if (overtmp_falg) { - over_tmp_deque.push_back(1); - if (over_tmp_deque.size() > 10) { - over_tmp_deque.erase(over_tmp_deque.begin()); - } - overtem_cnt = 0; - for (int i = 0; i < over_tmp_deque.size(); ++i) { - if (over_tmp_deque[i] == 1) { - overtem_cnt++; - } - } - overtem_cnt_for_log = overtem_cnt; - - if (overtem_cnt >= 3) { - Alarm.ifalarm = 1; - over_tmp_deque.assign(9, 0); - over_tmp_deque.push_back(1); - } - else { - memset(result, '0', 4 * sizeof(char)); - } - } - else { - over_tmp_deque.push_back(0); - // 保持队列长度为10,如果超过长度则移除最前面的元素 - if (over_tmp_deque.size() > 10) { - over_tmp_deque.erase(over_tmp_deque.begin()); - } - } - - - // temp_env = (buffer[1541]*256+buffer[1540])/100.0; - cout << "最大温度: " << max_temperature << endl; - cout << "环境温度" << temp_env << endl; - cout << "预警温度: " << WARN_TEMPERATURE << endl; - cout << "直接喷水温度: " << ALARM_TEMPERATURE << endl; - if (max_temperature > WARN_TEMPERATURE) { - temperature_log << endl << "---------------------------------------------------" << endl; - temperature_log << Get_Time(1) << endl; - temperature_log << "最大温度: " << max_temperature << endl; - temperature_log << "环境温度: " << temp_env << endl; - temperature_log << "预警温度: " << WARN_TEMPERATURE << endl; - temperature_log << "直接喷水温度: " << ALARM_TEMPERATURE << endl; - temperature_log << "超温队列:"; - for (int i = 0; i < over_tmp_deque.size(); ++i) { - temperature_log << over_tmp_deque[i] << " "; - } - temperature_log << endl; - } - if (Alarm.ifalarm) { - printf("temprature > %d°C !\n", ALARM_TEMPERATURE); - // 将字符数组拼接成字符串 - std::string resultString(result, 4); - std::cout << ALARM_TEMPERATURE << "度结果: " << resultString << std::endl; - temperature_log << ALARM_TEMPERATURE << "度结果: " << resultString << std::endl; - std::string resultString_warn(result_warn, 4); - std::cout << WARN_TEMPERATURE << "度结果: " << resultString_warn << std::endl; - temperature_log << WARN_TEMPERATURE << "度结果: " << resultString_warn << std::endl; - } - else if (Alarm.ifwarn) { - printf("temprature > %d°C !\n", WARN_TEMPERATURE); - std::string resultString_warn(result_warn, 4); - std::cout << WARN_TEMPERATURE << "结果: " << resultString_warn << std::endl; - temperature_log << WARN_TEMPERATURE << "结果: " << resultString_warn << std::endl; - } - } - - if (Alarm.ifwarn) { - struct timeval start; - struct timeval end; - now_result.clear(); - temperature_log << "上帧总的结果:" << endl; - for (auto i : last_result) { - temperature_log << "(" << i[0] << " " << i[1] << ") (" << i[2] << " " << i[3] << ")" << endl; - } - printf("%s_rknn_run\n", labels[0]); - yolov5_detect_run(ctx, src, &detect_result_group); - } - - //计算时间差 - if (detect_result_group.count > 0) { - auto current_time_now = std::chrono::high_resolution_clock::now();// 时间 - auto value_time = std::chrono::duration_cast(current_time_now - last_result_time);// 计算距离开始时间的时间差 - - if (value_time.count() - 10000 > 0) { - last_result.clear(); - } - } - - - - /* 算法结果在图像中画出并保存 */ - int name_int = 0; - // char result[4]={'0','0','0','0'}; - for (int i = 0; i < detect_result_group.count; i++) - { - yolov5_detect_result_t* det_result = &(detect_result_group.results[i]); - - if (det_result->prop < Confidence_Threshold) - { - continue; - } - - - cout << "Detected object: " << det_result->name << endl; - - - if (Alarm.ifwarn) { - printf("%s @ (%d %d %d %d) %f\n", - det_result->name, - det_result->box.left, det_result->box.top, det_result->box.right, det_result->box.bottom, - det_result->prop); - vector now; - now.push_back(det_result->box.left); - now.push_back(det_result->box.top); - now.push_back(det_result->box.right); - now.push_back(det_result->box.bottom); - now_result.push_back(now); - if (check_whether_in_last_result(last_result, now, temperature_log)) { - continue; - } - } - int x1 = det_result->box.left; - int y1 = det_result->box.top; - int x2 = det_result->box.right; - int y2 = det_result->box.bottom; - - //检测区域 - if (Alarm.ifwarn) { - checkCoverage(x1, x2, 1480, result_fire_rknn); - } - - char label_text[50]; - memset(label_text, 0, sizeof(label_text)); - sprintf(label_text, "%s %0.2f", det_result->name, det_result->prop); - plot_one_box(src, x1, x2, y1, y2, label_text, i % 10); - } - - if (Alarm.ifwarn) { - // if(!now_result.empty()){ - // last_result.clear(); - // last_result = now_result; - // } - - //若上帧结果为空,依然清理结果队列 --2024.11.4 - last_result.clear(); - last_result = now_result; - last_result_time = std::chrono::high_resolution_clock::now();// 时间 - std::string resultString_fire(result_fire_rknn, 4); - std::cout << "rknn检测结果: " << resultString_fire << std::endl; - temperature_log << "rknn检测结果: " << resultString_fire << std::endl; - //对45度区域和火焰检测区域做出 与操作 - and_result(result_warn, result_fire_rknn); - //对火与45度结果 与 60 度结果 做或操作 - or_result(result, result_warn); - temperature_log << "报警输入:" << string(result, 4) << endl; - //处理ControlInstructions数据 - - if (result[0] == '1') ControlInstructions[(g_camera_number - 1) * 4] = 0x01; - if (result[1] == '1') ControlInstructions[(g_camera_number - 1) * 4] = 0x01; - if (result[2] == '1') ControlInstructions[(g_camera_number - 1) * 4] = 0x01; - if (result[3] == '1') ControlInstructions[(g_camera_number - 1) * 4] = 0x01; - std::string indices = generateIndices(result, &Alarm); - std::cout << "结果: " << indices << std::endl; - Alarm.alarmCoverage = indices; - } - - - if (time2run && Alarm.ifalarm) { - - printf("******************************\n"); - // 创建第一个子进程:控制继电器 - pid_t relay_pid = fork(); - if (relay_pid == 0) { - printf("kongzhi jidianqi\n"); - reset_relay(); - exit(0); // 子进程完成继电器控制后退出 - } - - // 创建第二个子进程:播放音频 - pid_t audio_pid = fork(); - if (audio_pid == 0) { - printf("yuyin bobao\n"); - jbus_hdl_t jbus = jbus_init("spktest"); - jmss_hdl_t jms = JES_MSS_Init(jbus); - jspk_hdl_t jspk = JES_SPK_Init(jbus); - - JMediaAencParam_t adec; - JES_SPK_GetParam(jspk, &adec, JFALSE); - adec.attr.volume = 80; - adec.attr.encType = JVMEDIA_AUDIO_TYPE_G711_A; - JES_SPK_SetParam(jspk, &adec); - - // 播放音频 - play_audio("/demo/bin/Sound.g711u", jspk); - - // 清理 - JES_SPK_Deinit(jspk); - JES_MSS_Deinit(jms); - jbus_cleanup(jbus); - exit(0); // 子进程完成音频播放后退出 - } - - - - cv::Mat rgb_img; - cv::cvtColor(src, rgb_img, COLOR_BGR2RGB); - // std::string filename = "result" + std::string(labels[name_int]) + ".jpg"; - std::string filename = "/demo/pic/" + Get_Time(2) + ".jpg"; - cv::imwrite(filename, rgb_img, compression_params); - std::ifstream file(filename, std::ios::in | std::ios::binary); - std::ostringstream oss; - oss << file.rdbuf(); - std::string orig_data = oss.str(); - // 编码图片数据为base64格式 - std::string encoded_data = base64_encode(reinterpret_cast(orig_data.c_str()), orig_data.length()); - Alarm.alarmBase64 = encoded_data; - Alarm.alarmMsg = std::string(labels[0]); - Alarm.alarmMsg = std::string(labels[name_int]); - pthread_t upload_message_tidp; - pthread_create(&upload_message_tidp, NULL, upload_message, static_cast(&Alarm)); - pthread_t upload_message_controller_tidp; - int ret = pthread_create(&upload_message_controller_tidp, NULL, upload_message_controller, static_cast(&Alarm)); - if (ret != 0) { - std::cerr << "Error creating controller thread: " << strerror(ret) << std::endl; - } - else { - std::cerr << "success creating controller thread" << std::endl; - } - } - } - - /* 算法模型空间释放 */ - yolov5_detect_release(ctx); - //文件关闭 - temperature_log.close(); - return 0; - -} - -void* upload_message(void* args) -{ - pthread_detach(pthread_self()); - // 获取上报url - char upload_url[200] = { 0 }; - if (!_geturlFromfile(DOWNLOAD_VERSION_PATH, upload_url, sizeof(upload_url))) { - printf("结束进程\n"); - return 0; - } - - Alarm* alarm = static_cast(args); - - // 获取当前系统时间 - std::time_t alarmTime_std = std::time(nullptr); - - // 将时间转换为本地时间 - std::tm* localTime = std::localtime(&alarmTime_std); - - // 从本地时间结构中获取时间信息 - int year = localTime->tm_year + 1900; - int month = localTime->tm_mon + 1; - int day = localTime->tm_mday; - int hour = localTime->tm_hour; - int minute = localTime->tm_min; - int second = localTime->tm_sec; - - // 拼接成字符串 - std::ostringstream oss_alarmTime; - oss_alarmTime << std::setfill('0') - << std::setw(4) << year << "-" - << std::setw(2) << month << "-" - << std::setw(2) << day << " " - << std::setw(2) << hour << ":" - << std::setw(2) << minute << ":" - << std::setw(2) << second; - - // 获取拼接后的字符串 - std::string formattedTime = oss_alarmTime.str(); - - std::string cameraId = DeviceID; - std::string controllerId = response_controllerId; - std::string msg = (alarm->alarmMsg).c_str(); - std::string type = "1"; - std::string time = formattedTime; - std::string img = (alarm->alarmBase64).c_str(); - std::string Coverage = (alarm->alarmCoverage).c_str(); - - std::cout << "cameraId: " << cameraId << " msg: " << msg << " type: " << type << " time: " << time << std::endl; - - std::string MessageString = - R"({ - "cameraid": ")" + cameraId + R"(", - "controllerId": ")" + controllerId + R"(", - "msg": ")" + msg + R"(", - "type": ")" + type + R"(", - "errNum": ")" + Coverage + R"(", - "img": ")" + img + R"(", - "time": ")" + time + R"(" -})"; - - CURL* curl; - CURLcode res; - curl_global_init(CURL_GLOBAL_ALL); - curl = curl_easy_init(); - - if (curl) - { - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); - curl_easy_setopt(curl, CURLOPT_URL, upload_url); - /* Now specify the POST data */ - struct curl_slist* plist = nullptr; - plist = curl_slist_append(plist, "Content-Type:application/json;charset=UTF-8"); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, plist); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, MessageString.c_str()); - - std::string response; - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); - - res = curl_easy_perform(curl); - /* Check for errors */ - // if(res != CURLE_OK) - // fprintf(stderr, "curl_easy_perform() failed: %s\n",curl_easy_strerror(res)); - if (res != CURLE_OK) { - std::cerr << "Failed to perform cURL request: " << curl_easy_strerror(res) << std::endl; - } - else { - std::cout << "Request successful!" << std::endl; - std::cout << "Response: " << response << std::endl; - } - - - curl_easy_cleanup(curl); - } - curl_global_cleanup(); -} - -void* upload_message_controller(void* args) -{ - pthread_detach(pthread_self()); - Alarm* alarm = static_cast(args); - - // 获取当前系统时间 - std::time_t alarmTime_std = std::time(nullptr); - - // 将时间转换为本地时间 - std::tm* localTime = std::localtime(&alarmTime_std); - - // 从本地时间结构中获取时间信息 - int year = localTime->tm_year + 1900; - int month = localTime->tm_mon + 1; - int day = localTime->tm_mday; - int hour = localTime->tm_hour; - int minute = localTime->tm_min; - int second = localTime->tm_sec; - - // 拼接成字符串 - std::ostringstream oss_alarmTime; - oss_alarmTime << std::setfill('0') - << std::setw(4) << year << "-" - << std::setw(2) << month << "-" - << std::setw(2) << day << " " - << std::setw(2) << hour << ":" - << std::setw(2) << minute << ":" - << std::setw(2) << second; - - // 获取拼接后的字符串 - std::string formattedTime = oss_alarmTime.str(); - - std::string cameraId = DeviceID; - std::string Coverage = (alarm->alarmCoverage).c_str(); - - std::cout << "cameraid: " << cameraId << " errNum: " << Coverage << std::endl; - - std::string MessageString = - R"({ - "cameraid": ")" + cameraId + R"(", - "errNum": ")" + Coverage + R"(" -})"; - - CURL* curl; - CURLcode res; - curl_global_init(CURL_GLOBAL_ALL); - curl = curl_easy_init(); - - if (curl) - { - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); - curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.1.23:9527/device/alarm"); - /* Now specify the POST data */ - struct curl_slist* plist = nullptr; - plist = curl_slist_append(plist, "Content-Type:application/json;charset=UTF-8"); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, plist); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, MessageString.c_str()); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); - - // std::string response; - // curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); - // curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); - - res = curl_easy_perform(curl); - /* Check for errors */ - // if(res != CURLE_OK) - // fprintf(stderr, "curl_easy_perform() failed: %s\n",curl_easy_strerror(res)); - if (res != CURLE_OK) { - std::cerr << "controller: Failed to perform cURL request: " << curl_easy_strerror(res) << std::endl; - } - else { - std::cout << "controller: Request successful!" << std::endl; - // std::cout << "controller: Response: " << response << std::endl; - } - - - curl_easy_cleanup(curl); - } - curl_global_cleanup(); -} - -void* heart_beat(void* args) { - pthread_detach(pthread_self()); - auto last_time = std::chrono::high_resolution_clock::now();// 记录开始时间 - int time2run = 1; - while (!quit) { - - auto current_time = std::chrono::high_resolution_clock::now(); - auto elapsed_time = std::chrono::duration_cast(current_time - last_time);// 计算距离开始时间的时间差 - - if (elapsed_time.count() - 30000 > 0) { - last_time = current_time; - time2run = 1; - } - - if (time2run) { - std::cout << "心跳上报" << std::endl; - std::string cameraId = DeviceID; - std::string IP = "987654"; - int state = 1; - std::string http_address = "http"; - - std::string MessageString = - R"({ - "cameraId": ")" + cameraId + R"(", - "IP": ")" + IP + R"(", - "state": )" + std::to_string(state) + R"(, - "http_address": ")" + http_address + R"(" -})"; - CURL* curl; - CURLcode res; - curl_global_init(CURL_GLOBAL_ALL); - curl = curl_easy_init(); - - if (curl) - { - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); - curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.1.23:9527/device/heartbeat"); - /* Now specify the POST data */ - struct curl_slist* plist = nullptr; - plist = curl_slist_append(plist, "Content-Type:application/json;charset=UTF-8"); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, plist); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, MessageString.c_str()); - - std::string response; - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); - - res = curl_easy_perform(curl); - /* Check for errors */ - // if(res != CURLE_OK) - // fprintf(stderr, "curl_easy_perform() failed: %s\n",curl_easy_strerror(res)); - if (res != CURLE_OK) { - std::cerr << "heart beat: Failed to perform cURL request: " << curl_easy_strerror(res) << std::endl; - } - else { - std::cout << "heart beat: Request successful!" << std::endl; - std::cout << "heart beat: Response: " << response << std::endl; - // 解析 JSON 字符串 - try { - json jsonData = json::parse(response); - - // 提取 controllerId 字段的内容 - response_controllerId = jsonData["controllerId"]; - - std::cout << "Controller ID: " << response_controllerId << std::endl; - } - catch (const json::parse_error& e) { - std::cerr << "JSON parsing error: " << e.what() << std::endl; - } - } - - - curl_easy_cleanup(curl); - } - curl_global_cleanup(); - } - time2run = 0; - } -} - - -void* read_serial_thread(void* args) -{ - pthread_detach(pthread_self()); - ssize_t bytesRead; - serialPortInfraredSensor = open(SERIAL_PORT_INFRARED_SENSOR, O_RDWR | O_NOCTTY | O_NDELAY); - if (serialPortInfraredSensor == -1) { - printf("Failed to open serial port: %s\n", SERIAL_PORT_INFRARED_SENSOR); - return 0; - } - - struct termios tty; - memset(&tty, 0, sizeof(tty)); - if (tcgetattr(serialPortInfraredSensor, &tty) != 0) { - printf("Failed to get serial port attributes\n"); - close(serialPortInfraredSensor); - return 0; - } - cfsetospeed(&tty, BAUD_RATE); - cfsetispeed(&tty, BAUD_RATE); - tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; - tty.c_cflag &= ~(PARENB | PARODD); - tty.c_cflag &= ~CSTOPB; - tty.c_cflag |= CREAD | CLOCAL; - tty.c_iflag = IGNPAR; - tty.c_oflag = 0; - tty.c_lflag = 0; - if (tcsetattr(serialPortInfraredSensor, TCSANOW, &tty) != 0) { - printf("Failed to set serial port attributes\n"); - close(serialPortInfraredSensor); - return 0; - } - - fd_set readfds; - struct timeval timeout; - int selectResult; - - while (1) { - FD_ZERO(&readfds); - FD_SET(serialPortInfraredSensor, &readfds); - - timeout.tv_sec = 5; // 5秒超时 - timeout.tv_usec = 0; - - selectResult = select(serialPortInfraredSensor + 1, &readfds, NULL, NULL, &timeout); - - if (selectResult > 0) { - if (FD_ISSET(serialPortInfraredSensor, &readfds)) { - mtx.lock(); - bytesRead = read(serialPortInfraredSensor, buffer, sizeof(buffer)); - mtx.unlock(); - - if (bytesRead > 0) { - if (buffer[0] == 0x5a && buffer[1] == 0x5a) { - // printf("readed serialPortInfraredSensor date\n"); - } - else { - // printf("read failed\n"); - } - } - } - } - else if (selectResult == 0) { - // 超时,没有数据可读 - // printf("Timeout, no data available\n"); - } - else { - // select出错 - printf("select() failed\n"); - break; - } - } -} - -// pthread_t storage_serial; -// pthread_create(&storage_serial, NULL, storage_serial_thread, NULL); - -// 首先定义协议相关的常量 -#define PROTOCOL_HEAD 0x7E -#define PROTOCOL_VERSION 1 -#define PROTOCOL_LENGTH 22 -#define SOLENOID_VALVE_COUNT 16 -#define COMMAND_QUERY 1 -#define COMMAND_RESPONSE 2 - -// 定义协议结构体 -typedef struct tagCamera485Protocol { - uint8_t m_head; // 协议头 0x7e - uint8_t m_version; // 版本1~255 - uint8_t m_length; // 协议总长度,包含校验位 - uint8_t m_address; // 地址0~255 - uint8_t m_command; // 操作指令 - uint8_t m_solenoidValve[SOLENOID_VALVE_COUNT]; // 电磁阀状态 - uint8_t m_checkSum; // 校验和 -} CCamera485Protocol; - -// 优化后的storage_serial_thread函数 -void* storage_serial_thread(void* args) { - pthread_detach(pthread_self()); - - // { - // test *ptest1 = NULL; - // test *ptest2[2] = {}; - // if (ptest1 == ptest2[0]) - // { - // printf("ptest1 == ptest2"); - // } - // else - // { - // printf("ptest1 != ptest2"); - // } - // return 0; - // } - - juart_hdl_t hdl = juart_open("/dev/ttyS5"); - JUartAttr_t attr = {.baudrate = 9600, - .datawidth = 8, - .stopbit = 1, - .parity = 0}; - - juart_set_attr(hdl, &attr); - juart_set_rs485(hdl, 0); - - unsigned char hexData[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B}; - juart_send(hdl, (char*)hexData, sizeof(hexData)); - printf("send: "); - hexdump((char*)hexData, sizeof(hexData)); - - while (1) - { - CCamera485Protocol protocol; - int len = juart_recv(hdl, (char *)&protocol, sizeof(CCamera485Protocol), 30); - // if (len <= 0) - // { - // printf("==============>>>: %s,%d: recv timeout!\n", strrchr(__FILE__,'/'),__LINE__); - // } - - if (len == sizeof(CCamera485Protocol)) - { - hexdump((char*)&protocol,len); - // 处理协议 - if (protocol.m_head == PROTOCOL_HEAD && - protocol.m_command == COMMAND_QUERY && - protocol.m_address == (g_camera_number - 1)) - { - // 构造响应 - uint8_t response_array[22] = {0}; - // 1. 填充头部 - response_array[0] = PROTOCOL_HEAD; // 协议头 - response_array[1] = PROTOCOL_VERSION; // 版本 - response_array[2] = PROTOCOL_LENGTH; // 长度 - response_array[3] = g_camera_number - 1; // 地址 - response_array[4] = COMMAND_RESPONSE; // 命令 - - // 2. 填充电磁阀状态 - mtx.lock(); - for (int i = 0; i < SOLENOID_VALVE_COUNT; i++) { - response_array[5 + i] = ControlInstructions[i]; - } - mtx.unlock(); - - // 3. 计算校验和(前21字节累加和) - uint8_t sum = 0; - for (int i = 0; i < 21; i++) { - sum += response_array[i]; - } - response_array[21] = sum; // 校验和 - juart_send(hdl, (char*)response_array, sizeof(response_array)); - hexdump((char*)&response_array,sizeof(response_array)); - std::fill(ControlInstructions.begin(), ControlInstructions.end(), 0x00); - //sleep(2); - - } - } - } - juart_close(hdl); - return 0; -} \ No newline at end of file