dynamic sensor discovery

This commit is contained in:
Staars 2020-02-02 17:44:26 +01:00
parent cb067237ad
commit b64abc9757
1 changed files with 130 additions and 74 deletions

View File

@ -70,26 +70,20 @@ struct {
#pragma pack(0) #pragma pack(0)
struct mi_sensor_t{ struct mi_sensor_t{
uint8_t type; //flora = 1; MI-HT_V1=2; LYWSD02=3; LYWSD03=4 uint8_t type; //Flora = 1; MI-HT_V1=2; LYWSD02=3; LYWSD03=4
uint8_t serial[6]; uint8_t serial[6];
uint8_t showedUp; uint8_t showedUp;
float temp; //Flora, MJ_HT_V1, LYWSD0x
union { union {
struct { struct {
float temp;
float moisture; float moisture;
float fertility; float fertility;
uint16_t lux; uint16_t lux;
} Flora; }; // Flora
struct { struct {
float temp;
float hum; float hum;
uint8_t bat; uint8_t bat;
} MJ_HT_V1; }; // MJ_HT_V1, LYWSD0x
struct {
float temp;
float hum;
uint8_t bat;
} LYWSD0x; // LYWSD02 and LYWSD03
}; };
}; };
@ -101,24 +95,21 @@ std::vector<mi_sensor_t> MIBLEsensors;
#define D_CMND_HM10 "HM10" #define D_CMND_HM10 "HM10"
// const char S_JSON_HM10_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_HM10 "%s\":%d}"; uint8_t kHM10SlaveID[4][3] = { 0xC4,0x7C,0x8D, // Flora
// const char S_JSON_HM10_COMMAND[] PROGMEM = "{\"" D_CMND_HM10 "%s\"}"; 0x58,0x2D,0x34, // MJ_HT_V1
// const char kHM10_Commands[] PROGMEM = "Track|Play"; 0xE7,0x2E,0x00, // LYWSD02
0xA4,0xC1,0x38, // LYWSD03
};
const char kHM10SlaveID0[] PROGMEM = ""; const char kHM10SlaveType1[] PROGMEM = "Flora";
const char kHM10SlaveID1[] PROGMEM = ""; const char kHM10SlaveType2[] PROGMEM = "MJ_HT_V1";
const char kHM10SlaveID2[] PROGMEM = ""; const char kHM10SlaveType3[] PROGMEM = "LYWSD02";
const char kHM10SlaveID3[] PROGMEM = ""; const char kHM10SlaveType4[] PROGMEM = "LYWSD03";
const char kHM10SlaveID4[] PROGMEM = "A4C138"; const char * kHM10SlaveType[] PROGMEM = {kHM10SlaveType1,kHM10SlaveType2,kHM10SlaveType3,kHM10SlaveType4};
const char * kHM10SlaveID[] PROGMEM = {kHM10SlaveID0,kHM10SlaveID1,kHM10SlaveID2,kHM10SlaveID3,kHM10SlaveID4};
// const char kHM10Mac0[] PROGMEM = "A4C138ED815A"; // uint8_t HM10Mac[2][6]={0xA4,0xC1,0x38,0xED,0x81,0x5A,
// const char kHM10Mac1[] PROGMEM = "A4C1382AC8B3"; // 0xA4,0xC1,0x38,0x2A,0xC8,0xB3};
// const char * kHM10Mac[] PROGMEM ={kHM10Mac0, kHM10Mac1};
uint8_t HM10Mac[2][6]={0xA4,0xC1,0x38,0xED,0x81,0x5A,
0xA4,0xC1,0x38,0x2A,0xC8,0xB3};
/*********************************************************************************************\ /*********************************************************************************************\
* enumerations * enumerations
@ -179,7 +170,7 @@ void HM10_Reset(void) { HM10_Launchtask(TASK_HM10_DISCONN,0,1); // discon
HM10_Launchtask(TASK_HM10_IMME1,2,1); // set imme to 1 HM10_Launchtask(TASK_HM10_IMME1,2,1); // set imme to 1
HM10_Launchtask(TASK_HM10_RESET,3,1); // reset Device HM10_Launchtask(TASK_HM10_RESET,3,1); // reset Device
HM10_Launchtask(TASK_HM10_VERSION,4,10); // read SW Version HM10_Launchtask(TASK_HM10_VERSION,4,10); // read SW Version
HM10_Launchtask(TASK_HM10_DISC,5,1); // disscovery HM10_Launchtask(TASK_HM10_DISC,5,50); // discovery
} }
void HM10_Read_Sensor(void) { void HM10_Read_Sensor(void) {
@ -206,10 +197,24 @@ void HM10_Read_Sensor1(void) {
* @brief Return the slot number of a known sensor or return create new sensor slot * @brief Return the slot number of a known sensor or return create new sensor slot
* *
* @param _serial BLE address of the sensor * @param _serial BLE address of the sensor
* @param _type Type number of the sensor * @param _type Type number of the sensor, 0xff for Auto-type
* @return uint32_t Known or new slot in the sensors-vector * @return uint32_t Known or new slot in the sensors-vector
*/ */
uint32_t MIBLEgetSensorSlot(uint8_t (&_serial)[6], uint8_t _type){ uint32_t MIBLEgetSensorSlot(uint8_t (&_serial)[6], uint8_t _type){
if(_type==0xff){
DEBUG_SENSOR_LOG(PSTR("MIBLE: will test MAC-type"));
for (uint32_t i=0;i<4;i++){
if(memcmp(_serial,kHM10SlaveID+i,3)==0){
DEBUG_SENSOR_LOG(PSTR("MIBLE: MAC is type %u"), i);
_type = i+1;
}
else {
DEBUG_SENSOR_LOG(PSTR("MIBLE: MAC-type is unknown"));
}
}
}
if(_type==0xff) return _type; // error
DEBUG_SENSOR_LOG(PSTR("MIBLE: vector size %u"), MIBLEsensors.size()); DEBUG_SENSOR_LOG(PSTR("MIBLE: vector size %u"), MIBLEsensors.size());
for(uint32_t i=0; i<MIBLEsensors.size(); i++){ for(uint32_t i=0; i<MIBLEsensors.size(); i++){
if(memcmp(_serial,MIBLEsensors.at(i).serial,sizeof(_serial))==0){ if(memcmp(_serial,MIBLEsensors.at(i).serial,sizeof(_serial))==0){
@ -227,23 +232,17 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_serial)[6], uint8_t _type){
memcpy(_newSensor.serial,_serial, sizeof(_serial)); memcpy(_newSensor.serial,_serial, sizeof(_serial));
_newSensor.type = _type; _newSensor.type = _type;
_newSensor.showedUp = 1; _newSensor.showedUp = 1;
_newSensor.temp =-1000.0f;
switch (_type) switch (_type)
{ {
case 1: case 1:
_newSensor.Flora.temp =-1000.0f; _newSensor.moisture =-1000.0f;
_newSensor.Flora.moisture =-1000.0f; _newSensor.fertility =-1000.0f;
_newSensor.Flora.fertility =-1000.0f; _newSensor.lux = 0xffff;
_newSensor.Flora.lux = 0xffff;
break; break;
case 2: case 2: case 3: case 4:
_newSensor.MJ_HT_V1.temp=-1000.0f; _newSensor.hum=-1.0f;
_newSensor.MJ_HT_V1.hum=-1.0f; _newSensor.bat=0xff;
_newSensor.MJ_HT_V1.bat=0xff;
break;
case 3: case 4:
_newSensor.LYWSD0x.temp=-1000.0f;
_newSensor.LYWSD0x.hum=-1.0f;
_newSensor.LYWSD0x.bat=0xff;
break; break;
default: default:
break; break;
@ -286,6 +285,26 @@ void HM10SerialInit(void) {
// return; // return;
// } // }
void HM10datahex(const char* string, uint8_t _mac[]) {
uint32_t slength = 12;
// uint8_t _mac[6] = {0};
uint32_t index = 0;
DEBUG_SENSOR_LOG(PSTR("HM10: mac-string %s"), string);
while (index < slength) {
char c = string[index];
uint32_t value = 0;
if(c >= '0' && c <= '9')
value = (c - '0');
else if (c >= 'A' && c <= 'F')
value = (10 + (c - 'A'));
_mac[(index/2)] += value << (((index + 1) % 2) * 4);
// DEBUG_SENSOR_LOG(PSTR("HM10: Char: %c, Value: %x, Index/2: %u, valueadded: %x, MAC-index: %x"), c, value,(index/2),value << (((index + 1) % 2) * 4), _mac[index/2]);
index++;
}
DEBUG_SENSOR_LOG(PSTR("HM10: MAC-array: %x%x%x%x%x%x"),_mac[0],_mac[1],_mac[2],_mac[3],_mac[4],_mac[5]);
}
/*********************************************************************************************\ /*********************************************************************************************\
* parse the response * parse the response
\*********************************************************************************************/ \*********************************************************************************************/
@ -298,8 +317,18 @@ void HM10ParseResponse(char *buf) {
memcpy((void *)_fw,(void *)(buf+8),3); memcpy((void *)_fw,(void *)(buf+8),3);
HM10.firmware = atoi(_fw); HM10.firmware = atoi(_fw);
DEBUG_SENSOR_LOG(PSTR("HM10: Firmware: %d"), HM10.firmware); DEBUG_SENSOR_LOG(PSTR("HM10: Firmware: %d"), HM10.firmware);
return;
}
char * _pos = strstr(buf, "IS0:");
if(_pos) {
const char* _mac = "000000000000";
memcpy((void *)_mac,(void *)(_pos+4),12);
DEBUG_SENSOR_LOG(PSTR("HM10: found Mac: %s"), _mac);
uint8_t _newMacArray[6] = {0};
HM10datahex(_mac, _newMacArray);
DEBUG_SENSOR_LOG(PSTR("HM10: MAC-array: %x%x%x%x%x%x"),_newMacArray[0],_newMacArray[1],_newMacArray[2],_newMacArray[3],_newMacArray[4],_newMacArray[5]);
MIBLEgetSensorSlot(_newMacArray, 0xff);
} }
else { else {
DEBUG_SENSOR_LOG(PSTR("HM10: empty response")); DEBUG_SENSOR_LOG(PSTR("HM10: empty response"));
} }
@ -311,16 +340,18 @@ void HM10readTempHum(char *_buf){
memcpy(&LYWSD03,(void *)_buf,3); memcpy(&LYWSD03,(void *)_buf,3);
DEBUG_SENSOR_LOG(PSTR("HM10: Temperature * 100: %u, Humidity: %u"),LYWSD03.temp,LYWSD03.hum); DEBUG_SENSOR_LOG(PSTR("HM10: Temperature * 100: %u, Humidity: %u"),LYWSD03.temp,LYWSD03.hum);
// uint8_t _serial[6] = {0}; // uint8_t _serial[6] = {0};
uint32_t _slot = MIBLEgetSensorSlot(HM10Mac[HM10.state.sensor], 4); // uint32_t _slot = MIBLEgetSensorSlot(HM10Mac[HM10.state.sensor], 4);
uint32_t _slot = HM10.state.sensor;
DEBUG_SENSOR_LOG(PSTR("MIBLE: Sensor slot: %u"), _slot); DEBUG_SENSOR_LOG(PSTR("MIBLE: Sensor slot: %u"), _slot);
static float _tempFloat; static float _tempFloat;
_tempFloat=(float)(LYWSD03.temp)/100.0f; _tempFloat=(float)(LYWSD03.temp)/100.0f;
if(_tempFloat<60){ if(_tempFloat<60){
MIBLEsensors.at(_slot).LYWSD0x.temp=_tempFloat; MIBLEsensors.at(_slot).temp=_tempFloat;
} }
_tempFloat=(float)LYWSD03.hum; _tempFloat=(float)LYWSD03.hum;
if(_tempFloat<100){ if(_tempFloat<100){
MIBLEsensors.at(_slot).LYWSD0x.hum = _tempFloat; MIBLEsensors.at(_slot).hum = _tempFloat;
DEBUG_SENSOR_LOG(PSTR("LYWSD03: hum updated")); DEBUG_SENSOR_LOG(PSTR("LYWSD03: hum updated"));
} }
} }
@ -411,7 +442,7 @@ void HM10_TaskEvery100ms(){
runningTaskLoop = false; runningTaskLoop = false;
// HM10Serial->write("AT+CONA4C138ED815A"); // HM10Serial->write("AT+CONA4C138ED815A");
char _con[20]; char _con[20];
sprintf_P(_con,"AT+CON%02x%02x%02x%02x%02x%02x",HM10Mac[HM10.state.sensor][0],HM10Mac[HM10.state.sensor][1],HM10Mac[HM10.state.sensor][2],HM10Mac[HM10.state.sensor][3],HM10Mac[HM10.state.sensor][4],HM10Mac[HM10.state.sensor][5]); sprintf_P(_con,"AT+CON%02x%02x%02x%02x%02x%02x",MIBLEsensors.at(HM10.state.sensor).serial[0],MIBLEsensors.at(HM10.state.sensor).serial[1],MIBLEsensors.at(HM10.state.sensor).serial[2],MIBLEsensors.at(HM10.state.sensor).serial[3],MIBLEsensors.at(HM10.state.sensor).serial[4],MIBLEsensors.at(HM10.state.sensor).serial[5]);
HM10Serial->write(_con); HM10Serial->write(_con);
// HM10Serial->write(kHM10Mac[HM10.state.sensor]); // HM10Serial->write(kHM10Mac[HM10.state.sensor]);
break; break;
@ -505,17 +536,31 @@ void HM10EverySecond(){
if(HM10.firmware == 0) return; if(HM10.firmware == 0) return;
if(HM10.mode.pending_task == 1) return; if(HM10.mode.pending_task == 1) return;
static uint32_t _counter = 0; static uint32_t _counter = 0;
if(_counter == 0) { if(_counter==0 && HM10.mode.pending_task==0) {
if (MIBLEsensors.size()>0) {
if(MIBLEsensors.at(HM10.state.sensor).type==3) {
HM10.mode.pending_task = 1;
HM10_Read_Sensor1(); HM10_Read_Sensor1();
HM10.mode.pending_task == 1; }
_counter = 60; else {
HM10.state.sensor++; AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s active sensor not type 3: %u"),D_CMND_HM10, HM10.state.sensor);
if (HM10.state.sensor>1) { }
}
else {
HM10.mode.pending_task = 1;
HM10_Launchtask(TASK_HM10_DISC,0,1); // start new discovery
return;
}
if (HM10.state.sensor==MIBLEsensors.size()-1) {
HM10.state.sensor=0; HM10.state.sensor=0;
_counter = 60;
}
else {
HM10.state.sensor++;
} }
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s active sensor now: %u"),D_CMND_HM10, HM10.state.sensor); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s active sensor now: %u"),D_CMND_HM10, HM10.state.sensor);
} }
_counter--; if(_counter>0) _counter--;
} }
/*********************************************************************************************\ /*********************************************************************************************\
@ -525,29 +570,37 @@ void HM10EverySecond(){
const char HTTP_HM10[] PROGMEM = const char HTTP_HM10[] PROGMEM =
"{s}HM10" " Firmware " "{m}%u{e}"; "{s}HM10" " Firmware " "{m}%u{e}";
const char HTTP_HM10_SERIAL[] PROGMEM =
"{s}%s" " Address" "{m}%02x:%02x:%02x:%02x:%02x:%02x%{e}";
void HM10Show(bool json) void HM10Show(bool json)
{ {
if (json) { if (json) {
if (MIBLEsensors.size()==0) return; for (uint32_t i = 0; i < MIBLEsensors.size(); i++) {
// char slave[33];
char temperature[33]; // sprintf_P(slave,"%s-%02x%02x%02x",MIBLESlaveFlora,MIBLEsensors.at(i).serial[2],MIBLEsensors.at(i).serial[1],MIBLEsensors.at(i).serial[0]);
dtostrfd(MIBLEsensors.at(0).LYWSD0x.temp, Settings.flag2.temperature_resolution, temperature); char temperature[33]; // all sensors have temperature
dtostrfd(MIBLEsensors.at(i).temp, Settings.flag2.temperature_resolution, temperature);
if (MIBLEsensors.at(i).type>1){
char humidity[33]; char humidity[33];
dtostrfd(MIBLEsensors.at(0).LYWSD0x.hum, Settings.flag2.humidity_resolution, humidity); dtostrfd(MIBLEsensors.at(i).hum, Settings.flag2.humidity_resolution, humidity);
ResponseAppend_P(JSON_SNS_TEMPHUM, kHM10SlaveType[MIBLEsensors.at(i).type-1], temperature, humidity);
ResponseAppend_P(JSON_SNS_TEMPHUM, F("LYWSD03"), temperature, humidity); }
}
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
} else { } else {
WSContentSend_PD(HTTP_HM10, HM10.firmware); WSContentSend_PD(HTTP_HM10, HM10.firmware);
if (MIBLEsensors.size()==0) return; for (uint32_t i = 0; i < MIBLEsensors.size(); i++) {
WSContentSend_PD(HTTP_HM10_SERIAL, kHM10SlaveType[MIBLEsensors.at(i).type-1], MIBLEsensors.at(i).serial[5], MIBLEsensors.at(i).serial[4],MIBLEsensors.at(i).serial[3],MIBLEsensors.at(i).serial[2],MIBLEsensors.at(i).serial[1],MIBLEsensors.at(i).serial[0]);
char temperature[33]; char temperature[33];
dtostrfd(MIBLEsensors.at(0).LYWSD0x.temp, Settings.flag2.temperature_resolution, temperature); dtostrfd(MIBLEsensors.at(i).temp, Settings.flag2.temperature_resolution, temperature);
WSContentSend_PD(HTTP_SNS_TEMP, kHM10SlaveType[MIBLEsensors.at(i).type-1], temperature, TempUnit());
if (MIBLEsensors.at(i).type>1){ // everything "above" Flora
char humidity[33]; char humidity[33];
dtostrfd(MIBLEsensors.at(0).LYWSD0x.hum, Settings.flag2.humidity_resolution, humidity); dtostrfd(MIBLEsensors.at(i).hum, Settings.flag2.humidity_resolution, humidity);
WSContentSend_PD(HTTP_SNS_HUM, kHM10SlaveType[MIBLEsensors.at(i).type-1], humidity);
WSContentSend_PD(HTTP_SNS_TEMP, F("LYWSD03"), temperature, TempUnit()); }
WSContentSend_PD(HTTP_SNS_HUM, F("LYWSD03"), humidity); }
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
} }
} }
@ -566,10 +619,13 @@ bool Xsns92(uint8_t function)
case FUNC_INIT: case FUNC_INIT:
HM10SerialInit(); // init and start communication HM10SerialInit(); // init and start communication
break; break;
case FUNC_EVERY_50_MSECOND:
HM10SerialHandleFeedback(); // -> sniff for device feedback
break;
case FUNC_EVERY_100_MSECOND: case FUNC_EVERY_100_MSECOND:
if (HM10_TASK_LIST[0][0] == TASK_HM10_NOTASK) { // no task running if (HM10_TASK_LIST[0][0] == TASK_HM10_NOTASK) { // no task running
// DEBUG_SENSOR_LOG(PSTR("HM10: no TASK in array")); // DEBUG_SENSOR_LOG(PSTR("HM10: no TASK in array"));
HM10SerialHandleFeedback(); // -> sniff for device feedback // HM10SerialHandleFeedback(); // -> sniff for device feedback
break; break;
} }
else { else {
@ -580,7 +636,7 @@ bool Xsns92(uint8_t function)
break; break;
case FUNC_EVERY_SECOND: case FUNC_EVERY_SECOND:
HM10EverySecond(); HM10EverySecond();
DEBUG_SENSOR_LOG(PSTR("HM10: every second")); // DEBUG_SENSOR_LOG(PSTR("HM10: every second"));
break; break;
case FUNC_JSON_APPEND: case FUNC_JSON_APPEND:
HM10Show(1); HM10Show(1);