forked from gary/ems
2
0
Fork 0

删除无效文件

This commit is contained in:
ahu_gq 2025-06-21 16:57:11 +08:00
parent ea4d11107a
commit 23f43f43a5
29 changed files with 7 additions and 7635 deletions

View File

@ -52,8 +52,6 @@ add_executable(${ProjectName}
bsp/bsp_data_mode.c
bsp/bsp_mqttClient.c
bsp/bsp_mqttAsync.c
bsp/bsp_msgQueue.c
driver/drv_tcp_client.c
@ -70,17 +68,6 @@ add_executable(${ProjectName}
kernel/kit_core.c
mw/mw_schedule_handle.c
logic/logic_main.c
logic/logic_peakvalley.c
logic/logic_protected.c
logic/logic_demandctrl.c
logic/logic_debug.c
logic/logic_power_distr.c
logic/logic_task_data.c
logic/logic_dido.c
logic/logic_bcu2bsu.c
logic/logic_tempCtrl.c
)
#

View File

@ -462,19 +462,19 @@ void regeditThreadEntry(void *map_t) // 创建线程入口
creatGetLocalParamTaskEntry(100); // 100*50 ms 换算5秒执行一次
/* 创建各种转发任务 */
creatNetMqttTaskEntry();
//creatNetMqttTaskEntry();
/*创建存储任务*/
creatScheduledStorageTask();
/*创建gpio任务*/
creatGpioModTaskEntry(10); // 初始化 GPIO模块 10*50 ms 换算500ms执行一次
//creatGpioModTaskEntry(10); // 初始化 GPIO模块 10*50 ms 换算500ms执行一次
/*创建温控任务*/
creatLogicTempCtrlEntry();
//creatLogicTempCtrlEntry();
/*创建策略任务*/
creatLogicCtrTaskEntry();
//creatLogicCtrTaskEntry();
}
/*********************************************************************

View File

@ -27,8 +27,7 @@
#include "bsp_ntp.h"
#include "kit_log.h"
#include "app_parse.h"
#include "bsp_mqttClient.h"
#include "logic_main.h"
#include "drv_gpio.h"
#define THREAD_PRIORITY_MAX 90

View File

@ -1,153 +0,0 @@
#include "bsp_mqttAsync.h"
volatile int finished = 0;
Queue g_qMsg;
Queue g_qHistory;
// 当连接成功时的回调函数
void onConnect(void *context, MQTTAsync_successData *response)
{
printf("Connected successfully\n");
MQTTAsync client = (MQTTAsync)context;
int rc;
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
// 设置响应选项
opts.onSuccess = NULL;
opts.onFailure = NULL;
opts.context = client;
// 订阅指定的主题
if ((rc = MQTTAsync_subscribe(client, TOPIC, QOS, &opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start subscribe, return code %d\n", rc);
}
printf("Subscribed to topic %s with QOS %d\n", TOPIC, QOS);
}
// 当连接失败时的回调函数
void onConnectFailure(void *context, MQTTAsync_failureData *response)
{
// 创建一个新的断点记录
// 尝试重新连接
while (1)
{
// 尝试重新连接
// 将存储的历史数据入数据库
}
}
// 当成功断开连接时的回调函数
void onDisconnect(void *context, MQTTAsync_successData *response)
{
printf("Disconnected successfully\n");
finished = 1; // 设置完成标志以终止任务
}
// 当订阅失败时的回调函数
void onSubscribeFailure(void *context, MQTTAsync_failureData *response)
{
printf("Subscribe failed, rc %d\n", response ? response->code : 0);
finished = 1; // 设置完成标志以终止任务
}
// 当消息到达时的回调函数
int messageArrived(void *context, char *topicName, int topicLen, MQTTAsync_message *message)
{
printf("Message arrived on topic %s\n", topicName);
printf("Message: %.*s\n", message->payloadlen, (char *)message->payload);
// 释放消息和主题名内存
MQTTAsync_freeMessage(&message);
MQTTAsync_free(topicName);
return 1; // 消息处理成功
}
// 发布消息的函数
void publishMessage(MQTTAsync client)
{
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
Queue *pNode = (Queue *)&g_qMsg;
while (!isQueueEmpty(pNode))
{
// 设置消息参数
pubmsg.payload = pNode->head->data;
pubmsg.payloadlen = (int)strlen(pNode->head->data);
pubmsg.qos = QOS;
pubmsg.retained = 0;
opts.onSuccess = NULL;
opts.onFailure = NULL;
opts.context = client;
int rc = 0;
// 发送消息
if ((rc = MQTTAsync_sendMessage(client, pNode->head->topic, &pubmsg, &opts)) != MQTTASYNC_SUCCESS)
{
// 发送成功,则将消息出队
dequeue(pNode);
printf("Failed to publish message, return code %d\n", rc);
}
else
{
// 修改主题为历史数据,入历史数据队列,并将元素出队
pNode->head->topic;
enqueue(&g_qHistory, pNode->head);
dequeue(pNode);
}
}
}
// 主任务函数管理MQTT连接、订阅和发布
int MQTTAsyncTask(int argc, char *argv[])
{
initQueue(&g_qMsg);
initQueue(&g_qHistory);
MQTTAsync client;
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
// 创建MQTT客户端
MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
// 设置回调函数
MQTTAsync_setCallbacks(client, NULL, NULL, messageArrived, NULL);
// 设置连接选项
conn_opts.keepAliveInterval = 20; // 保持连接的心跳间隔
conn_opts.cleansession = 1; // 创建一个会话
conn_opts.onSuccess = onConnect; // 设置连接成功的回调
conn_opts.onFailure = onConnectFailure; // 设置连接失败的回调
conn_opts.context = client;
// 发起连接
if (MQTTAsync_connect(client, &conn_opts) != MQTTASYNC_SUCCESS)
{
printf("Failed to start connect\n");
return EXIT_FAILURE;
}
// 等待任务完成
while (!finished)
{
usleep(10000L); // 微小延迟用以减少CPU占用
}
//void *msg = NULL;
// 发布消息到主题
publishMessage(client);
MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer;
disc_opts.onSuccess = onDisconnect; // 设置断开成功的回调
// 断开连接
MQTTAsync_disconnect(client, &disc_opts);
// 销毁MQTT客户端
MQTTAsync_destroy(&client);
return EXIT_SUCCESS;
}

View File

@ -1,12 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "MQTTAsync.h"
#include "bsp_msgQueue.h"
#define ADDRESS "tcp://broker.hivemq.com:1883"
#define CLIENTID "ExampleMQTTAsyncClient"
#define TOPIC "test/topic"
#define PAYLOAD "Hello MQTT"
#define QOS 1
#define TIMEOUT 10000L

File diff suppressed because it is too large Load Diff

View File

@ -1,367 +0,0 @@
/*****************************************************************************
* @copyright 1997-2050, . POWER SUPPLY CO., LTD.
* @file bsp_mqttClient.c
* @brief mqtt通信客户端程序
* @author mdy
* @date 2024-09-29
* @remark
*****************************************************************************/
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <assert.h>
#include "MQTTClient.h"
#include "MQTTAsync.h"
#include <cjson/cJSON.h>
#include "bsp_rtdb.h"
#include "bsp_comm.h"
#include <semaphore.h>
#include <signal.h>
#include "kit_db.h"
#include "kit_core.h"
#include "logic_bcu2bsu.h"
#include "logic_main.h"
#include "logic_dido.h"
#define D_MAX_MQTT_DEV_POINT_NUM (2000) // 每类设备最大的上云测点个数
#define D_MAX_DEV_NUM (100) // 子设备最大数量
#define D_MAX_DEV_NAME_LEN (100)
#define D_MAX_DEV_KEYWORD (11)
#define D_MAX_IPV4_LENGTH (16)
#define D_MAX_USERNAME_LENGTH (20)
#define D_MAX_PASSWORD_LENGTH (20)
#define QOS 1
#define TIMEOUT 10000L
#define MQTT_ROOT_TOPIC_KEY "root"
#define MQTT_PERIOD_TOPIC_KEY "period"
#define MQTT_CHANGE_TOPIC_KEY "change"
#define MQTT_HISTORY_TOPIC_KEY "history"
#define MQTT_CONTROL_TOPIC_KEY "control"
#define MQTT_READ_TOPIC_KEY "read"
#define MQTT_REPLY_TOPIC_KEY "reply"
#define MQTT_PAYLOAD_MAX_LEN (1024 * 1024) // 能源云限制报文长度最大为1MB
#define MQTT_PERIOD_SEND_FAIL_WORDS "period send fail." // 周期发送失败
#define D_MAX_TOPIC_NUM (7)
#define MQTT_STATUS_DONT_TRANS -100 // 还未执行完策略,当前的配置参数不上传
#define MQTT_STATUS_CFG_UPLOADED 100 // 策略配置传送完毕
#define MAX_MQTT_HISTORY_MSG_NUM 1000
#define D_PERIODSEND_T_SEQ (0)
#define D_HISTORY_T_SEQ (1)
#define D_DATACHK_T_SEQ (2)
#define D_MAX_THREAD_NUM (3)
#define D_STR_CONNECT_WORD "已连接"
#define D_STR_DISCONN_WORD "已断开"
#define RECORDNETSTATUS(word) kit_insert_lost_contact_record(word);
// MQTT主题枚举定义
typedef enum
{
kEmsTopicType_Start,
kEmsTopicType_root = kEmsTopicType_Start, // 初始化主题
kEmsTopicType_period, // 周期上报主题
kEmsTopicType_change, // 突变上报主题
kEmsTopicType_history, // 历史数据上报主题
kEmsTopicType_control, // 控制指令下发主题
kEmsTopicType_read, // 读参数主题
kEmsTopicType_reply_control, // 回复控制指令下发主题
kEmsTopicType_reply_read, // 回复读参数主题
kEmsTopicType_End = kEmsTopicType_reply_read,
} ems_topic_type_e;
// 数据变化事件分类
typedef enum
{
kEvent_topo_send = 1, // 拓扑发送完成
kEvent_has_history_record = 2, // 存在历史记录record
kEvent_change_devTopo = 4, // 设备列表变化
kEvent_rename_anydev = 8, // 重命名子设备
kEvent_int_change = 16, // 子设备整型测点值变化越死区
kEvent_float_change = 32, // 子设备浮点型测点值变化越死区
kEvent_pointlistcfg_change = 64, // 设备测点配置改变
kEvent_Reconnect_success = 128, // MQTT重连成功
kEvent_Reconnect_failed = 256, // MQTT重连失败
kEvent_Period_Task_begin = 512, // 周期发送任务启动完成
} kEvent_ems_data;
// EMS总的工作模式
typedef enum
{
KEms_cfg_Start, // 无
KEms_cfg_DEBUG, // 调试模式
KEms_cfg_PEAKVALLY, // 削峰填谷模式
KEms_cfg_DEMANDRES, // 需求响应模式
KEms_cfg_LOADTRACK, // 负载跟踪模式
KEms_cfg_DMDCTRL, // 需量控制
KEms_cfg_PFCTRL, // 功率因数
KEms_cfg_Protect, // 保护策略
KEms_cfg_END,
} cfgType_e;
typedef enum
{
kQos_0,//最多交付一次
kQos_1,//至少交付一次
kQos_2,//只交付一次
}Qos_e;
// 拓扑结构结构体
typedef struct
{
int dbId; // 键:数据库中的 ID
topology_t *topology; // 值:指向 topology_t 结构体的指针
UT_hash_handle hh; // uthash 处理句柄,使结构体可哈希
} topology_hash_entry_t;
// MQTT单个测点的db查找表
typedef struct
{
// 取测点使用参数
rtdb_type_e dbType; // 数据库类型
uint16_t devType; // 设备类型
uint16_t devId; // 区分同类型不同设备实体的标识
uint16_t pointId; // 测点id
up_dis_config_type_e txOrRx; // 是上传的测点还是接收云端指令0-仅上报 1-下发
bool whether; // 接收用户输入1-上传0-不上传
double value; // 该测点值的备份用于检测变化事件
bool ifchg; // 是否需要变化上送
} mqtt2db_t;
typedef mqtt2db_t mqttGetDBElem;
typedef mqtt2db_t mqttSetDBElem;
void pointListener(mqtt2db_t *tab);
// 一个设备实体的测点信息表结构体
typedef struct
{
mqttGetDBElem rtdbGetTab[D_MAX_MQTT_DEV_POINT_NUM]; // 实时数据库查找表,对应上传点位
mqttSetDBElem rtdbSetTab[D_MAX_MQTT_DEV_POINT_NUM]; // 实时数据库查找表,对应相应云端控制的下发点位,云端写RTDB操作只能操作该表中的点
bool bChgFlag; // 变化标志
int txcount; // 记录加入payload的测点数量
int rxcount;
} payloadlist_t;
// mqtt通信参数结构体
typedef struct
{
char stationName[100]; // 站点名称
char stationID[20]; // 站点id
dev_type_e devType; // 设备类别
char *devName[D_MAX_DEV_NAME_LEN]; // 设备名称
char sn[D_MAX_DEV_NUM][60]; // 设备SN
char identifier[60]; // 消息服务标识
int devNum; // 设备数量
payloadlist_t pllist[D_MAX_DEV_NUM]; // 该类设备下每个设备实体一张mqtt2db关联表依据该表中的元素操作RTDB
bool bChgFlag;
} mqtt_option_map_t;
// payloadlists
// 保留给回调函数的上下文结构体
typedef struct
{
MQTTClient client;
MQTTClient_connectOptions connopts;
mqtt_lib_t mlib;
int modeword;
} ConnContext;
//所有算法配置的联合体
typedef union
{
peakvalley_zone_tab_t pkvly; // 削峰填谷参数 IN
demandRes_params_t demand; // 需求响应参数
loadTrack_params_t loadTrack; // 负载跟踪参数
debug_params_t debug; // 调试参数 IN
protect_params_t protect; // 保护参数 IN
power_distr_t distr; // 功率分配参数 IN
} logic_Params;
//中断记录与历史数据数组关联的结构体
typedef struct
{
break_record_t record; // 中断记录
UT_array *dataArray; // 其关联的数据存储集合
} break_record_with_data_t;
//从云端MQTT报文返回的信息结构体
typedef struct
{
char *transaction;
int modeWord;
} arvcfgInfo_ret_t;
typedef void (*setCfgCB)(void *);
void setdbgCB(void *arg);
void setPkvlCB(void *arg);
void setDmdRspCB(void *arg);
void setLoadTrackCB(void *arg);
void setDmdCtrlCB(void *arg);
void setPFCtrlCB(void *arg);
/*****************************************************************************
* @brief
* @param[in] context: MQTT上下文结构体
* @param[in] dt:
* @return NONE
*****************************************************************************/
void deliveredCB(void *context, MQTTClient_deliveryToken dt);
/*****************************************************************************
* @brief
* @param[in] context: MQTT上下文结构体
* @param[in] topicName:
* @param[in] topicLen
* @return
*****************************************************************************/
int msgarrvdCB(void *context, char *topicName, int topicLen, MQTTClient_message *message);
/*****************************************************************************
* @brief
* @param[in] context: MQTT上下文结构体
* @param[in] cause:
* @return NONE
*****************************************************************************/
void connlostCB(void *context, char *cause);
/*****************************************************************************
* @brief MQTT参数
* @param[in] mlt: MQTT连接配置
* @param[in] map:
* @return NONE
*****************************************************************************/
void updateMqttPara(mqtt_lib_t *mlt, mqtt_option_map_t *map);
/*****************************************************************************
* @brief MQTT参数
* @param[in] mlt: MQTT连接配置
* @param[in] map:
* @return NONE
*****************************************************************************/
int chkDataChange(mqtt_option_map_t *now, mqtt_option_map_t *old);
/*****************************************************************************
* @brief MQTT周期发送线程
* @param[in] arg:
* @return NONE
*****************************************************************************/
void *periodSendTask(void *arg);
/*****************************************************************************
* @brief
* @param[in] arg:
* @return NONE
************************************************************************/
void *dataChgMonitor(void *arg);
/*****************************************************************************
* @brief MQTT字符串中获取关键字返回主题类型
* @param[in] topic: MQTT主题字符串
* @return
*****************************************************************************/
int getKeywordsByTopic(char *topic);
/*****************************************************************************
* @brief
* @param[in] payload
* @param[in] type
* @param[in] tot
* @return NONE
*****************************************************************************/
void genDevGrpPeriodPayload(char *payload, dev_type_e type, mqtt_option_map_t *tot);
/*****************************************************************************
* @brief JSON
* @param[in] parentArray: JSON
* @param[in] parentId: ID
* @param[in] topologyById:
* @return
*****************************************************************************/
void addChildrenToJson(cJSON *parentArray, int parentId, topology_hash_entry_t *topologyById);
/*****************************************************************************
* @brief EMS JSON
* @param[out] json: JSON JSON
* @return 0- 1-
*****************************************************************************/
int getTopologyJsonByDb(char **json);
/*****************************************************************************
* @brief
* @param[out] type
* @return
*****************************************************************************/
char *devTypeToString(dev_type_e type);
/*****************************************************************************
* @brief
* @param[in] a
* @param[in] b
* @return 0-1-
*****************************************************************************/
bool ifSameTopoElem(const topology_t *a, const topology_t *b);
/*****************************************************************************
* @brief
* @param[in] arr1
* @param[in] arr2
* @return 0-1-
*****************************************************************************/
bool chkTopoDiff(UT_array *arr1, UT_array *arr2);
/*****************************************************************************
* @brief
* @return
*****************************************************************************/
char *getTmstr2();
/*****************************************************************************
* @brief
* @param[in] jsonStringjson串
* @param[in] arr
* @return 0-1-
*****************************************************************************/
arvcfgInfo_ret_t parseEmsCfgJson(const char *jsonString, logic_Params *lP);
/*****************************************************************************
* @brief
* @param[in] tot: mqtt_lib_t中的主题字符串指针
* @return false- true-
*****************************************************************************/
bool ifSingledevPointsChg(payloadlist_t *list);
/*****************************************************************************
* @brief
* @param[in] map:
* @return false- true-
*****************************************************************************/
bool ifDevGrpPointsChg(mqtt_option_map_t *map);
/*****************************************************************************
* @brief
* @param[in] topic: mqtt_lib_t中的主题字符串指针
* @param[in] payload:mqtt_lib_t中的成员应对应payload的缓冲区长度足够
* @return NONE
*****************************************************************************/
int genChgDevGrpPeriodPayload(char *payload, dev_type_e type, mqtt_option_map_t *tot);
/*****************************************************************************
* @brief
* @return
*****************************************************************************/
int parseStrategyJsonObject(cJSON *json, int modeword, logic_Params *lp);
/*****************************************************************************
* @brief JSON
* @param[in] arvcfgInfo_ret_t cfg
* void *arg logic_Params
* @return char* JSON
*****************************************************************************/
char *createStrategyCfgJsonString(arvcfgInfo_ret_t cfg, const void *arg, int rw);
/*****************************************************************************
* @brief
* @param[in] argtcp连接上下文
* @return 0-1-
*****************************************************************************/
bool is_mqtt_connected();
/*****************************************************************************
* @brief MQTT主函数
* @param[in] arg:
* @return NONE
*****************************************************************************/
void *MqttTask(void *arg);
/*****************************************************************************
* @brief MQTT转发任务入口
* @return NONE
*****************************************************************************/
void creatNetMqttTaskEntry();

