在逗猫棒的基础上实现蓝牙转USB功能,目前功能已经实现,还需裁剪掉之前逗猫棒的业务程序
This commit is contained in:
@@ -0,0 +1,711 @@
|
||||
#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
|
||||
@@ -0,0 +1,186 @@
|
||||
#include "system/includes.h"
|
||||
#include "app_config.h"
|
||||
#include "asm/pwm_led.h"
|
||||
#include "tone_player.h"
|
||||
#include "ui_manage.h"
|
||||
#include "app_main.h"
|
||||
#include "app_task.h"
|
||||
#include "asm/charge.h"
|
||||
#include "app_power_manage.h"
|
||||
#include "app_charge.h"
|
||||
#include "user_cfg.h"
|
||||
#include "audio.h"
|
||||
#include "vm.h"
|
||||
#include "sys_time.h"
|
||||
|
||||
// 定义时间结构体
|
||||
typedef struct {
|
||||
uint16_t year; // 年份 (1970-2106)
|
||||
uint8_t month; // 月份 (1-12)
|
||||
uint8_t day; // 日 (1-31)
|
||||
uint8_t hour; // 时 (0-23)
|
||||
uint8_t minute; // 分 (0-59)
|
||||
uint8_t second; // 秒 (0-59)
|
||||
} DateTime;
|
||||
|
||||
DateTime usr_dt;
|
||||
|
||||
void parseMillisecondTimestamp(int64_t timestampMs, int64_t timezoneOffset, DateTime *dt);
|
||||
void usr_set_data_time(int64_t timestampMs, int64_t timezoneOffset)
|
||||
{
|
||||
parseMillisecondTimestamp(timestampMs,timezoneOffset,&usr_dt);
|
||||
}
|
||||
|
||||
extern struct sys_time usr_set_time;
|
||||
|
||||
extern void usr_set_sys_time();//设置时间
|
||||
|
||||
// 判断是否为闰年
|
||||
static uint8_t isLeapYear(uint16_t year) {
|
||||
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// 计算从1970年到指定年份之前的总天数
|
||||
static uint32_t getDaysSinceEpoch(uint16_t year) {
|
||||
uint32_t days = 0;
|
||||
for (uint16_t y = 1970; y < year; y++) {
|
||||
days += isLeapYear(y) ? 366 : 365;
|
||||
}
|
||||
return days;
|
||||
}
|
||||
// 获取指定年份和月份的天数
|
||||
static uint8_t getDaysInMonth(uint16_t year, uint8_t month) {
|
||||
const uint8_t daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
if (month == 2 && isLeapYear(year)) {
|
||||
return 29;
|
||||
}
|
||||
if (month >= 1 && month <= 12) {
|
||||
return daysInMonth[month - 1];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 解析毫秒级UTC时间戳并应用时区偏移
|
||||
void parseMillisecondTimestamp(int64_t timestampMs, int64_t timezoneOffset, DateTime *dt)
|
||||
{
|
||||
// 转换为秒(丢弃毫秒部分)
|
||||
int64_t timestamp = timestampMs ;/// 1000;
|
||||
|
||||
// 应用时区偏移(转换为秒)
|
||||
timestamp += timezoneOffset;// * 3600;
|
||||
usr_var.usr_timezoneOffset = timezoneOffset;
|
||||
// 处理可能的负值
|
||||
if (timestamp < 0) {
|
||||
timestamp = 0;
|
||||
}
|
||||
|
||||
uint64_t days, seconds, minutes, hours;
|
||||
uint16_t year = 1970;
|
||||
uint8_t month = 1;
|
||||
|
||||
// 计算秒、分、时
|
||||
seconds = timestamp % 60;
|
||||
timestamp /= 60;
|
||||
minutes = timestamp % 60;
|
||||
timestamp /= 60;
|
||||
hours = timestamp % 24;
|
||||
timestamp /= 24;
|
||||
|
||||
// 计算年月日
|
||||
while (1) {
|
||||
uint16_t daysInYear = isLeapYear(year) ? 366 : 365;
|
||||
if (timestamp >= daysInYear) {
|
||||
timestamp -= daysInYear;
|
||||
year++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
uint8_t daysInMonth = getDaysInMonth(year, month);
|
||||
if (timestamp >= daysInMonth) {
|
||||
timestamp -= daysInMonth;
|
||||
month++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 填充结构体
|
||||
dt->year = year;
|
||||
dt->month = month;
|
||||
dt->day = (uint8_t)(timestamp + 1);
|
||||
dt->hour = (uint8_t)hours;
|
||||
dt->minute = (uint8_t)minutes;
|
||||
dt->second = (uint8_t)seconds;
|
||||
|
||||
|
||||
usr_set_time.year=dt->year;
|
||||
usr_set_time.month=dt->month;
|
||||
usr_set_time.day=dt->day;
|
||||
usr_set_time.hour=dt->hour;
|
||||
usr_set_time.min=dt->minute;
|
||||
usr_set_time.sec=dt->second;
|
||||
|
||||
|
||||
usr_set_sys_time();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
> 喂食计划设置请求
|
||||
* 命令ID: 205
|
||||
* 参数说明
|
||||
|
||||
| 索引 | 类型 | 描述 | 取值 |
|
||||
| ---- | ------ | ------------------------------------------------------------ | ---------------------------- |
|
||||
| 0 | int32 | 喂食计划个数(最多10个计划) | 0-10 |
|
||||
| 0-N | string | 周计划 + 时间点 + 份数 +开关<br />周计划:ddddddd, 从左到右表示7个,分别表示周一到周日,1表示有效,0表示无效
|
||||
<br />时间点:hhmm, hh表示小时,mm表示分钟<br />份数 :n 表示份数<br />开关:x 1 表示开,0表示关<br />
|
||||
例如<br />0000001+1828+5+1 表示每周日重复 +18:28+5份粮+开<br />
|
||||
1000001+0928+3+1 表示每周一和周日重复+09:28+3份粮+开<br />
|
||||
1100000+1328+2+0 表示每周一和周二重复+13:28+2份粮+关<br />
|
||||
0000000+1032+1+1 表示单次 +10:32+1份粮+开 | 字符串<br />ddddddd+hhmm+n+x |
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 示例用法
|
||||
|
||||
int utc_test_main() {
|
||||
/* DateTime dt;
|
||||
uint64_t utcTimestamp = 1747568305845; // 2024-05-18 00:00:00 UTC
|
||||
int32_t timezoneOffset = 8*60*60; // 东八区(北京时间)
|
||||
|
||||
parseMillisecondTimestamp(utcTimestamp, timezoneOffset, &dt);
|
||||
printf("utc_read_sys_time: %d-%d-%d %d:%d:%d\n",
|
||||
dt.year,
|
||||
dt.month,
|
||||
dt.day,
|
||||
dt.hour,
|
||||
dt.minute,
|
||||
dt.second);
|
||||
// 现在dt结构体中包含解析后的本地时间信息
|
||||
// dt.year = 2024
|
||||
// dt.month = 5
|
||||
// dt.day = 18
|
||||
// dt.hour = 8 (UTC+8)
|
||||
// dt.minute = 0
|
||||
// dt.second = 0
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
#include "system/includes.h"
|
||||
#include "app_config.h"
|
||||
#include "asm/pwm_led.h"
|
||||
#include "tone_player.h"
|
||||
#include "ui_manage.h"
|
||||
#include "app_main.h"
|
||||
#include "app_task.h"
|
||||
#include "asm/charge.h"
|
||||
#include "app_power_manage.h"
|
||||
#include "app_charge.h"
|
||||
#include "user_cfg.h"
|
||||
#include "audio.h"
|
||||
#include "vm.h"
|
||||
#include "sys_time.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// 判断是否为闰年
|
||||
static uint8_t isLeapYear(uint16_t year) {
|
||||
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 计算从1970年到指定年份之前的总天数
|
||||
static uint32_t getDaysSinceEpoch(uint16_t year) {
|
||||
uint32_t days = 0;
|
||||
for (uint16_t y = 1970; y < year; y++) {
|
||||
days += isLeapYear(y) ? 366 : 365;
|
||||
}
|
||||
return days;
|
||||
}
|
||||
|
||||
// 计算指定年份中到指定月份之前的总天数
|
||||
static uint32_t getDaysInYear(uint16_t year, uint8_t month) {
|
||||
const uint8_t daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
uint32_t days = 0;
|
||||
|
||||
for (uint8_t m = 1; m < month; m++) {
|
||||
days += daysInMonth[m - 1];
|
||||
// 处理闰年二月
|
||||
if (m == 2 && isLeapYear(year)) {
|
||||
days += 1;
|
||||
}
|
||||
}
|
||||
return days;
|
||||
}
|
||||
|
||||
// 将日期时间转换为UTC时间戳(秒级)
|
||||
// 参数范围检查:1970 <= year <= 2106, 1 <= month <= 12, 1 <= day <= 31
|
||||
// 0 <= hour <= 23, 0 <= minute <= 59, 0 <= second <= 59
|
||||
uint32_t convertToUtcTimestamp(uint16_t year, uint8_t month, uint8_t day,
|
||||
uint8_t hour, uint8_t minute, uint8_t second) {
|
||||
// 1. 计算从1970年到目标年份之前的总天数
|
||||
uint32_t totalDays = getDaysSinceEpoch(year);
|
||||
|
||||
// 2. 加上目标年份中到目标月份之前的天数
|
||||
totalDays += getDaysInYear(year, month);
|
||||
|
||||
// 3. 加上当月已过的天数(day-1,因为当天还没过完)
|
||||
totalDays += (day - 1);
|
||||
|
||||
// 4. 计算总秒数
|
||||
uint32_t totalSeconds = totalDays * 86400UL; // 每天86400秒
|
||||
totalSeconds += hour * 3600UL; // 小时转秒
|
||||
totalSeconds += minute * 60UL; // 分钟转秒
|
||||
totalSeconds += second; // 加上秒
|
||||
|
||||
return totalSeconds;
|
||||
}
|
||||
|
||||
// 示例用法
|
||||
|
||||
int utc_dec_test_main()
|
||||
{
|
||||
// 北京时间2025-05-19 00:38:25 (UTC时间2025-05-18 16:38:25)
|
||||
/*uint32_t timestamp = convertToUtcTimestamp(2025, 5, 18, 16, 38, 25);
|
||||
// 应返回1747568305 (对应的毫秒时间戳是1747568305000)
|
||||
|
||||
printf("UTC timestamp: %lu\n", timestamp);*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user