Browse Source

IEC61850 解析json起服务端

xhj 6 months ago
parent
commit
35119b56ac

+ 5 - 7
CMakeLists.txt

@@ -26,14 +26,12 @@ set(DATA_BASE_JSON_DIR /usr/local/bin/database/json)
 # set(DATA_BASE_JSON_DIR ${CMAKE_CURRENT_SOURCE_DIR}/database/json)
 
 
-# 设置交叉编译器路径
-set(TOOLCHAIN_PREFIX /home/ubuntu/Desktop/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-)
+# Set the toolchain prefix for cross-compilation on Windows
+set(TOOLCHAIN_PREFIX "E:/xhj/gcc-linaro-7.5.0-2019/gcc-linaro-7.5.0-2019.12-i686-mingw32_aarch64-linux-gnu/bin/aarch64-linux-gnu-")
 
-# 设置 C 编译器
-set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc)
-
-# 设置 C++ 编译器
-set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++)
+# Specify the C and C++ compilers for cross-compilation
+set(CMAKE_C_COMPILER "${TOOLCHAIN_PREFIX}gcc.exe")
+set(CMAKE_CXX_COMPILER "${TOOLCHAIN_PREFIX}g++.exe")
 
 # 指定目标系统
 set(CMAKE_SYSTEM_NAME Linux)

+ 5 - 5
modules/gateway-scheduler/src/main.cpp

