/*** 
 * @Author: mbw
 * @Date: 2024-11-30 15:46:21
 * @LastEditors: mbw && 1600520629@qq.com
 * @LastEditTime: 2024-12-04 18:49:45
 * @FilePath: \ble_bjq_ch303rct6_ml307\bsp\inc\bsp_ml307.h
 * @Description: 
 * @
 * @Copyright (c) 2024 by ${git_name_email}, All Rights Reserved. 
 */

#include <at_device_ml307.h>
#include "drv_gpio.h"


#define MAX_VALVE_NUM 8


#define ML307_ENABLE_3_8_V       GET_PIN(B, 3)
#define ML307_PWR_PIN            GET_PIN(B, 4)
#define ML307_RST_PIN            GET_PIN(B, 5)
#define ML307_USIM_DECT_PIN      GET_PIN(B, 6)

#define ML307_SAMPLE_DEIVCE_NAME "ml307"

/*默认参数*/
#define DEVICE_MANUFACTURE 0x4454 // DT

/*命令集*/
#define CMD_TYPE_DEVICE_DATA_REPORT  0x10 // 命令类型 - 设备数据上报 (设备->平台)
#define CMD_TYPE_DEVICE_EVENT_REPORT 0x11 // 命令类型 - 设备事件上报 (设备->平台)
#define CMD_TYPE_SERVER_REPLY        0x12 // 命令类型 - 服务器回复 (平台->设备)
#define CMD_TYPE_INSTRUCTION_DOWN    0x13 // 命令类型 - 指令下发 (平台->设备)
#define CMD_TYPE_INSTRUCTION_REPLY   0x14 // 命令类型 - 指令下发回复 (设备->平台)
#define CMD_TYPE_TIME_CALIBRATION    0x15 // 命令类型 - 时间校准 (设备->平台)

#define PROTOCOL_VERSION             0x41 /*协议版本*/
/*数据序列号*/
#define DATA_SERIAL_NUM 0x0001 // 1

/*设备类型*/
#define DEVICE_TYPE_ML307 0x21

/*事件类型*/
#define EVENT_TYPE_HEARTBEAT        0x30 // 心跳事件
#define EVENT_TYPE_SELF_CHECK       0x31 // 自检事件
#define EVENT_TYPE_SILENCE          0x32 // 消音事件
#define EVENT_TYPE_EXCEPTION        0x33 // 异常事件
#define EVENT_TYPE_VALVE_STATUS     0x40 // 电磁阀状态改变事件
#define EVENT_TYPE_FAN_STATUS       0x41 // 风机状态改变事件
#define EVENT_TYPE_TEMP_ANOMALY     0x42 // 产品工作温度异常事件
#define EVENT_TYPE_POWER_ON         0x43 // 上电事件
#define EVENT_TYPE_POWER_OFF        0x44 // 掉电事件
#define EVENT_TYPE_ALARM            0x45 // 报警事件
#define EVENT_TYPE_ALARM_RECOVER    0x46 // 报警恢复事件
#define EVENT_TYPE_FAULT            0x47 // 故障事件
#define EVENT_TYPE_FAULT_RECOVER    0x48 // 故障恢复事件
#define EVENT_TYPE_DEVICE_FAILURE   0x49 // 设备失效事件
#define EVENT_TYPE_TIME_CALIBRATION 0x50 // 时间校准事件

/*调压器新增事件类型*/

