mirror of https://github.com/arendst/Tasmota.git
MI sensors - updates to how it deciodes what to display, so that 'unknown' MI devices can display correct data. re-add 'pairing' button.
This commit is contained in:
parent
d84de90b1b
commit
34216db1b4
|
@ -5,6 +5,7 @@
|
|||
|
||||
|
||||
Copyright (C) 2020 Christian Baars and Theo Arends
|
||||
Also Simon Hailes and Robert Klauco
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -23,6 +24,9 @@
|
|||
--------------------------------------------------------------------------------------------
|
||||
Version yyyymmdd Action Description
|
||||
--------------------------------------------------------------------------------------------
|
||||
0.9.2.1 20210217 changed - make features alos depend on received data - i.e. 'unknown' devices will show what they send.
|
||||
Add MI32Option6 1 to switch to tele/tasmota_ble/<somename> style MQTT independent of HASS discovery.
|
||||
-------
|
||||
0.9.2.0 20210127 changed - Officially includes as the mi driver when using USE_BLE_ESP32.
|
||||
-------
|
||||
0.9.1.9 20201226 changed - All change now.
|
||||
|
@ -124,6 +128,7 @@ struct {
|
|||
uint32_t ignoreBogusBattery:1;
|
||||
uint32_t minimalSummary:1; // DEPRECATED!!
|
||||
uint32_t onlyAliased:1; // only include sensors that are aliased
|
||||
uint32_t MQTTType:1;
|
||||
} option;
|
||||
} MI32;
|
||||
|
||||
|
@ -279,6 +284,8 @@ struct mi_sensor_t{
|
|||
uint32_t NMT:1;
|
||||
uint32_t PIR:1;
|
||||
uint32_t Btn:1;
|
||||
uint32_t events:1;
|
||||
uint32_t pairing:1;
|
||||
};
|
||||
uint32_t raw;
|
||||
} feature;
|
||||
|
@ -1409,6 +1416,7 @@ uint32_t MIBLEgetSensorSlot(const uint8_t *mac, uint16_t _type, uint8_t counter)
|
|||
_newSensor.events=0x00;
|
||||
_newSensor.feature.PIR=1;
|
||||
_newSensor.feature.NMT=1;
|
||||
_newSensor.feature.events=1;
|
||||
break;
|
||||
case MI_MJYD2S:
|
||||
_newSensor.NMT=0;
|
||||
|
@ -1417,6 +1425,7 @@ uint32_t MIBLEgetSensorSlot(const uint8_t *mac, uint16_t _type, uint8_t counter)
|
|||
_newSensor.feature.NMT=1;
|
||||
_newSensor.feature.lux=1;
|
||||
_newSensor.feature.bat=1;
|
||||
_newSensor.feature.events=1;
|
||||
break;
|
||||
case MI_YEERC:
|
||||
case MI_DOOR:
|
||||
|
@ -1637,15 +1646,25 @@ int MI32parseMiPayload(int _slot, struct mi_beacon_data_t *parsed){
|
|||
char tmp[20];
|
||||
BLE_ESP32::dump(tmp, 20, (uint8_t*)&(parsed->payload), parsed->payload.size+3);
|
||||
if (BLE_ESP32::BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG_MORE,PSTR("M32: MI%d payload %s"), _slot, tmp);
|
||||
|
||||
// clear this for every payload
|
||||
MIBLEsensors[_slot].pairing = 0;
|
||||
MIBLEsensors[_slot].eventType.PairBtn = 0;
|
||||
|
||||
switch(parsed->payload.type){
|
||||
case 0x01: // button press
|
||||
MIBLEsensors[_slot].Btn = pld->Btn.num + (pld->Btn.longPress/2)*6;
|
||||
MIBLEsensors[_slot].feature.Btn = 1;
|
||||
MIBLEsensors[_slot].eventType.Btn = 1;
|
||||
MI32.mode.shallTriggerTele = 1;
|
||||
MIBLEsensors[_slot].shallSendMQTT = 1;
|
||||
break;
|
||||
case 0x02:
|
||||
res = 0;
|
||||
case 0x02: // related to pair button?
|
||||
MIBLEsensors[_slot].pairing = 1;
|
||||
MIBLEsensors[_slot].eventType.PairBtn = 1;
|
||||
MIBLEsensors[_slot].feature.pairing = 1;
|
||||
MI32.mode.shallTriggerTele = 1;
|
||||
MIBLEsensors[_slot].shallSendMQTT = 1;
|
||||
break;
|
||||
case 0x03: {// motion? 1 byte
|
||||
uint8_t motion = parsed->payload.data[0];
|
||||
|
@ -1655,6 +1674,7 @@ int MI32parseMiPayload(int _slot, struct mi_beacon_data_t *parsed){
|
|||
float _tempFloat=(float)(pld->temp)/10.0f;
|
||||
if(_tempFloat<60){
|
||||
MIBLEsensors[_slot].temp=_tempFloat;
|
||||
MIBLEsensors[_slot].feature.temp = 1;
|
||||
MIBLEsensors[_slot].eventType.temp = 1;
|
||||
if (BLE_ESP32::BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG_MORE,PSTR("M32: Mode 4: temp updated"));
|
||||
} else {
|
||||
|
@ -1666,6 +1686,7 @@ int MI32parseMiPayload(int _slot, struct mi_beacon_data_t *parsed){
|
|||
float _tempFloat=(float)(pld->hum)/10.0f;
|
||||
if(_tempFloat<101){
|
||||
MIBLEsensors[_slot].hum=_tempFloat;
|
||||
MIBLEsensors[_slot].feature.hum = 1;
|
||||
MIBLEsensors[_slot].eventType.hum = 1;
|
||||
if (BLE_ESP32::BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG_MORE,PSTR("M32: Mode 6: hum updated"));
|
||||
} else {
|
||||
|
@ -1679,17 +1700,20 @@ int MI32parseMiPayload(int _slot, struct mi_beacon_data_t *parsed){
|
|||
MIBLEsensors[_slot].eventType.noMotion = 1;
|
||||
}
|
||||
MIBLEsensors[_slot].eventType.lux = 1;
|
||||
MIBLEsensors[_slot].feature.lux = 1;
|
||||
// AddLog(LOG_LEVEL_DEBUG,PSTR("M32: Mode 7: U24: %u Lux"), _beacon.lux & 0x00ffffff);
|
||||
break;
|
||||
case 0x08:
|
||||
MIBLEsensors[_slot].moisture=pld->moist;
|
||||
MIBLEsensors[_slot].eventType.moist = 1;
|
||||
MIBLEsensors[_slot].feature.moist = 1;
|
||||
if (BLE_ESP32::BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG_MORE,PSTR("M32: Mode 8: moisture updated"));
|
||||
// AddLog(LOG_LEVEL_DEBUG,PSTR("M32: Mode 8: U8: %u Moisture"), _beacon.moist);
|
||||
break;
|
||||
case 0x09: // 'conductivity'
|
||||
MIBLEsensors[_slot].fertility=pld->fert;
|
||||
MIBLEsensors[_slot].eventType.fert = 1;
|
||||
MIBLEsensors[_slot].feature.fert = 1;
|
||||
if (BLE_ESP32::BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG_MORE,PSTR("M32: Mode 9: fertility updated"));
|
||||
// AddLog(LOG_LEVEL_DEBUG,PSTR("M32: Mode 9: U16: %u Fertility"), _beacon.fert);
|
||||
break;
|
||||
|
@ -1700,6 +1724,7 @@ int MI32parseMiPayload(int _slot, struct mi_beacon_data_t *parsed){
|
|||
break;
|
||||
}
|
||||
}
|
||||
MIBLEsensors[_slot].feature.bat = 1;
|
||||
if(pld->bat<101){
|
||||
MIBLEsensors[_slot].bat = pld->bat;
|
||||
MIBLEsensors[_slot].eventType.bat = 1;
|
||||
|
@ -1712,6 +1737,7 @@ int MI32parseMiPayload(int _slot, struct mi_beacon_data_t *parsed){
|
|||
// AddLog(LOG_LEVEL_DEBUG,PSTR("M32: Mode a: U8: %u %%"), _beacon.bat);
|
||||
break;
|
||||
case 0x0d:{
|
||||
MIBLEsensors[_slot].feature.tempHum = 1;
|
||||
float _tempFloat=(float)(pld->HT.temp)/10.0f;
|
||||
if(_tempFloat < 60){
|
||||
MIBLEsensors[_slot].temp = _tempFloat;
|
||||
|
@ -1738,6 +1764,11 @@ int MI32parseMiPayload(int _slot, struct mi_beacon_data_t *parsed){
|
|||
MIBLEsensors[_slot].eventType.lux = 1;
|
||||
MIBLEsensors[_slot].NMT = 0;
|
||||
MI32.mode.shallTriggerTele = 1;
|
||||
MIBLEsensors[_slot].shallSendMQTT = 1;
|
||||
MIBLEsensors[_slot].feature.lux = 1;
|
||||
MIBLEsensors[_slot].feature.NMT = 1;
|
||||
MIBLEsensors[_slot].feature.events=1;
|
||||
|
||||
// AddLog(LOG_LEVEL_DEBUG,PSTR("M32: PIR: primary"),MIBLEsensors[_slot].lux );
|
||||
break;
|
||||
case 0x10:{ // 'formaldehide'
|
||||
|
@ -1762,6 +1793,9 @@ int MI32parseMiPayload(int _slot, struct mi_beacon_data_t *parsed){
|
|||
MIBLEsensors[_slot].NMT = pld->NMT;
|
||||
MIBLEsensors[_slot].eventType.NMT = 1;
|
||||
MI32.mode.shallTriggerTele = 1;
|
||||
MIBLEsensors[_slot].shallSendMQTT = 1;
|
||||
MIBLEsensors[_slot].feature.NMT = 1;
|
||||
|
||||
// AddLog(LOG_LEVEL_DEBUG,PSTR("M32: Mode 17: NMT: %u seconds"), _beacon.NMT);
|
||||
} break;
|
||||
|
||||
|
@ -1769,6 +1803,8 @@ int MI32parseMiPayload(int _slot, struct mi_beacon_data_t *parsed){
|
|||
MIBLEsensors[_slot].Btn = uint8_t(parsed->payload.data[0]); // just an 8 bit value in a union.
|
||||
MIBLEsensors[_slot].eventType.Btn = 1;
|
||||
MI32.mode.shallTriggerTele = 1;
|
||||
MIBLEsensors[_slot].shallSendMQTT = 1;
|
||||
MIBLEsensors[_slot].feature.Btn = 1;
|
||||
} break;
|
||||
|
||||
default: {
|
||||
|
@ -1904,10 +1940,12 @@ void MI32EverySecond(bool restart){
|
|||
// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("M32: onesec"));
|
||||
MI32TimeoutSensors();
|
||||
|
||||
MI32ShowSomeSensors();
|
||||
|
||||
MI32DiscoveryOneMISensor();
|
||||
MI32ShowOneMISensor();
|
||||
if (MI32.option.MQTTType == 0){
|
||||
MI32ShowSomeSensors();
|
||||
} else {
|
||||
MI32DiscoveryOneMISensor();
|
||||
MI32ShowOneMISensor();
|
||||
}
|
||||
|
||||
// read a battery if
|
||||
// MI32.batteryreader.slot < filled and !MI32.batteryreader.active
|
||||
|
@ -2132,16 +2170,24 @@ void CmndMi32Option(void){
|
|||
bool onOff = atoi(XdrvMailbox.data);
|
||||
switch(XdrvMailbox.index) {
|
||||
case 0:
|
||||
MI32.option.allwaysAggregate = onOff;
|
||||
MI32.option.allwaysAggregate = onOff;
|
||||
ResponseCmndNumber(onOff);
|
||||
return;
|
||||
break;
|
||||
case 1:
|
||||
MI32.option.noSummary = onOff;
|
||||
ResponseCmndNumber(onOff);
|
||||
return;
|
||||
break;
|
||||
case 2:
|
||||
MI32.option.directBridgeMode = onOff;
|
||||
ResponseCmndNumber(onOff);
|
||||
return;
|
||||
break;
|
||||
case 4:{
|
||||
MI32.option.ignoreBogusBattery = onOff;
|
||||
ResponseCmndNumber(onOff);
|
||||
return;
|
||||
} break;
|
||||
case 5:{
|
||||
MI32.option.onlyAliased = onOff;
|
||||
|
@ -2149,7 +2195,15 @@ void CmndMi32Option(void){
|
|||
// discard all sensors for a restart
|
||||
MIBLEsensors.clear();
|
||||
}
|
||||
ResponseCmndNumber(onOff);
|
||||
return;
|
||||
} break;
|
||||
case 6:{
|
||||
MI32.option.MQTTType = onOff;
|
||||
ResponseCmndNumber(onOff);
|
||||
return;
|
||||
} break;
|
||||
|
||||
}
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
@ -2249,7 +2303,7 @@ void CmndMi32Keys(void){
|
|||
* Presentation
|
||||
\*********************************************************************************************/
|
||||
|
||||
const char HTTP_MI32[] PROGMEM = "{s}MI ESP32 v0920{m}%u%s / %u{e}";
|
||||
const char HTTP_MI32[] PROGMEM = "{s}MI ESP32 v0921{m}%u%s / %u{e}";
|
||||
const char HTTP_MI32_ALIAS[] PROGMEM = "{s}%s Alias {m}%s{e}";
|
||||
const char HTTP_MI32_MAC[] PROGMEM = "{s}%s %s{m}%s{e}";
|
||||
const char HTTP_RSSI[] PROGMEM = "{s}%s " D_RSSI "{m}%d dBm{e}";
|
||||
|
@ -2527,9 +2581,13 @@ void MI32ShowSomeSensors(){
|
|||
|
||||
ResponseTime_P(PSTR(""));
|
||||
int cnt = 0;
|
||||
for (; (MI32.mqttCurrentSlot < numsensors) && (cnt < 4); MI32.mqttCurrentSlot++, cnt++) {
|
||||
int maxcnt = 4;
|
||||
mi_sensor_t *p;
|
||||
for (; (MI32.mqttCurrentSlot < numsensors) && (cnt < maxcnt); MI32.mqttCurrentSlot++, cnt++) {
|
||||
ResponseAppend_P(PSTR(","));
|
||||
MI32GetOneSensorJson(MI32.mqttCurrentSlot, 0);
|
||||
p = &MIBLEsensors[MI32.mqttCurrentSlot];
|
||||
|
||||
MI32GetOneSensorJson(MI32.mqttCurrentSlot, (maxcnt == 1));
|
||||
int mlen = strlen(TasmotaGlobal.mqtt_data);
|
||||
|
||||
// if we ran out of room, leave here.
|
||||
|
@ -2537,6 +2595,7 @@ void MI32ShowSomeSensors(){
|
|||
MI32.mqttCurrentSlot++;
|
||||
break;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
ResponseAppend_P(PSTR("}"));
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
|
||||
|
@ -2567,8 +2626,13 @@ void MI32ShowOneMISensor(){
|
|||
return;
|
||||
}
|
||||
|
||||
if(
|
||||
#ifdef USE_HOME_ASSISTANT
|
||||
if(Settings.flag.hass_discovery){
|
||||
Settings.flag.hass_discovery
|
||||
||
|
||||
#endif //USE_HOME_ASSISTANT
|
||||
MI32.option.MQTTType == 1
|
||||
){
|
||||
|
||||
ResponseTime_P(PSTR(","));
|
||||
MI32GetOneSensorJson(MI32.mqttCurrentSingleSlot, 1);
|
||||
|
@ -2594,7 +2658,6 @@ void MI32ShowOneMISensor(){
|
|||
MqttPublish(SensorTopic);
|
||||
//AddLog_P(LOG_LEVEL_DEBUG,PSTR("M32: %s: show some %d %s"),D_CMND_MI32, MI32.mqttCurrentSlot, TasmotaGlobal.mqtt_data);
|
||||
}
|
||||
#endif //USE_HOME_ASSISTANT
|
||||
MI32.mqttCurrentSingleSlot++;
|
||||
}
|
||||
|
||||
|
@ -2749,11 +2812,23 @@ void MI32ShowTriggeredSensors(){
|
|||
|
||||
int sensor = 0;
|
||||
|
||||
int maxcnt = 4;
|
||||
if(
|
||||
#ifdef USE_HOME_ASSISTANT
|
||||
Settings.flag.hass_discovery
|
||||
||
|
||||
#endif //USE_HOME_ASSISTANT
|
||||
MI32.option.MQTTType == 1
|
||||
){
|
||||
maxcnt = 1;
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
ResponseTime_P(PSTR(""));
|
||||
int cnt = 0;
|
||||
for (; (sensor < numsensors) && (cnt < 4); sensor++) {
|
||||
mi_sensor_t *p;
|
||||
mi_sensor_t *p;
|
||||
for (; (sensor < numsensors) && (cnt < maxcnt); sensor++) {
|
||||
p = &MIBLEsensors[sensor];
|
||||
if(p->eventType.raw == 0) continue;
|
||||
if(p->shallSendMQTT==0) continue;
|
||||
|
@ -2771,7 +2846,30 @@ void MI32ShowTriggeredSensors(){
|
|||
}
|
||||
if (cnt){ // if we got one, then publish
|
||||
ResponseAppend_P(PSTR("}"));
|
||||
MqttPublishPrefixTopic_P(STAT, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
|
||||
if(
|
||||
#ifdef USE_HOME_ASSISTANT
|
||||
Settings.flag.hass_discovery
|
||||
||
|
||||
#endif //USE_HOME_ASSISTANT
|
||||
MI32.option.MQTTType == 1
|
||||
){
|
||||
char SensorTopic[60];
|
||||
char idstr[32];
|
||||
const char *alias = BLE_ESP32::getAlias(p->MAC);
|
||||
const char *id = idstr;
|
||||
if (alias && *alias){
|
||||
id = alias;
|
||||
} else {
|
||||
sprintf(idstr, PSTR("%s%02x%02x%02x"),
|
||||
kMI32DeviceType[p->type-1],
|
||||
p->MAC[3], p->MAC[4], p->MAC[5]);
|
||||
}
|
||||
sprintf(SensorTopic, "tele/tasmota_ble/%s",
|
||||
id);
|
||||
MqttPublish(SensorTopic);
|
||||
} else {
|
||||
MqttPublishPrefixTopic_P(STAT, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
|
||||
}
|
||||
AddLog(LOG_LEVEL_DEBUG,PSTR("M32: %s: triggered %d %s"),D_CMND_MI32, sensor, TasmotaGlobal.mqtt_data);
|
||||
|
||||
#ifdef USE_RULES
|
||||
|
@ -2887,21 +2985,25 @@ void MI32Show(bool json)
|
|||
WSContentSend_PD(HTTP_NEEDKEY, typeName, _MAC, Webserver->client().localIP().toString().c_str(), tmp );
|
||||
}
|
||||
|
||||
if (p->type==MI_NLIGHT || p->type==MI_MJYD2S) {
|
||||
#else
|
||||
if (p->type==MI_NLIGHT) {
|
||||
#endif //USE_MI_DECRYPTION
|
||||
|
||||
if (p->feature.events){
|
||||
WSContentSend_PD(HTTP_EVENTS, typeName, p->events);
|
||||
}
|
||||
if (p->feature.NMT){
|
||||
// no motion time
|
||||
if(p->NMT>0) WSContentSend_PD(HTTP_NMT, typeName, p->NMT);
|
||||
}
|
||||
|
||||
if (p->lux!=0x00ffffff) { // this is the error code -> no valid value
|
||||
WSContentSend_PD(HTTP_SNS_ILLUMINANCE, typeName, p->lux);
|
||||
if (p->feature.lux){
|
||||
if (p->lux!=0x00ffffff) { // this is the error code -> no valid value
|
||||
WSContentSend_PD(HTTP_SNS_ILLUMINANCE, typeName, p->lux);
|
||||
}
|
||||
}
|
||||
if(p->bat!=0x00){
|
||||
WSContentSend_PD(HTTP_BATTERY, typeName, p->bat);
|
||||
}
|
||||
if (p->type==MI_YEERC || p->type==MI_DOOR){
|
||||
if (p->feature.Btn){
|
||||
WSContentSend_PD(HTTP_LASTBUTTON, typeName, p->Btn);
|
||||
}
|
||||
if (p->pairing){
|
||||
|
|
Loading…
Reference in New Issue