From 829fe6c6bc33d53fda9c31fd45a37e1df87befff Mon Sep 17 00:00:00 2001
From: mrDarker <mr.darker@163.com>
Date: 星期五, 30 一月 2026 11:16:24 +0800
Subject: [PATCH] Merge branch 'clh' into liuyang

---
 SourceCode/Bond/BoounionPLC/Model.cpp |  110 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 110 insertions(+), 0 deletions(-)

diff --git a/SourceCode/Bond/BoounionPLC/Model.cpp b/SourceCode/Bond/BoounionPLC/Model.cpp
index 307a16a..051b050 100644
--- a/SourceCode/Bond/BoounionPLC/Model.cpp
+++ b/SourceCode/Bond/BoounionPLC/Model.cpp
@@ -2,6 +2,9 @@
 #include "Model.h"
 #include "Log.h"
 #include "Common.h"
+#include "ToolUnits.h"
+
+// 常量
 
 
 CModel* g_pModel = NULL;
@@ -18,11 +21,16 @@
 	m_pObservableEmitter = nullptr;
 	m_pObservable = nullptr;
 	m_nTimerID = 0;
+	m_pActivePlc = nullptr;
 }
 
 
 CModel::~CModel()
 {
+	for (auto item : m_mapPlc) {
+		delete item.second;
+	}
+	m_mapPlc.clear();
 }
 
 IObservable* CModel::getObservable()
@@ -68,11 +76,21 @@
 	g_pModel = this;
 
 
+	// 获取所有PLC信息
+	std::vector<PlcInfo> plcList;
+	m_configuration.getAllPLCInfo(plcList);
+	for (const auto& plc : plcList) {
+		addPlc(plc.strName, plc.strIp, plc.nPort);
+	}
+
 	return 0;
 }
 
 int CModel::term()
 {
+	for (auto item : m_mapPlc) {
+		item.second->term();
+	}
 	CLog::GetLog()->SetOnLogCallback(nullptr);
 	return 0;
 }
@@ -284,5 +302,97 @@
 
 void CModel::onTimer(UINT nTimerid)
 {
+	static int ii = 0;
+	ii++;
 
+
+	// 检测是否断开,重连
+	if (ii % 5 == 0) {
+		for (auto item : m_mapPlc) {
+			if (!item.second->isConnected()) {
+				item.second->connect();
+			}
+		}
+	}
+
+
+	// 读取产能信息
+	CPLC* pPlc = getCurrentPlc();
+	if (pPlc != nullptr) {
+		pPlc->readPLCDataRegularly();
+	}
 }
+
+std::map<std::string, CPLC*>& CModel::getPlcMap()
+{
+	return m_mapPlc;
+}
+
+int CModel::addPlc(const char* pszName, const char* pszIp, const unsigned int port)
+{
+	auto iter = m_mapPlc.find(pszName);
+	if (iter != m_mapPlc.end()) return -1;
+	CString strPlcDir;
+	strPlcDir.Format(_T("%s\\Plcs\\%s"), (LPTSTR)(LPCTSTR)m_strWorkDir, pszName);
+	CPLC* pPLC = new CPLC(pszName, pszIp, port);
+	pPLC->setWorkDir((LPTSTR)(LPCTSTR)strPlcDir);
+	PLCListener listener;
+	listener.onStateChanged = [&](void* pFrom, int state) -> void {
+		notifyPtr(RX_PLC_STATE_CHANGED, pFrom);
+	};
+	listener.onMonitorData = [&](void* pFrom, int id) -> void {
+		LOGD("PLConMonitorData,%d", id);
+	};
+	listener.onAlarm = [&](void* pFrom, CAlarm* pAlarm, int flag) -> void {
+		LOGE("onAlarm,%d %s", pAlarm->getId(), flag != 0 ? "ON" : "Off");
+		if (flag == 1) {
+			pAlarm->addRef();
+			notifyObjAndPtr(RX_CODE_ALARM_ON, pAlarm, pFrom);
+			pAlarm->release();
+		}
+		else {
+			pAlarm->addRef();
+			notifyObjAndPtr(RX_CODE_ALARM_OFF, pAlarm, pFrom);
+			pAlarm->release();
+		}
+
+	};
+	pPLC->setListener(listener);
+	pPLC->init();
+	m_mapPlc[pszName] = pPLC;
+
+	CString strDir;
+	strDir.Format(_T("%s\\PLCs\\%s"), (LPTSTR)(LPCTSTR)m_strWorkDir, (LPTSTR)(LPCTSTR)pszName);
+	CToolUnits::createDir(strDir);
+	m_configuration.addPLC(pszName, pszIp, port);
+
+	notifyPtr(RX_CODE_ADD_PLC, pPLC);
+	return 0;
+}
+
+int CModel::removePlc(const char* pszName)
+{
+	auto iter = m_mapPlc.find(pszName);
+	if (iter == m_mapPlc.end()) return -1;
+
+	CString strDir;
+	strDir.Format(_T("%s\\PLCs\\%s"), (LPTSTR)(LPCTSTR)m_strWorkDir, (LPTSTR)(LPCTSTR)pszName);
+	CToolUnits::deleteDir(strDir);
+	m_configuration.removePLC(pszName);
+
+	notifyPtr(RX_CODE_REMOVE_PLC, iter->second);
+	delete iter->second;
+	m_mapPlc.erase(iter);
+
+	return 0;
+}
+
+void CModel::setCurrentPlc(CPLC* pPlc)
+{
+	m_pActivePlc = pPlc;
+}
+
+CPLC* CModel::getCurrentPlc()
+{
+	return m_pActivePlc;
+}
\ No newline at end of file

--
Gitblit v1.9.3