/***************************************************************************** * 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 * *

© COPYRIGHT(c) 2021 LandPower

* * 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 #include #include #include #include #include #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 ****/