/*指令下发*/
#define INSTRUCTION_DOWN_SELF_CHECK       0x50 // 指令下发 - 自检
#define INSTRUCTION_DOWN_MUTE             0x51 // 指令下发 - 消音
#define INSTRUCTION_DOWN_CLOSE_VALVE      0x52 // 指令下发 - 关阀
#define INSTRUCTION_DOWN_OPEN_VALVE       0x53 // 指令下发 - 开阀
#define INSTRUCTION_DOWN_OPEN_RELAY       0x54 // 指令下发 - 开继电器
#define INSTRUCTION_DOWN_CLOSE_RELAY      0x55 // 指令下发 - 关继电器
#define INSTRUCTION_DOWN_QUERY_PARAMS     0x56 // 指令下发 - 查询系统参数
#define INSTRUCTION_DOWN_CONFIG_PARAMS    0x57 // 指令下发 - 配置系统参数
#define INSTRUCTION_DOWN_TIME_CALIBRATION 0x58 // 指令下发 - 时间校准
#define INSTRUCTION_HEART_BEAT            0x59 // 心跳
#define INSTRUCTION_DOWN_SEVER_ADDR       0x60 // 设置服务器地址和端口

/**********************************调压器新增指令下发**********************************************************/
#define INSTRUCTION_DOWN_VALVE_ADD    0x61 // 新增阀门设备
#define INSTRUCTION_DOWN_VALVE_REPLACE 0x62 // 更换阀门设备
#define INSTRUCTION_DOWN_VALVE_REMOVE  0x63 // 移除阀门设备
/************************************************************************************************************/
#define RESPONSE_CODE_SUCCESS          0x00 // 响应码 - 操作成功
#define RESPONSE_CODE_CRC_FAIL         0x01 // 响应码 - CRC 校验失败
#define RESPONSE_CODE_PARSE_FAIL       0x02 // 响应码 - 数据解析失败(命令错误或者其他指令错误)
#define RESPONSE_CODE_ACTION_FAILURE   0x03 // 响应码 - 动作执行失败
#define RESPONSE_CODE_NO_FUNCTION      0xAF // 响应码 - 无此功能
#define RESPONSE_CODE_OTHER_ERROR      0xFF // 响应码 - 其他错误

#define MAX_DATA_LEN                   512 // 数据长度

#define ML307_DEFIENE_DATA             "000000000000000000000000000000"

#define DEVICE_DEFINE                  1 // 具备该设备功能
#define DEVICE_NOT_DEFINE              0 // 不具备该功能
#define DEVICE_CONNECTED               1 // 设备连接上
#define DEVICE_DISCONNECTED            0 // 设备未连接
#define DEVICE_OPEN                    1 // 设备开启
#define DEVICE_CLOSE                   0 // 设备关闭
typedef enum
{
    /****************优先级最低***************** */
    kMl307HeartbeatEvent,       // 定时心跳事件
    kMl307SilenceEvent,         // 消音事件
    kMl307ExceptionEvent,       // 异常事件
    kMl307ValveStatusEvent,     // 电磁阀状态改变事件
    kMl307FanStatusEvent,       // 风机状态改变事件
    kMl307TempAnomalyEvent,     // 产品工作温度异常事件
    kMl307AlarmEvent,           // 报警事件
    kMl307AlarmRcyEvent,        // 报警恢复事件
    kMl307FaultEvent,           // 故障事件
    kMl307FaultRcyEvent,        // 故障恢复事件
    kMl307DeviceFailureEvent,   // 设备失效事件
    kMl307TimeCalibrationEvent, // 时间校准事件
                                /**********************优先级第三************************* */
    kMl307SelfCheckEvent,       // 自检事件
                                /**********************优先级第二************************* */
    kMl307PowerDownEvent,       // 掉电事件
                                /**********************优先级第一************************* */
    kMl307PowerOnEvent,         // 上电事件

    kMl307MaxEventcnt // 最大事件计数
} Ml307Event;         // 当前所处的事件类型

typedef enum
{
    kHeartbeatStatus,         // 定时心跳状态
    kConcentrationHighStatus, // 浓度异常状态
    kSelfCheckStatus,         // 自检触发状态
    kAlarmStatus,             // 报警触发状态
    kAlarmClearedStatus,      // 报警解除状态
    kSensorFaultStatus,       // 传感器故障触发状态
    kSensorRecoveredStatus,   // 传感器故障解除状态
    kPowerDownStatus,         // 掉电状态
} Ml307Status;                // 当前所处的上报状态

