/****************************************************************************** * file lib/process/gis.c * author YuLiang * version 1.0.0 * date 23-Feb-2023 * brief This file provides all the gis operation functions. * ****************************************************************************** * Attention * *

© COPYRIGHT(c) 2023 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 "pd_dau.h" #include "pd_main.h" /* Private define ------------------------------------------------------------*/ #define GIS_MIN_VALUE PD_GIS_MIN_VALUE // 特高频局放的采集数值下限 -800 (-80.0dBm). /* Private macro -------------------------------------------------------------*/ /* Private typedef -----------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ extern void _gis_prps_default(int16_t *prps); extern void _gis_prps_denoise(uint8_t unit, uint8_t port); extern void _gis_prps_denoise_relevance(uint8_t unit, uint8_t port); extern void _gis_prps_denoise_statistics(uint8_t unit, uint8_t port); extern void _gis_denoise(uint8_t unit, uint8_t port); extern void _gis_denoise_relevance(uint8_t unit, uint8_t port); extern void _gis_denoise_statistics(uint8_t unit, uint8_t port); extern void _gis_event(uint8_t unit, uint8_t port); extern void _gis_trend(uint8_t unit, uint8_t port, uint16_t trend_sec); dau_port_func_t gis_func = { _gis_prps_default, _gis_prps_denoise, _gis_prps_denoise_relevance, _gis_prps_denoise_statistics, _gis_denoise, _gis_denoise_relevance, _gis_denoise_statistics, _gis_event, _gis_trend }; /* Internal functions --------------------------------------------------------*/ void _gis_prps_default(int16_t *prps) { uint16_t i = 0; for(i = 0; i < PD_PRPS_NUM; i++) { prps[i] = GIS_MIN_VALUE; } } /* 通道的实时数据 (自动 / 手动) 降噪的计算处理 (用于实时PRPS的临时显示使用). */ void _gis_prps_denoise(uint8_t unit, uint8_t port) { pd_prps_t *data = pd_data.denoise; int16_t *buf = NULL; int16_t *buf_prps = NULL; uint8_t pf_cnt = 0; uint8_t i = 0; uint16_t manual_noise_reduction = 0; int16_t manual_noise_level = 0; int16_t noise_level = 0; int32_t phase_avg = 0; int32_t temp = 0; /* 噪声传感器在关联降噪中运算. */ if (PD_SEN_TYPE_NOISE == pd_config.port_config[unit][port].config.sensor_type || !pd_config.port_config[unit][port].is_concern || !dau[unit]->port_state[port].is_complete) { return; } /* 非噪声通道处理. */ for(pf_cnt = 0; pf_cnt < PD_POWER_FRE; pf_cnt++) { /* 左移 7 位正好是乘以 128(PD_PHASE_NUM). */ buf = &data->data[unit][port].data[pf_cnt << 7]; buf_prps = &dau[unit]->port_state[port].prps[pf_cnt << 7]; phase_avg = 0; for(i = 0; i < PD_PHASE_NUM; i++) { if (buf_prps[i] < GIS_MIN_VALUE) { buf[i] = GIS_MIN_VALUE; } else { buf[i] = buf_prps[i]; } phase_avg += buf[i]; } phase_avg = (phase_avg / PD_PHASE_NUM); noise_level = phase_avg + pd_config.port_config[unit][port].config.noise_reduction; // 普通降噪水平 默认:30 单位:0.1dBm dau[unit]->port_state[port].noise_level[pf_cnt] = noise_level; // 局放计数时的比较幅值. /* 未配置通道类型的不再进行下去. */ if (pd_config.port_config[unit][port].config.sensor_type != PD_SEN_TYPE_SIG && pd_config.port_config[unit][port].config.sensor_type != PD_SEN_TYPE_SIG_NOISE) { continue; } if (pd_config.port_config[unit][port].auto_noise_reduction) { /* 自适应降噪. */ temp = phase_avg - GIS_MIN_VALUE; /* 低于平均值的不显示, 低于普通降噪水平的减去平均值, 余下的原值显示. */ for(i = 0; i < PD_PHASE_NUM; i++) { if (buf[i] <= phase_avg) { buf[i] = GIS_MIN_VALUE; } else if(buf[i] <= noise_level) { buf[i] -= temp; } } } else if(pd_config.port_config[unit][port].manual_noise_reduction) { /* 手动降噪. */ manual_noise_reduction = pd_config.port_config[unit][port].manual_noise_reduction; if (manual_noise_reduction > 800) { manual_noise_reduction = 800; manual_noise_level = 0; } else { manual_noise_level = GIS_MIN_VALUE + manual_noise_reduction; } for(i = 0; i < PD_PHASE_NUM; i++) { /* 手动降噪水平小于普通降噪水平, 需要考虑降噪水平, 否则不考虑普通降噪水平. */ if (manual_noise_level < noise_level) { /* 低于手动降噪水平的不显示, 低于普通降噪水平的减去手动降噪水平, 余下的原值显示. */ if (buf[i] <= manual_noise_level) { buf[i] = GIS_MIN_VALUE; } else if( buf[i] <= noise_level) { buf[i] -= manual_noise_reduction; } } else { /* 低于手动降噪水平的不显示, 余下的原值显示. */ if (buf[i] <= manual_noise_level) { buf[i] = GIS_MIN_VALUE; } } } } } } /* 通道的实时数据关联降噪的计算处理 (用于实时PRPS的临时显示使用). */ void _gis_prps_denoise_relevance(uint8_t unit, uint8_t port) { pd_prps_t *data = pd_data.denoise; int16_t *buf = NULL; int16_t *buf_prps = NULL; int16_t *buf_noise = NULL; uint8_t unit_r = 0; // 关联降噪的单元. uint8_t port_r = 0; // 关联降噪的端口. uint8_t pf_cnt = 0; uint8_t i = 0; int16_t noise_level = 0; int32_t phase_avg = 0; if (pd_config.port_config[unit][port].config.sensor_type != PD_SEN_TYPE_NOISE || !dau[unit]->port_state[port].is_complete) { return; } /* 噪声通道处理. */ for(pf_cnt = 0; pf_cnt < PD_POWER_FRE; pf_cnt++) { /* 左移 7 位正好是乘以 128(PD_PHASE_NUM). */ buf = &data->data[unit][port].data[pf_cnt << 7]; buf_prps = &dau[unit]->port_state[port].prps[pf_cnt << 7]; phase_avg = 0; for(i = 0; i < PD_PHASE_NUM; i++) { if (buf_prps[i] < GIS_MIN_VALUE) { buf[i] = GIS_MIN_VALUE; } else { buf[i] = buf_prps[i]; } phase_avg += buf[i]; } phase_avg = (phase_avg / PD_PHASE_NUM); noise_level = phase_avg + pd_config.port_config[unit][port].config.noise_reduction; // 普通降噪水平 默认:30 单位:0.1dBm dau[unit]->port_state[port].noise_level[pf_cnt] = noise_level; // 局放计数时的比较幅值. for(unit_r = 0; unit_r < PD_DAU_SUM; unit_r++) { if (!dau[unit_r]) { continue; } for(port_r = 0; port_r < dau[unit_r]->port_num; port_r++) { if (!pd_config.port_config[unit_r][port_r].r_noise_reduction || !dau[unit_r]->port_state[port_r].is_complete || (pd_config.port_config[unit_r][port_r].config.sensor_type != PD_SEN_TYPE_SIG && pd_config.port_config[unit_r][port_r].config.sensor_type != PD_SEN_TYPE_SIG_NOISE)) { continue; } buf_noise = &data->data[unit][port].data[pf_cnt << 7]; buf = &data->data[unit_r][port_r].data[pf_cnt << 7]; /* 噪声通道工频内的第一值比噪声通道的平均降噪等级还要大. */ if (buf_noise[0] > noise_level) { if (pf_cnt > 0) { data->data[unit_r][port_r].data[(pf_cnt << 7) - 1] = GIS_MIN_VALUE; } buf[0] = GIS_MIN_VALUE; buf[1] = GIS_MIN_VALUE; } if (buf_noise[PD_PHASE_NUM - 1] > noise_level) { if (pf_cnt < 49) { buf[PD_PHASE_NUM] = GIS_MIN_VALUE; } buf[PD_PHASE_NUM - 1] = GIS_MIN_VALUE; buf[PD_PHASE_NUM - 2] = GIS_MIN_VALUE; } for(i = 1; i < PD_PHASE_NUM - 1; i++) { if (buf_noise[i] > noise_level) { buf[i-1] = GIS_MIN_VALUE; buf[i ] = GIS_MIN_VALUE; buf[i+1] = GIS_MIN_VALUE; } } } } } } /* 通道的实时数据统计信息 (用于实时 PRPS 的临时显示使用). */ void _gis_prps_denoise_statistics(uint8_t unit, uint8_t port) { pd_prps_t *data = pd_data.denoise; int16_t *buf = NULL; uint8_t pf_cnt = 0; uint8_t i = 0; int16_t noise_level = 0; uint16_t cnt = 0; int16_t max = GIS_MIN_VALUE; int32_t avg = 0; if (!pd_config.port_config[unit][port].is_concern) { return; } data->data[unit][port].is_valid = dau[unit]->port_state[port].is_complete; if (!dau[unit]->port_state[port].is_complete) { return; } /* 数值的计算 最大值, 平均值, 放电次数. */ for(pf_cnt = 0; pf_cnt < PD_POWER_FRE; pf_cnt++) { buf = &data->data[unit][port].data[pf_cnt << 7]; noise_level = dau[unit]->port_state[port].noise_level[pf_cnt]; for(i = 0; i < PD_PHASE_NUM; i++) { if (buf[i] > max ) { max = buf[i]; } if (buf[i] > noise_level) { avg += buf[i]; cnt++; } } } data->data[unit][port].max = max; data->data[unit][port].cnt = cnt; data->data[unit][port].avg = cnt ? avg / cnt : GIS_MIN_VALUE; } /* 通道的实时数据 (自动 / 手动) 降噪的计算处理. */ void _gis_denoise(uint8_t unit, uint8_t port) { pd_prps_t *data = &pd_data.real; int16_t *buf = NULL; int16_t *buf_real = NULL; uint8_t pf_cnt = 0; uint8_t i = 0; uint16_t manual_noise_reduction = 0; int16_t manual_noise_level = 0; int16_t noise_level = 0; int32_t avg = 0; int32_t phase_avg = 0; int32_t temp = 0; /* 噪声传感器在关联降噪中运算. */ if (PD_SEN_TYPE_NOISE == pd_config.port_config[unit][port].config.sensor_type) { return; } for(pf_cnt = 0; pf_cnt < PD_POWER_FRE; pf_cnt++) { /* 计算平均值. */ buf = &dau[unit]->port_state[port].prps[pf_cnt << 7]; buf_real = &data->data[unit][port].data[pf_cnt << 7]; phase_avg = 0; for(i = 0; i < PD_PHASE_NUM; i++) { if (buf[i] < GIS_MIN_VALUE) { buf_real[i] = GIS_MIN_VALUE; } else { buf_real[i] = buf[i]; } phase_avg += buf_real[i]; } avg += phase_avg; phase_avg = (phase_avg / PD_PHASE_NUM); noise_level = phase_avg + pd_config.port_config[unit][port].config.noise_reduction; // 普通降噪水平 默认:30 单位:0.1dBm /* 未配置通道类型的不再进行下去. */ if (pd_config.port_config[unit][port].config.sensor_type != PD_SEN_TYPE_SIG && pd_config.port_config[unit][port].config.sensor_type != PD_SEN_TYPE_SIG_NOISE) { continue; } /* 降噪处理. */ if (100 == pd_config.port_config[unit][port].config.env_noise) // 自动降噪. { temp = phase_avg - GIS_MIN_VALUE; /* 低于平均值的不显示, 低于普通降噪水平的减去平均值, 余下的原值显示. */ for(i = 0; i < PD_PHASE_NUM; i++) { if (buf_real[i] <= phase_avg) { buf_real[i] = GIS_MIN_VALUE; } else if(buf_real[i] <= noise_level) { buf_real[i] -= temp; } } } else if(0 == pd_config.port_config[unit][port].config.env_noise) // 不降噪. { NULL; } else // 人工降噪. { manual_noise_reduction = pd_config.port_config[unit][port].config.env_noise; if (manual_noise_reduction > 800) { manual_noise_reduction = 800; manual_noise_level = 0; } else { manual_noise_level = GIS_MIN_VALUE + manual_noise_reduction; } for(i = 0; i < PD_PHASE_NUM; i++) { /* 手动降噪水平小于普通降噪水平, 需要考虑降噪水平, 否则不考虑普通降噪水平. */ if (manual_noise_level < noise_level) { /* 低于手动降噪水平的不显示, 低于普通降噪水平的减去手动降噪水平, 余下的原值显示. */ if (buf_real[i] <= manual_noise_level) { buf_real[i] = GIS_MIN_VALUE; } else if( buf_real[i] <= noise_level) { buf_real[i] -= manual_noise_reduction; } } else { /* 低于手动降噪水平的不显示, 余下的原值显示. */ if (buf_real[i] <= manual_noise_level) { buf_real[i] = GIS_MIN_VALUE; } } } } } /* 数据统计. */ data->data[unit][port].avg_o = avg / PD_PRPS_NUM; } /* 通道的实时数据关联降噪的计算处理. */ void _gis_denoise_relevance(uint8_t unit, uint8_t port) { pd_prps_t *data = &pd_data.real; int16_t *buf = NULL; int16_t *buf_real = NULL; int16_t *buf_noise = NULL; uint8_t unit_r = 0; // 关联降噪的单元. uint8_t port_r = 0; // 关联降噪的端口. uint8_t pf_cnt = 0; uint8_t i = 0; int16_t noise_level = 0; int32_t avg = 0; int32_t phase_avg = 0; if (pd_config.port_config[unit][port].config.sensor_type != PD_SEN_TYPE_NOISE) { return; } /* 噪声通道处理. */ for(pf_cnt = 0; pf_cnt < PD_POWER_FRE; pf_cnt++) { /* 左移 7 位正好是乘以 128(PD_PHASE_NUM). */ buf = &dau[unit]->port_state[port].prps[pf_cnt << 7]; buf_real = &data->data[unit][port].data[pf_cnt << 7]; phase_avg = 0; for(i = 0; i < PD_PHASE_NUM; i++) { if (buf[i] < GIS_MIN_VALUE) { buf_real[i] = GIS_MIN_VALUE; } else { buf_real[i] = buf[i]; } phase_avg += buf[i]; } avg += phase_avg; phase_avg = (phase_avg / PD_PHASE_NUM); noise_level = phase_avg + pd_config.port_config[unit][port].config.noise_reduction; // 普通降噪水平 默认:30 单位:0.1dBm for(unit_r = 0; unit_r < PD_DAU_SUM; unit_r++) { if (!dau[unit_r]) { continue; } for(port_r = 0; port_r < dau[unit_r]->port_num; port_r++) { if (pd_config.port_config[unit_r][port_r].config.sensor_type != PD_SEN_TYPE_SIG_NOISE) { continue; } buf_noise = &data->data[unit][port].data[pf_cnt << 7]; buf = &data->data[unit_r][port_r].data[pf_cnt << 7]; /* 噪声通道工频内的第一值比噪声通道的平均降噪等级还要大. */ if (buf_noise[0] > noise_level) { if (pf_cnt > 0) { data->data[unit_r][port_r].data[(pf_cnt << 7) - 1] = GIS_MIN_VALUE; } buf[0] = GIS_MIN_VALUE; buf[1] = GIS_MIN_VALUE; } if (buf_noise[PD_PHASE_NUM - 1] > noise_level) { if (pf_cnt < 49) { buf[PD_PHASE_NUM] = GIS_MIN_VALUE; } buf[PD_PHASE_NUM - 1] = GIS_MIN_VALUE; buf[PD_PHASE_NUM - 2] = GIS_MIN_VALUE; } for(i = 1; i < PD_PHASE_NUM - 1; i++) { if (buf_noise[i] > noise_level) { buf[i-1] = GIS_MIN_VALUE; buf[i ] = GIS_MIN_VALUE; buf[i+1] = GIS_MIN_VALUE; } } } } } /* 数据统计. */ data->data[unit][port].avg_o = avg / PD_PRPS_NUM; } /* 通道的实时数据统计信息. */ void _gis_denoise_statistics(uint8_t unit, uint8_t port) { pd_prps_data_t *real_data = &pd_data.real.data[unit][port]; int16_t *buf = NULL; int16_t noise_level = 0; int32_t avg = 0; uint8_t pf_cnt = 0; uint8_t i = 0; /* 初始化原始值. */ if (pd_config.port_config[unit][port].config.env_noise > 0) { noise_level = GIS_MIN_VALUE + pd_config.port_config[unit][port].config.noise_reduction; } else { noise_level = -790; } real_data->max = GIS_MIN_VALUE; real_data->cnt = 0; for(i = 0; i < PD_PHASE_NUM; i++) { real_data->phase_max[i] = GIS_MIN_VALUE; real_data->phase_sum[i] = 0; real_data->phase_cnt[i] = 0; } /* 数值的计算 最大值, 平均值, 放电次数. */ for(pf_cnt = 0; pf_cnt < PD_POWER_FRE; pf_cnt++) { buf = &real_data->data[pf_cnt << 7]; 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] > noise_level) { real_data->phase_sum[i] += buf[i]; real_data->phase_cnt[i]++; } } } 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] : GIS_MIN_VALUE; } real_data->avg = real_data->cnt ? avg / real_data->cnt : GIS_MIN_VALUE; } /* 通道事件计算. */ void _gis_event(uint8_t unit, uint8_t port) { pd_prps_data_t *real_data = &pd_data.real.data[unit][port]; pd_event_t *event = &pd_data.event[unit][port]; int16_t *buf = NULL; int16_t event_thr = 0; uint8_t pf_cnt = 0; uint8_t i = 0; /* 只处理信号传感器. */ if (pd_config.port_config[unit][port].config.sensor_type != PD_SEN_TYPE_SIG && pd_config.port_config[unit][port].config.sensor_type != PD_SEN_TYPE_SIG_NOISE) { return; } event_thr = pd_config.port_config[unit][port].config.event_threshold + real_data->avg_o; event->max = GIS_MIN_VALUE; event->avg = 0; event->cnt = 0; for(i = 0; i < PD_PHASE_NUM; i++) { event->phase_max[i] = GIS_MIN_VALUE; event->phase_sum[i] = 0; event->phase_cnt[i] = 0; } /* 计算超过阈值的放电次数. */ for(pf_cnt = 0; pf_cnt < PD_POWER_FRE; pf_cnt++) { buf = &real_data->data[pf_cnt << 7]; for(i = 0; i < PD_PHASE_NUM; i++) { if (buf[i] > event->phase_max[i]) { event->phase_max[i] = buf[i]; } if (buf[i] > event_thr) { event->phase_sum[i] += buf[i]; event->phase_cnt[i]++; } } } for(i = 0; i < PD_PHASE_NUM; i++) { if (event->phase_max[i] > event->max) { event->max = event->phase_max[i]; } event->avg += event->phase_sum[i]; event->cnt += event->phase_cnt[i]; event->phase_avg[i] = event->phase_cnt[i] ? event->phase_sum[i] / event->phase_cnt[i] : GIS_MIN_VALUE; } event->avg = event->cnt ? event->avg / event->cnt : GIS_MIN_VALUE; } void _gis_trend(uint8_t unit, uint8_t port, uint16_t trend_sec) { pd_trend_data_t *trend_data = &pd_data.trend.data[unit][port]; pd_prps_data_t *real_data = &pd_data.real.data[unit][port]; dau_t *dau_node = dau[unit]; int64_t phase_cmp = 0x8000000000000000; uint8_t phase_cmp_idx = 0; uint8_t i = 0; /* 初始化数据. */ if (1 == trend_sec) { pd_data.trend.index = dau_ctrl.trend_idx++; pd_data.trend.utc = pd_data.real.utc; trend_data->noise = 0; trend_data->max = GIS_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] = GIS_MIN_VALUE; trend_data->phase_cnt[i] = 0; } } /* 填充数据. */ 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; /* 计算数据. */ if (trend_sec >= pd_config.config.trend_period * 60) { 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] : GIS_MIN_VALUE; /* 查找最大放电周期. */ if (trend_data->phase_cnt[i] && trend_data->phase_sum[i] > phase_cmp) { phase_cmp_idx = i; phase_cmp = trend_data->phase_sum[i]; } } trend_data->phase = 360 * phase_cmp_idx / PD_PHASE_NUM ; // 放电相位 trend_data->avg = trend_data->cnt ? trend_data->avg / trend_data->cnt : GIS_MIN_VALUE; trend_data->cnt = trend_data->cnt / trend_sec; // 每秒钟的脉冲计数值 trend_data->noise = trend_data->noise / (10 * trend_sec) ; // 趋势数据中的底噪值: 单位 dBm. trend_data->event_cnt = dau_ctrl.event_index[unit][port] - dau_ctrl.trend_event_index[unit][port]; /* 更新索引. */ dau_ctrl.trend_event_index[unit][port] = dau_ctrl.event_index[unit][port]; } } /* Interface functions -------------------------------------------------------*/ #endif /************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/