From 07df4c1dfb4f1718cc3bea655e1f6ce4e137a2d2 Mon Sep 17 00:00:00 2001 From: Staars Date: Thu, 30 Jan 2020 08:39:28 +0100 Subject: [PATCH 01/17] start hm-10-driver --- tasmota/xsns_92_MI_HM10.ino | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tasmota/xsns_92_MI_HM10.ino diff --git a/tasmota/xsns_92_MI_HM10.ino b/tasmota/xsns_92_MI_HM10.ino new file mode 100644 index 000000000..6defdb76f --- /dev/null +++ b/tasmota/xsns_92_MI_HM10.ino @@ -0,0 +1,29 @@ +/* + xsns_92_Ml_BLE.ino - MI-BLE-sensors via HM-10 support for Tasmota + + Copyright (C) 2020 Christian Baars and Theo Arends + + 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + + -------------------------------------------------------------------------------------------- + Version yyyymmdd Action Description + -------------------------------------------------------------------------------------------- + + --- + 0.9.0.0 20191127 started - further development by Christian Baars + base - no real base project + forked - from arendst/tasmota - https://github.com/arendst/Tasmota + +*/ From 15428f59e9004e71b34c35ca6719eba9acabb4c5 Mon Sep 17 00:00:00 2001 From: Staars Date: Thu, 30 Jan 2020 09:18:21 +0100 Subject: [PATCH 02/17] add some stuff from the mp3-driver --- tasmota/xsns_92_MI_HM10.ino | 229 +++++++++++++++++++++++++++++++++++- 1 file changed, 228 insertions(+), 1 deletion(-) diff --git a/tasmota/xsns_92_MI_HM10.ino b/tasmota/xsns_92_MI_HM10.ino index 6defdb76f..f86d434b6 100644 --- a/tasmota/xsns_92_MI_HM10.ino +++ b/tasmota/xsns_92_MI_HM10.ino @@ -22,8 +22,235 @@ -------------------------------------------------------------------------------------------- --- - 0.9.0.0 20191127 started - further development by Christian Baars + 0.9.0.0 20200130 started - further development by Christian Baars base - no real base project forked - from arendst/tasmota - https://github.com/arendst/Tasmota */ + +#define XSNS_92 92 + +#include + +TasmotaSerial *HM10Serial; + +#define HM10_MAX_TASK_NUMBER 12 +uint8_t HM10_TASK_LIST[HM10_MAX_TASK_NUMBER+1][2]; // first value: kind of task - second value: delay in x * 100ms +uint8_t HM10_CURRENT_TASK_DELAY = 0; // number of 100ms-cycles +uint8_t HM10_LAST_COMMAND; // task command code + +uint16_t HM10_CURRENT_PAYLOAD = 0; // payload of a supported command + +#define HM10_MAX_RX_BUF 512 +char HM10_RX_STRING[HM10_MAX_RX_BUF] = {0}; // make a buffer bigger than the usual 10-byte-message + + + + + +/*********************************************************************************************\ + * constants +\*********************************************************************************************/ + +#define D_CMND_HM10 "HM10" + +const char S_JSON_HM10_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_HM10 "%s\":%d}"; +const char S_JSON_HM10_COMMAND[] PROGMEM = "{\"" D_CMND_HM10 "%s\"}"; +const char kHM10_Commands[] PROGMEM = "Track|Play"; + +/*********************************************************************************************\ + * enumerations +\*********************************************************************************************/ + +enum HM10_Commands { + CMND_HM10_TRACK +}; + +/*********************************************************************************************\ + * command defines +\*********************************************************************************************/ + + + +/*********************************************************************************************\ + * Task codes defines +\*********************************************************************************************/ + +#define TASK_HM10_NOTASK 0 // nothing to be done +#define TASK_HM10_FEEDBACK 1 // check the feedback from the device +#define TASK_HM10_DONE 99 // used, if there was a task in the slot or just to wait + +/*********************************************************************************************\ + * Helper functions +\*********************************************************************************************/ + +void HM10_Launchtask(uint8_t task, uint8_t slot, uint8_t delay){ + HM10_TASK_LIST[slot][0] = task; + HM10_TASK_LIST[slot][1] = delay; + HM10_TASK_LIST[slot+1][0] = TASK_HM10_NOTASK; // the tasks must always be launched in ascending order!! + HM10_CURRENT_TASK_DELAY = HM10_TASK_LIST[0][1]; +} + +void HM10_TaskReplaceInSlot(uint8_t task, uint8_t slot){ + HM10_LAST_COMMAND = HM10_TASK_LIST[slot][0]; // save command + HM10_TASK_LIST[slot][0] = task; +} + +void HM10_Reset(void) { HM10_LAST_COMMAND = TASK_HM10_DONE; // task command code + HM10State.activeFolder = 0; // see the line above + HM10_Launchtask(TASK_HM10_DONE,0,10); // just wait for some time , equals delay(1000) -> 10 * 100 + HM10_Launchtask(TASK_HM10_RESET_DEVICE, 1,0); // reset Device + HM10_Launchtask(TASK_HM10_Q_VERSION, 2,10); // read SW Version at startup + } // ASAP + + +/*********************************************************************************************\ + * init serial + * define serial rx/tx port fixed with 115200 baud +\*********************************************************************************************/ + +void HM10SerialInit(void) { + HM10Serial = new TasmotaSerial(pin[GPIO_RXD], pin[GPIO_TXD], 1, 0, HM10_MAX_RX_BUF); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sstart serial communication fixed to 115200 baud"),S_CONTROL_HM10); + if (HM10Serial->begin(115200)) { + if (UBXSerial->hardwareSerial()) { + ClaimSerial(); + DEBUG_SENSOR_LOG(PSTR("HM10: claim HW")); + } + HM10_Reset(); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK_LIST initialized, now return to main loop"),S_CONTROL_HM10); + } + return; +} + +/*********************************************************************************************\ + * create the HM10 commands payload, and send it via serial interface to the HM10 player + \*********************************************************************************************/ + +void HM10_CMD(uint8_t _cmd,uint16_t _val) { + + HM10Serial->write(cmd, sizeof(cmd)); / + return; +} + +/*********************************************************************************************\ + * handle the return value from the HM10 +\*********************************************************************************************/ + +bool HM10SerialHandleFeedback(){ + bool success = true; // true disables possible repetition of commands, set to false only for debugging + uint8_t i = 0; + uint8_t ret[HM10_MAX_RX_BUF] = {0}; // reset array with zeros + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%swaiting for response"),S_CONTROL_HM10); + bool receive_data_message = false; // special response with the format d,a, ...,a,d + + while(HM10Serial->available()) { + // delay(0); + if(iread(); + } + i++; + } + return success; +} + +/*********************************************************************************************\ + * execute the next Task +\*********************************************************************************************/ + +void HM10_TaskEvery100ms(){ + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK to be done %u"),S_CONTROL_HM10,HM10_TASK_LIST[0][0]); + if (HM10_CURRENT_TASK_DELAY == 0) { + uint8_t i = 0; + bool runningTaskLoop = true; + while (runningTaskLoop) { // always iterate through the whole task list + switch(HM10_TASK_LIST[i][0]) { // handle the kind of task + case TASK_HM10_FEEDBACK: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s%sFeedback"),S_CONTROL_HM10,S_TASK_HM10); + if(HM10_RETRIES>0) { + if (HM10SerialHandleFeedback()) { + HM10_TASK_LIST[i][0] = TASK_HM10_DONE; // mark slot as handled if successful + HM10_CURRENT_TASK_DELAY = HM10_TASK_LIST[i+1][1]; // assign the delay of the next slot to the current global delay + } + else { + HM10_TASK_LIST[i][0] = HM10_LAST_COMMAND; // reinsert unsuccessful task into the current slot + HM10_CURRENT_TASK_DELAY++; + HM10_RETRIES--; + } + } + else { + HM10_TASK_LIST[i][0] = TASK_HM10_DONE; // mark slot as handled even if not successful + HM10_CURRENT_TASK_DELAY = HM10_TASK_LIST[i+1][1]; // assign the delay of the next slot to the current global delay + HM10_RETRIES = 3; + } + runningTaskLoop = false; // return to main loop + break; + case TASK_HM10_PLAY: + HM10_CMD(HM10_CMD_PLAY, 0); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s%sPlay"),S_CONTROL_HM10,S_TASK_HM10); + HM10State.PlayMode = 1; + HM10_TaskReplaceInSlot(TASK_HM10_Q_TRACK,i); + runningTaskLoop = false; + break; + + case TASK_HM10_RESET_DEVICE: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s%sReset Device"),S_CONTROL_HM10,S_TASK_HM10); + HM10_CMD(HM10_CMD_RESET, HM10_CMD_RESET_VALUE); + HM10_CURRENT_TASK_DELAY = HM10_TASK_LIST[i+1][1]; // set task delay + HM10_TASK_LIST[i][0] = TASK_HM10_DONE; // no feedback for reset + runningTaskLoop = false; // return to main loop + break; + + case TASK_HM10_DONE: // this entry was already handled + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sFound done HM10_TASK"),S_CONTROL_HM10); + if(HM10_TASK_LIST[i+1][0] == TASK_HM10_NOTASK) { // check the next entry and if there is none + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s%sno Tasks left"),S_CONTROL_HM10,S_TASK_HM10); + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK_DONE current slot %u"),S_CONTROL_HM10, i); + for (uint8_t j = 0; j < HM10_MAX_TASK_NUMBER+1; j++) { // do a clean-up: + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK cleanup slot %u"),S_CONTROL_HM10, j); + HM10_TASK_LIST[j][0] = TASK_HM10_NOTASK; // reset all task entries + HM10_TASK_LIST[j][1] = 0; // reset all delays + } + runningTaskLoop = false; // return to main loop + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sUpdate GUI via AJAX"),S_CONTROL_HM10); + // HM10_GUI_NEEDS_UPDATE = true; + break; + } + } + i++; + } + } + else { + HM10_CURRENT_TASK_DELAY--; // count down every 100 ms + } +} + + + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv92(uint8_t function) +{ + bool result = false; + + if ((pin[GPIO_RXD] < 99) && (pin[GPIO_TXD] < 99)) { + switch (function) { + case FUNC_PRE_INIT: + HM10SerialInit(); // init and start communication + break; + case FUNC_EVERY_100_MSECOND: + if (HM10_TASK_LIST[0][0] == TASK_HM10_NOTASK) { // no task running + HM10SerialHandleFeedback(); // -> sniff for device feedback + break; + } + else { + HM10_TaskEvery100ms(); // something has to be done, we'll check in the next step + break; + } + } + } + return result; +} + From b9e38153587e2e0adbf182d93bc323a8bc354572 Mon Sep 17 00:00:00 2001 From: Staars Date: Fri, 31 Jan 2020 10:12:48 +0100 Subject: [PATCH 03/17] adding stuff --- tasmota/xsns_92_MI_HM10.ino | 192 ++++++++++++++++++++++++------------ 1 file changed, 127 insertions(+), 65 deletions(-) diff --git a/tasmota/xsns_92_MI_HM10.ino b/tasmota/xsns_92_MI_HM10.ino index f86d434b6..51c02ea07 100644 --- a/tasmota/xsns_92_MI_HM10.ino +++ b/tasmota/xsns_92_MI_HM10.ino @@ -30,11 +30,14 @@ #define XSNS_92 92 +#define HM_PIN_RX 5 // D1 Hardcoded while developing +#define HM_PIN_TX 4 // D2 + #include TasmotaSerial *HM10Serial; -#define HM10_MAX_TASK_NUMBER 12 +#define HM10_MAX_TASK_NUMBER 8 uint8_t HM10_TASK_LIST[HM10_MAX_TASK_NUMBER+1][2]; // first value: kind of task - second value: delay in x * 100ms uint8_t HM10_CURRENT_TASK_DELAY = 0; // number of 100ms-cycles uint8_t HM10_LAST_COMMAND; // task command code @@ -44,8 +47,13 @@ uint16_t HM10_CURRENT_PAYLOAD = 0; // payload of a supported c #define HM10_MAX_RX_BUF 512 char HM10_RX_STRING[HM10_MAX_RX_BUF] = {0}; // make a buffer bigger than the usual 10-byte-message - - +struct { + uint8_t current_task_delay; + struct { + uint32_t init:1; + // TODO: more to come + } mode; +} HM10; /*********************************************************************************************\ @@ -72,12 +80,23 @@ enum HM10_Commands { + /*********************************************************************************************\ * Task codes defines \*********************************************************************************************/ #define TASK_HM10_NOTASK 0 // nothing to be done -#define TASK_HM10_FEEDBACK 1 // check the feedback from the device +#define TASK_HM10_ROLE1 1 // change role to 1 +#define TASK_HM10_IMME1 2 // change imme to 1 +#define TASK_HM10_RENEW 3 // device factory setting +#define TASK_HM10_RESET 4 // device reset +#define TASK_HM10_DISC 5 // device discovery scan +#define TASK_HM10_CONN 6 // connect to given MAC +#define TASK_HM10_VERSION 7 // query FW version +#define TASK_HM10_NAME 8 // query device name +#define TASK_HM10_FEEDBACK 9 // get device response + + #define TASK_HM10_DONE 99 // used, if there was a task in the slot or just to wait /*********************************************************************************************\ @@ -96,12 +115,14 @@ void HM10_TaskReplaceInSlot(uint8_t task, uint8_t slot){ HM10_TASK_LIST[slot][0] = task; } -void HM10_Reset(void) { HM10_LAST_COMMAND = TASK_HM10_DONE; // task command code - HM10State.activeFolder = 0; // see the line above - HM10_Launchtask(TASK_HM10_DONE,0,10); // just wait for some time , equals delay(1000) -> 10 * 100 - HM10_Launchtask(TASK_HM10_RESET_DEVICE, 1,0); // reset Device - HM10_Launchtask(TASK_HM10_Q_VERSION, 2,10); // read SW Version at startup - } // ASAP +void HM10_Reset(void) { HM10_Launchtask(TASK_HM10_ROLE1,0,10); // set role to 1 + HM10_Launchtask(TASK_HM10_IMME1,1,10); // set imme to 1 + HM10_Launchtask(TASK_HM10_RESET,2,10); // reset Device + HM10_Launchtask(TASK_HM10_VERSION,3,10); // read SW Version + HM10_Launchtask(TASK_HM10_NAME,4,10); // read name + } + + /*********************************************************************************************\ @@ -110,15 +131,17 @@ void HM10_Reset(void) { HM10_LAST_COMMAND = TASK_HM10_DONE; \*********************************************************************************************/ void HM10SerialInit(void) { - HM10Serial = new TasmotaSerial(pin[GPIO_RXD], pin[GPIO_TXD], 1, 0, HM10_MAX_RX_BUF); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sstart serial communication fixed to 115200 baud"),S_CONTROL_HM10); + HM10.mode.init = false; + HM10Serial = new TasmotaSerial(HM_PIN_RX, HM_PIN_TX, 1, 0, HM10_MAX_RX_BUF); if (HM10Serial->begin(115200)) { - if (UBXSerial->hardwareSerial()) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sstart serial communication fixed to 115200 baud"),D_CMND_HM10); + if (HM10Serial->hardwareSerial()) { ClaimSerial(); DEBUG_SENSOR_LOG(PSTR("HM10: claim HW")); } HM10_Reset(); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK_LIST initialized, now return to main loop"),S_CONTROL_HM10); + HM10.mode.init = true; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK_LIST initialized, now return to main loop"),D_CMND_HM10); } return; } @@ -127,10 +150,22 @@ void HM10SerialInit(void) { * create the HM10 commands payload, and send it via serial interface to the HM10 player \*********************************************************************************************/ -void HM10_CMD(uint8_t _cmd,uint16_t _val) { +// void HM10_CMD(uint8_t _cmd,uint16_t _val) { - HM10Serial->write(cmd, sizeof(cmd)); / - return; +// HM10Serial->write(cmd, sizeof(cmd)); / +// return; +// } + +/*********************************************************************************************\ + * parse the response +\*********************************************************************************************/ +void HM10ParseResponse(char *buf) { + if (!strncmp(buf,"OK",2)) { + DEBUG_SENSOR_LOG(PSTR("HM10: got OK")); + } + else { + DEBUG_SENSOR_LOG(PSTR("HM10: empty response")); + } } /*********************************************************************************************\ @@ -138,19 +173,26 @@ void HM10_CMD(uint8_t _cmd,uint16_t _val) { \*********************************************************************************************/ bool HM10SerialHandleFeedback(){ - bool success = true; // true disables possible repetition of commands, set to false only for debugging - uint8_t i = 0; - uint8_t ret[HM10_MAX_RX_BUF] = {0}; // reset array with zeros - // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%swaiting for response"),S_CONTROL_HM10); - bool receive_data_message = false; // special response with the format d,a, ...,a,d - + bool success = false; // true disables possible repetition of commands, set to false only for debugging + uint32_t i = 0; + char ret[HM10_MAX_RX_BUF] = {0}; // reset array with zeros + + while(HM10Serial->available()) { // delay(0); if(iread(); } i++; - } + success = true; + } + if(success) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s response: %s"),D_CMND_HM10, (char *)ret); + HM10ParseResponse(ret); + } + else { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s got no response"),D_CMND_HM10); + } return success; } @@ -159,65 +201,82 @@ bool HM10SerialHandleFeedback(){ \*********************************************************************************************/ void HM10_TaskEvery100ms(){ - // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK to be done %u"),S_CONTROL_HM10,HM10_TASK_LIST[0][0]); + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK to be done %u"),D_CMND_HM10,HM10_TASK_LIST[0][0]); if (HM10_CURRENT_TASK_DELAY == 0) { uint8_t i = 0; bool runningTaskLoop = true; while (runningTaskLoop) { // always iterate through the whole task list switch(HM10_TASK_LIST[i][0]) { // handle the kind of task - case TASK_HM10_FEEDBACK: - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s%sFeedback"),S_CONTROL_HM10,S_TASK_HM10); - if(HM10_RETRIES>0) { - if (HM10SerialHandleFeedback()) { - HM10_TASK_LIST[i][0] = TASK_HM10_DONE; // mark slot as handled if successful - HM10_CURRENT_TASK_DELAY = HM10_TASK_LIST[i+1][1]; // assign the delay of the next slot to the current global delay - } - else { - HM10_TASK_LIST[i][0] = HM10_LAST_COMMAND; // reinsert unsuccessful task into the current slot - HM10_CURRENT_TASK_DELAY++; - HM10_RETRIES--; - } - } - else { - HM10_TASK_LIST[i][0] = TASK_HM10_DONE; // mark slot as handled even if not successful - HM10_CURRENT_TASK_DELAY = HM10_TASK_LIST[i+1][1]; // assign the delay of the next slot to the current global delay - HM10_RETRIES = 3; - } - runningTaskLoop = false; // return to main loop + case TASK_HM10_ROLE1: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s set role to 1"),D_CMND_HM10); + HM10_CURRENT_TASK_DELAY = 5; // set task delay + HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); + runningTaskLoop = false; + HM10Serial->write("AT+ROLE1"); break; - case TASK_HM10_PLAY: - HM10_CMD(HM10_CMD_PLAY, 0); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s%sPlay"),S_CONTROL_HM10,S_TASK_HM10); - HM10State.PlayMode = 1; - HM10_TaskReplaceInSlot(TASK_HM10_Q_TRACK,i); + case TASK_HM10_IMME1: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s set imme to 1"),D_CMND_HM10); + HM10_CURRENT_TASK_DELAY = 5; // set task delay + HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); + runningTaskLoop = false; + HM10Serial->write("AT+IMME1"); + break; + case TASK_HM10_DISC: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s set role to 1"),D_CMND_HM10); + HM10_CURRENT_TASK_DELAY = 35; // set task delay + HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); + runningTaskLoop = false; + HM10Serial->write("AT+DISC?"); + break; + case TASK_HM10_VERSION: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s read version"),D_CMND_HM10); + HM10_CURRENT_TASK_DELAY = 5; // set task delay + HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); + runningTaskLoop = false; + HM10Serial->write("AT+VERR?"); + break; + case TASK_HM10_NAME: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s read name"),D_CMND_HM10); + HM10_CURRENT_TASK_DELAY = 5; // set task delay + HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); + runningTaskLoop = false; + HM10Serial->write("AT+NAME?"); + break; + + case TASK_HM10_RESET: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s Reset Device"),D_CMND_HM10); + HM10Serial->write("AT+RESET"); + HM10_CURRENT_TASK_DELAY = 5; // set task delay + HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); runningTaskLoop = false; break; - case TASK_HM10_RESET_DEVICE: - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s%sReset Device"),S_CONTROL_HM10,S_TASK_HM10); - HM10_CMD(HM10_CMD_RESET, HM10_CMD_RESET_VALUE); - HM10_CURRENT_TASK_DELAY = HM10_TASK_LIST[i+1][1]; // set task delay + case TASK_HM10_FEEDBACK: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s get response"),D_CMND_HM10); + HM10SerialHandleFeedback(); + HM10_CURRENT_TASK_DELAY = HM10_TASK_LIST[i+1][1];; // set task delay HM10_TASK_LIST[i][0] = TASK_HM10_DONE; // no feedback for reset - runningTaskLoop = false; // return to main loop + runningTaskLoop = false; break; case TASK_HM10_DONE: // this entry was already handled - // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sFound done HM10_TASK"),S_CONTROL_HM10); + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sFound done HM10_TASK"),D_CMND_HM10); + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%snext slot:%u, i: %u"),D_CMND_HM10, HM10_TASK_LIST[i+1][0],i); if(HM10_TASK_LIST[i+1][0] == TASK_HM10_NOTASK) { // check the next entry and if there is none - // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s%sno Tasks left"),S_CONTROL_HM10,S_TASK_HM10); - // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK_DONE current slot %u"),S_CONTROL_HM10, i); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sno Tasks left"),D_CMND_HM10); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK_DONE current slot %u"),D_CMND_HM10, i); for (uint8_t j = 0; j < HM10_MAX_TASK_NUMBER+1; j++) { // do a clean-up: - // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK cleanup slot %u"),S_CONTROL_HM10, j); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK cleanup slot %u"),D_CMND_HM10, j); HM10_TASK_LIST[j][0] = TASK_HM10_NOTASK; // reset all task entries HM10_TASK_LIST[j][1] = 0; // reset all delays } runningTaskLoop = false; // return to main loop - // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sUpdate GUI via AJAX"),S_CONTROL_HM10); + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sUpdate GUI via AJAX"),D_CMND_HM10); // HM10_GUI_NEEDS_UPDATE = true; break; } } - i++; + i++; } } else { @@ -231,26 +290,29 @@ void HM10_TaskEvery100ms(){ * Interface \*********************************************************************************************/ -bool Xdrv92(uint8_t function) +bool Xsns92(uint8_t function) { bool result = false; - if ((pin[GPIO_RXD] < 99) && (pin[GPIO_TXD] < 99)) { + // if ((pin[HM_PIN_RX] < 99) && (pin[HM_PIN_TX] < 99)) { + if (true) { switch (function) { - case FUNC_PRE_INIT: + case FUNC_INIT: HM10SerialInit(); // init and start communication break; case FUNC_EVERY_100_MSECOND: if (HM10_TASK_LIST[0][0] == TASK_HM10_NOTASK) { // no task running + // DEBUG_SENSOR_LOG(PSTR("HM10: no TASK in array")); HM10SerialHandleFeedback(); // -> sniff for device feedback break; } else { + // DEBUG_SENSOR_LOG(PSTR("HM10: every 100msec")); HM10_TaskEvery100ms(); // something has to be done, we'll check in the next step break; } + break; } } return result; -} - +} \ No newline at end of file From a1d7d2baf81a15510ac0c0ae5a7318258d6c4a27 Mon Sep 17 00:00:00 2001 From: Staars Date: Fri, 31 Jan 2020 15:28:34 +0100 Subject: [PATCH 04/17] output working --- tasmota/xsns_92_MI_HM10.ino | 165 +++++++++++++++++++++++++++++------- 1 file changed, 136 insertions(+), 29 deletions(-) diff --git a/tasmota/xsns_92_MI_HM10.ino b/tasmota/xsns_92_MI_HM10.ino index 51c02ea07..045392d73 100644 --- a/tasmota/xsns_92_MI_HM10.ino +++ b/tasmota/xsns_92_MI_HM10.ino @@ -37,24 +37,32 @@ TasmotaSerial *HM10Serial; -#define HM10_MAX_TASK_NUMBER 8 +#define HM10_MAX_TASK_NUMBER 12 uint8_t HM10_TASK_LIST[HM10_MAX_TASK_NUMBER+1][2]; // first value: kind of task - second value: delay in x * 100ms -uint8_t HM10_CURRENT_TASK_DELAY = 0; // number of 100ms-cycles -uint8_t HM10_LAST_COMMAND; // task command code +// uint8_t HM10.current_task_delay = 0; // number of 100ms-cycles +// uint8_t HM10.last_command; -uint16_t HM10_CURRENT_PAYLOAD = 0; // payload of a supported command #define HM10_MAX_RX_BUF 512 char HM10_RX_STRING[HM10_MAX_RX_BUF] = {0}; // make a buffer bigger than the usual 10-byte-message struct { uint8_t current_task_delay; + uint8_t last_command; + uint16_t firmware; struct { uint32_t init:1; + uint32_t subscribed:1; // TODO: more to come } mode; } HM10; +#pragma pack(1) +struct { + uint16_t temp; + uint8_t hum; +} LYWSD03; +#pragma pack(0) /*********************************************************************************************\ * constants @@ -95,7 +103,10 @@ enum HM10_Commands { #define TASK_HM10_VERSION 7 // query FW version #define TASK_HM10_NAME 8 // query device name #define TASK_HM10_FEEDBACK 9 // get device response - +#define TASK_HM10_DISCONN 10 // disconnect +#define TASK_HM10_SUBSCR 11 // subscribe to service handle +#define TASK_HM10_READ 12 // read from handle +#define TASK_HM10_FINDALLCHARS 13 // read all available characteristics #define TASK_HM10_DONE 99 // used, if there was a task in the slot or just to wait @@ -107,19 +118,26 @@ void HM10_Launchtask(uint8_t task, uint8_t slot, uint8_t delay){ HM10_TASK_LIST[slot][0] = task; HM10_TASK_LIST[slot][1] = delay; HM10_TASK_LIST[slot+1][0] = TASK_HM10_NOTASK; // the tasks must always be launched in ascending order!! - HM10_CURRENT_TASK_DELAY = HM10_TASK_LIST[0][1]; + HM10.current_task_delay = HM10_TASK_LIST[0][1]; } void HM10_TaskReplaceInSlot(uint8_t task, uint8_t slot){ - HM10_LAST_COMMAND = HM10_TASK_LIST[slot][0]; // save command + HM10.last_command = HM10_TASK_LIST[slot][0]; // save command HM10_TASK_LIST[slot][0] = task; } -void HM10_Reset(void) { HM10_Launchtask(TASK_HM10_ROLE1,0,10); // set role to 1 - HM10_Launchtask(TASK_HM10_IMME1,1,10); // set imme to 1 - HM10_Launchtask(TASK_HM10_RESET,2,10); // reset Device +void HM10_Reset(void) { HM10_Launchtask(TASK_HM10_ROLE1,0,1); // set role to 1 + HM10_Launchtask(TASK_HM10_IMME1,1,1); // set imme to 1 + HM10_Launchtask(TASK_HM10_RESET,2,1); // reset Device HM10_Launchtask(TASK_HM10_VERSION,3,10); // read SW Version - HM10_Launchtask(TASK_HM10_NAME,4,10); // read name + HM10_Launchtask(TASK_HM10_DISC,4,1); // disscovery + HM10_Launchtask(TASK_HM10_CONN,5,5); // connect + HM10_Launchtask(TASK_HM10_FEEDBACK,6,35); // get OK+CONN + HM10_Launchtask(TASK_HM10_SUBSCR,7,20); // subscribe + HM10_Launchtask(TASK_HM10_READ,8,35); // read + HM10_Launchtask(TASK_HM10_READ,9,35); // read + HM10_Launchtask(TASK_HM10_READ,10,35); // read + HM10_Launchtask(TASK_HM10_DISCONN,11,250); // disconnect } @@ -134,14 +152,14 @@ void HM10SerialInit(void) { HM10.mode.init = false; HM10Serial = new TasmotaSerial(HM_PIN_RX, HM_PIN_TX, 1, 0, HM10_MAX_RX_BUF); if (HM10Serial->begin(115200)) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sstart serial communication fixed to 115200 baud"),D_CMND_HM10); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s start serial communication fixed to 115200 baud"),D_CMND_HM10); if (HM10Serial->hardwareSerial()) { ClaimSerial(); DEBUG_SENSOR_LOG(PSTR("HM10: claim HW")); } HM10_Reset(); HM10.mode.init = true; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK_LIST initialized, now return to main loop"),D_CMND_HM10); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s_TASK_LIST initialized, now return to main loop"),D_CMND_HM10); } return; } @@ -160,12 +178,19 @@ void HM10SerialInit(void) { * parse the response \*********************************************************************************************/ void HM10ParseResponse(char *buf) { - if (!strncmp(buf,"OK",2)) { + if (!strncmp(buf,"OK",2)) { DEBUG_SENSOR_LOG(PSTR("HM10: got OK")); } - else { - DEBUG_SENSOR_LOG(PSTR("HM10: empty response")); + if (!strncmp(buf,"HMSoft",6)) { //8 + const char* _fw = "000"; + memcpy((void *)_fw,(void *)(buf+8),3); + HM10.firmware = atoi(_fw); + DEBUG_SENSOR_LOG(PSTR("HM10: Firmware: %d"), HM10.firmware); } + + else { + DEBUG_SENSOR_LOG(PSTR("HM10: empty response")); + } } /*********************************************************************************************\ @@ -186,7 +211,14 @@ bool HM10SerialHandleFeedback(){ i++; success = true; } - if(success) { + if(HM10.mode.subscribed) { + DEBUG_SENSOR_LOG(PSTR("HM10: raw data: %x%x%x%x%x%x%x"),ret[0],ret[1],ret[2],ret[3],ret[4],ret[5],ret[6]); + if(ret[0] != 0 && ret[1] != 0){ + memcpy(&LYWSD03,(void *)ret,3); + DEBUG_SENSOR_LOG(PSTR("HM10: Temperature * 100: %u, Humidity: %u"),LYWSD03.temp,LYWSD03.hum); + } + } + else if(success) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s response: %s"),D_CMND_HM10, (char *)ret); HM10ParseResponse(ret); } @@ -202,59 +234,92 @@ bool HM10SerialHandleFeedback(){ void HM10_TaskEvery100ms(){ // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK to be done %u"),D_CMND_HM10,HM10_TASK_LIST[0][0]); - if (HM10_CURRENT_TASK_DELAY == 0) { + if (HM10.current_task_delay == 0) { uint8_t i = 0; bool runningTaskLoop = true; while (runningTaskLoop) { // always iterate through the whole task list switch(HM10_TASK_LIST[i][0]) { // handle the kind of task case TASK_HM10_ROLE1: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s set role to 1"),D_CMND_HM10); - HM10_CURRENT_TASK_DELAY = 5; // set task delay + HM10.current_task_delay = 5; // set task delay HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); runningTaskLoop = false; HM10Serial->write("AT+ROLE1"); break; case TASK_HM10_IMME1: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s set imme to 1"),D_CMND_HM10); - HM10_CURRENT_TASK_DELAY = 5; // set task delay + HM10.current_task_delay = 5; // set task delay HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); runningTaskLoop = false; HM10Serial->write("AT+IMME1"); break; case TASK_HM10_DISC: - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s set role to 1"),D_CMND_HM10); - HM10_CURRENT_TASK_DELAY = 35; // set task delay + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s start discovery"),D_CMND_HM10); + HM10.current_task_delay = 35; // set task delay HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); runningTaskLoop = false; HM10Serial->write("AT+DISC?"); break; case TASK_HM10_VERSION: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s read version"),D_CMND_HM10); - HM10_CURRENT_TASK_DELAY = 5; // set task delay + HM10.current_task_delay = 5; // set task delay HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); runningTaskLoop = false; HM10Serial->write("AT+VERR?"); break; case TASK_HM10_NAME: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s read name"),D_CMND_HM10); - HM10_CURRENT_TASK_DELAY = 5; // set task delay + HM10.current_task_delay = 5; // set task delay HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); runningTaskLoop = false; HM10Serial->write("AT+NAME?"); break; - + case TASK_HM10_CONN: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s connect"),D_CMND_HM10); + HM10.current_task_delay = 2; // set task delay + HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); + runningTaskLoop = false; + HM10Serial->write("AT+CONA4C138ED815A"); + break; + case TASK_HM10_DISCONN: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s disconnect"),D_CMND_HM10); + HM10.current_task_delay = 5; // set task delay + HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); + runningTaskLoop = false; + HM10Serial->write("AT"); + HM10.mode.subscribed = false; + break; case TASK_HM10_RESET: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s Reset Device"),D_CMND_HM10); HM10Serial->write("AT+RESET"); - HM10_CURRENT_TASK_DELAY = 5; // set task delay + HM10.current_task_delay = 5; // set task delay HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); runningTaskLoop = false; break; - + case TASK_HM10_SUBSCR: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s subscribe"),D_CMND_HM10); + HM10.current_task_delay = 15; // set task delay + HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); + runningTaskLoop = false; + HM10Serial->write("AT+NOTIFY_ON0037"); + + case TASK_HM10_READ: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s read handle 0036"),D_CMND_HM10); + HM10.current_task_delay = 0; // set task delay + HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); + runningTaskLoop = false; + HM10Serial->write("AT+READDATA0036?"); + HM10.mode.subscribed = true; + case TASK_HM10_FINDALLCHARS: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s find all chars"),D_CMND_HM10); + HM10.current_task_delay = 35; // set task delay + HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); + runningTaskLoop = false; + HM10Serial->write("AT+FINDALLCHARS?"); case TASK_HM10_FEEDBACK: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s get response"),D_CMND_HM10); HM10SerialHandleFeedback(); - HM10_CURRENT_TASK_DELAY = HM10_TASK_LIST[i+1][1];; // set task delay + HM10.current_task_delay = HM10_TASK_LIST[i+1][1];; // set task delay HM10_TASK_LIST[i][0] = TASK_HM10_DONE; // no feedback for reset runningTaskLoop = false; break; @@ -280,11 +345,45 @@ void HM10_TaskEvery100ms(){ } } else { - HM10_CURRENT_TASK_DELAY--; // count down every 100 ms + HM10.current_task_delay--; // count down every 100 ms } } +const char HTTP_HM10[] PROGMEM = + "{s}HM10" " Firmware " "{m}%u{e}"; + +void HM10Show(bool json) +{ + if (HM10.firmware>0) { + char temperature[33]; + float _temp = (float)LYWSD03.temp/100.0F; + dtostrfd(_temp, Settings.flag2.temperature_resolution, temperature); + char humidity[33]; + dtostrfd(LYWSD03.hum, Settings.flag2.humidity_resolution, humidity); + + if (json) { + ResponseAppend_P(JSON_SNS_TEMPHUM, F("LYWSD03"), temperature, humidity); +#ifdef USE_DOMOTICZ + if (0 == tele_period) { + DomoticzTempHumSensor(temperature, humidity); + } +#endif // USE_DOMOTICZ +#ifdef USE_KNX + if (0 == tele_period) { + KnxSensor(KNX_TEMPERATURE, _temp); + KnxSensor(KNX_HUMIDITY, LYWSD03.hum); + } +#endif // USE_KNX +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_HM10, HM10.firmware); + WSContentSend_PD(HTTP_SNS_TEMP, F("LYWSD03"), temperature, TempUnit()); + WSContentSend_PD(HTTP_SNS_HUM, F("LYWSD03"), humidity); +#endif // USE_WEBSERVER + } + } +} /*********************************************************************************************\ * Interface @@ -312,6 +411,14 @@ bool Xsns92(uint8_t function) break; } break; + case FUNC_JSON_APPEND: + HM10Show(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + HM10Show(0); + break; +#endif // USE_WEBSERVER } } return result; From f6a93a8d60ce876cacd494ff157606576a522841 Mon Sep 17 00:00:00 2001 From: Staars Date: Fri, 31 Jan 2020 18:50:11 +0100 Subject: [PATCH 05/17] unify codebase --- tasmota/xsns_92_MI_HM10.ino | 131 +++++++++++++++++++++++++++++------- 1 file changed, 107 insertions(+), 24 deletions(-) diff --git a/tasmota/xsns_92_MI_HM10.ino b/tasmota/xsns_92_MI_HM10.ino index 045392d73..a384d446a 100644 --- a/tasmota/xsns_92_MI_HM10.ino +++ b/tasmota/xsns_92_MI_HM10.ino @@ -34,20 +34,20 @@ #define HM_PIN_TX 4 // D2 #include +#include TasmotaSerial *HM10Serial; #define HM10_MAX_TASK_NUMBER 12 uint8_t HM10_TASK_LIST[HM10_MAX_TASK_NUMBER+1][2]; // first value: kind of task - second value: delay in x * 100ms -// uint8_t HM10.current_task_delay = 0; // number of 100ms-cycles -// uint8_t HM10.last_command; + #define HM10_MAX_RX_BUF 512 -char HM10_RX_STRING[HM10_MAX_RX_BUF] = {0}; // make a buffer bigger than the usual 10-byte-message +char HM10_RX_STRING[HM10_MAX_RX_BUF] = {0}; struct { - uint8_t current_task_delay; + uint8_t current_task_delay; // number of 100ms-cycles uint8_t last_command; uint16_t firmware; struct { @@ -64,6 +64,32 @@ struct { } LYWSD03; #pragma pack(0) +struct mi_sensor_t{ + uint8_t type; //flora = 1; MI-HT_V1=2; LYWSD02=3; LYWSD03=4 + uint8_t serial[6]; + uint8_t showedUp; + union { + struct { + float temp; + float moisture; + float fertility; + uint16_t lux; + } Flora; + struct { + float temp; + float hum; + uint8_t bat; + } MJ_HT_V1; + struct { + float temp; + float hum; + uint8_t bat; + } LYWSD0x; // LYWSD02 and LYWSD03 + }; +}; + +std::vector MIBLEsensors; + /*********************************************************************************************\ * constants \*********************************************************************************************/ @@ -140,7 +166,56 @@ void HM10_Reset(void) { HM10_Launchtask(TASK_HM10_ROLE1,0,1); // set r HM10_Launchtask(TASK_HM10_DISCONN,11,250); // disconnect } - +/** + * @brief Return the slot number of a known sensor or return create new sensor slot + * + * @param _serial BLE address of the sensor + * @param _type Type number of the sensor + * @return uint32_t Known or new slot in the sensors-vector + */ +uint32_t MIBLEgetSensorSlot(uint8_t (&_serial)[6], uint8_t _type){ + DEBUG_SENSOR_LOG(PSTR("MIBLE: vector size %u"), MIBLEsensors.size()); + for(uint32_t i=0; i0) { - char temperature[33]; - float _temp = (float)LYWSD03.temp/100.0F; - dtostrfd(_temp, Settings.flag2.temperature_resolution, temperature); - char humidity[33]; - dtostrfd(LYWSD03.hum, Settings.flag2.humidity_resolution, humidity); - if (json) { + if (MIBLEsensors.size()==0) return; + + char temperature[33]; + dtostrfd(MIBLEsensors.at(0).LYWSD0x.temp, Settings.flag2.temperature_resolution, temperature); + char humidity[33]; + dtostrfd(MIBLEsensors.at(0).LYWSD0x.hum, Settings.flag2.humidity_resolution, humidity); + ResponseAppend_P(JSON_SNS_TEMPHUM, F("LYWSD03"), temperature, humidity); -#ifdef USE_DOMOTICZ - if (0 == tele_period) { - DomoticzTempHumSensor(temperature, humidity); - } -#endif // USE_DOMOTICZ -#ifdef USE_KNX - if (0 == tele_period) { - KnxSensor(KNX_TEMPERATURE, _temp); - KnxSensor(KNX_HUMIDITY, LYWSD03.hum); - } -#endif // USE_KNX #ifdef USE_WEBSERVER } else { WSContentSend_PD(HTTP_HM10, HM10.firmware); + if (MIBLEsensors.size()==0) return; + + char temperature[33]; + dtostrfd(MIBLEsensors.at(0).LYWSD0x.temp, Settings.flag2.temperature_resolution, temperature); + char humidity[33]; + dtostrfd(MIBLEsensors.at(0).LYWSD0x.hum, Settings.flag2.humidity_resolution, humidity); + WSContentSend_PD(HTTP_SNS_TEMP, F("LYWSD03"), temperature, TempUnit()); WSContentSend_PD(HTTP_SNS_HUM, F("LYWSD03"), humidity); #endif // USE_WEBSERVER } - } } /*********************************************************************************************\ From cb067237ad1d56be59697454b1043a850977b95c Mon Sep 17 00:00:00 2001 From: Staars Date: Sat, 1 Feb 2020 16:17:20 +0100 Subject: [PATCH 06/17] stabilize readings --- tasmota/xsns_92_MI_HM10.ino | 184 ++++++++++++++++++++++++++---------- 1 file changed, 136 insertions(+), 48 deletions(-) diff --git a/tasmota/xsns_92_MI_HM10.ino b/tasmota/xsns_92_MI_HM10.ino index a384d446a..b91d75d31 100644 --- a/tasmota/xsns_92_MI_HM10.ino +++ b/tasmota/xsns_92_MI_HM10.ino @@ -47,14 +47,19 @@ uint8_t HM10_TASK_LIST[HM10_MAX_TASK_NUMBER+1][2]; // first value: kind of ta char HM10_RX_STRING[HM10_MAX_RX_BUF] = {0}; struct { - uint8_t current_task_delay; // number of 100ms-cycles + uint8_t current_task_delay; // number of 100ms-cycles uint8_t last_command; uint16_t firmware; struct { uint32_t init:1; uint32_t subscribed:1; + uint32_t pending_task:1; // TODO: more to come } mode; + struct { + uint8_t sensor; // points to to the number 0...255 + // TODO: more to come + } state; } HM10; #pragma pack(1) @@ -96,17 +101,32 @@ std::vector MIBLEsensors; #define D_CMND_HM10 "HM10" -const char S_JSON_HM10_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_HM10 "%s\":%d}"; -const char S_JSON_HM10_COMMAND[] PROGMEM = "{\"" D_CMND_HM10 "%s\"}"; -const char kHM10_Commands[] PROGMEM = "Track|Play"; +// const char S_JSON_HM10_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_HM10 "%s\":%d}"; +// const char S_JSON_HM10_COMMAND[] PROGMEM = "{\"" D_CMND_HM10 "%s\"}"; +// const char kHM10_Commands[] PROGMEM = "Track|Play"; + +const char kHM10SlaveID0[] PROGMEM = ""; +const char kHM10SlaveID1[] PROGMEM = ""; +const char kHM10SlaveID2[] PROGMEM = ""; +const char kHM10SlaveID3[] PROGMEM = ""; +const char kHM10SlaveID4[] PROGMEM = "A4C138"; +const char * kHM10SlaveID[] PROGMEM = {kHM10SlaveID0,kHM10SlaveID1,kHM10SlaveID2,kHM10SlaveID3,kHM10SlaveID4}; + + +// const char kHM10Mac0[] PROGMEM = "A4C138ED815A"; +// const char kHM10Mac1[] PROGMEM = "A4C1382AC8B3"; +// const char * kHM10Mac[] PROGMEM ={kHM10Mac0, kHM10Mac1}; + +uint8_t HM10Mac[2][6]={0xA4,0xC1,0x38,0xED,0x81,0x5A, + 0xA4,0xC1,0x38,0x2A,0xC8,0xB3}; /*********************************************************************************************\ * enumerations \*********************************************************************************************/ -enum HM10_Commands { - CMND_HM10_TRACK -}; +// enum HM10_Commands { +// CMND_HM10_TRACK +// }; /*********************************************************************************************\ * command defines @@ -130,9 +150,11 @@ enum HM10_Commands { #define TASK_HM10_NAME 8 // query device name #define TASK_HM10_FEEDBACK 9 // get device response #define TASK_HM10_DISCONN 10 // disconnect -#define TASK_HM10_SUBSCR 11 // subscribe to service handle -#define TASK_HM10_READ 12 // read from handle +#define TASK_HM10_SUBSCR 11 // subscribe to service handle 37 +#define TASK_HM10_READ 12 // read from handle 36 #define TASK_HM10_FINDALLCHARS 13 // read all available characteristics +#define TASK_HM10_UNSUBSCR 14 // subscribe service handle 37 +#define TASK_HM10_DELAY_SUB 15 // start reading from subscription delayed #define TASK_HM10_DONE 99 // used, if there was a task in the slot or just to wait @@ -152,19 +174,33 @@ void HM10_TaskReplaceInSlot(uint8_t task, uint8_t slot){ HM10_TASK_LIST[slot][0] = task; } -void HM10_Reset(void) { HM10_Launchtask(TASK_HM10_ROLE1,0,1); // set role to 1 - HM10_Launchtask(TASK_HM10_IMME1,1,1); // set imme to 1 - HM10_Launchtask(TASK_HM10_RESET,2,1); // reset Device - HM10_Launchtask(TASK_HM10_VERSION,3,10); // read SW Version - HM10_Launchtask(TASK_HM10_DISC,4,1); // disscovery - HM10_Launchtask(TASK_HM10_CONN,5,5); // connect - HM10_Launchtask(TASK_HM10_FEEDBACK,6,35); // get OK+CONN - HM10_Launchtask(TASK_HM10_SUBSCR,7,20); // subscribe - HM10_Launchtask(TASK_HM10_READ,8,35); // read - HM10_Launchtask(TASK_HM10_READ,9,35); // read - HM10_Launchtask(TASK_HM10_READ,10,35); // read - HM10_Launchtask(TASK_HM10_DISCONN,11,250); // disconnect - } +void HM10_Reset(void) { HM10_Launchtask(TASK_HM10_DISCONN,0,1); // disconnect + HM10_Launchtask(TASK_HM10_ROLE1,1,1); // set role 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_VERSION,4,10); // read SW Version + HM10_Launchtask(TASK_HM10_DISC,5,1); // disscovery + } + +void HM10_Read_Sensor(void) { + HM10_Launchtask(TASK_HM10_CONN,0,1); // connect + HM10_Launchtask(TASK_HM10_FEEDBACK,1,35); // get OK+CONN + HM10_Launchtask(TASK_HM10_SUBSCR,2,10); // subscribe + HM10_Launchtask(TASK_HM10_READ,3,15); // read + HM10_Launchtask(TASK_HM10_READ,4,15); // read + HM10_Launchtask(TASK_HM10_READ,5,15); // read + HM10_Launchtask(TASK_HM10_UNSUBSCR,6,10); // unsubscribe + HM10_Launchtask(TASK_HM10_DISCONN,7,0); // disconnect + } + +void HM10_Read_Sensor1(void) { + HM10_Launchtask(TASK_HM10_CONN,0,1); // connect + HM10_Launchtask(TASK_HM10_FEEDBACK,1,35); // get OK+CONN + HM10_Launchtask(TASK_HM10_SUBSCR,2,10); // subscribe + HM10_Launchtask(TASK_HM10_UNSUBSCR,3,60); // unsubscribe + HM10_Launchtask(TASK_HM10_DISCONN,4,0); // disconnect + } + /** * @brief Return the slot number of a known sensor or return create new sensor slot @@ -233,7 +269,8 @@ void HM10SerialInit(void) { DEBUG_SENSOR_LOG(PSTR("HM10: claim HW")); } HM10_Reset(); - HM10.mode.init = true; + HM10.mode.pending_task = 1; + HM10.mode.init = 1; AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s_TASK_LIST initialized, now return to main loop"),D_CMND_HM10); } return; @@ -268,12 +305,33 @@ void HM10ParseResponse(char *buf) { } } +void HM10readTempHum(char *_buf){ + DEBUG_SENSOR_LOG(PSTR("HM10: raw data: %x%x%x%x%x%x%x"),_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6]); + if(_buf[0] != 0 && _buf[1] != 0){ + memcpy(&LYWSD03,(void *)_buf,3); + DEBUG_SENSOR_LOG(PSTR("HM10: Temperature * 100: %u, Humidity: %u"),LYWSD03.temp,LYWSD03.hum); + // uint8_t _serial[6] = {0}; + uint32_t _slot = MIBLEgetSensorSlot(HM10Mac[HM10.state.sensor], 4); + DEBUG_SENSOR_LOG(PSTR("MIBLE: Sensor slot: %u"), _slot); + static float _tempFloat; + _tempFloat=(float)(LYWSD03.temp)/100.0f; + if(_tempFloat<60){ + MIBLEsensors.at(_slot).LYWSD0x.temp=_tempFloat; + } + _tempFloat=(float)LYWSD03.hum; + if(_tempFloat<100){ + MIBLEsensors.at(_slot).LYWSD0x.hum = _tempFloat; + DEBUG_SENSOR_LOG(PSTR("LYWSD03: hum updated")); + } + } +} + /*********************************************************************************************\ * handle the return value from the HM10 \*********************************************************************************************/ bool HM10SerialHandleFeedback(){ - bool success = false; // true disables possible repetition of commands, set to false only for debugging + bool success = false; // true disables possible repetition of commands, set to false only for debugging uint32_t i = 0; char ret[HM10_MAX_RX_BUF] = {0}; // reset array with zeros @@ -287,31 +345,14 @@ bool HM10SerialHandleFeedback(){ success = true; } if(HM10.mode.subscribed) { - DEBUG_SENSOR_LOG(PSTR("HM10: raw data: %x%x%x%x%x%x%x"),ret[0],ret[1],ret[2],ret[3],ret[4],ret[5],ret[6]); - if(ret[0] != 0 && ret[1] != 0){ - memcpy(&LYWSD03,(void *)ret,3); - DEBUG_SENSOR_LOG(PSTR("HM10: Temperature * 100: %u, Humidity: %u"),LYWSD03.temp,LYWSD03.hum); - uint8_t _serial[6] = {0}; - uint32_t _slot = MIBLEgetSensorSlot(_serial, 4); - DEBUG_SENSOR_LOG(PSTR("MIBLE: Sensor slot: %u"), _slot); - static float _tempFloat; - _tempFloat=(float)(LYWSD03.temp)/100.0f; - if(_tempFloat<60){ - MIBLEsensors.at(_slot).LYWSD0x.temp=_tempFloat; - } - _tempFloat=(float)LYWSD03.hum; - if(_tempFloat<100){ - MIBLEsensors.at(_slot).LYWSD0x.hum = _tempFloat; - DEBUG_SENSOR_LOG(PSTR("MJ_HT_V1: hum updated")); - } - } + HM10readTempHum(ret); } else if(success) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s response: %s"),D_CMND_HM10, (char *)ret); HM10ParseResponse(ret); } else { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s got no response"),D_CMND_HM10); + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s got no response"),D_CMND_HM10); } return success; } @@ -321,6 +362,7 @@ bool HM10SerialHandleFeedback(){ \*********************************************************************************************/ void HM10_TaskEvery100ms(){ + HM10SerialHandleFeedback(); // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK to be done %u"),D_CMND_HM10,HM10_TASK_LIST[0][0]); if (HM10.current_task_delay == 0) { uint8_t i = 0; @@ -367,7 +409,11 @@ void HM10_TaskEvery100ms(){ HM10.current_task_delay = 2; // set task delay HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); runningTaskLoop = false; - HM10Serial->write("AT+CONA4C138ED815A"); + // HM10Serial->write("AT+CONA4C138ED815A"); + 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]); + HM10Serial->write(_con); + // HM10Serial->write(kHM10Mac[HM10.state.sensor]); break; case TASK_HM10_DISCONN: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s disconnect"),D_CMND_HM10); @@ -375,7 +421,6 @@ void HM10_TaskEvery100ms(){ HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); runningTaskLoop = false; HM10Serial->write("AT"); - HM10.mode.subscribed = false; break; case TASK_HM10_RESET: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s Reset Device"),D_CMND_HM10); @@ -386,11 +431,19 @@ void HM10_TaskEvery100ms(){ break; case TASK_HM10_SUBSCR: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s subscribe"),D_CMND_HM10); - HM10.current_task_delay = 15; // set task delay - HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); + HM10.current_task_delay = 25; // set task delay + HM10_TaskReplaceInSlot(TASK_HM10_DELAY_SUB,i); runningTaskLoop = false; HM10Serial->write("AT+NOTIFY_ON0037"); - + break; + case TASK_HM10_UNSUBSCR: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s un-subscribe"),D_CMND_HM10); + HM10.current_task_delay = 5; // set task delay + HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); + runningTaskLoop = false; + HM10.mode.subscribed = false; + HM10Serial->write("AT+NOTIFYOFF0037"); + break; case TASK_HM10_READ: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s read handle 0036"),D_CMND_HM10); HM10.current_task_delay = 0; // set task delay @@ -398,12 +451,14 @@ void HM10_TaskEvery100ms(){ runningTaskLoop = false; HM10Serial->write("AT+READDATA0036?"); HM10.mode.subscribed = true; + break; case TASK_HM10_FINDALLCHARS: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s find all chars"),D_CMND_HM10); HM10.current_task_delay = 35; // set task delay HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); runningTaskLoop = false; HM10Serial->write("AT+FINDALLCHARS?"); + break; case TASK_HM10_FEEDBACK: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s get response"),D_CMND_HM10); HM10SerialHandleFeedback(); @@ -411,6 +466,14 @@ void HM10_TaskEvery100ms(){ HM10_TASK_LIST[i][0] = TASK_HM10_DONE; // no feedback for reset runningTaskLoop = false; break; + case TASK_HM10_DELAY_SUB: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s start reading"),D_CMND_HM10); + HM10SerialHandleFeedback(); + HM10.current_task_delay = HM10_TASK_LIST[i+1][1];; // set task delay + HM10_TASK_LIST[i][0] = TASK_HM10_DONE; // no feedback for reset + HM10.mode.subscribed = true; + runningTaskLoop = false; + break; case TASK_HM10_DONE: // this entry was already handled // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sFound done HM10_TASK"),D_CMND_HM10); @@ -426,6 +489,7 @@ void HM10_TaskEvery100ms(){ runningTaskLoop = false; // return to main loop // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sUpdate GUI via AJAX"),D_CMND_HM10); // HM10_GUI_NEEDS_UPDATE = true; + HM10.mode.pending_task = 0; break; } } @@ -437,6 +501,26 @@ void HM10_TaskEvery100ms(){ } } +void HM10EverySecond(){ + if(HM10.firmware == 0) return; + if(HM10.mode.pending_task == 1) return; + static uint32_t _counter = 0; + if(_counter == 0) { + HM10_Read_Sensor1(); + HM10.mode.pending_task == 1; + _counter = 60; + HM10.state.sensor++; + if (HM10.state.sensor>1) { + HM10.state.sensor=0; + } + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s active sensor now: %u"),D_CMND_HM10, HM10.state.sensor); + } + _counter--; +} + +/*********************************************************************************************\ + * Presentation +\*********************************************************************************************/ const char HTTP_HM10[] PROGMEM = "{s}HM10" " Firmware " "{m}%u{e}"; @@ -494,6 +578,10 @@ bool Xsns92(uint8_t function) break; } break; + case FUNC_EVERY_SECOND: + HM10EverySecond(); + DEBUG_SENSOR_LOG(PSTR("HM10: every second")); + break; case FUNC_JSON_APPEND: HM10Show(1); break; From b64abc9757e2ec211a4adedf5d6227e90a015bc6 Mon Sep 17 00:00:00 2001 From: Staars Date: Sun, 2 Feb 2020 17:44:26 +0100 Subject: [PATCH 07/17] dynamic sensor discovery --- tasmota/xsns_92_MI_HM10.ino | 204 +++++++++++++++++++++++------------- 1 file changed, 130 insertions(+), 74 deletions(-) diff --git a/tasmota/xsns_92_MI_HM10.ino b/tasmota/xsns_92_MI_HM10.ino index b91d75d31..8e1b1e699 100644 --- a/tasmota/xsns_92_MI_HM10.ino +++ b/tasmota/xsns_92_MI_HM10.ino @@ -70,26 +70,20 @@ struct { #pragma pack(0) 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 showedUp; + float temp; //Flora, MJ_HT_V1, LYWSD0x union { struct { - float temp; float moisture; float fertility; uint16_t lux; - } Flora; + }; // Flora struct { - float temp; float hum; uint8_t bat; - } MJ_HT_V1; - struct { - float temp; - float hum; - uint8_t bat; - } LYWSD0x; // LYWSD02 and LYWSD03 + }; // MJ_HT_V1, LYWSD0x }; }; @@ -101,24 +95,21 @@ std::vector MIBLEsensors; #define D_CMND_HM10 "HM10" -// const char S_JSON_HM10_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_HM10 "%s\":%d}"; -// const char S_JSON_HM10_COMMAND[] PROGMEM = "{\"" D_CMND_HM10 "%s\"}"; -// const char kHM10_Commands[] PROGMEM = "Track|Play"; +uint8_t kHM10SlaveID[4][3] = { 0xC4,0x7C,0x8D, // Flora + 0x58,0x2D,0x34, // MJ_HT_V1 + 0xE7,0x2E,0x00, // LYWSD02 + 0xA4,0xC1,0x38, // LYWSD03 + }; -const char kHM10SlaveID0[] PROGMEM = ""; -const char kHM10SlaveID1[] PROGMEM = ""; -const char kHM10SlaveID2[] PROGMEM = ""; -const char kHM10SlaveID3[] PROGMEM = ""; -const char kHM10SlaveID4[] PROGMEM = "A4C138"; -const char * kHM10SlaveID[] PROGMEM = {kHM10SlaveID0,kHM10SlaveID1,kHM10SlaveID2,kHM10SlaveID3,kHM10SlaveID4}; +const char kHM10SlaveType1[] PROGMEM = "Flora"; +const char kHM10SlaveType2[] PROGMEM = "MJ_HT_V1"; +const char kHM10SlaveType3[] PROGMEM = "LYWSD02"; +const char kHM10SlaveType4[] PROGMEM = "LYWSD03"; +const char * kHM10SlaveType[] PROGMEM = {kHM10SlaveType1,kHM10SlaveType2,kHM10SlaveType3,kHM10SlaveType4}; -// const char kHM10Mac0[] PROGMEM = "A4C138ED815A"; -// const char kHM10Mac1[] PROGMEM = "A4C1382AC8B3"; -// const char * kHM10Mac[] PROGMEM ={kHM10Mac0, kHM10Mac1}; - -uint8_t HM10Mac[2][6]={0xA4,0xC1,0x38,0xED,0x81,0x5A, - 0xA4,0xC1,0x38,0x2A,0xC8,0xB3}; +// uint8_t HM10Mac[2][6]={0xA4,0xC1,0x38,0xED,0x81,0x5A, +// 0xA4,0xC1,0x38,0x2A,0xC8,0xB3}; /*********************************************************************************************\ * enumerations @@ -174,12 +165,12 @@ void HM10_TaskReplaceInSlot(uint8_t task, uint8_t slot){ HM10_TASK_LIST[slot][0] = task; } -void HM10_Reset(void) { HM10_Launchtask(TASK_HM10_DISCONN,0,1); // disconnect +void HM10_Reset(void) { HM10_Launchtask(TASK_HM10_DISCONN,0,1); // disconnect HM10_Launchtask(TASK_HM10_ROLE1,1,1); // set role 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_VERSION,4,10); // read SW Version - HM10_Launchtask(TASK_HM10_DISC,5,1); // disscovery + HM10_Launchtask(TASK_HM10_VERSION,4,10); // read SW Version + HM10_Launchtask(TASK_HM10_DISC,5,50); // discovery } 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 * * @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 */ 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()); for(uint32_t i=0; i= '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 \*********************************************************************************************/ @@ -298,8 +317,18 @@ void HM10ParseResponse(char *buf) { memcpy((void *)_fw,(void *)(buf+8),3); HM10.firmware = atoi(_fw); 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 { DEBUG_SENSOR_LOG(PSTR("HM10: empty response")); } @@ -311,16 +340,18 @@ void HM10readTempHum(char *_buf){ memcpy(&LYWSD03,(void *)_buf,3); DEBUG_SENSOR_LOG(PSTR("HM10: Temperature * 100: %u, Humidity: %u"),LYWSD03.temp,LYWSD03.hum); // 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); static float _tempFloat; _tempFloat=(float)(LYWSD03.temp)/100.0f; if(_tempFloat<60){ - MIBLEsensors.at(_slot).LYWSD0x.temp=_tempFloat; + MIBLEsensors.at(_slot).temp=_tempFloat; } _tempFloat=(float)LYWSD03.hum; if(_tempFloat<100){ - MIBLEsensors.at(_slot).LYWSD0x.hum = _tempFloat; + MIBLEsensors.at(_slot).hum = _tempFloat; DEBUG_SENSOR_LOG(PSTR("LYWSD03: hum updated")); } } @@ -411,7 +442,7 @@ void HM10_TaskEvery100ms(){ runningTaskLoop = false; // HM10Serial->write("AT+CONA4C138ED815A"); 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(kHM10Mac[HM10.state.sensor]); break; @@ -505,17 +536,31 @@ void HM10EverySecond(){ if(HM10.firmware == 0) return; if(HM10.mode.pending_task == 1) return; static uint32_t _counter = 0; - if(_counter == 0) { - HM10_Read_Sensor1(); - HM10.mode.pending_task == 1; - _counter = 60; - HM10.state.sensor++; - if (HM10.state.sensor>1) { + 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(); + } + else { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s active sensor not type 3: %u"),D_CMND_HM10, HM10.state.sensor); + } + } + 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; + _counter = 60; + } + else { + 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 = "{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) { - if (json) { - if (MIBLEsensors.size()==0) return; - - char temperature[33]; - dtostrfd(MIBLEsensors.at(0).LYWSD0x.temp, Settings.flag2.temperature_resolution, temperature); - char humidity[33]; - dtostrfd(MIBLEsensors.at(0).LYWSD0x.hum, Settings.flag2.humidity_resolution, humidity); - - ResponseAppend_P(JSON_SNS_TEMPHUM, F("LYWSD03"), temperature, humidity); + if (json) { + for (uint32_t i = 0; i < MIBLEsensors.size(); i++) { + // char slave[33]; + // sprintf_P(slave,"%s-%02x%02x%02x",MIBLESlaveFlora,MIBLEsensors.at(i).serial[2],MIBLEsensors.at(i).serial[1],MIBLEsensors.at(i).serial[0]); + 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]; + dtostrfd(MIBLEsensors.at(i).hum, Settings.flag2.humidity_resolution, humidity); + ResponseAppend_P(JSON_SNS_TEMPHUM, kHM10SlaveType[MIBLEsensors.at(i).type-1], temperature, humidity); + } + } #ifdef USE_WEBSERVER } else { WSContentSend_PD(HTTP_HM10, HM10.firmware); - if (MIBLEsensors.size()==0) return; - - char temperature[33]; - dtostrfd(MIBLEsensors.at(0).LYWSD0x.temp, Settings.flag2.temperature_resolution, temperature); - char humidity[33]; - dtostrfd(MIBLEsensors.at(0).LYWSD0x.hum, Settings.flag2.humidity_resolution, humidity); - - WSContentSend_PD(HTTP_SNS_TEMP, F("LYWSD03"), temperature, TempUnit()); - WSContentSend_PD(HTTP_SNS_HUM, F("LYWSD03"), humidity); + 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]; + 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]; + dtostrfd(MIBLEsensors.at(i).hum, Settings.flag2.humidity_resolution, humidity); + WSContentSend_PD(HTTP_SNS_HUM, kHM10SlaveType[MIBLEsensors.at(i).type-1], humidity); + } + } #endif // USE_WEBSERVER } } @@ -566,10 +619,13 @@ bool Xsns92(uint8_t function) case FUNC_INIT: HM10SerialInit(); // init and start communication break; + case FUNC_EVERY_50_MSECOND: + HM10SerialHandleFeedback(); // -> sniff for device feedback + break; case FUNC_EVERY_100_MSECOND: if (HM10_TASK_LIST[0][0] == TASK_HM10_NOTASK) { // no task running // DEBUG_SENSOR_LOG(PSTR("HM10: no TASK in array")); - HM10SerialHandleFeedback(); // -> sniff for device feedback + // HM10SerialHandleFeedback(); // -> sniff for device feedback break; } else { @@ -580,7 +636,7 @@ bool Xsns92(uint8_t function) break; case FUNC_EVERY_SECOND: HM10EverySecond(); - DEBUG_SENSOR_LOG(PSTR("HM10: every second")); + // DEBUG_SENSOR_LOG(PSTR("HM10: every second")); break; case FUNC_JSON_APPEND: HM10Show(1); From 46e06a6fcb832f46cfa99fbd09213a4f473ad2bf Mon Sep 17 00:00:00 2001 From: Staars Date: Sun, 2 Feb 2020 19:07:31 +0100 Subject: [PATCH 08/17] error fixes --- tasmota/xsns_92_MI_HM10.ino | 112 ++++++++++++++++++++++++++---------- 1 file changed, 81 insertions(+), 31 deletions(-) diff --git a/tasmota/xsns_92_MI_HM10.ino b/tasmota/xsns_92_MI_HM10.ino index 8e1b1e699..18c101101 100644 --- a/tasmota/xsns_92_MI_HM10.ino +++ b/tasmota/xsns_92_MI_HM10.ino @@ -41,8 +41,6 @@ TasmotaSerial *HM10Serial; #define HM10_MAX_TASK_NUMBER 12 uint8_t HM10_TASK_LIST[HM10_MAX_TASK_NUMBER+1][2]; // first value: kind of task - second value: delay in x * 100ms - - #define HM10_MAX_RX_BUF 512 char HM10_RX_STRING[HM10_MAX_RX_BUF] = {0}; @@ -535,29 +533,27 @@ void HM10_TaskEvery100ms(){ void HM10EverySecond(){ if(HM10.firmware == 0) return; if(HM10.mode.pending_task == 1) return; - static uint32_t _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(); - } - else { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s active sensor not type 3: %u"),D_CMND_HM10, HM10.state.sensor); - } - } - else { + if (MIBLEsensors.size()==0) { HM10.mode.pending_task = 1; HM10_Launchtask(TASK_HM10_DISC,0,1); // start new discovery return; + } + static uint32_t _counter = 0; + static uint32_t _nextSensorSlot = 0; + if(_counter==0) { + HM10.state.sensor = _nextSensorSlot; + _nextSensorSlot++; + if(MIBLEsensors.at(HM10.state.sensor).type==4) { + HM10.mode.pending_task = 1; + HM10_Read_Sensor1(); + } + else { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s active sensor not type 3: %u"),D_CMND_HM10, HM10.state.sensor); } if (HM10.state.sensor==MIBLEsensors.size()-1) { - HM10.state.sensor=0; + _nextSensorSlot= 0; _counter = 60; } - else { - HM10.state.sensor++; - } AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s active sensor now: %u"),D_CMND_HM10, HM10.state.sensor); } if(_counter>0) _counter--; @@ -573,32 +569,86 @@ const char HTTP_HM10[] PROGMEM = const char HTTP_HM10_SERIAL[] PROGMEM = "{s}%s" " Address" "{m}%02x:%02x:%02x:%02x:%02x:%02x%{e}"; +const char HTTP_BATTERY[] PROGMEM = + "{s}%s" " Battery" "{m}%u%%{e}"; + +const char HTTP_HM10_FLORA_DATA[] PROGMEM = + "{s}%s" " Fertility" "{m}%sus/cm{e}"; + void HM10Show(bool json) { if (json) { for (uint32_t i = 0; i < MIBLEsensors.size(); i++) { - // char slave[33]; - // sprintf_P(slave,"%s-%02x%02x%02x",MIBLESlaveFlora,MIBLEsensors.at(i).serial[2],MIBLEsensors.at(i).serial[1],MIBLEsensors.at(i).serial[0]); + char slave[33]; + sprintf_P(slave,"%s-%02x%02x%02x",kHM10SlaveType[MIBLEsensors.at(i).type-1],MIBLEsensors.at(i).serial[2],MIBLEsensors.at(i).serial[1],MIBLEsensors.at(i).serial[0]); 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]; - 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(PSTR(",\"%s\":{"),slave); + if(MIBLEsensors.at(i).temp!=-1000.0f){ // this is the error code -> no temperature + ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%s"), temperature); + } + if (MIBLEsensors.at(i).type==1){ + char lux[33]; + char moisture[33]; + char fertility[33]; + dtostrfd((float)MIBLEsensors.at(i).lux, 0, lux); + dtostrfd(MIBLEsensors.at(i).moisture, 0, moisture); + dtostrfd(MIBLEsensors.at(i).fertility, 0, fertility); + if(MIBLEsensors.at(i).lux!=0xffff){ // this is the error code -> no temperature + ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%s"), lux); + } + if(MIBLEsensors.at(i).moisture!=-1000.0f){ // this is the error code -> no temperature + ResponseAppend_P(PSTR(",\"" D_JSON_MOISTURE "\":%s"), moisture); + } + if(MIBLEsensors.at(i).fertility!=-1000.0f){ // this is the error code -> no temperature + ResponseAppend_P(PSTR(",\"Fertility\":%s"), fertility); + } + } + if (MIBLEsensors.at(i).type>1){ + char humidity[33]; + dtostrfd(MIBLEsensors.at(i).hum, Settings.flag2.humidity_resolution, humidity); + if(MIBLEsensors.at(i).hum!=-1.0f){ // this is the error code -> no temperature + ResponseAppend_P(PSTR(",\"" D_JSON_HUMIDITY "\":%s"), humidity); + } + if(MIBLEsensors.at(i).bat!=0xff){ // this is the error code -> no temperature + ResponseAppend_P(PSTR(",\"Battery\":%u"), MIBLEsensors.at(i).bat); + } + } + ResponseAppend_P(PSTR("}")); } #ifdef USE_WEBSERVER } else { WSContentSend_PD(HTTP_HM10, HM10.firmware); 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]; - 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).temp!=-1000.0f){ + char temperature[33]; + 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){ + if(MIBLEsensors.at(i).lux!=0xffff){ // this is the error code -> no temperature + WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kHM10SlaveType[MIBLEsensors.at(i).type-1], MIBLEsensors.at(i).lux); + } + if(MIBLEsensors.at(i).moisture!=-1000.0f){ // this is the error code -> no temperature + WSContentSend_PD(HTTP_SNS_MOISTURE, kHM10SlaveType[MIBLEsensors.at(i).type-1], MIBLEsensors.at(i).moisture); + } + if(MIBLEsensors.at(i).fertility!=-1000.0f){ // this is the error code -> no temperature + char fertility[33]; + dtostrfd(MIBLEsensors.at(i).fertility, 0, fertility); + WSContentSend_PD(HTTP_HM10_FLORA_DATA, kHM10SlaveType[MIBLEsensors.at(i).type-1], fertility); + } + } if (MIBLEsensors.at(i).type>1){ // everything "above" Flora - char humidity[33]; - dtostrfd(MIBLEsensors.at(i).hum, Settings.flag2.humidity_resolution, humidity); - WSContentSend_PD(HTTP_SNS_HUM, kHM10SlaveType[MIBLEsensors.at(i).type-1], humidity); + if(MIBLEsensors.at(i).hum!=-1.0f){ // this is the error code -> no humidity + char humidity[33]; + dtostrfd(MIBLEsensors.at(i).hum, Settings.flag2.humidity_resolution, humidity); + WSContentSend_PD(HTTP_SNS_HUM, kHM10SlaveType[MIBLEsensors.at(i).type-1], humidity); + } + if(MIBLEsensors.at(i).bat!=0xff){ + WSContentSend_PD(HTTP_BATTERY, kHM10SlaveType[MIBLEsensors.at(i).type-1], MIBLEsensors.at(i).bat); + } } } #endif // USE_WEBSERVER From 0b8040c3c070ca42a4aea24036936d9454165b63 Mon Sep 17 00:00:00 2001 From: Staars Date: Tue, 4 Feb 2020 08:13:09 +0100 Subject: [PATCH 09/17] add battery, some fixes --- tasmota/xsns_92_MI_HM10.ino | 85 +++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 23 deletions(-) diff --git a/tasmota/xsns_92_MI_HM10.ino b/tasmota/xsns_92_MI_HM10.ino index 18c101101..185e498a2 100644 --- a/tasmota/xsns_92_MI_HM10.ino +++ b/tasmota/xsns_92_MI_HM10.ino @@ -50,8 +50,10 @@ struct { uint16_t firmware; struct { uint32_t init:1; - uint32_t subscribed:1; uint32_t pending_task:1; + uint32_t subscribed:1; + uint32_t awaitingHT:1; + uint32_t awaitingB:1; // TODO: more to come } mode; struct { @@ -93,6 +95,11 @@ std::vector MIBLEsensors; #define D_CMND_HM10 "HM10" +#define FLORA 1 +#define MJ_HT_V1 2 +#define LYWSD02 3 +#define LYWSD03MMC 4 + uint8_t kHM10SlaveID[4][3] = { 0xC4,0x7C,0x8D, // Flora 0x58,0x2D,0x34, // MJ_HT_V1 0xE7,0x2E,0x00, // LYWSD02 @@ -140,10 +147,11 @@ const char * kHM10SlaveType[] PROGMEM = {kHM10SlaveType1,kHM10SlaveType2,kHM10Sl #define TASK_HM10_FEEDBACK 9 // get device response #define TASK_HM10_DISCONN 10 // disconnect #define TASK_HM10_SUBSCR 11 // subscribe to service handle 37 -#define TASK_HM10_READ 12 // read from handle 36 +#define TASK_HM10_READ_HT 12 // read from handle 36 -> Hum & Temp #define TASK_HM10_FINDALLCHARS 13 // read all available characteristics #define TASK_HM10_UNSUBSCR 14 // subscribe service handle 37 #define TASK_HM10_DELAY_SUB 15 // start reading from subscription delayed +#define TASK_HM10_READ_BT 16 // read from handle 3A -> Battery #define TASK_HM10_DONE 99 // used, if there was a task in the slot or just to wait @@ -175,9 +183,9 @@ void HM10_Read_Sensor(void) { HM10_Launchtask(TASK_HM10_CONN,0,1); // connect HM10_Launchtask(TASK_HM10_FEEDBACK,1,35); // get OK+CONN HM10_Launchtask(TASK_HM10_SUBSCR,2,10); // subscribe - HM10_Launchtask(TASK_HM10_READ,3,15); // read - HM10_Launchtask(TASK_HM10_READ,4,15); // read - HM10_Launchtask(TASK_HM10_READ,5,15); // read + HM10_Launchtask(TASK_HM10_READ_HT,3,15); // read + HM10_Launchtask(TASK_HM10_READ_HT,4,15); // read + HM10_Launchtask(TASK_HM10_READ_HT,5,15); // read HM10_Launchtask(TASK_HM10_UNSUBSCR,6,10); // unsubscribe HM10_Launchtask(TASK_HM10_DISCONN,7,0); // disconnect } @@ -186,8 +194,9 @@ void HM10_Read_Sensor1(void) { HM10_Launchtask(TASK_HM10_CONN,0,1); // connect HM10_Launchtask(TASK_HM10_FEEDBACK,1,35); // get OK+CONN HM10_Launchtask(TASK_HM10_SUBSCR,2,10); // subscribe - HM10_Launchtask(TASK_HM10_UNSUBSCR,3,60); // unsubscribe - HM10_Launchtask(TASK_HM10_DISCONN,4,0); // disconnect + HM10_Launchtask(TASK_HM10_UNSUBSCR,3,40); // unsubscribe + HM10_Launchtask(TASK_HM10_READ_BT,4,5); // read Battery + HM10_Launchtask(TASK_HM10_DISCONN,5,5); // disconnect } @@ -222,14 +231,14 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_serial)[6], uint8_t _type){ } return i; } - DEBUG_SENSOR_LOG(PSTR("MIBLE i: %x %x %x %x %x %x"), 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]); - DEBUG_SENSOR_LOG(PSTR("MIBLE n: %x %x %x %x %x %x"), _serial[5], _serial[4], _serial[3],_serial[2],_serial[1],_serial[0]); + DEBUG_SENSOR_LOG(PSTR("MIBLE i: %x %x %x %x %x %x"), MIBLEsensors.at(i).serial[0], MIBLEsensors.at(i).serial[1],MIBLEsensors.at(i).serial[2],MIBLEsensors.at(i).serial[3],MIBLEsensors.at(i).serial[4],MIBLEsensors.at(i).serial[5]); + DEBUG_SENSOR_LOG(PSTR("MIBLE n: %x %x %x %x %x %x"), _serial[0], _serial[1], _serial[2],_serial[3],_serial[4],_serial[5]); } DEBUG_SENSOR_LOG(PSTR("MIBLE: found new sensor")); mi_sensor_t _newSensor; memcpy(_newSensor.serial,_serial, sizeof(_serial)); _newSensor.type = _type; - _newSensor.showedUp = 1; + _newSensor.showedUp = 1; // does not matter for HM-10 _newSensor.temp =-1000.0f; switch (_type) { @@ -355,6 +364,21 @@ void HM10readTempHum(char *_buf){ } } +void HM10readBat(char *_buf){ + DEBUG_SENSOR_LOG(PSTR("HM10: raw data: %x%x%x%x%x%x%x"),_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6]); + if(_buf[0] != 0){ + DEBUG_SENSOR_LOG(PSTR("HM10: Battery: %u"),_buf[0]); + // uint8_t _serial[6] = {0}; + // uint32_t _slot = MIBLEgetSensorSlot(HM10Mac[HM10.state.sensor], 4); + uint32_t _slot = HM10.state.sensor; + + DEBUG_SENSOR_LOG(PSTR("MIBLE: Sensor slot: %u"), _slot); + if(_buf[0]<101){ + MIBLEsensors.at(_slot).bat=_buf[0]; + } + } +} + /*********************************************************************************************\ * handle the return value from the HM10 \*********************************************************************************************/ @@ -373,8 +397,15 @@ bool HM10SerialHandleFeedback(){ i++; success = true; } - if(HM10.mode.subscribed) { + if(HM10.mode.awaitingHT) { HM10readTempHum(ret); + HM10.mode.awaitingHT = false; + HM10.current_task_delay = 0; + } + else if(HM10.mode.awaitingB) { + HM10readBat(ret); + HM10.mode.awaitingB = false; + HM10.current_task_delay = 0; } else if(success) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s response: %s"),D_CMND_HM10, (char *)ret); @@ -442,7 +473,7 @@ void HM10_TaskEvery100ms(){ char _con[20]; 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(kHM10Mac[HM10.state.sensor]); + HM10.mode.awaitingB = false; break; case TASK_HM10_DISCONN: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s disconnect"),D_CMND_HM10); @@ -470,20 +501,28 @@ void HM10_TaskEvery100ms(){ HM10.current_task_delay = 5; // set task delay HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); runningTaskLoop = false; - HM10.mode.subscribed = false; + HM10.mode.awaitingHT = false; HM10Serial->write("AT+NOTIFYOFF0037"); break; - case TASK_HM10_READ: + case TASK_HM10_READ_HT: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s read handle 0036"),D_CMND_HM10); HM10.current_task_delay = 0; // set task delay HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); runningTaskLoop = false; HM10Serial->write("AT+READDATA0036?"); - HM10.mode.subscribed = true; + HM10.mode.awaitingHT = true; + break; + case TASK_HM10_READ_BT: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s read handle 003A"),D_CMND_HM10); + HM10.current_task_delay = 0; // set task delay + HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); + runningTaskLoop = false; + HM10Serial->write("AT+READDATA003A?"); + HM10.mode.awaitingB = true; break; case TASK_HM10_FINDALLCHARS: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s find all chars"),D_CMND_HM10); - HM10.current_task_delay = 35; // set task delay + HM10.current_task_delay = 5; // set task delay HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); runningTaskLoop = false; HM10Serial->write("AT+FINDALLCHARS?"); @@ -500,7 +539,7 @@ void HM10_TaskEvery100ms(){ HM10SerialHandleFeedback(); HM10.current_task_delay = HM10_TASK_LIST[i+1][1];; // set task delay HM10_TASK_LIST[i][0] = TASK_HM10_DONE; // no feedback for reset - HM10.mode.subscribed = true; + HM10.mode.awaitingHT = true; runningTaskLoop = false; break; @@ -580,7 +619,7 @@ void HM10Show(bool json) if (json) { for (uint32_t i = 0; i < MIBLEsensors.size(); i++) { char slave[33]; - sprintf_P(slave,"%s-%02x%02x%02x",kHM10SlaveType[MIBLEsensors.at(i).type-1],MIBLEsensors.at(i).serial[2],MIBLEsensors.at(i).serial[1],MIBLEsensors.at(i).serial[0]); + sprintf_P(slave,"%s-%02x%02x%02x",kHM10SlaveType[MIBLEsensors.at(i).type-1],MIBLEsensors.at(i).serial[3],MIBLEsensors.at(i).serial[4],MIBLEsensors.at(i).serial[5]); char temperature[33]; // all sensors have temperature dtostrfd(MIBLEsensors.at(i).temp, Settings.flag2.temperature_resolution, temperature); @@ -588,7 +627,7 @@ void HM10Show(bool json) if(MIBLEsensors.at(i).temp!=-1000.0f){ // this is the error code -> no temperature ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%s"), temperature); } - if (MIBLEsensors.at(i).type==1){ + if (MIBLEsensors.at(i).type==FLORA){ char lux[33]; char moisture[33]; char fertility[33]; @@ -605,7 +644,7 @@ void HM10Show(bool json) ResponseAppend_P(PSTR(",\"Fertility\":%s"), fertility); } } - if (MIBLEsensors.at(i).type>1){ + if (MIBLEsensors.at(i).type>FLORA){ char humidity[33]; dtostrfd(MIBLEsensors.at(i).hum, Settings.flag2.humidity_resolution, humidity); if(MIBLEsensors.at(i).hum!=-1.0f){ // this is the error code -> no temperature @@ -621,13 +660,13 @@ void HM10Show(bool json) } else { WSContentSend_PD(HTTP_HM10, HM10.firmware); 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]); + WSContentSend_PD(HTTP_HM10_SERIAL, kHM10SlaveType[MIBLEsensors.at(i).type-1], MIBLEsensors.at(i).serial[0], MIBLEsensors.at(i).serial[1],MIBLEsensors.at(i).serial[2],MIBLEsensors.at(i).serial[3],MIBLEsensors.at(i).serial[4],MIBLEsensors.at(i).serial[5]); if(MIBLEsensors.at(i).temp!=-1000.0f){ char temperature[33]; 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){ + if (MIBLEsensors.at(i).type==FLORA){ if(MIBLEsensors.at(i).lux!=0xffff){ // this is the error code -> no temperature WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kHM10SlaveType[MIBLEsensors.at(i).type-1], MIBLEsensors.at(i).lux); } @@ -640,7 +679,7 @@ void HM10Show(bool json) WSContentSend_PD(HTTP_HM10_FLORA_DATA, kHM10SlaveType[MIBLEsensors.at(i).type-1], fertility); } } - if (MIBLEsensors.at(i).type>1){ // everything "above" Flora + if (MIBLEsensors.at(i).type>FLORA){ // everything "above" Flora if(MIBLEsensors.at(i).hum!=-1.0f){ // this is the error code -> no humidity char humidity[33]; dtostrfd(MIBLEsensors.at(i).hum, Settings.flag2.humidity_resolution, humidity); From e1973fbfffc3d99d48139002f6cb1ef646798967 Mon Sep 17 00:00:00 2001 From: Staars Date: Tue, 4 Feb 2020 14:12:46 +0100 Subject: [PATCH 10/17] fix regression: no temp/hum-read --- tasmota/xsns_92_MI_HM10.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/xsns_92_MI_HM10.ino b/tasmota/xsns_92_MI_HM10.ino index 185e498a2..6065a6c7f 100644 --- a/tasmota/xsns_92_MI_HM10.ino +++ b/tasmota/xsns_92_MI_HM10.ino @@ -355,6 +355,8 @@ void HM10readTempHum(char *_buf){ _tempFloat=(float)(LYWSD03.temp)/100.0f; if(_tempFloat<60){ MIBLEsensors.at(_slot).temp=_tempFloat; + HM10.mode.awaitingHT = false; + HM10.current_task_delay = 0; } _tempFloat=(float)LYWSD03.hum; if(_tempFloat<100){ @@ -399,8 +401,6 @@ bool HM10SerialHandleFeedback(){ } if(HM10.mode.awaitingHT) { HM10readTempHum(ret); - HM10.mode.awaitingHT = false; - HM10.current_task_delay = 0; } else if(HM10.mode.awaitingB) { HM10readBat(ret); From c4d92d6368277f1091f80966f2bebac697472ae3 Mon Sep 17 00:00:00 2001 From: Staars Date: Tue, 4 Feb 2020 15:02:47 +0100 Subject: [PATCH 11/17] add command interface: HM10SCAN and HM10PERIOD --- tasmota/xsns_92_MI_HM10.ino | 69 +++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/tasmota/xsns_92_MI_HM10.ino b/tasmota/xsns_92_MI_HM10.ino index 6065a6c7f..2464bfc55 100644 --- a/tasmota/xsns_92_MI_HM10.ino +++ b/tasmota/xsns_92_MI_HM10.ino @@ -48,6 +48,7 @@ struct { uint8_t current_task_delay; // number of 100ms-cycles uint8_t last_command; uint16_t firmware; + uint32_t period; // set manually in addition to TELE-period struct { uint32_t init:1; uint32_t pending_task:1; @@ -95,6 +96,10 @@ std::vector MIBLEsensors; #define D_CMND_HM10 "HM10" +const char S_JSON_HM10_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_HM10 "%s\":%d}"; +const char S_JSON_HM10_COMMAND[] PROGMEM = "{\"" D_CMND_HM10 "%s\"}"; +const char kHM10_Commands[] PROGMEM = "Scan|Period"; + #define FLORA 1 #define MJ_HT_V1 2 #define LYWSD02 3 @@ -120,9 +125,11 @@ const char * kHM10SlaveType[] PROGMEM = {kHM10SlaveType1,kHM10SlaveType2,kHM10Sl * enumerations \*********************************************************************************************/ -// enum HM10_Commands { -// CMND_HM10_TRACK -// }; +enum HM10_Commands { // commands useable in console or rules + CMND_HM10_DISC_SCAN, + CMND_HM10_PERIOD + }; // set dac, 1=off, 0=on, DAC is turned on (0) by default + /*********************************************************************************************\ * command defines @@ -130,7 +137,6 @@ const char * kHM10SlaveType[] PROGMEM = {kHM10SlaveType1,kHM10SlaveType2,kHM10Sl - /*********************************************************************************************\ * Task codes defines \*********************************************************************************************/ @@ -179,22 +185,16 @@ void HM10_Reset(void) { HM10_Launchtask(TASK_HM10_DISCONN,0,1); // disco HM10_Launchtask(TASK_HM10_DISC,5,50); // discovery } -void HM10_Read_Sensor(void) { - HM10_Launchtask(TASK_HM10_CONN,0,1); // connect - HM10_Launchtask(TASK_HM10_FEEDBACK,1,35); // get OK+CONN - HM10_Launchtask(TASK_HM10_SUBSCR,2,10); // subscribe - HM10_Launchtask(TASK_HM10_READ_HT,3,15); // read - HM10_Launchtask(TASK_HM10_READ_HT,4,15); // read - HM10_Launchtask(TASK_HM10_READ_HT,5,15); // read - HM10_Launchtask(TASK_HM10_UNSUBSCR,6,10); // unsubscribe - HM10_Launchtask(TASK_HM10_DISCONN,7,0); // disconnect +void HM10_Discovery_Scan(void) { + HM10_Launchtask(TASK_HM10_DISCONN,0,1); // disconnect + HM10_Launchtask(TASK_HM10_DISC,1,1); // discovery } void HM10_Read_Sensor1(void) { HM10_Launchtask(TASK_HM10_CONN,0,1); // connect HM10_Launchtask(TASK_HM10_FEEDBACK,1,35); // get OK+CONN HM10_Launchtask(TASK_HM10_SUBSCR,2,10); // subscribe - HM10_Launchtask(TASK_HM10_UNSUBSCR,3,40); // unsubscribe + HM10_Launchtask(TASK_HM10_UNSUBSCR,3,60); // unsubscribe HM10_Launchtask(TASK_HM10_READ_BT,4,5); // read Battery HM10_Launchtask(TASK_HM10_DISCONN,5,5); // disconnect } @@ -277,6 +277,7 @@ void HM10SerialInit(void) { HM10_Reset(); HM10.mode.pending_task = 1; HM10.mode.init = 1; + HM10.period = Settings.tele_period; AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s_TASK_LIST initialized, now return to main loop"),D_CMND_HM10); } return; @@ -569,6 +570,10 @@ void HM10_TaskEvery100ms(){ } } +/* +|* Loops +\* */ + void HM10EverySecond(){ if(HM10.firmware == 0) return; if(HM10.mode.pending_task == 1) return; @@ -591,13 +596,44 @@ void HM10EverySecond(){ } if (HM10.state.sensor==MIBLEsensors.size()-1) { _nextSensorSlot= 0; - _counter = 60; + _counter = HM10.period; } AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s active sensor now: %u"),D_CMND_HM10, HM10.state.sensor); } if(_counter>0) _counter--; } +bool HM10Cmd(void) { + char command[CMDSZ]; + bool serviced = true; + uint8_t disp_len = strlen(D_CMND_HM10); + + if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_HM10), disp_len)) { // prefix + uint32_t command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + disp_len, kHM10_Commands); + switch (command_code) { + case CMND_HM10_PERIOD: + if (XdrvMailbox.data_len > 0) { + if (command_code == CMND_HM10_PERIOD) { HM10.period = XdrvMailbox.payload; } + } + Response_P(S_JSON_HM10_COMMAND_NVALUE, command, XdrvMailbox.payload); + break; + case CMND_HM10_DISC_SCAN: + if (command_code == CMND_HM10_DISC_SCAN) { HM10_Discovery_Scan(); } + + Response_P(S_JSON_HM10_COMMAND, command, XdrvMailbox.payload); + break; + default: + // else for Unknown command + serviced = false; + break; + } + } else { + return false; + } + return serviced; +} + + /*********************************************************************************************\ * Presentation \*********************************************************************************************/ @@ -727,6 +763,9 @@ bool Xsns92(uint8_t function) HM10EverySecond(); // DEBUG_SENSOR_LOG(PSTR("HM10: every second")); break; + case FUNC_COMMAND: + result = HM10Cmd(); + break; case FUNC_JSON_APPEND: HM10Show(1); break; From 09ba4d15fcbc18724b3f2908be0a2ce5be51c5e4 Mon Sep 17 00:00:00 2001 From: Staars Date: Tue, 4 Feb 2020 17:55:48 +0100 Subject: [PATCH 12/17] cleanup and refactoring, HM10PERIOD now shows value --- tasmota/xsns_92_MI_HM10.ino | 89 +++++++++++-------------------------- 1 file changed, 26 insertions(+), 63 deletions(-) diff --git a/tasmota/xsns_92_MI_HM10.ino b/tasmota/xsns_92_MI_HM10.ino index 2464bfc55..ef9a0c9c1 100644 --- a/tasmota/xsns_92_MI_HM10.ino +++ b/tasmota/xsns_92_MI_HM10.ino @@ -117,25 +117,14 @@ const char kHM10SlaveType3[] PROGMEM = "LYWSD02"; const char kHM10SlaveType4[] PROGMEM = "LYWSD03"; const char * kHM10SlaveType[] PROGMEM = {kHM10SlaveType1,kHM10SlaveType2,kHM10SlaveType3,kHM10SlaveType4}; - -// uint8_t HM10Mac[2][6]={0xA4,0xC1,0x38,0xED,0x81,0x5A, -// 0xA4,0xC1,0x38,0x2A,0xC8,0xB3}; - /*********************************************************************************************\ * enumerations \*********************************************************************************************/ -enum HM10_Commands { // commands useable in console or rules - CMND_HM10_DISC_SCAN, - CMND_HM10_PERIOD - }; // set dac, 1=off, 0=on, DAC is turned on (0) by default - - -/*********************************************************************************************\ - * command defines -\*********************************************************************************************/ - - +enum HM10_Commands { // commands useable in console or rules + CMND_HM10_DISC_SCAN, // re-scan for sensors + CMND_HM10_PERIOD // set period like TELE-period in seconds between read-cycles + }; /*********************************************************************************************\ * Task codes defines @@ -278,21 +267,15 @@ void HM10SerialInit(void) { HM10.mode.pending_task = 1; HM10.mode.init = 1; HM10.period = Settings.tele_period; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s_TASK_LIST initialized, now return to main loop"),D_CMND_HM10); + DEBUG_SENSOR_LOG(PSTR("%s_TASK_LIST initialized, now return to main loop"),D_CMND_HM10); } return; } /*********************************************************************************************\ - * create the HM10 commands payload, and send it via serial interface to the HM10 player + * create the HM10 commands payload, and send it via serial interface to the HM10 module \*********************************************************************************************/ -// void HM10_CMD(uint8_t _cmd,uint16_t _val) { - -// HM10Serial->write(cmd, sizeof(cmd)); / -// return; -// } - void HM10datahex(const char* string, uint8_t _mac[]) { uint32_t slength = 12; // uint8_t _mac[6] = {0}; @@ -371,10 +354,7 @@ void HM10readBat(char *_buf){ DEBUG_SENSOR_LOG(PSTR("HM10: raw data: %x%x%x%x%x%x%x"),_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6]); if(_buf[0] != 0){ DEBUG_SENSOR_LOG(PSTR("HM10: Battery: %u"),_buf[0]); - // uint8_t _serial[6] = {0}; - // uint32_t _slot = MIBLEgetSensorSlot(HM10Mac[HM10.state.sensor], 4); uint32_t _slot = HM10.state.sensor; - DEBUG_SENSOR_LOG(PSTR("MIBLE: Sensor slot: %u"), _slot); if(_buf[0]<101){ MIBLEsensors.at(_slot).bat=_buf[0]; @@ -386,7 +366,7 @@ void HM10readBat(char *_buf){ * handle the return value from the HM10 \*********************************************************************************************/ -bool HM10SerialHandleFeedback(){ +bool HM10SerialHandleFeedback(){ // every 50 milliseconds bool success = false; // true disables possible repetition of commands, set to false only for debugging uint32_t i = 0; char ret[HM10_MAX_RX_BUF] = {0}; // reset array with zeros @@ -413,7 +393,7 @@ bool HM10SerialHandleFeedback(){ HM10ParseResponse(ret); } else { - // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s got no response"),D_CMND_HM10); + // DEBUG_SENSOR_LOG(PSTR("%s got no response"),D_CMND_HM10); } return success; } @@ -423,8 +403,7 @@ bool HM10SerialHandleFeedback(){ \*********************************************************************************************/ void HM10_TaskEvery100ms(){ - HM10SerialHandleFeedback(); - // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK to be done %u"),D_CMND_HM10,HM10_TASK_LIST[0][0]); + // HM10SerialHandleFeedback(); if (HM10.current_task_delay == 0) { uint8_t i = 0; bool runningTaskLoop = true; @@ -470,7 +449,6 @@ void HM10_TaskEvery100ms(){ HM10.current_task_delay = 2; // set task delay HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); runningTaskLoop = false; - // HM10Serial->write("AT+CONA4C138ED815A"); char _con[20]; 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); @@ -548,10 +526,10 @@ void HM10_TaskEvery100ms(){ // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sFound done HM10_TASK"),D_CMND_HM10); // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%snext slot:%u, i: %u"),D_CMND_HM10, HM10_TASK_LIST[i+1][0],i); if(HM10_TASK_LIST[i+1][0] == TASK_HM10_NOTASK) { // check the next entry and if there is none - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sno Tasks left"),D_CMND_HM10); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK_DONE current slot %u"),D_CMND_HM10, i); + DEBUG_SENSOR_LOG(PSTR("%sno Tasks left"),D_CMND_HM10); + DEBUG_SENSOR_LOG(PSTR("%sHM10_TASK_DONE current slot %u"),D_CMND_HM10, i); for (uint8_t j = 0; j < HM10_MAX_TASK_NUMBER+1; j++) { // do a clean-up: - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sHM10_TASK cleanup slot %u"),D_CMND_HM10, j); + DEBUG_SENSOR_LOG(PSTR("%sHM10_TASK cleanup slot %u"),D_CMND_HM10, j); HM10_TASK_LIST[j][0] = TASK_HM10_NOTASK; // reset all task entries HM10_TASK_LIST[j][1] = 0; // reset all delays } @@ -579,26 +557,23 @@ void HM10EverySecond(){ if(HM10.mode.pending_task == 1) return; if (MIBLEsensors.size()==0) { HM10.mode.pending_task = 1; - HM10_Launchtask(TASK_HM10_DISC,0,1); // start new discovery + HM10_Launchtask(TASK_HM10_DISC,0,50); // start new discovery return; } static uint32_t _counter = 0; static uint32_t _nextSensorSlot = 0; if(_counter==0) { - HM10.state.sensor = _nextSensorSlot; - _nextSensorSlot++; - if(MIBLEsensors.at(HM10.state.sensor).type==4) { + HM10.state.sensor = _nextSensorSlot; + _nextSensorSlot++; + if(MIBLEsensors.at(HM10.state.sensor).type==LYWSD03MMC) { // only this sensor for now HM10.mode.pending_task = 1; HM10_Read_Sensor1(); - } - else { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s active sensor not type 3: %u"),D_CMND_HM10, HM10.state.sensor); } if (HM10.state.sensor==MIBLEsensors.size()-1) { _nextSensorSlot= 0; _counter = HM10.period; } - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s active sensor now: %u"),D_CMND_HM10, HM10.state.sensor); + DEBUG_SENSOR_LOG(PSTR("%s active sensor now: %u"),D_CMND_HM10, HM10.state.sensor); } if(_counter>0) _counter--; } @@ -615,6 +590,9 @@ bool HM10Cmd(void) { if (XdrvMailbox.data_len > 0) { if (command_code == CMND_HM10_PERIOD) { HM10.period = XdrvMailbox.payload; } } + else { + if (command_code == CMND_HM10_PERIOD) XdrvMailbox.payload = HM10.period; + } Response_P(S_JSON_HM10_COMMAND_NVALUE, command, XdrvMailbox.payload); break; case CMND_HM10_DISC_SCAN: @@ -638,17 +616,10 @@ bool HM10Cmd(void) { * Presentation \*********************************************************************************************/ -const char HTTP_HM10[] PROGMEM = - "{s}HM10" " Firmware " "{m}%u{e}"; - -const char HTTP_HM10_SERIAL[] PROGMEM = - "{s}%s" " Address" "{m}%02x:%02x:%02x:%02x:%02x:%02x%{e}"; - -const char HTTP_BATTERY[] PROGMEM = - "{s}%s" " Battery" "{m}%u%%{e}"; - -const char HTTP_HM10_FLORA_DATA[] PROGMEM = - "{s}%s" " Fertility" "{m}%sus/cm{e}"; +const char HTTP_HM10[] PROGMEM = "{s}HM10" " Firmware " "{m}%u{e}"; +const char HTTP_HM10_SERIAL[] PROGMEM = "{s}%s" " Address" "{m}%02x:%02x:%02x:%02x:%02x:%02x%{e}"; +const char HTTP_BATTERY[] PROGMEM = "{s}%s" " Battery" "{m}%u%%{e}"; +const char HTTP_HM10_FLORA_DATA[] PROGMEM = "{s}%s" " Fertility" "{m}%sus/cm{e}"; void HM10Show(bool json) { @@ -745,23 +716,15 @@ bool Xsns92(uint8_t function) HM10SerialInit(); // init and start communication break; case FUNC_EVERY_50_MSECOND: - HM10SerialHandleFeedback(); // -> sniff for device feedback + HM10SerialHandleFeedback(); // -> sniff for device feedback very often break; case FUNC_EVERY_100_MSECOND: - if (HM10_TASK_LIST[0][0] == TASK_HM10_NOTASK) { // no task running - // DEBUG_SENSOR_LOG(PSTR("HM10: no TASK in array")); - // HM10SerialHandleFeedback(); // -> sniff for device feedback - break; - } - else { - // DEBUG_SENSOR_LOG(PSTR("HM10: every 100msec")); + if (HM10_TASK_LIST[0][0] != TASK_HM10_NOTASK) { HM10_TaskEvery100ms(); // something has to be done, we'll check in the next step - break; } break; case FUNC_EVERY_SECOND: HM10EverySecond(); - // DEBUG_SENSOR_LOG(PSTR("HM10: every second")); break; case FUNC_COMMAND: result = HM10Cmd(); From 47ead336cb8cf3beee8082375ba032f4370fcdb2 Mon Sep 17 00:00:00 2001 From: Staars Date: Tue, 4 Feb 2020 19:30:41 +0100 Subject: [PATCH 13/17] adding HM10AT and HM10BAUD, HM10PERIOD now immediately takes effect --- tasmota/xsns_92_MI_HM10.ino | 61 +++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/tasmota/xsns_92_MI_HM10.ino b/tasmota/xsns_92_MI_HM10.ino index ef9a0c9c1..316d1886d 100644 --- a/tasmota/xsns_92_MI_HM10.ino +++ b/tasmota/xsns_92_MI_HM10.ino @@ -22,8 +22,7 @@ -------------------------------------------------------------------------------------------- --- - 0.9.0.0 20200130 started - further development by Christian Baars - base - no real base project + 0.9.0.0 20200130 started - initial development by Christian Baars forked - from arendst/tasmota - https://github.com/arendst/Tasmota */ @@ -37,6 +36,7 @@ #include TasmotaSerial *HM10Serial; +#define HM10_BAUDRATE 115200 // default with FW>700 is 115200 #define HM10_MAX_TASK_NUMBER 12 uint8_t HM10_TASK_LIST[HM10_MAX_TASK_NUMBER+1][2]; // first value: kind of task - second value: delay in x * 100ms @@ -49,6 +49,7 @@ struct { uint8_t last_command; uint16_t firmware; uint32_t period; // set manually in addition to TELE-period + uint32_t serialSpeed; struct { uint32_t init:1; uint32_t pending_task:1; @@ -97,8 +98,8 @@ std::vector MIBLEsensors; #define D_CMND_HM10 "HM10" const char S_JSON_HM10_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_HM10 "%s\":%d}"; -const char S_JSON_HM10_COMMAND[] PROGMEM = "{\"" D_CMND_HM10 "%s\"}"; -const char kHM10_Commands[] PROGMEM = "Scan|Period"; +const char S_JSON_HM10_COMMAND[] PROGMEM = "{\"" D_CMND_HM10 "%s%s\"}"; +const char kHM10_Commands[] PROGMEM = "Scan|AT|Period|Baud"; #define FLORA 1 #define MJ_HT_V1 2 @@ -123,7 +124,9 @@ const char * kHM10SlaveType[] PROGMEM = {kHM10SlaveType1,kHM10SlaveType2,kHM10Sl enum HM10_Commands { // commands useable in console or rules CMND_HM10_DISC_SCAN, // re-scan for sensors - CMND_HM10_PERIOD // set period like TELE-period in seconds between read-cycles + CMND_HM10_AT, // send AT-command for debugging and special configuration + CMND_HM10_PERIOD, // set period like TELE-period in seconds between read-cycles + CMND_HM10_BAUD // serial speed of ESP8266 (<-> HM10), does not change baud rate of HM10 }; /*********************************************************************************************\ @@ -179,11 +182,11 @@ void HM10_Discovery_Scan(void) { HM10_Launchtask(TASK_HM10_DISC,1,1); // discovery } -void HM10_Read_Sensor1(void) { +void HM10_Read_Sensor(void) { HM10_Launchtask(TASK_HM10_CONN,0,1); // connect HM10_Launchtask(TASK_HM10_FEEDBACK,1,35); // get OK+CONN HM10_Launchtask(TASK_HM10_SUBSCR,2,10); // subscribe - HM10_Launchtask(TASK_HM10_UNSUBSCR,3,60); // unsubscribe + HM10_Launchtask(TASK_HM10_UNSUBSCR,3,80); // unsubscribe HM10_Launchtask(TASK_HM10_READ_BT,4,5); // read Battery HM10_Launchtask(TASK_HM10_DISCONN,5,5); // disconnect } @@ -256,8 +259,9 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_serial)[6], uint8_t _type){ void HM10SerialInit(void) { HM10.mode.init = false; + HM10.serialSpeed = HM10_BAUDRATE; HM10Serial = new TasmotaSerial(HM_PIN_RX, HM_PIN_TX, 1, 0, HM10_MAX_RX_BUF); - if (HM10Serial->begin(115200)) { + if (HM10Serial->begin(HM10.serialSpeed)) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s start serial communication fixed to 115200 baud"),D_CMND_HM10); if (HM10Serial->hardwareSerial()) { ClaimSerial(); @@ -555,11 +559,8 @@ void HM10_TaskEvery100ms(){ void HM10EverySecond(){ if(HM10.firmware == 0) return; if(HM10.mode.pending_task == 1) return; - if (MIBLEsensors.size()==0) { - HM10.mode.pending_task = 1; - HM10_Launchtask(TASK_HM10_DISC,0,50); // start new discovery - return; - } + if (MIBLEsensors.size()==0) return; + static uint32_t _counter = 0; static uint32_t _nextSensorSlot = 0; if(_counter==0) { @@ -567,15 +568,17 @@ void HM10EverySecond(){ _nextSensorSlot++; if(MIBLEsensors.at(HM10.state.sensor).type==LYWSD03MMC) { // only this sensor for now HM10.mode.pending_task = 1; - HM10_Read_Sensor1(); + HM10_Read_Sensor(); } if (HM10.state.sensor==MIBLEsensors.size()-1) { _nextSensorSlot= 0; - _counter = HM10.period; + _counter++; } + DEBUG_SENSOR_LOG(PSTR("%s active sensor now: %u"),D_CMND_HM10, HM10.state.sensor); } - if(_counter>0) _counter--; + else _counter++; + if (_counter>HM10.period) _counter = 0; } bool HM10Cmd(void) { @@ -595,10 +598,30 @@ bool HM10Cmd(void) { } Response_P(S_JSON_HM10_COMMAND_NVALUE, command, XdrvMailbox.payload); break; + case CMND_HM10_BAUD: + if (XdrvMailbox.data_len > 0) { + if (command_code == CMND_HM10_BAUD) { + HM10.serialSpeed = XdrvMailbox.payload; + HM10Serial->begin(HM10.serialSpeed); + } + } + else { + if (command_code == CMND_HM10_BAUD) XdrvMailbox.payload = HM10.serialSpeed; + } + Response_P(S_JSON_HM10_COMMAND_NVALUE, command, XdrvMailbox.payload); + break; + case CMND_HM10_AT: + HM10Serial->write("AT"); // without an argument this will disconnect + if (strlen(XdrvMailbox.data)!=0) { + HM10Serial->write("+"); + HM10Serial->write(XdrvMailbox.data); // pass everything without checks + Response_P(S_JSON_HM10_COMMAND, ":AT+",XdrvMailbox.data); + } + else Response_P(S_JSON_HM10_COMMAND, ":AT",XdrvMailbox.data); + break; case CMND_HM10_DISC_SCAN: - if (command_code == CMND_HM10_DISC_SCAN) { HM10_Discovery_Scan(); } - - Response_P(S_JSON_HM10_COMMAND, command, XdrvMailbox.payload); + if (command_code == CMND_HM10_DISC_SCAN) { HM10_Discovery_Scan(); } + Response_P(S_JSON_HM10_COMMAND, command, ""); break; default: // else for Unknown command From e8f8b48c7786264773d55f53358e4a9da06696a3 Mon Sep 17 00:00:00 2001 From: Staars Date: Wed, 5 Feb 2020 16:56:41 +0100 Subject: [PATCH 14/17] clean ups, hopefully no real code changes --- tasmota/xsns_92_MI_HM10.ino | 68 ++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/tasmota/xsns_92_MI_HM10.ino b/tasmota/xsns_92_MI_HM10.ino index 316d1886d..b9dd74db5 100644 --- a/tasmota/xsns_92_MI_HM10.ino +++ b/tasmota/xsns_92_MI_HM10.ino @@ -48,7 +48,7 @@ struct { uint8_t current_task_delay; // number of 100ms-cycles uint8_t last_command; uint16_t firmware; - uint32_t period; // set manually in addition to TELE-period + uint32_t period; // set manually in addition to TELE-period, is set to TELE-period after start uint32_t serialSpeed; struct { uint32_t init:1; @@ -59,7 +59,7 @@ struct { // TODO: more to come } mode; struct { - uint8_t sensor; // points to to the number 0...255 + uint8_t sensor; // points to to the number 0...255 // TODO: more to come } state; } HM10; @@ -68,7 +68,7 @@ struct { struct { uint16_t temp; uint8_t hum; -} LYWSD03; +} LYWSD03_HT; #pragma pack(0) struct mi_sensor_t{ @@ -125,7 +125,7 @@ const char * kHM10SlaveType[] PROGMEM = {kHM10SlaveType1,kHM10SlaveType2,kHM10Sl enum HM10_Commands { // commands useable in console or rules CMND_HM10_DISC_SCAN, // re-scan for sensors CMND_HM10_AT, // send AT-command for debugging and special configuration - CMND_HM10_PERIOD, // set period like TELE-period in seconds between read-cycles + CMND_HM10_PERIOD, // set period like TELE-period in seconds between read-cycles CMND_HM10_BAUD // serial speed of ESP8266 (<-> HM10), does not change baud rate of HM10 }; @@ -169,6 +169,10 @@ void HM10_TaskReplaceInSlot(uint8_t task, uint8_t slot){ HM10_TASK_LIST[slot][0] = task; } +/*********************************************************************************************\ + * chained tasks +\*********************************************************************************************/ + void HM10_Reset(void) { HM10_Launchtask(TASK_HM10_DISCONN,0,1); // disconnect HM10_Launchtask(TASK_HM10_ROLE1,1,1); // set role to 1 HM10_Launchtask(TASK_HM10_IMME1,2,1); // set imme to 1 @@ -179,19 +183,18 @@ void HM10_Reset(void) { HM10_Launchtask(TASK_HM10_DISCONN,0,1); // disco void HM10_Discovery_Scan(void) { HM10_Launchtask(TASK_HM10_DISCONN,0,1); // disconnect - HM10_Launchtask(TASK_HM10_DISC,1,1); // discovery + HM10_Launchtask(TASK_HM10_DISC,1,1); // discovery } - + void HM10_Read_Sensor(void) { HM10_Launchtask(TASK_HM10_CONN,0,1); // connect HM10_Launchtask(TASK_HM10_FEEDBACK,1,35); // get OK+CONN HM10_Launchtask(TASK_HM10_SUBSCR,2,10); // subscribe HM10_Launchtask(TASK_HM10_UNSUBSCR,3,80); // unsubscribe - HM10_Launchtask(TASK_HM10_READ_BT,4,5); // read Battery + HM10_Launchtask(TASK_HM10_READ_BT,4,5); // read Battery HM10_Launchtask(TASK_HM10_DISCONN,5,5); // disconnect } - /** * @brief Return the slot number of a known sensor or return create new sensor slot * @@ -276,16 +279,16 @@ void HM10SerialInit(void) { return; } -/*********************************************************************************************\ - * create the HM10 commands payload, and send it via serial interface to the HM10 module - \*********************************************************************************************/ +/** + * @brief convert Mac-String to byte array + * + * @param string Hex-string, must contain 12 chars (no error checking) + * @param _mac Must be a uint8_t[6], filled with zeros + */ -void HM10datahex(const char* string, uint8_t _mac[]) { - uint32_t slength = 12; - // uint8_t _mac[6] = {0}; +void HM10MACStringToBytes(const char* string, uint8_t _mac[]) { uint32_t index = 0; - DEBUG_SENSOR_LOG(PSTR("HM10: mac-string %s"), string); - while (index < slength) { + while (index < 12) { char c = string[index]; uint32_t value = 0; if(c >= '0' && c <= '9') @@ -303,6 +306,7 @@ void HM10datahex(const char* string, uint8_t _mac[]) { /*********************************************************************************************\ * parse the response \*********************************************************************************************/ + void HM10ParseResponse(char *buf) { if (!strncmp(buf,"OK",2)) { DEBUG_SENSOR_LOG(PSTR("HM10: got OK")); @@ -320,7 +324,7 @@ void HM10ParseResponse(char *buf) { memcpy((void *)_mac,(void *)(_pos+4),12); DEBUG_SENSOR_LOG(PSTR("HM10: found Mac: %s"), _mac); uint8_t _newMacArray[6] = {0}; - HM10datahex(_mac, _newMacArray); + HM10MACStringToBytes(_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); } @@ -332,21 +336,19 @@ void HM10ParseResponse(char *buf) { void HM10readTempHum(char *_buf){ DEBUG_SENSOR_LOG(PSTR("HM10: raw data: %x%x%x%x%x%x%x"),_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6]); if(_buf[0] != 0 && _buf[1] != 0){ - memcpy(&LYWSD03,(void *)_buf,3); - DEBUG_SENSOR_LOG(PSTR("HM10: Temperature * 100: %u, Humidity: %u"),LYWSD03.temp,LYWSD03.hum); - // uint8_t _serial[6] = {0}; - // uint32_t _slot = MIBLEgetSensorSlot(HM10Mac[HM10.state.sensor], 4); + memcpy(&LYWSD03_HT,(void *)_buf,3); + DEBUG_SENSOR_LOG(PSTR("HM10: Temperature * 100: %u, Humidity: %u"),LYWSD03_HT.temp,LYWSD03_HT.hum); uint32_t _slot = HM10.state.sensor; DEBUG_SENSOR_LOG(PSTR("MIBLE: Sensor slot: %u"), _slot); static float _tempFloat; - _tempFloat=(float)(LYWSD03.temp)/100.0f; + _tempFloat=(float)(LYWSD03_HT.temp)/100.0f; if(_tempFloat<60){ MIBLEsensors.at(_slot).temp=_tempFloat; HM10.mode.awaitingHT = false; HM10.current_task_delay = 0; } - _tempFloat=(float)LYWSD03.hum; + _tempFloat=(float)LYWSD03_HT.hum; if(_tempFloat<100){ MIBLEsensors.at(_slot).hum = _tempFloat; DEBUG_SENSOR_LOG(PSTR("LYWSD03: hum updated")); @@ -371,7 +373,7 @@ void HM10readBat(char *_buf){ \*********************************************************************************************/ bool HM10SerialHandleFeedback(){ // every 50 milliseconds - bool success = false; // true disables possible repetition of commands, set to false only for debugging + bool success = false; uint32_t i = 0; char ret[HM10_MAX_RX_BUF] = {0}; // reset array with zeros @@ -407,7 +409,6 @@ bool HM10SerialHandleFeedback(){ // every 50 milliseconds \*********************************************************************************************/ void HM10_TaskEvery100ms(){ - // HM10SerialHandleFeedback(); if (HM10.current_task_delay == 0) { uint8_t i = 0; bool runningTaskLoop = true; @@ -525,7 +526,6 @@ void HM10_TaskEvery100ms(){ HM10.mode.awaitingHT = true; runningTaskLoop = false; break; - case TASK_HM10_DONE: // this entry was already handled // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sFound done HM10_TASK"),D_CMND_HM10); // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%snext slot:%u, i: %u"),D_CMND_HM10, HM10_TASK_LIST[i+1][0],i); @@ -538,9 +538,7 @@ void HM10_TaskEvery100ms(){ HM10_TASK_LIST[j][1] = 0; // reset all delays } runningTaskLoop = false; // return to main loop - // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%sUpdate GUI via AJAX"),D_CMND_HM10); - // HM10_GUI_NEEDS_UPDATE = true; - HM10.mode.pending_task = 0; + HM10.mode.pending_task = 0; // back to main loop control break; } } @@ -552,9 +550,10 @@ void HM10_TaskEvery100ms(){ } } -/* -|* Loops -\* */ +/** + * @brief Main loop of the driver, "high level"-loop + * + */ void HM10EverySecond(){ if(HM10.firmware == 0) return; @@ -574,7 +573,6 @@ void HM10EverySecond(){ _nextSensorSlot= 0; _counter++; } - DEBUG_SENSOR_LOG(PSTR("%s active sensor now: %u"),D_CMND_HM10, HM10.state.sensor); } else _counter++; @@ -736,14 +734,14 @@ bool Xsns92(uint8_t function) if (true) { switch (function) { case FUNC_INIT: - HM10SerialInit(); // init and start communication + HM10SerialInit(); // init and start communication break; case FUNC_EVERY_50_MSECOND: HM10SerialHandleFeedback(); // -> sniff for device feedback very often break; case FUNC_EVERY_100_MSECOND: if (HM10_TASK_LIST[0][0] != TASK_HM10_NOTASK) { - HM10_TaskEvery100ms(); // something has to be done, we'll check in the next step + HM10_TaskEvery100ms(); // something has to be done, we'll check in the next step } break; case FUNC_EVERY_SECOND: From a4e613a99255cb2b8db52b426ff2fa5a29bf6274 Mon Sep 17 00:00:00 2001 From: Staars Date: Wed, 5 Feb 2020 20:34:38 +0100 Subject: [PATCH 15/17] use MAC, small WEB-UI changes --- tasmota/xsns_92_MI_HM10.ino | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tasmota/xsns_92_MI_HM10.ino b/tasmota/xsns_92_MI_HM10.ino index b9dd74db5..0c253f5fc 100644 --- a/tasmota/xsns_92_MI_HM10.ino +++ b/tasmota/xsns_92_MI_HM10.ino @@ -638,9 +638,10 @@ bool HM10Cmd(void) { \*********************************************************************************************/ const char HTTP_HM10[] PROGMEM = "{s}HM10" " Firmware " "{m}%u{e}"; -const char HTTP_HM10_SERIAL[] PROGMEM = "{s}%s" " Address" "{m}%02x:%02x:%02x:%02x:%02x:%02x%{e}"; +const char HTTP_HM10_SERIAL[] PROGMEM = "{s}%s %s{m}%02x:%02x:%02x:%02x:%02x:%02x%{e}"; const char HTTP_BATTERY[] PROGMEM = "{s}%s" " Battery" "{m}%u%%{e}"; const char HTTP_HM10_FLORA_DATA[] PROGMEM = "{s}%s" " Fertility" "{m}%sus/cm{e}"; +const char HTTP_HM10_HL[] PROGMEM = "{s}
{m}
{e}"; void HM10Show(bool json) { @@ -688,20 +689,21 @@ void HM10Show(bool json) } else { WSContentSend_PD(HTTP_HM10, HM10.firmware); for (uint32_t i = 0; i < MIBLEsensors.size(); i++) { - WSContentSend_PD(HTTP_HM10_SERIAL, kHM10SlaveType[MIBLEsensors.at(i).type-1], MIBLEsensors.at(i).serial[0], MIBLEsensors.at(i).serial[1],MIBLEsensors.at(i).serial[2],MIBLEsensors.at(i).serial[3],MIBLEsensors.at(i).serial[4],MIBLEsensors.at(i).serial[5]); + WSContentSend_PD(HTTP_HM10_HL); + WSContentSend_PD(HTTP_HM10_SERIAL, kHM10SlaveType[MIBLEsensors.at(i).type-1], D_MAC_ADDRESS, MIBLEsensors.at(i).serial[0], MIBLEsensors.at(i).serial[1],MIBLEsensors.at(i).serial[2],MIBLEsensors.at(i).serial[3],MIBLEsensors.at(i).serial[4],MIBLEsensors.at(i).serial[5]); if(MIBLEsensors.at(i).temp!=-1000.0f){ char temperature[33]; 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==FLORA){ - if(MIBLEsensors.at(i).lux!=0xffff){ // this is the error code -> no temperature + if(MIBLEsensors.at(i).lux!=0xffff){ // this is the error code -> no valid value WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kHM10SlaveType[MIBLEsensors.at(i).type-1], MIBLEsensors.at(i).lux); } - if(MIBLEsensors.at(i).moisture!=-1000.0f){ // this is the error code -> no temperature + if(MIBLEsensors.at(i).moisture!=-1000.0f){ // this is the error code -> no valid value WSContentSend_PD(HTTP_SNS_MOISTURE, kHM10SlaveType[MIBLEsensors.at(i).type-1], MIBLEsensors.at(i).moisture); } - if(MIBLEsensors.at(i).fertility!=-1000.0f){ // this is the error code -> no temperature + if(MIBLEsensors.at(i).fertility!=-1000.0f){ // this is the error code -> no valid value char fertility[33]; dtostrfd(MIBLEsensors.at(i).fertility, 0, fertility); WSContentSend_PD(HTTP_HM10_FLORA_DATA, kHM10SlaveType[MIBLEsensors.at(i).type-1], fertility); From 8d48cf3731d615f48e90b872fa9d6b564af294d9 Mon Sep 17 00:00:00 2001 From: Staars Date: Thu, 6 Feb 2020 17:05:37 +0100 Subject: [PATCH 16/17] pin configs and renames to prepare PR --- tasmota/language/bg-BG.h | 2 ++ tasmota/language/cs-CZ.h | 2 ++ tasmota/language/de-DE.h | 2 ++ tasmota/language/el-GR.h | 2 ++ tasmota/language/en-GB.h | 2 ++ tasmota/language/es-ES.h | 2 ++ tasmota/language/fr-FR.h | 2 ++ tasmota/language/he-HE.h | 2 ++ tasmota/language/hu-HU.h | 2 ++ tasmota/language/it-IT.h | 2 ++ tasmota/language/ko-KO.h | 2 ++ tasmota/language/nl-NL.h | 2 ++ tasmota/language/pl-PL.h | 2 ++ tasmota/language/pt-BR.h | 2 ++ tasmota/language/pt-PT.h | 2 ++ tasmota/language/ru-RU.h | 2 ++ tasmota/language/sk-SK.h | 2 ++ tasmota/language/sv-SE.h | 2 ++ tasmota/language/tr-TR.h | 2 ++ tasmota/language/uk-UA.h | 2 ++ tasmota/language/zh-CN.h | 2 ++ tasmota/language/zh-TW.h | 2 ++ tasmota/my_user_config.h | 1 + tasmota/tasmota_template.h | 8 +++++++- ...sns_92_MI_HM10.ino => xsns_62_MI_HM10.ino} | 20 +++++++++---------- 25 files changed, 61 insertions(+), 12 deletions(-) rename tasmota/{xsns_92_MI_HM10.ino => xsns_62_MI_HM10.ino} (98%) diff --git a/tasmota/language/bg-BG.h b/tasmota/language/bg-BG.h index e89903cee..1189620b8 100644 --- a/tasmota/language/bg-BG.h +++ b/tasmota/language/bg-BG.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/cs-CZ.h b/tasmota/language/cs-CZ.h index d7e8e188e..aeff6b45a 100644 --- a/tasmota/language/cs-CZ.h +++ b/tasmota/language/cs-CZ.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/de-DE.h b/tasmota/language/de-DE.h index b710e2975..ff6cfc2e4 100644 --- a/tasmota/language/de-DE.h +++ b/tasmota/language/de-DE.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/el-GR.h b/tasmota/language/el-GR.h index 1c76125fa..e82e3dc53 100644 --- a/tasmota/language/el-GR.h +++ b/tasmota/language/el-GR.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/en-GB.h b/tasmota/language/en-GB.h index b994b0409..df4fb86da 100644 --- a/tasmota/language/en-GB.h +++ b/tasmota/language/en-GB.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/es-ES.h b/tasmota/language/es-ES.h index 6b8d60d01..89e8bb849 100644 --- a/tasmota/language/es-ES.h +++ b/tasmota/language/es-ES.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/fr-FR.h b/tasmota/language/fr-FR.h index 4a861bd82..847e831ef 100644 --- a/tasmota/language/fr-FR.h +++ b/tasmota/language/fr-FR.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Esclave Rst" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_GPS_RX "GPS RX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/he-HE.h b/tasmota/language/he-HE.h index 166c5c735..abf6a640b 100644 --- a/tasmota/language/he-HE.h +++ b/tasmota/language/he-HE.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/hu-HU.h b/tasmota/language/hu-HU.h index e1cec813a..8c3b63402 100644 --- a/tasmota/language/hu-HU.h +++ b/tasmota/language/hu-HU.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/it-IT.h b/tasmota/language/it-IT.h index d7ec1e0e5..54c0a03d8 100644 --- a/tasmota/language/it-IT.h +++ b/tasmota/language/it-IT.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/ko-KO.h b/tasmota/language/ko-KO.h index 55b8dba97..cc0b0443a 100644 --- a/tasmota/language/ko-KO.h +++ b/tasmota/language/ko-KO.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/nl-NL.h b/tasmota/language/nl-NL.h index c0b5a9862..7362b3b76 100644 --- a/tasmota/language/nl-NL.h +++ b/tasmota/language/nl-NL.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pl-PL.h b/tasmota/language/pl-PL.h index 237bc66f1..403ac0908 100644 --- a/tasmota/language/pl-PL.h +++ b/tasmota/language/pl-PL.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pt-BR.h b/tasmota/language/pt-BR.h index c56262b11..2d60d1352 100644 --- a/tasmota/language/pt-BR.h +++ b/tasmota/language/pt-BR.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pt-PT.h b/tasmota/language/pt-PT.h index be9c6d493..b171eb997 100644 --- a/tasmota/language/pt-PT.h +++ b/tasmota/language/pt-PT.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/ru-RU.h b/tasmota/language/ru-RU.h index 57dfa40e1..ccbe91c36 100644 --- a/tasmota/language/ru-RU.h +++ b/tasmota/language/ru-RU.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "А" diff --git a/tasmota/language/sk-SK.h b/tasmota/language/sk-SK.h index ee7afb49f..860082464 100644 --- a/tasmota/language/sk-SK.h +++ b/tasmota/language/sk-SK.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/sv-SE.h b/tasmota/language/sv-SE.h index 351bf6dbb..d05bfd179 100644 --- a/tasmota/language/sv-SE.h +++ b/tasmota/language/sv-SE.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/tr-TR.h b/tasmota/language/tr-TR.h index fced504d3..88e8bfe54 100644 --- a/tasmota/language/tr-TR.h +++ b/tasmota/language/tr-TR.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/uk-UA.h b/tasmota/language/uk-UA.h index 81d02a8b3..f88ef9cb8 100644 --- a/tasmota/language/uk-UA.h +++ b/tasmota/language/uk-UA.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "А" diff --git a/tasmota/language/zh-CN.h b/tasmota/language/zh-CN.h index 12c368cd3..f14dc7ec9 100644 --- a/tasmota/language/zh-CN.h +++ b/tasmota/language/zh-CN.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "安" diff --git a/tasmota/language/zh-TW.h b/tasmota/language/zh-TW.h index 7c1b2e3fb..afb92d25c 100644 --- a/tasmota/language/zh-TW.h +++ b/tasmota/language/zh-TW.h @@ -635,6 +635,8 @@ #define D_SENSOR_SLAVE_RESET "Slave RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" // Units #define D_UNIT_AMPERE "安" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 8b52aa7a7..0e01ffb8c 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -542,6 +542,7 @@ //#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) //#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM) // #define USE_FLOG // Add support for GPS logging in OTA's Flash (Experimental) (+ 2.9kb flash, +8 bytes RAM) +#define USE_HM10 // Add support for HM-10 as a BLE-bridge for the LYWSD03 (+... code) // -- Power monitoring sensors -------------------- #define USE_ENERGY_MARGIN_DETECTION // Add support for Energy Margin detection (+1k6 code) diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index f041620c6..ba7c7c318 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -216,6 +216,8 @@ enum UserSelectablePins { GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface GPIO_GPS_RX, // GPS serial interface GPIO_GPS_TX, // GPS serial interface + GPIO_HM10_RX, // HM10-BLE-Mijia-bridge serial interface + GPIO_HM10_TX, // HM10-BLE-Mijia-bridge serial interface GPIO_SENSOR_END }; // Programmer selectable GPIO functionality @@ -296,7 +298,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_DEEPSLEEP "|" D_SENSOR_EXS_ENABLE "|" D_SENSOR_SLAVE_TX "|" D_SENSOR_SLAVE_RX "|" D_SENSOR_SLAVE_RESET "|" D_SENSOR_SLAVE_RESET "i|" D_SENSOR_HPMA_RX "|" D_SENSOR_HPMA_TX "|" - D_SENSOR_GPS_RX "|" D_SENSOR_GPS_TX + D_SENSOR_GPS_RX "|" D_SENSOR_GPS_TX "|" D_SENSOR_HM10_RX "|" D_SENSOR_HM10_TX ; const char kSensorNamesFixed[] PROGMEM = @@ -737,6 +739,10 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_GPS_RX, // GPS serial interface GPIO_GPS_TX, // GPS serial interface #endif +#ifdef USE_HM10 + GPIO_HM10_RX, // GPS serial interface + GPIO_HM10_TX, // GPS serial interface +#endif #ifdef USE_MGC3130 GPIO_MGC3130_XFER, diff --git a/tasmota/xsns_92_MI_HM10.ino b/tasmota/xsns_62_MI_HM10.ino similarity index 98% rename from tasmota/xsns_92_MI_HM10.ino rename to tasmota/xsns_62_MI_HM10.ino index 0c253f5fc..6255da01f 100644 --- a/tasmota/xsns_92_MI_HM10.ino +++ b/tasmota/xsns_62_MI_HM10.ino @@ -22,15 +22,13 @@ -------------------------------------------------------------------------------------------- --- - 0.9.0.0 20200130 started - initial development by Christian Baars + 0.9.0.0 20200130 started - initial development by Christian Baars (support LYWSD03 only) forked - from arendst/tasmota - https://github.com/arendst/Tasmota */ +#ifdef USE_HM10 -#define XSNS_92 92 - -#define HM_PIN_RX 5 // D1 Hardcoded while developing -#define HM_PIN_TX 4 // D2 +#define XSNS_62 62 #include #include @@ -263,7 +261,7 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_serial)[6], uint8_t _type){ void HM10SerialInit(void) { HM10.mode.init = false; HM10.serialSpeed = HM10_BAUDRATE; - HM10Serial = new TasmotaSerial(HM_PIN_RX, HM_PIN_TX, 1, 0, HM10_MAX_RX_BUF); + HM10Serial = new TasmotaSerial(pin[GPIO_HM10_RX], pin[GPIO_HM10_TX], 1, 0, HM10_MAX_RX_BUF); if (HM10Serial->begin(HM10.serialSpeed)) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s start serial communication fixed to 115200 baud"),D_CMND_HM10); if (HM10Serial->hardwareSerial()) { @@ -728,18 +726,17 @@ void HM10Show(bool json) * Interface \*********************************************************************************************/ -bool Xsns92(uint8_t function) +bool Xsns62(uint8_t function) { bool result = false; - // if ((pin[HM_PIN_RX] < 99) && (pin[HM_PIN_TX] < 99)) { - if (true) { + if ((pin[GPIO_HM10_RX] < 99) && (pin[GPIO_HM10_TX] < 99)) { switch (function) { case FUNC_INIT: HM10SerialInit(); // init and start communication break; case FUNC_EVERY_50_MSECOND: - HM10SerialHandleFeedback(); // -> sniff for device feedback very often + HM10SerialHandleFeedback(); // check for device feedback very often break; case FUNC_EVERY_100_MSECOND: if (HM10_TASK_LIST[0][0] != TASK_HM10_NOTASK) { @@ -763,4 +760,5 @@ bool Xsns92(uint8_t function) } } return result; -} \ No newline at end of file +} +#endif //USE_HM10 \ No newline at end of file From a95c5b4f6a05055511271bd3be42404204cff45f Mon Sep 17 00:00:00 2001 From: Staars Date: Thu, 6 Feb 2020 19:06:09 +0100 Subject: [PATCH 17/17] resolve conflict --- tasmota/tasmota_template.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index ba7c7c318..347ca4a4f 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -216,6 +216,8 @@ enum UserSelectablePins { GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface GPIO_GPS_RX, // GPS serial interface GPIO_GPS_TX, // GPS serial interface + GPIO_DSB_OUT, // Pseudo Single wire DS18B20 or DS18S20 + GPIO_DHT11_OUT, // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 GPIO_HM10_RX, // HM10-BLE-Mijia-bridge serial interface GPIO_HM10_TX, // HM10-BLE-Mijia-bridge serial interface GPIO_SENSOR_END };