Files
BLE-USB_Dongle/apps/usr_utc/usr_plan.c
T

712 lines
22 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.
#include "app_config.h"
#include "key_event_deal.h"
#include "system/includes.h"
#include "tone_player.h"
#include "app_task.h"
#include "tone_player.h"
#include "media/includes.h"
#include "system/sys_time.h"
#include "ui/ui_api.h"
#include "clock_cfg.h"
#include "ui/ui_style.h"
#include "ui_manage.h"
#include "app_main.h"
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "printf.h"
#define MAX_ENTRIES 10
#define ENTRY_LENGTH 17
typedef struct {
bool weekdays[7]; // 周一到周日,true表示有效
int start_hour; // 开始时间(小时)
int start_minute; // 开始时间(分钟)
int end_hour; // 结束时间(小时)
int end_minute; // 结束时间(分钟)
bool is_valid; // 数据是否有效
} TimeSlot;
typedef struct {
TimeSlot slots[MAX_ENTRIES];
int count;
} TimeSlotResult;
// 星期枚举 - 按照周一到周日排列(1-7)
typedef enum {
MONDAY = 1,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
} Weekday;
extern uint32_t convertToUtcTimestamp(uint16_t year, uint8_t month, uint8_t day,uint8_t hour, uint8_t minute, uint8_t second);
extern void usr_plan_dec(u8* data,u8 cur_hour,u8 cur_min,u8 cur_week);
// 星期几转换为字符串
const char* weekdayNames[] = {"", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday", "Sunday"};
///"1000001+0928+3+1"
u8 usr_we_plan_table[170];
struct sys_time usr_current_time;
struct sys_time usr_set_time;
// 将两个字符转换为数字
static int parse_two_digits(const char* str) {
if (!isdigit(str[0])) return -1;
if (!isdigit(str[1])) return -1;
return (str[0] - '0') * 10 + (str[1] - '0');
}
// 解析单个时间区间数据
bool parse_single_entry(const char* data, TimeSlot* slot) {
// 检查终止符
if (data[0] == 0xFF) {
return false;
}
// 初始化结构体
memset(slot, 0, sizeof(TimeSlot));
slot->is_valid = true;
// 解析周一到周日有效性 (前7位)
for (int i = 0; i < 7; i++) {
if (data[i] != '0' && data[i] != '1') {
slot->is_valid = false;
return true;
}
slot->weekdays[i] = (data[i] == '1');
}
// 检查分隔符
if (data[7] != '+' || data[12] != '+') {
slot->is_valid = false;
return true;
}
// 解析开始时间 (第8-11位,格式1828)
slot->start_hour = parse_two_digits(data + 8);
slot->start_minute = parse_two_digits(data + 10);
// 解析结束时间 (第13-16位,格式1930)
slot->end_hour = parse_two_digits(data + 13);
slot->end_minute = parse_two_digits(data + 15);
// 验证时间有效性
if (slot->start_hour < 0 || /*slot->start_hour >= 24 ||*/
slot->start_minute < 0 || slot->start_minute >= 60 ||
slot->end_hour < 0 || /*slot->end_hour >= 24 ||*/
slot->end_minute < 0 || slot->end_minute >= 60) {
printf("!!!!!!!!!!!!!1 time invalid\n");
slot->is_valid = false;
}
return true;
}
// 解析时间区间数据数组
void parse_time_slots(const unsigned char* data, int data_length, TimeSlotResult* result) {
result->count = 0;
// 检查输入数据长度是否合理
if (data_length < ENTRY_LENGTH || data_length > MAX_ENTRIES * ENTRY_LENGTH) {
printf("!!!!!!!!!!invalid date1\n");
return;
}
// 解析每组数据
for (int i = 0; i < MAX_ENTRIES; i++) {
int offset = i * ENTRY_LENGTH;
// 检查是否超出数据范围
if (offset + ENTRY_LENGTH > data_length) {
printf("!!!!!!!!!!invalid date2\n");
return;
}
// 检查终止符
if (data[offset] == 0xFF) {
//printf("!!!!!!!!!!date end\n");
return;
}
// 解析单个条目
if (!parse_single_entry((const char*)(data + offset), &result->slots[result->count])) {
return;
}
// 只有有效数据才计数
if (result->slots[result->count].is_valid) {
result->count++;
}
}
}
// 打印时间区间信息
void print_time_slot(const TimeSlot* slot) {
const char* weekday_names[] = {" WEEK1", "WEEK2", "WEEK3", "WEEK4", "WEEK5", "WEEK6", "WEEK7"};
printf("WEEK: ");
int valid_days = 0;
for (int i = 0; i < 7; i++) {
if (slot->weekdays[i]) {
printf("%s ", weekday_names[i]);
valid_days++;
}
}
if (valid_days == 0) {
printf("unknown");
}
printf("\ntime: %02d:%02d - %02d:%02d\n",
slot->start_hour, slot->start_minute,
slot->end_hour, slot->end_minute);
}
int plan_test_main() {
// 示例数据 (170字节数组,实际只填充部分数据)
unsigned char test_data[170] = {
'0','0','0','0','0','0','1','+','1','8','2','8','+','1','9','3','0', // 条目1
'1','0','0','0','0','0','0','+','0','8','0','0','+','1','2','0','0', // 条目2
'0','1','0','0','0','0','0','+','1','3','0','0','+','1','7','3','0', // 条目3
'0','0','0','0','0','0','0','+','1','8','2','8','+','1','9','3','0',
'1','1','1','1','1','1','1','+','1','2','2','4','+','2','3','3','0',
0xFF, // 终止符
// 剩余数据...
};
TimeSlotResult result = {0};
parse_time_slots(test_data, sizeof(test_data), &result);
printf("total num %d :\n", result.count);
for (int i = 0; i < result.count; i++) {
printf("\nnum %d:\n", i+1);
print_time_slot(&result.slots[i]);
}
return 0;
}
// 计算某年某月某日是星期几(返回1-7对应周一到周日)
uint8_t calculateWeekday(uint16_t year, uint8_t month, uint8_t day)
{
// 如果月份是1月或2月,当作前一年的13月或14月
if (month < 3) {
month += 12;
year -= 1;
}
uint16_t century = year / 100;
uint16_t yearInCentury = year % 100;
// Zeller公式
// h = (q + [(13(m+1))/5] + K + K/4 + J/4 + 5J) mod 7
// h是星期几(0=周六,1=周日,2=周一,...,6=周五)
uint16_t h = (day + (13 * (month + 1)) / 5 + yearInCentury + yearInCentury / 4 + century / 4 + 5 * century) % 7;
// 转换为1=周一,2=周二,...,7=周日
uint8_t weekday = (h + 5) % 7 + 1;
return weekday;
}
void usr_get_sys_time()//获取时间
{
u8 usr_week_data=0;
/*if (!__this->dev_handle) {
return ;
}*/
//if(usr_time_set_flag==0)return;
//dev_ioctl(__this->dev_handle, IOCTL_GET_SYS_TIME, (u32)&usr_current_time);
read_sys_time(&usr_current_time);
usr_week_data=calculateWeekday(usr_current_time.year,usr_current_time.month,usr_current_time.day);
/*printf("time: %d-%d-%d %d:%d:%d",
usr_current_time.year,
usr_current_time.month,
usr_current_time.day,
usr_current_time.hour,
usr_current_time.min,
usr_current_time.sec);*/
//printf("Day of week: %s\n", weekdayNames[usr_week_data]);
if((usr_current_time.year<2025)||(usr_current_time.year>2098))return;
usr_var.usr_cureent_utc=convertToUtcTimestamp(usr_current_time.year,usr_current_time.month,usr_current_time.day,usr_current_time.hour,usr_current_time.min,usr_current_time.sec);
if(usr_var.usr_cureent_utc)
{
if(usr_var.usr_cureent_utc>usr_var.usr_timezoneOffset)usr_var.usr_cureent_utc=usr_var.usr_cureent_utc-usr_var.usr_timezoneOffset;
}
/*
0000001+1828+05+1
1000001+0928+03+1
1100000+1328+02+0
0000000+1032+01+1
*/
//if(usr_time_set_flag)
{
usr_plan_dec(usr_we_plan_table,usr_current_time.hour,usr_current_time.min,usr_week_data);
}
}
void usr_set_sys_time()//设置时间
{
/*usr_set_time.year=data_time->year;
usr_set_time.month=data_time->month;
usr_set_time.day=data_time->day;
usr_set_time.hour=data_time->hour;
usr_set_time.min=data_time->minute;
usr_set_time.sec=data_time->second;*/
//dev_ioctl(__this->dev_handle, IOCTL_SET_SYS_TIME, (u32)&usr_set_time);
write_sys_time(&usr_set_time);
//dev_ioctl(__this->dev_handle, IOCTL_GET_SYS_TIME, (u32)&usr_current_time);
read_sys_time(&usr_current_time);
usr_current_time.year=usr_set_time.year;
usr_current_time.month=usr_set_time.month;
usr_current_time.day=usr_set_time.day;
usr_current_time.hour=usr_set_time.hour;
usr_current_time.min=usr_set_time.min;
usr_current_time.sec=usr_set_time.sec;
usr_var.usr_cureent_utc=convertToUtcTimestamp(usr_current_time.year,usr_current_time.month,usr_current_time.day,usr_current_time.hour,usr_current_time.min,usr_current_time.sec);
if(usr_var.usr_cureent_utc)
{
if(usr_var.usr_cureent_utc>usr_var.usr_timezoneOffset)usr_var.usr_cureent_utc=usr_var.usr_cureent_utc-usr_var.usr_timezoneOffset;
}
printf("##### usr_var.usr_cureent_utc = %d\n",usr_var.usr_cureent_utc);
}
void usr_rtc_get_time()
{
usr_get_sys_time();
}
///"1000001+0928+3+1"
void usr_read_plan()
{
int ret=0;
u8 default_str[]={'1','1','1','1','1','1','1','+','2','2','0','0','+','0','6','0','0',};
//i=CFG_USER_PLAN_INFO1;
printf("usr_read_plan start\n");
ret = syscfg_read(CFG_USER_PLAN_INFO1,usr_we_plan_table,170);
printf("ret = %d\n",ret);
if(ret<=0)
{
memset(usr_we_plan_table,0xff,170);
memcpy(usr_we_plan_table,default_str,17);
syscfg_write(CFG_USER_PLAN_INFO1,usr_we_plan_table,170);
}
for(u8 i=0;i<5;i++)
{
printf_buf(&usr_we_plan_table[i*17],17);
}
printf("usr_read_plan end\n");
}
void usr_clear_plan()
{
u8 default_str[]={'1','1','1','1','1','1','1','+','2','2','0','0','+','0','6','0','0',};
memset(usr_we_plan_table,0xff,170);
memcpy(usr_we_plan_table,default_str,17);
syscfg_write(CFG_USER_PLAN_INFO1,usr_we_plan_table,170);
}
void usr_write_plan(u8 write_num,u8*data)
{
memcpy(&usr_we_plan_table[write_num*17],data,17);
//printf("w data:");
//printf_buf(data,17);
//memcpy(&usr_we_plan_table[write_num][0],data,17);
}
void usr_write_plan_to_vm()
{
syscfg_write(CFG_USER_PLAN_INFO1,usr_we_plan_table,170);
}
void usr_plan_init()
{
// usr_clear_min_cache();
// rtc_task_start();
usr_read_plan();
usr_var.usr_timezoneOffset=0;
}
/*
typedef struct {
bool weekdays[7]; // 周一到周日,true表示有效
int start_hour; // 开始时间(小时)
int start_minute; // 开始时间(分钟)
int end_hour; // 结束时间(小时)
int end_minute; // 结束时间(分钟)
bool is_valid; // 数据是否有效
} TimeSlot;
typedef struct {
TimeSlot slots[MAX_ENTRIES];
int count;
} TimeSlotResult;
*/
// 更通用的版本,可以指定任意开始和结束时间
int isWithinCustomTimeRange(u16 cur_hour,u16 cur_min,u16 start_hour,u16 start_min,u16 end_hour,u16 end_min) {
// 将当前时间转换为总分钟数
int current_minutes = cur_hour * 60 + cur_min;
// 将开始时间和结束时间转换为总分钟数
int start_minutes = start_hour * 60 + start_min;
int end_minutes = end_hour * 60 + end_min;
// 判断时间段是否跨天
int crosses_midnight = (start_minutes > end_minutes);
if (crosses_midnight) {
// 跨天的情况
if (current_minutes >= start_minutes || current_minutes < end_minutes) {
return 1;
} else {
return 0;
}
} else {
// 不跨天的情况
if (current_minutes >= start_minutes && current_minutes < end_minutes) {
return 1;
} else {
return 0;
}
}
}
void usr_plan_dec(u8* data,u8 cur_hour,u8 cur_min,u8 cur_week)
{
TimeSlotResult result = {0};
parse_time_slots(data, 170, &result);
if(result.count>1)result.count=1;
usr_var.usr_plan_cnt=result.count;
u8 i=0;
if(_usr_module_cfg.wuraomoshi_onoff==0)
{
usr_var.usr_disable_zjhendong=0;
return;
}
if((result.slots[i].start_hour==0)&&(result.slots[i].end_hour==0))
{
usr_var.usr_disable_zjhendong=1;
return ;
}
if((result.slots[i].start_hour==0)&&(result.slots[i].end_hour==24))
{
usr_var.usr_disable_zjhendong=1;
return ;
}
if((result.slots[i].start_hour==24)&&(result.slots[i].end_hour==0))
{
usr_var.usr_disable_zjhendong=1;
return ;
}
if((result.slots[i].start_hour==24)&&(result.slots[i].end_hour==24))
{
usr_var.usr_disable_zjhendong=1;
return ;
}
//printf("total num %d :\n", result.count);
for (u8 i = 0; i < result.count; i++)
{
//printf("time: %02d:%02d - %02d:%02d\n",\
// result.slots[i].start_hour, result.slots[i].start_minute,\
// result.slots[i].end_hour, result.slots[i].end_minute);
//printf("cur_week = [%d]",cur_week);
if(usr_we_plan_table[cur_week-1]==0x30)
{
usr_var.usr_disable_zjhendong=0;
return;
}
for(u8 j=0;j<7;j++)
{
if(usr_we_plan_table[j]==0x31)
{
if((j+1)==cur_week)
{
if(isWithinCustomTimeRange(cur_hour,cur_min,result.slots[i].start_hour,result.slots[i].start_minute,\
result.slots[i].end_hour,result.slots[i].end_minute))
{
//putchar('1');
usr_var.usr_disable_zjhendong=1;
}
else
{
//putchar('0');
usr_var.usr_disable_zjhendong=0;
}
}
}
}
}
//plan_test_main();
}
#if 0
u8 usr_weishi_plan_cnt=0;
void usr_plan_dec(u8* data,u8 cur_hour,u8 cur_min,u8 cur_week)
{
// 示例数据(usr_we_plan_table,包含2组有效数据+0xFF填充)
/* uint8_t usr_we_plan_table[160] = {
// 第1组: "0000001+1828+5+1"(周一执行,18:28,重复5次,启用)
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x2B,0x31, 0x38, 0x32, 0x38, 0x2B, 0x35, 0x2B, 0x31,
// 第2组: "1000001+0928+3+1"(周日和周一执行,09:28,重复3次,启用)
0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x2B,0x30, 0x39, 0x32, 0x38, 0x2B, 0x33, 0x2B, 0x31,
// 剩余部分填充0xFF(无效数据)
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
// ...(后续全部0xFF
};*/
/*
task1: week=0x01, time=18:28, action_cnt=5, onoff=1
task2: week=0x41, time=09:28, action_cnt=3, onoff=1
task3: week=0x60, time=13:28, action_cnt=2, onoff=0
task4: week=0x00, time=10:32, action_cnt=1, onoff=1
*/
u8 usr_cur_week=0;
usr_cur_week=cur_week;
TaskConfig tasks[MAX_TASKS]; // 存储解析结果
uint8_t task_count = parse_multiple_tasks(data, tasks, MAX_TASKS);
usr_weishi_plan_cnt=task_count;
//printf("ana %d task min_cache = %d\n", task_count,min_cache);
for (uint8_t i = 0; i < task_count; i++)
{
usr_weishi_index=i;
/*printf("task%d: week=0x%02X, time=%02d:%02d, action_cnt=%d, onoff=%d\n",i + 1,
tasks[i].execute_days,
tasks[i].hour,
tasks[i].minute,
tasks[i].repeat_count,
tasks[i].is_enabled);*/
if(min_cache<0xff)
{
if(cur_min>min_cache)
{
min_cache=0xff;
}
}
if(tasks[i].execute_days==0x00)
{
if(tasks[i].is_enabled)
{
if((cur_hour==tasks[i].hour)&&(cur_min==tasks[i].minute))
{
if(min_cache!=cur_min)
{
printf("plan to feed!\n");
usr_set_werishi(tasks[i].repeat_count,1);
min_cache=cur_min;
// 修改第任务的 is_enabled 为 0(关闭)
bool success = update_task_enabled(data, &tasks[i], false);
if (success) {
printf("close task!\n");
printf("new enabled is: %d\n", tasks[i].is_enabled);
}
}
}
else
{
//min_cache=0xff;
}
}
}
switch(cur_week)
{
case 0x01:
if(tasks[i].execute_days&BIT(6))///周一有计划
{
if(tasks[i].is_enabled)
{
if((cur_hour==tasks[i].hour)&&(cur_min==tasks[i].minute))
{
if(min_cache!=cur_min)
{
printf("plan to feed!\n");
usr_set_werishi(tasks[i].repeat_count,1);
min_cache=cur_min;
}
}
else
{
//min_cache=0xff;
}
}
}
break;
case 0x02:
if(tasks[i].execute_days&BIT(5))///周二有计划
{
if(tasks[i].is_enabled)
{
if((cur_hour==tasks[i].hour)&&(cur_min==tasks[i].minute))
{
if(min_cache!=cur_min)
{
printf("plan to feed!\n");
usr_set_werishi(tasks[i].repeat_count,1);
min_cache=cur_min;
}
}
else
{
// min_cache=0xff;
}
}
}
break;
case 0x03:
if(tasks[i].execute_days&BIT(4))///周三有计划
{
if(tasks[i].is_enabled)
{
if((cur_hour==tasks[i].hour)&&(cur_min==tasks[i].minute))
{
if(min_cache!=cur_min)
{
printf("plan to feed!\n");
usr_set_werishi(tasks[i].repeat_count,1);
min_cache=cur_min;
}
}
else
{
///min_cache=0xff;
}
}
}
break;
case 0x04:
if(tasks[i].execute_days&BIT(3))///周四有计划
{
if(tasks[i].is_enabled)
{
//printf("cur_hour = %d tasks[%d].hour = %d\n",cur_hour,i,tasks[i].hour);
//printf("cur_min = %d tasks[%d].minute = %d\n",cur_min,i,tasks[i].minute);
if((cur_hour==tasks[i].hour)&&(cur_min==tasks[i].minute))
{
if(min_cache!=cur_min)
{
printf("plan to feed!\n");
usr_set_werishi(tasks[i].repeat_count,1);
min_cache=cur_min;
//printf("min_cache2 = %d\n",min_cache);
}
}
else
{
//min_cache=0xff;
//printf("min_cache3 = %d\n",min_cache);
}
}
}
break;
case 0x05:
if(tasks[i].execute_days&BIT(2))///周五有计划
{
if(tasks[i].is_enabled)
{
if((cur_hour==tasks[i].hour)&&(cur_min==tasks[i].minute))
{
if(min_cache!=cur_min)
{
printf("plan to feed!\n");
usr_set_werishi(tasks[i].repeat_count,1);
min_cache=cur_min;
}
}
else
{
//min_cache=0xff;
}
}
}
break;
case 0x06:
if(tasks[i].execute_days&BIT(1))///周六有计划
{
if(tasks[i].is_enabled)
{
if((cur_hour==tasks[i].hour)&&(cur_min==tasks[i].minute))
{
if(min_cache!=cur_min)
{
printf("plan to feed!\n");
usr_set_werishi(tasks[i].repeat_count,1);
min_cache=cur_min;
}
}
else
{
//min_cache=0xff;
}
}
}
break;
case 0x07:
if(tasks[i].execute_days&BIT(0))///周日有计划
{
if(tasks[i].is_enabled)
{
if((cur_hour==tasks[i].hour)&&(cur_min==tasks[i].minute))
{
if(min_cache!=cur_min)
{
printf("plan to feed!\n");
usr_set_werishi(tasks[i].repeat_count,1);
min_cache=cur_min;
}
}
else
{
//min_cache=0xff;
}
}
}
break;
}
}
}
#endif // 0