Merge remote-tracking branch 'origin/main'

This commit is contained in:
chenhaojie 2024-10-21 16:56:26 +08:00
commit f58f0cc26a
33 changed files with 2456 additions and 231 deletions

57
.vscode/settings.json vendored
View File

@ -10,6 +10,61 @@
"xloctime": "cpp",
"xhash": "cpp",
"string": "cpp",
"sstream": "cpp"
"sstream": "cpp",
"xutility": "cpp",
"array": "cpp",
"ranges": "cpp",
"span": "cpp",
"vector": "cpp",
"system_error": "cpp",
"algorithm": "cpp",
"atomic": "cpp",
"bit": "cpp",
"cctype": "cpp",
"charconv": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"compare": "cpp",
"concepts": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"deque": "cpp",
"exception": "cpp",
"format": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"ios": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"iterator": "cpp",
"limits": "cpp",
"list": "cpp",
"map": "cpp",
"memory": "cpp",
"new": "cpp",
"optional": "cpp",
"ostream": "cpp",
"set": "cpp",
"stack": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"typeinfo": "cpp",
"utility": "cpp",
"xfacet": "cpp",
"xiosbase": "cpp",
"xlocbuf": "cpp",
"xlocinfo": "cpp",
"xmemory": "cpp",
"xtr1common": "cpp",
"xtree": "cpp"
}
}

View File

@ -220,5 +220,6 @@ if (UNIX)
#set (APP_LIBS ${APP_LIBS} websockets)
endif()
#add_link_options (-static)
add_executable (application ${APP_SRCS})
target_link_libraries (application ${APP_LIBS})

View File

@ -48,8 +48,6 @@ CChangeMaster::CChangeMaster()
memset(m_control.m_hostTr, 0, HOST_NAME_LENGTH);
m_control.m_total = TCI_CHANGE_FULL_CRITICAL;
uart_fd = -1;
m_conn = NULL;
}
CChangeMaster::~CChangeMaster()
@ -114,7 +112,7 @@ BOOLEAN CChangeMaster::uart_init(const char *dev)
return TRUE;
}
BOOLEAN CChangeMaster::Init(noPollConn *conn)
BOOLEAN CChangeMaster::Init(void)
{
if (nodes.interfaces.enable)
{
@ -123,10 +121,6 @@ BOOLEAN CChangeMaster::Init(noPollConn *conn)
return uart_init(uart_dev);
}
if (conn)
{
m_conn = conn;
}
return TRUE;
}
@ -348,7 +342,7 @@ void CChangeMaster::StartUp(void)
else if (PROTOCOL_HOST_MODBUS_TCP == config.processes[i].proto)
{
vLog(LOG_INFO, "协议<%d>创建为: modbus tcp主协议.\n", i);
procs[i] = new CHostModbusTcpProcess(m_conn);
procs[i] = new CHostModbusTcpProcess();
}
else if (PROTOCOL_HOST_IEC104 == config.processes[i].proto)
{

View File

@ -5,9 +5,6 @@
#include <map>
#include <string>
#include <nopoll.h>
#include <nopoll_decl.h>
#define MASTER_TCI_ALIVE 0x55
#define MASTER_TCI_SEND_INTERVAL (1000*200) //sleep(1)
#define TCI_CHANGE_FULL_CRITICAL 5
@ -51,7 +48,7 @@ public:
ChangeMaster m_changeStruct;
ChangeControl m_control;
public:
BOOLEAN Init(noPollConn *conn);
BOOLEAN Init(void);
void OnReceive(ChangeMaster chControl);
protected:
@ -74,8 +71,6 @@ private:
BOOLEAN IsMasterTci();
void StartUp(void);
noPollConn *m_conn;
};
void *ChangeNewObject(void *args);

View File