View File

@ -1,91 +0,0 @@
#include "logic_bcu2bsu.h"
#define MAX_BSU_MQTT_POINTNUM (24)
// 定义哈希表的结构
// 声明全局变量
#if 1
// 初始化全局哈希表
void init_bcu_bsu_map(BcuBsuMap **bsu_map)
{
// 原始映射数组
bcu2bsu_t g_transBcu[] =
{
{kBsu_SysVolt, kBcu_TotalVolt},
{kBsu_SysCur, kBcu_TotalCur},
{kBsu_SOC, kBcu_SOC},
{kBsu_SOH, kBcu_SOH},
{kBsu_MaxCellTemp, kBcu_MaxCellTemp},
{kBsu_MinCellTemp, kBcu_MinCellTemp},
{kBsu_TotalChgE, kBcu_TotalChgCap},
{kBsu_TotalDChgE, kBcu_TotalDisChgCap},
};
for (int i = 0; i < sizeof(g_transBcu) / sizeof(g_transBcu[0]); i++)
{
BcuBsuMap *entry = (BcuBsuMap *)malloc(sizeof(BcuBsuMap));
if (entry == NULL)
{
// 处理内存分配失败
perror("无法为 BcuBsuMap 分配内存");
return;
}
entry->bsupointId = g_transBcu[i].bsupointId;
entry->bcupointId = g_transBcu[i].bcupointId;
HASH_ADD_INT(*bsu_map, bsupointId, entry);
}
}
// 清理全局哈希表
void free_bcu_bsu_map(BcuBsuMap *bsu_map)
{
BcuBsuMap *current_entry, *tmp;
HASH_ITER(hh, bsu_map, current_entry, tmp)
{
HASH_DEL(bsu_map, current_entry);
free(current_entry);
}
}
// 使用哈希表
int bcuTransbsuPoint(BcuBsuMap *hash_table, uint16_t key)
{
int value = 0;
// BcuBsuMap *element = NULL;
// if (element != NULL)
// {
// value = element->bcupointId; // 找到值
// }
// else
// {
// value = -1;
// }
BcuBsuMap *current;
for (current = hash_table; current != NULL; current = current->hh.next)
{
if(current->bsupointId==key)
{
value = current->bcupointId;
break;
}
value = -1;
}
return value; // 未找到
}
double getBsuRTDBPointValue(BcuBsuMap *bsu_map, rtdb_type_e type, uint16_t devType, uint16_t devId, uint16_t pointId)
{
if (devType == kDev_Type_BSU && bcuTransbsuPoint(bsu_map, pointId) != -1)
{
return getRtdbPointValue(type, kDev_Type_BCU, 0, bcuTransbsuPoint(bsu_map, pointId));
}
else
{
return getRtdbPointValue(type, devType, devId, pointId);
}
}
#endif

View File

@ -1,36 +0,0 @@
#pragma once
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <sys/time.h>
#include <pthread.h>
#include "bsp_rtdb.h"
#include "kit_math.h"
#include "kit_data.h"
#include "kit_db.h"
#include "utextend.h"
#include "uthash.h"
typedef struct
{
uint16_t bsupointId;
uint16_t bcupointId;
} bcu2bsu_t;
typedef struct
{
uint16_t bsupointId; // key
int bcupointId; // value
UT_hash_handle hh; // makes this structure hashable
} BcuBsuMap;
// 初始化全局哈希表
void init_bcu_bsu_map(BcuBsuMap **bsu_map);
// 清理全局哈希表
void free_bcu_bsu_map(BcuBsuMap *bsu_map);
// 使用哈希表
int bcuTransbsuPoint(BcuBsuMap *bsu_map, uint16_t bsupointId);
double getBsuRTDBPointValue(BcuBsuMap *bsu_map, rtdb_type_e type, uint16_t devType, uint16_t devId, uint16_t pointId);

View File

@ -1,210 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_comm.h
* @brief xxxx
* @author Gary
* @date 2024/09/20
* @remark
*****************************************************************************/
#ifndef __LOGIC_COMMON_H__
#define __LOGIC_COMMON_H__
#pragma once
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <sys/time.h>
#include <pthread.h>
#include <stdatomic.h>
#include "bsp_rtdb.h"
#include "kit_math.h"
#include "kit_data.h"
#include "kit_db.h"
#include "../kernel/kit_log.h"
#include "utextend.h"
#include "logic_debug.h"
#include "logic_demandctrl.h"
#include "logic_peakvalley.h"
#include "logic_power_distr.h"
#include "logic_protected.h"
#define LOGIC_SIGN_NONE 0
#define LOGIC_SIGN_MESSAGE 1
#define LOGIC_SIGN_UPLOAD 2
#define _PCS // 华三PCS目前 开关是两个点需要特殊处理
// #define OTHER ;
// 系统状态
typedef enum
{
kState_Start, // 无
kState_Charging, // 充电
kState_Discharging, // 放电
kState_Standby, // 待机
kState_Shutdown, // 停机
kState_Fault, // 故障
kState_end
} state_e;
// 用于log打印 与 枚举state_e 强绑定
extern const char* workModeNames[];
// 任务
typedef enum
{
kTask_Start, // 无
kTask_Debug, // 调试
kTask_Peakvalley, // 削峰填谷
kTask_DemdRespond, // 需求侧相应
kTask_PowerTrace, // 负载跟踪
kTask_demandCtrl, // 需量控制
kTask_PFCtrl, // 功率因数
kTask_end
} task_e;
// 保护
typedef enum
{
kProtect_start,
kProtect_backFlow, // 逆流保护
kProtect_freqAdj, // 调频保护
kProtect_demand, // 需量保护
kProtect_end
} protect_e;
// 下发
typedef struct
{
int runPeriod; // 运行周期 ms
float_t power; // 目标功率 INOUT
// 可配参数(未知)
} demandRes_params_t; // 需求响应参数(未实现 暂放在这里)
typedef struct
{
int runPeriod; // 运行周期 ms
float_t power; // 目标功率 INOUT
// 可配参数
float_t percent; // 负载跟踪百分比 10% = 0.1
} loadTrack_params_t; // 负载跟踪参数(未实现 暂放在这里)
typedef struct
{
peakvalley_params_t pkvly; // 削峰填谷参数 IN
demandRes_params_t demand; // 需求响应参数
loadTrack_params_t loadTrack; // 负载跟踪参数
debug_params_t debug; // 调试参数 IN
protect_params_t protect; // 保护参数 IN
power_distr_t distr; // 功率分配参数 IN
} logic_paramIn_t;
typedef union
{
struct
{
unsigned int Res1 : 9; // 预留位
unsigned int debug : 1; // 调试模式
unsigned int peakValley : 1; // 削峰填谷模式
unsigned int demandRes : 1; // 需求响应模式
unsigned int loadTrack : 1; // 负载跟踪模式
unsigned int dmdCtrl : 1; // 需量控制
unsigned int pfCtrl : 1; // 功率因数控制
unsigned int Res2 : 17; // 预留位
} bits;
unsigned int ParaChangeUnion; // 用于一次性访问所有位的整型变量
} SignFlags;
typedef struct
{
work_mode_e mode; // 总工作模式 IN
SignFlags ParaChangeSign; // 总参数更新标志
logic_paramIn_t task_params; // 入参数据 IN
} task_params_t; // 调试函数传参结构体
/*modbus客户端信息*/
typedef struct
{
/*线程属性*/
pthread_t tfd; // 线程fd
uint8_t exitTaskFlag; // 退出线程标记
uint8_t taskStateFlag; // 处理任务标志0-无需处理1-更新参数2-参数上传
task_params_t para_delivery; // 参数传递
} logic_pthread_t;
extern logic_pthread_t stlogic;
// 实时库获取数据
typedef struct
{
uint16_t No;
dev_type_e devType;
uint16_t pointId;
} ParamFromRTDB;
// 实时库参数枚举
typedef enum
{
e_Logic_RTDB_start,
e_Logic_totalAcPower = e_Logic_RTDB_start, // 总电表总有功功率
e_Logic_emsActivePower, // 储能测总有功功率
e_Logic_bmsSoc, // 实时每个柜子的BMS的SOC
e_Logic_pcsMaxChaPower, // 最大充电功率
e_Logic_pcsMaxDiscPower, // 最大放电功率
e_Logic_nowBmsPower, // bms当前实时功率
e_Logic_nowActiveDemand, // 实时需量
e_Logic_distrPower, // 下发功率
e_Logic_pcsSwitch, // PCS开关
e_Logic_pcsState, // pcs在线状态
e_Logic_bmsState, // bms在线状态
e_Logic_emsMode, // ems运行模式
// e_Logic_emsStat, // ems运行状态
e_Logic_bsuMaxCellTemp, // BMS单体最高温度
e_Logic_bsuMinCellTemp, // BMS单体最低温度
// e_Logic_AcLiquidSwitch, // 液冷机组开关
// e_Logic_AcLiquidHeatTemp, // 液冷机组制热温度
// e_Logic_AcLiquidColdTemp, // 液冷机组制冷温度
e_Logic_RTDB_end
} ParamFromRTDB_e;
// 需量超阈值防护 负载预测
void logic_protect_demandCtrl(protect_params_t *charge_params);
// 获取需执行的命令以及策略运行的所以参数
void logic_getRTDBParams();
/*****************************************************************************
* @brief RTDB参数
* @param[in]
* @return
*****************************************************************************/
void logic_getValue(int No, void *value, data_type_e dataType);
/*****************************************************************************
* @brief RTDB参数
* @param[in] No RTDBtable
* @param[in] value
* @param[in] dataType Uint8Int16
* @return
*****************************************************************************/
void logic_setValue(int No, void *value, uint16_t num, data_type_e dataType);
// 初始化 GPIO模块 任务入口
void creatGpioModTaskEntry(uint16_t time);
/*********************************************************************
* @brief
* @param[in]
* @return 0sucessful1fault
*********************************************************************/
int creatLogicTempCtrlEntry();
/*********************************************************************
* @brief
* @param[in]
* @return
*********************************************************************/
int logic_paramUpload();
// 更新系统状态函数 (内部带互斥锁)
void updateState(state_e newState, bool enOrDisable);
#endif

View File

@ -1,60 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_debug.c
* @brief xxxx
* @author Gary
* @date 2024/09/27
* @remark
*****************************************************************************/
#include "logic_comm.h"
/*****************************************************************************
* @brief ()
* @return 0 -1 1
*****************************************************************************/
int logic_debugParamUpdate()
{
static debug_params_t *debug_params = &stlogic.para_delivery.task_params.debug;
if (NULL == debug_params)
{
return 1;
}
// 配置变化标志
debug_algorithm_t p_debugAlgo = {0, 0, 0};
if (1 == kit_get_debug_algorithm(&p_debugAlgo))
{
return 1;
}
debug_params->activePower = p_debugAlgo.activePower;
debug_params->reactivePower = p_debugAlgo.reactivePower;
debug_params->pcsSwitch = p_debugAlgo.pcsSwitch;
debug_params->protectSwitch = p_debugAlgo.protectSwitch;
//debug_params->protectSwitch =1;
if(debug_params->pcsSwitch)
{
stlogic.para_delivery.task_params.protect.power = debug_params->activePower;
stlogic.para_delivery.task_params.protect.rePower = debug_params->reactivePower;
}
else
{
debug_params->activePower = 0;
debug_params->reactivePower = 0;
}
return 0;
}
/*****************************************************************************
* @brief ()
* @return -1 0
*****************************************************************************/
int logicFun_debug()
{
debug_params_t *debug_params = &stlogic.para_delivery.task_params.debug;
if(NULL == debug_params)
{
return -1;
}
stlogic.para_delivery.task_params.protect.power = debug_params->activePower;
return 0;
}

View File

@ -1,26 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_debug.h
* @brief xxxx
* @author Gary
* @date 2024/09/21
* @remark
*****************************************************************************/
#ifndef __LOGIC_DEBUG_H__
#define __LOGIC_DEBUG_H__
typedef struct
{
// 用户可配参数
float_t activePower; // 目标有功功率
float_t reactivePower; // 目标无功功率 kw
bool pcsSwitch; // 充放电开关 1 开 0 关
uint8_t protectSwitch; // 保护算法开关 1 开 0 跳过
// 中间变量
int runPeriod; // 运行周期 ms
} debug_params_t; // 调试函数传参结构体
// 获取调试模式运行参数接口
int logicFun_debug();
int logic_debugParamUpdate();
#endif

View File

@ -1,172 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_demandctrl.c
* @brief xxxx
* @author Gary
* @date 2024/09/27
* @remark
*****************************************************************************/
#include "logic_comm.h"
// static sliding_window_t g_window; //滑差结构体
void initSlidingWindow(sliding_window_t *window)
{
window->pccCount = 0;
window->pccIndex = 0;
window->pccSum = 0;
window->loadCount = 0;
window->loadIndex = 0;
window->loadSum = 0;
window->foreCount = 0;
window->foreIndex = 0;
}
int updateSlidingWindow(sliding_window_t *window, double_t pcc, double_t load)
{
// 如果窗口尚未填满,直接添加数据并更新总和
if (window->pccCount < 450)
{
window->pccDemand[window->pccCount] = pcc;
window->pccSum += pcc;
window->pccCount++;
window->loadDemand[window->loadCount] = load;
window->loadSum += load;
window->loadCount++;
return 0;
}
else
{
// 如果窗口已经填满,移除最早的数据并添加新数据
window->pccSum -= window->pccDemand[window->pccIndex];
window->pccDemand[window->pccIndex] = pcc;
window->pccSum += pcc;
window->pccIndex = (window->pccIndex + 1) % 450; // 更新索引
window->loadSum -= window->loadDemand[window->loadIndex];
window->loadDemand[window->loadIndex] = load;
window->loadSum += load;
window->loadIndex = (window->loadIndex + 1) % 450; // 更新索引
return 1;
}
}
int UpdateForeDemand(sliding_window_t *window, double_t fore)
{
// 如果窗口尚未填满,直接添加数据并更新总和
if (window->foreCount < 15)
{
window->foreDemand[window->foreCount] = fore;
window->foreCount++;
return 0;
}
else
{
// 如果窗口已经填满,移除最早的数据并添加新数据
window->foreDemand[window->foreIndex] = fore;
window->foreIndex = (window->foreIndex + 1) % 15; // 更新索引
return 1;
}
}
// 拟合二次方程
double_t fitQuadraticEquation(double_t *loadDemand)
{
// 拟合二次方程y = ax^2 + bx + c
double sum_x = 0, sum_x2 = 0, sum_x3 = 0, sum_x4 = 0;
double sum_y = 0, sum_xy = 0, sum_x2y = 0;
for (int i = 0; i < 15; ++i)
{
double x = i + 1; // 每分钟对应的时间
double y = loadDemand[i]; // 对应的数据点
sum_x += x;
sum_x2 += x * x;
sum_x3 += x * x * x;
sum_x4 += x * x * x * x;
sum_y += y;
sum_xy += x * y;
sum_x2y += x * x * y;
}
// 计算二次方程系数
double a = (sum_x2y * sum_x2 - sum_xy * sum_x3) / (sum_x2 * sum_x4 - sum_x3 * sum_x3);
double b = (sum_xy - a * sum_x3) / sum_x2;
double c = (sum_y - a * sum_x4 - b * sum_x3) / sum_x2;
printf("拟合的二次方程为: y = %.2fx^2 + %.2fx + %.2f\n", a, b, c);
return a * 15 * 15 + b * 15 + c;
}
/*****************************************************************************
* @brief
* @param[in] float_t aimDemand float_t nowDemand
* float_t maxActivePower
* @return float_t
*****************************************************************************/
float_t getActiveDemand(float_t aimDemand, float_t nowDemand, float_t maxActivePower)
{
return float_min(float_max(aimDemand, nowDemand), maxActivePower);
}
/*****************************************************************************
* @brief
* @param[in] protect_demand_t demandParams
* @return
*****************************************************************************/
void logic_protect_demandCtrl(protect_params_t *charge_params)
{
float_t demand = getActiveDemand(charge_params->aimActiveDemand, charge_params->nowActiveDemand, charge_params->maxActivePower);
float_t tmp_active_demand = demand - charge_params->demandCtrlCloseLimt; // 预留
if (tmp_active_demand >= charge_params->totalActivePower) // 关机判断
{
float_t load_active_power = charge_params->totalActivePower - charge_params->emsActivePower; // 算出负载功率
tmp_active_demand = demand - charge_params->demandCtrlLowLimt; // 限流值
if (tmp_active_demand >= charge_params->totalActivePower) // 限流判断
{
float_t tmp_power = tmp_active_demand - load_active_power - charge_params->demandCtrlLowLimt / 10;
if (tmp_power > 0)
{
charge_params->power = -float_min(abs(charge_params->power), tmp_power);
}
else
{
charge_params->power = 0;
}
if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
{
KITLOG(LOG_MODBUS_EN, INFO_EN, "触发需量保护!!! 并网点功率:%.2f kw 目标需量:%.2f kw 实时需量:%.2f kw 新的目标功率:%.2f kw",
charge_params->totalActivePower, charge_params->aimActiveDemand, charge_params->nowActiveDemand, charge_params->power);
KITLOG(LOG_MODBUS_EN, INFO_EN, "触发需量保护!!! 并网点功率:%.2f kw 目标需量:%.2f kw 实时需量:%.2f kw 新的目标功率:%.2f kw",
charge_params->totalActivePower, charge_params->aimActiveDemand, charge_params->nowActiveDemand, charge_params->power);
}
}
else
{
float_t tmp_power = tmp_active_demand - load_active_power - charge_params->demandCtrlLowLimt / 2;
if (tmp_power > 0)
{
charge_params->power = -float_min(abs(charge_params->power), tmp_power);
}
else
{
charge_params->power = 0;
}
}
}
else
{
charge_params->power = 0;
if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
{
KITLOG(LOG_MODBUS_EN, INFO_EN, "触发需量关机!!! 并网点功率:%.2f kw 目标需量:%.2f kw 实时需量:%.2f kw 新的目标功率:%.2f kw",
charge_params->totalActivePower, charge_params->aimActiveDemand, charge_params->nowActiveDemand, charge_params->power);
KITLOG(LOG_MODBUS_EN, INFO_EN, "触发需量关机!!! 并网点功率:%.2f kw 目标需量:%.2f kw 实时需量:%.2f kw 新的目标功率:%.2f kw",
charge_params->totalActivePower, charge_params->aimActiveDemand, charge_params->nowActiveDemand, charge_params->power);
}
}
}

View File

