Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Periodically fetch weather in background #367

Merged
merged 1 commit into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/src/applications/weather/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
if (CONFIG_ZSWATCH_PCB_REV GREATER_EQUAL 4)
if (CONFIG_ZSWATCH_PCB_REV GREATER_EQUAL 4 OR CONFIG_BOARD_NATIVE_POSIX)
FILE(GLOB app_sources *.c)
target_sources(app PRIVATE ${app_sources})
endif()
46 changes: 40 additions & 6 deletions app/src/applications/weather/weather_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,22 @@ LOG_MODULE_REGISTER(weather_app, LOG_LEVEL_DBG);
#define HTTP_REQUEST_URL_FMT "https://api.open-meteo.com/v1/forecast?latitude=%f&longitude=%f&current=wind_speed_10m,temperature_2m,apparent_temperature,weather_code&daily=weather_code,temperature_2m_max,temperature_2m_min,apparent_temperature_max,apparent_temperature_min,precipitation_sum,rain_sum,precipitation_probability_max&wind_speed_unit=ms&timezone=auto&forecast_days=%d"

#define MAX_GPS_AGED_TIME_MS 30 * 60 * 1000
#define WEATHER_BACKGROUND_FETCH_INTERVAL_S (30 * 60)

// Functions needed for all applications
static void weather_app_start(lv_obj_t *root, lv_group_t *group);
static void weather_app_stop(void);
static void on_zbus_ble_data_callback(const struct zbus_channel *chan);
static void periodic_fetch_weather_data(struct k_work *work);
static void publish_weather_data(struct k_work *work);

ZBUS_CHAN_DECLARE(ble_comm_data_chan);
ZBUS_LISTENER_DEFINE(weather_ble_comm_lis, on_zbus_ble_data_callback);
ZBUS_CHAN_ADD_OBS(ble_comm_data_chan, weather_ble_comm_lis, 1);

K_WORK_DELAYABLE_DEFINE(weather_app_fetch_work, periodic_fetch_weather_data);
K_WORK_DEFINE(weather_app_publish, publish_weather_data);

ZSW_LV_IMG_DECLARE(weather_app_icon);

static bool active;
Expand All @@ -34,6 +40,8 @@ static uint64_t last_update_weather_time;
static double last_lat;
static double last_lon;

static ble_comm_weather_t last_weather;

static application_t app = {
.name = "Weather",
.icon = ZSW_LV_IMG_USE(weather_app_icon),
Expand All @@ -48,10 +56,6 @@ static void http_rsp_cb(ble_http_status_code_t status, char *response)
weather_ui_forecast_data_t forecasts[WEATHER_UI_NUM_FORECASTS];
char *days[] = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};

if (!active) {
return;
}

if (status == BLE_HTTP_STATUS_OK) {
zsw_clock_get_time(&time_now);
cJSON *parsed_response = cJSON_Parse(response);
Expand Down Expand Up @@ -85,15 +89,32 @@ static void http_rsp_cb(ble_http_status_code_t status, char *response)

weather_ui_set_weather_data(current_weather, forecasts, cJSON_GetArraySize(weather_code_list));

ble_comm_request_gps_status(false);
last_weather.temperature_c = current_weather.temperature;
last_weather.humidity = 0;
last_weather.wind = current_weather.wind_speed;
last_weather.wind_direction = 0;
last_weather.weather_code = wmo_code_to_weather_code(current_weather_code->valueint);
strncpy(last_weather.report_text, current_weather.text, sizeof(last_weather.report_text));

cJSON_Delete(parsed_response);
last_update_weather_time = k_uptime_get();
ble_comm_request_gps_status(false);

k_work_submit(&weather_app_publish);
} else {
LOG_ERR("HTTP request failed\n");
weather_ui_set_error(status == BLE_HTTP_STATUS_TIMEOUT ? "Timeout" : "Failed");
}
}

static void publish_weather_data(struct k_work *work)
{
ble_comm_cb_data_t data;
data.type = BLE_COMM_DATA_TYPE_WEATHER;
data.data.weather = last_weather;
zbus_chan_pub(&ble_comm_data_chan, &data, K_MSEC(250));
}

static void fetch_weather_data(double lat, double lon)
{
char weather_url[512];
Expand All @@ -105,6 +126,15 @@ static void fetch_weather_data(double lat, double lon)
}
}

static void periodic_fetch_weather_data(struct k_work *work)
{
int ret = ble_comm_request_gps_status(true);
if (ret != 0) {
LOG_ERR("Failed to disable phone GPS: %d", ret);
}
k_work_reschedule(&weather_app_fetch_work, K_SECONDS(WEATHER_BACKGROUND_FETCH_INTERVAL_S));
}

static void on_zbus_ble_data_callback(const struct zbus_channel *chan)
{
const struct ble_data_event *event = zbus_chan_const_msg(chan);
Expand All @@ -117,6 +147,10 @@ static void on_zbus_ble_data_callback(const struct zbus_channel *chan)
last_lat = event->data.data.gps.lat;
last_lon = event->data.data.gps.lon;
fetch_weather_data(event->data.data.gps.lat, event->data.data.gps.lon);
int ret = ble_comm_request_gps_status(false);
if (ret != 0) {
LOG_ERR("Failed to request GPS data: %d", ret);
}
}
}

Expand Down Expand Up @@ -152,7 +186,7 @@ static int weather_app_add(void)
{
zsw_app_manager_add_application(&app);

// TODO Add periodic GPS and weather polling in backgrund.
k_work_reschedule(&weather_app_fetch_work, K_SECONDS(30));

return 0;
}
Expand Down
92 changes: 91 additions & 1 deletion app/src/ui/utils/zsw_ui_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,99 @@ const lv_img_dsc_t *zsw_ui_utils_icon_from_weather_code(int code, lv_color_t *ic
}
}

int wmo_code_to_weather_code(int wmo_code)
{
switch (wmo_code) {
case 0: {
return 800;
}
case 1: {
return 800;
}
case 2: {
return 800;
}
case 3: {
return 803;
}
case 45: {
return 700;
}
case 48: {
return 700;
}
case 51: {
return 700;
}
case 53: {
return 512;
}
case 55: {
return 512;
}
case 80: {
return 512;
}
case 81: {
return 512;
}
case 82: {
return 512;
}
case 61: {
return 512;
}
case 63: {
return 512;
}
case 65: {
return 512;
}
case 56: {
return 512;
}
case 57: {
return 512;
}
case 66: {
return 512;
}
case 67: {
return 512;
}
case 71: {
return 511;
}
case 73: {
return 511;
}
case 75: {
return 511;
}
case 77: {
return 511;
}
case 85: {
return 511;
}
case 86: {
return 511;
}
case 95: {
return 200;
}
case 96: {
return 200;
}
case 99: {
return 200;
}
}
return -1;
}

const void *zsw_ui_utils_icon_from_wmo_weather_code(int code, lv_color_t *color, char **text)
{
printk("WMO Code: %d\n", code);
switch (code) {
case 0: {
*color = lv_color_hex(0xF1F1F1);
Expand Down
2 changes: 2 additions & 0 deletions app/src/ui/utils/zsw_ui_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ const lv_img_dsc_t *zsw_ui_utils_icon_from_weather_code(int code, lv_color_t *ic

const void *zsw_ui_utils_icon_from_wmo_weather_code(int code, lv_color_t *color, char **text);

int wmo_code_to_weather_code(int wmo_code);

const void *zsw_ui_utils_icon_from_notification(zsw_notification_src_t src);

const char *zsw_ui_utils_source_from_notification(zsw_notification_src_t src);
Expand Down