TT12-MCU/applications/alarmer.c
2023-08-26 16:49:19 +08:00

317 lines
8.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-06-19 murmur the first version
*/
/*
** 程序清单:这是一个 RTC 设备使用例程
** 例程导出了 alarm_sample 命令到控制终端
** 命令调用格式alarm_sample
** 程序功能设置RTC时间创建闹钟模式每秒触发启动闹钟
**/
#include <rtthread.h>
#include <rtdevice.h>
#define LOG_TAG "alarm"
#define LOG_LVL LOG_LVL_DBG
#include <ulog.h>
void user_alarm_callback(rt_alarm_t alarm, time_t timestamp)
{
rt_kprintf("user alarm callback function.\n");
}
void alarm_sample(int argc, char *argv[])
{
rt_device_t dev = rt_device_find("rtc");
struct rt_alarm_setup setup;
struct rt_alarm * alarm = RT_NULL;
static time_t now;
struct tm p_tm;
if (alarm != RT_NULL)
return;
/* 获取当前时间戳,并把下一秒时间设置为闹钟时间 */
now = time(NULL) + 10;
gmtime_r(&now,&p_tm);
setup.flag = RT_ALARM_DAILY;
setup.wktime.tm_year = p_tm.tm_year;
setup.wktime.tm_mon = p_tm.tm_mon;
setup.wktime.tm_mday = p_tm.tm_mday;
setup.wktime.tm_wday = p_tm.tm_wday;
setup.wktime.tm_hour = atoi(argv[1]);//p_tm.tm_hour;
setup.wktime.tm_min = 0;//p_tm.tm_min;
setup.wktime.tm_sec = 0;//p_tm.tm_sec;
alarm = rt_alarm_create(user_alarm_callback, &setup);
if(RT_NULL != alarm)
{
rt_alarm_start(alarm);
LOG_D("alarm started.");
}
}
/* export msh cmd */
MSH_CMD_EXPORT(alarm_sample,alarm sample);
void poTT_callback(rt_alarm_t alarm, time_t timestamp)
{
LOG_D("power UP TT by RTC.");
initTT();
setWindowMode();
}
void pdTT_callback(rt_alarm_t alarm, time_t timestamp)
{
LOG_D("power DOWN TT by RTC.");
deInitTT();
}
void poTT2_callback(rt_alarm_t alarm, time_t timestamp)
{
LOG_D("power UP TT by RTC.");
initTT();
}
//每个开窗设置对应两个rtc闹钟一个上电一个下电
//更新开窗设置前需要先清空闹钟设置。可改为调用rt_alarm_control()修改。
static struct rt_alarm *alarm[4+1];//支持2组开窗共4个闹钟加一个定时发送闹钟
#ifndef al
void InitAlarm()
{
struct rt_alarm_setup setup;
time_t now;
struct tm p_tm;
/* 获取当前时间戳,并把下一秒时间设置为闹钟时间 */
now = time(NULL);
gmtime_r(&now, &p_tm);
setup.flag = RT_ALARM_DAILY;//天重复
setup.wktime.tm_year = p_tm.tm_year;
setup.wktime.tm_mon = p_tm.tm_mon;
setup.wktime.tm_mday = p_tm.tm_mday;
setup.wktime.tm_wday = p_tm.tm_wday;
setup.wktime.tm_hour = 1; //整点
setup.wktime.tm_min = 0; //p_tm.tm_min;
setup.wktime.tm_sec = 0; //p_tm.tm_sec;
if (RT_NULL != alarm[0])
{
rt_alarm_delete(alarm[0]); //
}
alarm[0] = rt_alarm_create(poTT_callback, &setup);
setup.wktime.tm_hour = 2; //开窗1闭合点
if (RT_NULL != alarm[1])
{
rt_alarm_delete(alarm[1]); //
}
alarm[1] = rt_alarm_create(pdTT_callback, &setup);
setup.wktime.tm_hour = 7; //开窗2开启点
if (RT_NULL != alarm[2])
{
rt_alarm_delete(alarm[2]); //
}
alarm[2] = rt_alarm_create(poTT_callback, &setup);
setup.wktime.tm_hour = 8; //开窗2闭合点
if (RT_NULL != alarm[3])
{
rt_alarm_delete(alarm[3]); //
}
alarm[3] = rt_alarm_create(pdTT_callback, &setup);
setup.flag = RT_ALARM_HOUR;//小时重复
setup.wktime.tm_min = 15; //每小时的1刻钟启动发送
if (RT_NULL != alarm[4])
{
rt_alarm_delete(alarm[4]); //
}
alarm[4] = rt_alarm_create(poTT2_callback, &setup);
for (size_t var = 0; var < 5; var++) {
if (alarm[var] != RT_NULL) {
rt_alarm_start(alarm[var]);
// LOG_D("alarm %d(%02d:%02d) started.",var+1,alarm[var]->wktime.tm_hour+8,alarm[var]->wktime.tm_min);
}
else {
LOG_E("Failed to start alarm %d.",var+1);
}
}
}
#else
void updateAlarm(uint8_t *t, size_t len);
void InitAlarm()
{
updateAlarm(scfg.openWindowTime, 8);
}
#endif
INIT_APP_EXPORT(InitAlarm);
/**
* 更新rtc闹钟
* @param t 每个rtc时刻组成的数组依次对应开窗时段的开始和结束
*/
void updateAlarm(uint8_t *t, size_t len)
{
// LOG_HEX("alarm",16,t,4);
struct rt_alarm_setup setup;
time_t now;
struct tm p_tm;
/* 获取当前时间戳,并把下一秒时间设置为闹钟时间 */
now = time(NULL);
gmtime_r(&now, &p_tm);
setup.flag = RT_ALARM_DAILY;//天重复
setup.wktime.tm_year = p_tm.tm_year;
setup.wktime.tm_mon = p_tm.tm_mon;
setup.wktime.tm_mday = p_tm.tm_mday;
setup.wktime.tm_wday = p_tm.tm_wday;
// setup.wktime.tm_hour = 1; //整点
setup.wktime.tm_min = 0; //p_tm.tm_min;
setup.wktime.tm_sec = 0; //p_tm.tm_sec;
setup.wktime.tm_hour = t[0]; //开窗1开启点
setup.wktime.tm_min = t[1]; //开窗1开启点
if (RT_NULL != alarm[0])
{
rt_alarm_delete(alarm[0]); //
}
alarm[0] = rt_alarm_create(poTT_callback, &setup);
setup.wktime.tm_hour = t[2]; //开窗1闭合点
setup.wktime.tm_min = t[3]; //开窗1开启点
if (RT_NULL != alarm[1])
{
rt_alarm_delete(alarm[1]); //
}
alarm[1] = rt_alarm_create(pdTT_callback, &setup);
setup.wktime.tm_hour = t[4]; //开窗2开启点
setup.wktime.tm_min = t[5]; //开窗2开启点
if (RT_NULL != alarm[2])
{
rt_alarm_delete(alarm[2]); //
}
alarm[2] = rt_alarm_create(poTT_callback, &setup);
setup.wktime.tm_hour = t[6]; //开窗2闭合点
setup.wktime.tm_min = t[7]; //开窗2开启点
if (RT_NULL != alarm[3])
{
rt_alarm_delete(alarm[3]); //
}
alarm[3] = rt_alarm_create(pdTT_callback, &setup);
for (size_t var = 0; var < 4; var++) {
if (alarm[var] != RT_NULL) {
rt_alarm_start(alarm[var]);
// LOG_D("alarm %d started.",var+1);
LOG_D("alarmer %d(%02d:%02d) started.",var+1,alarm[var]->wktime.tm_hour+8,alarm[var]->wktime.tm_min);
}
else {
LOG_E("Failed to start alarm %d.",var+1);
}
}
// rt_alarm_control(alarm[0],RT_ALARM_CTRL_MODIFY,&setup);
}
/**
* 关闭rtc闹钟
*/
void stopAlarm()
{
for (size_t var = 0; var < 4; var++) {
if (alarm[var] != RT_NULL) {
rt_alarm_stop(alarm[var]);
LOG_D("alarm %d stopped.",var+1);
}
else {
LOG_E("Failed to stop alarm %d.",var+1);
}
}
}
/**
* 恢复rtc闹钟
*/
void startAlarm()
{
for (size_t var = 0; var < 4; var++) {
if (alarm[var] != RT_NULL) {
rt_alarm_start(alarm[var]);
LOG_D("alarm %d started.",var+1);
}
else {
LOG_E("Failed to start alarm %d.",var+1);
}
}
}
/**
* check if in the WINs zone
* @return 1-in,0-not in
*/
int isInWindowZone()
{
struct timeval tv;
gettimeofday(&tv, NULL);
time_t now = (long) tv.tv_sec;
// LOG_D("now = %ld", now);
struct tm *alBegin = &alarm[0]->wktime;
alBegin->tm_hour += 8;
time_t tBegin = mktime(alBegin);
struct tm *alEnd = &alarm[1]->wktime;
alEnd->tm_hour += 8;
time_t tEnd = mktime(alEnd);
// LOG_D("%ld-%ld", (long)tBegin,(long)tEnd);
uint8_t isIn1 = (now > tBegin && now < tEnd);
alBegin = &alarm[2]->wktime;
alBegin->tm_hour += 8;
tBegin = mktime(alBegin);
alEnd = &alarm[3]->wktime;
alEnd->tm_hour += 8;
tEnd = mktime(alEnd);
// LOG_D("%ld-%ld", (long)tBegin,(long)tEnd);
uint8_t isIn2 = (now > tBegin && now < tEnd);
if (isIn1 || isIn2)
{
LOG_D("is in window zone.");
return 1;
}
else {
return 0;
}
}
//读取系统毫秒级时间
//long getCurrentTime()
//
//{
//
//struct timeval tv;
//
//gettimeofday(&tv,NULL);
//
//LOG_D("ms=%lld", tv.tv_sec * 1000 + tv.tv_usec / 1000);
//
//LOG_D("Current time: %ld.%06ld\n", tv.tv_sec, tv.tv_usec);
//
//}
MSH_CMD_EXPORT(stopAlarm,stop);
MSH_CMD_EXPORT(startAlarm,start);
MSH_CMD_EXPORT(isInWindowZone,isInWindow);
//MSH_CMD_EXPORT(getCurrentTime,getCurrentTime);