基本完成功能,去除了独立升级功能的支持
This commit is contained in:
@ -57,14 +57,23 @@ typedef struct _HFUART
|
||||
}HFUART,*PHFUART;
|
||||
|
||||
|
||||
void HSF_API HF_Debug(int debug_level, const char *format , ... );
|
||||
#if defined(DEBUG_LOG_ENABLE)
|
||||
#define HF_Debug( debug_level, format, ...) printf(format, ##__VA_ARGS__)
|
||||
#else
|
||||
void HSF_API HF_Debug(int debug_level, const char *format, ...);
|
||||
#endif
|
||||
|
||||
#define hfdbg_error(...) HF_Debug(DEBUG_ERROR,"[ %d error %s %d]",hfsys_get_time(),__FUNCTION__,__LINE__); \
|
||||
HF_Debug(DEBUG_ERROR,__VA_ARGS__)
|
||||
#define hfdbg_warn(...) HF_Debug(DEBUG_WARN,"[warnning %d %s %d]",hfsys_get_time(),__FUNCTION__,__LINE__); \
|
||||
HF_Debug(DEBUG_WARN,__VA_ARGS__)
|
||||
#define u_printf(...) HF_Debug(DEBUG_LEVEL_USER,__VA_ARGS__)
|
||||
|
||||
#define e_printf(...) \
|
||||
do { \
|
||||
HF_Debug(DEBUG_WARN, "[Ekko]%d %s():%d: ", hfsys_get_time(), \
|
||||
__FUNCTION__, __LINE__); \
|
||||
HF_Debug(DEBUG_WARN, __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
int hfuart_config(hfuart_handle_t huart, int baudrate, ENCOMPARITY_E parity, ENCOMBITS_E databits, ENCOMSTOPBITS_E stopbits, ENCOMUARTCTL_E fc);
|
||||
|
||||
|
@ -6,12 +6,19 @@ set(COMPONENT_NAME "user_main")
|
||||
|
||||
set(SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/app_main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spotlight/spotlight_main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spotlight/device_module.c
|
||||
)
|
||||
if (DEFINES MATCHES "CONFIG_SPOTLIGHT_UT")
|
||||
list(APPEND SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/spotlight/spotlight_ut.c)
|
||||
endif()
|
||||
|
||||
if (DEFINES MATCHES "HF_MCU_OTA")
|
||||
list(APPEND SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/mcu_update.c)
|
||||
endif()
|
||||
set(PUBLIC_HEADER
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spotlight/
|
||||
)
|
||||
|
||||
set(PRIVATE_HEADER
|
||||
|
@ -11,6 +11,7 @@
|
||||
#ifdef HF_MCU_OTA
|
||||
#include "mcu_update.h"
|
||||
#endif
|
||||
|
||||
int g_module_id = HFM_TYPE_LPT262;
|
||||
const int hf_lpt_262_gpio_fid_to_pid_map_table[HFM_MAX_FUNC_CODE]=
|
||||
{
|
||||
@ -197,15 +198,34 @@ int hf_atcmd_appver(pat_session_t s,int argc,char *argv[],char *rsp,int len)
|
||||
}
|
||||
return -3;
|
||||
}
|
||||
int hf_atcmd_reset(pat_session_t s,int argc,char *argv[],char *rsp,int len)
|
||||
{
|
||||
extern int HILINK_RestoreFactorySettings(void);
|
||||
HILINK_RestoreFactorySettings();
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_SPOTLIGHT_UT
|
||||
extern int hf_atcmd_pwm(pat_session_t s, int argc, char *argv[], char *rsp, int len);
|
||||
extern int hf_atcmd_pwm_query(pat_session_t s, int argc, char *argv[], char *rsp, int len);
|
||||
extern int hf_atcmd_light(pat_session_t s, int argc, char *argv[], char *rsp, int len);
|
||||
extern int hf_atcmd_light_query(pat_session_t s, int argc, char *argv[], char *rsp, int len);
|
||||
#endif
|
||||
const hfat_cmd_t user_define_at_cmds_table[]=
|
||||
{
|
||||
{"APPVER", hf_atcmd_appver, "AT+APPVER: get version. \r\n",NULL},
|
||||
{"RESET", hf_atcmd_reset, "AT+RESET: reset. \r\n",NULL},
|
||||
#ifdef HF_MCU_OTA
|
||||
{"MCUOTA", hf_atcmd_mcu, "AT+MCUOTA: start mcu ota. \r\n",NULL},
|
||||
{"MCUVER", hf_atcmd_mcuver, "AT+MCUVER: get mcu version. \r\n",NULL},
|
||||
{"OTAWAITTIME", hf_atcmd_ota_wait_time, "AT+OTAWAITTIME: set/get uart send mcu ota time\r\n", NULL},
|
||||
#endif
|
||||
{NULL, NULL, NULL, NULL} //the last item must be null
|
||||
#ifdef CONFIG_SPOTLIGHT_UT
|
||||
{"UTPWM", hf_atcmd_pwm, "AT+PWM=<channel>,<duty>: Set PWM duty cycle (0-1000)\r\n", NULL},
|
||||
{"UTLIGHT", hf_atcmd_light, "AT+LIGHT=<brightness>,<cct>: Set brightness(0-1000) and CCT(2700-6000)\r\n", NULL},
|
||||
{"UTPWMQ", NULL, "AT+PWMQ=<channel>,<duty>: Set PWM duty cycle (0-1000)\r\n", hf_atcmd_pwm_query},
|
||||
{"UTLIGHTQ", NULL, "AT+LIGHTQ=<brightness>,<cct>: Set brightness(0-1000) and CCT(2700-6000)\r\n", hf_atcmd_light_query},
|
||||
#endif
|
||||
{NULL, NULL, NULL, NULL} //the last item must be null
|
||||
};
|
||||
|
||||
int USER_FUNC user_app_main(void)
|
||||
@ -220,7 +240,7 @@ int USER_FUNC user_app_main(void)
|
||||
HF_Debug(DEBUG_WARN,"init mcu ota fail!\r\n");
|
||||
#endif
|
||||
//See Wi-Fi Config tools APP for detailed usage of this thread, only debug mode open
|
||||
if(hfdbg_get_level())
|
||||
if(0 && hfdbg_get_level())
|
||||
{
|
||||
while(!hfnet_wifi_is_active())
|
||||
{
|
||||
@ -233,7 +253,6 @@ int USER_FUNC user_app_main(void)
|
||||
}
|
||||
e_printf("start assis success!\r\n");
|
||||
// hfgpio_pwm_enable(HFGPIO_F_SPI_CLK, 1000, 50);
|
||||
spotlight_main();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1,70 +1,296 @@
|
||||
#include "spotlight.h"
|
||||
#include "cJSON.h"
|
||||
|
||||
// 服务处理函数定义
|
||||
typedef int (*handle_put_func)(const char* svc_id, const char* payload, unsigned int len);
|
||||
typedef int (*handle_get_func)(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len);
|
||||
// 服务注册信息定义
|
||||
typedef struct{
|
||||
// service id
|
||||
char* sid;
|
||||
// HILINK_PutCharState cmd function
|
||||
handle_put_func putFunc;
|
||||
// handle HILINK_GetCharState cmd function
|
||||
handle_get_func getFunc;
|
||||
} HANDLE_SVC_INFO;
|
||||
|
||||
#define CHECK_JSON_ITEM(condition) if(condition) { \
|
||||
goto lab_end; \
|
||||
}
|
||||
|
||||
#define MAX_BRIGHTNESS 100
|
||||
#define MIN_BRIGHTNESS 0
|
||||
#define MAX_CCT 6500
|
||||
#define MIN_CCT 2700
|
||||
extern device_control_t g_device_control;
|
||||
|
||||
typedef struct device_control_s {
|
||||
bool on;
|
||||
int32_t colorTemperature;
|
||||
int32_t brightness;
|
||||
} device_control_t;
|
||||
// 场景模式预设值定义
|
||||
typedef struct {
|
||||
int brightness;
|
||||
int cct;
|
||||
} scene_preset_t;
|
||||
|
||||
device_control_t g_device_control = {
|
||||
.on = false,
|
||||
.colorTemperature = MAX_CCT,
|
||||
.brightness = MAX_BRIGHTNESS / 2,
|
||||
static const scene_preset_t scene_presets[] = {
|
||||
{(INIT_STA__BRIGHTNESS), (INIT_STA__CCT)}, // 模式0:非情景模式 配网成功后的默认
|
||||
{(50), (4000)}, // 模式1:休闲模式 - 较低亮度,暖色调
|
||||
{(10), (3000)}, // 模式2:观影模式 - 低亮度,暖色调
|
||||
{(100), (4000)}, // 模式3:用餐模式 - 中等亮度,自然光
|
||||
{(80), (3500)}, // 模式4:回家模式 - 较高亮度,自然光
|
||||
{(100), (CCT_MIN)}, // 模式5:冬天模式 - 中等亮度,暖色调
|
||||
{(100), (CCT_MAX)}, // 模式6:夏天模式 - 较高亮度,冷色调
|
||||
};
|
||||
|
||||
int device_module_control(const char *svcId, const char *payload, unsigned int len)
|
||||
#define SCENE_MODE_COUNT (sizeof(scene_presets) / sizeof(scene_presets[0]))
|
||||
|
||||
// 处理亮度控制
|
||||
static int handle_put_brightness(const char* svc_id, const char* payload, unsigned int len)
|
||||
{
|
||||
if ((svcId == NULL) || (payload == NULL)) {
|
||||
int ret = -1;
|
||||
cJSON *json = cJSON_Parse(payload);
|
||||
if (json == NULL) {
|
||||
return -1;
|
||||
}
|
||||
cJSON *item = NULL;
|
||||
cJSON *json = cJSON_Parse(payload);
|
||||
CHECK_JSON_ITEM(json == NULL);
|
||||
|
||||
e_printf("put char sid:%s,payload:%s\r\n",svcId,payload);
|
||||
if(strcmp(svcId, "brightness") == 0)
|
||||
{
|
||||
item = cJSON_GetObjectItem(json,"brightness");
|
||||
CHECK_JSON_ITEM(item == NULL);
|
||||
CHECK_JSON_ITEM(!cJSON_IsNumber(item));
|
||||
}
|
||||
else if(strcmp(svcId, "cct") == 0)
|
||||
{
|
||||
item = cJSON_GetObjectItem(json,"colorTemperature");
|
||||
CHECK_JSON_ITEM(item == NULL);
|
||||
CHECK_JSON_ITEM(!cJSON_IsNumber(item));
|
||||
} else if(strcmp(svcId, "lightMode") == 0) // scense mode
|
||||
{
|
||||
item = cJSON_GetObjectItem(json,"mode");
|
||||
CHECK_JSON_ITEM(item == NULL);
|
||||
CHECK_JSON_ITEM(!cJSON_IsNumber(item));
|
||||
|
||||
}
|
||||
else if(strcmp(svcId, "switch") == 0) // device open/close
|
||||
{
|
||||
item = cJSON_GetObjectItem(json,"on");
|
||||
CHECK_JSON_ITEM(item == NULL);
|
||||
CHECK_JSON_ITEM(!cJSON_IsNumber(item));
|
||||
}
|
||||
|
||||
lab_end:
|
||||
if(json != NULL)
|
||||
{
|
||||
cJSON *item = cJSON_GetObjectItem(json, JSON_FIELD_BRIGHTNESS);
|
||||
if (item == NULL || !cJSON_IsNumber(item)) {
|
||||
cJSON_Delete(json);
|
||||
json = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int brightness = item->valueint;
|
||||
if (brightness < BRIGHTNESS_MIN) brightness = BRIGHTNESS_MIN;
|
||||
if (brightness > BRIGHTNESS_MAX) brightness = BRIGHTNESS_MAX;
|
||||
|
||||
// g_device_control.brightness_local = brightness;
|
||||
g_device_control.elightMode = LIGHT_MODE_CUSTOMER;
|
||||
ret = set_light(BRIGHTNESS_REMOTE2LOCAL(brightness), -1); // 只更新亮度,色温保持不变
|
||||
|
||||
cJSON_Delete(json);
|
||||
return ret; //异步上报
|
||||
}
|
||||
|
||||
// 处理色温控制
|
||||
static int handle_put_cct(const char* svc_id, const char* payload, unsigned int len)
|
||||
{
|
||||
int ret = -1;
|
||||
cJSON *json = cJSON_Parse(payload);
|
||||
if (json == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cJSON *item = cJSON_GetObjectItem(json, JSON_FIELD_CCT);
|
||||
if (item == NULL || !cJSON_IsNumber(item)) {
|
||||
cJSON_Delete(json);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cct = item->valueint;
|
||||
if (cct < CCT_MIN) cct = CCT_MIN;
|
||||
if (cct > CCT_MAX) cct = CCT_MAX;
|
||||
|
||||
// g_device_control.cct_local = cct;
|
||||
g_device_control.elightMode = LIGHT_MODE_CUSTOMER;
|
||||
ret = set_light(-1, CCT_REMOTE2LOCAL(cct)); // 只更新色温,亮度保持不变
|
||||
|
||||
cJSON_Delete(json);
|
||||
return ret ;//异步上报
|
||||
}
|
||||
|
||||
// 处理场景模式控制
|
||||
static int handle_put_lightMode(const char* svc_id, const char* payload, unsigned int len)
|
||||
{
|
||||
int ret = -1;
|
||||
cJSON *json = cJSON_Parse(payload);
|
||||
if (json == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cJSON *item = cJSON_GetObjectItem(json, JSON_FIELD_MODE);
|
||||
if (item == NULL || !cJSON_IsNumber(item)) {
|
||||
cJSON_Delete(json);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint16_t mode = item->valueint;
|
||||
if (mode >= 0 && mode < SCENE_MODE_COUNT) {
|
||||
g_device_control.elightMode = mode;
|
||||
|
||||
// 同时更新亮度和色温
|
||||
ret = set_light(BRIGHTNESS_REMOTE2LOCAL(scene_presets[mode].brightness), CCT_REMOTE2LOCAL(scene_presets[mode].cct));
|
||||
}
|
||||
|
||||
cJSON_Delete(json);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 处理开关控制
|
||||
static int handle_put_switch(const char* svc_id, const char* payload, unsigned int len)
|
||||
{
|
||||
int ret = -1;
|
||||
cJSON *json = cJSON_Parse(payload);
|
||||
if (json == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cJSON *item = cJSON_GetObjectItem(json, JSON_FIELD_ON);
|
||||
if (item == NULL || !cJSON_IsNumber(item)) {
|
||||
cJSON_Delete(json);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool on = (item->valueint != 0);
|
||||
g_device_control.on = on;
|
||||
ret = set_switch(on);
|
||||
|
||||
cJSON_Delete(json);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 获取亮度状态
|
||||
static int handle_get_brightness(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len)
|
||||
{
|
||||
*out_len = 32;
|
||||
*out = (char*)malloc(*out_len);
|
||||
if (NULL == *out) {
|
||||
return -1;
|
||||
}
|
||||
*out_len = sprintf_s(*out, *out_len, "{\"%s\":%d}", JSON_FIELD_BRIGHTNESS, BRIGHTNESS_LOCAL2REMOTE(g_device_control.brightness_local));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 获取色温状态
|
||||
static int handle_get_cct(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len)
|
||||
{
|
||||
*out_len = 32;
|
||||
*out = (char*)malloc(*out_len);
|
||||
if (NULL == *out) {
|
||||
return -1;
|
||||
}
|
||||
*out_len = sprintf_s(*out, *out_len, "{\"%s\":%d}", JSON_FIELD_CCT, CCT_LOCAL2REMOTE(g_device_control.cct_local));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 获取场景模式状态
|
||||
static int handle_get_lightMode(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len)
|
||||
{
|
||||
*out_len = 32;
|
||||
*out = (char*)malloc(*out_len);
|
||||
if (NULL == *out) {
|
||||
return -1;
|
||||
}
|
||||
*out_len = sprintf_s(*out, *out_len, "{\"%s\":%d}", JSON_FIELD_MODE, g_device_control.elightMode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 获取开关状态
|
||||
static int handle_get_switch(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len)
|
||||
{
|
||||
*out_len = 32;
|
||||
*out = (char*)malloc(*out_len);
|
||||
if (NULL == *out) {
|
||||
return -1;
|
||||
}
|
||||
*out_len = sprintf_s(*out, *out_len, "{\"%s\":%d}", JSON_FIELD_ON, g_device_control.on);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 处理渐变时长控制
|
||||
static int handle_put_smooth_time(const char* svc_id, const char* payload, unsigned int len)
|
||||
{
|
||||
int ret = -1;
|
||||
e_printf("[handle_put_smooth_time] Received smooth time setting request: %s\n", payload);
|
||||
|
||||
cJSON *json = cJSON_Parse(payload);
|
||||
if (json == NULL) {
|
||||
e_printf("[handle_put_smooth_time] JSON parsing failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cJSON *item = cJSON_GetObjectItem(json, JSON_FIELD_FADE_TIME);
|
||||
if (item == NULL || !cJSON_IsNumber(item)) {
|
||||
e_printf("[handle_put_smooth_time] Invalid smooth time parameter\n");
|
||||
cJSON_Delete(json);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int smooth_time = item->valueint;
|
||||
e_printf("[handle_put_smooth_time] Setting smooth time: %d s\n", smooth_time);
|
||||
ret = set_smooth_time(smooth_time);
|
||||
|
||||
cJSON_Delete(json);
|
||||
// e_printf("[handle_put_smooth_time] Smooth time setting completed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 获取渐变时长状态
|
||||
static int handle_get_smooth_time(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len)
|
||||
{
|
||||
*out_len = 32;
|
||||
*out = (char*)malloc(*out_len);
|
||||
if (NULL == *out) {
|
||||
e_printf("[handle_get_smooth_time] Memory allocation failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*out_len = sprintf_s(*out, *out_len, "{\"%s\":%d}", JSON_FIELD_FADE_TIME, g_device_control.fade_time);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 服务处理信息注册
|
||||
HANDLE_SVC_INFO g_device_profile[] = {
|
||||
{SVC_ID_SWITCH, handle_put_switch, handle_get_switch},
|
||||
{SVC_ID_BRIGHTNESS, handle_put_brightness, handle_get_brightness},
|
||||
{SVC_ID_CCT, handle_put_cct, handle_get_cct},
|
||||
{SVC_ID_LIGHT_MODE, handle_put_lightMode, handle_get_lightMode},
|
||||
{SVC_ID_FADE_TIME, handle_put_smooth_time, handle_get_smooth_time},
|
||||
};
|
||||
|
||||
// 服务总数量
|
||||
int g_device_profile_count = sizeof(g_device_profile) / sizeof(HANDLE_SVC_INFO);
|
||||
|
||||
// 辅助函数,用于查找服务注册信息
|
||||
static HANDLE_SVC_INFO* find_handle(const char* svc_id)
|
||||
{
|
||||
for(int i = 0; i < g_device_profile_count; i++) {
|
||||
HANDLE_SVC_INFO handle = g_device_profile[i];
|
||||
if(strcmp(handle.sid, svc_id) == 0) {
|
||||
return &g_device_profile[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 分发设备控制指令
|
||||
int device_module_control(const char* svc_id, const char* payload, unsigned int len)
|
||||
{
|
||||
e_printf("[device_module_control] Received control command: svc_id=%s, payload=%s\n", svc_id, payload);
|
||||
|
||||
HANDLE_SVC_INFO* handle = find_handle(svc_id);
|
||||
if(handle == NULL) {
|
||||
e_printf("[device_module_control] No service handler found\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
handle_put_func function = handle->putFunc;
|
||||
if(function == NULL) {
|
||||
e_printf("[device_module_control] Service handler function is NULL\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = function(svc_id, payload, len);
|
||||
e_printf("[device_module_control] Control command processing completed, return value: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 分发获取状态指令
|
||||
int device_module_get_state(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len)
|
||||
{
|
||||
HANDLE_SVC_INFO* handle = find_handle(svc_id);
|
||||
if(handle == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
handle_get_func function = handle->getFunc;
|
||||
if(function == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return function(svc_id, in, in_len, out, out_len);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2,6 +2,166 @@
|
||||
#define __SPOTLIGHT_H__
|
||||
|
||||
#include <hsf.h>
|
||||
|
||||
typedef enum elightMode {
|
||||
LIGHT_MODE_CUSTOMER = 0, // 非情景模式
|
||||
LIGHT_MODE_RELAX, // 休闲模式
|
||||
LIGHT_MODE_MOVIE, // 观影模式
|
||||
LIGHT_MODE_DINING, // 用餐模式
|
||||
LIGHT_MODE_HOME, // 回家模式
|
||||
LIGHT_MODE_WINTER, // 冬天模式
|
||||
LIGHT_MODE_SUMMER, // 夏天模式
|
||||
LIGHT_MODE_MAX // 模式数量
|
||||
} lightMode_e;
|
||||
|
||||
typedef enum {
|
||||
INIT_POWER_ON,
|
||||
NET_CONFIGING,
|
||||
BIND_OK,
|
||||
}eDeviceBindStatus;
|
||||
|
||||
|
||||
// 服务ID定义
|
||||
#define SVC_ID_SWITCH "switch" // 开关控制
|
||||
#define SVC_ID_BRIGHTNESS "brightness" // 亮度控制
|
||||
#define SVC_ID_CCT "cct" // 色温控制
|
||||
#define SVC_ID_LIGHT_MODE "lightMode" // 场景模式控制
|
||||
#define SVC_ID_FADE_TIME "progressSwitch" // 渐变时长的控制
|
||||
|
||||
// JSON字段名定义
|
||||
#define JSON_FIELD_ON "on" // 开关状态字段
|
||||
#define JSON_FIELD_BRIGHTNESS "brightness" // 亮度字段
|
||||
#define JSON_FIELD_CCT "colorTemperature" // 色温字段
|
||||
#define JSON_FIELD_MODE "mode" // 场景模式字段
|
||||
#define JSON_FIELD_FADE_TIME "fadeTime" // 渐变时长字段
|
||||
|
||||
|
||||
// 当前亮度和色温状态
|
||||
typedef struct {
|
||||
// 物模型同步需要 持久化维持
|
||||
bool on; // 开关状态
|
||||
lightMode_e elightMode;
|
||||
uint16_t brightness_local; // 当前亮度 (0-1000)
|
||||
uint16_t fade_time; // s
|
||||
uint16_t cct_local; // 当前色温 (2700-6500)
|
||||
// 持久化维持
|
||||
int32_t power_on_cnt; // 上电次数计数
|
||||
bool is_networked; // 是否已配网
|
||||
//运行时的数据
|
||||
bool read_done; // 读取数据done
|
||||
uint16_t duty_cw; // 冷白LED占空比
|
||||
uint16_t duty_ww; // 暖白LED占空比
|
||||
} device_control_t;
|
||||
|
||||
// 色温范围定义
|
||||
#define CCT_MIN 2700 // 最小色温 2700K (暖白)
|
||||
#define CCT_MAX 6000 // 最大色温 6000K (冷白)
|
||||
#define CCT_RANGE (CCT_MAX - CCT_MIN)
|
||||
#define CCT_LOCAL_MIN 0 // 最小色温 0K (暖白)
|
||||
#define CCT_LOCAL_MAX (CCT_LOCAL_MIN + CCT_RANGE) // 最大色温 6000K (冷白)
|
||||
#define CCT_LOCAL2REMOTE(x) (x + (CCT_MIN - CCT_LOCAL_MIN))
|
||||
#define CCT_REMOTE2LOCAL(x) (x - (CCT_MIN - CCT_LOCAL_MIN))
|
||||
#define CCT_LITME_RANGE(x) do { \
|
||||
if (x > CCT_LOCAL_MAX) x = CCT_LOCAL_MAX; \
|
||||
if (x < CCT_LOCAL_MIN) x = CCT_LOCAL_MIN; \
|
||||
} while (0)
|
||||
|
||||
// 亮度范围定义
|
||||
#define BRIGHTNESS_MIN 0 // 最小亮度
|
||||
#define BRIGHTNESS_MAX 100 // 最大亮度
|
||||
#define BRIGHTNESS_LOCAL_MIN 0 // 最小亮度
|
||||
#define BRIGHTNESS_LOCAL_MAX 1000 // 最大亮度
|
||||
#define BRIGHTNESS_REMOTE2LOCAL(x) (x * 10) //变化范围0 -1000
|
||||
#define BRIGHTNESS_LOCAL2REMOTE(x) (x / 10)
|
||||
|
||||
#define BRIGHTNESS_LITME_RANGE(x) do { \
|
||||
if (x > BRIGHTNESS_LOCAL_MAX) x = BRIGHTNESS_LOCAL_MAX; \
|
||||
if (x < BRIGHTNESS_LOCAL_MIN) x = BRIGHTNESS_LOCAL_MIN; \
|
||||
} while (0)
|
||||
|
||||
// 设备上电并未进入配网的状态
|
||||
#define INIT_STA__LIGHT_MODE LIGHT_MODE_CUSTOMER
|
||||
#define INIT_STA__BRIGHTNESS 50
|
||||
#define INIT_STA__CCT 4000
|
||||
|
||||
#define INIT_NET_CFG_PWOER_ON_KEEP_TIME (5 * 1000) // 统计进入配网每次打开状态的保持时间
|
||||
|
||||
#define NET_CFG_ENTRY_CNT 6 // 配网进入的上电次数
|
||||
#define NET_CFG_BREATH_DURATION 1*60*1000 // 配网呼吸灯持续时间(ms)
|
||||
#define NET_CFG_TOTAL_TIMEOUT 10*60*1000 // 配网总超时时间(ms)
|
||||
|
||||
// 配网成功后的默认值
|
||||
#define NET_CFG_DEFAULT_BRIGHTNESS 80 // 默认亮度
|
||||
#define NET_CFG_DEFAULT_CCT 6000 // 默认色温
|
||||
#define NET_CFG_DEFAULT_FADE_TIME 1 // 默认渐变时长(s)
|
||||
#define NET_CFG_DEFAULT_LIGHTMODE LIGHT_MODE_CUSTOMER // 默认模式
|
||||
|
||||
// 配网超时后的默认值
|
||||
#define NET_CFG_TIMEOUT_BRIGHTNESS 50 // 呼吸灯超时后的亮度
|
||||
#define NET_CFG_TIMEOUT_CCT 4000 // 呼吸灯超时后的色温
|
||||
|
||||
#define FADE_INTERVAL_MIN (1*1000) //us
|
||||
|
||||
#define PWM_DUTY_RATIO_MAX 1000
|
||||
|
||||
//呼吸灯定义
|
||||
#define BREARTH_PERIOD (3*1000*1000) //呼吸灯周期(Us)
|
||||
#define BREARTH_INTERVAL (3*1000) //更新pwm的间隔 us
|
||||
#define BREARTH_STEP ((PWM_DUTY_RATIO_MAX) * 2) / (BREARTH_PERIOD / BREARTH_INTERVAL) //每次变化的幅度
|
||||
|
||||
|
||||
//渐变范围
|
||||
#define SMOOTH_TIME_MAX 30
|
||||
#define SMOOTH_TIME_MIN 0
|
||||
|
||||
#define SUPPORT_SAVE_TO_FLASH 1
|
||||
|
||||
// 定义Flash存储地址和大小
|
||||
#define DEVICE_DATA_FLASH_ADDR 0x000000 // 主数据区地址
|
||||
#define DEVICE_DATA_BACKUP_ADDR 0x001000 // 备份数据区地址
|
||||
#define DEVICE_DATA_FLASH_SIZE 0x001000 // 使用一个页的大小
|
||||
|
||||
// 设备数据结构
|
||||
typedef struct {
|
||||
uint32_t checksum; // 校验和
|
||||
uint32_t magic; // 魔数,用于验证数据有效性
|
||||
uint32_t version; // 数据版本号
|
||||
device_control_t control; // 设备控制状态
|
||||
} device_data_t;
|
||||
|
||||
#define DEVICE_DATA_MAGIC 0x4C505426 // "LPT&"的ASCII码
|
||||
#define DEVICE_DATA_VERSION 1 // 数据版本号
|
||||
|
||||
int spotlight_main(void);
|
||||
int set_light(int32_t brightness, int32_t cct); // 新的统一控制函数
|
||||
int set_switch(bool open);
|
||||
int set_smooth_time(uint32_t smooth_time); // 设置渐变时长
|
||||
|
||||
extern int fast_report(const char* svc_id);
|
||||
|
||||
// 保存任务相关定义
|
||||
#define SAVE_TASK_PRIO 25
|
||||
#define SAVE_TASK_STACK_SIZE 0x1000
|
||||
#define SAVE_TASK_SLEEP_TIME 100 // 100ms
|
||||
|
||||
// 保存任务状态
|
||||
typedef enum {
|
||||
SAVE_STATE_IDLE = 0, // 空闲状态
|
||||
SAVE_STATE_SAVING, // 正在保存
|
||||
SAVE_STATE_WAITING // 等待保存
|
||||
} save_state_e;
|
||||
|
||||
#define DEFAULT_DEVICE_DATA { \
|
||||
.read_done = false, \
|
||||
.on = true, \
|
||||
.elightMode = INIT_STA__LIGHT_MODE, \
|
||||
.cct_local = CCT_REMOTE2LOCAL(INIT_STA__CCT), \
|
||||
.brightness_local = BRIGHTNESS_REMOTE2LOCAL(INIT_STA__BRIGHTNESS), \
|
||||
.fade_time = NET_CFG_DEFAULT_FADE_TIME, \
|
||||
.is_networked = false, \
|
||||
.duty_cw = 0, \
|
||||
.duty_ww = 0, \
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
116
application/ws63/user_main/spotlight/spotlight_ut.c
Normal file
116
application/ws63/user_main/spotlight/spotlight_ut.c
Normal file
@ -0,0 +1,116 @@
|
||||
#include "hsf.h"
|
||||
#include "spotlight.h"
|
||||
#include "pinctrl.h"
|
||||
#include "gpio.h"
|
||||
#include "pinctrl.h"
|
||||
#include "pwm.h"
|
||||
#include "timer.h"
|
||||
#include "soc_osal.h"
|
||||
#include "systick.h"
|
||||
|
||||
extern device_control_t g_device_control;
|
||||
extern void update_pwm_output(void);
|
||||
extern void calculate_pwm_duty(void);
|
||||
|
||||
// AT指令:设置PWM占空比
|
||||
// 格式:AT+PWM=<channel>,<duty>
|
||||
// channel: 0-冷白LED, 1-暖白LED
|
||||
// duty: 0-1000
|
||||
int hf_atcmd_pwm(pat_session_t s, int argc, char *argv[], char *rsp, int len)
|
||||
{
|
||||
if (argc != 2) {
|
||||
e_printf(rsp, "ERROR: Invalid parameters. Usage: AT+PWM=<channel>,<duty>");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int channel = atoi(argv[0]);
|
||||
int duty = atoi(argv[1]);
|
||||
|
||||
// 参数检查
|
||||
if (channel < 0 || channel > 1) {
|
||||
e_printf(rsp, "ERROR: Invalid channel. Must be 0(CW) or 1(WW)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (duty < 0 || duty > PWM_DUTY_RATIO_MAX) {
|
||||
e_printf(rsp, "ERROR: Invalid duty. Must be 0-%d", PWM_DUTY_RATIO_MAX);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 设置PWM占空比
|
||||
if (channel == 0) {
|
||||
g_device_control.duty_cw = duty;
|
||||
} else {
|
||||
g_device_control.duty_ww = duty;
|
||||
}
|
||||
|
||||
// 更新PWM输出
|
||||
update_pwm_output();
|
||||
|
||||
sprintf(rsp, "OK: Channel %d PWM duty set to %d", channel, duty);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// AT指令:获取当前PWM占空比
|
||||
// 格式:AT+PWM?
|
||||
int hf_atcmd_pwm_query(pat_session_t s, int argc, char *argv[], char *rsp, int len)
|
||||
{
|
||||
sprintf(rsp, "+PWM: CW=%d,WW=%d", g_device_control.duty_cw, g_device_control.duty_ww);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// AT指令:直接设置色温和亮度
|
||||
// 格式:AT+LIGHT=<brightness>,<cct>
|
||||
// brightness: 0-1000
|
||||
// cct: 2700-6500
|
||||
int hf_atcmd_light(pat_session_t s, int argc, char *argv[], char *rsp, int len)
|
||||
{
|
||||
if (argc != 2) {
|
||||
e_printf(rsp, "ERROR: Invalid parameters. Usage: AT+LIGHT=<brightness>,<cct>");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int brightness = atoi(argv[0]);
|
||||
int cct = atoi(argv[1]);
|
||||
|
||||
// 参数检查
|
||||
if (brightness < 0 || brightness > BRIGHTNESS_MAX) {
|
||||
e_printf(rsp, "ERROR: Invalid brightness. Must be 0-%d", BRIGHTNESS_MAX);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cct < CCT_MIN || cct > CCT_MAX) {
|
||||
e_printf(rsp, "ERROR: Invalid CCT. Must be %d-%d", CCT_MIN, CCT_MAX);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 设置亮度和色温
|
||||
g_device_control.brightness_local = BRIGHTNESS_REMOTE2LOCAL(brightness);
|
||||
g_device_control.cct_local = CCT_REMOTE2LOCAL(cct);
|
||||
|
||||
// 计算PWM占空比并更新输出
|
||||
calculate_pwm_duty();
|
||||
update_pwm_output();
|
||||
|
||||
sprintf(rsp, "OK: Brightness=%d, CCT=%d, CW=%d%%%%, WW=%d%%%%",
|
||||
brightness, cct, g_device_control.duty_cw, g_device_control.duty_ww);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// AT指令:获取当前亮度和色温
|
||||
// 格式:AT+LIGHT?
|
||||
int hf_atcmd_light_query(pat_session_t s, int argc, char *argv[], char *rsp, int len)
|
||||
{
|
||||
sprintf(rsp, "+LIGHT: Brightness=%d, CCT=%d, CW=%d, WW=%d",
|
||||
g_device_control.brightness_local,
|
||||
g_device_control.cct_local,
|
||||
g_device_control.duty_cw,
|
||||
g_device_control.duty_ww);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 注册AT指令
|
||||
const hfat_cmd_t spotlight_ut_cmds_table[] = {
|
||||
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
Reference in New Issue
Block a user