BLE_TYQ_BJQ_CH32V303/bsp/src/bsp_ml307.c

1822 lines
67 KiB
C
Raw Normal View History

2024-12-03 10:24:55 +08:00
/*
* @Author: mbw
* @Date: 2024-11-30 15:46:21
* @LastEditors: mbw && 1600520629@qq.com
2024-12-16 15:35:19 +08:00
* @LastEditTime: 2024-12-15 17:09:30
2024-12-03 10:24:55 +08:00
* @FilePath: \ble_bjq_ch303rct6_ml307\bsp\src\bsp_ml307.c
2024-12-04 18:55:59 +08:00
* @Description:
*
* Copyright (c) 2024 by ${git_name_email}, All Rights Reserved.
2024-12-03 10:24:55 +08:00
*/
#include <at_device_ml307.h>
#include "drv_gpio.h"
#include "bsp_ml307.h"
#include "user_sys.h"
#include "bsp_flash.h"
#include "stddef.h"
#include "bsp_rtc.h"
2024-12-04 18:55:59 +08:00
#include "bsp_bt.h"
#include "bsp_mq.h"
2024-12-03 10:24:55 +08:00
#define LOG_TAG "ml307"
#include <at_log.h>
#if IOT_MODULE_SWITCH == 1
2024-12-05 16:57:19 +08:00
#define ML307_THREAD_STACK_SIZE (4096 + 2048)
#define ML307_RECV_THREAD_STACK_SIZE (4096 + 2048)
2024-12-03 10:24:55 +08:00
#define ML307_LIFE_THREAD_STACK_SIZE (1024)
#define ML307_THREAD_PRIORITY 25
#define ML307_THREAD_TICKS 50
#define ML307_RECV_THREAD_PRIORITY 24
#define ML307_RECV_THREAD_TICKS 10
#define ML307_LIFE_THREAD_PRIORITY 26
#define ML307_LIFE_THREAD_TICKS 10
// static rt_uint32_t ml307_status = 0;
ALIGN(RT_ALIGN_SIZE)
static char ml307_thread_stack[ML307_THREAD_STACK_SIZE];
static struct rt_thread ml307_thread;
ALIGN(RT_ALIGN_SIZE)
static char ml307_recv_thread_stack[ML307_RECV_THREAD_STACK_SIZE];
static struct rt_thread ml307_recv_thread;
ALIGN(RT_ALIGN_SIZE)
static char ml307_life_thread_stack[ML307_LIFE_THREAD_STACK_SIZE];
static struct rt_thread ml307_life_thread;
struct rt_event at_device_event;
rt_sem_t ml307_recv_sem;
rt_sem_t ml307_life_sem;
2024-12-13 19:07:17 +08:00
static rt_timer_t ml307_timer; // 上报心跳
static rt_timer_t ml307_upload_timer; // 更新本地时间定时器
static rt_timer_t ml307_power_error_timer; // 上电失败情况下启动定时器
2024-12-03 10:24:55 +08:00
static rt_timer_t ml307_heartbeat_check_timer; // 用于检测定时器是否工作
2024-12-13 19:07:17 +08:00
2024-12-03 10:24:55 +08:00
rt_uint8_t ml307_conncet_tcp_flag;
Ml307EventIndex ml307_event_index;
rt_uint8_t power_on_send_flag = 0;
rt_mutex_t ml307_mutex;
2024-12-04 18:55:59 +08:00
2024-12-16 15:35:19 +08:00
extern valve_data valve[MAX_VALVE_NUM];
2024-12-04 18:55:59 +08:00
2024-12-03 10:24:55 +08:00
int BSP_Ml307_Init(struct Ml307_Ops *ops, rt_uint8_t version);
int BSP_Ml307_Update(struct Ml307_Ops *ops, rt_uint8_t device_type, rt_uint8_t event_type);
int Ml307_Send_Data(struct Ml307_Ops *ops, rt_uint8_t data_num, rt_uint8_t cmd, rt_uint8_t device_type, rt_uint8_t event_type);
int Data_Resp(struct Ml307_Ops *ops, rt_uint8_t data_num, rt_uint8_t cmd, rt_uint8_t device_type, rt_uint8_t event_type, char *data, rt_uint8_t res);
2024-12-16 15:35:19 +08:00
// int Ml307_Recv_Data(struct Ml307_Ops *ops, char *data);
2024-12-03 10:24:55 +08:00
static struct DataBody body;
static struct Ml307DataFrame frame;
static struct Ml307RecvData ml307_recv;
struct Ml307_Ops ml307_ops = {
.body = &body,
.frame = &frame,
.recv = &ml307_recv,
.init = BSP_Ml307_Init,
.update_data = BSP_Ml307_Update,
.send = Ml307_Send_Data,
.Resp = Data_Resp,
// .Recv = Ml307_Recv_Data,//,没用到
};
static struct at_device_ml307 _dev = {
ML307_SAMPLE_DEIVCE_NAME,
ML307_SAMPLE_CLIENT_NAME,
ML307_ENABLE_3_8_V,
ML307_PWR_PIN,
ML307_RST_PIN,
ML307_USIM_DECT_PIN,
ML307_SAMPLE_RECV_BUFF_LEN,
};
static rt_uint32_t ml307_event_flags[kMl307MaxEventcnt] = {0};
2024-12-04 18:55:59 +08:00
static rt_bool_t ml307_event_initialized = RT_FALSE; // 是否初始化完成
2024-12-03 10:24:55 +08:00
typedef enum
{
ML307_PRIORITY_LOWEST, // 4、优先级最低定时心跳、浓度异常、报警触发、报警解除、传感器故障触发 传感器故障解除)
ML307_PRIORITY_MEDIUM, // 2、优先级第三高 自检触发
ML307_PRIORITY_HIGH, // 1、优先级第二高 掉电
ML307_PRIORITY_HIGHEST, // 0 优先级最高(设备上电时的定时心跳)
} Ml307Priority;
typedef struct
{
Ml307Event event_flag;
Ml307Priority priority;
const char *event_name;
int (*send_func)(struct at_device *device, void *param);
} Ml307EventInfo;
static void Ml307_Set_Event(Ml307Event event_type)
{
if (event_type < kMl307MaxEventcnt)
{
ml307_event_flags[event_type] = (1 << event_type);
}
}
void Ml307_Event_Init(void)
{
rt_err_t ret = rt_event_init(&at_device_event, "ml307_event", RT_IPC_FLAG_PRIO);
if (ret == RT_EOK)
{
ml307_event_initialized = RT_TRUE;
for (Ml307Event event = kMl307HeartbeatEvent; event < kMl307MaxEventcnt; event++)
{
Ml307_Set_Event(event);
}
}
else
{
LOG_E("ml307_event init failed!");
}
}
rt_uint32_t Ml307_Get_Event_Flag(Ml307Event event_type)
{
if (event_type < kMl307MaxEventcnt)
{
return ml307_event_flags[event_type];
}
return 0;
}
void Ml307_Send_Event(Ml307Event event_type)
{
ml307_event_index.last_event = ml307_event_index.current_event;
ml307_event_index.current_event = event_type;
if (ml307_event_initialized == RT_TRUE)
{
2024-12-04 10:31:57 +08:00
LOG_I("Send_Ml307_Event = %d", event_type);
2024-12-03 10:24:55 +08:00
rt_event_send(&at_device_event, Ml307_Get_Event_Flag(event_type));
}
else
{
LOG_E("ml307_event_initialized is false");
}
}
static rt_uint8_t last_value = 0; // 用于存储上次检测的值
static rt_uint8_t current_value = 0; // 用于存储当前检测的值
// 定义定时器回调函数
static void Ml307_Ht_Timer_Cb(void *parameter)
{
current_value++;
Ml307_Send_Event(kMl307HeartbeatEvent);
}
static void Ml307_Error_Timer_Cb(void *parameter)
{
if (power_on_send_flag) // 上电成功时,停止定时器
{
rt_timer_stop(ml307_power_error_timer);
}
else
{
Ml307_Send_Event(kMl307PowerOnEvent);
}
}
static void Ml307_Heartbeat_check_Timer_Cb(void *parameter)
{
2024-12-04 18:55:59 +08:00
// static rt_uint8_t relay_cnt = 0;
2024-12-03 10:24:55 +08:00
if (last_value == current_value)
{
// rt_timer_start(ml307_timer); // 重启一下定时器
// relay_cnt++;
2024-12-04 18:55:59 +08:00
reboot(); // 三个心跳周期定时器都没启动,直接重启
2024-12-03 10:24:55 +08:00
}
// else
// {
// if (current_value > 100) // 随便设一个不大于255的数就行 目的就是循环检测,不超
// {
// last_value = current_value;
// current_value = 0;
// }
// }
}
int _Pack_Send(struct Ml307_Ops *ops, char *buf)
{
2024-12-04 18:55:59 +08:00
char ml307_send_buf[1024] = {0}; // 发送缓冲区,用于存储最终发送的数据
2024-12-05 16:57:19 +08:00
// char byteArr1[512]; // 转换成字节值
unsigned short crc16 = 0; // 存储CRC16校验和
2024-12-03 10:24:55 +08:00
struct at_device *device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, ML307_SAMPLE_DEIVCE_NAME);
ASSERT(device);
crc16 = crc1021(buf, rt_strlen(buf));
2024-12-04 18:55:59 +08:00
LOG_D("buf: %s", buf);
2024-12-03 10:24:55 +08:00
LOG_D("crc16: %X", crc16);
// 将数据、校验和及尾部标识添加到发送缓冲区中
if (rt_snprintf(ml307_send_buf, sizeof(ml307_send_buf),
"%s%04X%02X%02X%02X",
buf,
crc16,
ops->frame->tail[0],
ops->frame->tail[1],
ops->frame->tail[2]) >= sizeof(ml307_send_buf))
{
// 发生缓冲区溢出
LOG_E("Buffer overflow in ml307_send_buf");
return -RT_ERROR;
}
// 打印调试信息
// LOG_D("ml307_send_buf: %s", ml307_send_buf);
rt_uint16_t data_len = rt_strlen(ml307_send_buf);
// 通过AT指令发送数据给ML307模块
2024-12-05 16:57:19 +08:00
if (at_send_data(device, ml307_send_buf, data_len / 2) != RT_EOK)
2024-12-03 10:24:55 +08:00
{
return -RT_ERROR;
}
return RT_EOK;
}
/**
* @brief ml307模块
*
* CRC16校验和
* ML307模块
*@param version
* @param data
* @param len
* @param data_num
* @param cmd_num
* @return int 0
*/
static int _Send_Handle(struct Ml307_Ops *ops, rt_size_t data_num, rt_size_t cmd_num, const char *data)
{
// 临时缓冲区,用于格式化数据
2024-12-04 18:55:59 +08:00
char data_buf[1024] = {0};
2024-12-05 16:57:19 +08:00
rt_size_t data_len = rt_strlen(data);
2024-12-03 10:24:55 +08:00
// 格式化数据构建发送给ML307模块的数据包
rt_int32_t len = rt_snprintf(data_buf, sizeof(data_buf),
"%02X%02X%02X%02X%04X%04X%02X%04X%s",
ops->frame->header[0],
ops->frame->header[1],
ops->frame->header[2],
ops->frame->version, // 协议版本
ops->frame->manufacture, // 制造商ID
data_num,
cmd_num,
2024-12-04 18:55:59 +08:00
data_len / 2,
2024-12-03 10:24:55 +08:00
data);
if (len < 0 || len >= sizeof(data_buf))
{
LOG_E("Send Data buffer overflow");
return -RT_ERROR;
}
// LOG_D("data_buf: %s", data_buf);
return _Pack_Send(ops, data_buf);
}
// 初始化函数
int BSP_Ml307_Init(struct Ml307_Ops *ops, rt_uint8_t version)
{
if (ops->frame == RT_NULL)
{
LOG_E("Memory allocation failed");
return -RT_ENOMEM;
}
rt_memset(ops->frame, 0, sizeof(struct Ml307DataFrame));
ops->frame->header[0] = 0x4A;
ops->frame->header[1] = 0x54;
2024-12-04 18:55:59 +08:00
ops->frame->header[2] = 0x30;
2024-12-03 10:24:55 +08:00
ops->frame->version = version;
ops->frame->manufacture = DEVICE_MANUFACTURE;
ops->frame->tail[0] = 0x42;
ops->frame->tail[1] = 0x4A;
ops->frame->tail[2] = 0x51;
return RT_EOK;
}
2024-12-04 18:55:59 +08:00
int _Update_Valve_Data(struct Ml307_Ops *ops)
{
2024-12-16 15:35:19 +08:00
ops->body->valve_num = Flash_Get_Valve_Num();
2024-12-05 16:57:19 +08:00
if (ops->body->valve_num == 0) // 确保至少有一个阀门数据体
2024-12-04 18:55:59 +08:00
{
LOG_D("No valve data");
2024-12-16 15:35:19 +08:00
rt_memset(&ops->body->valve_data, 0, sizeof(struct valve_t)); // 直接全部发送0
2024-12-04 18:55:59 +08:00
}
else
{
2024-12-16 15:35:19 +08:00
LOG_D("valve_num: %d", ops->body->valve_num);
rt_memcpy(&ops->body->valve_data[0], &valve[0], sizeof(struct valve_t));
2024-12-04 18:55:59 +08:00
}
return RT_EOK;
}
2024-12-16 15:35:19 +08:00
2024-12-03 10:24:55 +08:00
// 更新函数
int BSP_Ml307_Update(struct Ml307_Ops *ops, rt_uint8_t device_type, rt_uint8_t event_type)
{
2024-12-05 16:57:19 +08:00
2024-12-03 10:24:55 +08:00
ops->body->device_type = device_type;
ops->body->event_type = event_type;
ops->body->hw = (rt_uint8_t)Flash_Get_SysCfg(kHwVerId);
ops->body->sw = (rt_uint8_t)Flash_Get_SysCfg(kSwVerId);
2024-12-04 18:55:59 +08:00
rt_memcpy(ops->body->imei, &ml307, sizeof(ml307_sys_info)); // 直接赋值结构体数据
ops->body->gas_voltage = Get_Gas_VoltageInt1000x();
ops->body->product_work_temperature = 0x32;
2024-12-03 10:24:55 +08:00
ops->body->work_duration = work_duration;
ops->body->device_status = device_state_flag;
2024-12-05 16:57:19 +08:00
ops->body->valve_num = Flash_Get_Valve_Num();
2024-12-04 18:55:59 +08:00
_Update_Valve_Data(ops);
2024-12-03 10:24:55 +08:00
return RT_EOK;
}
int Ml307_Send_Data(struct Ml307_Ops *ops, rt_uint8_t data_num, rt_uint8_t cmd, rt_uint8_t device_type, rt_uint8_t event_type)
{
2024-12-05 16:57:19 +08:00
rt_size_t lenght = 0;
int ret = 0;
2024-12-04 18:55:59 +08:00
char data_buf[1024] = {0};
2024-12-03 10:24:55 +08:00
char temp[3]; // 临时缓冲区,用于存储每个字节的十六进制表示
if (ops == NULL || ops->body == NULL)
{
// 处理 ops 或 ops->body 为 NULL 的情况
return RT_ERROR; // 或者抛出异常,返回错误码等
}
if (sizeof(struct DataBody) == 0)
{
data_buf[0] = '\0'; // 确保 data_buf 被正确初始化
return RT_ERROR;
}
rt_memset(ops->body, 0, sizeof(struct DataBody));
rt_mutex_take(ml307_mutex, RT_WAITING_FOREVER);
if (ml307_conncet_tcp_flag)
{
2024-12-04 18:55:59 +08:00
ret = ml307_ops.update_data(ops, device_type, event_type);
2024-12-03 10:24:55 +08:00
if (ret == RT_EOK)
{
2024-12-04 18:55:59 +08:00
if (ops->body->valve_num == 0)
{
2024-12-16 15:35:19 +08:00
lenght = (sizeof(struct DataBody) - (MAX_VALVE_NUM - 1) * sizeof(struct valve_t)); // 至少要发送一个阀门数据体
2024-12-04 18:55:59 +08:00
}
else
{
2024-12-16 15:35:19 +08:00
lenght = (sizeof(struct DataBody) - (MAX_VALVE_NUM - ops->body->valve_num) * sizeof(struct valve_t)); // 至少要发送一个阀门数据体
2024-12-04 18:55:59 +08:00
}
for (int i = 0; i < lenght; i++)
2024-12-03 10:24:55 +08:00
{
rt_snprintf(temp, sizeof(temp), "%02X", ((rt_uint8_t *)ops->body)[i]);
rt_memcpy(data_buf + i * 2, temp, 2);
}
rt_mutex_release(ml307_mutex);
ret = _Send_Handle(ops, data_num, cmd, data_buf);
if (ret != RT_EOK)
{
return -ret;
}
}
}
else
{
2024-12-04 18:55:59 +08:00
rt_mutex_release(ml307_mutex);
2024-12-03 10:24:55 +08:00
LOG_E("ml307_conncet_tcp_flag = 0");
2024-12-04 18:55:59 +08:00
ret = -RT_ERROR;
2024-12-03 10:24:55 +08:00
}
2024-12-05 09:13:31 +08:00
2024-12-03 10:24:55 +08:00
return ret;
}
int Data_Resp(struct Ml307_Ops *ops, rt_uint8_t data_num, rt_uint8_t cmd, rt_uint8_t device_type, rt_uint8_t event_type, char *data, rt_uint8_t res)
{
if (ml307_conncet_tcp_flag != 1)
{
LOG_E("ml307_conncet_tcp_flag error");
return -RT_ERROR;
}
char data_buf[512] = {0};
rt_int32_t len = rt_snprintf(data_buf, sizeof(data_buf), "%02X%02X%30s%02X", device_type, event_type, data, res);
if (len < 0 || len >= sizeof(data_buf))
{
LOG_E("Resp Data buffer overflow");
return -RT_ERROR;
}
// LOG_D("data_buf: %s", data_buf);
return _Send_Handle(ops, data_num, cmd, data_buf);
}
2024-12-16 15:35:19 +08:00
#if 0
2024-12-03 10:24:55 +08:00
int Ml307_Recv_Data(struct Ml307_Ops *ops, char *data)
{
// ops->body = (struct DataBody *)rt_malloc(sizeof(struct DataBody));
// rt_memset(ops->body, 0, sizeof(struct DataBody));
// rt_free(ops->body);
return RT_EOK;
}
2024-12-16 15:35:19 +08:00
#endif
2024-12-03 10:24:55 +08:00
/***************************************发送处理函数************************************************ */
/**
*
* @param device
* @param param
* @return
*/
int Ml307_Send_Heartbeat(struct at_device *device, void *param)
{
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)param;
2024-12-04 18:55:59 +08:00
int ret = 0;
2024-12-03 10:24:55 +08:00
if ((device == RT_NULL) || (ml307_ops == RT_NULL))
{
LOG_E("ml307 param error\n");
return RT_ERROR;
}
ret = device->class->device_ops->control(device, AT_DEVICE_CTRL_GET_SIGNAL, RT_NULL);
if (ret != RT_EOK)
{
LOG_E("ml307 get signal failed\n");
return -RT_ERROR;
}
ret = ml307_ops->send(ml307_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_DATA_REPORT, DEVICE_TYPE_ML307, EVENT_TYPE_HEARTBEAT);
if (ret != RT_EOK)
{
LOG_E("ml307 send data failed\n");
return ret;
}
return RT_EOK;
}
/**
*
* @param device
* @param param
* @return
*/
int Ml307_Send_Time_Calibration(struct at_device *device, void *param)
{
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)param;
if ((device == RT_NULL) || (ml307_ops == RT_NULL))
{
LOG_E("ml307 param error\n");
return RT_ERROR;
}
if (ml307_ops->send(ml307_ops, DATA_SERIAL_NUM, CMD_TYPE_TIME_CALIBRATION, DEVICE_TYPE_ML307, EVENT_TYPE_TIME_CALIBRATION))
{
LOG_E("ml307 send cmd[%X] failed\n", CMD_TYPE_TIME_CALIBRATION);
return -RT_ERROR;
}
return RT_EOK;
}
/**
*
* @param device
* @param param
* @return
*/
int Ml307_Send_Alarm(struct at_device *device, void *param)
{
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)param;
if ((device == RT_NULL) || (ml307_ops == RT_NULL))
{
LOG_E("ml307 param error\n");
return RT_ERROR;
}
if (ml307_ops->send(ml307_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_ML307, EVENT_TYPE_ALARM))
{
LOG_E("ml307 send cmd[%X] failed\n", EVENT_TYPE_ALARM);
return -RT_ERROR;
}
return RT_EOK;
}
/**
*
* @param device
* @param param
* @return
*/
int Ml307_Send_Alarm_Recover(struct at_device *device, void *param)
{
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)param;
if ((device == RT_NULL) || (ml307_ops == RT_NULL))
{
LOG_E("ml307 param error\n");
return RT_ERROR;
}
if (ml307_ops->send(ml307_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_ML307, EVENT_TYPE_ALARM_RECOVER))
{
LOG_E("ml307 send cmd[%X] failed\n", EVENT_TYPE_ALARM_RECOVER);
return -RT_ERROR;
}
return RT_EOK;
}
/**
*
* @param device
* @param param
* @return
*/
int Ml307_Send_Fault(struct at_device *device, void *param)
{
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)param;
if ((device == RT_NULL) || (ml307_ops == RT_NULL))
{
LOG_E("ml307 param error\n");
return RT_ERROR;
}
if (ml307_ops->send(ml307_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_ML307, EVENT_TYPE_FAULT))
{
LOG_E("ml307 send cmd[%X] failed\n", EVENT_TYPE_FAULT);
return -RT_ERROR;
}
return RT_EOK;
}
/**
*
* @param device
* @param param
* @return
*/
int Ml307_Send_Fault_Recover(struct at_device *device, void *param)
{
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)param;
if ((device == RT_NULL) || (ml307_ops == RT_NULL))
{
LOG_E("ml307 param error\n");
return RT_ERROR;
}
if (ml307_ops->send(ml307_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_ML307, EVENT_TYPE_FAULT_RECOVER))
{
LOG_E("ml307 send cmd[%X] failed\n", EVENT_TYPE_FAULT_RECOVER);
return -RT_ERROR;
}
return RT_EOK;
}
/**
*
* @param device
* @param param
* @return
*/
int Ml307_Send_Self_Check(struct at_device *device, void *param)
{
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)param;
if ((device == RT_NULL) || (ml307_ops == RT_NULL))
{
LOG_E("ml307 param error\n");
return RT_ERROR;
}
if (ml307_ops->send(ml307_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_ML307, EVENT_TYPE_SELF_CHECK))
{
LOG_E("ml307 send cmd[%X] failed\n", EVENT_TYPE_SELF_CHECK);
return -RT_ERROR;
}
return RT_EOK;
}
/**
*
* @param device
* @param param
* @return
*/
int Ml307_Send_Silence(struct at_device *device, void *param)
{
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)param;
if ((device == RT_NULL) || (ml307_ops == RT_NULL))
{
LOG_E("ml307 param error\n");
return RT_ERROR;
}
if (ml307_ops->send(ml307_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_ML307, EVENT_TYPE_SILENCE))
{
LOG_E("ml307 send cmd[%X] failed\n", EVENT_TYPE_SILENCE);
return -RT_ERROR;
}
return RT_EOK;
}
/**
*
* @param device
* @param param
* @return
*/
int Ml307_Send_Exception(struct at_device *device, void *param)
{
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)param;
if ((device == RT_NULL) || (ml307_ops == RT_NULL))
{
LOG_E("ml307 param error\n");
return RT_ERROR;
}
if (ml307_ops->send(ml307_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_ML307, EVENT_TYPE_EXCEPTION))
{
LOG_E("ml307 send cmd[%X] failed\n", EVENT_TYPE_EXCEPTION);
return -RT_ERROR;
}
return RT_EOK;
}
/**
*
* @param device
* @param param
* @return
*/
int Ml307_Send_Valve_Status(struct at_device *device, void *param)
{
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)param;
if ((device == RT_NULL) || (ml307_ops == RT_NULL))
{
LOG_E("ml307 param error\n");
return RT_ERROR;
}
if (ml307_ops->send(ml307_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_ML307, EVENT_TYPE_VALVE_STATUS))
{
LOG_E("ml307 send cmd[%X] failed\n", EVENT_TYPE_VALVE_STATUS);
return -RT_ERROR;
}
return RT_EOK;
}
/**
*
* @param device
* @param param
* @return
*/
int Ml307_Send_Fan_Status(struct at_device *device, void *param)
{
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)param;
if ((device == RT_NULL) || (ml307_ops == RT_NULL))
{
LOG_E("ml307 param error\n");
return RT_ERROR;
}
if (ml307_ops->send(ml307_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_ML307, EVENT_TYPE_FAN_STATUS))
{
LOG_E("ml307 send cmd[%X] failed\n", EVENT_TYPE_FAN_STATUS);
return -RT_ERROR;
}
return RT_EOK;
}
/**
*
* @param device
* @param param
* @return
*/
int Ml307_Send_Temp_Anomaly(struct at_device *device, void *param)
{
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)param;
if ((device == RT_NULL) || (ml307_ops == RT_NULL))
{
LOG_E("ml307 param error\n");
return RT_ERROR;
}
if (ml307_ops->send(ml307_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_ML307, EVENT_TYPE_TEMP_ANOMALY))
{
LOG_E("ml307 send cmd[%X] failed\n", EVENT_TYPE_TEMP_ANOMALY);
return -RT_ERROR;
}
return RT_EOK;
}
/**
*
* @param device
* @param param
* @return
*/
int Ml307_Send_Power_Off(struct at_device *device, void *param)
{
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)param;
if ((device == RT_NULL) || (ml307_ops == RT_NULL))
{
LOG_E("ml307 param error\n");
return RT_ERROR;
}
if (ml307_ops->send(ml307_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_ML307, EVENT_TYPE_POWER_OFF))
{
LOG_E("ml307 send cmd[%X] failed\n", EVENT_TYPE_POWER_OFF);
return -RT_ERROR;
}
return RT_EOK;
}
/**
*
* @param device
* @param param
* @return
*/
int Ml307_Send_Power_On(struct at_device *device, void *param)
{
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)param;
if ((device == RT_NULL) || (ml307_ops == RT_NULL))
{
LOG_E("ml307 param error\n");
return RT_ERROR;
}
if (ml307_ops->send(ml307_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_ML307, EVENT_TYPE_POWER_ON))
{
LOG_E("ml307 send cmd[%X] failed\n", EVENT_TYPE_POWER_ON);
return -RT_ERROR;
}
return RT_EOK;
}
/**
*
* @param device
* @param param
* @return
*/
int Ml307_Send_Device_Failure(struct at_device *device, void *param)
{
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)param;
if ((device == RT_NULL) || (ml307_ops == RT_NULL))
{
LOG_E("ml307 param error\n");
return RT_ERROR;
}
if (ml307_ops->send(ml307_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_ML307, EVENT_TYPE_DEVICE_FAILURE))
{
LOG_E("ml307 send cmd[%X] failed\n", EVENT_TYPE_DEVICE_FAILURE);
return -RT_ERROR;
}
return RT_EOK;
}
/*这个【4、优先级最低当同时触发后相同服务直接合并】暂时还没想好怎么做
线
线
使*/
const Ml307EventInfo ml307_event_info[] = {
{kMl307PowerOnEvent, ML307_PRIORITY_HIGHEST, "上电心跳事件", Ml307_Send_Power_On},
{kMl307PowerDownEvent, ML307_PRIORITY_HIGH, "掉电事件", Ml307_Send_Power_Off},
{kMl307SelfCheckEvent, ML307_PRIORITY_MEDIUM, "自检事件", Ml307_Send_Self_Check},
{kMl307HeartbeatEvent, ML307_PRIORITY_LOWEST, "定时心跳事件", Ml307_Send_Heartbeat},
{kMl307TempAnomalyEvent, ML307_PRIORITY_LOWEST, "温度异常事件", Ml307_Send_Temp_Anomaly},
{kMl307AlarmEvent, ML307_PRIORITY_LOWEST, "报警触发事件", Ml307_Send_Alarm},
{kMl307AlarmRcyEvent, ML307_PRIORITY_LOWEST, "报警解除事件", Ml307_Send_Alarm_Recover},
{kMl307FaultEvent, ML307_PRIORITY_LOWEST, "传感器故障事件", Ml307_Send_Fault},
{kMl307FaultRcyEvent, ML307_PRIORITY_LOWEST, "传感器故障解除事件", Ml307_Send_Fault_Recover},
{kMl307TimeCalibrationEvent, ML307_PRIORITY_LOWEST, "时间校准事件", Ml307_Send_Time_Calibration},
{kMl307SilenceEvent, ML307_PRIORITY_LOWEST, "消音事件", Ml307_Send_Silence},
2024-12-04 18:55:59 +08:00
// {kMl307ExceptionEvent, ML307_PRIORITY_LOWEST, "异常事件", Ml307_Send_Exception},
2024-12-03 10:24:55 +08:00
{kMl307ValveStatusEvent, ML307_PRIORITY_LOWEST, "电磁阀状态改变事件", Ml307_Send_Valve_Status},
{kMl307FanStatusEvent, ML307_PRIORITY_LOWEST, "风机状态改变事件", Ml307_Send_Fan_Status},
{kMl307DeviceFailureEvent, ML307_PRIORITY_LOWEST, "设备失效事件", Ml307_Send_Device_Failure}};
/**
* ML307设备的事件
* @param ml307_recv_event ML307事件标志
* @return
*/
int Ml307_Process_Events(Ml307Event ml307_recv_event, struct at_device *device, void *param)
{
2024-12-04 18:55:59 +08:00
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)param;
2024-12-03 10:24:55 +08:00
const Ml307EventInfo *event = RT_NULL;
for (size_t i = 0; i < sizeof(ml307_event_info) / sizeof(Ml307EventInfo); ++i)
{
// 检查当前事件是否在接收到的事件标志中
if (ml307_recv_event == ml307_event_info[i].event_flag)
{
event = &ml307_event_info[i];
break;
}
}
2024-12-05 16:57:19 +08:00
if (event) // 处理该事件
2024-12-03 10:24:55 +08:00
{
// 打印事件的名称
LOG_D("%s上报\n", event->event_name);
// 如果事件有关联的发送函数,则调用该发送函数
if (event->send_func)
{
int result = event->send_func(device, ml307_ops);
if (result != RT_EOK)
{
LOG_E("ml307 send cmd failed\n");
Ml307_Reset(device); // 重启模组
rt_thread_mdelay(5000);
if (ml307_conncet_tcp_flag != 1)
{
if (device->class->device_ops->control(device, AT_DEVICE_CTRL_NET_CONN, RT_NULL) == RT_EOK) // 打开连接
{
2024-12-05 16:57:19 +08:00
// Reset_Ml307_Life_Timer();
2024-12-03 10:24:55 +08:00
// 重启后重新尝试发送
result = event->send_func(device, ml307_ops);
if (result != RT_EOK)
{
LOG_E("ml307 send cmd after module reset failed\n");
// Flash_Set_WorkDuration(work_duration); // 重启前保存参数
// NVIC_SystemReset(); // 直接重启系统
Ml307_Reset(device);
rt_thread_mdelay(5000);
}
}
else
{
LOG_E("ml307 connect tcp failed\n");
}
}
}
else
return RT_EOK;
}
}
// 函数执行完毕返回0
return RT_EOK;
}
// 比较帧头和帧尾
int Compare_HeaderToTail(struct Ml307_Ops *ops)
{
// 比较帧头
for (int i = 0; i < 3; i++)
{
if (ops->frame->header[i] != ops->recv->header[i])
{
LOG_E("ops->frame->header[%x] != ops->recv->header[%x]\n", ops->frame->header[i], ops->recv->header[i]);
return -1;
}
}
// 比较帧尾
for (int i = 0; i < 3; i++)
{
if (ops->frame->tail[i] != ops->recv->tail[i])
{
LOG_E("ops->frame->tail[%x] != ops->recv->tail[%x]\n", ops->frame->tail[i], ops->recv->tail[i]);
return -2;
}
}
if (ops->recv->recv_data.res_num != RESPONSE_CODE_SUCCESS) // 判断是否为成功响应
{
LOG_E("ops->recv->recv_data.res_num[%x] != RESPONSE_CODE_SUCCESS\n", ops->recv->recv_data.res_num);
return -3;
}
return RT_EOK;
}
void Handle_Server_Reply(struct Ml307_Ops *ops)
{
2024-12-05 16:57:19 +08:00
if ((ops->recv->recv_data.event_type == INSTRUCTION_HEART_BEAT) || (ops->recv->recv_data.event_type == EVENT_TYPE_POWER_ON))
2024-12-03 10:24:55 +08:00
{
2024-12-05 09:13:31 +08:00
LOG_D("服务器响应成功,响应码:[%02X]\n", ops->recv->recv_data.event_type);
2024-12-03 10:24:55 +08:00
}
}
void Handle_Self_Check(struct Ml307_Ops *ops)
{
LOG_D("服务器下发自检指令\n");
char imei[16] = {0};
Get_Iot_Imei(imei, FLASH_NB_IMEI_LEN);
LOG_D("imei:%s\n", imei);
_Self_Check_Mode();
rt_thread_mdelay(100);
char temp[32] = "0";
String2Hex(temp, imei); // 将字符串转为十六进制字符串
LOG_D("temp: %s", temp);
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_SELF_CHECK, temp, RESPONSE_CODE_SUCCESS);
Send_Laser_Alarm_Event(SysControl.status); // 自检完要恢复当前系统状态,恢复现场
}
void Handle_Mute(struct Ml307_Ops *ops)
{
LOG_D("服务器下发消音指令\n");
char imei[16] = {0};
Get_Iot_Imei(imei, FLASH_NB_IMEI_LEN);
char temp[32] = "0";
String2Hex(temp, imei); // 将字符串转为十六进制字符串
Send_Laser_Alarm_Event(KMuteEvent);
rt_thread_mdelay(100);
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_MUTE, temp, RESPONSE_CODE_SUCCESS);
}
2024-12-04 18:55:59 +08:00
/*关阀 52-阀门编号1byte+ MAC地址6byte+ 补零字节 = 15byte 如果内容全部为0则默认为关闭有线阀门*/
rt_err_t Handle_Close_Valve(struct Ml307_Ops *ops)
2024-12-03 10:24:55 +08:00
{
LOG_D("服务器下发关闭阀门指令\n");
2024-12-13 19:07:17 +08:00
int i = 0;
2024-12-05 16:57:19 +08:00
rt_uint8_t data[FLASH_VALVE_MAC_ADDR_LEN + 1] = {0};
2024-12-13 19:07:17 +08:00
rt_uint8_t mac_addr[6] = {0};
char imei[16] = {0};
2024-12-03 10:24:55 +08:00
Get_Iot_Imei(imei, FLASH_NB_IMEI_LEN);
char temp[32] = "0";
2024-12-13 19:07:17 +08:00
String2Hex(temp, imei); // 将字符串转为十六进制字符串
2024-12-05 16:57:19 +08:00
rt_memcpy(data, (ops->recv->recv_data.res_data + 8), FLASH_VALVE_MAC_ADDR_LEN + 1);
LOG_D("data[0] = %x data[1] = %x data[2] = %x data[3] = %x data[4] = %x, data[5] = %x data[6] = %x", data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
if ((data[0] > 0) && (data[0] < MAX_VALVE_NUM)) // 不为零则说明关闭无线阀门
2024-12-04 18:55:59 +08:00
{
2024-12-05 16:57:19 +08:00
LOG_D("无线阀门编号:%d\n", data[0]);
Flash_Get_Mac_Addr(mac_addr, data[0] - 1);
LOG_D("mac_addr[0] = %x mac_addr[1] = %x mac_addr[2] = %x mac_addr[3] = %x mac_addr[4] = %x, mac_addr[5] = %x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
2024-12-04 18:55:59 +08:00
/*对两个数组进行比较,如果值不同则退出*/
for (; i < FLASH_VALVE_MAC_ADDR_LEN; i++)
{
2024-12-13 19:07:17 +08:00
if (mac_addr[i] != data[i + 1])
2024-12-04 18:55:59 +08:00
{
2024-12-13 19:07:17 +08:00
LOG_E("mac_addr[%d][%x]!= data[%d][%x]\n", i, mac_addr[i], i + 1, data[i + 1]);
2024-12-05 16:57:19 +08:00
2024-12-04 18:55:59 +08:00
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_CLOSE_VALVE, temp, RESPONSE_CODE_ACTION_FAILURE);
2024-12-13 19:07:17 +08:00
2024-12-04 18:55:59 +08:00
return RT_ERROR;
}
}
2024-12-05 16:57:19 +08:00
if (i == FLASH_VALVE_MAC_ADDR_LEN)
2024-12-04 18:55:59 +08:00
{
LOG_D("mac地址匹配成功,执行关阀动作\n");
2024-12-05 16:57:19 +08:00
// TODO:此处需要增加关阀无线阀门的逻辑
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_CLOSE_VALVE, temp, RESPONSE_CODE_SUCCESS);
return RT_EOK;
2024-12-04 18:55:59 +08:00
}
else
{
LOG_E("mac地址匹配失败\n");
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_CLOSE_VALVE, temp, RESPONSE_CODE_ACTION_FAILURE);
}
}
else
{
LOG_D("关闭有线阀门\n");
2024-12-05 16:57:19 +08:00
// TODO:此处需要增加关阀有线阀门的逻辑
// emv_state_flag = 0; // 电磁阀动作
// rt_thread_mdelay(20);
// emv_state_flag = 0;
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_CLOSE_VALVE, temp, RESPONSE_CODE_SUCCESS);
2024-12-04 18:55:59 +08:00
return RT_EOK;
}
2024-12-03 10:24:55 +08:00
}
void Handle_Open_Valve(struct Ml307_Ops *ops)
{
LOG_D("服务器下发打开阀门指令\n");
2024-12-04 18:55:59 +08:00
char imei[16] = {0};
Get_Iot_Imei(imei, FLASH_NB_IMEI_LEN);
char temp[32] = "0";
String2Hex(temp, imei); // 将字符串转为十六进制字符串
2024-12-03 10:24:55 +08:00
// // rt_uint8_t ret = BSP_Set_Emv_Status(1);
// emv_state_flag = 1; // 电磁阀动作
// rt_thread_mdelay(20);
// emv_state_flag = 0;
2024-12-04 18:55:59 +08:00
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_OPEN_VALVE, temp, RESPONSE_CODE_SUCCESS);
2024-12-03 10:24:55 +08:00
}
void Handle_Open_Relay(struct Ml307_Ops *ops)
{
LOG_D("服务器下发打开继电器指令\n");
char imei[16] = {0};
Get_Iot_Imei(imei, FLASH_NB_IMEI_LEN);
char temp[32] = "0";
String2Hex(temp, imei); // 将字符串转为十六进制字符串
// relay_state_flag = 1;
rt_thread_mdelay(10);
// rt_uint8_t ret = BSP_Set_Relay_Status(0);
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_OPEN_RELAY, temp, RESPONSE_CODE_SUCCESS);
}
void Handle_Close_Relay(struct Ml307_Ops *ops)
{
LOG_D("服务器下发关闭继电器指令\n");
char imei[16] = {0};
char temp[32] = "0";
Get_Iot_Imei(imei, FLASH_NB_IMEI_LEN);
String2Hex(temp, imei); // 将字符串转为十六进制字符串
// relay_state_flag = 0;
rt_thread_mdelay(100);
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_CLOSE_RELAY, temp, RESPONSE_CODE_SUCCESS);
}
void Handle_Query_Params(struct Ml307_Ops *ops)
{
rt_uint8_t data[10] = {0};
char str[64] = {0};
LOG_D("服务器下发查询系统参数\n");
rt_memcpy(data, (rt_uint8_t *)FLASH_HW_VER_ADDR, sizeof(sys_config_info) - 50);
LOG_D("hw_ver:%02x sw_ver:%02x alarm_low:%02x alarm_high:%02x temp_alarm:%02x nb_upload_cycle:%dmin retry:%02x emagnetic:%02X relay_switch:%02X\n",
data[0], data[1], data[2], data[3], data[4], ((data[5]) | (data[6] << 8)), data[7], data[8], data[9]);
rt_sprintf(str, "0000000000%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9]);
rt_thread_mdelay(100); // 释放下线程
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_QUERY_PARAMS, str, RESPONSE_CODE_SUCCESS);
}
int Handle_Config_Params(struct Ml307_Ops *ops)
{
char data_buf[32] = {0};
rt_uint8_t recv_data[16] = {0};
rt_uint8_t flash_info[16] = {0};
char imei[16] = {0};
char temp[32] = "0";
LOG_D("服务器下发配置参数\n");
Get_Iot_Imei(imei, FLASH_NB_IMEI_LEN);
String2Hex(temp, imei); // 将字符串转为十六进制字符串
rt_memset(data_buf, '0', 32);
rt_memcpy(recv_data, (ops->recv->recv_data.res_data + 5), sizeof(sys_config_info) - 50);
rt_memcpy(flash_info, (rt_uint8_t *)FLASH_HW_VER_ADDR, sizeof(sys_config_info) - 50);
LOG_D("hw_ver:%02x sw_ver:%02x alarm_low:%02x alarm_high:%02x temp_alarm:%02x nb_upload_cycle:%d min retry:%02x emagnetic:%02X relay_switch:%02X\n",
flash_info[0], flash_info[1], flash_info[2], flash_info[3], flash_info[4], (flash_info[5] | (flash_info[6] << 8)), flash_info[7], flash_info[8], recv_data[9]);
LOG_D("recv_data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x \n",
recv_data[0], recv_data[1], recv_data[2], recv_data[3], recv_data[4],
recv_data[5], recv_data[6], recv_data[7], recv_data[8], recv_data[9],
recv_data[10], recv_data[11], recv_data[12], recv_data[13], recv_data[14], recv_data[15]);
LOG_D("data:%s\n", data_buf);
for (rt_uint8_t i = 0; i < (sizeof(sys_config_info) - 50); i++)
{
LOG_D("recv_data[%d] = %d", i, recv_data[i]);
if (recv_data[i] != flash_info[i])
{
if ((recv_data[2] > 25) || (recv_data[2] < 5)) /*家报的报警设定值应在5%~25%之间*/
{
if (ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_CONFIG_PARAMS, temp, RESPONSE_CODE_ACTION_FAILURE) == RT_EOK)
{
LOG_W("recv_data[3] :%d", recv_data[3]);
LOG_W("配置参数超出范围,请核实后重试\n");
}
return RT_EOK;
}
else // 如果没有超出,再写入信息
{
if (BSP_Flash_Write_Info(recv_data, sizeof(sys_config_info) - 50) != 0)
{
rt_uint16_t nb_upload_time = (uint16_t)Flash_Get_SysCfg(kIotUploadCycleId);
unsigned long timeout = nb_upload_time * 60 * RT_TICK_PER_SECOND;
rt_timer_control(ml307_timer, RT_TIMER_CTRL_SET_TIME, (void *)&timeout); // 更新上报周期
LOG_D("上报周期由%dmin更新为%dmin", ((flash_info[5] << 8) | flash_info[6]), nb_upload_time);
if (ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_CONFIG_PARAMS, temp, RESPONSE_CODE_SUCCESS) == RT_EOK)
{
LOG_D("配置参数写入成功\n");
}
return RT_EOK;
}
else
{
LOG_D("配置参数写入失败\n");
if (ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_CONFIG_PARAMS, temp, RESPONSE_CODE_ACTION_FAILURE) == RT_EOK)
{
LOG_D("写入失败响应成功\n");
}
return RT_ERROR;
}
}
}
}
if (ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_CONFIG_PARAMS, temp, RESPONSE_CODE_SUCCESS) == RT_EOK)
{
LOG_D("配置参数没有变化\n");
}
return RT_EOK;
}
void Handle_Time_Calibration_Data(struct Ml307_Ops *ops)
{
rt_uint8_t data[10] = {0};
TsRtcDateTime rtc_dt;
char imei[16] = {0};
char temp[32] = "0";
LOG_D("时间校准数据\n");
Get_Iot_Imei(imei, FLASH_NB_IMEI_LEN);
String2Hex(temp, imei); // 将字符串转为十六进制字符串
rt_memcpy(data, ops->recv->recv_data.res_data, sizeof(data));
// 提取后4个字节作为时间戳
time_t timestamp = (data[6] << 24) | (data[7] << 16) | (data[8] << 8) | data[9];
Timestamp_To_Rtc_DateTime(timestamp, &rtc_dt);
// 打印结果
LOG_I("时间: %04d-%02d-%02d %02d:%02d:%02d (星期%d)\n",
rtc_dt.year, rtc_dt.month, rtc_dt.day, rtc_dt.hour, rtc_dt.minute, rtc_dt.second, rtc_dt.week);
RTC_SetTime(rtc_dt.year, rtc_dt.month, rtc_dt.day, rtc_dt.hour, rtc_dt.minute, 0); /* Setup Time */
rt_thread_mdelay(100); // 释放下线程
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_TIME_CALIBRATION, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_TIME_CALIBRATION, temp, RESPONSE_CODE_SUCCESS);
}
2024-12-04 18:55:59 +08:00
// 下发修改服务器地址指令
2024-12-03 10:24:55 +08:00
void Handle_Sever_Addr_Set(struct Ml307_Ops *ops)
{
rt_uint8_t data[6] = {0};
2024-12-04 18:55:59 +08:00
char imei[16] = {0};
char temp[32] = "0";
2024-12-03 10:24:55 +08:00
Get_Iot_Imei(imei, FLASH_NB_IMEI_LEN);
String2Hex(temp, imei); // 将字符串转为十六进制字符串
rt_memcpy(data, (ops->recv->recv_data.res_data + 9), FLASH_SERVER_LEN);
LOG_D("data[%d] = %x data[%d] = %x data[%d] = %x data[%d] = %x data[%d] = %x data[%d] = %x", 0, data[0], 1, data[1], 2, data[2], 3, data[3], 4, data[4], 5, data[5]);
Flash_Set_Sever_Addr_Info(data);
2024-12-05 09:13:31 +08:00
if (Flash_Get_Sever_Addr_Info(&sever_info) == RESET)
2024-12-03 10:24:55 +08:00
{
LOG_E("服务器地址修改失败\n");
}
else
{
LOG_D("服务器地址修改成功\n");
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_SEVER_ADDR, temp, RESPONSE_CODE_SUCCESS);
}
2024-12-04 18:55:59 +08:00
}
/*新增阀门设备*/
rt_err_t Handle_Valve_Add(struct Ml307_Ops *ops)
{
2024-12-05 16:57:19 +08:00
rt_uint8_t data[7] = {0};
char imei[16] = {0};
char temp[32] = "0";
rt_uint8_t cnt = Flash_Get_Valve_Num();
2024-12-05 09:13:31 +08:00
rt_uint8_t mac_addr[FLASH_VALVE_MAC_ADDR_LEN + 1] = {0};
2024-12-04 18:55:59 +08:00
Get_Iot_Imei(imei, FLASH_NB_IMEI_LEN);
String2Hex(temp, imei); // 将字符串转为十六进制字符串
if (cnt > MAX_VALVE_NUM)
{
LOG_E("阀门设备数量超过最大值\n");
2024-12-05 09:13:31 +08:00
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_ADD, temp, RESPONSE_CODE_ACTION_FAILURE);
2024-12-04 18:55:59 +08:00
return RT_ERROR;
}
rt_memcpy(data, (ops->recv->recv_data.res_data + 8), FLASH_VALVE_MAC_ADDR_LEN + 1);
2024-12-05 16:57:19 +08:00
LOG_D("data[0] = %x data[1] = %x data[2] = %x data[3] = %x data[4] = %x, data[5] = %x data[6] = %x", data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
2024-12-13 19:07:17 +08:00
// 无阀门数据时添加,有阀门数据时不添加
if ((Flash_Get_Mac_Addr(mac_addr, data[0]) == RT_EEMPTY) || ((Flash_Get_Mac_Addr(mac_addr, data[0]) == RT_EOK)))
2024-12-04 18:55:59 +08:00
{
2024-12-13 19:07:17 +08:00
if (mac_addr[0] == 0) // 无MAC地址数据写入MAC地址数据
2024-12-05 09:13:31 +08:00
{
2024-12-16 15:35:19 +08:00
valve[data[0] - 1].valve_id = data[0];
rt_memcpy(valve[data[0] - 1].valve_mac, &data[1], FLASH_VALVE_MAC_ADDR_LEN); // 将信息更新
2024-12-13 19:07:17 +08:00
if (Bt_Valve_Handler(kValveCmdReg, data[0] - 1, RT_NULL) != RT_EOK)
2024-12-05 09:13:31 +08:00
{
LOG_E("新增阀门设备失败\n");
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_ADD, temp, RESPONSE_CODE_ACTION_FAILURE);
return RT_ERROR;
}
2024-12-16 15:35:19 +08:00
// TODO:此处需要等待蓝牙响应数据
if (rt_sem_take(&bt_reg_sem, 10000) != RT_EOK) // 等待十秒获取信号量
2024-12-13 19:07:17 +08:00
{
LOG_E("获取信号量失败\n");
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_ADD, temp, RESPONSE_CODE_ACTION_FAILURE);
return RT_ERROR;
}
else
{
if (Flash_Set_Mac_Addr(&data[1], (data[0] - 1)) == RESET)
{
LOG_E("阀门设备写入FLash失败\n");
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_ADD, temp, RESPONSE_CODE_ACTION_FAILURE);
return RT_ERROR;
}
LOG_D("新增阀门设备成功\n");
Flash_Set_Valve_Num(cnt + 1);
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_ADD, temp, RESPONSE_CODE_SUCCESS);
return RT_EOK;
}
2024-12-05 09:13:31 +08:00
}
2024-12-13 19:07:17 +08:00
else // 不为空,不添加
2024-12-05 09:13:31 +08:00
{
LOG_E("该阀门设备已存在,请选择更换阀门编号后重试\n");
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_ADD, temp, RESPONSE_CODE_OTHER_ERROR);
return RT_EOK;
}
2024-12-04 18:55:59 +08:00
}
2024-12-13 19:07:17 +08:00
return RT_EOK;
2024-12-04 18:55:59 +08:00
}
/*更换阀门设备*/
rt_err_t Handle_Valve_Replace(struct Ml307_Ops *ops)
{
2024-12-05 16:57:19 +08:00
size_t i = 0;
rt_uint8_t data[13] = {0};
rt_uint8_t mac_addr[FLASH_VALVE_MAC_ADDR_LEN] = {0};
char imei[16] = {0};
char temp[32] = "0";
2024-12-04 18:55:59 +08:00
Get_Iot_Imei(imei, FLASH_NB_IMEI_LEN);
String2Hex(temp, imei); // 将字符串转为十六进制字符串
2024-12-05 16:57:19 +08:00
rt_memcpy(data, (ops->recv->recv_data.res_data + 3), (2 * FLASH_VALVE_MAC_ADDR_LEN + 1));
/*设备编号1byte+ 新MAC地址6+ 旧阀门MAC地址6 + 补零字节= 15byte*/
if (Flash_Get_Mac_Addr(mac_addr, data[0]) == RT_EOK)
{
for (; i < FLASH_VALVE_MAC_ADDR_LEN; i++)
{
if (mac_addr[i] != data[i + 7])
{
LOG_E("旧阀门MAC地址错误\n");
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_REPLACE, temp, RESPONSE_CODE_OTHER_ERROR);
2024-12-13 19:07:17 +08:00
2024-12-05 16:57:19 +08:00
return RT_ERROR;
}
}
LOG_D("data[0] = %x data[1] = %x data[2] = %x data[3] = %x data[4] = %x, data[5] = %x data[6] = %x data[7] = %x data[8] = %x data[9] = %x data[10] = %x data[11] = %x data[12] = %x",
data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12]);
if (i == FLASH_VALVE_MAC_ADDR_LEN)
{
2024-12-16 15:35:19 +08:00
if (Bt_Valve_Handler(kValveCmdRep, data[0] - 1, &data[2]) != RT_EOK)
2024-12-13 19:07:17 +08:00
{
LOG_E("更换阀门设备失败\n");
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_REPLACE, temp, RESPONSE_CODE_ACTION_FAILURE);
return RT_ERROR;
}
2024-12-05 16:57:19 +08:00
if (Flash_Set_Mac_Addr(&data[2], data[0]) == RESET)
{
LOG_E("更换阀门设备失败\n");
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_REPLACE, temp, RESPONSE_CODE_ACTION_FAILURE);
return RT_ERROR;
}
LOG_D("更换阀门设备成功\n");
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_REPLACE, temp, RESPONSE_CODE_SUCCESS);
return RT_EOK;
}
}
2024-12-05 09:13:31 +08:00
if (Flash_Set_Mac_Addr(&data[1], data[0]) == RESET)
2024-12-04 18:55:59 +08:00
{
LOG_E("更换阀门设备失败\n");
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_REPLACE, temp, RESPONSE_CODE_ACTION_FAILURE);
return RT_ERROR;
}
else
{
LOG_D("更换阀门设备成功\n");
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_REPLACE, temp, RESPONSE_CODE_SUCCESS);
return RT_EOK;
}
}
/*移除阀门设备*/
rt_err_t Handle_Remove_Valve(struct Ml307_Ops *ops)
{
rt_uint8_t data[6] = {0};
char imei[16] = {0};
char temp[32] = "0";
rt_uint8_t cnt = Flash_Get_Valve_Num();
Get_Iot_Imei(imei, FLASH_NB_IMEI_LEN);
String2Hex(temp, imei); // 将字符串转为十六进制字符串
if (cnt == 0)
{
LOG_E("阀门设备数量为0, 无法移除\n");
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_REMOVE, temp, RESPONSE_CODE_ACTION_FAILURE);
2024-12-13 19:07:17 +08:00
2024-12-04 18:55:59 +08:00
return RT_ERROR;
}
rt_memcpy(data, (ops->recv->recv_data.res_data + 8), FLASH_VALVE_MAC_ADDR_LEN + 1);
LOG_D("data[0] = %x data[1] = %x data[2] = %x data[3] = %x data[4] = %x, data[5] = %x", data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
rt_memset(&data[1], 0, sizeof(data) - 1);
2024-12-13 19:07:17 +08:00
if (Bt_Valve_Handler(kValveCmdRem, data[0] - 1, RT_NULL) != RT_EOK)
{
LOG_E("移除阀门设备失败\n");
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_REMOVE, temp, RESPONSE_CODE_ACTION_FAILURE);
return RT_ERROR;
}
2024-12-05 16:57:19 +08:00
if (Flash_Set_Mac_Addr(&data[1], data[0] - 1) == RESET)
2024-12-04 18:55:59 +08:00
{
LOG_E("移除阀门设备失败\n");
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_REMOVE, temp, RESPONSE_CODE_ACTION_FAILURE);
2024-12-13 19:07:17 +08:00
2024-12-04 18:55:59 +08:00
return RT_ERROR;
}
else
{
LOG_D("移除阀门设备成功\n");
Flash_Set_Valve_Num(cnt - 1);
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_REMOVE, temp, RESPONSE_CODE_SUCCESS);
2024-12-13 19:07:17 +08:00
2024-12-04 18:55:59 +08:00
return RT_EOK;
}
2024-12-03 10:24:55 +08:00
}
void Handle_Error(struct Ml307_Ops *ops, rt_err_t ret)
{
LOG_E("数据帧解析失败,错误码: %d", ret);
char imei[16] = {0};
char temp[32] = "0";
Get_Iot_Imei(imei, FLASH_NB_IMEI_LEN);
String2Hex(temp, imei); // 将字符串转为十六进制字符串
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, ops->recv->cmd, temp, RESPONSE_CODE_PARSE_FAIL);
}
void Handle_Instruction_Down(struct Ml307_Ops *ops)
{
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)ops;
switch (ml307_ops->recv->recv_data.event_type)
{
case INSTRUCTION_DOWN_SELF_CHECK:
Handle_Self_Check(ml307_ops);
break;
case INSTRUCTION_DOWN_MUTE:
Handle_Mute(ml307_ops);
break;
case INSTRUCTION_DOWN_CLOSE_VALVE:
Handle_Close_Valve(ml307_ops);
break;
case INSTRUCTION_DOWN_OPEN_VALVE:
Handle_Open_Valve(ml307_ops);
break;
case INSTRUCTION_DOWN_OPEN_RELAY:
Handle_Open_Relay(ml307_ops);
break;
case INSTRUCTION_DOWN_CLOSE_RELAY:
Handle_Close_Relay(ml307_ops);
break;
case INSTRUCTION_DOWN_QUERY_PARAMS:
Handle_Query_Params(ml307_ops);
break;
case INSTRUCTION_DOWN_CONFIG_PARAMS:
Handle_Config_Params(ml307_ops);
break;
case INSTRUCTION_DOWN_TIME_CALIBRATION:
Handle_Time_Calibration_Data(ml307_ops);
break;
case INSTRUCTION_DOWN_SEVER_ADDR:
Handle_Sever_Addr_Set(ml307_ops);
break;
2024-12-04 18:55:59 +08:00
case INSTRUCTION_DOWN_VALVE_ADD:
Handle_Valve_Add(ml307_ops);
break;
case INSTRUCTION_DOWN_VALVE_REPLACE:
Handle_Valve_Replace(ml307_ops);
break;
case INSTRUCTION_DOWN_VALVE_REMOVE:
Handle_Remove_Valve(ml307_ops);
break;
2024-12-03 10:24:55 +08:00
}
}
void Handle_Time_Calibration(struct Ml307_Ops *ops)
{
rt_uint8_t data[10] = {0};
LOG_D("服务器下发时间校准数据\n");
rt_memcpy(data, ops->recv->recv_data.res_data, sizeof(data));
TsRtcDateTime rtc_dt;
// 提取后4个字节作为时间戳
time_t timestamp = (data[6] << 24) | (data[7] << 16) | (data[8] << 8) | data[9];
Timestamp_To_Rtc_DateTime(timestamp, &rtc_dt);
// 打印结果
LOG_I("时间: %04d-%02d-%02d %02d:%02d:%02d (星期%d)\n",
rtc_dt.year, rtc_dt.month, rtc_dt.day, rtc_dt.hour, rtc_dt.minute, rtc_dt.second, rtc_dt.week);
RTC_SetTime(rtc_dt.year, rtc_dt.month, rtc_dt.day, rtc_dt.hour, rtc_dt.minute, rtc_dt.second); /* Setup Time */
ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_TIME_CALIBRATION, ML307_DEFIENE_DATA, RESPONSE_CODE_SUCCESS);
}
void Handle_Cmd_Type(struct Ml307_Ops *ops)
{
struct Ml307_Ops *ml307_ops = (struct Ml307_Ops *)ops;
switch (ml307_ops->recv->cmd)
{
case CMD_TYPE_SERVER_REPLY:
Handle_Server_Reply(ml307_ops);
break;
case CMD_TYPE_INSTRUCTION_DOWN:
Handle_Instruction_Down(ml307_ops);
break;
case CMD_TYPE_TIME_CALIBRATION:
Handle_Time_Calibration(ml307_ops);
break;
default:
ml307_ops->Resp(ml307_ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, ops->recv->cmd, ML307_DEFIENE_DATA, RESPONSE_CODE_PARSE_FAIL);
break;
}
}
void Analyze_Recv_Frame(struct at_device *device, struct Ml307_Ops *ops)
{
rt_err_t ret = RT_EOK;
2024-12-05 16:57:19 +08:00
// Reset_Ml307_Life_Timer(); // 只要数据,则重置定时器,不管数据是否正确
2024-12-03 10:24:55 +08:00
ret = Compare_HeaderToTail(ops);
if (ret == RT_EOK)
{
Handle_Cmd_Type(ops);
}
else
{
Handle_Error(ops, ret);
}
}
/*
120
*/
static void Ml307_Send_Thread_Entry(void *param)
{
rt_err_t result = RT_EOK;
rt_uint32_t ml307_recv_event;
LOG_D("ml307 thread entry\n");
2024-12-04 18:55:59 +08:00
struct Ml307_Ops *ops = (struct Ml307_Ops *)param;
2024-12-03 10:24:55 +08:00
struct at_device_ml307 *ml307 = &_dev;
2024-12-04 18:55:59 +08:00
struct at_device *device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, ml307->device_name);
2024-12-03 10:24:55 +08:00
RT_ASSERT(device);
if (ops->init(ops, PROTOCOL_VERSION) != RT_EOK)
{
LOG_E("ml307 init failed\n");
}
else
{
LOG_D("ml307 init success\n");
rt_completion_wait(&ml307_init_complate, RT_WAITING_FOREVER); // wait for ml307 init finish
Ml307_Send_Event(kMl307PowerOnEvent);
}
while (1)
{
result = rt_event_recv(&at_device_event,
Ml307_Get_Event_Flag(kMl307PowerOnEvent) |
Ml307_Get_Event_Flag(kMl307HeartbeatEvent) |
Ml307_Get_Event_Flag(kMl307SelfCheckEvent) |
Ml307_Get_Event_Flag(kMl307SilenceEvent) |
Ml307_Get_Event_Flag(kMl307ExceptionEvent) |
Ml307_Get_Event_Flag(kMl307ValveStatusEvent) |
Ml307_Get_Event_Flag(kMl307FanStatusEvent) |
Ml307_Get_Event_Flag(kMl307TempAnomalyEvent) |
Ml307_Get_Event_Flag(kMl307PowerOnEvent) |
Ml307_Get_Event_Flag(kMl307PowerDownEvent) |
Ml307_Get_Event_Flag(kMl307AlarmEvent) |
Ml307_Get_Event_Flag(kMl307AlarmRcyEvent) |
Ml307_Get_Event_Flag(kMl307FaultEvent) |
Ml307_Get_Event_Flag(kMl307FaultRcyEvent) |
Ml307_Get_Event_Flag(kMl307DeviceFailureEvent) |
Ml307_Get_Event_Flag(kMl307TimeCalibrationEvent),
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
RT_WAITING_FOREVER, &ml307_recv_event); // 这个事件一般是设备端发生了变化,发送到服务器时调用
if (result == RT_EOK)
{
LOG_D("ml307 recv event OK\n");
if (ml307_conncet_tcp_flag != 1)
{
if (device->class->device_ops->control(device, AT_DEVICE_CTRL_NET_CONN, RT_NULL) == RT_EOK) // 打开连接
{
LOG_I("ml307 connect tcp success\n");
}
else
{
LOG_E("ml307 connect tcp failed\n");
}
}
if (ml307_conncet_tcp_flag)
{
2024-12-05 16:57:19 +08:00
// Reset_Ml307_Life_Timer();
2024-12-03 10:24:55 +08:00
if (ml307_recv_event & Ml307_Get_Event_Flag(kMl307PowerOnEvent))
{
result = Ml307_Process_Events(kMl307PowerOnEvent, device, ops); // 当上电心跳包发送不成功时,其他事件不启动
if (result)
{
power_on_send_flag = 0;
rt_timer_start(ml307_power_error_timer); // 启动重连定时器, 3min一次直到发送成功
LOG_E("ml307 send data failed result = [%d]\n", result);
}
else
{
rt_timer_start(ml307_timer); // 当上电心跳包发送成功时, 开始心跳包周期发送
power_on_send_flag = 1;
2024-12-05 16:57:19 +08:00
Ml307_Send_Event(kMl307TimeCalibrationEvent); // 上电网络连接成功时,更新下时间
2024-12-03 10:24:55 +08:00
rt_timer_start(ml307_upload_timer);
}
}
if (power_on_send_flag)
{
if (ml307_recv_event & Ml307_Get_Event_Flag(kMl307HeartbeatEvent))
{
result = Ml307_Process_Events(kMl307HeartbeatEvent, device, ops);
if (result)
{
LOG_E("ml307 send data failed result = [%d]\n", result);
}
}
else if (ml307_recv_event & Ml307_Get_Event_Flag(kMl307TimeCalibrationEvent))
{
Time_Calibration(device);
}
else if (ml307_recv_event & Ml307_Get_Event_Flag(kMl307AlarmEvent))
{
result = Ml307_Process_Events(kMl307AlarmEvent, device, ops);
if (result)
{
LOG_E("ml307 send data failed result = [%d]\n", result);
}
}
else if (ml307_recv_event & Ml307_Get_Event_Flag(kMl307AlarmRcyEvent))
{
result = Ml307_Process_Events(kMl307AlarmRcyEvent, device, ops);
if (result)
{
LOG_E("ml307 send data failed result = [%d]\n", result);
}
}
else if (ml307_recv_event & Ml307_Get_Event_Flag(kMl307FaultEvent))
{
if (device_state_flag != 1) // 当设备失效时,只上报失效信息
{
result = Ml307_Process_Events(kMl307FaultEvent, device, ops);
if (result)
{
LOG_E("ml307 send data failed result = [%d]\n", result);
}
}
}
else if (ml307_recv_event & Ml307_Get_Event_Flag(kMl307FaultRcyEvent))
{
result = Ml307_Process_Events(kMl307FaultRcyEvent, device, ops);
if (result)
{
LOG_E("ml307 send data failed result = [%d]\n", result);
}
}
else if (ml307_recv_event & Ml307_Get_Event_Flag(kMl307SelfCheckEvent))
{
result = Ml307_Process_Events(kMl307SelfCheckEvent, device, ops);
if (result)
{
LOG_E("ml307 send data failed result = [%d]\n", result);
}
}
else if (ml307_recv_event & Ml307_Get_Event_Flag(kMl307SilenceEvent))
{
result = Ml307_Process_Events(kMl307SilenceEvent, device, ops);
if (result)
{
LOG_E("ml307 send data failed result = [%d]\n", result);
}
}
else if (ml307_recv_event & Ml307_Get_Event_Flag(kMl307ExceptionEvent))
{
result = Ml307_Process_Events(kMl307ExceptionEvent, device, ops);
if (result)
{
LOG_E("ml307 send data failed result = [%d]\n", result);
}
}
else if (ml307_recv_event & Ml307_Get_Event_Flag(kMl307ValveStatusEvent))
{
result = Ml307_Process_Events(kMl307ValveStatusEvent, device, ops);
if (result)
{
LOG_E("ml307 send data failed result = [%d]\n", result);
}
}
else if (ml307_recv_event & Ml307_Get_Event_Flag(kMl307FanStatusEvent))
{
result = Ml307_Process_Events(kMl307FanStatusEvent, device, ops);
if (result)
{
LOG_E("ml307 send data failed result = [%d]\n", result);
}
}
else if (ml307_recv_event & Ml307_Get_Event_Flag(kMl307TempAnomalyEvent))
{
result = Ml307_Process_Events(kMl307TempAnomalyEvent, device, ops);
if (result)
{
LOG_E("ml307 send data failed result = [%d]\n", result);
}
}
else if (ml307_recv_event & Ml307_Get_Event_Flag(kMl307PowerDownEvent))
{
result = Ml307_Process_Events(kMl307PowerDownEvent, device, ops);
if (result)
{
LOG_E("ml307 send data failed result = [%d]\n", result);
}
2024-12-05 16:57:19 +08:00
ml307_event_initialized = RT_FALSE; // 当接收到掉电事件时,不再接收其他事件
// rt_event_detach(&at_device_event);
2024-12-03 10:24:55 +08:00
}
else if (ml307_recv_event & Ml307_Get_Event_Flag(kMl307DeviceFailureEvent))
{
result = Ml307_Process_Events(kMl307DeviceFailureEvent, device, ops);
if (result)
{
LOG_E("ml307 send data failed result = [%d]\n", result);
}
}
}
rt_thread_mdelay(1); // 释放下线程
}
}
}
}
static void Ml307_Recv_Thread_Entry(void *parameter)
{
2024-12-04 18:55:59 +08:00
struct Ml307_Ops *ops = (struct Ml307_Ops *)parameter;
2024-12-03 10:24:55 +08:00
struct at_device_ml307 *ml307 = &_dev;
2024-12-04 18:55:59 +08:00
struct at_device *device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, ml307->device_name);
2024-12-03 10:24:55 +08:00
RT_ASSERT(device);
rt_err_t ret;
LOG_D("ml307 recv thread entry\n");
while (1)
{
ret = rt_sem_take(ml307_recv_sem, RT_WAITING_FOREVER); // 这个主要用来处理的数据
if (ret == RT_EOK)
{
2024-12-05 16:57:19 +08:00
// rt_timer_start(ml307_life_timer);
2024-12-03 10:24:55 +08:00
/*对数据帧进行分析,判断所处的是对服务器响应还是指令下发*/
Analyze_Recv_Frame(device, ops);
}
}
}
static void Ml307_Life_Thread_Entry(void *parameter)
{
struct at_device_ml307 *ml307 = &_dev;
2024-12-04 18:55:59 +08:00
struct at_device *device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, ml307->device_name);
2024-12-03 10:24:55 +08:00
RT_ASSERT(device);
rt_err_t ret;
LOG_D("ml307_life_thread entry\n");
while (1)
{
ret = rt_sem_take(ml307_life_sem, RT_WAITING_FOREVER);
if (ret == RT_EOK)
{
2024-12-05 16:57:19 +08:00
if (ml307_conncet_tcp_flag != RT_TRUE)
2024-12-03 10:24:55 +08:00
{
2024-12-05 16:57:19 +08:00
device->class->device_ops->control(device, AT_DEVICE_CTRL_NET_CONN, RT_NULL);
LOG_D("retry ml307 tcp connect\n ");
2024-12-03 10:24:55 +08:00
}
}
}
}
// 定时器回调函数,当1分钟内没有数据交互时关闭tcp连接
static void Ml307_Upload_Timer_Cb(void *parameter)
{
Ml307_Send_Event(kMl307TimeCalibrationEvent); // 更新下时间
}
int BSP_Ml307_Thread_Init(void)
{
rt_err_t ret;
Ml307_Event_Init();
rt_uint32_t nb_upload_time = (uint16_t)Flash_Get_SysCfg(kIotUploadCycleId);
unsigned long timeout = nb_upload_time * 60 * RT_TICK_PER_SECOND;
LOG_I("上报服务器周期:%d分钟", nb_upload_time);
ml307_mutex = rt_mutex_create("ml307_mutex", RT_IPC_FLAG_FIFO);
if (ml307_mutex == RT_NULL)
{
LOG_E("ml307_mutex create failed");
}
ml307_recv_sem = rt_sem_create("ml307_recv", 0, RT_IPC_FLAG_FIFO);
if (ml307_recv_sem == RT_NULL)
{
LOG_E("ml307_recv_sem create failed");
}
ml307_life_sem = rt_sem_create("ml307_life", 0, RT_IPC_FLAG_FIFO);
if (ml307_life_sem == RT_NULL)
{
LOG_E("ml307_life_sem create failed");
}
// 创建定时器
ml307_timer = rt_timer_create("heartbeat",
2024-12-04 18:55:59 +08:00
Ml307_Ht_Timer_Cb, // 回调函数
RT_NULL, // 参数
timeout, // 定时周期120分钟
RT_TIMER_FLAG_PERIODIC); // 周期性定时器
2024-12-03 10:24:55 +08:00
if (ml307_timer == RT_NULL)
{
rt_kprintf("创建定时器失败\n");
return -1;
}
ml307_power_error_timer = rt_timer_create("ml307_error_timer",
2024-12-04 18:55:59 +08:00
Ml307_Error_Timer_Cb,
RT_NULL,
3 * 60 * RT_TICK_PER_SECOND, // 3分钟
RT_TIMER_FLAG_PERIODIC);
2024-12-03 10:24:55 +08:00
ml307_upload_timer = rt_timer_create("ml307_upload_timer",
2024-12-04 18:55:59 +08:00
Ml307_Upload_Timer_Cb,
RT_NULL,
24 * 60 * RT_TICK_PER_SECOND, //
RT_TIMER_FLAG_PERIODIC);
2024-12-03 10:24:55 +08:00
// 创建定时器
ml307_heartbeat_check_timer = rt_timer_create("ml307_check_hb",
2024-12-04 18:55:59 +08:00
Ml307_Heartbeat_check_Timer_Cb,
RT_NULL,
timeout * 3, // 3个定时心跳没有发送就重启发送
RT_TIMER_FLAG_PERIODIC);
2024-12-03 10:24:55 +08:00
if (ml307_heartbeat_check_timer != RT_NULL)
{
rt_timer_start(ml307_heartbeat_check_timer);
}
ret = rt_thread_init(&ml307_thread,
"ml307_send_thread",
Ml307_Send_Thread_Entry,
&ml307_ops,
&ml307_thread_stack[0],
sizeof(ml307_thread_stack),
ML307_THREAD_PRIORITY,
ML307_THREAD_TICKS);
rt_thread_startup(&ml307_thread);
ret = rt_thread_init(&ml307_recv_thread,
"ml307_recv_thread",
Ml307_Recv_Thread_Entry,
&ml307_ops,
&ml307_recv_thread_stack[0],
sizeof(ml307_recv_thread_stack),
ML307_RECV_THREAD_PRIORITY,
ML307_RECV_THREAD_TICKS);
rt_thread_startup(&ml307_recv_thread);
ret = rt_thread_init(&ml307_life_thread,
"ml307_life_thread",
Ml307_Life_Thread_Entry,
&ml307_ops,
&ml307_life_thread_stack[0],
sizeof(ml307_life_thread_stack),
ML307_LIFE_THREAD_PRIORITY,
ML307_LIFE_THREAD_TICKS);
2024-12-13 19:07:17 +08:00
rt_thread_startup(&ml307_life_thread);
2024-12-03 10:24:55 +08:00
return ret;
}
INIT_APP_EXPORT(BSP_Ml307_Thread_Init);
static int ml307_device_register(void)
{
struct at_device_ml307 *ml307 = &_dev;
return at_device_register(&(ml307->device),
ml307->device_name,
ml307->client_name,
AT_DEVICE_CLASS_ML307,
(void *)ml307);
}
2024-12-04 10:31:57 +08:00
INIT_DEVICE_EXPORT(ml307_device_register);
2024-12-03 10:24:55 +08:00
#endif // IOT_MODULE_SWITCH