为状态机增加了线程运行,并补充了数据库

This commit is contained in:
zjk
2025-02-10 21:30:53 +08:00
parent 59faa14afb
commit ed0d7f7fe0
8 changed files with 189 additions and 170 deletions
+38 -13
View File
@@ -20,6 +20,12 @@ bool _ListenCB(void * pParam)
return pMe->ListenLoopUDP();
}
bool _FsmCB(void * pParam)
{
PowerManger* pMe = (PowerManger* )pParam;
return pMe->FsmLoop();
}
//---------------------------------------------------------
// Constructor()
@@ -38,9 +44,9 @@ PowerManger::PowerManger()
//初始化数据库
string dbPath = "/home/zjk/project/H100/H100PowerManger/data/power_data.db";
m_db = new SQLiteDB(dbPath);
m_db->createTables();
m_db->createPowerDataTables();
m_db->createStateTables();
//注册状态机
m_fsm.RegisterState("Init", 1, m_Inite_s1);
m_fsm.RegisterState("Fault", 99, m_Fault_s99);
@@ -111,10 +117,14 @@ bool PowerManger::Iterate()
updatePmState();
updateTime();
//2. 运行状态机
m_fsm.run(m_pmState,this);
// m_fsm.run(m_pmState,this);
if (FSM_RUN_IS_OK)
m_FsmThread.Start();
else
m_FsmThread.Stop();
// 数据库测试
PowerData data;
data.id = 1;
// data.id = 1;
data.timestamp = "2023-05-22 10:00:00";
data.voltage = 12.3 + rand() % 100 / 100.0;
data.current = 4.5 + rand() % 100 / 100.0;
@@ -188,6 +198,7 @@ bool PowerManger::OnStartUp()
}
m_ListenThread.Initialise(_ListenCB,this);
m_ListenThread.Start();
m_FsmThread.Initialise(_FsmCB,this);
return(true);
}
@@ -259,6 +270,17 @@ bool PowerManger::ListenLoopUDP()
return true;
}
bool PowerManger::FsmLoop()
{
while (!m_FsmThread.IsQuitRequested())
{
m_fsm.run(m_pmState,this);
//延时200ms
usleep(200000);
}
return true;
}
bool PowerManger::updatePmState()
{
@@ -338,12 +360,11 @@ string PowerManger::getTypeName(const string typeName)
} else if (typeName == "St6vector" || typeName == "St5deque" || typeName == "St4list" || typeName == "St4pair") {
return "_array";
} else {
// 默认情况下,我们假设它是一个对象
// 默认情况
return "_obj";
}
}
bool PowerManger::buildPowerSysReport()
{
//TODO: 构建能源系统报告
@@ -455,12 +476,6 @@ bool PowerManger::buildPowerSysReport()
suffix = getTypeName(typeid(m_pmCurrentState.ccustate.flameDetection).name());
fcs[VAR_TO_STR(flameDet)+suffix] = m_pmCurrentState.ccustate.flameDetection;
// unsigned char fcuGZ_1L;
// unsigned char fcuGZ_1H;
// unsigned char fcuGZ_2L;
// unsigned char fcuGZ_2H;
// unsigned char fcuGZ_3L;
// unsigned char fcuGZ_3H;
unsigned short faultCode1;
unsigned short faultCode2;
unsigned short faultCode3;
@@ -801,6 +816,16 @@ bool PowerManger::disSystemOperation(disBreaker optBreaker, disBreakerOpt)
return true;
}
void PowerManger::printState(FSM_State st, string desp){
cout << MOOS::ConsoleColours::Yellow() << "STATE " << st.id << " [" << st.name << "] " << MOOS::ConsoleColours::reset();
cout << MOOS::ConsoleColours::Blue() << " -> " << MOOS::ConsoleColours::reset();
// 检查desp是否有“故障”
if (desp.find("故障") != string::npos) {
cout << MOOS::ConsoleColours::Red() << desp << MOOS::ConsoleColours::reset() << endl;
return;
}
cout << MOOS::ConsoleColours::Green() << desp << MOOS::ConsoleColours::reset() << endl;
}
int PowerManger::handleInite_s1(FSM_State &fsm, void* pData)
{
+4 -11
View File
@@ -54,6 +54,7 @@ class PowerManger : public AppCastingMOOSApp
~PowerManger();
public:
bool ListenLoopUDP();
bool FsmLoop();
protected: // Standard MOOSApp functions to overload
bool OnNewMail(MOOSMSG_LIST &NewMail);
@@ -97,6 +98,7 @@ class PowerManger : public AppCastingMOOSApp
udpComm m_udpComm;
XPCUdpSocket *m_pCcuUdpComm;
CMOOSThread m_ListenThread;
CMOOSThread m_FsmThread;
long m_lPort;
unsigned int m_nReceiveBufferSizeKB;
unsigned int m_nSendBufferSizeKB;
@@ -113,17 +115,8 @@ class PowerManger : public AppCastingMOOSApp
public: //状态实现
void printState(FSM_State st, string desp){
cout << MOOS::ConsoleColours::Yellow() << "STATE " << st.id << " [" << st.name << "] " << MOOS::ConsoleColours::reset();
cout << MOOS::ConsoleColours::Blue() << " -> " << MOOS::ConsoleColours::reset();
// 检查desp是否有“故障”
if (desp.find("故障") != string::npos) {
cout << MOOS::ConsoleColours::Red() << desp << MOOS::ConsoleColours::reset() << endl;
return;
}
cout << MOOS::ConsoleColours::Green() << desp << MOOS::ConsoleColours::reset() << endl;
}
void printState(FSM_State st, string desp);
bool FSM_RUN_IS_OK = true;
FSM_State m_pmState; //当前状态
string m_pmEvent;
FSM m_fsm;
+44 -42
View File
@@ -16,7 +16,7 @@ SQLiteDB::~SQLiteDB() {
}
}
void SQLiteDB::createTables() {
void SQLiteDB::createPowerDataTables() {
if (!m_db) return;
const char* sql = "CREATE TABLE IF NOT EXISTS power_data ("
@@ -34,6 +34,24 @@ void SQLiteDB::createTables() {
}
}
void SQLiteDB::createStateTables() {
if (!m_db) return;
const char* sql = "CREATE TABLE IF NOT EXISTS state_data ("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,"
"state_id INTEGER NOT NULL,"
"state_name TEXT NOT NULL,"
"event TEXT NOT NULL,"
"event_id INTEGER NOT NULL,"
"fault_code INTEGER NOT NULL);";
char* errMsg = nullptr;
if (sqlite3_exec(m_db, sql, nullptr, nullptr, &errMsg) != SQLITE_OK) {
std::cerr << "SQL error: " << errMsg << std::endl;
sqlite3_free(errMsg);
}
}
void SQLiteDB::insertPowerData(float voltage, float current, float power, float temperature) {
if (!m_db) return;
@@ -56,6 +74,29 @@ void SQLiteDB::insertPowerData(float voltage, float current, float power, float
}
}
void SQLiteDB::insertStateData(StateData stateData) {
if (!m_db) return;
const char* sql = "INSERT INTO state_data (timestamp, state_id, state_name, event, event_id, fault_code) VALUES (?, ?, ?, ?, ?, ?);";
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(m_db, sql, -1, &stmt, nullptr) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, stateData.timestamp.c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_int(stmt, 2, stateData.state_id);
sqlite3_bind_text(stmt, 3, stateData.state_name.c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 4, stateData.event.c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_int(stmt, 5, stateData.event_id);
sqlite3_bind_int(stmt, 6, stateData.fault_code);
if (sqlite3_step(stmt) != SQLITE_DONE) {
std::cerr << "Error inserting data: " << sqlite3_errmsg(m_db) << std::endl;
}
sqlite3_finalize(stmt);
} else {
std::cerr << "Error preparing statement: " << sqlite3_errmsg(m_db) << std::endl;
}
}
std::vector<PowerData> SQLiteDB::getPowerData(int limit) {
std::vector<PowerData> data;
if (!m_db) return data;
@@ -68,7 +109,7 @@ std::vector<PowerData> SQLiteDB::getPowerData(int limit) {
while (sqlite3_step(stmt) == SQLITE_ROW) {
PowerData record;
record.id = sqlite3_column_int(stmt, 0);
// record.id = sqlite3_column_int(stmt, 0);
record.timestamp = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
record.voltage = sqlite3_column_double(stmt, 2);
record.current = sqlite3_column_double(stmt, 3);
@@ -83,43 +124,4 @@ std::vector<PowerData> SQLiteDB::getPowerData(int limit) {
}
return data;
}
// 显式实例化模板
template void SQLiteDB::insertStructData<PowerData>(const std::string&, const PowerData&);
template<typename T>
std::string SQLiteDB::serializeStruct(const T& data) {
Json::Value j;
j["id"] = data.id;
j["timestamp"] = data.timestamp;
j["voltage"] = data.voltage;
j["current"] = data.current;
j["power"] = data.power;
j["temperature"] = data.temperature;
Json::StreamWriterBuilder writer;
return Json::writeString(writer, j);
}
template<typename T>
void SQLiteDB::insertStructData(const std::string& tableName, const T& data) {
if (!m_db) return;
std::string jsonData = serializeStruct(data);
std::string sql = "INSERT INTO " + tableName + " (data) VALUES (?);";
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, nullptr) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, jsonData.c_str(), -1, SQLITE_TRANSIENT);
if (sqlite3_step(stmt) != SQLITE_DONE) {
std::cerr << "Error inserting data: " << sqlite3_errmsg(m_db) << std::endl;
}
sqlite3_finalize(stmt);
} else {
std::cerr << "Error preparing statement: " << sqlite3_errmsg(m_db) << std::endl;
}
}
}
+12 -9
View File
@@ -8,7 +8,6 @@
// #include <nlohmann/json.hpp>
struct PowerData {
int id;
std::string timestamp;
double voltage;
double current;
@@ -16,24 +15,28 @@ struct PowerData {
double temperature;
};
struct StateData {
std::string timestamp;
int state_id;
std::string state_name;
std::string event;
int event_id;
int fault_code;
};
class SQLiteDB {
public:
SQLiteDB(const std::string& dbPath);
~SQLiteDB();
void createTables();
void createPowerDataTables();
void insertPowerData(float voltage, float current, float power, float temperature);
void createStateTables();
void insertStateData(StateData stateData);
std::vector<PowerData> getPowerData(int limit = 100);
template<typename T>
void insertStructData(const std::string& tableName, const T& data);
private:
sqlite3* m_db;
template<typename T>
std::string serializeStruct(const T& data);
};
#endif // SQLITEDB_H