@ -1,31 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_demandctrl.h
* @brief xxxx
* @author Gary
* @date 2024/09/27
* @remark
*****************************************************************************/
#ifndef __LOGIC_DEMANDCTRL_H__
#define __LOGIC_DEMANDCTRL_H__
// 滑差窗口结构体
typedef struct
{
double_t pccDemand[450]; // 实时需量
int pccCount; // 当前实时需量的数量
int pccIndex; // 当前实时需量的索引
double_t pccSum; // 窗口内实时需量的总和
double_t loadDemand[450]; // 负荷实时需量
int loadCount; // 当前负荷实时需量的数量
int loadIndex; // 当前负荷实时需量的索引
double_t loadSum; // 窗口内负荷实时需量的总和
double_t foreDemand[15]; // 负荷预测需量
int foreCount; // 当前负荷预测需量的数量
int foreIndex; // 当前负荷预测需量的索引
} sliding_window_t;
#endif

View File

@ -1,920 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_dido.C
* @brief xxxx
* @author Gary
* @date 2024/10/18
* @remark
*****************************************************************************/
#include "logic_comm.h"
#include "logic_dido.h"
// dido任务数组
static gpio_func_t gpioDiTask[MAX_NUM_CABINT][DI_End - DI_Start] = {NULL};
static gpio_func_t gpioDoTask[MAX_NUM_CABINT][DO_End - DO_Start] = {NULL};
static gpio_rtdb_data_parsing_t gpioRtdbData = {0};
pthread_mutex_t stateMutex = PTHREAD_MUTEX_INITIALIZER;
// 开启对应功能的led闪烁
uint8_t ledFucSwitch[kLedFuc_End] = {0};
/*****************************************************************************
* @brief ()
* @param[in] state_e newState
* @param[in] 使 enOrDisable 0 使 1 使 ()
* @return
*****************************************************************************/
void updateState(state_e newState, bool enOrDisable)
{
static state_e currentState = kState_Start;
pthread_mutex_lock(&stateMutex);
if (currentState == kState_Fault)
{
if (newState == kState_Fault)
{
if (enOrDisable)
{
// 故障状态再次被调用,保持故障状态
pthread_mutex_unlock(&stateMutex);
return;
}
else
{
// 故障解除 切为停机
currentState = kState_Shutdown;
}
}
else
{
// 非故障状态调用,忽略
pthread_mutex_unlock(&stateMutex);
return;
}
}
else if (currentState == newState)
{
// 非故障状态再次被调用,保持故障状态
pthread_mutex_unlock(&stateMutex);
return;
}
else // 所有状态的更新
{
if (enOrDisable)
{
currentState = newState;
}
else
{
// 防止多次调用故障解除
pthread_mutex_unlock(&stateMutex);
return;
}
}
// 系统状态写入实时库
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_RunState, (double)currentState);
pthread_mutex_unlock(&stateMutex);
return;
}
// RTDB数据获取
void faultDataGet()
{
uint8_t loop = 0;
// DI值获取
for (loop = 0; loop < (DI_End - DI_Start); loop++)
{
gpioRtdbData.diValue[loop] = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Di_Start + loop));
}
// 获取联网状态
ledFucSwitch[kLedFuc_wlan] = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_netStatus);
gpioRtdbData.pccmeterStatus = (uint8_t)(0 == (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_Pccmeter, 0, kPCC_IsOnline));
gpioRtdbData.bsmeterStatus = (uint8_t)(0 == (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_Bsmeter, 0, kBs_IsOnline));
for (loop = 0; loop < gpioRtdbData.pcsSum; loop++)
{
gpioRtdbData.pcsStatus[loop] = 0;
gpioRtdbData.pcsStatus[loop] += (uint8_t)(0 == (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_PCS, loop, kPcs_IsOnline));
gpioRtdbData.pcsStatus[loop] += (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_PCS, loop, kPcs_TotalFault);
}
for (loop = 0; loop < gpioRtdbData.bsuNum; loop++)
{
gpioRtdbData.bsuStatus[loop] = 0;
gpioRtdbData.bsuStatus[loop] += (uint8_t)(0 == (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_BSU, loop, kBsu_IsOnline));
gpioRtdbData.bsuStatus[loop] += (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_BSU, loop, kBsu_TotalAlarm);
gpioRtdbData.bsuStatus[loop] += (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_BSU, loop, kBsu_TotalFault);
}
for (loop = 0; loop < gpioRtdbData.bcuNum; loop++)
{
gpioRtdbData.bcuStatus[loop] = 0;
gpioRtdbData.bcuStatus[loop] += (uint8_t)(0 == (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_BCU, loop, kBcu_IsOnline));
gpioRtdbData.bcuStatus[loop] += (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_BCU, loop, kBsu_TotalAlarm);
gpioRtdbData.bcuStatus[loop] += (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_BCU, loop, kBsu_TotalFault);
}
for (loop = 0; loop < gpioRtdbData.thsensorNum; loop++)
{
gpioRtdbData.thsensorStatus[loop] = (uint8_t)(0 == (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_Thsensor, loop, kTHSenor_IsOnline));
gpioRtdbData.tmp[loop] = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_Thsensor, loop, kTHSenor_Temp);
}
for (loop = 0; loop < gpioRtdbData.upsNum; loop++)
{
gpioRtdbData.upsStatus[loop] = (uint8_t)(0 == (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_UPS, loop, kUps_IsOnline));
}
for (loop = 0; loop < gpioRtdbData.airCondNum; loop++)
{
gpioRtdbData.airCondStatus[loop] = (uint8_t)(0 == (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_AirCond_LiquidCool, loop, kAcLiquidMac_IsOnline));
}
#if 0
printf("******************************************************** tmp %d 度\r\n",(uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_Thsensor, 0, kTHSenor_Temp));
printf("输入:\r\n 水浸传感器低:%d\r\n水浸传感器高:%d\r\n急停:%d\r\n烟感:%d\r\n温感:%d\r\n消防触发反馈:%d\r\n门禁传感器:%d\r\n交流断路器反馈:%d\r\n",
(uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Di1),
(uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Di1+1),
(uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Di1+2),
(uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Di1+3),
(uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Di1+4),
(uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Di1+5),
(uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Di1+6),
(uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Di1+7));
printf("\r\n输入:\r\n运行灯:%d\r\n故障灯:%d\r\n交流断路器分励脱扣:%d\r\n机柜风扇:%d\r\n消防一级准备:%d\r\n消防二级触发:%d\r\n",
(uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Do1),
(uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Do1+1),
(uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Do1+2),
(uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Do1+3),
(uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Do1+4),
(uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Do1+5));
#endif
return;
}
// RTDB数据写入
void faultDataSet(uint8_t cabt)
{
return;
}
// 水浸低(常闭)
void diWaterLowGetOn(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.waterLow[cabt] = kGpioSwitch_off;
}
else
{
gpioRtdbData.waterLow[cabt] = kGpioSwitch_on;
}
}
// 水浸低(常开)
void diWaterLowGetOff(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.waterLow[cabt] = kGpioSwitch_on;
}
else
{
gpioRtdbData.waterLow[cabt] = kGpioSwitch_off;
}
}
// 水浸高(常闭)
void diWaterHighGetOn(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.waterHigh[cabt] = kGpioSwitch_off;
}
else
{
gpioRtdbData.waterHigh[cabt] = kGpioSwitch_on;
}
}
// 水浸高(常开)
void diWaterHighGetOff(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.waterHigh[cabt] = kGpioSwitch_on;
}
else
{
gpioRtdbData.waterHigh[cabt] = kGpioSwitch_off;
}
}
// 急停(常闭)
void diEmergSignalGetOn(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.emergStop[cabt] = kGpioSwitch_off;
}
else
{
gpioRtdbData.emergStop[cabt] = kGpioSwitch_on;
}
}
// 急停(常开)
void diEmergSignalGetOff(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.emergStop[cabt] = kGpioSwitch_on;
}
else
{
gpioRtdbData.emergStop[cabt] = kGpioSwitch_off;
}
}
// 烟感(常闭)
void diSmokeSignalGetOn(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.smokeDetec[cabt] = kGpioSwitch_off;
}
else
{
gpioRtdbData.smokeDetec[cabt] = kGpioSwitch_on;
}
}
// 烟感(常开)
void diSmokeSignalGetOff(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.smokeDetec[cabt] = kGpioSwitch_on;
}
else
{
gpioRtdbData.smokeDetec[cabt] = kGpioSwitch_off;
}
}
// 温感(常闭)
void diTempSignalGetOn(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.tempSensor[cabt] = kGpioSwitch_off;
}
else
{
gpioRtdbData.tempSensor[cabt] = kGpioSwitch_on;
}
}
// 温感(常开)
void diTempSignalGetOff(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.tempSensor[cabt] = kGpioSwitch_on;
}
else
{
gpioRtdbData.tempSensor[cabt] = kGpioSwitch_off;
}
}
// 消防触发反馈(常闭)
void diFireFeedbackSignalGetOn(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.fireFeedback[cabt] = kGpioSwitch_off; // 消防触发
}
else
{
gpioRtdbData.fireFeedback[cabt] = kGpioSwitch_on; // 消防未触发
}
}
// 消防触发反馈(常开)
void diFireFeedbackSignalGetOff(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.fireFeedback[cabt] = kGpioSwitch_on; // 消防触发
}
else
{
gpioRtdbData.fireFeedback[cabt] = kGpioSwitch_off; // 消防未触发
}
}
// 门禁传感器(常闭)
void diAccessSignalGetOn(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.accessSensor[cabt] = kGpioSwitch_off;
}
else
{
gpioRtdbData.accessSensor[cabt] = kGpioSwitch_on;
}
}
// 门禁传感器(常开)
void diAccessSignalGetOff(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.accessSensor[cabt] = kGpioSwitch_on;
}
else
{
gpioRtdbData.accessSensor[cabt] = kGpioSwitch_off;
}
}
// 交流断路器反馈(常闭)
void diCircuitFeedGetOn(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.circuitFeed[cabt] = kGpioSwitch_off;
}
else
{
gpioRtdbData.circuitFeed[cabt] = kGpioSwitch_on;
}
}
// 交流断路器反馈(常开)
void diCircuitFeedGetOff(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.circuitFeed[cabt] = kGpioSwitch_on;
}
else
{
gpioRtdbData.circuitFeed[cabt] = kGpioSwitch_off;
}
}
// 气溶胶触发反馈(常闭)
void diFireAerosolGetOn(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.fireAerosol[cabt] = kGpioSwitch_off;
}
else
{
gpioRtdbData.fireAerosol[cabt] = kGpioSwitch_on;
}
}
// 气溶胶触发反馈(常开)
void diFireAerosolGetOff(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.fireAerosol[cabt] = kGpioSwitch_on;
}
else
{
gpioRtdbData.fireAerosol[cabt] = kGpioSwitch_off;
}
}
// 浪涌辅助触点(常闭)
void diSurgeGetOn(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.surge[cabt] = kGpioSwitch_off;
}
else
{
gpioRtdbData.surge[cabt] = kGpioSwitch_on;
}
}
// 浪涌辅助触点(常开)
void diSurgeGetOff(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.surge[cabt] = kGpioSwitch_on;
}
else
{
gpioRtdbData.surge[cabt] = kGpioSwitch_off;
}
}
// 消防故障(常闭)
void diFireFaultGetOn(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.fireFault[cabt] = kGpioSwitch_off;
}
else
{
gpioRtdbData.fireFault[cabt] = kGpioSwitch_on;
}
}
// 消防故障(常开)
void diFireFaultGetOff(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.diValue[indx])
{
gpioRtdbData.fireFault[cabt] = kGpioSwitch_on;
}
else
{
gpioRtdbData.fireFault[cabt] = kGpioSwitch_off;
}
}
// LED闪烁模式
void doRunLedBliCtrl(uint8_t cabt, uint16_t indx)
{
static int rtLedStat[MAX_NUM_CABINT] = {kGpioSwitch_off};
// 本机LED闪烁与DIDO策略无关仅用于开发
ledFucSwitch[kLedFuc_on] = kGpioSwitch_on;
if (rtLedStat[cabt])
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on);
// drvGpioWrite(DO_Start + indx, kGpioSwitch_on);
rtLedStat[cabt] = kGpioSwitch_off;
}
else
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off);
// drvGpioWrite(DO_Start + indx, kGpioSwitch_off);
rtLedStat[cabt] = kGpioSwitch_on;
}
return;
}
// LED常亮常灭模式
void doRunLedContnCtrl(uint8_t cabt, uint16_t indx)
{
static gpioSwitch_e rtLedStat[MAX_NUM_CABINT] = {kGpioSwitch_off};
if (kGpioSwitch_on) // 待获取开灯条件
{
if (1 != rtLedStat[cabt])
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on);
drvGpioWrite(DO_Start + indx, kGpioSwitch_on); // 写DO任务暂时在这里
rtLedStat[cabt] = kGpioSwitch_on;
// 本机LED闪烁与DIDO策略无关仅用于开发
ledFucSwitch[kLedFuc_on] = kGpioSwitch_on;
}
}
else if (kGpioSwitch_off)
{
if (0 != rtLedStat[cabt])
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off);
drvGpioWrite(DO_Start + indx, kGpioSwitch_off); // 写DO任务暂时在这里
rtLedStat[cabt] = kGpioSwitch_off;
// 本机LED闪烁与DIDO策略无关仅用于开发
ledFucSwitch[kLedFuc_on] = kGpioSwitch_off;
}
}
return;
}
// 故障LED闪烁模式
void doFaultLedBliCtrl(uint8_t cabt, uint16_t indx)
{
static int rtLedStat[MAX_NUM_CABINT] = {kGpioSwitch_off}, flag = 0;
// 告警
if (gpioRtdbData.thsensorStatus[cabt] || gpioRtdbData.upsStatus[cabt] || gpioRtdbData.airCondStatus[cabt])
{
// EMS自带告警灯闪烁
ledFucSwitch[kLedFuc_alarm] = kGpioSwitch_on;
}
else
{
ledFucSwitch[kLedFuc_alarm] = kGpioSwitch_off;
}
// 故障
if (gpioRtdbData.pccmeterStatus || gpioRtdbData.bsmeterStatus || gpioRtdbData.pcsStatus[cabt] ||
gpioRtdbData.bsuStatus[cabt] || gpioRtdbData.bcuStatus[cabt])
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off); // 关灯 // 控灯
// 故障上报
updateState(kState_Fault, true);
flag = 1;
// EMS自带故障灯闪烁
ledFucSwitch[kLedFuc_fault] = kGpioSwitch_on;
}
else if (flag)
{
// 故障恢复上报
updateState(kState_Fault, false);
flag = 0; // 恢复只能调用一次
drvGpioWrite(DO_Start + indx, kGpioSwitch_off);
ledFucSwitch[kLedFuc_fault] = kGpioSwitch_off;
return;
}
if (rtLedStat[cabt])
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on);
// drvGpioWrite(DO_Start + indx, kGpioSwitch_on);
rtLedStat[cabt] = kGpioSwitch_off;
}
else
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off);
// drvGpioWrite(DO_Start + indx, kGpioSwitch_off);
rtLedStat[cabt] = kGpioSwitch_on;
}
return;
}
// 故障和告警LED常亮常灭模式
void doFaultLedContnCtrl(uint8_t cabt, uint16_t indx)
{
static gpioSwitch_e rtLedStat[MAX_NUM_CABINT] = {kGpioSwitch_off};
if (gpioRtdbData.pccmeterStatus || gpioRtdbData.bsmeterStatus || gpioRtdbData.pcsStatus[cabt] ||
gpioRtdbData.bsuStatus[cabt] || gpioRtdbData.bcuStatus[cabt])
{
if (kGpioSwitch_on != rtLedStat[cabt])
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on);
drvGpioWrite(DO_Start + indx, kGpioSwitch_on); // 写DO任务暂时在这里
rtLedStat[cabt] = kGpioSwitch_on;
// 故障上报
updateState(kState_Fault, true);
// 本机LED闪烁与DIDO策略无关仅用于开发
ledFucSwitch[kLedFuc_fault] = kGpioSwitch_on;
}
}
else
{
if (kGpioSwitch_off != rtLedStat[cabt])
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off);
drvGpioWrite(DO_Start + indx, kGpioSwitch_off); // 写DO任务暂时在这里
rtLedStat[cabt] = kGpioSwitch_off;
// 故障恢复上报
updateState(kState_Fault, false);
// 本机LED闪烁与DIDO策略无关仅用于开发
ledFucSwitch[kLedFuc_fault] = kGpioSwitch_on;
}
}
// 告警
if (gpioRtdbData.thsensorStatus[cabt] || gpioRtdbData.upsStatus[cabt] || gpioRtdbData.airCondStatus[cabt])
{
// EMS自带告警灯闪烁
ledFucSwitch[kLedFuc_alarm] = kGpioSwitch_on;
}
else
{
ledFucSwitch[kLedFuc_alarm] = kGpioSwitch_off;
}
return;
}
// 交流断路器分励脱扣
void doCircuitTrippingCtrl(uint8_t cabt, uint16_t indx)
{
static gpioSwitch_e rtDoStat[MAX_NUM_CABINT] = {kGpioSwitch_off};
if (gpioRtdbData.emergStop[cabt] || (gpioRtdbData.waterHigh[cabt] && gpioRtdbData.waterHigh[cabt]) ||
gpioRtdbData.tempSensor[cabt] || gpioRtdbData.smokeDetec[cabt] || gpioRtdbData.fireFeedback[cabt])
{
if (kGpioSwitch_on != gpioRtdbData.circuitFeed[cabt] && kGpioSwitch_on != rtDoStat[cabt])
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on);
drvGpioWrite(DO_Start + indx, kGpioSwitch_on); // 写DO任务暂时在这里
rtDoStat[cabt] = kGpioSwitch_on;
}
if (1 != stlogic.para_delivery.task_params.protect.scramButton)
{
stlogic.para_delivery.task_params.protect.scramButton = 1;
}
// 不仅仅是交流脱扣 还有 PCS 停机 BMS脱扣
}
else
{
if (0 != stlogic.para_delivery.task_params.protect.scramButton)
{
stlogic.para_delivery.task_params.protect.scramButton = 0;
}
if (kGpioSwitch_off != rtDoStat[cabt])
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off);
drvGpioWrite(DO_Start + indx, kGpioSwitch_off); // 写DO任务暂时在这里
rtDoStat[cabt] = kGpioSwitch_off;
}
}
}
// 机柜风扇控制
void doFanCtrl(uint8_t cabt, uint16_t indx)
{
static gpioSwitch_e rtFanStat[MAX_NUM_CABINT] = {kGpioSwitch_off};
if (gpioRtdbData.tmp[cabt] >= 35) // 判断风扇开启条件
{
if (rtFanStat[cabt] != kGpioSwitch_on) // 开启
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on);
drvGpioWrite(DO_Start + indx, kGpioSwitch_on);
rtFanStat[cabt] = kGpioSwitch_on;
}
}
else if (gpioRtdbData.tmp[cabt] < 30 && 1 == rtFanStat[cabt]) // 回差判断
{
if (rtFanStat[cabt] != kGpioSwitch_off) // 关闭
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off);
drvGpioWrite(DO_Start + indx, kGpioSwitch_off);
rtFanStat[cabt] = kGpioSwitch_off;
}
}
return;
}
// 消防一级准备 暂时不启用
void multiCondTrigFire1(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.smokeDetec[cabt] && gpioRtdbData.tempSensor[cabt])
{
if (kGpioSwitch_off == gpioRtdbData.fireFeedback[cabt])
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on);
// drvGpioWrite(DO_Start + indx, kGpioSwitch_on);
}
}
else
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off);
// drvGpioWrite(DO_Start + indx, kGpioSwitch_off);
}
return;
}
// 消防二级触发 暂时不启用
void multiCondTrigFire2(uint8_t cabt, uint16_t indx)
{
if (gpioRtdbData.smokeDetec[cabt] && gpioRtdbData.tempSensor[cabt])
{
if (kGpioSwitch_off == gpioRtdbData.fireFeedback[cabt])
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on);
// drvGpioWrite(DO_Start + indx, kGpioSwitch_on);
}
}
else
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off);
// drvGpioWrite(DO_Start + indx, kGpioSwitch_off);
}
return;
}
// 对应DO口输出高电平
void doPutHigh(uint8_t cabt, uint16_t indx)
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on);
drvGpioWrite(DO_Start + indx, kGpioSwitch_on);
return;
}
// 对应DO口输出低电平
void doPutLow(uint8_t cabt, uint16_t indx)
{
setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off);
drvGpioWrite(DO_Start + indx, kGpioSwitch_off);
return;
}
static gpio_func_t diFuc[kDiFuc_End] =
{
NULL,
diWaterLowGetOn, // 水浸传感器低常闭0
diWaterLowGetOff, // 水浸传感器低常开1
diWaterHighGetOn, // 水浸传感器高常闭2
diWaterHighGetOff, // 水浸传感器高常开3
diEmergSignalGetOn, // 急停常闭4
diEmergSignalGetOff, // 急停常开5
diSmokeSignalGetOn, // 烟感常闭6
diSmokeSignalGetOff, // 烟感常开7
diTempSignalGetOn, // 温感常闭8
diTempSignalGetOff, // 温感常开9
diFireFeedbackSignalGetOn, // 消防触发反馈常闭10
diFireFeedbackSignalGetOff, // 消防触发反馈常开11
diAccessSignalGetOn, // 门禁传感器常闭12
diAccessSignalGetOff, // 门禁传感器常开13
diCircuitFeedGetOn, // 交流断路器反馈常闭14
diCircuitFeedGetOff, // 交流断路器反馈常开15
diFireAerosolGetOn, // 气溶胶触发反馈常闭16
diFireAerosolGetOff, // 气溶胶触发反馈常开17
diSurgeGetOn, // 浪涌辅助触点常闭18
diSurgeGetOff, // 浪涌辅助触点常开19
diFireFaultGetOn, // 消防故障常闭20
diFireFaultGetOff // 消防故障常开21
};
static gpio_func_t doFuc[kDoFuc_End] =
{
NULL,
doRunLedContnCtrl, // 运行灯 常亮 0
doRunLedBliCtrl, // 运行灯 闪烁 1
doFaultLedContnCtrl, // 故障灯 常亮 2
doFaultLedBliCtrl, // 故障灯 闪烁 3
doCircuitTrippingCtrl, // 交流断路器分励脱扣 4
doFanCtrl, // 机柜风扇 5
multiCondTrigFire1, // 消防一级准备 6
multiCondTrigFire2, // 消防二级触发 一级二级同时置高电平才真的喷洒 7
doPutHigh, // 对应DO口输出高电平8
doPutLow // 对应DO口输出低电平9
};
// 从sq获取配置用于初始化DIDO定义
int didoConfigInit()
{
// 初始化
memset(&gpioRtdbData, 0, sizeof(gpio_rtdb_data_parsing_t));
UT_array *didoInfoArr = NULL;
// 测试使用默认配置
#if 0
gpioDiTask[0][0] = diFuc[0];
gpioDiTask[0][1] = diFuc[1];
gpioDiTask[0][2] = diFuc[2];
gpioDiTask[0][3] = diFuc[3];
gpioDiTask[0][4] = diFuc[4];
gpioDiTask[0][5] = diFuc[5];
gpioDiTask[0][6] = diFuc[6];
gpioDiTask[0][7] = diFuc[7];
gpioDoTask[0][0] = doFuc[0];
gpioDoTask[0][1] = doFuc[2];
gpioDoTask[0][2] = doFuc[4];
gpioDoTask[0][3] = doFuc[5];
gpioDoTask[0][4] = doFuc[6];
gpioDoTask[0][5] = doFuc[7];
#endif
// 获取数据库ID、设备类型、设备编号、协议类型
if (0 != kit_get_di_do_set_arr(&didoInfoArr))
{
return 1;
}
// 遍历设备
utarray_foreach(didoInfoArr, di_do_logic_set_t *, p_didoInfo)
{
if (kDi == p_didoInfo->dIDOType)
{
gpioDiTask[p_didoInfo->cabinetCode][p_didoInfo->dIDOseq] = diFuc[p_didoInfo->strategySeqDi];
}
else if (kDo == p_didoInfo->dIDOType)
{
gpioDoTask[p_didoInfo->cabinetCode][p_didoInfo->dIDOseq] = doFuc[p_didoInfo->strategySeqDo];
}
}
utarray_free(didoInfoArr); // 释放 UT_array
gpioDoTask[0][0] = doFuc[1];
gpioDoTask[0][1] = doFuc[3];
return 0;
}
// 初始化rtdb 固定的的数据
void gpioRtdbDataInit()
{
// 设备数量读取
gpioRtdbData.pccmeterNum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_PccmeterNum);
gpioRtdbData.bsmeterNum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_BsmeterNum);
gpioRtdbData.pcsSum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_PCSNum);
gpioRtdbData.bsuNum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_BSUNum);
gpioRtdbData.bcuNum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_BCUNum);
gpioRtdbData.thsensorNum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_ThsensorNum);
// gpioRtdbData.didoNum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_DI_Num);
gpioRtdbData.upsNum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_UPSNum);
gpioRtdbData.airCondNum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_AirCondNum);
return;
}
// 模块主循环
void *taskGpioProduce(void *itime)
{
uint16_t cnt = 0;
uint16_t time = *(uint16_t *)itime;
uint8_t loop = 0, cabt = 0;
if (time == 0)
{
KITPTF(LOG_MODBUS_EN, INFO_EN, "EMS本地DIDO处理 线程 延时参数有误!!");
KITLOG(LOG_MODBUS_EN, INFO_EN, "EMS本地DIDO处理 线程 延时参数有误!!");
}
while (1)
{
if (0 == cnt % time)
{
faultDataGet(); // 故障数据刷新
for (cabt = 0; cabt < MAX_NUM_CABINT; cabt++)
{
for (loop = 0; loop < (DI_End - DI_Start); loop++)
{
if (NULL != gpioDiTask[cabt][loop])
{
(*gpioDiTask[cabt][loop])(cabt, loop);
}
}
for (loop = 0; loop < (DO_End - DO_Start); loop++)
{
if (NULL != gpioDoTask[cabt][loop])
{
(*gpioDoTask[cabt][loop])(cabt, loop);
}
}
// 维护RTDB故障
faultDataSet(cabt);
}
cnt = 0;
}
cnt++;
usleep(50000);
}
}
void *led_blink_thread(void *arg)
{
uint8_t led_status = kGpioSwitch_on;
ledFuc_e step = 0;
while (1)
{
// 运行灯必然会闪烁
if (ledFucSwitch[kLedFuc_on])
{
led_status = (led_status == kGpioSwitch_on) ? kGpioSwitch_off : kGpioSwitch_on;
for (step = 0; step < kLedFuc_End; step++)
{
switch (step)
{
case kLedFuc_on:
drvGpioWrite(LED1, (int)(led_status && ledFucSwitch[step])); // 开机控灯
break;
case kLedFuc_alarm:
drvGpioWrite(LED2, (int)ledFucSwitch[step]); // 告警控灯
break;
case kLedFuc_wlan:
drvGpioWrite(LED3, (int)(led_status && ledFucSwitch[step])); // 连网控灯
break;
case kLedFuc_fault:
drvGpioWrite(LED4, (int)ledFucSwitch[step]); // 故障控灯
break;
default:
break;
}
}
}
else
{
sleep(1);
}
usleep(50000);
}
pthread_exit(NULL);
}
/*********************************************************************
* @brief GPIO模块
* @param[in] time
* @return
*********************************************************************/
void creatGpioModTaskEntry(uint16_t time)
{
// GPIO配置只在启动时读一遍 修改需要重启
if (0 != didoConfigInit())
{
KITPTF(LOG_MODBUS_EN, ERROR_EN, "EMS获取DIDO配置失败");
KITLOG(LOG_MODBUS_EN, ERROR_EN, "EMS获取DIDO配置失败");
return;
}
// 一些固定数据获取
gpioRtdbDataInit();
static uint16_t itime = 10;
itime = time;
pthread_t pfd, led_thread;
if (pthread_create(&pfd, NULL, taskGpioProduce, (void *)&itime))
{
KITPTF(LOG_MODBUS_EN, INFO_EN, "EMS本地DIDO处理 线程 创建成功");
KITLOG(LOG_MODBUS_EN, INFO_EN, "EMS本地DIDO处理 线程 创建成功");
}
// 创建LED闪烁线程
if (pthread_create(&led_thread, NULL, led_blink_thread, NULL) != 0)
{
KITPTF(LOG_MODBUS_EN, INFO_EN, "LED闪烁 线程 创建成功");
KITLOG(LOG_MODBUS_EN, INFO_EN, "LED闪烁 线程 创建成功");
}
}