@ -2127,7 +2127,7 @@ int main(int argc, char** argv)
char host[256] = {"127.0.0.1"};
int port = 7790;
char nodeId[128] = {"runyang_dn"};
char version[128] = {"v1.0"};
char version[128] = {"0"};
//获取可执行文件所在目录
const char default_config[] = "[global]\n"
@ -2215,7 +2215,6 @@ int main(int argc, char** argv)
noPollConn *conn;
DWORD last_connect_sec = 0;
#else
noPollConn *conn = NULL;
CRYDevice ryDevice;
#endif
@ -2243,7 +2242,6 @@ int main(int argc, char** argv)
}
} else {
if (enable_auto_platform) { //增加协议和单元配置的数量统计
#ifdef MAIN_FILE
vLog(LOG_DEBUG, "configed node id is: %s.\n", nodes.m_node[0].m_machine_name);
snprintf(nodeId, sizeof(nodeId), "%s", nodes.m_node[0].m_machine_name);
if (system32.version[0] != '\0') {
@ -2251,6 +2249,7 @@ int main(int argc, char** argv)
} else {
snprintf(version, sizeof(version), "%s", "1");
}
#ifdef MAIN_FILE
unitname2service_map.clear();
for (int i = 0; i < UNIT_NUM; i++) {
if (config.units[i].state != TRUE) continue;
@ -2308,7 +2307,7 @@ int main(int argc, char** argv)
//last_connect_sec = system32.timers;
}
#else
conn = ryDevice.ry_init(host, port, nodeId, version);
ryDevice.ry_init(host, port, nodeId, version);
#endif
}
@ -2317,7 +2316,7 @@ int main(int argc, char** argv)
unsigned int critical = 0;
CChangeMaster masterTci;
if (!masterTci.Init(conn)) {
if (!masterTci.Init()) {
break;
}

View File

@ -297,7 +297,7 @@ bool CRYDevice::publish_sensor_data(noPollConn* conn, const std::string traceId,
jsonRoot["cmd"] = command;
char str[128];
snprintf(str, sizeof(str), "%lld", snowflake_next_id(&m_sf));
snprintf(str, sizeof(str), "%lld", snowflake_next_id());
if (traceId == "") {
jsonRoot["cmdId"] = str;
@ -311,7 +311,7 @@ bool CRYDevice::publish_sensor_data(noPollConn* conn, const std::string traceId,
jsonRoot["data"] = payload;
std::string outputConfig = Json::writeString(builder, jsonRoot);
vLog(LOG_DEBUG, "send cmd: %s, payload: %d\n%s\n", command, outputConfig.length(), outputConfig.c_str());
vLog(LOG_DEBUG, "send cmd: %s, payload: %d\n", command, outputConfig.length());
int rc = websocket_write(conn, outputConfig.c_str(), outputConfig.length());
if (rc != 0) {
vLog(LOG_DEBUG, "websocket write is error<%d>,insert into database.\n", rc);
@ -1450,7 +1450,9 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
if (attr["type"].isString()) type = attr["type"].asString();
struct_attr name_param;
name_param.name = "";
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 (type == "yc") ycs.push_back(name_param);
else if (type == "yx") yxs.push_back(name_param);
@ -1504,10 +1506,12 @@ bool CRYDevice::dealConfigFile(const Json::Value jsonRoot)
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].value;
if (!param.isNull()) {
if (param["coef"].isDouble()) config_config.units[uid].ycs[k].coef = param["coef"].asFloat();
if (param["base"].isDouble()) config_config.units[uid].ycs[k].base = param["base"].asFloat();
if (param["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();
@ -1826,6 +1830,9 @@ bool CRYDevice::publishAnalogData(noPollConn* conn, int uid)
}
}
if (values.size()) {
Json::Int64 datatime = (Json::Int64)time(NULL);
datatime *= 1000;
root["dataTime"] = datatime;
root["deviceId"] = static_units[uid].deviceId;
root["values"] = values;
return publish_sensor_data(conn, "", "analogData", root);
@ -1845,6 +1852,9 @@ bool CRYDevice::publishStateData(noPollConn* conn, int uid)
}
}
if (values.size()) {
Json::Int64 datatime = (Json::Int64)time(NULL);
datatime *= 1000;
root["dataTime"] = datatime;
root["deviceId"] = static_units[uid].deviceId;
root["values"] = values;
return publish_sensor_data(conn, "", "stateData", root);
@ -1886,7 +1896,7 @@ void CRYDevice::releaseAllUnits(void)
}
}
noPollConn *CRYDevice::ry_init(const char *host, const int port, const char *nodeId, const char *version)
BOOLEAN CRYDevice::ry_init(const char *host, const int port, const char *nodeId, const char *version)
{
snprintf(m_host, sizeof(m_host), "%s", host);
snprintf(m_nodeId, sizeof(m_nodeId), "%s", nodeId);
@ -1948,10 +1958,10 @@ noPollConn *CRYDevice::ry_init(const char *host, const int port, const char *nod
vLog(LOG_DEBUG, "%d here to connect:%s:%s.\n", __LINE__, m_host, cPort);
releaseAllUnits();
conn = nopoll_conn_new(ctx, m_host, cPort, NULL, url, NULL, NULL);
//last_connect_sec = system32.timers;
g_conn = conn;
}
return conn;
return TRUE;
}
bool CRYDevice::ry_run(void)
@ -1960,7 +1970,7 @@ bool CRYDevice::ry_run(void)
if (isOk) {
last_connect_sec = system32.timers;
int msg_count = 0;
noPollMsg *msg[40];
noPollMsg *msg[2048];
while ((msg[msg_count] = nopoll_conn_get_msg(conn)) != NULL) {
vLog(LOG_DEBUG, "recv length = %d, %d\n", nopoll_msg_get_payload_size(msg[msg_count]), nopoll_msg_is_final(msg[msg_count]));
if (nopoll_msg_is_final(msg[msg_count])) {
@ -1994,6 +2004,7 @@ bool CRYDevice::ry_run(void)
vLog(LOG_DEBUG, "%d here to connect:%s:%s.\n", __LINE__, m_host, cPort);
releaseAllUnits();
conn = nopoll_conn_new(ctx, m_host, cPort, NULL, url, NULL, NULL);
g_conn = conn;
last_connect_sec = system32.timers;
}
}
@ -2012,7 +2023,7 @@ bool CRYDevice::ry_run(void)
MakeYKFrame(conn, i);
MakeYTFrame(conn, i);
if (sec_changed) {
publishinitDeviceData(conn, i);
//publishinitDeviceData(conn, i);
if ((last_sec % 60) == 0) { //更新数据
publishAnalogData(conn, i);
publishStateData(conn, i);

View File

@ -46,30 +46,17 @@ typedef std::unordered_map<std::string, name2servicemap> unitname2servicemap;
typedef struct {
std::string name;
Json::Value value;
int highSpeed;
} struct_attr;
typedef std::vector<struct_attr> attrvector;
#define WORKER_ID_BITS 5
#define DATA_CENTER_ID_BITS 5
#define SEQUENCE_BITS 12
#define MAX_WORKER_ID ((1 << WORKER_ID_BITS) - 1)
#define MAX_DATA_CENTER_ID ((1 << DATA_CENTER_ID_BITS) - 1)
#define SEQUENCE_MASK ((1 << SEQUENCE_BITS) - 1)
#define EPOCH 1640995200000 // 2022-01-01 00:00:00
typedef struct {
uint64_t worker_id;
uint64_t data_center_id;
uint64_t sequence;
uint64_t last_timestamp;
} Snowflake;
class CRYDevice
{
public:
CRYDevice();
~CRYDevice();
noPollConn *ry_init(const char*, const int, const char*, const char*);
BOOLEAN ry_init(const char*, const int, const char*, const char*);
void ry_destroy(void);
bool ry_run(void);
private:
@ -81,8 +68,6 @@ private:
LONG m_yxbwload = 0;
LONG m_ycbwload = 0;
Snowflake m_sf = {1, 1, 0, 0};
struSystem config_system32;
struConfig config_config;
struDatabase config_database;
@ -104,32 +89,6 @@ private:
time_t last_sec;
private:
uint64_t current_time() {
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
}
uint64_t snowflake_next_id(Snowflake *sf) {
uint64_t timestamp = current_time();
if (timestamp < sf->last_timestamp) {
return 0;
}
if (sf->last_timestamp == timestamp) {
sf->sequence = (sf->sequence + 1) & SEQUENCE_MASK;
if (sf->sequence == 0) {
while (current_time() <= sf->last_timestamp);
}
} else {
sf->sequence = 0; // reset sequence
}
sf->last_timestamp = timestamp;
return ((timestamp - EPOCH) << (WORKER_ID_BITS + DATA_CENTER_ID_BITS + SEQUENCE_BITS)) |
(sf->data_center_id << (WORKER_ID_BITS + SEQUENCE_BITS)) |
(sf->worker_id << SEQUENCE_BITS) |
sf->sequence;
}
std::vector<std::string> split(const std::string &s, char delimiter);
bool configInitializeMemory(void);

View File

@ -1720,15 +1720,7 @@ BOOLEAN CProcess::Create(int id)
}
return TRUE;
}
#if 0
BOOLEAN CProcess::OnCreated(int id)
{
m_bRunFlag = TRUE;
threadpool_add_task(&pool, main_run_process, this);
return TRUE;
}
#endif
BOOLEAN CProcess::OnCreated(int id)
{
m_bRunFlag = TRUE;

View File

@ -53,6 +53,9 @@ char configfile[MAX_PATH] = "./conf/config.db"; //配置文件
QWORD system_timems;
noPollConn *g_conn;
Snowflake g_sf = {1, 1, 0, 0};
static eLogLevel eLevelMax = LOG_DEBUG; //LOG_DEBUG;
static const char* arszLevel2Str[] = { "NULL", "ERROR", "WARN", "INFO", "DEBUG" };
static pthread_t p_id[MAX_THREAD_NUM];
@ -447,6 +450,46 @@ unionCP56Time Time_ttounionCP56Time(time_t st)
return ct;
}
QLONG filetime_to_unix(QLONG ft)
{
uint64_t winTime = ft;
// 将100纳秒间隔转换为毫秒
winTime /= 10000;
// 减去从1601年到1970年的毫秒数
winTime -= 11644473600000LL;
// 将毫秒转换为秒
return (winTime);
}
QWORD current_time()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
}
QWORD snowflake_next_id(void)
{
QWORD timestamp = current_time();
if (timestamp < g_sf.last_timestamp) {
return 0;
}
if (g_sf.last_timestamp == timestamp) {
g_sf.sequence = (g_sf.sequence + 1) & SEQUENCE_MASK;
if (g_sf.sequence == 0) {
while (current_time() <= g_sf.last_timestamp);
}
} else {
g_sf.sequence = 0; // reset sequence
}
g_sf.last_timestamp = timestamp;
return ((timestamp - EPOCH) << (WORKER_ID_BITS + DATA_CENTER_ID_BITS + SEQUENCE_BITS)) |
(g_sf.data_center_id << (WORKER_ID_BITS + SEQUENCE_BITS)) |
(g_sf.worker_id << SEQUENCE_BITS) |
g_sf.sequence;
}
void alarm(void)
{
}

File diff suppressed because it is too large Load Diff

View File

@ -4,10 +4,169 @@
#include "netproc.h"
#include "modbus_def.h"
#define HAVE_FTP_PROCESS
#ifdef HAVE_FTP_PROCESS
#include <dirent.h>
#include <nopoll.h>
#include <nopoll_decl.h>
#pragma pack(1)
typedef struct {
QLONG localtime;// PLC本地时间 8 none 0.0001 毫秒 little endian 系统
WORD iGenSpeed;// 发电机转速 2 200 0.1 转/分 40ms 控制系统
WORD iGenPower;// 机组有功功率 2 201 0.1 千瓦 40ms 控制系统
WORD iWindSpeed;// 风速 2 202 0.01 米/秒 40ms 气象
WORD iVibrationY;// 机舱振动前后方向 2 203 0.001 米/秒^2 40ms 机舱
WORD iVibrationZ;// 机舱振动左右方向 2 204 0.001 米/秒^2 40ms 机舱
WORD iTurbineOperationMode;// 运行模式 2 205 1 需要解析 1s 控制系统
WORD iBPLevel;// 刹车等级 2 206 1 需要解析 1s 控制系统
WORD iYPLevel;// 偏航运行模式 2 207 1 需要解析 1s 控制系统
WORD iGenSpeed1s;// 发电机转速1秒均值 2 209 0.1 转/分 1s 控制系统
WORD iGenPower1s;// 机组有功1秒均值 2 210 0.1 千瓦 1s 控制系统
WORD iWindSpeed1s;// 风速1秒均值 2 208 0.01 米/秒 1s 控制系统
WORD iGenToruqe1s;// 发电机扭矩1秒均值 2 211 0.1 牛米 1s 控制系统
WORD iRotorSpeed;// 风轮转速 2 212 0.1 转/分 1s 控制系统
WORD iTheoreticalPower;// 理论有功功率 2 213 0.1 千瓦 1s 控制系统
WORD iReactivePower;// 无功功率 2 214 0.1 千乏 1s 控制系统
WORD iActivePowerSetPointValue;// 有功设定值 2 215 0.1 千瓦 1s 控制系统
WORD iCosPhiSetValue;// 功率因数设定值 2 216 0.001 . 1s 控制系统
WORD iSetValueGenSpeed;// 发电机转速设定值 2 217 0.1 转/分 1s 控制系统
WORD iSetValuePitchAngle;// 桨叶角度设定值 2 218 0.01 度 1s 控制系统
WORD iPitchAngle1RefValue;// 桨叶1角度给定 2 219 0.01 度 1s 控制系统
WORD iPitchAngle2RefValue;// 桨叶2角度给定 2 220 0.01 度 1s 控制系统
WORD iPitchAngle3RefValue;// 桨叶3角度给定 2 221 0.01 度 1s 控制系统
WORD iPitchAngle1;// 桨叶1角度 2 222 0.01 度 1s 变桨系统
WORD iPitchAngle2;// 桨叶2角度 2 223 0.01 度 1s 变桨系统
WORD iPitchAngle3;// 桨叶3角度 2 224 0.01 度 1s 变桨系统
WORD iVaneDirection;// 机舱方向 2 225 0.1 度 1s 气象
WORD iWindDirection;// 风向(与机舱夹角) 2 226 0.1 度 1s 气象
WORD StateWord01;// 状态字01 2 227 1 需要解析 1s 控制系统 详细解析见 状态字解析
WORD StateWord02;// 状态字02 2 228 1 需要解析 1s 控制系统
WORD StateWord03;// 状态字03 2 229 1 需要解析 1s 控制系统
WORD StateWord04;// 状态字04 2 230 1 需要解析 1s 控制系统
WORD StateWord05;// 状态字05 2 231 1 需要解析 1s 控制系统
WORD StateWord06;// 状态字06 2 232 1 需要解析 1s 控制系统
WORD StateWord07;// 状态字07 2 233 1 需要解析 1s 控制系统
WORD StateWord08;// 状态字08 2 234 1 需要解析 1s 控制系统
DWORD ActiveStatusCode01;// 故障代码01 4 235 1 需要解析 1s 控制系统 代表目前已经触发的故障代码类似02HH04HL005L
DWORD ActiveStatusCode02;// 故障代码02 4 237 1 需要解析 1s 控制系统 详细解析见故障代码字解析
DWORD ActiveStatusCode03;// 故障代码03 4 239 1 需要解析 1s 控制系统
DWORD ActiveStatusCode04;// 故障代码04 4 241 1 需要解析 1s 控制系统
DWORD ActiveStatusCode05;// 故障代码05 4 243 1 需要解析 1s 控制系统
DWORD ActiveStatusCode06;// 故障代码06 4 245 1 需要解析 1s 控制系统
DWORD ActiveStatusCode07;// 故障代码07 4 247 1 需要解析 1s 控制系统
DWORD ActiveStatusCode08;// 故障代码08 4 249 1 需要解析 1s 控制系统
WORD iFrequency;// 电网频率 2 251 0.01 赫兹 1s 电网
WORD iUL1_690V;// 电网L1相电压 2 252 0.1 伏 1s 电网
WORD iUL2_690V;// 电网L2相电压 2 253 0.1 伏 1s 电网
WORD iUL3_690V;// 电网L3相电压 2 254 0.1 伏 1s 电网
WORD iIL1_690V;// 电网L1相电流 2 255 0.1 安 1s 电网
WORD iIL2_690V;// 电网L2相电流 2 256 0.1 安 1s 电网
WORD iIL3_690V;// 电网L3相电流 2 257 0.1 安 1s 电网
WORD iBlade1MotorCurrent;// 变桨电机1电流 2 258 0.1 安 1s 变桨系统
WORD iBlade2MotorCurrent;// 变桨电机2电流 2 259 0.1 安 1s 变桨系统
WORD iBlade3MotorCurrent;// 变桨电机3电流 2 260 0.1 安 1s 变桨系统
WORD iPitchAngleBk1;// 备用桨叶角度1 2 261 0.01 度 1s 变桨系统
WORD iPitchAngleBk2;// 备用桨叶角度2 2 262 0.01 度 1s 变桨系统
WORD iPitchAngleBk3;// 备用桨叶角度3 2 263 0.01 度 1s 变桨系统
WORD iCosPhi;// 并网点功率因数 2 264 0.001 . 1s 电网
WORD iGearPressA;// 齿轮箱油压A 2 265 0.1 巴 1s 齿轮箱
WORD iGearPressB;// 齿轮箱油压B 2 266 0.1 巴 1s 齿轮箱
WORD iHydrPress;// 液压系统压力 2 267 0.1 巴 1s 液压系统
WORD iNacellePositionLtd;// 机舱绝对方向 2 268 0.1 度 1s 机舱
WORD iCableTwistTotal;// 总扭缆角度 2 269 0.1 度 1s 机舱
WORD iNacellePositionTotal;// 机舱方向 2 270 0.1 度 1s 机舱
WORD iTempOutdoor_1sec;// 环境温度 2 271 0.1 摄氏度 1s 环境
WORD iTempHub_1sec;// 轮毂内温度 2 272 0.1 摄氏度 1s 轮毂
WORD iTempNacelle_1sec;// 机舱内温度 2 273 0.1 摄氏度 1s 机舱
WORD iTempTowerBase_1sec;// 塔基内温度 2 274 0.1 摄氏度 1s 塔基
WORD iTempCabinetNacelle_1sec;// 机舱柜内温度 2 275 0.1 摄氏度 1s 机舱
WORD iTempCabinetTowerBase_1sec;// 塔基柜内温度 2 276 0.1 摄氏度 1s 塔基
WORD iTempTransformer690_400V_1sec;// 400伏变压器温度 2 277 0.1 摄氏度 1s 塔基
WORD iTempMV_1sec;// 箱变温度 2 278 0.1 摄氏度 1s 箱变
WORD iBlade1TempMotor_1sec;// 变桨电机1温度 2 279 0.1 摄氏度 1s 变桨系统
WORD iBlade2TempMotor_1sec;// 变桨电机2温度 2 280 0.1 摄氏度 1s 变桨系统
WORD iBlade3TempMotor_1sec;// 变桨电机3温度 2 281 0.1 摄氏度 1s 变桨系统
WORD iBlade1TempBattBox_1sec;// 变桨电池柜1温度 2 282 0.1 摄氏度 1s 变桨系统
WORD iBlade2TempBattBox_1sec;// 变桨电池柜2温度 2 283 0.1 摄氏度 1s 变桨系统
WORD iBlade3TempBattBox_1sec;// 变桨电池柜3温度 2 284 0.1 摄氏度 1s 变桨系统
WORD iTempCntr_1sec;// 变桨中控箱温度 2 285 0.1 摄氏度 1s 变桨系统
WORD iBlade1TempInvBox_1sec;// 变桨逆变器1温度 2 286 0.1 摄氏度 1s 变桨系统
WORD iBlade2TempInvBox_1sec;// 变桨逆变器2温度 2 287 0.1 摄氏度 1s 变桨系统
WORD iBlade3TempInvBox_1sec;// 变桨逆变器3温度 2 288 0.1 摄氏度 1s 变桨系统
WORD iBlade1TempPMMHeatsink_1sec;// 变桨PMM1散热器温度 2 289 0.1 摄氏度 1s 变桨系统
WORD iBlade2TempPMMHeatsink_1sec;// 变桨PMM2散热器温度 2 290 0.1 摄氏度 1s 变桨系统
WORD iBlade3TempPMMHeatsink_1sec;// 变桨PMM3散热器温度 2 291 0.1 摄氏度 1s 变桨系统
WORD iBlade1TempPMCHeatsink_1sec;// 变桨PMC1散热器温度 2 292 0.1 摄氏度 1s 变桨系统
WORD iBlade2TempPMCHeatsink_1sec;// 变桨PMC2散热器温度 2 293 0.1 摄氏度 1s 变桨系统
WORD iBlade3TempPMCHeatsink_1sec;// 变桨PMC3散热器温度 2 294 0.1 摄氏度 1s 变桨系统
WORD iTempRotorBearA_1sec;// 主轴承A温度 2 295 0.1 摄氏度 1s 传动链
WORD iTempRotorBearB_1sec;// 主轴承B温度 2 296 0.1 摄氏度 1s 传动链
WORD iTemp1GearOil_1sec;// 齿轮箱油温 2 297 0.1 摄氏度 1s 齿轮箱
WORD iTempGearBearDE_1sec;// 齿轮箱驱动齿轴承温度 2 298 0.1 摄氏度 1s 齿轮箱
WORD iTempGearBearNDE_1sec;// 齿轮箱非驱动侧轴承温度 2 299 0.1 摄氏度 1s 发电机
WORD iTempGenBearDE_1sec;// 发电机驱动侧轴承温度 2 300 0.1 摄氏度 1s 发电机
WORD iTempGenBearNDE_1sec;// 发电机非驱动侧轴承温度 2 301 0.1 摄氏度 1s 发电机
WORD iTempGenStatorU_1sec;// 发电机绕组U温度 2 302 0.1 摄氏度 1s 发电机
WORD iTempGenStatorV_1sec;// 发电机绕组V温度 2 303 0.1 摄氏度 1s 发电机
WORD iTempGenStatorW_1sec;// 发电机绕组W温度 2 304 0.1 摄氏度 1s 发电机
WORD iTempGenCoolingAir_1sec;// 发电机冷却风温度 2 305 0.1 摄氏度 1s 发电机
WORD iAvailabillityToday;// 当天可利用率 2 306 0.001 . 1s 控制系统
WORD iAvailabillityTotal;// 总可利用率 2 307 0.001 . 1s 控制系统
DWORD iKWhThisDay;// 当天发电量 2 308 千瓦时 1s 控制系统
DWORD iKWhOverall;// 总发电量 2 310 千瓦时 1s 控制系统
WORD iOperationHoursDay;// 当天发电小时数 2 312 小时 1s 控制系统
DWORD iOperationHoursOverall;// 总发电小时数 2 313 小时 1s 控制系统
WORD iLostKWhThisDay;// 当天损失发电量 2 315 千瓦时 1s 控制系统
DWORD iLostKWhOverall;// 总损失发电量 2 316 千瓦时 1s 控制系统
DWORD FirstTriggeredCode;// 首触故障代码高 4 318 1 1s 控制系统 详细解析见故障代码字解析
WORD SCW001;// 故障代码字01 2 320 1 1s 控制系统
WORD SCW002;// 故障代码字02 2 321 1 1s 控制系统
WORD SCW003;// 故障代码字03 2 322 1 1s 控制系统
WORD SCW004;// 故障代码字04 2 323 1 1s 控制系统
WORD SCW005;// 故障代码字05 2 324 1 1s 控制系统
WORD SCW006;// 故障代码字06 2 325 1 1s 控制系统
WORD SCW007;// 故障代码字07 2 326 1 1s 控制系统
WORD SCW008;// 故障代码字08 2 327 1 1s 控制系统
WORD SCW009;// 故障代码字09 2 328 1 1s 控制系统
WORD SCW010;// 故障代码字10 2 329 1 1s 控制系统
WORD SCW011;// 故障代码字11 2 330 1 1s 控制系统
WORD SCW012;// 故障代码字12 2 331 1 1s 控制系统
WORD SCW013;// 故障代码字13 2 332 1 1s 控制系统
WORD SCW014;// 故障代码字14 2 333 1 1s 控制系统
WORD SCW015;// 故障代码字15 2 334 1 1s 控制系统
WORD SCW016;// 故障代码字16 2 335 1 1s 控制系统
WORD SCW017;// 故障代码字17 2 336 1 1s 控制系统
WORD SCW018;// 故障代码字18 2 337 1 1s 控制系统
WORD SCW019;// 故障代码字19 2 338 1 1s 控制系统
WORD SCW020;// 故障代码字20 2 339 1 1s 控制系统
WORD SCW021;// 故障代码字21 2 340 1 1s 控制系统
WORD SCW022;// 故障代码字22 2 341 1 1s 控制系统
WORD SCW023;// 故障代码字23 2 342 1 1s 控制系统
WORD SCW024;// 故障代码字24 2 343 1 1s 控制系统
WORD SCW025;// 故障代码字25 2 344 1 1s 控制系统
WORD SCW026;// 故障代码字26 2 345 1 1s 控制系统
WORD SCW027;// 故障代码字27 2 346 1 1s 控制系统
WORD SCW028;// 故障代码字28 2 347 1 1s 控制系统
WORD SCW029;// 故障代码字29 2 348 1 1s 控制系统
WORD SCW030;// 故障代码字30 2 349 1 1s 控制系统
WORD SCW031;// 故障代码字31 2 350 1 1s 控制系统
WORD SCW032;// 故障代码字32 2 351 1 1s 控制系统
WORD SCW033;// 故障代码字33 2 352 1 1s 控制系统
WORD SCW034;// 故障代码字34 2 353 1 1s 控制系统
WORD SCW035;// 故障代码字35 2 354 1 1s 控制系统
WORD SCW036;// 故障代码字36 2 355 1 1s 控制系统
WORD SCW037;// 故障代码字37 2 356 1 1s 控制系统
WORD SCW038;// 故障代码字38 2 357 1 1s 控制系统
WORD SCW039;// 故障代码字39 2 358 1 1s 控制系统
WORD SCW040;// 故障代码字40 2 359 1 1s 控制系统
WORD SCW041;// 故障代码字41 2 360 1 1s 控制系统
WORD SCW042;// 故障代码字42 2 361 1 1s 控制系统
} struRYDeviceData;
#pragma pack()
#endif
class CHostModbusTcpProcessItem : public CNetProcessItem
{
public:
@ -56,11 +215,12 @@ private:
void sort1(STRUCT_PARAM*, int); //功能码排序
void sort2(STRUCT_PARAM*, int); //寄存地址排序
#ifdef HAVE_FTP_PROCESS
//增加websocket连接
pthread_t m_pid;
short m_uid;
public:
noPollConn *m_conn;
int m_iv;
LONG m_currentDirNo; //当前目录编号
LONG m_currentFileNo; //当前文件编号
@ -83,8 +243,10 @@ public:
return 1;
}
#endif
public:
CHostModbusTcpProcess(noPollConn *conn);
CHostModbusTcpProcess();
virtual ~CHostModbusTcpProcess();
CNetProcessItem *CreateItem(int ord);
@ -102,7 +264,9 @@ public:
BOOLEAN OnReceiveData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count);
int OnPackageReceived(BYTE* pBuf, int count, int ord /* = -1 */);
#ifdef HAVE_FTP_PROCESS
virtual BOOLEAN OnReceiveIDData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count);
#endif
virtual BOOLEAN OnReceiveYXData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count);
virtual BOOLEAN OnReceiveYCData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count);
virtual BOOLEAN OnReceiveYMData(CHostModbusTcpProcessItem *pItem, BYTE* pData, int count);

View File

@ -40,6 +40,8 @@ typedef int SOCKET;
#include <vector>
#include <sys/stat.h>
#include "zlog/zlog.h"
#include <nopoll.h>
#include <nopoll_decl.h>
#define MEMERY_1M 65536 //设置位64K
#define DELAY_RUN 5000
@ -405,6 +407,22 @@ typedef int SOCKET;
#define MAX_TARGET_FORMULA_LEN 1024
#define FORMULA_STRING_LENGTH 200
#define WORKER_ID_BITS 5
#define DATA_CENTER_ID_BITS 5
#define SEQUENCE_BITS 12
#define MAX_WORKER_ID ((1 << WORKER_ID_BITS) - 1)
#define MAX_DATA_CENTER_ID ((1 << DATA_CENTER_ID_BITS) - 1)
#define SEQUENCE_MASK ((1 << SEQUENCE_BITS) - 1)
#define EPOCH 1640995200000 // 2022-01-01 00:00:00
typedef struct {
uint64_t worker_id;
uint64_t data_center_id;
uint64_t sequence;
uint64_t last_timestamp;
} Snowflake;
#pragma pack(1)
//for formulas
@ -861,6 +879,8 @@ typedef struct
DWORD update_time;
QLONG irn;
//是否高频属性, 0 - 不是, 1 - 是
BOOLEAN highSpeed;
//上界
float upBound;
//下界
@ -1278,9 +1298,8 @@ extern struMsgBuffer msgBuffer;
extern struNodeOption nodes;
extern char configpath[MAX_PATH]; //配置文件所在目录
extern char configfile[MAX_PATH]; //配置文件
#if 0
extern threadpool_t pool;
#endif
extern noPollConn *g_conn;
typedef struct
{
//网络配置信息
@ -1309,53 +1328,6 @@ typedef struct
#define MQTT_DEFAULT_PORT 1883
#if 0
typedef struct ANYWARN
{
BYTE type;
BYTE warnType;
} ANYWARN, *PANYWARN;
typedef struct YX_WARN {
BYTE type;
BYTE warnType;
BYTE unitID;
BYTE realVal;
short dotNo;
unionCP56Time warnTime;
} YX_WARN,*PYX_WARN;
typedef struct YC_WARN {
BYTE type;
BYTE warnType;
BYTE unitID;
short dotNo;
float realVal;
unionCP56Time warnTime;
} YC_WARN, *PYC_WARN;
typedef struct UNIT_WARN {
BYTE type;
BYTE warnType;
BYTE unitID;
BYTE realVal;
unionCP56Time warnTime;
} UNIT_WARN, *PUNIT_WARN;
typedef union WARN {
ANYWARN any_warn;
YX_WARN yx_warn;
YC_WARN yc_warn;
UNIT_WARN unit_warn;
} WARN, *PWARN;
typedef struct _tag_SEND_WARNBUF {
LONG total_warn;
LONG id;
WARN warn[1];
} SEND_WARNBUF, *PSEND_WARNBUF;
#endif
#pragma pack()
//////////////////////////////////////////////////////////////////////////
@ -1372,6 +1344,7 @@ int unionCP56TimeToBuf(BYTE* buf, unionCP56Time st);
int GetFileSize(const char* fname);
time_t unionCP56TimetoTime_t(unionCP56Time* st);
unionCP56Time Time_ttounionCP56Time(time_t st);
QLONG filetime_to_unix(QLONG ft);
QWORD getTimeInMs();
//////////////////////////////////////////////////////////////////////////
typedef enum
@ -1390,6 +1363,7 @@ extern "C"
void yk(void);
void yt(void);
void dumpLogs(void);
QWORD snowflake_next_id(void);
BOOLEAN initialize_system(BOOLEAN, BOOLEAN, const char*, char*);
BOOLEAN initialize_thread(void);
BOOLEAN destroy_thread(void);

View File

@ -41,9 +41,6 @@ public class SysMenusController {
if(!hasPermission){
return R.fail("没有系统管理权限");
}
if (StringUtils.isAllEnglishLetters(sysMenuDto.getMenuName())){
return R.fail("菜单名称,必须为英文");
}
return R.success(sysMenuService.createMenu(sysMenuDto));
}

View File

@ -0,0 +1,112 @@
package com.das.modules.equipment.controller;
import cn.dev33.satoken.stp.StpUtil;
import com.das.common.constant.SysAuthorityIds;
import com.das.common.exceptions.ServiceException;
import com.das.common.result.R;
import com.das.common.utils.PageDataInfo;
import com.das.modules.equipment.domain.dto.SysEnumTypesDto;
import com.das.modules.equipment.domain.dto.SysEnumValuesDto;
import com.das.modules.equipment.domain.vo.SysEnumTypesVo;
import com.das.modules.equipment.domain.vo.SysEnumValuesVo;
import com.das.modules.equipment.service.SysEnumService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 枚举类型配置Controller
*/
@RestController
@RequestMapping("/api/enum")
public class SysEnumController {
@Autowired
private SysEnumService sysEnumService;
/** 新增枚举类型 */
@PostMapping("/addEnumTypes")
public R<SysEnumTypesVo> addEnumTypes(@RequestBody SysEnumTypesDto sysEnumTypesDto) {
//判断是否有权限
boolean hasPermission = StpUtil.hasPermission(SysAuthorityIds.SYS_AUTHORITY_ID_DEVICE_MGR.toString());
if(!hasPermission){
return R.fail("没有设备管理权限");
}
if (StringUtils.isBlank(sysEnumTypesDto.getName())) {
throw new ServiceException("参数缺失");
}
SysEnumTypesVo sysEnumTypesVo = sysEnumService.addEnumTypes(sysEnumTypesDto);
return R.success(sysEnumTypesVo);
}
/** 新增枚举值 */
@PostMapping("/addEnumValues")
public R<SysEnumValuesVo> addEnumValues(@RequestBody SysEnumValuesDto sysEnumValuesDto) {
//判断是否有权限
boolean hasPermission = StpUtil.hasPermission(SysAuthorityIds.SYS_AUTHORITY_ID_DEVICE_MGR.toString());
if(!hasPermission){
return R.fail("没有设备管理权限");
}
if (sysEnumValuesDto.getEnumTypeId() ==null && StringUtils.isBlank(sysEnumValuesDto.getValue())
|| sysEnumValuesDto.getOrderNumber() == null || sysEnumValuesDto.getIsActive() ==null) {
throw new ServiceException("参数缺失");
}
SysEnumValuesVo sysEnumValuesVo = sysEnumService.addEnumValues(sysEnumValuesDto);
return R.success(sysEnumValuesVo);
}
/**
* 查询枚举类型列表
*
* */
@PostMapping("/queryEnumTypesList")
public R<List<SysEnumTypesVo>> queryEnumTypesList() {
return R.success(sysEnumService.queryEnumTypesList());
}
/**
* 查询枚举类型列表
*
* */
@PostMapping("/queryEnumValuesList")
public R<PageDataInfo<SysEnumValuesVo>> queryEnumValuesList(@RequestBody SysEnumValuesDto sysEnumValuesDto) {
if (sysEnumValuesDto.getEnumTypeId() == null) {
throw new ServiceException("参数缺失");
}
if (sysEnumValuesDto.getPageNum() ==null){
sysEnumValuesDto.setPageNum(1);
}
if (sysEnumValuesDto.getPageSize() ==null){
sysEnumValuesDto.setPageSize(30);
}
return R.success(sysEnumService.queryEnumValuesList(sysEnumValuesDto));
}
/**
* 删除枚举值
* */
@PostMapping("/deleteEnumValues")
public R<List<SysEnumValuesVo>> deleteEnumValues(@RequestBody SysEnumValuesDto sysEnumValuesDto) {
//判断是否有权限
boolean hasPermission = StpUtil.hasPermission(SysAuthorityIds.SYS_AUTHORITY_ID_DEVICE_MGR.toString());
if(!hasPermission){
return R.fail("没有设备管理权限");
}
if (sysEnumValuesDto.getId() ==null){
throw new ServiceException("参数缺失");
}
sysEnumService.deleteEnumValues(sysEnumValuesDto);
return R.success();
}
}

View File

@ -0,0 +1,27 @@
package com.das.modules.equipment.domain.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SysEnumTypesDto {
@Serial
private static final long serialVersionUID = 1L;
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
private String name;
private String description;
}

View File

@ -0,0 +1,51 @@
package com.das.modules.equipment.domain.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import java.io.Serial;
@Data
public class SysEnumValuesDto {
@Serial
private static final long serialVersionUID = 1L;
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 关联到枚举类型表的ID
*/
private Long enumTypeId;
/**
* 枚举值的具体内容
*/
private String value;
/**
* 描述
*/
private String description;
/**
* 排序
*/
private Integer orderNumber;
/**
* 是否有效
*/
private Integer isActive;
/**
* 分页大小
*/
private Integer pageSize;
/**
* 当前页数
*/
private Integer pageNum;
}

View File

@ -0,0 +1,27 @@
package com.das.modules.equipment.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SysEnumTypesVo {
@Serial
private static final long serialVersionUID = 1L;
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
private String name;
private String description;
}

View File

@ -0,0 +1,41 @@
package com.das.modules.equipment.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import java.io.Serial;
@Data
public class SysEnumValuesVo {
@Serial
private static final long serialVersionUID = 1L;
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 关联到枚举类型表的ID
*/
private Long enumTypeId;
/**
* 枚举值的具体内容
*/
private String value;
/**
* 描述
*/
private String description;
/**
* 排序
*/
private Integer orderNumber;
/**
* 是否有效
*/
private Integer isActive;
}

View File

@ -0,0 +1,37 @@
package com.das.modules.equipment.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.das.common.constant.BaseEntity;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.io.Serial;
@EqualsAndHashCode(callSuper = true)
@TableName("sys_enum_types")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SysEnumTypes extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.ASSIGN_ID)
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
@TableField("name")
private String name;
@TableField("description")
private String description;
}

