This commit is contained in:
高云鹏 2024-11-26 10:52:46 +08:00
commit bd221860c7
26 changed files with 1078 additions and 370 deletions

View File

@ -5,6 +5,8 @@ CRYDevice::CRYDevice()
{ {
ctx = NULL; ctx = NULL;
conn = NULL; conn = NULL;
msg_count = 0;
} }
CRYDevice::~CRYDevice() CRYDevice::~CRYDevice()
@ -1788,7 +1790,7 @@ BOOLEAN CRYDevice::processSubModbusPointParam(const Json::Value jsonRoot, int ui
{ {
if (uid < 0 || uid >= UNIT_NUM) return FALSE; if (uid < 0 || uid >= UNIT_NUM) return FALSE;
if (point < 0) return FALSE; if (point < 0) return FALSE;
vLog(LOG_DEBUG, "%s", jsonRoot.toStyledString().c_str()); //vLog(LOG_DEBUG, "%s", jsonRoot.toStyledString().c_str());
switch (type) switch (type)
{ {
case POINT_TYPE_YX: case POINT_TYPE_YX:
@ -1849,16 +1851,38 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
int count = links.size(); int count = links.size();
int uartId = 0; int uartId = 0;
//m_gLinkIDs.clear(); int uid = 0;
uid2pid_map.clear(); uid2pid_map.clear();
long yxorder = 0, ycorder = 0, ymorder = 0, ykorder = 0, ytorder = 0;
string2intmap map_yxorders, map_ycorders, map_ymorders, map_ykorders, map_ytorders;
pid2attrvectormap map_pid2attrserice;
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+");
map_yxorders.clear(); map_ycorders.clear(); map_ymorders.clear(); map_ykorders.clear(); map_ytorders.clear();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
const Json::Value link = links[i]; const Json::Value link = links[i];
config_config.processes[i].state = TRUE; config_config.processes[i].state = TRUE;
config_config.processes[i].type = MASTER_UNIT;
config_config.processes[i].time_gap = 300; //默认参数 config_config.processes[i].time_gap = 300; //默认参数
config_config.processes[i].poll_gap = 5; config_config.processes[i].poll_gap = 5;
config_config.processes[i].mode = PROCESS_MODE_MASTER;
if (link["linkName"].isString()) { if (link["linkName"].isString()) {
snprintf(config_config.processes[i].name, sizeof(config_config.processes[i].name), "%s", link["linkName"].asCString()); snprintf(config_config.processes[i].name, sizeof(config_config.processes[i].name), "%s", link["linkName"].asCString());
@ -1869,32 +1893,49 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
if (link["protocol"].isInt()) { if (link["protocol"].isInt()) {
config_config.processes[i].proto = link["protocol"].asInt(); config_config.processes[i].proto = link["protocol"].asInt();
} }
//处理链路参数,根据协议参数的不同来处理 //处理链路参数,根据协议参数的不同来处理
BYTE addrType = ADDR_TYPE_NORMAL; //根据协议设定单元地址类型
const Json::Value params = link["params"]; const Json::Value params = link["params"];
if (!params.isNull()) { if (!params.isNull()) {
switch (config_config.processes[i].proto) { switch (config_config.processes[i].proto) {
case PROTOCOL_HOST_MODBUS_RTU: case PROTOCOL_HOST_MODBUS_RTU:
processUartParam(params, uartId); processUartParam(params, uartId);
config_config.processes[i].order = uartId++; config_config.processes[i].order = uartId++;
config_config.processes[i].type = 1;
config_config.processes[i].mode = PROCESS_MODE_MASTER;
break; break;
case PROTOCOL_HOST_MODBUS_TCP: case PROTOCOL_HOST_MODBUS_TCP:
processHostModbustcpParam(params, i); processHostModbustcpParam(params, i);
config_config.processes[i].type = 3;
config_config.processes[i].mode = PROCESS_MODE_MASTER;
addrType = ADDR_TYPE_IPV4;
break; break;
case PROTOCOL_HOST_BF_MODBUSTCP: case PROTOCOL_HOST_BF_MODBUSTCP:
processRymodbustcpParam(params, i); processRymodbustcpParam(params, i);
config_config.processes[i].type = 3;
config_config.processes[i].mode = PROCESS_MODE_MASTER;
addrType = ADDR_TYPE_IPV4;
break; break;
case PROTOCOL_FTP2MINIO: case PROTOCOL_FTP2MINIO:
processRyFTP2MinioParam(params, i); processRyFTP2MinioParam(params, i);
break; break;
case PROTOCOL_HOST_IEC104: case PROTOCOL_HOST_IEC104:
processHostIEC104ProcessParam(params, i); processHostIEC104ProcessParam(params, i);
config_config.processes[i].type = 3;
config_config.processes[i].mode = PROCESS_MODE_MASTER;
addrType = ADDR_TYPE_IPV4_FACNO;
break; break;
case PROTOCOL_SUB_IEC104: case PROTOCOL_SUB_IEC104:
processSubIEC104ProcessParam(params, i); processSubIEC104ProcessParam(params, i);
config_config.processes[i].type = 3;
config_config.processes[i].mode = PROCESS_MODE_SLAVE;
addrType = ADDR_TYPE_IPV4_FACNO;
break; break;
case PROTOCOL_SUB_MODBUS_TCP: case PROTOCOL_SUB_MODBUS_TCP:
processSubModbustcpParam(params, i); processSubModbustcpParam(params, i);
config_config.processes[i].type = 3;
config_config.processes[i].mode = PROCESS_MODE_SLAVE;
addrType = ADDR_TYPE_IPV4;
break; break;
default: default:
break; break;
@ -1904,15 +1945,557 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
const Json::Value devices = link["devices"]; const Json::Value devices = link["devices"];
if (devices.isArray()) { if (devices.isArray()) {
int size = devices.size(); int size = devices.size();
if (config_config.processes[i].mode == PROCESS_MODE_SLAVE)
{
attrvectorGroup attrsItem;
for (int j = 0; j < size; j++) { for (int j = 0; j < size; j++) {
std::string id = devices[j].asCString(); const Json::Value device = devices[j];
if (uid2pid_map.find(id) == uid2pid_map.end()) { std::string id = "";
uid2pid_map.insert(uid2pidmap::value_type(id, i)); std::string address = "";
if (device["id"].isString()) {
id = device["id"].asString();
}
if (device["addr"].isString()) {
address = device["addr"].asString();
}
//此处先将数据缓存。然后在处理
const Json::Value attrs = device["attrs"];
if (!attrs.isNull()) {
int size = attrs.size();
for (int k = 0; k < size; k++) {
const Json::Value attr = attrs[k];
std::string type = "";
if (attr["type"].isString()) type = attr["type"].asString();
struct_attr name_param;
name_param.name = "";
name_param.highSpeed = 0;
name_param.order = -1;
if (attr["name"].isString()) name_param.name = id + attr["name"].asString();
if (attr["order"].isInt()) name_param.order = attr["order"].asInt();
if (attr["params"].isObject()) name_param.params = attr["params"];
if (type == "yc") attrsItem.ycs.push_back(name_param);
else if (type == "yx") attrsItem.yxs.push_back(name_param);
else if (type == "ym") attrsItem.yms.push_back(name_param);
} }
} }
const Json::Value services = device["services"];
if (!services.isNull()) {
int size = services.size();
for (int k = 0; k < size; k++) {
const Json::Value service = services[k];
std::string type = "";
if (service["type"].isString()) type = service["type"].asString();
struct_attr name_param;
name_param.name = "";
name_param.order = -1;
if (service["name"].isString()) name_param.name = id + service["name"].asString();
if (service["order"].isInt()) name_param.order = service["order"].asInt();
if (service["params"].isObject()) name_param.params = service["params"];
if (type == "yk") attrsItem.yks.push_back(name_param);
else if (type == "yt") attrsItem.yts.push_back(name_param);
}
}
}
if (map_pid2attrserice.find(i) == map_pid2attrserice.end()) {
map_pid2attrserice.insert(pid2attrvectormap::value_type(i, attrsItem));
}
}
else if (config_config.processes[i].mode == PROCESS_MODE_MASTER)
{
for (int j = 0; j < size; j++) {
const Json::Value device = devices[j];
std::string id = "";
std::string address = "";
if (device["id"].isString()) {
id = device["id"].asString();
}
if (device["addr"].isString()) {
address = device["addr"].asString();
}
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);
snprintf(config_static_units[uid].manufacturerId, sizeof(config_static_units[uid].manufacturerId), "%s", "iss");
if (id != "") {
snprintf(config_static_units[uid].deviceId, sizeof(config_static_units[uid].deviceId), "%s", id.c_str());
} else {
snprintf(config_static_units[uid].deviceId, sizeof(config_static_units[uid].deviceId), "iss_%d", uid);
}
config_config.processes[i].units[j] = uid;
//根据协议修改地址
if (address != "") {
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));
}
}
attrvector yxs, ycs, yms, yks, yts;
const Json::Value attrs = device["attrs"];
if (!attrs.isNull()) {
int size = attrs.size();
for (int k = 0; k < size; k++) {
const Json::Value attr = attrs[k];
std::string type = "";
if (attr["type"].isString()) type = attr["type"].asString();
struct_attr name_param;
name_param.name = "";
name_param.highSpeed = 0;
name_param.order = -1;
if (attr["name"].isString()) name_param.name = attr["name"].asString();
if (attr["highSpeed"].isInt()) name_param.highSpeed = attr["highSpeed"].asInt();
if (attr["order"].isInt()) name_param.order = attr["order"].asInt();
if (attr["params"].isObject()) name_param.params = 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 = device["services"];
if (!services.isNull()) {
int size = services.size();
for (int k = 0; k < size; k++) {
const Json::Value service = services[k];
std::string type = "";
if (service["type"].isString()) type = service["type"].asString();
struct_attr name_param;
name_param.name = "";
name_param.order = -1;
if (service["name"].isString()) name_param.name = service["name"].asString();
if (service["order"].isInt()) name_param.order = service["order"].asInt();
if (service["params"].isObject()) name_param.params = service["params"];
if (type == "yk") yks.push_back(name_param);
else if (type == "yt") yts.push_back(name_param);
} }
} }
config_config.units[uid].value = SPI_ON;
config_config.units[uid].softdog = UNIT_WATCHDOG_TIME;
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++;
std::string idattrname = id + ycs[k].name;
if (map_ycorders.find(idattrname) == map_ycorders.end()) {
map_ycorders.insert(string2intmap::value_type(idattrname, config_config.units[uid].ycs[k].order));
}
config_config.units[uid].ycs[k].value = 0;
config_config.units[uid].ycs[k].qds = 0x80; //默认为无效
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;
config_config.units[uid].ycs[k].highSpeed = ycs[k].highSpeed;
Json::Value param = ycs[k].params;
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["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();
//vLog(LOG_DEBUG, "config_config.units[%d].ycs[%d].coef is: %f\n", uid, k, config_config.units[uid].ycs[k].coef);
switch (config_config.processes[i].proto) {
case PROTOCOL_HOST_MODBUS_RTU:
case PROTOCOL_HOST_MODBUS_TCP:
case PROTOCOL_HOST_MODBUS_RTU_TCP:
case PROTOCOL_HOST_BF_MODBUSTCP:
processHostModbusPointParam(param, uid, k, POINT_TYPE_YC);
break;
case PROTOCOL_HOST_IEC104:
break;
case PROTOCOL_SUB_MODBUS_TCP:
processSubModbusPointParam(param, uid, k, POINT_TYPE_YC);
break;
}
}
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);
}
}
}
}
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++;
std::string idattrname = id + yms[k].name;
if (map_ymorders.find(idattrname) == map_ymorders.end()) {
map_ymorders.insert(string2intmap::value_type(idattrname, config_config.units[uid].yms[k].order));
}
config_config.units[uid].yms[k].value = 0;
config_config.units[uid].yms[k].coef = 1.0f;
config_config.units[uid].yms[k].base = 0;
Json::Value param = yms[k].params;
if (!param.isNull()) {
switch (config_config.processes[i].proto) {
case PROTOCOL_HOST_MODBUS_RTU:
case PROTOCOL_HOST_MODBUS_TCP:
case PROTOCOL_HOST_MODBUS_RTU_TCP:
case PROTOCOL_HOST_BF_MODBUSTCP:
processHostModbusPointParam(param, uid, k, POINT_TYPE_YM);
break;
case PROTOCOL_HOST_IEC104:
break;
}
}
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;
}
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++;
std::string idserverrname = id + yks[k].name;
if (map_ykorders.find(idserverrname) == map_ykorders.end()) {
map_ykorders.insert(string2intmap::value_type(idserverrname, config_config.units[uid].yks[k].order));
}
Json::Value param = yks[k].params;
if (!param.isNull()) {
switch (config_config.processes[i].proto) {
case PROTOCOL_HOST_MODBUS_RTU:
case PROTOCOL_HOST_MODBUS_TCP:
case PROTOCOL_HOST_MODBUS_RTU_TCP:
case PROTOCOL_HOST_BF_MODBUSTCP:
processHostModbusPointParam(param, uid, k, POINT_TYPE_YK);
break;
case PROTOCOL_HOST_IEC104:
break;
}
}
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++;
std::string idserverrname = id + yts[k].name;
if (map_ytorders.find(idserverrname) == map_ytorders.end()) {
map_ytorders.insert(string2intmap::value_type(idserverrname, config_config.units[uid].yts[k].order));
}
Json::Value param = yts[k].params;
if (!param.isNull()) {
switch (config_config.processes[i].proto) {
case PROTOCOL_HOST_MODBUS_RTU:
case PROTOCOL_HOST_MODBUS_TCP:
case PROTOCOL_HOST_MODBUS_RTU_TCP:
case PROTOCOL_HOST_BF_MODBUSTCP:
processHostModbusPointParam(param, uid, k, POINT_TYPE_YT);
break;
case PROTOCOL_HOST_IEC104:
break;
}
}
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++;
std::string idattrname = id + yxs[k].name;
if (map_yxorders.find(idattrname) == map_yxorders.end()) {
map_yxorders.insert(string2intmap::value_type(idattrname, config_config.units[uid].yxs[k].order));
}
config_config.units[uid].yxs[k].value = 0;
config_config.units[uid].yxs[k].qds = 0x80; //默认为无效
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].params;
if (!param.isNull()) {
if (param["invert"].asInt()) config_config.units[uid].yxs[k].invert = param["invert"].asInt();
switch (config_config.processes[i].proto) {
case PROTOCOL_HOST_MODBUS_RTU:
case PROTOCOL_HOST_MODBUS_TCP:
case PROTOCOL_HOST_MODBUS_RTU_TCP:
case PROTOCOL_HOST_BF_MODBUSTCP:
processHostModbusPointParam(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);
}
}
}
}
uid++;
}
}
}
}
#if 1
//判断从设备列表
int sub_uid = uid;
for (pid2attrvectormap::iterator it = map_pid2attrserice.begin(); it != map_pid2attrserice.end(); it++)
{
int pid = it->first;
attrvectorGroup attrs = it->second;
switch (config_config.processes[pid].proto)
{
case PROTOCOL_SUB_MODBUS_TCP:
config_config.units[sub_uid].addr[4] = 1;
config_config.processes[pid].option.smodbus.defaultYCType = 1;
break;
case PROTOCOL_SUB_IEC104:
config_config.units[sub_uid].addr[4] = 1;
break;
}
config_config.units[sub_uid].value = SPI_ON;
config_config.units[sub_uid].softdog = UNIT_WATCHDOG_TIME;
config_config.units[sub_uid].state = TRUE;
config_config.units[sub_uid].type = SLAVER_UNIT;
config_config.units[sub_uid].yxcount = attrs.yxs.size();
config_config.units[sub_uid].yccount = attrs.ycs.size();
config_config.units[sub_uid].ymcount = attrs.yms.size();
config_config.units[sub_uid].ykcount = attrs.yks.size();
config_config.units[sub_uid].ytcount = attrs.yts.size();
config_config.processes[pid].units[0] = sub_uid;
if (config_config.units[sub_uid].yccount > 0)
{
config_config.units[sub_uid].ycs = new struUnitYC[config_config.units[sub_uid].yccount];
if (NULL != config_config.units[sub_uid].ycs) {
memset(config_config.units[sub_uid].ycs, 0, sizeof(struUnitYC) * config_config.units[sub_uid].yccount);
}
for (int i = 0; i < config_config.units[sub_uid].yccount; i++) {
std::string key = attrs.ycs[i].name;
int order = -1;
int point = i;
if (map_ycorders.find(key) != map_ycorders.end())
{
order = map_ycorders[key];
}
Json::Value param = attrs.ycs[i].params;
if (!param["order"].isNull())
{
if (param["order"].isInt()) point = param["order"].asInt();
if (param["order"].isString()) point = atoi(param["order"].asCString());
}
snprintf(config_config.units[sub_uid].ycs[point].name, sizeof(config_config.units[sub_uid].ycs[point].name), "%s", key.c_str());
config_config.units[sub_uid].ycs[point].order = order;
config_config.units[sub_uid].ycs[point].value = 0;
config_config.units[sub_uid].ycs[point].qds = 0x80; //默认为无效
config_config.units[sub_uid].ycs[point].factor = 1;
config_config.units[sub_uid].ycs[point].change_pos = 2;
if (order >= 0) {
config_config.units[sub_uid].ycs[point].coef = config_database.ycs[order].coef;
config_config.units[sub_uid].ycs[point].base = config_database.ycs[order].base;
} else {
config_config.units[sub_uid].ycs[point].coef = 1.0f;
config_config.units[sub_uid].ycs[point].base = 0.0f;
}
config_config.units[sub_uid].ycs[point].upBound = 9999999.999f;
config_config.units[sub_uid].ycs[point].lowBound = -9999999.999f;
config_config.units[sub_uid].ycs[point].limit1Enable = FALSE;
config_config.units[sub_uid].ycs[point].limit1Low = 0;
config_config.units[sub_uid].ycs[point].limit1High = 0.0f;
config_config.units[sub_uid].ycs[point].limit2Enable = FALSE;
config_config.units[sub_uid].ycs[point].limit2Low = 0;
config_config.units[sub_uid].ycs[point].limit2High = 0.0f;
config_config.units[sub_uid].ycs[point].highSpeed = FALSE;
}
}
if (config_config.units[sub_uid].ymcount > 0)
{
config_config.units[sub_uid].yms = new struUnitYM[config_config.units[sub_uid].ymcount];
if (NULL != config_config.units[sub_uid].yms) {
memset(config_config.units[sub_uid].yms, 0, sizeof(struUnitYM) * config_config.units[sub_uid].ymcount);
}
for (int i = 0; i < config_config.units[sub_uid].ymcount; i++) {
std::string key = attrs.yms[i].name;
int order = -1;
int point = i;
if (map_ymorders.find(key) != map_ymorders.end())
{
order = map_ymorders[key];
}
Json::Value param = attrs.yms[i].params;
if (!param["order"].isNull())
{
if (param["order"].isInt()) point = param["order"].asInt();
if (param["order"].isString()) point = atoi(param["order"].asCString());
}
snprintf(config_config.units[sub_uid].yms[point].name, sizeof(config_config.units[sub_uid].yms[point].name), "%s", key.c_str());
config_config.units[sub_uid].yms[point].order = order;
config_config.units[sub_uid].yms[point].value = 0;
if (order >= 0) {
config_config.units[sub_uid].yms[point].coef = config_database.yms[order].coef;
config_config.units[sub_uid].yms[point].base = config_database.yms[order].base;
} else {
config_config.units[sub_uid].yms[point].coef = 1.0f;
config_config.units[sub_uid].yms[point].base = 0.0f;
}
}
}
if (config_config.units[sub_uid].ykcount > 0)
{
config_config.units[sub_uid].yks = new struUnitYK[config_config.units[sub_uid].ykcount];
if (NULL != config_config.units[sub_uid].yks) {
memset(config_config.units[sub_uid].yks, 0, sizeof(struUnitYK) * config_config.units[sub_uid].ykcount);
}
for (int i = 0; i < config_config.units[sub_uid].ykcount; i++) {
std::string key = attrs.yks[i].name;
int order = -1;
int point = i;
if (map_ykorders.find(key) != map_ykorders.end())
{
order = map_ykorders[key];
}
Json::Value param = attrs.yks[i].params;
if (!param["order"].isNull())
{
if (param["order"].isInt()) point = param["order"].asInt();
if (param["order"].isString()) point = atoi(param["order"].asCString());
}
snprintf(config_config.units[sub_uid].yks[point].name, sizeof(config_config.units[sub_uid].yks[point].name), "%s", key.c_str());
config_config.units[sub_uid].yks[point].order = order;
}
}
if (config_config.units[sub_uid].ytcount > 0)
{
config_config.units[sub_uid].yts = new struUnitYT[config_config.units[sub_uid].ytcount];
if (NULL != config_config.units[sub_uid].yts) {
memset(config_config.units[sub_uid].yts, 0, sizeof(struUnitYT) * config_config.units[sub_uid].ytcount);
}
for (int i = 0; i < config_config.units[sub_uid].ytcount; i++) {
std::string key = attrs.yts[i].name;
int order = -1;
int point = i;
if (map_ytorders.find(key) != map_ytorders.end())
{
order = map_ytorders[key];
}
Json::Value param = attrs.yts[i].params;
if (!param["order"].isNull())
{
if (param["order"].isInt()) point = param["order"].asInt();
if (param["order"].isString()) point = atoi(param["order"].asCString());
}
snprintf(config_config.units[sub_uid].yts[point].name, sizeof(config_config.units[sub_uid].yts[point].name), "%s", key.c_str());
config_config.units[sub_uid].yts[point].order = order;
}
}
if (config_config.units[sub_uid].yxcount > 0)
{
config_config.units[sub_uid].yxs = new struUnitYX[config_config.units[sub_uid].yxcount];
if (NULL != config_config.units[sub_uid].yxs) {
memset(config_config.units[sub_uid].yxs, 0, sizeof(struUnitYX) * config_config.units[sub_uid].yxcount);
}
for (int i = 0; i < config_config.units[sub_uid].yxcount; i++) {
std::string key = attrs.yxs[i].name;
int order = -1;
int point = i;
if (map_yxorders.find(key) != map_yxorders.end())
{
order = map_yxorders[key];
}
Json::Value param = attrs.yxs[i].params;
if (!param["order"].isNull())
{
if (param["order"].isInt()) point = param["order"].asInt();
if (param["order"].isString()) point = atoi(param["order"].asCString());
}
snprintf(config_config.units[sub_uid].yxs[point].name, sizeof(config_config.units[sub_uid].yxs[point].name), "%s", key.c_str());
config_config.units[sub_uid].yxs[point].order = order;
config_config.units[sub_uid].yxs[point].value = 0;
config_config.units[sub_uid].yxs[point].value = 0;
config_config.units[sub_uid].yxs[point].qds = 0x80; //默认为无效
config_config.units[sub_uid].yxs[point].invert = 0;
}
}
sub_uid++;
}
#endif
#if 0
//更新设备列表 //更新设备列表
const Json::Value equipments = jsonRoot["equipments"]; const Json::Value equipments = jsonRoot["equipments"];
{ {
@ -2020,7 +2603,7 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
name_param.highSpeed = 0; name_param.highSpeed = 0;
if (attr["name"].isString()) name_param.name = attr["name"].asString(); if (attr["name"].isString()) name_param.name = attr["name"].asString();
if (attr["highSpeed"].isInt()) name_param.highSpeed = attr["highSpeed"].asInt(); if (attr["highSpeed"].isInt()) name_param.highSpeed = attr["highSpeed"].asInt();
if (attr["params"].isObject()) name_param.value = attr["params"]; if (attr["params"].isObject()) name_param.params = attr["params"];
if (type == "yc") ycs.push_back(name_param); if (type == "yc") ycs.push_back(name_param);
else if (type == "yx") yxs.push_back(name_param); else if (type == "yx") yxs.push_back(name_param);
else if (type == "ym") yms.push_back(name_param); else if (type == "ym") yms.push_back(name_param);
@ -2036,7 +2619,7 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
struct_attr name_param; struct_attr name_param;
name_param.name = ""; name_param.name = "";
if (service["name"].isString()) name_param.name = service["name"].asString(); if (service["name"].isString()) name_param.name = service["name"].asString();
if (service["params"].isObject()) name_param.value = service["params"]; if (service["params"].isObject()) name_param.params = service["params"];
if (type == "yk") yks.push_back(name_param); if (type == "yk") yks.push_back(name_param);
else if (type == "yt") yts.push_back(name_param); else if (type == "yt") yts.push_back(name_param);
} }
@ -2074,7 +2657,7 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
config_config.units[uid].ycs[k].limit2Low = 0; config_config.units[uid].ycs[k].limit2Low = 0;
config_config.units[uid].ycs[k].limit2High = 0.0f; config_config.units[uid].ycs[k].limit2High = 0.0f;
config_config.units[uid].ycs[k].highSpeed = ycs[k].highSpeed; config_config.units[uid].ycs[k].highSpeed = ycs[k].highSpeed;
Json::Value param = ycs[k].value; Json::Value param = ycs[k].params;
if (!param.isNull()) { if (!param.isNull()) {
if (param["coef"].isDouble()) config_config.units[uid].ycs[k].coef = param["coef"].asFloat(); 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["base"].isDouble()) config_config.units[uid].ycs[k].base = param["base"].asFloat();
@ -2124,7 +2707,7 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
config_config.units[uid].yms[k].coef = 1.0f; config_config.units[uid].yms[k].coef = 1.0f;
config_config.units[uid].yms[k].base = 0; config_config.units[uid].yms[k].base = 0;
Json::Value param = yms[k].value; Json::Value param = yms[k].params;
if (!param.isNull()) { if (!param.isNull()) {
switch (config_config.processes[pid].proto) { switch (config_config.processes[pid].proto) {
case PROTOCOL_HOST_MODBUS_RTU: case PROTOCOL_HOST_MODBUS_RTU:
@ -2157,7 +2740,7 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
snprintf(config_config.units[uid].yks[k].name, sizeof(config_config.units[uid].yks[k].name), "%s", yks[k].name.c_str()); 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++; config_config.units[uid].yks[k].order = ykorder++;
Json::Value param = yks[k].value; Json::Value param = yks[k].params;
if (!param.isNull()) { if (!param.isNull()) {
switch (config_config.processes[pid].proto) { switch (config_config.processes[pid].proto) {
case PROTOCOL_HOST_MODBUS_RTU: case PROTOCOL_HOST_MODBUS_RTU:
@ -2185,7 +2768,7 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
snprintf(config_config.units[uid].yts[k].name, sizeof(config_config.units[uid].yts[k].name), "%s", yts[k].name.c_str()); 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++; config_config.units[uid].yts[k].order = ytorder++;
Json::Value param = yts[k].value; Json::Value param = yts[k].params;
if (!param.isNull()) { if (!param.isNull()) {
switch (config_config.processes[pid].proto) { switch (config_config.processes[pid].proto) {
case PROTOCOL_HOST_MODBUS_RTU: case PROTOCOL_HOST_MODBUS_RTU:
@ -2217,7 +2800,7 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
config_config.units[uid].yxs[k].invert = 0; config_config.units[uid].yxs[k].invert = 0;
config_database.yxs[config_config.units[uid].yxs[k].order].auto_reset = 0; config_database.yxs[config_config.units[uid].yxs[k].order].auto_reset = 0;
Json::Value param = yxs[k].value; Json::Value param = yxs[k].params;
if (!param.isNull()) { if (!param.isNull()) {
if (param["invert"].asInt()) config_config.units[uid].yxs[k].invert = param["invert"].asInt(); if (param["invert"].asInt()) config_config.units[uid].yxs[k].invert = param["invert"].asInt();
switch (config_config.processes[pid].proto) { switch (config_config.processes[pid].proto) {
@ -2245,6 +2828,13 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
if (pfdbykname) fclose(pfdbykname); if (pfdbykname) fclose(pfdbykname);
if (pfdbytname) fclose(pfdbytname); if (pfdbytname) fclose(pfdbytname);
} }
#endif
//保存数据库静态数据
if (pfdbyxname) fclose(pfdbyxname);
if (pfdbycname) fclose(pfdbycname);
if (pfdbymname) fclose(pfdbymname);
if (pfdbykname) fclose(pfdbykname);
if (pfdbytname) fclose(pfdbytname);
//保存数据 //保存数据
configWriteNodeCFG(); configWriteNodeCFG();
configWriteSystemCFG(); configWriteSystemCFG();
@ -2296,11 +2886,11 @@ void CRYDevice::on_message(const char *msg, const int size)
Json::CharReaderBuilder builder; Json::CharReaderBuilder builder;
Json::CharReader* reader(builder.newCharReader()); Json::CharReader* reader(builder.newCharReader());
vLog(LOG_DEBUG, "Received: %s.\n", msg); //vLog(LOG_DEBUG, "Received: %s.\n", msg);
do { do {
if (!reader->parse(msg, msg + size, &jsonRoot, &err)) { 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()); vLog(LOG_ERROR, "on_message reader->parse(msg, msg + size, &jsonRoot, &err) error<%d,%s>。\n", errno, err.c_str());
break; break;
} }
if (jsonRoot["cmd"].isNull()) { if (jsonRoot["cmd"].isNull()) {
@ -2522,6 +3112,7 @@ BOOLEAN CRYDevice::ry_init(const char *host, const int port, const char *nodeId,
unitname2service_map.clear(); unitname2service_map.clear();
for (int i = 0; i < UNIT_NUM; i++) { for (int i = 0; i < UNIT_NUM; i++) {
if (config.units[i].state != TRUE) continue; if (config.units[i].state != TRUE) continue;
if ((config.units[i].type & 0x0f) == SLAVER_UNIT) continue;
std::string unit_id = static_units[i].deviceId; std::string unit_id = static_units[i].deviceId;
name2servicemap name2service_map; name2servicemap name2service_map;
for (int j = 0; j < config.units[i].ykcount; j++) { for (int j = 0; j < config.units[i].ykcount; j++) {
@ -2581,22 +3172,14 @@ bool CRYDevice::ry_run(void)
while ((msg[msg_count] = nopoll_conn_get_msg(conn)) != NULL) { while ((msg[msg_count] = nopoll_conn_get_msg(conn)) != NULL) {
#if 1 #if 1
vLog(LOG_DEBUG, "recv %d length = %d, %d\n", msg_count, nopoll_msg_get_payload_size(msg[msg_count]), nopoll_msg_is_final(msg[msg_count])); vLog(LOG_DEBUG, "recv %d length = %d, final is: %d, fragment is: %d\n", msg_count, nopoll_msg_get_payload_size(msg[msg_count]), nopoll_msg_is_final(msg[msg_count]), nopoll_msg_is_fragment(msg[msg_count]));
#endif
#if 0
char pathN[256];
snprintf(pathN, sizeof(pathN), "0/_%d.txt", msg_count);
FILE* pf = fopen(pathN, "w+");
if (pf) {
fwrite(nopoll_msg_get_payload(msg[msg_count]), nopoll_msg_get_payload_size(msg[msg_count]), 1, pf);
fclose(pf);
}
#endif #endif
if (nopoll_msg_is_final(msg[msg_count])) { if (nopoll_msg_is_final(msg[msg_count])) {
msg_count++; msg_count++;
if (msg_count > 0) { if (msg_count > 0) {
int buffer_len; int buffer_len;
BYTE *buffer = NULL; BYTE *buffer = NULL;
vLog(LOG_DEBUG, "here... msg count is: %d\n", msg_count);
if (websocket_msg_join(msg, msg_count, buffer, buffer_len)) { if (websocket_msg_join(msg, msg_count, buffer, buffer_len)) {
if (buffer) { if (buffer) {
on_message((const char *)buffer, buffer_len); on_message((const char *)buffer, buffer_len);

View File

@ -46,11 +46,26 @@ typedef std::unordered_map<std::string, std::string> unitserviceName2cmdIdmap;
typedef struct { typedef struct {
std::string name; std::string name;
Json::Value value; Json::Value params;
int highSpeed; int highSpeed;
int order;
} struct_attr; } struct_attr;
typedef std::vector<struct_attr> attrvector; typedef std::vector<struct_attr> attrvector;
//设备id和attrs/services名称对应的测点序号
typedef std::unordered_map<std::string, int> string2intmap;
//设备unit和attrvector对应的关系
typedef struct {
attrvector yxs;
attrvector ycs;
attrvector yms;
attrvector yks;
attrvector yts;
} attrvectorGroup;
typedef std::unordered_map<int, attrvectorGroup> pid2attrvectormap;
class CRYDevice class CRYDevice
{ {
public: public:

View File

@ -642,6 +642,12 @@ typedef struct
struModbusOption modbus; struModbusOption modbus;
} struUnitModbusOption; } struUnitModbusOption;
typedef struct
{
struNetWorkOption net;
BYTE defaultYCType;
} struSubModbusTCPOption;
typedef struct typedef struct
{ {
BYTE addressLength; BYTE addressLength;
@ -858,6 +864,7 @@ typedef union
struIEC104Option iec104; struIEC104Option iec104;
struIEC103Option iec103; struIEC103Option iec103;
struIEC101Option iec101; struIEC101Option iec101;
struSubModbusTCPOption smodbus;
struRYModbusOption rymodbus; struRYModbusOption rymodbus;
struRYFTP2MINIOOption ftp2minio; struRYFTP2MINIOOption ftp2minio;
} unionProcOption; } unionProcOption;

View File

@ -123,37 +123,38 @@ BOOLEAN CSubModbusTcpProcess::OnPreCreate(int id)
m_DiscreteTable.clear(); m_DiscreteTable.clear();
m_HoldingRegTable.clear(); m_HoldingRegTable.clear();
m_InputRegTable.clear(); m_InputRegTable.clear();
#if 1
//获取遥信数量 //获取遥信数量
int yxcount = GetUnitYXCount(uid); int yxcount = GetUnitYXCount(uid);
//获取coil和discrete寄存器
for (j = 0; j < yxcount; j++) { for (j = 0; j < yxcount; j++) {
BYTE* param = GetUnitYXParamByPoint(uid, j);
if (param) {
if (param[0] == 0 || param[0] == 1) {
m_DiscreteTable.push_back(j); m_DiscreteTable.push_back(j);
} else { }
int ykcount = GetUnitYKCount(uid);
for (j = 0; j < ykcount; j++) {
m_CoilRegTable.push_back(j); m_CoilRegTable.push_back(j);
} }
}
}
int yccount = GetUnitYCCount(uid); int yccount = GetUnitYCCount(uid);
for (j = 0; j < yccount; j++) { for (j = 0; j < yccount; j++) {
BYTE* param = GetUnitYCParamByPoint(uid, j);
if (param) {
if (param[0] == 0 || param[0] == 1) {
m_InputRegTable.push_back(j); m_InputRegTable.push_back(j);
} else { }
int ymcount = GetUnitYMCount(uid);
for (j = 0; j < ymcount; j++) {
m_InputRegTable.push_back(j);
}
int ytcount = GetUnitYTCount(uid);
for (j = 0; j < ytcount; j++) {
m_HoldingRegTable.push_back(j); m_HoldingRegTable.push_back(j);
} }
}
}
if (m_CoilRegTable.size() > 0) if (m_CoilRegTable.size() > 0)
{ {
pItem->m_CoilRegCount = m_CoilRegTable.size(); pItem->m_CoilRegCount = m_CoilRegTable.size();
pItem->m_pCoilRegTable = new BYTE[pItem->m_CoilRegCount]; pItem->m_pCoilRegTable = new BYTE[pItem->m_CoilRegCount];
memset(pItem->m_pCoilRegTable, 0, sizeof(BYTE) * pItem->m_CoilRegCount); memset(pItem->m_pCoilRegTable, 0, sizeof(BYTE) * pItem->m_CoilRegCount);
pItem->m_ykcount = ykcount;
} }
if (m_DiscreteTable.size() > 0) if (m_DiscreteTable.size() > 0)
{ {
@ -165,25 +166,51 @@ BOOLEAN CSubModbusTcpProcess::OnPreCreate(int id)
{ {
int count = 0; int count = 0;
if (m_YC_Type == M_ME_NC) count = (m_InputRegTable.size() << 1); if (m_YC_Type == M_ME_NC) count = (m_InputRegTable.size() << 1);
else count = m_InputRegTable.size(); else {
count = yccount + (ymcount << 1);
}
pItem->m_InputregCount = count; pItem->m_InputregCount = count;
pItem->m_pInputRegTable = new WORD[count]; pItem->m_pInputRegTable = new WORD[count];
memset(pItem->m_pInputRegTable, 0, sizeof(WORD) * count); memset(pItem->m_pInputRegTable, 0, sizeof(WORD) * count);
pItem->m_yccount = yccount;
pItem->m_ymcount = ymcount;
} }
int ymcount = GetUnitYMCount(uid); if (m_HoldingRegTable.size() > 0)
if (m_HoldingRegTable.size() > 0 || ymcount > 0)
{ {
int count = m_HoldingRegTable.size(); int count = m_HoldingRegTable.size();
if (m_YC_Type == M_ME_NC) count = (count << 1);
count += (ymcount << 1);
pItem->m_HoldingRegCount = count; pItem->m_HoldingRegCount = count;
pItem->m_pHoldingRegTable = new WORD[count]; pItem->m_pHoldingRegTable = new WORD[count];
memset(pItem->m_pHoldingRegTable, 0, sizeof(WORD) * count); memset(pItem->m_pHoldingRegTable, 0, sizeof(WORD) * count);
pItem->m_ytcount = ytcount;
} }
#else
pItem->m_yxcount = GetUnitYXCount(uid);
pItem->m_yccount = GetUnitYCCount(uid);
pItem->m_ymcount = GetUnitYMCount(uid);
pItem->m_ykcount = GetUnitYKCount(uid);
pItem->m_ytcount = GetUnitYTCount(uid);
pItem->m_CoilRegCount = UNIT_YK_MAX;
pItem->m_pCoilRegTable = new BYTE[pItem->m_CoilRegCount];
memset(pItem->m_pCoilRegTable, 0, sizeof(BYTE) * pItem->m_CoilRegCount);
pItem->m_DiscreteRegCount = UNIT_YX_MAX;
pItem->m_pDiscreteRegTable = new BYTE[pItem->m_DiscreteRegCount];
memset(pItem->m_pDiscreteRegTable, 0, sizeof(BYTE) * pItem->m_DiscreteRegCount);
pItem->m_HoldingRegCount = UNIT_YT_MAX;
pItem->m_pHoldingRegTable = new WORD[pItem->m_HoldingRegCount];
memset(pItem->m_pHoldingRegTable, 0, sizeof(WORD) * pItem->m_HoldingRegCount);
pItem->m_InputregCount = 0x5700;
pItem->m_pHoldingRegTable = new WORD[pItem->m_InputregCount];
memset(pItem->m_pHoldingRegTable, 0, sizeof(WORD) * pItem->m_InputregCount);
#endif
} }
return TRUE; return TRUE;
} }
BOOLEAN CSubModbusTcpProcess::Run(void) BOOLEAN CSubModbusTcpProcess::Run(void)
{ {
if (!CNetProcess::Run()) return FALSE; if (!CNetProcess::Run()) return FALSE;
@ -199,17 +226,12 @@ BOOLEAN CSubModbusTcpProcess::Run(void)
if (uid < 0) continue; if (uid < 0) continue;
//刷新寄存器 //刷新寄存器
WORD *wd_input = NULL; WORD *wd_input = NULL;
WORD *wd_hold = NULL;
BYTE *bt_coil = NULL;
BYTE *bt_discrete = NULL; BYTE *bt_discrete = NULL;
if (pItem->m_pInputRegTable) { if (pItem->m_pInputRegTable)
{
wd_input = (WORD *)pItem->m_pInputRegTable; wd_input = (WORD *)pItem->m_pInputRegTable;
} for (j = 0; j < pItem->m_yccount; j++)
if (pItem->m_pHoldingRegTable) {
wd_hold = (WORD *)pItem->m_pHoldingRegTable;
}
for (j = 0; j < m_InputRegTable.size(); j++)
{ {
if (m_YC_Type == M_ME_NC) if (m_YC_Type == M_ME_NC)
{ {
@ -218,17 +240,16 @@ BOOLEAN CSubModbusTcpProcess::Run(void)
float fv; float fv;
DWORD dv; DWORD dv;
} val; } val;
val.fv = GetUnitYCReal(uid, j);
val.fv = GetUnitYCReal(uid, m_InputRegTable[j]);
*wd_input = ((val.dv >> 16) & 0xffff); wd_input++; *wd_input = ((val.dv >> 16) & 0xffff); wd_input++;
*wd_input = (val.dv & 0xffff); wd_input++; *wd_input = (val.dv & 0xffff); wd_input++;
} }
else else
{ {
*wd_input = (WORD)GetUnitYC(uid, m_InputRegTable[j]); wd_input++; *wd_input = (WORD)GetUnitYC(uid, j); wd_input++;
} }
} }
for (j = 0; j < m_HoldingRegTable.size(); j++) for (j = 0; j < pItem->m_ymcount; j++)
{ {
if (m_YC_Type == M_ME_NC) if (m_YC_Type == M_ME_NC)
{ {
@ -237,33 +258,22 @@ BOOLEAN CSubModbusTcpProcess::Run(void)
float fv; float fv;
DWORD dv; DWORD dv;
} val; } val;
val.fv = GetUnitYMReal(uid, j);
val.fv = GetUnitYCReal(uid, m_HoldingRegTable[j]); *wd_input = ((val.dv >> 16) & 0xffff); wd_input++;
*wd_hold = ((val.dv >> 16) & 0xffff); wd_hold++; *wd_input = (val.dv & 0xffff); wd_input++;
*wd_hold = (val.dv & 0xffff); wd_hold++;
} }
else else
{ {
*wd_hold = (WORD)GetUnitYC(uid, m_HoldingRegTable[j]); wd_hold++; DWORD value = GetUnitYM(uid, j);
*wd_input = ((value >> 16) & 0xffff); wd_input++;
*wd_input = (value & 0xffff); wd_input++;
} }
} }
for (j = 0; j < GetUnitYMCount(uid); j++)
{
DWORD val = (DWORD)GetUnitYM(uid, j);
*wd_hold = ((val >> 16) & 0xffff); wd_hold++;
*wd_hold = (val & 0xffff); wd_hold++;
} }
if (pItem->m_pCoilRegTable) {
bt_coil = (BYTE *)pItem->m_pCoilRegTable;
for (j = 0; j < m_CoilRegTable.size(); j++)
{
*bt_coil = (BYTE)GetUnitYX(uid, m_CoilRegTable[j]); bt_coil++;
}
}
if (pItem->m_pDiscreteRegTable) { if (pItem->m_pDiscreteRegTable) {
bt_discrete = (BYTE *)pItem->m_pDiscreteRegTable; bt_discrete = (BYTE *)pItem->m_pDiscreteRegTable;
for (j = 0; j < m_DiscreteTable.size(); j++) for (j = 0; j < pItem->m_yxcount; j++)
{ {
*bt_discrete = (BYTE)GetUnitYX(uid, m_DiscreteTable[j]); bt_discrete++; *bt_discrete = (BYTE)GetUnitYX(uid, m_DiscreteTable[j]); bt_discrete++;
} }
@ -382,11 +392,13 @@ int CSubModbusTcpProcess::OnPackageReceived(BYTE* pBuf, int count, int ord)
BYTE *ppucFrame = &pBuf[MB_TCP_FUNC]; BYTE *ppucFrame = &pBuf[MB_TCP_FUNC];
BYTE ucRcvAddress = pBuf[MB_TCP_UID]; BYTE ucRcvAddress = pBuf[MB_TCP_UID];
#if 0
if (ucRcvAddress != pItem->ied_addr && ucRcvAddress != MB_ADDRESS_BROADCAST) if (ucRcvAddress != pItem->ied_addr && ucRcvAddress != MB_ADDRESS_BROADCAST)
{ {
vLog(LOG_DEBUG, "数据不是发送给我的.\n"); vLog(LOG_DEBUG, "数据不是发送给我的.\n");
return count; return count;
} }
#endif
BYTE ucFunctionCode = ppucFrame[MB_PDU_FUNC_OFF]; BYTE ucFunctionCode = ppucFrame[MB_PDU_FUNC_OFF];
eMBException eException; eMBException eException;
eMBErrorCode eStatus = MB_ENOERR; eMBErrorCode eStatus = MB_ENOERR;
@ -422,7 +434,6 @@ int CSubModbusTcpProcess::OnPackageReceived(BYTE* pBuf, int count, int ord)
break; break;
default: default:
break; break;
} }
if (ucRcvAddress != MB_ADDRESS_BROADCAST) if (ucRcvAddress != MB_ADDRESS_BROADCAST)
{ {
@ -433,7 +444,7 @@ int CSubModbusTcpProcess::OnPackageReceived(BYTE* pBuf, int count, int ord)
ppucFrame[usLength++] = eException; ppucFrame[usLength++] = eException;
} }
eStatus = eMBTCPSend(ucRcvAddress, ppucFrame, usLength); eStatus = eMBTCPSend(ucRcvAddress, ppucFrame, usLength, ord);
if (eStatus != MB_ENOERR) if (eStatus != MB_ENOERR)
{ {
vLog(LOG_ERROR, "modbus tcp send error(%d)\n", eStatus); vLog(LOG_ERROR, "modbus tcp send error(%d)\n", eStatus);
@ -443,7 +454,7 @@ int CSubModbusTcpProcess::OnPackageReceived(BYTE* pBuf, int count, int ord)
return (count); return (count);
} }
eMBErrorCode CSubModbusTcpProcess::eMBTCPSend(BYTE ucSlaveAddress, const BYTE *pucFrame, WORD usLength) eMBErrorCode CSubModbusTcpProcess::eMBTCPSend(BYTE ucSlaveAddress, const BYTE *pucFrame, WORD usLength, int ord)
{ {
eMBErrorCode eStatus = MB_ENOERR; eMBErrorCode eStatus = MB_ENOERR;
BYTE *pucMBTCPFrame = (BYTE *) pucFrame - MB_TCP_FUNC; BYTE *pucMBTCPFrame = (BYTE *) pucFrame - MB_TCP_FUNC;
@ -451,7 +462,7 @@ eMBErrorCode CSubModbusTcpProcess::eMBTCPSend(BYTE ucSlaveAddress, const BYTE *p
pucMBTCPFrame[MB_TCP_LEN] = (usLength + 1) >> 8U; pucMBTCPFrame[MB_TCP_LEN] = (usLength + 1) >> 8U;
pucMBTCPFrame[MB_TCP_LEN + 1] = (usLength + 1) & 0xFF; pucMBTCPFrame[MB_TCP_LEN + 1] = (usLength + 1) & 0xFF;
if (WriteData(pucMBTCPFrame, usTCPLength, GetCurOrder())) if (WriteData(pucMBTCPFrame, usTCPLength, ord))
{ {
DisplayTxData(pucMBTCPFrame, usTCPLength, TRUE); DisplayTxData(pucMBTCPFrame, usTCPLength, TRUE);
} }

View File

@ -5,14 +5,6 @@
#include "modbus_def.h" #include "modbus_def.h"
#include <vector> #include <vector>
#pragma pack(1)
typedef struct
{
struNetWorkOption net;
BYTE defaultYCType;
} struSubModbusTCPOption;
#pragma pack()
typedef std::vector<int> vecInt; typedef std::vector<int> vecInt;
class CSubModbusTcpProcessItem : public CNetProcessItem class CSubModbusTcpProcessItem : public CNetProcessItem
@ -31,6 +23,12 @@ public:
WORD *m_pHoldingRegTable; WORD *m_pHoldingRegTable;
WORD *m_pInputRegTable; WORD *m_pInputRegTable;
int m_yccount;
int m_ymcount;
int m_yxcount;
int m_ykcount;
int m_ytcount;
public: public:
CSubModbusTcpProcessItem(); CSubModbusTcpProcessItem();
virtual ~CSubModbusTcpProcessItem(); virtual ~CSubModbusTcpProcessItem();
@ -68,11 +66,11 @@ private:
private: private:
int OnPackageReceived(BYTE* pBuf, int count, int ord /* = -1 */); int OnPackageReceived(BYTE* pBuf, int count, int ord /* = -1 */);
BOOLEAN OnReceiveData(CSubModbusTcpProcessItem *pItem, BYTE* pData, int count, int uid); BOOLEAN OnReceiveData(CSubModbusTcpProcessItem*, BYTE*, int, int);
eMBErrorCode eMBTCPSend(BYTE ucSlaveAddress, const BYTE *pucFrame, WORD usLength); eMBErrorCode eMBTCPSend(BYTE, const BYTE*, WORD, int);
eMBException prveMBError2Exception(eMBErrorCode eErrorCode); eMBException prveMBError2Exception(eMBErrorCode);
eMBException eMBFuncReadInputRegister(CSubModbusTcpProcessItem *pItem, BYTE* pucFrame, WORD* usLen); eMBException eMBFuncReadInputRegister(CSubModbusTcpProcessItem *pItem, BYTE* pucFrame, WORD* usLen);
eMBException eMBFuncReadHoldingRegister(CSubModbusTcpProcessItem *pItem, BYTE* pucFrame, WORD* usLen); eMBException eMBFuncReadHoldingRegister(CSubModbusTcpProcessItem *pItem, BYTE* pucFrame, WORD* usLen);
eMBException eMBFuncWriteHoldingRegister(CSubModbusTcpProcessItem *pItem, BYTE* pucFrame, WORD* usLen); eMBException eMBFuncWriteHoldingRegister(CSubModbusTcpProcessItem *pItem, BYTE* pucFrame, WORD* usLen);

View File

@ -3244,8 +3244,7 @@ noPollMsg * nopoll_conn_get_msg (noPollConn * conn)
/* update remaining bytes */ /* update remaining bytes */
msg->payload_size = msg->remain_bytes; msg->payload_size = msg->remain_bytes;
nopoll_free (msg->payload); nopoll_free (msg->payload);
nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "reusing noPollMsg reference (%p) since last payload read was 0, remaining: %d", msg, nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "reusing noPollMsg reference (%p) since last payload read was 0, remaining: %d", msg, msg->payload_size);
msg->payload_size);
} }
/* nullify references */ /* nullify references */
@ -3384,6 +3383,7 @@ noPollMsg * nopoll_conn_get_msg (noPollConn * conn)
msg->payload_size = nopoll_get_16bit (buffer + 2); msg->payload_size = nopoll_get_16bit (buffer + 2);
nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "Received (%d) bytes in header (size %d) for payload size indication, which finally is: %d", bytes, header_size,(int) msg->payload_size); nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "Received (%d) bytes in header (size %d) for payload size indication, which finally is: %d", bytes, header_size,(int) msg->payload_size);
fprintf(stderr, "Received (%d) bytes in header (size %d) for payload size indication, which finally is: %d\n", bytes, header_size,(int) msg->payload_size);
} else if (msg->payload_size == 127) { } else if (msg->payload_size == 127) {
/* read more content (next 8 bytes) */ /* read more content (next 8 bytes) */
@ -3479,6 +3479,8 @@ noPollMsg * nopoll_conn_get_msg (noPollConn * conn)
nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "Detected incoming websocket frame: fin(%d), op_code(%d), is_masked(%d), payload size(%ld), mask=%d", nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "Detected incoming websocket frame: fin(%d), op_code(%d), is_masked(%d), payload size(%ld), mask=%d",
msg->has_fin, msg->op_code, msg->is_masked, msg->payload_size, nopoll_get_32bit (msg->mask)); msg->has_fin, msg->op_code, msg->is_masked, msg->payload_size, nopoll_get_32bit (msg->mask));
fprintf(stderr, "Detected incoming websocket frame: fin(%d), op_code(%d), is_masked(%d), payload size(%ld), mask=%d\n",
msg->has_fin, msg->op_code, msg->is_masked, msg->payload_size, nopoll_get_32bit (msg->mask));
/* check payload size */ /* check payload size */
if (msg->payload_size == 0) { if (msg->payload_size == 0) {

View File

@ -809,7 +809,7 @@ BOOLEAN CZJD3100Process::OnSyntaxUnitYC(char *pData, int uid, int ord)
} }
else else
{ {
value = (float)config.units[uid].ycs[i].value * database.ycs[udb].coef + database.ycs[udb].base; value = (float)config.units[uid].ycs[i].value * config.units[uid].ycs[i].coef + config.units[uid].ycs[i].base;
} }
sprintf(buffer, "%4d %5.3f %-2s\t", i, value, ((config.units[uid].ycs[i].qds & 0x80) ? "IV" : " ")); sprintf(buffer, "%4d %5.3f %-2s\t", i, value, ((config.units[uid].ycs[i].qds & 0x80) ? "IV" : " "));

View File

@ -96,6 +96,7 @@ public class SysEquipmentServiceImpl implements SysEquipmentService {
SysEquipment sysEquipment = new SysEquipment(); SysEquipment sysEquipment = new SysEquipment();
BeanCopyUtils.copy(sysEquipmentDto, sysEquipment); BeanCopyUtils.copy(sysEquipmentDto, sysEquipment);
SysUserVo sysUserVo = (SysUserVo) StpUtil.getTokenSession().get(SessionUtil.SESSION_USER_KEY); SysUserVo sysUserVo = (SysUserVo) StpUtil.getTokenSession().get(SessionUtil.SESSION_USER_KEY);
SysEquipment oldModelSysEquipInfo = sysEquipmentMapper.selectById(sysEquipmentDto.getId());
SysEquipmentVo oldSysEquipment = sysEquipmentMapper.queryEquipmentInfoByCode(sysEquipmentDto.getCode()); SysEquipmentVo oldSysEquipment = sysEquipmentMapper.queryEquipmentInfoByCode(sysEquipmentDto.getCode());
// 判断设备编码是否存在 // 判断设备编码是否存在
if (sysEquipmentMapper.queryEquipmentByCode(sysEquipment.getCode()) > 0) { if (sysEquipmentMapper.queryEquipmentByCode(sysEquipment.getCode()) > 0) {
@ -106,7 +107,8 @@ public class SysEquipmentServiceImpl implements SysEquipmentService {
sysEquipment.setUpdatedTime(new Date()); sysEquipment.setUpdatedTime(new Date());
sysEquipment.setUpdatedBy(sysUserVo.getAccount()); sysEquipment.setUpdatedBy(sysUserVo.getAccount());
sysEquipmentMapper.updateById(sysEquipment); sysEquipmentMapper.updateById(sysEquipment);
if (oldSysEquipment.getIotModelId() == null && sysEquipment.getIotModelId() != null){
if (oldModelSysEquipInfo.getIotModelId() == null && sysEquipment.getIotModelId() != null){
dataService.deviceModelMap.put(sysEquipment.getId().toString(),dataService.iotModelMap.get(sysEquipment.getIotModelId().toString())); dataService.deviceModelMap.put(sysEquipment.getId().toString(),dataService.iotModelMap.get(sysEquipment.getIotModelId().toString()));
} }
SysEquipmentVo sysEquipmentVo = new SysEquipmentVo(); SysEquipmentVo sysEquipmentVo = new SysEquipmentVo();

View File

@ -20,8 +20,6 @@ public class ConfigUpdateVo {
private List<LinkVo> links; private List<LinkVo> links;
private List<EquipmentAndMappingVo> equipments;
public ConfigUpdateVo() { public ConfigUpdateVo() {
} }

View File

@ -4,6 +4,8 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data; import lombok.Data;
import java.util.List;
@Data @Data
public class LinkVo { public class LinkVo {
/** /**
@ -26,5 +28,5 @@ public class LinkVo {
/** /**
* 关联的设备列表设备id字符串列表 * 关联的设备列表设备id字符串列表
*/ */
private String[] devices; private List<EquipmentAndMappingVo> devices;
} }

View File

@ -63,4 +63,9 @@ public class SysTabMappingVo {
* 参数 * 参数
*/ */
private String params; private String params;
/**
* 协议号
*/
private Integer protocol;
} }

View File

@ -1,6 +1,8 @@
package com.das.modules.node.service.impl; package com.das.modules.node.service.impl;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.das.common.constant.MeasType; import com.das.common.constant.MeasType;
import com.das.common.utils.AdminRedisTemplate; import com.das.common.utils.AdminRedisTemplate;
@ -44,6 +46,7 @@ import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.stream.Collectors;
@Slf4j @Slf4j
@Service @Service
@ -131,7 +134,6 @@ public class NodeMessageServiceImpl extends TextWebSocketHandler implements Node
public JsonNode sendTerminalConfig(Long nodeId) { public JsonNode sendTerminalConfig(Long nodeId) {
ConfigUpdateVo configUpdateVo = new ConfigUpdateVo(); ConfigUpdateVo configUpdateVo = new ConfigUpdateVo();
List<LinkVo> links = new ArrayList<>(); List<LinkVo> links = new ArrayList<>();
List<EquipmentAndMappingVo> equipments = new ArrayList<>();
try { try {
// 获取所有的链路信息 // 获取所有的链路信息
List<SysCommunicationLinkVo> sysCommunicationLinkVoList = sysCommunicationLinkMapper.querySysCommunicationLink(nodeId); List<SysCommunicationLinkVo> sysCommunicationLinkVoList = sysCommunicationLinkMapper.querySysCommunicationLink(nodeId);
@ -142,14 +144,10 @@ public class NodeMessageServiceImpl extends TextWebSocketHandler implements Node
linkVo.setLinkName(sysCommunicationLinkVo.getLinkName()); linkVo.setLinkName(sysCommunicationLinkVo.getLinkName());
linkVo.setParams(jsonNode); linkVo.setParams(jsonNode);
linkVo.setProtocol(sysCommunicationLinkVo.getProtocol()); linkVo.setProtocol(sysCommunicationLinkVo.getProtocol());
List<String> stringList = new ArrayList<>(); // 获取关联的设备所有属性
// 获取关联的设备Id
List<EquipmentVo> equipmentList = sysImptabmappingMapper.getBindDeviceByLink(sysCommunicationLinkVo.getId()); List<EquipmentVo> equipmentList = sysImptabmappingMapper.getBindDeviceByLink(sysCommunicationLinkVo.getId());
for (EquipmentVo dev : equipmentList) {
stringList.add(String.valueOf(dev.getId())); List<EquipmentAndMappingVo> equipmentAndMappingVoList = new ArrayList<>();
}
String[] stringArray = stringList.toArray(new String[0]);
linkVo.setDevices(stringArray);
links.add(linkVo); links.add(linkVo);
for (EquipmentVo dev : equipmentList) { for (EquipmentVo dev : equipmentList) {
@ -162,6 +160,11 @@ public class NodeMessageServiceImpl extends TextWebSocketHandler implements Node
List<SysTabMappingVo> tabMappingVoList = sysImptabmappingMapper.getMappingInfoListByLinkIdAndDeviceId(sysCommunicationLinkVo.getId(), dev.getId()); List<SysTabMappingVo> tabMappingVoList = sysImptabmappingMapper.getMappingInfoListByLinkIdAndDeviceId(sysCommunicationLinkVo.getId(), dev.getId());
if (sysCommunicationLinkVo.getProtocol() == 17 || sysCommunicationLinkVo.getProtocol() == 9){
List<SysTabMappingVo> orderMappingVoList = tabMappingVoList.stream().filter(item -> ObjectUtil.isNotEmpty(JSONObject.parseObject(item.getParams()).get("order"))).collect(Collectors.toList());
tabMappingVoList.clear();
tabMappingVoList.addAll(orderMappingVoList);
}
if (!CollectionUtils.isEmpty(tabMappingVoList)) { if (!CollectionUtils.isEmpty(tabMappingVoList)) {
for (SysTabMappingVo info : tabMappingVoList) { for (SysTabMappingVo info : tabMappingVoList) {
@ -202,8 +205,10 @@ public class NodeMessageServiceImpl extends TextWebSocketHandler implements Node
equipment.setId(dev.getId()); equipment.setId(dev.getId());
equipment.setAttrs(attrs); equipment.setAttrs(attrs);
equipment.setServices(services); equipment.setServices(services);
equipments.add(equipment); equipmentAndMappingVoList.add(equipment);
} }
//改成list
linkVo.setDevices(equipmentAndMappingVoList);
} }
} catch (Exception e) { } catch (Exception e) {
log.error("获取设备配置信息失败", e); log.error("获取设备配置信息失败", e);
@ -212,7 +217,6 @@ public class NodeMessageServiceImpl extends TextWebSocketHandler implements Node
configUpdateVo.setNodeId(nodeId); configUpdateVo.setNodeId(nodeId);
configUpdateVo.setVersion(1); configUpdateVo.setVersion(1);
configUpdateVo.setLinks(links); configUpdateVo.setLinks(links);
configUpdateVo.setEquipments(equipments);
log.info("下发配置为{}", configUpdateVo); log.info("下发配置为{}", configUpdateVo);
JsonNode jsonNode = JSON_MAPPER.valueToTree(configUpdateVo); JsonNode jsonNode = JSON_MAPPER.valueToTree(configUpdateVo);
@ -225,7 +229,9 @@ public class NodeMessageServiceImpl extends TextWebSocketHandler implements Node
.data(jsonNode) .data(jsonNode)
.build(); .build();
sendActionMessage(nodeId, configUpdate); sendActionMessage(nodeId, configUpdate);
System.out.println(jsonNode);
return jsonNode; return jsonNode;
} }
@Override @Override
@ -363,18 +369,18 @@ public class NodeMessageServiceImpl extends TextWebSocketHandler implements Node
deviceEventInfo.setConfirmed(0); deviceEventInfo.setConfirmed(0);
if (!StringUtils.isEmpty(eventType) && eventType.equals("遥信变位")) { if (!StringUtils.isEmpty(eventType) && eventType.equals("遥信变位")) {
if (item.getAttrValue().equals(0)) { if (item.getAttrValue().equals(0)) {
deviceEventInfo.setEventText(fieldName + " 复归"); deviceEventInfo.setEventText(item.getAttrCode()+fieldName + " 复归");
deviceEventInfo.setEventLevel(0); deviceEventInfo.setEventLevel(0);
} else { } else {
deviceEventInfo.setEventText(fieldName + " 动作"); deviceEventInfo.setEventText(item.getAttrCode()+fieldName + " 动作");
Integer level = dataService.eventLevelMap.get(model).get(item.getAttrCode()); Integer level = dataService.eventLevelMap.get(model).get(item.getAttrCode());
log.info("level:{}",level); log.info("level:{}",level);
log.info("fieldname{}",fieldName); log.info("fieldname{}",fieldName);
deviceEventInfo.setEventLevel( level == null ? 0 : level); deviceEventInfo.setEventLevel( level == null ? 0 : level);
} }
} else { } else {
deviceEventInfo.setEventText(fieldName + eventType + ",属性值为:" + item.getAttrValue() + ",越限值为:" + item.getLimitValue()); deviceEventInfo.setEventText(item.getAttrCode()+fieldName + eventType + ",属性值为:" + item.getAttrValue() + ",越限值为:" + item.getLimitValue());
deviceEventInfo.setEventLevel(1); deviceEventInfo.setEventLevel(1);
} }
valueList.add(deviceEventInfo); valueList.add(deviceEventInfo);

View File

@ -5,6 +5,7 @@ import cn.hutool.core.io.IoUtil;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.das.common.config.SessionUtil; import com.das.common.config.SessionUtil;
import com.das.common.constant.MeasType; import com.das.common.constant.MeasType;
import com.das.common.exceptions.ServiceException;
import com.das.common.utils.BeanCopyUtils; import com.das.common.utils.BeanCopyUtils;
import com.das.common.utils.PageDataInfo; import com.das.common.utils.PageDataInfo;
import com.das.common.utils.PageQuery; import com.das.common.utils.PageQuery;
@ -14,6 +15,7 @@ import com.das.modules.auth.entity.SysOrg;
import com.das.modules.auth.mapper.SysOrgMapper; import com.das.modules.auth.mapper.SysOrgMapper;
import com.das.modules.equipment.domain.vo.SysIotModelFieldVo; import com.das.modules.equipment.domain.vo.SysIotModelFieldVo;
import com.das.modules.equipment.domain.vo.SysIotModelServiceVo; import com.das.modules.equipment.domain.vo.SysIotModelServiceVo;
import com.das.modules.equipment.entity.SysIotModelField;
import com.das.modules.equipment.mapper.SysEquipmentMapper; import com.das.modules.equipment.mapper.SysEquipmentMapper;
import com.das.modules.equipment.mapper.SysIotModelFieldMapper; import com.das.modules.equipment.mapper.SysIotModelFieldMapper;
import com.das.modules.equipment.mapper.SysIotModelServiceMapper; import com.das.modules.equipment.mapper.SysIotModelServiceMapper;
@ -32,6 +34,7 @@ import com.das.modules.node.mapper.SysCommunicationLinkMapper;
import com.das.modules.node.mapper.SysImpTabMappingMapper; import com.das.modules.node.mapper.SysImpTabMappingMapper;
import com.das.modules.node.mapper.SysNodeMapper; import com.das.modules.node.mapper.SysNodeMapper;
import com.das.modules.node.service.SysNodeService; import com.das.modules.node.service.SysNodeService;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
@ -48,6 +51,7 @@ import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Service @Service
@ -352,8 +356,21 @@ public class SysNodeServiceImpl implements SysNodeService {
if (!CollectionUtils.isEmpty(impList)) { if (!CollectionUtils.isEmpty(impList)) {
List<SysTabMapping> list = new ArrayList<>(); List<SysTabMapping> list = new ArrayList<>();
if (impList.get(0).getProtocol() == 9 || impList.get(0).getProtocol() == 17){
Map<Long, Integer> collect = sysImptabmappingMapper.getMappingInfoListByLinkId(impList.get(0).getLinkId()).stream().collect(Collectors.toMap(SysTabMappingVo::getId, SysTabMappingVo::getMeasPointType, (value1, value2) -> value1));
List<SysTabMappingVo> analogList = impList.stream().filter(item -> collect.get(item.getId()) == 138).collect(Collectors.toList());
List<SysTabMappingVo> accumulator = impList.stream().filter(item -> collect.get(item.getId()) == 139).collect(Collectors.toList());
List<SysTabMappingVo> discrete = impList.stream().filter(item -> collect.get(item.getId()) == 140).collect(Collectors.toList());
List<SysTabMappingVo> setPoint = impList.stream().filter(item -> collect.get(item.getId()) == 146).collect(Collectors.toList());
List<SysTabMappingVo> control = impList.stream().filter(item -> collect.get(item.getId()) == 147).collect(Collectors.toList());
if (checkOrderRepeated(analogList) || checkOrderRepeated(accumulator) || checkOrderRepeated(discrete) || checkOrderRepeated(setPoint) || checkOrderRepeated(control)){
throw new ServiceException("检查顺序,排序不能重复");
}
}
SysUserVo sysUserVo = (SysUserVo) StpUtil.getTokenSession().get(SessionUtil.SESSION_USER_KEY); SysUserVo sysUserVo = (SysUserVo) StpUtil.getTokenSession().get(SessionUtil.SESSION_USER_KEY);
for (SysTabMappingVo imp : impList) { for (SysTabMappingVo imp : impList) {
//校验param里面order不重复
SysTabMapping rec = sysImptabmappingMapper.selectById(imp.getId()); SysTabMapping rec = sysImptabmappingMapper.selectById(imp.getId());
rec.setUpdatedTime(new Date()); rec.setUpdatedTime(new Date());
rec.setUpdatedBy(sysUserVo.getAccount()); rec.setUpdatedBy(sysUserVo.getAccount());
@ -466,4 +483,29 @@ public class SysNodeServiceImpl implements SysNodeService {
return flag; return flag;
} }
private Boolean checkOrderRepeated(List<SysTabMappingVo> mappings) {
ObjectMapper objectMapper = new ObjectMapper();
Boolean orderRepeated = false;
try {
// 提取所有的 order 字段转换为 Set
Set<String> orderSet = new HashSet<>();
orderRepeated = mappings.stream()
.map(SysTabMappingVo::getParams) // 提取 param 字段
.map(param -> {
try {
// 解析 JSON 并提取 order
JsonNode jsonNode = objectMapper.readTree(param);
return jsonNode.get("order").asText();
} catch (Exception e) {
throw new RuntimeException("JSON 解析失败: " + param, e);
}
})
.anyMatch(order -> !orderSet.add(order));
}catch (Exception e){
log.error("校验order不重复失败:{}",e);
}
return orderRepeated;
}
} }

View File

@ -14,6 +14,8 @@ public class WindTurbinesPageVo {
private String name; private String name;
private String deviceCode;
@JsonSerialize(using = ToStringSerializer.class) @JsonSerialize(using = ToStringSerializer.class)
private Long modelId; private Long modelId;

View File

@ -104,6 +104,7 @@ public class WindTurbinesPageServiceImpl implements WindTurbinesPageService {
windTurbinesPageVo.setIrn(item.getId()); windTurbinesPageVo.setIrn(item.getId());
windTurbinesPageVo.setName(item.getName()); windTurbinesPageVo.setName(item.getName());
windTurbinesPageVo.setModel(item.getModel()); windTurbinesPageVo.setModel(item.getModel());
windTurbinesPageVo.setDeviceCode(item.getCode());
windTurbinesPageVo.setMadeinfactory(item.getMadeinFactory()); windTurbinesPageVo.setMadeinfactory(item.getMadeinFactory());
windTurbinesPageVo.setModelId(item.getIotModelId()); windTurbinesPageVo.setModelId(item.getIotModelId());
windTurbinesPageVo.setBelongLine(item.getBelongLine()); windTurbinesPageVo.setBelongLine(item.getBelongLine());

View File

@ -7,14 +7,7 @@ export const queryWindTurbinesPages = () => {
}) })
} }
export const historyReq = (data: { export const historyReq = (data: any) => {
devices: {
deviceId: string
attributes: string
}
startTime: string
endTime: string
}) => {
return createAxios({ return createAxios({
url: '/api/data/history', url: '/api/data/history',
method: 'post', method: 'post',

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

@ -184,12 +184,16 @@ function createAxios<Data = any, T = ApiPromise<Data>>(axiosConfig: AxiosRequest
error.config && removePending(error.config) error.config && removePending(error.config)
options.loading && closeLoading(options) // 关闭loading options.loading && closeLoading(options) // 关闭loading
options.showErrorMessage && httpErrorStatusHandle(error) // 处理错误状态码 options.showErrorMessage && httpErrorStatusHandle(error) // 处理错误状态码
if (error.response){
if (error.response.status == 401) { if (error.response.status == 401) {
let routerPath = adminBaseRoute.path let routerPath = adminBaseRoute.path
adminInfo.removeToken() adminInfo.removeToken()
routerPath += '/login' routerPath += '/login'
router.push({ path: routerPath }) router.push({ path: routerPath })
} }
}
return Promise.reject(error) // 错误继续返回给到具体页面 return Promise.reject(error) // 错误继续返回给到具体页面
} }
) )

View File

@ -17,12 +17,17 @@
/> />
<div style="width: 20px"></div> <div style="width: 20px"></div>
<div style="width: fit-content; min-width: 60px">{{ t('airBlower.airBlowerNumber') }}</div> <div style="width: fit-content; min-width: 60px">{{ t('airBlower.airBlowerNumber') }}</div>
<el-select v-model="airBlowerNumberValue" :placeholder="t('alarm.select') + t('airBlower.airBlowerNumber')" class="alarmSelect"> <el-select
v-model="airBlowerNumberValue"
:placeholder="t('alarm.select') + t('airBlower.airBlowerNumber')"
class="alarmSelect"
clearable
>
<el-option v-for="v in airBlowerList" :key="v.value" :label="v.label" :value="v.value"></el-option> <el-option v-for="v in airBlowerList" :key="v.value" :label="v.label" :value="v.value"></el-option>
</el-select> </el-select>
<div style="width: 20px"></div> <div style="width: 20px"></div>
<div style="width: fit-content; min-width: 30px">{{ t('alarm.type') }}</div> <div style="width: fit-content; min-width: 30px">{{ t('alarm.type') }}</div>
<el-select v-model="alarmTypeValue" :placeholder="t('alarm.select') + t('alarm.type')" class="alarmSelect"> <el-select v-model="alarmTypeValue" :placeholder="t('alarm.select') + t('alarm.type')" class="alarmSelect" clearable>
<el-option v-for="v in alarmTypes" :key="v.value" :label="v.label" :value="v.value"></el-option> <el-option v-for="v in alarmTypes" :key="v.value" :label="v.label" :value="v.value"></el-option>
</el-select> </el-select>
<div style="width: 20px"></div> <div style="width: 20px"></div>
@ -153,7 +158,7 @@ const searchalarms = (): GetAlarmsTableParam => {
const start = timeRange.value[0] const start = timeRange.value[0]
const end = timeRange.value[1] const end = timeRange.value[1]
const deviceCode: any = [] const deviceCode: any = []
if (airBlowerNumberValue.value.length) { if (airBlowerNumberValue.value && airBlowerNumberValue.value.length) {
deviceCode.push(airBlowerNumberValue.value) deviceCode.push(airBlowerNumberValue.value)
} else { } else {
airBlowerList.value.forEach((item: any) => { airBlowerList.value.forEach((item: any) => {

View File

@ -3,11 +3,11 @@
<el-row style="margin: 0px;"> <el-row style="margin: 0px;">
<el-col :md="24" :lg="24" class="col-top"> <el-col :md="24" :lg="24" class="col-top">
<el-row class="overview"> <el-row class="overview">
<el-col :sm="24" :md="12" :lg="4"> <el-col :xs="12" :sm="8" :md="8" :lg="4">
<div class="overviewItem" style="margin-left: 0px;"> <div class="overviewItem" style="margin-left: 0px;">
<img class="small-panel-pic" src="~assets/dashboard/overview01.png" alt="" /> <img class="small-panel-pic" src="~assets/dashboard/overview01.png" alt="" />
<div class="small-base"> <div class="small-base">
<div class="small-title">平均风速</div> <div class="small-title">平均风速</div>
<div class="small-value"> <div class="small-value">
<span class="content-number">{{realData.attributeMap.windfarmavgwindspeed}}</span> <span class="content-number">{{realData.attributeMap.windfarmavgwindspeed}}</span>
<span>m/s</span> <span>m/s</span>
@ -15,24 +15,24 @@
</div> </div>
</div> </div>
</el-col> </el-col>
<el-col :sm="24" :md="12" :lg="4"> <el-col :xs="12" :sm="8" :md="8" :lg="4">
<div class="overviewItem"> <div class="overviewItem">
<img class="small-panel-pic" src="~assets/dashboard/overview02.png" alt="" /> <img class="small-panel-pic" src="~assets/dashboard/overview02.png" alt="" />
<div class="small-base"> <div class="small-base">
<div class="small-title">实时有功</div> <div class="small-title">实时有功</div>
<div class="small-value"> <div class="small-value">
<span class="content-number">{{realData.attributeMap.windfarmactivepower}}</span> <span class="content-number">{{realData.attributeMap.windfarmactivepower}}</span>
<span>MW</span> <span>kW</span>
</div> </div>
</div> </div>
</div> </div>
</el-col> </el-col>
<el-col :sm="24" :md="12" :lg="4"> <el-col :xs="12" :sm="8" :md="8" :lg="4">
<div class="overviewItem"> <div class="overviewItem">
<img class="small-panel-pic" src="~assets/dashboard/overview03.png" alt="" /> <img class="small-panel-pic" src="~assets/dashboard/overview03.png" alt="" />
<div class="small-base"> <div class="small-base">
<div class="small-title">实时无功</div> <div class="small-title">实时无功</div>
<div class="small-value"> <div class="small-value">
<span class="content-number">{{realData.attributeMap.windfarmreactivepower}}</span> <span class="content-number">{{realData.attributeMap.windfarmreactivepower}}</span>
<span>kvar</span> <span>kvar</span>
@ -41,7 +41,7 @@
</div> </div>
</el-col> </el-col>
<el-col :sm="24" :md="12" :lg="4"> <el-col :xs="12" :sm="8" :md="8" :lg="4">
<div class="overviewItem"> <div class="overviewItem">
<img class="small-panel-pic" src="~assets/dashboard/overview04.png" alt="" /> <img class="small-panel-pic" src="~assets/dashboard/overview04.png" alt="" />
<div class="small-base"> <div class="small-base">
@ -54,7 +54,7 @@
</div> </div>
</el-col> </el-col>
<el-col :sm="24" :md="12" :lg="4"> <el-col :xs="12" :sm="8" :md="8" :lg="4">
<div class="overviewItem"> <div class="overviewItem">
<img class="small-panel-pic" src="~assets/dashboard/overview05.png" alt="" /> <img class="small-panel-pic" src="~assets/dashboard/overview05.png" alt="" />
<div class="small-base"> <div class="small-base">
@ -66,7 +66,7 @@
</div> </div>
</div> </div>
</el-col> </el-col>
<el-col :sm="24" :md="12" :lg="4"> <el-col :xs="12" :sm="8" :md="8" :lg="4">
<div class="overviewItem" style="margin-right: 0px;"> <div class="overviewItem" style="margin-right: 0px;">
<img class="small-panel-pic" src="~assets/dashboard/overview06.png" alt="" /> <img class="small-panel-pic" src="~assets/dashboard/overview06.png" alt="" />
<div class="small-base"> <div class="small-base">
@ -349,7 +349,7 @@ const getTableData = (deviceCode) => {
limit: 100, limit: 100,
eventLevel:2 eventLevel:2
} }
console.log(JSON.stringify(data)) // console.log(JSON.stringify(data))
getAlarmListReq(data).then((res) => { getAlarmListReq(data).then((res) => {
if (res.code == 200) { if (res.code == 200) {
//tableData.value = res.rows //tableData.value = res.rows
@ -431,11 +431,7 @@ const createScroll = () => {
const activeName = ref('first')
//let autoUpdateTimer: any = null
let autoUpdateForSecondTimer: any = null let autoUpdateForSecondTimer: any = null
let autoUpdateTimerForMinuteTimer: any = null
let autoUpdateTimerForHourTimer: any = null
const autoUpdate = () => { const autoUpdate = () => {
if (!autoUpdateForSecondTimer) { if (!autoUpdateForSecondTimer) {
autoUpdateForSecondTimer = setInterval(() => { autoUpdateForSecondTimer = setInterval(() => {
@ -474,7 +470,7 @@ onMounted(() => {
equipList({ objectType: 10002 }).then((res) => { equipList({ objectType: 10002 }).then((res) => {
res.data.map((item: any) => { res.data.map((item: any) => {
deviceCode.value.push(item.name) deviceCode.value.push(item.code)
}) })
getTableData(deviceCode.value) getTableData(deviceCode.value)
@ -485,10 +481,6 @@ onUnmounted(() => {
window.removeEventListener('resize', sizeChange) window.removeEventListener('resize', sizeChange)
clearInterval(timer) clearInterval(timer)
autoUpdateForSecondTimer && clearInterval(autoUpdateForSecondTimer) autoUpdateForSecondTimer && clearInterval(autoUpdateForSecondTimer)
/*const chartKeys = Object.keys(state.charts) as Array<keyof typeof state.charts>
chartKeys.forEach((key) => {
state.charts[key].dispose()
})*/
}) })
</script> </script>
@ -552,8 +544,8 @@ $labelHeight: 30px;
align-items: center; align-items: center;
color: #4E5969; color: #4E5969;
.small-panel-pic{ .small-panel-pic{
width: 100px; width: 80px;
height: 100px; height: 80px;
} }
} }
@ -585,6 +577,9 @@ $labelHeight: 30px;
p{ p{
padding-right: 30px; padding-right: 30px;
display: inline-block; display: inline-block;
span{
padding-right: 10px;
}
} }
} }
} }
@ -602,7 +597,7 @@ $labelHeight: 30px;
.matrix { .matrix {
@include cardlabel; @include cardlabel;
background: url('/@/assets/dashboard/bg1.png') no-repeat #ffffff; background: url('/@/assets/dashboard/bg2.png') no-repeat #ffffff;
background-size: 100% 100%; background-size: 100% 100%;
/* min-height: 900px;*/ /* min-height: 900px;*/
width: 100%; width: 100%;
@ -622,59 +617,18 @@ $labelHeight: 30px;
} }
} }
@media screen and (max-width: 1920px) {
.default-main {
.trend {
height: 315px !important;
}
}
}
@media screen and (max-width: 1280px) {
.default-main {
/*height: auto !important;*/
.windtitle {
margin-bottom: 10px;
}
.summarize {
.summarize-panel {
margin: 2px !important;
.summarize-panel-base {
white-space: normal !important;
}
}
}
}
}
@media screen and (max-width: 1360px) { @media screen and (max-width: 1360px) {
.default-main { .default-main {
font-size: 11px !important; font-size: 11px !important;
.summarize {
word-break: break-all !important;
}
.overview {
.small-panel {
.small-base {
margin-left: 0px !important;
font-size: 11px !important;
}
}
}
} }
} }
@media screen and (max-width: 1480px) { @media screen and (max-width: 1480px) {
.default-main { .default-main {
font-size: 12px !important; font-size: 12px !important;
.overview { .content-number {
.small-panel { font-size: 16px !important;
padding: 13px 0px !important;
}
}
.status {
.status-panel {
.status-base-main {
margin-left: 5px !important;
}
}
} }
} }
} }
@ -682,7 +636,7 @@ $labelHeight: 30px;
.default-main { .default-main {
/*font-size: 12px !important;*/ /*font-size: 12px !important;*/
.content-number { .content-number {
font-size: 16px !important; font-size: 18px !important;
} }
.homelabel { .homelabel {
@ -697,26 +651,6 @@ $labelHeight: 30px;
/* padding: 10px !important;*/ /* padding: 10px !important;*/
margin-bottom: 10px !important; margin-bottom: 10px !important;
} }
.summarize {
margin-bottom: 10px !important;
}
}
.toal-panel {
padding: 0 !important;
padding-bottom: 10px !important;
}
// .matrix {
// height: 900px !important;
// }
:deep(.el-tabs__header) {
margin-top: -33px !important;
}
.overview {
.small-panel {
.small-base {
margin-left: 5px !important;
}
}
} }
} }
} }

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="FanList-content"> <div class="FanList-content">
<el-row :gutter="10"> <el-row :gutter="10">
<el-col :xs="24" :sm="12" :md="12" :lg="4" :xl="3" v-for="(item, index) in props.parentData" style="margin-bottom: 5px"> <el-col :xs="12" :sm="8" :md="8" :lg="4" :xl="3" v-for="(item, index) in props.parentData" style="margin-bottom: 5px">
<div class="grid-content ep-bg-purple" @dblclick="handleDoubleClick(item)"> <div class="grid-content ep-bg-purple" @dblclick="handleDoubleClick(item)">
<div class="FanList-panel" :class="item.standard == true ? 'wind-mark' : 'wind-default'"> <div class="FanList-panel" :class="item.standard == true ? 'wind-mark' : 'wind-default'">
<div class="fanlist-top"> <div class="fanlist-top">
@ -55,7 +55,7 @@
</div> </div>
<div class="fanlist-text"> <div class="fanlist-text">
<span class="content-number">{{ item.attributeMap.igenpower }}</span> <span class="content-number">{{ item.attributeMap.igenpower }}</span>
<span>MW</span> <span>kW</span>
</div> </div>
<div class="fanlist-text"> <div class="fanlist-text">
<span class="content-number">{{ item.attributeMap.ikwhthisday }}</span> <span class="content-number">{{ item.attributeMap.ikwhthisday }}</span>
@ -233,7 +233,7 @@ const handleDoubleClick = (row) => {
.fanlist-main { .fanlist-main {
width: 100%; width: 100%;
display: flex; display: flex;
/*padding: 10px;*/ justify-content: space-between;
padding: 5px 10px 0 10px; padding: 5px 10px 0 10px;
text-align: center; text-align: center;
.fanlist-pic { .fanlist-pic {

View File

@ -169,8 +169,8 @@ const tableItem1: any = [
title: '发电机转速' title: '发电机转速'
}, },
{ {
label: '有功功率 (MW)', label: '有功功率 (kW)',
unit:' (MW)', unit:' (kW)',
prop: 'igenpower', prop: 'igenpower',
align: 'center', align: 'center',
custom: 'header', custom: 'header',
@ -408,6 +408,7 @@ const selectTable = (selected: TableType[] | null) => {
console.error('Selected is null or undefined') console.error('Selected is null or undefined')
return return
} }
debugger
selected.forEach((item, index) => { selected.forEach((item, index) => {
if (!multipleSelection.value.some(item1 => item1.attributeCode === item.attributeCode)) { if (!multipleSelection.value.some(item1 => item1.attributeCode === item.attributeCode)) {
multipleSelection.value.push(item); multipleSelection.value.push(item);
@ -561,15 +562,31 @@ const getTableData = () => {
}); });
tableColumn.value = [...tableItem0, ...tableColumnEnds.value]; tableColumn.value = [...tableItem0, ...tableColumnEnds.value];
} }
tableData.value = []
const deviceNameList=deviceList.value.map((item) => {
return {
id:item.id,
name: item.name ?? '-',
}
});
deviceId.forEach((item,index) => { deviceId.forEach((item,index) => {
objparms.deviceId=item objparms.deviceId=item
objparms.attributes=multipleSelection.value.map((item) => item.attributeCode) objparms.attributes=multipleSelection.value.map((item) => item.attributeCode)
snapshotParms.push({...objparms}) snapshotParms.push({...objparms})
}) })
deviceNameList.forEach((item1,index) => {
const NameItem={
id:item1.id,
name: item1.name,
}
tableData.value.push({...NameItem})
})
getsnapshotData(snapshotParms).then((res) => { getsnapshotData(snapshotParms).then((res) => {
if (res.code == 200) { if (res.code == 200) {
const tsnapshotVoObject: any = res.data; const tsnapshotVoObject: any = res.data;
multipleSelection.value.map((item1: any) => { multipleSelection.value.map((item1: any) => {
//tableData.value = [];
tableData.value.forEach((item: any, i: number, arr: any) => { tableData.value.forEach((item: any, i: number, arr: any) => {
for (const itemKey in tsnapshotVoObject) { for (const itemKey in tsnapshotVoObject) {
if (item.id === itemKey) { if (item.id === itemKey) {

View File

@ -10,7 +10,7 @@
</div> </div>
</div> </div>
<div class="topRight"> <div class="topRight">
<el-button type="primary" @click="statAnalysisOperate()">{{ t('statAnalysis.search') }}</el-button> <el-button type="primary" :loading="isLoading" @click="statAnalysisOperate()">{{ t('statAnalysis.search') }}</el-button>
<el-button style="color: #0064aa" @click="statAnalysisExport()">{{ t('statAnalysis.export') }}</el-button> <el-button style="color: #0064aa" @click="statAnalysisExport()">{{ t('statAnalysis.export') }}</el-button>
</div> </div>
</el-header> </el-header>
@ -95,6 +95,7 @@ const option: any = {
itemGap: 20, itemGap: 20,
itemWidth: 8, itemWidth: 8,
itemHeight: 8, itemHeight: 8,
selectedMode: true,
data: [], data: [],
}, },
xAxis: { xAxis: {
@ -152,6 +153,16 @@ onMounted(() => {
right: '3%', right: '3%',
}, },
}) })
chart.value.on('legendselectchanged', function (event: any) {
var isSelected = event.selected[event.name]
var series = chart.value.getOption().series
for (var i = 0; i < series.length; i++) {
if (series[i].name === event.name) {
series[i].show = isSelected
}
}
chart.value.setOption({ series: series })
})
} }
queryWindTurbines() queryWindTurbines()
queryfactoery() queryfactoery()
@ -165,31 +176,6 @@ const queryfactoery = () => {
}) })
} }
const querytheoretical = (val: any) => {
const madeinfactory = val.split(':')[0]
const model = val.split(':')[1]
powerCurveQuery(madeinfactory, model).then((res) => {
if (res.code == 200) {
const resData = res.data
if (resData.length) {
const seriesData = resData.map((item: any) => {
return [item.speed, item.power]
})
const series = {
type: 'line',
data: seriesData,
name: '理论值',
smooth: true,
}
option.series.push(series)
option.legend.data.push('理论值')
chart.value.setOption(option)
}
} else {
ElMessage.warning('查询失败')
}
})
}
const queryWindTurbines = () => { const queryWindTurbines = () => {
queryWindTurbinesPages().then((res) => { queryWindTurbinesPages().then((res) => {
if (res.code == 200) { if (res.code == 200) {
@ -276,10 +262,12 @@ const getDateRange = (type: 'week' | 'month') => {
} }
} }
const isLoading = ref(false)
const statAnalysisOperate = () => { const statAnalysisOperate = () => {
isLoading.value = true
option.series = [] option.series = []
option.legend.data = []
chart.value.setOption(option, { notMerge: true }) chart.value.setOption(option, { notMerge: true })
// chart.value.clear()
const requestData = { const requestData = {
devices: [ devices: [
{ {
@ -292,16 +280,48 @@ const statAnalysisOperate = () => {
endTime: new Date(statAnalysisTime.value[1]).getTime(), endTime: new Date(statAnalysisTime.value[1]).getTime(),
} }
const params = statAnalysisFatory.value ? statAnalysisFatory.value : statAnalysisDeviceId.value const params = statAnalysisFatory.value ? statAnalysisFatory.value : statAnalysisDeviceId.value
querytheoretical(params) const promise1 = new Promise((resolve, reject) => {
historyDataReq(requestData) const madeinfactory = params.split(':')[0]
} const model = params.split(':')[1]
const historyDataReq = (data: any) => { powerCurveQuery(madeinfactory, model)
historyReq(data).then((res) => { .then((res) => {
if (res.code == 200) { if (res.code == 200) {
const resData = res.data[statAnalysisDeviceId.value.split(':')[2]] resolve(res.data)
if (resData) { } else {
const iGenPower = resData['iGenPower']['values'] isLoading.value = false
const iWindSpeed = resData['iWindSpeed']['values'] ElMessage.warning('查询失败')
}
})
.catch((error) => {
resolve(error)
})
})
const promise2 = new Promise((resolve, reject) => {
historyReq(requestData)
.then((res) => {
if (res.code == 200) {
resolve(res.data)
} else {
isLoading.value = false
ElMessage.warning('查询失败')
}
})
.catch((error) => {
resolve(error)
})
})
Promise.all([promise1, promise2])
.then((results: any) => {
isLoading.value = false
const resData0 = results[1][statAnalysisDeviceId.value.split(':')[2]]
const resData1 = results[0]
if (resData0) {
const iGenPower = resData0['iGenPower']['values']
const iWindSpeed = resData0['iWindSpeed']['values']
if (!iWindSpeed.length) {
ElMessage.info(`实时值数据为空`)
} else {
const seriesData = iGenPower.map((item: any, index: number) => { const seriesData = iGenPower.map((item: any, index: number) => {
return [iWindSpeed[index], item] return [iWindSpeed[index], item]
}) })
@ -313,14 +333,31 @@ const historyDataReq = (data: any) => {
data: seriesData, data: seriesData,
name: '实际值', name: '实际值',
smooth: true, smooth: true,
animation: false,
} }
option.series.push(series) option.series.push(series)
option.legend.data.push('实际值') option.legend.data.push('实际值')
}
}
if (resData1.length) {
const seriesData = resData1.map((item: any) => {
return [item.speed, item.power]
})
const series = {
type: 'line',
data: seriesData,
name: '理论值',
smooth: true,
animation: false,
}
option.series.push(series)
option.legend.data.push('理论值')
}
chart.value.setOption(option) chart.value.setOption(option)
} })
} else { .catch((error) => {
ElMessage.warning('查询失败') isLoading.value = false
} ElMessage.warning(error)
}) })
} }

View File

@ -30,7 +30,7 @@
</div> </div>
</div> </div>
<div class="topRight"> <div class="topRight">
<el-button type="primary" @click="statAnalysisOperate()">{{ t('statAnalysis.search') }}</el-button> <el-button type="primary" :loading="isLoading" @click="statAnalysisOperate()">{{ t('statAnalysis.search') }}</el-button>
<el-button style="color: #0064aa" @click="statAnalysisExport()">{{ t('statAnalysis.export') }}</el-button> <el-button style="color: #0064aa" @click="statAnalysisExport()">{{ t('statAnalysis.export') }}</el-button>
</div> </div>
</el-header> </el-header>
@ -121,7 +121,7 @@ const addTime = (index: any) => {
const switchTime = (index: number) => { const switchTime = (index: number) => {
times.splice(index, 1) times.splice(index, 1)
customName.splice(index, 1) customName.splice(index, 1)
calculate.splice(index, 1) calculate.value.splice(index, 1)
} }
const timechange = (value: any) => { const timechange = (value: any) => {
const count = getTimeIntervals(times[0][0], times[0][1]) const count = getTimeIntervals(times[0][0], times[0][1])
@ -324,7 +324,6 @@ const getTimeIntervals = (startTimestamp: number, endTimestamp: number) => {
const startDate: any = new Date(startTimestamp) const startDate: any = new Date(startTimestamp)
const endDate: any = new Date(endTimestamp) const endDate: any = new Date(endTimestamp)
let count = 0 let count = 0
switch (statAnalysisSelect.interval) { switch (statAnalysisSelect.interval) {
case 'NONE': case 'NONE':
count = Math.floor((endDate - startDate) / 1000) count = Math.floor((endDate - startDate) / 1000)
@ -341,19 +340,23 @@ const getTimeIntervals = (startTimestamp: number, endTimestamp: number) => {
case '1d': case '1d':
count = Math.floor((endDate - startDate) / (1 * 24 * 60 * 60 * 1000)) count = Math.floor((endDate - startDate) / (1 * 24 * 60 * 60 * 1000))
break break
// default: default:
// throw new Error('Invalid interval') count = Math.floor((endDate - startDate) / (5 * 60 * 1000))
} }
return count return count
} }
const calculate: any = reactive([{ max: '', min: '', average: '' }]) const calculate: any = ref([{ max: '', min: '', average: '' }])
var xDatas: any = [] var xDatas: any = []
const isLoading = ref(false)
const statAnalysisOperate = () => { const statAnalysisOperate = () => {
isLoading.value = true
option.series = [] option.series = []
option.legend.data = [] option.legend.data = []
xDatas = [] xDatas = []
calculate.value = []
chart.value.setOption(option, { notMerge: true }) chart.value.setOption(option, { notMerge: true })
const promises: any = []
times.forEach((time: any, index: number) => { times.forEach((time: any, index: number) => {
if (time[0] && time[1]) { if (time[0] && time[1]) {
const requestData = { const requestData = {
@ -367,21 +370,40 @@ const statAnalysisOperate = () => {
startTime: new Date(time[0]).getTime(), startTime: new Date(time[0]).getTime(),
endTime: new Date(time[1]).getTime(), endTime: new Date(time[1]).getTime(),
} }
historyDataReq(requestData, index) const promise = new Promise((resolve, reject) => {
historyReq(requestData)
.then((res) => {
if (res.code == 200) {
resolve(res.data)
} else {
ElMessage.warning('查询失败')
} }
}) })
.catch((error) => {
reject(error)
})
})
promises.push(promise)
}
})
historyDataReq(promises)
} }
const historyDataReq = (data: any, index: number) => { const historyDataReq = (promises: any) => {
historyReq(data).then((res) => { Promise.all(promises)
if (res.code == 200) { .then((results: any) => {
isLoading.value = false
const deviceId = statAnalysisSelect.deviceId const deviceId = statAnalysisSelect.deviceId
const attributeCode = statAnalysisSelect.attributeCode const attributeCode = statAnalysisSelect.attributeCode
const resData = (res.data && deviceId in res.data && res.data[deviceId][attributeCode]) || undefined results.forEach((res: any, index: number) => {
if (resData) { const resData = (res && deviceId in res && res[deviceId][attributeCode]) || undefined
const xData = resData['times'] const xData = resData['times']
const yData = resData['values'] const yData = resData['values']
calculate[index] = calculateStats(yData) if (!yData.length) {
ElMessage.info(`${customName[index]}数据为空`)
return
}
calculate.value[index] = calculateStats(yData)
xDatas.push({ xDatas.push({
series: String(customName[index]), series: String(customName[index]),
data: xData, data: xData,
@ -405,16 +427,17 @@ const historyDataReq = (data: any, index: number) => {
type: 'line', type: 'line',
data: yData, data: yData,
showSymbol: true, showSymbol: true,
animation: false,
} }
option.legend.data.push(customName[index]) option.legend.data.push(customName[index])
option.series.push(seriesData) option.series.push(seriesData)
chart.value.setOption(option) chart.value.setOption(option)
} else { })
ElMessage.warning('查询失败1') })
} .catch((error) => {
} else { isLoading.value = false
ElMessage.warning('查询失败') console.error(error)
} ElMessage.warning(error)
}) })
} }
@ -437,7 +460,6 @@ const statAnalysisExport = () => {
requestData.push(devices) requestData.push(devices)
} }
}) })
console.log(requestData)
trendAnalyseExport(requestData).then((res: any) => { trendAnalyseExport(requestData).then((res: any) => {
const downloadUrl = window.URL.createObjectURL(res) const downloadUrl = window.URL.createObjectURL(res)
const a = document.createElement('a') const a = document.createElement('a')

View File

@ -22,7 +22,7 @@
</div> </div>
</div> </div>
<div class="topRight"> <div class="topRight">
<el-button type="primary" @click="statAnalysisOperate()">{{ t('statAnalysis.search') }}</el-button> <el-button type="primary" :loading="isLoading" @click="statAnalysisOperate()">{{ t('statAnalysis.search') }}</el-button>
<el-button style="color: #0064aa" @click="statAnalysisExport()">{{ t('statAnalysis.export') }}</el-button> <el-button style="color: #0064aa" @click="statAnalysisExport()">{{ t('statAnalysis.export') }}</el-button>
</div> </div>
</el-header> </el-header>
@ -138,7 +138,7 @@ const switchDevice = (index: number) => {
statAnalysisAttributes.splice(index, 1) statAnalysisAttributes.splice(index, 1)
statAnalysisAttributeCode.splice(index, 1) statAnalysisAttributeCode.splice(index, 1)
customName.splice(index, 1) customName.splice(index, 1)
calculate.splice(index, 1) calculate.value.splice(index, 1)
} }
const isExpand = ref(false) const isExpand = ref(false)
@ -323,12 +323,21 @@ const getDateRange = (type: 'week' | 'month') => {
} }
} }
const isLoading = ref(false)
const statAnalysisOperate = () => { const statAnalysisOperate = () => {
isLoading.value = true
option.series = []
option.legend.data = []
calculate.value = []
chart.value.setOption(option, { notMerge: true })
historyDataReq(getRequestData()) historyDataReq(getRequestData())
} }
const calculate: any = reactive([{ max: '', min: '', average: '' }]) const calculate: any = ref([{ max: '', min: '', average: '' }])
const historyDataReq = (data: any) => { const historyDataReq = (data: any) => {
historyReq(data).then((res) => { historyReq(data)
.then((res) => {
isLoading.value = false
if (res.code == 200) { if (res.code == 200) {
const resData = res.data const resData = res.data
const deviceIdKeys = Object.keys(resData) const deviceIdKeys = Object.keys(resData)
@ -342,12 +351,17 @@ const historyDataReq = (data: any) => {
const historyData = resData[item][value] const historyData = resData[item][value]
const xData = historyData['times'] const xData = historyData['times']
const yData = historyData['values'] const yData = historyData['values']
if (!yData.length) {
ElMessage.info(`${customName[dataIndex]}数据为空`)
return
}
const seriesData = { const seriesData = {
name: customName[dataIndex], name: customName[dataIndex],
type: 'line', type: 'line',
data: yData, data: yData,
animation: false,
} }
calculate[dataIndex] = calculateStats(yData) calculate.value[dataIndex] = calculateStats(yData)
option.tooltip = { option.tooltip = {
show: true, show: true,
trigger: 'axis', trigger: 'axis',
@ -367,9 +381,15 @@ const historyDataReq = (data: any) => {
}) })
} }
} else { } else {
isLoading.value = false
ElMessage.warning('查询失败') ElMessage.warning('查询失败')
} }
}) })
.catch((error) => {
isLoading.value = false
console.error(error)
ElMessage.warning(error)
})
} }
const findAllOccurrences = (arr: any, target: any) => { const findAllOccurrences = (arr: any, target: any) => {

View File

@ -95,6 +95,7 @@ const deviceQuery = (data: any) => {
}) })
} }
const handleNodeClick = (data: any) => { const handleNodeClick = (data: any) => {
selectcheck.value=[]
SelectdeviceId.value=data.id SelectdeviceId.value=data.id
state.charts.temperatureChart.clear() state.charts.temperatureChart.clear()
console.log(JSON.stringify({deviceId:SelectdeviceId.value,attributes:attributesDefault})) console.log(JSON.stringify({deviceId:SelectdeviceId.value,attributes:attributesDefault}))
@ -293,10 +294,11 @@ const variableList = () =>{
measPointCode: item.measPointCode measPointCode: item.measPointCode
} }
}) })
if(!selectcheck.value.length){
checkList.value=attributesDefault checkList.value=attributesDefault
/* checkList.value=res.data.map((item) => { }else{
return item.measPointCode checkList.value=selectcheck.value
})*/ }
} }
}) })