// // Created by zx on 2019/12/9. // #include "plc_data.h" #include Plc_data *Plc_data::g_ins = 0; std::mutex Plc_data::g_lock; /** * 获取单例句柄 * */ Plc_data *Plc_data::get_instance(std::string ip) { if (g_ins == 0) { std::lock_guard lock(g_lock); if (g_ins == 0) { if (ip != "") { g_ins = new Plc_data(ip); LOG(INFO) << "plc data, handle created"; } else { return 0; } } } return g_ins; } // void Plc_data::Release() // { // if (g_ins) // { // g_ins->m_cond_exit.Notify(true); // LOG(INFO) << "plc data, try to exit plc send thread"; // g_lock.lock(); // if (g_ins->p_send_thread) // { // LOG(INFO) << "plc data, try to join plc send thread"; // // LOG(INFO) << g_ins->p_send_thread->joinable(); // if (g_ins->p_send_thread->joinable()) // g_ins->p_send_thread->join(); // LOG(INFO) << "plc data, try to delete plc send thread"; // delete g_ins->p_send_thread; // g_ins->p_send_thread = 0; // LOG(INFO) << "plc data, delete data send thread"; // } // g_lock.unlock(); // LOG(INFO) << "plc data, start to exit plc handle"; // // if(g_instance->p_plc){ // // LOG(INFO)<<"plc data, try to delete plc handle"; // // delete g_instance->p_plc; // // g_instance->p_plc = 0; // // } // // LOG(INFO)<<"plc data, delete plc handle"; // LOG(INFO) << "plc data, delete instance"; // // delete g_ins; // // g_ins = 0; // LOG(INFO) << "plc data, instance deleted"; // } // else // { // LOG(WARNING) << "plc data, cannot find the instance"; // } // } /** * 更新区域状态 * */ void Plc_data::update_data(int state_code, int border_status, int id) { // LOG(INFO) << "plc data 更新数据 id: "<=MAX_REGIONS) return ; std::lock_guard lock(g_lock); m_data[2 * id] = state_code; m_data[2 * id + 1] = border_status; } /** * plc更新线程,将区域状态写入plc * */ void Plc_data::plc_update_thread(Plc_data *p) { if (p == 0) { LOG(ERROR) << "plc update thread null pointer"; return; } while (!p->m_cond_exit.wait_for_millisecond(1)) { // 判断plc状态 if (p->m_plc.getConnection() && p->mb_is_ready) { for (int i = 0; i < ELE_FENCE_COUNT; ++i) { g_lock.lock(); p->mb_is_ready = p->m_plc.WriteShorts(ELE_FENCE_DB_NUM, ELE_FENCE_BOUNDARY_START_ADDR + i * ELE_FENCE_OFFSET, 2, p->m_data + (i * 2)); memcpy(p->m_last_data + (i * 2), p->m_data + (i * 2), 2 * sizeof(short)); g_lock.unlock(); usleep(10 * 1000); } } else { // 重连plc LOG(WARNING) << "find plc connection error, trying to reconnect."; g_lock.lock(); p->m_plc.disconnect(); // LOG(WARNING) << "find plc connection error, diconnect first."; if (p->m_ip_str != "") { p->mb_is_ready = p->m_plc.connect(p->m_ip_str); // LOG(WARNING) << "find plc connection error, trying to connect"; if (p->mb_is_ready) { LOG(INFO) << "successfully reconnect."; } else { LOG(WARNING) << "failed to connect plc."; } } g_lock.unlock(); usleep(p->m_update_interval_milli * 5 * 1000); } usleep(p->m_update_interval_milli * 1000); } } /** * 有参构造 * */ Plc_data::Plc_data(std::string ip) : mp_update_thread(0), m_ip_str(""), mb_is_ready(0) { m_ip_str = ip; memset(m_data, 0, MAX_REGIONS*2 * sizeof(short)); memset(m_last_data, 0, MAX_REGIONS*2 * sizeof(short)); // p_plc = new S7PLC(); if (m_ip_str != "") { if (m_plc.connect(m_ip_str)) { mb_is_ready = true; } else { LOG(ERROR) << "Plc_data instance, connect failed"; } } else { LOG(ERROR) << "Plc_data instance, empty ip string."; } m_cond_exit.notify_all(false); mp_update_thread = new std::thread(plc_update_thread, this); mp_update_thread->detach(); } /** * 获取plc连接状态 * */ bool Plc_data::get_plc_status() { return mb_is_ready; }