/****************************************************************************** * Copyright 2013-2014 Espressif Systems (Wuxi) * * FileName: esp_platform_user_timer.c * * Description: * * Modification history: * 2014/5/09, v1.0 create this file. *******************************************************************************/ #include "ets_sys.h" #include "os_type.h" #include "mem.h" #include "osapi.h" #include "user_interface.h" #include "espconn.h" #include "user_esp_platform.h" #define ESP_DEBUG #ifdef ESP_DEBUG #define ESP_DBG os_printf #else #define ESP_DBG #endif LOCAL os_timer_t device_timer; uint32 min_wait_second; char timestamp_str[11]; int timestamp = 0; char *timer_splits[20] = {NULL}; struct esp_platform_wait_timer_param { uint8 wait_time_param[11]; uint8 wait_action[15]; int wait_time_second; }; struct wait_param { uint8 action[20][15]; uint16 action_number; uint16 count; uint32 min_time_backup; }; void esp_platform_timer_action(struct esp_platform_wait_timer_param *timer_wait_param, uint16 count); /****************************************************************************** * FunctionName : split * Description : split string p1 according to sting p2 and save the splits * Parameters : p1 , p2 ,splits[] * Returns : the number of splits *******************************************************************************/ uint16 ICACHE_FLASH_ATTR split(char *p1, char *p2, char *splits[]) { int i = 0; int j = 0; while (i != -1) { int start = i; int end = indexof(p1, p2, start); if (end == -1) { end = os_strlen(p1); } char *p = (char *) os_zalloc(100); os_memcpy(p, p1 + start, end - start); p[end - start] = '\0'; splits[j] = p; j++; i = end + 1; if (i > os_strlen(p1)) { break; } } return j; } /****************************************************************************** * FunctionName : indexof * Description : calculate the offset of p2 relate to start of p1 * Parameters : p1,p1,start * Returns : the offset of p2 relate to the start *******************************************************************************/ int ICACHE_FLASH_ATTR indexof(char *p1, char *p2, int start) { char *find = (char *)os_strstr(p1 + start, p2); if (find != NULL) { return (find - p1); } return -1; } /****************************************************************************** * FunctionName : esp_platform_find_min_time * Description : find the minimum wait second in timer list * Parameters : timer_wait_param -- param of timer action and wait time param * count -- The number of timers given by server * Returns : none *******************************************************************************/ void ICACHE_FLASH_ATTR esp_platform_find_min_time(struct esp_platform_wait_timer_param *timer_wait_param , uint16 count) { uint16 i = 0; min_wait_second = 0xFFFFFFF; for (i = 0; i < count ; i++) { if (timer_wait_param[i].wait_time_second < min_wait_second && timer_wait_param[i].wait_time_second >= 0) { min_wait_second = timer_wait_param[i].wait_time_second; } } } /****************************************************************************** * FunctionName : user_platform_timer_first_start * Description : calculate the wait time of each timer * Parameters : count -- The number of timers given by server * Returns : none *******************************************************************************/ void ICACHE_FLASH_ATTR user_platform_timer_first_start(uint16 count) { int i = 0; struct esp_platform_wait_timer_param timer_wait_param[100] = {0}; ESP_DBG("current timestamp= %ds\n", timestamp); timestamp = timestamp + min_wait_second; for (i = 0 ; i < count ; i++) { char *str = timer_splits[i]; if (indexof(str, "f", 0) == 0) { char *fixed_wait[2]; ESP_DBG("timer is fixed mode\n"); split(str, "=", fixed_wait); os_memcpy(timer_wait_param[i].wait_time_param, fixed_wait[0] + 1, os_strlen(fixed_wait[0]) - 1); os_memcpy(timer_wait_param[i].wait_action, fixed_wait[1], os_strlen(fixed_wait[1])); timer_wait_param[i].wait_time_second = atoi(timer_wait_param[i].wait_time_param) - timestamp; os_free(fixed_wait[0]); os_free(fixed_wait[1]); } else if (indexof(str, "l", 0) == 0) { char *loop_wait[2]; ESP_DBG("timer is loop mode\n"); split(str, "=", loop_wait); os_memcpy(timer_wait_param[i].wait_time_param, loop_wait[0] + 1, os_strlen(loop_wait[0]) - 1); os_memcpy(timer_wait_param[i].wait_action, loop_wait[1], os_strlen(loop_wait[1])); timer_wait_param[i].wait_time_second = atoi(timer_wait_param[i].wait_time_param) - (timestamp % atoi(timer_wait_param[i].wait_time_param)); os_free(loop_wait[0]); os_free(loop_wait[1]); } else if (indexof(str, "w", 0) == 0) { char *week_wait[2]; int monday_wait_time = 0; ESP_DBG("timer is weekend mode\n"); split(str, "=", week_wait); os_memcpy(timer_wait_param[i].wait_time_param, week_wait[0] + 1, os_strlen(week_wait[0]) - 1); os_memcpy(timer_wait_param[i].wait_action, week_wait[1], os_strlen(week_wait[1])); monday_wait_time = (timestamp - 1388937600) % (7 * 24 * 3600); ESP_DBG("monday_wait_time == %d", monday_wait_time); if (atoi(timer_wait_param[i].wait_time_param) > monday_wait_time) { timer_wait_param[i].wait_time_second = atoi(timer_wait_param[i].wait_time_param) - monday_wait_time; } else { timer_wait_param[i].wait_time_second = 7 * 24 * 3600 - monday_wait_time + atoi(timer_wait_param[i].wait_time_param); } os_free(week_wait[0]); os_free(week_wait[1]); } } esp_platform_find_min_time(timer_wait_param, count); if(min_wait_second == 0) { return; } esp_platform_timer_action(timer_wait_param, count); } /****************************************************************************** * FunctionName : user_esp_platform_device_action * Description : Execute the actions of minimum wait time * Parameters : pwait_action -- point the list of actions which need execute * * Returns : none *******************************************************************************/ void ICACHE_FLASH_ATTR user_esp_platform_device_action(struct wait_param *pwait_action) { uint8 i = 0; uint16 count = pwait_action->count; uint16 action_number = pwait_action->action_number; ESP_DBG("there is %d action at the same time\n", pwait_action->action_number); #if PLUG_DEVICE for (i = 0; i < action_number && pwait_action->action[i][0] != '0'; i++) { ESP_DBG("%s\n",pwait_action->action[i]); if (os_strcmp(pwait_action->action[i], "on_switch", 9) == 0) { user_plug_set_status(0x01); } else if (os_strcmp(pwait_action->action[i], "off_switch", 10) == 0) { user_plug_set_status(0x00); } else if (os_strcmp(pwait_action->action[i], "on_off_switch", 13) == 0) { if (user_plug_get_status() == 0) { user_plug_set_status(0x01); } else { user_plug_set_status(0x00); } } else { return; } } user_platform_timer_first_start(count); #endif } /****************************************************************************** * FunctionName : user_platform_timer_start * Description : Processing the message about timer from the server * Parameters : timer_wait_param -- The received data from the server * count -- the espconn used to connetion with the host * Returns : none *******************************************************************************/ void ICACHE_FLASH_ATTR user_esp_platform_wait_time_overflow_check(struct wait_param *pwait_action) { ESP_DBG("min_wait_second = %d", min_wait_second); if (pwait_action->min_time_backup >= 3600) { os_timer_disarm(&device_timer); os_timer_setfn(&device_timer, (os_timer_func_t *)user_esp_platform_wait_time_overflow_check, pwait_action); os_timer_arm(&device_timer, 3600000, 0); ESP_DBG("min_wait_second is extended\n"); } else { os_timer_disarm(&device_timer); os_timer_setfn(&device_timer, (os_timer_func_t *)user_esp_platform_device_action, pwait_action); os_timer_arm(&device_timer, pwait_action->min_time_backup * 1000, 0); ESP_DBG("min_wait_second is = %dms\n", pwait_action->min_time_backup * 1000); } pwait_action->min_time_backup -= 3600; } /****************************************************************************** * FunctionName : user_platform_timer_start * Description : Processing the message about timer from the server * Parameters : timer_wait_param -- The received data from the server * count -- the espconn used to connetion with the host * Returns : none *******************************************************************************/ void ICACHE_FLASH_ATTR esp_platform_timer_action(struct esp_platform_wait_timer_param *timer_wait_param, uint16 count) { uint16 i = 0; uint16 action_number; struct wait_param pwait_action = {0}; pwait_action.count = count; action_number = 0; for (i = 0; i < count ; i++) { if (timer_wait_param[i].wait_time_second == min_wait_second) { os_memcpy(pwait_action.action[action_number], timer_wait_param[i].wait_action, os_strlen(timer_wait_param[i].wait_action)); ESP_DBG("*****%s*****\n", timer_wait_param[i].wait_action); action_number++; } } pwait_action.action_number = action_number; pwait_action.min_time_backup = min_wait_second; user_esp_platform_wait_time_overflow_check(&pwait_action); } /****************************************************************************** * FunctionName : user_platform_timer_start * Description : Processing the message about timer from the server * Parameters : pbuffer -- The received data from the server * Returns : none *******************************************************************************/ void ICACHE_FLASH_ATTR user_platform_timer_start(char *pbuffer) { int str_begin = 0; int str_end = 0; uint8 i = 0; char *pstr_start = NULL; char *pstr_end = NULL; struct esp_platform_wait_timer_param timer_wait_param[20]; char *pstr = NULL; min_wait_second = 0; if ((pstr = (char *)os_strstr(pbuffer, "\"timestamp\":")) != NULL) { pstr_start = pstr + 13; pstr_end = (char *)os_strstr(pstr_start, ","); if (pstr != NULL) { os_memcpy(timestamp_str, pstr_start, pstr_end - pstr_start); timestamp = atoi(timestamp_str); } } for (i = 0 ; i < 20 ; i++) { if (timer_splits[i] != NULL) { os_free(timer_splits[i]); timer_splits[i] = NULL; } } if ((pstr_start = (char *)os_strstr(pbuffer, "\"timers\": \"")) != NULL) { str_begin = 11; str_end = indexof(pstr_start, "\"", str_begin); if (str_begin == str_end) { os_timer_disarm(&device_timer); return; } char *split_buffer = (char *)os_zalloc(str_end - str_begin + 1); os_memcpy(split_buffer, pstr_start + str_begin, str_end - str_begin); uint16 count = split(split_buffer , ";" , timer_splits); os_free(split_buffer); user_platform_timer_first_start(count); } }