@@ -16,19 +16,19 @@ int main(int argc, char* argv[]) {
   std::set_terminate(terminate);
   MESSAGE_PRINT(" scheduler starting");
   try {
-    /*
+
     int tcpPort = 102;
 
     if (argc > 1) {
         tcpPort = atoi(argv[1]);
     }
 
-    MyIec61850::MyIec61850Server server(tcpPort);
+    MyIec61850::MyIec61850Server server("/root/config.json");
 
     server.start();
     server.run();
     server.stop();
-    */
+
     /*
     int port = 512;
     if(argc == 2){
@@ -41,12 +41,12 @@ int main(int argc, char* argv[]) {
     auto report = new TaskReportService();
     report->start();
 */ 
-
+    /*
     auto queue = new QueueService();
     queue->initializeQueue();
     auto scheduler = new ScheduleService();
     scheduler->schedule();
-
+    */
 
   } catch (std::exception& exception) {
     MESSAGE_PRINT(" enter the catch function ");

+ 116 - 36
modules/gateway-scheduler/src/report/MyIec61850Server.cpp

@@ -1,61 +1,134 @@
 #include "MyIec61850Server.h"
+#include <signal.h>
+#include <stdio.h>
 
 static int running = 0;
 
 void sigint_handler(int signalId) {
+    printf("Received SIGINT, stopping server...\n");
     running = 0;
 }
 
 using namespace MyIec61850;
 
-MyIec61850Server::MyIec61850Server(int port) : port(port), iedServer(nullptr), model(nullptr),
-                                               lDevice1(nullptr), lln0(nullptr), ttmp1(nullptr),
-                                               temperatureValue(nullptr), temperatureTimestamp(nullptr),
-                                               hhum1(nullptr), humidityValue(nullptr), humidityTimestamp(nullptr),
-                                               dataSet(nullptr) {
-    setupDataModel();
+MyIec61850Server::MyIec61850Server(const std::string& configFilePath) {
+  setupDataModelFromConfig(configFilePath);
+  port = 102;
 }
 
+
 MyIec61850Server::~MyIec61850Server() {
+    printf("Destroying IEC 61850 Server\n");
     stop();
     if (model) {
         IedModel_destroy(model);
+        model = nullptr;
     }
 }
+void MyIec61850Server::setupDataModelFromConfig(const std::string& configFilePath) {
+    // 加载并解析配置文件
+    std::ifstream configFile(configFilePath);
+    if (!configFile.is_open()) {
+        std::cerr << "Failed to open config file." << std::endl;
+        return;
+    }
 
-void MyIec61850Server::setupDataModel() {
-    model = IedModel_create("TemperatureHumiditySensor");
+    json config;
+    configFile >> config;
+
+    // 创建 IED 模型
+    model = IedModel_create("EnvironmentalSensors");
+
+    for (const auto& device : config["devices"]) {
+        std::string deviceType = device["type"];
+        std::string deviceId = device["id"];
+
+        // 根据设备类型创建逻辑设备
+        LogicalDevice* lDevice = LogicalDevice_create(deviceId.c_str(), model);
+
+        // 创建 LLN0 逻辑节点(标准逻辑节点)
+        LogicalNode* lln0 = LogicalNode_create("LLN0", lDevice);
+
+        if (deviceType == "sensor") {
+            // 创建温度传感器逻辑节点
+            std::string temperatureName = device["temperature"]["name"];
+            std::string temperatureDataObject = device["temperature"]["dataObject"];
+            LogicalNode* ttmp1 = LogicalNode_create(temperatureName.c_str(), lDevice);
+            DataObject* ttmp1_tmpsv = CDC_SAV_create(temperatureDataObject.c_str(), (ModelNode*) ttmp1, 0, false);
+            DataAttribute* temperatureValue = (DataAttribute*) ModelNode_getChild((ModelNode*) ttmp1_tmpsv, "instMag.f");
+            DataAttribute* temperatureTimestamp = (DataAttribute*) ModelNode_getChild((ModelNode*) ttmp1_tmpsv, "t");
+
+            // 创建湿度传感器逻辑节点
+            std::string humidityName = device["humidity"]["name"];
+            std::string humidityDataObject = device["humidity"]["dataObject"];
+            LogicalNode* hhum1 = LogicalNode_create(humidityName.c_str(), lDevice);
+            DataObject* hhum1_humsv = CDC_SAV_create(humidityDataObject.c_str(), (ModelNode*) hhum1, 0, false);
+            DataAttribute* humidityValue = (DataAttribute*) ModelNode_getChild((ModelNode*) hhum1_humsv, "instMag.f");
+            DataAttribute* humidityTimestamp = (DataAttribute*) ModelNode_getChild((ModelNode*) hhum1_humsv, "t");
+
+            // 创建数据集用于报告 - 温湿度传感器
+            DataSet* dataSet_sensors = DataSet_create("sensorData", lln0);
+            DataSetEntry_create(dataSet_sensors, (temperatureName + "$MX$" + temperatureDataObject + "$instMag$f").c_str(), -1, NULL);
+            DataSetEntry_create(dataSet_sensors, (humidityName + "$MX$" + humidityDataObject + "$instMag$f").c_str(), -1, NULL);
+
+            // 创建报告控制块 - 温湿度传感器
+            uint8_t rptOptions_sensors = RPT_OPT_SEQ_NUM | RPT_OPT_TIME_STAMP | RPT_OPT_REASON_FOR_INCLUSION;
+            ReportControlBlock_create("sensorReport", lln0, "sensorReport", false, NULL, 1, TRG_OPT_DATA_CHANGED, rptOptions_sensors, 50, 0);
+        } else if (deviceType == "smoke_detector") {
+            // 创建烟雾报警器逻辑节点
+            std::string smokeStatusName = device["status"]["name"];
+            std::string smokeStatusDataObject = device["status"]["dataObject"];
+            LogicalNode* ssmg1 = LogicalNode_create(smokeStatusName.c_str(), lDevice);
+            DataObject* ssmg1_smokeStatus = CDC_BSC_create(smokeStatusDataObject.c_str(), (ModelNode*) ssmg1, 0, 0, false);
+            DataAttribute* smokeStatus = (DataAttribute*) ModelNode_getChild((ModelNode*) ssmg1_smokeStatus, "stVal");
+
+            // 创建数据集用于报告 - 烟雾报警器
+            DataSet* dataSet_smoke = DataSet_create("smokeData", lln0);
+            DataSetEntry_create(dataSet_smoke, (smokeStatusName + "$MX$" + smokeStatusDataObject + "$stVal").c_str(), -1, NULL);
+
+            // 创建报告控制块 - 烟雾报警器
+            uint8_t rptOptions_smoke = RPT_OPT_SEQ_NUM | RPT_OPT_TIME_STAMP | RPT_OPT_REASON_FOR_INCLUSION;
+            ReportControlBlock_create("smokeReport", lln0, "smokeReport", false, NULL, 1, TRG_OPT_DATA_CHANGED, rptOptions_smoke, 50, 0);
+        }else if (deviceType == "flood_sensor") {
+          // 创建水浸传感器逻辑节点
+          std::string floodStatusName = device["status"]["name"];
+          std::string floodStatusDataObject = device["status"]["dataObject"];
+          LogicalNode* ffls1 = LogicalNode_create(floodStatusName.c_str(), lDevice);
+          DataObject* ffls1_floodStatus = CDC_BSC_create(floodStatusDataObject.c_str(), (ModelNode*) ffls1, 0, 0, false);
+          DataAttribute* floodStatus = (DataAttribute*) ModelNode_getChild((ModelNode*) ffls1_floodStatus, "stVal");
+
+          // 创建数据集用于报告 - 水浸传感器
+          DataSet* dataSet_flood = DataSet_create("floodData", lln0);
+          DataSetEntry_create(dataSet_flood, (floodStatusName + "$MX$" + floodStatusDataObject + "$stVal").c_str(), -1, NULL);
+
+          // 创建报告控制块 - 水浸传感器
+          uint8_t rptOptions_flood = RPT_OPT_SEQ_NUM | RPT_OPT_TIME_STAMP | RPT_OPT_REASON_FOR_INCLUSION;
+          ReportControlBlock_create("floodReport", lln0, "floodReport", false, NULL, 1, TRG_OPT_DATA_CHANGED, rptOptions_flood, 50, 0);
+        }
 
-    lDevice1 = LogicalDevice_create("SENSORS", model);
+    }
+}
 
-    lln0 = LogicalNode_create("LLN0", lDevice1);
+void onRCBEvent(void* parameter, ReportControlBlock* rcb, ClientConnection connection, IedServer_RCBEventType event, const char* parameterName, MmsDataAccessError serviceError) {
+    // 打印事件详情
+    printf("RCB Event: %d\n", event);
+    printf("RCB Name: %s\n", ReportControlBlock_getName(rcb));
+    printf("Client Address: %s\n", ClientConnection_getPeerAddress(connection));
 
-    /* Create a Temperature Sensor LN */
-    ttmp1 = LogicalNode_create("TTMP1", lDevice1);
-    DataObject* ttmp1_tmpsv = CDC_SAV_create("TmpSv", (ModelNode*) ttmp1, 0, false);
 
-    temperatureValue = (DataAttribute*) ModelNode_getChild((ModelNode*) ttmp1_tmpsv, "instMag.f");
-    temperatureTimestamp = (DataAttribute*) ModelNode_getChild((ModelNode*) ttmp1_tmpsv, "t");
+    if (serviceError != DATA_ACCESS_ERROR_SUCCESS) {
+        printf("Service Error: %d\n", serviceError);
+    }
+}
 
-    /* Create a Humidity Sensor LN */
-    hhum1 = LogicalNode_create("HHUM1", lDevice1);
-    DataObject* hhum1_humsv = CDC_SAV_create("HumSv", (ModelNode*) hhum1, 0, false);
 
-    humidityValue = (DataAttribute*) ModelNode_getChild((ModelNode*) hhum1_humsv, "instMag.f");
-    humidityTimestamp = (DataAttribute*) ModelNode_getChild((ModelNode*) hhum1_humsv, "t");
+void MyIec61850Server::start() {
+    printf("Starting IEC 61850 Server...\n");
 
-    /* Create DataSet for reporting */
-    dataSet = DataSet_create("sensorData", lln0);
-    DataSetEntry_create(dataSet, "TTMP1$MX$TmpSv$instMag$f", -1, NULL);
-    DataSetEntry_create(dataSet, "HHUM1$MX$HumSv$instMag$f", -1, NULL);
+    iedServer = IedServer_create(model); // 确保使用 sIedServer*
 
-    /* Create Report Control Block */
-    uint8_t rptOptions = RPT_OPT_SEQ_NUM | RPT_OPT_TIME_STAMP | RPT_OPT_REASON_FOR_INCLUSION;
-    ReportControlBlock_create("sensorReport", lln0, "sensorReport", false, NULL, 1, TRG_OPT_DATA_CHANGED, rptOptions, 50, 0);
-}
+    IedServer_setRCBEventHandler(iedServer, onRCBEvent, NULL);
 
-void MyIec61850Server::start() {
-    iedServer = IedServer_create(model); // 确保使用 sIedServer*
 
     /* MMS server will be instructed to start listening to client connections. */
     IedServer_start(iedServer, port);
@@ -69,9 +142,11 @@ void MyIec61850Server::start() {
 
 void MyIec61850Server::stop() {
     if (iedServer != nullptr) {
+        printf("Stopping IED Server...\n");
         IedServer_stop(iedServer);
         IedServer_destroy(iedServer); // 传递 sIedServer* 类型的参数
         iedServer = nullptr; // 手动将指针置为 nullptr
+        printf("IED Server stopped.\n");
     }
 }
 
@@ -82,15 +157,18 @@ void MyIec61850Server::run() {
     float temperature = 25.0f; // Initial temperature value
     float humidity = 50.0f;    // Initial humidity value
 
+    printf("Server is running and updating sensor values periodically.\n");
+
     while (running) {
         IedServer_lockDataModel(iedServer);
+        printf("Updating sensor values: Temperature=%.2f, Humidity=%.2f\n", temperature, humidity);
 
         /* Update temperature and humidity values */
-        IedServer_updateUTCTimeAttributeValue(iedServer, temperatureTimestamp, Hal_getTimeInMs());
-        IedServer_updateFloatAttributeValue(iedServer, temperatureValue, temperature);
-
-        IedServer_updateUTCTimeAttributeValue(iedServer, humidityTimestamp, Hal_getTimeInMs());
-        IedServer_updateFloatAttributeValue(iedServer, humidityValue, humidity);
+        // IedServer_updateUTCTimeAttributeValue(iedServer, temperatureTimestamp, Hal_getTimeInMs());
+        // IedServer_updateFloatAttributeValue(iedServer, temperatureValue, temperature);
+        //
+        // IedServer_updateUTCTimeAttributeValue(iedServer, humidityTimestamp, Hal_getTimeInMs());
+        // IedServer_updateFloatAttributeValue(iedServer, humidityValue, humidity);
 
         IedServer_unlockDataModel(iedServer);
 
@@ -100,4 +178,6 @@ void MyIec61850Server::run() {
 
         Thread_sleep(1000); // Sleep for 1 second
     }
-}
+
+    printf("Server stopped.\n");
+}

+ 48 - 19
modules/gateway-scheduler/src/report/MyIec61850Server.h

@@ -6,35 +6,64 @@
 #include <signal.h>
 #include <stdlib.h>
 #include <stdio.h>
-
+#include <fstream>
+#include <iostream>
+#include <nlohmann/json.hpp> // 假设你使用 nlohmann/json 库来解析 JSON
 namespace MyIec61850 {
+//
+// class MyIec61850Server {
+// public:
+//     MyIec61850Server(int port = 102);
+//     ~MyIec61850Server();
+//
+//     void start();
+//     void stop();
+//     void run();
+//
+// private:
+//     void setupDataModel(); // 声明 setupDataModel 方法
+//
+//     int port;
+//     sIedServer* iedServer; // 确保使用 sIedServer* 类型
+//     IedModel* model;
+//
+//     LogicalDevice* lDevice1;
+//     LogicalDevice* lDevice2;
+//
+//     LogicalNode* lln0_sensors;
+//     LogicalNode* lln0_smoke;
+//
+//     LogicalNode* ttmp1;
+//     LogicalNode* hhum1;
+//
+//     LogicalNode* ssmg1;
+//
+//     DataAttribute* temperatureValue;
+//     DataAttribute* temperatureTimestamp;
+//     DataAttribute* humidityValue;
+//     DataAttribute* humidityTimestamp;
+//     DataAttribute* smokeStatus;
+//
+//     DataSet* dataSet_sensors;
+//     DataSet* dataSet_smoke;
+//
+//     DataSet* dataSet;
+// };
+  using json = nlohmann::json;
 
 class MyIec61850Server {
-public:
-    MyIec61850Server(int port = 102);
+  public:
+    MyIec61850Server(const std::string& configFilePath);
     ~MyIec61850Server();
-
+    void setupDataModelFromConfig(const std::string& configFilePath);
     void start();
     void stop();
     void run();
 
-private:
-    void setupDataModel(); // 声明 setupDataModel 方法
-
+  private:
+    IedModel* model;
     int port;
     sIedServer* iedServer; // 确保使用 sIedServer* 类型
-    IedModel* model;
-
-    LogicalDevice* lDevice1;
-    LogicalNode* lln0;
-    LogicalNode* ttmp1;
-    DataAttribute* temperatureValue;
-    DataAttribute* temperatureTimestamp;
-    LogicalNode* hhum1;
-    DataAttribute* humidityValue;
-    DataAttribute* humidityTimestamp;
-
-    DataSet* dataSet;
 };
 
 } // namespace MyIec61850