/************************************************************************************************** * Copyright (c) Fenda Technologies Co., Ltd. 2020-2021. All rights reserved. * Description: 天气接口函数 * Author: ball.caojianguang * Create: 2020-6-4 ************************************************************************************************/ #include "ble_protocol.h" #include "ble_device_setup_server.h" #include "ble_data_transmission.h" #include "ble_weather_server.h" #include "user_adapter.h" #include "sql_weather.h" #include "task_ble.h" #include "task_ui.h" #define ENABLE_STATIC_PRINT true extern uint32_t am_util_stdio_printf(const char *pcFmt, ...); #define static_print_remind(...) am_util_stdio_printf(__VA_ARGS__) #if ENABLE_STATIC_PRINT #define static_print_info(...) am_util_stdio_printf(__VA_ARGS__) #else #define static_print_info(...) #endif /**************************************************************************** APP下发实时和预报天气(UTF-8编码)--4.16.1 *****************************************************************************/ void BleDistributeRTAndForecastWeather(uint8_t *in_data, uint16_t in_len, uint8_t *out_data, uint16_t *out_len) { protocol_data_info_t data_info = {0}; uint16_t write_idx = 0; uint32_t u32_temp = 0; uint16_t u16_temp = 0; float float_temp = 0; uint16_t ErrCnt = 0; uint8_t ForecastID = 0; uint8_t ForeCastItemLen = 0; static_print_info("func:%s, line:%d, start.\n", __FUNCTION__, __LINE__); data_info.error = FENDA_SUCCESS; do { user_get_data_info(&data_info, &in_data, &in_len); switch(data_info.type) { //无子节点 case LOCATE_NAME_TYPE: sql_weather_set_location_txt((char *)data_info.p_data, data_info.len); static_print_info("locate name type received.\r\n"); break; case UPDATE_TIME_TYPE: u32_temp = (*data_info.p_data++) * 0x1000000; u32_temp += ((*data_info.p_data++) * 0x10000); u32_temp += ((*data_info.p_data++) * 0x100); u32_temp += (*data_info.p_data); sql_weather_set_update_timestamp(u32_temp); static_print_info("Weather updateTime = %u.\r\n", u32_temp); break; case NOW_TEMPER_TYPE: float_temp = (*data_info.p_data++) * 0x100; float_temp += (*data_info.p_data); float_temp /= 10; //按协议传输放大了10倍 sql_weather_set_now_temperature(float_temp); static_print_info("Weather NowTempture = %f.\r\n", float_temp); break; case NOW_WEATHER_ICON_TYPE: u16_temp = (*data_info.p_data++) * 0x100; u16_temp += (*data_info.p_data); sql_weather_set_forecast_protocol_value(0,u16_temp); static_print_info("Weather protocol_value = %d.\r\n", u16_temp); //将协议的天气图片索引转换成真实资源图片ID // weatherInfo_temp.nowWeatherIcon = GetWeatherIcon(weatherInfo_temp.nowWeatherIcon); // static_print_info("222 Weather nowWeatherIcon = %d.\r\n", weatherInfo_temp.nowWeatherIcon); break; case NOW_WEATHER_TEXT_TYPE: static_print_info("Weather nowWeatherText data_info.len = %d.\r\n", ForecastID, data_info.len); sql_weather_set_forecast_weather_text(0,(char *)data_info.p_data, data_info.len); break; case FORECAST_ITEM_LEN_TYPE: //Forecast weather item start ... ForeCastItemLen = *data_info.p_data; static_print_info("Weather ForeCastItemLen = %d.\r\n", ForeCastItemLen); //因为不同类型设备,天气预报天数不同,以7天最大值为判断依据 // if(ForecastID >= WEATHER_FORECAST_DAYS) { if(ForecastID >= sql_weather_get_forecast_max()) { ErrCnt++; data_info.error = PARAM_ERROR; } ForecastID++; sql_weather_set_forecast_count(ForecastID); static_print_info("Weather ForecastID = %d.\r\n", ForecastID); // static_print_info("in_data[15-16] = 0x%x 0x%x.\r\n", in_data[15], in_data[16]); // data_info.type = 16 + in_data[15]; // static_print_info("temperMax in_data[%d,4]: 0x%x, 0x%x, 0x%x, 0x%x.\r\n", data_info.type - 1, in_data[data_info.type - 1], in_data[data_info.type], in_data[data_info.type + 1], in_data[data_info.type + 2]); // static_print_info("temperMin in_data[%d,4]: 0x%x, 0x%x, 0x%x, 0x%x.\r\n", data_info.type + 3, in_data[data_info.type + 3], in_data[data_info.type + 4], in_data[data_info.type + 5], in_data[data_info.type + 6]); break; case FORECAST_ITEM_TIME_TYPE: if(ForecastID > sql_weather_get_forecast_max()) { break; } u32_temp = (*data_info.p_data++) * 0x1000000; u32_temp += ((*data_info.p_data++) * 0x10000); u32_temp += ((*data_info.p_data++) * 0x100); u32_temp += (*data_info.p_data); sql_weather_set_forecast_date_timestamp(ForecastID-1, u32_temp); static_print_info("weatherForecast[%d] dateTimes = %d.\r\n", ForecastID, u32_temp); break; case FORECAST_ITEM_WEATHER_ICON_TYPE: if(ForecastID > sql_weather_get_forecast_max()) { break; } u16_temp = (*data_info.p_data++) * 0x100; u16_temp += (*data_info.p_data); sql_weather_set_forecast_protocol_value(ForecastID-1, u16_temp); static_print_info("weatherForecast[%d] weatherIcon = %d.\r\n", ForecastID, u16_temp); // //将协议的天气图片索引转换成真实资源图片ID // weatherInfo_temp.weatherForecast[ForecastID - 1].weatherIcon = GetWeatherIcon(weatherInfo_temp.weatherForecast[ForecastID - 1].weatherIcon); // static_print_info("222 weatherForecast[%d] weatherIcon = %d.\r\n", ForecastID, weatherInfo_temp.weatherForecast[ForecastID - 1].weatherIcon); break; case FORECAST_ITEM_WEATHER_TEXT_TYPE: static_print_info("weatherForecast[%d] weatherText data_info.len = %d.\r\n", ForecastID, data_info.len); if(ForecastID > sql_weather_get_forecast_max()) { break; } sql_weather_set_forecast_weather_text(ForecastID-1, (char *)data_info.p_data, data_info.len); break; case FORECAST_ITEM_AQI_TYPE: if(ForecastID > sql_weather_get_forecast_max()) { break; } u16_temp = (*data_info.p_data++) * 0x100; u16_temp += (*data_info.p_data); sql_weather_set_forecast_aqi(ForecastID-1, u16_temp); static_print_info("weatherForecast[%d] aqi = %d.\r\n", ForecastID, u16_temp); break; case FORECAST_ITEM_AQI_TEXT_TYPE: if(ForecastID > sql_weather_get_forecast_max()) { break; } static_print_info("weatherForecast[%d] aqiText data_info.len = %d.\r\n", ForecastID, data_info.len); sql_weather_set_forecast_aqi_text(ForecastID-1, (char *)data_info.p_data, data_info.len); break; case FORECAST_ITEM_TEMPER_MAX_TYPE: if(ForecastID > sql_weather_get_forecast_max()) { break; } float_temp = (*data_info.p_data++) * 0x100; float_temp += (*data_info.p_data); static_print_info("weatherForecast[%d] temperMax = %f.\r\n", ForecastID, float_temp); float_temp /= 10;//按协议传输放大了10倍 sql_weather_set_forecast_temperature_max(ForecastID-1, float_temp); static_print_info("222 weatherForecast[%d] temperMax = %f.\r\n", ForecastID, float_temp); break; case FORECAST_ITEM_TEMPER_MIN_TYPE: if(ForecastID > sql_weather_get_forecast_max()) { break; } float_temp = (*data_info.p_data++) * 0x100; float_temp += (*data_info.p_data); static_print_info("weatherForecast[%d] temperMax = %f.\r\n", ForecastID, float_temp); float_temp /= 10;//按协议传输放大了10倍 sql_weather_set_forecast_temperature_min(ForecastID-1, float_temp); static_print_info("222 weatherForecast[%d] temperMax = %f.\r\n", ForecastID, float_temp); break; default: break; } if(data_info.error == PARAM_ERROR) { break; } in_data = in_data + (data_info.len); in_len = in_len - (2 + data_info.len); if(in_len > FRAM_MAX_SIZ) { in_len = 0; } }while(in_len); sql_weather_set_net_state(1); task_ble_notify(BLE_SAVE_WEATHER_MSG, (ForecastID << 8 | ErrCnt)); // 异步存储天气信息,并按ErrCnt进行日志打点 // ------TO BE ADDED 向UI发送消息 ------- task_ui_notify(EVENT_WEATHER_UPDATE,NULL,NULL,NULL); static_print_info("func:%s, data_info.error = %d.\r\n", __FUNCTION__, data_info.error); write_idx = user_set_protocol_error(out_data, WEATHER_SERVER, data_info.error); *out_len = write_idx; } /*************************************************************************************************** 设备通知APP更新天气--4.16.2 ***************************************************************************************************/ void BLE_DeviceNotifyAppUpdateweather(void) { uint16_t write_idx = 0; uint8_t buf_temp[WEATHER_TEMP_NUM_MAX] = {0}; buf_temp[write_idx++] = 0x03; //LTV L值 buf_temp[write_idx++] = UPDATE_WEARTHER_TYPE; //type buf_temp[write_idx++] = 0x01; //value BLE_SendFrameById(WEATHER_SERVER, DVE_req_weather_ID, buf_temp, write_idx); } void BLE_NotifyUpdateweatherReportACK(uint8_t *in_data, uint16_t in_len, uint8_t *out_data, uint16_t *out_len) { protocol_data_info_t data_info = {0}; // uint8_t UpdateweatherReportACK[2] = {0}; data_info.error = FENDA_SUCCESS; do { user_get_data_info(&data_info, &in_data, &in_len); switch(data_info.type & 0x7f) { //无子节点 case WeatherSwitchType: // UpdateweatherReportACK[0] = *data_info.p_data++; // UpdateweatherReportACK[1] = *data_info.p_data; break; default: break; } in_data = data_info.p_data; in_data = in_data + (data_info.len); in_len = in_len - (2 + data_info.len); if(in_len > FRAM_MAX_SIZ) { in_len = 0; } } while(in_len); *out_len = 0; } /*************************************************************************************************** APP设置天气开关--4.16.3 ***************************************************************************************************/ void BleAppSetWeatherSwitch(uint8_t *in_data, uint16_t in_len, uint8_t *out_data, uint16_t *out_len) { protocol_data_info_t data_info = {0}; uint16_t write_idx = 0; uint8_t weather_appSwitch = 0; data_info.error = PARAM_ERROR; do { user_get_data_info(&data_info, &in_data, &in_len); switch(data_info.type & 0x7f) { //无子节点 case WeatherSwitchType: weather_appSwitch = *data_info.p_data; data_info.error = FENDA_SUCCESS; break; default: break; } in_data = in_data + (data_info.len); in_len = in_len - (2 + data_info.len); if(in_len > FRAM_MAX_SIZ) { in_len = 0; } }while(in_len); static_print_info("weather_appSwitch = %d \r\n", weather_appSwitch); if(data_info.error == FENDA_SUCCESS) { //重置并保存天气温度开关 sql_weather_set_switch(weather_appSwitch); task_ble_notify(BLE_SAVE_WEATHER_MSG, 0); // 异步存储天气信息 if(weather_appSwitch) { task_ble_notify(BLE_WEATHER_UPDATE_MSG, 0); } // ------TO BE ADDED 向UI发送消息 ------- task_ui_notify(EVENT_WEATHER_UPDATE,NULL,NULL,NULL); } write_idx = user_set_protocol_error(out_data, WEATHER_SERVER, data_info.error); *out_len = write_idx; } // 所有涉及到天气的函数指针,这里的顺序和common id 顺序相同 const p_func_t WeatherServerFunc[WEATHER_SERVERE_MAX_ID] = { user_null_func, BleDistributeRTAndForecastWeather, //4.16.1 BLE_NotifyUpdateweatherReportACK, //4.16.2 BleAppSetWeatherSwitch //4.16.3 };