typedef struct
{
    Ml307Event current_event; // 当前事件
    Ml307Event last_event;    // 上次事件
} Ml307EventIndex;

/*
无线调压阀编号
无线调压阀 MAC 地址
无线调压阀连接状态
无线调压阀开关状态
无线调压阀温度
无线调压阀进口压力
无线调压阀出口压力
无线调压阀大气压
*/
typedef struct valve_data valve_data_t;


struct __attribute__((packed)) valve_data
{
    uint8_t valve_id;
    uint8_t valve_mac[6];
    uint8_t valve_connct_status;
    uint8_t valve_switch_status;
    uint8_t valve_temp;
    uint32_t valve_in_pressure;
    uint32_t valve_out_pressure;
    uint32_t valve_atm_pressure;
};


struct __attribute__((packed)) DataBody
{
    uint8_t device_type;            // 设备类型
    uint8_t event_type;             // 事件类型
    uint8_t hw;                     // 硬件版本
    uint8_t sw;                     // 软件版本
    uint8_t imei[15];               // 设备编号（IMEI）
    uint8_t iccid[20];              // ICCID
    uint8_t imsi[15];               // IMSI
    uint8_t rssi;                   // RSSI
    uint8_t rsrp;                   // RSRP
    uint16_t gas_voltage;           // 传感器电压
    uint8_t product_work_temperature; //产品工作温度
    uint16_t work_duration; //工作时长
    uint8_t device_status; // 设备失效状态
    rt_uint8_t valve_num;           // 阀门数量
    struct valve_data valve_data[MAX_VALVE_NUM];
    //  valve_data_t* valve_data;       // 阀门数据指针
};

// 定义数据帧结构体
struct __attribute__((packed)) Ml307DataFrame
{
    uint8_t header[3];    // 帧头
    uint8_t version;      // 协议版本
    uint16_t manufacture; // 厂商标识
    uint16_t datanumber;  // 数据序列号
    uint8_t cmd;          // 命令位
    uint16_t datalen;     // 数据长度
    struct DataBody data; // 数据体
    uint16_t crc16;       // 校验位
    uint8_t tail[3];      // 帧尾
};

struct __attribute__((packed)) Ml307Data
{
    rt_uint8_t device_type;  // 设备类型
    rt_uint8_t event_type;   // 事件类型
    rt_uint8_t res_data[15]; //
    rt_uint8_t res_num;
};

struct __attribute__((packed)) Ml307RecvData
{
    rt_uint8_t header[3];       // 帧头
    rt_uint8_t version;         // 协议版本
    rt_uint16_t manufacture;    // 厂商标识
    rt_uint16_t datanumber;     // 数据序列号
    rt_uint8_t cmd;             // 命令位
    rt_uint16_t datalen;        // 数据长度
    struct Ml307Data recv_data; // 接收数据体
    rt_uint16_t crc16;          // 校验位
    rt_uint8_t tail[3];         // 帧尾
};

struct Ml307_Ops
{
    struct DataBody *body;
    struct Ml307DataFrame *frame;
    struct Ml307RecvData *recv;
    int (*init)(struct Ml307_Ops *ops, rt_uint8_t version);
    int (*update_data)(struct Ml307_Ops *ops, rt_uint8_t device_type, rt_uint8_t cmd);
    int (*send)(struct Ml307_Ops *ops, rt_uint8_t data_num, rt_uint8_t cmd, rt_uint8_t device_type, rt_uint8_t event_type);
    int (*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);
    int (*Recv)(struct Ml307_Ops *ops, char *data); // 解析数据
};

extern struct Ml307_Ops ml307_ops;
extern rt_sem_t ml307_recv_sem;
extern rt_uint8_t ml307_conncet_tcp_flag;

void Ml307_Send_Event(Ml307Event event_type);