View File

@ -1,76 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_dido.h
* @brief xxxx
* @author Gary
* @date 2024/10/18
* @remark
*****************************************************************************/
#ifndef __LOGIC_DIDO_H__
#define __LOGIC_DIDO_H__
#include "../driver/drv_gpio.h"
// 开关
typedef enum
{
kGpioSwitch_Start = 0, // 起始
kGpioSwitch_off = kGpioSwitch_Start, // 关 0
kGpioSwitch_on, // 开 1
kLedSwitch_End // 结束
} gpioSwitch_e;
// LED功能
typedef enum
{
kLedFuc_Start = 0, // 起始
kLedFuc_on, // 开机自启灯(绿)
kLedFuc_alarm, // 告警(红)
kLedFuc_wlan, // 联网灯(绿)
kLedFuc_fault, // 故障灯(红)
kLedFuc_End // 结束
} ledFuc_e;
typedef struct
{
uint8_t pccmeterNum; // PCC电表数量
uint8_t bsmeterNum; // 储能电表数量
uint8_t pcsSum; // PCS 数量
uint8_t bsuNum; // 电池堆数量
uint8_t bcuNum; // 电池簇数量
uint8_t thsensorNum; // 温湿度传感器数量
uint8_t upsNum; // UPS设备数量
uint8_t airCondNum; // 空调组数量
uint8_t pccmeterStatus; // PCC电表状态 1 故障 0 正常
uint8_t bsmeterStatus; // 储能电表状态 1 故障 0 正常
uint8_t pcsStatus[MAX_NUM_CABINT]; // pcs状态 1 故障 0 正常
uint8_t bsuStatus[MAX_NUM_CABINT]; // 电池堆状态 1 故障 0 正常
uint8_t bcuStatus[MAX_NUM_CABINT]; // 电池簇状态 1 故障 0 正常
uint8_t thsensorStatus[MAX_NUM_CABINT]; // 温湿度传感器状态 1 故障 0 正常
uint8_t tmp[MAX_NUM_CABINT]; // 柜内温度 ℃
uint8_t upsStatus[MAX_NUM_CABINT]; // UPS设备状态 1 故障 0 正常
uint8_t airCondStatus[MAX_NUM_CABINT]; // 空调组状态 1 故障 0 正常
// DI1-DI40 (可配所以都是未知包括柜号)
uint8_t diValue[DI_End - DI_Start]; // DI值
// DI 根据配置已知
uint8_t waterLow[MAX_NUM_CABINT]; // 水浸传感器低
uint8_t waterHigh[MAX_NUM_CABINT]; // 水浸传感器高
uint8_t emergStop[MAX_NUM_CABINT]; // 急停
uint8_t smokeDetec[MAX_NUM_CABINT]; // 烟感
uint8_t tempSensor[MAX_NUM_CABINT]; // 温感
uint8_t fireFeedback[MAX_NUM_CABINT]; // 消防喷洒触发反馈
uint8_t fireAerosol[MAX_NUM_CABINT]; // 消防气溶胶触发反馈
uint8_t surge[MAX_NUM_CABINT]; // 浪涌辅助触点
uint8_t fireFault[MAX_NUM_CABINT]; // 消防故障
uint8_t accessSensor[MAX_NUM_CABINT]; // 门禁传感器
uint8_t circuitFeed[MAX_NUM_CABINT]; // 交流断路器反馈
} gpio_rtdb_data_parsing_t; // 解析rtdb的数据用于GPIO
extern uint8_t ledFucSwitch[kLedFuc_End];
typedef void (*gpio_func_t)(uint8_t cabt, uint16_t indx); // 定义函数指针类型,无返回值
#endif

View File

@ -1,384 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_main.c
* @brief xxxx
* @author Gary
* @date 2024/09/29
* @remark
*****************************************************************************/
#include "logic_main.h"
logic_pthread_t stlogic = {0};
tast_register_execute *task_group[E_TACTIC_MODE_END] = {0}; // MAX_TASK_NUM改用枚举
// 用于log打印 与 work_mode_e 强绑定
const char *workModeNames[] = {
"",
"调试模式",
"削峰填谷模式",
"需求响应模式",
"负载跟踪模式",
"需量控制",
"功率因数",
"null"};
/*********************************************************************
* @brief
* @param[in]
* @return 0sucessful1fault
*********************************************************************/
static int initTaskParam()
{
logic_getProtectParam();
logic_getPowerDistrParam();
work_mode_set_t tempMode;
if (0 == kit_get_work_mode_set(&tempMode))
{
stlogic.para_delivery.mode = tempMode.workMode;
}
else if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
{
KITLOG(LOG_MODBUS_EN, INFO_EN, "获取调试配置失败 %s ==> %s", workModeNames[stlogic.para_delivery.mode], workModeNames[tempMode.workMode]);
KITPTF(LOG_MODBUS_EN, INFO_EN, "获取调试配置失败 %s ==> %s", workModeNames[stlogic.para_delivery.mode], workModeNames[tempMode.workMode]);
return 1;
}
else
{
return 1;
}
// 读取参数值
switch (stlogic.para_delivery.mode)
{
case E_TACTIC_MODE_DEBUG: // 调试模式
logic_debugParamUpdate();
break;
case E_TACTIC_MODE_PEAKVALLY: // 削峰填谷模式
logic_peakValleyUpdate();
break;
case E_TACTIC_MODE_DEMANDRES: // 需求响应模式
/* 暂未实现 */
break;
case E_TACTIC_MODE_LOADTRACK: // 负载跟踪模式
/* 暂未实现 */
break;
case E_TACTIC_MODE_DMDCTRL: // 需量控制模式
/* 暂未实现 */
break;
case E_TACTIC_MODE_PFCTRL: // 功率因数模式
/* 暂未实现 */
break;
default:
/*无模式*/
break;
}
return 0;
}
/*********************************************************************
* @brief
* @param[in] task_func
* @return NULL
*********************************************************************/
// 初始化任务链表节点
tast_register_execute *register_task(task_func_t task_func)
{
tast_register_execute *new_task = (tast_register_execute *)malloc(sizeof(tast_register_execute));
if (new_task == NULL)
{
printf("Memory allocation failed!\n");
return NULL;
}
// new_task->taskPeriod = period;
new_task->task = task_func;
new_task->next = NULL;
return new_task;
}
/*********************************************************************
* @brief
* @param[in] count
* @param[in] ...
* @return NULL
*********************************************************************/
tast_register_execute *init_task_list(int count, ...)
{
if (count <= 0)
return NULL; // 确保任务数量合法
va_list args; // 用于处理可变参数
va_start(args, count); // 初始化可变参数列表
tast_register_execute *head = NULL, *current = NULL;
// 循环遍历每个任务函数
for (int i = 0; i < count; i++)
{
task_func_t task_func = va_arg(args, task_func_t); // 获取当前任务函数指针
tast_register_execute *new_task = register_task(task_func);
if (new_task == NULL)
{
// 内存分配失败时,清理已分配的节点并返回 NULL
// free_task_list(head);
va_end(args); // 清理可变参数列表
return NULL;
}
if (head == NULL)
{
// 第一个任务作为头节点
head = new_task;
}
else
{
// 将新任务链接到链表末尾
current->next = new_task;
}
current = new_task; // 更新当前任务
}
va_end(args); // 结束可变参数处理
return head;
}
/*********************************************************************
* @brief
* @param[in]
* @return 0sucessful1fault
*********************************************************************/
static int logic_initTaskRegister()
{
INIT_TASK_GROUP();
for (int i = 0; i < E_TACTIC_MODE_END; i++)
{
if (task_group[i] == NULL)
{
printf("Failed to initialize task group 0.\n");
return 1; // 错误返回
}
}
return 0;
}
/*********************************************************************
* @brief 线
* @param[in]
* @return
*********************************************************************/
static int creatLogicTaskEntry()
{
if (pthread_create(&stlogic.tfd, NULL, creatLogicTaskThread, (void *)&stlogic.para_delivery) == 0)
{
KITPTF(LOG_LOGIC_EN, INFO_EN, "task线程创建成功");
KITLOG(LOG_LOGIC_EN, INFO_EN, "task线程创建成功");
return 0;
}
else
{
return 1;
}
}
/*********************************************************************
* @brief
* @param[in]
* @return 0sucessful1fault
*********************************************************************/
int creatLogicCtrTaskEntry()
{
initTaskParam();
if (logic_initTaskRegister() != 0)
{
return 1;
}
if (creatLogicTaskEntry() != 0)
{
return 1;
}
return 0;
}
/*********************************************************************
* @brief ,
* @param[in]
* @return
*********************************************************************/
void logic_taskTrigger()
{
int modeChange = 0;
// 读取是否参数更新
for (u_int16_t i = kSign_Logic_Start; i < kSign_Logic_End; i++)
{
stlogic.para_delivery.ParaChangeSign.ParaChangeUnion |= ((readWebSign(kSign_ShMem, i) == LOGIC_SIGN_MESSAGE) << i);
}
// 读取是否切换模式
if (LOGIC_SIGN_MESSAGE == readWebSign(kSign_ShMem, kSign_LogicMode))
{
writeWebSign(kSign_ShMem, kSign_LogicMode, 0);
modeChange = 1;
work_mode_set_t tempMode;
if (0 != kit_get_work_mode_set(&tempMode))
{
if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
{
KITLOG(LOG_LOGIC_EN, INFO_EN, "获取调试配置失败 模式切换失败!!! %s ==> %s",workModeNames[stlogic.para_delivery.mode],workModeNames[tempMode.workMode]);
KITPTF(LOG_LOGIC_EN, INFO_EN, "获取调试配置失败 模式切换失败!!! %s ==> %s",workModeNames[stlogic.para_delivery.mode],workModeNames[tempMode.workMode]);
return;
}
}
if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
{
KITLOG(LOG_LOGIC_EN, INFO_EN, "模式切换 %s ==> %s",workModeNames[stlogic.para_delivery.mode],workModeNames[tempMode.workMode]);
KITPTF(LOG_LOGIC_EN, INFO_EN, "模式切换 %s ==> %s",workModeNames[stlogic.para_delivery.mode],workModeNames[tempMode.workMode]);
return;
}
stlogic.para_delivery.mode = tempMode.workMode;
}
stlogic.para_delivery.task_params.protect.protectSign = (readWebSign(kSign_ShMem, kSign_Protect) == LOGIC_SIGN_MESSAGE);
stlogic.para_delivery.task_params.distr.powerSign = (readWebSign(kSign_ShMem, kSign_ActivePower) == LOGIC_SIGN_MESSAGE);
//数据库获取参数
/****保护****/
if (LOGIC_SIGN_MESSAGE == stlogic.para_delivery.task_params.protect.protectSign)
{
if (1 == logic_getProtectParam())
{
KITLOG(LOG_LOGIC_EN, INFO_EN, "保护参数错误");
KITPTF(LOG_LOGIC_EN, INFO_EN, "保护参数错误");
return;
}
stlogic.para_delivery.task_params.protect.protectSign = LOGIC_SIGN_UPLOAD;
}
/****功率分配****/
if (LOGIC_SIGN_MESSAGE == stlogic.para_delivery.task_params.distr.powerSign)
{
if (1 == logic_getPowerDistrParam())
{
KITLOG(LOG_LOGIC_EN, INFO_EN, "分配参数错误");
KITPTF(LOG_LOGIC_EN, INFO_EN, "分配参数错误");
return;
}
// 成功读完清除标志
stlogic.para_delivery.task_params.distr.powerSign = LOGIC_SIGN_UPLOAD;
}
//判定是否模式和参数统一
switch (stlogic.para_delivery.mode)
{
case E_TACTIC_MODE_DEBUG: // 调试模式
if (stlogic.para_delivery.ParaChangeSign.bits.debug || modeChange)
{
writeWebSign(kSign_ShMem, kSign_LogicDebug, LOGIC_SIGN_NONE);
if (1 == logic_debugParamUpdate())
{
KITLOG(LOG_LOGIC_EN, INFO_EN, "调试参数错误");
KITPTF(LOG_LOGIC_EN, INFO_EN, "调试参数错误");
}
// 成功读完清除标志
stlogic.para_delivery.ParaChangeSign.bits.debug = LOGIC_SIGN_NONE;
}
break;
case E_TACTIC_MODE_PEAKVALLY: // 削峰填谷模式
if (stlogic.para_delivery.ParaChangeSign.bits.peakValley || modeChange)
{
writeWebSign(kSign_ShMem, kSign_LogicPeakValley, LOGIC_SIGN_NONE);
if (1 == logic_peakValleyUpdate())
{
KITLOG(LOG_LOGIC_EN, INFO_EN, "削峰填谷参数错误");
KITPTF(LOG_LOGIC_EN, INFO_EN, "削峰填谷参数错误");
}
// 成功读完清除标志
stlogic.para_delivery.ParaChangeSign.bits.peakValley = LOGIC_SIGN_NONE;
}
break;
case E_TACTIC_MODE_DEMANDRES: // 需求响应模式
/* 暂未实现 */
break;
case E_TACTIC_MODE_LOADTRACK: // 负载跟踪模式
/* 暂未实现 */
break;
case E_TACTIC_MODE_DMDCTRL: // 需量控制
/* 暂未实现 */
break;
case E_TACTIC_MODE_PFCTRL: // 功率因数
/* 暂未实现 */
break;
default:
/*无模式*/
stlogic.para_delivery.task_params.distr.power = 0;
stlogic.para_delivery.task_params.protect.power = 0;
break;
}
}
/*********************************************************************
* @brief
* @param[in] task_param
* @return 0: , 1:
*********************************************************************/
int logic_taskExe(work_mode_e mode)
{
if (mode >= E_TACTIC_MODE_END)
{
// printf("Invalid task group index!\n");
return 1; // 返回错误
}
tast_register_execute *current = task_group[mode];
// 遍历并执行任务链表中的所有任务
while (current != NULL)
{
current->task(); // 执行当前任务
current = current->next; // 移动到下一个任务
}
return 0; // 成功
}
/*****************************************************************************
* @brief 线
* @param[in]
* @return
*****************************************************************************/
void *creatLogicTaskThread(void *arg)
{
task_params_t *task_param_in = (task_params_t *)arg;
while (stlogic.exitTaskFlag == 0)
{
logic_taskTrigger();
logic_getRTDBParams();
if (0 != logic_taskExe(task_param_in->mode))
{
// 处理调度错误,可以记录日志
KITLOG(LOG_LOGIC_EN, ERROR_EN, "任务调度失败,参数无效");
usleep(50000); // 50ms sleep
continue;
}
logic_paramUpload();
usleep(20000); // 20ms sleep
}
pthread_exit(NULL);
}
void example_task1()
{
;
}

