Add command ``SetOption115 1`` to enable ESP32 MiBle

Add command ``SetOption115 1`` to enable ESP32 MiBle
This commit is contained in:
Theo Arends 2020-11-13 17:00:44 +01:00
parent 54fd3d2129
commit 203124d678
6 changed files with 127 additions and 126 deletions

View File

@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
- Commands ``TuyaRGB``, ``TuyaEnum`` and ``TuyaEnumList`` (#9769) - Commands ``TuyaRGB``, ``TuyaEnum`` and ``TuyaEnumList`` (#9769)
- Zigbee command ``ZbInfo`` and prepare support for EEPROM - Zigbee command ``ZbInfo`` and prepare support for EEPROM
- Support for AS608 optical and R503 capacitive fingerprint sensor - Support for AS608 optical and R503 capacitive fingerprint sensor
- Command ``SetOption115 1`` to enable ESP32 MiBle
### Changed ### Changed
- Core library from v2.7.4.5 to v2.7.4.7 - Core library from v2.7.4.5 to v2.7.4.7

View File

@ -58,6 +58,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
## Changelog v9.1.0.1 ## Changelog v9.1.0.1
### Added ### Added
- Command ``SetOption115 1`` to enable ESP32 MiBle
- Commands ``TuyaRGB``, ``TuyaEnum`` and ``TuyaEnumList`` (#9769) - Commands ``TuyaRGB``, ``TuyaEnum`` and ``TuyaEnumList`` (#9769)
- Zigbee command ``ZbInfo`` and prepare support for EEPROM - Zigbee command ``ZbInfo`` and prepare support for EEPROM
- Zigbee support for Mi Door and Contact (#9759) - Zigbee support for Mi Door and Contact (#9759)

View File

@ -139,9 +139,8 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
typedef union { // Restricted by MISRA-C Rule 18.4 but so useful... typedef union { // Restricted by MISRA-C Rule 18.4 but so useful...
uint32_t data; // Allow bit manipulation using SetOption uint32_t data; // Allow bit manipulation using SetOption
struct { // SetOption114 .. SetOption145 struct { // SetOption114 .. SetOption145
uint32_t mqtt_switches : 1; // bit 0 (V9.0.0.3) - SetOption114 - Detach Switches from relays and enable MQTT action state for all the SwitchModes uint32_t mqtt_switches : 1; // bit 0 (v9.0.0.3) - SetOption114 - Detach Switches from relays and enable MQTT action state for all the SwitchModes
//uint32_t spare00 : 1; // bit 0 uint32_t mi32_enable : 1; // bit 1 (v9.1.0.1) - SetOption115 - Enable ESP32 MI32 BLE
uint32_t spare01 : 1; // bit 1
uint32_t spare02 : 1; // bit 2 uint32_t spare02 : 1; // bit 2
uint32_t spare03 : 1; // bit 3 uint32_t spare03 : 1; // bit 3
uint32_t spare04 : 1; // bit 4 uint32_t spare04 : 1; // bit 4

View File

@ -955,6 +955,12 @@ void CmndSetoption(void)
} }
else if (5 == ptype) { // SetOption114 .. 145 else if (5 == ptype) { // SetOption114 .. 145
bitWrite(Settings.flag5.data, pindex, XdrvMailbox.payload); bitWrite(Settings.flag5.data, pindex, XdrvMailbox.payload);
switch (pindex) {
case 1: // SetOption115 - Enable ESP32 MI32
Settings.flag3.sleep_normal = 1; // SetOption60 - Enable normal sleep instead of dynamic sleep
TasmotaGlobal.restart_flag = 2;
break;
}
} }
} else { } else {
ptype = 99; // Command Error ptype = 99; // Command Error

View File

@ -284,11 +284,17 @@ static BLEScan* MI32Scan;
#define D_CMND_MI32 "MI32" #define D_CMND_MI32 "MI32"
const char S_JSON_MI32_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_MI32 "%s\":%d}"; const char kMI32_Commands[] PROGMEM = D_CMND_MI32 "|"
const char S_JSON_MI32_COMMAND[] PROGMEM = "{\"" D_CMND_MI32 "%s%s\"}"; #ifdef USE_MI_DECRYPTION
// const char S_JSON_MI32_BCOMMAND_SVALUE[] PROGMEM = "{\"" D_CMND_MI32 "%s\":%s}"; "Key|"
const char S_JSON_MI32_BCOMMAND_SVALUE[] PROGMEM = "{\"" D_CMND_MI32 "%s%u\":\"%s\"}"; #endif // USE_MI_DECRYPTION
const char kMI32_Commands[] PROGMEM = "Period|Time|Page|Battery|Unit|Key|Beacon"; "Period|Time|Page|Battery|Unit|Beacon";
void (*const MI32_Commands[])(void) PROGMEM = {
#ifdef USE_MI_DECRYPTION
&CmndMi32Key,
#endif // USE_MI_DECRYPTION
&CmndMi32Period, &CmndMi32Time, &CmndMi32Page, &CmndMi32Battery, &CmndMi32Unit, &CmndMi32Beacon };
#define FLORA 1 #define FLORA 1
#define MJ_HT_V1 2 #define MJ_HT_V1 2
@ -763,11 +769,19 @@ void MI32PreInit(void) {
} }
void MI32Init(void) { void MI32Init(void) {
if (MI32.mode.init) return; if (MI32.mode.init) { return; }
if(WiFi.getSleep() == false){
AddLog_P(LOG_LEVEL_DEBUG,PSTR("MI32: WiFi modem not in sleep mode, BLE cannot start yet")); if (TasmotaGlobal.global_state.wifi_down) { return; }
if (WiFi.getSleep() == false) {
// AddLog_P(LOG_LEVEL_DEBUG,PSTR("MI32: WiFi modem not in sleep mode, BLE cannot start yet"));
if (0 == Settings.flag3.sleep_normal) {
AddLog_P(LOG_LEVEL_DEBUG,PSTR("MI32: About to restart to put WiFi modem in sleep mode"));
Settings.flag3.sleep_normal = 1; // SetOption60 - Enable normal sleep instead of dynamic sleep
TasmotaGlobal.restart_flag = 2;
}
return; return;
} }
if (!MI32.mode.init) { if (!MI32.mode.init) {
NimBLEDevice::init(""); NimBLEDevice::init("");
AddLog_P(LOG_LEVEL_INFO,PSTR("MI32: init BLE device")); AddLog_P(LOG_LEVEL_INFO,PSTR("MI32: init BLE device"));
@ -1771,120 +1785,96 @@ void MI32EverySecond(bool restart){
* Commands * Commands
\*********************************************************************************************/ \*********************************************************************************************/
bool MI32Cmd(void) { void CmndMi32Period(void) {
char command[CMDSZ];
bool serviced = true;
uint8_t disp_len = strlen(D_CMND_MI32);
if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_MI32), disp_len)) { // prefix
uint32_t command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + disp_len, kMI32_Commands);
switch (command_code) {
case CMND_MI32_PERIOD:
if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.data_len > 0) {
if (XdrvMailbox.payload==1) { if (1 == XdrvMailbox.payload) {
MI32EverySecond(true); MI32EverySecond(true);
XdrvMailbox.payload = MI32.period; } else {
}
else {
MI32.period = XdrvMailbox.payload; MI32.period = XdrvMailbox.payload;
} }
} }
else { ResponseCmndNumber(MI32.period);
XdrvMailbox.payload = MI32.period; }
}
Response_P(S_JSON_MI32_COMMAND_NVALUE, command, XdrvMailbox.payload); void CmndMi32Time(void) {
break;
case CMND_MI32_TIME:
if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.data_len > 0) {
if(MIBLEsensors.size()>XdrvMailbox.payload){ if (MIBLEsensors.size() > XdrvMailbox.payload) {
if(MIBLEsensors[XdrvMailbox.payload].type == LYWSD02 || MIBLEsensors[XdrvMailbox.payload].type == MHOC303){ if ((LYWSD02 == MIBLEsensors[XdrvMailbox.payload].type) || (MHOC303 == MIBLEsensors[XdrvMailbox.payload].type)) {
AddLog_P(LOG_LEVEL_DEBUG,PSTR("%s: will set Time"),D_CMND_MI32); AddLog_P(LOG_LEVEL_DEBUG, PSTR("MI32: will set Time"));
MI32.state.sensor = XdrvMailbox.payload; MI32.state.sensor = XdrvMailbox.payload;
MI32.mode.canScan = 0; MI32.mode.canScan = 0;
MI32.mode.canConnect = 0; MI32.mode.canConnect = 0;
MI32.mode.shallSetTime = 1; MI32.mode.shallSetTime = 1;
MI32.mode.willSetTime = 0; MI32.mode.willSetTime = 0;
ResponseCmndNumber(XdrvMailbox.payload);
} }
} }
} }
Response_P(S_JSON_MI32_COMMAND_NVALUE, command, XdrvMailbox.payload); }
break;
case CMND_MI32_UNIT: void CmndMi32Page(void) {
if (XdrvMailbox.payload > 0) {
MI32.perPage = XdrvMailbox.payload;
}
ResponseCmndNumber(MI32.perPage);
}
void CmndMi32Battery(void) {
MI32EverySecond(true);
MI32.mode.shallReadBatt = 1;
MI32.mode.canConnect = 1;
ResponseCmndDone();
}
void CmndMi32Unit(void) {
if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.data_len > 0) {
if(MIBLEsensors.size()>XdrvMailbox.payload){ if (MIBLEsensors.size() > XdrvMailbox.payload) {
if(MIBLEsensors[XdrvMailbox.payload].type == LYWSD02 || MIBLEsensors[XdrvMailbox.payload].type == MHOC303){ if ((LYWSD02 == MIBLEsensors[XdrvMailbox.payload].type) || (MHOC303 == MIBLEsensors[XdrvMailbox.payload].type)) {
AddLog_P(LOG_LEVEL_DEBUG,PSTR("%s: will set Unit"),D_CMND_MI32); AddLog_P(LOG_LEVEL_DEBUG,PSTR("MI32: will set Unit"));
MI32.state.sensor = XdrvMailbox.payload; MI32.state.sensor = XdrvMailbox.payload;
MI32.mode.canScan = 0; MI32.mode.canScan = 0;
MI32.mode.canConnect = 0; MI32.mode.canConnect = 0;
MI32.mode.shallSetUnit = 1; MI32.mode.shallSetUnit = 1;
MI32.mode.willSetUnit = 0; MI32.mode.willSetUnit = 0;
ResponseCmndNumber(XdrvMailbox.payload);
} }
} }
} }
Response_P(S_JSON_MI32_COMMAND_NVALUE, command, XdrvMailbox.payload); }
break;
case CMND_MI32_PAGE:
if (XdrvMailbox.data_len > 0) {
if (XdrvMailbox.payload == 0) XdrvMailbox.payload = MI32.perPage; // ignore 0
MI32.perPage = XdrvMailbox.payload;
}
else XdrvMailbox.payload = MI32.perPage;
Response_P(S_JSON_MI32_COMMAND_NVALUE, command, XdrvMailbox.payload);
break;
case CMND_MI32_BATTERY:
MI32EverySecond(true);
MI32.mode.shallReadBatt = 1;
MI32.mode.canConnect = 1;
XdrvMailbox.payload = MI32.period;
Response_P(S_JSON_MI32_COMMAND, command, "");
break;
#ifdef USE_MI_DECRYPTION #ifdef USE_MI_DECRYPTION
case CMND_MI32_KEY: void CmndMi32Key(void) {
if (XdrvMailbox.data_len==44){ // a KEY-MAC-string if (44 == XdrvMailbox.data_len) { // a KEY-MAC-string
MI32AddKey(XdrvMailbox.data); MI32AddKey(XdrvMailbox.data);
Response_P(S_JSON_MI32_COMMAND, command, XdrvMailbox.data); ResponseCmndDone();
} }
break; }
#endif //USE_MI_DECRYPTION #endif // USE_MI_DECRYPTION
case CMND_MI32_BEACON:
void CmndMi32Beacon(void) {
if (XdrvMailbox.data_len == 0) { if (XdrvMailbox.data_len == 0) {
switch(XdrvMailbox.index){ switch (XdrvMailbox.index) {
case 0: case 0:
MI32.state.beaconScanCounter = 8; MI32.state.beaconScanCounter = 8;
Response_P(S_JSON_MI32_BCOMMAND_SVALUE, command, XdrvMailbox.index,PSTR("scanning")); ResponseCmndIdxChar(PSTR("Scanning..."));
break; break;
case 1: case 2: case 3: case 4: case 1: case 2: case 3: case 4:
char _MAC[18]; char _MAC[18];
ToHex_P(MIBLEbeacons[XdrvMailbox.index-1].MAC,6,_MAC,18,':'); ResponseCmndIdxChar(ToHex_P(MIBLEbeacons[XdrvMailbox.index-1].MAC, 6, _MAC, 18, ':'));
Response_P(S_JSON_MI32_BCOMMAND_SVALUE, command, XdrvMailbox.index,_MAC);
break;
}
}
else {
if(XdrvMailbox.data_len == 12 || XdrvMailbox.data_len == 17){ // MAC-string without or with colons
switch(XdrvMailbox.index){
case 1: case 2: case 3: case 4:
MI32addBeacon(XdrvMailbox.index,XdrvMailbox.data);
break;
}
}
Response_P(S_JSON_MI32_BCOMMAND_SVALUE, command, XdrvMailbox.index,XdrvMailbox.data);
}
break;
default:
// else for Unknown command
serviced = false;
break; break;
} }
} else { } else {
return false; if ((12 == XdrvMailbox.data_len) || (17 == XdrvMailbox.data_len)) { // MAC-string without or with colons
switch (XdrvMailbox.index) {
case 1: case 2: case 3: case 4:
MI32addBeacon(XdrvMailbox.index, XdrvMailbox.data);
break;
}
}
ResponseCmndIdxChar(XdrvMailbox.data);
} }
return serviced;
} }
/*********************************************************************************************\ /*********************************************************************************************\
* Presentation * Presentation
\*********************************************************************************************/ \*********************************************************************************************/
@ -2185,13 +2175,16 @@ void MI32Show(bool json)
bool Xsns62(uint8_t function) bool Xsns62(uint8_t function)
{ {
if (!Settings.flag5.mi32_enable) { return false; }
bool result = false; bool result = false;
if (FUNC_INIT == function){ if (FUNC_INIT == function){
MI32PreInit(); MI32PreInit();
} }
if(!MI32.mode.init){ if (!MI32.mode.init) {
if(function==FUNC_EVERY_250_MSECOND){ if (function == FUNC_EVERY_250_MSECOND) {
MI32Init(); MI32Init();
} }
return result; return result;
@ -2204,7 +2197,7 @@ bool Xsns62(uint8_t function)
MI32EverySecond(false); MI32EverySecond(false);
break; break;
case FUNC_COMMAND: case FUNC_COMMAND:
result = MI32Cmd(); result = DecodeCommand(kMI32_Commands, MI32_Commands);
break; break;
case FUNC_JSON_APPEND: case FUNC_JSON_APPEND:
MI32Show(1); MI32Show(1);

View File

@ -169,7 +169,8 @@ a_setoption = [[
"Set dimmer low on rotary dial after power off" "Set dimmer low on rotary dial after power off"
],[ ],[
"Detach Switches from Relays and enable MQTT action state for all the SwitchModes", "Detach Switches from Relays and enable MQTT action state for all the SwitchModes",
"","","", "Enable ESP32 MI32 BLE",
"","",
"","","","", "","","","",
"","","","", "","","","",
"","","","", "","","","",
@ -269,7 +270,7 @@ else:
obj = json.load(fp) obj = json.load(fp)
def StartDecode(): def StartDecode():
print ("\n*** decode-status.py v20201110 by Theo Arends and Jacek Ziolkowski ***") print ("\n*** decode-status.py v20201113 by Theo Arends and Jacek Ziolkowski ***")
# print("Decoding\n{}".format(obj)) # print("Decoding\n{}".format(obj))