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.

814 lines
27 KiB
C

2 days ago
/******************************************************************************
* file lib/process/pd_uhf.c
* author YuLiang
* version 1.0.0
* date 29-July-2025
* brief This file provides all the UHF operation functions.
*
******************************************************************************
* Attention
*
* <h2><center>&copy; 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 UHF_MIN_VALUE -800 // 局放的采集数值下限.
#define UHF_MANUAL_NOISE_MAX 800 // 手动降噪最大值.
/* 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; // 计算后的突发平均值阈值
} uhf_burst_t;
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
extern void _uhf_prps_default(int16_t *prps);
extern void _uhf_denoise(uint8_t unit, uint8_t port);
extern void _uhf_denoise_r(uint8_t unit, uint8_t port);
extern void _uhf_denoise_statistics(uint8_t unit, uint8_t port);
extern void _uhf_event_init(uint8_t unit, uint8_t port);
extern void _uhf_event(uint8_t unit, uint8_t port, uint16_t event_cnt);
extern void _uhf_trend_init(uint8_t unit, uint8_t port);
extern void _uhf_trend(uint8_t unit, uint8_t port, uint16_t trend_sec);
dau_port_func_t uhf_func =
{
_uhf_prps_default,
NULL,
NULL,
NULL,
NULL,
_uhf_denoise,
_uhf_denoise_r,
_uhf_denoise_statistics,
_uhf_event_init,
_uhf_event,
_uhf_trend_init,
_uhf_trend
};
/* 突发判断全局变量 */
static uhf_burst_t _hf_burst;
/* Internal functions --------------------------------------------------------*/
/* prps 默认值. */
void _uhf_prps_default(int16_t *prps)
{
}
/* 通道的实时数据 (自动 / 手动) 降噪的计算处理. */
void _uhf_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 i = 0;
int32_t phase_avg = 0;
uint32_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;
/* 噪声传感器不降噪 */
if (PD_SEN_TYPE_NOISE == pd_config.config_port[unit][port].sensor_type)
{
return;
}
/* 遍历所有数据并降噪 */
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 < UHF_MIN_VALUE)
{
buf[i] = UHF_MIN_VALUE;
}
else
{
buf[i] = buf_prps[i].data;
}
phase_avg += 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 = 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; // 普通降噪水平
}
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++)
{
if (buf[i] <= denoise_level)
{
noise_cnt++;
noise_sum += buf[i];
buf[i] = UHF_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;
if (denoise_manual > UHF_MANUAL_NOISE_MAX)
{
denoise_manual = UHF_MIN_VALUE + UHF_MANUAL_NOISE_MAX;
}
else
{
denoise_manual = UHF_MIN_VALUE + denoise_manual;
}
for (i = 0; i < PD_PHASE_NUM; i++)
{
/* 低于手动降噪水平的不显示, 余下的原值显示. */
if (buf[i] <= denoise_manual)
{
noise_cnt++;
noise_sum += buf[i];
buf[i] = UHF_MIN_VALUE;
}
}
}
else
{
/* 不降噪的情况下也要统计底噪 */
for(i = 0; i < PD_PHASE_NUM; i++)
{
if (buf[i] <= denoise_level)
{
noise_cnt++;
noise_sum += buf[i];
}
}
}
}
/* 数据原始数据平均值, 先除以 PD_PHASE_NUM 再除以工频周期数. */
pd_data.real->data[unit][port].avg_o = noise_cnt ? (int32_t)(noise_sum / noise_cnt) : UHF_MIN_VALUE;
}
/* 通道的实时数据关联降噪的计算处理. */
void _uhf_denoise_r(uint8_t unit, uint8_t port)
{
int16_t *buf = NULL;
int16_t *buf_noise = NULL;
dau_prps_date_t *buf_prps = NULL;
uint8_t unit_r = 0; // 关联降噪的单元.
uint8_t port_r = 0; // 关联降噪的端口.
uint16_t i = 0;
uint16_t pf_cnt = 0;
int16_t diff = 0;
int16_t denoise_level = 0;
int32_t avg = 0;
int32_t phase_avg = 0;
int32_t noise_sum = 0;
int32_t noise_cnt = 0;
double variance = 0;
/* 非噪声传感器不降噪 */
if (pd_config.config_port[unit][port].sensor_type != PD_SEN_TYPE_NOISE)
{
return;
}
/* 遍历所有数据并降噪 */
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 < UHF_MIN_VALUE)
{
buf[i]= UHF_MIN_VALUE;
}
else
{
buf[i] = buf_prps[i].data;
}
phase_avg += 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 = 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; // 普通降噪水平
}
dau[unit]->port_state[port].denoise_level[pf_cnt] = denoise_level; // 局放计数时的比较幅值
/* 不降噪的情况下也要统计底噪 */
for(i = 0; i < PD_PHASE_NUM; i++)
{
if (buf[i] <= denoise_level)
{
noise_cnt++;
noise_sum += buf[i];
}
}
/* 关联降噪 */
for(unit_r = 0; unit_r < PD_DAU_SUM; unit_r++)
{
if (!dau_is_valid(dau[unit_r]))
{
continue;
}
buf_noise = &pd_data.real->data[unit][port].prps[pf_cnt << 8];
for(port_r = 0; port_r < dau[unit_r]->port_num; port_r++)
{
if (pd_config.config_port[unit_r][port_r].sensor_type != PD_SEN_TYPE_SIG_NOISE)
{
continue;
}
buf = &pd_data.real->data[unit_r][port_r].prps[pf_cnt << 8];
/* 噪声通道工频内的第一值比噪声通道的平均降噪等级还要大. */
if (buf_noise[0] >= denoise_level)
{
if (pf_cnt > 0)
{
pd_data.real->data[unit_r][port_r].prps[(pf_cnt << 8) - 1] = UHF_MIN_VALUE;
}
buf[0] = UHF_MIN_VALUE;
buf[1] = UHF_MIN_VALUE;
}
if (buf_noise[PD_PHASE_NUM - 1] >= denoise_level)
{
if (pf_cnt < pd_data.real->data[unit][port].fre_cnt - 1)
{
buf[PD_PHASE_NUM] = UHF_MIN_VALUE;
}
buf[PD_PHASE_NUM - 1] = UHF_MIN_VALUE;
buf[PD_PHASE_NUM - 2] = UHF_MIN_VALUE;
}
for(i = 1; i < PD_PHASE_NUM - 1; i++)
{
if (buf_noise[i] >= denoise_level)
{
buf[i-1] = UHF_MIN_VALUE;
buf[i ] = UHF_MIN_VALUE;
buf[i+1] = UHF_MIN_VALUE;
}
}
}
}
}
/* 数据统计. */
pd_data.real->data[unit][port].avg_o = noise_cnt ? (noise_sum / noise_cnt) : UHF_MIN_VALUE;
}
/* 通道的实时数据统计信息. */
void _uhf_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 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 + UHF_MIN_VALUE;
int16_t event_thr_l = pd_config.config_port[unit][port].event_thr_l + UHF_MIN_VALUE;
uint32_t point_cnt = 0;
int64_t avg = 0;
/* 统计初始化 */
real_data->max = UHF_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] = UHF_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++)
{
if (buf[i] > real_data->phase_max[i])
{
real_data->phase_max[i] = buf[i];
}
/* 计算事件触发高低值阈值计数 */
if (buf[i] >= event_thr_h)
{
real_data->cnt_h++;
}
if (buf[i] >= event_thr_l)
{
real_data->cnt_l++;
}
if (buf[i] > denoise_level)
{
real_data->phase_sum[i] += buf[i];
real_data->phase_cnt[i]++;
}
/* 每秒最多采集 12800 个点 */
if (point_cnt >= PD_PRPS_POINT_MAX)
{
continue;
}
if (buf[i] > 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] : UHF_MIN_VALUE;
}
real_data->avg = real_data->cnt ? avg / real_data->cnt : UHF_MIN_VALUE;
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 _uhf_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(uhf_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 < real_data->avg)
{
_hf_burst.cnt = 1;
_hf_burst.state = 1;
_hf_burst.avg_thr = avg + _hf_burst.burst_thr;
}
}
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 _uhf_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 = UHF_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 _uhf_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 |= _uhf_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 : UHF_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 _uhf_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 = UHF_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] = UHF_MIN_VALUE;
trend_data->phase_cnt[i] = 0;
}
}
/* 趋势数据处理 */
void _uhf_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++)
{
/* 左移 5 位表示除以 32, 将数据缩小到 0-256 */
idx = ((real_data->point[i].data + 800) * 10) >> 5;
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] : UHF_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 : UHF_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 ****************/