View File

@ -1,67 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_main.h
* @brief xxxx
* @author Gary
* @date 2024/09/29
* @remark
*****************************************************************************/
#pragma once
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include "logic_comm.h"
#define MAX_TASK_NUM 10
// 在头文件中配置任务链
#define INIT_TASK_GROUP() \
{ \
task_group[E_TACTIC_MODE_START] = init_task_list(1, example_task1); \
task_group[E_TACTIC_MODE_DEBUG] = init_task_list(2, logicFun_protect,logicFun_powerDistr); \
task_group[E_TACTIC_MODE_PEAKVALLY] = init_task_list(3, logicFun_peakValley,logicFun_protect,logicFun_powerDistr); \
task_group[E_TACTIC_MODE_DEMANDRES] = init_task_list(1, example_task1); \
task_group[E_TACTIC_MODE_LOADTRACK] = init_task_list(1, example_task1); \
task_group[E_TACTIC_MODE_DMDCTRL] = init_task_list(1, example_task1); \
task_group[E_TACTIC_MODE_PFCTRL] = init_task_list(1, example_task1); \
}
typedef int (*task_func_t)(); // 定义函数指针类型返回值为int
typedef enum
{
E_RUN_ONCE, //单次运行
E_RUN_period //周期运行
} task_run_type;
typedef struct tast_register_execute
{
// protocol_type_master_e protocolType; // 任务
// task_run_type taskType; // 任务类型
// uint16_t taskPeriod; // 任务间隔 ms
task_func_t task; // 任务指针
struct tast_register_execute* next; // 指向下一个任务
} tast_register_execute;
extern tast_register_execute* task_group[E_TACTIC_MODE_END];
void example_task1();
//初始化任务链表,支持多个任务函数指针
tast_register_execute* init_task_list(int count, ...);
/*****************************************************************************
* @brief 线
* @param[in]
* @return
*****************************************************************************/
void* creatLogicTaskThread(void* arg);
/*********************************************************************
* @brief
* @param[in]
* @return 0sucessful1fault
*********************************************************************/
int creatLogicCtrTaskEntry();

View File

@ -1,230 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_peakvalley.c
* @brief
* @author Gary
* @date 2024/09/21
* @remark
*****************************************************************************/
#include "logic_comm.h"
// 削峰填谷参数数据库配置
peakvalley_zone_tab_t zone_tab_obj = {0}; // 定义一个结构体变量
peakvalley_zone_tab_t* zone_tab = &zone_tab_obj; // 使指针指向该变量
/*****************************************************************************
* @brief
* @param[in] char* dateStr "MM-DD"
* @param[out] int* month
* @param[out] int* day
* @return 0
*****************************************************************************/
static int parseDate(const char* dateStr, int* month, int* day)
{
int result = sscanf(dateStr, "%d-%d", month, day); // 解析字符串获取月份和日期
return (result == 2) ? 0 : -1; // 返回0表示成功其他值表示失败
}
/*****************************************************************************
* @brief
* @param[in] pv_time_config_t *ret_params() u_int16_t slotTabLen
* @return
*****************************************************************************/
static float_t getPeakValleyPower(pv_time_config_t* ret_params, u_int16_t slotTabLen)
{
// 获取当前时间
time_t current_time;
struct tm* timeinfo;
time(&current_time); // 获取当前时间戳
timeinfo = localtime(&current_time); // 将时间戳转换为当地时间
uint32_t now_seconds = timeinfo->tm_hour * 3600 + timeinfo->tm_min * 60 + timeinfo->tm_sec; // 计算当前秒数
// EMS要求最小的时间间隔不得小于15分钟换算之后一天不可大于96个时段
if (slotTabLen > MAX_TIME_SEGMENTS)
{
// 检查传入的时间段表长度是否合法
KITLOG(LOG_LOGIC_EN, WARN_EN, "获取时段表的长度非法 len:%d\n", slotTabLen);
return 0; // 返回0表示未能获取有效功率
}
for (int loop = 0; loop < slotTabLen; loop++)
{
// 跳过开始时间和结束时间相同的时间段
if (ret_params[loop].startTime == ret_params[loop].endTime)
{
continue;
}
// 检查当前时间是否在时间段内
if (now_seconds >= ret_params[loop].startTime &&
now_seconds <= ret_params[loop].endTime)
{
return ret_params[loop].power; // 返回当前时间段的功率值
}
}
// 未命中任意时段则停机返回0
return 0;
}
/*****************************************************************************
* @brief
* @param[in] int dateMonth
* @param[in] int dateDay
* @param[in] const char* startDateStr
* @param[in] const char* endDateStr
* @return 1 0 -1
*****************************************************************************/
static int isDateInRange(int dateMonth, int dateDay, const char* startDateStr, const char* endDateStr)
{
if (NULL == startDateStr || NULL == endDateStr)
{
// 检查开始和结束日期指针是否为空
KITLOG(LOG_LOGIC_EN, ERROR_EN, "入参指针为空");
return -1; // 返回-1表示参数异常
}
int startMonth, startDay, endMonth, endDay;
if (0 != parseDate(startDateStr, &startMonth, &startDay))
{
// 解析开始日期字符串失败
KITLOG(LOG_LOGIC_EN, ERROR_EN, "开始日期字符串匹配失败");
return -1; // 返回-1表示参数解析失败
}
if (0 != parseDate(endDateStr, &endMonth, &endDay))
{
// 解析结束日期字符串失败
KITLOG(LOG_LOGIC_EN, ERROR_EN, "结束日期字符串匹配失败");
return -1; // 返回-1表示参数解析失败
}
// 日期保护,确保开始日期在结束日期之前
if (startMonth > endMonth || (startMonth == endMonth && startDay > endDay))
{
return 0; // 返回0表示不在范围内
}
// 判断是否在日期内
if (dateMonth > startMonth || (dateMonth == startMonth && dateDay >= startDay))
{
if (dateMonth < endMonth || (dateMonth == endMonth && dateDay <= endDay))
{
return 1; // 返回1表示在时间段内
}
}
return 0; // 返回0表示不在范围内
}
/*****************************************************************************
* @brief
* @return 0 -1
*****************************************************************************/
int logic_peakValleyUpdate()
{
UT_array* pvDateConfigs;
// 清空之前的时段表
if (zone_tab->peakItem != NULL)
{
for (int j = 0; j < zone_tab->zoneTabLen; ++j)
{
if (zone_tab->peakItem[j].timeCfgTab != NULL)
free(zone_tab->peakItem[j].timeCfgTab);
zone_tab->peakItem[j].timeCfgTab = NULL;
}
free(zone_tab->peakItem);
zone_tab->peakItem = NULL;
}
// 从数据库获取新的削峰填谷时段表数据
if (kit_get_pv_date_cfg_db_data(&pvDateConfigs) != 0)
{
KITLOG(LOG_LOGIC_EN, ERROR_EN, "获取削峰填谷时段表失败");
return 1; // 返回错误码
}
// 获取数据个数
size_t numConfigs = utarray_len(pvDateConfigs);
// 检查时段表长度是否合法
if (MAX_DATA_SEGMENTS < numConfigs || numConfigs <= 0)
{
KITLOG(LOG_LOGIC_EN, ERROR_EN, "时区表表长异常: %zu", numConfigs);
utarray_free(pvDateConfigs); // 释放资源
return 1; // 返回错误码
}
// 分配空间
zone_tab->peakItem = (pv_date_config_t*)calloc(numConfigs, sizeof(pv_date_config_t));
if (zone_tab->peakItem == NULL)
{
KITLOG(LOG_LOGIC_EN, ERROR_EN, "内存分配失败");
utarray_free(pvDateConfigs); // 释放资源
return 1; // 返回错误码
}
// 更新日期配置个数
zone_tab->zoneTabLen = numConfigs;
// 遍历并复制数据 使用 memcpy 整体复制结构体
for (int i = 0; i < numConfigs; ++i)
{
pv_date_config_t* srcConfig = (pv_date_config_t*)utarray_eltptr(pvDateConfigs, i);
pv_date_config_t* dstConfig = &zone_tab->peakItem[i]; // 直接访问数组元素
// 复制 timeCfgTab 前先分配内存
dstConfig->timeCfgTab = (pv_time_config_t*)calloc(srcConfig->timeCfgLen, sizeof(pv_time_config_t));
if (dstConfig->timeCfgTab == NULL)
{
KITLOG(LOG_LOGIC_EN, ERROR_EN, "内存分配失败");
// 释放已分配的内存
for (int j = 0; j < i; ++j)
{
free(zone_tab->peakItem[j].timeCfgTab);
}
free(zone_tab->peakItem);
utarray_free(pvDateConfigs); // 释放资源
return 1; // 返回错误码
}
memcpy(dstConfig, srcConfig, sizeof(pv_date_config_t)); // 整体复制结构体
memcpy(dstConfig->timeCfgTab, srcConfig->timeCfgTab, srcConfig->timeCfgLen * sizeof(pv_time_config_t));
}
utarray_free(pvDateConfigs); // 释放 UT_array 资源
return 0; // 返回成功
}
/*****************************************************************************
* @brief
* @param[in] bool sign
* @return 0 -1
*****************************************************************************/
int logicFun_peakValley()
{
// 获取任务参数
peakvalley_params_t* task_params = &stlogic.para_delivery.task_params.pkvly;
time_t current_time;
struct tm* timeinfo;
time(&current_time); // 获取当前时间
timeinfo = localtime(&current_time); // 转换为当地时间
// 获取日期
int month = timeinfo->tm_mon + 1; // 月份从0开始需要加1
int day = timeinfo->tm_mday; // 天
if (zone_tab == NULL)
{
// 检查时段表指针是否为空
KITLOG(LOG_LOGIC_EN, ERROR_EN, "入参指针为空");
return -1; // 返回-1表示失败
}
for (int loop = 0; loop < zone_tab->zoneTabLen; loop++)
{
// 检查当前日期是否在时段表中
if (1 == isDateInRange(month, day, (char*)zone_tab->peakItem[loop].startDate, (char*)zone_tab->peakItem[loop].endDate))
{
// 获取对应时间段的功率配置
task_params->power = getPeakValleyPower(zone_tab->peakItem[loop].timeCfgTab, zone_tab->peakItem[loop].timeCfgLen);
return 0; // 返回0表示成功
}
}
// 没找到合适的日期返回0
task_params->power = 0;
return 0;
}

View File

@ -1,53 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_peakvalley.h
* @brief xxxx
* @author Gary
* @date 2024/09/20
* @remark
*****************************************************************************/
#ifndef __LOGIC_PEAKVALLEY_H__
#define __LOGIC_PEAKVALLEY_H__
#define MAX_DATA_SEGMENTS 0x0C // 一年12个月最多分 12个时间段
#define MAX_TIME_SEGMENTS 0x60 // 一天24小时最多分 96个时间段
#include "kit_data.h"
// // 时段类型
// typedef enum
// {
// kPeakvalley_Start = 0, // 开始值
// kPeakvalley_Valley, // 谷
// kPeakvalley_Peak, // 峰
// kPeakvalley_Flat, // 平
// kPeakvalley_End // 结束值
// } peak_valley_e;
// 所有时间表结构体 用于查询
typedef struct
{
pv_date_config_t* peakItem; // 时区表
int zoneTabLen; // 时区表实际表长
} peakvalley_zone_tab_t;
// 削峰填谷传参结构体
typedef struct
{
int runPeriod; // 运行周期 ms
float_t power; // 最终计算的目标功率
} peakvalley_params_t;
/*****************************************************************************
* @brief
* @return 0 -1
*****************************************************************************/
int logic_getProtectParam();
/*****************************************************************************
* @brief
* @return 0 -1
*****************************************************************************/
int logic_peakValleyUpdate();
#endif

View File