View File

@ -0,0 +1,65 @@
package com.das.modules.equipment.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.das.common.constant.BaseEntity;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.io.Serial;
@EqualsAndHashCode(callSuper = true)
@TableName("sys_enum_values")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SysEnumValues extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.ASSIGN_ID)
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 关联到枚举类型表的ID
*/
@TableField("enum_type_id")
private Long enumTypeId;
/**
* 枚举值的具体内容
*/
@TableField("value")
private String value;
/**
* 描述
*/
@TableField("description")
private String description;
/**
* 排序
*/
@TableField("order_number")
private Integer orderNumber;
/**
* 是否有效
*/
@TableField("is_active")
private Integer isActive;
}

View File

@ -0,0 +1,9 @@
package com.das.modules.equipment.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.das.modules.equipment.entity.SysEnumTypes;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SysEnumTypesMapper extends BaseMapper<SysEnumTypes> {
}

View File

@ -0,0 +1,17 @@
package com.das.modules.equipment.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.das.common.utils.PageDataInfo;
import com.das.modules.auth.mapper.BaseMapperPlus;
import com.das.modules.equipment.domain.dto.SysEnumValuesDto;
import com.das.modules.equipment.domain.vo.SysEnumValuesVo;
import com.das.modules.equipment.entity.SysEnumValues;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface SysEnumValuesMapper extends BaseMapperPlus<SysEnumValues,SysEnumValues> {
IPage <SysEnumValuesVo> queryEnumValuesList(IPage<SysEnumValuesVo> page ,
@Param("sysEnumValuesDto") SysEnumValuesDto sysEnumValuesDto);
}

