Merge pull request #8941 from Staars/development

new MQTT presentation for MI-ESP32
This commit is contained in:
Theo Arends 2020-07-20 10:52:41 +02:00 committed by GitHub
commit f40c186e79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 233 additions and 79 deletions

View File

@ -66,14 +66,21 @@ struct {
uint32_t willReadBatt:1; uint32_t willReadBatt:1;
uint32_t shallSetUnit:1; uint32_t shallSetUnit:1;
uint32_t willSetUnit:1; uint32_t willSetUnit:1;
uint32_t shallTriggerTele:1;
uint32_t triggeredTele:1; uint32_t triggeredTele:1;
uint32_t shallClearResults:1; uint32_t shallClearResults:1; // BLE scan results
uint32_t directMQTT:1; // TODO: direct bridging of every single sensor message
} mode; } mode;
struct { struct {
uint8_t sensor; // points to to the number 0...255 uint8_t sensor; // points to to the number 0...255
} state; } state;
struct {
uint32_t allwaysAggregate:1;
uint32_t showRSSI:1;
uint32_t ignoreBogusBattery:1;
uint32_t noSummary:1;
uint32_t minimalSummary:1;
} option;
} MI32; } MI32;
#pragma pack(1) // byte-aligned structures to read the sensor data #pragma pack(1) // byte-aligned structures to read the sensor data
@ -162,8 +169,39 @@ struct mi_sensor_t{
uint8_t lastCnt; //device generated counter of the packet uint8_t lastCnt; //device generated counter of the packet
uint8_t shallSendMQTT; uint8_t shallSendMQTT;
uint8_t MAC[6]; uint8_t MAC[6];
union {
struct {
uint32_t temp:1;
uint32_t hum:1;
uint32_t tempHum:1; //every hum sensor has temp too, easier to use Tasmota dew point functions
uint32_t lux:1;
uint32_t moist:1;
uint32_t fert:1;
uint32_t bat:1;
uint32_t NMT:1;
uint32_t PIR:1;
uint32_t Btn:1;
};
uint32_t raw;
} feature;
union {
struct {
uint32_t temp:1;
uint32_t hum:1;
uint32_t tempHum:1; //can be combined from the sensor
uint32_t lux:1;
uint32_t moist:1;
uint32_t fert:1;
uint32_t bat:1;
uint32_t NMT:1;
uint32_t motion:1;
uint32_t noMotion:1;
uint32_t Btn:1;
};
uint32_t raw;
} eventType;
int rssi; int rssi;
// uint8_t showedUp;
uint32_t lastTime; uint32_t lastTime;
uint32_t lux; uint32_t lux;
float temp; //Flora, MJ_HT_V1, LYWSD0x, CGx float temp; //Flora, MJ_HT_V1, LYWSD0x, CGx
@ -179,7 +217,6 @@ struct mi_sensor_t{
struct { struct {
uint16_t events; //"alarms" since boot uint16_t events; //"alarms" since boot
uint32_t NMT; // no motion time in seconds for the MJYD2S uint32_t NMT; // no motion time in seconds for the MJYD2S
uint8_t eventType; //internal type of actual event for the MJYD2S -> 1: PIR, 2: No PIR, 3: NMT
}; };
uint16_t Btn; uint16_t Btn;
}; };
@ -523,7 +560,8 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_MAC)[6], uint16_t _type, uint8_t counter)
mi_sensor_t _newSensor; mi_sensor_t _newSensor;
memcpy(_newSensor.MAC,_MAC, sizeof(_MAC)); memcpy(_newSensor.MAC,_MAC, sizeof(_MAC));
_newSensor.type = _type; _newSensor.type = _type;
_newSensor.eventType.raw = 0;
_newSensor.feature.raw = 0;
_newSensor.temp =NAN; _newSensor.temp =NAN;
_newSensor.bat=0x00; _newSensor.bat=0x00;
_newSensor.rssi=0xffff; _newSensor.rssi=0xffff;
@ -534,14 +572,34 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_MAC)[6], uint16_t _type, uint8_t counter)
_newSensor.moisture =0xff; _newSensor.moisture =0xff;
_newSensor.fertility =0xffff; _newSensor.fertility =0xffff;
_newSensor.firmware[0]='\0'; _newSensor.firmware[0]='\0';
_newSensor.feature.temp=1;
_newSensor.feature.moist=1;
_newSensor.feature.fert=1;
_newSensor.feature.lux=1;
_newSensor.feature.bat=1;
break; break;
case NLIGHT: case MJYD2S: case NLIGHT:
_newSensor.events=0x00;
_newSensor.feature.PIR=1;
_newSensor.feature.NMT=1;
break;
case MJYD2S:
_newSensor.NMT=0; _newSensor.NMT=0;
_newSensor.events=0x00; _newSensor.events=0x00;
_newSensor.eventType=0x00; _newSensor.feature.PIR=1;
_newSensor.feature.NMT=1;
_newSensor.feature.lux=1;
_newSensor.feature.bat=1;
break;
case YEERC:
_newSensor.feature.Btn=1;
break; break;
default: default:
_newSensor.hum=NAN; _newSensor.hum=NAN;
_newSensor.feature.temp=1;
_newSensor.feature.hum=1;
_newSensor.feature.tempHum=1;
_newSensor.feature.bat=1;
break; break;
} }
MIBLEsensors.push_back(_newSensor); MIBLEsensors.push_back(_newSensor);
@ -554,7 +612,7 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_MAC)[6], uint16_t _type, uint8_t counter)
* *
*/ */
void MI32triggerTele(void){ void MI32triggerTele(void){
MI32.mode.triggeredTele = true; MI32.mode.triggeredTele = 1;
mqtt_data[0] = '\0'; mqtt_data[0] = '\0';
if (MqttShowSensor()) { if (MqttShowSensor()) {
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
@ -576,6 +634,13 @@ void MI32Init(void) {
MI32.mode.init = 1; MI32.mode.init = 1;
MI32.period = Settings.tele_period; MI32.period = Settings.tele_period;
//test section for options
MI32.option.allwaysAggregate = 1;
MI32.option.showRSSI = 1;
MI32.option.ignoreBogusBattery = 1; // from advertisements
MI32.option.noSummary = 0;
MI32.option.minimalSummary = 1;
MI32StartScanTask(); // Let's get started !! MI32StartScanTask(); // Let's get started !!
} }
return; return;
@ -603,7 +668,14 @@ void MI32StartTask(uint32_t task){
break; break;
case MI32_TASK_BATT: case MI32_TASK_BATT:
if (MI32.mode.willReadBatt == 1) return; if (MI32.mode.willReadBatt == 1) return;
MI32StartBatteryTask(); switch(MIBLEsensors[MI32.state.sensor].type) {
case LYWSD03MMC: case MHOC401: // the "original" battery value is crap ...
MI32.mode.willReadBatt = 1;
MI32StartSensorTask(); // ... but the part of the temp/hum-message is good!
break;
default:
MI32StartBatteryTask();
}
break; break;
case MI32_TASK_UNIT: case MI32_TASK_UNIT:
if (MI32.mode.shallSetUnit == 0) return; if (MI32.mode.shallSetUnit == 0) return;
@ -720,6 +792,7 @@ void MI32SensorTask(void *pvParameters){
MI32Client->disconnect(); MI32Client->disconnect();
// NimBLEDevice::deleteClient(MI32Client); // NimBLEDevice::deleteClient(MI32Client);
MI32.mode.willConnect = 0; MI32.mode.willConnect = 0;
MI32.mode.willReadBatt = 0; //could be a "battery task" for LYWSD03MMC or MHO-C401
vTaskDelay(100/ portTICK_PERIOD_MS); vTaskDelay(100/ portTICK_PERIOD_MS);
vTaskDelete( NULL ); vTaskDelete( NULL );
} }
@ -1054,7 +1127,7 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot, uint16_t _bufSize){
// MIBLEsensors[_slot].lastTime = millis(); // MIBLEsensors[_slot].lastTime = millis();
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: MJYD2S secondary PIR")); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: MJYD2S secondary PIR"));
// MIBLEsensors[_slot].NMT = 0; // MIBLEsensors[_slot].NMT = 0;
// MI32triggerTele(); // MI32.mode.shallTriggerTele = 1;
// } // }
} }
break; break;
@ -1067,56 +1140,63 @@ if (MIBLEsensors[_slot].type==NLIGHT){
} }
if(MIBLEsensors[_slot].type==6){ if(MIBLEsensors[_slot].type==6){
DEBUG_SENSOR_LOG(PSTR("LYWSD03 and CGD1 no support for MiBeacon, type %u"),MIBLEsensors[_slot].type); DEBUG_SENSOR_LOG(PSTR("CGD1 no support for MiBeacon, type %u"),MIBLEsensors[_slot].type);
return; return;
} }
AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32DeviceType[MIBLEsensors[_slot].type-1],_slot); AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32DeviceType[MIBLEsensors[_slot].type-1],_slot);
switch(_beacon.type){ switch(_beacon.type){
case 0x01: case 0x01:
MIBLEsensors[_slot].Btn=_beacon.Btn.num + (_beacon.Btn.longPress/2)*6; MIBLEsensors[_slot].Btn=_beacon.Btn.num + (_beacon.Btn.longPress/2)*6;
MIBLEsensors[_slot].shallSendMQTT = 1; MIBLEsensors[_slot].eventType.Btn = 1;
MI32triggerTele();
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 1: U16: %u Button"), MIBLEsensors[_slot].Btn ); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 1: U16: %u Button"), MIBLEsensors[_slot].Btn );
break; break;
case 0x04: case 0x04:
_tempFloat=(float)(_beacon.temp)/10.0f; _tempFloat=(float)(_beacon.temp)/10.0f;
if(_tempFloat<60){ if(_tempFloat<60){
MIBLEsensors[_slot].temp=_tempFloat; MIBLEsensors[_slot].temp=_tempFloat;
DEBUG_SENSOR_LOG(PSTR("Mode 4: temp updated")); MIBLEsensors[_slot].eventType.temp = 1;
DEBUG_SENSOR_LOG(PSTR("Mode 4: temp updated"));
} }
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 4: U16: %u Temp"), _beacon.temp ); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 4: U16: %u Temp"), _beacon.temp );
break; break;
case 0x06: case 0x06:
_tempFloat=(float)(_beacon.hum)/10.0f; _tempFloat=(float)(_beacon.hum)/10.0f;
if(_tempFloat<101){ if(_tempFloat<101){
MIBLEsensors[_slot].hum=_tempFloat; MIBLEsensors[_slot].hum=_tempFloat;
DEBUG_SENSOR_LOG(PSTR("Mode 6: hum updated")); MIBLEsensors[_slot].eventType.hum = 1;
DEBUG_SENSOR_LOG(PSTR("Mode 6: hum updated"));
} }
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 6: U16: %u Hum"), _beacon.hum); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 6: U16: %u Hum"), _beacon.hum);
break; break;
case 0x07: case 0x07:
MIBLEsensors[_slot].lux=_beacon.lux & 0x00ffffff; MIBLEsensors[_slot].lux=_beacon.lux & 0x00ffffff;
if(MIBLEsensors[_slot].type==MJYD2S){ if(MIBLEsensors[_slot].type==MJYD2S){
MIBLEsensors[_slot].eventType = 2; //No PIR MIBLEsensors[_slot].eventType.noMotion = 1;
MIBLEsensors[_slot].shallSendMQTT = 1;
MIBLEsensors[_slot].lastTime = millis();
MI32triggerTele();
} }
MIBLEsensors[_slot].eventType.lux = 1;
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 7: U24: %u Lux"), _beacon.lux & 0x00ffffff); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 7: U24: %u Lux"), _beacon.lux & 0x00ffffff);
break; break;
case 0x08: case 0x08:
MIBLEsensors[_slot].moisture=_beacon.moist; MIBLEsensors[_slot].moisture=_beacon.moist;
DEBUG_SENSOR_LOG(PSTR("Mode 8: moisture updated")); MIBLEsensors[_slot].eventType.moist = 1;
DEBUG_SENSOR_LOG(PSTR("Mode 8: moisture updated"));
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 8: U8: %u Moisture"), _beacon.moist); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 8: U8: %u Moisture"), _beacon.moist);
break; break;
case 0x09: case 0x09:
MIBLEsensors[_slot].fertility=_beacon.fert; MIBLEsensors[_slot].fertility=_beacon.fert;
MIBLEsensors[_slot].eventType.fert = 1;
DEBUG_SENSOR_LOG(PSTR("Mode 9: fertility updated")); DEBUG_SENSOR_LOG(PSTR("Mode 9: fertility updated"));
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 9: U16: %u Fertility"), _beacon.fert); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 9: U16: %u Fertility"), _beacon.fert);
break; break;
case 0x0a: case 0x0a:
if(MI32.option.ignoreBogusBattery){
if(MIBLEsensors[_slot].type==LYWSD03MMC || MIBLEsensors[_slot].type==MHOC401){
break;
}
}
if(_beacon.bat<101){ if(_beacon.bat<101){
MIBLEsensors[_slot].bat = _beacon.bat; MIBLEsensors[_slot].bat = _beacon.bat;
MIBLEsensors[_slot].eventType.bat = 1;
DEBUG_SENSOR_LOG(PSTR("Mode a: bat updated")); DEBUG_SENSOR_LOG(PSTR("Mode a: bat updated"));
} }
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode a: U8: %u %%"), _beacon.bat); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode a: U8: %u %%"), _beacon.bat);
@ -1132,40 +1212,39 @@ if (MIBLEsensors[_slot].type==NLIGHT){
MIBLEsensors[_slot].hum = _tempFloat; MIBLEsensors[_slot].hum = _tempFloat;
DEBUG_SENSOR_LOG(PSTR("Mode d: hum updated")); DEBUG_SENSOR_LOG(PSTR("Mode d: hum updated"));
} }
MIBLEsensors[_slot].eventType.tempHum = 1;
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode d: U16: %x Temp U16: %x Hum"), _beacon.HT.temp, _beacon.HT.hum); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode d: U16: %x Temp U16: %x Hum"), _beacon.HT.temp, _beacon.HT.hum);
break; break;
#ifdef USE_MI_DECRYPTION #ifdef USE_MI_DECRYPTION
case 0x0f: case 0x0f:
if (_beacon.ten!=0) break; if (_beacon.ten!=0) break;
MIBLEsensors[_slot].eventType = 1; //PIR MIBLEsensors[_slot].eventType.motion = 1;
MIBLEsensors[_slot].shallSendMQTT = 1;
MIBLEsensors[_slot].lastTime = millis(); MIBLEsensors[_slot].lastTime = millis();
MIBLEsensors[_slot].events++; MIBLEsensors[_slot].events++;
MIBLEsensors[_slot].lux = _beacon.lux; MIBLEsensors[_slot].lux = _beacon.lux;
MIBLEsensors[_slot].eventType.lux = 1;
MIBLEsensors[_slot].NMT = 0; MIBLEsensors[_slot].NMT = 0;
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("PIR: primary"),MIBLEsensors[_slot].lux ); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("PIR: primary"),MIBLEsensors[_slot].lux );
MI32triggerTele();
break; break;
case 0x17: case 0x17:
MIBLEsensors[_slot].NMT = _beacon.NMT; MIBLEsensors[_slot].NMT = _beacon.NMT;
MIBLEsensors[_slot].eventType = 3; // NMT MIBLEsensors[_slot].eventType.NMT = 1;
MIBLEsensors[_slot].shallSendMQTT = 1;
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 17: NMT: %u seconds"), _beacon.NMT); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 17: NMT: %u seconds"), _beacon.NMT);
MI32triggerTele();
break; break;
#endif //USE_MI_DECRYPTION #endif //USE_MI_DECRYPTION
default: default:
if (MIBLEsensors[_slot].type==NLIGHT){ if (MIBLEsensors[_slot].type==NLIGHT){
MIBLEsensors[_slot].eventType = 1; //PIR MIBLEsensors[_slot].eventType.motion = 1; //PIR
MIBLEsensors[_slot].shallSendMQTT = 1;
MIBLEsensors[_slot].events++; MIBLEsensors[_slot].events++;
MIBLEsensors[_slot].NMT = 0; MIBLEsensors[_slot].NMT = 0;
MIBLEsensors[_slot].lastTime = millis(); MIBLEsensors[_slot].lastTime = millis();
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("PIR: primary"),MIBLEsensors[_slot].lux ); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("PIR: primary"),MIBLEsensors[_slot].lux );
MI32triggerTele();
} }
break; break;
} }
if(MIBLEsensors[_slot].eventType.raw == 0) return;
MIBLEsensors[_slot].shallSendMQTT = 1;
MI32.mode.shallTriggerTele = 1;
} }
void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6], int rssi){ // no MiBeacon void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6], int rssi){ // no MiBeacon
@ -1183,11 +1262,13 @@ void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6], int rssi
_tempFloat=(float)(_packet.temp)/10.0f; _tempFloat=(float)(_packet.temp)/10.0f;
if(_tempFloat<60){ if(_tempFloat<60){
MIBLEsensors.at(_slot).temp = _tempFloat; MIBLEsensors.at(_slot).temp = _tempFloat;
MIBLEsensors[_slot].eventType.temp = 1;
DEBUG_SENSOR_LOG(PSTR("CGD1: temp updated")); DEBUG_SENSOR_LOG(PSTR("CGD1: temp updated"));
} }
_tempFloat=(float)(_packet.hum)/10.0f; _tempFloat=(float)(_packet.hum)/10.0f;
if(_tempFloat<100){ if(_tempFloat<100){
MIBLEsensors.at(_slot).hum = _tempFloat; MIBLEsensors.at(_slot).hum = _tempFloat;
MIBLEsensors[_slot].eventType.hum = 1;
DEBUG_SENSOR_LOG(PSTR("CGD1: hum updated")); DEBUG_SENSOR_LOG(PSTR("CGD1: hum updated"));
} }
DEBUG_SENSOR_LOG(PSTR("CGD1: U16: %x Temp U16: %x Hum"), _packet.temp, _packet.hum); DEBUG_SENSOR_LOG(PSTR("CGD1: U16: %x Temp U16: %x Hum"), _packet.temp, _packet.hum);
@ -1195,12 +1276,16 @@ void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6], int rssi
case 0x0102: case 0x0102:
if(_packet.bat<101){ if(_packet.bat<101){
MIBLEsensors.at(_slot).bat = _packet.bat; MIBLEsensors.at(_slot).bat = _packet.bat;
MIBLEsensors[_slot].eventType.bat = 1;
DEBUG_SENSOR_LOG(PSTR("Mode a: bat updated")); DEBUG_SENSOR_LOG(PSTR("Mode a: bat updated"));
} }
break; break;
default: default:
DEBUG_SENSOR_LOG(PSTR("MI32: unexpected CGD1-packet")); DEBUG_SENSOR_LOG(PSTR("MI32: unexpected CGD1-packet"));
} }
if(MIBLEsensors[_slot].eventType.raw == 0) return;
MIBLEsensors[_slot].shallSendMQTT = 1;
MI32.mode.shallTriggerTele = 1;
} }
void MI32ParseResponse(char *buf, uint16_t bufsize, uint8_t addr[6], int rssi) { void MI32ParseResponse(char *buf, uint16_t bufsize, uint8_t addr[6], int rssi) {
@ -1241,9 +1326,14 @@ void MI32readHT_LY(char *_buf){
MIBLEsensors[_slot].hum = _tempFloat; MIBLEsensors[_slot].hum = _tempFloat;
DEBUG_SENSOR_LOG(PSTR("LYWSD0x: hum updated")); DEBUG_SENSOR_LOG(PSTR("LYWSD0x: hum updated"));
} }
MIBLEsensors[_slot].eventType.tempHum = 1;
if (MIBLEsensors[_slot].type == LYWSD03MMC || MIBLEsensors[_slot].type == MHOC401){ if (MIBLEsensors[_slot].type == LYWSD03MMC || MIBLEsensors[_slot].type == MHOC401){
MIBLEsensors[_slot].bat = ((float)LYWSD0x_HT.volt-2100.0f)/12.0f; MIBLEsensors[_slot].bat = ((float)LYWSD0x_HT.volt-2100.0f)/12.0f;
MI32.mode.willReadBatt = 0;
MIBLEsensors[_slot].eventType.bat = 1;
} }
MIBLEsensors[_slot].shallSendMQTT = 1;
MI32.mode.shallTriggerTele = 1;
} }
} }
@ -1260,12 +1350,27 @@ bool MI32readBat(char *_buf){
MIBLEsensors[_slot].firmware[5] = '\0'; MIBLEsensors[_slot].firmware[5] = '\0';
AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: Firmware: %s"),D_CMND_MI32,MIBLEsensors[_slot].firmware); AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: Firmware: %s"),D_CMND_MI32,MIBLEsensors[_slot].firmware);
} }
return true; MIBLEsensors[_slot].eventType.bat = 1;
MIBLEsensors[_slot].shallSendMQTT = 1;
MI32.mode.shallTriggerTele = 1;
return true;
} }
} }
return false; return false;
} }
/**
* @brief Launch functions from Core 1 to make race conditions less likely
*
*/
void MI32Every50mSecond(){
if(MI32.mode.shallTriggerTele){
MI32.mode.shallTriggerTele = 0;
MI32triggerTele();
}
}
/** /**
* @brief Main loop of the driver, "high level"-loop * @brief Main loop of the driver, "high level"-loop
* *
@ -1473,71 +1578,117 @@ void MI32Show(bool json)
if (json) { if (json) {
if(!MI32.mode.triggeredTele){ if(!MI32.mode.triggeredTele){
MI32.mode.shallClearResults=1; MI32.mode.shallClearResults=1;
if(MI32.option.noSummary) return; // no message at TELEPERIOD
} }
for (uint32_t i = 0; i < MIBLEsensors.size(); i++) {
switch(MIBLEsensors[i].type){
case NLIGHT: case MJYD2S: case YEERC:
if(MIBLEsensors[i].shallSendMQTT==0) continue;
break;
default:
if(MI32.mode.triggeredTele) continue;
break;
}
ResponseAppend_P(PSTR(",\"%s-%02x%02x%02x\":{"), 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;
ResponseAppend_P(PSTR(",\"%s-%02x%02x%02x\":"), // do not add the '{' now ...
kMI32DeviceType[MIBLEsensors[i].type-1], kMI32DeviceType[MIBLEsensors[i].type-1],
MIBLEsensors[i].MAC[3], MIBLEsensors[i].MAC[4], MIBLEsensors[i].MAC[5]); MIBLEsensors[i].MAC[3], MIBLEsensors[i].MAC[4], MIBLEsensors[i].MAC[5]);
ResponseAppend_P(PSTR("\"RSSI\":%d"), MIBLEsensors[i].rssi); uint32_t _positionCurlyBracket = strlen(mqtt_data); // ... this will be a ',' first, but later be replaced
if (MIBLEsensors[i].type == FLORA) { if((!MI32.mode.triggeredTele && !MI32.option.minimalSummary)||MI32.mode.triggeredTele){
if (!isnan(MIBLEsensors[i].temp)) { bool tempHumSended = false;
char temperature[FLOATSZ]; // all sensors have temperature if(MIBLEsensors[i].feature.tempHum){
dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, temperature); if(MIBLEsensors[i].eventType.tempHum || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){
ResponseAppend_P(PSTR(",\"" D_JSON_TEMPERATURE "\":%s"), temperature); if (!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)) {
ResponseAppend_P(PSTR(","));
ResponseAppendTHD(MIBLEsensors[i].temp, MIBLEsensors[i].hum);
tempHumSended = true;
}
}
} }
if (MIBLEsensors[i].lux!=0x0ffffff) { // this is the error code -> no lux if(MIBLEsensors[i].feature.temp && !tempHumSended){
ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux); if(MIBLEsensors[i].eventType.temp || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate) {
if (!isnan(MIBLEsensors[i].temp)) {
char temperature[FLOATSZ];
dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, temperature);
ResponseAppend_P(PSTR(",\"" D_JSON_TEMPERATURE "\":%s"), temperature);
}
}
} }
if (MIBLEsensors[i].moisture!=0xff) { if(MIBLEsensors[i].feature.hum && !tempHumSended){
ResponseAppend_P(PSTR(",\"" D_JSON_MOISTURE "\":%u"), MIBLEsensors[i].moisture); if(MIBLEsensors[i].eventType.hum || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate) {
if (!isnan(MIBLEsensors[i].hum)) {
char hum[FLOATSZ];
dtostrfd(MIBLEsensors[i].hum, Settings.flag2.humidity_resolution, hum);
ResponseAppend_P(PSTR(",\"" D_JSON_HUMIDITY "\":%s"), hum);
}
}
} }
if (MIBLEsensors[i].fertility!=0xffff) { if (MIBLEsensors[i].feature.lux){
ResponseAppend_P(PSTR(",\"Fertility\":%u"), MIBLEsensors[i].fertility); if(MIBLEsensors[i].eventType.lux || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){
if (MIBLEsensors[i].lux!=0x0ffffff) { // this is the error code -> no lux
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){
if (MIBLEsensors[i].moisture!=0xff) {
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){
if (MIBLEsensors[i].fertility!=0xffff) {
ResponseAppend_P(PSTR(",\"Fertility\":%u"), MIBLEsensors[i].fertility);
}
}
}
if (MIBLEsensors[i].feature.Btn){
if(MIBLEsensors[i].eventType.Btn){
ResponseAppend_P(PSTR(",\"Btn\":%u"),MIBLEsensors[i].Btn);
}
}
} // minimal summary
if (MIBLEsensors[i].feature.PIR){
if(MIBLEsensors[i].eventType.motion || !MI32.mode.triggeredTele){
if(MI32.mode.triggeredTele) ResponseAppend_P(PSTR(",\"PIR\":1")); // only real-time
ResponseAppend_P(PSTR(",\"Events\":%u"),MIBLEsensors[i].events);
}
else if(MIBLEsensors[i].eventType.noMotion && MI32.mode.triggeredTele){
ResponseAppend_P(PSTR(",\"PIR\":0"));
}
}
if (MIBLEsensors[i].type == FLORA && !MI32.mode.triggeredTele) {
if (MIBLEsensors[i].firmware[0] != '\0') { // this is the error code -> no firmware if (MIBLEsensors[i].firmware[0] != '\0') { // this is the error code -> no firmware
ResponseAppend_P(PSTR(",\"Firmware\":\"%s\""), MIBLEsensors[i].firmware); ResponseAppend_P(PSTR(",\"Firmware\":\"%s\""), MIBLEsensors[i].firmware);
} }
} }
if (MIBLEsensors[i].type > FLORA){
if (!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)) { if (MIBLEsensors[i].feature.NMT || !MI32.mode.triggeredTele){
ResponseAppend_P(PSTR(",")); if(MIBLEsensors[i].eventType.NMT){
ResponseAppendTHD(MIBLEsensors[i].temp, MIBLEsensors[i].hum); ResponseAppend_P(PSTR(",\"NMT\":%u"), MIBLEsensors[i].NMT);
} }
} }
#ifdef USE_MI_DECRYPTION if (MIBLEsensors[i].feature.bat){
if (MIBLEsensors[i].type == MJYD2S){ if(MIBLEsensors[i].eventType.bat || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){
ResponseAppend_P(PSTR(",\"Events\":%u"),MIBLEsensors[i].events); if (MIBLEsensors[i].bat != 0x00) { // this is the error code -> no battery
if(MIBLEsensors[i].shallSendMQTT && MIBLEsensors[i].eventType<3) ResponseAppend_P(PSTR(",\"PIR\":%u"), 2 - MIBLEsensors[i].eventType); ResponseAppend_P(PSTR(",\"Battery\":%u"), MIBLEsensors[i].bat);
if(MIBLEsensors[i].eventType==3) ResponseAppend_P(PSTR(",\"NMT\":%u"), MIBLEsensors[i].NMT); }
MIBLEsensors[i].eventType=0; }
if(MIBLEsensors[i].lux!=0x0ffffff) ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux);
}
#endif //USE_MI_DECRYPTION
if (MIBLEsensors[i].type == NLIGHT){
ResponseAppend_P(PSTR(",\"Events\":%u"),MIBLEsensors[i].events);
if(MIBLEsensors[i].shallSendMQTT) ResponseAppend_P(PSTR(",\"PIR\":1"));
}
if (MIBLEsensors[i].type == YEERC){
if(MIBLEsensors[i].shallSendMQTT) ResponseAppend_P(PSTR(",\"Btn\":%u"),MIBLEsensors[i].Btn);
}
if (MIBLEsensors[i].bat != 0x00) { // this is the error code -> no battery
ResponseAppend_P(PSTR(",\"Battery\":%u"), MIBLEsensors[i].bat);
} }
if (MI32.option.showRSSI && MI32.mode.triggeredTele) ResponseAppend_P(PSTR(",\"RSSI\":%d"), MIBLEsensors[i].rssi);
if(_positionCurlyBracket==strlen(mqtt_data)) ResponseAppend_P(PSTR(",")); // write some random char, to be overwritten in the next step
ResponseAppend_P(PSTR("}")); ResponseAppend_P(PSTR("}"));
MIBLEsensors[i].shallSendMQTT = 0; mqtt_data[_positionCurlyBracket] = '{';
MI32.mode.triggeredTele = 0; MIBLEsensors[i].eventType.raw = 0;
if(MIBLEsensors[i].shallSendMQTT==1){
MIBLEsensors[i].shallSendMQTT = 0;
break;
}
} }
MI32.mode.triggeredTele = 0;
// ResponseAppend_P(PSTR("}"));
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
} else { } else {
static uint16_t _page = 0; static uint16_t _page = 0;
@ -1618,6 +1769,9 @@ bool Xsns62(uint8_t function)
if (MI32.mode.init) { if (MI32.mode.init) {
switch (function) { switch (function) {
case FUNC_EVERY_50_MSECOND:
MI32Every50mSecond();
break;
case FUNC_EVERY_SECOND: case FUNC_EVERY_SECOND:
MI32EverySecond(false); MI32EverySecond(false);
break; break;