@ -1,176 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_power_distr.c
* @brief xxxx
* @author Gary
* @date 2024/09/28
* @remark
*****************************************************************************/
#include "logic_comm.h"
/*****************************************************************************
* @brief
*
* @return 0 -1 1
*****************************************************************************/
int logic_getPowerDistrParam()
{
static allocate_power_t getPowerBuff;
if (0 != kit_get_allocate_power(&getPowerBuff))
{
// INLOG(Log_LOGIC_EN, ERROR_EN, "获取保护配置失败\n");
return 1;
}
stlogic.para_delivery.task_params.distr.cabintCont = getPowerBuff.pcsNum;
stlogic.para_delivery.task_params.distr.chgDirection = getPowerBuff.chgDirection;
stlogic.para_delivery.task_params.distr.allocateMode = getPowerBuff.allocateMode;
return 0;
}
/*****************************************************************************
* @brief
* @param[in] power_distr_t distPower
* @return -1 0
*****************************************************************************/
void logic_PowerCal(power_distr_t *distPower, float_t tempPower, int loop)
{
float_t finalPower = 0;
// if (distPower->nowDistPower[loop] < 0) // 充电
if (tempPower < 0) // 充电
{
finalPower = -float_min(abs(tempPower), distPower->pcsMaxChaPower[loop]);
if (float_diff(distPower->nowBmsPower[loop], finalPower)) // 实时功率比较 差距大再下发
{
if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
{
KITLOG(LOG_MODBUS_EN, INFO_EN, "柜 %d 功率变化 %.2f kw ==> %.2f kw", loop, distPower->nowDistPower[loop], finalPower * distPower->chgDirection);
KITPTF(LOG_MODBUS_EN, INFO_EN, "柜 %d 功率变化 %.2f kw ==> %.2f kw", loop, distPower->nowDistPower[loop], finalPower * distPower->chgDirection);
}
distPower->nowDistPower[loop] = finalPower * distPower->chgDirection;
}
// 调试模式PCS开关由指令决定
if (stlogic.para_delivery.mode == E_TACTIC_MODE_DEBUG)
{
distPower->pcsSwitch[loop] = stlogic.para_delivery.task_params.debug.pcsSwitch;
}
else
{
// distPower->pcsSwitch[loop] = distPower->pcsOn; // pcs 功能码可定制 在这里
distPower->pcsSwitch[loop] = 1;
}
// 系统状态更新
updateState(kState_Charging, true);
}
else if (tempPower > 0) // 放电
{
finalPower = float_min(tempPower, distPower->pcsMaxDiscPower[loop]);
if (float_diff(distPower->nowBmsPower[loop], finalPower)) // 与实时功率比较 差距大再下发
{
if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
{
KITLOG(LOG_MODBUS_EN, INFO_EN, "柜 %d 功率变化 %.2f kw ==> %.2f kw", loop, distPower->nowDistPower[loop], finalPower * distPower->chgDirection);
KITPTF(LOG_MODBUS_EN, INFO_EN, "柜 %d 功率变化 %.2f kw ==> %.2f kw", loop, distPower->nowDistPower[loop], finalPower * distPower->chgDirection);
}
distPower->nowDistPower[loop] = finalPower * distPower->chgDirection;
}
// 调试模式PCS开关由指令决定
if (stlogic.para_delivery.mode == E_TACTIC_MODE_DEBUG)
{
distPower->pcsSwitch[loop] = stlogic.para_delivery.task_params.debug.pcsSwitch;
}
else
{
// distPower->pcsSwitch[loop] = distPower->pcsOn; // pcs 功能码可定制 在这里
distPower->pcsSwitch[loop] = 1;
}
// 系统状态更新
updateState(kState_Discharging, true);
}
else // 待机
{
// distPower->pcsSwitch[loop] = distPower->pcsOff;
if (0 != distPower->nowDistPower[loop])
{
if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
{
KITLOG(LOG_MODBUS_EN, INFO_EN, "柜 %d 功率变化 %.2f kw ==> 0 kw", loop, distPower->nowDistPower[loop]);
KITPTF(LOG_MODBUS_EN, INFO_EN, "柜 %d 功率变化 %.2f kw ==> 0 kw", loop, distPower->nowDistPower[loop]);
}
}
distPower->nowDistPower[loop] = 0;
// 调试模式PCS开关由指令决定
if (stlogic.para_delivery.mode == E_TACTIC_MODE_DEBUG)
{
distPower->pcsSwitch[loop] = stlogic.para_delivery.task_params.debug.pcsSwitch;
}
else
{
// distPower->pcsSwitch[loop] = distPower->pcsOn; // pcs 功能码可定制 在这里
distPower->pcsSwitch[loop] = 0;
}
// 系统状态更新
updateState(kState_Standby, true);
}
}
/*****************************************************************************
* @brief
*
* @return -1 0
*****************************************************************************/
void logicFun_powerDistr()
{
power_distr_t *charge_params = &stlogic.para_delivery.task_params.distr;
float_t tempPower = 0;
int loop = 0, closePrtc = 0;
if (charge_params == NULL)
{
// INLOG(Log_LOGIC_EN, ERROR_EN, "入参指针为空!\n");
return;
}
// 把保护计算完的的功率拿出来分配
charge_params->power = stlogic.para_delivery.task_params.protect.power;
if (E_TACTIC_MODE_DEBUG == stlogic.para_delivery.mode && stlogic.para_delivery.task_params.debug.protectSwitch)
{
closePrtc = 1;
}
// 计算每个柜子分多少功率
for (loop = 0; loop < charge_params->cabintCont; loop++)
{
if (charge_params->power < 0 && charge_params->sumSoc != 0) // 充电
{
if (closePrtc || (charge_params->pcsMaxChaPower[loop] != 0 && charge_params->pcsState[loop] != 0 && charge_params->bmsState[loop] != 0))
{
tempPower = charge_params->power * (SOCMAX - charge_params->bmsSoc[loop]) / charge_params->sumSoc;
logic_PowerCal(charge_params, tempPower, loop);
}
else
{
charge_params->nowDistPower[loop] = 0;
}
}
else if (charge_params->power > 0 && charge_params->sumSoc != 0) // 放电
{
if (closePrtc || (charge_params->pcsMaxDiscPower[loop] != 0 && charge_params->pcsState[loop] != 0 && charge_params->bmsState[loop] != 0))
{
tempPower = charge_params->power * (charge_params->bmsSoc[loop]) / charge_params->sumSoc;
logic_PowerCal(charge_params, tempPower, loop);
}
else
{
charge_params->nowDistPower[loop] = 0;
}
}
else // 待机
{
charge_params->nowDistPower[loop] = 0;
logic_PowerCal(charge_params, tempPower, loop);
}
}
}

View File

@ -1,80 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_power_issue.h
* @brief xxxx
* @author Gary
* @date 2024/09/28
* @remark
*****************************************************************************/
#ifndef __LOGIC_POWERISSUE_H__
#define __LOGIC_POWERISSUE_H__
#define MAX_NUM_CABINT 3 // 默认最大柜体个数为3RTDB预留
#define SOCMAX 100
extern int g_iPcsChargeDirection; // PCS充放电方向 1(正放 负充) -1负放 正充) 默认1
typedef enum
{
kBms_State_Start = 0,
kBms_State_Normal, // 正常rack可以放电, 可以充电)
kBms_State_NoCharge, // 禁充rack可以放电, 不能充电)
kBms_State_NoDischarge, // 禁放rack可以充电, 不能放电)
kBms_State_Down, // 停机rack不能充放
kBms_state_end
} bms_state_e;
// // 充放电模式
// typedef enum
// {
// kCharge_Mode_Start = 0, // 开始值
// kCharge_Mode_charge ,
// kCharge_Mode_discharge,
// kCharge_Mode_rest,
// kCharge_Mode_End // 结束值
// } charge_mode_e;
typedef struct
{
// charge_mode_e issueMod; // 本次下发充放电模式 ps模式暂时不用 充放电方向: 默认1(正放 负充)
// bms_state_e rackRunState[MAX_NUM_CABINT]; // 实时每个柜子的BMS的状态 IN
// 从实时库获取
float_t bmsSoc[MAX_NUM_CABINT]; // 实时每个柜子的BMS的SOC IN
float_t pcsMaxChaPower[MAX_NUM_CABINT]; // 最大充电功率 kw IN
float_t pcsMaxDiscPower[MAX_NUM_CABINT]; // 最大放电功率 kw IN
float_t nowBmsPower[MAX_NUM_CABINT]; // bms当前实时功率 kw IN
uint8_t pcsState[MAX_NUM_CABINT]; // pcs在线状态
uint8_t bmsState[MAX_NUM_CABINT]; // bms在线状态
// 可配置参数
uint16_t cabintCont; // 当前实际并柜数量 IN
int chgDirection; // 充放电方向 1(正放 负充) -1(正充 负放)
uint8_t allocateMode; // 下发功率开关总功率0分相功率1
uint16_t pcsOn; // PCS开机字 功能码可定制
uint16_t pcsOff; // PCS关机字 功能码可定制
int runPeriod; // 运行周期 ms
uint8_t powerSign; // 功率分配配置修改标志
// 中间参数
float_t stationBmsSoc; // 站级SOC OUT
float_t sumSoc; // SOC累加
float_t power; // 总的目标功率 kw IN
float_t nowDistPower[MAX_NUM_CABINT]; // 分配后下发的目标功率 kw OUT
uint16_t pcsSwitch[MAX_NUM_CABINT]; // PCS开关
} power_distr_t;
/*****************************************************************************
* @brief
*
* @return 0 -1 1
*****************************************************************************/
int logic_getPowerDistrParam();
// 功率分发接口
void logicFun_powerDistr();
#endif

View File

@ -1,293 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_protected.c
* @brief xxxx
* @author Gary
* @date 2024/09/21
* @remark
*****************************************************************************/
#include "logic_comm.h"
/*****************************************************************************
* @brief
* @return 0 -1
*****************************************************************************/
int logic_getProtectParam()
{
static protect_algorithm_t getProtectBuff = {0.0f, 0.0f, 0.0f, 0.0f, 0, 0.0f, 0.0f, 0.0f, 0, 0.0f, 0.0f};
static protect_params_t *tmpProtectBuff = &stlogic.para_delivery.task_params.protect;
if (0 != kit_get_protect_algorithm(&getProtectBuff))
{
// INLOG(Log_LOGIC_EN, ERROR_EN, "获取保护配置失败\n");
return 1;
}
// 防过载和功率限制
tmpProtectBuff->maxActivePower = getProtectBuff.transCapacity;
tmpProtectBuff->overFlowLowLimt = getProtectBuff.olWarnLimitVal;
tmpProtectBuff->overFlowCloseLimt = getProtectBuff.olShutdownVal;
tmpProtectBuff->maxPower = getProtectBuff.maxPower;
// 防需和防逆流
tmpProtectBuff->demandCtl = getProtectBuff.demandSwitch;
tmpProtectBuff->aimActiveDemand = getProtectBuff.targetDemand;
tmpProtectBuff->demandCtrlLowLimt = getProtectBuff.deWarnLimitVal;
tmpProtectBuff->demandCtrlCloseLimt = getProtectBuff.deShutdownVal;
tmpProtectBuff->backFlow = getProtectBuff.backflowSwitch;
tmpProtectBuff->backFlowLowLimt = getProtectBuff.bfWarnLimitVal;
tmpProtectBuff->backFlowCloseLimt = getProtectBuff.bfShutdownVal;
// soc 保护
tmpProtectBuff->socForbidCharge = getProtectBuff.socForbidChg;
tmpProtectBuff->socForbidDischarge = getProtectBuff.socForbidDischg;
return 0;
}
/*****************************************************************************
* @brief
* @param[inout] protect_params_t *charge_params
* @return
*****************************************************************************/
void logic_protect_overload(protect_params_t *charge_params)
{
float_t tmp_max_power = charge_params->maxActivePower - charge_params->overFlowCloseLimt; // 计算关机功率点
if (tmp_max_power >= charge_params->totalActivePower) // 关机判断
{
float_t load_active_power = charge_params->totalActivePower - charge_params->emsActivePower; // 算出负载功率
tmp_max_power = charge_params->maxActivePower - charge_params->overFlowLowLimt;
if (tmp_max_power >= charge_params->totalActivePower) // 限流判断
{
float_t tmp_power = tmp_max_power - load_active_power - charge_params->overFlowLowLimt / 10;
if (tmp_power > 0)
{
charge_params->power = -float_min(abs(charge_params->power), tmp_power);
}
else
{
charge_params->power = 0;
}
if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
{
KITLOG(LOG_MODBUS_EN, INFO_EN, "触发过载保护!!! 并网点功率:%.2f kw 新的目标功率:%.2f kw", charge_params->totalActivePower, charge_params->power);
KITPTF(LOG_MODBUS_EN, INFO_EN, "触发过载保护!!! 并网点功率:%.2f kw 新的目标功率:%.2f kw", charge_params->totalActivePower, charge_params->power);
}
}
else
{
float_t tmp_power = tmp_max_power - load_active_power - charge_params->overFlowLowLimt / 2;
if (tmp_power > 0)
{
charge_params->power = -float_min(abs(charge_params->power), tmp_power);
}
else
{
charge_params->power = 0;
}
}
}
else
{
charge_params->power = 0;
if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
{
KITLOG(LOG_MODBUS_EN, INFO_EN, "触发过载保护!!! 并网点功率:%.2f kw 新的目标功率:%.2f kw", charge_params->totalActivePower, charge_params->power);
KITPTF(LOG_MODBUS_EN, INFO_EN, "触发过载保护!!! 并网点功率:%.2f kw 新的目标功率:%.2f kw", charge_params->totalActivePower, charge_params->power);
}
}
}
/*****************************************************************************
* @brief
* @param[in] protect_backflow_t backflowParams
* @return
*****************************************************************************/
void logic_protect_backflow(protect_params_t *charge_params)
{
float_t load_active_power = charge_params->totalActivePower - charge_params->emsActivePower; // 算出负载功率
if (charge_params->totalActivePower > charge_params->backFlowCloseLimt) // 关机判断
{
if (load_active_power > charge_params->backFlowLowLimt) // 限流判断
{
float_t tmp_power = load_active_power - charge_params->backFlowLowLimt * 1.10;
if (tmp_power > 0)
{
charge_params->power = float_min(charge_params->power, tmp_power);
}
else
{
charge_params->power = 0;
}
if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
{
KITLOG(LOG_MODBUS_EN, INFO_EN, "触发逆流保护!!! 并网点功率:%.2f kw 新的目标功率:%.2f kw", charge_params->totalActivePower, charge_params->power);
KITPTF(LOG_MODBUS_EN, INFO_EN, "触发逆流保护!!! 并网点功率:%.2f kw 新的目标功率:%.2f kw", charge_params->totalActivePower, charge_params->power);
}
}
else
{
float_t tmp_power = load_active_power - charge_params->backFlowLowLimt * 1.50;
if (tmp_power > 0)
{
charge_params->power = float_min(charge_params->power, tmp_power);
}
else
{
charge_params->power = 0;
}
}
}
else
{
charge_params->power = 0;
if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
{
KITLOG(LOG_MODBUS_EN, INFO_EN, "触发逆流关机!!! 并网点功率:%.2f kw 新的目标功率:%.2f kw", charge_params->totalActivePower, charge_params->power);
KITPTF(LOG_MODBUS_EN, INFO_EN, "触发逆流关机!!! 并网点功率:%.2f kw 新的目标功率:%.2f kw", charge_params->totalActivePower, charge_params->power);
}
}
}
/*****************************************************************************
* @brief
* @param[in] protect_backflow_t backflowParams
* @return
*****************************************************************************/
void logic_protect_maxPower(protect_params_t *charge_params)
{
if (charge_params->power < 0) // 充电
{
charge_params->power = -float_min(abs(charge_params->power), abs(charge_params->maxPower));
}
else if (charge_params->power > 0) // 放电
{
charge_params->power = float_min(charge_params->power, abs(charge_params->maxPower));
}
}
/*****************************************************************************
* @brief
* @return -1 0
*****************************************************************************/
int logicFun_protect()
{
protect_params_t *charge_params = &stlogic.para_delivery.task_params.protect;
if (charge_params->scramButton)
{
charge_params->power = 0;
return 0;
}
switch (stlogic.para_delivery.mode)
{
case E_TACTIC_MODE_DEBUG: // 调试模式
charge_params->power = stlogic.para_delivery.task_params.debug.activePower;
charge_params->rePower = stlogic.para_delivery.task_params.debug.reactivePower;
break;
case E_TACTIC_MODE_PEAKVALLY: // 削峰填谷模式
charge_params->power = stlogic.para_delivery.task_params.pkvly.power;
break;
case E_TACTIC_MODE_DEMANDRES: // 需求响应模式
/* 暂未实现 */
charge_params->power = stlogic.para_delivery.task_params.demand.power;
break;
case E_TACTIC_MODE_LOADTRACK: // 负载跟踪模式
/* 暂未实现 */
charge_params->power = stlogic.para_delivery.task_params.loadTrack.power;
break;
default:
/*未知模式*/
stlogic.para_delivery.task_params.distr.power = 0;
stlogic.para_delivery.task_params.protect.power = 0;
break;
}
// 统计总SOC
int bmsOlineNum = 0;
stlogic.para_delivery.task_params.distr.sumSoc = 0; // 参数清零
if (charge_params->power < 0) // 充电
{
stlogic.para_delivery.task_params.distr.stationBmsSoc = 0;
for (int loop = 0; loop < stlogic.para_delivery.task_params.distr.cabintCont; loop++)
{
if (!float_equal(stlogic.para_delivery.task_params.distr.pcsMaxChaPower[loop], 0) &&
stlogic.para_delivery.task_params.distr.pcsState[loop] != 0 && stlogic.para_delivery.task_params.distr.bmsState[loop] != 0)
{
stlogic.para_delivery.task_params.distr.sumSoc += (SOCMAX - stlogic.para_delivery.task_params.distr.bmsSoc[loop]);
bmsOlineNum++;
}
}
if (bmsOlineNum)
{
stlogic.para_delivery.task_params.distr.stationBmsSoc = (((SOCMAX * bmsOlineNum) - stlogic.para_delivery.task_params.distr.sumSoc) / (SOCMAX * bmsOlineNum)) * 100.0;
}
else
{
stlogic.para_delivery.task_params.distr.stationBmsSoc = 0.0;
}
}
else if (charge_params->power > 0) // 放电
{
stlogic.para_delivery.task_params.distr.stationBmsSoc = 0;
for (int loop = 0; loop < stlogic.para_delivery.task_params.distr.cabintCont; loop++)
{
if (!float_equal(stlogic.para_delivery.task_params.distr.pcsMaxDiscPower[loop], 0) &&
stlogic.para_delivery.task_params.distr.pcsState[loop] != 0 && stlogic.para_delivery.task_params.distr.bmsState[loop] != 0)
{
stlogic.para_delivery.task_params.distr.sumSoc += stlogic.para_delivery.task_params.distr.bmsSoc[loop];
bmsOlineNum++;
}
}
if (bmsOlineNum)
{
stlogic.para_delivery.task_params.distr.stationBmsSoc = (stlogic.para_delivery.task_params.distr.sumSoc / (SOCMAX * bmsOlineNum)) * 100.0;
}
else
{
stlogic.para_delivery.task_params.distr.stationBmsSoc = 0.0;
}
}
if (E_TACTIC_MODE_DEBUG == stlogic.para_delivery.mode && stlogic.para_delivery.task_params.debug.protectSwitch)
{
charge_params = NULL;
return 0; // 调试模式保护跳过
}
if (charge_params->power < 0) // 充电
{
if (stlogic.para_delivery.task_params.distr.stationBmsSoc >= charge_params->socForbidCharge)
{
// 到达禁充SOC
charge_params->power = 0;
return 0;
}
logic_protect_overload(charge_params); // 防过载
if (charge_params->demandCtl)
{
logic_protect_demandCtrl(charge_params); // 需量控制
}
}
else if (charge_params->power > 0) // 放电
{
if (stlogic.para_delivery.task_params.distr.stationBmsSoc <= charge_params->socForbidDischarge)
{
// 到达禁放SOC
charge_params->power = 0;
return 0;
}
if (charge_params->backFlow)
{
logic_protect_backflow(charge_params); // 防逆流
}
}
else // 待机
{
// 待机目前考虑不用保护
}
logic_protect_maxPower(charge_params); // 限制功率
charge_params = NULL;
return 0; // 处理结束
}

View File

