20){ //TODO: Make a choosable timeout later
mi_homekit_update_value(MIBLEsensors[i].motion_hap_service,0.0f,0x0f);
}
#endif //USE_MI_HOMEKIT
}
}
}
/*********************************************************************************************\
* Commands
\*********************************************************************************************/
void CmndMi32Key(void) {
if (44 == XdrvMailbox.data_len || 36 == XdrvMailbox.data_len) { // a KEY-MAC-string
mi_bindKey_t keyMAC;
MI32HexStringToBytes(XdrvMailbox.data,keyMAC.buf);
if(36 == XdrvMailbox.data_len){
memmove(keyMAC.buf + 10, keyMAC.buf + 6, 12);
const uint8_t _fillbytes[4] = {0x8d,0x3d,0x3c,0x97}; // only valid for YLKG08 and YLKG07 ??
memcpy(keyMAC.buf + 6,_fillbytes,4);
AddLogBuffer(LOG_LEVEL_DEBUG,(uint8_t*) keyMAC.buf, 16);
}
MI32AddKey(keyMAC);
ResponseCmndDone();
}
}
void CmndMi32Cfg(void) {
MI32saveConfig();
ResponseCmndDone();
}
void CmndMi32Option(void){
bool onOff = atoi(XdrvMailbox.data);
switch(XdrvMailbox.index) {
case 0:
MI32.option.allwaysAggregate = onOff;
break;
case 1:
MI32.option.noSummary = onOff;
break;
case 2:
MI32.option.directBridgeMode = onOff;
break;
case 3:
MI32.mode.didGetConfig = onOff;
break;
}
ResponseCmndDone();
}
/*********************************************************************************************\
* Presentation
\*********************************************************************************************/
#ifdef USE_MI_EXT_GUI
bool MI32HandleWebGUIResponse(void){
char tmp[16];
WebGetArg(PSTR("wi"), tmp, sizeof(tmp));
if (strlen(tmp)) {
WSContentBegin(200, CT_PLAIN);
if(MI32.widgetSlot==0) {WSContentEnd();return true;}
for(uint32_t i=0;i<32;i++){
if(bitRead(MI32.widgetSlot,i)){
MI32sendWidget(i);
WSContentEnd();
bitClear(MI32.widgetSlot,i);
return true;
}
}
WSContentEnd();
return true;
}
return false;
}
#ifdef USE_MI_ESP32_ENERGY
//https://gist.github.com/LingDong-/7e4c4cae5cbbc44400a05fba65f06f23
// used for logarithmic mapping of 0 - 3600 watts to 0-20 pixel - TaylorLog did not work as expected
float MI32ln(float x) {
unsigned int bx = * (unsigned int *) (&x);
unsigned int ex = bx >> 23;
signed int t = (signed int)ex-(signed int)127;
unsigned int s = (t < 0) ? (-t) : t;
bx = 1065353216 | (bx & 8388607);
x = * (float *) (&bx);
return -1.49278+(2.11263+(-0.729104+0.10969*x)*x)*x+0.6931471806*t;
}
#endif //USE_MI_ESP32_ENERGY
void MI32createPolyline(char *polyline, uint8_t *history){
uint32_t _pos = 0;
uint32_t _inc = 0;
for (uint32_t i = 0; i<24;i++){
uint32_t y = 21-MI32fetchHistory(history,i);
if (y>20){
y = 150; //create a big gap in the graph to represent invalidated data
}
_inc = snprintf_P(polyline+_pos,10,PSTR("%u,%u "),i*6,y);
_pos+=_inc;
}
// AddLog(LOG_LEVEL_DEBUG,PSTR("M32: polyline: %s"),polyline);
}
#ifdef USE_MI_ESP32_ENERGY
void MI32sendEnergyWidget(){
if (Energy.current_available && Energy.voltage_available) {
WSContentSend_P(HTTP_MI32_POWER_WIDGET,MIBLEsensors.size()+1, Energy.voltage,Energy.current[1]);
char _polyline[176];
MI32createPolyline(_polyline,MI32.energy_history);
WSContentSend_P(PSTR("" D_POWERUSAGE ": %.1f " D_UNIT_WATT ""),Energy.active_power);
WSContentSend_P(HTTP_MI32_GRAPH,_polyline,185,124,124,_polyline,1);
WSContentSend_P(PSTR("
"));
}
}
#endif //USE_MI_ESP32_ENERGY
void MI32sendWidget(uint32_t slot){
auto _sensor = MIBLEsensors[slot];
char _MAC[13];
ToHex_P(_sensor.MAC,6,_MAC,13);
uint32_t _opacity = 1;
if(_sensor.RSSI == 0){
_opacity=0;
}
char _key[33] ={0};
if(_sensor.key!=nullptr){
ToHex_P(_sensor.key,16,_key,33);
}
else if(_sensor.feature.needsKey == 1){
snprintf_P(_key,32,PSTR("!! needs key !!"));
_opacity=0;
}
if (_sensor.status.hasWrongKey == 1){
snprintf_P(_key,32,PSTR("!! wrong key !!"));
_opacity=0;
}
if (_sensor.status.isUnbounded == 1){
if(_sensor.type != CGD1){ //only exception atm
snprintf_P(_key,32,PSTR("!! not paired !!"));
_opacity=0;
}
}
char _bat[24];
snprintf_P(_bat,24,PSTR("🔋%u%%"), _sensor.bat);
if(!_sensor.feature.bat) _bat[0] = 0;
if (_sensor.bat == 0) _bat[9] = 0;
WSContentSend_P(HTTP_MI32_WIDGET,slot+1,_opacity,_MAC,_sensor.RSSI,_bat,_key,kMI32DeviceType[_sensor.type-1]);
if(_sensor.feature.tempHum){
if(!isnan(_sensor.temp)){
char _polyline[176];
MI32createPolyline(_polyline,_sensor.temp_history);
WSContentSend_P(PSTR("" D_JSON_TEMPERATURE ": %.1f °C"),_sensor.temp);
WSContentSend_P(HTTP_MI32_GRAPH,_polyline,185,124,124,_polyline,1);
WSContentSend_P(PSTR("
"));
}
if(!isnan(_sensor.hum)){
char _polyline[176];
MI32createPolyline(_polyline,_sensor.hum_history);
WSContentSend_P(PSTR("" D_JSON_HUMIDITY ": %.1f %%"),_sensor.hum);
WSContentSend_P(HTTP_MI32_GRAPH,_polyline,151,190,216,_polyline,2);
WSContentSend_P(PSTR("
"));
}
if(!isnan(_sensor.temp) && !isnan(_sensor.hum)){
WSContentSend_P(PSTR("" D_JSON_DEWPOINT ": %.1f °C"),CalcTempHumToDew(_sensor.temp,_sensor.hum));
}
}
else if(_sensor.feature.temp){
if(!isnan(_sensor.temp)){
char _polyline[176];
MI32createPolyline(_polyline,_sensor.temp_history);
WSContentSend_P(PSTR("" D_JSON_TEMPERATURE ": %.1f °C"),_sensor.temp);
WSContentSend_P(HTTP_MI32_GRAPH,_polyline,185,124,124,_polyline,1);
WSContentSend_P(PSTR("
"));
}
}
if(_sensor.feature.lux){
if(_sensor.lux!=0x00ffffff){
char _polyline[176];
MI32createPolyline(_polyline,_sensor.lux_history);
WSContentSend_P(PSTR("" D_JSON_ILLUMINANCE ": %d Lux"),_sensor.lux);
WSContentSend_P(HTTP_MI32_GRAPH,_polyline,242,240,176,_polyline,3);
WSContentSend_P(PSTR("
"));
}
}
if(_sensor.feature.Btn){
if(_sensor.Btn<12) WSContentSend_P(PSTR("Last Button: %u
"),_sensor.Btn);
}
if(_sensor.feature.motion){
WSContentSend_P(PSTR("Events: %u
"),_sensor.events);
WSContentSend_P(PSTR("No motion for > %u seconds
"),_sensor.NMT);
}
if(_sensor.feature.door){
if(_sensor.door!=255){
if(_sensor.door==1){
WSContentSend_P(PSTR("Contact open
"));
}
else{
WSContentSend_P(PSTR("Contact closed
"));
}
WSContentSend_P(PSTR("Events: %u
"),_sensor.events);
}
}
if(_sensor.feature.leak){
if(_sensor.leak==1){
WSContentSend_P(PSTR("Leak !!!
"));
}
else{
WSContentSend_P(PSTR("no leak
"));
}
}
WSContentSend_P(PSTR(""));
}
void MI32InitGUI(void){
MI32suspendScanTask();
MI32.widgetSlot=0;
WSContentStart_P("m32");
WSContentSend_P(HTTP_MI32_SCRIPT_1);
// WSContentSend_P(HTTP_MI32_SCRIPT_1);
WSContentSendStyle();
WSContentSend_P(HTTP_MI32_STYLE);
WSContentSend_P(HTTP_MI32_STYLE_SVG,1,185,124,124,185,124,124);
WSContentSend_P(HTTP_MI32_STYLE_SVG,2,151,190,216,151,190,216);
WSContentSend_P(HTTP_MI32_STYLE_SVG,3,242,240,176,242,240,176);
#ifdef USE_MI_HOMEKIT
WSContentSend_P((HTTP_MI32_PARENT_START),MIBLEsensors.size(),UpTime(),MI32.hk_setup_code,MI32.HKconnectedControllers,ESP.getFreeHeap()/1024);
#else
const char _setupCode[1] = {0};
WSContentSend_P((HTTP_MI32_PARENT_START),MIBLEsensors.size(),UpTime(),_setupCode,ESP.getFreeHeap()/1024);
#endif //USE_MI_HOMEKIT
for(uint32_t _slot = 0;_slot"));
WSContentSpaceButton(BUTTON_MAIN);
WSContentStop();
vTaskResume(MI32.ScanTask);
}
void MI32HandleWebGUI(void){
if (!HttpCheckPriviledgedAccess()) { return; }
if (MI32HandleWebGUIResponse()) { return; }
MI32InitGUI();
}
#endif //USE_MI_EXT_GUI
const char HTTP_MI32[] PROGMEM = "{s}Mi ESP32 {m} %u devices{e}";
#ifndef USE_MI_EXT_GUI
const char HTTP_BATTERY[] PROGMEM = "{s}%s" " Battery" "{m}%u %%{e}";
const char HTTP_LASTBUTTON[] PROGMEM = "{s}%s Last Button{m}%u {e}";
const char HTTP_EVENTS[] PROGMEM = "{s}%s Events{m}%u {e}";
const char HTTP_NMT[] PROGMEM = "{s}%s No motion{m}> %u seconds{e}";
const char HTTP_DOOR[] PROGMEM = "{s}%s Door{m}> %u open/closed{e}";
const char HTTP_MI32_FLORA_DATA[] PROGMEM = "{s}%s" " Fertility" "{m}%u us/cm{e}";
#endif //USE_MI_EXT_GUI
const char HTTP_MI32_MAC[] PROGMEM = "{s}%s %s{m}%s{e}";
const char HTTP_MI32_HL[] PROGMEM = "{s}
{m}
{e}";
const char HTTP_RSSI[] PROGMEM = "{s}%s " D_RSSI "{m}%d dBm{e}";
void MI32ShowContinuation(bool *commaflg) {
if (*commaflg) {
ResponseAppend_P(PSTR(","));
} else {
*commaflg = true;
}
}
void MI32Show(bool json)
{
if (json) {
#ifdef USE_HOME_ASSISTANT
bool _noSummarySave = MI32.option.noSummary;
bool _minimalSummarySave = MI32.option.minimalSummary;
if(hass_mode==2){
MI32.option.noSummary = false;
MI32.option.minimalSummary = false;
}
#endif //USE_HOME_ASSISTANT
if(!MI32.mode.triggeredTele){
// MI32.mode.shallClearResults=1;
if(MI32.option.noSummary) return; // no message at TELEPERIOD
}
MI32suspendScanTask();
for (uint32_t i = 0; i < MIBLEsensors.size(); i++) {
if(MI32.mode.triggeredTele && MIBLEsensors[i].eventType.raw == 0) continue;
if(MI32.mode.triggeredTele && MIBLEsensors[i].shallSendMQTT==0) continue;
bool commaflg = false;
ResponseAppend_P(PSTR(",\"%s-%02x%02x%02x\":{"),
kMI32DeviceType[MIBLEsensors[i].type-1],
MIBLEsensors[i].MAC[3], MIBLEsensors[i].MAC[4], MIBLEsensors[i].MAC[5]);
if((!MI32.mode.triggeredTele && !MI32.option.minimalSummary)||MI32.mode.triggeredTele){
bool tempHumSended = false;
if(MIBLEsensors[i].feature.tempHum){
if(MIBLEsensors[i].eventType.tempHum || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){
if (!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)
#ifdef USE_HOME_ASSISTANT
||(hass_mode!=-1)
#endif //USE_HOME_ASSISTANT
) {
MI32ShowContinuation(&commaflg);
ResponseAppendTHD(MIBLEsensors[i].temp, MIBLEsensors[i].hum);
tempHumSended = true;
}
}
}
if(MIBLEsensors[i].feature.temp && !tempHumSended){
if(MIBLEsensors[i].eventType.temp || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate) {
if (!isnan(MIBLEsensors[i].temp)
#ifdef USE_HOME_ASSISTANT
||(hass_mode!=-1)
#endif //USE_HOME_ASSISTANT
) {
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%*_f"),
Settings->flag2.temperature_resolution, &MIBLEsensors[i].temp);
}
}
}
if(MIBLEsensors[i].feature.hum && !tempHumSended){
if(MIBLEsensors[i].eventType.hum || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate) {
if (!isnan(MIBLEsensors[i].hum)
#ifdef USE_HOME_ASSISTANT
||(hass_mode!=-1)
#endif //USE_HOME_ASSISTANT
) {
char hum[FLOATSZ];
dtostrfd(MIBLEsensors[i].hum, Settings->flag2.humidity_resolution, hum);
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"" D_JSON_HUMIDITY "\":%s"), hum);
}
}
}
if (MIBLEsensors[i].feature.lux){
if(MIBLEsensors[i].eventType.lux || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){
#ifdef USE_HOME_ASSISTANT
if ((hass_mode != -1) && (MIBLEsensors[i].lux == 0x0ffffff)) {
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"" D_JSON_ILLUMINANCE "\":null"));
} else
#endif //USE_HOME_ASSISTANT
if ((MIBLEsensors[i].lux != 0x0ffffff)
#ifdef USE_HOME_ASSISTANT
|| (hass_mode != -1)
#endif //USE_HOME_ASSISTANT
) { // this is the error code -> no lux
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux);
}
}
}
if (MIBLEsensors[i].feature.moist){
if(MIBLEsensors[i].eventType.moist || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){
#ifdef USE_HOME_ASSISTANT
if ((hass_mode != -1) && (MIBLEsensors[i].moisture == 0xff)) {
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"" D_JSON_MOISTURE "\":null"));
} else
#endif //USE_HOME_ASSISTANT
if ((MIBLEsensors[i].moisture != 0xff)
#ifdef USE_HOME_ASSISTANT
|| (hass_mode != -1)
#endif //USE_HOME_ASSISTANT
) {
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"" D_JSON_MOISTURE "\":%u"), MIBLEsensors[i].moisture);
}
}
}
if (MIBLEsensors[i].feature.fert){
if(MIBLEsensors[i].eventType.fert || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){
#ifdef USE_HOME_ASSISTANT
if ((hass_mode != -1) && (MIBLEsensors[i].fertility == 0xffff)) {
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"Fertility\":null"));
} else
#endif //USE_HOME_ASSISTANT
if ((MIBLEsensors[i].fertility != 0xffff)
#ifdef USE_HOME_ASSISTANT
|| (hass_mode != -1)
#endif //USE_HOME_ASSISTANT
) {
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"Fertility\":%u"), MIBLEsensors[i].fertility);
}
}
}
if (MIBLEsensors[i].feature.Btn){
if(MIBLEsensors[i].eventType.Btn
#ifdef USE_HOME_ASSISTANT
||(hass_mode==2)
#endif //USE_HOME_ASSISTANT
){
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"Btn\":%u"),MIBLEsensors[i].Btn);
}
}
} // minimal summary
if (MIBLEsensors[i].feature.motion){
if(MIBLEsensors[i].eventType.motion || !MI32.mode.triggeredTele){
if(MI32.mode.triggeredTele) {
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"motion\":1")); // only real-time
}
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"Events\":%u"),MIBLEsensors[i].events);
}
else if(MIBLEsensors[i].eventType.noMotion && MI32.mode.triggeredTele){
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"motion\":0"));
}
}
if (MIBLEsensors[i].feature.door){
if(MIBLEsensors[i].eventType.door || !MI32.mode.triggeredTele){
if(MI32.mode.triggeredTele) {
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"DOOR\":%u"),MIBLEsensors[i].door); // only real-time
}
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"Events\":%u"),MIBLEsensors[i].events);
}
}
if (MIBLEsensors[i].type == FLORA && !MI32.mode.triggeredTele) {
if (MIBLEsensors[i].firmware[0] != '\0') { // this is the error code -> no firmware
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"Firmware\":\"%s\""), MIBLEsensors[i].firmware);
}
}
if (MIBLEsensors[i].feature.NMT || !MI32.mode.triggeredTele){
if(MIBLEsensors[i].eventType.NMT){
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"NMT\":%u"), MIBLEsensors[i].NMT);
}
}
if (MIBLEsensors[i].feature.bat){
if(MIBLEsensors[i].eventType.bat || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){
#ifdef USE_HOME_ASSISTANT
if ((hass_mode != -1) && (MIBLEsensors[i].bat == 0x00)) {
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"Battery\":null"));
} else
#endif //USE_HOME_ASSISTANT
if ((MIBLEsensors[i].bat != 0x00)
#ifdef USE_HOME_ASSISTANT
|| (hass_mode != -1)
#endif //USE_HOME_ASSISTANT
) {
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"Battery\":%u"), MIBLEsensors[i].bat);
}
}
}
if (MI32.option.showRSSI) {
MI32ShowContinuation(&commaflg);
ResponseAppend_P(PSTR("\"RSSI\":%d"), MIBLEsensors[i].RSSI);
}
ResponseJsonEnd();
MIBLEsensors[i].eventType.raw = 0;
if(MIBLEsensors[i].shallSendMQTT==1){
MIBLEsensors[i].shallSendMQTT = 0;
continue;
}
}
MI32.mode.triggeredTele = 0;
#ifdef USE_HOME_ASSISTANT
if(hass_mode==2){
MI32.option.noSummary = _noSummarySave;
MI32.option.minimalSummary = _minimalSummarySave;
}
#endif //USE_HOME_ASSISTANT
#ifdef USE_MI_EXT_GUI
Mi32invalidateOldHistory();
#ifdef USE_MI_ESP32_ENERGY
MI32addHistory(MI32.energy_history,Energy.active_power[0],100); //TODO: which value??
#endif //USE_MI_ESP32_ENERGY
#endif //USE_MI_EXT_GUI
vTaskResume(MI32.ScanTask);
#ifdef USE_WEBSERVER
} else {
MI32suspendScanTask();
WSContentSend_P(HTTP_MI32, MIBLEsensors.size());
#ifdef USE_MI_HOMEKIT
if(MI32.mode.didStartHAP){
WSContentSend_PD(PSTR("{s}HomeKit Code{m} %s{e}"),MI32.hk_setup_code);
}
#endif //USE_MI_HOMEKIT
#ifndef USE_MI_EXT_GUI
for (uint32_t i = 0; iFLORA) { // everything "above" Flora
if (!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)) {
WSContentSend_THD(kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].temp, MIBLEsensors[i].hum);
}
}
if (MIBLEsensors[i].feature.needsKey) {
if(MIBLEsensors[i].key == nullptr){
WSContentSend_PD(PSTR("{s}No known Key!!{m} can not decrypt messages{e}"));
}
else if(MIBLEsensors[i].status.hasWrongKey){
WSContentSend_PD(PSTR("{s}Wrong Key!!{m} can not decrypt messages{e}"));
}
}
if (MIBLEsensors[i].type==NLIGHT || MIBLEsensors[i].type==MJYD2S) {
WSContentSend_PD(HTTP_EVENTS, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].events);
if(MIBLEsensors[i].NMT>0) WSContentSend_PD(HTTP_NMT, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].NMT);
}
if(MIBLEsensors[i].door != 255 && MIBLEsensors[i].type==MCCGQ02){
WSContentSend_PD(HTTP_DOOR, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].door);
}
if (MIBLEsensors[i].lux!=0x00ffffff) { // this is the error code -> no valid value
WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].lux);
}
if(MIBLEsensors[i].bat!=0x00){
WSContentSend_PD(HTTP_BATTERY, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].bat);
}
if (MIBLEsensors[i].type==YEERC){
WSContentSend_PD(HTTP_LASTBUTTON, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].Btn);
}
}
#endif //USE_MI_EXT_GUI
#endif // USE_WEBSERVER
}
vTaskResume(MI32.ScanTask);
}
int ExtStopBLE(){
if(Settings->flag5.mi32_enable == 0) return 0;
if (MI32.ScanTask != nullptr){
MI32Scan->stop();
vTaskDelete(MI32.ScanTask);
AddLog(LOG_LEVEL_INFO,PSTR("M32: stop BLE"));
}
#ifdef USE_MI_HOMEKIT
if(MI32.mode.didStartHAP) {
AddLog(LOG_LEVEL_INFO,PSTR("M32: stop Homebridge"));
mi_homekit_stop();
}
#endif //USE_MI_HOMEKIT
return 0;
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
bool Xsns62(uint8_t function)
{
if (!Settings->flag5.mi32_enable) { return false; } // SetOption115 - Enable ESP32 MI32 BLE
bool result = false;
if (FUNC_INIT == function){
MI32PreInit();
}
if (!MI32.mode.init) {
if (function == FUNC_EVERY_250_MSECOND) {
MI32Init();
}
return result;
}
switch (function) {
case FUNC_EVERY_50_MSECOND:
MI32Every50mSecond();
break;
case FUNC_EVERY_SECOND:
MI32EverySecond(false);
break;
case FUNC_SAVE_BEFORE_RESTART:
ExtStopBLE();
break;
case FUNC_COMMAND:
result = DecodeCommand(kMI32_Commands, MI32_Commands);
break;
case FUNC_JSON_APPEND:
MI32Show(1);
break;
#ifdef USE_WEBSERVER
case FUNC_WEB_SENSOR:
MI32Show(0);
break;
#ifdef USE_MI_EXT_GUI
case FUNC_WEB_ADD_MAIN_BUTTON:
if (MI32.mode.didGetConfig) WSContentSend_P(HTTP_BTN_MENU_MI32);
break;
case FUNC_WEB_ADD_HANDLER:
WebServer_on(PSTR("/m32"), MI32HandleWebGUI);
break;
#endif //USE_MI_EXT_GUI
#endif // USE_WEBSERVER
}
return result;
}
#endif // USE_MI_ESP32
#endif // CONFIG_IDF_TARGET_ESP32 or CONFIG_IDF_TARGET_ESP32C3
#endif // ESP32
#endif // USE_BLE_ESP32