本项目中的邮件报警模块在用户在网页激活后会自动监测当前的温度,并且与用户设置的温度阈值做比较,一旦检测到当前温度超过用户设定的温度阈值,系统便会向用户所指定的邮箱发送一封报警邮件。当然,你也可以接入各种各样的监测模块,实现更多状态的监测与报警。

目录

SMTP 软件包的使用

邮件报警模块源码详解

模块结构体

模块函数简介

模块函数详解

smtp_module_init

prepare_content

smtp_thread

smtp_data_config

smtp_enable&smtp_disable

json_create_smtp_data


SMTP 软件包的使用

邮件使用的是SMTP_CLIENT软件包,查看软件包链接。

该软件包实现了基于SMTP协议的邮件发送功能,并且支持加密端口,但其对用户提供的接口非常简洁易懂,使用者并不需要了解SMTP协议的具体内容便可非常方便地使用。在本项目中,使用到了如下接口:

smtp_client_init()        //初始化 smtp_client 客户端smtp_set_server_addr()    //设置服务器的地址及端口smtp_set_auth()           //设置服务器认证信息smtp_add_receiver()       //添加收件人地址smtp_send_mail()          //发送邮件

以上接口顺序执行就是一个完整的smtp邮件发送流程。在本项目中,虽然对其中的几个接口进行了进一步的封装从而实现更加高级的功能,但底层的逻辑还是上述接口。

邮件报警模块源码详解

模块结构体

邮件模块结构体如下所示:

typedef struct
{uint8_t enable;        //邮件功能使能uint32_t cold_time;    //报警冷却时间char server_addr[100]; //邮件服务器地址char server_port[10];  //邮件服务器端口char username[50];     //用户名char password[50];     //密码char receiver[100];    //收件人地址
} smtp_module_t;

enable成员是邮件功能的开启标志,cold_time存储了报警冷却时间,即两个连续的报警之间的最小间隔,若在这个间隔内模块不会进行第二次报警。server_addr为邮件服务器地址,server_port为邮件服务器端口,普通端口一般为 25,同时该软件包也支持465/587两个加密端口,需要注意的是,使用加密端口前应开启软件包加密功能,在env工具中的配置如下:

username与password分别为所要使用的发件人的用户名及密码,receiver是收件人的邮箱地址。

模块函数简介

函数名 函数简介
smtp_module_init 邮件模块初始化
prepare_content 生成报警内容
smtp_thread 邮件核心处理线程
smtp_data_config 配置邮件参数
smtp_enable&smtp_disable 邮件报警功能启用/禁用
json_create_smtp_data 生成邮件参数json字符串

模块函数详解

smtp_module_init

该函数为smtp模块初始化函数,该函数实现了邮件工作线程的创建与开启。

int smtp_module_init(void)
{rt_thread_t smtp_client_tid;//创建邮件发送线程(如果选择在主函数中直接调用邮件发送函数,需要注意主函数堆栈大小,必要时调大)smtp_client_tid = rt_thread_create("smtp", smtp_thread, RT_NULL, SMTP_CLIENT_THREAD_STACK_SIZE, 20, 5);if (smtp_client_tid != RT_NULL){rt_thread_startup(smtp_client_tid);}return RT_EOK;
}

prepare_content

该函数实现了邮件内容的拼接,将当前温湿度加入到报警字符串中。

//准备邮件内容
static void prepare_content(void)
{sprintf(content, "W601监测系统报警\r\n-------------------------\r\n当前温度:%.2f C\r\n当前湿度:%.2f%% \r\n",w601_aht10.cur_temp, w601_aht10.cur_humi);
}

smtp_thread

该函数为邮件工作的主线程,在该线程的一开始对smtp客户端进行初始化。在线程中,首先会检测邮件报警功能是否开启,若开启了该功能,系统会比对当前温度和报警阈值温度,若当前温度超出了报警阈值温度,同时报警冷却时间已到(最近一段时间内没有产生过报警),系统便会生成报警字符串并且发送报警邮件。

void smtp_thread(void *param)
{//初始化smtp客户端smtp_client_init();//清空设置rt_memset(&w601_smtp, 0, sizeof(smtp_module_t));while (1){if (w601_smtp.cold_time){w601_smtp.cold_time--;}if (w601_smtp.enable) //使能邮件功能{if (w601_aht10.cur_temp > w601_aht10.temp_warn) //有报警{//冷却时间内不重复报警if (w601_smtp.cold_time){}else{//设置报警冷却时间w601_smtp.cold_time = WARNING_COLD_TIME;LOG_W("system warning,smtp send!");prepare_content();smtp_send_mail(SMTP_SUBJECT, content);}}}rt_thread_mdelay(1000);}
}

smtp_data_config

该函数实现了邮件参数的设置功能,当接收到前端传来的设置请求时,系统会提取相对应的设置参数,并且将参数传入该函数,在该函数中进行参数的配置。需要注意的是,由于本项目只支持一个收件人(软件包本身支持多收件人),所以在函数开头会删除原先已保存的收件人,并且在下面添加新的收件人。当然你也可以通过修改模块源码使其支持多收件人。

int smtp_data_config(char *server_addr, char *server_port,char *username, char *password,char *receiver, char *temp_warn)
{if (w601_smtp.receiver[0] != '\0'){smtp_delete_receiver(w601_smtp.receiver);}strcpy(w601_smtp.server_addr, server_addr);strcpy(w601_smtp.server_port, server_port);strcpy(w601_smtp.username, username);strcpy(w601_smtp.password, password);strcpy(w601_smtp.receiver, receiver);smtp_set_server_addr(w601_smtp.server_addr,ADDRESS_TYPE_DOMAIN,w601_smtp.server_port);smtp_set_auth(w601_smtp.username, w601_smtp.password);smtp_add_receiver(receiver);w601_aht10.temp_warn = atof(temp_warn);return 0;
}