View File

@ -0,0 +1,24 @@
package com.das.modules.equipment.service;
import com.das.common.utils.PageDataInfo;
import com.das.modules.equipment.domain.dto.SysEnumTypesDto;
import com.das.modules.equipment.domain.dto.SysEnumValuesDto;
import com.das.modules.equipment.domain.vo.SysEnumTypesVo;
import com.das.modules.equipment.domain.vo.SysEnumValuesVo;
import java.util.List;
public interface SysEnumService {
SysEnumTypesVo addEnumTypes(SysEnumTypesDto sysEnumTypesDto);
SysEnumValuesVo addEnumValues(SysEnumValuesDto sysEnumValuesDto);
List<SysEnumTypesVo> queryEnumTypesList();
PageDataInfo<SysEnumValuesVo> queryEnumValuesList(SysEnumValuesDto sysEnumValuesDto);
void deleteEnumValues(SysEnumValuesDto sysEnumValuesDto);
}

View File

@ -0,0 +1,115 @@
package com.das.modules.equipment.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.das.common.config.SessionUtil;
import com.das.common.utils.BeanCopyUtils;
import com.das.common.utils.PageDataInfo;
import com.das.common.utils.PageQuery;
import com.das.modules.auth.domain.vo.SysUserVo;
import com.das.modules.equipment.domain.dto.SysEnumTypesDto;
import com.das.modules.equipment.domain.dto.SysEnumValuesDto;
import com.das.modules.equipment.domain.vo.SysEnumTypesVo;
import com.das.modules.equipment.domain.vo.SysEnumValuesVo;
import com.das.modules.equipment.entity.SysEnumTypes;
import com.das.modules.equipment.entity.SysEnumValues;
import com.das.modules.equipment.mapper.SysEnumTypesMapper;
import com.das.modules.equipment.mapper.SysEnumValuesMapper;
import com.das.modules.equipment.service.SysEnumService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Service
public class SysEnumServiceImpl implements SysEnumService {
@Autowired
private SysEnumTypesMapper sysEnumTypesMapper;
@Autowired
private SysEnumValuesMapper sysEnumValuesMapper;
/** 新增枚举类型 */
@Override
public SysEnumTypesVo addEnumTypes(SysEnumTypesDto sysEnumTypesDto) {
SysEnumTypes sysEnumTypes = new SysEnumTypes();
BeanCopyUtils.copy(sysEnumTypesDto, sysEnumTypes);
SysUserVo sysUserVo = (SysUserVo) StpUtil.getTokenSession().get(SessionUtil.SESSION_USER_KEY);
sysEnumTypes.setCreatedTime(new Date());
sysEnumTypes.setUpdatedTime(new Date());
sysEnumTypes.setCreatedBy(sysUserVo.getAccount());
sysEnumTypes.setUpdatedBy(sysUserVo.getAccount());
sysEnumTypes.setRevision(1);
sysEnumTypesMapper.insert(sysEnumTypes);
SysEnumTypesVo sysEnumTypesVo = new SysEnumTypesVo();
BeanCopyUtils.copy(sysEnumTypes, sysEnumTypesVo);
return sysEnumTypesVo;
}
/** 新增枚举值 */
@Override
public SysEnumValuesVo addEnumValues(SysEnumValuesDto sysEnumValuesDto) {
SysEnumValues sysEnumValues = new SysEnumValues();
BeanCopyUtils.copy(sysEnumValuesDto,sysEnumValues);
SysUserVo sysUserVo = (SysUserVo) StpUtil.getTokenSession().get(SessionUtil.SESSION_USER_KEY);
sysEnumValues.setCreatedTime(new Date());
sysEnumValues.setUpdatedTime(new Date());
sysEnumValues.setCreatedBy(sysUserVo.getAccount());
sysEnumValues.setUpdatedBy(sysUserVo.getAccount());
sysEnumValues.setRevision(1);
sysEnumValuesMapper.insert(sysEnumValues);
SysEnumValuesVo sysEnumValuesVo = new SysEnumValuesVo();
BeanCopyUtils.copy(sysEnumValues, sysEnumValuesVo);
return sysEnumValuesVo;
}
/**
* 查询枚举类型列表
* @return
*/
@Override
public List<SysEnumTypesVo> queryEnumTypesList() {
List<SysEnumTypes> sysEnumTypes = sysEnumTypesMapper.selectList(null);
List<SysEnumTypesVo> resultList = new ArrayList<>();
for (SysEnumTypes sysEnumType : sysEnumTypes) {
SysEnumTypesVo sysEnumTypesVo = new SysEnumTypesVo();
BeanCopyUtils.copy(sysEnumType,sysEnumTypesVo);
resultList.add(sysEnumTypesVo);
}
return resultList;
}
/**
* 查询枚举类型列表
* @param sysEnumValuesDto
* @return
*/
@Override
public PageDataInfo<SysEnumValuesVo> queryEnumValuesList(SysEnumValuesDto sysEnumValuesDto) {
PageQuery pageQuery = new PageQuery();
pageQuery.setPageNum(sysEnumValuesDto.getPageNum());
pageQuery.setPageSize(sysEnumValuesDto.getPageSize());
IPage<SysEnumValuesVo> iPage =
sysEnumValuesMapper.queryEnumValuesList(pageQuery.build(), sysEnumValuesDto);
return PageDataInfo.build(iPage.getRecords(), iPage.getTotal());
}
/**
* 删除枚举值
* @param sysEnumValuesDto
*/
@Override
public void deleteEnumValues(SysEnumValuesDto sysEnumValuesDto) {
SysEnumValues sysEnumValues = new SysEnumValues();
BeanCopyUtils.copy(sysEnumValuesDto,sysEnumValues);
SysUserVo sysUserVo = (SysUserVo) StpUtil.getTokenSession().get(SessionUtil.SESSION_USER_KEY);
sysEnumValues.setUpdatedBy(sysUserVo.getAccount());
sysEnumValues.setUpdatedTime(new Date());
sysEnumValues.setIsActive(0);
sysEnumValuesMapper.updateById(sysEnumValues);
}
}

