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.
684 lines
23 KiB
C
684 lines
23 KiB
C
![]()
2 days ago
|
/******************************************************************************
|
||
|
* file lib/process/pd_hf.c
|
||
|
* author YuLiang
|
||
|
* version 1.0.0
|
||
|
* date 05-March-2025
|
||
|
* brief This file provides all the HF operation functions.
|
||
|
*
|
||
|
******************************************************************************
|
||
|
* Attention
|
||
|
*
|
||
|
* <h2><center>© COPYRIGHT(c) 2025 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 <math.h>
|
||
|
|
||
|
/* 用户代码头文件. */
|
||
|
#include "pd_dau.h"
|
||
|
#include "pd_main.h"
|
||
|
|
||
|
/* Private define ------------------------------------------------------------*/
|
||
|
#define HF_MIN_VALUE 0 // 局放的采集数值下限.
|
||
|
#define HF_MAX_VALUE_NEGA -8000 // 局放的采集数负数最大值.
|
||
|
#define HF_MAX_VALUE_POST 8000 // 局放的采集数正数最大值.
|
||
|
#define HF_POINT_MAX 64 // 每个工频周期最多有多少个点, 自适应降噪点位调节点.
|
||
|
#define HF_MANUAL_NOISE_MAX 8000 // 手动降噪最大值.
|
||
|
|
||
|
/* Private macro -------------------------------------------------------------*/
|
||
|
|
||
|
/* Private typedef -----------------------------------------------------------*/
|
||
|
/* 突发判断结构体 */
|
||
|
typedef struct {
|
||
|
uint8_t state; // 状态位, 0-未发现突变 1-发现突变
|
||
|
uint8_t data_cnt; // 第一次统计, 数据稳定时间
|
||
|
uint8_t cnt; // 突变后数据保持时间
|
||
|
uint8_t idx; // 平均值数据指针
|
||
|
uint8_t burst_time; // 突变判断时间
|
||
|
uint16_t burst_thr; // 突变判断阈值
|
||
|
int16_t avg_sec[5]; // 突变平均值数组
|
||
|
int32_t avg_thr; // 计算后的突发平均值阈值
|
||
|
} hf_burst_t;
|
||
|
|
||
|
/* Private variables ---------------------------------------------------------*/
|
||
|
|
||
|
/* Private function prototypes -----------------------------------------------*/
|
||
|
extern void _hf_prps_default(int16_t *prps);
|
||
|
extern void _hf_denoise(uint8_t unit, uint8_t port);
|
||
|
extern void _hf_denoise_statistics(uint8_t unit, uint8_t port);
|
||
|
extern void _hf_event_init(uint8_t unit, uint8_t port);
|
||
|
extern void _hf_event(uint8_t unit, uint8_t port, uint16_t event_cnt);
|
||
|
extern void _hf_trend_init(uint8_t unit, uint8_t port);
|
||
|
extern void _hf_trend(uint8_t unit, uint8_t port, uint16_t trend_sec);
|
||
|
|
||
|
dau_port_func_t hf_func =
|
||
|
{
|
||
|
_hf_prps_default,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
_hf_denoise,
|
||
|
NULL,
|
||
|
_hf_denoise_statistics,
|
||
|
_hf_event_init,
|
||
|
_hf_event,
|
||
|
_hf_trend_init,
|
||
|
_hf_trend
|
||
|
};
|
||
|
|
||
|
/* 突发判断全局变量 */
|
||
|
static hf_burst_t _hf_burst;
|
||
|
|
||
|
/* Internal functions --------------------------------------------------------*/
|
||
|
/* prps 默认值. */
|
||
|
void _hf_prps_default(int16_t *prps)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
/* 通道的实时数据 (自动 / 手动) 降噪的计算处理. */
|
||
|
void _hf_denoise(uint8_t unit, uint8_t port)
|
||
|
{
|
||
|
int16_t *buf = NULL;
|
||
|
dau_prps_date_t *buf_prps = NULL;
|
||
|
int16_t diff = 0;
|
||
|
uint16_t pf_cnt = 0;
|
||
|
int16_t denoise_manual = 0;
|
||
|
int16_t denoise_level = 0;
|
||
|
uint16_t abs_data = 0;
|
||
|
uint16_t i = 0;
|
||
|
int32_t phase_avg = 0;
|
||
|
int32_t noise_cnt = 0;
|
||
|
int32_t avg = 0;
|
||
|
int32_t noise_sum = 0;
|
||
|
double variance = 0;
|
||
|
|
||
|
/* 遍历所有数据并降噪 */
|
||
|
pd_data.real->data[unit][port].fre_cnt = dau[unit]->port_state[port].prps_fre_cnt;
|
||
|
for(pf_cnt = 0; pf_cnt < pd_data.real->data[unit][port].fre_cnt; pf_cnt++)
|
||
|
{
|
||
|
/* 计算平均值, 每个工频周期 256 个点, 左移 8 位正好是除以 256 */
|
||
|
buf = &pd_data.real->data[unit][port].prps[pf_cnt << 8];
|
||
|
buf_prps = &dau[unit]->port_state[port].prps[pf_cnt << 8];
|
||
|
phase_avg = 0;
|
||
|
|
||
|
for(i = 0; i < PD_PHASE_NUM; i++)
|
||
|
{
|
||
|
if (buf_prps[i].data < HF_MAX_VALUE_NEGA)
|
||
|
{
|
||
|
buf[i] = HF_MAX_VALUE_NEGA;
|
||
|
}
|
||
|
else if (buf_prps[i].data > HF_MAX_VALUE_POST)
|
||
|
{
|
||
|
buf[i] = HF_MAX_VALUE_POST;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
buf[i] = buf_prps[i].data;
|
||
|
}
|
||
|
|
||
|
phase_avg += abs(buf[i]);
|
||
|
}
|
||
|
avg += phase_avg;
|
||
|
phase_avg = phase_avg / PD_PHASE_NUM;
|
||
|
|
||
|
/* 计算降噪阈值, 该阈值还用于判断是否为脉冲 */
|
||
|
if (PD_DENOISE_TYPE_VARIANCE == pd_config.config_real[unit][port].denoise_type)
|
||
|
{
|
||
|
/* 方差降噪 */
|
||
|
variance = 0;
|
||
|
for(i = 0; i < PD_PHASE_NUM; i++)
|
||
|
{
|
||
|
diff = abs(buf[i]) - phase_avg;
|
||
|
variance += diff * diff;
|
||
|
}
|
||
|
variance = sqrt(variance / PD_PHASE_NUM) * dau[unit]->port_state[port].denoise_variance / 100;
|
||
|
denoise_level = phase_avg + variance;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* 自动降噪 */
|
||
|
denoise_level = phase_avg + (dau[unit]->port_state[port].denoise_auto << 1); // 普通降噪水平
|
||
|
}
|
||
|
|
||
|
dau[unit]->port_state[port].denoise_level[pf_cnt] = denoise_level; // 局放计数时的比较幅值
|
||
|
|
||
|
/* 降噪处理, 小于等于降噪等级的点在统计的时候根本不会被记录 */
|
||
|
if (PD_DENOISE_TYPE_AOTU == pd_config.config_real[unit][port].denoise_type
|
||
|
|| PD_DENOISE_TYPE_VARIANCE == pd_config.config_real[unit][port].denoise_type) // 自动降噪和方差降噪
|
||
|
{
|
||
|
/* 低于降噪水平的点不显示 */
|
||
|
for(i = 0; i < PD_PHASE_NUM; i++)
|
||
|
{
|
||
|
abs_data = abs(buf[i]);
|
||
|
if (abs_data <= denoise_level)
|
||
|
{
|
||
|
noise_cnt++;
|
||
|
noise_sum += abs_data;
|
||
|
buf[i] = HF_MIN_VALUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if (PD_DENOISE_TYPE_MANUAL == pd_config.config_real[unit][port].denoise_type) // 人工降噪.
|
||
|
{
|
||
|
denoise_manual = (pd_config.config_real[unit][port].denoise_manual << 1);
|
||
|
if (denoise_manual > HF_MANUAL_NOISE_MAX)
|
||
|
{
|
||
|
denoise_manual = HF_MANUAL_NOISE_MAX;
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < PD_PHASE_NUM; i++)
|
||
|
{
|
||
|
/* 低于手动降噪水平的不显示, 余下的原值显示. */
|
||
|
abs_data = abs(buf[i]);
|
||
|
if (abs_data <= denoise_manual)
|
||
|
{
|
||
|
noise_cnt++;
|
||
|
noise_sum += abs_data;
|
||
|
buf[i] = HF_MIN_VALUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* 不降噪的情况下也要统计底噪 */
|
||
|
for(i = 0; i < PD_PHASE_NUM; i++)
|
||
|
{
|
||
|
abs_data = abs(buf[i]);
|
||
|
if (abs_data <= denoise_level)
|
||
|
{
|
||
|
noise_cnt++;
|
||
|
noise_sum += abs_data;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* 数据原始数据平均值, 先除以 PD_PHASE_NUM 再除以工频周期数. */
|
||
|
pd_data.real->data[unit][port].avg_o = noise_cnt ? (int32_t)(noise_sum / noise_cnt) : HF_MIN_VALUE;
|
||
|
}
|
||
|
|
||
|
/* 通道的实时数据统计信息. */
|
||
|
void _hf_denoise_statistics(uint8_t unit, uint8_t port)
|
||
|
{
|
||
|
pd_prps_data_point_t *real_data = &pd_data.real->data[unit][port];
|
||
|
dau_prps_date_t *buf_prps = NULL;
|
||
|
int16_t *buf = NULL;
|
||
|
uint16_t abs_data = 0;
|
||
|
uint16_t pf_cnt = 0;
|
||
|
uint16_t i = 0;
|
||
|
int16_t denoise_level = 0;
|
||
|
int16_t event_thr_h = pd_config.config_port[unit][port].event_thr_h << 1;
|
||
|
int16_t event_thr_l = pd_config.config_port[unit][port].event_thr_l << 1;
|
||
|
uint32_t point_cnt = 0;
|
||
|
int64_t avg = 0;
|
||
|
|
||
|
/* 统计初始化 */
|
||
|
real_data->max = HF_MIN_VALUE;
|
||
|
real_data->cnt = 0;
|
||
|
real_data->cnt_h = 0;
|
||
|
real_data->cnt_l = 0;
|
||
|
|
||
|
for(i = 0; i < PD_PHASE_NUM; i++)
|
||
|
{
|
||
|
real_data->phase_max[i] = HF_MIN_VALUE;
|
||
|
real_data->phase_sum[i] = 0;
|
||
|
real_data->phase_cnt[i] = 0;
|
||
|
}
|
||
|
|
||
|
/* 数值的计算 最大值, 平均值, 放电次数, 和压缩点数 */
|
||
|
for(pf_cnt = 0; pf_cnt < pd_data.real->data[unit][port].fre_cnt; pf_cnt++)
|
||
|
{
|
||
|
buf = &real_data->prps[pf_cnt << 8];
|
||
|
buf_prps = &dau[unit]->port_state[port].prps[pf_cnt << 8];
|
||
|
denoise_level = dau[unit]->port_state[port].denoise_level[pf_cnt];
|
||
|
|
||
|
for(i = 0; i < PD_PHASE_NUM; i++)
|
||
|
{
|
||
|
abs_data = abs(buf[i]);
|
||
|
if (abs_data > real_data->phase_max[i])
|
||
|
{
|
||
|
real_data->phase_max[i] = abs_data;
|
||
|
}
|
||
|
|
||
|
/* 计算事件触发高低值阈值计数 */
|
||
|
if (abs_data > event_thr_h)
|
||
|
{
|
||
|
real_data->cnt_h++;
|
||
|
}
|
||
|
if (abs_data > event_thr_l)
|
||
|
{
|
||
|
real_data->cnt_l++;
|
||
|
}
|
||
|
|
||
|
if (abs_data > denoise_level)
|
||
|
{
|
||
|
real_data->phase_sum[i] += abs_data;
|
||
|
real_data->phase_cnt[i]++;
|
||
|
}
|
||
|
|
||
|
/* 每秒最多采集 12800 个点 */
|
||
|
if (point_cnt >= PD_PRPS_POINT_MAX)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (abs_data > denoise_level)
|
||
|
{
|
||
|
real_data->point[point_cnt].time = buf_prps[i].time;
|
||
|
real_data->point[point_cnt].index = i;
|
||
|
real_data->point[point_cnt].data = buf[i];
|
||
|
point_cnt++;
|
||
|
}
|
||
|
else if (0 == i)
|
||
|
{
|
||
|
real_data->point[point_cnt].time = buf_prps[i].time;
|
||
|
real_data->point[point_cnt].index = i;
|
||
|
real_data->point[point_cnt].data = buf[i];
|
||
|
point_cnt++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
real_data->point_cnt = point_cnt;
|
||
|
|
||
|
for(i = 0; i < PD_PHASE_NUM; i++)
|
||
|
{
|
||
|
if (real_data->phase_max[i] > real_data->max)
|
||
|
{
|
||
|
real_data->max = real_data->phase_max[i];
|
||
|
}
|
||
|
|
||
|
if (real_data->phase_cnt[i])
|
||
|
{
|
||
|
avg += real_data->phase_sum[i];
|
||
|
real_data->cnt += real_data->phase_cnt[i];
|
||
|
}
|
||
|
|
||
|
real_data->phase_avg[i] = real_data->phase_cnt[i] ? real_data->phase_sum[i] / real_data->phase_cnt[i] : HF_MIN_VALUE;
|
||
|
}
|
||
|
real_data->avg = real_data->cnt ? avg / real_data->cnt : HF_MIN_VALUE;
|
||
|
/* 当最大值为 0 时生成随机最大值, 便于通过灵敏度测试 */
|
||
|
if (!real_data->max)
|
||
|
{
|
||
|
real_data->max = (rand() & 0x1) << 1;
|
||
|
}
|
||
|
|
||
|
DBG(DBG_M_PD_DATA, "port %d max %d avg %d cnt %d avg_o %d\r\n", port, real_data->max, real_data->avg, real_data->cnt, real_data->avg_o);
|
||
|
|
||
|
/* 根据局放次数, 自动调节降噪等级 */
|
||
|
if (pd_config.config_port[unit][port].is_auto_noise)
|
||
|
{
|
||
|
if (PD_DENOISE_TYPE_VARIANCE == pd_config.config_real[unit][port].denoise_type)
|
||
|
{
|
||
|
/* 左移 6 位相当于乘以 64, 即每个工频周期最多统计 64 个点 */
|
||
|
if (real_data->cnt >= pd_config.config_port[unit][port].auto_noise_cnt)
|
||
|
{
|
||
|
dau[unit]->port_state[port].denoise_variance += 1;
|
||
|
}
|
||
|
else if (dau[unit]->port_state[port].denoise_variance <= pd_config.config_port[unit][port].denoise_variance)
|
||
|
{
|
||
|
dau[unit]->port_state[port].denoise_variance = pd_config.config_port[unit][port].denoise_variance;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (dau[unit]->port_state[port].denoise_variance >= 1)
|
||
|
{
|
||
|
dau[unit]->port_state[port].denoise_variance -= 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dau[unit]->port_state[port].denoise_variance = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* 左移 6 位相当于乘以 64, 即每个工频周期最多统计 64 个点 */
|
||
|
if (real_data->cnt >= pd_config.config_port[unit][port].auto_noise_cnt)
|
||
|
{
|
||
|
dau[unit]->port_state[port].denoise_auto += 10;
|
||
|
}
|
||
|
else if (dau[unit]->port_state[port].denoise_auto <= pd_config.config_port[unit][port].denoise_auto)
|
||
|
{
|
||
|
dau[unit]->port_state[port].denoise_auto = pd_config.config_port[unit][port].denoise_auto;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (dau[unit]->port_state[port].denoise_auto >= 10)
|
||
|
dau[unit]->port_state[port].denoise_auto -= 10;
|
||
|
else
|
||
|
dau[unit]->port_state[port].denoise_auto = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dau[unit]->port_state[port].denoise_auto = pd_config.config_port[unit][port].denoise_auto;
|
||
|
dau[unit]->port_state[port].denoise_variance = pd_config.config_port[unit][port].denoise_variance;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* 突变事件判断 */
|
||
|
bool _hf_event_burst(uint8_t unit, uint8_t port)
|
||
|
{
|
||
|
pd_prps_data_point_t *real_data = &pd_data.real->data[unit][port];
|
||
|
int32_t avg = 0;
|
||
|
uint8_t i = 0;
|
||
|
|
||
|
/* 配置修改后, 重新计算 */
|
||
|
if (_hf_burst.burst_time != pd_config.config_port[unit][port].burst_time
|
||
|
|| _hf_burst.burst_thr != pd_config.config_port[unit][port].burst_thr)
|
||
|
{
|
||
|
memset(&_hf_burst, 0, sizeof(hf_burst_t));
|
||
|
_hf_burst.burst_time = pd_config.config_port[unit][port].burst_time;
|
||
|
_hf_burst.burst_thr = pd_config.config_port[unit][port].burst_thr;
|
||
|
}
|
||
|
|
||
|
/* 计算前 5 秒平均值 */
|
||
|
for(i = 0; i < _hf_burst.burst_time; i++)
|
||
|
{
|
||
|
avg += _hf_burst.avg_sec[i];
|
||
|
}
|
||
|
avg = avg / _hf_burst.burst_time;
|
||
|
|
||
|
/* 更新前 5s 平均值数组 */
|
||
|
_hf_burst.avg_sec[_hf_burst.idx] = real_data->avg;
|
||
|
_hf_burst.idx++;
|
||
|
if (_hf_burst.idx >= _hf_burst.burst_time)
|
||
|
{
|
||
|
_hf_burst.idx = 0;
|
||
|
}
|
||
|
|
||
|
/* 上电非稳定期间的数据丢弃 */
|
||
|
if (_hf_burst.data_cnt < _hf_burst.burst_time)
|
||
|
{
|
||
|
_hf_burst.data_cnt++;
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
/* 突发事件计数 */
|
||
|
if (0 == _hf_burst.state)
|
||
|
{
|
||
|
if (avg + (_hf_burst.burst_thr << 1) < real_data->avg)
|
||
|
{
|
||
|
_hf_burst.cnt = 1;
|
||
|
_hf_burst.state = 1;
|
||
|
_hf_burst.avg_thr = avg + (_hf_burst.burst_thr << 1);
|
||
|
}
|
||
|
}
|
||
|
else if (1 == _hf_burst.state)
|
||
|
{
|
||
|
if (_hf_burst.avg_thr < real_data->avg)
|
||
|
{
|
||
|
_hf_burst.cnt++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_hf_burst.cnt = 0;
|
||
|
_hf_burst.state = 0;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_hf_burst.cnt = 0;
|
||
|
_hf_burst.state = 0;
|
||
|
}
|
||
|
|
||
|
/* 判断是否突发 */
|
||
|
if (_hf_burst.cnt >= _hf_burst.burst_time)
|
||
|
{
|
||
|
_hf_burst.cnt = 0;
|
||
|
_hf_burst.state = 0;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
/* 事件结构体初始化 */
|
||
|
void _hf_event_init(uint8_t unit, uint8_t port)
|
||
|
{
|
||
|
pd_event_port_t *event_data = &pd_data.event->port[unit][port];
|
||
|
|
||
|
/* 初始化数据. */
|
||
|
event_data->vport = dau_port_to_vport(unit, port);
|
||
|
event_data->power_fre = 0;
|
||
|
event_data->utc = 0;
|
||
|
event_data->data_cnt = 0;
|
||
|
event_data->event_cnt = 0;
|
||
|
event_data->index = dau_ctrl.event_index[unit][port];
|
||
|
event_data->is_burst = FALSE;
|
||
|
event_data->max = HF_MIN_VALUE;
|
||
|
event_data->avg_o = 0;
|
||
|
event_data->avg = 0;
|
||
|
event_data->cnt = 0;
|
||
|
event_data->is_sec_h = TRUE;
|
||
|
event_data->is_sec_l = TRUE;
|
||
|
event_data->type = PD_EVENT_TYPE_NONE;
|
||
|
event_data->cnt_h = 0;
|
||
|
event_data->cnt_l = 0;
|
||
|
event_data->point_cnt = 0;
|
||
|
}
|
||
|
|
||
|
/* 事件处理 */
|
||
|
void _hf_event(uint8_t unit, uint8_t port, uint16_t event_cnt)
|
||
|
{
|
||
|
pd_event_port_t *event_data = &pd_data.event->port[unit][port];
|
||
|
pd_prps_data_point_t *real_data = &pd_data.real->data[unit][port];
|
||
|
uint16_t i = 0;
|
||
|
|
||
|
/* 填充数据, pd_data_point_t 结构体大小为 8, 这里用左移 3 位来计算复制数据的大小. */
|
||
|
event_data->data_cnt++;
|
||
|
memcpy(&event_data->point[event_data->point_cnt], real_data->point, real_data->point_cnt << 3);
|
||
|
event_data->point_cnt += real_data->point_cnt;
|
||
|
|
||
|
/* 统计平均值, 最大值, 脉冲计数 */
|
||
|
for(i = 0; i < PD_PHASE_NUM; i++)
|
||
|
{
|
||
|
if (real_data->phase_cnt[i])
|
||
|
{
|
||
|
event_data->avg += real_data->phase_sum[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (event_data->max < real_data->max)
|
||
|
{
|
||
|
event_data->max = real_data->max;
|
||
|
}
|
||
|
|
||
|
event_data->power_fre += real_data->fre_cnt;
|
||
|
event_data->cnt += real_data->cnt;
|
||
|
event_data->avg_o += real_data->avg_o;
|
||
|
event_data->cnt_h += real_data->cnt_h;
|
||
|
event_data->cnt_l += real_data->cnt_l;
|
||
|
|
||
|
/* 计算事件触发高低每秒脉冲计数 */
|
||
|
if (real_data->cnt < pd_config.config_port[unit][port].event_sec_h)
|
||
|
{
|
||
|
event_data->is_sec_h = FALSE;
|
||
|
}
|
||
|
if (real_data->cnt < pd_config.config_port[unit][port].event_sec_l)
|
||
|
{
|
||
|
event_data->is_sec_l = FALSE;
|
||
|
}
|
||
|
|
||
|
event_data->is_burst |= _hf_event_burst(unit, port);
|
||
|
|
||
|
/* 计算数据 */
|
||
|
if (event_data->data_cnt >= DAU_EVENT_SUM
|
||
|
|| event_cnt == (DAU_EVENT_SUM - 1))
|
||
|
{
|
||
|
event_data->power_fre = event_data->power_fre / event_data->data_cnt;
|
||
|
event_data->avg = event_data->cnt ? event_data->avg / event_data->cnt : HF_MIN_VALUE;
|
||
|
event_data->avg_o = event_data->avg_o / event_data->data_cnt; // 底噪值(原始数据平均值)
|
||
|
event_data->utc = pd_data.real->utc;
|
||
|
|
||
|
/* 判断事件类型 */
|
||
|
if (event_data->is_sec_h && event_data->cnt >= pd_config.config_port[unit][port].event_counter_h)
|
||
|
{
|
||
|
event_data->type = PD_EVENT_TYPE_CNTH;
|
||
|
}
|
||
|
else if (event_data->cnt_h >= pd_config.config_port[unit][port].event_counter_thr_h)
|
||
|
{
|
||
|
event_data->type = PD_EVENT_TYPE_THRH;
|
||
|
}
|
||
|
else if (event_data->is_burst)
|
||
|
{
|
||
|
event_data->type = PD_EVENT_TYPE_BURST;
|
||
|
}
|
||
|
else if (event_data->cnt >= pd_config.config_port[unit][port].event_counter_l
|
||
|
&& event_data->is_sec_l
|
||
|
&& event_data->cnt_l >= pd_config.config_port[unit][port].event_counter_thr_h)
|
||
|
{
|
||
|
event_data->type = PD_EVENT_TYPE_THRL;
|
||
|
}
|
||
|
|
||
|
//if (event_data->type != PD_EVENT_TYPE_NONE)
|
||
|
{
|
||
|
DBG(DBG_M_PD_DATA, "port %d evnet %d\r\n", port, event_data->type);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* 趋势初始化 */
|
||
|
void _hf_trend_init(uint8_t unit, uint8_t port)
|
||
|
{
|
||
|
pd_trend_data_t *trend_data = &pd_data.trend_col.data[unit][port];
|
||
|
pd_trend_prps_port_t *prps = &pd_data.trend.prps.port[unit][port];
|
||
|
uint16_t i = 0;
|
||
|
|
||
|
prps->point_cnt_temp = 0;
|
||
|
trend_data->trend_sec = 0;
|
||
|
trend_data->data_cnt = 0;
|
||
|
trend_data->noise = 0;
|
||
|
trend_data->max = HF_MIN_VALUE;
|
||
|
trend_data->avg = 0;
|
||
|
trend_data->cnt = 0;
|
||
|
|
||
|
for(i = 0; i < PD_PHASE_NUM; i++)
|
||
|
{
|
||
|
trend_data->phase_sum[i] = 0;
|
||
|
trend_data->phase_max[i] = HF_MIN_VALUE;
|
||
|
trend_data->phase_cnt[i] = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* 趋势数据处理 */
|
||
|
void _hf_trend(uint8_t unit, uint8_t port, uint16_t trend_sec)
|
||
|
{
|
||
|
pd_trend_prpd_port_t *prpd = &pd_data.trend_prpd->port[unit][port];
|
||
|
pd_trend_prps_port_t *prps = &pd_data.trend.prps.port[unit][port];
|
||
|
pd_trend_data_t *trend_data = &pd_data.trend_col.data[unit][port];
|
||
|
pd_prps_data_point_t *real_data = &pd_data.real->data[unit][port];
|
||
|
uint8_t idx = 0;
|
||
|
uint8_t phase_cmp_idx = 0;
|
||
|
uint16_t i = 0;
|
||
|
uint32_t phase_cmp = 0;
|
||
|
|
||
|
/* 填充数据. */
|
||
|
trend_data->data_cnt++;
|
||
|
for(i = 0; i < PD_PHASE_NUM; i++)
|
||
|
{
|
||
|
if (real_data->phase_cnt[i])
|
||
|
{
|
||
|
trend_data->phase_sum[i] += real_data->phase_sum[i];
|
||
|
trend_data->phase_cnt[i] += real_data->phase_cnt[i];
|
||
|
trend_data->avg += real_data->phase_sum[i];
|
||
|
trend_data->cnt += real_data->phase_cnt[i];
|
||
|
}
|
||
|
|
||
|
if (real_data->phase_max[i] > trend_data->phase_max[i])
|
||
|
{
|
||
|
trend_data->phase_max[i] = real_data->phase_max[i];
|
||
|
}
|
||
|
|
||
|
if (real_data->phase_max[i] > trend_data->max)
|
||
|
{
|
||
|
trend_data->max = real_data->phase_max[i];
|
||
|
}
|
||
|
}
|
||
|
trend_data->noise += real_data->avg_o;
|
||
|
|
||
|
/* 计算 PRPD */
|
||
|
for(i = 0; i < real_data->point_cnt; i++)
|
||
|
{
|
||
|
idx = real_data->point[i].data / 64;
|
||
|
|
||
|
if (prpd->data[real_data->point[i].index][idx] != 65535)
|
||
|
{
|
||
|
prpd->data[real_data->point[i].index][idx]++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* 复制最后 10s 的 PRPS 数据 */
|
||
|
if (trend_sec + DAU_TREND_PRPS_SUM >= pd_config.config.trend_period)
|
||
|
{
|
||
|
/* 最多采集 128000 个点 */
|
||
|
if ((prps->point_cnt_temp + real_data->point_cnt) <= PD_TREND_POINT_MAX)
|
||
|
{
|
||
|
memcpy(&prps->point[prps->point_cnt_temp], real_data->point, real_data->point_cnt << 3);
|
||
|
prps->point_cnt_temp += real_data->point_cnt;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* 计算数据. */
|
||
|
if (trend_sec >= (pd_config.config.trend_period - 1))
|
||
|
{
|
||
|
for(i = 0; i < PD_PHASE_NUM; i++)
|
||
|
{
|
||
|
trend_data->phase_avg[i] = trend_data->phase_cnt[i] ? trend_data->phase_sum[i] / trend_data->phase_cnt[i] : HF_MIN_VALUE;
|
||
|
|
||
|
/* 查找最大放电周期. */
|
||
|
if (trend_data->phase_cnt[i] > phase_cmp)
|
||
|
{
|
||
|
phase_cmp_idx = i;
|
||
|
phase_cmp = trend_data->phase_cnt[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
trend_data->phase = 360.0 * phase_cmp_idx / PD_PHASE_NUM; // 放电相位
|
||
|
trend_data->avg = trend_data->cnt ? trend_data->avg / trend_data->cnt : HF_MIN_VALUE;
|
||
|
trend_data->noise = trend_data->noise / trend_data->data_cnt; // 趋势数据中的底噪值
|
||
|
trend_data->event_cnt = dau_ctrl.event_index[unit][port] - dau_ctrl.trend_event_index[unit][port];
|
||
|
|
||
|
/* 更新 PRPS 点计数 */
|
||
|
prps->point_cnt = prps->point_cnt_temp;
|
||
|
|
||
|
/* 更新索引. */
|
||
|
dau_ctrl.trend_event_index[unit][port] = dau_ctrl.event_index[unit][port];
|
||
|
}
|
||
|
}
|
||
|
/* Interface functions -------------------------------------------------------*/
|
||
|
#endif
|
||
|
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/
|