mcu_hi3321_watch/tjd/sql/sql_weather.c
2025-05-26 20:15:20 +08:00

616 lines
19 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*----------------------------------------------------------------------------
* Copyright (c) Fenda Technologies Co., Ltd. 2021. All rights reserved.
*
* Description: sql_weather.c
*
* Author: saimen
*
* Create: 2024-06-08
*--------------------------------------------------------------------------*/
#include "string.h"
#include <stdlib.h>
#include "sys_typedef.h"
#include "sys_config.h"
#include "linux/crc32.h"
#include "sql_weather.h"
/**********************************************************************************************************************
* DEFINE
*/
#define ENABLE_STATIC_PRINT false
#define static_print_error(...) sys_sql_log_e(__VA_ARGS__) //错误信息打印一般常开
#define static_print_warn(...) sys_sql_log_w(__VA_ARGS__) //警告信息打印一般常开
#if ENABLE_STATIC_PRINT
#define static_print_debug(...) sys_sql_log_d(__VA_ARGS__)
#else
#define static_print_debug(...)
#endif
#define FILE_VERSION_WEATHER (1)//>0
#define FILE_PATH_WEATHER "/system/sql_weather.bin"
#define WEATHER_TIMEOUT_SECOND_DIFF (12*60*60) //12小时秒数
#define WEATHERUPDATE_MIN_COUNT 120 //2小时分钟数
#define WEATHERUPDATE_SECOND_DIFF_COUNT 2 //设备与APP秒数误差
#define WEATHER_FORECAST_DAYS 7 //预报天数
#define LOCATION_TEXT_MAX_LEN 32 //地址描述最大字节数
#define WEATHER_TEXT_MAX_LEN 20 //天气描述最大字节数
#define AIR_TEXT_MAX_LEN 16 //空气描述最大字节数
typedef struct {
uint32_t date_timestamp; //预报日期,日的秒级
int8_t temperature_min; //最低温度(℃) ,放大十倍后的数据
int8_t temperature_max; //最高温度(℃)
uint16_t protocol_value; //天气状况协议值
uint16_t aqi; //空气质量指数
char aqi_text[AIR_TEXT_MAX_LEN]; //空气质量文字描述(最多5个中文字比如 重度污染) -- utf-8
char weather_text[WEATHER_TEXT_MAX_LEN]; //天气状况文字描述(最多6个中文字) -- utf-8
} weather_forecast_t;
#pragma pack(4) //alignment 4 bytes
typedef struct {
uint32_t init_flag:8; //标记模块是否初始化。=0 无效数据;=1 正常数据;=2 恢复数据。
uint32_t version:8; //结构体版本
uint32_t app_switch:8; //APP天气开关
uint32_t timeout:8; //天气过期0x55-未过期,其它-已过期过期时间以12小时为限
uint32_t update_timestamp; //更新时间 UTC 秒
weather_forecast_t forecast[WEATHER_FORECAST_DAYS]; //N天天气(当天算起的N天)
uint8_t forecast_count; //实际预报天数
int8_t now_temperature; //当前温度(℃)
int8_t now_humidity; //当前湿度(%)
int8_t now_wind_speed; //当前风速(级)
uint8_t net_state; //APP天气连网状态0=无网络1=有网络
uint8_t temper_unit; //温度单位0=℃1= F -- 取TemperatureType枚举量
uint16_t sunrise_time; //日出时间 单位:分钟
uint16_t sunset_time; //日落时间 单位:分钟
uint8_t update_hour; //更新时间-小时
uint8_t update_minute; //更新时间-分钟在SetWeatherInfo的时候转换为RTC时间用于UI显示更新时间
char location_txt[LOCATION_TEXT_MAX_LEN]; //市区域名称
//uint8_t revs[4]; //保证8字节对齐
uint32_t crc32; //
} weather_def_t;
#pragma pack()
static weather_def_t g_weather_info = {0};
static bool g_weather_need_save = false;
/**********************************************************************************************************************
* 固定接口
*/
int sql_weather_init(void)
{
int ret = RET_SUCCESS;
uint32_t ui32_crc;
static_print_warn("[%s],sizeof(weather_def_t) = %d\r\n", FILE_PATH_WEATHER, sizeof(weather_def_t));
ui32_crc = Crc32Part(0,(const char *)&g_weather_info, sizeof(weather_def_t) - 4);
if(ui32_crc != g_weather_info.crc32 || g_weather_info.version != FILE_VERSION_WEATHER)
{
sql_weather_test();
/*----------------test------------------*/
memcpy(g_weather_info.location_txt, "深圳市", sizeof("深圳市"));
g_weather_info.now_temperature = 29;
g_weather_info.update_hour = 11;
g_weather_info.update_minute = 15;
g_weather_info.forecast[0].protocol_value = 0x02;
g_weather_info.forecast[0].temperature_max = 35;
g_weather_info.forecast[0].temperature_min = 20;
/*----------------end------------------*/
g_weather_need_save = true;
}
return ret;
}
void* sql_weather_get_info(uint32_t *len, char **path)
{
g_weather_info.crc32 = Crc32Part(0,(const char *)&g_weather_info, sizeof(weather_def_t) - 4);
*len = sizeof(weather_def_t);
*path = (char*)FILE_PATH_WEATHER;
return &g_weather_info;
}
void sql_weather_set_save_flag(uint8_t value)
{
g_weather_need_save = value;
}
uint8_t sql_weather_get_save_flag(void)
{
return g_weather_need_save;
}
/**********************************************************************************************************************
* 通用接口
*/
void sql_weather_set_switch(uint8_t en)
{
if(g_weather_info.app_switch != en)
{
g_weather_info.app_switch = en;
g_weather_need_save = true;
}
}
uint8_t sql_weather_get_switch(void)
{
return g_weather_info.app_switch;
}
void sql_weather_set_temper_unit(uint8_t unit)
{
if(g_weather_info.temper_unit != unit)
{
g_weather_info.temper_unit = unit;
g_weather_need_save = true;
}
}
uint8_t sql_weather_get_temper_unit(void)
{
return g_weather_info.temper_unit;
}
void sql_weather_set_net_state(uint8_t state)
{
if(g_weather_info.net_state != state)
{
g_weather_info.net_state = state;
g_weather_need_save = true;
}
}
uint8_t sql_weather_get_net_state(void)
{
return g_weather_info.net_state;
}
void sql_weather_set_timeout(uint8_t en)
{
if(g_weather_info.timeout != en)
{
g_weather_info.timeout = en;
g_weather_need_save = true;
}
}
uint8_t sql_weather_get_timeout(void)
{
return g_weather_info.timeout;
}
void sql_weather_set_update_timestamp(uint32_t time)
{
if(g_weather_info.update_timestamp != time)
{
g_weather_info.version = FILE_VERSION_WEATHER; //让数据保留
g_weather_info.update_timestamp = time;
g_weather_need_save = true;
}
}
uint32_t sql_weather_get_update_timestamp(void)
{
return g_weather_info.update_timestamp;
}
void sql_weather_set_location_txt( char *text,uint32_t len)
{
uint32_t str_len;
str_len = len;
if(str_len>=LOCATION_TEXT_MAX_LEN)
{
str_len = LOCATION_TEXT_MAX_LEN - 1;
}
memcpy(g_weather_info.location_txt, text, str_len);
g_weather_info.location_txt[str_len] = 0;
g_weather_need_save = true;
}
char* sql_weather_get_location_txt(void)
{
return &g_weather_info.location_txt[0];
}
void sql_weather_set_now_temperature(int8_t temper)
{
if(g_weather_info.now_temperature != temper)
{
g_weather_info.now_temperature = temper;
g_weather_need_save = true;
}
}
int8_t sql_weather_get_now_temperature(void)
{
return g_weather_info.now_temperature;
}
void sql_weather_set_update_hour(uint8_t hour)
{
if(g_weather_info.update_hour != hour)
{
g_weather_info.update_hour = hour;
g_weather_need_save = true;
}
}
uint8_t sql_weather_get_update_hour(void)
{
return g_weather_info.update_hour;
}
void sql_weather_set_update_minute(uint8_t minute)
{
if(g_weather_info.update_minute != minute)
{
g_weather_info.update_minute = minute;
g_weather_need_save = true;
}
}
uint8_t sql_weather_get_update_minute(void)
{
return g_weather_info.update_minute;
}
void sql_weather_set_sunrise_time(uint16_t sunrise_time)
{
if(g_weather_info.sunrise_time != sunrise_time)
{
g_weather_info.sunrise_time = sunrise_time;
g_weather_need_save = true;
}
}
uint16_t sql_weather_get_sunrise_time(void)
{
return g_weather_info.sunrise_time;
}
void sql_weather_set_sunset_time(uint16_t sunset_time)
{
if(g_weather_info.sunset_time != sunset_time)
{
g_weather_info.sunset_time = sunset_time;
g_weather_need_save = true;
}
}
uint16_t sql_weather_get_sunset_time(void)
{
return g_weather_info.sunset_time;
}
/**********************************************************************************************************************
* weather forecast
*/
uint8_t sql_weather_get_forecast_max(void)
{
return WEATHER_FORECAST_DAYS;
}
void sql_weather_set_forecast_count(uint8_t value)
{
if(value<=WEATHER_FORECAST_DAYS)
{
if(g_weather_info.forecast_count != value)
{
g_weather_info.forecast_count = value;
g_weather_need_save = true;
}
}
}
uint8_t sql_weather_get_forecast_count(void)
{
return g_weather_info.forecast_count;
}
void sql_weather_set_forecast_protocol_value(uint8_t index,uint16_t value)
{
if(index<WEATHER_FORECAST_DAYS)
{
if(g_weather_info.forecast[index].protocol_value != value)
{
g_weather_info.forecast[index].protocol_value = value;
g_weather_need_save = true;
}
}
}
uint16_t sql_weather_get_forecast_protocol_value(uint8_t index)
{
if(index<WEATHER_FORECAST_DAYS)
{
return g_weather_info.forecast[index].protocol_value;
}
else
{
return RET_ERROR;
}
}
void sql_weather_set_forecast_date_timestamp(uint8_t index,uint32_t time)
{
if(index<WEATHER_FORECAST_DAYS)
{
if(g_weather_info.forecast[index].date_timestamp != time)
{
g_weather_info.forecast[index].date_timestamp = time;
g_weather_need_save = true;
}
}
}
uint32_t sql_weather_get_forecast_date_timestamp(uint8_t index)
{
if(index<WEATHER_FORECAST_DAYS)
{
return g_weather_info.forecast[index].date_timestamp;
}
else
{
return RET_ERROR;
}
}
void sql_weather_set_forecast_temperature_max(uint8_t index,int8_t value)
{
if(index<WEATHER_FORECAST_DAYS)
{
if(g_weather_info.forecast[index].temperature_max != value)
{
g_weather_info.forecast[index].temperature_max = value;
g_weather_need_save = true;
}
}
}
int8_t sql_weather_get_forecast_temperature_max(uint8_t index)
{
if(index<WEATHER_FORECAST_DAYS)
{
return g_weather_info.forecast[index].temperature_max;
}
else
{
return RET_ERROR;
}
}
void sql_weather_set_forecast_temperature_min(uint8_t index,int8_t value)
{
if(index<WEATHER_FORECAST_DAYS)
{
if(g_weather_info.forecast[index].temperature_min != value)
{
g_weather_info.forecast[index].temperature_min = value;
g_weather_need_save = true;
}
}
}
int8_t sql_weather_get_forecast_temperature_min(uint8_t index)
{
if(index<WEATHER_FORECAST_DAYS)
{
return g_weather_info.forecast[index].temperature_min;
}
else
{
return RET_ERROR;
}
}
void sql_weather_set_humidity(uint8_t value)
{
if(g_weather_info.now_humidity != value)
{
g_weather_info.now_humidity = value;
g_weather_need_save = true;
}
}
int8_t sql_weather_get_humidity(void)
{
return g_weather_info.now_humidity;
}
void sql_weather_set_wind_speed(uint8_t value)
{
if(g_weather_info.now_wind_speed != value)
{
g_weather_info.now_wind_speed = value;
g_weather_need_save = true;
}
}
uint8_t sql_weather_get_wind_speed(void)
{
return g_weather_info.now_wind_speed;
}
void sql_weather_set_forecast_aqi(uint8_t index,uint16_t value)
{
if(index<WEATHER_FORECAST_DAYS)
{
if(g_weather_info.forecast[index].aqi != value)
{
g_weather_info.forecast[index].aqi = value;
g_weather_need_save = true;
}
}
}
uint16_t sql_weather_get_forecast_aqi(uint8_t index)
{
if(index<WEATHER_FORECAST_DAYS)
{
return g_weather_info.forecast[index].aqi;
}
else
{
return RET_ERROR;
}
}
void sql_weather_set_forecast_aqi_text(uint8_t index,char *text,uint32_t len)
{
if(index<WEATHER_FORECAST_DAYS)
{
uint32_t str_len;
str_len = len;
if(str_len>=AIR_TEXT_MAX_LEN)
{
str_len = AIR_TEXT_MAX_LEN - 1;
}
memcpy(g_weather_info.forecast[index].aqi_text, text, str_len);
g_weather_info.forecast[index].aqi_text[str_len] = 0;
g_weather_need_save = true;
}
}
char * sql_weather_get_forecast_aqi_text(uint8_t index)
{
if(index<WEATHER_FORECAST_DAYS)
{
return &g_weather_info.forecast[index].aqi_text[0];
}
else
{
return NULL;
}
}
void sql_weather_set_forecast_weather_text(uint8_t index,char *text,uint32_t len)
{
if(index<WEATHER_FORECAST_DAYS)
{
uint32_t str_len;
str_len = len;
if(str_len>=WEATHER_TEXT_MAX_LEN)
{
str_len = WEATHER_TEXT_MAX_LEN - 1;
}
memcpy(g_weather_info.forecast[index].weather_text, text, str_len);
g_weather_info.forecast[index].weather_text[str_len] = 0;
g_weather_need_save = true;
}
}
char * sql_weather_get_forecast_weather_text(uint8_t index)
{
if(index<WEATHER_FORECAST_DAYS)
{
return &g_weather_info.forecast[index].weather_text[0];
}
else
{
return NULL;
}
}
//--------------------------------------------------------------------------------------------------------
// ----------------- 模拟测试代码 ------------------
//--------------------------------------------------------------------------------------------------------
//#include "rtc_api.h"
void sql_weather_test(void)
{
static uint32_t cnt = 0;
uint32_t mode = 0;
weather_def_t* weatherInfo = &g_weather_info;
static_print_warn("sql_weather_test()\r\n");
//打桩设置实时天气数据
//weatherInfo.appSwitch = 1;
#if 1
//weatherInfo->update_timestamp = rtc_api_get_utc_timestamp();
//设置随机数种子
srand(weatherInfo->update_timestamp);
switch(rand() % 5) { //范围0~4
case 0:
strcpy(weatherInfo->location_txt, "高新区");
break;
case 1:
strcpy(weatherInfo->location_txt, "宝安区");
break;
case 2:
strcpy(weatherInfo->location_txt, "迎泽区");
break;
case 3:
strcpy(weatherInfo->location_txt, "Huangpu Area");
break;
case 4:
strcpy(weatherInfo->location_txt, "Haidian Area");
break;
default:
strcpy(weatherInfo->location_txt, "雁塔区");
break;
}
//struct tm *dateTime = rtc_api_get_datetime_by_timestamp(weatherInfo->update_timestamp + (8*3600));
//weatherInfo->update_hour = dateTime->tm_hour;
//weatherInfo->update_minute = dateTime->tm_min;
if((rand() % 2) == 1) {
weatherInfo->timeout = 0x55;
} else {
weatherInfo->timeout = 0;
}
mode = cnt % 6;
if(mode == 5) {
weatherInfo->temper_unit = TEMP_FAHRENHEIT;
} else {
weatherInfo->temper_unit = (temperature_enum)(rand() % 2); //温度类型范围0~1
}
weatherInfo->now_temperature = (rand() % 100) - 50; //默认为摄氏度,天气温范围:-50~49单位摄氏度
mode = cnt % 6;
//打桩设置预报天气数据
weatherInfo->forecast_count = ARRY_NUM(g_weather_info.forecast);
for(int i = 0; i < ARRY_NUM(g_weather_info.forecast); i++) {
if(weatherInfo->forecast[i].protocol_value == 0) { //实时天气为晴
weatherInfo->forecast[i].protocol_value = 999;
strcpy(weatherInfo->forecast[i].weather_text, "阴天多云");
weatherInfo->forecast[i].aqi = 19; //天气指数低
strcpy(weatherInfo->forecast[i].aqi_text, "");
} else {
weatherInfo->forecast[i].protocol_value = 104;
strcpy(weatherInfo->forecast[i].weather_text, "晴转多云");
weatherInfo->forecast[i].aqi = rand() % 500; //天气指数随机
strcpy(weatherInfo->forecast[i].aqi_text, "");
}
//默认按照摄氏度计算
if(mode == 5) {
//最高温度
weatherInfo->forecast[i].temperature_max = 49.0;
//最低温度
weatherInfo->forecast[i].temperature_min = -50.0;
} else {
if(weatherInfo->now_temperature >= 0) {
//最高温度
weatherInfo->forecast[i].temperature_max = (rand() % (50 - (int)weatherInfo->now_temperature)) + weatherInfo->now_temperature;
weatherInfo->forecast[i].temperature_max = ((weatherInfo->forecast[i].temperature_max) > 49 ? 49 : (weatherInfo->forecast[i].temperature_max));
//最低温度
weatherInfo->forecast[i].temperature_min = (rand() % (50 + (int)weatherInfo->now_temperature)) - 50;
weatherInfo->forecast[i].temperature_min = (weatherInfo->forecast[i].temperature_min) < (-50) ? (-50) : (weatherInfo->forecast[i].temperature_min);
} else {
//最高温度
weatherInfo->forecast[i].temperature_max = (rand() % (49 - (int)weatherInfo->now_temperature)) + weatherInfo->now_temperature + 1;
weatherInfo->forecast[i].temperature_max = ((weatherInfo->forecast[i].temperature_max) > 49 ? 49 : (weatherInfo->forecast[i].temperature_max));
//最低温度
weatherInfo->forecast[i].temperature_min = (rand() % (51 + (int)weatherInfo->now_temperature)) - 50;
weatherInfo->forecast[i].temperature_min = (weatherInfo->forecast[i].temperature_min) < (-50) ? (-50) : (weatherInfo->forecast[i].temperature_min);
}
}
weatherInfo->forecast[i].date_timestamp = weatherInfo->update_timestamp + (i + 1) * 86400;
}
#endif
cnt++;
}