mirror of
https://github.com/oopuuu/zTC1.git
synced 2025-12-13 13:38:14 +08:00
358 lines
11 KiB
C
358 lines
11 KiB
C
#include "http_server/web_log.h"
|
||
|
||
#include "main.h"
|
||
#include "user_gpio.h"
|
||
#include "user_wifi.h"
|
||
#include "mqtt_server/user_mqtt_client.h"
|
||
|
||
mico_gpio_t relay[Relay_NUM] = {Relay_0, Relay_1, Relay_2, Relay_3, Relay_4, Relay_5};
|
||
char socket_status[32] = {0};
|
||
char short_click_config[32] = {0};
|
||
char long_click_config[32] = {0};
|
||
|
||
void UserLedSet(char x) {
|
||
if (x == -1)
|
||
MicoGpioOutputTrigger(Led);
|
||
else if (x)
|
||
MicoGpioOutputHigh(Led);
|
||
else
|
||
MicoGpioOutputLow(Led);
|
||
}
|
||
|
||
bool RelayOut(void) {
|
||
int i;
|
||
for (i = 0; i < SOCKET_NUM; i++) {
|
||
if (user_config->socket_status[i] != 0) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
const char *get_func_name(char func_code) {
|
||
static char buffer[32];
|
||
switch (func_code) {
|
||
case SWITCH_ALL_SOCKETS:
|
||
return "Toggle All Sockets";
|
||
case SWITCH_SOCKET_1:
|
||
case SWITCH_SOCKET_2:
|
||
case SWITCH_SOCKET_3:
|
||
case SWITCH_SOCKET_4:
|
||
case SWITCH_SOCKET_5:
|
||
case SWITCH_SOCKET_6:
|
||
sprintf(buffer, "Toggle Socket %d %s", func_code - 1,
|
||
user_config->socket_names[func_code - 1]);
|
||
return buffer;
|
||
case SWITCH_LED_ENABLE:
|
||
return "Toggle LED";
|
||
case REBOOT_SYSTEM:
|
||
return "Reboot";
|
||
case CONFIG_WIFI:
|
||
return "WiFi Config";
|
||
case RESET_SYSTEM:
|
||
return "Factory Reset";
|
||
case -1:
|
||
case NO_FUNCTION:
|
||
return "Unassigned";
|
||
default:
|
||
return "Unknown";
|
||
}
|
||
}
|
||
|
||
/// 针对电源按钮的点击事件
|
||
/// \param index 判断短按(连击)时,代表连击次数,判断长按时代表长按秒数
|
||
/// \param short_func 功能码 在user_gpio.h中定义了
|
||
/// \param long_func 功能码 在user_gpio.h中定义了
|
||
void set_key_map(int index, char short_func, char long_func) {
|
||
user_config->user[index] = ((long_func & 0x0F) << 4) | (short_func & 0x0F);
|
||
}
|
||
|
||
char get_short_func(char val) {
|
||
char func = val & 0x0F;
|
||
return (func == NO_FUNCTION) ? -1 : func; // -1 表示未配置
|
||
}
|
||
|
||
char get_long_func(char val) {
|
||
char func = (val >> 4) & 0x0F;
|
||
return (func == NO_FUNCTION) ? -1 : func; // -1 表示未配置
|
||
}
|
||
|
||
|
||
char *GetSocketStatus() {
|
||
sprintf(socket_status, "%d,%d,%d,%d,%d,%d",
|
||
user_config->socket_status[0],
|
||
user_config->socket_status[1],
|
||
user_config->socket_status[2],
|
||
user_config->socket_status[3],
|
||
user_config->socket_status[4],
|
||
user_config->socket_status[5]);
|
||
return socket_status;
|
||
}
|
||
|
||
char *GetShortClickConfig() {
|
||
sprintf(short_click_config, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
|
||
get_short_func(user_config->user[1]),
|
||
get_short_func(user_config->user[2]),
|
||
get_short_func(user_config->user[3]),
|
||
get_short_func(user_config->user[4]),
|
||
get_short_func(user_config->user[5]),
|
||
get_short_func(user_config->user[6]),
|
||
get_short_func(user_config->user[7]),
|
||
get_short_func(user_config->user[8]),
|
||
get_short_func(user_config->user[9]),
|
||
get_short_func(user_config->user[10]));
|
||
return short_click_config;
|
||
}
|
||
|
||
void SetSocketStatus(char *socket_status) {
|
||
sscanf(socket_status, "%d,%d,%d,%d,%d,%d,",
|
||
(int *) &user_config->socket_status[0],
|
||
(int *) &user_config->socket_status[1],
|
||
(int *) &user_config->socket_status[2],
|
||
(int *) &user_config->socket_status[3],
|
||
(int *) &user_config->socket_status[4],
|
||
(int *) &user_config->socket_status[5]);
|
||
int i = 0;
|
||
for (i = 0; i < SOCKET_NUM; i++) {
|
||
UserRelaySet(i, user_config->socket_status[i]);
|
||
UserMqttSendSocketState(i);
|
||
}
|
||
UserMqttSendTotalSocketState();
|
||
mico_system_context_update(sys_config);
|
||
}
|
||
|
||
/*UserRelaySet
|
||
* 设置继电器开关
|
||
* i:编号 0-5
|
||
* on:开关 0:关 1:开 -1:切换
|
||
*/
|
||
void UserRelaySet(unsigned char i, char on) {
|
||
if (i < 0 || i >= SOCKET_NUM) return;
|
||
|
||
if (on == Relay_ON) {
|
||
MicoGpioOutputHigh(relay[i]);
|
||
} else if (on == Relay_OFF) {
|
||
MicoGpioOutputLow(relay[i]);
|
||
} else if (on == Relay_TOGGLE) {
|
||
if (user_config->socket_status[i] == Relay_OFF) {
|
||
MicoGpioOutputHigh(relay[i]);
|
||
} else {
|
||
MicoGpioOutputLow(relay[i]);
|
||
}
|
||
}
|
||
user_config->socket_status[i] = on >= 0 ? on : (user_config->socket_status[i] == 0 ? 1 : 0);
|
||
|
||
if (RelayOut() && user_config->power_led_enabled) {
|
||
UserLedSet(1);
|
||
} else {
|
||
UserLedSet(0);
|
||
}
|
||
}
|
||
|
||
/*
|
||
* 设置所有继电器开关
|
||
* y: 0:全部关 1:全部开
|
||
*
|
||
*/
|
||
void UserRelaySetAll(char y) {
|
||
int i;
|
||
for (i = 0; i < SOCKET_NUM; i++)
|
||
UserRelaySet(i, y);
|
||
}
|
||
static void KeyEventHandler(int num, boolean longPress) {
|
||
key_log("WARNGIN:Power key %s %d %s", !longPress ? "quick clicked" : "longPressed", num,
|
||
num > 1 ? (longPress ? "seconds" : "times") : (longPress ? "second" : "time"));
|
||
if (num > 30 || num <= 0)
|
||
return;
|
||
int function = !longPress ? get_short_func(user_config->user[num]) : get_long_func(
|
||
user_config->user[num]);key_log("WARNGIN:%s", get_func_name(function));
|
||
switch (function) {
|
||
case SWITCH_ALL_SOCKETS:
|
||
if (RelayOut()) {
|
||
UserRelaySetAll(0);
|
||
} else {
|
||
UserRelaySetAll(1);
|
||
}
|
||
mico_system_context_update(sys_config);
|
||
for (int i = 0; i < SOCKET_NUM; i++) {
|
||
UserMqttSendSocketState(i);
|
||
}
|
||
UserMqttSendTotalSocketState();
|
||
break;
|
||
case SWITCH_SOCKET_1:
|
||
case SWITCH_SOCKET_2:
|
||
case SWITCH_SOCKET_3:
|
||
case SWITCH_SOCKET_4:
|
||
case SWITCH_SOCKET_5:
|
||
case SWITCH_SOCKET_6:
|
||
UserRelaySet(user_config->user[num] - 1, Relay_TOGGLE);
|
||
UserMqttSendSocketState(user_config->user[num] - 1);
|
||
UserMqttSendTotalSocketState();
|
||
mico_system_context_update(sys_config);
|
||
break;
|
||
case SWITCH_LED_ENABLE:
|
||
MQTT_LED_ENABLED = MQTT_LED_ENABLED == 0 ? 1 : 0;
|
||
if (RelayOut() && MQTT_LED_ENABLED) {
|
||
UserLedSet(1);
|
||
} else {
|
||
UserLedSet(0);
|
||
}
|
||
UserMqttSendLedState();
|
||
mico_system_context_update(sys_config);
|
||
break;
|
||
case REBOOT_SYSTEM:
|
||
MicoSystemReboot();
|
||
break;
|
||
case CONFIG_WIFI:
|
||
StartLedBlink(3);
|
||
micoWlanSuspendStation();
|
||
ApInit(true);
|
||
break;
|
||
case RESET_SYSTEM:
|
||
StartLedBlink(8);
|
||
mico_system_context_restore(sys_config);
|
||
mico_rtos_thread_sleep(1);
|
||
MicoSystemReboot();
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
mico_timer_t user_key_timer;
|
||
// 全局静态变量声明
|
||
static uint8_t click_count = 0;
|
||
static mico_timer_t click_end_timer;
|
||
uint16_t key_time = 0;
|
||
|
||
static mico_timer_t led_blink_timer;
|
||
static bool timer_initialized = false;
|
||
|
||
static uint8_t total_blinks = 0;
|
||
static uint8_t blink_counter = 0;
|
||
static bool led_state = false;
|
||
#define BUTTON_LONG_PRESS_TIME 10 //100ms*10=1s
|
||
// 定时器回调
|
||
static void _led_blink_timer_handler(void *arg)
|
||
{
|
||
if (blink_counter >= total_blinks) {
|
||
UserLedSet(0); // 闪烁完成,灭灯
|
||
mico_stop_timer(&led_blink_timer);
|
||
mico_deinit_timer(&led_blink_timer);
|
||
timer_initialized = false;
|
||
return;
|
||
}
|
||
|
||
led_state = !led_state;
|
||
UserLedSet(led_state ? 1 : 0);
|
||
blink_counter++;
|
||
}
|
||
|
||
// 安全重入的启动函数
|
||
void StartLedBlink(uint8_t times)
|
||
{
|
||
if (times == 0) return;
|
||
|
||
// 如果之前已启动,先停止并清理
|
||
if (timer_initialized) {
|
||
mico_stop_timer(&led_blink_timer);
|
||
mico_deinit_timer(&led_blink_timer);
|
||
timer_initialized = false;
|
||
}
|
||
|
||
total_blinks = times * 2;
|
||
blink_counter = 0;
|
||
led_state = false;
|
||
|
||
mico_init_timer(&led_blink_timer, 100, _led_blink_timer_handler, NULL);
|
||
mico_start_timer(&led_blink_timer);
|
||
timer_initialized = true;
|
||
}
|
||
static void ClickEndTimeoutHandler(void *arg) {
|
||
if (click_count <= 0) {
|
||
click_count = 0;
|
||
return;
|
||
}
|
||
KeyEventHandler(click_count,false);
|
||
click_count = 0;
|
||
}
|
||
|
||
static void KeyTimeoutHandler(void *arg) {
|
||
if (childLockEnabled)
|
||
return;
|
||
|
||
static char key_trigger, key_continue;
|
||
static uint8_t key_time = 0;
|
||
|
||
char tmp = ~(0xfe | MicoGpioInputGet(Button));
|
||
key_trigger = tmp & (tmp ^ key_continue);
|
||
key_continue = tmp;
|
||
|
||
if (key_trigger != 0)
|
||
key_time = 0;
|
||
|
||
if (key_continue != 0) {
|
||
key_time++;
|
||
// if (key_time > BUTTON_LONG_PRESS_TIME) {
|
||
// if (key_time == 50) {
|
||
// KeyLong5sPress();
|
||
// } else if (key_time > 50 && key_time < 57) {
|
||
// switch (key_time) {
|
||
// case 51:
|
||
// UserLedSet(1);
|
||
// break;
|
||
// case 52:
|
||
// UserLedSet(0);
|
||
// break;
|
||
// case 53:
|
||
// UserLedSet(1);
|
||
// break;
|
||
// case 54:
|
||
// UserLedSet(0);
|
||
// break;
|
||
// case 55:
|
||
// UserLedSet(1);
|
||
// break;
|
||
// case 56:
|
||
// UserLedSet(0);
|
||
// break;
|
||
// }
|
||
// } else if (key_time == 57) {
|
||
// UserLedSet(RelayOut() && user_config->power_led_enabled);
|
||
// } else if (key_time == 100) {
|
||
// KeyLong10sPress();
|
||
// } else if (key_time == 102) {
|
||
// UserLedSet(1);
|
||
// } else if (key_time == 103) {
|
||
// UserLedSet(0);
|
||
// key_time = 101;
|
||
// }
|
||
// }
|
||
} else {
|
||
if (key_time < BUTTON_LONG_PRESS_TIME) {
|
||
click_count++;
|
||
|
||
// 重启 click_end_timer(300ms)
|
||
mico_rtos_stop_timer(&click_end_timer);
|
||
mico_rtos_start_timer(&click_end_timer);
|
||
} else {
|
||
KeyEventHandler(key_time/10,true);
|
||
}
|
||
|
||
mico_rtos_stop_timer(&user_key_timer);
|
||
}
|
||
}
|
||
|
||
static void KeyFallingIrqHandler(void *arg) {
|
||
mico_rtos_start_timer(&user_key_timer);
|
||
}
|
||
|
||
void KeyInit(void) {
|
||
MicoGpioInitialize(Button, INPUT_PULL_UP);
|
||
mico_rtos_init_timer(&user_key_timer, 100, KeyTimeoutHandler, NULL);
|
||
mico_rtos_init_timer(&click_end_timer, 400, ClickEndTimeoutHandler, NULL);
|
||
MicoGpioEnableIRQ(Button, IRQ_TRIGGER_FALLING_EDGE, KeyFallingIrqHandler, NULL);
|
||
|
||
}
|
||
|