@ -1,54 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_protected.h
* @brief xxxx
* @author Gary
* @date 2024/09/21
* @remark
*****************************************************************************/
#ifndef __LOGIC_PROTECTED_H__
#define __LOGIC_PROTECTED_H__
typedef struct
{
// 中间参数
float_t power; // 目标功率 INOUT
float_t rePower; // 目标无功功率 INOUT
float_t nowActiveDemand; // 实时需量
int runPeriod; // 运行周期 ms
uint8_t protectSign; // 保护配置更新标志
// 读实时库
float_t totalActivePower; // 变压器下总电表总有功功率 IN
float_t emsActivePower; // 储能测总有功功率 IN
// 可配置参数
float_t maxActivePower; // 变压器总容量 IN
float_t overFlowLowLimt; // 过载预警限流值 IN
float_t overFlowCloseLimt; // 过载关机值 IN
float_t maxPower; // 充放电功率上限(一律为正值)
bool demandCtl; // 防需量开关 IN
float_t aimActiveDemand; // 目标需量 IN
float_t demandCtrlLowLimt; // 防需预警限流值 IN
float_t demandCtrlCloseLimt; // 防需关机值 IN
bool backFlow; // 防逆流开关 IN
float_t backFlowLowLimt; // 逆流预警限流值 IN
float_t backFlowCloseLimt; // 逆流关机值 IN
uint16_t socForbidCharge; // 禁充SOC [55%-100%]
uint16_t socForbidDischarge; // 禁放SOC [0%-45%]
// DIDO接口
uint16_t scramButton; // 急停开关1打开
} protect_params_t; // 保护函数传参结构体
/*****************************************************************************
* @brief
* @param[in] bool sign
* @return 0 -1
*****************************************************************************/
int logicFun_peakValley();
// 策略数据计算及保护接口
int logicFun_protect();
#endif

View File

@ -1,398 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_task_schedu.c
* @brief xxxx
* @author Gary
* @date 2024/09/28
* @remark
*****************************************************************************/
#include <pthread.h>
#include "logic_comm.h"
// 各模块任务函数注册
// static task_funcPoint_t g_taskUnitSet;
// 设置任务的固定参数和初始参数
// static task_params_t g_defaultParams;
// 序号设备号点位ID
ParamFromRTDB RTDBtable[e_Logic_RTDB_end] =
{
{e_Logic_totalAcPower, kDev_Type_Pccmeter, kPCC_TotalActivePwr },
{e_Logic_emsActivePower, kDev_Type_Bsmeter, kBs_TotalActivePwr },
{e_Logic_bmsSoc, kDev_Type_BCU, kBcu_SOC },
{e_Logic_pcsMaxChaPower, kDev_Type_PCS, kPcs_MaxAllowedChgPwr },
{e_Logic_pcsMaxDiscPower, kDev_Type_PCS, kPcs_MaxAllowedDisChgPwr },
{e_Logic_nowBmsPower, kDev_Type_PCS, kPcs_TotalActivePwr },
{e_Logic_nowActiveDemand, kDev_Type_Pccmeter, kPCC_MaxDemandActiveFwd },
{e_Logic_distrPower, kDev_Type_PCS, kPcs_ConstantActivePwrSet },
{e_Logic_pcsSwitch, kDev_Type_PCS, kPcs_DeviceSwitchCommand },
{e_Logic_pcsState, kDev_Type_PCS, kPcs_IsOnline },
{e_Logic_bmsState, kDev_Type_BCU, kBcu_IsOnline },
{e_Logic_emsMode, kDev_Type_EMS, kEms_LogicMode },
{e_Logic_bsuMaxCellTemp, kDev_Type_BSU, kBsu_MaxCellTemp },
{e_Logic_bsuMinCellTemp, kDev_Type_BSU, kBsu_MinCellTemp }
// {e_Logic_AcLiquidSwitch, kDev_Type_AirCond_LiquidCool, kAcLiquidMac_SetOnOff },
// {e_Logic_AcLiquidHeatTemp, kDev_Type_AirCond_LiquidCool, kAcLiquidMac_SetHeatTemp },
// {e_Logic_AcLiquidColdTemp, kDev_Type_AirCond_LiquidCool, kAcLiquidMac_SetCoolDiff }
};
/*****************************************************************************
* @brief RTDB参数
* @param[in]
* @return
*****************************************************************************/
void logic_getValue(int No, void *value, data_type_e dataType)
{
if (No < 0 || No >= e_Logic_RTDB_end)
{
// 输入的 No 无效
return;
}
// 从表格中获取对应的条目
ParamFromRTDB entry = RTDBtable[No];
switch (dataType)
{
case Uint8:
{
// 对于 uint8_t 类型
uint8_t *uint8Value = (uint8_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
uint8Value[i] = (uint8_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Int8:
{
// 对于 int8_t 类型
int8_t *int8Value = (int8_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
int8Value[i] = (int8_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Uint16:
{
// 对于 uint16_t 类型
uint16_t *uint16Value = (uint16_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
uint16Value[i] = (uint16_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Int16:
{
// 对于 int16_t 类型
int16_t *int16Value = (int16_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
int16Value[i] = (int16_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Uint32:
{
// 对于 uint32_t 类型
uint32_t *uint32Value = (uint32_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
uint32Value[i] = (uint32_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Int32:
{
// 对于 int32_t 类型
int32_t *int32Value = (int32_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
int32Value[i] = (int32_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Uint64:
{
// 对于 uint64_t 类型
uint64_t *uint64Value = (uint64_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
uint64Value[i] = (uint64_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Int64:
{
// 对于 int64_t 类型
int64_t *int64Value = (int64_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
int64Value[i] = (int64_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Float32:
{
// 对于 float_t (Float32) 类型
float_t *floatValue = (float_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
floatValue[i] = (float_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Float64:
{
// 对于 double (Float64) 类型
double *doubleValue = (double *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
doubleValue[i] = getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
default:
// 不支持的类型
return;
}
return;
}
/*****************************************************************************
* @brief
* @param[in] No RTDBtable
* @param[in] value
* @param[in] num
* @return
*****************************************************************************/
void logic_skip_judge(bool *skip, uint16_t num, int No, void *value, data_type_e dataType)
{
ParamFromRTDB entry = RTDBtable[No];
for (uint16_t i = 0; i < num; i++)
{
// skip[i] = false; // 默认不跳过
if(stlogic.para_delivery.task_params.distr.allocateMode)
{
float_t *floatValue = (float_t *)value;
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_APhaseAPSet, (float_t)floatValue[i]/3);
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_BPhaseAPSet, (float_t)floatValue[i]/3);
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_CPhaseAPSet, (float_t)floatValue[i]/3);
skip[i] = true; // 标记跳过
continue;
}
// 根据 No 值进行不同的处理
switch (No)
{
case e_Logic_pcsSwitch: // PCS开关
// 判断 pcsState 和 bmsState
if (stlogic.para_delivery.task_params.distr.pcsState[i] == 0 ||
stlogic.para_delivery.task_params.distr.bmsState[i] == 0)
{
skip[i] = true; // 标记跳过
}
else
{
// _PCS 特殊处理
#ifdef _PCS
// if (dataType == Uint16 && value != NULL)
// {
uint16_t *uint16Value = (uint16_t *)value;
if (uint16Value[i])
{
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_DeviceStartup, 1.0);
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_DeviceShutdown, 0.0);
}
else
{
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_DeviceStartup, 0.0);
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_DeviceShutdown, 1.0);
}
// }
skip[i] = true; // 标记跳过
#endif
}
break;
case e_Logic_distrPower: // distrPower 为 No 的处理逻辑
// 判断 pcsState 和 bmsState
if (stlogic.para_delivery.task_params.distr.pcsState[i] == 0 ||
stlogic.para_delivery.task_params.distr.bmsState[i] == 0)
{
// 分配电力为 No 且满足保护条件时跳过
if (E_TACTIC_MODE_DEBUG != stlogic.para_delivery.mode ||
!stlogic.para_delivery.task_params.debug.protectSwitch)
{
skip[i] = true; // 标记跳过
}
}
break;
default:
// 如果 No 不符合任何已定义的条件,默认不跳过
break;
}
}
}
/*****************************************************************************
* @brief RTDB参数
* @param[in] No RTDBtable
* @param[in] value
* @param[in] num
* @param[in] dataType Uint8Int16
* @return
*****************************************************************************/
void logic_setValue(int No, void *value, uint16_t num, data_type_e dataType)
{
if (No < 0 || No >= e_Logic_RTDB_end)
{
// 输入的 No 无效
return;
}
// 从表格中获取对应的条目
ParamFromRTDB entry = RTDBtable[No];
bool skip[MAX_NUM_CABINT] = {false};
// 调用跳过判断逻辑
logic_skip_judge(skip, num, No, value, dataType);
for (uint16_t i = 0; i < num; i++)
{
if (skip[i])
continue;
switch (dataType)
{
case Uint8:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((uint8_t*)value)[i]);
break;
case Int8:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((int8_t*)value)[i]);
break;
case Uint16:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((uint16_t*)value)[i]);
break;
case Int16:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((int16_t*)value)[i]);
break;
case Uint32:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((uint32_t*)value)[i]);
break;
case Int32:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((int32_t*)value)[i]);
break;
case Uint64:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((uint64_t*)value)[i]);
break;
case Int64:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((int64_t*)value)[i]);
break;
case Float32:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((float*)value)[i]);
break;
case Float64:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, ((double*)value)[i]);
break;
default:
// 不支持的类型,返回
return;
}
}
return;
}
/*****************************************************************************
* @brief
*
* @return 0 -1 1
*****************************************************************************/
void logic_getRTDBParams()
{
/*获取电表的数据*/
logic_getValue(e_Logic_totalAcPower, &stlogic.para_delivery.task_params.protect.totalActivePower, Float32);
logic_getValue(e_Logic_emsActivePower, &stlogic.para_delivery.task_params.protect.emsActivePower, Float32);
logic_getValue(e_Logic_nowActiveDemand, &stlogic.para_delivery.task_params.protect.nowActiveDemand, Float32);
/*获取pcs的数据*/
logic_getValue(e_Logic_bmsSoc, &stlogic.para_delivery.task_params.distr.bmsSoc, Float32);
logic_getValue(e_Logic_pcsMaxChaPower, &stlogic.para_delivery.task_params.distr.pcsMaxChaPower, Float32);
logic_getValue(e_Logic_pcsMaxDiscPower, &stlogic.para_delivery.task_params.distr.pcsMaxDiscPower, Float32);
logic_getValue(e_Logic_nowBmsPower, &stlogic.para_delivery.task_params.distr.nowBmsPower, Float32);
logic_getValue(e_Logic_pcsState, &stlogic.para_delivery.task_params.distr.pcsState, Uint8);
logic_getValue(e_Logic_bmsState, &stlogic.para_delivery.task_params.distr.bmsState, Uint8);
}
/*********************************************************************
* @brief
* @param[in]
* @return
*********************************************************************/
int logic_paramUpload()
{
if (LOGIC_SIGN_UPLOAD == stlogic.para_delivery.task_params.protect.protectSign)
{
stlogic.para_delivery.task_params.protect.protectSign = LOGIC_SIGN_NONE;
writeWebSign(kSign_ShMem, kSign_Protect, LOGIC_SIGN_UPLOAD);
}
if (LOGIC_SIGN_UPLOAD == stlogic.para_delivery.task_params.distr.powerSign)
{
stlogic.para_delivery.task_params.distr.powerSign = LOGIC_SIGN_NONE;
writeWebSign(kSign_ShMem, kSign_ActivePower, LOGIC_SIGN_UPLOAD);
}
switch (stlogic.para_delivery.mode)
{
case E_TACTIC_MODE_DEBUG: // 调试模式
writeWebSign(kSign_ShMem, kSign_LogicDebug, LOGIC_SIGN_UPLOAD);
// PCS开关机下发
logic_setValue(e_Logic_pcsSwitch, &stlogic.para_delivery.task_params.distr.pcsSwitch, stlogic.para_delivery.task_params.distr.cabintCont, Uint16);
// 功率下发
logic_setValue(e_Logic_distrPower, &stlogic.para_delivery.task_params.distr.nowDistPower, stlogic.para_delivery.task_params.distr.cabintCont, Float32);
break;
case E_TACTIC_MODE_PEAKVALLY: // 削峰填谷模式
writeWebSign(kSign_ShMem, kSign_LogicPeakValley, LOGIC_SIGN_UPLOAD);
// PCS开关机下发
logic_setValue(e_Logic_pcsSwitch, &stlogic.para_delivery.task_params.distr.pcsSwitch, stlogic.para_delivery.task_params.distr.cabintCont, Uint16);
// 功率下发
logic_setValue(e_Logic_distrPower, &stlogic.para_delivery.task_params.distr.nowDistPower, stlogic.para_delivery.task_params.distr.cabintCont, Float32);
break;
case E_TACTIC_MODE_DEMANDRES: // 需求响应模式
/* 暂未实现 */
// 系统状态更新为停机
updateState(kState_Shutdown, true);
break;
case E_TACTIC_MODE_LOADTRACK: // 负载跟踪模式
/* 暂未实现 */
// 系统状态更新为停机
updateState(kState_Shutdown, true);
break;
case E_TACTIC_MODE_DMDCTRL: // 需量控制
/* 暂未实现 */
// 系统状态更新为停机
updateState(kState_Shutdown, true);
break;
case E_TACTIC_MODE_PFCTRL: // 功率因数
/* 暂未实现 */
// 系统状态更新为停机
updateState(kState_Shutdown, true);
break;
default:
// 系统状态更新为停机
updateState(kState_Shutdown, true);
break;
}
// 运行模式入RTDB
logic_setValue(e_Logic_emsMode, &stlogic.para_delivery.mode, 1, Uint16);
return 0;
}

View File

@ -1,723 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_tempCtrl.c
* @brief xxxx
* @author Gary
* @date 2024/11/26
* @remark
*****************************************************************************/
#include "logic_tempCtrl.h"
temp_judge_mod_e logicTempState[MAX_NUM_CABINT] = {0};
logic_pthread_t stTemp = {0};
logicTempEquip tempEquipCall[kTemperature_ctrl_end] =
{
Logic_Temp_Select_AC,
Logic_Temp_Select_LC,
Logic_Temp_Select_AC_Auto,
Logic_Temp_Select_LC_Auto
};
logicTempExe tempFunCall[kTemperature_ctrl_end][kTemp_Judge_end] = {
// kTemperature_ctrl_Ac
{
kAC_Normal_Callback,
kAC_OverTemp_Callback,
kAC_OverLock_Callback,
kAC_UnderTemp_Callback,
kAC_UnderLock_Callback,
kAC_Close_Callback
},
// kTemperature_ctrl_Lc
{
kLC_Normal_Callback,
kLC_OverTemp_Callback,
kLC_OverLock_Callback,
kLC_UnderTemp_Callback,
kLC_UnderLock_Callback,
kLC_Close_Callback
},
// kTemperature_auto_Ac
{
kAC_Auto_Callback,
},
// kTemperature_auto_Lc
{
kLC_Auto_Callback,
}
};
/*****************************************************************************
* @brief
* @return None
*****************************************************************************/
static void Logic_Temp_initParam(temp_ctrl_algorithm_t* sqlPara,temp_params_t *para)
{
for (u_int16_t i = 0; i < MAX_NUM_CABINT; i++)
{
logicTempState[i] = kTemp_Judge_Normal;
}
para->mod = sqlPara->mod;
para->workTemp.coolTrigTemp = sqlPara->workCoolTrigTemp;
para->workTemp.coolHys = sqlPara->workCoolHys;
para->workTemp.heatTrigTemp = sqlPara->workHeatTrigTemp;
para->workTemp.heatHys = sqlPara->workHeatHys;
para->standByTemp.coolTrigTemp = sqlPara->standbyCoolTrigTemp;
para->standByTemp.coolHys = sqlPara->standbyCoolHys;
para->standByTemp.heatTrigTemp = sqlPara->standbyHeatTrigTemp;
para->standByTemp.heatHys = sqlPara->standbyHeatHys;
para->standByLimit.maxlimit = sqlPara->standbyMaxLimit;
para->standByLimit.minlimit = sqlPara->standbyMinLimit;
para->standByLimit.maxbacklimit = sqlPara->standbyMaxbackLimit;
para->standByLimit.minbacklimit = sqlPara->standbyMinbackLimit;
para->tempCmd_normal = sqlPara->tempCmdNormal;
para->tempCmd_heat = sqlPara->tempCmdHeat;
para->tempCmd_cold = sqlPara->tempCmdCold;
para->tempCmdOpen = sqlPara->tempCmdOpen;
para->tempCmdClose = sqlPara->tempCmdClose;
}
/*****************************************************************************
* @brief
* @param[in] para
* @return None
*****************************************************************************/
void Logic_Temp_Collect(temp_params_t *para)
{
logic_getValue(e_Logic_nowBmsPower, para->pcsPower, Float32);
logic_getValue(e_Logic_bsuMaxCellTemp, para->maxCellTemp, Float32);
logic_getValue(e_Logic_bsuMinCellTemp, para->minCellTemp, Float32);
// para->pcsPower[0] = 6;
// printf("请输入最大单元温度: ");
// scanf("%f", &para->maxCellTemp[0]); // 输入最大单元温度
// printf("请输入最小单元温度: ");
// scanf("%f", &para->minCellTemp[0]); // 输入最小单元温度
// para->maxCellTemp[0] = 41;
// para->minCellTemp[0] = 25;
}
/*****************************************************************************
* @brief
* @return None
*****************************************************************************/
static void Logic_Temp_initEquip(temp_params_t *para)
{
// 创建一个临时副本,防止修改影响原始数据
temp_params_t temppara = *para; // 进行浅拷贝,副本和原始数据不同
Logic_Temp_Collect(&temppara); // 使用副本进行操作
for (u_int16_t i = 0; i < gStDevTypeNum[kDev_Type_AirCond_LiquidCool]; i++)
{
switch (temppara.mod)
{
default:
break;
case kTemperature_ctrl_Ac:
// 判断是否需要开机
// if (para->maxCellTemp[i] - temppara.workTemp.coolTrigTemp > EPSILON
// || temppara.workTemp.heatTrigTemp - para->minCellTemp[i] < EPSILON)
// {
// setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetOnOff, temppara.tempCmdOpen);
// }
if (temppara.tempCmdClose == getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetOnOff))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetOnOff, temppara.tempCmdOpen);
}
break;
case kTemperature_ctrl_Lc:
if (para->maxCellTemp[i] - temppara.standByLimit.maxlimit > EPSILON
|| temppara.standByLimit.minlimit - para->minCellTemp[i] < EPSILON)
{
kLC_Normal_Callback((void *)&temppara , (void *)&i);
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_RunTemp, TEMP_AC_TEMP);
}
break;
case kTemperature_auto_Ac:
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetOnOff, temppara.tempCmdOpen);
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetCoolTemp, temppara.workTemp.coolTrigTemp);
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetHeatTemp, temppara.workTemp.heatTrigTemp);
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetCoolDiff, temppara.workTemp.coolHys);
// setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetHeatDiff, temppara.workTemp.heatHys);
break;
case kTemperature_auto_Lc:
break;
}
}
}
/*****************************************************************************
* @brief
* @param[in] para
* @param[in] No
* @return
*
* @note
*
*****************************************************************************/
void Logic_Temp_Select_LC(temp_params_t *para, u_int16_t No)
{
// 检查参数编号是否合法
if (No >= MAX_NUM_CABINT)
{
return;
}
temp_limit_t temp_limit;
// 错误数据
if (fabs(para->maxCellTemp[No]) > 255.0f || fabs(para->minCellTemp[No]) > 255.0f)
{
logicTempState[No] = kTemp_Judge_Close;
return;
}
// 没有电池温度,关机
if (para->maxCellTemp[No] < EPSILON && para->minCellTemp[No] < EPSILON)
{
logicTempState[No] = kTemp_Judge_Close;
return;
}
// 根据当前功率判断使用待机温度或工作温度
if (abs(para->pcsPower[No]) < TEMP_WORKPOWER)
{
temp_limit = para->standByTemp; // 使用待机温度
}
else
{
temp_limit = para->workTemp; // 使用工作温度
}
// 判断是否需要触发制冷或制热
if (para->maxCellTemp[No] - temp_limit.coolTrigTemp > -EPSILON)
{
// 过温状态
logicTempState[No] = kTemp_Judge_OverTemp;
return;
}
else if (temp_limit.heatTrigTemp - para->minCellTemp[No] > -EPSILON)
{
// 欠温状态
logicTempState[No] = kTemp_Judge_UnderTemp;
return;
}
// 根据当前温度状态进行判断和状态转换
switch (logicTempState[No])
{
// 过温判断
case kTemp_Judge_OverTemp:
case kTemp_Judge_OverLock:
if (temp_limit.coolTrigTemp - temp_limit.coolHys - para->maxCellTemp[No] > -EPSILON)
{
// 恢复正常状态
logicTempState[No] = kTemp_Judge_Normal;
}
else
{
// 保持过温锁定状态
logicTempState[No] = kTemp_Judge_OverLock;
}
break;
// 欠温判断
case kTemp_Judge_UnderTemp:
case kTemp_Judge_UnderLock:
if (temp_limit.heatTrigTemp + temp_limit.heatHys - para->minCellTemp[No] < EPSILON)
{
// 恢复正常状态
logicTempState[No] = kTemp_Judge_Normal;
}
else
{
// 保持欠温锁定状态
logicTempState[No] = kTemp_Judge_UnderLock;
}
break;
// 正常循环状态
case kTemp_Judge_Normal:
if (abs(para->pcsPower[No]) < TEMP_WORKPOWER)
{
// 检查是否符合待机关闭条件
if (para->maxCellTemp[No] - (para->standByLimit.maxlimit - para->standByLimit.maxbacklimit) <= EPSILON
&& para->standByLimit.minlimit + para->standByLimit.minbacklimit - para->minCellTemp[No] <= EPSILON)
{
logicTempState[No] = kTemp_Judge_Close; // 进入关闭状态
}
}
break;
// 关机状态
case kTemp_Judge_Close:
if (abs(para->pcsPower[No]) < TEMP_WORKPOWER)
{
// 检查是否符合恢复正常条件
if (para->maxCellTemp[No] - para->standByLimit.maxlimit > -EPSILON
|| para->standByLimit.minlimit - para->minCellTemp[No] > -EPSILON)
{
logicTempState[No] = kTemp_Judge_Normal; // 恢复正常状态
}
}
break;
// 其他状态,保持原有状态
default:
break;
}
}
/*****************************************************************************
* @brief
* @param[in] para
* @param[in] No
* @return
*
* @note
*
*****************************************************************************/
void Logic_Temp_Select_AC(temp_params_t *para, u_int16_t No)
{
// 检查参数编号是否合法
if (No >= MAX_NUM_CABINT)
{
return;
}
temp_limit_t temp_limit;
temp_limit = para->workTemp; // 使用工作温度
// 错误数据
if (fabs(para->maxCellTemp[No]) > 255.0f || fabs(para->minCellTemp[No]) > 255.0f)
{
logicTempState[No] = kTemp_Judge_Close;
return;
}
// 没有电池温度,关机
if (para->maxCellTemp[No] < EPSILON && para->minCellTemp[No] < EPSILON)
{
logicTempState[No] = kTemp_Judge_Close;
return;
}
// 判断是否需要触发制冷或制热
if (para->maxCellTemp[No] - temp_limit.coolTrigTemp > EPSILON)
{
// 过温状态
logicTempState[No] = kTemp_Judge_OverTemp;
return;
}
else if (temp_limit.heatTrigTemp - para->minCellTemp[No] > EPSILON)
{
// 欠温状态
logicTempState[No] = kTemp_Judge_UnderTemp;
return;
}
// 根据当前温度状态进行判断和状态转换
switch (logicTempState[No])
{
// 过温判断
case kTemp_Judge_OverTemp:
case kTemp_Judge_OverLock:
if (temp_limit.coolTrigTemp - temp_limit.coolHys - para->maxCellTemp[No] > EPSILON)
{
// 恢复正常状态
logicTempState[No] = kTemp_Judge_Normal;
}
else
{
// 保持过温锁定状态
logicTempState[No] = kTemp_Judge_OverLock;
}
break;
// 欠温判断
case kTemp_Judge_UnderTemp:
case kTemp_Judge_UnderLock:
if (temp_limit.heatTrigTemp + temp_limit.heatHys - para->minCellTemp[No] < EPSILON)
{
// 恢复正常状态
logicTempState[No] = kTemp_Judge_Normal;
}
else
{
// 保持欠温锁定状态
logicTempState[No] = kTemp_Judge_UnderLock;
}
break;
// 其他状态,保持原有状态
default:
break;
}
}
void Logic_Temp_Select_AC_Auto(temp_params_t *para, u_int16_t No)
{
;
}
void Logic_Temp_Select_LC_Auto(temp_params_t *para, u_int16_t No)
{
;
}
/*****************************************************************************
* @brief 线
* @param[in]
* @return
*****************************************************************************/
void *creatLogicTempThread(void *arg)
{
temp_params_t *temp_params_in = (temp_params_t *)arg;
while (stTemp.exitTaskFlag == 0)
{
// 读取更新信号
// if(1 == readWebSign(kSign_ShMem, kSign_TempCtrl))
// {
// writeWebSign(kSign_ShMem, kSign_TempCtrl, 0);
// temp_ctrl_algorithm_t temp_infoFromDB;
// int ret = kit_get_temp_ctrl_algorithm(&temp_infoFromDB);
// if (ret != 0) // 判断是否成功
// {
// KITLOG(LOG_KIT_EN, ERROR_EN, "读取温控配置失败");
// stTemp.exitTaskFlag = 1;
// continue;
// }
// Logic_Temp_initParam(&temp_infoFromDB, temp_params_in);
// }
Logic_Temp_Collect(temp_params_in);
for(u_int16_t i = 0;i < gStDevTypeNum[kDev_Type_AirCond_LiquidCool]; i++)
{
tempEquipCall[temp_params_in->mod](temp_params_in, i);
tempFunCall[temp_params_in->mod][logicTempState[i]](temp_params_in, &i);
}
usleep(1000000); // 1s sleep
}
free(temp_params_in); // 线程结束后释放内存
pthread_exit(NULL);
}
/*********************************************************************
* @brief
* @param[in]
* @return 0sucessful1fault
*********************************************************************/
int creatLogicTempCtrlEntry()
{
if(0 == gStDevTypeNum[kDev_Type_AirCond_LiquidCool])
{
return 1;
}
temp_ctrl_algorithm_t temp_infoFromDB;
temp_params_t *tempPara = (temp_params_t *)malloc(sizeof(temp_params_t));
if (tempPara == NULL) // 检查内存分配是否成功
{
KITLOG(LOG_KIT_EN, ERROR_EN, "内存分配失败");
return 1;
}
int ret = kit_get_temp_ctrl_algorithm(&temp_infoFromDB);
if (ret != 0) // 判断是否成功
{
free(tempPara);
return 1;
}
Logic_Temp_initParam(&temp_infoFromDB, tempPara);
Logic_Temp_initEquip(tempPara);
if (pthread_create(&stTemp.tfd, NULL, creatLogicTempThread, (void *)tempPara) != 0)
{
KITPTF(LOG_LOGIC_EN, ERROR_EN, "temp线程创建失败");
KITLOG(LOG_LOGIC_EN, ERROR_EN, "temp线程创建失败");
free(tempPara);
return 1;
}
KITPTF(LOG_LOGIC_EN, INFO_EN, "temp线程创建成功");
KITLOG(LOG_LOGIC_EN, INFO_EN, "temp线程创建成功");
return 0;
}
/*****************************************************************************
* @brief
* @param[in] para
* @param[in] No
* @return None
*****************************************************************************/
void kLC_OverTemp_Callback(void *arg, void *no)
{
uint16_t i = *(uint16_t *)no;
temp_params_t *temp_params_in = (temp_params_t *)arg;
if (temp_params_in->tempCmdClose == getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_Switch))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_Switch, temp_params_in->tempCmdOpen);
}
if (temp_params_in->tempCmd_cold != getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_RunMode))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_RunMode, temp_params_in->tempCmd_cold);
}
}
/*****************************************************************************
* @brief
* @param[in] para
* @param[in] No
* @return None
*****************************************************************************/
void kLC_OverLock_Callback(void *arg, void *no)
{
uint16_t i = *(uint16_t *)no;
temp_params_t *temp_params_in = (temp_params_t *)arg;
if (temp_params_in->tempCmdClose == getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_Switch))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_Switch, temp_params_in->tempCmdOpen);
}
if (temp_params_in->tempCmd_cold != getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_RunMode))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_RunMode, temp_params_in->tempCmd_cold);
}
}
/*****************************************************************************
* @brief
* @param[in] para
* @param[in] No
* @return None
*****************************************************************************/
void kLC_Normal_Callback(void *arg, void *no)
{
uint16_t i = *(uint16_t *)no;
temp_params_t *temp_params_in = (temp_params_t *)arg;
if (temp_params_in->tempCmdClose == getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_Switch))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_Switch, temp_params_in->tempCmdOpen);
}
if (temp_params_in->tempCmd_normal != getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_RunMode))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_RunMode, temp_params_in->tempCmd_normal);
}
}
/*****************************************************************************
* @brief
* @param[in] para
* @param[in] No
* @return None
*****************************************************************************/
void kLC_UnderTemp_Callback(void *arg, void *no)
{
uint16_t i = *(uint16_t *)no;
temp_params_t *temp_params_in = (temp_params_t *)arg;
if (temp_params_in->tempCmdClose == getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_Switch))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_Switch, temp_params_in->tempCmdOpen);
}
if (temp_params_in->tempCmd_heat != getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_RunMode))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_RunMode, temp_params_in->tempCmd_heat);
}
}
/*****************************************************************************
* @brief
* @param[in] para
* @param[in] No
* @return None
*****************************************************************************/
void kLC_UnderLock_Callback(void *arg, void *no)
{
uint16_t i = *(uint16_t *)no;
temp_params_t *temp_params_in = (temp_params_t *)arg;
if (temp_params_in->tempCmdClose == getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_Switch))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_Switch, temp_params_in->tempCmdOpen);
}
if (temp_params_in->tempCmd_heat != getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_RunMode))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_RunMode, temp_params_in->tempCmd_heat);
}
}
/*****************************************************************************
* @brief
* @param[in] para
* @param[in] No
* @return None
*****************************************************************************/
void kLC_Close_Callback(void *arg, void *no)
{
uint16_t i = *(uint16_t *)no;
temp_params_t *temp_params_in = (temp_params_t *)arg;
if (temp_params_in->tempCmdOpen == getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_Switch))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_Switch, temp_params_in->tempCmdClose);
}
if (temp_params_in->tempCmd_normal != getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_RunMode))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_Lc_RunMode, temp_params_in->tempCmd_normal);
}
}
/*****************************************************************************
* @brief
* @param[in] para
* @param[in] No
* @return None
*****************************************************************************/
void kAC_OverTemp_Callback(void *arg, void *no)
{
uint16_t i = *(uint16_t *)no;
temp_params_t *temp_params_in = (temp_params_t *)arg;
if (temp_params_in->tempCmdClose == getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetOnOff))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetOnOff, temp_params_in->tempCmdOpen);
}
if (temp_params_in->tempCmd_cold != getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetCoolTemp))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetCoolTemp, TEMP_AC_TEMP);
}
}
/*****************************************************************************
* @brief
* @param[in] para
* @param[in] No
* @return None
*****************************************************************************/
void kAC_OverLock_Callback(void *arg, void *no)
{
uint16_t i = *(uint16_t *)no;
temp_params_t *temp_params_in = (temp_params_t *)arg;
if (temp_params_in->tempCmdClose == getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetOnOff))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetOnOff, temp_params_in->tempCmdOpen);
}
if (temp_params_in->tempCmd_cold != getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetCoolTemp))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetCoolTemp, TEMP_AC_TEMP);
}
}
/*****************************************************************************
* @brief
* @param[in] para
* @param[in] No
* @return None
*****************************************************************************/
void kAC_Normal_Callback(void *arg, void *no)
{
uint16_t i = *(uint16_t *)no;
temp_params_t *temp_params_in = (temp_params_t *)arg;
if (temp_params_in->tempCmdOpen == getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetOnOff))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetOnOff, temp_params_in->tempCmdClose);
}
}
/*****************************************************************************
* @brief
* @param[in] para
* @param[in] No
* @return None
*****************************************************************************/
void kAC_UnderTemp_Callback(void *arg, void *no)
{
uint16_t i = *(uint16_t *)no;
temp_params_t *temp_params_in = (temp_params_t *)arg;
if (temp_params_in->tempCmdClose == getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetOnOff))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetOnOff, temp_params_in->tempCmdOpen);
}
if (temp_params_in->tempCmd_heat != getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetHeatTemp))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetHeatTemp, temp_params_in->tempCmd_heat);
}
}
/*****************************************************************************
* @brief
* @param[in] para
* @param[in] No
* @return None
*****************************************************************************/
void kAC_UnderLock_Callback(void *arg, void *no)
{
uint16_t i = *(uint16_t *)no;
temp_params_t *temp_params_in = (temp_params_t *)arg;
if (temp_params_in->tempCmdClose == getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetOnOff))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetOnOff, temp_params_in->tempCmdOpen);
}
if (temp_params_in->tempCmd_heat != getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetHeatTemp))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetHeatTemp, temp_params_in->tempCmd_heat);
}
}
/*****************************************************************************
* @brief
* @param[in] para
* @param[in] No
* @return None
*****************************************************************************/
void kAC_Close_Callback(void *arg, void *no)
{
uint16_t i = *(uint16_t *)no;
temp_params_t *temp_params_in = (temp_params_t *)arg;
if (temp_params_in->tempCmdOpen == getRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetOnOff))
{
setRtdbPointValue(Rtdb_ShMem, kDev_Type_AirCond_LiquidCool, i, kAcLiquidMac_SetOnOff, temp_params_in->tempCmdClose);
}
}
/*****************************************************************************
* @brief
* @param[in] para
* @param[in] No
* @return None
*****************************************************************************/
void kAC_Auto_Callback(void *arg, void *no)
{
;
}
/*****************************************************************************
* @brief
* @param[in] para
* @param[in] No
* @return None
*****************************************************************************/
void kLC_Auto_Callback(void *arg, void *no)
{
;
}

