diff --git a/src/config.h b/src/config.h index 049153e..02da125 100644 --- a/src/config.h +++ b/src/config.h @@ -31,6 +31,6 @@ /* * firmeware version string */ - #define __FIRMWARE__ "2020072306" + #define __FIRMWARE__ "2020072308" #endif // _CONFIG_H diff --git a/src/gui/mainbar/setup_tile/update/update.cpp b/src/gui/mainbar/setup_tile/update/update.cpp index fc9c0e1..3f2dbb1 100644 --- a/src/gui/mainbar/setup_tile/update/update.cpp +++ b/src/gui/mainbar/setup_tile/update/update.cpp @@ -103,7 +103,7 @@ void update_tile_setup( lv_obj_t *tile, lv_style_t *style, lv_coord_t hres, lv_c xTaskCreate( update_Task, /* Function to implement the task */ "update Task", /* Name of the task */ - 10000, /* Stack size in words */ + 5000, /* Stack size in words */ NULL, /* Task input parameter */ 1, /* Priority of the task */ &_update_Task ); /* Task handle. */ diff --git a/src/gui/widget/weather/images/resolve_owm_icon.cpp b/src/gui/widget/weather/images/resolve_owm_icon.cpp index 465818c..6094250 100644 --- a/src/gui/widget/weather/images/resolve_owm_icon.cpp +++ b/src/gui/widget/weather/images/resolve_owm_icon.cpp @@ -53,15 +53,15 @@ struct owm_icon owm_icon[ 18 ] = { { "11d", &owm_11d_64px }, { "12d", &owm_13d_64px }, { "50d", &owm_50d_64px }, - { "01d", &owm_01n_64px }, - { "02d", &owm_02n_64px }, - { "03d", &owm_03n_64px }, - { "04d", &owm_04n_64px }, - { "09d", &owm_09n_64px }, - { "10d", &owm_10n_64px }, - { "11d", &owm_11n_64px }, - { "12d", &owm_13n_64px }, - { "50d", &owm_50n_64px } + { "01n", &owm_01n_64px }, + { "02n", &owm_02n_64px }, + { "03n", &owm_03n_64px }, + { "04n", &owm_04n_64px }, + { "09n", &owm_09n_64px }, + { "10n", &owm_10n_64px }, + { "11n", &owm_11n_64px }, + { "12n", &owm_13n_64px }, + { "50n", &owm_50n_64px } }; const void * resolve_owm_icon( char *iconname ) { diff --git a/src/gui/widget/weather/weather.cpp b/src/gui/widget/weather/weather.cpp index 586a96c..bbcdf12 100644 --- a/src/gui/widget/weather/weather.cpp +++ b/src/gui/widget/weather/weather.cpp @@ -37,7 +37,6 @@ void weather_widget_sync_Task( void * pvParameters ); weather_config_t weather_config; weather_forcast_t weather_today; -weather_forcast_t weather_forecast[ WEATHER_MAX_FORECAST ]; lv_tile_number weather_widget_tile_num = NO_TILE; lv_tile_number weather_widget_setup_tile_num = NO_TILE; @@ -90,7 +89,7 @@ void weather_widget_setup( void ) { xTaskCreate( weather_widget_sync_Task, /* Function to implement the task */ "weather sync Task", /* Name of the task */ - 10000, /* Stack size in words */ + 2000, /* Stack size in words */ NULL, /* Task input parameter */ 1, /* Priority of the task */ &_weather_widget_sync_Task ); /* Task handle. */ @@ -111,7 +110,7 @@ void weather_jump_to_setup( void ) { mainbar_jump_to_tilenumber( weather_widget_setup_tile_num, LV_ANIM_ON ); } -void weather_sync_request( void ) { +void weather_widget_sync_request( void ) { xEventGroupSetBits( weather_widget_event_handle, WEATHER_WIDGET_SYNC_REQUEST ); vTaskResume( _weather_widget_sync_Task ); } @@ -128,7 +127,6 @@ void weather_widget_sync_Task( void * pvParameters ) { if ( weather_config.autosync ) { weather_fetch_today( &weather_config, &weather_today ); if ( weather_today.valide ) { - Serial.printf("weather fetch ok\r\n"); lv_label_set_text( weather_widget_temperature_label, weather_today.temp ); lv_imgbtn_set_src( weather_widget_condition_img, LV_BTN_STATE_RELEASED, resolve_owm_icon( weather_today.icon ) ); lv_imgbtn_set_src( weather_widget_condition_img, LV_BTN_STATE_PRESSED, resolve_owm_icon( weather_today.icon ) ); diff --git a/src/gui/widget/weather/weather.h b/src/gui/widget/weather/weather.h index 567c14a..ce92789 100644 --- a/src/gui/widget/weather/weather.h +++ b/src/gui/widget/weather/weather.h @@ -28,8 +28,6 @@ #define WEATHER_WIDGET_SYNC_REQUEST _BV(0) - #define WEATHER_MAX_FORECAST 4 - typedef struct { char apikey[64] = ""; char lon[16] = ""; @@ -58,7 +56,7 @@ void weather_jump_to_setup( void ); - void weather_sync_request( void ); + void weather_widget_sync_request( void ); void weather_save_config( void ); diff --git a/src/gui/widget/weather/weather_fetch.cpp b/src/gui/widget/weather/weather_fetch.cpp index 29c07d4..61ea00e 100644 --- a/src/gui/widget/weather/weather_fetch.cpp +++ b/src/gui/widget/weather/weather_fetch.cpp @@ -27,22 +27,20 @@ #include "weather.h" #include "weather_fetch.h" +#include "weather_forecast.h" void weather_fetch_today( weather_config_t *weather_config, weather_forcast_t *weather_today ) { - WiFiClient client; - char *ptr = NULL; - char json[2000] = ""; - StaticJsonDocument<2000> doc; + WiFiClient today_client; weather_today->valide = false; - if ( !client.connect( OWM_HOST, OWM_PORT ) ) { + if ( !today_client.connect( OWM_HOST, OWM_PORT ) ) { Serial.println("Connection failed"); return; } - client.printf( "GET /data/2.5/weather?lat=%s&lon=%s&appid=%s HTTP/1.1\r\n" + today_client.printf( "GET /data/2.5/weather?lat=%s&lon=%s&appid=%s HTTP/1.1\r\n" "Host: %s\r\n" "Connection: close\r\n" "Pragma: no-cache\r\n" @@ -51,21 +49,23 @@ void weather_fetch_today( weather_config_t *weather_config, weather_forcast_t *w "Accept: text/html,application/json\r\n\r\n", weather_config->lat, weather_config->lon, weather_config->apikey, OWM_HOST ); uint64_t startMillis = millis(); - while ( client.available() == 0 ) { + while ( today_client.available() == 0 ) { if ( millis() - startMillis > 5000 ) { - client.stop(); + today_client.stop(); return; } } - ptr = json; + char *json = (char *)ps_malloc( 40000 ); + char *ptr = json; + bool data_begin = false; - while( client.available() ) { + while( today_client.available() ) { if ( data_begin ) { - *ptr = client.read(); + *ptr = today_client.read(); ptr++; } - else if ( client.read() == '{' ) { + else if ( today_client.read() == '{' ) { data_begin = true; *ptr = '{'; ptr++; @@ -76,20 +76,99 @@ void weather_fetch_today( weather_config_t *weather_config, weather_forcast_t *w return; } + today_client.stop(); + + DynamicJsonDocument doc(20000); DeserializationError error = deserializeJson( doc, json); if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.c_str()); + doc.clear(); + free( json ); return; } weather_today->valide = true; snprintf( weather_today->temp, sizeof( weather_today->temp ),"%0.1f°C", doc["main"]["temp"].as() - 273.15 ); snprintf( weather_today->humidity, sizeof( weather_today->humidity ),"%f%%", doc["main"]["humidity"].as() ); - snprintf( weather_today->pressure, sizeof( weather_today->pressure ),"%fpha", doc["main"]["ressure"].as() ); + snprintf( weather_today->pressure, sizeof( weather_today->pressure ),"%fpha", doc["main"]["pressure"].as() ); strcpy( weather_today->icon, doc["weather"][0]["icon"] ); strcpy( weather_today->name, doc["name"] ); - client.stop(); + doc.clear(); + free( json ); +} + +void weather_fetch_forecast( weather_config_t *weather_config, weather_forcast_t * weather_forecast ) { + + WiFiClient forecast_client; + + weather_forecast[ 0 ].valide = false; + + if ( !forecast_client.connect( OWM_HOST, OWM_PORT ) ) { + Serial.println("Connection failed"); + return; + } + + forecast_client.printf( "GET /data/2.5/forecast?cnt=%d&lat=%s&lon=%s&appid=%s HTTP/1.1\r\n" + "Host: %s\r\n" + "Connection: close\r\n" + "Pragma: no-cache\r\n" + "Cache-Control: no-cache\r\n" + "User-Agent: ESP32\r\n" + "Accept: text/html,application/json\r\n\r\n", WEATHER_MAX_FORECAST, weather_config->lat, weather_config->lon, weather_config->apikey, OWM_HOST ); + + uint64_t startMillis = millis(); + while ( forecast_client.available() == 0 ) { + if ( millis() - startMillis > 5000 ) { + forecast_client.stop(); + return; + } + } + + char *json = (char *)ps_malloc( 20000 ); + char *ptr = json; + + bool data_begin = false; + while( forecast_client.available() ) { + if ( data_begin ) { + ptr[ forecast_client.readBytes( ptr, 40000 ) ] = '\0'; + } + else if ( forecast_client.read() == '{' ) { + data_begin = true; + *ptr = '{'; + ptr++; + } + } + + forecast_client.stop(); + + if ( data_begin == false ) { + Serial.printf("No json data\r\n"); + free( json ); + return; + } + + DynamicJsonDocument doc(20000); + DeserializationError error = deserializeJson( doc, json ); + if (error) { + Serial.print(F("deserializeJson() failed: ")); + Serial.println(error.c_str()); + doc.clear(); + free( json ); + return; + } + + weather_forecast[0].valide = true; + for ( int i = 0 ; i < WEATHER_MAX_FORECAST ; i++ ) { + snprintf( weather_forecast[ i ].temp, sizeof( weather_forecast[ i ].temp ),"%0.1f", doc["list"][i]["main"]["temp"].as() - 273.15 ); + snprintf( weather_forecast[ i ].humidity, sizeof( weather_forecast[ i ].humidity ),"%f", doc["list"][i]["main"]["humidity"].as() ); + snprintf( weather_forecast[ i ].pressure, sizeof( weather_forecast[ i ].pressure ),"%f", doc["list"][i]["main"]["pressure"].as() ); + strcpy( weather_forecast[ i ].icon, doc["list"][i]["weather"][0]["icon"] ); + strcpy( weather_forecast[ i ].name, doc["city"]["name"] ); + } + + doc.clear(); + free( json ); } \ No newline at end of file diff --git a/src/gui/widget/weather/weather_fetch.h b/src/gui/widget/weather/weather_fetch.h index 4996d74..ef054fd 100644 --- a/src/gui/widget/weather/weather_fetch.h +++ b/src/gui/widget/weather/weather_fetch.h @@ -26,5 +26,6 @@ #define OWM_PORT 80 void weather_fetch_today( weather_config_t * weather_config, weather_forcast_t * weather_today ); + void weather_fetch_forecast( weather_config_t *weather_config, weather_forcast_t * weather_forecast ); #endif // _WEATHER_FETCH_H \ No newline at end of file diff --git a/src/gui/widget/weather/weather_forecast.cpp b/src/gui/widget/weather/weather_forecast.cpp index b8dafb8..60b3ac0 100644 --- a/src/gui/widget/weather/weather_forecast.cpp +++ b/src/gui/widget/weather/weather_forecast.cpp @@ -20,6 +20,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include +#include #include "weather.h" #include "weather_fetch.h" @@ -30,9 +31,15 @@ #include "gui/statusbar.h" #include "gui/keyboard.h" +EventGroupHandle_t weather_forecast_event_handle = NULL; +TaskHandle_t _weather_forecast_sync_Task; +void weather_forecast_sync_Task( void * pvParameters ); + lv_obj_t *weather_widget_tile = NULL; lv_style_t weather_widget_style; +weather_forcast_t weather_forecast[ WEATHER_MAX_FORECAST ]; + LV_IMG_DECLARE(exit_32px); LV_IMG_DECLARE(setup_32px); LV_IMG_DECLARE(refresh_32px); @@ -69,6 +76,23 @@ void weather_widget_tile_setup( lv_obj_t *tile, lv_style_t *style, lv_coord_t hr lv_obj_align(reload_btn, tile, LV_ALIGN_IN_TOP_RIGHT, -10 , STATUSBAR_HEIGHT + 10 ); lv_obj_set_event_cb( reload_btn, refresh_weather_widget_event_cb ); + // regster callback for wifi sync + WiFi.onEvent( [](WiFiEvent_t event, WiFiEventInfo_t info) { + xEventGroupSetBits( weather_forecast_event_handle, WEATHER_WIDGET_SYNC_REQUEST ); + vTaskResume( _weather_forecast_sync_Task ); + }, WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP ); + + weather_forecast_event_handle = xEventGroupCreate(); + xEventGroupClearBits( weather_forecast_event_handle, WEATHER_WIDGET_SYNC_REQUEST ); + + xTaskCreate( + weather_forecast_sync_Task, /* Function to implement the task */ + "weather sync Task", /* Name of the task */ + 10000, /* Stack size in words */ + NULL, /* Task input parameter */ + 1, /* Priority of the task */ + &_weather_forecast_sync_Task ); /* Task handle. */ + } static void exit_weather_widget_event_cb( lv_obj_t * obj, lv_event_t event ) { @@ -87,7 +111,36 @@ static void setup_weather_widget_event_cb( lv_obj_t * obj, lv_event_t event ) { static void refresh_weather_widget_event_cb( lv_obj_t * obj, lv_event_t event ) { switch( event ) { - case( LV_EVENT_CLICKED ): weather_sync_request(); + case( LV_EVENT_CLICKED ): weather_forecast_sync_request(); + weather_widget_sync_request(); break; } } + +void weather_forecast_sync_request( void ) { + xEventGroupSetBits( weather_forecast_event_handle, WEATHER_WIDGET_SYNC_REQUEST ); + vTaskResume( _weather_forecast_sync_Task ); +} + +void weather_forecast_sync_Task( void * pvParameters ) { + weather_config_t *weather_config = weather_get_config(); + + while( true ) { + vTaskDelay( 250 ); + if ( xEventGroupGetBits( weather_forecast_event_handle ) & WEATHER_WIDGET_SYNC_REQUEST ) { + if ( weather_config->autosync ) { + weather_fetch_forecast( weather_get_config() , &weather_forecast[ 0 ] ); + if ( !weather_forecast[ 0 ].valide ) + weather_fetch_forecast( weather_get_config() , &weather_forecast[ 0 ] ); + if ( weather_forecast[ 0 ].valide ) { + Serial.printf("weather forecast fetch ok\r\n"); + for( int i = 0 ; i < WEATHER_MAX_FORECAST ; i++ ) { + Serial.printf("Temp %02d: %s\r\n", i, weather_forecast[ i ].temp ); + } + } + } + xEventGroupClearBits( weather_forecast_event_handle, WEATHER_WIDGET_SYNC_REQUEST ); + } + vTaskSuspend( _weather_forecast_sync_Task ); + } +} diff --git a/src/gui/widget/weather/weather_forecast.h b/src/gui/widget/weather/weather_forecast.h index 7e8461f..faf9f42 100644 --- a/src/gui/widget/weather/weather_forecast.h +++ b/src/gui/widget/weather/weather_forecast.h @@ -3,6 +3,10 @@ #include + #define WEATHER_WIDGET_SYNC_REQUEST _BV(0) + #define WEATHER_MAX_FORECAST 18 + void weather_widget_tile_setup( lv_obj_t *tile, lv_style_t *style, lv_coord_t hres, lv_coord_t vres ); + void weather_forecast_sync_request( void ); #endif // _WEATHER_FORECAST_H \ No newline at end of file diff --git a/src/hardware/timesync.cpp b/src/hardware/timesync.cpp index bf601ff..44e36ca 100644 --- a/src/hardware/timesync.cpp +++ b/src/hardware/timesync.cpp @@ -46,7 +46,7 @@ void timesync_setup( TTGOClass *ttgo ) { xTaskCreate( timesync_Task, /* Function to implement the task */ "timesync Task", /* Name of the task */ - 10000, /* Stack size in words */ + 2000, /* Stack size in words */ NULL, /* Task input parameter */ 1, /* Priority of the task */ &_timesync_Task ); /* Task handle. */ diff --git a/src/hardware/wifictl.cpp b/src/hardware/wifictl.cpp index 58d8bc2..3ff885b 100644 --- a/src/hardware/wifictl.cpp +++ b/src/hardware/wifictl.cpp @@ -121,7 +121,7 @@ void wifictl_setup( void ) { xTaskCreatePinnedToCore( wifictl_Task, /* Function to implement the task */ "wifictl Task", /* Name of the task */ - 10000, /* Stack size in words */ + 2000, /* Stack size in words */ NULL, /* Task input parameter */ 1, /* Priority of the task */ &_wifictl_Task, /* Task handle. */ diff --git a/src/my-ttgo-watch.ino b/src/my-ttgo-watch.ino index 394bb8d..3815f6a 100644 --- a/src/my-ttgo-watch.ino +++ b/src/my-ttgo-watch.ino @@ -69,7 +69,11 @@ void setup() for( int bl = 0 ; bl < display_get_brightness() ; bl++ ) { ttgo->bl->adjust( bl ); delay(5); - } + } + Serial.printf("Total heap: %d\r\n", ESP.getHeapSize()); + Serial.printf("Free heap: %d\r\n", ESP.getFreeHeap()); + Serial.printf("Total PSRAM: %d\r\n", ESP.getPsramSize()); + Serial.printf("Free PSRAM: %d\r\n", ESP.getFreePsram()); } void loop() diff --git a/ttgo-t-watch2020_v1.ino.bin b/ttgo-t-watch2020_v1.ino.bin index 2510850..bc2e801 100644 Binary files a/ttgo-t-watch2020_v1.ino.bin and b/ttgo-t-watch2020_v1.ino.bin differ