Skip to content

Commit

Permalink
Weather App: Periodically fetch weather over HTTP.
Browse files Browse the repository at this point in the history
  • Loading branch information
jakkra committed Oct 29, 2024
1 parent 3b413ad commit 92060da
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 8 deletions.
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

0 comments on commit 92060da

Please sign in to comment.