View File

@ -1,106 +0,0 @@
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_tempCtrl.h
* @brief xxxx
* @author Gary
* @date 2024/09/21
* @remark
*****************************************************************************/
#ifndef __LOGIC_TEMPCTRL_H__
#define __LOGIC_TEMPCTRL_H__
#include "logic_comm.h"
#define TEMP_WORKPOWER 2
#define TEMP_AC_TEMP 25
// 温控模式
// typedef enum
// {
// kTemp_ctrl_Start, // 无
// kTemp_ctrl_Ac = kTemp_ctrl_Start, // 风冷模式
// kTemp_ctrl_Lc, // 液冷模式
// kTemp_ctrl_end
// } temp_ctrl_mod_e;
typedef enum
{
kTemp_Judge_Start, // 无
kTemp_Judge_Normal = kTemp_Judge_Start, // 正常温度(自循环)
kTemp_Judge_OverTemp, // 高温
kTemp_Judge_OverLock, // 高温自锁
kTemp_Judge_UnderTemp, // 低温
kTemp_Judge_UnderLock, // 低温自锁
kTemp_Judge_Close, // 关机
kTemp_Judge_end
} temp_judge_mod_e;
typedef struct
{
float_t coolTrigTemp; // 制冷触发温度
float_t coolHys; // 制冷回差
float_t heatTrigTemp; // 制热触发温度
float_t heatHys; // 制热回差
}temp_limit_t; // 温度控制参数
typedef struct
{
float_t maxlimit; //开启自循环高温
float_t minlimit; //开启自循环低温
float_t maxbacklimit; //自循环高温回温
float_t minbacklimit; //自循环低温回温
}temp_standby_limit_t; // 温度控制参数
typedef struct
{
/*用户可配参数*/
temperature_ctrl_mod_e mod;
temp_limit_t workTemp; // 工作温度
temp_limit_t standByTemp; // 静置温度(液冷)
temp_standby_limit_t standByLimit; // 静置自循环温度限制(液冷)
u_int16_t tempCmd_normal; //循环控制字
u_int16_t tempCmd_heat; //制热控制字
u_int16_t tempCmd_cold; //制冷控制字
uint8_t tempCmdOpen; // 开控制字
uint8_t tempCmdClose; // 关控制字
/*中间变量*/
float_t pcsPower[MAX_NUM_CABINT]; // kPcs_TotalActivePwr 总有功功率
float_t maxCellTemp[MAX_NUM_CABINT]; // kBsu_MaxCellTemp 单体最高温度
float_t minCellTemp[MAX_NUM_CABINT]; // kBsu_MinCellTemp 单体最低温度
} temp_params_t; // 温度控制参数
extern temp_judge_mod_e logicTempState[MAX_NUM_CABINT];
void Logic_Temp_Select_LC(temp_params_t *para, u_int16_t No);
void Logic_Temp_Select_AC(temp_params_t *para, u_int16_t No);
void Logic_Temp_Select_AC_Auto(temp_params_t *para, u_int16_t No);
void Logic_Temp_Select_LC_Auto(temp_params_t *para, u_int16_t No);
void kLC_OverTemp_Callback(void *arg, void *no);
void kLC_OverLock_Callback(void *arg, void *no);
void kLC_Normal_Callback(void *arg, void *no);
void kLC_UnderTemp_Callback(void *arg, void *no);
void kLC_UnderLock_Callback(void *arg, void *no);
void kLC_Close_Callback(void *arg, void *no);
void kAC_OverTemp_Callback(void *arg, void *no);
void kAC_OverLock_Callback(void *arg, void *no);
void kAC_Normal_Callback(void *arg, void *no);
void kAC_UnderTemp_Callback(void *arg, void *no);
void kAC_UnderLock_Callback(void *arg, void *no);
void kAC_Close_Callback(void *arg, void *no);
void kAC_Auto_Callback(void *arg, void *no);
void kLC_Auto_Callback(void *arg, void *no);
typedef void (*logicTempEquip)(temp_params_t *para, u_int16_t No);
typedef void (*logicTempExe)(void * , void *);
#endif

View File

@ -28,7 +28,7 @@
#include "kit_db.h"
#include "kit_log.h"
#include "utextend.h"
#include "logic_power_distr.h"
#include "mw_schedule_handle.h"
#include "drv_4g.h"
#include "drv_wifi.h"

View File

@ -9,6 +9,7 @@
#ifndef MW_SCHEDULE_HANDLE
#define MW_SCHEDULE_HANDLE
#define MAX_NUM_CABINT 3
/*****************************************************************************
* @brief
* @return void