#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 #include #include #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