GrpcPrint/PrintS/Communication/OxygenClient.cpp
2024-04-15 10:08:28 +08:00

315 lines
11 KiB
C++

#include "OxygenClient.h"
#include "Modbus.h"
#include <shared_mutex>
#include "../SystemInfo.h"
#include "../config/ConfigManager.h"
OxygenClient::OxygenClient(CommunicationCfg* pconfig) :TcpClient(pconfig)
{
m_Freq = 100;
m_ExtCfg = ConfigManager::GetInstance()->GetExtCfg();
//size_t ptrSize = sizeof(nullptr); //指针大小
//void* startPtr = &m_DoluyoChillerStat.m_startFlag + 1;
//size_t count = ((size_t)&m_DoluyoChillerStat.m_endFlag - (size_t)&startPtr) / ptrSize;
//InsertMp(startPtr, count);
}
OxygenClient::~OxygenClient()
{
Shutdown();
//OutputDebugString("oxygen close\n");
}
void OxygenClient::AddToBaseMp(int i, Oxygenstat* stat) {
size_t ptrSize = sizeof(nullptr); //指针大小
void* startPtr = &stat->m_startFlag + 1;
size_t count = ((size_t)&stat->m_endFlag - (size_t)&startPtr) / ptrSize;
for (size_t i = 0; i < count; ++i) {
BaseData* bd = *((BaseData**)((char*)startPtr + ptrSize * i));
string code = bd->GetCode() + "_" + to_string(i); //区分key,添加上"_i"
if (m_baseMp.find(code) != m_baseMp.end()) {
printf("%s is repeated...\n", code.c_str());
}
else { m_baseMp.insert(make_pair(code, bd)); }
}
}
void OxygenClient::InitCommand()
{
map<int, int> tref;
tref[1] = m_ExtCfg->m_Oxygen1SensorType;
tref[2] = m_ExtCfg->m_Oxygen2SensorType;
tref[3] = m_ExtCfg->m_OutOxygenSensorType;
tref[4] = m_ExtCfg->m_CleanBoxOxygenSensorType;
for (int i = 1; i <= 4;i++) {
Oxygenstat* stat = new Oxygenstat();
AddToBaseMp(i, stat); //添加到map
m_Oxygens[i] = stat;
switch (tref[i]) {
case ExtCfg::MOT500_LOW: {
Command* stat3Value = new ReadModbus(i, 0x6004, 11);
stat3Value->m_Fun = &OxygenClient::ProcNewVersion;
stat3Value->m_Ref = this;
stat3Value->isNeedDel = false;
m_CycleCommands.push_back(stat3Value);
}break;
case ExtCfg::MOT500_HIGH: {
Command* stat1Value = new ReadModbus(i, 0x05, 2);
stat1Value->m_Fun = &OxygenClient::ProcPointInfo;
stat1Value->m_Ref = this;
stat1Value->isNeedDel = false;
Command* pValue1 = new ReadModbus(i, 0x09D0, 2);
pValue1->m_Fun = &OxygenClient::PorcConcentrationValue;
pValue1->m_Ref = this;
pValue1->isNeedDel = false;
Command* ptempValue1 = new ReadModbus(i, 0x0A07, 2);
ptempValue1->m_Fun = &OxygenClient::ProcTempInfo;
ptempValue1->m_Ref = this;
ptempValue1->isNeedDel = false;
m_CycleCommands.push_back(stat1Value);
m_CycleCommands.push_back(pValue1);
m_CycleCommands.push_back(ptempValue1);
}break;
case ExtCfg::HT: {
Command* pPointInfo = new ReadModbus(i, 0x02, 2);
pPointInfo->m_Fun = &OxygenClient::PorcOxygenValue;
pPointInfo->m_Ref = this;
pPointInfo->isNeedDel = false;
m_CycleCommands.push_back(pPointInfo);
}break;
}
}
for (size_t i = 0; i < m_CycleCommands.size(); i++)
{
ReadModbus* command = (ReadModbus*)m_CycleCommands[i];
if (command->m_addr == 4)
{
//m_PurifierOxygenCommands.push_back(command);
if (!m_ExtCfg->m_HasCleanBoxOxygenSensor)
{
command->isNeedSend = false;
command->isNeedRead = false;
}
}
}
}
void OxygenClient::ProcPointInfo(void* pobject, Command* pcommand)
{
if (pobject == NULL)return;
OxygenClient* pOD = (OxygenClient*)pobject;
unsigned char* rseq = pcommand->m_RespSeq;
unsigned char addr = rseq[0];
unsigned short pointindex = ((rseq[3] & 0xff) << 8) + (rseq[4] & 0xff);
unsigned short unit = ((rseq[5] & 0xff) << 8) + (rseq[6] & 0xff);
int scale = 1;
for (unsigned short i = 0; i < pointindex; i++) {
scale *= 10;
}
if (pOD->m_Oxygens.find(addr) == pOD->m_Oxygens.end())return;
Oxygenstat* stat = pOD->m_Oxygens[addr];
EnterCriticalSection(&pOD->m_ValueCS);
stat->scale->SetValue(scale);
switch (unit) {
case 0:stat->valueUnit ->SetValue("PPM"); break;
case 1:stat->valueUnit->SetValue("VOL"); break;
case 2:stat->valueUnit->SetValue("LEL"); break;
}
LeaveCriticalSection(&pOD->m_ValueCS);
}
void OxygenClient::PorcConcentrationValue(void* pobject, Command* pcommand)
{
if (pobject == NULL)return;
OxygenClient* pOD = (OxygenClient*)pobject;
unsigned char* rseq = pcommand->m_RespSeq;
unsigned char addr = rseq[0];
unsigned int concentrationValue = (((rseq[3] & 0xff) << 24) + ((rseq[4] & 0xff) << 16) + ((rseq[5] & 0xff) << 8) + (rseq[6] & 0xff));
if (pOD->m_Oxygens.find(addr) == pOD->m_Oxygens.end())return;
Oxygenstat* stat = pOD->m_Oxygens[addr];
if (stat->scale == 0)return;
EnterCriticalSection(&pOD->m_ValueCS);
stat->concentrationValue->SetValue((float)concentrationValue / stat->scale->GetValue());
LeaveCriticalSection(&pOD->m_ValueCS);
}
void OxygenClient::ProcTempInfo(void* pobject, Command* pcommand)
{
if (pobject == NULL)return;
OxygenClient* pOD = (OxygenClient*)pobject;
unsigned char* rseq = pcommand->m_RespSeq;
unsigned char addr = rseq[0];
short tempValue = (((rseq[3] & 0xff) << 8) + (rseq[4] & 0xff));
unsigned short humidityValue = ((rseq[5] & 0xff) << 8) + (rseq[6] & 0xff);
if (pOD->m_Oxygens.find(addr) == pOD->m_Oxygens.end())return;
Oxygenstat* stat = pOD->m_Oxygens[addr];
EnterCriticalSection(&pOD->m_ValueCS);
stat->tempValue->SetValue((float)tempValue / 10.0f);
stat->humidityValue->SetValue((float)humidityValue / 100.0f);
LeaveCriticalSection(&pOD->m_ValueCS);
}
void OxygenClient::ServerDisconnectProc() {
EnterCriticalSection(&m_ValueCS);
for (auto& chiller : m_Oxygens) {
chiller.second->baseStat.isConnected = false;
}
LeaveCriticalSection(&m_ValueCS);
}
void OxygenClient::WriteSuccessProc(int wlength, unsigned char* buffer, Command* pcommand)
{
Modbus* command = (Modbus*)pcommand;
unsigned char addr = command->m_addr;
if (m_Oxygens.find(addr) == m_Oxygens.end())return;
EnterCriticalSection(&m_ValueCS);
m_Oxygens[addr]->baseStat.writeTimeoutFlag = 0;
LeaveCriticalSection(&m_ValueCS);
}
void OxygenClient::WriteTimeoutProc(Command* pcommand)
{
Modbus* command = (Modbus*)pcommand;
unsigned char addr = command->m_addr;
if (m_Oxygens.find(addr) == m_Oxygens.end())return;
EnterCriticalSection(&m_ValueCS);
Oxygenstat* oxygen = m_Oxygens[addr];
oxygen->baseStat.writeTimeoutFlag++;
if (oxygen->baseStat.writeTimeoutFlag >= m_Config->m_AlarmTimeoutTimes) {
oxygen->baseStat.isConnected = false;
}
LeaveCriticalSection(&m_ValueCS);
}
void OxygenClient::ReadTimeoutProc(Command* pcommand)
{
Modbus* command = (Modbus*)pcommand;
unsigned char addr = command->m_addr;
if (m_Oxygens.find(addr) == m_Oxygens.end())return;
EnterCriticalSection(&m_ValueCS);
Oxygenstat* oxygen = m_Oxygens[addr];
oxygen->baseStat.readTimeoutFlag++;
if (oxygen->baseStat.readTimeoutFlag >= m_Config->m_AlarmTimeoutTimes) {
oxygen->baseStat.isConnected = false;
}
LeaveCriticalSection(&m_ValueCS);
}
void OxygenClient::ReadSuccessProc(int rlength, unsigned char* buffer, Command* pcommand)
{
Modbus* command = (Modbus*)pcommand;
unsigned char addr = command->m_addr;
if (m_Oxygens.find(addr) == m_Oxygens.end())return;
EnterCriticalSection(&m_ValueCS);
Oxygenstat* oxygen = m_Oxygens[addr];
oxygen->baseStat.readTimeoutFlag = 0;
oxygen->baseStat.isConnected = true;
LeaveCriticalSection(&m_ValueCS);
}
void OxygenClient::GetOxygenStat(unsigned char addr, Oxygenstat& stat)
{
if (m_Oxygens.find(addr) == m_Oxygens.end())return;
Oxygenstat* oxygenstat =m_Oxygens[addr];
EnterCriticalSection(&m_ValueCS);
stat.baseStat = oxygenstat->baseStat;
stat.concentrationValue= oxygenstat->concentrationValue;
stat.valueUnit= oxygenstat->valueUnit;
stat.scale= oxygenstat->scale;
stat.tempValue= oxygenstat->tempValue;
stat.humidityValue= oxygenstat->humidityValue;
LeaveCriticalSection(&m_ValueCS);
}
void OxygenClient::GetOxygenStat(Oxygenstat& stat1, Oxygenstat& stat2, Oxygenstat& stat3)
{
EnterCriticalSection(&m_ValueCS);
Oxygenstat* oxygen1=m_Oxygens[1];
Oxygenstat* oxygen2 = m_Oxygens[2];
Oxygenstat* outside = m_Oxygens[3];
stat1.baseStat = oxygen1->baseStat;
stat1.concentrationValue = oxygen1->concentrationValue;
stat1.valueUnit = oxygen1->valueUnit;
stat1.scale = oxygen1->scale;
stat1.tempValue = oxygen1->tempValue;
stat1.humidityValue = oxygen1->humidityValue;
stat2.baseStat = oxygen2->baseStat;
stat2.concentrationValue = oxygen2->concentrationValue;
stat2.valueUnit = oxygen2->valueUnit;
stat2.scale = oxygen2->scale;
stat2.tempValue = oxygen2->tempValue;
stat2.humidityValue = oxygen2->humidityValue;
stat3.baseStat = outside->baseStat;
stat3.concentrationValue = outside->concentrationValue;
stat3.valueUnit = outside->valueUnit;
stat3.scale = outside->scale;
stat3.tempValue = outside->tempValue;
stat3.humidityValue = outside->humidityValue;
LeaveCriticalSection(&m_ValueCS);
}
void OxygenClient::PorcOxygenValue(void* pobject, Command* pcommand)
{
if (pobject == NULL)return;
OxygenClient* pOD = (OxygenClient*)pobject;
unsigned char* rseq = pcommand->m_RespSeq;
unsigned char addr = rseq[0];
if (pOD->m_Oxygens.find(addr) == pOD->m_Oxygens.end())return;
int value = ((rseq[3] & 0xff) << 24) + ((rseq[4] & 0xff) << 16) + ((rseq[5] & 0xff) << 8) + (rseq[6] & 0xff);
EnterCriticalSection(&pOD->m_ValueCS);
pOD->m_Oxygens[addr]->concentrationValue->SetValue((float)value / 100.0f);
LeaveCriticalSection(&pOD->m_ValueCS);
}
void OxygenClient::ProcNewVersion(void* pobject, Command* pcommand)
{
if (pobject == NULL)return;
OxygenClient* pOD = (OxygenClient*)pobject;
unsigned char* rseq = pcommand->m_RespSeq;
unsigned char addr = rseq[0];
if (pOD->m_Oxygens.find(addr) == pOD->m_Oxygens.end())return;
unsigned char pointindex = rseq[4];
unsigned short unit = ((rseq[5] & 0xff) << 8) + (rseq[6] & 0xff);
unsigned int concentrationValue = (((rseq[7] & 0xff) << 24) + ((rseq[8] & 0xff) << 16) + ((rseq[9] & 0xff) << 8) + (rseq[10] & 0xff));
unsigned int concentrationAgValue = (((rseq[11] & 0xff) << 24) + ((rseq[12] & 0xff) << 16) + ((rseq[13] & 0xff) << 8) + (rseq[14] & 0xff));
//unsigned short alarm = ((rseq[15] & 0xff) << 8) + (rseq[16] & 0xff);
//unsigned int concentrationRangeValue = (((rseq[17] & 0xff) << 24) + ((rseq[18] & 0xff) << 16) + ((rseq[19] & 0xff) << 8) + (rseq[20] & 0xff));
short tempValue = (((rseq[21] & 0xff) << 8) + (rseq[22] & 0xff));
unsigned short humidityValue = ((rseq[23] & 0xff) << 8) + (rseq[24] & 0xff);
int scale = 1;
for (unsigned char i = 0; i < pointindex; i++) {
scale *= 10;
}
Oxygenstat* stat = pOD->m_Oxygens[addr];
EnterCriticalSection(&pOD->m_ValueCS);
stat->scale->SetValue(scale);
switch (unit) {
case 0:stat->valueUnit->SetValue("PPM"); break;
case 1:stat->valueUnit->SetValue("VOL"); break;
case 2:stat->valueUnit->SetValue("LEL"); break;
}
if(stat->scale!=0)stat->concentrationValue->SetValue((float)concentrationValue / stat->scale->GetValue());
else stat->concentrationValue->SetValue((float)concentrationValue);
stat->concentrationAgValue->SetValue(concentrationAgValue);
stat->tempValue->SetValue((float)tempValue / 10.0f);
stat->humidityValue->SetValue((float)humidityValue / 1000.0f);
LeaveCriticalSection(&pOD->m_ValueCS);
}