smtp_enable&smtp_disable

这两个函数非常简单,通过给模块结构体的使能成员赋值来实现邮件功能的开关。用户通过网页进行开关设置。

void smtp_enable(void)
{w601_smtp.enable = 1;
}void smtp_disable(void)
{w601_smtp.enable = 0;
}

json_create_smtp_data

该函数是将邮件模块的参数转换为json格式的字符串,主要用于与网页的通信。将当前邮件参数传输给网页显示。

char *json_create_smtp_data(void)
{char *json_data = RT_NULL;char value[10] = "";cJSON *root = cJSON_CreateObject();snprintf(value, sizeof(value), "%.2f", w601_aht10.temp_warn);cJSON_AddItemToObject(root, "server_addr", cJSON_CreateString(w601_smtp.server_addr));cJSON_AddItemToObject(root, "server_port", cJSON_CreateString(w601_smtp.server_port));cJSON_AddItemToObject(root, "username", cJSON_CreateString(w601_smtp.username));cJSON_AddItemToObject(root, "password", cJSON_CreateString(w601_smtp.password));cJSON_AddItemToObject(root, "receiver", cJSON_CreateString(w601_smtp.receiver));cJSON_AddItemToObject(root, "temp_warn", cJSON_CreateString(value));cJSON_AddItemToObject(root, "enable", cJSON_CreateNumber(w601_smtp.enable));json_data = cJSON_PrintUnformatted(root);cJSON_Delete(root);return json_data;
}

W601温湿度监测与邮件报警系统 — 源码详解(邮件报警模块)相关推荐

  1. 【Live555】live555源码详解(九):ServerMediaSession、ServerMediaSubsession、live555MediaServer

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的三个类所在的位置: ServerMediaSession.ServerMediaSubsession.Dy ...

  2. 【Live555】live555源码详解系列笔记

    [Live555]liveMedia下载.配置.编译.安装.基本概念 [Live555]live555源码详解(一):BasicUsageEnvironment.UsageEnvironment [L ...

  3. 【Live555】live555源码详解(八):testRTSPClient

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的testRTSPClient实现的三个类所在的位置: ourRTSPClient.StreamClient ...

  4. 【Live555】live555源码详解(七):GenericMediaServer、RTSPServer、RTSPClient

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的三个类所在的位置: GenericMediaServer.RTSPServer.RTSPClient 14 ...

  5. 【Live555】live555源码详解(六):FramedSource、RTPSource、RTPSink

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的三个类所在的位置: FramedSource.RTPSource.RTPSink 11.FramedSou ...

  6. 【Live555】live555源码详解(五):MediaSource、MediaSink、MediaSession、MediaSubsession

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的四个类所在的位置: MediaSource.MediaSink.MediaSession.MediaSub ...

  7. 【Live555】live555源码详解(四):Medium媒体基础类

    [Live555]live555源码详解系列笔记 7.Media Medai所依赖关系图 依赖Medai关系图 Media和UsageEnvironment关联图

  8. 【Live555】live555源码详解(二):BasicHashTable、DelayQueue、HandlerSet

    [Live555]live555源码详解系列笔记 3.BasicHashTable 哈希表 协作图: 3.1 BasicHashTable BasicHashTable 继承自 HashTable 重 ...

  9. 【Live555】live555源码详解(一):BasicUsageEnvironment、UsageEnvironment

    [Live555]live555源码详解系列笔记 类关系图 1.UsageEnvironment 详解 1.1 BasicUsageEnvironment BasicUsageEnvironment ...

最新文章

  1. PHPExcel读取excel的多个sheet存入数据库
  2. Qt Creator连接Android设备
  3. 如何轻松将上亿的数据玩弄于股掌之中?
  4. 使用Akka处理1000万条消息
  5. Hystrix 熔断器舱壁模式
  6. 使用Python扩展库spleeter分离MP3音乐文件中的伴奏和人声
  7. 24. Navigator taintEnabled() 方法
  8. day6--pandas
  9. 数字信号处理实验matlab,数字信号处理实验Matlab代码
  10. 在我笔记本Ubuntu上装普罗米修斯记录
  11. vue 跳转html页面,vue项目实现页面的跳转
  12. 考研:研究生考试(五天学完)之《线性代数与空间解析几何》研究生学霸重点知识点总结之第四课欧氏空间
  13. 南京软件测试女薪资2019,2019年第一扎!南京最新平均工资最新出炉,看完不敢过年!...
  14. R语言——数据格式和数据读取
  15. 离散信号的抽取和内插例题_抽取和内插
  16. jemeter做微信公众号压测
  17. RAR文件解压缩时系统提示“CRC校验失败,文件被破坏”,修复损坏文件的办法!
  18. 软件测试面试题:什么是断言和验证?
  19. make[2]: *** [/home/nnnn/calibration/devel/lib/libcalibrationtoolkit.so] Error 1
  20. 获取Class的三种方法

热门文章

  1. MySQL忘记登录密码解决
  2. 照片变漫画怎么做?分享这几个照片变漫画的技巧给你
  3. 个人知识变现者必备基本功:造课卖课能力
  4. 鱼刺等食物卡到喉咙的海姆立克急救…
  5. TCPIP卷一(1):二层封装与路由器转发数据过程
  6. linux 触摸屏测试源码_Linux和android下测试键盘和触摸屏
  7. Java运行出现except,运行Struts项目时出现java.lang.reflect.InvocationTargetException异常解决办法...
  8. bootstrap富文本编辑器的使用
  9. 世上最健康的作息时间表 11点半睡觉7点半起床
  10. 最精彩的火狐集成器械栏──Stumble