GrpcPrint/PrintS/Communication/PowerMeterClient.cpp
2024-05-28 13:28:07 +08:00

308 lines
10 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "PowerMeterClient.h"
#include "Modbus.h"
#include "../utils/DataByte.h"
#include "../external/imgui/imgui_custom.h"
#include "../LanguageManager.h"
#include "../config/ConfigManager.h"
#include "../PLC/SignalService.h"
PowerMeterClient::PowerMeterClient(CommunicationCfg* pconfig):TcpClient(pconfig)
{
m_RunCfg = ConfigManager::GetInstance()->GetRunCfg();
m_AlarmCfgWrapper = ConfigManager::GetInstance()->GetAlarmCfg();
size_t ptrSize = sizeof(nullptr); //指针大小
void* startPtr = &m_State.m_startFlag + 1;
size_t count = ((size_t)&m_State.m_endFlag - (size_t)startPtr) / ptrSize;
InsertMp(startPtr, count);
}
PowerMeterClient::~PowerMeterClient()
{
Shutdown();
}
void PowerMeterClient::InitCommand()
{
Command* pUnit = new ReadModbus(m_Config->m_Addr, 0x0006, 2);
pUnit->m_Fun = &PowerMeterClient::ProcUnitValue;
pUnit->m_Ref = this;
pUnit->isNeedDel = false;
Command* pPowerInfo = new ReadModbus(m_Config->m_Addr, 0x101E, 22);
pPowerInfo->m_Fun = &PowerMeterClient::PorcPowerValue;
pPowerInfo->m_Ref = this;
pPowerInfo->isNeedDel = false;
Command* pPowerInfo2 = new ReadModbus(m_Config->m_Addr, 0x103C, 22);
pPowerInfo2->m_Fun = &PowerMeterClient::PorcPowerValue2;
pPowerInfo2->m_Ref = this;
pPowerInfo2->isNeedDel = false;
Command* pVoltageInfo = new ReadModbus(m_Config->m_Addr, 0x2000, 34);
pVoltageInfo->m_Fun = &PowerMeterClient::PorcVoltageValue;
pVoltageInfo->m_Ref = this;
pVoltageInfo->isNeedDel = false;
Command* pVoltageInfo2 = new ReadModbus(m_Config->m_Addr, 0x202A, 28);
pVoltageInfo2->m_Fun = &PowerMeterClient::PorcVoltageValue2;
pVoltageInfo2->m_Ref = this;
pVoltageInfo2->isNeedDel = false;
m_CycleCommands.push_back(pUnit);
m_CycleCommands.push_back(pPowerInfo);
m_CycleCommands.push_back(pPowerInfo2);
m_CycleCommands.push_back(pVoltageInfo);
m_CycleCommands.push_back(pVoltageInfo2);
}
void PowerMeterClient::ResetElec()
{
short realvalue = 1;
WriteModbus* pSet = new WriteModbus(m_Config->m_Addr, 0x02);
pSet->AddShort(realvalue);
pSet->m_Ref = this;
EnterCriticalSection(&m_RtcCS);
m_RTCommands.push(pSet);
LeaveCriticalSection(&m_RtcCS);
}
void PowerMeterClient::ProcUnitValue(void* pobject, Command* pcommand)
{
if (pobject == NULL)return;
PowerMeterClient* pmc = (PowerMeterClient*)pobject;
unsigned char* rseq = pcommand->m_RespSeq;
EnterCriticalSection(&pmc->m_ValueCS);
pmc->m_State.irAt ->SetValue((float) ((rseq[3] & 0xff) << 8) + (rseq[4] & 0xff));
pmc->m_State.urAt->SetValue((((rseq[5] & 0xff) << 8) + (rseq[6] & 0xff)) * 0.1f);
LeaveCriticalSection(&pmc->m_ValueCS);
}
void PowerMeterClient::PorcPowerValue(void* pobject, Command* pcommand)
{
if (pobject == NULL)return;
PowerMeterClient* pmc = (PowerMeterClient*)pobject;
unsigned char* rseq = pcommand->m_RespSeq;
FLOATDATA impEp, expEp, q1Eq;
impEp.Desc(&rseq[3]);
expEp.Desc(&rseq[23]);
q1Eq.Desc(&rseq[43]);
EnterCriticalSection(&pmc->m_ValueCS);
float urat = pmc->m_State.urAt->GetValue(), irat = pmc->m_State.irAt->GetValue();
pmc->m_State.impEp->SetValue(impEp.fValue * urat * irat);
pmc->m_State.expEp->SetValue(expEp.fValue * urat * irat);
pmc->m_State.q1Eq->SetValue(q1Eq.fValue * urat * irat);
LeaveCriticalSection(&pmc->m_ValueCS);
}
void PowerMeterClient::PorcPowerValue2(void* pobject, Command* pcommand)
{
if (pobject == NULL)return;
PowerMeterClient* pmc = (PowerMeterClient*)pobject;
unsigned char* rseq = pcommand->m_RespSeq;
FLOATDATA q2Eq, q3Eq, q4Eq;
q2Eq.Desc(&rseq[3]);
q3Eq.Desc(&rseq[23]);
q4Eq.Desc(&rseq[43]);
EnterCriticalSection(&pmc->m_ValueCS);
float urat = pmc->m_State.urAt->GetValue(), irat = pmc->m_State.irAt->GetValue();
pmc->m_State.q2Eq->SetValue(q2Eq.fValue * urat * irat);
pmc->m_State.q3Eq->SetValue(q3Eq.fValue * urat * irat);
pmc->m_State.q4Eq->SetValue(q4Eq.fValue * urat * irat);
LeaveCriticalSection(&pmc->m_ValueCS);
}
void PowerMeterClient::PorcVoltageValue(void* pobject, Command* pcommand)
{
if (pobject == NULL)return;
PowerMeterClient* pmc = (PowerMeterClient*)pobject;
unsigned char* rseq = pcommand->m_RespSeq;
FLOATDATA uab, ubc, uca;
FLOATDATA ua, ub, uc;
FLOATDATA ia, ib, ic;
FLOATDATA pt, pa, pb, pc;
FLOATDATA qt, qa, qb, qc;
int flag = 3;
uab.Desc(&rseq[flag]);
ubc.Desc(&rseq[flag += 4]);
uca.Desc(&rseq[flag += 4]);
ua.Desc(&rseq[flag += 4]);
ub.Desc(&rseq[flag += 4]);
uc.Desc(&rseq[flag += 4]);
ia.Desc(&rseq[flag += 4]);
ib.Desc(&rseq[flag += 4]);
ic.Desc(&rseq[flag += 4]);
pt.Desc(&rseq[flag += 4]);
pa.Desc(&rseq[flag += 4]);
pb.Desc(&rseq[flag += 4]);
pc.Desc(&rseq[flag += 4]);
qt.Desc(&rseq[flag += 4]);
qa.Desc(&rseq[flag += 4]);
qb.Desc(&rseq[flag += 4]);
qc.Desc(&rseq[flag += 4]);
EnterCriticalSection(&pmc->m_ValueCS); //wxxtest
float urat = pmc->m_State.urAt->GetValue();
float irat = pmc->m_State.irAt->GetValue();
float t_uab = uab.fValue * urat * 0.1f;
float t_ubc = ubc.fValue * urat * 0.1f;
float t_uca = uca.fValue * urat * 0.1f;
pmc->m_State.uab->SetValue(t_uab);
pmc->m_State.ubc->SetValue(t_ubc);
pmc->m_State.uca->SetValue(t_uca);
pmc->m_State.ua->SetValue(ua.fValue * urat * 0.1f);
pmc->m_State.ub->SetValue(ub.fValue * urat * 0.1f);
pmc->m_State.uc->SetValue(uc.fValue * urat * 0.1f);
pmc->m_State.ia->SetValue(ia.fValue * irat * 0.001f);
pmc->m_State.ib->SetValue(ib.fValue * irat * 0.001f);
pmc->m_State.ic->SetValue(ic.fValue * irat * 0.001f);
pmc->m_State.pt->SetValue(pt.fValue * urat * irat * 0.1f);
pmc->m_State.pa->SetValue(pa.fValue * urat * irat * 0.1f);
pmc->m_State.pb->SetValue(pb.fValue * urat * irat * 0.1f);
pmc->m_State.pc->SetValue(pc.fValue * urat * irat * 0.1f);
pmc->m_State.qt->SetValue(qt.fValue * urat * irat * 0.1f);
pmc->m_State.qa->SetValue(qa.fValue * urat * irat * 0.1f);
pmc->m_State.qb->SetValue(qb.fValue * urat * irat * 0.1f);
pmc->m_State.qc->SetValue(qc.fValue * urat * irat * 0.1f);
LeaveCriticalSection(&pmc->m_ValueCS);
float umin = (float)380.0 * (1.0f - pmc->m_RunCfg->m_VoltageAlarmOffset->GetValue() / 100.0f);
float umax = (float)380.0 * (1.0f + pmc->m_RunCfg->m_VoltageAlarmOffset->GetValue() / 100.0f);
SignalService& alarmService = SignalService::GetInstance();
//pmc->m_AlarmCfgWrapper->Lock();
if ((t_uab<umin || t_uab>umax) || (t_ubc<umin || t_ubc>umax) || (t_uca<umin || t_uca>umax)) {
if (pmc->m_AlarmCfgWrapper->m_VoltageAlarm)alarmService.SetAlarm(pmc->m_AlarmCfgWrapper->m_VoltageAlarm, true);
}
else {
if (pmc->m_AlarmCfgWrapper->m_VoltageAlarm)alarmService.SetAlarm(pmc->m_AlarmCfgWrapper->m_VoltageAlarm, false);
}
//pmc->m_AlarmCfgWrapper->UnLock();
}
void PowerMeterClient::PorcVoltageValue2(void* pobject, Command* pcommand)
{
if (pobject == NULL)return;
PowerMeterClient* pmc = (PowerMeterClient*)pobject;
unsigned char* rseq = pcommand->m_RespSeq;
FLOATDATA pft, pfa, pfb, pfc;
FLOATDATA freq;
int flag = 3;
pft.Desc(&rseq[flag]);
pfa.Desc(&rseq[flag += 4]);
pfb.Desc(&rseq[flag += 4]);
pfc.Desc(&rseq[flag += 4]);
freq.Desc(&rseq[55]);
EnterCriticalSection(&pmc->m_ValueCS);
pmc->m_State.pft->SetValue(pft.fValue * 0.001f);
pmc->m_State.pfa->SetValue(pfa.fValue * 0.001f);
pmc->m_State.pfb->SetValue(pfb.fValue * 0.001f);
pmc->m_State.pfc->SetValue(pfc.fValue * 0.001f);
pmc->m_State.freq->SetValue(freq.fValue * 0.01f);
LeaveCriticalSection(&pmc->m_ValueCS);
}
void PowerMeterClient::GetState(PowerStat& stat)
{
EnterCriticalSection(&m_ValueCS);
memcpy_s(&stat,sizeof(stat), &m_State,sizeof(m_State));
LeaveCriticalSection(&m_ValueCS);
}
//void PowerMeterClient::DrawUI(bool* isshow)
//{
// ImGui::Begin(_(u8"电能质量").c_str(), isshow, ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoNav);
// PowerStat ps;
// GetState(ps);
//
// ImGui::BeginGroup();
// if (IsServerConnected()) {
// ImGui::TextColored(ImVec4(0.0, 1.0, 0.0, 1.0), _(u8"端口连接:正常").c_str());
// }
// else {
// ImGui::TextColored(ImVec4(1.0, 0.0, 0.0, 1.0), _(u8"端口连接:断开").c_str());
// }
// if (IsComConnected()) {
// ImGui::TextColored(ImVec4(0.0, 1.0, 0.0, 1.0), _(u8"通讯连接:正常").c_str());
// }
// else {
// ImGui::TextColored(ImVec4(1.0, 0.0, 0.0, 1.0), _(u8"通讯连接:断开").c_str());
// }
//
// ImGui::Dummy(ImVec2(0, 10));
// ImGui::Text(_(u8"AB线电压%.1f V").c_str(), ps.uab);
// ImGui::Text(_(u8"BC线电压%.1f V").c_str(), ps.ubc);
// ImGui::Text(_(u8"CA线电压%.1f V").c_str(), ps.uca);
// ImGui::Dummy(ImVec2(0, 10));
// ImGui::Text(_(u8"A相电压%.1f V").c_str(), ps.ua);
// ImGui::Text(_(u8"B相电压%.1f V").c_str(), ps.ub);
// ImGui::Text(_(u8"C相电压%.1f V").c_str(), ps.uc);
// ImGui::Dummy(ImVec2(0, 10));
// ImGui::Text(_(u8"A相电流%.3f A").c_str(), ps.ia);
// ImGui::Text(_(u8"B相电流%.3f A").c_str(), ps.ib);
// ImGui::Text(_(u8"C相电流%.3f A").c_str(), ps.ic);
// ImGui::EndGroup();
//
// ImGui::SameLine();
// ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
// ImGui::SameLine();
//
// ImGui::BeginGroup();
// ImGui::Text(_(u8"总有功功率:%.1f W").c_str(), ps.pt);
// ImGui::Text(_(u8"A相有功功率%.1f W").c_str(), ps.pa);
// ImGui::Text(_(u8"B相有功功率%.1f W").c_str(), ps.pb);
// ImGui::Text(_(u8"C相有功功率%.1f W").c_str(), ps.pc);
// ImGui::Dummy(ImVec2(0, 10));
// ImGui::Text(_(u8"总无功功率:%.1f var").c_str(), ps.qt);
// ImGui::Text(_(u8"A相无功功率%.1f var").c_str(), ps.qa);
// ImGui::Text(_(u8"B相无功功率%.1f var").c_str(), ps.qb);
// ImGui::Text(_(u8"C相无功功率%.1f var").c_str(), ps.qc);
// ImGui::EndGroup();
//
// ImGui::SameLine();
// ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
// ImGui::SameLine();
//
// ImGui::BeginGroup();
// ImGui::Text(_(u8"总功率因数:%.3f").c_str(), ps.pft);
// ImGui::Text(_(u8"A相功率因数%.3f").c_str(), ps.pfa);
// ImGui::Text(_(u8"B相功率因数%.3f").c_str(), ps.pfb);
// ImGui::Text(_(u8"C相功率因数%.3f").c_str(), ps.pfc);
// ImGui::Dummy(ImVec2(0, 10));
// ImGui::Text(_(u8"频率:%.2f Hz").c_str(), ps.freq);
// ImGui::Dummy(ImVec2(0, 10));
// ImGui::Text(_(u8"正向有功总电能:%.2f kWh").c_str(), ps.impEp);
// ImGui::Text(_(u8"反向有功总电能:%.2f kWh").c_str(), ps.expEp);
// ImGui::Text(_(u8"第一象限无功总电能:%.2f kvarh").c_str(), ps.q1Eq);
// ImGui::Text(_(u8"第二象限无功总电能:%.2f kvarh").c_str(), ps.q2Eq);
// ImGui::Text(_(u8"第三象限无功总电能:%.2f kvarh").c_str(), ps.q3Eq);
// ImGui::Text(_(u8"第四象限无功总电能:%.2f kvarh").c_str(), ps.q4Eq);
//
// if (ImGui::Button(_(u8"电能清零").c_str()))
// {
// ResetElec();
// }
// ImGui::EndGroup();
//
// ImGui::End();
//}