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;
conn = NULL;
msg_count = 0;
}
CRYDevice::~CRYDevice()
@ -1788,7 +1790,7 @@ BOOLEAN CRYDevice::processSubModbusPointParam(const Json::Value jsonRoot, int ui
{
if (uid < 0 || uid >= UNIT_NUM) 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)
{
case POINT_TYPE_YX:
@ -1849,16 +1851,38 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
int count = links.size();
int uartId = 0;
//m_gLinkIDs.clear();
int uid = 0;
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++) {
const Json::Value link = links[i];
config_config.processes[i].state = TRUE;
config_config.processes[i].type = MASTER_UNIT;
config_config.processes[i].time_gap = 300; //默认参数
config_config.processes[i].poll_gap = 5;
config_config.processes[i].mode = PROCESS_MODE_MASTER;
if (link["linkName"].isString()) {
snprintf(config_config.processes[i].name, sizeof(config_config.processes[i].name), "%s", link["linkName"].asCString());
@ -1869,32 +1893,49 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
if (link["protocol"].isInt()) {
config_config.processes[i].proto = link["protocol"].asInt();
}
//处理链路参数,根据协议参数的不同来处理
BYTE addrType = ADDR_TYPE_NORMAL; //根据协议设定单元地址类型
const Json::Value params = link["params"];
if (!params.isNull()) {
switch (config_config.processes[i].proto) {
case PROTOCOL_HOST_MODBUS_RTU:
processUartParam(params, uartId);
config_config.processes[i].order = uartId++;
config_config.processes[i].type = 1;
config_config.processes[i].mode = PROCESS_MODE_MASTER;
break;
case PROTOCOL_HOST_MODBUS_TCP:
processHostModbustcpParam(params, i);
config_config.processes[i].type = 3;
config_config.processes[i].mode = PROCESS_MODE_MASTER;
addrType = ADDR_TYPE_IPV4;
break;
case PROTOCOL_HOST_BF_MODBUSTCP:
processRymodbustcpParam(params, i);
config_config.processes[i].type = 3;
config_config.processes[i].mode = PROCESS_MODE_MASTER;
addrType = ADDR_TYPE_IPV4;
break;
case PROTOCOL_FTP2MINIO:
processRyFTP2MinioParam(params, i);
break;
case PROTOCOL_HOST_IEC104:
processHostIEC104ProcessParam(params, i);
config_config.processes[i].type = 3;
config_config.processes[i].mode = PROCESS_MODE_MASTER;
addrType = ADDR_TYPE_IPV4_FACNO;
break;
case PROTOCOL_SUB_IEC104:
processSubIEC104ProcessParam(params, i);
config_config.processes[i].type = 3;
config_config.processes[i].mode = PROCESS_MODE_SLAVE;
addrType = ADDR_TYPE_IPV4_FACNO;
break;
case PROTOCOL_SUB_MODBUS_TCP:
processSubModbustcpParam(params, i);
config_config.processes[i].type = 3;
config_config.processes[i].mode = PROCESS_MODE_SLAVE;
addrType = ADDR_TYPE_IPV4;
break;
default:
break;
@ -1904,15 +1945,557 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
const Json::Value devices = link["devices"];
if (devices.isArray()) {
int size = devices.size();
if (config_config.processes[i].mode == PROCESS_MODE_SLAVE)
{
attrvectorGroup attrsItem;
for (int j = 0; j < size; j++) {
std::string id = devices[j].asCString();
if (uid2pid_map.find(id) == uid2pid_map.end()) {
uid2pid_map.insert(uid2pidmap::value_type(id, i));
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();
}
//此处先将数据缓存。然后在处理
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"];
{
@ -2020,7 +2603,7 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
name_param.highSpeed = 0;
if (attr["name"].isString()) name_param.name = attr["name"].asString();
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);
else if (type == "yx") yxs.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;
name_param.name = "";
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);
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].limit2High = 0.0f;
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["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();
@ -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].base = 0;
Json::Value param = yms[k].value;
Json::Value param = yms[k].params;
if (!param.isNull()) {
switch (config_config.processes[pid].proto) {
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());
config_config.units[uid].yks[k].order = ykorder++;
Json::Value param = yks[k].value;
Json::Value param = yks[k].params;
if (!param.isNull()) {
switch (config_config.processes[pid].proto) {
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());
config_config.units[uid].yts[k].order = ytorder++;
Json::Value param = yts[k].value;
Json::Value param = yts[k].params;
if (!param.isNull()) {
switch (config_config.processes[pid].proto) {
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_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["invert"].asInt()) config_config.units[uid].yxs[k].invert = param["invert"].asInt();
switch (config_config.processes[pid].proto) {
@ -2245,6 +2828,13 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
if (pfdbykname) fclose(pfdbykname);
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();
configWriteSystemCFG();
@ -2296,11 +2886,11 @@ void CRYDevice::on_message(const char *msg, const int size)
Json::CharReaderBuilder builder;
Json::CharReader* reader(builder.newCharReader());
vLog(LOG_DEBUG, "Received: %s.\n", msg);
//vLog(LOG_DEBUG, "Received: %s.\n", msg);
do {
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;
}
if (jsonRoot["cmd"].isNull()) {
@ -2522,6 +3112,7 @@ BOOLEAN CRYDevice::ry_init(const char *host, const int port, const char *nodeId,
unitname2service_map.clear();
for (int i = 0; i < UNIT_NUM; i++) {
if (config.units[i].state != TRUE) continue;
if ((config.units[i].type & 0x0f) == SLAVER_UNIT) continue;
std::string unit_id = static_units[i].deviceId;
name2servicemap name2service_map;
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) {
#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]));
#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);
}
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 (nopoll_msg_is_final(msg[msg_count])) {
msg_count++;
if (msg_count > 0) {
int buffer_len;
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 (buffer) {
on_message((const char *)buffer, buffer_len);

View File

@ -46,11 +46,26 @@ typedef std::unordered_map<std::string, std::string> unitserviceName2cmdIdmap;
typedef struct {
std::string name;
Json::Value value;
Json::Value params;
int highSpeed;
int order;
} struct_attr;
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
{
public:

View File

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

View File

@ -123,37 +123,38 @@ BOOLEAN CSubModbusTcpProcess::OnPreCreate(int id)
m_DiscreteTable.clear();
m_HoldingRegTable.clear();
m_InputRegTable.clear();
#if 1
//获取遥信数量
int yxcount = GetUnitYXCount(uid);
//获取coil和discrete寄存器
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);
} else {
}
int ykcount = GetUnitYKCount(uid);
for (j = 0; j < ykcount; j++) {
m_CoilRegTable.push_back(j);
}
}
}
int yccount = GetUnitYCCount(uid);
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);
} 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);
}
}
}
if (m_CoilRegTable.size() > 0)
{
pItem->m_CoilRegCount = m_CoilRegTable.size();
pItem->m_pCoilRegTable = new BYTE[pItem->m_CoilRegCount];
memset(pItem->m_pCoilRegTable, 0, sizeof(BYTE) * pItem->m_CoilRegCount);
pItem->m_ykcount = ykcount;
}
if (m_DiscreteTable.size() > 0)
{
@ -165,25 +166,51 @@ BOOLEAN CSubModbusTcpProcess::OnPreCreate(int id)
{
int count = 0;
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_pInputRegTable = new 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 || ymcount > 0)
if (m_HoldingRegTable.size() > 0)
{
int count = m_HoldingRegTable.size();
if (m_YC_Type == M_ME_NC) count = (count << 1);
count += (ymcount << 1);
pItem->m_HoldingRegCount = count;
pItem->m_pHoldingRegTable = new 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;
}
BOOLEAN CSubModbusTcpProcess::Run(void)
{
if (!CNetProcess::Run()) return FALSE;
@ -199,17 +226,12 @@ BOOLEAN CSubModbusTcpProcess::Run(void)
if (uid < 0) continue;
//刷新寄存器
WORD *wd_input = NULL;
WORD *wd_hold = NULL;
BYTE *bt_coil = NULL;
BYTE *bt_discrete = NULL;
if (pItem->m_pInputRegTable) {
if (pItem->m_pInputRegTable)
{
wd_input = (WORD *)pItem->m_pInputRegTable;
}
if (pItem->m_pHoldingRegTable) {
wd_hold = (WORD *)pItem->m_pHoldingRegTable;
}
for (j = 0; j < m_InputRegTable.size(); j++)
for (j = 0; j < pItem->m_yccount; j++)
{
if (m_YC_Type == M_ME_NC)
{
@ -218,17 +240,16 @@ BOOLEAN CSubModbusTcpProcess::Run(void)
float fv;
DWORD dv;
} val;
val.fv = GetUnitYCReal(uid, m_InputRegTable[j]);
val.fv = GetUnitYCReal(uid, j);
*wd_input = ((val.dv >> 16) & 0xffff); wd_input++;
*wd_input = (val.dv & 0xffff); wd_input++;
}
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)
{
@ -237,33 +258,22 @@ BOOLEAN CSubModbusTcpProcess::Run(void)
float fv;
DWORD dv;
} val;
val.fv = GetUnitYCReal(uid, m_HoldingRegTable[j]);
*wd_hold = ((val.dv >> 16) & 0xffff); wd_hold++;
*wd_hold = (val.dv & 0xffff); wd_hold++;
val.fv = GetUnitYMReal(uid, j);
*wd_input = ((val.dv >> 16) & 0xffff); wd_input++;
*wd_input = (val.dv & 0xffff); wd_input++;
}
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) {
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++;
}
@ -382,11 +392,13 @@ int CSubModbusTcpProcess::OnPackageReceived(BYTE* pBuf, int count, int ord)
BYTE *ppucFrame = &pBuf[MB_TCP_FUNC];
BYTE ucRcvAddress = pBuf[MB_TCP_UID];
#if 0
if (ucRcvAddress != pItem->ied_addr && ucRcvAddress != MB_ADDRESS_BROADCAST)
{
vLog(LOG_DEBUG, "数据不是发送给我的.\n");
return count;
}
#endif
BYTE ucFunctionCode = ppucFrame[MB_PDU_FUNC_OFF];
eMBException eException;
eMBErrorCode eStatus = MB_ENOERR;
@ -422,7 +434,6 @@ int CSubModbusTcpProcess::OnPackageReceived(BYTE* pBuf, int count, int ord)
break;
default:
break;
}
if (ucRcvAddress != MB_ADDRESS_BROADCAST)
{
@ -433,7 +444,7 @@ int CSubModbusTcpProcess::OnPackageReceived(BYTE* pBuf, int count, int ord)
ppucFrame[usLength++] = eException;
}
eStatus = eMBTCPSend(ucRcvAddress, ppucFrame, usLength);
eStatus = eMBTCPSend(ucRcvAddress, ppucFrame, usLength, ord);
if (eStatus != MB_ENOERR)
{
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);
}
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;
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 + 1] = (usLength + 1) & 0xFF;
if (WriteData(pucMBTCPFrame, usTCPLength, GetCurOrder()))
if (WriteData(pucMBTCPFrame, usTCPLength, ord))
{
DisplayTxData(pucMBTCPFrame, usTCPLength, TRUE);
}

View File

@ -5,14 +5,6 @@
#include "modbus_def.h"
#include <vector>
#pragma pack(1)
typedef struct
{
struNetWorkOption net;
BYTE defaultYCType;
} struSubModbusTCPOption;
#pragma pack()
typedef std::vector<int> vecInt;
class CSubModbusTcpProcessItem : public CNetProcessItem
@ -31,6 +23,12 @@ public:
WORD *m_pHoldingRegTable;
WORD *m_pInputRegTable;
int m_yccount;
int m_ymcount;
int m_yxcount;
int m_ykcount;
int m_ytcount;
public:
CSubModbusTcpProcessItem();
virtual ~CSubModbusTcpProcessItem();
@ -68,11 +66,11 @@ private:
private:
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 eMBFuncReadHoldingRegister(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 */
msg->payload_size = msg->remain_bytes;
nopoll_free (msg->payload);
nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "reusing noPollMsg reference (%p) since last payload read was 0, remaining: %d", msg,
msg->payload_size);
nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "reusing noPollMsg reference (%p) since last payload read was 0, remaining: %d", msg, msg->payload_size);
}
/* nullify references */
@ -3384,6 +3383,7 @@ noPollMsg * nopoll_conn_get_msg (noPollConn * conn)
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);
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) {
/* 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",
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 */
if (msg->payload_size == 0) {

View File

@ -809,7 +809,7 @@ BOOLEAN CZJD3100Process::OnSyntaxUnitYC(char *pData, int uid, int ord)
}
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" : " "));

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,6 +5,7 @@ import cn.hutool.core.io.IoUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.das.common.config.SessionUtil;
import com.das.common.constant.MeasType;
import com.das.common.exceptions.ServiceException;
import com.das.common.utils.BeanCopyUtils;
import com.das.common.utils.PageDataInfo;
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.equipment.domain.vo.SysIotModelFieldVo;
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.SysIotModelFieldMapper;
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.SysNodeMapper;
import com.das.modules.node.service.SysNodeService;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@ -48,6 +51,7 @@ import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
@Transactional(rollbackFor = Exception.class)
@Service
@ -352,8 +356,21 @@ public class SysNodeServiceImpl implements SysNodeService {
if (!CollectionUtils.isEmpty(impList)) {
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);
for (SysTabMappingVo imp : impList) {
//校验param里面order不重复
SysTabMapping rec = sysImptabmappingMapper.selectById(imp.getId());
rec.setUpdatedTime(new Date());
rec.setUpdatedBy(sysUserVo.getAccount());
@ -466,4 +483,29 @@ public class SysNodeServiceImpl implements SysNodeService {
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 deviceCode;
@JsonSerialize(using = ToStringSerializer.class)
private Long modelId;

View File

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

View File

@ -7,14 +7,7 @@ export const queryWindTurbinesPages = () => {
})
}
export const historyReq = (data: {
devices: {
deviceId: string
attributes: string
}
startTime: string
endTime: string
}) => {
export const historyReq = (data: any) => {
return createAxios({
url: '/api/data/history',
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)
options.loading && closeLoading(options) // 关闭loading
options.showErrorMessage && httpErrorStatusHandle(error) // 处理错误状态码
if (error.response){
if (error.response.status == 401) {
let routerPath = adminBaseRoute.path
adminInfo.removeToken()
routerPath += '/login'
router.push({ path: routerPath })
}
}
return Promise.reject(error) // 错误继续返回给到具体页面
}
)

View File

@ -17,12 +17,17 @@
/>
<div style="width: 20px"></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-select>
<div style="width: 20px"></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-select>
<div style="width: 20px"></div>
@ -153,7 +158,7 @@ const searchalarms = (): GetAlarmsTableParam => {
const start = timeRange.value[0]
const end = timeRange.value[1]
const deviceCode: any = []
if (airBlowerNumberValue.value.length) {
if (airBlowerNumberValue.value && airBlowerNumberValue.value.length) {
deviceCode.push(airBlowerNumberValue.value)
} else {
airBlowerList.value.forEach((item: any) => {

View File

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

View File

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

View File

@ -10,7 +10,7 @@
</div>
</div>
<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>
</div>
</el-header>
@ -95,6 +95,7 @@ const option: any = {
itemGap: 20,
itemWidth: 8,
itemHeight: 8,
selectedMode: true,
data: [],
},
xAxis: {
@ -152,6 +153,16 @@ onMounted(() => {
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()
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 = () => {
queryWindTurbinesPages().then((res) => {
if (res.code == 200) {
@ -276,10 +262,12 @@ const getDateRange = (type: 'week' | 'month') => {
}
}
const isLoading = ref(false)
const statAnalysisOperate = () => {
isLoading.value = true
option.series = []
option.legend.data = []
chart.value.setOption(option, { notMerge: true })
// chart.value.clear()
const requestData = {
devices: [
{
@ -292,16 +280,48 @@ const statAnalysisOperate = () => {
endTime: new Date(statAnalysisTime.value[1]).getTime(),
}
const params = statAnalysisFatory.value ? statAnalysisFatory.value : statAnalysisDeviceId.value
querytheoretical(params)
historyDataReq(requestData)
}
const historyDataReq = (data: any) => {
historyReq(data).then((res) => {
const promise1 = new Promise((resolve, reject) => {
const madeinfactory = params.split(':')[0]
const model = params.split(':')[1]
powerCurveQuery(madeinfactory, model)
.then((res) => {
if (res.code == 200) {
const resData = res.data[statAnalysisDeviceId.value.split(':')[2]]
if (resData) {
const iGenPower = resData['iGenPower']['values']
const iWindSpeed = resData['iWindSpeed']['values']
resolve(res.data)
} else {
isLoading.value = false
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) => {
return [iWindSpeed[index], item]
})
@ -313,14 +333,31 @@ const historyDataReq = (data: any) => {
data: seriesData,
name: '实际值',
smooth: true,
animation: false,
}
option.series.push(series)
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)
}
} else {
ElMessage.warning('查询失败')
}
})
.catch((error) => {
isLoading.value = false
ElMessage.warning(error)
})
}

View File

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

View File

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

View File

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