map/das-dn/cmg/main.cpp

2443 lines
97 KiB
C++
Raw Normal View History

2024-07-08 10:27:17 +08:00
/*
* File: main.cpp
* Author: zhouhuang
*
* Created on October 10, 2015, 3:17 PM
*/
#include <cstdlib>
#include <signal.h>
2024-07-19 17:28:02 +08:00
#include <getopt.h>
2024-07-08 10:27:17 +08:00
#include "process.h"
2024-10-14 20:26:21 +08:00
#include "changemaster.h"
#include "ry.h"
2024-07-08 10:27:17 +08:00
2024-10-14 20:26:21 +08:00
#ifdef MAIN_FILE
2024-07-08 10:27:17 +08:00
#include <fstream>
#include <string>
2024-07-19 17:28:02 +08:00
#include <map>
2024-07-08 10:27:17 +08:00
#include <unordered_map>
#include <libgen.h>
#include <dirent.h>
#include <fnmatch.h>
#include <signal.h>
2024-10-14 20:26:21 +08:00
2024-07-19 17:28:02 +08:00
#include <nopoll.h>
#include <nopoll_decl.h>
2024-07-08 10:27:17 +08:00
#include <json.h>
#include <md5.h>
#include <base64.h>
#include <mbedtls/aes.h>
#include <mbedtls/error.h>
#include "soe.h"
#include "yklog.h"
#include "ytlog.h"
2024-07-19 17:28:02 +08:00
#include "public.h"
2024-08-09 08:50:19 +08:00
#define MAX_MSG_COUNT 4096
2024-07-08 10:27:17 +08:00
bool g_dataAcquisitionReload = false;
2024-10-14 20:26:21 +08:00
2024-07-08 10:27:17 +08:00
std::string g_traceId;
LONG m_soeload = 0;
LONG m_yxbwload = 0;
LONG m_ycbwload = 0;
2024-09-24 15:59:22 +08:00
typedef std::unordered_map<std::string, short> uid2pidmap;
uid2pidmap uid2pid_map;
2024-07-19 17:28:02 +08:00
#define CMD_CONTROL_OPERATION 0
#define CMD_CONTROL_SETTING 1
typedef struct {
int uid;
int point;
int order;
int type;
} struct_service_item;
typedef std::unordered_map<std::string, struct_service_item> name2servicemap;
typedef std::unordered_map<std::string, name2servicemap> unitname2servicemap;
unitname2servicemap unitname2service_map;
typedef struct {
std::string name;
Json::Value value;
} struct_attr;
typedef std::vector<struct_attr> attrvector;
2024-07-08 10:27:17 +08:00
2024-08-09 08:50:19 +08:00
#define WORKER_ID_BITS 5
#define DATA_CENTER_ID_BITS 5
#define SEQUENCE_BITS 12
#define MAX_WORKER_ID ((1 << WORKER_ID_BITS) - 1)
#define MAX_DATA_CENTER_ID ((1 << DATA_CENTER_ID_BITS) - 1)
#define SEQUENCE_MASK ((1 << SEQUENCE_BITS) - 1)
#define EPOCH 1640995200000 // 2022-01-01 00:00:00
typedef struct {
uint64_t worker_id;
uint64_t data_center_id;
uint64_t sequence;
uint64_t last_timestamp;
} Snowflake;
uint64_t current_time() {
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
}
2024-07-08 10:27:17 +08:00
2024-08-09 08:50:19 +08:00
uint64_t snowflake_next_id(Snowflake *sf) {
uint64_t timestamp = current_time();
if (timestamp < sf->last_timestamp) {
return 0;
}
if (sf->last_timestamp == timestamp) {
sf->sequence = (sf->sequence + 1) & SEQUENCE_MASK;
if (sf->sequence == 0) {
while (current_time() <= sf->last_timestamp);
}
} else {
sf->sequence = 0; // reset sequence
}
sf->last_timestamp = timestamp;
return ((timestamp - EPOCH) << (WORKER_ID_BITS + DATA_CENTER_ID_BITS + SEQUENCE_BITS)) |
(sf->data_center_id << (WORKER_ID_BITS + SEQUENCE_BITS)) |
(sf->worker_id << SEQUENCE_BITS) |
sf->sequence;
}
Snowflake g_sf = {1, 1, 0, 0};
2024-10-14 20:26:21 +08:00
2024-07-08 10:27:17 +08:00
std::vector<std::string> split(const std::string &s, char delimiter)
{
std::vector<std::string> tokens;
std::istringstream tokenStream(s);
std::string token;
while (std::getline(tokenStream, token, delimiter)) {
tokens.push_back(token);
}
return tokens;
}
2024-07-19 17:28:02 +08:00
struSystem config_system32;
struConfig config_config;
struDatabase config_database;
struNodeOption config_nodes;
struUnitStatic config_static_units[UNIT_NUM];
bool configInitializeMemory(void)
2024-07-08 10:27:17 +08:00
{
2024-07-19 17:28:02 +08:00
int i, j;
if (config_database.yxs) delete [] config_database.yxs;
if (config_database.ycs) delete [] config_database.ycs;
if (config_database.yms) delete [] config_database.yms;
if (config_database.yks) delete [] config_database.yks;
if (config_database.yts) delete [] config_database.yts;
for (i = 0; i < UNIT_NUM; i++) {
if (config_config.units[i].yxs) delete [] config_config.units[i].yxs;
if (config_config.units[i].ycs) delete [] config_config.units[i].ycs;
if (config_config.units[i].yms) delete [] config_config.units[i].yms;
if (config_config.units[i].yks) delete [] config_config.units[i].yks;
if (config_config.units[i].yts) delete [] config_config.units[i].yts;
}
memset(&config_system32, 0, sizeof(config_system32));
memset(&config_config, 0, sizeof(config_config));
memset(&config_database, 0, sizeof(config_database));
memset(&config_nodes, 0, sizeof(config_nodes));
memset(config_static_units, 0, sizeof(config_static_units));
config_database.yxs = new struYX[DATABASE_YX_NUM];
if (config_database.yxs == NULL) return FALSE;
memset(config_database.yxs, 0, sizeof(struYX) * DATABASE_YX_NUM);
config_database.ycs = new struYC[DATABASE_YC_NUM];
if (config_database.ycs == NULL) return FALSE;
memset(config_database.ycs, 0, sizeof(struYC) * DATABASE_YC_NUM);
config_database.yms = new struYM[DATABASE_YM_NUM];
if (config_database.yms == NULL) return FALSE;
memset(config_database.yms, 0, sizeof(struYM) * DATABASE_YM_NUM);
config_database.yks = new struYK[DATABASE_YK_NUM];
if (config_database.yks == NULL) return FALSE;
memset(config_database.yks, 0, sizeof(struYK) * DATABASE_YK_NUM);
config_database.yts = new struYT[DATABASE_YT_NUM];
if (config_database.yts == NULL) return FALSE;
memset(config_database.yts, 0, sizeof(struYT) * DATABASE_YT_NUM);
strcpy(config_system32.yk_pass, "12345");
2024-08-09 08:50:19 +08:00
snprintf(config_system32.version, sizeof(config_system32.version), "%s", "0");
2024-07-19 17:28:02 +08:00
config_system32.yk_keep = 30;
config_system32.interval_time = 2;
config_system32.log_enabled = FALSE;
config_system32.zjd_log_bind_addr = INADDR_ANY;
config_system32.zjd_log_bind_port = 0;
for (i = 0; i < HARDWARE_PORTS_NUM; i++) {
config_config.hardware.ports[i].baud = 9600;
config_config.hardware.ports[i].data = 8;
config_config.hardware.ports[i].parity = 0;
config_config.hardware.ports[i].stop = 0;
config_config.hardware.ports[i].timeout = 1000; //1s
}
for (i = 0; i < PROCESSES_NUM; i++) {
config_config.processes[i].softdog = 0;
for (j = 0; j < PROCESS_UNIT_NUM; j++) {
config_config.processes[i].units[j] = -1;
}
}
for (i = 0; i < UNIT_NUM; i++) {
config_config.units[i].softdog = 0;
2024-07-08 10:27:17 +08:00
}
2024-07-19 17:28:02 +08:00
return true;
2024-07-08 10:27:17 +08:00
}
2024-07-19 17:28:02 +08:00
bool configWriteSystemCFG(void)
2024-07-08 10:27:17 +08:00
{
2024-07-19 17:28:02 +08:00
FILE* pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_SYSTEM_CONFIG);
pf = fopen(pathName, "wb+");
if (pf != NULL) {
fwrite(&config_system32, sizeof(config_system32), 1, pf);
fclose(pf);
return true;
}
return false;
2024-07-08 10:27:17 +08:00
}
2024-07-19 17:28:02 +08:00
bool configWriteNodeCFG(void)
2024-07-08 10:27:17 +08:00
{
2024-07-19 17:28:02 +08:00
FILE *pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_NODE_CONFIG);
pf = fopen(pathName, "wb+");
if (pf != NULL) {
fwrite(&config_nodes, sizeof(config_nodes), 1, pf);
fclose(pf);
return true;
}
return false;
2024-07-08 10:27:17 +08:00
}
2024-07-19 17:28:02 +08:00
bool configWriteHardwareCFG(void)
2024-07-08 10:27:17 +08:00
{
2024-07-19 17:28:02 +08:00
FILE* pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_HARDWARE_CONFIG);
pf = fopen(pathName, "wb+");
if (pf != NULL) {
fwrite(&config_config.hardware, sizeof(config_config.hardware), 1, pf);
fclose(pf);
return true;
}
return false;
}
bool configWriteProcessCFG(void)
{
FILE* pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_PROCESS_CONFIG);
pf = fopen(pathName, "wb+");
if (pf != NULL) {
fwrite(&config_config.processes, sizeof(config_config.processes), 1, pf);
fclose(pf);
return true;
}
return false;
}
bool configWriteUnitCFG(void)
{
int i;
char filename[512];
char pathName[512];
FILE *pf = NULL;
FILE *pfPoint = NULL;
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_UNIT_CONFIG);
pf = fopen(pathName, "wb+");
if (pf != NULL) {
for (i = 0; i < UNIT_NUM; i++) {
if (fwrite(&config_config.units[i], sizeof(config_config.units[i]), 1, pf) != 1) break;
if (config_config.units[i].yxcount > 0) {
if (config_config.units[i].yxs != NULL) {
snprintf(filename, sizeof(filename), FILE_UNIT_YX_CONFIG, configpath, i);
pfPoint = fopen(filename, "wb+");
if (pfPoint != NULL) {
fwrite(config_config.units[i].yxs, sizeof(struUnitYX)*config_config.units[i].yxcount, 1, pfPoint);
fclose(pfPoint);
}
}
2024-07-08 10:27:17 +08:00
}
2024-07-19 17:28:02 +08:00
if (config_config.units[i].yccount > 0) {
if (config_config.units[i].ycs != NULL) {
snprintf(filename, sizeof(filename), FILE_UNIT_YC_CONFIG, configpath, i);
pfPoint = fopen(filename, "wb+");
if (pfPoint != NULL) {
fwrite(config_config.units[i].ycs, sizeof(struUnitYC)*config_config.units[i].yccount, 1, pfPoint);
fclose(pfPoint);
}
}
}
if (config_config.units[i].ymcount > 0) {
if (config_config.units[i].yms != NULL) {
snprintf(filename, sizeof(filename), FILE_UNIT_YM_CONFIG, configpath, i);
pfPoint = fopen(filename, "wb+");
if (pfPoint != NULL) {
fwrite(config_config.units[i].yms, sizeof(struUnitYM)*config_config.units[i].ymcount, 1, pfPoint);
fclose(pfPoint);
}
}
}
if (config_config.units[i].ykcount > 0) {
if (config_config.units[i].yks != NULL) {
snprintf(filename, sizeof(filename), FILE_UNIT_YK_CONFIG, configpath, i);
pfPoint = fopen(filename, "wb+");
if (pfPoint != NULL) {
fwrite(config_config.units[i].yks, sizeof(struUnitYK)*config_config.units[i].ykcount, 1, pfPoint);
fclose(pfPoint);
}
}
}
if (config_config.units[i].ytcount > 0) {
if (config_config.units[i].yts != NULL) {
snprintf(filename, sizeof(filename), FILE_UNIT_YT_CONFIG, configpath, i);
pfPoint = fopen(filename, "wb+");
if (pfPoint != NULL) {
fwrite(config_config.units[i].yts, sizeof(struUnitYT)*config_config.units[i].ytcount, 1, pfPoint);
fclose(pfPoint);
}
}
2024-07-08 10:27:17 +08:00
}
2024-07-19 17:28:02 +08:00
}
fclose(pf);
return true;
2024-07-08 10:27:17 +08:00
}
2024-07-19 17:28:02 +08:00
return false;
2024-07-08 10:27:17 +08:00
}
2024-07-19 17:28:02 +08:00
bool configWriteStaticUnitCFG(void)
{
FILE *pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_UNIT_STATIC);
pf = fopen(pathName, "w+");
if (pf != NULL) {
fwrite(config_static_units, sizeof(config_static_units), 1, pf);
fclose(pf);
return true;
}
return false;
}
2024-07-08 10:27:17 +08:00
2024-07-19 17:28:02 +08:00
bool configWriteDatabaseCFG(void)
{
FILE *pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_DATABASE_CONFIG);
pf = fopen(pathName, "wb+");
if (pf != NULL) {
fwrite(config_database.yxs, sizeof(struYX) * DATABASE_YX_NUM, 1, pf);
fwrite(config_database.ycs, sizeof(struYC) * DATABASE_YC_NUM, 1, pf);
fwrite(config_database.yms, sizeof(struYM) * DATABASE_YM_NUM, 1, pf);
fwrite(config_database.yks, sizeof(struYK) * DATABASE_YK_NUM, 1, pf);
fwrite(config_database.yts, sizeof(struYT) * DATABASE_YT_NUM, 1, pf);
fclose(pf);
return true;
}
return false;
}
2024-09-24 15:59:22 +08:00
BOOLEAN websocket_msg_join(noPollMsg **msg, int msg_count, BYTE* &buffer, int &buffer_size)
{
if (msg_count <= 0 || msg_count >= MAX_MSG_COUNT) return FALSE;
if (msg[0] == NULL) return FALSE;
buffer_size = 0;
for (int i = 0; i < msg_count; i++)
{
buffer_size += nopoll_msg_get_payload_size(msg[i]);
}
buffer = new BYTE[buffer_size + 1];
int len = 0;
for (int i = 0; i < msg_count; i++)
{
memcpy(&buffer[len], nopoll_msg_get_payload(msg[i]), nopoll_msg_get_payload_size(msg[i]));
len += nopoll_msg_get_payload_size(msg[i]);
}
buffer[buffer_size] = 0;
return TRUE;
}
2024-10-14 20:26:21 +08:00
2024-07-19 17:28:02 +08:00
int websocket_write(noPollConn* conn, const char * buffer, int buffer_len)
{
int result;
result = nopoll_conn_send_text(conn, (const char *)buffer, buffer_len);
/* ensure we have written all bytes but limit operation to 2 seconds */
result = nopoll_conn_flush_writes(conn, 2000000, result);
return (result == buffer_len) ? 0 : -1;
}
bool publish_sensor_data(noPollConn* conn, const std::string traceId, const char* command, const Json::Value payload)
2024-07-08 10:27:17 +08:00
{
Json::StreamWriterBuilder builder;
builder["indentation"] = "";
builder["emitUTF8"] = true;
Json::Value jsonRoot;
2024-07-19 17:28:02 +08:00
jsonRoot["cmd"] = command;
2024-07-08 10:27:17 +08:00
2024-08-09 08:50:19 +08:00
char str[128];
snprintf(str, sizeof(str), "%lld", snowflake_next_id(&g_sf));
2024-10-14 20:26:21 +08:00
2024-07-19 17:28:02 +08:00
if (traceId == "") {
jsonRoot["cmdId"] = str;
} else {
jsonRoot["cmdId"] = traceId;
2024-07-08 10:27:17 +08:00
}
Json::Int64 mtime = (Json::Int64)time(NULL);
mtime *= 1000;
2024-07-19 17:28:02 +08:00
jsonRoot["time"] = mtime;
jsonRoot["data"] = payload;
2024-07-08 10:27:17 +08:00
std::string outputConfig = Json::writeString(builder, jsonRoot);
2024-08-09 08:50:19 +08:00
vLog(LOG_DEBUG, "send cmd: %s, payload: %d\n%s\n", command, outputConfig.length(), outputConfig.c_str());
2024-07-19 17:28:02 +08:00
int rc = websocket_write(conn, outputConfig.c_str(), outputConfig.length());
if (rc != 0) {
2024-08-09 08:50:19 +08:00
vLog(LOG_DEBUG, "websocket write is error<%d>,insert into database.\n", rc);
//插入数据库
2024-07-08 10:27:17 +08:00
return false;
}
return true;
}
static int GetUnitYXCount(int uid)
{
if (uid < 0 || uid >= UNIT_NUM) return 0;
return config.units[uid].yxcount;
}
static int GetUnitYCCount(int uid)
{
if (uid < 0 || uid >= UNIT_NUM) return 0;
return config.units[uid].yccount;
}
static int GetUnitYMCount(int uid)
{
if (uid < 0 || uid >= UNIT_NUM) return 0;
return config.units[uid].ymcount;
}
static float GetUnitYCReal(int uid, int order)
{
int udb;
long value;
float coef;
float base;
struUnit* pUnit;
struUnitYC* pYC;
if (uid < 0 || uid >= UNIT_NUM) return 0;
pUnit = &config.units[uid];
if ((pUnit->state & 0x01) != TRUE) return 0;
if (order < 0 || order >= pUnit->yccount) return 0;
pYC = &pUnit->ycs[order];
udb = pYC->order;
2024-08-09 08:50:19 +08:00
if (udb < 0 || udb >= DATABASE_YC_NUM) {
2024-07-08 10:27:17 +08:00
value = pYC->value;
coef = 1.0f;
base = 0.0f;
2024-08-09 08:50:19 +08:00
} else {
2024-07-08 10:27:17 +08:00
value = database.ycs[udb].value;
coef = pYC->coef;
base = pYC->base;
pYC->value = value;
pYC->update_time = database.ycs[udb].update_time;
pYC->qds = database.ycs[udb].qds;
}
return (float)((float)value * coef + base);
}
static float GetUnitYCRealFromValue(int uid, int order, long value)
{
int udb;
float coef;
float base;
struUnit* pUnit;
struUnitYC* pYC;
if (uid < 0 || uid >= UNIT_NUM) return 0;
pUnit = &config.units[uid];
if ((pUnit->state & 0x01) != TRUE) return 0;
if (order < 0 || order >= pUnit->yccount) return 0;
pYC = &pUnit->ycs[order];
udb = pYC->order;
2024-08-09 08:50:19 +08:00
if (udb < 0 || udb >= DATABASE_YC_NUM) {
2024-07-08 10:27:17 +08:00
coef = 1.0f;
base = 0.0f;
2024-08-09 08:50:19 +08:00
} else {
2024-07-08 10:27:17 +08:00
coef = pYC->coef;
base = pYC->base;
}
return (float)(value * coef + base);
}
static float GetUnitYMReal(int uid, int order)
{
int udb;
long value;
float coef;
float base;
struUnit* pUnit;
struUnitYM* pYM;
if (uid < 0 || uid >= UNIT_NUM) return 0;
pUnit = &config.units[uid];
if ((pUnit->state & 0x01) != TRUE) return 0;
if (order < 0 || order >= pUnit->ymcount) return 0;
pYM = &pUnit->yms[order];
udb = pYM->order;
2024-08-09 08:50:19 +08:00
if (udb < 0 || udb >= DATABASE_YM_NUM) {
2024-07-08 10:27:17 +08:00
value = pYM->value;
coef = 1.0f;
base = 0.0f;
2024-08-09 08:50:19 +08:00
} else {
2024-07-08 10:27:17 +08:00
value = (long)database.yms[udb].value;
pYM->update_time = database.yms[udb].update_time;
coef = pYM->coef;
base = pYM->base;
pYM->value = value;
}
return (float)(value * coef + base);
}
static BYTE GetUnitYX(int uid, int point)
{
int udb;
BOOLEAN value;
struUnit* pUnit;
struUnitYX* pYX;
if (uid < 0 || uid >= UNIT_NUM) return 0;
pUnit = &config.units[uid];
if ((pUnit->state & 0x01) != TRUE) return 0;
if (point < 0 || point >= pUnit->yxcount) return 0;
pYX = &pUnit->yxs[point];
udb = pYX->order;
2024-08-09 08:50:19 +08:00
if (udb < 0 || udb >= DATABASE_YX_NUM) {
2024-07-08 10:27:17 +08:00
value = pYX->value;
2024-08-09 08:50:19 +08:00
} else {
2024-07-08 10:27:17 +08:00
value = database.yxs[udb].value;
pYX->value = value;
pYX->update_time = database.yxs[udb].update_time;
}
return value;
}
int GetUnitYXBW(int& uid, BOOLEAN& value, BYTE& qds, int& type, unionCP56Time& st)
{
int order;
int point;
while (yxbw.GetYXBW(m_yxbwload, st, order, value, qds, uid, point, type))
{
m_yxbwload++;
return point;
}
return -1;
}
int GetUnitSOE(int& uid, BOOLEAN& value, BYTE& qds, unionCP56Time& st)
{
int order;
int point;
2024-08-09 08:50:19 +08:00
while (soe.GetSOE(m_soeload, st, order, value, qds, uid, point)) {
2024-07-08 10:27:17 +08:00
m_soeload++;
return point;
}
return -1;
}
int GetUnitYCBW(int& uid, LONG& value, BYTE& qds, int& type, unionCP56Time& st)
{
int order;
int point;
2024-08-09 08:50:19 +08:00
while (ycbw.GetYCBW(m_ycbwload, st, order, value, qds, uid, point, type)) {
2024-07-08 10:27:17 +08:00
m_ycbwload++;
return point;
}
return -1;
}
BOOLEAN GetUnitYK(int uid, int& order, BYTE& value, BYTE& act, BYTE& result)
{
int i;
int udb;
struUnit* pUnit;
struYK* pYK;
if (uid < 0 || uid >= UNIT_NUM) return FALSE;
pUnit = &config.units[uid];
if ((pUnit->state & 0x01) != TRUE) return FALSE;
for (i = 0; i < pUnit->ykcount; i++) {
udb = pUnit->yks[i].order;
if (udb < 0 || udb >= DATABASE_YK_NUM) continue;
pYK = &database.yks[udb];
order = i;
value = pYK->value;
act = (BYTE)pYK->state;
result = (BYTE)pYK->result;
if (pYK->op_unit != uid) continue;
switch (act) {
case YKS_SELED:
if (result == YKR_SUCC) {
pYK->result = YKR_OPER;
yklog.PushYKLog(system32.now, udb, value, YKT_SELRET, YKS_PROC, uid);
return TRUE;
2024-08-09 08:50:19 +08:00
} else if (result == YKR_FAIL) {
2024-07-08 10:27:17 +08:00
pYK->state = YKS_IDLE;
pYK->result = YKR_IDLE;
pYK->op_unit = -1;
return TRUE;
2024-08-09 08:50:19 +08:00
} else if (result == YKR_IDLE) {
2024-07-08 10:27:17 +08:00
pYK->state = YKS_IDLE;
pYK->op_unit = -1;
}
break;
case YKS_EXEED:
pYK->state = YKS_IDLE;
pYK->result = YKR_IDLE;
pYK->op_unit = -1;
if (result == YKR_SUCC || result == YKR_FAIL) {
return TRUE;
}
break;
case YKS_ABRED:
pYK->state = YKS_IDLE;
pYK->result = YKR_IDLE;
pYK->op_unit = -1;
return TRUE;
case YKS_EXEING:
if (result == YKR_OVER) {
pYK->state = YKS_IDLE;
pYK->result = YKR_IDLE;
pYK->op_unit = -1;
return TRUE;
}
break;
case YKS_SELREQ:
if (result == YKR_OVER) {
pYK->state = YKS_IDLE;
pYK->result = YKR_IDLE;
pYK->op_unit = -1;
return TRUE;
}
break;
case YKS_SELING:
if (result == YKR_OVER) {
pYK->state = YKS_IDLE;
pYK->result = YKR_IDLE;
pYK->op_unit = -1;
return TRUE;
}
break;
case YKS_ABRREQ:
case YKS_EXEREQ:
case YKS_IDLE:
break;
default:
pYK->state = YKS_IDLE;
pYK->result = YKR_IDLE;
pYK->op_unit = -1;
break;
}
}
return FALSE;
}
void SetUnitYK(int uid, int order, BYTE value, BYTE act, BYTE result)
{
int udb;
struUnit* pUnit;
struYK* pYK;
if (uid < 0 || uid >= UNIT_NUM) return;
pUnit = &config.units[uid];
if ((pUnit->state & 0x01) != TRUE) return;
if (order < 0 || order >= pUnit->ykcount) return;
udb = pUnit->yks[order].order;
if (udb < 0 || udb >= DATABASE_YK_NUM) return;
pYK = &database.yks[udb];
switch (act) {
case YKS_SELREQ:
if (pYK->state == YKS_IDLE /*&& pYK->op_unit == -1*/) {
pYK->state = act;
pYK->result = YKR_IDLE;
pYK->value = value;
pYK->op_time = system32.timers;
pYK->op_unit = uid;
yklog.PushYKLog(system32.now, udb, value, YKT_SELREQ, YKS_PROC, uid);
}
break;
case YKS_ABRREQ:
if (pYK->op_unit != uid) break;
if (pYK->value != value) break;
if (pYK->state != YKS_IDLE && pYK->state != YKS_EXEED) {
pYK->state = act;
pYK->result = YKR_IDLE;
yklog.PushYKLog(system32.now, udb, value, YKT_ABRREQ, YKS_PROC, uid);
}
break;
case YKS_EXEREQ:
if (pYK->op_unit != uid) break;
if (pYK->value != value) break;
if (pYK->state == YKS_SELED && pYK->result == YKR_OPER) {
pYK->state = act;
pYK->result = YKR_IDLE;
yklog.PushYKLog(system32.now, udb, value, YKT_EXEREQ, YKS_PROC, uid);
}
break;
}
}
BOOLEAN GetUnitYT(int uid, int& order, DWORD& value, BYTE& act, BYTE& result)
{
int i;
int udb;
struUnit* pUnit;
struYT* pYT;
if (uid < 0 || uid >= UNIT_NUM) return FALSE;
pUnit = &config.units[uid];
if ((pUnit->state & 0x01) != TRUE) return FALSE;
for (i = 0; i < pUnit->ytcount; i++) {
udb = pUnit->yts[i].order;
if (udb < 0 || udb >= DATABASE_YT_NUM) continue;
pYT = &database.yts[udb];
order = i;
value = (DWORD)pYT->value;
act = (BYTE)pYT->state;
result = (BYTE)pYT->result;
if (pYT->op_unit != uid) continue;
switch (act) {
case YTS_SELED:
if (result == YTR_SUCC) {
pYT->result = YTR_OPER;
ytlog.PushYTLog(system32.now, udb, value, YTT_SELRET, YTS_PROC, uid);
return TRUE;
2024-08-09 08:50:19 +08:00
} else if (result == YTR_FAIL) {
2024-07-08 10:27:17 +08:00
pYT->state = YTS_IDLE;
pYT->result = YTR_IDLE;
pYT->op_unit = -1;
return TRUE;
2024-08-09 08:50:19 +08:00
} else if (result == YTR_IDLE) {
2024-07-08 10:27:17 +08:00
pYT->state = YTS_IDLE;
pYT->op_unit = -1;
}
break;
case YTS_EXEED:
pYT->state = YTS_IDLE;
pYT->result = YTR_IDLE;
pYT->op_unit = -1;
if (result == YTR_SUCC || result == YTR_FAIL) {
return TRUE;
}
break;
case YTS_ABRED:
pYT->state = YTS_IDLE;
pYT->result = YTR_IDLE;
pYT->op_unit = -1;
return TRUE;
case YTS_EXEING:
if (result == YTR_OVER) {
pYT->state = YTS_IDLE;
pYT->result = YTR_IDLE;
pYT->op_unit = -1;
return TRUE;
}
break;
case YTS_SELREQ:
if (result == YTR_OVER) {
pYT->state = YTS_IDLE;
pYT->result = YTR_IDLE;
pYT->op_unit = -1;
return TRUE;
}
break;
case YTS_SELING:
if (result == YTR_OVER) {
pYT->state = YTS_IDLE;
pYT->result = YTR_IDLE;
pYT->op_unit = -1;
return TRUE;
}
break;
case YTS_ABRREQ:
case YTS_EXEREQ:
case YTS_IDLE:
break;
default:
pYT->state = YTS_IDLE;
pYT->result = YTR_IDLE;
pYT->op_unit = -1;
break;
}
}
return FALSE;
}
void SetUnitYT(int uid, int order, DWORD value, BYTE act, BYTE result)
{
int udb;
struUnit* pUnit;
struYT* pYT;
if (uid < 0 || uid >= UNIT_NUM) return;
pUnit = &config.units[uid];
if ((pUnit->state & 0x01) != TRUE) return;
if (order < 0 || order >= pUnit->ytcount) return;
udb = pUnit->yts[order].order;
if (udb < 0 || udb >= DATABASE_YT_NUM) return;
pYT = &database.yts[udb];
switch (act) {
case YTS_SELREQ:
if (pYT->state == YTS_IDLE /*&& pYT->op_unit == -1*/) {
pYT->state = act;
pYT->result = YTR_IDLE;
pYT->value = value;
pYT->op_time = system32.timers;
pYT->op_unit = uid;
ytlog.PushYTLog(system32.now, udb, value, YTT_SELREQ, YTS_PROC, uid);
}
break;
case YTS_ABRREQ:
if (pYT->op_unit != uid) break;
if (pYT->value != (long)value) break;
if (pYT->state != YTS_IDLE && pYT->state != YTS_EXEED) {
pYT->state = act;
pYT->result = YTR_IDLE;
ytlog.PushYTLog(system32.now, udb, value, YTT_ABRREQ, YTS_PROC, uid);
}
break;
case YTS_EXEREQ:
if ((pYT->state == YTS_SELED || pYT->state == YTS_IDLE)) {
pYT->state = act;
pYT->result = YTR_IDLE;
pYT->value = value;
pYT->op_time = system32.timers;
pYT->op_unit = uid;
ytlog.PushYTLog(system32.now, udb, value, YTT_EXEREQ, YTS_PROC, uid);
}
break;
}
}
2024-07-19 17:28:02 +08:00
int MakeYKFrame(noPollConn* conn, int uid)
2024-07-08 10:27:17 +08:00
{
int order;
BYTE value, action, result;
2024-07-19 17:28:02 +08:00
//for (int i = 0; i < m_total_units.size(); i++)
2024-07-08 10:27:17 +08:00
{
2024-07-19 17:28:02 +08:00
//uid = m_total_units.at(i);
if (uid < 0 || uid >= UNIT_NUM) return -1;
if (!GetUnitYK(uid, order, value, action, result)) return -1;
2024-07-08 10:27:17 +08:00
vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is %s result is %s\n", uid, order, (value ? "CLOSE" : "TRIP"), val_to_str(action, yk_state, "STATE=%d"), val_to_str(result, yk_result, "RESULT=%d"));
//发送确认
Json::Value jsonRoot;
2024-08-09 08:50:19 +08:00
jsonRoot["deviceId"] = static_units[uid].deviceId;
jsonRoot["serviceName"] = (const char *)config.units[uid].yks[order].name;
jsonRoot["opValue"] = value;
if (YKS_SELED == action && YKR_FAIL == result) {
2024-07-08 10:27:17 +08:00
action = YKS_ABRED;
2024-08-09 08:50:19 +08:00
} else if (YKS_SELREQ == action && YKR_OVER == result) {
2024-07-08 10:27:17 +08:00
action = YKS_ABRED;
2024-08-09 08:50:19 +08:00
} else if (YKS_SELING == action && YKR_OVER == result) {
2024-07-08 10:27:17 +08:00
action = YKS_ABRED;
}
2024-08-09 08:50:19 +08:00
if (YKS_SELED == action) {
2024-07-08 10:27:17 +08:00
SetUnitYK(uid, order, value, YKS_EXEREQ, YKR_IDLE);
vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_EXEREQ result is YKR_IDLE.\n", uid, order, (value ? "CLOSE" : "TRIP"));
return 1;
2024-08-09 08:50:19 +08:00
} else if (YKS_ABRED == action) {
2024-07-08 10:27:17 +08:00
SetUnitYK(uid, order, value, YKS_ABRREQ, YKR_IDLE);
vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_ABRREQ result is YKR_IDLE.\n", uid, order, (value ? "CLOSE" : "TRIP"));
jsonRoot["result"] = false;
2024-08-09 08:50:19 +08:00
} else {
2024-07-08 10:27:17 +08:00
jsonRoot["result"] = true;
}
2024-07-19 17:28:02 +08:00
publish_sensor_data(conn, g_traceId, "deviceControlResp", jsonRoot);
2024-07-08 10:27:17 +08:00
return 1;
}
return 0;
}
2024-07-19 17:28:02 +08:00
int MakeYTFrame(noPollConn* conn, int uid)
2024-07-08 10:27:17 +08:00
{
int order;
BYTE action, result;
DWORD value;
2024-07-19 17:28:02 +08:00
//for (int i = 0; i < m_total_units.size(); i++)
2024-07-08 10:27:17 +08:00
{
2024-07-19 17:28:02 +08:00
if (uid < 0 || uid >= UNIT_NUM) return -1;
if (!GetUnitYT(uid, order, value, action, result)) return -1;
2024-07-08 10:27:17 +08:00
vLog(LOG_DEBUG, "Unit(%d) set point(%d) %d state is %s result is %s\n", uid, order, value, val_to_str(action, yt_state, "STATE=%d"), val_to_str(result, yt_result, "RESULT=%d"));
//发送确认
Json::Value jsonRoot;
2024-08-09 08:50:19 +08:00
jsonRoot["deviceId"] = static_units[uid].deviceId;
jsonRoot["serviceName"] = (const char *)config.units[uid].yts[order].name;
jsonRoot["opValue"] = value;
if (YTS_SELED == action && YTR_FAIL == result) {
2024-07-08 10:27:17 +08:00
action = YTS_ABRED;
2024-08-09 08:50:19 +08:00
} else if (YTS_SELREQ == action && YTR_OVER == result) {
2024-07-08 10:27:17 +08:00
action = YTS_ABRED;
2024-08-09 08:50:19 +08:00
} else if (YTS_SELING == action && YTR_OVER == result) {
2024-07-08 10:27:17 +08:00
action = YTS_ABRED;
}
2024-08-09 08:50:19 +08:00
if (YTS_SELED == action) {
2024-07-08 10:27:17 +08:00
SetUnitYT(uid, order, value, YTS_EXEREQ, YTR_IDLE);
vLog(LOG_DEBUG, "Unit(%d) set point(%d) %d state is YTS_EXEREQ result is YTR_IDLE.\n", uid, order, value);
return 1;
2024-08-09 08:50:19 +08:00
} else if (YTS_ABRED == action) {
2024-07-08 10:27:17 +08:00
SetUnitYT(uid, order, value, YTS_ABRREQ, YTR_IDLE);
vLog(LOG_DEBUG, "Unit(%d) set point(%d) %d state is YTS_ABRREQ result is YTR_IDLE.\n", uid, order, value);
jsonRoot["result"] = false;
2024-08-09 08:50:19 +08:00
} else {
2024-07-08 10:27:17 +08:00
jsonRoot["result"] = true;
}
2024-07-19 17:28:02 +08:00
publish_sensor_data(conn, g_traceId, "deviceControlResp", jsonRoot);
2024-07-08 10:27:17 +08:00
return 1;
}
return 0;
}
2024-07-19 17:28:02 +08:00
bool OnReceivedDeviceCommand(const Json::Value jsonRoot)
2024-07-08 10:27:17 +08:00
{
2024-07-19 17:28:02 +08:00
if (jsonRoot["deviceId"].isNull()) return FALSE;
if (jsonRoot["serviceName"].isNull()) return FALSE;
if (jsonRoot["opValue"].isNull()) return FALSE;
2024-07-08 10:27:17 +08:00
2024-07-19 17:28:02 +08:00
std::string deviceId = jsonRoot["deviceId"].asString();
std::string serviceName = jsonRoot["serviceName"].asString();
if (unitname2service_map.find(deviceId) == unitname2service_map.end()) {
vLog(LOG_WARN, "下发了一个不存在services的控制设备id<%s>。\n", deviceId.c_str());
return false;
}
name2servicemap name2service_map = unitname2service_map[deviceId];
if (name2service_map.find(serviceName) == name2service_map.end()) {
vLog(LOG_WARN, "下发了一个不存在的service名称<%s>。\n", serviceName.c_str());
return false;
}
2024-07-08 10:27:17 +08:00
2024-07-19 17:28:02 +08:00
struct_service_item item = name2service_map[serviceName];
int operType = item.type;
int uid = item.uid;
int point = item.point;
2024-07-08 10:27:17 +08:00
2024-07-19 17:28:02 +08:00
if (operType == CMD_CONTROL_OPERATION) { //遥控
if (point < 0) {
2024-07-08 10:27:17 +08:00
vLog(LOG_ERROR, "未能找到对应的遥控点号,请检查并确认。\n");
return FALSE;
}
2024-07-19 17:28:02 +08:00
int operValue = jsonRoot["opValue"].asInt();
2024-07-08 10:27:17 +08:00
SetUnitYK(uid, point, (operValue & 0x03), YKS_SELREQ, YKR_IDLE);
vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_SELREQ result is YKR_IDLE.\n", uid, point, ((operValue & 0x03) ? "CLOSE" : "TRIP"));
2024-07-19 17:28:02 +08:00
} else if (operType == CMD_CONTROL_SETTING) { //遥调
2024-08-09 08:50:19 +08:00
union {
2024-07-19 17:28:02 +08:00
float fval;
DWORD dval;
} operValue;
if (point < 0) {
2024-07-08 10:27:17 +08:00
vLog(LOG_ERROR, "未能找到对应的遥调点号,请检查并确认。\n");
return FALSE;
}
2024-09-24 15:59:22 +08:00
if (jsonRoot["opValue"].isInt()) operValue.dval = jsonRoot["opValue"].asInt();
else if (jsonRoot["opValue"].isDouble()) operValue.fval = jsonRoot["opValue"].asFloat();
2024-07-19 17:28:02 +08:00
SetUnitYT(uid, point, operValue.dval, YTS_EXEREQ, YTR_IDLE);
vLog(LOG_DEBUG, "Unit(%d) set point(%d) %d state is YTS_EXEREQ result is YTR_IDLE.\n", uid, point, operValue.dval);
} else {
2024-07-08 10:27:17 +08:00
vLog(LOG_ERROR, "平台下发的<%d>命令错误。operType不是<0-遥控或1-遥调>,系统不支持的命令!\n", operType);
return FALSE;
}
return TRUE;
}
2024-08-09 08:50:19 +08:00
static BOOLEAN processUartParam(const Json::Value jsonRoot, int ord)
2024-07-08 10:27:17 +08:00
{
2024-08-09 08:50:19 +08:00
if (ord < 0 || ord >= HARDWARE_PORTS_NUM) return FALSE;
2024-07-08 10:27:17 +08:00
2024-07-19 17:28:02 +08:00
config_config.hardware.ports[ord].state = TRUE;
snprintf(config_config.hardware.ports[ord].name, sizeof(config_config.hardware.ports[ord].name), "ttyS%d", ord);
config_config.hardware.ports[ord].baud = 9600;
config_config.hardware.ports[ord].data = 8;
config_config.hardware.ports[ord].parity = 0;
config_config.hardware.ports[ord].stop = 0;
config_config.hardware.ports[ord].timeout = 1000;
2024-07-08 10:27:17 +08:00
2024-07-19 17:28:02 +08:00
if (jsonRoot["name"].isString()) {
snprintf(config_config.hardware.ports[ord].name, sizeof(config_config.hardware.ports[ord].name), "%s", jsonRoot["name"].asCString());
}
if (jsonRoot["baud"].isInt()) {
config_config.hardware.ports[ord].baud = jsonRoot["baud"].asInt();
} else if (jsonRoot["baud"].isString()) {
config_config.hardware.ports[ord].baud = atoi(jsonRoot["baud"].asCString());
}
if (jsonRoot["data"].isInt()) {
config_config.hardware.ports[ord].data = jsonRoot["data"].asInt();
} else if (jsonRoot["data"].isString()) {
config_config.hardware.ports[ord].data = atoi(jsonRoot["data"].asCString());
}
if (jsonRoot["parity"].isInt()) {
config_config.hardware.ports[ord].parity = jsonRoot["parity"].asInt();
} else if (jsonRoot["parity"].isString()) {
config_config.hardware.ports[ord].parity = atoi(jsonRoot["parity"].asCString());
}
if (jsonRoot["stop"].isInt()) {
if (jsonRoot["stop"].asInt() == 1) config_config.hardware.ports[ord].stop = 0;
else if (jsonRoot["stop"].asInt() == 2) config_config.hardware.ports[ord].stop = 2;
} else if (jsonRoot["stop"].isString()) {
if (jsonRoot["stop"].asString() == "1") config_config.hardware.ports[ord].stop = 0;
else if (jsonRoot["stop"].asString() == "2") config_config.hardware.ports[ord].stop = 2;
}
if (jsonRoot["timeout"].isInt()) {
config_config.hardware.ports[ord].timeout = jsonRoot["timeout"].asInt();
} else if (jsonRoot["timeout"].isString()) {
config_config.hardware.ports[ord].timeout = atoi(jsonRoot["timeout"].asCString());
}
2024-07-08 10:27:17 +08:00
2024-07-19 17:28:02 +08:00
return TRUE;
}
2024-10-14 20:26:21 +08:00
2024-08-09 08:50:19 +08:00
static BOOLEAN processNetworkParam(const Json::Value jsonRoot, int pid)
2024-07-19 17:28:02 +08:00
{
2024-08-09 08:50:19 +08:00
if (pid < 0 || pid >= PROCESSES_NUM) return FALSE;
2024-07-19 17:28:02 +08:00
2024-09-24 15:59:22 +08:00
config_config.processes[pid].option.network.ignored_source = TRUE;
config_config.processes[pid].option.network.socket_type = SOCK_STREAM;
config_config.processes[pid].option.network.bind_addr = INADDR_ANY;
config_config.processes[pid].option.network.bind_port = 0;
config_config.processes[pid].option.network.target_addr = INADDR_ANY;
config_config.processes[pid].option.network.target_port = 502;
if (jsonRoot["targetAddr"].isInt()) {
config_config.processes[pid].option.network.target_addr = jsonRoot["targetAddr"].asInt();
} else if (jsonRoot["targetAddr"].isString()) {
if (inet_pton(AF_INET, jsonRoot["targetAddr"].asCString(), &config_config.processes[pid].option.network.target_addr) == 1) {
2024-08-09 08:50:19 +08:00
vLog(LOG_DEBUG, "IPv4 地址转换成功,网络字节序为: %u.\n", config_config.processes[pid].option.network.target_addr);
} else {
vLog(LOG_ERROR, "inet_pton error(%d,%s).\n", errno, strerror(errno));
}
2024-07-19 17:28:02 +08:00
}
2024-09-24 15:59:22 +08:00
if (jsonRoot["targetPort"].isInt()) {
config_config.processes[pid].option.network.target_port = jsonRoot["targetPort"].asInt();
} else if (jsonRoot["targetPort"].isString()) {
config_config.processes[pid].option.network.target_port = atoi(jsonRoot["targetPort"].asCString());
2024-08-09 08:50:19 +08:00
}
2024-09-24 15:59:22 +08:00
return TRUE;
2024-08-09 08:50:19 +08:00
}
static BOOLEAN processHostIEC104ProcessParam(const Json::Value jsonRoot, int pid)
{
if (pid < 0 || pid >= PROCESSES_NUM) return FALSE;
2024-09-24 15:59:22 +08:00
config_config.processes[pid].option.iec104.net.ignored_source = TRUE;
config_config.processes[pid].option.iec104.net.socket_type = SOCK_STREAM;
config_config.processes[pid].option.iec104.net.target_addr = INADDR_ANY;
config_config.processes[pid].option.iec104.net.target_port = 2404;
config_config.processes[pid].option.iec104.asdu_addr_size = 2;
config_config.processes[pid].option.iec104.cot_size = 2;
config_config.processes[pid].option.iec104.info_addr_size = 3;
config_config.processes[pid].option.iec104.t0 = 30;
config_config.processes[pid].option.iec104.t1 = 15;
config_config.processes[pid].option.iec104.t2 = 10;
config_config.processes[pid].option.iec104.t3 = 20;
config_config.processes[pid].option.iec104.k = 12;
config_config.processes[pid].option.iec104.w = 8;
2024-07-19 17:28:02 +08:00
if (jsonRoot["host"].isInt()) {
config_config.processes[pid].option.iec104.net.target_addr = jsonRoot["host"].asInt();
} else if (jsonRoot["host"].isString()) {
if (inet_pton(AF_INET, jsonRoot["host"].asCString(), &config_config.processes[pid].option.iec104.net.target_addr) == 1) {
vLog(LOG_DEBUG, "IPv4 地址转换成功,网络字节序为: %u.\n", config_config.processes[pid].option.iec104.net.target_addr);
} else {
vLog(LOG_ERROR, "inet_pton error(%d,%s).\n", errno, strerror(errno));
}
}
if (jsonRoot["port"].isInt()) {
config_config.processes[pid].option.iec104.net.target_port = jsonRoot["port"].asInt();
} else if (jsonRoot["port"].isString()) {
config_config.processes[pid].option.iec104.net.target_port = atoi(jsonRoot["port"].asCString());
}
if (jsonRoot["t0"].isInt()) {
config_config.processes[pid].option.iec104.t0 = jsonRoot["t0"].asInt();
} else if (jsonRoot["t0"].isString()) {
config_config.processes[pid].option.iec104.t0 = atoi(jsonRoot["t0"].asCString());
}
if (jsonRoot["t1"].isInt()) {
config_config.processes[pid].option.iec104.t0 = jsonRoot["t1"].asInt();
} else if (jsonRoot["t1"].isString()) {
config_config.processes[pid].option.iec104.t0 = atoi(jsonRoot["t1"].asCString());
}
if (jsonRoot["t2"].isInt()) {
config_config.processes[pid].option.iec104.t0 = jsonRoot["t2"].asInt();
} else if (jsonRoot["t2"].isString()) {
config_config.processes[pid].option.iec104.t0 = atoi(jsonRoot["t2"].asCString());
}
if (jsonRoot["t3"].isInt()) {
config_config.processes[pid].option.iec104.t0 = jsonRoot["t3"].asInt();
} else if (jsonRoot["t3"].isString()) {
config_config.processes[pid].option.iec104.t0 = atoi(jsonRoot["t3"].asCString());
}
return TRUE;
}
2024-09-24 15:59:22 +08:00
#define POINT_TYPE_YX 0
#define POINT_TYPE_YC 1
#define POINT_TYPE_YM 2
#define POINT_TYPE_YK 3
#define POINT_TYPE_YT 4
BOOLEAN processModbusPointParam(const Json::Value jsonRoot, int uid, int point, int type)
{
if (uid < 0 || uid >= UNIT_NUM) return FALSE;
if (point < 0) return FALSE;
switch (type)
{
case POINT_TYPE_YX:
if (point >= config_config.units[uid].yxcount) return FALSE;
if (jsonRoot["col1"].isString()) {
BYTE funcCode = (BYTE)atoi(jsonRoot["col1"].asCString());
config_config.units[uid].yxs[point].m_param[0] = funcCode;
} else if (jsonRoot["col1"].isInt()) {
BYTE funcCode = (BYTE)jsonRoot["col1"].asInt();
config_config.units[uid].yxs[point].m_param[0] = funcCode;
} else {
config_config.units[uid].yxs[point].m_param[0] = 0;
}
if (jsonRoot["col2"].isString()) {
BYTE offSet = (BYTE)atoi(jsonRoot["col2"].asCString());
config_config.units[uid].yxs[point].m_param[3] = offSet;
} if (jsonRoot["col2"].isInt()) {
BYTE offSet = (BYTE)jsonRoot["col2"].asInt();
config_config.units[uid].yxs[point].m_param[3] = offSet;
} else {
config_config.units[uid].yxs[point].m_param[3] = 0;
}
if (jsonRoot["col3"].isString()) {
WORD registerAddr = (WORD)atoi(jsonRoot["col3"].asCString());
config_config.units[uid].yxs[point].m_param[1] = (registerAddr & 0xff);
config_config.units[uid].yxs[point].m_param[2] = ((registerAddr >> 8) & 0xff);
} if (jsonRoot["col3"].isInt()) {
WORD registerAddr = (WORD)jsonRoot["col3"].asInt();
config_config.units[uid].yxs[point].m_param[1] = (registerAddr & 0xff);
config_config.units[uid].yxs[point].m_param[2] = ((registerAddr >> 8) & 0xff);
} else {
config_config.units[uid].yxs[point].m_param[1] = 0;
config_config.units[uid].yxs[point].m_param[2] = 0;
}
break;
case POINT_TYPE_YC:
if (point >= config_config.units[uid].yccount) return FALSE;
if (jsonRoot["col1"].isString()) {
BYTE funcCode = (BYTE)atoi(jsonRoot["col1"].asCString());
config_config.units[uid].ycs[point].m_param[0] = funcCode;
} else if (jsonRoot["col1"].isInt()) {
BYTE funcCode = jsonRoot["col1"].asInt();
config_config.units[uid].ycs[point].m_param[0] = funcCode;
} else {
config_config.units[uid].ycs[point].m_param[0] = 0;
}
if (jsonRoot["col3"].isString()) {
BYTE dataType = (BYTE)atoi(jsonRoot["col3"].asCString());
config_config.units[uid].ycs[point].m_param[4] = dataType;
if (dataType == 2 || dataType == 8) config_config.units[uid].ycs[point].m_param[3] = 1;
else config_config.units[uid].ycs[point].m_param[3] = 2;
} else if (jsonRoot["col3"].isInt()) {
BYTE dataType = jsonRoot["col3"].asInt();
config_config.units[uid].ycs[point].m_param[4] = dataType;
if (dataType == 2 || dataType == 8) config_config.units[uid].ycs[point].m_param[3] = 1;
else config_config.units[uid].ycs[point].m_param[3] = 2;
} else {
config_config.units[uid].ycs[point].m_param[4] = 0;
config_config.units[uid].ycs[point].m_param[3] = 1;
}
if (jsonRoot["col2"].isString()) {
BYTE signMark = (BYTE)atoi(jsonRoot["col2"].asCString());
config_config.units[uid].ycs[point].m_param[5] = signMark;
} else if (jsonRoot["col2"].isInt()) {
BYTE signMark = jsonRoot["col2"].asInt();
config_config.units[uid].ycs[point].m_param[5] = signMark;
} else {
config_config.units[uid].ycs[point].m_param[5] = 0;
}
if (jsonRoot["col4"].isString()) {
WORD registerAddr = (WORD)atoi(jsonRoot["col4"].asCString());
config_config.units[uid].ycs[point].m_param[1] = (registerAddr & 0xff);
config_config.units[uid].ycs[point].m_param[2] = ((registerAddr >> 8) & 0xff);
} else if (jsonRoot["col4"].isInt()) {
WORD registerAddr = (WORD)jsonRoot["col4"].asInt();
config_config.units[uid].ycs[point].m_param[1] = (registerAddr & 0xff);
config_config.units[uid].ycs[point].m_param[2] = ((registerAddr >> 8) & 0xff);
} else {
config_config.units[uid].ycs[point].m_param[1] = 0;
config_config.units[uid].ycs[point].m_param[2] = 0;
}
break;
case POINT_TYPE_YM:
if (point >= config_config.units[uid].ymcount) return FALSE;
if (jsonRoot["col1"].isString()) {
BYTE funcCode = (BYTE)atoi(jsonRoot["col1"].asCString());
config.units[uid].yms[point].m_param[0] = funcCode;
} else {
config.units[uid].yms[point].m_param[0] = 0;
}
if (jsonRoot["col2"].isString()) {
BYTE dataType = (BYTE)atoi(jsonRoot["col2"].asCString());
config.units[uid].yms[point].m_param[4] = dataType;
if (dataType == 0) config.units[uid].yms[point].m_param[3] = 1;
if (dataType == 7 || dataType == 8) config.units[uid].yms[point].m_param[3] = 4;
else config.units[uid].yms[point].m_param[3] = 2;
} else {
config.units[uid].yms[point].m_param[4] = 0;
config.units[uid].yms[point].m_param[3] = 1;
}
if (jsonRoot["col4"].isString()) {
WORD registerAddr = (WORD)atoi(jsonRoot["col4"].asCString());
config.units[uid].yms[point].m_param[1] = (registerAddr & 0xff);
config.units[uid].yms[point].m_param[2] = ((registerAddr >> 8) & 0xff);
} else {
config.units[uid].yms[point].m_param[1] = 0;
config.units[uid].yms[point].m_param[2] = 0;
}
break;
case POINT_TYPE_YK:
if (point >= config_config.units[uid].ykcount) return FALSE;
config_config.units[uid].yks[point].m_param[1] = 0;
config_config.units[uid].yks[point].m_param[2] = 0;
config_config.units[uid].yks[point].m_param[4] = 0xFF;
config_config.units[uid].yks[point].m_param[5] = 0xFF;
config_config.units[uid].yks[point].m_param[8] = 0xFF;
config_config.units[uid].yks[point].m_param[9] = 0xFF;
config_config.units[uid].yks[point].m_param[12] = 0xFF;
config_config.units[uid].yks[point].m_param[13] = 0xFF;
config_config.units[uid].yks[point].m_param[16] = 0xFF;
config_config.units[uid].yks[point].m_param[17] = 0xFF;
if (jsonRoot["col1"].isString()) {
BYTE funcCode = (BYTE)atoi(jsonRoot["col1"].asCString());
config_config.units[uid].yks[point].m_param[0] = funcCode;
} if (jsonRoot["col1"].isInt()) {
BYTE funcCode = (BYTE)jsonRoot["col1"].asInt();
config_config.units[uid].yks[point].m_param[0] = funcCode;
} else {
config_config.units[uid].yks[point].m_param[0] = 0;
}
if (jsonRoot["col4"].isString()) {
WORD registerAddr = (WORD)atoi(jsonRoot["col4"].asCString());
config_config.units[uid].yks[point].m_param[6] = (registerAddr & 0xff);
config_config.units[uid].yks[point].m_param[7] = ((registerAddr >> 8) & 0xff);
} if (jsonRoot["col4"].isInt()) {
WORD registerAddr = (WORD)jsonRoot["col4"].asInt();
config_config.units[uid].yks[point].m_param[6] = (registerAddr & 0xff);
config_config.units[uid].yks[point].m_param[7] = ((registerAddr >> 8) & 0xff);
} else {
config_config.units[uid].yks[point].m_param[6] = 0xFF;
config_config.units[uid].yks[point].m_param[7] = 0xFF;
}
if (jsonRoot["col6"].isString()) {
WORD closeVal = (WORD)atoi(jsonRoot["col6"].asCString());
config_config.units[uid].yks[point].m_param[10] = (closeVal & 0xff);
config_config.units[uid].yks[point].m_param[11] = ((closeVal >> 8) & 0xff);
} if (jsonRoot["col6"].isInt()) {
WORD closeVal = (WORD)jsonRoot["col6"].asInt();
config_config.units[uid].yks[point].m_param[10] = (closeVal & 0xff);
config_config.units[uid].yks[point].m_param[11] = ((closeVal >> 8) & 0xff);
} else {
config_config.units[uid].yks[point].m_param[10] = 0xFF;
config_config.units[uid].yks[point].m_param[11] = 0xFF;
}
if (jsonRoot["col8"].isString()) {
WORD registerAddr = (WORD)atoi(jsonRoot["col8"].asCString());
config_config.units[uid].yks[point].m_param[14] = (registerAddr & 0xff);
config_config.units[uid].yks[point].m_param[15] = ((registerAddr >> 8) & 0xff);
} if (jsonRoot["col8"].isInt()) {
WORD registerAddr = (WORD)jsonRoot["col8"].asInt();
config_config.units[uid].yks[point].m_param[14] = (registerAddr & 0xff);
config_config.units[uid].yks[point].m_param[15] = ((registerAddr >> 8) & 0xff);
} else {
config_config.units[uid].yks[point].m_param[14] = 0xFF;
config_config.units[uid].yks[point].m_param[15] = 0xFF;
}
if (jsonRoot["col10"].isString()) {
WORD openVal = (WORD)atoi(jsonRoot["col10"].asCString());
config_config.units[uid].yks[point].m_param[18] = (openVal & 0xff);
config_config.units[uid].yks[point].m_param[19] = ((openVal >> 8) & 0xff);
} if (jsonRoot["col10"].isInt()) {
WORD openVal = (WORD)jsonRoot["col10"].asInt();
config_config.units[uid].yks[point].m_param[18] = (openVal & 0xff);
config_config.units[uid].yks[point].m_param[19] = ((openVal >> 8) & 0xff);
} else {
config_config.units[uid].yks[point].m_param[18] = 0xFF;
config_config.units[uid].yks[point].m_param[19] = 0xFF;
}
break;
case POINT_TYPE_YT:
if (point >= config_config.units[uid].ytcount) return FALSE;
config_config.units[uid].yts[point].m_param[2] = 0;
config_config.units[uid].yts[point].m_param[4] = 0xFF;
config_config.units[uid].yts[point].m_param[5] = 0xFF;
config_config.units[uid].yts[point].m_param[8] = 0xFF;
config_config.units[uid].yts[point].m_param[9] = 0xFF;
if (jsonRoot["col1"].isString()) {
BYTE nSetType = (BYTE)atoi(jsonRoot["col1"].asCString());
config_config.units[uid].yts[point].m_param[0] = nSetType;
} if (jsonRoot["col1"].isInt()) {
BYTE nSetType = (BYTE)jsonRoot["col1"].asInt();
config_config.units[uid].yts[point].m_param[0] = nSetType;
} else {
config_config.units[uid].yts[point].m_param[0] = 0;
}
if (jsonRoot["col2"].isString()) {
BYTE funcCode = (BYTE)atoi(jsonRoot["col2"].asCString());
config_config.units[uid].yts[point].m_param[1] = funcCode;
} if (jsonRoot["col2"].isInt()) {
BYTE funcCode = (BYTE)jsonRoot["col2"].asInt();
config_config.units[uid].yts[point].m_param[1] = funcCode;
} else {
config_config.units[uid].yts[point].m_param[1] = 0;
}
if (jsonRoot["col5"].isString()) {
WORD registerAddr = (WORD)atoi(jsonRoot["col5"].asCString());
config_config.units[uid].yts[point].m_param[6] = (registerAddr & 0xff);
config_config.units[uid].yts[point].m_param[7] = ((registerAddr >> 8) & 0xff);
} if (jsonRoot["col5"].isInt()) {
WORD registerAddr = (WORD)jsonRoot["col5"].asInt();
config_config.units[uid].yts[point].m_param[6] = (registerAddr & 0xff);
config_config.units[uid].yts[point].m_param[7] = ((registerAddr >> 8) & 0xff);
} else {
config_config.units[uid].yts[point].m_param[6] = 0xFF;
config_config.units[uid].yts[point].m_param[7] = 0xFF;
}
break;
default: break;
}
return TRUE;
}
2024-07-19 17:28:02 +08:00
static bool dealConfigFile(const Json::Value jsonRoot)
{
2024-08-09 08:50:19 +08:00
bool result = false;
2024-07-19 17:28:02 +08:00
do {
2024-08-09 08:50:19 +08:00
FILE* pf = fopen("aaa.json", "w+");
if (pf) {
fwrite(jsonRoot.toStyledString().c_str(), jsonRoot.toStyledString().length(), 1, pf);
fclose(pf);
}
2024-07-19 17:28:02 +08:00
if (!configInitializeMemory()) {
vLog(LOG_ERROR, "Fail initialize memory!\n");
break;
}
if (!jsonRoot["nodeId"].isString()) {
vLog(LOG_ERROR, "配置文件格式错误缺少节点ID的配置信息请检查。\n");
break;
}
2024-08-09 08:50:19 +08:00
if (jsonRoot["version"].isNull()) {
vLog(LOG_WARN, "配置文件格式错误,缺少版本信息,请检查。\n");
}
if (jsonRoot["version"].isInt()) {
snprintf(config_system32.version, sizeof(config_system32.version), "%d", jsonRoot["version"].asInt());
} else if (jsonRoot["version"].isString()) {
2024-09-24 15:59:22 +08:00
snprintf(config_system32.version, sizeof(config_system32.version), "%s", jsonRoot["version"].asCString());
2024-08-09 08:50:19 +08:00
}
2024-09-24 15:59:22 +08:00
2024-07-19 17:28:02 +08:00
//更新节点配置
config_nodes.m_node[0].m_netnode_no = 0;
config_nodes.m_node[0].m_tcitype = 1;
config_nodes.m_node[0].m_target_addr = INADDR_LOOPBACK;
config_nodes.m_node[0].m_target_port = 15000;
snprintf(config_nodes.m_node[0].m_machine_name, sizeof(config_nodes.m_node[0].m_machine_name), "%s", jsonRoot["nodeId"].asCString());
2024-09-24 15:59:22 +08:00
//更新链路配置文件
const Json::Value links = jsonRoot["links"];
int count = links.size();
int uartId = 0;
//m_gLinkIDs.clear();
uid2pid_map.clear();
for (int i = 0; i < count; i++) {
const Json::Value link = links[i];
config_config.processes[i].state = TRUE;
config_config.processes[i].type = MASTER_UNIT;
config_config.processes[i].time_gap = 300; //默认参数
config_config.processes[i].poll_gap = 5;
config_config.processes[i].mode = PROCESS_MODE_MASTER;
if (link["linkName"].isString()) {
snprintf(config_config.processes[i].name, sizeof(config_config.processes[i].name), "%s", link["linkName"].asCString());
}
if (link["linkId"].isString()) {
config_config.processes[i].irn = strtoll(link["linkId"].asCString(), NULL, 10);
}
if (link["protocol"].isInt()) {
config_config.processes[i].proto = link["protocol"].asInt();
}
//处理链路参数,根据协议参数的不同来处理
const Json::Value params = link["params"];
if (!params.isNull()) {
switch (config_config.processes[i].proto) {
case PROTOCOL_HOST_MODBUS_RTU:
processUartParam(params, uartId);
config_config.processes[i].order = uartId++;
break;
case PROTOCOL_HOST_MODBUS_TCP:
case PROTOCOL_HOST_MODBUS_RTU_TCP:
processNetworkParam(params, i);
break;
case PROTOCOL_HOST_IEC104:
processHostIEC104ProcessParam(params, i);
break;
}
}
//处理链接设备
const Json::Value devices = link["devices"];
if (devices.isArray()) {
int size = devices.size();
for (int j = 0; j < size; j++) {
std::string id = devices[j].asCString();
if (uid2pid_map.find(id) == uid2pid_map.end()) {
uid2pid_map.insert(uid2pidmap::value_type(id, i));
}
}
}
}
2024-07-19 17:28:02 +08:00
//更新设备列表
const Json::Value equipments = jsonRoot["equipments"];
{
long yxorder = 0, ycorder = 0, ymorder = 0, ykorder = 0, ytorder = 0;
char dbyxname[512];
snprintf(dbyxname, sizeof(dbyxname), "%s/%s", configpath, FILE_DATABASE_YX_STATIC);
FILE *pfdbyxname = fopen(dbyxname, "wb+");
char dbycname[512];
snprintf(dbycname, sizeof(dbycname), "%s/%s", configpath, FILE_DATABASE_YC_STATIC);
FILE *pfdbycname = fopen(dbycname, "wb+");
char dbymname[512];
snprintf(dbymname, sizeof(dbymname), "%s/%s", configpath, FILE_DATABASE_YM_STATIC);
FILE *pfdbymname = fopen(dbymname, "wb+");
char dbykname[512];
snprintf(dbykname, sizeof(dbykname), "%s/%s", configpath, FILE_DATABASE_YK_STATIC);
FILE *pfdbykname = fopen(dbykname, "wb+");
char dbytname[512];
snprintf(dbytname, sizeof(dbytname), "%s/%s", configpath, FILE_DATABASE_YT_STATIC);
FILE *pfdbytname = fopen(dbytname, "wb+");
int count = equipments.size();
for (int i = 0; i < count; i++) {
const Json::Value equipment = equipments[i];
int uid = i;
2024-09-24 15:59:22 +08:00
short pid = -1;
2024-07-19 17:28:02 +08:00
2024-08-09 08:50:19 +08:00
snprintf(config_static_units[uid].name, sizeof(config_static_units[uid].name), "device_%d", uid);
snprintf(config_static_units[uid].model, sizeof(config_static_units[uid].model), "model_%d", uid);
2024-07-19 17:28:02 +08:00
snprintf(config_static_units[uid].manufacturerId, sizeof(config_static_units[uid].manufacturerId), "%s", "iss");
2024-08-09 08:50:19 +08:00
std::string id = "";
std::string address = "";
2024-07-19 17:28:02 +08:00
if (equipment["id"].isString()) {
2024-08-09 08:50:19 +08:00
id = equipment["id"].asString();
2024-07-19 17:28:02 +08:00
snprintf(config_static_units[uid].deviceId, sizeof(config_static_units[uid].deviceId), "%s", id.c_str());
} else {
2024-08-09 08:50:19 +08:00
snprintf(config_static_units[uid].deviceId, sizeof(config_static_units[uid].deviceId), "iss_%d", uid);
}
if (equipment["addr"].isString()) {
address = equipment["addr"].asString();
}
2024-09-24 15:59:22 +08:00
if (uid2pid_map.find(id) != uid2pid_map.end()) {
pid = uid2pid_map[id];
if (pid < 0 || pid >= PROCESSES_NUM) continue;
for (int u = 0; u < PROCESS_UNIT_NUM; u++) {
if (config_config.processes[pid].units[u] < 0) {
config_config.processes[pid].units[u] = uid;
break;
}
}
//根据协议修改地址
if (address != "") {
BYTE addrType = ADDR_TYPE_NORMAL; //根据协议设定单元地址类型
switch (config_config.processes[pid].proto) {
case PROTOCOL_HOST_MODBUS_RTU:
break;
case PROTOCOL_HOST_MODBUS_TCP:
case PROTOCOL_HOST_MODBUS_RTU_TCP:
addrType = ADDR_TYPE_IPV4;
break;
case PROTOCOL_HOST_IEC104:
addrType = ADDR_TYPE_IPV4_FACNO;
break;
}
if (addrType == ADDR_TYPE_HEX) {
StringToHex(address.c_str(), config_config.units[uid].addr);
} else if (addrType == ADDR_TYPE_IPV4) {
DWORD addr;
inet_pton(AF_INET, address.c_str(), (struct in_addr*)&addr);
memcpy(config_config.units[uid].addr, &addr, sizeof(addr));
} else if (addrType == ADDR_TYPE_IPV4_FACNO) {
std::vector<std::string> tokens = split(address, ':');
if (tokens.size() >= 2) {
DWORD addr;
inet_pton(AF_INET, tokens.at(0).c_str(), (struct in_addr*)&addr);
memcpy(config_config.units[uid].addr, &addr, sizeof(addr));
addr = (DWORD)atoi(tokens.at(1).c_str());
memcpy(&config_config.units[uid].addr[4], &addr, sizeof(addr));
} else {
DWORD addr;
inet_pton(AF_INET, tokens.at(0).c_str(), (struct in_addr*)&addr);
memcpy(config_config.units[uid].addr, &addr, sizeof(addr));
addr = 1;
memcpy(&config_config.units[uid].addr[4], &addr, sizeof(addr));
}
} else {
DWORD addr = (DWORD)atoi(address.c_str());
memcpy(config_config.units[uid].addr, &addr, sizeof(addr));
}
}
2024-08-09 08:50:19 +08:00
} else {
2024-09-24 15:59:22 +08:00
vLog(LOG_DEBUG, "该链路上连接的设备ID<%s>不在设备列表中,请检查后重新下发.\n", id.c_str());
2024-07-08 10:27:17 +08:00
}
2024-07-19 17:28:02 +08:00
attrvector yxs, ycs, yms, yks, yts;
const Json::Value attrs = equipment["attrs"];
if (!attrs.isNull()) {
int size = attrs.size();
for (int j = 0; j < size; j++) {
const Json::Value attr = attrs[j];
std::string type = "";
if (attr["type"].isString()) type = attr["type"].asString();
struct_attr name_param;
name_param.name = "";
if (attr["name"].isString()) name_param.name = attr["name"].asString();
if (attr["params"].isObject()) name_param.value = attr["params"];
if (type == "yc") ycs.push_back(name_param);
else if (type == "yx") yxs.push_back(name_param);
else if (type == "ym") yms.push_back(name_param);
}
}
const Json::Value services = equipment["services"];
if (!services.isNull()) {
int size = services.size();
for (int j = 0; j < size; j++) {
const Json::Value service = services[j];
std::string type = "";
if (service["type"].isString()) type = service["type"].asString();
struct_attr name_param;
name_param.name = "";
if (service["name"].isString()) name_param.name = service["name"].asString();
if (service["params"].isObject()) name_param.value = service["params"];
if (type == "yk") yks.push_back(name_param);
else if (type == "yt") yts.push_back(name_param);
}
}
2024-08-09 08:50:19 +08:00
config_config.units[uid].value = SPI_ON;
config_config.units[uid].softdog = UNIT_WATCHDOG_TIME;
2024-07-19 17:28:02 +08:00
config_config.units[uid].state = TRUE;
config_config.units[uid].type = MASTER_UNIT;
config_config.units[uid].yxcount = yxs.size();
config_config.units[uid].yccount = ycs.size();
config_config.units[uid].ymcount = yms.size();
config_config.units[uid].ykcount = yks.size();
config_config.units[uid].ytcount = yts.size();
if (config_config.units[uid].yccount > 0) {
config_config.units[uid].ycs = new struUnitYC[config_config.units[uid].yccount];
if (NULL != config_config.units[uid].ycs) {
memset(config_config.units[uid].ycs, 0, sizeof(struUnitYC) * config_config.units[uid].yccount);
for (int k = 0; k < config_config.units[uid].yccount; k++) {
snprintf(config_config.units[uid].ycs[k].name, sizeof(config_config.units[uid].ycs[k].name), "%s", ycs[k].name.c_str());
config_config.units[uid].ycs[k].order = ycorder++;
2024-08-09 08:50:19 +08:00
config_config.units[uid].ycs[k].value = 0;
config_config.units[uid].ycs[k].qds = 0x80; //默认为无效
2024-07-19 17:28:02 +08:00
config_config.units[uid].ycs[k].factor = 1;
config_config.units[uid].ycs[k].change_pos = 2;
config_config.units[uid].ycs[k].coef = 1.0f;
config_config.units[uid].ycs[k].base = 0;
config_config.units[uid].ycs[k].upBound = 9999999.999f;
config_config.units[uid].ycs[k].lowBound = -9999999.999f;
config_config.units[uid].ycs[k].limit1Enable = FALSE;
config_config.units[uid].ycs[k].limit1Low = 0;
config_config.units[uid].ycs[k].limit1High = 0.0f;
config_config.units[uid].ycs[k].limit2Enable = FALSE;
config_config.units[uid].ycs[k].limit2Low = 0;
config_config.units[uid].ycs[k].limit2High = 0.0f;
Json::Value param = ycs[k].value;
if (!param.isNull()) {
if (param["coef"].isDouble()) config_config.units[uid].ycs[k].coef = param["coef"].asFloat();
if (param["base"].isDouble()) config_config.units[uid].ycs[k].base = param["base"].asFloat();
if (param["upBound"].isDouble()) config_config.units[uid].ycs[k].upBound = param["upBound"].asFloat();
if (param["lowBound"].isDouble()) config_config.units[uid].ycs[k].lowBound = param["lowBound"].asFloat();
if (param["limit1Enable"].isInt()) config_config.units[uid].ycs[k].limit1Enable = param["limit1Enable"].asInt();
if (param["limit2Enable"].isInt()) config_config.units[uid].ycs[k].limit2Enable = param["limit2Enable"].asInt();
if (param["limit1Low"].isDouble()) config_config.units[uid].ycs[k].limit1Low = param["limit1Low"].asFloat();
if (param["limit2Low"].isDouble()) config_config.units[uid].ycs[k].limit2Low = param["limit2Low"].asFloat();
if (param["limit1High"].isDouble()) config_config.units[uid].ycs[k].limit1High = param["limit1High"].asFloat();
if (param["limit2High"].isDouble()) config_config.units[uid].ycs[k].limit2High = param["limit2High"].asFloat();
2024-09-24 15:59:22 +08:00
switch (config_config.processes[pid].proto) {
case PROTOCOL_HOST_MODBUS_RTU:
case PROTOCOL_HOST_MODBUS_TCP:
case PROTOCOL_HOST_MODBUS_RTU_TCP:
processModbusPointParam(param, uid, k, POINT_TYPE_YC);
break;
case PROTOCOL_HOST_IEC104:
break;
}
2024-07-19 17:28:02 +08:00
}
if (config_config.units[uid].type == MASTER_UNIT) {
config_database.ycs[config_config.units[uid].ycs[k].order].coef = config_config.units[uid].ycs[k].coef;
config_database.ycs[config_config.units[uid].ycs[k].order].base = config_config.units[uid].ycs[k].base;
}
if (pfdbycname) {
fseek(pfdbycname, sizeof(struYCStatic) * config_config.units[uid].ycs[k].order, SEEK_SET);
fwrite(ycs[k].name.c_str(), (MAX_NAME_SIZE << 2), 1, pfdbycname);
}
2024-07-08 10:27:17 +08:00
}
}
2024-07-19 17:28:02 +08:00
}
if (config_config.units[uid].ymcount > 0) {
config_config.units[uid].yms = new struUnitYM[config_config.units[uid].ymcount];
if (NULL != config_config.units[uid].yms) {
memset(config_config.units[uid].yms, 0, sizeof(struUnitYM) * config_config.units[uid].ymcount);
for (int k = 0; k < config_config.units[uid].ymcount; k++) {
snprintf(config_config.units[uid].yms[k].name, sizeof(config_config.units[uid].yms[k].name), "%s", yms[k].name.c_str());
config_config.units[uid].yms[k].order = ymorder++;
2024-08-09 08:50:19 +08:00
config_config.units[uid].yms[k].value = 0;
2024-07-19 17:28:02 +08:00
config_config.units[uid].yms[k].coef = 1.0f;
config_config.units[uid].yms[k].base = 0;
2024-09-24 15:59:22 +08:00
Json::Value param = yms[k].value;
if (!param.isNull()) {
switch (config_config.processes[pid].proto) {
case PROTOCOL_HOST_MODBUS_RTU:
case PROTOCOL_HOST_MODBUS_TCP:
case PROTOCOL_HOST_MODBUS_RTU_TCP:
processModbusPointParam(param, uid, k, POINT_TYPE_YM);
break;
case PROTOCOL_HOST_IEC104:
break;
}
}
2024-07-19 17:28:02 +08:00
if (config_config.units[uid].type == MASTER_UNIT) {
config_database.yms[config_config.units[uid].yms[k].order].coef = config_config.units[uid].yms[k].coef;
config_database.yms[config_config.units[uid].yms[k].order].base = config_config.units[uid].yms[k].base;
}
2024-07-08 10:27:17 +08:00
2024-07-19 17:28:02 +08:00
if (pfdbymname) {
fseek(pfdbymname, sizeof(struYMStatic) * config_config.units[uid].yms[k].order, SEEK_SET);
fwrite(yms[k].name.c_str(), (MAX_NAME_SIZE << 2), 1, pfdbymname);
}
}
}
}
if (config_config.units[uid].ykcount > 0) {
config_config.units[uid].yks = new struUnitYK[config_config.units[uid].ykcount];
if (NULL != config_config.units[uid].yks) {
memset(config_config.units[uid].yks, 0, sizeof(struUnitYK) * config_config.units[uid].ykcount);
for (int k = 0; k < config_config.units[uid].ykcount; k++) {
snprintf(config_config.units[uid].yks[k].name, sizeof(config_config.units[uid].yks[k].name), "%s", yks[k].name.c_str());
config_config.units[uid].yks[k].order = ykorder++;
2024-09-24 15:59:22 +08:00
Json::Value param = yks[k].value;
if (!param.isNull()) {
switch (config_config.processes[pid].proto) {
case PROTOCOL_HOST_MODBUS_RTU:
case PROTOCOL_HOST_MODBUS_TCP:
case PROTOCOL_HOST_MODBUS_RTU_TCP:
processModbusPointParam(param, uid, k, POINT_TYPE_YK);
break;
case PROTOCOL_HOST_IEC104:
break;
}
}
2024-07-19 17:28:02 +08:00
if (pfdbykname) {
fseek(pfdbykname, sizeof(struYKStatic) * config_config.units[uid].yks[k].order, SEEK_SET);
fwrite(yks[k].name.c_str(), (MAX_NAME_SIZE << 2), 1, pfdbykname);
}
}
}
}
if (config_config.units[uid].ytcount > 0) {
config_config.units[uid].yts = new struUnitYT[config_config.units[uid].ytcount];
if (NULL != config_config.units[uid].yts) {
memset(config_config.units[uid].yts, 0, sizeof(struUnitYT) * config_config.units[uid].ytcount);
for (int k = 0; k < config_config.units[uid].ytcount; k++) {
snprintf(config_config.units[uid].yts[k].name, sizeof(config_config.units[uid].yts[k].name), "%s", yts[k].name.c_str());
config_config.units[uid].yts[k].order = ytorder++;
2024-09-24 15:59:22 +08:00
Json::Value param = yts[k].value;
if (!param.isNull()) {
switch (config_config.processes[pid].proto) {
case PROTOCOL_HOST_MODBUS_RTU:
case PROTOCOL_HOST_MODBUS_TCP:
case PROTOCOL_HOST_MODBUS_RTU_TCP:
processModbusPointParam(param, uid, k, POINT_TYPE_YT);
break;
case PROTOCOL_HOST_IEC104:
break;
}
}
2024-07-19 17:28:02 +08:00
if (pfdbytname) {
fseek(pfdbytname, sizeof(struYTStatic) * config_config.units[uid].yts[k].order, SEEK_SET);
fwrite(yts[k].name.c_str(), (MAX_NAME_SIZE << 2), 1, pfdbytname);
}
}
}
}
if (config_config.units[uid].yxcount > 0) {
config_config.units[uid].yxs = new struUnitYX[config_config.units[uid].yxcount];
if (NULL != config_config.units[uid].yxs) {
memset(config_config.units[uid].yxs, 0, sizeof(struUnitYX) * config_config.units[uid].yxcount);
for (int k = 0; k < config_config.units[uid].yxcount; k++) {
snprintf(config_config.units[uid].yxs[k].name, sizeof(config_config.units[uid].yxs[k].name), "%s", yxs[k].name.c_str());
config_config.units[uid].yxs[k].order = yxorder++;
2024-08-09 08:50:19 +08:00
config_config.units[uid].yxs[k].value = 0;
config_config.units[uid].yxs[k].qds = 0x80; //默认为无效
2024-07-19 17:28:02 +08:00
config_config.units[uid].yxs[k].invert = 0;
config_database.yxs[config_config.units[uid].yxs[k].order].auto_reset = 0;
Json::Value param = yxs[k].value;
if (!param.isNull()) {
if (param["invert"].asInt()) config_config.units[uid].yxs[k].invert = param["invert"].asInt();
2024-09-24 15:59:22 +08:00
switch (config_config.processes[pid].proto) {
case PROTOCOL_HOST_MODBUS_RTU:
case PROTOCOL_HOST_MODBUS_TCP:
case PROTOCOL_HOST_MODBUS_RTU_TCP:
processModbusPointParam(param, uid, k, POINT_TYPE_YX);
break;
case PROTOCOL_HOST_IEC104:
break;
}
}
if (pfdbyxname) {
fseek(pfdbyxname, sizeof(struYKStatic) * config_config.units[uid].yxs[k].order, SEEK_SET);
fwrite(yxs[k].name.c_str(), (MAX_NAME_SIZE << 2), 1, pfdbyxname);
2024-07-19 17:28:02 +08:00
}
}
}
2024-07-08 10:27:17 +08:00
}
}
2024-07-19 17:28:02 +08:00
if (pfdbyxname) fclose(pfdbyxname);
if (pfdbycname) fclose(pfdbycname);
if (pfdbymname) fclose(pfdbymname);
if (pfdbykname) fclose(pfdbykname);
if (pfdbytname) fclose(pfdbytname);
2024-07-08 10:27:17 +08:00
}
2024-07-19 17:28:02 +08:00
2024-09-24 15:59:22 +08:00
#if 0
{
int pid = PROCESSES_NUM - 1;
int uid = UNIT_NUM - 1;
config_config.processes[pid].state = TRUE;
snprintf(config_config.processes[pid].name, sizeof(config_config.processes[pid].name), "localDebug");
config_config.processes[pid].type = TRUE;
config_config.processes[pid].time_accept = TRUE; //accept set time command from this proc
config_config.processes[pid].proto = PROTOCOL_LOCAL_DEBUG;
config_config.processes[pid].order = 0; //CARD or PORT order
config_config.processes[pid].mode = 1; //slave mode or master mode or duplex mode
config_config.processes[pid].time_gap = 300; //send out time from this proc 18.2c/s
config_config.processes[pid].poll_gap = 5; //send out command 18.2c/s
config_config.processes[pid].softdog = 0; //software watchdog counter
config_config.processes[pid].units[0] = uid;
config_config.processes[pid].option.network.ignored_source = TRUE;
config_config.processes[pid].option.network.socket_type = SOCK_STREAM;
config_config.processes[pid].option.network.bind_addr = INADDR_ANY;
config_config.processes[pid].option.network.bind_port = 9000;
config_config.processes[pid].option.network.target_addr = INADDR_ANY;
config_config.processes[pid].option.network.target_port = 0;
config_config.units[uid].state = TRUE;
config_config.units[uid].type = 1;
config_config.units[uid].addr[0] = 0;
memset(config_config.units[uid].m_param, 0, sizeof(config_config.units[uid].m_param)); //每个单元有256个字节的参数。
config_config.units[uid].yxcount = 0;
config_config.units[uid].yccount = 0;
config_config.units[uid].ymcount = 0;
config_config.units[uid].ykcount = 0;
config_config.units[uid].ytcount = 0;
config_config.units[uid].softdog = 0;
config_config.units[uid].yxbwload = 0;
config_config.units[uid].soeload = 0;
config_config.units[uid].ycbwload = 0;
config_config.units[uid].value = 0; //单元状态
}
#endif
2024-07-19 17:28:02 +08:00
//保存数据
configWriteNodeCFG();
configWriteSystemCFG();
configWriteHardwareCFG();
configWriteProcessCFG();
configWriteUnitCFG();
configWriteDatabaseCFG();
//保存静态文件
configWriteStaticUnitCFG(); //units.sta
2024-08-09 08:50:19 +08:00
result = true;
2024-07-08 10:27:17 +08:00
} while (0);
2024-08-09 08:50:19 +08:00
//重启application
if (result) {
g_dataAcquisitionReload = true;
} else {
vLog(LOG_WARN, "配置文件读取失败,请检查后下发!\n");
}
2024-09-24 15:59:22 +08:00
return true;
2024-07-08 10:27:17 +08:00
}
2024-07-19 17:28:02 +08:00
bool OnReceivedSystemAction(noPollConn* conn, const std::string cmdId, const std::string cmd, const Json::Value data)
2024-07-08 10:27:17 +08:00
{
2024-07-19 17:28:02 +08:00
do {
if (cmd == "configUpdate") { //配置更新
g_traceId = cmdId;
dealConfigFile(data);
} else if (cmd == "deviceControl") {
g_traceId = cmdId; //response命令的traceId
OnReceivedDeviceCommand(data);
} else {
vLog(LOG_DEBUG, "command: %s is not supported.\n", cmd.c_str());
}
} while (0);
return true;
2024-07-08 10:27:17 +08:00
}
2024-07-19 17:28:02 +08:00
void on_message(noPollConn* conn, const char *msg, const int size)
2024-07-08 10:27:17 +08:00
{
2024-07-19 17:28:02 +08:00
if (msg == NULL) return;
if (size <= 0) return;
2024-07-08 10:27:17 +08:00
2024-07-19 17:28:02 +08:00
Json::Value jsonRoot;
2024-07-08 10:27:17 +08:00
jsonRoot.clear();
std::string err;
Json::CharReaderBuilder builder;
Json::CharReader* reader(builder.newCharReader());
2024-08-09 08:50:19 +08:00
vLog(LOG_DEBUG, "Received: %s.\n", msg);
2024-07-08 10:27:17 +08:00
do {
2024-07-19 17:28:02 +08:00
if (!reader->parse(msg, msg + size, &jsonRoot, &err)) {
vLog(LOG_ERROR, "reader->parse(msg, msg + size, &jsonRoot, &err) error<%d,%s>。\n", errno, err.c_str());
2024-07-08 10:27:17 +08:00
break;
}
2024-07-19 17:28:02 +08:00
if (jsonRoot["cmd"].isNull()) {
vLog(LOG_ERROR, "json format lost cmd part.\n");
2024-07-08 10:27:17 +08:00
break;
}
2024-07-19 17:28:02 +08:00
if (jsonRoot["data"].isNull()) {
vLog(LOG_ERROR, "json format lost data part.\n");
2024-07-08 10:27:17 +08:00
break;
}
2024-07-19 17:28:02 +08:00
std::string cmd = jsonRoot["cmd"].asString();
std::string cmdId = jsonRoot["cmdId"].asString();
2024-09-24 15:59:22 +08:00
#if 0
2024-07-19 17:28:02 +08:00
Json::Int64 mtime = jsonRoot["time"].asInt64();
2024-09-24 15:59:22 +08:00
#endif
2024-07-19 17:28:02 +08:00
Json::Value datas = jsonRoot["data"];
OnReceivedSystemAction(conn, cmdId, cmd, datas);
2024-07-08 10:27:17 +08:00
} while (0);
}
2024-07-19 17:28:02 +08:00
void heart_beat(noPollConn* conn, int status)
2024-07-08 10:27:17 +08:00
{
//发送心跳报文
Json::Value payload;
payload["ttl"] = 30000;
payload["status"] = status;
2024-08-09 08:50:19 +08:00
if (status == 1) {
2024-07-08 10:27:17 +08:00
Json::Value jsonItem;
Json::Value jsonValue;
2024-08-09 08:50:19 +08:00
//for (int i = 0; i < static_cast<int>(m_gLinkIDs.size()); i++) {
2024-09-24 15:59:22 +08:00
for (int i = 0; i < PROCESSES_NUM - 1; i++) {
2024-07-19 17:28:02 +08:00
if (config.processes[i].state == TRUE) {
2024-08-09 08:50:19 +08:00
char linkId[32];
snprintf(linkId, sizeof(linkId), "%lld", config.processes[i].irn);
jsonValue["linkId"] = linkId;
2024-07-08 10:27:17 +08:00
jsonValue["online"] = (config.processes[i].softdog >= PROCESS_WATCHDOG_TIME) ? false : true;
jsonItem.append(jsonValue);
}
}
2024-07-19 17:28:02 +08:00
if (jsonItem.size() > 0) {
2024-07-08 10:27:17 +08:00
payload["links"] = jsonItem;
}
}
2024-07-19 17:28:02 +08:00
publish_sensor_data(conn, "", "heartbeat", payload);
2024-07-08 10:27:17 +08:00
}
2024-07-19 17:28:02 +08:00
bool publishinitDeviceData(noPollConn* conn, int uid)
{
if (uid < 0 || uid >= UNIT_NUM) return false;
2024-08-09 08:50:19 +08:00
if ((config.units[uid].state & 0x80) != 0x80) {
return false;
}
if ((config.units[uid].state & 0x40) == 0x40) { //该设备已经发送过初始化
return false;
}
2024-07-19 17:28:02 +08:00
Json::Value root;
Json::Value values;
2024-07-08 10:27:17 +08:00
2024-07-19 17:28:02 +08:00
int i;
int count = GetUnitYCCount(uid);
if (count) {
for (i = 0; i < count; i++) {
values[(const char *)config.units[uid].ycs[i].name] = GetUnitYCReal(uid, i);
}
}
count = GetUnitYMCount(uid);
if (count) {
for (i = 0; i < count; i++) {
values[(const char *)config.units[uid].yms[i].name] = GetUnitYMReal(uid, i);
}
}
count = GetUnitYXCount(uid);
if (count) {
for (i = 0; i < count; i++) {
values[(const char *)config.units[uid].yxs[i].name] = GetUnitYX(uid, i);
}
}
if (values.size()) {
root["deviceId"] = static_units[uid].deviceId;
root["values"] = values;
2024-08-09 08:50:19 +08:00
config.units[uid].state |= 0x40;
2024-07-19 17:28:02 +08:00
return publish_sensor_data(conn, "", "initDeviceData", root);
}
return false;
}
2024-08-09 08:50:19 +08:00
bool publishAnalogData(noPollConn* conn, int uid)
2024-07-08 10:27:17 +08:00
{
2024-08-09 08:50:19 +08:00
if (uid < 0 || uid >= UNIT_NUM) return false;
Json::Value root;
Json::Value values;
int count = GetUnitYCCount(uid);
if (count) {
for (int i = 0; i < count; i++) {
values[(const char *)config.units[uid].ycs[i].name] = GetUnitYCReal(uid, i);
2024-07-08 10:27:17 +08:00
}
2024-08-09 08:50:19 +08:00
}
if (values.size()) {
root["deviceId"] = static_units[uid].deviceId;
root["values"] = values;
return publish_sensor_data(conn, "", "analogData", root);
}
return false;
}
bool publishStateData(noPollConn* conn, int uid)
{
if (uid < 0 || uid >= UNIT_NUM) return false;
Json::Value root;
Json::Value values;
int count = GetUnitYXCount(uid);
if (count) {
for (int i = 0; i < count; i++) {
values[(const char *)config.units[uid].yxs[i].name] = GetUnitYX(uid, i);
2024-07-08 10:27:17 +08:00
}
}
2024-08-09 08:50:19 +08:00
if (values.size()) {
root["deviceId"] = static_units[uid].deviceId;
root["values"] = values;
return publish_sensor_data(conn, "", "stateData", root);
}
2024-07-19 17:28:02 +08:00
return false;
2024-07-08 10:27:17 +08:00
}
2024-08-09 08:50:19 +08:00
bool publishHistoryAnalogData(noPollConn* conn, int uid)
{
if (uid < 0 || uid >= UNIT_NUM) return false;
Json::Value root;
Json::Value values;
if (values.size()) {
root["deviceId"] = static_units[uid].deviceId;
root["values"] = values;
return publish_sensor_data(conn, "", "historyAnalogData", root);
}
return false;
}
bool publishHistoryStateData(noPollConn* conn, int uid)
{
if (uid < 0 || uid >= UNIT_NUM) return false;
Json::Value root;
Json::Value values;
if (values.size()) {
root["deviceId"] = static_units[uid].deviceId;
root["values"] = values;
return publish_sensor_data(conn, "", "historyStateData", root);
}
return false;
}
2024-07-08 10:27:17 +08:00
2024-10-14 20:26:21 +08:00
void releaseAllUnits(void)
{
for (int i = 0; i < UNIT_NUM; i++) {
if ((config.units[i].state & 0x01) != 0x01) continue;
config.units[i].state &= 0xBF; //0x40取反
}
}
2024-07-08 10:27:17 +08:00
#endif
2024-10-14 20:26:21 +08:00
pthread_mutex_t mutex;
2024-07-08 10:27:17 +08:00
2024-10-14 20:26:21 +08:00
void stop(int signo)
2024-07-08 10:27:17 +08:00
{
2024-10-14 20:26:21 +08:00
pthread_mutex_lock(&mutex);
int i;
2024-07-08 10:27:17 +08:00
2024-10-14 20:26:21 +08:00
vLog(LOG_ERROR, "cmg received exit signel(%d)\n", signo);
2024-07-08 10:27:17 +08:00
{
2024-10-14 20:26:21 +08:00
for (i = 0; i < PROCESSES_NUM; i++)
{
if (procs[i] != NULL)
{
procs[i]->Destroy();
delete procs[i];
procs[i] = NULL;
}
}
destroy_thread();
}
if (zlog_inited) zlog_fini();
2024-07-08 10:27:17 +08:00
2024-10-14 20:26:21 +08:00
signo = 0;
pthread_mutex_unlock(&mutex);
exit(signo);
2024-07-08 10:27:17 +08:00
}
2024-10-14 20:26:21 +08:00
2024-07-19 17:28:02 +08:00
void freeMem(void)
{
if (database.yxs) {
delete [] database.yxs;
database.yxs = NULL;
}
if (database.ycs) {
delete [] database.ycs;
database.ycs = NULL;
}
if (database.yms) {
delete [] database.yms;
database.yms = NULL;
}
if (database.yks) {
delete [] database.yks;
database.yks = NULL;
}
if (database.yts) {
delete [] database.yts;
database.yts = NULL;
}
for (int i = 0; i < UNIT_NUM; i++) {
if (config.units[i].yxs) {
delete [] config.units[i].yxs;
config.units[i].yxs = NULL;
}
if (config.units[i].ycs) {
delete [] config.units[i].ycs;
config.units[i].ycs = NULL;
}
if (config.units[i].yms) {
delete [] config.units[i].yms;
config.units[i].yms = NULL;
}
if (config.units[i].yks) {
delete [] config.units[i].yks;
config.units[i].yks = NULL;
}
if (config.units[i].yts) {
delete [] config.units[i].yts;
config.units[i].yts = NULL;
}
}
if (msgBuffer.buf) {
delete [] msgBuffer.buf;
msgBuffer.buf = NULL;
}
if (channelBuffer.buf) {
delete [] channelBuffer.buf;
channelBuffer.buf = NULL;
}
}
2024-07-08 10:27:17 +08:00
int main(int argc, char** argv)
{
int c;
BOOLEAN enable_auto_platform = TRUE;
2024-07-19 17:28:02 +08:00
char host[256] = {"127.0.0.1"};
int port = 7790;
char nodeId[128] = {"runyang_dn"};
char version[128] = {"v1.0"};
2024-07-08 10:27:17 +08:00
//获取可执行文件所在目录
const char default_config[] = "[global]\n"
"default format = \"%d.%ms [%-6V] - %m%n\"\n"
"[rules]\n"
"my_cat.* >stderr\n";
int rc = dzlog_init("./application.conf", "my_cat");
2024-07-19 17:28:02 +08:00
if (rc < 0) {
2024-07-08 10:27:17 +08:00
rc = dzlog_init(default_config, "my_cat");
2024-07-19 17:28:02 +08:00
if (rc < 0) {
zlog_inited = FALSE;
} else {
2024-07-08 10:27:17 +08:00
fprintf(stderr, "dzlog_init(\"./application.conf\", \"my_cat\") failed, load default config.\n");
zlog_inited = TRUE;
}
2024-07-19 17:28:02 +08:00
} else {
2024-07-08 10:27:17 +08:00
zlog_inited = TRUE;
}
pthread_mutex_init(&mutex, NULL);
static struct option long_options[] =
{
{ "directory", required_argument, NULL, 'd' },
{ "host", required_argument, NULL, 'h'},
{ "port", required_argument, NULL, 'p'},
2024-07-19 17:28:02 +08:00
{ "nodeId", required_argument, NULL, 'n' },
{ "version", required_argument, NULL, 'v'},
2024-07-08 10:27:17 +08:00
{ "help", no_argument, NULL, 'H' },
{ NULL, 0, NULL, 0 }
};
while (1)
{
int opt_index = 0;
2024-07-19 17:28:02 +08:00
c = getopt_long(argc, argv, "d:h:p:n:v:H", long_options, &opt_index);
2024-07-08 10:27:17 +08:00
if (c == -1) break;
switch (c)
{
case 'd':
snprintf(configpath, sizeof(configpath), "%s", optarg);
break;
case 'h':
snprintf(host, sizeof(host), "%s", optarg);
break;
case 'p':
port = strtol(optarg, NULL, 10);
break;
2024-07-19 17:28:02 +08:00
case 'n':
snprintf(nodeId, sizeof(nodeId), "%s", optarg);
2024-07-08 10:27:17 +08:00
break;
2024-07-19 17:28:02 +08:00
case 'v':
snprintf(version, sizeof(version), "%s", optarg);
2024-07-08 10:27:17 +08:00
break;
case '?':
case 'H':
vLog(LOG_DEBUG, "Usage: %s [OPTION]... \n"
" -d, --directory : set configuration file directory. Default is /data/config/rtufiles\n"
2024-07-19 17:28:02 +08:00
" -h, --host : ws ip. Default is localhost\n"
" -p, --port : ws port, default is 1883\n"
" -n, --nodeid : ws nodeId, default is runyang_dn\n"
" -v, --version : sw version, default is v1.0\n"
2024-07-08 10:27:17 +08:00
" -H, --help : print this usage\n", argv[0]);
return (EXIT_SUCCESS);
default:
vLog(LOG_DEBUG, "?? getopt returned character code 0%c ??\n", c);
}
}
2024-07-19 17:28:02 +08:00
2024-07-08 10:27:17 +08:00
signal(SIGHUP, stop);
signal(SIGQUIT, stop);
signal(SIGKILL, stop);
signal(SIGPIPE, stop);
signal(SIGSTOP, stop);
signal(SIGINT, stop);
signal(SIGILL, stop);
signal(SIGSEGV, stop);
signal(SIGTERM, stop);
signal(SIGABRT, stop);
signal(SIGFPE, stop);
2024-10-14 20:26:21 +08:00
#ifdef MAIN_FILE
2024-07-19 17:28:02 +08:00
noPollCtx *ctx = nopoll_ctx_new();
2024-08-09 08:50:19 +08:00
nopoll_log_enable(ctx, nopoll_false);
nopoll_log_color_enable(ctx, nopoll_false);
2024-07-19 17:28:02 +08:00
noPollConn *conn;
2024-08-09 08:50:19 +08:00
DWORD last_connect_sec = 0;
#else
2024-10-14 20:26:21 +08:00
noPollConn *conn = NULL;
CRYDevice ryDevice;
2024-07-19 17:28:02 +08:00
#endif
2024-10-14 20:26:21 +08:00
2024-07-19 17:28:02 +08:00
do {
2024-10-14 20:26:21 +08:00
#ifdef MAIN_FILE
2024-07-08 10:27:17 +08:00
int status = 2; //0 - 离线, 1 - 在线, 2 - 未配置
2024-10-14 20:26:21 +08:00
time_t last_sec = 0;
2024-07-08 10:27:17 +08:00
g_dataAcquisitionReload = false;
2024-10-14 20:26:21 +08:00
#endif
2024-07-08 10:27:17 +08:00
vLog(LOG_DEBUG, "system initialize...\n");
char szHostCode[128];
memset(szHostCode, '\0', sizeof(szHostCode));
2024-07-19 17:28:02 +08:00
if (!initialize_system(FALSE, FALSE, NULL, szHostCode)) {
2024-07-08 10:27:17 +08:00
vLog(LOG_ERROR, "system initialize error.\n");
2024-07-19 17:28:02 +08:00
if (enable_auto_platform) { //主动和平台链接
2024-07-08 10:27:17 +08:00
char szHostName[32] = "";
gethostname(szHostName, sizeof(szHostName));
nodes.m_node[0].m_netnode_no = 0;
nodes.m_node[0].m_tcitype = MASTER_TCI;
nodes.m_node[0].m_target_addr = INADDR_LOOPBACK;
nodes.m_node[0].m_target_port = 15000;
snprintf(nodes.m_node[0].m_machine_name, sizeof(nodes.m_node[0].m_machine_name), "%s", szHostName);
2024-07-19 17:28:02 +08:00
nodes.m_node[0].irn = 0; //没有配置
2024-07-08 10:27:17 +08:00
vLog(LOG_DEBUG, "nodes.m_node[0].m_machine_name is: %s\n", nodes.m_node[0].m_machine_name);
}
2024-07-19 17:28:02 +08:00
} else {
if (enable_auto_platform) { //增加协议和单元配置的数量统计
2024-10-14 20:26:21 +08:00
#ifdef MAIN_FILE
vLog(LOG_DEBUG, "configed node id is: %s.\n", nodes.m_node[0].m_machine_name);
snprintf(nodeId, sizeof(nodeId), "%s", nodes.m_node[0].m_machine_name);
if (system32.version[0] != '\0') {
snprintf(version, sizeof(version), "%s", system32.version);
} else {
snprintf(version, sizeof(version), "%s", "1");
2024-08-09 08:50:19 +08:00
}
2024-10-14 20:26:21 +08:00
unitname2service_map.clear();
2024-07-19 17:28:02 +08:00
for (int i = 0; i < UNIT_NUM; i++) {
if (config.units[i].state != TRUE) continue;
std::string unit_id = static_units[i].deviceId;
name2servicemap name2service_map;
for (int j = 0; j < config.units[i].ykcount; j++) {
std::string name = config.units[i].yks[j].name;
if (name2service_map.find(name) == name2service_map.end()) {
struct_service_item item;
item.type = CMD_CONTROL_OPERATION;
item.uid = i;
item.point = j;
item.order = config.units[i].yks[j].order;
name2service_map.insert(name2servicemap::value_type(name, item));
} else {
vLog(LOG_WARN, "同一个设备不能有两个相同的遥控名<%s>,请检查。\n", name.c_str());
2024-07-08 10:27:17 +08:00
}
}
2024-07-19 17:28:02 +08:00
for (int j = 0; j < config.units[i].ytcount; j++) {
std::string name = config.units[i].yts[j].name;
if (name2service_map.find(name) == name2service_map.end()) {
struct_service_item item;
item.type = CMD_CONTROL_SETTING;
item.uid = i;
item.point = j;
item.order = config.units[i].yts[j].order;
name2service_map.insert(name2servicemap::value_type(name, item));
} else {
vLog(LOG_WARN, "同一个设备不能有两个相同的遥调名<%s>,请检查。\n", name.c_str());
}
}
if (unitname2service_map.find(unit_id) == unitname2service_map.end()) {
unitname2service_map.insert(unitname2servicemap::value_type(unit_id, name2service_map));
} else {
vLog(LOG_WARN, "系统配置了两个相同的设备ID<%s>,请检查。\n", unit_id.c_str());
}
2024-07-08 10:27:17 +08:00
}
status = 1;
2024-10-14 20:26:21 +08:00
#endif
2024-07-08 10:27:17 +08:00
}
}
2024-07-19 17:28:02 +08:00
if (enable_auto_platform) {
2024-10-14 20:26:21 +08:00
#ifdef MAIN_FILE
2024-07-19 17:28:02 +08:00
//创建WS链接
if (ctx != NULL) {
2024-08-09 08:50:19 +08:00
nopoll_conn_connect_timeout(ctx, 50000);
2024-07-19 17:28:02 +08:00
char url[512];
char cPort[64];
2024-08-09 08:50:19 +08:00
snprintf(url, sizeof(url), "/node/%s/%s", nodeId, version);
2024-07-19 17:28:02 +08:00
snprintf(cPort, sizeof(cPort), "%d", port);
2024-08-09 08:50:19 +08:00
vLog(LOG_DEBUG, "%d here to connect:%s:%s.\n", __LINE__, host, cPort);
releaseAllUnits();
2024-07-19 17:28:02 +08:00
conn = nopoll_conn_new(ctx, host, cPort, NULL, url, NULL, NULL);
2024-09-24 15:59:22 +08:00
//last_connect_sec = system32.timers;
2024-08-09 08:50:19 +08:00
}
2024-10-14 20:26:21 +08:00
#else
conn = ryDevice.ry_init(host, port, nodeId, version);
2024-07-19 17:28:02 +08:00
#endif
2024-07-08 10:27:17 +08:00
}
unsigned int m_runCount = 0;
unsigned int count = 0;
unsigned int critical = 0;
CChangeMaster masterTci;
2024-10-14 20:26:21 +08:00
if (!masterTci.Init(conn)) {
2024-07-08 10:27:17 +08:00
break;
}
masterTci.MasterTciFirstRun();
2024-07-19 17:28:02 +08:00
while (TRUE) {
2024-07-08 10:27:17 +08:00
m_runCount++;
masterTci.MasterSend();
usleep(MASTER_TCI_SEND_INTERVAL);
2024-07-19 17:28:02 +08:00
if (MASTER_TCI == CChangeMaster::m_tcitype) {
if (m_runCount > count) {
2024-07-08 10:27:17 +08:00
count = m_runCount;
critical = 0;
2024-07-19 17:28:02 +08:00
} else {
2024-07-08 10:27:17 +08:00
critical++;
2024-07-19 17:28:02 +08:00
if (critical > 15) {
2024-07-08 10:27:17 +08:00
break;
}
}
2024-07-19 17:28:02 +08:00
if (enable_auto_platform) {
2024-10-14 20:26:21 +08:00
#ifdef MAIN_FILE
2024-08-09 08:50:19 +08:00
nopoll_bool isOk = nopoll_conn_is_ready(conn);
if (isOk) {
2024-09-24 15:59:22 +08:00
last_connect_sec = system32.timers;
2024-08-09 08:50:19 +08:00
int msg_count = 0;
noPollMsg *msg[40];
while ((msg[msg_count] = nopoll_conn_get_msg(conn)) != NULL) {
vLog(LOG_DEBUG, "recv length = %d, %d\n", nopoll_msg_get_payload_size(msg[msg_count]), nopoll_msg_is_final(msg[msg_count]));
if (nopoll_msg_is_final(msg[msg_count])) {
msg_count++;
break;
} else {
msg_count++;
}
2024-07-19 17:28:02 +08:00
}
2024-08-09 08:50:19 +08:00
if (msg_count > 0) {
int buffer_len;
2024-09-24 15:59:22 +08:00
BYTE *buffer = NULL;
if (websocket_msg_join(msg, msg_count, buffer, buffer_len)) {
if (buffer) {
on_message(conn, (const char *)buffer, buffer_len);
delete [] buffer;
buffer = NULL;
}
2024-08-09 08:50:19 +08:00
}
2024-07-19 17:28:02 +08:00
}
2024-08-09 08:50:19 +08:00
for (int i = 0; i < msg_count; i++) {
nopoll_msg_unref(msg[i]);
2024-07-19 17:28:02 +08:00
}
2024-08-09 08:50:19 +08:00
} else {
if (last_connect_sec > 0 && system32.timers > (last_connect_sec + 30)) {
nopoll_conn_connect_timeout(ctx, 50000);
char url[512];
char cPort[64];
snprintf(url, sizeof(url), "/node/%s/%s", nodeId, version);
snprintf(cPort, sizeof(cPort), "%d", port);
vLog(LOG_DEBUG, "%d here to connect:%s:%s.\n", __LINE__, host, cPort);
releaseAllUnits();
conn = nopoll_conn_new(ctx, host, cPort, NULL, url, NULL, NULL);
last_connect_sec = system32.timers;
}
}
2024-07-08 10:27:17 +08:00
BOOLEAN sec_changed = FALSE;
2024-07-19 17:28:02 +08:00
if (last_sec != (time_t)system32.timers) {
2024-07-08 10:27:17 +08:00
last_sec = system32.timers;
sec_changed = TRUE;
}
2024-07-19 17:28:02 +08:00
if (sec_changed) {
if ((last_sec % 20) == 0) {
heart_beat(conn, status);
2024-07-08 10:27:17 +08:00
}
2024-07-19 17:28:02 +08:00
}
for (int i = 0; i < UNIT_NUM; i++) {
2024-09-24 15:59:22 +08:00
if ((config.units[i].state & 0x01) != TRUE) continue;
2024-07-19 17:28:02 +08:00
MakeYKFrame(conn, i);
MakeYTFrame(conn, i);
if (sec_changed) {
2024-08-09 08:50:19 +08:00
publishinitDeviceData(conn, i);
2024-07-19 17:28:02 +08:00
if ((last_sec % 60) == 0) { //更新数据
2024-08-09 08:50:19 +08:00
publishAnalogData(conn, i);
publishStateData(conn, i);
2024-07-19 17:28:02 +08:00
}
2024-07-08 10:27:17 +08:00
}
}
2024-08-09 08:50:19 +08:00
#else
2024-10-14 20:26:21 +08:00
if (ryDevice.ry_run()) {
break;
}
2024-07-19 17:28:02 +08:00
#endif
2024-07-08 10:27:17 +08:00
}
}
2024-10-14 20:26:21 +08:00
#ifdef MAIN_FILE
2024-07-19 17:28:02 +08:00
if (g_dataAcquisitionReload) {
2024-07-08 10:27:17 +08:00
break;
}
2024-10-14 20:26:21 +08:00
#endif
2024-07-08 10:27:17 +08:00
}
2024-07-19 17:28:02 +08:00
if (critical > 15) {
2024-07-08 10:27:17 +08:00
vLog(LOG_ERROR, "unknow error.\n");
}
masterTci.ChangeDelete();
2024-07-19 17:28:02 +08:00
destroy_thread();
freeMem();
vLog(LOG_DEBUG, "App: dataAcquisition start reload.\n");
2024-08-09 08:50:19 +08:00
} while(1);
2024-07-08 10:27:17 +08:00
pthread_mutex_destroy(&mutex);
2024-07-19 17:28:02 +08:00
if (zlog_inited) zlog_fini();
2024-10-14 20:26:21 +08:00
#ifdef MAIN_FILE
2024-07-19 17:28:02 +08:00
nopoll_conn_close(conn);
nopoll_ctx_unref(ctx);
2024-10-14 20:26:21 +08:00
#else
ryDevice.ry_destroy();
2024-07-19 17:28:02 +08:00
#endif
2024-10-14 20:26:21 +08:00
2024-07-08 10:27:17 +08:00
vLog(LOG_DEBUG, "system stop okay.\n");
return EXIT_SUCCESS;
}