Files
kunlun/app/brm/src/iot_brm_proto_devadp_645_ext.c
2024-09-28 14:24:04 +08:00

899 lines
31 KiB
C
Executable File

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
/* os shim includes */
#include "os_types_api.h"
#include "os_mem_api.h"
#include "iot_io_api.h"
/* common includes */
#include "iot_utils_api.h"
#include "iot_errno_api.h"
#include "iot_bitmap_api.h"
#include "iot_sg_sta_drv_api.h"
#include "iot_sg_ext_api.h"
#include "iot_module_api.h"
#include "iot_brm_rtc.h"
#include "iot_brm_adp.h"
#include "iot_brm_proto_devadp_645_ext.h"
#include "proto_645.h"
#include "proto_645_vendor.h"
#include "iot_brm_common.h"
#include "iot_brm_rec.h"
#if (IOT_BRM_ENABLE && PLC_SUPPORT_STA_ROLE)
#if BRM_PROTO_645_EXT_DEBUG
#define PROTO_645_EXT_LOG_BUF_LEN 1024
static char proto_645_ext_log_buf[PROTO_645_EXT_LOG_BUF_LEN] = {0};
void proto_645_ext_data_print(const char* str, uint8_t* buf,
uint32_t len)
{
uint32_t offset = 0;
offset = iot_sprintf(proto_645_ext_log_buf, "%s[len:%d]", str, len);
for (uint32_t i = 0; i < len; ++i) {
offset += iot_sprintf(proto_645_ext_log_buf + offset, "%02X ", buf[i]);
if (PROTO_645_EXT_LOG_BUF_LEN <= offset + 4) {
break;
}
}
proto_645_ext_log_buf[offset] = 0;
iot_cus_printf("%s\n", proto_645_ext_log_buf);
}
#else
#define proto_645_ext_data_print(str, buf, len)
#endif
/* limit of args. */
#define PROTO_645_EXT_SECONDS_PER_MIN (60)
#define PROTO_645_EXT_MINUTES_PER_HOUR (60)
#define PROTO_645_EXT_HOURS_PER_DAY (24)
#define PROTO_645_EXT_DAYS_PER_MONTH (31)
#define PROTO_645_EXT_MONTHS_PER_YEAR (12)
#define PROTO_645_EXT_YEARS_PER_CENTURY (100)
#define PROTO_645_EXT_EVENT_COUNTER_LIMIT (511)
#define PROTO_645_EXT_EVENT_REQ_NUM_LIMIT (5)
#define SECONDS_PER_SEVEN_POINT_FIVE_MINUTES (15*30)
/* Externally defined function. */
extern uint32_t iot_smart_meter_get_mac_addr_reversed(uint8_t *resp_addr,
uint8_t len);
/* transfer the event type from local type to host type*/
static uint8_t proto_645_ext_event_adp_to_meter(uint32_t event_type)
{
switch(event_type) {
case DM_EVENT_DEV_POWER_ON:
return PROTO_645_EXT_EVENT_DEV_POWER_ON;
case DM_EVENT_DEV_POWER_OFF:
return PROTO_645_EXT_EVENT_DEV_POWER_OFF;
case DM_EVENT_DEV_WORK_START:
return PROTO_645_EXT_EVENT_DEV_WORK_START;
case DM_EVENT_DEV_WORK_STOP:
return PROTO_645_EXT_EVENT_DEV_WORK_STOP;
case DM_EVENT_DEV_TRAP_START:
return PROTO_645_EXT_EVENT_DEV_TRAP_START;
case DM_EVENT_DEV_TRAP_STOP:
return PROTO_645_EXT_EVENT_DEV_TRAP_STOP;
default:
return PROTO_645_EXT_EVENT_INVALID;
}
return PROTO_645_EXT_EVENT_INVALID;
}
/**
* @brief proto_645_ext_handle_month_bcd_to_byte() - Handles month transitions
* from bcd to byte.
* @param value: Data that needs to be transformed.
*/
static inline uint8_t
proto_645_ext_handle_month_bcd_to_byte(uint8_t value)
{
return ((value >> 4) & 0x01) * 10 + (value & 0x0F);
}
/**
* @brief proto_645_ext_handle_month_byte_to_bcd() - Handles month transitions
* from byte to bcd.
* @param value: First data that needs to be transformed.
* @param week: Second data that needs to be transformed.
*/
static inline uint8_t
proto_645_ext_handle_month_byte_to_bcd(uint8_t value,
uint8_t week)
{
return ((((value / 10) << 4) + (value % 10)) | (week << 5));
}
static inline void proto_645_ext_correct_time_bcd_to_byte(
proto_645_ext_corr_time_t *tm, iot_time_tm_t *time)
{
time->tm_year = iot_bcd_to_byte(tm->year) + 2000;
time->tm_mon = proto_645_ext_handle_month_bcd_to_byte(tm->month);
time->tm_mday = iot_bcd_to_byte(tm->day);
time->tm_hour = iot_bcd_to_byte(tm->hour);
time->tm_min = iot_bcd_to_byte(tm->minute);
time->tm_sec = iot_bcd_to_byte(tm->second);
}
static inline void proto_645_ext_correct_time_byte_to_bcd(uint32_t tm,
proto_645_ext_corr_time_t *time)
{
iot_time_tm_t rtc_tm = {0};
iot_brm_time_to_rtctime(tm, &rtc_tm);
time->year = iot_byte_to_bcd(rtc_tm.tm_year - 2000);
time->month = proto_645_ext_handle_month_byte_to_bcd(rtc_tm.tm_mon, 0);
time->day = iot_byte_to_bcd(rtc_tm.tm_mday);
time->hour = iot_byte_to_bcd(rtc_tm.tm_hour);
time->minute = iot_byte_to_bcd(rtc_tm.tm_min);
time->second = iot_byte_to_bcd(rtc_tm.tm_sec);
}
/**
* @brief proto_645_ext_power_byte_to_bcd() - Power format from byte to bcd.
* @param power: The power value to be converted, the unit is 0.1W.
* @param p_07: The power format of bcd, the unit is kW.
*/
static inline void proto_645_ext_power_byte_to_bcd(
int32_t power, proto_645_07_ext_p_t *p_07)
{
int32_t power_tmp = power;
if (power_tmp < 0) {
p_07->s = 1;
power_tmp *= -1;
}
if (power_tmp / 10000 >= 40) {
power_tmp = power / 10;
p_07->d = 1;
} else {
p_07->d = 0;
}
p_07->ten_thousandth = (power_tmp % 10) & 0xf;
p_07->thousandth = ((power_tmp / 10) % 10) & 0xf;
p_07->hundredth = ((power_tmp / 100) % 10) & 0xf;
p_07->tenth = ((power_tmp / 1000) % 10) & 0xf;
p_07->one = ((power_tmp / 10000) % 10) & 0xf;
p_07->ten = ((power_tmp / 100000) % 10) & 0xf;
return;
}
/**
* @brief proto_645_ext_power_bcd_to_byte() - Power format from bcd to byte.
* @param p_07: The power format of bcd, the unit is kW.
* @return: The power value format of byte, the unit is 0.1W.
*/
static inline int32_t proto_645_ext_power_bcd_to_byte(
proto_645_07_ext_p_t *p_07)
{
int32_t power = 0;
power = p_07->ten_thousandth +
p_07->thousandth * 10 +
p_07->hundredth * 100 +
p_07->tenth * 1000 +
p_07->one * 10000 +
p_07->ten * 100000;
if(1 == p_07->d) {
power *= 10;
}
if(1 == p_07->s) {
power *= -1;
}
return power;
}
/**
* @brief proto_645_ext_fill_invalid_field() - Filled the invalid field.
* @param data: The data that need to been filled.
* @param len: The length of the data field.
*/
static inline void proto_645_ext_fill_invalid_field(void *data, uint32_t len)
{
os_mem_set(data, 0xff, len);
}
/**
* @brief proto_645_ext_fill_invalid_value() - Filled the invalid value(0xee).
* @param data: The data that need to been filled.
* @param len: The length of the data field.
*/
static inline void proto_645_ext_fill_invalid_value(void *data, uint32_t len)
{
os_mem_set(data, 0xee, len);
}
/* request read current and power limit parameters */
void proto_handle_645_ext_req_read_threshold(uint8_t* out_buf, uint8_t *out_len)
{
proto_645_ext_resp_threashold_t *power_threshold = NULL;
iot_brm_threshold_t *threshold = iot_brm_adp_get_threshold();
proto_645_2007_di_to_byte(PROTO_645_EXT_CURRENT_AND_POWER_THR_DI, out_buf);
*out_len = PROTO_645_2007_DI_LEN + sizeof(proto_645_ext_resp_threashold_t);
power_threshold =
(proto_645_ext_resp_threashold_t*)(out_buf + PROTO_645_2007_DI_LEN);
iot_cus_printf("[brmadp] %s i_standby=%d, i_work=%d, p_trap=%d.\n",
__FUNCTION__, threshold->i_standby, threshold->i_work,
threshold->p_trap);
proto_645_sig_to_bcd(threshold->i_standby, PROTO_645_07_A_LEN,
(uint8_t*)(&(power_threshold->i_standby)));
proto_645_sig_to_bcd(threshold->i_work, PROTO_645_07_A_LEN,
(uint8_t*)(&(power_threshold->i_work)));
proto_645_ext_power_byte_to_bcd(threshold->p_trap,
&power_threshold->p_trap);
return;
}
/* request read counter of event in someday */
void proto_handle_645_ext_req_read_event_counter(uint8_t *payload,
uint8_t payload_len, uint8_t* out_buf, uint8_t *out_len)
{
uint32_t ts;
iot_time_tm_t tm= {0};
proto_645_ext_corr_time_t *event_tm;
proto_645_ext_resp_event_counter_t *event_cnt;
if((NULL == payload) ||
(sizeof(proto_645_ext_corr_time_t) != payload_len)) {
iot_cus_printf("[brmadp] %s len=%d err\n",__FUNCTION__, payload_len);
*out_len = 0;
return;
}
event_tm = (proto_645_ext_corr_time_t*)payload;
proto_645_ext_correct_time_bcd_to_byte(event_tm,&tm);
proto_645_2007_di_to_byte(PROTO_645_EXT_EVT_COUNTER_DI, out_buf);
*out_len = PROTO_645_2007_DI_LEN +
sizeof(proto_645_ext_resp_event_counter_t);
event_cnt = (proto_645_ext_resp_event_counter_t*)
(out_buf + PROTO_645_2007_DI_LEN);
os_mem_cpy(&event_cnt->start_time, event_tm,
sizeof(proto_645_ext_corr_time_t));
/* get counter record for the date */
tm.tm_sec = 0;
tm.tm_min = 0;
tm.tm_hour = 0;
ts = iot_brm_rtctime_to_time(&tm);
event_cnt->event_counter = iot_brm_read_adp_evt_daily_cnt(ts);
iot_cus_printf("read %d-%d-%d %d:%d:%d count=%d\n", tm.tm_year, tm.tm_mon,
tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, event_cnt->event_counter);
return;
}
void iot_brm_adp_trans_evt_to_resp(uint8_t *event, uint8_t *data)
{
iot_brm_rec_head_t *hdr = (iot_brm_rec_head_t*)event;;
iot_brm_load_record_t *rcd_data = (iot_brm_load_record_t*)hdr->data;
proto_645_ext_event_record_item_t *resp =
(proto_645_ext_event_record_item_t*)data;
iot_brm_meter_info_t *m_info = iot_brm_load_meter_info();
resp->type = proto_645_ext_event_adp_to_meter((uint8_t)rcd_data->event);
proto_645_ext_correct_time_byte_to_bcd(hdr->ts, &resp->etime);
/* voltage */
proto_645_unsig_to_bcd(rcd_data->v[IOT_BRM_PHASE_A-1], PROTO_645_V_LEN,
(uint8_t*)(&(resp->event_record_item.v.A)));
proto_645_unsig_to_bcd(rcd_data->v[IOT_BRM_PHASE_B-1], PROTO_645_V_LEN,
(uint8_t*)(&(resp->event_record_item.v.B)));
proto_645_unsig_to_bcd(rcd_data->v[IOT_BRM_PHASE_C-1], PROTO_645_V_LEN,
(uint8_t*)(&(resp->event_record_item.v.C)));
/* current */
proto_645_sig_to_bcd(rcd_data->i[IOT_BRM_PHASE_A-1], PROTO_645_07_A_LEN,
(uint8_t*)(&(resp->event_record_item.i.A)));
proto_645_sig_to_bcd(rcd_data->i[IOT_BRM_PHASE_B-1], PROTO_645_07_A_LEN,
(uint8_t*)(&(resp->event_record_item.i.B)));
proto_645_sig_to_bcd(rcd_data->i[IOT_BRM_PHASE_C-1], PROTO_645_07_A_LEN,
(uint8_t*)(&(resp->event_record_item.i.C)));
/* power */
proto_645_sig_to_bcd(rcd_data->p[IOT_BRM_PHASE_ALL], PROTO_645_07_P_LEN,
(uint8_t*)(&(resp->event_record_item.p.total)));
proto_645_sig_to_bcd(rcd_data->p[IOT_BRM_PHASE_A], PROTO_645_07_P_LEN,
(uint8_t*)(&(resp->event_record_item.p.A)));
proto_645_sig_to_bcd(rcd_data->p[IOT_BRM_PHASE_B], PROTO_645_07_P_LEN,
(uint8_t*)(&(resp->event_record_item.p.B)));
proto_645_sig_to_bcd(rcd_data->p[IOT_BRM_PHASE_C], PROTO_645_07_P_LEN,
(uint8_t*)(&(resp->event_record_item.p.C)));
/* power factor */
proto_645_sig_to_bcd(rcd_data->f[IOT_BRM_PHASE_ALL], PROTO_645_07_PF_LEN,
(uint8_t*)(&(resp->event_record_item.pf.total)));
proto_645_sig_to_bcd(rcd_data->f[IOT_BRM_PHASE_A], PROTO_645_07_PF_LEN,
(uint8_t*)(&(resp->event_record_item.pf.A)));
proto_645_sig_to_bcd(rcd_data->f[IOT_BRM_PHASE_B], PROTO_645_07_PF_LEN,
(uint8_t*)(&(resp->event_record_item.pf.B)));
proto_645_sig_to_bcd(rcd_data->f[IOT_BRM_PHASE_C], PROTO_645_07_PF_LEN,
(uint8_t*)(&(resp->event_record_item.pf.C)));
/* bottom value */
iot_brm_e_to_proto_645(rcd_data->w, m_info->var.ec,
(uint8_t*)(&(resp->event_record_item.w)));
iot_cus_printf("resp type=%d tm==%lu "
"%02x-%02x-%02x %02x:%02x:%02x type=%d\n", resp->type, hdr->ts,
resp->etime.year, resp->etime.month,
resp->etime.day, resp->etime.hour,
resp->etime.minute, resp->etime.second);
iot_cus_printf("[brmadp]resp voltage=[%d %d %d], energe[%d]\n",
rcd_data->v[IOT_BRM_PHASE_A-1],
rcd_data->v[IOT_BRM_PHASE_B-1],
rcd_data->v[IOT_BRM_PHASE_C-1],
rcd_data->w);
}
void iot_brm_adp_load_resp_init(uint8_t *data, uint32_t ts, uint8_t cnt)
{
uint8_t idx = 0;
uint8_t *data_pos = data;
proto_645_ext_load_diagram_item_t *resp = NULL;
for (idx = 0; idx < cnt; idx++) {
resp =(proto_645_ext_load_diagram_item_t*)data_pos;
os_mem_set(data_pos, 0xEE, sizeof(*resp));
proto_645_ext_correct_time_byte_to_bcd(ts + idx * 900, &resp->etime);
data_pos += sizeof(*resp);
}
}
void iot_brm_adp_trans_load_to_resp(uint8_t *load, uint8_t *data)
{
iot_brm_rec_head_t *hdr = (iot_brm_rec_head_t*)load;;
iot_brm_curve_entry_t *rcd_data = (iot_brm_curve_entry_t*)hdr->data;
proto_645_ext_load_diagram_item_t *resp =
(proto_645_ext_load_diagram_item_t*)data;
iot_brm_meter_info_t *m_info = iot_brm_load_meter_info();
proto_645_ext_correct_time_byte_to_bcd(hdr->ts, &resp->etime);
/* voltage */
proto_645_unsig_to_bcd(rcd_data->v[IOT_BRM_PHASE_A-1], PROTO_645_V_LEN,
(uint8_t*)(&(resp->load_diagram_item.v.A)));
proto_645_unsig_to_bcd(rcd_data->v[IOT_BRM_PHASE_B-1], PROTO_645_V_LEN,
(uint8_t*)(&(resp->load_diagram_item.v.B)));
proto_645_unsig_to_bcd(rcd_data->v[IOT_BRM_PHASE_C-1], PROTO_645_V_LEN,
(uint8_t*)(&(resp->load_diagram_item.v.C)));
/* current */
proto_645_sig_to_bcd(rcd_data->i[IOT_BRM_PHASE_A-1], PROTO_645_07_A_LEN,
(uint8_t*)(&(resp->load_diagram_item.i.A)));
proto_645_sig_to_bcd(rcd_data->i[IOT_BRM_PHASE_B-1], PROTO_645_07_A_LEN,
(uint8_t*)(&(resp->load_diagram_item.i.B)));
proto_645_sig_to_bcd(rcd_data->i[IOT_BRM_PHASE_C-1], PROTO_645_07_A_LEN,
(uint8_t*)(&(resp->load_diagram_item.i.C)));
/* power */
proto_645_sig_to_bcd(rcd_data->p[IOT_BRM_PHASE_ALL], PROTO_645_07_P_LEN,
(uint8_t*)(&(resp->load_diagram_item.p.total)));
proto_645_sig_to_bcd(rcd_data->p[IOT_BRM_PHASE_A], PROTO_645_07_P_LEN,
(uint8_t*)(&(resp->load_diagram_item.p.A)));
proto_645_sig_to_bcd(rcd_data->p[IOT_BRM_PHASE_B], PROTO_645_07_P_LEN,
(uint8_t*)(&(resp->load_diagram_item.p.B)));
proto_645_sig_to_bcd(rcd_data->p[IOT_BRM_PHASE_C], PROTO_645_07_P_LEN,
(uint8_t*)(&(resp->load_diagram_item.p.C)));
/* power factor */
proto_645_sig_to_bcd(rcd_data->pf[IOT_BRM_PHASE_ALL], PROTO_645_07_PF_LEN,
(uint8_t*)(&(resp->load_diagram_item.pf.total)));
proto_645_sig_to_bcd(rcd_data->pf[IOT_BRM_PHASE_A], PROTO_645_07_PF_LEN,
(uint8_t*)(&(resp->load_diagram_item.pf.A)));
proto_645_sig_to_bcd(rcd_data->pf[IOT_BRM_PHASE_B], PROTO_645_07_PF_LEN,
(uint8_t*)(&(resp->load_diagram_item.pf.B)));
proto_645_sig_to_bcd(rcd_data->pf[IOT_BRM_PHASE_C], PROTO_645_07_PF_LEN,
(uint8_t*)(&(resp->load_diagram_item.pf.C)));
/* bottom value */
iot_brm_e_to_proto_645(rcd_data->ept_pos[IOT_BRM_PHASE_ALL],
m_info->var.ec, (uint8_t*)(&(resp->load_diagram_item.w)));
iot_cus_printf("resp tm==%lu "
"%02x-%02x-%02x %02x:%02x:%02x type=%d\n", hdr->ts,
resp->etime.year, resp->etime.month,
resp->etime.day, resp->etime.hour,
resp->etime.minute, resp->etime.second);
iot_cus_printf("[brmadp]resp voltage=%d %d %d\n",
rcd_data->v[IOT_BRM_PHASE_A-1],
rcd_data->v[IOT_BRM_PHASE_B-1],
rcd_data->v[IOT_BRM_PHASE_C-1]);
}
/* request read record of event in someday */
void proto_handle_645_ext_req_read_event_record(uint8_t *payload,
uint8_t payload_len, uint8_t* out_buf, uint8_t *out_len)
{
uint32_t ts;
iot_time_tm_t tm= {0};
iot_pkt_t *pkt = NULL;
iot_brm_adp_cmd_event_record_query_t *event;
proto_645_ext_resp_event_record_t *resp_event;
if((NULL == payload) ||
(sizeof(iot_brm_adp_cmd_event_record_query_t) != payload_len)) {
iot_cus_printf("[brmadp] %s len=%d err\n",__FUNCTION__, payload_len);
*out_len = 0;
return;
}
event = (iot_brm_adp_cmd_event_record_query_t*)payload;
/* query record event */
proto_645_ext_correct_time_bcd_to_byte(&event->start_time, &tm);
tm.tm_sec = 0;
tm.tm_min = 0;
tm.tm_hour = 0;
ts = iot_brm_rtctime_to_time(&tm);
iot_cus_printf("read_tm=%d-%d-%d %d:%d:%d start_idx=%d count=%d\n",
tm.tm_year,tm.tm_mon,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec,
event->start_idx, event->record_num);
proto_645_2007_di_to_byte(PROTO_645_EXT_EVT_RECORD_DI, out_buf);
*out_len = PROTO_645_2007_DI_LEN +
sizeof(proto_645_ext_resp_event_record_t);
resp_event =
(proto_645_ext_resp_event_record_t*)(out_buf + PROTO_645_2007_DI_LEN);
/* get record date */
resp_event->record_num = iot_brm_adp_evt_load(ts, event->start_idx,
event->record_num, &pkt);
resp_event->record_start_index = event->start_idx;
iot_cus_printf("[brmadp]resp %s start=%d counter=%d\n",__FUNCTION__,
resp_event->record_start_index, resp_event->record_num);
if (NULL != pkt) {
os_mem_cpy(resp_event->record_data, iot_pkt_data(pkt),
iot_pkt_data_len(pkt));
*out_len += iot_pkt_data_len(pkt);
iot_pkt_free(pkt);
}
return;
}
/* request read diagram of load */
void proto_handle_645_ext_req_read_load_diagram(uint8_t *payload,
uint8_t payload_len, uint8_t* out_buf, uint8_t *out_len)
{
uint32_t ts;
iot_time_tm_t tm= {0};
iot_pkt_t *pkt = NULL;
uint8_t read_cnt;
iot_brm_adp_cmd_load_record_query_t *read_data;
proto_645_ext_resp_load_diagram_t *rsp_data;
if((NULL == payload) ||
(sizeof(iot_brm_adp_cmd_load_record_query_t) != payload_len)) {
iot_cus_printf("[brmadp] %s len=%d err\n",__FUNCTION__, payload_len);
*out_len = 0;
return;
}
read_data = (iot_brm_adp_cmd_load_record_query_t*)payload;
proto_645_ext_correct_time_bcd_to_byte(&read_data->start_time, &tm);
read_cnt = read_data->recode_counter;
ts = iot_brm_rtctime_to_time(&tm);
if (ts % (15 * 60) != 0) {
ts = (ts / 900 + 1) * 900;
}
iot_brm_printf("%s ts %lu, time %lu-%lu-%lu %lu:%lu:%lu\n",
__FUNCTION__, ts, tm.tm_year, tm.tm_mon, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
*out_len = PROTO_645_2007_DI_LEN +
sizeof(proto_645_ext_resp_load_diagram_t);
proto_645_2007_di_to_byte(PROTO_645_EXT_LOAD_DIAGRAM_DI, out_buf);
rsp_data =
(proto_645_ext_resp_load_diagram_t*)(out_buf + PROTO_645_2007_DI_LEN);
rsp_data->record_num = iot_brm_adp_load_data(ts, read_cnt, &pkt);
iot_cus_printf("[brmadp]%s resp load counter=%d\n",__FUNCTION__,
rsp_data->record_num);
if (NULL != pkt) {
os_mem_cpy(rsp_data->load_diagram, iot_pkt_data(pkt),
iot_pkt_data_len(pkt));
*out_len += iot_pkt_data_len(pkt);
iot_pkt_free(pkt);
}
return;
}
/* request read real time data */
void proto_handle_645_ext_req_read_realtime_load_data(uint8_t* out_buf,
uint8_t *out_len)
{
proto_645_ext_realtime_load_data_t *load_data;
iot_time_tm_t tm = {0};
uint8_t week = 0;
iot_brm_meter_info_t *m_info = NULL;
iot_cus_printf("[brmadp]read real time data\n");
*out_len = PROTO_645_2007_DI_LEN + sizeof(proto_645_ext_realtime_load_data_t);
load_data =
(proto_645_ext_realtime_load_data_t*)(out_buf + PROTO_645_2007_DI_LEN);
proto_645_2007_di_to_byte(PROTO_645_EXT_REAL_TIME_DATA_DI, out_buf);
iot_brm_rtc_get_time(&tm, &week);
load_data->etime.second = iot_byte_to_bcd(tm.tm_sec);
load_data->etime.minute= iot_byte_to_bcd(tm.tm_min);
load_data->etime.hour = iot_byte_to_bcd(tm.tm_hour);
load_data->etime.day = iot_byte_to_bcd(tm.tm_mday);
load_data->etime.month = iot_byte_to_bcd(tm.tm_mon);
load_data->etime.year = iot_byte_to_bcd(tm.tm_year - 2000);
m_info = iot_brm_load_meter_info();
/* voltage info */
proto_645_unsig_to_bcd(m_info->var.v[IOT_BRM_PHASE_A - 1],
PROTO_645_V_LEN, (uint8_t *)(&(load_data->realtime_load_data.v.A)));
proto_645_unsig_to_bcd(m_info->var.v[IOT_BRM_PHASE_B - 1],
PROTO_645_V_LEN, (uint8_t *)(&(load_data->realtime_load_data.v.B)));
proto_645_unsig_to_bcd(m_info->var.v[IOT_BRM_PHASE_C - 1],
PROTO_645_V_LEN, (uint8_t *)(&(load_data->realtime_load_data.v.C)));
/* current info */
proto_645_sig_to_bcd(m_info->var.i[IOT_BRM_PHASE_A - 1],
PROTO_645_07_A_LEN, (uint8_t *)(&(load_data->realtime_load_data.i.A)));
proto_645_sig_to_bcd(m_info->var.i[IOT_BRM_PHASE_B - 1],
PROTO_645_07_A_LEN, (uint8_t *)(&(load_data->realtime_load_data.i.B)));
proto_645_sig_to_bcd(m_info->var.i[IOT_BRM_PHASE_C - 1],
PROTO_645_07_A_LEN, (uint8_t *)(&(load_data->realtime_load_data.i.C)));
/* active power infor */
proto_645_sig_to_bcd(m_info->var.p[IOT_BRM_PHASE_ALL], PROTO_645_07_P_LEN,
(uint8_t *)(&(load_data->realtime_load_data.p.total)));
proto_645_sig_to_bcd(m_info->var.p[IOT_BRM_PHASE_A], PROTO_645_07_P_LEN,
(uint8_t *)(&(load_data->realtime_load_data.p.A)));
proto_645_sig_to_bcd(m_info->var.p[IOT_BRM_PHASE_B], PROTO_645_07_P_LEN,
(uint8_t *)(&(load_data->realtime_load_data.p.B)));
proto_645_sig_to_bcd(m_info->var.p[IOT_BRM_PHASE_C], PROTO_645_07_P_LEN,
(uint8_t *)(&(load_data->realtime_load_data.p.C)));
/* power factor infor */
proto_645_sig_to_bcd(m_info->var.pf[IOT_BRM_PHASE_ALL], PROTO_645_07_PF_LEN,
(uint8_t *)(&(load_data->realtime_load_data.pf.total)));
proto_645_sig_to_bcd(m_info->var.pf[IOT_BRM_PHASE_A], PROTO_645_07_PF_LEN,
(uint8_t *)(&(load_data->realtime_load_data.pf.A)));
proto_645_sig_to_bcd(m_info->var.pf[IOT_BRM_PHASE_B], PROTO_645_07_PF_LEN,
(uint8_t *)(&(load_data->realtime_load_data.pf.B)));
proto_645_sig_to_bcd(m_info->var.pf[IOT_BRM_PHASE_C], PROTO_645_07_PF_LEN,
(uint8_t *)(&(load_data->realtime_load_data.pf.C)));
/* meter base value */
iot_brm_e_to_proto_645(m_info->e_t.ept_pos[0], m_info->var.ec,
(uint8_t *)(&(load_data->realtime_load_data.w)));
return;
}
/* request write current and power limit parameters */
void proto_handle_645_ext_req_write_threshold(uint8_t* data, uint8_t len)
{
proto_645_ext_resp_threashold_t *set_para;
iot_brm_threshold_t save_para = {0};
if((NULL == data) || (sizeof(proto_645_ext_resp_threashold_t) != len)) {
iot_cus_printf("[brmadp] %s len=%d err\n", __FUNCTION__, len);
return;
}
set_para = (proto_645_ext_resp_threashold_t*)data;
save_para.i_standby = proto_645_bcd_to_integer(
(uint8_t *)(&(set_para->i_standby)), PROTO_645_07_A_LEN, 1);
save_para.i_work = proto_645_bcd_to_integer(
(uint8_t *)(&(set_para->i_work)), PROTO_645_07_A_LEN, 1);
save_para.p_trap = proto_645_ext_power_bcd_to_byte(&set_para->p_trap);
iot_cus_printf("[brmadp] %s set threshold i_standby=%d, i_work=%d, "
"p_trap=%d.\n", __FUNCTION__, save_para.i_standby,
save_para.i_work, save_para.p_trap);
iot_brm_adp_threshold_save(&save_para);
return;
}
/* query count of indication event handler */
void proto_handle_645_ext_query_ind_evt_count(uint8_t* out_buf,
uint8_t *out_len)
{
uint16_t evt_cnt = 0;
proto_645_ext_resp_ind_event_cnt_t *resp = NULL;
proto_645_2007_di_to_byte(PROTO_645_EXT_EVT_IND_CNT_DI, out_buf);
*out_len = PROTO_645_2007_DI_LEN + sizeof(*resp);
evt_cnt = 1;
resp =
(proto_645_ext_resp_ind_event_cnt_t*)(out_buf + PROTO_645_2007_DI_LEN);
iot_cus_printf("[brmadp] %s ind_event count =%lu.\n",
__FUNCTION__, evt_cnt);
resp->count = evt_cnt;
resp->resv = 0;
return;
}
/* query indication event handler */
void proto_handle_645_ext_query_ind_evt(uint8_t* out_buf, uint8_t *out_len)
{
proto_645_ext_resp_read_ind_event_t *resp = NULL;
proto_645_ext_event_record_item_t *evt_data = NULL;
iot_pkt_t *pkt = NULL;
proto_645_2007_di_to_byte(PROTO_645_EXT_REQ_EVT_IND_DI, out_buf);
*out_len = PROTO_645_2007_DI_LEN + sizeof(*resp);
iot_cus_printf("[brmadp]report latest event record\n");
resp = (proto_645_ext_resp_read_ind_event_t *)(out_buf +
PROTO_645_2007_DI_LEN);
if (ERR_OK == iot_brm_adp_latest_evt_load(&pkt)) {
evt_data = (proto_645_ext_event_record_item_t *)iot_pkt_data(pkt);
resp->etime = evt_data->etime;
resp->event_record_item = evt_data->event_record_item;
resp->type = evt_data->type;
} else {
os_mem_set(out_buf, 0, *out_len);
}
if (NULL != pkt) {
iot_pkt_free(pkt);
}
return;
}
/* request write bottom value */
void proto_handle_645_ext_req_write_bottom_value(uint8_t* data, uint8_t len)
{
proto_645_ext_bottom_val_t *bottom_value;
uint32_t set_bot_val;
if((NULL == data) || (sizeof(proto_645_ext_bottom_val_t) != len)) {
iot_cus_printf("[brmadp] %s len=%d err\n", __FUNCTION__, len);
return;
}
bottom_value = (proto_645_ext_bottom_val_t*)data;
set_bot_val =
proto_645_bcd_to_integer((uint8_t*)(&(bottom_value->bottom_val)),
PROTO_645_07_ENERGY_DATA_LEN, 0);
iot_cus_printf("[brmadp] %s set bottom value=%d\n", __FUNCTION__,
set_bot_val);
iot_brm_adp_bottom_val_save(set_bot_val);
return;
}
/* handler extern brm adp write frame */
uint8_t iot_brm_proto_645_w_ext_data_hander(uint8_t *in_data,
uint8_t in_len, uint32_t di, uint8_t *len)
{
uint8_t err_code = PROTO_645_2007_ERR_OTHER;
uint8_t *set_data = in_data +
PROTO_645_2007_PASSWORD_LEN + PROTO_645_2007_OPERATOR_LEN;
in_len -= (PROTO_645_2007_PASSWORD_LEN + PROTO_645_2007_OPERATOR_LEN);
switch (di) {
case PROTO_645_EXT_CURRENT_AND_POWER_THR_DI:
{
proto_handle_645_ext_req_write_threshold(set_data, in_len);
*len = 0;
err_code = PROTO_645_2007_ERR_OK;
break;
}
case PROTO_645_EXT_METER_BOTTOM_VALUE_DI:
{
proto_handle_645_ext_req_write_bottom_value(set_data, in_len);
*len = 0;
err_code = PROTO_645_2007_ERR_OK;
break;
}
default:
break;
}
return err_code;
}
/* handler extern brm adp read frame */
uint8_t iot_brm_proto_645_r_ext_data_hander(uint8_t *in_data,
uint8_t in_len, uint8_t *out_buf, uint8_t *out_len)
{
uint8_t err_code = PROTO_645_2007_ERR_OTHER;
uint32_t di = proto_645_2007_byte_to_di(in_data);
uint8_t *payload = in_data + PROTO_645_2007_DI_LEN;
uint8_t payload_len = in_len - PROTO_645_2007_DI_LEN;
switch (di) {
case PROTO_645_EXT_CURRENT_AND_POWER_THR_DI:
{
proto_handle_645_ext_req_read_threshold(out_buf, out_len);
err_code = PROTO_645_2007_ERR_OK;
break;
}
case PROTO_645_EXT_EVT_COUNTER_DI:
{
proto_handle_645_ext_req_read_event_counter(payload, payload_len,
out_buf, out_len);
err_code = PROTO_645_2007_ERR_OK;
break;
}
case PROTO_645_EXT_EVT_RECORD_DI:
{
proto_handle_645_ext_req_read_event_record(payload, payload_len,
out_buf, out_len);
err_code = PROTO_645_2007_ERR_OK;
break;
}
case PROTO_645_EXT_LOAD_DIAGRAM_DI:
{
proto_handle_645_ext_req_read_load_diagram(payload, payload_len,
out_buf, out_len);
err_code = PROTO_645_2007_ERR_OK;
break;
}
case PROTO_645_EXT_REAL_TIME_DATA_DI:
{
proto_handle_645_ext_req_read_realtime_load_data(out_buf, out_len);
err_code = PROTO_645_2007_ERR_OK;
break;
}
case PROTO_645_EXT_READ_04400059_DI:
case PROTO_645_EXT_READ_0440005A_DI:
{
err_code = PROTO_645_2007_ERR_GO_OUT_FWD;
break;
}
case PROTO_645_EXT_EVT_IND_CNT_DI:
{
proto_handle_645_ext_query_ind_evt_count(out_buf, out_len);
err_code = PROTO_645_2007_ERR_OK;
break;
}
case PROTO_645_EXT_REQ_EVT_IND_DI:
{
proto_handle_645_ext_query_ind_evt(out_buf, out_len);
err_code = PROTO_645_2007_ERR_OK;
break;
}
default:
break;
}
return err_code;
}
uint8_t iot_brm_adp_read_ws_n01_humi_temp(iot_pkt_t *pkt)
{
uint8_t dir = 0xFF;
uint32_t di = 0xFFFFFFFF;
proto_modbus_read_humi_temp_t read_cmd = {0x1,0x3,0x0,0x0,0x2,0x0BC4};
uint8_t ret = ERR_FAIL;
if (ERR_OK == proto_645_pkt_check_handle(pkt, &dir, &di)) {
if (dir == PROTO_645_DIR_MASTER &&
di == PROTO_645_EXT_READ_04400059_DI) {
ret = ERR_OK;
iot_pkt_free(pkt);
pkt = iot_pkt_alloc(sizeof(read_cmd), IOT_BRM_MID);
if (pkt) {
iot_pkt_put(pkt, sizeof(read_cmd));
os_mem_cpy(iot_pkt_data(pkt), &read_cmd, sizeof(read_cmd));
}
}
}
return ret;
}
uint8_t iot_brm_adp_resp_ws_n01_humi_temp(iot_pkt_t* pkt)
{
uint8_t *data_ptr = NULL;
uint8_t ret = ERR_FAIL;
uint8_t local_addr[IOT_MAC_ADDR_LEN] = { 0 };
uint16_t payload_len = 0;
uint32_t frm_len = 0;
iot_pkt_t *resp_pkt = NULL;
proto_645_ext_resp_humi_temp_t *rpt_evt = NULL;
proto_modbus_resp_humi_temp_t *resp_cmd = NULL;
if (pkt) {
if (ERR_OK == proto_645_pkt_check_handle(pkt, NULL, NULL)) {
goto out;
}
resp_cmd = (proto_modbus_resp_humi_temp_t*)iot_pkt_data(pkt);
if (iot_pkt_data_len(pkt) != sizeof(*resp_cmd) ||
resp_cmd->len != sizeof(*rpt_evt)){
iot_cus_printf("[brmadp] recv humi_temp data length error!\n");
goto out;
}
resp_pkt = iot_pkt_alloc(PROTO_645_MAX_DATA_LEN, IOT_BRM_MID);
if (resp_pkt == NULL) {
iot_cus_printf("[brmadp] %s alloc pkt failed!\n", __FUNCTION__);
goto out;
}
iot_pkt_reserve(resp_pkt, IOT_SG_EXT_HEADROOM);
data_ptr = iot_pkt_data(resp_pkt) + sizeof(proto_645_header_t);
proto_645_2007_di_to_byte(
PROTO_645_EXT_READ_04400059_DI, data_ptr);
data_ptr += PROTO_645_2007_DI_FOR_WATTH_T_LEN;
rpt_evt = (proto_645_ext_resp_humi_temp_t *)data_ptr;
iot_data_reverse((uint8_t*)&resp_cmd->humi, sizeof(uint16_t)),
iot_data_reverse((uint8_t*)&resp_cmd->temp, sizeof(uint16_t));
proto_645_unsig_to_bcd(resp_cmd->humi, sizeof(uint16_t),
(uint8_t*)&rpt_evt->humi);
proto_645_unsig_to_bcd(resp_cmd->temp, sizeof(int16_t),
(uint8_t*)&rpt_evt->temp);
iot_cus_printf("[brmadp] resp humi=%x temp=%x\n",
rpt_evt->humi, rpt_evt->temp);
iot_brm_get_dev_addr(&local_addr[0]);
payload_len = PROTO_645_2007_DI_FOR_WATTH_T_LEN + sizeof(*rpt_evt);
data_ptr = iot_pkt_data(resp_pkt) + sizeof(proto_645_header_t);
frm_len =
proto_645_fill_frame(iot_pkt_data(resp_pkt), PROTO_645_2007_ID,
local_addr, PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
PROTO_645_FOLLOW_INVALID, PROTO_645_2007_FN_READ_DATA,
PROTO_645_INVALID_DI, payload_len, data_ptr);
iot_pkt_put(resp_pkt, frm_len);
proto_645_ext_data_print("resp cmd", iot_pkt_data(resp_pkt), frm_len);
iot_brm_send_resp_pkt(resp_pkt, iot_brm_data_owner_sg_app);
ret = ERR_OK;
}
out:
return ret;
}
#endif