From f0929e14d9c47b012222d75d02e4da00a88a7b05 Mon Sep 17 00:00:00 2001 From: Staars Date: Fri, 23 Oct 2020 10:18:57 +0200 Subject: [PATCH 1/5] add beacon functions --- tasmota/xsns_62_MI_ESP32.ino | 413 ++++++++++++++++++++++++++++------- 1 file changed, 335 insertions(+), 78 deletions(-) diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index 814d31151..36fdd7fdf 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -20,6 +20,8 @@ -------------------------------------------------------------------------------------------- Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 0.9.1.6 20201022 changed - Beacon support, RSSI at TELEPERIOD, refactoring + ------- 0.9.1.5 20201021 changed - HASS related ('null', hold back discovery), number of found sensors for RULES ------- 0.9.1.4 20201020 changed - use BearSSL for decryption, revert to old TELEPERIOD-cycle as default @@ -57,7 +59,6 @@ void MI32scanEndedCB(NimBLEScanResults results); void MI32notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify); - struct { uint16_t perPage = 4; uint32_t period; // set manually in addition to TELE-period, is set to TELE-period after start @@ -82,11 +83,13 @@ struct { uint32_t shallClearResults:1; // BLE scan results uint32_t shallShowStatusInfo:1; // react to amount of found sensors via RULES uint32_t firstAutodiscoveryDone:1; + uint32_t activeBeacon; }; uint32_t all = 0; } mode; struct { - uint8_t sensor; // points to to the number 0...255 + uint8_t sensor; // points to to the number 0...255 + uint8_t beaconScanCounter; // countdown timer in seconds } state; struct { uint32_t allwaysAggregate:1; // always show all known values of one sensor in brdigemode @@ -226,7 +229,7 @@ struct mi_sensor_t{ uint32_t raw; } eventType; - int rssi; + int RSSI; uint32_t lastTime; uint32_t lux; float temp; //Flora, MJ_HT_V1, LYWSD0x, CGx @@ -250,8 +253,28 @@ struct mi_sensor_t{ }; }; +struct scan_entry_t { + uint8_t MAC[6]; + uint16_t CID; + uint16_t SVC; + uint16_t UUID; + int32_t RSSI; +}; + +struct generic_beacon_t { + uint8_t MAC[6]; + uint32_t time; + int32_t RSSI; + uint16_t CID; // company identifier + uint16_t UUID; // the first, if more than one exists + uint16_t SVC; + bool active = false; +}; + std::vector MIBLEsensors; std::vector MIBLEbindKeys; +std::array MIBLEbeacons; // we support a fixed number +std::vector MINBLEscanResult; static BLEScan* MI32Scan; @@ -263,7 +286,9 @@ static BLEScan* MI32Scan; const char S_JSON_MI32_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_MI32 "%s\":%d}"; const char S_JSON_MI32_COMMAND[] PROGMEM = "{\"" D_CMND_MI32 "%s%s\"}"; -const char kMI32_Commands[] PROGMEM = "Period|Time|Page|Battery|Unit|Key"; +// const char S_JSON_MI32_BCOMMAND_SVALUE[] PROGMEM = "{\"" D_CMND_MI32 "%s\":%s}"; +const char S_JSON_MI32_BCOMMAND_SVALUE[] PROGMEM = "{\"" D_CMND_MI32 "%s%u\":\"%s\"}"; +const char kMI32_Commands[] PROGMEM = "Period|Time|Page|Battery|Unit|Key|Beacon"; #define FLORA 1 #define MJ_HT_V1 2 @@ -318,7 +343,8 @@ enum MI32_Commands { // commands useable in console or rules CMND_MI32_PAGE, // sensor entries per web page, which will be shown alternated CMND_MI32_BATTERY, // read all battery levels CMND_MI32_UNIT, // toggles the displayed unit between C/F (LYWSD02) - CMND_MI32_KEY // add bind key to a mac for packet decryption + CMND_MI32_KEY, // add bind key to a mac for packet decryption + CMND_MI32_BEACON // add up to 4 beacons defined by their MAC addresses }; enum MI32_TASK { @@ -329,6 +355,12 @@ enum MI32_TASK { MI32_TASK_UNIT = 4, }; +enum MI32_BEACON_CMND { + MI32_BEACON_ON = 0, + MI32_BEACON_OFF = 1, + MI32_BEACON_DEL = 2, +}; + /*********************************************************************************************\ * Classes \*********************************************************************************************/ @@ -360,32 +392,40 @@ class MI32SensorCallback : public NimBLEClientCallbacks { class MI32AdvCallbacks: public NimBLEAdvertisedDeviceCallbacks { void onResult(NimBLEAdvertisedDevice* advertisedDevice) { // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Advertised Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData(0).length()); - if (advertisedDevice->getServiceDataCount() == 0) { - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData(0).length()); - MI32Scan->erase(advertisedDevice->getAddress()); - return; - } - uint16_t uuid = advertisedDevice->getServiceDataUUID(0).getNative()->u16.value; - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("UUID: %x"),uuid); + int RSSI = advertisedDevice->getRSSI(); uint8_t addr[6]; memcpy(addr,advertisedDevice->getAddress().getNative(),6); MI32_ReverseMAC(addr); - int rssi = 0xffff; - if(advertisedDevice->haveRSSI()) { - rssi = advertisedDevice->getRSSI(); + if (advertisedDevice->getServiceDataCount() == 0) { + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData(0).length()); + if(MI32.state.beaconScanCounter==0 && !MI32.mode.activeBeacon){ + MI32Scan->erase(advertisedDevice->getAddress()); + return; + } + else{ + MI32HandleGenericBeacon(advertisedDevice->getPayload(), advertisedDevice->getPayloadLength(), RSSI, addr); + return; + } + } - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("RSSI: %d"),rssi); // actually i never got a 0xffff - if(uuid==0xfe95) { - MI32ParseResponse((char*)advertisedDevice->getServiceData(0).data(),advertisedDevice->getServiceData(0).length(), addr, rssi); + uint16_t UUID = advertisedDevice->getServiceDataUUID(0).getNative()->u16.value; + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("UUID: %x"),UUID); + + size_t ServiceDataLength = advertisedDevice->getServiceData(0).length(); + if(UUID==0xfe95) { + MI32ParseResponse((char*)advertisedDevice->getServiceData(0).data(),ServiceDataLength, addr, RSSI); } - else if(uuid==0xfdcd) { - MI32parseCGD1Packet((char*)advertisedDevice->getServiceData(0).data(),advertisedDevice->getServiceData(0).length(), addr, rssi); + else if(UUID==0xfdcd) { + MI32parseCGD1Packet((char*)advertisedDevice->getServiceData(0).data(),ServiceDataLength, addr, RSSI); } - else if(uuid==0x181a) { //ATC - MI32ParseATCPacket((char*)advertisedDevice->getServiceData(0).data(),advertisedDevice->getServiceData(0).length(), addr, rssi); + else if(UUID==0x181a) { //ATC + MI32ParseATCPacket((char*)advertisedDevice->getServiceData(0).data(),ServiceDataLength, addr, RSSI); } else { - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %x: %s Buffer: %u"), uuid, advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData(0).length()); + if(MI32.state.beaconScanCounter!=0 || MI32.mode.activeBeacon){ + MI32HandleGenericBeacon(advertisedDevice->getPayload(), advertisedDevice->getPayloadLength(), RSSI, addr); + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %x: %s Buffer: %u"), UUID, advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData(0).length()); MI32Scan->erase(advertisedDevice->getAddress()); } }; @@ -421,6 +461,54 @@ void MI32notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pD * Helper functions \*********************************************************************************************/ +/** + * @brief Remove all colons from null terminated char array + * + * @param _string Typically representing a MAC-address like AA:BB:CC:DD:EE:FF + */ +void MI32stripColon(char* _string){ + uint32_t _length = strlen(_string); + uint32_t _index = 0; + while (_index < _length) { + char c = _string[_index]; + if(c==':'){ + memmove(_string+_index,_string+_index+1,_length-_index); + } + _index++; + } + _string[_index] = 0; +} + +/** + * @brief Convert string that repesents a hexadecimal number to a byte array + * + * @param _string input string in format: AABBCCDDEEFF or AA:BB:CC:DD:EE:FF, caseinsensitive + * @param _mac target byte array must match the correct size (i.e. AA:BB -> uint8_t bytes[2]) + */ + +void MI32HexStringToBytes(char* _string, uint8_t* _byteArray) { + MI32stripColon(_string); + UpperCase(_string,_string); + uint32_t index = 0; + uint32_t _end = strlen(_string); + memset(_byteArray,0,_end/2); + while (index < _end) { + char c = _string[index]; + uint8_t value = 0; + if(c >= '0' && c <= '9') + value = (c - '0'); + else if (c >= 'A' && c <= 'F') + value = (10 + (c - 'A')); + _byteArray[(index/2)] += value << (((index + 1) % 2) * 4); + index++; + } +} + +/** + * @brief Reverse an array of 6 bytes + * + * @param _mac a byte array of size 6 (typicalliy representing a MAC address) + */ void MI32_ReverseMAC(uint8_t _mac[]){ uint8_t _reversedMAC[6]; for (uint8_t i=0; i<6; i++){ @@ -432,9 +520,7 @@ void MI32_ReverseMAC(uint8_t _mac[]){ #ifdef USE_MI_DECRYPTION void MI32AddKey(char* payload){ mi_bindKey_t keyMAC; - memset(keyMAC.buf,0,sizeof(keyMAC)); - UpperCase(payload,payload); - MI32KeyMACStringToBytes(payload,keyMAC.buf); + MI32HexStringToBytes(payload,keyMAC.buf); bool unknownKey = true; for(uint32_t i=0; i= '0' && c <= '9') - value = (c - '0'); - else if (c >= 'A' && c <= 'F') - value = (10 + (c - 'A')); - _keyMAC[(index/2)] += value << (((index + 1) % 2) * 4); - index++; - } - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: %s to:"),_string); - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: key-array: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"),_keyMAC[0],_keyMAC[1],_keyMAC[2],_keyMAC[3],_keyMAC[4],_keyMAC[5],_keyMAC[6],_keyMAC[7],_keyMAC[8],_keyMAC[9],_keyMAC[10],_keyMAC[11],_string,_keyMAC[12],_keyMAC[13],_keyMAC[14],_keyMAC[15]); - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: MAC-array: %02X%02X%02X%02X%02X%02X"),_keyMAC[16],_keyMAC[17],_keyMAC[18],_keyMAC[19],_keyMAC[20],_keyMAC[21]); -} - /** * @brief Decrypts payload in place * @@ -533,10 +596,7 @@ int MI32_decryptPacket(char *_buf, uint16_t _bufSize, uint32_t _type){ br_ccm_run(&ctx, 0, payload, data_len); memcpy((uint8_t*)packet->payload+1,payload,data_len); //back to the packet - // br_ccm_get_tag(&ctx, &checkTag); ret = br_ccm_check_tag(&ctx, &tag); - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("packetTag: %08x"),tag); - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("computedTag: %08x"),checkTag); AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: Err:%i, Decrypted : %02x %02x %02x %02x %02x "), ret, packet->payload[1],packet->payload[2],packet->payload[3],packet->payload[4],packet->payload[5]); return ret-1; @@ -611,7 +671,7 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_MAC)[6], uint16_t _type, uint8_t counter) _newSensor.feature.raw = 0; _newSensor.temp =NAN; _newSensor.bat=0x00; - _newSensor.rssi=0xffff; + _newSensor.RSSI=0xffff; _newSensor.lux = 0x00ffffff; switch (_type) { @@ -670,6 +730,10 @@ void MI32triggerTele(void){ } } +/** + * @brief Is called after every finding of new BLE sensor + * + */ void MI32StatusInfo() { MI32.mode.shallShowStatusInfo = 0; Response_P(PSTR("{\"%s\":{\"found\":%u}}"), D_CMND_MI32, MIBLEsensors.size()); @@ -684,6 +748,7 @@ void MI32Init(void) { MIBLEsensors.reserve(10); MIBLEbindKeys.reserve(10); +MINBLEscanResult.reserve(20); MI32.mode.init = false; if (!MI32.mode.init) { NimBLEDevice::init(""); @@ -1167,6 +1232,7 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot, uint16_t _bufSize){ decryptRet = MI32_decryptPacket((char*)&_beacon.productID,_bufSize, LYWSD03MMC); //start with PID // AddLogBuffer(LOG_LEVEL_DEBUG,(uint8_t*)&_beacon.productID,_bufSize); } + else return; // 0x3058 holds no data, TODO: check for unpaired devices, that need connections break; case MJYD2S: AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MJYD2S: %x"),_beacon.frame); @@ -1180,18 +1246,6 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot, uint16_t _bufSize){ if (_beacon.frame != 0x5910){ decryptRet = MI32_decryptPacket((char*)&_beacon.productID,_bufSize,MJYD2S); //start with PID } - else{ - // This seems to be some kind of wake-up packet only, as it shows up before all kinds of messages, not only motion - // if(millis()-MIBLEsensors[_slot].lastTime>120000){ - // MIBLEsensors[_slot].eventType = 1; - // MIBLEsensors[_slot].events++; - // MIBLEsensors[_slot].shallSendMQTT = 1; - // MIBLEsensors[_slot].lastTime = millis(); - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: MJYD2S secondary PIR")); - // MIBLEsensors[_slot].NMT = 0; - // MI32.mode.shallTriggerTele = 1; - // } - } break; } if(decryptRet!=0){ @@ -1315,13 +1369,13 @@ if(decryptRet!=0){ if(MI32.option.directBridgeMode) MI32.mode.shallTriggerTele = 1; } -void MI32ParseATCPacket(char * _buf, uint32_t length, uint8_t addr[6], int rssi){ +void MI32ParseATCPacket(char * _buf, uint32_t length, uint8_t addr[6], int RSSI){ ATCPacket_t *_packet = (ATCPacket_t*)_buf; uint32_t _slot = MIBLEgetSensorSlot(_packet->MAC, 0x0a1c, _packet->frameCnt); // This must be a hard-coded fake ID AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32DeviceType[MIBLEsensors[_slot].type-1],_slot); if(_slot==0xff) return; - MIBLEsensors[_slot].rssi=rssi; + MIBLEsensors[_slot].RSSI=RSSI; MIBLEsensors.at(_slot).temp = (float)(__builtin_bswap16(_packet->temp))/10.0f; MIBLEsensors.at(_slot).hum = (float)_packet->hum; @@ -1334,13 +1388,13 @@ void MI32ParseATCPacket(char * _buf, uint32_t length, uint8_t addr[6], int rssi) } -void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6], int rssi){ // no MiBeacon +void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6], int RSSI){ // no MiBeacon uint8_t _addr[6]; memcpy(_addr,addr,6); uint32_t _slot = MIBLEgetSensorSlot(_addr, 0x0576, 0); // This must be hard-coded, no object-id in Cleargrass-packet, we have no packet counter too AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32DeviceType[MIBLEsensors[_slot].type-1],_slot); if(_slot==0xff) return; - MIBLEsensors[_slot].rssi=rssi; + MIBLEsensors[_slot].RSSI=RSSI; cg_packet_t _packet; memcpy((char*)&_packet,_buf,sizeof(_packet)); switch (_packet.mode){ @@ -1375,7 +1429,7 @@ void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6], int rssi if(MI32.option.directBridgeMode) MI32.mode.shallTriggerTele = 1; } -void MI32ParseResponse(char *buf, uint16_t bufsize, uint8_t addr[6], int rssi) { +void MI32ParseResponse(char *buf, uint16_t bufsize, uint8_t addr[6], int RSSI) { if(bufsize<9) { //9 is from the NLIGHT return; } @@ -1385,11 +1439,137 @@ void MI32ParseResponse(char *buf, uint16_t bufsize, uint8_t addr[6], int rssi) { memcpy(_addr,addr,6); uint16_t _slot = MIBLEgetSensorSlot(_addr, _type, buf[4]); if(_slot!=0xff) { - MIBLEsensors[_slot].rssi=rssi; + MIBLEsensors[_slot].RSSI=RSSI; MI32parseMiBeacon(buf,_slot,bufsize); } } +/** + * @brief Parse a BLE advertisement packet + * + * @param payload + * @param payloadLength + * @param CID + * @param SVC + * @param UUID + */ +void MI32ParseGenericBeacon(uint8_t* payload, size_t payloadLength, uint16_t* CID, uint16_t*SVC, uint16_t* UUID){ + AddLog_P2(LOG_LEVEL_DEBUG_MORE,PSTR("MI32: Beacon:____________")); + for (uint32_t i = 0; i19) { + AddLog_P2(LOG_LEVEL_INFO,PSTR("MI32: Scan buffer full")); + MI32.state.beaconScanCounter = 1; + return; + } + for(auto _scanResult : MINBLEscanResult){ + if(memcmp(addr,_scanResult.MAC,6)==0){ + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MI32: known device")); + return; + } + } + scan_entry_t _new; + _new.RSSI = RSSI; + _new.CID = 0; + _new.SVC = 0; + _new.UUID = 0; + memcpy(_new.MAC,addr,sizeof(_new.MAC)); + MI32ParseGenericBeacon(payload,payloadLength,&_new.CID,&_new.SVC,&_new.UUID); + MINBLEscanResult.push_back(_new); +} + + +/** + * @brief Add a beacon defined by its MAC-address, if only zeros are given, the beacon will be deactivated + * + * @param index 1-4 beacons are currently supported + * @param data null terminated char array representing a MAC-address in hex + */ +void MI32addBeacon(uint8_t index, char* data){ + auto &_new = MIBLEbeacons[index-1]; //TODO: check + MI32HexStringToBytes(data,_new.MAC); + char _MAC[18]; + ToHex_P(MIBLEbeacons[index-1].MAC,6,_MAC,18,':'); + char _empty[6] = {0}; + _new.time = 0; + if(memcmp(_empty,_new.MAC,6) == 0){ + _new.active = false; + AddLog_P2(LOG_LEVEL_INFO,PSTR("MI32: beacon%u deactivated"), index); + } + else{ + _new.active = true; + MI32.mode.activeBeacon = 1; + AddLog_P2(LOG_LEVEL_INFO,PSTR("MI32: beacon added with MAC: %s"), _MAC); + } +} + +/** + * @brief Present BLE scan in the console, after that deleting the scan data + * + */ +void MI32showScanResults(){ + AddLog_P2(LOG_LEVEL_INFO,PSTR("MI32: found %u devices in scan:"), MINBLEscanResult.size()); + for(auto _scanResult : MINBLEscanResult){ + char _MAC[18]; + ToHex_P(_scanResult.MAC,6,_MAC,18,':'); + AddLog_P2(LOG_LEVEL_INFO,PSTR("MAC: %s _ CID: %04x _ SVC: %04x _ UUID: %04x _ RSSI: %d"), _MAC, _scanResult.CID, _scanResult.SVC, _scanResult.UUID, _scanResult.RSSI); + } + MINBLEscanResult.clear(); +} /***********************************************************************\ * Read data from connections \***********************************************************************/ @@ -1473,6 +1653,25 @@ void MI32EverySecond(bool restart){ } } + uint32_t _idx = 0; + uint32_t _activeBeacons = 0; + for (auto &_beacon : MIBLEbeacons){ + _idx++; + if(_beacon.active == false) continue; + _activeBeacons++; + _beacon.time++; + Response_P(PSTR("{\"Beacon%u\":{\"Time\":%u}}"), _beacon.time); + XdrvRulesProcess(); + } + if(_activeBeacons==0) MI32.mode.activeBeacon = 0; + + if(MI32.state.beaconScanCounter!=0){ + MI32.state.beaconScanCounter--; + if(MI32.state.beaconScanCounter==0){ + MI32showScanResults(); + } + } + if(MI32.mode.shallShowStatusInfo == 1){ MI32StatusInfo(); } @@ -1522,16 +1721,17 @@ void MI32EverySecond(bool restart){ if(_counter==0) { MI32.state.sensor = _nextSensorSlot; - AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: active sensor now: %u of %u"),D_CMND_MI32, MI32.state.sensor, MIBLEsensors.size()-1); MI32.mode.canScan = 0; // if (MI32.mode.runningScan|| MI32.mode.connected || MI32.mode.willConnect) return; if (MI32.mode.connected || MI32.mode.willConnect) return; _nextSensorSlot++; MI32.mode.canConnect = 1; if(MI32.mode.connected == 0) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("will connect to %s"),kMI32DeviceType[MIBLEsensors[MI32.state.sensor].type-1] ); + if (MI32.mode.shallReadBatt) { + //TODO: decide automatically, which sensor can not work without connections + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: active sensor now: %u of %u"),D_CMND_MI32, MI32.state.sensor, MIBLEsensors.size()-1); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("will connect to %s"),kMI32DeviceType[MIBLEsensors[MI32.state.sensor].type-1] ); - if (MI32.mode.shallReadBatt) { MI32StartTask(MI32_TASK_BATT); } #ifndef USE_MI_DECRYPTION // turn off connections, because we only listen to advertisements @@ -1638,6 +1838,32 @@ bool MI32Cmd(void) { } break; #endif //USE_MI_DECRYPTION + case CMND_MI32_BEACON: + if (XdrvMailbox.data_len == 0) { + switch(XdrvMailbox.index){ + case 0: + MI32.state.beaconScanCounter = 8; + Response_P(S_JSON_MI32_BCOMMAND_SVALUE, command, XdrvMailbox.index,PSTR("\"scanning\"")); + break; + case 1: case 2: case 3: case 4: + char _MAC[18]; + ToHex_P(MIBLEbeacons[XdrvMailbox.index-1].MAC,6,_MAC,18,':'); + Response_P(S_JSON_MI32_BCOMMAND_SVALUE, command, XdrvMailbox.index,_MAC); + break; + } + } + else { + if(XdrvMailbox.data_len == 12 || XdrvMailbox.data_len == 17){ // MAC-string without or with colons + switch(XdrvMailbox.index){ + case 1: case 2: case 3: case 4: + MI32addBeacon(XdrvMailbox.index,XdrvMailbox.data); + break; + } + } + Response_P(S_JSON_MI32_BCOMMAND_SVALUE, command, XdrvMailbox.index,XdrvMailbox.data); + } + break; + default: // else for Unknown command serviced = false; @@ -1654,7 +1880,7 @@ bool MI32Cmd(void) { * Presentation \*********************************************************************************************/ -const char HTTP_MI32[] PROGMEM = "{s}MI ESP32 v0.9.1.5{m}%u%s / %u{e}"; +const char HTTP_MI32[] PROGMEM = "{s}MI ESP32 v0916{m}%u%s / %u{e}"; const char HTTP_MI32_MAC[] PROGMEM = "{s}%s %s{m}%s{e}"; const char HTTP_RSSI[] PROGMEM = "{s}%s " D_RSSI "{m}%d dBm{e}"; const char HTTP_BATTERY[] PROGMEM = "{s}%s" " Battery" "{m}%u %%{e}"; @@ -1825,8 +2051,7 @@ void MI32Show(bool json) } } } - if (MI32.option.showRSSI && MI32.mode.triggeredTele) ResponseAppend_P(PSTR(",\"RSSI\":%d"), MIBLEsensors[i].rssi); - + if (MI32.option.showRSSI) ResponseAppend_P(PSTR(",\"RSSI\":%d"), MIBLEsensors[i].RSSI); if(_positionCurlyBracket==strlen(mqtt_data)) ResponseAppend_P(PSTR(",")); // write some random char, to be overwritten in the next step ResponseAppend_P(PSTR("}")); @@ -1838,6 +2063,17 @@ void MI32Show(bool json) } } MI32.mode.triggeredTele = 0; +// add beacons + uint32_t _idx = 0; + for (auto _beacon : MIBLEbeacons){ + _idx++; + if(!_beacon.active) continue; + char _MAC[18]; + ToHex_P(_beacon.MAC,6,_MAC,18,':'); + ResponseAppend_P(PSTR(",\"Beacon%u\":{\"MAC\":\"%s\",\"CID\":\"0x%04x\",\"SVC\":\"0x%04x\"," + "\"UUID\":\"0x%04x\",\"Time\":%u,\"RSSI\":%d}"), + _idx,_MAC,_beacon.CID,_beacon.SVC,_beacon.UUID,_beacon.time,_beacon.RSSI); + } #ifdef USE_HOME_ASSISTANT if(hass_mode==2){ MI32.option.noSummary = _noSummarySave; @@ -1865,7 +2101,7 @@ void MI32Show(bool json) char _MAC[18]; ToHex_P(MIBLEsensors[i].MAC,6,_MAC,18,':'); WSContentSend_PD(HTTP_MI32_MAC, kMI32DeviceType[MIBLEsensors[i].type-1], D_MAC_ADDRESS, _MAC); - WSContentSend_PD(HTTP_RSSI, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].rssi); + WSContentSend_PD(HTTP_RSSI, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].RSSI); if (MIBLEsensors[i].type==FLORA) { if (!isnan(MIBLEsensors[i].temp)) { char temperature[FLOATSZ]; @@ -1909,6 +2145,27 @@ void MI32Show(bool json) } if (MIBLEsensors.size()%MI32.perPage==0 && _page==MIBLEsensors.size()/MI32.perPage) { _page = 0; } if (_page>MIBLEsensors.size()/MI32.perPage) { _page = 0; } + + //always at the bottom of the page + uint32_t _idx=0; + if(MI32.mode.activeBeacon){ + WSContentSend_PD(HTTP_MI32_HL); + char _sbeacon[] = "Beacon1"; + for (auto &_beacon : MIBLEbeacons){ + _idx++; + if(!_beacon.active) continue; + WSContentSend_PD(HTTP_MI32_HL); + _sbeacon[6] = _idx + 0x30; + char _MAC[18]; + ToHex_P(_beacon.MAC,6,_MAC,18,':'); + WSContentSend_PD(HTTP_MI32_MAC, _sbeacon, D_MAC_ADDRESS, _MAC); + WSContentSend_PD(HTTP_RSSI, _sbeacon, _beacon.RSSI); + if(_beacon.CID!=0) WSContentSend_PD(PSTR("{s}Beacon%u CID{m}0x%04X{e}"),_idx, _beacon.CID); + if(_beacon.SVC!=0) WSContentSend_PD(PSTR("{s}Beacon%u SVC{m}0x%04X{e}"),_idx, _beacon.SVC); + if(_beacon.UUID!=0) WSContentSend_PD(PSTR("{s}Beacon%u UUID{m}0x%04X{e}"),_idx, _beacon.UUID); + WSContentSend_PD(PSTR("{s}Beacon%u Time{m}%u seconds{e}"),_idx, _beacon.time); + } + } #endif // USE_WEBSERVER } } From 0f805014e6ed28a082f5f7b4219e7f0a4680cae5 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 23 Oct 2020 15:18:58 +0200 Subject: [PATCH 2/5] Support WT32-ETH01 - Support for fixed output Hi or Lo GPIO - Support for ESP32 based Wireless-Tag WT32-ETH01 (#9496) --- CHANGELOG.md | 2 ++ RELEASENOTES.md | 2 ++ tasmota/language/bg_BG.h | 4 ++-- tasmota/language/cs_CZ.h | 4 ++-- tasmota/language/de_DE.h | 4 ++-- tasmota/language/el_GR.h | 4 ++-- tasmota/language/en_GB.h | 4 ++-- tasmota/language/es_ES.h | 4 ++-- tasmota/language/fr_FR.h | 4 ++-- tasmota/language/he_HE.h | 4 ++-- tasmota/language/hu_HU.h | 4 ++-- tasmota/language/it_IT.h | 4 ++-- tasmota/language/ko_KO.h | 4 ++-- tasmota/language/nl_NL.h | 4 ++-- tasmota/language/pl_PL.h | 4 ++-- tasmota/language/pt_BR.h | 4 ++-- tasmota/language/pt_PT.h | 4 ++-- tasmota/language/ro_RO.h | 4 ++-- tasmota/language/ru_RU.h | 4 ++-- tasmota/language/sk_SK.h | 4 ++-- tasmota/language/sv_SE.h | 4 ++-- tasmota/language/tr_TR.h | 4 ++-- tasmota/language/uk_UA.h | 4 ++-- tasmota/language/vi_VN.h | 4 ++-- tasmota/language/zh_CN.h | 4 ++-- tasmota/language/zh_TW.h | 4 ++-- tasmota/support_tasmota.ino | 14 +++++++++++--- tasmota/tasmota_template.h | 14 ++++++-------- tasmota/xdrv_82_ethernet.ino | 32 +++++++++++++++++++++++--------- 29 files changed, 92 insertions(+), 68 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 156a7489f..a6a3245f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ All notable changes to this project will be documented in this file. - Support for EZO RTD sensors by Christopher Tremblay (#9585) - On ZigbeeBridge support for glowing led when permit join is active (#9581) - Support for PWM Dimmer multi-press and ledmask (#9584) +- Support for fixed output Hi or Lo GPIO +- Support for ESP32 based Wireless-Tag WT32-ETH01 (#9496) ### Changed - Command ``Gpio17`` replaces command ``Adc`` diff --git a/RELEASENOTES.md b/RELEASENOTES.md index d7d1a1aac..96bb8b58d 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -72,6 +72,8 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - Support for Vietnamese language translations by Tâm.NT - Support for timers in case of no-sunset permanent day by cybermaus (#9543) - Support for EZO Ph, ORP and RTD sensors by Christopher Tremblay (#9567, #9585) +- Support for fixed output Hi or Lo GPIO +- Support for ESP32 based Wireless-Tag WT32-ETH01 (#9496) ### Breaking Changed - Redesigned ESP8266 GPIO internal representation in line with ESP32 changing ``Template`` layout too diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index f0a869cf9..7e54d9435 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index ec09983a7..62e3e04dd 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 4d3d9eecd..248e0984b 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 1f20dd270..9e5c3d5e2 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 7e84ff75b..e15b03ba2 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 35f0ac6f5..54673f584 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 4c7775e49..62caf9a85 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -663,8 +663,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 TX" #define D_SENSOR_DDS2382_RX "DDS238-2 RX" #define D_SENSOR_DDSU666_TX "DDSU666 TX" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 4fb8cf5b6..a7723edcb 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index d0cddc994..affa62c19 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 44c671fdb..f074a67e2 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 - STP" #define D_SENSOR_A4988_ENA "A4988 - ENA" #define D_SENSOR_A4988_MS1 "A4988 - MS1" -#define D_SENSOR_A4988_MS2 "A4988 - MS2" -#define D_SENSOR_A4988_MS3 "A4988 - MS3" +#define D_SENSOR_OUTPUT_HI "Output - Hi" +#define D_SENSOR_OUTPUT_LO "Output - Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 - TX" #define D_SENSOR_DDS2382_RX "DDS238-2 - RX" #define D_SENSOR_DDSU666_TX "DDSU666 - TX" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index a0c162c17..61f2caee7 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 5abc5852a..19287551b 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 4d274f6c8..f785a31ff 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index b81212785..634199ba3 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 684f87424..49835816e 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index f61504c4e..b0ace2dbd 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 1bef3939e..2340710e9 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index d090767a4..140214a56 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index d186cf43b..5edc4cc35 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 244dad325..b6d0917fe 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 1f3448303..7e38ad2ba 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index e0700ba32..cf32f7194 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index a7d930ae4..805422779 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 4243f0b55..d3fa4767b 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -667,8 +667,8 @@ #define D_SENSOR_A4988_STP "A4988 STP" #define D_SENSOR_A4988_ENA "A4988 ENA" #define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_A4988_MS2 "A4988 MS2" -#define D_SENSOR_A4988_MS3 "A4988 MS3" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" #define D_SENSOR_DDS2382_TX "DDS238-2 Tx" #define D_SENSOR_DDS2382_RX "DDS238-2 Rx" #define D_SENSOR_DDSU666_TX "DDSU666 Tx" diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index d8bc55e98..b3aa012cf 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1642,12 +1642,20 @@ void GpioInit(void) #endif // ESP8266 - ESP32 soft_spi_flg = (PinUsed(GPIO_SSPI_SCLK) && (PinUsed(GPIO_SSPI_MOSI) || PinUsed(GPIO_SSPI_MISO))); - // Set any non-used GPIO to INPUT - Related to resetPins() in support_legacy_cores.ino - // Doing it here solves relay toggles at restart. for (uint32_t i = 0; i < ARRAY_SIZE(my_module.io); i++) { uint32_t mpin = ValidPin(i, my_module.io[i]); // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("INI: gpio pin %d, mpin %d"), i, mpin); - if (((i < 6) || (i > 11)) && (0 == mpin)) { // Skip SPI flash interface + if (AGPIO(GPIO_OUTPUT_HI) == mpin) { + pinMode(i, OUTPUT); + digitalWrite(i, 1); + } + else if (AGPIO(GPIO_OUTPUT_LO) == mpin) { + pinMode(i, OUTPUT); + digitalWrite(i, 0); + } + // Set any non-used GPIO to INPUT - Related to resetPins() in support_legacy_cores.ino + // Doing it here solves relay toggles at restart. + else if (((i < 6) || (i > 11)) && (GPIO_NONE == mpin)) { // Skip SPI flash interface if (!((1 == i) || (3 == i))) { // Skip serial pinMode(i, INPUT); } diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 4457dc57f..9d5c10a47 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -101,8 +101,7 @@ enum UserSelectablePins { GPIO_RDM6300_RX, // RDM6300 RX GPIO_IBEACON_TX, GPIO_IBEACON_RX, // HM17 IBEACON Serial interface GPIO_A4988_DIR, GPIO_A4988_STP, GPIO_A4988_ENA, GPIO_A4988_MS1, // A4988 interface - GPIO_SPARE1, // Do not use - GPIO_SPARE2, // Do not use + GPIO_OUTPUT_HI, GPIO_OUTPUT_LO, // Fixed output state GPIO_DDS2382_TX, GPIO_DDS2382_RX, // DDS2382 Serial interface GPIO_DDSU666_TX, GPIO_DDSU666_RX, // DDSU666 Serial interface GPIO_SM2135_CLK, GPIO_SM2135_DAT, // SM2135 PWM controller @@ -147,10 +146,8 @@ enum UserSelectablePins { GPIO_IEM3000_TX, GPIO_IEM3000_RX, // IEM3000 Serial interface GPIO_ZIGBEE_RST, // Zigbee reset GPIO_DYP_RX, - GPIO_MIEL_HVAC_TX, // Mitsubishi Electric HVAC TX pin - GPIO_MIEL_HVAC_RX, // Mitsubishi Electric HVAC RX pin - GPIO_WE517_TX, // ORNO WE517 Serial interface - GPIO_WE517_RX, // ORNO WE517 Serial interface + GPIO_MIEL_HVAC_TX, GPIO_MIEL_HVAC_RX, // Mitsubishi Electric HVAC + GPIO_WE517_TX, GPIO_WE517_RX, // ORNO WE517 Serial interface GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -214,8 +211,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_RDM6300_RX "|" D_SENSOR_IBEACON_TX "|" D_SENSOR_IBEACON_RX "|" D_SENSOR_A4988_DIR "|" D_SENSOR_A4988_STP "|" D_SENSOR_A4988_ENA "|" D_SENSOR_A4988_MS1 "|" - "s1|" - "s2|" + D_SENSOR_OUTPUT_HI "|" D_SENSOR_OUTPUT_LO "|" D_SENSOR_DDS2382_TX "|" D_SENSOR_DDS2382_RX "|" D_SENSOR_DDSU666_TX "|" D_SENSOR_DDSU666_RX "|" D_SENSOR_SM2135_CLK "|" D_SENSOR_SM2135_DAT "|" @@ -297,6 +293,8 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif AGPIO(GPIO_LEDLNK), // Link led AGPIO(GPIO_LEDLNK_INV), // Inverted link led + AGPIO(GPIO_OUTPUT_HI), // Fixed output high + AGPIO(GPIO_OUTPUT_LO), // Fixed output low /*-------------------------------------------------------------------------------------------*\ * Protocol specifics diff --git a/tasmota/xdrv_82_ethernet.ino b/tasmota/xdrv_82_ethernet.ino index dcaa5fde8..fde8a417a 100644 --- a/tasmota/xdrv_82_ethernet.ino +++ b/tasmota/xdrv_82_ethernet.ino @@ -32,7 +32,28 @@ * GPIO27 - EMAC_RX_CRS_DV * * {"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} + * GPIO12 = ETH POWER + * GPIO18 = ETH MDIO + * GPIO23 = ETH MDC + * #define ETH_TYPE ETH_PHY_LAN8720 + * #define ETH_CLKMODE ETH_CLOCK_GPIO17_OUT + * #define ETH_ADDR 0 + * * {"NAME":"wESP32","GPIO":[0,0,1,0,1,1,0,0,1,1,1,1,5568,5600,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} + * GPIO16 = ETH MDC + * GPIO17 = ETH MDIO + * #define ETH_TYPE ETH_PHY_LAN8720 + * #define ETH_CLKMODE ETH_CLOCK_GPIO0_IN + * #define ETH_ADDR 0 + * + * {"NAME":"WT32-ETH01","GPIO":[1,1,1,1,1,1,0,0,1,0,1,1,3840,576,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,1],"FLAG":0,"BASE":1} + * GPIO16 = Force Hi + * GPIO18 = ETH MDIO + * GPIO23 = ETH MDC + * #define ETH_TYPE ETH_PHY_LAN8720 + * #define ETH_CLKMODE ETH_CLOCK_GPIO0_IN + * #define ETH_ADDR 1 + * \*********************************************************************************************/ #define XDRV_82 82 @@ -68,19 +89,12 @@ void EthernetEvent(WiFiEvent_t event) { ETH.setHostname(eth_hostname); break; case SYSTEM_EVENT_ETH_CONNECTED: - AddLog_P2(LOG_LEVEL_INFO, PSTR("ETH: " D_CONNECTED)); + AddLog_P2(LOG_LEVEL_INFO, PSTR("ETH: " D_CONNECTED " at %dMbps%s"), + ETH.linkSpeed(), (ETH.fullDuplex()) ? " Full Duplex" : ""); break; case SYSTEM_EVENT_ETH_GOT_IP: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: Mac %s, IPAddress %s, Hostname %s"), ETH.macAddress().c_str(), ETH.localIP().toString().c_str(), eth_hostname); -/* - if (ETH.fullDuplex()) { - Serial.print(", FULL_DUPLEX"); - } - Serial.print(", "); - Serial.print(ETH.linkSpeed()); - Serial.println("Mbps"); -*/ Settings.ip_address[1] = (uint32_t)ETH.gatewayIP(); Settings.ip_address[2] = (uint32_t)ETH.subnetMask(); Settings.ip_address[3] = (uint32_t)ETH.dnsIP(); From 1021cf3ca542a3733021bdea0a9f7781c3afe5ac Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 23 Oct 2020 16:56:03 +0200 Subject: [PATCH 3/5] Update changelog and releasenotes --- BUILDS.md | 1 + CHANGELOG.md | 14 +++++++++++--- RELEASENOTES.md | 15 +++++++++++---- tasmota/support_features.ino | 8 +++++--- tasmota/tasmota_configurations.h | 7 ++++--- tools/decode-status.py | 4 ++-- 6 files changed, 34 insertions(+), 15 deletions(-) diff --git a/BUILDS.md b/BUILDS.md index 849441ebf..aed8361da 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -134,6 +134,7 @@ | USE_EZOPH | - | - | - | - | - | - | - | | USE_EZOORP | - | - | - | - | - | - | - | | USE_EZORTD | - | - | - | - | - | - | - | +| USE_EZOHUM | - | - | - | - | - | - | - | | | | | | | | | | | Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks | USE_SPI | - | - | - | - | - | - | x | diff --git a/CHANGELOG.md b/CHANGELOG.md index a6a3245f6..01322f166 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,20 +9,24 @@ All notable changes to this project will be documented in this file. - Support for timers in case of no-sunset permanent day by cybermaus (#9543) - Command ``NoDelay`` for immediate backlog command execution by Erik Montnemery (#9544) - Command ``SwitchMode 15`` sending only MQTT message on switch change (#9593) +- Command ``ShutterChange`` to increment change position (#9594) - Support for EZO Ph and ORP sensors by Christopher Tremblay (#9567) - Support for EZO RTD sensors by Christopher Tremblay (#9585) +- Support for EZO HUM sensors by Christopher Tremblay (#9599) - On ZigbeeBridge support for glowing led when permit join is active (#9581) - Support for PWM Dimmer multi-press and ledmask (#9584) -- Support for fixed output Hi or Lo GPIO -- Support for ESP32 based Wireless-Tag WT32-ETH01 (#9496) +- Support for fixed output Hi or Lo GPIO selection +- ESP32 support for Wireless-Tag WT32-ETH01 (#9496) +- ESP32 MI32 Beacon support, RSSI at TELEPERIOD, refactoring (#9609) ### Changed - Command ``Gpio17`` replaces command ``Adc`` - Command ``Gpios`` replaces command ``Adcs`` - Management of serial baudrate (#9554) -- ``#define MQTT_FINGERPRINT`` from string to hexnumbers (#9570) +- TLS fingerprint ``#define MQTT_FINGERPRINT`` from string to hexnumbers (#9570) - Rotary driver adjusted accordingly if Mi Desk Lamp module is selected (#9399) - Tasmota Arduino Core v2.7.4.5 allowing webpassword over 47 characters (#9687) +- Webserver code optimizations (#9580, #9590) ### Fixed - Convert AdcParam parameters from versions before v9.0.0.2 @@ -30,7 +34,11 @@ All notable changes to this project will be documented in this file. - Correct Energy period display shortly after midnight by gominoa (#9536) - Rule handling of Var or Mem using text regression from v8.5.0.1 (#9540) - TuyaMcu energy display regression from v8.5.0.1 (#9547) +- Tuyamcu dimmers MQTT topic (#9606) - MQTT data corruption on ``MQTTLog 4`` (#9571) +- Scripter memory alignment (#9608) +- Zigbee battery percentage (#9607) +- HassAnyKey anomaly (#9601) ## [9.0.0.1] - 20201010 ### Added diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 96bb8b58d..3dc27f6bb 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -61,6 +61,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota ### Added - Command ``NoDelay`` for immediate backlog command execution by Erik Montnemery (#9544) - Command ``SwitchMode 15`` sending only MQTT message on switch change (#9593) +- Command ``ShutterChange`` to increment change position (#9594) - Zigbee command ``ZbData`` for better support of device specific data - Optional support for Mitsubishi Electric HVAC by David Gwynne (#9237) - Optional support for Orno WE517-Modbus energy meter by Maxime Vincent (#9353) @@ -71,13 +72,14 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - Support for analog buttons indexed within standard button range - Support for Vietnamese language translations by Tâm.NT - Support for timers in case of no-sunset permanent day by cybermaus (#9543) -- Support for EZO Ph, ORP and RTD sensors by Christopher Tremblay (#9567, #9585) -- Support for fixed output Hi or Lo GPIO -- Support for ESP32 based Wireless-Tag WT32-ETH01 (#9496) +- Support for EZO Ph, ORP, RTD and HUM sensors by Christopher Tremblay (#9567, #9585, #9599) +- Support for fixed output Hi or Lo GPIO selection +- ESP32 support for Wireless-Tag WT32-ETH01 (#9496) +- ESP32 MI32 Beacon support, RSSI at TELEPERIOD, refactoring (#9609) ### Breaking Changed - Redesigned ESP8266 GPIO internal representation in line with ESP32 changing ``Template`` layout too -- ``#define MQTT_FINGERPRINT`` from string to hexnumbers (#9570) +- TLS fingerprint ``#define MQTT_FINGERPRINT`` from string to hexnumbers (#9570) - Command ``Status`` output for disabled status types now returns {"Command":"Error"} - MAX31865 driver to support up to 6 thermocouples selected by ``MX31865 CS`` instead of ``SSPI CS`` (#9103) @@ -92,6 +94,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - Management of serial baudrate (#9554) - Rotary driver adjusted accordingly if Mi Desk Lamp module is selected (#9399) - Tasmota Arduino Core v2.7.4.5 allowing webpassword over 47 characters (#9687) +- Webserver code optimizations (#9580, #9590) ### Fixed - Ledlink blink when no network connected regression from v8.3.1.4 (#9292) @@ -103,6 +106,10 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - Rule handling of Var or Mem using text regression from v8.5.0.1 (#9540) - Correct Energy period display shortly after midnight by gominoa (#9536) - TuyaMcu energy display regression from v8.5.0.1 (#9547) +- Tuyamcu dimmers MQTT topic (#9606) +- Scripter memory alignment (#9608) +- Zigbee battery percentage (#9607) +- HassAnyKey anomaly (#9601) ### Removed - Support for direct upgrade from Tasmota versions before v7.0 diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index b77f560db..1d5150226 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -631,12 +631,14 @@ void GetFeatures(void) feature7 = 0x00000000; #if defined(USE_I2C) && defined(USE_EZOORP) - feature7 |= 0x00000001; // xsns_79_ezoorp.ino + feature7 |= 0x00000001; // xsns_78_ezoorp.ino #endif #if defined(USE_I2C) && defined(USE_EZORTD) - feature7 |= 0x00000002; // xsns_80_ezortd.ino + feature7 |= 0x00000002; // xsns_78_ezortd.ino +#endif +#if defined(USE_I2C) && defined(USE_EZOHUM) + feature7 |= 0x00000004; // xsns_78_exohum.ino #endif -// feature7 |= 0x00000004; // feature7 |= 0x00000008; // feature7 |= 0x00000010; diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 81fdfd9f3..37f6d107f 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -127,9 +127,10 @@ //#define USE_MCP9808 // [I2cDriver51] Enable MCP9808 temperature sensor (I2C addresses 0x18 - 0x1F) (+0k9 code) //#define USE_HP303B // [I2cDriver52] Enable HP303B temperature and pressure sensor (I2C address 0x76 or 0x77) (+6k2 code) //#define USE_MLX90640 // [I2cDriver53] Enable MLX90640 IR array temperature sensor (I2C address 0x33) (+20k code) -//#define USE_EZOPH // [I2cDriver55] Enable support for EZO's pH sensor (+0k6 code) - Shared EZO code required for any EZO device (+1k0 code) -//#define USE_EZOORP // [I2cDriver55] Enable support for EZO's ORP sensor (+0k6 code) - Shared EZO code required for any EZO device (+1k0 code) -//#define USE_EZORTD // [I2cDriver55] Enable support for EZO's RTD sensor (+0k6 code) - Shared EZO code required for any EZO device (+1k0 code) +//#define USE_EZOPH // [I2cDriver55] Enable support for EZO's pH sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code) +//#define USE_EZOORP // [I2cDriver55] Enable support for EZO's ORP sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code) +//#define USE_EZORTD // [I2cDriver55] Enable support for EZO's RTD sensor (+0k2 code) - Shared EZO code required for any EZO device (+1k2 code) +//#define USE_EZOHUM // [I2cDriver55] Enable support for EZO's HUM sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code) #define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code) #define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code) diff --git a/tools/decode-status.py b/tools/decode-status.py index 7380e2c90..6498a98d4 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -232,7 +232,7 @@ a_features = [[ "USE_MLX90640","USE_VL53L1X","USE_MIEL_HVAC","USE_WE517", "USE_EZOPH","USE_TTGO_WATCH","USE_ETHERNET","USE_WEBCAM" ],[ - "USE_EZOORP","USE_EZORTD","","", + "USE_EZOORP","USE_EZORTD","USE_EZOHUM","", "","","","", "","","","", "","","","", @@ -267,7 +267,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v20201020 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v20201023 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj)) From f3498f031b1d209a2fe72df616a85dc7f79ed135 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 23 Oct 2020 17:55:07 +0200 Subject: [PATCH 4/5] Fixed ESP32 Webcam broken Fixed ESP32 Webcam broken regression from #9590 --- CHANGELOG.md | 1 + tasmota/xdrv_81_webcam.ino | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01322f166..7b4279acf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ All notable changes to this project will be documented in this file. - Scripter memory alignment (#9608) - Zigbee battery percentage (#9607) - HassAnyKey anomaly (#9601) +- ESP32 Webcam broken regression from #9590 ## [9.0.0.1] - 20201010 ### Added diff --git a/tasmota/xdrv_81_webcam.ino b/tasmota/xdrv_81_webcam.ino index 18eaf04d7..0b3c35193 100755 --- a/tasmota/xdrv_81_webcam.ino +++ b/tasmota/xdrv_81_webcam.ino @@ -814,10 +814,15 @@ uint32_t WcSetStreamserver(uint32_t flag) { if (flag) { if (!CamServer) { CamServer = new ESP8266WebServer(81); - WebServer_on(PSTR("/"), HandleWebcamRoot); - WebServer_on(PSTR("/cam.mjpeg"), HandleWebcamMjpeg); - WebServer_on(PSTR("/cam.jpg"), HandleWebcamMjpeg); - WebServer_on(PSTR("/stream"), HandleWebcamMjpeg); + CamServer->on("/", HandleWebcamRoot); + CamServer->on("/cam.mjpeg", HandleWebcamMjpeg); + CamServer->on("/cam.jpg", HandleWebcamMjpeg); + CamServer->on("/stream", HandleWebcamMjpeg); + +// WebServer_on(PSTR("/"), HandleWebcamRoot); +// WebServer_on(PSTR("/cam.mjpeg"), HandleWebcamMjpeg); +// WebServer_on(PSTR("/cam.jpg"), HandleWebcamMjpeg); +// WebServer_on(PSTR("/stream"), HandleWebcamMjpeg); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Stream init")); CamServer->begin(); } From f566660fb80e9032c02db9617615d6624afc6aef Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Fri, 23 Oct 2020 22:49:51 +0200 Subject: [PATCH 5/5] Zigbee support for Terncy Smart Dial (#9612) * Zigbee support for Terncy Smart Dial * Fix wrong attributes for TerncyDuration * Fix wrong type for TerncyDuration Co-authored-by: Stephan Hadinger --- tasmota/xdrv_23_zigbee_5__constants.ino | 182 ++++++++++++------------ tasmota/xdrv_23_zigbee_5_converters.ino | 8 +- tasmota/xdrv_23_zigbee_6_commands.ino | 6 + 3 files changed, 105 insertions(+), 91 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_5__constants.ino b/tasmota/xdrv_23_zigbee_5__constants.ino index f28ea0b5b..4786cc944 100644 --- a/tasmota/xdrv_23_zigbee_5__constants.ino +++ b/tasmota/xdrv_23_zigbee_5__constants.ino @@ -381,6 +381,8 @@ const char Z_strings[] PROGMEM = "TuyaFanMode" "\x00" "TuyaForceMode" "\x00" "TuyaWeekSelect" "\x00" + "TerncyRotate" "\x00" + "TerncyDuration" "\x00" "Identify" "\x00" "xxxx" "\x00" "IdentifyQuery" "\x00" @@ -780,95 +782,97 @@ enum Z_offsets { Zo_TuyaFanMode = 5097, Zo_TuyaForceMode = 5109, Zo_TuyaWeekSelect = 5123, - Zo_Identify = 5138, - Zo_xxxx = 5147, - Zo_IdentifyQuery = 5152, - Zo_AddGroup = 5166, - Zo_xxxx00 = 5175, - Zo_ViewGroup = 5182, - Zo_GetGroup = 5192, - Zo_01xxxx = 5201, - Zo_GetAllGroups = 5208, - Zo_00 = 5221, - Zo_RemoveGroup = 5224, - Zo_RemoveAllGroups = 5236, - Zo_ViewScene = 5252, - Zo_xxxxyy = 5262, - Zo_RemoveScene = 5269, - Zo_RemoveAllScenes = 5281, - Zo_RecallScene = 5297, - Zo_GetSceneMembership = 5309, - Zo_PowerOffEffect = 5328, - Zo_xxyy = 5343, - Zo_PowerOnRecall = 5348, - Zo_PowerOnTimer = 5362, - Zo_xxyyyyzzzz = 5375, - Zo_xx0A00 = 5386, - Zo_DimmerUp = 5393, - Zo_00190200 = 5402, - Zo_DimmerDown = 5411, - Zo_01190200 = 5422, - Zo_DimmerStop = 5431, - Zo_ResetAlarm = 5442, - Zo_xxyyyy = 5453, - Zo_ResetAllAlarms = 5460, - Zo_xx000A00 = 5475, - Zo_HueSat = 5484, - Zo_xxyy0A00 = 5491, - Zo_Color = 5500, - Zo_xxxxyyyy0A00 = 5506, - Zo_xxxx0A00 = 5519, - Zo_ShutterOpen = 5528, - Zo_ShutterClose = 5540, - Zo_ShutterStop = 5553, - Zo_ShutterLift = 5565, - Zo_xx = 5577, - Zo_ShutterTilt = 5580, - Zo_Shutter = 5592, - Zo_DimmerMove = 5600, - Zo_xx0A = 5611, - Zo_DimmerStepUp = 5616, - Zo_00xx0A00 = 5629, - Zo_DimmerStepDown = 5638, - Zo_01xx0A00 = 5653, - Zo_DimmerStep = 5662, - Zo_xx190A00 = 5673, - Zo_01 = 5682, - Zo_HueMove = 5685, - Zo_xx19 = 5693, - Zo_HueStepUp = 5698, - Zo_HueStepDown = 5708, - Zo_03xx0A00 = 5720, - Zo_HueStep = 5729, - Zo_SatMove = 5737, - Zo_SatStep = 5745, - Zo_xx190A = 5753, - Zo_ColorMove = 5760, - Zo_xxxxyyyy = 5770, - Zo_ColorStep = 5779, - Zo_ColorTempMoveUp = 5789, - Zo_01xxxx000000000000 = 5805, - Zo_ColorTempMoveDown = 5824, - Zo_03xxxx000000000000 = 5842, - Zo_ColorTempMoveStop = 5861, - Zo_00xxxx000000000000 = 5879, - Zo_ColorTempMove = 5898, - Zo_xxyyyy000000000000 = 5912, - Zo_ColorTempStepUp = 5931, - Zo_01xxxx0A0000000000 = 5947, - Zo_ColorTempStepDown = 5966, - Zo_03xxxx0A0000000000 = 5984, - Zo_ColorTempStep = 6003, - Zo_xxyyyy0A0000000000 = 6017, - Zo_ArrowClick = 6036, - Zo_ArrowHold = 6047, - Zo_ArrowRelease = 6057, - Zo_ZoneStatusChange = 6070, - Zo_xxxxyyzz = 6087, - Zo_xxyyzzzz = 6096, - Zo_AddScene = 6105, - Zo_xxyyyyzz = 6114, - Zo_StoreScene = 6123, + Zo_TerncyRotate = 5138, + Zo_TerncyDuration = 5151, + Zo_Identify = 5166, + Zo_xxxx = 5175, + Zo_IdentifyQuery = 5180, + Zo_AddGroup = 5194, + Zo_xxxx00 = 5203, + Zo_ViewGroup = 5210, + Zo_GetGroup = 5220, + Zo_01xxxx = 5229, + Zo_GetAllGroups = 5236, + Zo_00 = 5249, + Zo_RemoveGroup = 5252, + Zo_RemoveAllGroups = 5264, + Zo_ViewScene = 5280, + Zo_xxxxyy = 5290, + Zo_RemoveScene = 5297, + Zo_RemoveAllScenes = 5309, + Zo_RecallScene = 5325, + Zo_GetSceneMembership = 5337, + Zo_PowerOffEffect = 5356, + Zo_xxyy = 5371, + Zo_PowerOnRecall = 5376, + Zo_PowerOnTimer = 5390, + Zo_xxyyyyzzzz = 5403, + Zo_xx0A00 = 5414, + Zo_DimmerUp = 5421, + Zo_00190200 = 5430, + Zo_DimmerDown = 5439, + Zo_01190200 = 5450, + Zo_DimmerStop = 5459, + Zo_ResetAlarm = 5470, + Zo_xxyyyy = 5481, + Zo_ResetAllAlarms = 5488, + Zo_xx000A00 = 5503, + Zo_HueSat = 5512, + Zo_xxyy0A00 = 5519, + Zo_Color = 5528, + Zo_xxxxyyyy0A00 = 5534, + Zo_xxxx0A00 = 5547, + Zo_ShutterOpen = 5556, + Zo_ShutterClose = 5568, + Zo_ShutterStop = 5581, + Zo_ShutterLift = 5593, + Zo_xx = 5605, + Zo_ShutterTilt = 5608, + Zo_Shutter = 5620, + Zo_DimmerMove = 5628, + Zo_xx0A = 5639, + Zo_DimmerStepUp = 5644, + Zo_00xx0A00 = 5657, + Zo_DimmerStepDown = 5666, + Zo_01xx0A00 = 5681, + Zo_DimmerStep = 5690, + Zo_xx190A00 = 5701, + Zo_01 = 5710, + Zo_HueMove = 5713, + Zo_xx19 = 5721, + Zo_HueStepUp = 5726, + Zo_HueStepDown = 5736, + Zo_03xx0A00 = 5748, + Zo_HueStep = 5757, + Zo_SatMove = 5765, + Zo_SatStep = 5773, + Zo_xx190A = 5781, + Zo_ColorMove = 5788, + Zo_xxxxyyyy = 5798, + Zo_ColorStep = 5807, + Zo_ColorTempMoveUp = 5817, + Zo_01xxxx000000000000 = 5833, + Zo_ColorTempMoveDown = 5852, + Zo_03xxxx000000000000 = 5870, + Zo_ColorTempMoveStop = 5889, + Zo_00xxxx000000000000 = 5907, + Zo_ColorTempMove = 5926, + Zo_xxyyyy000000000000 = 5940, + Zo_ColorTempStepUp = 5959, + Zo_01xxxx0A0000000000 = 5975, + Zo_ColorTempStepDown = 5994, + Zo_03xxxx0A0000000000 = 6012, + Zo_ColorTempStep = 6031, + Zo_xxyyyy0A0000000000 = 6045, + Zo_ArrowClick = 6064, + Zo_ArrowHold = 6075, + Zo_ArrowRelease = 6085, + Zo_ZoneStatusChange = 6098, + Zo_xxxxyyzz = 6115, + Zo_xxyyzzzz = 6124, + Zo_AddScene = 6133, + Zo_xxyyyyzz = 6142, + Zo_StoreScene = 6151, }; diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index bbaf670a0..5d96d9c70 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -129,7 +129,7 @@ enum Cx_cluster_short { Cx0010, Cx0011, Cx0012, Cx0013, Cx0014, Cx001A, Cx0020, Cx0100, Cx0101, Cx0102, Cx0201, Cx0300, Cx0400, Cx0401, Cx0402, Cx0403, Cx0404, Cx0405, Cx0406, Cx0500, Cx0702, Cx0B01, Cx0B04, Cx0B05, - CxEF00, + CxEF00, CxFCCC, }; const uint16_t Cx_cluster[] PROGMEM = { @@ -138,7 +138,7 @@ const uint16_t Cx_cluster[] PROGMEM = { 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x001A, 0x0020, 0x0100, 0x0101, 0x0102, 0x0201, 0x0300, 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0500, 0x0702, 0x0B01, 0x0B04, 0x0B05, - 0xEF00, + 0xEF00, 0xFCCC, }; uint16_t CxToCluster(uint8_t cx) { @@ -611,6 +611,10 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = { { Ztuya1, CxEF00, 0x0405, Z_(TuyaFanMode), Cm1, 0 }, { Ztuya1, CxEF00, 0x046A, Z_(TuyaForceMode), Cm1, 0 }, { Ztuya1, CxEF00, 0x046F, Z_(TuyaWeekSelect), Cm1, 0 }, + + // Terncy specific - 0xFCCC + { Zuint16, CxFCCC, 0x001A, Z_(TerncyDuration), Cm1, 0 }, + { Zint16, CxFCCC, 0x001B, Z_(TerncyRotate), Cm1, 0 }, }; #pragma GCC diagnostic pop diff --git a/tasmota/xdrv_23_zigbee_6_commands.ino b/tasmota/xdrv_23_zigbee_6_commands.ino index f3ad8748a..b409dcf86 100644 --- a/tasmota/xdrv_23_zigbee_6_commands.ino +++ b/tasmota/xdrv_23_zigbee_6_commands.ino @@ -136,6 +136,8 @@ const Z_CommandConverter Z_Commands[] PROGMEM = { { Z_(GetSceneMembership),0x0005, 0x06, 0x82,Z_(xxyyzzzz) }, // specific // Tuya - Moes specific { Z_(), 0xEF00, 0xFF, 0x83, Z_() }, // capture any command in 0xEF00 cluster + // Terncy specific + { Z_(), 0xFCCC, 0x00, 0x82, Z_(xxyy) }, // Terncy button (multi-)press }; /*********************************************************************************************\ @@ -419,6 +421,10 @@ void convertClusterSpecific(class Z_attribute_list &attr_list, uint16_t cluster, attr_list.removeAttribute(&attr_raw); // remove raw command } break; + case 0xFCCC0000: // Terncy button (multi-)press + attr_list.addAttribute(PSTR("TerncyPress"), true).setUInt(xyz.y); + attr_list.addAttribute(PSTR("TerncyCount"), true).setUInt(xyz.x); + break; } } else { // general case // do we send command with endpoint suffix