View File

@ -58,21 +58,131 @@ public class TDEngineService {
}
}
/**
* 创建超级表
*/
public void createStable(String iotModelCode, String stableType, Map<String, String> fieldNameTypeMap) {
try (Connection conn = hikariDataSource.getConnection();
Statement pstmt = conn.createStatement()) {
StringBuilder sb = new StringBuilder(1024 * 1024);
sb.setLength(0);
Set<String> keySet = fieldNameTypeMap.keySet();
if (keySet.size() != 0) {
sb.append("CREATE STABLE IF NOT EXISTS ");
sb.append(stableType).append(iotModelCode);
sb.append(" (`updatetime` TIMESTAMP");
// 使用增强的 for 循环遍历键
for (String key : keySet) {
sb.append(", ");
sb.append(key);
sb.append(" " + fieldNameTypeMap.get(key));
}
sb.append(") TAGS (`deviceid` BIGINT);");
try {
System.out.println(sb.toString());
pstmt.executeUpdate(sb.toString());
} catch (Exception e) {
log.error("创建超级表失败,失败原因{}", e);
}
}
} catch (Exception ignored) {
}
}
/**
* 新增超级表列
*/
public void addStableColumn(String iotModelCode, String stableType, Map<String, String> fieldNameTypeMap) {
try (Connection conn = hikariDataSource.getConnection();
Statement pstmt = conn.createStatement()) {
StringBuilder sb = new StringBuilder(1024 * 1024);
sb.setLength(0);
Set<String> keySet = fieldNameTypeMap.keySet();
if (keySet.size() != 0) {
for (String key : keySet) {
sb.append("ALTER STABLE ");
sb.append(stableType).append(iotModelCode);
sb.append(" ADD COLUMN ");
sb.append(key);
sb.append(" " + fieldNameTypeMap.get(key));
sb.append(";");
try {
pstmt.executeUpdate(sb.toString());
} catch (Exception e) {
log.error("新增超级表列失败:{},失败原因{}", sb.toString(), e);
}
}
}
} catch (Exception ignored) {
}
}
/**
* 删除超级表列
*/
public void deleteColumn(String stableName, String fieldCode) {
try (Connection conn = hikariDataSource.getConnection();
Statement pstmt = conn.createStatement()) {
StringBuilder sb = new StringBuilder(1024 * 1024);
sb.setLength(0);
sb.append("ALTER STABLE ");
sb.append(stableName);
sb.append(" DROP COLUMN");;
sb.append(fieldCode);
sb.append(";");
try {
pstmt.executeUpdate(sb.toString());
} catch (Exception e) {
log.error("删除超级表列失败:{},失败原因{}", sb.toString(), e);
}
}catch (Exception ignored){
}
}
/**
* 删除超级表
*/
public void deleteStable(String stableName){
try (Connection conn = hikariDataSource.getConnection();
Statement pstmt = conn.createStatement()) {
StringBuilder sb = new StringBuilder(1024 * 1024);
sb.setLength(0);
sb.append("DROP STABLE ");
sb.append(stableName);
sb.append(";");
try {
pstmt.executeUpdate(sb.toString());
} catch (Exception e) {
log.error("删除超级表失败:{},失败原因{}", sb.toString(), e);
}
}catch (Exception ignored){
}
}
// 遍历所有的物模型存入内存中
public void initIotModel(List<IotModelFieldVo> allIotModel, ConcurrentHashMap<String,Map<String, Object>> highIotFieldMap,ConcurrentHashMap<String,Map<String, Object>> lowIotFieldMap) {
public void initIotModel(List<IotModelFieldVo> allIotModel, ConcurrentHashMap<String, Map<String, Object>> highIotFieldMap, ConcurrentHashMap<String, Map<String, Object>> lowIotFieldMap) {
// 创建物模型超级表
try (Connection conn = hikariDataSource.getConnection();
Statement pstmt = conn.createStatement()) {
ListUtil.page(allIotModel, batchSize, list ->{
ListUtil.page(allIotModel, batchSize, list -> {
for (IotModelFieldVo info : list) {
StringBuilder sb = new StringBuilder(1024*1024);
StringBuilder sb = new StringBuilder(1024 * 1024);
sb.setLength(0);
Map<String, Object> map = highIotFieldMap.get(info.getIotModelCode());
Set<String> keySet = map.keySet();
if (keySet.size() != 0){
if (keySet.size() != 0) {
sb.append("CREATE STABLE IF NOT EXISTS ");
sb.append("h_").append(info.getIotModelCode());
sb.append(" (`updatetime` TIMESTAMP");
@ -81,7 +191,7 @@ public class TDEngineService {
for (String key : map.keySet()) {
sb.append(", ");
sb.append(key);
sb.append(" float");
sb.append(" "+map.get(key));
}
sb.append(") TAGS (`deviceid` BIGINT);");
try {
@ -94,10 +204,10 @@ public class TDEngineService {
}
for (IotModelFieldVo info : list) {
StringBuilder sb = new StringBuilder(1024*1024);
StringBuilder sb = new StringBuilder(1024 * 1024);
sb.setLength(0);
Map<String, Object> map = lowIotFieldMap.get(info.getIotModelCode());
if (map.keySet().size() != 0){
if (map.keySet().size() != 0) {
sb.append("CREATE STABLE IF NOT EXISTS ");
sb.append("l_").append(info.getIotModelCode());
sb.append(" (`updatetime` TIMESTAMP");
@ -105,7 +215,7 @@ public class TDEngineService {
for (String key : map.keySet()) {
sb.append(", ");
sb.append(key);
sb.append(" float");
sb.append(" "+map.get(key));
}
sb.append(") TAGS (`deviceid` BIGINT);");
try {
@ -125,20 +235,20 @@ public class TDEngineService {
@Async
public void updateYCHighValues(List<RTData> values, String iotModelCode) {
StringBuilder sb = new StringBuilder(1024*1024);
StringBuilder sb = new StringBuilder(1024 * 1024);
try (Connection conn = hikariDataSource.getConnection();
Statement pstmt = conn.createStatement()) {
ListUtil.page(values, batchSize, (list)->{
ListUtil.page(values, batchSize, (list) -> {
sb.setLength(0);
sb.append("insert into ");
for (RTData dv : list) {
sb.append("h");
sb.append(dv.getDeviceId());
sb.append(" using h_" );
sb.append(" using h_");
sb.append(iotModelCode);
sb.append(" tags (");
sb.append(dv.getDeviceId());
sb.append(") (");
sb.append(") (updatetime");
dv.getValues().forEach((key, value) ->
sb.append(",").append(key)
);
@ -163,20 +273,20 @@ public class TDEngineService {
@Async
public void updateYCLowValues(List<RTData> values, String iotModelCode) {
StringBuilder sb = new StringBuilder(1024*1024);
StringBuilder sb = new StringBuilder(1024 * 1024);
try (Connection conn = hikariDataSource.getConnection();
Statement pstmt = conn.createStatement()) {
ListUtil.page(values, batchSize, (list)->{
ListUtil.page(values, batchSize, (list) -> {
sb.setLength(0);
sb.append("insert into ");
for (RTData dv : list) {
sb.append("l");
sb.append(dv.getDeviceId());
sb.append(" using l_" );
sb.append(" using l_");
sb.append(iotModelCode);
sb.append(" tags (");
sb.append(dv.getDeviceId());
sb.append(") (");
sb.append(") (updatetime");
dv.getValues().forEach((key, value) ->
sb.append(",").append(key)
);
@ -201,16 +311,16 @@ public class TDEngineService {
@Async
public void updateStataValues(List<RTData> values, String iotModelCode) {
StringBuilder sb = new StringBuilder(1024*1024);
StringBuilder sb = new StringBuilder(1024 * 1024);
try (Connection conn = hikariDataSource.getConnection();
Statement pstmt = conn.createStatement()) {
ListUtil.page(values, batchSize, (list)->{
ListUtil.page(values, batchSize, (list) -> {
sb.setLength(0);
sb.append("insert into ");
for (RTData dv : list) {
sb.append("d");
sb.append(dv.getDeviceId());
sb.append(" using " );
sb.append(" using ");
sb.append(iotModelCode);
sb.append(" tags (");
sb.append(dv.getDeviceId());

View File

@ -218,16 +218,16 @@ public class DataServiceImpl implements DataService {
String key = String.valueOf(item.getId());
iotModelMap.put(key, item.getIotModelCode());
List<SysIotModelField> allIotModelField = sysIotModelMapper.getAllIotModelField(item.getId());
List<String> LowModelFieldList = allIotModelField.stream().filter(field -> field.getHighSpeed() == 0).map(SysIotModelField::getAttributeCode).collect(Collectors.toList());
List<String> HighModelFieldList = allIotModelField.stream().filter(field -> field.getHighSpeed() == 1).map(SysIotModelField::getAttributeCode).collect(Collectors.toList());
Map<String,String> LowModelFieldList = allIotModelField.stream().filter(field -> field.getHighSpeed() == 0).collect(Collectors.toMap(SysIotModelField::getAttributeCode, SysIotModelField::getDataType, (value1, value2) -> value1));
Map<String,String> HighModelFieldList = allIotModelField.stream().filter(field -> field.getHighSpeed() == 1).collect(Collectors.toMap(SysIotModelField::getAttributeCode, SysIotModelField::getDataType, (value1, value2) -> value1));
Map<String, Object> map = new HashMap<>();
for (String field : HighModelFieldList) {
map.put(field, null);
for (String field : HighModelFieldList.keySet()) {
map.put(field, HighModelFieldList.get(field));
}
highIotFieldMap.put(item.getIotModelCode(), map);
Map<String, Object> lowMap = new HashMap<>();
for (String field : LowModelFieldList) {
lowMap.put(field, null);
for (String field : LowModelFieldList.keySet()) {
lowMap.put(field, LowModelFieldList.get(field));
}
lowIotFieldMap.put(item.getIotModelCode(), lowMap);
}
@ -288,7 +288,7 @@ public class DataServiceImpl implements DataService {
keyValueMap.put(fieldName, values.get(fieldName));
}
Long dataTime = data.getTime();
Long dataTime = jsonNode.get("dataTime").asLong();
List<RTData> highList = new ArrayList<>();
RTData rtHighData = RTData.builder()
.dataTime(dataTime)
@ -315,7 +315,7 @@ public class DataServiceImpl implements DataService {
keyValueMap.put(fieldName, values.get(fieldName));
}
Long dataTime = data.getTime();
Long dataTime = jsonNode.get("dataTime").asLong();
List<RTData> highList = new ArrayList<>();
RTData rtHighData = RTData.builder()
.dataTime(dataTime)

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.das.modules.equipment.mapper.SysEnumValuesMapper">
<resultMap type="com.das.modules.equipment.domain.vo.SysEnumValuesVo" id="EnumValuesMap">
<result property="enumTypeId" column="enum_type_id" jdbcType="BIGINT"/>
<result property="value" column="value" jdbcType="VARCHAR"/>
<result property="description" column="description" jdbcType="VARCHAR"/>
<result property="orderNumber" column="order_number" jdbcType="INTEGER"/>
<result property="isActive" column="is_active" jdbcType="INTEGER"/>
</resultMap>
<select id="queryEnumValuesList" resultMap="EnumValuesMap">
select e.* from sys_enum_values e
<where>
<if test="sysEnumValuesDto.description != null and sysEnumValuesDto.description != ''">
and e.description like concat('%',#{sysEnumValuesDto.description},'%')
</if>
<if test="sysEnumValuesDto.enumTypeId != null and sysEnumValuesDto.enumTypeId != ''">
and e.enum_type_id =#{sysEnumValuesDto.enumTypeId}
</if>
<if test="sysEnumValuesDto.isActive != null and sysEnumValuesDto.isActive != ''">
and e.is_active =#{sysEnumValuesDto.isActive}
</if>
</where>
</select>
</mapper>

View File

@ -77,7 +77,7 @@
where se.id = #{id}
</select>
<select id="getAllIotModelField" resultType="com.das.modules.equipment.entity.SysIotModelField">
select simf.attribute_code as attributeCode,simf.highspeed as highSpeed from sys_iot_model_field simf where simf.iot_model_id = #{id} order by simf.attribute_code
select simf.attribute_code as attributeCode,simf.highspeed as highSpeed,simf.datatype as dataType from sys_iot_model_field simf where simf.iot_model_id = #{id} order by simf.attribute_code
</select>

View File

@ -21,10 +21,18 @@ POST 请求接口
```json
{
[
{
"deviceId":"129476828342323",
"attributes":["power","windSpeed","dailyUsageHours","monthlyUsageHours"]
}
},
{
"deviceId":"129476828342324",
"attributes":["power","windSpeed","dailyUsageHours","monthlyUsageHours"]
}
......
]
```
入参描述
@ -33,6 +41,8 @@ POST 请求接口
| deviceId | String | no | 设备ID |
| attributes | StringArray | no | 要查询实时数据的设备属性列表 |
> PS: 当attributes为空时返回所有属性。
返回报文
```json
@ -41,14 +51,97 @@ POST 请求接口
"msg": "操作成功",
"success": true,
"data": {
"129476828342323":{
"power": 56.2,
"windSpeed": 45.3,
"dailyUsageHours": 20,
"monthlyUsageHours": 78,
....
},
"129476828342324":{
"power": 53.2,
"windSpeed": 35.3,
"dailyUsageHours": 10,
"monthlyUsageHours": 48,
....
}
}
}
```
返参描述
data 中以字典的方式,返回查询的属性的实时值。
data 中以字典的方式,返回查询的每个设备的属性的实时值。
### 历史区间数据查询
根据提供的开始时间及结束时间,查询指定设备在指定时间段内的历史数据。
POST 请求接口
> /api/data/history
请求参数
```json
{
//开始时间
"startTime": "123452435324242",
//结束时间
"endTime": "123452435924242",
//查询设备列表
"devices": [
{
//设备ID
"deviceId":"129476828342323",
//要查询的属性列表
"attributes":["power","windSpeed"]
},
{
"deviceId":"129476828342324",
"attributes":["power","dailyUsageHours"]
}
],
"interval": "1h"
}
```
入参描述
| 参数名 | 参数类型 | 可选 | 描述 |
| ------------ | -------- | ---- |------|
| startTime | String | no | 开始时间戳 |
| endTime | String | no | 结束时间戳 |
| devices.deviceId | String | no | 设备ID |
| devices.attributes | StringArray | no | 要查询实时数据的设备属性列表 |
| interval | String | yes | 抽样间隔,1a(毫秒),1s(秒),1m(分),1h(小时),1d(天),1w(周)。 忽略或者值为空时,返回原始数据(不抽样) |
| endTime | String | no | 结束时间戳 |
返回报文
```json
{
"code": 200,
"msg": "操作成功",
"success": true,
"data": {
//设备ID
"129476828342323":{
//属性名
"power": {
//时间戳列表
"times": [123452435924242,123452435924342,123452435924442,123452435924542],
//值列表
"values": [123.23,35.21,34.56,67]
} ,
//属性名
"windSpeed": {
"times": [123452435924242,123452435924342,123452435924442,123452435924542],
"values": [123.23,35.21,34.56,67]
}
},
.......
}
}
```

View File

@ -90,24 +90,33 @@
<el-main class="mainMain">
<el-tabs v-model="ModelTabs" @tab-change="changeTabs" class="tabsPart">
<el-tab-pane :label="modelTabsType['attribute']" name="attribute">
<el-table :data="attributeTableData" class="tablePart" highlight-current-row>
<el-table :data="attributeTableData" @sort-change="sortChange" class="tablePart" highlight-current-row>
<el-table-column
prop="porder"
:label="ModelAttributeFieldsEnums['porder']"
align="center"
sortable="custom"
width="80"
></el-table-column>
<el-table-column
prop="attributeName"
:label="ModelAttributeFieldsEnums['attributeName']"
align="center"
sortable="custom"
></el-table-column>
<el-table-column
prop="attributeCode"
:label="ModelAttributeFieldsEnums['attributeCode']"
align="center"
sortable="custom"
></el-table-column>
<el-table-column
prop="attributeTypeName"
:label="ModelAttributeFieldsEnums['attributeTypeName']"
align="center"
sortable="custom"
></el-table-column>
<el-table-column prop="porder" :label="ModelAttributeFieldsEnums['porder']" align="center"></el-table-column>
<el-table-column fixed="right" label="操作" min-width="80" align="center">
<el-table-column fixed="right" label="操作" width="130" align="center">
<template #default="scope">
<div class="tableOperate">
<a @click="editAttributeForm(scope.row)">编辑</a>
@ -123,15 +132,32 @@
</el-table>
</el-tab-pane>
<el-tab-pane :label="modelTabsType['service']" name="service">
<el-table :data="serviceTableData" class="tablePart">
<el-table-column prop="serviceName" :label="ModelServiceFieldsEnums['serviceName']" align="center"></el-table-column>
<el-table-column prop="serviceCode" :label="ModelServiceFieldsEnums['serviceCode']" align="center"></el-table-column>
<el-table :data="serviceTableData" @sort-change="sortChange" class="tablePart">
<el-table-column
prop="porder"
:label="ModelServiceFieldsEnums['porder']"
align="center"
sortable="custom"
width="80"
></el-table-column>
<el-table-column
prop="serviceName"
:label="ModelServiceFieldsEnums['serviceName']"
align="center"
sortable="custom"
></el-table-column>
<el-table-column
prop="serviceCode"
:label="ModelServiceFieldsEnums['serviceCode']"
align="center"
sortable="custom"
></el-table-column>
<el-table-column
prop="serviceTypeName"
:label="ModelServiceFieldsEnums['serviceTypeName']"
align="center"
sortable="custom"
></el-table-column>
<el-table-column prop="porder" :label="ModelServiceFieldsEnums['porder']" align="center"></el-table-column>
<el-table-column fixed="right" label="操作" min-width="80" align="center">
<template #default="scope">
<div class="tableOperate">
@ -197,15 +223,13 @@
<el-option label="离散量" :value="140"></el-option>
</el-select>
</el-form-item>
<template v-if="attributeForm.attributeType !== 140">
<el-form-item :label="ModelAttributeFieldsEnums['dataType']" prop="dataType">
<el-select
:disabled="!attributeForm.attributeType || attributeForm.attributeType === 140"
v-model="attributeForm.dataType"
:placeholder="'请选择' + ModelAttributeFieldsEnums['dataType']"
>
<el-select v-model="attributeForm.dataType" :placeholder="'请选择' + ModelAttributeFieldsEnums['dataType']">
<el-option v-for="v in attributeFormDataTypeOptions" :key="v.value" :label="v.value" :value="v.value"></el-option>
</el-select>
</el-form-item>
</template>
</div>
<el-form-item :label="ModelAttributeFieldsEnums['porder']" prop="porder">
<el-input v-model="attributeForm.porder" :placeholder="'请输入' + ModelAttributeFieldsEnums['porder']"></el-input>
@ -481,15 +505,15 @@ const modelAttributeAndServiceInputValue = ref('')
const searchModelAttribute = () => {
if (modelAttributeSearchRadio.value === 'Name') {
if (ModelTabs.value === 'attribute') {
getAttributeList(modelAttributeSearchRadio.value, modelAttributeAndServiceInputValue.value)
getAttributeList({ type: modelAttributeSearchRadio.value, value: modelAttributeAndServiceInputValue.value })
} else if (ModelTabs.value === 'service') {
getServiceList(modelAttributeSearchRadio.value, modelAttributeAndServiceInputValue.value)
getServiceList({ type: modelAttributeSearchRadio.value, value: modelAttributeAndServiceInputValue.value })
}
} else if (modelAttributeSearchRadio.value === 'Code') {
if (ModelTabs.value === 'attribute') {
getAttributeList(modelAttributeSearchRadio.value, modelAttributeAndServiceInputValue.value)
getAttributeList({ type: modelAttributeSearchRadio.value, value: modelAttributeAndServiceInputValue.value })
} else if (ModelTabs.value === 'service') {
getServiceList(modelAttributeSearchRadio.value, modelAttributeAndServiceInputValue.value)
getServiceList({ type: modelAttributeSearchRadio.value, value: modelAttributeAndServiceInputValue.value })
}
}
}
@ -504,6 +528,39 @@ const changeTabs = (name: any) => {
getServiceList()
}
}
const sortData = reactive<{ orderColumn: string | undefined; orderType: 'desc' | 'asc' | undefined }>({
orderColumn: undefined,
orderType: undefined,
})
const sortChange = ({
prop,
order,
}: {
prop: keyof typeof ModelAttributeFieldsEnums | keyof typeof ModelServiceFieldsEnums
order: 'ascending' | 'descending' | null
}) => {
const propEnums = {
attributeCode: 'attribute_code',
attributeName: 'attribute_name',
attributeTypeName: 'attribute_type',
porder: 'porder',
serviceCode: 'service_code',
serviceName: 'service_name',
serviceTypeName: 'service_type',
}
const orderType = order === 'ascending' ? 'asc' : order === 'descending' ? 'desc' : undefined
const filed = propEnums[prop as keyof typeof propEnums]
sortData.orderColumn = orderType ? filed : undefined
sortData.orderType = orderType
if (ModelTabs.value === 'attribute') {
getAttributeList()
} else if (ModelTabs.value === 'service') {
getServiceList()
}
}
const attributeTableData = ref<ModelAttributeTableType[]>([])
const editAttributeForm = (data: AddModelAttributeType & UpdateModelAttributeType) => {
@ -526,11 +583,23 @@ const delAttributeForm = (data: AddModelAttributeType & UpdateModelAttributeType
})
}
const getAttributeList = (type?: radioGroupType, value?: string) => {
const getAttributeList = ({
type,
value,
order,
orderFiled,
}: {
type?: radioGroupType
value?: string
order?: 'asc' | 'desc' | undefined
orderFiled?: keyof typeof ModelAttributeFieldsEnums
} = {}) => {
const requestData: GetModelAttributeType = {
iotModelId: curContextMenuTreeData.value!.id!,
pageNum: currentPage.value,
pageSize: currentPageSize.value,
orderColumn: sortData.orderColumn,
orderType: sortData.orderType,
}
if (type === 'Name') {
requestData.attributeName = value
@ -570,11 +639,19 @@ const getAttributeList = (type?: radioGroupType, value?: string) => {
})
}
const getServiceList = (type?: radioGroupType, value?: string) => {
const getServiceList = ({
type,
value,
}: {
type?: radioGroupType
value?: string
} = {}) => {
const requestData: GetModelServiceType = {
iotModelId: curContextMenuTreeData.value!.id!,
pageNum: currentPage.value,
pageSize: currentPageSize.value,
orderColumn: sortData.orderColumn,
orderType: sortData.orderType,
}
if (type === 'Name') {
requestData.serviceName = value
@ -659,7 +736,7 @@ const attributeForm = ref<AddModelAttributeType & UpdateModelAttributeType>(JSON
const attributeTypeChange = (value: ModelAttributeType) => {
if (value === 140) {
attributeForm.value.dataType = ''
}else{
} else {
attributeForm.value.dataType = 'float'
}
}

View File

@ -94,6 +94,8 @@ export type GetModelAttributeType = {
attributeName?: string
pageSize: number
pageNum: number
orderColumn?: string
orderType?: 'desc' | 'asc'
}
export type attributeTypeDataType = "float" | "double" | "tinyint" | "smallint" | "int" | "bigint"
@ -128,6 +130,8 @@ export type GetModelServiceType = {
serviceName?: string
pageSize: number
pageNum: number
orderColumn?: string
orderType?: 'desc' | 'asc'
}
export type AddModelServiceType = {

View File

@ -98,6 +98,7 @@ import router from '/@/router'
import toggleDark from '/@/utils/useDark'
import { fullUrl } from '/@/utils/common'
import { adminBaseRoutePath } from '/@/router/static/adminBase'
import { log } from '/@/api/backend/routine/AdminInfo'
let timer: number
const config = useConfig()
@ -205,6 +206,14 @@ const onSubmit = () => {
load()
}
})
.catch((err) => {
ElNotification({
message: err?.msg ?? '登录失败',
type: 'error',
})
load()
})
.finally(() => {
state.submitLoading = false
// load()

View File

@ -23,6 +23,50 @@ export const excelDefaultConfig: any = {
label: '寄存器地址',
code: 'col4',
},
{
label: '上界',
code: 'upBound',
},
{
label: '下界',
code: 'lowBound'
},
{
label: '基值',
code: 'base',
default: 0
},
{
label: '系数',
code: 'coef',
default: 1
},
{
label: '限值1',
code: 'limit1Enable',
default: 0
},
{
label: '限值1下限',
code: 'limit1Low'
},
{
label: '限值1上限',
code: 'limit1High'
},
{
label: '限值2',
code: 'limit2Enable',
default: 0
},
{
label: '限值2上限',
code: 'limit2High'
},
{
label: '限值2下限',
code: 'limit2Low'
}
],
R0C4: ['03', '04'],
R0C5: [
@ -191,6 +235,46 @@ export const excelDefaultConfig: any = {
label: '寄存器地址',
code: 'col4',
},
{
label: '上界',
code: 'upBound',
},
{
label: '下界',
code: 'lowBound'
},
{
label: '基值',
code: 'base'
},
{
label: '系数',
code: 'coef'
},
{
label: '限值1',
code: 'limit1Enable'
},
{
label: '限值1下限',
code: 'limit1Low'
},
{
label: '限值1上限',
code: 'limit1High'
},
{
label: '限值2',
code: 'limit2Enable'
},
{
label: '限值2上限',
code: 'limit2High'
},
{
label: '限值2下限',
code: 'limit2Low'
}
],
R0C4: ['03', '04'],
R0C5: [
@ -347,6 +431,46 @@ export const excelDefaultConfig: any = {
label: '信息体地址',
code: 'ioa',
},
{
label: '上界',
code: 'upBound',
},
{
label: '下界',
code: 'lowBound'
},
{
label: '基值',
code: 'base'
},
{
label: '系数',
code: 'coef'
},
{
label: '限值1',
code: 'limit1Enable'
},
{
label: '限值1下限',
code: 'limit1Low'
},
{
label: '限值1上限',
code: 'limit1High'
},
{
label: '限值2',
code: 'limit2Enable'
},
{
label: '限值2上限',
code: 'limit2High'
},
{
label: '限值2下限',
code: 'limit2Low'
}
],
},
//遥控147 CONTROL
@ -400,6 +524,46 @@ export const excelDefaultConfig: any = {
label: '是否转发',
code: 'ts',
},
{
label: '上界',
code: 'upBound',
},
{
label: '下界',
code: 'lowBound'
},
{
label: '基值',
code: 'base'
},
{
label: '系数',
code: 'coef'
},
{
label: '限值1',
code: 'limit1Enable'
},
{
label: '限值1下限',
code: 'limit1Low'
},
{
label: '限值1上限',
code: 'limit1High'
},
{
label: '限值2',
code: 'limit2Enable'
},
{
label: '限值2上限',
code: 'limit2High'
},
{
label: '限值2下限',
code: 'limit2Low'
}
],
R0C4: ['否--0', '是--1']
},
@ -497,7 +661,7 @@ const createHeaderData = (protocol: string | number) => {
s: '1',
custom: 'equipmentName',
},
1:{
1: {
v: '设备编码',
s: '1',
custom: 'equipmentCode',
@ -507,7 +671,7 @@ const createHeaderData = (protocol: string | number) => {
s: '1',
custom: 'name',
},
3:{
3: {
v: '属性编码',
s: '1',
custom: 'code',
@ -537,6 +701,7 @@ export const setExcelNameToLinkId = (id: string) => {
*/
export const createWookbookData = (protocol: number, linkId: string, data: any = {}) => {
const headerData = createHeaderData(protocol)
const sheetData: any = {}
//#region
Object.keys(headerData).forEach((item) => {
@ -652,8 +817,6 @@ export const createSheetData = (data: any, protocol: string | number) => {
})
const result: any = {}
data[item].forEach((obj: any, index: number) => {
console.log(obj)
const params = obj.params && obj.params !== '' ? JSON.parse(obj.params) : {}
obj = { ...obj, ...params }
const row = index + 1
@ -674,5 +837,7 @@ export const createSheetData = (data: any, protocol: string | number) => {
})
resultData[item] = result
})
return resultData
}