增加部分状态显示
This commit is contained in:
@@ -37,6 +37,8 @@ PowerManger::PowerManger()
|
|||||||
m_leakage = 0;
|
m_leakage = 0;
|
||||||
faultCode.clear();
|
faultCode.clear();
|
||||||
|
|
||||||
|
m_skew = 2;
|
||||||
|
|
||||||
m_pmCurrentState = {};
|
m_pmCurrentState = {};
|
||||||
m_currentDisBreakerState = {};
|
m_currentDisBreakerState = {};
|
||||||
m_targetDisBreakerState = {};
|
m_targetDisBreakerState = {};
|
||||||
@@ -92,6 +94,13 @@ bool PowerManger::OnNewMail(MOOSMSG_LIST &NewMail)
|
|||||||
CMOOSMsg &msg = *p;
|
CMOOSMsg &msg = *p;
|
||||||
string key = msg.GetKey();
|
string key = msg.GetKey();
|
||||||
string strJson = msg.GetString();
|
string strJson = msg.GetString();
|
||||||
|
double dfT;
|
||||||
|
msg.IsSkewed(m_curr_time, &dfT);
|
||||||
|
if(fabs(dfT) > m_skew)
|
||||||
|
{
|
||||||
|
LOG_F(INFO, "Message from %s at time %f is Skewed", msg.GetSource().c_str(), dfT);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
//处理上位机发送的控制指令
|
//处理上位机发送的控制指令
|
||||||
if(!m_upperCommManager->processUpperMsg(key,strJson))
|
if(!m_upperCommManager->processUpperMsg(key,strJson))
|
||||||
{
|
{
|
||||||
@@ -134,7 +143,7 @@ bool PowerManger::OnConnectToServer()
|
|||||||
bool PowerManger::Iterate()
|
bool PowerManger::Iterate()
|
||||||
{
|
{
|
||||||
AppCastingMOOSApp::Iterate();
|
AppCastingMOOSApp::Iterate();
|
||||||
// 打印当前状态
|
// 触发定时任务
|
||||||
CycleTriggeredEvent cycleEvent;
|
CycleTriggeredEvent cycleEvent;
|
||||||
PowerManagerFsm::dispatch(cycleEvent);
|
PowerManagerFsm::dispatch(cycleEvent);
|
||||||
faultLevel = getFaultLevel();
|
faultLevel = getFaultLevel();
|
||||||
@@ -150,6 +159,8 @@ bool PowerManger::Iterate()
|
|||||||
m_systemData->device_common_status.dis_lv_c1.lastUpdateTime = m_lowerCommManager->msg_disHighBVolBusFbMsg_Update_time;
|
m_systemData->device_common_status.dis_lv_c1.lastUpdateTime = m_lowerCommManager->msg_disHighBVolBusFbMsg_Update_time;
|
||||||
m_systemData->device_common_status.dis_lv_c2.lastUpdateTime = m_lowerCommManager->msg_disLowBusFbMsg_Update_time;
|
m_systemData->device_common_status.dis_lv_c2.lastUpdateTime = m_lowerCommManager->msg_disLowBusFbMsg_Update_time;
|
||||||
m_systemData->updateCommonStatus();
|
m_systemData->updateCommonStatus();
|
||||||
|
// 运行状态
|
||||||
|
|
||||||
if (m_ticker++ % 5 == 0)
|
if (m_ticker++ % 5 == 0)
|
||||||
{
|
{
|
||||||
m_CcuColCmd.heartbeat++;
|
m_CcuColCmd.heartbeat++;
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ class PowerManger : public AppCastingMOOSApp
|
|||||||
unsigned int m_nSendBufferSizeKB;
|
unsigned int m_nSendBufferSizeKB;
|
||||||
double m_current_time;
|
double m_current_time;
|
||||||
unsigned int m_ticker;
|
unsigned int m_ticker;
|
||||||
|
double m_skew;
|
||||||
int connectState;
|
int connectState;
|
||||||
//=============================过程函数======================================
|
//=============================过程函数======================================
|
||||||
void initControlCmd();
|
void initControlCmd();
|
||||||
@@ -138,6 +139,9 @@ class PowerManger : public AppCastingMOOSApp
|
|||||||
double GetPublicCPULoad() { return GetCPULoad(); }
|
double GetPublicCPULoad() { return GetCPULoad(); }
|
||||||
double GetPublicTimeSinceIterate() { return GetTimeSinceIterate(); }
|
double GetPublicTimeSinceIterate() { return GetTimeSinceIterate(); }
|
||||||
double GetPublicLastIterateTime() { return GetLastIterateTime(); }
|
double GetPublicLastIterateTime() { return GetLastIterateTime(); }
|
||||||
|
int GetPublicIterateCount() { return GetIterateCount(); }
|
||||||
|
string GetServerHost() { return m_sServerHost; }
|
||||||
|
int GetServerPort() { return m_lServerPort; }
|
||||||
public:
|
public:
|
||||||
//故障注入
|
//故障注入
|
||||||
void injectFault(unsigned type,unsigned int faultCode);
|
void injectFault(unsigned type,unsigned int faultCode);
|
||||||
|
|||||||
@@ -27,8 +27,9 @@ bool UpperCommManager::processUpperMsg(const string& key, const string& strJson)
|
|||||||
{
|
{
|
||||||
m_pm->m_MSDriverCmd = m_equStateMsg.getEquipmentCmd(key, strJson);
|
m_pm->m_MSDriverCmd = m_equStateMsg.getEquipmentCmd(key, strJson);
|
||||||
vector<DriverCommand> devCmdExt = m_pm->m_driver.loadDriverIdFromJson(strJson);
|
vector<DriverCommand> devCmdExt = m_pm->m_driver.loadDriverIdFromJson(strJson);
|
||||||
if (devCmdExt.empty()) {
|
if (devCmdExt.empty())
|
||||||
LOG_F(WARNING, "控制指令");
|
{
|
||||||
|
LOG_F(WARNING, "控制指令为空");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (auto& cmd : devCmdExt) {
|
for (auto& cmd : devCmdExt) {
|
||||||
@@ -36,6 +37,7 @@ bool UpperCommManager::processUpperMsg(const string& key, const string& strJson)
|
|||||||
PowerManagerFsm::dispatch(event);
|
PowerManagerFsm::dispatch(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
// 次级配电状态处理
|
// 次级配电状态处理
|
||||||
else if(key == m_secdistStateMsg.key_fb)
|
else if(key == m_secdistStateMsg.key_fb)
|
||||||
|
|||||||
+23
-83
@@ -675,7 +675,7 @@ std::string Driver::saveDriverTableToJson(const DriverTable* driverTable)
|
|||||||
root["ctd1_uint8"] = driverTable->ctd1;
|
root["ctd1_uint8"] = driverTable->ctd1;
|
||||||
root["ctd2_uint8"] = driverTable->ctd2;
|
root["ctd2_uint8"] = driverTable->ctd2;
|
||||||
root["soundVeloc_uint8"] = driverTable->soundVeloc;
|
root["soundVeloc_uint8"] = driverTable->soundVeloc;
|
||||||
root["commMast_uint8"] = driverTable->commMast;
|
root["commDev_uint8"] = driverTable->commMast;
|
||||||
root["ins_uint8"] = driverTable->ins;
|
root["ins_uint8"] = driverTable->ins;
|
||||||
root["ntp_uint8"] = driverTable->ntp;
|
root["ntp_uint8"] = driverTable->ntp;
|
||||||
root["inputWaterSensor1_uint8"] = driverTable->inputWaterSensor1;
|
root["inputWaterSensor1_uint8"] = driverTable->inputWaterSensor1;
|
||||||
@@ -750,7 +750,7 @@ std::string Driver::getDriveStateJson(const DriverTable* driverTable)
|
|||||||
|
|
||||||
int Driver::SafeReadUInt(const Json::Value& root, const std::string& key, unsigned char& value) {
|
int Driver::SafeReadUInt(const Json::Value& root, const std::string& key, unsigned char& value) {
|
||||||
if (!root.isMember(key)) {
|
if (!root.isMember(key)) {
|
||||||
std::cerr << "错误: 缺少字段 " << key << std::endl;
|
// std::cerr << "错误: 缺少字段 " << key << std::endl;
|
||||||
return -1; // 返回-1表示缺少字段
|
return -1; // 返回-1表示缺少字段
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -777,27 +777,27 @@ vector<DriverCommand> Driver::loadDriverIdFromJson(const std::string &strJson) {
|
|||||||
}
|
}
|
||||||
// 设备字段名到ID的映射
|
// 设备字段名到ID的映射
|
||||||
const std::map<std::string, int> fieldToId = {
|
const std::map<std::string, int> fieldToId = {
|
||||||
{"depth1", 18}, {"depth2", 19}, {"depth3", 20},
|
{"depth1_uint8", 18}, {"depth2_uint8", 19}, {"depth3_uint8", 20},
|
||||||
{"overDeep1", 21}, {"overDeep2", 22},
|
{"overDeep1_uint8", 21}, {"overDeep2_uint8", 22},
|
||||||
{"ctd1", 23}, {"ctd2", 24}, {"soundVeloc", 25},
|
{"ctd1_uint8", 23}, {"ctd2_uint8", 24}, {"soundVeloc_uint8", 25},
|
||||||
{"commMast", 40}, {"ins", 57}, {"ntp", 58},
|
{"commDev_uint8", 40}, {"ins_uint8", 57}, {"ntp_uint8", 58},
|
||||||
{"inputWaterSensor1", 59}, {"inputWaterSensor2", 60}, {"inputWaterSensor3", 61},
|
{"inputWaterSensor1_uint8", 59}, {"inputWaterSensor2_uint8", 60}, {"inputWaterSensor3_uint8", 61},
|
||||||
{"singleBeamSonar1", 0}, {"singleBeamSonar2", 1}, {"singleBeamSonar3", 2},
|
{"singleBeamSonar1_uint8", 0}, {"singleBeamSonar2_uint8", 1}, {"singleBeamSonar3_uint8", 2},
|
||||||
{"singleBeamSonar4", 3}, {"singleBeamSonar5", 4}, {"singleBeamSonar6", 5},
|
{"singleBeamSonar4_uint8", 3}, {"singleBeamSonar5_uint8", 4}, {"singleBeamSonar6_uint8", 5},
|
||||||
{"singleBeamSonar7", 6}, {"singleBeamSonar8", 7}, {"forwardSonar", 8},
|
{"singleBeamSonar7_uint8", 6}, {"singleBeamSonar8_uint8", 7}, {"forwardSonar_uint8", 8},
|
||||||
{"DVL", 43}, {"lowFreqSonar", 36}, {"USBL", 42},
|
{"DVL_uint8", 43}, {"lowFreqSonar_uint8", 36}, {"USBL_uint8", 42},
|
||||||
{"bowCover1", 9}, {"bowCover2", 10}, {"bowCover3", 11},
|
{"bowCover1_uint8", 9}, {"bowCover2_uint8", 10}, {"bowCover3_uint8", 11},
|
||||||
{"bowCover4", 12}, {"bowCover5", 13}, {"bowCover6", 14},
|
{"bowCover4_uint8", 12}, {"bowCover5_uint8", 13}, {"bowCover6_uint8", 14},
|
||||||
{"bowRudderDeploy", 15}, {"bowRudderServo1", 16}, {"bowRudderServo2", 17},
|
{"bowRudderDeploy_uint8", 15}, {"bowRudderServo1_uint8", 16}, {"bowRudderServo2_uint8", 17},
|
||||||
{"bowWaterInet1", 27}, {"bowWaterInet2", 28}, {"bowWaterInet3", 29},
|
{"bowWaterInet1_uint8", 27}, {"bowWaterInet2_uint8", 28}, {"bowWaterInet3_uint8", 29},
|
||||||
{"bowWaterInet4", 30}, {"bowWaterInet5", 31}, {"bowWaterInet6", 32},
|
{"bowWaterInet4_uint8", 30}, {"bowWaterInet5_uint8", 31}, {"bowWaterInet6_uint8", 32},
|
||||||
{"bowWaterInet7", 33}, {"bowWaterInet8", 34}, {"waterInject", 26},
|
{"bowWaterInet7_uint8", 33}, {"bowWaterInet8_uint8", 34}, {"waterInject_uint8", 26},
|
||||||
{"mastLiftingServo", 41}, {"buoyancyAdjust1", 44}, {"buoyancyAdjust2", 45},
|
{"mastLiftingServo_uint8_uint8", 41}, {"buoyancyAdjust1_uint8", 44}, {"buoyancyAdjust2_uint8", 45},
|
||||||
{"buoyancyAdjust3", 46}, {"buoyancyAdjust4", 47}, {"buoyancyAdjust5", 48},
|
{"buoyancyAdjust3_uint8", 46}, {"buoyancyAdjust4_uint8", 47}, {"buoyancyAdjust5_uint8", 48},
|
||||||
{"sternRudderServo1", 49}, {"sternRudderServo2", 50}, {"sternRudderServo3", 51},
|
{"sternRudderServo1_uint8", 49}, {"sternRudderServo2_uint8", 50}, {"sternRudderServo3_uint8", 51},
|
||||||
{"sternRudderServo4", 52}, {"thruster", 53}, {"bowThrow", 54},
|
{"sternRudderServo4_uint8", 52}, {"thruster_uint8", 53}, {"bowThrow_uint8", 54},
|
||||||
{"sternThrow", 55}, {"photoSensor", 38}, {"electSensor", 39},
|
{"sternThrow_uint8", 55}, {"photoSensor_uint8", 38}, {"electSensor_uint8", 39},
|
||||||
{"launchControler", 37}, {"sideSonar", 35}, {"buoyage", 56}
|
{"launchControler_uint8", 37}, {"sideSonar_uint8", 35}, {"buoyage_uint8", 56}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto& [field, id] : fieldToId) {
|
for (const auto& [field, id] : fieldToId) {
|
||||||
@@ -831,13 +831,10 @@ int Driver::loadDriverTableFromJson(const std::string &strJson, DriverTable& tab
|
|||||||
int error_code = 0;
|
int error_code = 0;
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "depth1_uint8", table.depth1);
|
error_code = SafeReadUInt(root, "depth1_uint8", table.depth1);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "depth2_uint8", table.depth2);
|
error_code = SafeReadUInt(root, "depth2_uint8", table.depth2);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "depth3_uint8", table.depth3);
|
error_code = SafeReadUInt(root, "depth3_uint8", table.depth3);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
// error_code = SafeReadUInt(root, "overDeep1_uint8", table.overDeep1);
|
// error_code = SafeReadUInt(root, "overDeep1_uint8", table.overDeep1);
|
||||||
// if (error_code != 0) return error_code;
|
// if (error_code != 0) return error_code;
|
||||||
@@ -846,178 +843,121 @@ int Driver::loadDriverTableFromJson(const std::string &strJson, DriverTable& tab
|
|||||||
// if (error_code != 0) return error_code;
|
// if (error_code != 0) return error_code;
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "ctd1_uint8", table.ctd1);
|
error_code = SafeReadUInt(root, "ctd1_uint8", table.ctd1);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "ctd2_uint8", table.ctd2);
|
error_code = SafeReadUInt(root, "ctd2_uint8", table.ctd2);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "soundVeloc_uint8", table.soundVeloc);
|
error_code = SafeReadUInt(root, "soundVeloc_uint8", table.soundVeloc);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "commDev_uint8", table.commMast);
|
error_code = SafeReadUInt(root, "commDev_uint8", table.commMast);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "ins_uint8", table.ins);
|
error_code = SafeReadUInt(root, "ins_uint8", table.ins);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "ntp_uint8", table.ntp);
|
error_code = SafeReadUInt(root, "ntp_uint8", table.ntp);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "inputWaterSensor1_uint8", table.inputWaterSensor1);
|
error_code = SafeReadUInt(root, "inputWaterSensor1_uint8", table.inputWaterSensor1);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "inputWaterSensor2_uint8", table.inputWaterSensor2);
|
error_code = SafeReadUInt(root, "inputWaterSensor2_uint8", table.inputWaterSensor2);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "inputWaterSensor3_uint8", table.inputWaterSensor3);
|
error_code = SafeReadUInt(root, "inputWaterSensor3_uint8", table.inputWaterSensor3);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
// 水声设备
|
// 水声设备
|
||||||
error_code = SafeReadUInt(root, "singleBeamSonar1_uint8", table.singleBeamSonar1);
|
error_code = SafeReadUInt(root, "singleBeamSonar1_uint8", table.singleBeamSonar1);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "singleBeamSonar2_uint8", table.singleBeamSonar2);
|
error_code = SafeReadUInt(root, "singleBeamSonar2_uint8", table.singleBeamSonar2);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "singleBeamSonar3_uint8", table.singleBeamSonar3);
|
error_code = SafeReadUInt(root, "singleBeamSonar3_uint8", table.singleBeamSonar3);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "singleBeamSonar4_uint8", table.singleBeamSonar4);
|
error_code = SafeReadUInt(root, "singleBeamSonar4_uint8", table.singleBeamSonar4);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "singleBeamSonar5_uint8", table.singleBeamSonar5);
|
error_code = SafeReadUInt(root, "singleBeamSonar5_uint8", table.singleBeamSonar5);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "singleBeamSonar6_uint8", table.singleBeamSonar6);
|
error_code = SafeReadUInt(root, "singleBeamSonar6_uint8", table.singleBeamSonar6);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "singleBeamSonar7_uint8", table.singleBeamSonar7);
|
error_code = SafeReadUInt(root, "singleBeamSonar7_uint8", table.singleBeamSonar7);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "singleBeamSonar8_uint8", table.singleBeamSonar8);
|
error_code = SafeReadUInt(root, "singleBeamSonar8_uint8", table.singleBeamSonar8);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "forwardSonar_uint8", table.forwardSonar);
|
error_code = SafeReadUInt(root, "forwardSonar_uint8", table.forwardSonar);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "DVL_uint8", table.DVL);
|
error_code = SafeReadUInt(root, "DVL_uint8", table.DVL);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "lowFreqSonar_uint8", table.lowFreqSonar);
|
error_code = SafeReadUInt(root, "lowFreqSonar_uint8", table.lowFreqSonar);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "USBL_uint8", table.USBL);
|
error_code = SafeReadUInt(root, "USBL_uint8", table.USBL);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
// 执行机构
|
// 执行机构
|
||||||
error_code = SafeReadUInt(root, "bowWaterInet1_uint8", table.bowWaterInet1);
|
error_code = SafeReadUInt(root, "bowWaterInet1_uint8", table.bowWaterInet1);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "bowWaterInet2_uint8", table.bowWaterInet2);
|
error_code = SafeReadUInt(root, "bowWaterInet2_uint8", table.bowWaterInet2);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "bowWaterInet3_uint8", table.bowWaterInet3);
|
error_code = SafeReadUInt(root, "bowWaterInet3_uint8", table.bowWaterInet3);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "bowWaterInet4_uint8", table.bowWaterInet4);
|
error_code = SafeReadUInt(root, "bowWaterInet4_uint8", table.bowWaterInet4);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "bowWaterInet5_uint8", table.bowWaterInet5);
|
error_code = SafeReadUInt(root, "bowWaterInet5_uint8", table.bowWaterInet5);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "bowWaterInet6_uint8", table.bowWaterInet6);
|
error_code = SafeReadUInt(root, "bowWaterInet6_uint8", table.bowWaterInet6);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "bowWaterInet7_uint8", table.bowWaterInet7);
|
error_code = SafeReadUInt(root, "bowWaterInet7_uint8", table.bowWaterInet7);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "bowWaterInet8_uint8", table.bowWaterInet8);
|
error_code = SafeReadUInt(root, "bowWaterInet8_uint8", table.bowWaterInet8);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "bowRudderDeploy_uint8", table.bowRudderDeploy);
|
error_code = SafeReadUInt(root, "bowRudderDeploy_uint8", table.bowRudderDeploy);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "bowRudderServo1_uint8", table.bowRudderServo1);
|
error_code = SafeReadUInt(root, "bowRudderServo1_uint8", table.bowRudderServo1);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "bowRudderServo2_uint8", table.bowRudderServo2);
|
error_code = SafeReadUInt(root, "bowRudderServo2_uint8", table.bowRudderServo2);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "bowCover1_uint8", table.bowCover1);
|
error_code = SafeReadUInt(root, "bowCover1_uint8", table.bowCover1);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "bowCover2_uint8", table.bowCover2);
|
error_code = SafeReadUInt(root, "bowCover2_uint8", table.bowCover2);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "bowCover3_uint8", table.bowCover3);
|
error_code = SafeReadUInt(root, "bowCover3_uint8", table.bowCover3);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "bowCover4_uint8", table.bowCover4);
|
error_code = SafeReadUInt(root, "bowCover4_uint8", table.bowCover4);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "bowCover5_uint8", table.bowCover5);
|
error_code = SafeReadUInt(root, "bowCover5_uint8", table.bowCover5);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "bowCover6_uint8", table.bowCover6);
|
error_code = SafeReadUInt(root, "bowCover6_uint8", table.bowCover6);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "waterInject_uint8", table.waterInject);
|
error_code = SafeReadUInt(root, "waterInject_uint8", table.waterInject);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "mastLiftingServo_uint8", table.mastLiftingServo);
|
error_code = SafeReadUInt(root, "mastLiftingServo_uint8", table.mastLiftingServo);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "buoyancyAdjust1_uint8", table.buoyancyAdjust1);
|
error_code = SafeReadUInt(root, "buoyancyAdjust1_uint8", table.buoyancyAdjust1);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "buoyancyAdjust2_uint8", table.buoyancyAdjust2);
|
error_code = SafeReadUInt(root, "buoyancyAdjust2_uint8", table.buoyancyAdjust2);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "buoyancyAdjust3_uint8", table.buoyancyAdjust3);
|
error_code = SafeReadUInt(root, "buoyancyAdjust3_uint8", table.buoyancyAdjust3);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "buoyancyAdjust4_uint8", table.buoyancyAdjust4);
|
error_code = SafeReadUInt(root, "buoyancyAdjust4_uint8", table.buoyancyAdjust4);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "buoyancyAdjust5_uint8", table.buoyancyAdjust5);
|
error_code = SafeReadUInt(root, "buoyancyAdjust5_uint8", table.buoyancyAdjust5);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "sternRudderServo1_uint8", table.sternRudderServo1);
|
error_code = SafeReadUInt(root, "sternRudderServo1_uint8", table.sternRudderServo1);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "sternRudderServo2_uint8", table.sternRudderServo2);
|
error_code = SafeReadUInt(root, "sternRudderServo2_uint8", table.sternRudderServo2);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "sternRudderServo3_uint8", table.sternRudderServo3);
|
error_code = SafeReadUInt(root, "sternRudderServo3_uint8", table.sternRudderServo3);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "sternRudderServo4_uint8", table.sternRudderServo4);
|
error_code = SafeReadUInt(root, "sternRudderServo4_uint8", table.sternRudderServo4);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "thruster_uint8", table.thruster);
|
error_code = SafeReadUInt(root, "thruster_uint8", table.thruster);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "bowThrow_uint8", table.bowThrow);
|
error_code = SafeReadUInt(root, "bowThrow_uint8", table.bowThrow);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "sternThrow_uint8", table.sternThrow);
|
error_code = SafeReadUInt(root, "sternThrow_uint8", table.sternThrow);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
// 负载
|
// 负载
|
||||||
error_code = SafeReadUInt(root, "photoSensor_uint8", table.photoSensor);
|
error_code = SafeReadUInt(root, "photoSensor_uint8", table.photoSensor);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "electSensor_uint8", table.electSensor);
|
error_code = SafeReadUInt(root, "electSensor_uint8", table.electSensor);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "launchControler_uint8", table.launchControler);
|
error_code = SafeReadUInt(root, "launchControler_uint8", table.launchControler);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "sideSonar_uint8", table.sideSonar);
|
error_code = SafeReadUInt(root, "sideSonar_uint8", table.sideSonar);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
error_code = SafeReadUInt(root, "buoyage_uint8", table.buoyage);
|
error_code = SafeReadUInt(root, "buoyage_uint8", table.buoyage);
|
||||||
if (error_code != 0) return error_code;
|
|
||||||
|
|
||||||
return 0; // 返回0表示所有数据成功读取
|
return 0; // 返回0表示所有数据成功读取
|
||||||
}
|
}
|
||||||
@@ -635,7 +635,7 @@ void PowerManagerFsm::react(DevCmdExt const &e) {
|
|||||||
}
|
}
|
||||||
case 22:
|
case 22:
|
||||||
{
|
{
|
||||||
LOG_F(INFO, "DevCmdExt received overDeep1 - id: %d, cmd: %d", e.id, e.cmd);
|
LOG_F(INFO, " - id: %d, cmd: %d", e.id, e.cmd);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
pm->m_currentDriverState.overDeep2 = e.cmd;
|
pm->m_currentDriverState.overDeep2 = e.cmd;
|
||||||
#endif
|
#endif
|
||||||
@@ -1143,7 +1143,7 @@ void PowerManagerFsm::react(DevCmdExt const &e) {
|
|||||||
}
|
}
|
||||||
case 40:
|
case 40:
|
||||||
{
|
{
|
||||||
LOG_F(INFO, "DevCmdExt received overDeep1 - id: %d, cmd: %d", e.id, e.cmd);
|
LOG_F(INFO, "DevCmdExt received commMast - id: %d, cmd: %d", e.id, e.cmd);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
pm->m_currentDriverState.commMast = e.cmd;
|
pm->m_currentDriverState.commMast = e.cmd;
|
||||||
#endif
|
#endif
|
||||||
@@ -1960,8 +1960,8 @@ void PowerManagerFsm::emergencySystemFault(FaultEvent const &e)
|
|||||||
{
|
{
|
||||||
//备注:抛载具有自己的电池
|
//备注:抛载具有自己的电池
|
||||||
LOG_F(INFO, "部分抛载失效");
|
LOG_F(INFO, "部分抛载失效");
|
||||||
pm->faultCode.push_back(0x7102);
|
pm->faultCode.push_back(0x7202);
|
||||||
pm->faultCode.push_back(0x7103);
|
pm->faultCode.push_back(0x7203);
|
||||||
}
|
}
|
||||||
if ((e.injectionFaultCode==2))
|
if ((e.injectionFaultCode==2))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,28 +26,34 @@ void StandbyState::react(MasterCommandEvent const &) {
|
|||||||
|
|
||||||
void StandbyState::react(DevCmdExt const &e)
|
void StandbyState::react(DevCmdExt const &e)
|
||||||
{
|
{
|
||||||
LOG_F(INFO, "StandbyState::react(DevCmdExt const &e)");
|
LOG_F(INFO, "DevCmdExt 执行");
|
||||||
|
cout << "DevCmdExt 执行" << (int)e.id << (int)e.cmd << endl;
|
||||||
|
PowerManagerFsm::react(e);
|
||||||
|
cout << (int) pm->m_subDisSysCmd.commMast << endl;
|
||||||
|
cout << (int) pm->m_subDisSysCmd.mastLiftingServo << endl;
|
||||||
|
cout << "DevCmdExt 执行完成" << (int)e.id << (int)e.cmd << endl;
|
||||||
|
//TODO:屏蔽上电保护
|
||||||
//正常模式下,不允许执行DevCmdExt
|
//正常模式下,不允许执行DevCmdExt
|
||||||
if (pm->currentMod == RunMode::Normal )
|
// if (pm->currentMod == RunMode::Normal )
|
||||||
{
|
// {
|
||||||
LOG_F(INFO, "正常模式下,不允许执行DevCmdExt");
|
// LOG_F(INFO, "正常模式下,不允许执行DevCmdExt");
|
||||||
}
|
// }
|
||||||
else if (pm->currentMod == RunMode::Test)
|
// else if (pm->currentMod == RunMode::Test)
|
||||||
{
|
// {
|
||||||
if(handPowerProtection(e))
|
// if(handPowerProtection(e))
|
||||||
PowerManagerFsm::react(e);
|
// PowerManagerFsm::react(e);
|
||||||
else
|
// else
|
||||||
LOG_F(INFO, "DevCmdExt 执行失败");
|
// LOG_F(INFO, "DevCmdExt 执行失败");
|
||||||
}
|
// }
|
||||||
else if (pm->currentMod == RunMode::Debug)
|
// else if (pm->currentMod == RunMode::Debug)
|
||||||
{
|
// {
|
||||||
LOG_F(INFO, "调试模式下,直接执行DevCmdExt");
|
// LOG_F(INFO, "调试模式下,直接执行DevCmdExt");
|
||||||
PowerManagerFsm::react(e);
|
// PowerManagerFsm::react(e);
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
LOG_F(INFO, "当前模式未知");
|
// LOG_F(INFO, "当前模式未知");
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -86,6 +86,38 @@ void HttpServer::handleWebSocketEvent(struct mg_connection* c, int ev, void* ev_
|
|||||||
// 返回测试页面HTML
|
// 返回测试页面HTML
|
||||||
mg_http_reply(c, 200, "Content-Type: text/html; charset=utf-8\r\n", TESTPAGE_HTML.c_str());
|
mg_http_reply(c, 200, "Content-Type: text/html; charset=utf-8\r\n", TESTPAGE_HTML.c_str());
|
||||||
}
|
}
|
||||||
|
} else if (mg_match(hm->uri, mg_str("/moosdb_test"), NULL)) {
|
||||||
|
if (mg_strcmp(hm->method, mg_str("POST")) == 0) {
|
||||||
|
// 解析JSON请求
|
||||||
|
char *key = mg_json_get_str(hm->body, "$.key");
|
||||||
|
char *value = mg_json_get_str(hm->body, "$.value");
|
||||||
|
|
||||||
|
if (key && value) {
|
||||||
|
LOG_F(INFO, "Received MOOSDB test message: key=%s, value=%s", key, value);
|
||||||
|
|
||||||
|
// TODO: 这里添加处理MOOSDB测试消息的逻辑
|
||||||
|
// 例如: m_powerManger->handleMoosdbTest(key, value);
|
||||||
|
bool success = true;
|
||||||
|
success = m_powerManger->sendNotification(key,value);
|
||||||
|
if (!success) {
|
||||||
|
mg_http_reply(c, 500, "Content-Type: application/json\r\n",
|
||||||
|
"{\"success\": false, \"error\": \"Failed to send MOOSDB test message\"}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 返回成功响应
|
||||||
|
mg_http_reply(c, 200, "Content-Type: application/json\r\n",
|
||||||
|
"{\"success\": true, \"message\": \"MOOSDB test message received\"}");
|
||||||
|
} else {
|
||||||
|
mg_http_reply(c, 400, "Content-Type: application/json\r\n",
|
||||||
|
"{\"success\": false, \"error\": \"key and value fields are required\"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 释放分配的内存
|
||||||
|
if (key) free(key);
|
||||||
|
if (value) free(value);
|
||||||
|
} else {
|
||||||
|
mg_http_reply(c, 405, "Content-Type: text/plain\r\n", "Method Not Allowed");
|
||||||
|
}
|
||||||
} else if (mg_match(hm->uri, mg_str("/control"), NULL)) {
|
} else if (mg_match(hm->uri, mg_str("/control"), NULL)) {
|
||||||
// 处理断路器控制请求
|
// 处理断路器控制请求
|
||||||
if (mg_strcmp(hm->method, mg_str("POST")) == 0) {
|
if (mg_strcmp(hm->method, mg_str("POST")) == 0) {
|
||||||
@@ -520,6 +552,9 @@ void HttpServer::pushSystemData() {
|
|||||||
j["moosdb"]["cpuLoad"] = Json::Value(m_powerManger->GetPublicCPULoad());
|
j["moosdb"]["cpuLoad"] = Json::Value(m_powerManger->GetPublicCPULoad());
|
||||||
j["moosdb"]["timeSinceIterate"] = Json::Value(m_powerManger->GetPublicTimeSinceIterate());
|
j["moosdb"]["timeSinceIterate"] = Json::Value(m_powerManger->GetPublicTimeSinceIterate());
|
||||||
j["moosdb"]["lastIterateTime"] = Json::Value(m_powerManger->GetPublicLastIterateTime());
|
j["moosdb"]["lastIterateTime"] = Json::Value(m_powerManger->GetPublicLastIterateTime());
|
||||||
|
j["moosdb"]["lastIterateCount"] = Json::Value(m_powerManger->GetPublicIterateCount());
|
||||||
|
j["moosdb"]["serverHost"] = Json::Value(m_powerManger->GetServerHost());
|
||||||
|
j["moosdb"]["serverPort"] = Json::Value(m_powerManger->GetServerPort());
|
||||||
// 时间戳
|
// 时间戳
|
||||||
j["timestamp"] = Json::Value((Json::UInt64)(std::chrono::duration_cast<std::chrono::milliseconds>(
|
j["timestamp"] = Json::Value((Json::UInt64)(std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
std::chrono::system_clock::now().time_since_epoch()).count()));
|
std::chrono::system_clock::now().time_since_epoch()).count()));
|
||||||
|
|||||||
@@ -262,16 +262,49 @@ body {
|
|||||||
<div class="data-panel">
|
<div class="data-panel">
|
||||||
<div class="panel-title">测试表单</div>
|
<div class="panel-title">测试表单</div>
|
||||||
<form id="testForm">
|
<form id="testForm">
|
||||||
<div class="form-group">
|
<div class="form-section">
|
||||||
<label for="type" class="form-label">类型</label>
|
<div class="panel-subtitle">测试类型/ID设置</div>
|
||||||
<input type="number" id="type" name="type" class="form-input" min="0" required>
|
<div class="form-group">
|
||||||
|
<label for="type" class="form-label">类型</label>
|
||||||
|
<input type="number" id="type" name="type" class="form-input" min="0" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="id" class="form-label">ID</label>
|
||||||
|
<input type="number" id="id" name="id" class="form-input" min="0" required>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn" onclick="submitTestForm()">提交类型/ID</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
|
||||||
<label for="id" class="form-label">ID</label>
|
<div class="form-section">
|
||||||
<input type="number" id="id" name="id" class="form-input" min="0" required>
|
<div class="panel-subtitle">MOOSDB测试消息设置</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="key" class="form-label">键(Key)</label>
|
||||||
|
<input type="text" id="key" name="key" class="form-input" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="value" class="form-label">值(Value)</label>
|
||||||
|
<input type="text" id="value" name="value" class="form-input" required>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn" onclick="submitKeyValueForm()" style="background-color: #4f46e5;">提交键值对</button>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn" onclick="submitTestForm()">提交</button>
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.form-section {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
padding: 16px;
|
||||||
|
background: #f9fafb;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
.panel-subtitle {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #4b5563;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
border-bottom: 1px solid #e5e7eb;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -348,6 +381,53 @@ function submitTestForm() {
|
|||||||
id: idValue
|
id: idValue
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sendFormData(formData);
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitKeyValueForm() {
|
||||||
|
const key = document.getElementById('key').value.trim();
|
||||||
|
const value = document.getElementById('value').value.trim();
|
||||||
|
|
||||||
|
if (!key || !value) {
|
||||||
|
alert('请输入键和值');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 直接构造JSON对象,不通过form
|
||||||
|
const payload = {
|
||||||
|
key: key,
|
||||||
|
value: value
|
||||||
|
};
|
||||||
|
|
||||||
|
// 专门发送到MOOSDB测试消息接口
|
||||||
|
fetch('/moosdb_test', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(payload)
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
alert('MOOSDB测试消息提交成功: ' + data.message);
|
||||||
|
} else {
|
||||||
|
alert('MOOSDB测试消息提交失败: ' + data.error);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('MOOSDB测试消息提交错误:', error);
|
||||||
|
alert('MOOSDB测试消息提交过程中发生错误: ' + error.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendFormData(formData) {
|
||||||
|
|
||||||
fetch('/testpage', {
|
fetch('/testpage', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ public:
|
|||||||
fcs["faultCode2_uint16"] = data.fc_fault_level_2;
|
fcs["faultCode2_uint16"] = data.fc_fault_level_2;
|
||||||
fcs["faultCode3_uint16"] = data.fc_fault_level_3;
|
fcs["faultCode3_uint16"] = data.fc_fault_level_3;
|
||||||
fcs["faultCode4_uint16"] = data.fc_fault_level_4;
|
fcs["faultCode4_uint16"] = data.fc_fault_level_4;
|
||||||
|
//新增加通信状态字段
|
||||||
|
// fcs["fcCommState_uint8"] = data.device_common_status.ccu_status.isTimeout;
|
||||||
|
fcs["fcCommState_uint8"] = 0;
|
||||||
|
|
||||||
Json::StreamWriterBuilder writerBuilder;
|
Json::StreamWriterBuilder writerBuilder;
|
||||||
writerBuilder.settings_["indentation"] = "";
|
writerBuilder.settings_["indentation"] = "";
|
||||||
|
|||||||
@@ -55,6 +55,12 @@ public:
|
|||||||
lbs["powerPackVol_uint16"] = data.dyn_voltage_pack;
|
lbs["powerPackVol_uint16"] = data.dyn_voltage_pack;
|
||||||
lbs["powFaultCode_uint8"] = data.powfaultCode;
|
lbs["powFaultCode_uint8"] = data.powfaultCode;
|
||||||
lbs["insFaultCode_uint8"] = data.insfaultCode;
|
lbs["insFaultCode_uint8"] = data.insfaultCode;
|
||||||
|
//新增加两个通信状态字段
|
||||||
|
// lbs["insCommState_uint8"] = data.device_common_status.ccu_status.isTimeout;
|
||||||
|
// lbs["powCommState_uint8"] = data.device_common_status.ccu_status.isTimeout;
|
||||||
|
//TODO:默认屏蔽故障码
|
||||||
|
lbs["insCommState_uint8"] = 0;
|
||||||
|
lbs["powCommState_uint8"] = 0;
|
||||||
|
|
||||||
Json::StreamWriterBuilder writerBuilder;
|
Json::StreamWriterBuilder writerBuilder;
|
||||||
writerBuilder.settings_["indentation"] = "";
|
writerBuilder.settings_["indentation"] = "";
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public:
|
|||||||
// 状态赋值
|
// 状态赋值
|
||||||
Json::Value pms;
|
Json::Value pms;
|
||||||
|
|
||||||
pms["workCondition_uint"] = state.workCondition;
|
pms["workCondition_uint8"] = state.workCondition;
|
||||||
pms["currentMod_uint8"] = state.currentMod;
|
pms["currentMod_uint8"] = state.currentMod;
|
||||||
pms["powerState_uint8"] = state.powerState;
|
pms["powerState_uint8"] = state.powerState;
|
||||||
pms["faultLevel_uint8"] = state.faultLevel;
|
pms["faultLevel_uint8"] = state.faultLevel;
|
||||||
|
|||||||
Reference in New Issue
Block a user