You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

823 lines
21 KiB
C

/*****************************************************************************
* file lib/process/pd_main.c
* author YuLiang
* version 1.0.0
* date 07-Feb-2023
* brief This file provides all the partial discharge related operation functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef CFG_DEV_TYPE_LAND_PD
/* 标准C库头文件. */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "pd_cpld.h"
#include "pd_dau.h"
#include "pd_csg.h"
#include "pd_main.h"
#include "pd_storage.h"
#include "pd_dbg.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
pd_data_t pd_data;
pd_config_t pd_config;
pd_state_t pd_state;
cmd_node_t pd_port_node =
{
PORT_NODE,
CONFIG_NODE,
1,
NULL,
};
/* DAU 端口类型分类. */
static const char *pd_sen_type_str[PD_SEN_TYPE_COUNT] =
{
"",
"sig",
"noise",
"sig-noise"
};
/* Private function prototypes -----------------------------------------------*/
extern int32_t _pd_port_str_to_unit_port(const char *port_str, uint8_t *unit, uint8_t *port);
/* Internal functions --------------------------------------------------------*/
/* 进入 DAU 端口模式. */
CMD(pd_port_terminal,
pd_port_terminal_cmd,
"interface port WORD",
"Interface\n"
"Port\n"
"Port id: Ex: 1/1\n")
{
return CMD_SUCCESS;
uint8_t unit = 0;
uint8_t port = 0;
int32_t vport = 0;
/* 取出端口号. */
if (_pd_port_str_to_unit_port(argv[0], &unit, &port) != E_NONE)
{
return CMD_ERR_NO_MATCH;
}
/* 计算虚拟端口. */
vport = dau_port_to_vport(unit, port);
if (vport <= 0)
{
return CMD_ERR_NO_MATCH;
}
pd_port_node.param_num = vport;
snprintf(pd_port_node.prompt, PD_PORT_PROMPT_LEN, "%%s(interface port %d/%d)# ", unit + 1, port + 1);
vty->node = PORT_NODE;
return CMD_SUCCESS;
}
/* 配置端口类型. */
CMD(pd_sensor_type,
pd_sensor_type_cmd,
"sensor-type (sig|noise|sig-noise)",
"Sensor type\n"
"Signal\n"
"Noise\n"
"Signal associate noise\n")
{
return CMD_SUCCESS;
uint8_t sen_type = 0;
uint8_t unit = 0;
uint8_t port = 0;
/* 取出端口号. */
if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE)
{
return CMD_ERR_NO_MATCH;
}
for(sen_type = PD_SEN_TYPE_SIG; sen_type < PD_SEN_TYPE_COUNT; sen_type++)
{
if (strncmp(argv[0], pd_sen_type_str[sen_type], strlen(pd_sen_type_str[sen_type])))
{
continue;
}
pd_config.port_config[unit][port].config.sensor_type = sen_type;
}
return CMD_SUCCESS;
}
/* 配置端口降噪等级. */
CMD(pd_noise_reduction,
pd_noise_reduction_cmd,
"noise-reduction <0-800>",
"Noise reduction\n"
"Noise reduction unit: 0.1dBm\n")
{
return CMD_SUCCESS;
uint8_t unit = 0;
uint8_t port = 0;
/* 取出端口号. */
if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE)
{
return CMD_ERR_NO_MATCH;
}
pd_config.port_config[unit][port].config.noise_reduction = strtol(argv[0], NULL, 10);
return CMD_SUCCESS;
}
/* 配置端口降噪等级. */
CMD(pd_noise_reduction_auto,
pd_noise_reduction_auto_cmd,
"noise-reduction-auto (enable|disable)",
"Noise reduction auto\n"
"Enable\n"
"Disable\n")
{
return CMD_SUCCESS;
uint8_t unit = 0;
uint8_t port = 0;
uint8_t mode = FALSE;
/* 取出端口号. */
if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE)
{
return CMD_ERR_NO_MATCH;
}
if (0 == strncmp(argv[0], "en", 2))
{
mode = TRUE;
}
else if (0 == strncmp(argv[0], "di", 2))
{
mode = FALSE;
}
else
{
mode = FALSE;
}
//pd_config.port_config[unit][port].is_auto_noise = mode;
return CMD_SUCCESS;
}
/* 配置端口降噪等级. */
CMD(pd_noise_env,
pd_noise_env_cmd,
"noise-env <0-100>",
"Noise environment\n"
"Noise environment unit: dBm\n")
{
return CMD_SUCCESS;
uint8_t unit = 0;
uint8_t port = 0;
/* 取出端口号. */
if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE)
{
return CMD_ERR_NO_MATCH;
}
pd_config.port_config[unit][port].config.env_noise = strtol(argv[0], NULL, 10);
return CMD_SUCCESS;
}
/* 事件阈值. */
CMD(pd_evnet_thr,
pd_evnet_thr_cmd,
"evnet-thr <0-800>",
"Event threshold\n"
"Threshold: 0.1dBm\n")
{
return CMD_SUCCESS;
uint8_t unit = 0;
uint8_t port = 0;
/* 取出端口号. */
if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE)
{
return CMD_ERR_NO_MATCH;
}
pd_config.port_config[unit][port].config.event_threshold = strtol(argv[0], NULL, 10);
return CMD_SUCCESS;
}
/* 通道滤波类型. */
CMD(pd_evnet_cnt,
pd_evnet_cnt_cmd,
"evnet-cnt <0-1000>",
"Event conut threshold\n"
"Conut threshold\n")
{
return CMD_SUCCESS;
uint8_t unit = 0;
uint8_t port = 0;
/* 取出端口号. */
if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE)
{
return CMD_ERR_NO_MATCH;
}
pd_config.port_config[unit][port].config.event_counter = strtol(argv[0], NULL, 10);;
return CMD_SUCCESS;
}
/* 事件数据文件数量. */
CMD(pd_evnet_amount,
pd_evnet_amount_cmd,
"evnet-amount <500-5000>",
"Evnet file amount\n"
"Evnet file amount\n")
{
return CMD_SUCCESS;
uint8_t unit = 0;
uint8_t port = 0;
/* 取出端口号. */
if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE)
{
return CMD_ERR_NO_MATCH;
}
pd_config.port_config[unit][port].config.storage_event = strtol(argv[0], NULL, 10);;
return CMD_SUCCESS;
}
/* 实时数据上传间隔. */
CMD(pd_real_interval,
pd_real_interval_cmd,
"real-interval <1-60>",
"Real data interval\n"
"Interval time: min\n")
{
return CMD_SUCCESS;
pd_config.config.real_period = strtol(argv[0], NULL, 10);
return CMD_SUCCESS;
}
/* 事件存储间隔. */
CMD(pd_event_time,
pd_event_time_cmd,
"event-time <0-3600>",
"Event data time\n"
"Event time: second\n")
{
return CMD_SUCCESS;
pd_config.config.limit_event_time = strtol(argv[0], NULL, 10);
return CMD_SUCCESS;
}
/* 事件存储数量. */
CMD(pd_event_cnt,
pd_event_cnt_cmd,
"event-cnt <0-3600>",
"Event data conut\n"
"Event conut\n")
{
return CMD_SUCCESS;
pd_config.config.limit_event_cnt = strtol(argv[0], NULL, 10);
return CMD_SUCCESS;
}
/* 事件存储数量. */
CMD(pd_event_interval,
pd_event_interval_cmd,
"event-interval <0-3600>",
"Event data interval\n"
"Event interval: second\n")
{
return CMD_SUCCESS;
pd_config.config.limit_event_interval = strtol(argv[0], NULL, 10);
return CMD_SUCCESS;
}
/* 趋势数据上传间隔. */
CMD(pd_trend_interval,
pd_trend_interval_cmd,
"trend-interval <1-60>",
"Trend data interval\n"
"Interval time: min\n")
{
return CMD_SUCCESS;
pd_config.config.trend_period = strtol(argv[0], NULL, 10);
return CMD_SUCCESS;
}
/* 心跳上传间隔. */
CMD(pd_heartbeat_interval,
pd_heartbeat_interval_cmd,
"heartbeat-interval <1-60>",
"heartbeat interval\n"
"Interval time: min\n")
{
return CMD_SUCCESS;
pd_config.config.heartbeat_period = strtol(argv[0], NULL, 10);
return CMD_SUCCESS;
}
/* 趋势数据文件数量. */
CMD(pd_trend_amount,
pd_trend_amount_cmd,
"trend-amount <500-5000>",
"Trend file amount\n"
"Trend file amount\n")
{
return CMD_SUCCESS;
pd_config.config.storage_trend = strtol(argv[0], NULL, 10);
return CMD_SUCCESS;
}
/* 同步模式. */
CMD(pd_sync_mode,
pd_sync_mode_cmd,
"sync-mode (pt|power|outside)",
"Synchronize mode\n"
"PT\n"
"Power\n"
"Outside\n")
{
return CMD_SUCCESS;
uint8_t mode = 0;
if (0 == strncmp(argv[0], "pt", 2))
{
mode = PD_SYNC_PT;
}
else if (0 == strncmp(argv[0], "power", 5))
{
mode = PD_SYNC_POWER;
}
else if (0 == strncmp(argv[0], "outside", 5))
{
mode = PD_SYNC_OUTSIDE;
}
else
{
mode = 0;
}
pd_config.config.sync_mode = mode;
pd_sync_mode_set();
return CMD_SUCCESS;
}
/* 同步模式. */
CMD(pd_pps_mode,
pd_pps_mode_cmd,
"pps-mode (auto|master|slave)",
"PPS mode\n"
"Master\n"
"Slave\n")
{
return CMD_SUCCESS;
}
/* prps 实时上传控制. */
CMD(pd_prps_set,
pd_prps_set_cmd,
"prps-all (enable|disable)",
"PRPS all upload\n"
"Enable\n"
"Disable\n")
{
return CMD_SUCCESS;
uint8_t mode = FALSE;
if (0 == strncmp(argv[0], "en", 2))
{
mode = TRUE;
}
else if (0 == strncmp(argv[0], "di", 2))
{
mode = FALSE;
}
else
{
mode = FALSE;
}
pd_config.config.is_prps_save = mode;
return CMD_SUCCESS;
}
/* 显示 DAU 状态. */
CMD(show_prps,
show_prps_cmd,
"show prps",
"Show\n"
"PRPS\n")
{
return CMD_SUCCESS;
pd_prps_show();
return CMD_SUCCESS;
}
/* 显示 DAU 状态. */
CMD(show_pd,
show_pd_cmd,
"show pd",
"Show\n"
"Partial discharge\n")
{
return CMD_SUCCESS;
pd_show();
return CMD_SUCCESS;
}
/* 在终端上显示当前配置信息. */
CMD(show_running_port,
show_running_port_cmd,
"show running-config interface port WORD",
SHOW_STR
"Running configuration\n"
"Interface\n"
"Port\n"
"Port id: Ex: 1/1\n")
{
return CMD_SUCCESS;
}
/* 配置保存函数. */
int _pd_config_save(vty_t* vty)
{
int16_t i = 0;
vty_out(vty, "trend-interval %d%s", pd_config.config.trend_period, VTY_NEWLINE);
i++;
vty_out(vty, "real-interval %d%s", pd_config.config.real_period, VTY_NEWLINE);
i++;
vty_out(vty, "heartbeat-interval %d%s", pd_config.config.heartbeat_period, VTY_NEWLINE);
i++;
switch(pd_config.config.sync_mode)
{
case PD_SYNC_PT:
vty_out(vty, "sync-mode pt%s", VTY_NEWLINE);
i++;
break;
case PD_SYNC_POWER:
vty_out(vty, "sync-mode power%s", VTY_NEWLINE);
i++;
break;
case PD_SYNC_OUTSIDE:
vty_out(vty, "sync-mode outside%s", VTY_NEWLINE);
i++;
break;
default:
break;
}
return i;
}
/* config模式配置保存函数: vty -- 相应的终端 */
int32_t _pd_port_config_save(vty_t *vty)
{
array_t *configs = pd_port_node.configs;
pd_port_cmd_save_config_f *func = NULL;
uint8_t i = 0;
uint8_t unit = 0;
uint8_t port = 0;
uint16_t field = 0;
/* 其他配置保存 */
for(unit = 0; unit < PD_DAU_SUM; unit++)
{
if (!dau[unit])
{
continue;
}
if (!dau[unit]->is_valid)
{
continue;
}
for(port = 0; port < dau[unit]->port_num; port++)
{
vty_out(vty, "interface port %d/%d%s", unit + 1, port + 1, VTY_NEWLINE);
for(i = 0; i < array_active(configs); i++)
{
func = array_lookup(configs, i);
if (!func)
{
continue;
}
func(vty, unit, port);
}
field = pd_config.port_config[unit][port].config.sensor_type;
vty_out(vty, " sensor-type %s%s", pd_sen_type_str[field], VTY_NEWLINE);
vty_out(vty, " noise-reduction %d%s", pd_config.port_config[unit][port].config.noise_reduction, VTY_NEWLINE);
vty_out(vty, " noise-env %d%s", pd_config.port_config[unit][port].config.env_noise, VTY_NEWLINE);
vty_out(vty, " evnet-thr %d%s", pd_config.port_config[unit][port].config.event_threshold, VTY_NEWLINE);
vty_out(vty, " evnet-cnt %d%s", pd_config.port_config[unit][port].config.event_counter, VTY_NEWLINE);
vty_out(vty, "!%s", VTY_NEWLINE);
}
}
return E_NONE;
}
/* 将端口字符串, 转换成 unit port 格式. */
int32_t _pd_port_str_to_unit_port(const char *port_str, uint8_t *unit, uint8_t *port)
{
char *str = NULL;
char *p = NULL;
char temp[8];
uint8_t len = 0;
uint8_t i = 0;
snprintf(temp, 8, "%s", port_str);
str = strtok_r(temp, "/", &p);
while(str != NULL)
{
/* 检查长度. */
if (len >= 2)
{
return E_BAD_PARAM;
}
/* 检查字符串 */
for(i = 0; str[i] && str[i] != '\0'; i++)
{
if (!(str[i] >= '0' && str[i] <= '9'))
{
return E_BAD_PARAM;
}
}
/* 检查数据长度 */
if (i != 1)
{
return E_BAD_PARAM;
}
/* 读取板卡和端口号. */
if (0 == len)
{
*unit = strtol(str, NULL, 10) - 1;
}
else
{
*port = strtol(str, NULL, 10) - 1;
}
len++;
/* 获取下个数据 */
str = strtok_r(NULL, "/", &p);
}
return E_NONE;
}
/* Interface functions -------------------------------------------------------*/
/* description: 局放程序入口函数.
param:
return: */
int32_t pd_main(void)
{
#if 0
uint8_t i = 0;
uint8_t j = 0;
int32_t rv = 0;
/* 初始化基本参数. */
for(i = 0; i < PD_DAU_SUM; i++)
{
for(j = 0; j < PD_DAU_PORT_SUM; j++)
{
pd_config.port_config[i][j].config.sensor_type = PD_SEN_TYPE_SIG;
pd_config.port_config[i][j].config.filter = CSG_FILTER_TYPE_FR;
pd_config.port_config[i][j].config.phase_sequence = 1;
pd_config.port_config[i][j].config.event_threshold = 400;
pd_config.port_config[i][j].config.event_counter = 10;
pd_config.port_config[i][j].config.env_noise = 100;
pd_config.port_config[i][j].config.noise_reduction = 30;
pd_config.port_config[i][j].config.sample_rate = 50000000;
pd_config.port_config[i][j].config.storage_event = 1000;
pd_config.port_config[i][j].config.storage_wave = 1000;
}
}
pd_config.config.sync_mode = PD_SYNC_OUTSIDE;
pd_config.config.real_period = 1;
pd_config.config.storage_real = 1000;
pd_config.config.trend_period = 1;
pd_config.config.storage_trend = 1000;
pd_config.config.heartbeat_period = 1;
pd_config.config.limit_event_time = 300;
pd_config.config.limit_event_cnt = 5;
pd_config.config.limit_event_interval = 60;
/* 注册配置保存函数 */
rv = cmd_config_node_config_register(CONFIG_PRI_PD, _pd_config_save);
if (rv != E_NONE)
{
log_err(LOG_PD, "Command save register ERROR %d!", rv);
return rv;
}
#endif
/* 注册端口节点. */
cmd_install_node(&pd_port_node, _pd_port_config_save);
pd_port_node.prompt = XMALLOC(MTYPE_DAU, PD_PORT_PROMPT_LEN);
pd_port_node.configs = array_init(PD_PORT_CMD_PRI_COUNT, MTYPE_DAU);
cmd_install_element(CONFIG_NODE, &pd_event_time_cmd);
cmd_install_element(CONFIG_NODE, &pd_event_cnt_cmd);
cmd_install_element(CONFIG_NODE, &pd_event_interval_cmd);
cmd_install_element(CONFIG_NODE, &pd_real_interval_cmd);
cmd_install_element(CONFIG_NODE, &pd_trend_interval_cmd);
cmd_install_element(CONFIG_NODE, &pd_trend_amount_cmd);
cmd_install_element(CONFIG_NODE, &pd_heartbeat_interval_cmd);
cmd_install_element(CONFIG_NODE, &pd_sync_mode_cmd);
cmd_install_element(CONFIG_NODE, &pd_pps_mode_cmd);
cmd_install_element(CONFIG_NODE, &pd_prps_set_cmd);
cmd_install_element(CONFIG_NODE, &pd_port_terminal_cmd);
cmd_install_element(PORT_NODE, &pd_port_terminal_cmd);
cmd_install_element(PORT_NODE, &pd_sensor_type_cmd);
cmd_install_element(PORT_NODE, &pd_noise_reduction_cmd);
cmd_install_element(PORT_NODE, &pd_noise_reduction_auto_cmd);
cmd_install_element(PORT_NODE, &pd_noise_env_cmd);
cmd_install_element(PORT_NODE, &pd_evnet_thr_cmd);
cmd_install_element(PORT_NODE, &pd_evnet_cnt_cmd);
cmd_install_element(PORT_NODE, &pd_evnet_amount_cmd);
cmd_install_element(COMMON_NODE, &show_prps_cmd);
cmd_install_element(COMMON_NODE, &show_pd_cmd);
cmd_install_element(COMMON_NODE, &show_running_port_cmd);
//LD_E_RETURN(DBG_M_PD_ERR, log_handle_init());
LD_E_RETURN(DBG_M_PD_ERR, csg_handle_init());
LD_E_RETURN(DBG_M_PD_ERR, dau_handle_init());
//LD_E_RETURN(DBG_M_PD_ERR, localstorage_handle_init());
//LD_E_RETURN(DBG_M_PD_ERR, debug_handle_init());
return E_NONE;
}
int32_t pd_port_cmd_config_register(int32_t pri, pd_port_cmd_save_config_f *func)
{
cmd_node_t *node = &pd_port_node;
/* 参数检查 */
if (pri >= PD_PORT_CMD_PRI_COUNT || !func)
{
return E_BAD_PARAM;
}
/* 加入列表 */
array_set(node->configs, pri, func, MTYPE_DAU);
return 0;
}
void pd_sync_mode_set(void)
{
uint16_t temp = 0;
if (PD_SYNC_OUTSIDE == pd_config.config.sync_mode)
{
temp = CPLD_SYNC_OUTSIDE;
}
else
{
temp = CPLD_SYNC_PT;
}
cpld_write(CPLD_REG_SYNC, 1, &temp);
}
void pd_wdg_clr(void)
{
uint16_t temp = 0;
temp = 0x01;
cpld_write(CPLD_REG_WDG_CLR, 1, &temp);
}
void pd_sync_state_get(void)
{
uint16_t temp = 0;
cpld_read(CPLD_REG_STAT, 1, &temp);
pd_state.sync = ((temp & 0x2) != 0);
}
void pd_prps_show(void)
{
uint8_t unit = 0;
uint8_t port = 0;
pd_port_config_t *config = NULL;
printh("Concern Bitmap: 0x%x\r\n", pd_config.concern_bitmap);
printh("UN PO CO RN AN MN FC\r\n");
for(unit = 0; unit < PD_DAU_SUM; unit++)
{
if (!dau[unit])
{
continue;
}
for(port = 0; port < dau[unit]->port_num; port++)
{
config = &pd_config.port_config[unit][port];
printh("%-02d %-02d %-02d %-02d %-02d %-02d %-02d\r\n", unit, port, config->is_concern,
config->r_noise_reduction, config->auto_noise_reduction, config->manual_noise_reduction / 10,
config->filter_cfg);
}
}
}
void pd_show(void)
{
printh("Synchronization: %s\r\n", pd_state.sync ? "valid" : "invalid");
printh("Receive count: %d %d\r\n", dau_ctrl.recv_cnt, dau_ctrl.recv_cnt_old);
printh("Receive error count: %d %d\r\n", dau_ctrl.recv_err_cnt, dau_ctrl.recv_err_cnt_old);
printh("Data error count: %d %d\r\n", dau_ctrl.data_err_cnt, dau_ctrl.data_err_cnt_old);
printh("Send error count: %d %d\r\n\n", dau_ctrl.send_err_cnt, dau_ctrl.send_err_cnt_old);
}
#else
int32_t PD_main(void)
{
return 0;
}
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/