From 8be3da63e1ba7bf58eec5481887e9a5abfc1e459 Mon Sep 17 00:00:00 2001 From: Kevin Baluha Date: Thu, 31 Jan 2019 20:13:23 -0700 Subject: [PATCH 01/24] add functionality to use multiple ads1115's on one i2cbus --- sonoff/xsns_12_ads1115.ino | 77 +++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 22 deletions(-) diff --git a/sonoff/xsns_12_ads1115.ino b/sonoff/xsns_12_ads1115.ino index f75baa3e8..f2cfda028 100644 --- a/sonoff/xsns_12_ads1115.ino +++ b/sonoff/xsns_12_ads1115.ino @@ -119,7 +119,8 @@ CONFIG REGISTER uint8_t ads1115_type = 0; uint8_t ads1115_address; uint8_t ads1115_addresses[] = { ADS1115_ADDRESS_ADDR_GND, ADS1115_ADDRESS_ADDR_VDD, ADS1115_ADDRESS_ADDR_SDA, ADS1115_ADDRESS_ADDR_SCL }; - +uint8_t ads1115_found[] = {false,false,false,false}; +int16_t ads1115_values[4]; //Ads1115StartComparator(channel, ADS1115_REG_CONFIG_MODE_SINGLE); //Ads1115StartComparator(channel, ADS1115_REG_CONFIG_MODE_CONTIN); void Ads1115StartComparator(uint8_t channel, uint16_t mode) @@ -161,51 +162,83 @@ void Ads1115Detect(void) { uint16_t buffer; - if (ads1115_type) { - return; - } + //if (ads1115_type) { + //return; + //} for (uint8_t i = 0; i < sizeof(ads1115_addresses); i++) { ads1115_address = ads1115_addresses[i]; if (I2cValidRead16(&buffer, ads1115_address, ADS1115_REG_POINTER_CONVERT)) { Ads1115StartComparator(i, ADS1115_REG_CONFIG_MODE_CONTIN); ads1115_type = 1; + ads1115_found[i] = 1; snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "ADS1115", ads1115_address); AddLog(LOG_LEVEL_DEBUG); - break; + //break; } } } +void Ads1115GetValues(uint8_t address) { + uint8_t old_address = ads1115_address; + ads1115_address = address; + for (uint8_t i = 0; i < 4; i++) { + ads1115_values[i] = Ads1115GetConversion(i); + snprintf_P(log_data, sizeof(log_data), "Logging ADS1115 %02x (%i) = %i", address, i, ads1115_values[i] ); + AddLog(LOG_LEVEL_INFO); + } + ads1115_address = old_address; +} + +void Ads1115toJSON(char *comma_j) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s{"), mqtt_data,comma_j); + char *comma = (char*)""; + for (uint8_t i = 0; i < 4; i++) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"A%d\":%d"), mqtt_data, comma, i, ads1115_values[i]); + comma = (char*)","; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); +} + +void Ads1115toString(uint8_t address) { + char label[15]; + snprintf_P(label, sizeof(label), "ADS1115(%02x)", address); + + for (uint8_t i = 0; i < 4; i++) { + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, label, i, ads1115_values[i]); + } +} + void Ads1115Show(bool json) { - if (ads1115_type) { - char stemp[10]; + if (!ads1115_type) + return; - uint8_t dsxflg = 0; - for (uint8_t i = 0; i < 4; i++) { - int16_t adc_value = Ads1115GetConversion(i); + if (json) + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"ADS1115\":["), mqtt_data); + char *comma = (char*)""; + + for (uint8_t t = 0; t < sizeof(ads1115_addresses); t++) { + snprintf_P(log_data, sizeof(log_data), "Logging ADS1115 %02x", ads1115_addresses[t]); + AddLog(LOG_LEVEL_INFO); + if (ads1115_found[t]) { + Ads1115GetValues(ads1115_addresses[t]); if (json) { - if (!dsxflg ) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"ADS1115\":{"), mqtt_data); - stemp[0] = '\0'; + Ads1115toJSON(comma); + comma = (char*)","; } - dsxflg++; - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"A%d\":%d"), mqtt_data, stemp, i, adc_value); - strlcpy(stemp, ",", sizeof(stemp)); #ifdef USE_WEBSERVER - } else { - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, "ADS1115", i, adc_value); + else { + Ads1115toString(ads1115_addresses[t]); + } #endif // USE_WEBSERVER } } + if (json) { - if (dsxflg) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s]"), mqtt_data); } - } - } } /*********************************************************************************************\ From e9ad78c616c525ac70d9214c029b190723475d01 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 5 Feb 2019 10:13:22 +0100 Subject: [PATCH 02/24] Update xnrg_04_mcp39f501.ino Fix Exception 9 (Buffer overflow) --- sonoff/xnrg_04_mcp39f501.ino | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sonoff/xnrg_04_mcp39f501.ino b/sonoff/xnrg_04_mcp39f501.ino index 53034a73c..5247488e1 100644 --- a/sonoff/xnrg_04_mcp39f501.ino +++ b/sonoff/xnrg_04_mcp39f501.ino @@ -28,6 +28,7 @@ #define XNRG_04 4 +#define MCP_BAUDRATE 4800 #define MCP_TIMEOUT 4 #define MCP_CALIBRATION_TIMEOUT 2 @@ -66,7 +67,7 @@ #define MCP_BUFFER_SIZE 60 #include -TasmotaSerial *McpSerial; +TasmotaSerial *McpSerial = NULL; typedef struct mcp_cal_registers_type { uint16_t gain_current_rms; @@ -92,7 +93,6 @@ typedef struct mcp_cal_registers_type { } mcp_cal_registers_type; char *mcp_buffer = NULL; // Serial receive buffer -int mcp_byte_counter = 0; // Index in serial receive buffer unsigned long mcp_kWhcounter = 0; uint32_t mcp_system_configuration = 0x03000000; @@ -475,8 +475,10 @@ void McpParseData(void) void McpSerialInput(void) { if (McpSerial->available()) { + int mcp_byte_counter = 0; + unsigned long start = millis(); - while (millis() - start < 20) { + while ((millis() - start < (24000 / MCP_BAUDRATE) +1) && (mcp_byte_counter < MCP_BUFFER_SIZE)) { yield(); if (McpSerial->available()) { mcp_buffer[mcp_byte_counter++] = McpSerial->read(); @@ -515,7 +517,6 @@ void McpSerialInput(void) mcp_timeout = 0; } - mcp_byte_counter = 0; McpSerial->flush(); } } @@ -556,7 +557,7 @@ void McpSnsInit(void) { // Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions McpSerial = new TasmotaSerial(pin[GPIO_MCP39F5_RX], pin[GPIO_MCP39F5_TX], 1); - if (McpSerial->begin(4800)) { + if (McpSerial->begin(MCP_BAUDRATE)) { if (McpSerial->hardwareSerial()) { ClaimSerial(); } if (pin[GPIO_MCP39F5_RST] < 99) { digitalWrite(pin[GPIO_MCP39F5_RST], 1); // MCP enable @@ -652,10 +653,10 @@ int Xnrg04(uint8_t function) McpSnsInit(); break; case FUNC_LOOP: - McpSerialInput(); + if (McpSerial) { McpSerialInput(); } break; case FUNC_EVERY_SECOND: - McpEverySecond(); + if (McpSerial) { McpEverySecond(); } break; case FUNC_COMMAND: result = McpCommand(); From adecf6a9ce2d751064f5bd55b6179039cc86d32a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 5 Feb 2019 12:21:31 +0100 Subject: [PATCH 03/24] Fixes and Tuning Fixes and Tuning --- sonoff/xnrg_03_pzem004t.ino | 4 +-- sonoff/xnrg_04_mcp39f501.ino | 53 +++++++++++++++++++----------------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/sonoff/xnrg_03_pzem004t.ino b/sonoff/xnrg_03_pzem004t.ino index e0b6327bd..a15d61ba1 100644 --- a/sonoff/xnrg_03_pzem004t.ino +++ b/sonoff/xnrg_03_pzem004t.ino @@ -32,7 +32,7 @@ #include -TasmotaSerial *PzemSerial; +TasmotaSerial *PzemSerial = NULL; #define PZEM_VOLTAGE (uint8_t)0xB0 #define RESP_VOLTAGE (uint8_t)0xA0 @@ -239,7 +239,7 @@ int Xnrg03(uint8_t function) PzemSnsInit(); break; case FUNC_EVERY_200_MSECOND: - PzemEvery200ms(); + if (PzemSerial) { PzemEvery200ms(); } break; } } diff --git a/sonoff/xnrg_04_mcp39f501.ino b/sonoff/xnrg_04_mcp39f501.ino index 5247488e1..d878d9e8b 100644 --- a/sonoff/xnrg_04_mcp39f501.ino +++ b/sonoff/xnrg_04_mcp39f501.ino @@ -92,8 +92,8 @@ typedef struct mcp_cal_registers_type { uint16_t accumulation_interval; } mcp_cal_registers_type; -char *mcp_buffer = NULL; // Serial receive buffer - +char *mcp_buffer = NULL; +unsigned long mcp_window = 0; unsigned long mcp_kWhcounter = 0; uint32_t mcp_system_configuration = 0x03000000; uint32_t mcp_active_power; @@ -108,6 +108,7 @@ uint8_t mcp_calibration_active = 0; uint8_t mcp_init = 0; uint8_t mcp_timeout = 0; uint8_t mcp_calibrate = 0; +uint8_t mcp_byte_counter = 0; /*********************************************************************************************\ * Olimex tools @@ -474,21 +475,20 @@ void McpParseData(void) void McpSerialInput(void) { - if (McpSerial->available()) { - int mcp_byte_counter = 0; - - unsigned long start = millis(); - while ((millis() - start < (24000 / MCP_BAUDRATE) +1) && (mcp_byte_counter < MCP_BUFFER_SIZE)) { - yield(); - if (McpSerial->available()) { - mcp_buffer[mcp_byte_counter++] = McpSerial->read(); - start = millis(); - } - } + while ((McpSerial->available()) && (mcp_byte_counter < MCP_BUFFER_SIZE)) { + yield(); + mcp_buffer[mcp_byte_counter++] = McpSerial->read(); + mcp_window = millis(); + } + // Ignore until non received after 2 chars (= 12 bits/char) time + if ((mcp_byte_counter) && (millis() - mcp_window > (24000 / MCP_BAUDRATE) +1)) { AddLogBuffer(LOG_LEVEL_DEBUG_MORE, (uint8_t*)mcp_buffer, mcp_byte_counter); - if (1 == mcp_byte_counter) { + if (MCP_BUFFER_SIZE == mcp_byte_counter) { +// AddLog_P(LOG_LEVEL_DEBUG, PSTR("MCP: Overflow")); + } + else if (1 == mcp_byte_counter) { if (MCP_ERROR_CRC == mcp_buffer[0]) { // AddLog_P(LOG_LEVEL_DEBUG, PSTR("MCP: Send " D_CHECKSUM_FAILURE)); mcp_timeout = 0; @@ -517,6 +517,7 @@ void McpSerialInput(void) mcp_timeout = 0; } + mcp_byte_counter = 0; McpSerial->flush(); } } @@ -558,7 +559,12 @@ void McpSnsInit(void) // Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions McpSerial = new TasmotaSerial(pin[GPIO_MCP39F5_RX], pin[GPIO_MCP39F5_TX], 1); if (McpSerial->begin(MCP_BAUDRATE)) { - if (McpSerial->hardwareSerial()) { ClaimSerial(); } + if (McpSerial->hardwareSerial()) { + ClaimSerial(); + mcp_buffer = serial_in_buffer; // Use idle serial buffer to save RAM + } else { + mcp_buffer = (char*)(malloc(MCP_BUFFER_SIZE)); + } if (pin[GPIO_MCP39F5_RST] < 99) { digitalWrite(pin[GPIO_MCP39F5_RST], 1); // MCP enable } @@ -571,17 +577,14 @@ void McpDrvInit(void) { if (!energy_flg) { if ((pin[GPIO_MCP39F5_RX] < 99) && (pin[GPIO_MCP39F5_TX] < 99)) { - mcp_buffer = (char*)(malloc(MCP_BUFFER_SIZE)); - if (mcp_buffer != NULL) { - if (pin[GPIO_MCP39F5_RST] < 99) { - pinMode(pin[GPIO_MCP39F5_RST], OUTPUT); - digitalWrite(pin[GPIO_MCP39F5_RST], 0); // MCP disable - Reset Delta Sigma ADC's - } - mcp_calibrate = 0; - mcp_timeout = 2; // Initial wait - mcp_init = 2; // Initial setup steps - energy_flg = XNRG_04; + if (pin[GPIO_MCP39F5_RST] < 99) { + pinMode(pin[GPIO_MCP39F5_RST], OUTPUT); + digitalWrite(pin[GPIO_MCP39F5_RST], 0); // MCP disable - Reset Delta Sigma ADC's } + mcp_calibrate = 0; + mcp_timeout = 2; // Initial wait + mcp_init = 2; // Initial setup steps + energy_flg = XNRG_04; } } } From 9c8af6428ee9ce3ad6060e65d2774ebfa40e575d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 5 Feb 2019 14:13:53 +0100 Subject: [PATCH 04/24] Update xdrv_08_serial_bridge.ino Fix regression --- sonoff/xdrv_08_serial_bridge.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/xdrv_08_serial_bridge.ino b/sonoff/xdrv_08_serial_bridge.ino index bb2abab63..74915935c 100644 --- a/sonoff/xdrv_08_serial_bridge.ino +++ b/sonoff/xdrv_08_serial_bridge.ino @@ -42,7 +42,7 @@ void SerialBridgeInput(void) { while (SerialBridgeSerial->available()) { yield(); - uint8_t serial_in_uint8_t = SerialBridgeSerial->read(); + uint8_t serial_in_byte = SerialBridgeSerial->read(); if (serial_in_byte > 127) { // binary data... serial_bridge_in_byte_counter = 0; From c998760deb15caa37b3abcc079e007daab2e0669 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 5 Feb 2019 15:05:40 +0100 Subject: [PATCH 05/24] Update TasmotaSerial to 2.3.0 Update TasmotaSerial to 2.3.0 --- .../README.md | 0 .../examples/swsertest/swsertest.ino | 0 .../keywords.txt | 1 + .../library.json | 2 +- .../library.properties | 2 +- .../src/TasmotaSerial.cpp | 8 ++++---- .../src/TasmotaSerial.h | 4 ++-- 7 files changed, 9 insertions(+), 8 deletions(-) rename lib/{TasmotaSerial-2.2.0 => TasmotaSerial-2.3.0}/README.md (100%) rename lib/{TasmotaSerial-2.2.0 => TasmotaSerial-2.3.0}/examples/swsertest/swsertest.ino (100%) rename lib/{TasmotaSerial-2.2.0 => TasmotaSerial-2.3.0}/keywords.txt (95%) rename lib/{TasmotaSerial-2.2.0 => TasmotaSerial-2.3.0}/library.json (94%) rename lib/{TasmotaSerial-2.2.0 => TasmotaSerial-2.3.0}/library.properties (94%) rename lib/{TasmotaSerial-2.2.0 => TasmotaSerial-2.3.0}/src/TasmotaSerial.cpp (97%) rename lib/{TasmotaSerial-2.2.0 => TasmotaSerial-2.3.0}/src/TasmotaSerial.h (96%) diff --git a/lib/TasmotaSerial-2.2.0/README.md b/lib/TasmotaSerial-2.3.0/README.md similarity index 100% rename from lib/TasmotaSerial-2.2.0/README.md rename to lib/TasmotaSerial-2.3.0/README.md diff --git a/lib/TasmotaSerial-2.2.0/examples/swsertest/swsertest.ino b/lib/TasmotaSerial-2.3.0/examples/swsertest/swsertest.ino similarity index 100% rename from lib/TasmotaSerial-2.2.0/examples/swsertest/swsertest.ino rename to lib/TasmotaSerial-2.3.0/examples/swsertest/swsertest.ino diff --git a/lib/TasmotaSerial-2.2.0/keywords.txt b/lib/TasmotaSerial-2.3.0/keywords.txt similarity index 95% rename from lib/TasmotaSerial-2.2.0/keywords.txt rename to lib/TasmotaSerial-2.3.0/keywords.txt index 87974971e..9cf6d825c 100644 --- a/lib/TasmotaSerial-2.2.0/keywords.txt +++ b/lib/TasmotaSerial-2.3.0/keywords.txt @@ -14,6 +14,7 @@ TasmotaSerial KEYWORD1 ####################################### begin KEYWORD2 +hardwareSerial KEYWORD2 read KEYWORD2 write KEYWORD2 available KEYWORD2 diff --git a/lib/TasmotaSerial-2.2.0/library.json b/lib/TasmotaSerial-2.3.0/library.json similarity index 94% rename from lib/TasmotaSerial-2.2.0/library.json rename to lib/TasmotaSerial-2.3.0/library.json index 23a2ddab9..fad36bcc6 100644 --- a/lib/TasmotaSerial-2.2.0/library.json +++ b/lib/TasmotaSerial-2.3.0/library.json @@ -1,6 +1,6 @@ { "name": "TasmotaSerial", - "version": "2.2.0", + "version": "2.3.0", "keywords": [ "serial", "io", "TasmotaSerial" ], diff --git a/lib/TasmotaSerial-2.2.0/library.properties b/lib/TasmotaSerial-2.3.0/library.properties similarity index 94% rename from lib/TasmotaSerial-2.2.0/library.properties rename to lib/TasmotaSerial-2.3.0/library.properties index 54c79e218..095077d8e 100644 --- a/lib/TasmotaSerial-2.2.0/library.properties +++ b/lib/TasmotaSerial-2.3.0/library.properties @@ -1,5 +1,5 @@ name=TasmotaSerial -version=2.2.0 +version=2.3.0 author=Theo Arends maintainer=Theo Arends sentence=Implementation of software serial with hardware serial fallback for ESP8266. diff --git a/lib/TasmotaSerial-2.2.0/src/TasmotaSerial.cpp b/lib/TasmotaSerial-2.3.0/src/TasmotaSerial.cpp similarity index 97% rename from lib/TasmotaSerial-2.2.0/src/TasmotaSerial.cpp rename to lib/TasmotaSerial-2.3.0/src/TasmotaSerial.cpp index 3df42f834..eecdeb124 100644 --- a/lib/TasmotaSerial-2.2.0/src/TasmotaSerial.cpp +++ b/lib/TasmotaSerial-2.3.0/src/TasmotaSerial.cpp @@ -1,7 +1,7 @@ /* TasmotaSerial.cpp - Minimal implementation of software serial for Tasmota - Copyright (C) 2018 Theo Arends + Copyright (C) 2019 Theo Arends This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -100,7 +100,7 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fal m_buffer = (uint8_t*)malloc(TM_SERIAL_BUFFER_SIZE); if (m_buffer == NULL) return; // Use getCycleCount() loop to get as exact timing as possible - m_bit_time = ESP.getCpuFreqMHz() *1000000 /TM_SERIAL_BAUDRATE; + m_bit_time = F_CPU / TM_SERIAL_BAUDRATE; pinMode(m_rx_pin, INPUT); tms_obj_list[m_rx_pin] = this; attachInterrupt(m_rx_pin, ISRList[m_rx_pin], FALLING); @@ -145,7 +145,7 @@ bool TasmotaSerial::begin(long speed, int stop_bits) { } } else { // Use getCycleCount() loop to get as exact timing as possible - m_bit_time = ESP.getCpuFreqMHz() *1000000 /speed; + m_bit_time = F_CPU / speed; m_high_speed = (speed > 9600); } return m_valid; @@ -257,7 +257,7 @@ void TasmotaSerial::rxRead() TM_SERIAL_WAIT; } // Store the received value in the buffer unless we have an overflow - int next = (m_in_pos+1) % TM_SERIAL_BUFFER_SIZE; + unsigned int next = (m_in_pos+1) % TM_SERIAL_BUFFER_SIZE; if (next != (int)m_out_pos) { m_buffer[m_in_pos] = rec; m_in_pos = next; diff --git a/lib/TasmotaSerial-2.2.0/src/TasmotaSerial.h b/lib/TasmotaSerial-2.3.0/src/TasmotaSerial.h similarity index 96% rename from lib/TasmotaSerial-2.2.0/src/TasmotaSerial.h rename to lib/TasmotaSerial-2.3.0/src/TasmotaSerial.h index de991526a..9481ef370 100644 --- a/lib/TasmotaSerial-2.2.0/src/TasmotaSerial.h +++ b/lib/TasmotaSerial-2.3.0/src/TasmotaSerial.h @@ -1,7 +1,7 @@ /* TasmotaSerial.h - Minimal implementation of software serial for Tasmota - Copyright (C) 2018 Theo Arends + Copyright (C) 2019 Theo Arends This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,7 +22,7 @@ /*********************************************************************************************\ * TasmotaSerial supports up to 115200 baud with fixed buffer size of 64 bytes using optional no iram * - * Based on EspSoftwareSerial v3.3.1 by Peter Lerup (https://github.com/plerup/espsoftwareserial) + * Based on EspSoftwareSerial v3.4.3 by Peter Lerup (https://github.com/plerup/espsoftwareserial) \*********************************************************************************************/ #define TM_SERIAL_BAUDRATE 9600 // Default baudrate From 09732c9f2d116885ec3c748867e14f72820df947 Mon Sep 17 00:00:00 2001 From: Laurent Dong Date: Tue, 5 Feb 2019 09:34:17 -0500 Subject: [PATCH 06/24] Add new compare operators ("==", "!=" ,">=" and "<=") for rule Introduce new compare operators for rules and did some optimization as well. The new "==" operator act as a real number comparison instead of the previous "=" operator which is doing string comparison which result in FALSE for "1 + 1 = 2". For example: rule1 on event#test do backlog var1 1;add1 1; event CompareWith2=2 endon on event#CompareWith2=%var1% do ledpower on endon ledpower off rule1 on event test --- .gitignore | 1 + sonoff/xdrv_10_rules.ino | 82 ++++++++++++++++++++++++---------------- 2 files changed, 50 insertions(+), 33 deletions(-) diff --git a/.gitignore b/.gitignore index 028a76667..7e89f6cd2 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ build .vscode/.browse.c_cpp.db* .vscode/c_cpp_properties.json .vscode/launch.json +*.bak diff --git a/sonoff/xdrv_10_rules.ino b/sonoff/xdrv_10_rules.ino index 0ea47c369..d1f7c43b2 100644 --- a/sonoff/xdrv_10_rules.ino +++ b/sonoff/xdrv_10_rules.ino @@ -78,6 +78,27 @@ #define D_JSON_INITIATED "Initiated" +#define COMPARE_OPERATOR_NONE -1 +#define COMPARE_OPERATOR_EQUAL 0 +#define COMPARE_OPERATOR_BIGGER 1 +#define COMPARE_OPERATOR_SMALLER 2 +#define COMPARE_OPERATOR_EXACT_DIVISION 3 +#define COMPARE_OPERATOR_NUMBER_EQUAL 4 +#define COMPARE_OPERATOR_NOT_EQUAL 5 +#define COMPARE_OPERATOR_BIGGER_EQUAL 6 +#define COMPARE_OPERATOR_SMALLER_EQUAL 7 +#define MAXIMUM_COMPARE_OPERATOR COMPARE_OPERATOR_SMALLER_EQUAL +char* compare_operators[] = { + "=", + ">", + "<", + "|", + "==", + "!=", + ">=", + "<=" +}; + enum RulesCommands { CMND_RULE, CMND_RULETIMER, CMND_EVENT, CMND_VAR, CMND_MEM, CMND_ADD, CMND_SUB, CMND_MULT, CMND_SCALE, CMND_CALC_RESOLUTION }; const char kRulesCommands[] PROGMEM = D_CMND_RULE "|" D_CMND_RULETIMER "|" D_CMND_EVENT "|" D_CMND_VAR "|" D_CMND_MEM "|" D_CMND_ADD "|" D_CMND_SUB "|" D_CMND_MULT "|" D_CMND_SCALE "|" D_CMND_CALC_RESOLUTION ; @@ -128,31 +149,18 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule) String rule_name = rule.substring(pos +1); // "CURRENT>0.100" or "BOOT" or "%var1%" or "MINUTE|5" - char compare = ' '; - pos = rule_name.indexOf(">"); - if (pos > 0) { - compare = '>'; - } else { - pos = rule_name.indexOf("<"); - if (pos > 0) { - compare = '<'; - } else { - pos = rule_name.indexOf("="); - if (pos > 0) { - compare = '='; - } else { - pos = rule_name.indexOf("|"); // Modulo, cannot use % easily as it is used for variable detection - if (pos > 0) { - compare = '%'; - } - } + int8_t compare = COMPARE_OPERATOR_NONE; + for (int8_t i=MAXIMUM_COMPARE_OPERATOR; i>=0; i--) { + if ((pos = rule_name.indexOf(compare_operators[i])) > 0) { + compare = i; + break; } } char rule_svalue[CMDSZ] = { 0 }; double rule_value = 0; - if (pos > 0) { - String rule_param = rule_name.substring(pos + 1); + if (compare != COMPARE_OPERATOR_NONE) { + String rule_param = rule_name.substring(pos + strlen(compare_operators[compare])); for (uint8_t i = 0; i < MAX_RULE_VARS; i++) { snprintf_P(stemp, sizeof(stemp), PSTR("%%VAR%d%%"), i +1); if (rule_param.startsWith(stemp)) { @@ -224,24 +232,32 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule) int int_value = int(value); int int_rule_value = int(rule_value); switch (compare) { - case '%': - if ((int_value > 0) && (int_rule_value > 0)) { - if ((int_value % int_rule_value) == 0) { match = true; } - } + case COMPARE_OPERATOR_EXACT_DIVISION: + match = (int_rule_value && (int_value % int_rule_value) == 0); break; - case '>': - if (value > rule_value) { match = true; } + case COMPARE_OPERATOR_EQUAL: + match = (!strcasecmp(str_value, rule_svalue)); // Compare strings - this also works for hexadecimals break; - case '<': - if (value < rule_value) { match = true; } + case COMPARE_OPERATOR_BIGGER: + match = (value > rule_value); break; - case '=': -// if (value == rule_value) { match = true; } // Compare values - only decimals or partly hexadecimals - if (!strcasecmp(str_value, rule_svalue)) { match = true; } // Compare strings - this also works for hexadecimals + case COMPARE_OPERATOR_SMALLER: + match = (value < rule_value); break; - case ' ': - match = true; // Json value but not needed + case COMPARE_OPERATOR_NUMBER_EQUAL: + match = (value == rule_value); break; + case COMPARE_OPERATOR_NOT_EQUAL: + match = (value != rule_value); + break; + case COMPARE_OPERATOR_BIGGER_EQUAL: + match = (value >= rule_value); + break; + case COMPARE_OPERATOR_SMALLER_EQUAL: + match = (value <= rule_value); + break; + default: + match = true; } } else match = true; From ee2660b2bc332bf900897b1558bfb4f4c5a291cb Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 5 Feb 2019 17:45:35 +0100 Subject: [PATCH 07/24] Update xdrv_10_rules.ino Move const to flash --- sonoff/xdrv_10_rules.ino | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/sonoff/xdrv_10_rules.ino b/sonoff/xdrv_10_rules.ino index d1f7c43b2..327c128dc 100644 --- a/sonoff/xdrv_10_rules.ino +++ b/sonoff/xdrv_10_rules.ino @@ -78,26 +78,17 @@ #define D_JSON_INITIATED "Initiated" -#define COMPARE_OPERATOR_NONE -1 -#define COMPARE_OPERATOR_EQUAL 0 -#define COMPARE_OPERATOR_BIGGER 1 -#define COMPARE_OPERATOR_SMALLER 2 +#define COMPARE_OPERATOR_NONE -1 +#define COMPARE_OPERATOR_EQUAL 0 +#define COMPARE_OPERATOR_BIGGER 1 +#define COMPARE_OPERATOR_SMALLER 2 #define COMPARE_OPERATOR_EXACT_DIVISION 3 #define COMPARE_OPERATOR_NUMBER_EQUAL 4 #define COMPARE_OPERATOR_NOT_EQUAL 5 #define COMPARE_OPERATOR_BIGGER_EQUAL 6 #define COMPARE_OPERATOR_SMALLER_EQUAL 7 #define MAXIMUM_COMPARE_OPERATOR COMPARE_OPERATOR_SMALLER_EQUAL -char* compare_operators[] = { - "=", - ">", - "<", - "|", - "==", - "!=", - ">=", - "<=" -}; +const char kCompareOperators[] PROGMEM = "=\0>\0<\0|\0==!=>=<="; enum RulesCommands { CMND_RULE, CMND_RULETIMER, CMND_EVENT, CMND_VAR, CMND_MEM, CMND_ADD, CMND_SUB, CMND_MULT, CMND_SCALE, CMND_CALC_RESOLUTION }; const char kRulesCommands[] PROGMEM = D_CMND_RULE "|" D_CMND_RULETIMER "|" D_CMND_EVENT "|" D_CMND_VAR "|" D_CMND_MEM "|" D_CMND_ADD "|" D_CMND_SUB "|" D_CMND_MULT "|" D_CMND_SCALE "|" D_CMND_CALC_RESOLUTION ; @@ -149,9 +140,11 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule) String rule_name = rule.substring(pos +1); // "CURRENT>0.100" or "BOOT" or "%var1%" or "MINUTE|5" + char compare_operator[3]; int8_t compare = COMPARE_OPERATOR_NONE; - for (int8_t i=MAXIMUM_COMPARE_OPERATOR; i>=0; i--) { - if ((pos = rule_name.indexOf(compare_operators[i])) > 0) { + for (int8_t i = MAXIMUM_COMPARE_OPERATOR; i >= 0; i--) { + snprintf_P(compare_operator, sizeof(compare_operator), kCompareOperators + (i *2)); + if ((pos = rule_name.indexOf(compare_operator)) > 0) { compare = i; break; } @@ -160,7 +153,7 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule) char rule_svalue[CMDSZ] = { 0 }; double rule_value = 0; if (compare != COMPARE_OPERATOR_NONE) { - String rule_param = rule_name.substring(pos + strlen(compare_operators[compare])); + String rule_param = rule_name.substring(pos + strlen(compare_operator)); for (uint8_t i = 0; i < MAX_RULE_VARS; i++) { snprintf_P(stemp, sizeof(stemp), PSTR("%%VAR%d%%"), i +1); if (rule_param.startsWith(stemp)) { From b430a22e0ca931164b691aa3515990322d26aacc Mon Sep 17 00:00:00 2001 From: Jason2866 Date: Wed, 6 Feb 2019 19:57:11 +0100 Subject: [PATCH 08/24] Core 2.5.0 Release Changed core 2.5.0 beta3 to Release. --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 6b6176db0..5631982dd 100644 --- a/platformio.ini +++ b/platformio.ini @@ -65,7 +65,7 @@ build_flags = ${esp82xx_defaults.build_flags} -DVTABLES_IN_FLASH [core_2_5_0] -; *** Esp8266 core for Arduino version Core 2.5.0 beta3 tested for Tasmota +; *** Esp8266 core for Arduino version 2.5.0 release (still not available via platformio) platform = https://github.com/Jason2866/platform-espressif8266.git#Tasmota build_flags = ${esp82xx_defaults.build_flags} -Wl,-Teagle.flash.1m.ld From 3281055438bc6c17cfa379332e465bae81b51e19 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 6 Feb 2019 20:07:28 +0100 Subject: [PATCH 09/24] Add HASS status sensor --- sonoff/i18n.h | 1 + sonoff/xdrv_12_home_assistant.ino | 162 +++++++++++++++++++++++------- 2 files changed, 127 insertions(+), 36 deletions(-) diff --git a/sonoff/i18n.h b/sonoff/i18n.h index 3f9725772..7eace1215 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -160,6 +160,7 @@ #define D_JSON_ZERO_POINT_CALIBRATION "Zero Point Calibration" #define D_RSLT_ENERGY "ENERGY" +#define D_RSLT_HASS_STATE "HASS_STATE" #define D_RSLT_INFO "INFO" #define D_RSLT_MARGINS "MARGINS" #define D_RSLT_POWER "POWER" diff --git a/sonoff/xdrv_12_home_assistant.ino b/sonoff/xdrv_12_home_assistant.ino index 6b6d1bff3..155ee05a2 100644 --- a/sonoff/xdrv_12_home_assistant.ino +++ b/sonoff/xdrv_12_home_assistant.ino @@ -122,6 +122,11 @@ const char HASS_DISCOVER_SENSOR_ANY[] PROGMEM = "%s,\"unit_of_meas\":\" \"," // " " As unit of measurement to get a value graph in Hass "\"val_tpl\":\"{{value_json['%s'].%s}}\""; // "COUNTER":{"C1":0} -> {{ value_json['COUNTER'].C1 }} +const char HASS_DISCOVER_SENSOR_HASS_STATUS[] PROGMEM = + "%s,\"json_attributes_topic\":\"%s\"," + "\"unit_of_meas\":\" \"," // " " As unit of measurement to get a value graph in Hass + "\"val_tpl\":\"{{value_json['" D_JSON_RSSI "']}}\"";// "COUNTER":{"C1":0} -> {{ value_json['COUNTER'].C1 }} + const char HASS_DISCOVER_DEVICE_INFO[] PROGMEM = "%s,\"uniq_id\":\"%s\"," "\"device\":{\"identifiers\":[\"%06X\"]," @@ -130,11 +135,16 @@ const char HASS_DISCOVER_DEVICE_INFO[] PROGMEM = "\"sw_version\":\"%s%s\"," "\"manufacturer\":\"Tasmota\"}"; +const char HASS_DISCOVER_DEVICE_INFO_SHORT[] PROGMEM = + "%s,\"uniq_id\":\"%s\"," + "\"device\":{\"identifiers\":[\"%06X\"]}"; + const char HASS_DISCOVER_TOPIC_PREFIX[] PROGMEM = "%s, \"~\":\"%s\""; uint8_t hass_init_step = 0; uint8_t hass_mode = 0; +int hass_tele_period = 0; static void FindPrefix(char* s1, char* s2, char* out) { @@ -156,6 +166,23 @@ static void Shorten(char** s, char *prefix) } } +int try_snprintf_P(char *s, size_t n, const char *format, ... ) +{ + va_list args; + va_start(args, format); + int len = vsnprintf_P(NULL, 0, format, args); + if (len >= n) { + snprintf_P(log_data, sizeof(log_data), + PSTR("ERROR: MQTT discovery failed due to too long topic or friendly name. \ + Please shorten topic and friendly name.")); + AddLog(LOG_LEVEL_ERROR); + } else { + va_start(args, format); + vsnprintf_P(s, n, format, args); + } + va_end(args); +} + void HAssAnnounceRelayLight(void) { char stopic[TOPSZ]; @@ -174,11 +201,13 @@ void HAssAnnounceRelayLight(void) // Clear "other" topic first in case the device has been reconfigured from ligth to switch or vice versa snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s_%d"), ESP.getChipId(), (is_topic_light) ? "RL" : "LI", i); - snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s/config"), (is_topic_light) ? "switch" : "light", unique_id); + snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s/config"), + (is_topic_light) ? "switch" : "light", unique_id); MqttPublish(stopic, true); // Clear or Set topic snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s_%d"), ESP.getChipId(), (is_topic_light) ? "LI" : "RL", i); - snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s/config"), (is_topic_light) ? "light" : "switch", unique_id); + snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s/config"), + (is_topic_light) ? "light" : "switch", unique_id); if (Settings.flag.hass_discovery && (i <= devices_present)) { char name[33]; @@ -202,27 +231,30 @@ void HAssAnnounceRelayLight(void) Shorten(&command_topic, prefix); Shorten(&state_topic, prefix); Shorten(&availability_topic, prefix); - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_RELAY, + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_RELAY, name, command_topic, state_topic, value_template, Settings.state_text[0], Settings.state_text[1], availability_topic); + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_DEVICE_INFO_SHORT, mqtt_data, + unique_id, ESP.getChipId()); + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix); if (is_light) { char *brightness_command_topic = stemp1; GetTopic_P(brightness_command_topic, CMND, mqtt_topic, D_CMND_DIMMER); Shorten(&brightness_command_topic, prefix); - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_LIGHT_DIMMER, mqtt_data, brightness_command_topic, state_topic); + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_LIGHT_DIMMER, mqtt_data, brightness_command_topic, state_topic); if (light_subtype >= LST_RGB) { char *rgb_command_topic = stemp1; GetTopic_P(rgb_command_topic, CMND, mqtt_topic, D_CMND_COLOR); Shorten(&rgb_command_topic, prefix); - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_LIGHT_COLOR, mqtt_data, rgb_command_topic, state_topic); + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_LIGHT_COLOR, mqtt_data, rgb_command_topic, state_topic); char *effect_command_topic = stemp1; GetTopic_P(effect_command_topic, CMND, mqtt_topic, D_CMND_SCHEME); Shorten(&effect_command_topic, prefix); - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_LIGHT_SCHEME, mqtt_data, effect_command_topic, state_topic); + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_LIGHT_SCHEME, mqtt_data, effect_command_topic, state_topic); } if (LST_RGBW == light_subtype) { @@ -230,21 +262,17 @@ void HAssAnnounceRelayLight(void) GetTopic_P(white_temp_command_topic, CMND, mqtt_topic, D_CMND_WHITE); Shorten(&white_temp_command_topic, prefix); - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_LIGHT_WHITE, mqtt_data, white_temp_command_topic, state_topic); + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_LIGHT_WHITE, mqtt_data, white_temp_command_topic, state_topic); } if ((LST_COLDWARM == light_subtype) || (LST_RGBWC == light_subtype)) { char *color_temp_command_topic = stemp1; GetTopic_P(color_temp_command_topic, CMND, mqtt_topic, D_CMND_COLORTEMPERATURE); Shorten(&color_temp_command_topic, prefix); - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_LIGHT_CT, mqtt_data, color_temp_command_topic, state_topic); + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_LIGHT_CT, mqtt_data, color_temp_command_topic, state_topic); } } - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_DEVICE_INFO, mqtt_data, - unique_id, ESP.getChipId(), - Settings.friendlyname[0], ModuleName().c_str(), my_version, my_image); - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix); - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); + try_snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); } MqttPublish(stopic, true); } @@ -284,16 +312,15 @@ void HAssAnnounceButtonSwitch(uint8_t device, char* topic, uint8_t present, uint FindPrefix(state_topic, availability_topic, prefix); Shorten(&state_topic, prefix); Shorten(&availability_topic, prefix); - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_BUTTON_SWITCH, + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_BUTTON_SWITCH, name, state_topic, Settings.state_text[toggle?2:1], availability_topic); - if (toggle) snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_BUTTON_SWITCH_TOGGLE, mqtt_data); - else snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_BUTTON_SWITCH_ONOFF, mqtt_data, Settings.state_text[0]); + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_DEVICE_INFO_SHORT, mqtt_data, + unique_id, ESP.getChipId()); + if (strlen(prefix) > 0 ) try_snprintf_P(mqtt_data-1, sizeof(mqtt_data), HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix); + if (toggle) try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_BUTTON_SWITCH_TOGGLE, mqtt_data); + else try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_BUTTON_SWITCH_ONOFF, mqtt_data, Settings.state_text[0]); - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_DEVICE_INFO, mqtt_data, - unique_id, ESP.getChipId(), - Settings.friendlyname[0], ModuleName().c_str(), my_version, my_image); - if (strlen(prefix) > 0 ) snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix); - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); + try_snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); } MqttPublish(stopic, true); } @@ -386,39 +413,40 @@ void HAssAnnounceSensor(const char* sensorname, const char* subsensortype) Shorten(&state_topic, prefix); Shorten(&availability_topic, prefix); - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_SENSOR, + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR, name, state_topic, availability_topic); + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_DEVICE_INFO_SHORT, mqtt_data, + unique_id, ESP.getChipId()); + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix); if (!strcmp_P(subsensortype, PSTR(D_JSON_TEMPERATURE))) { - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_SENSOR_TEMP, + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_TEMP, mqtt_data, TempUnit(), sensorname); } else if (!strcmp_P(subsensortype, PSTR(D_JSON_HUMIDITY))) { - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_SENSOR_HUM, + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_HUM, mqtt_data, sensorname); } else if (!strcmp_P(subsensortype, PSTR(D_JSON_PRESSURE))) { - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_SENSOR_PRESS, + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_PRESS, mqtt_data, PressureUnit().c_str(), sensorname); - } else if (!strcmp_P(subsensortype, PSTR(D_JSON_TOTAL)) || !strcmp_P(subsensortype, PSTR(D_JSON_TODAY)) || !strcmp_P(subsensortype, PSTR(D_JSON_YESTERDAY))){ - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_SENSOR_KWH, + } else if (!strcmp_P(subsensortype, PSTR(D_JSON_TOTAL)) + || !strcmp_P(subsensortype, PSTR(D_JSON_TODAY)) + || !strcmp_P(subsensortype, PSTR(D_JSON_YESTERDAY))){ + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_KWH, mqtt_data, sensorname, subsensortype); } else if (!strcmp_P(subsensortype, PSTR(D_JSON_POWERUSAGE))){ - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_SENSOR_WATT, + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_WATT, mqtt_data, sensorname, subsensortype); } else if (!strcmp_P(subsensortype, PSTR(D_JSON_VOLTAGE))){ - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_SENSOR_VOLTAGE, + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_VOLTAGE, mqtt_data, sensorname, subsensortype); } else if (!strcmp_P(subsensortype, PSTR(D_JSON_CURRENT))){ - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_SENSOR_AMPERE, + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_AMPERE, mqtt_data, sensorname, subsensortype); } else { - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_SENSOR_ANY, + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_ANY, mqtt_data, sensorname, subsensortype); } - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_DEVICE_INFO, mqtt_data, - unique_id, ESP.getChipId(), - Settings.friendlyname[0], ModuleName().c_str(), my_version, my_image); - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix); - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); + try_snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); } MqttPublish(stopic, true); } @@ -469,6 +497,57 @@ void HAssAnnounceSensors(void) } while (hass_xsns_index != 0); } +void HAssAnnounceStatusSensor(void) +{ + char stopic[TOPSZ]; + char stemp1[TOPSZ]; + char stemp2[TOPSZ]; + char unique_id[30]; + + // Announce sensor + mqtt_data[0] = '\0'; // Clear retained message + + // Clear or Set topic + snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s"), ESP.getChipId(), "status"); + snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/sensor/%s/config"), unique_id); + + if (Settings.flag.hass_discovery) { + char name[33]; + char prefix[TOPSZ]; + char *state_topic = stemp1; + char *availability_topic = stemp2; + + snprintf_P(name, sizeof(name), PSTR("%s %s"), Settings.friendlyname[0], "status"); + GetTopic_P(state_topic, TELE, mqtt_topic, PSTR(D_RSLT_HASS_STATE)); + GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT); + FindPrefix(state_topic, availability_topic, prefix); + Shorten(&state_topic, prefix); + Shorten(&availability_topic, prefix); + + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR, + name, state_topic, availability_topic); + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_SENSOR_HASS_STATUS, + mqtt_data, state_topic); + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_DEVICE_INFO, mqtt_data, + unique_id, ESP.getChipId(), + Settings.friendlyname[0], ModuleName().c_str(), my_version, my_image); + try_snprintf_P(mqtt_data, sizeof(mqtt_data)-1, HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix); + try_snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); + } + MqttPublish(stopic, true); +} + +void HAssPublishStatus(void) +{ + snprintf_P(mqtt_data, sizeof(mqtt_data), + PSTR("{\"" D_JSON_VERSION "\":\"%s%s\",\"" D_CMND_MODULE "\":\"%s\",\"" D_JSON_RESTARTREASON "\":\"%s\",\"" + D_JSON_UPTIME "\":\"%s\",\"" D_JSON_BOOTCOUNT "\":%d,\"" D_JSON_SAVECOUNT "\":%d,\"" + D_CMND_IPADDRESS "\":\"%s\",\"" D_JSON_RSSI "\":\"%d\",\"LoadAvg\":%lu}"), + my_version, my_image, ModuleName().c_str(), GetResetReason().c_str(), GetUptime().c_str(), Settings.bootcount, + Settings.save_flag, WiFi.localIP().toString().c_str(), WifiGetRssiAsQuality(WiFi.RSSI()), loop_load_avg); + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_HASS_STATE)); +} + void HAssDiscovery(void) { // Configure Tasmota for default Home Assistant parameters to keep discovery message as short as possible @@ -496,6 +575,9 @@ void HAssDiscovery(void) // Send info about sensors HAssAnnounceSensors(); + + // Send info about status sensor + HAssAnnounceStatusSensor(); } } @@ -525,6 +607,14 @@ bool Xdrv12(uint8_t function) if (!hass_init_step) { HAssDiscovery(); // Scheduled discovery using available resources } + } else if (Settings.flag.hass_discovery && Settings.tele_period) { + hass_tele_period++; + if (hass_tele_period >= Settings.tele_period) { + hass_tele_period = 0; + + mqtt_data[0] = '\0'; + HAssPublishStatus(); + } } break; } From 08314bd9f8398c2497b7f67ad3c37eff17aa55f9 Mon Sep 17 00:00:00 2001 From: Jason2866 Date: Wed, 6 Feb 2019 22:34:41 +0100 Subject: [PATCH 10/24] Rf Bridge Gpio12 / 14 selectable Add GPIO12 and GPIO14 in Rf Bridge as GpioUser. This Gpio are not used and easy reachable via solder pads --- sonoff/sonoff_template.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index f86a6725d..1e5e1a573 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -1054,9 +1054,10 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { 0, // GPIO09 0, // GPIO10 // GPIO11 (SD_CMD Flash) - 0, + GPIO_USER, // GPIO12 Optional sensor GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status - 0, 0, 0, 0 + GPIO_USER, // GPIO14 Optional sensor + 0, 0, 0 }, { "Sonoff B1", // Sonoff B1 (ESP8285 - my9231) GPIO_KEY1, // GPIO00 Pad From a1ef7b254ed8b9c906c53532b1920c36c08f0ce9 Mon Sep 17 00:00:00 2001 From: Kevin Baluha Date: Thu, 7 Feb 2019 03:08:13 -0700 Subject: [PATCH 11/24] check if TSL2561::begin returns true to prevent false positives --- sonoff/xsns_12_ads1115.ino | 13 ++++++++----- sonoff/xsns_16_tsl2561.ino | 3 +-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/sonoff/xsns_12_ads1115.ino b/sonoff/xsns_12_ads1115.ino index f2cfda028..fa321a85c 100644 --- a/sonoff/xsns_12_ads1115.ino +++ b/sonoff/xsns_12_ads1115.ino @@ -161,6 +161,7 @@ int16_t Ads1115GetConversion(uint8_t channel) void Ads1115Detect(void) { uint16_t buffer; + uint16_t conf_buffer; //if (ads1115_type) { //return; @@ -168,7 +169,9 @@ void Ads1115Detect(void) for (uint8_t i = 0; i < sizeof(ads1115_addresses); i++) { ads1115_address = ads1115_addresses[i]; - if (I2cValidRead16(&buffer, ads1115_address, ADS1115_REG_POINTER_CONVERT)) { + if (I2cValidRead16(&buffer, ads1115_address, ADS1115_REG_POINTER_CONVERT) && + I2cValidRead16(&conf_buffer, ads1115_address, ADS1115_REG_POINTER_CONFIG)) { + Ads1115StartComparator(i, ADS1115_REG_CONFIG_MODE_CONTIN); ads1115_type = 1; ads1115_found[i] = 1; @@ -184,8 +187,8 @@ void Ads1115GetValues(uint8_t address) { ads1115_address = address; for (uint8_t i = 0; i < 4; i++) { ads1115_values[i] = Ads1115GetConversion(i); - snprintf_P(log_data, sizeof(log_data), "Logging ADS1115 %02x (%i) = %i", address, i, ads1115_values[i] ); - AddLog(LOG_LEVEL_INFO); + //snprintf_P(log_data, sizeof(log_data), "Logging ADS1115 %02x (%i) = %i", address, i, ads1115_values[i] ); + //AddLog(LOG_LEVEL_INFO); } ads1115_address = old_address; } @@ -220,8 +223,8 @@ void Ads1115Show(bool json) char *comma = (char*)""; for (uint8_t t = 0; t < sizeof(ads1115_addresses); t++) { - snprintf_P(log_data, sizeof(log_data), "Logging ADS1115 %02x", ads1115_addresses[t]); - AddLog(LOG_LEVEL_INFO); + //snprintf_P(log_data, sizeof(log_data), "Logging ADS1115 %02x", ads1115_addresses[t]); + //AddLog(LOG_LEVEL_INFO); if (ads1115_found[t]) { Ads1115GetValues(ads1115_addresses[t]); if (json) { diff --git a/sonoff/xsns_16_tsl2561.ino b/sonoff/xsns_16_tsl2561.ino index 0dbaf7141..a31debac6 100644 --- a/sonoff/xsns_16_tsl2561.ino +++ b/sonoff/xsns_16_tsl2561.ino @@ -65,8 +65,7 @@ void Tsl2561Detect(void) { if (tsl2561_type) { return; } - if (I2cDevice(0x29) || I2cDevice(0x39) || I2cDevice(0x49)) { - Tsl.begin(); + if ((I2cDevice(0x29) || I2cDevice(0x39) || I2cDevice(0x49))&&Tsl.begin()) { if (Tsl.on()) { tsl2561_type = 1; snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, tsl2561_types, Tsl.address()); From 58c7fac140ccdee8a53acb06a7a017ea3ca2ab1e Mon Sep 17 00:00:00 2001 From: Kevin Baluha Date: Thu, 7 Feb 2019 03:40:44 -0700 Subject: [PATCH 12/24] check id reg --- sonoff/xsns_16_tsl2561.ino | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sonoff/xsns_16_tsl2561.ino b/sonoff/xsns_16_tsl2561.ino index a31debac6..fecedd26e 100644 --- a/sonoff/xsns_16_tsl2561.ino +++ b/sonoff/xsns_16_tsl2561.ino @@ -64,11 +64,14 @@ bool Tsl2561Read(void) void Tsl2561Detect(void) { if (tsl2561_type) { return; } + uint8_t id; - if ((I2cDevice(0x29) || I2cDevice(0x39) || I2cDevice(0x49))&&Tsl.begin()) { + if (I2cDevice(0x29) || I2cDevice(0x39) || I2cDevice(0x49)) { + if (!Tsl.id(&id)) return; + Tsl.begin(); if (Tsl.on()) { tsl2561_type = 1; - snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, tsl2561_types, Tsl.address()); + snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, tsl2561_types, Tsl.address(), id); AddLog(LOG_LEVEL_DEBUG); } } From da3f4bcab7fea864d2f34741e7244dd9ba888725 Mon Sep 17 00:00:00 2001 From: Kevin Baluha Date: Thu, 7 Feb 2019 03:54:56 -0700 Subject: [PATCH 13/24] add a check for TLS2561 to prevent false positives --- sonoff/xsns_16_tsl2561.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/xsns_16_tsl2561.ino b/sonoff/xsns_16_tsl2561.ino index fecedd26e..f7777cf18 100644 --- a/sonoff/xsns_16_tsl2561.ino +++ b/sonoff/xsns_16_tsl2561.ino @@ -67,7 +67,7 @@ void Tsl2561Detect(void) uint8_t id; if (I2cDevice(0x29) || I2cDevice(0x39) || I2cDevice(0x49)) { - if (!Tsl.id(&id)) return; + if (!Tsl.id(id)) return; Tsl.begin(); if (Tsl.on()) { tsl2561_type = 1; From fd9f66ed6e04464d6bc66c8579e1716ff600ef4e Mon Sep 17 00:00:00 2001 From: andrethomas2 <43345003+andrethomas2@users.noreply.github.com> Date: Thu, 7 Feb 2019 19:09:49 +0200 Subject: [PATCH 14/24] ADS1115: Housekeeping --- sonoff/xsns_12_ads1115.ino | 73 ++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/sonoff/xsns_12_ads1115.ino b/sonoff/xsns_12_ads1115.ino index fa321a85c..51cbb6c43 100644 --- a/sonoff/xsns_12_ads1115.ino +++ b/sonoff/xsns_12_ads1115.ino @@ -161,64 +161,61 @@ int16_t Ads1115GetConversion(uint8_t channel) void Ads1115Detect(void) { uint16_t buffer; - uint16_t conf_buffer; - - //if (ads1115_type) { - //return; - //} - for (uint8_t i = 0; i < sizeof(ads1115_addresses); i++) { - ads1115_address = ads1115_addresses[i]; - if (I2cValidRead16(&buffer, ads1115_address, ADS1115_REG_POINTER_CONVERT) && - I2cValidRead16(&conf_buffer, ads1115_address, ADS1115_REG_POINTER_CONFIG)) { - - Ads1115StartComparator(i, ADS1115_REG_CONFIG_MODE_CONTIN); - ads1115_type = 1; - ads1115_found[i] = 1; - snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "ADS1115", ads1115_address); - AddLog(LOG_LEVEL_DEBUG); - //break; + if (!ads1115_found[i]) { + ads1115_address = ads1115_addresses[i]; + if (I2cValidRead16(&buffer, ads1115_address, ADS1115_REG_POINTER_CONVERT) && + I2cValidRead16(&buffer, ads1115_address, ADS1115_REG_POINTER_CONFIG)) { + Ads1115StartComparator(i, ADS1115_REG_CONFIG_MODE_CONTIN); + ads1115_type = 1; + ads1115_found[i] = 1; + snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "ADS1115", ads1115_address); + AddLog(LOG_LEVEL_DEBUG); + } } } } -void Ads1115GetValues(uint8_t address) { - uint8_t old_address = ads1115_address; - ads1115_address = address; - for (uint8_t i = 0; i < 4; i++) { - ads1115_values[i] = Ads1115GetConversion(i); - //snprintf_P(log_data, sizeof(log_data), "Logging ADS1115 %02x (%i) = %i", address, i, ads1115_values[i] ); - //AddLog(LOG_LEVEL_INFO); - } - ads1115_address = old_address; +void Ads1115GetValues(uint8_t address) +{ + uint8_t old_address = ads1115_address; + ads1115_address = address; + for (uint8_t i = 0; i < 4; i++) { + ads1115_values[i] = Ads1115GetConversion(i); + //snprintf_P(log_data, sizeof(log_data), "Logging ADS1115 %02x (%i) = %i", address, i, ads1115_values[i] ); + //AddLog(LOG_LEVEL_INFO); + } + ads1115_address = old_address; } -void Ads1115toJSON(char *comma_j) { +void Ads1115toJSON(char *comma_j) +{ snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s{"), mqtt_data,comma_j); char *comma = (char*)""; for (uint8_t i = 0; i < 4; i++) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"A%d\":%d"), mqtt_data, comma, i, ads1115_values[i]); comma = (char*)","; - } + } snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); } -void Ads1115toString(uint8_t address) { +void Ads1115toString(uint8_t address) +{ char label[15]; snprintf_P(label, sizeof(label), "ADS1115(%02x)", address); for (uint8_t i = 0; i < 4; i++) { snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, label, i, ads1115_values[i]); - } + } } void Ads1115Show(bool json) { - if (!ads1115_type) - return; + if (!ads1115_type) { return; } - if (json) + if (json) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"ADS1115\":["), mqtt_data); + } char *comma = (char*)""; @@ -230,18 +227,18 @@ void Ads1115Show(bool json) if (json) { Ads1115toJSON(comma); comma = (char*)","; - } + } #ifdef USE_WEBSERVER else { Ads1115toString(ads1115_addresses[t]); - } + } #endif // USE_WEBSERVER - } } + } - if (json) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s]"), mqtt_data); - } + if (json) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s]"), mqtt_data); + } } /*********************************************************************************************\ From afe797fd6ec9679c157ea2073f3d310e6a905234 Mon Sep 17 00:00:00 2001 From: Erik Date: Thu, 7 Feb 2019 20:41:38 +0100 Subject: [PATCH 15/24] Improve weblog robustness --- sonoff/xdrv_01_webserver.ino | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/sonoff/xdrv_01_webserver.ino b/sonoff/xdrv_01_webserver.ino index 51498abb4..316553130 100644 --- a/sonoff/xdrv_01_webserver.ino +++ b/sonoff/xdrv_01_webserver.ino @@ -129,11 +129,11 @@ const char HTTP_SCRIPT_CONSOL[] PROGMEM = "x.onreadystatechange=function(){" "if(x.readyState==4&&x.status==200){" "var z,d;" - "d=x.responseXML;" - "id=d.getElementsByTagName('i')[0].childNodes[0].nodeValue;" - "if(d.getElementsByTagName('j')[0].childNodes[0].nodeValue==0){t.value='';}" - "z=d.getElementsByTagName('l')[0].childNodes;" - "if(z.length>0){t.value+=decodeURIComponent(z[0].nodeValue);}" + "d=x.responseText.split(/\1/);" + "id=d.shift();" + "if(d.shift()==0){t.value='';}" + "z=d.shift();" + "if(z.length>0){t.value+=z;}" "t.scrollTop=99999;" "sn=t.scrollTop;" "}" @@ -1813,7 +1813,9 @@ void HandleAjaxConsoleRefresh(void) if (strlen(svalue)) { counter = atoi(svalue); } bool last_reset_web_log_flag = reset_web_log_flag; - String message = F("}9"); // Cannot load mqtt_data here as <> will be encoded by replacements below + // mqtt_data used as scratch space + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%d\1%d\1"), web_log_index, last_reset_web_log_flag); + String message = mqtt_data; if (!reset_web_log_flag) { counter = 0; reset_web_log_flag = true; @@ -1834,20 +1836,13 @@ void HandleAjaxConsoleRefresh(void) cflg = true; } strlcpy(mqtt_data, tmp, len); - message += mqtt_data; + message += mqtt_data; // mqtt_data used as scratch space } counter++; - if (!counter) { counter++; } // Skip 0 as it is not allowed + if (!counter) { counter++; } // Skip log index 0 as it is not allowed } while (counter != web_log_index); - // XML encoding to fix blank console log in concert with javascript decodeURIComponent - message.replace(F("%"), F("%25")); // Needs to be done first as otherwise the % in %26 will also be converted - message.replace(F("&"), F("%26")); - message.replace(F("<"), F("%3C")); - message.replace(F(">"), F("%3E")); } - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%d%d"), web_log_index, last_reset_web_log_flag); - message.replace(F("}9"), mqtt_data); // Save to load here - message += F(""); + message += F("\1"); WebServer->send(200, FPSTR(HDR_CTYPE_XML), message); } From 6f4e658f03541f579e2a0db6d623d1e2a5597b22 Mon Sep 17 00:00:00 2001 From: Erik Date: Thu, 7 Feb 2019 20:54:30 +0100 Subject: [PATCH 16/24] Increase length of name in HA AD msg. --- sonoff/xdrv_12_home_assistant.ino | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/sonoff/xdrv_12_home_assistant.ino b/sonoff/xdrv_12_home_assistant.ino index 155ee05a2..b6e6af299 100644 --- a/sonoff/xdrv_12_home_assistant.ino +++ b/sonoff/xdrv_12_home_assistant.ino @@ -173,8 +173,11 @@ int try_snprintf_P(char *s, size_t n, const char *format, ... ) int len = vsnprintf_P(NULL, 0, format, args); if (len >= n) { snprintf_P(log_data, sizeof(log_data), - PSTR("ERROR: MQTT discovery failed due to too long topic or friendly name. \ - Please shorten topic and friendly name.")); + PSTR("ERROR: MQTT discovery failed due to too long topic or friendly name. " + "Please shorten topic and friendly name. Failed to format(%u/%u):"), len, n); + AddLog(LOG_LEVEL_ERROR); + va_start(args, format); + vsnprintf_P(log_data, sizeof(log_data), format, args); AddLog(LOG_LEVEL_ERROR); } else { va_start(args, format); @@ -210,7 +213,7 @@ void HAssAnnounceRelayLight(void) (is_topic_light) ? "light" : "switch", unique_id); if (Settings.flag.hass_discovery && (i <= devices_present)) { - char name[33]; + char name[33+2]; // friendlyname(33) + " " + index char value_template[33]; char prefix[TOPSZ]; char *command_topic = stemp1; @@ -294,7 +297,7 @@ void HAssAnnounceButtonSwitch(uint8_t device, char* topic, uint8_t present, uint snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/binary_sensor/%s/config"), unique_id); if (Settings.flag.hass_discovery && present) { - char name[33]; + char name[33+6]; // friendlyname(33) + " " + "BTN" + " " + index char value_template[33]; char prefix[TOPSZ]; char *state_topic = stemp1; @@ -401,7 +404,7 @@ void HAssAnnounceSensor(const char* sensorname, const char* subsensortype) snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/sensor/%s/config"), unique_id); if (Settings.flag.hass_discovery) { - char name[33]; + char name[33+42]; // friendlyname(33) + " " + sensorname(20?) + " " + sensortype(20?) char prefix[TOPSZ]; char *state_topic = stemp1; char *availability_topic = stemp2; @@ -512,7 +515,7 @@ void HAssAnnounceStatusSensor(void) snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/sensor/%s/config"), unique_id); if (Settings.flag.hass_discovery) { - char name[33]; + char name[33+7]; // friendlyname(33) + " " + "status" char prefix[TOPSZ]; char *state_topic = stemp1; char *availability_topic = stemp2; From b76b615a6e3435517a10ea64ebc91605db931152 Mon Sep 17 00:00:00 2001 From: andrethomas Date: Fri, 8 Feb 2019 00:41:46 +0200 Subject: [PATCH 17/24] PN532: Deprecate I2C support --- sonoff/my_user_config.h | 3 - sonoff/xsns_40_pn532.ino | 0 sonoff/xsns_40_pn532_i2c.ino | 606 ----------------------------------- 3 files changed, 609 deletions(-) create mode 100644 sonoff/xsns_40_pn532.ino delete mode 100644 sonoff/xsns_40_pn532_i2c.ino diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index c9c6505d5..f9aaf25d7 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -326,9 +326,6 @@ // #define USE_DS3231 // Enable DS3231 external RTC in case no Wifi is avaliable. See docs in the source file (+1k2 code) // #define USE_RTC_ADDR 0x68 // Default I2C address 0x68 // #define USE_MGC3130 // Enable MGC3130 Electric Field Effect Sensor (I2C address 0x42) (+2k7 code, 0k3 mem) -// #define USE_PN532_I2C // Enable PN532 - Near Field Communication (NFC) controller (+1k7 code, 164 bytes of mem) -// #define USE_PN532_DATA_FUNCTION // Enable PN532 DATA Usage using Sensor15 command (+1k6 code, 316 bytes of mem) -// #define USE_PN532_CAUSE_EVENTS // Enable PN532 driver to cause event's on card read in addition to immediate telemetry (+64 bytes code, 48 bytes mem) // #define USE_MAX44009 // Enable MAX44009 Ambient Light sensor (I2C addresses 0x4A and 0x4B) (+0k8 code) // #define USE_DISPLAY // Add I2C Display Support (+2k code) diff --git a/sonoff/xsns_40_pn532.ino b/sonoff/xsns_40_pn532.ino new file mode 100644 index 000000000..e69de29bb diff --git a/sonoff/xsns_40_pn532_i2c.ino b/sonoff/xsns_40_pn532_i2c.ino deleted file mode 100644 index 640e21c6e..000000000 --- a/sonoff/xsns_40_pn532_i2c.ino +++ /dev/null @@ -1,606 +0,0 @@ -/* - xsns_40_pn532.ino - Support for PN532 (I2C) NFC Tag Reader - - Copyright (C) 2019 Andre Thomas 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 . -*/ - -#ifdef USE_I2C -#ifdef USE_PN532_I2C - -/*********************************************************************************************\ - * PN532 - Near Field Communication (NFC) controller - * - * Datasheet at https://www.nxp.com/docs/en/nxp/data-sheets/PN532_C1.pdf - * - * I2C Address: 0x24 -\*********************************************************************************************/ - -#define XSNS_40 40 - -#define PN532_I2C_ADDRESS 0x24 - -#define PN532_COMMAND_GETFIRMWAREVERSION 0x02 -#define PN532_COMMAND_SAMCONFIGURATION 0x14 -#define PN532_COMMAND_INDATAEXCHANGE 0x40 -#define PN532_COMMAND_INLISTPASSIVETARGET 0x4A - -#define MIFARE_CMD_READ 0x30 -#define MIFARE_CMD_AUTH_A 0x60 -#define MIFARE_CMD_AUTH_B 0x61 -#define MIFARE_CMD_WRITE 0xA0 - -#define PN532_PREAMBLE 0x00 -#define PN532_STARTCODE1 0x00 -#define PN532_STARTCODE2 0xFF -#define PN532_POSTAMBLE 0x00 - -#define PN532_HOSTTOPN532 0xD4 -#define PN532_PN532TOHOST 0xD5 - -#define PN532_INVALID_ACK -1 -#define PN532_TIMEOUT -2 -#define PN532_INVALID_FRAME -3 -#define PN532_NO_SPACE -4 - -#define PN532_MIFARE_ISO14443A 0x00 - -uint8_t pn532_i2c_detected = 0; -uint8_t pn532_i2c_packetbuffer[64]; -uint8_t pn532_i2c_scan_defer_report = 0; // If a valid card was found we will not scan for one again in the same two seconds so we set this to 19 if a card was found -uint8_t pn532_i2c_command = 0; - -uint8_t pn532_i2c_disable = 0; - -#ifdef USE_PN532_DATA_FUNCTION -uint8_t pn532_i2c_function = 0; -uint8_t pn532_i2c_newdata[16]; -uint8_t pn532_i2c_newdata_len = 0; -#endif // USE_PN532_DATA_FUNCTION - -const uint8_t PROGMEM pn532_global_timeout = 10; - -int16_t PN532_getResponseLength(uint8_t buf[], uint8_t len) { - const uint8_t PN532_NACK[] = {0, 0, 0xFF, 0xFF, 0, 0}; - uint8_t time = 0; - do { - if (Wire.requestFrom(PN532_I2C_ADDRESS, 6)) { - if (Wire.read() & 1) { // check first byte --- status - break; // PN532 is ready - } - } - delay(1); - time++; - if (time > pn532_global_timeout) { - return -1; - } - } while (1); - - if ((0x00 != Wire.read()) || (0x00 != Wire.read()) || (0xFF != Wire.read())) { // PREAMBLE || STARTCODE1 || STARTCODE2 - return PN532_INVALID_FRAME; - } - - uint8_t length = Wire.read(); - - // request for last respond msg again - Wire.beginTransmission(PN532_I2C_ADDRESS); - for (uint16_t i = 0;i < sizeof(PN532_NACK); ++i) { - Wire.write(PN532_NACK[i]); - } - Wire.endTransmission(); - return length; -} - - -int16_t PN532_readResponse(uint8_t buf[], uint8_t len) -{ - uint8_t time = 0; - uint8_t length; - - length = PN532_getResponseLength(buf, len); - - // [RDY] 00 00 FF LEN LCS (TFI PD0 ... PDn) DCS 00 - - do { - if (Wire.requestFrom(PN532_I2C_ADDRESS, 6 + length + 2)) { - if (Wire.read() & 1) { // check first byte --- status - break; // PN532 is ready - } - } - delay(1); - time++; - if (time > pn532_global_timeout) { - return -1; - } - } while (1); - - if ((0x00 != Wire.read()) || (0x00 != Wire.read()) || (0xFF != Wire.read())) { // PREAMBLE || STARTCODE1 || STARTCODE2 - return PN532_INVALID_FRAME; - } - - length = Wire.read(); - - if (0 != (uint8_t)(length + Wire.read())) { // checksum of length - return PN532_INVALID_FRAME; - } - - uint8_t cmd = pn532_i2c_command + 1; // response command - if ((PN532_PN532TOHOST != Wire.read()) || ((cmd) != Wire.read())) { - return PN532_INVALID_FRAME; - } - length -= 2; - if (length > len) { - return PN532_NO_SPACE; // not enough space - } - uint8_t sum = PN532_PN532TOHOST + cmd; - for (uint8_t i = 0; i < length; i++) { - buf[i] = Wire.read(); - sum += buf[i]; - } - uint8_t checksum = Wire.read(); - if (0 != (uint8_t)(sum + checksum)) { - return PN532_INVALID_FRAME; - } - Wire.read(); // POSTAMBLE - return length; -} - - -int8_t PN532_readAckFrame(void) -{ - const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0}; - uint8_t ackBuf[sizeof(PN532_ACK)]; - - uint8_t time = 0; - - do { - if (Wire.requestFrom(PN532_I2C_ADDRESS, sizeof(PN532_ACK) + 1)) { - if (Wire.read() & 1) { // check first byte --- status - break; // PN532 is ready - } - } - delay(1); - time++; - if (time > pn532_global_timeout) { // We time out after 10ms - return PN532_TIMEOUT; - } - } while (1); - - for (uint8_t i = 0; i < sizeof(PN532_ACK); i++) { - ackBuf[i] = Wire.read(); - } - - if (memcmp(ackBuf, PN532_ACK, sizeof(PN532_ACK))) { - return PN532_INVALID_ACK; - } - - return 0; -} - -int8_t PN532_writeCommand(const uint8_t *header, uint8_t hlen) -{ - pn532_i2c_command = header[0]; - Wire.beginTransmission(PN532_I2C_ADDRESS); - Wire.write(PN532_PREAMBLE); - Wire.write(PN532_STARTCODE1); - Wire.write(PN532_STARTCODE2); - uint8_t length = hlen + 1; // TFI + DATA - Wire.write(length); - Wire.write(~length + 1); // checksum of length - Wire.write(PN532_HOSTTOPN532); - uint8_t sum = PN532_HOSTTOPN532; // Sum of TFI + DATA - for (uint8_t i = 0; i < hlen; i++) { - if (Wire.write(header[i])) { - sum += header[i]; - } else { - return PN532_INVALID_FRAME; - } - } - uint8_t checksum = ~sum + 1; // Checksum of TFI + DATA - Wire.write(checksum); - Wire.write(PN532_POSTAMBLE); - Wire.endTransmission(); - return PN532_readAckFrame(); -} - -uint32_t PN532_getFirmwareVersion(void) -{ - uint32_t response; - pn532_i2c_packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION; - if (PN532_writeCommand(pn532_i2c_packetbuffer, 1)) { - return 0; - } - int16_t status = PN532_readResponse(pn532_i2c_packetbuffer, sizeof(pn532_i2c_packetbuffer)); - if (0 > status) { - return 0; - } - response = pn532_i2c_packetbuffer[0]; - response <<= 8; - response |= pn532_i2c_packetbuffer[1]; - response <<= 8; - response |= pn532_i2c_packetbuffer[2]; - response <<= 8; - response |= pn532_i2c_packetbuffer[3]; - return response; -} - -bool PN532_SAMConfig(void) -{ - pn532_i2c_packetbuffer[0] = PN532_COMMAND_SAMCONFIGURATION; - pn532_i2c_packetbuffer[1] = 0x01; // normal mode; - pn532_i2c_packetbuffer[2] = 0x01; // timeout 50ms * 1 = 50ms - pn532_i2c_packetbuffer[3] = 0x00; // Disable IRQ pin - - if (PN532_writeCommand(pn532_i2c_packetbuffer, 4)) - return false; - - return (0 < PN532_readResponse(pn532_i2c_packetbuffer, sizeof(pn532_i2c_packetbuffer))); -} - -void PN532_Detect(void) -{ - if ((pn532_i2c_detected) || (pn532_i2c_disable)) { return; } - - Wire.setClockStretchLimit(1000); // Enable 1ms clock stretch as per datasheet Table 12.25 (Timing for the I2C interface) - - uint32_t ver = PN532_getFirmwareVersion(); - if (ver) { - pn532_i2c_detected = 1; - snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "PN532 NFC Reader (V%u.%u)", PN532_I2C_ADDRESS); - snprintf_P(log_data, sizeof(log_data), log_data, (ver>>16) & 0xFF, (ver>>8) & 0xFF); - AddLog(LOG_LEVEL_DEBUG); - PN532_SAMConfig(); - } -} - -bool PN532_readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength) -{ - pn532_i2c_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET; - pn532_i2c_packetbuffer[1] = 1; - pn532_i2c_packetbuffer[2] = cardbaudrate; - - if (PN532_writeCommand(pn532_i2c_packetbuffer, 3)) { - return false; // command failed - } - - if (PN532_readResponse(pn532_i2c_packetbuffer, sizeof(pn532_i2c_packetbuffer)) < 0) { // No data packet so no tag was found - Wire.beginTransmission(PN532_I2C_ADDRESS); - Wire.endTransmission(); - return false; - } - - if (pn532_i2c_packetbuffer[0] != 1) { return false; } // Not a valid tag - - *uidLength = pn532_i2c_packetbuffer[5]; - for (uint8_t i = 0;i < pn532_i2c_packetbuffer[5]; i++) { - uid[i] = pn532_i2c_packetbuffer[6 + i]; - } - return true; -} - -#ifdef USE_PN532_DATA_FUNCTION - -uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) -{ - uint8_t i; - uint8_t _key[6]; - uint8_t _uid[7]; - uint8_t _uidLen; - - // Hang on to the key and uid data - memcpy (_key, keyData, 6); - memcpy (_uid, uid, uidLen); - _uidLen = uidLen; - - // Prepare the authentication command // - pn532_i2c_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; /* Data Exchange Header */ - pn532_i2c_packetbuffer[1] = 1; /* Max card numbers */ - pn532_i2c_packetbuffer[2] = (keyNumber) ? MIFARE_CMD_AUTH_B : MIFARE_CMD_AUTH_A; - pn532_i2c_packetbuffer[3] = blockNumber; /* Block Number (1K = 0..63, 4K = 0..255 */ - memcpy (&pn532_i2c_packetbuffer[4], _key, 6); - for (i = 0; i < _uidLen; i++) { - pn532_i2c_packetbuffer[10 + i] = _uid[i]; /* 4 bytes card ID */ - } - - if (PN532_writeCommand(pn532_i2c_packetbuffer, 10 + _uidLen)) - return 0; - - // Read the response packet - PN532_readResponse(pn532_i2c_packetbuffer, sizeof(pn532_i2c_packetbuffer)); - - // Check if the response is valid and we are authenticated??? - // for an auth success it should be bytes 5-7: 0xD5 0x41 0x00 - // Mifare auth error is technically byte 7: 0x14 but anything other and 0x00 is not good - if (pn532_i2c_packetbuffer[0] != 0x00) { - // Authentification failed - return 0; - } - - return 1; -} - -uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) -{ - /* Prepare the command */ - pn532_i2c_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; - pn532_i2c_packetbuffer[1] = 1; /* Card number */ - pn532_i2c_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */ - pn532_i2c_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */ - - /* Send the command */ - if (PN532_writeCommand(pn532_i2c_packetbuffer, 4)) { - return 0; - } - - /* Read the response packet */ - PN532_readResponse(pn532_i2c_packetbuffer, sizeof(pn532_i2c_packetbuffer)); - - /* If byte 8 isn't 0x00 we probably have an error */ - if (pn532_i2c_packetbuffer[0] != 0x00) { - return 0; - } - - /* Copy the 16 data bytes to the output buffer */ - /* Block content starts at byte 9 of a valid response */ - memcpy (data, &pn532_i2c_packetbuffer[1], 16); - - return 1; -} - -uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) -{ - /* Prepare the first command */ - pn532_i2c_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; - pn532_i2c_packetbuffer[1] = 1; /* Card number */ - pn532_i2c_packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */ - pn532_i2c_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */ - memcpy(&pn532_i2c_packetbuffer[4], data, 16); /* Data Payload */ - - /* Send the command */ - if (PN532_writeCommand(pn532_i2c_packetbuffer, 20)) { - return 0; - } - - /* Read the response packet */ - return (0 < PN532_readResponse(pn532_i2c_packetbuffer, sizeof(pn532_i2c_packetbuffer))); -} - -#endif // USE_PN532_DATA_FUNCTION - -void PN532_ScanForTag(void) -{ - if (pn532_i2c_disable) { return; } - uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; - uint8_t uid_len = 0; - uint8_t card_data[16]; - bool erase_success = false; - bool set_success = false; - if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uid_len)) { - if (pn532_i2c_scan_defer_report > 0) { - pn532_i2c_scan_defer_report--; - } else { - char uids[15]; - -#ifdef USE_PN532_DATA_FUNCTION - char card_datas[34]; -#endif // USE_PN532_DATA_FUNCTION - - sprintf(uids,""); - for (uint8_t i = 0;i < uid_len;i++) { - sprintf(uids,"%s%02X",uids,uid[i]); - } - -#ifdef USE_PN532_DATA_FUNCTION - if (uid_len == 4) { // Lets try to read block 0 of the mifare classic card for more information - uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) { - if (mifareclassic_ReadDataBlock(1, card_data)) { -#ifdef USE_PN532_DATA_RAW - memcpy(&card_datas,&card_data,sizeof(card_data)); -#else - for (uint8_t i = 0;i < sizeof(card_data);i++) { - if ((isalpha(card_data[i])) || ((isdigit(card_data[i])))) { - card_datas[i] = char(card_data[i]); - } else { - card_datas[i] = '\0'; - } - } -#endif // USE_PN532_DATA_RAW - } - if (pn532_i2c_function == 1) { // erase block 1 of card - for (uint8_t i = 0;i<16;i++) { - card_data[i] = 0x00; - } - if (mifareclassic_WriteDataBlock(1, card_data)) { - erase_success = true; - snprintf_P(log_data, sizeof(log_data),"I2C: PN532 NFC - Erase success"); - AddLog(LOG_LEVEL_INFO); - memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string - } - } - if (pn532_i2c_function == 2) { -#ifdef USE_PN532_DATA_RAW - memcpy(&card_data,&pn532_i2c_newdata,sizeof(card_data)); - if (mifareclassic_WriteDataBlock(1, card_data)) { - set_success = true; - snprintf_P(log_data, sizeof(log_data),"I2C: PN532 NFC - Data write successful"); - AddLog(LOG_LEVEL_INFO); - memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string - } -#else - bool IsAlphaNumeric = true; - for (uint8_t i = 0;i < pn532_i2c_newdata_len;i++) { - if ((!isalpha(pn532_i2c_newdata[i])) && (!isdigit(pn532_i2c_newdata[i]))) { - IsAlphaNumeric = false; - } - } - if (IsAlphaNumeric) { - memcpy(&card_data,&pn532_i2c_newdata,pn532_i2c_newdata_len); - card_data[pn532_i2c_newdata_len] = '\0'; // Enforce null termination - if (mifareclassic_WriteDataBlock(1, card_data)) { - set_success = true; - snprintf_P(log_data, sizeof(log_data),"I2C: PN532 NFC - Data write successful"); - AddLog(LOG_LEVEL_INFO); - memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string - } - } else { - snprintf_P(log_data, sizeof(log_data),"I2C: PN532 NFC - Data must be alphanumeric"); - AddLog(LOG_LEVEL_INFO); - } -#endif // USE_PN532_DATA_RAW - } - } else { - sprintf(card_datas,"AUTHFAIL"); - } - } - switch (pn532_i2c_function) { - case 0x01: - if (!erase_success) { - snprintf_P(log_data, sizeof(log_data),"I2C: PN532 NFC - Erase fail - exiting erase mode"); - AddLog(LOG_LEVEL_INFO); - } - break; - case 0x02: - if (!set_success) { - snprintf_P(log_data, sizeof(log_data),"I2C: PN532 NFC - Write failed - exiting set mode"); - AddLog(LOG_LEVEL_INFO); - } - default: - break; - } - pn532_i2c_function = 0; -#endif // USE_PN532_DATA_FUNCTION - - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL).c_str()); - -#ifdef USE_PN532_DATA_FUNCTION - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"PN532\":{\"UID\":\"%s\", \"DATA\":\"%s\"}}"), mqtt_data, uids, card_datas); -#else - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"PN532\":{\"UID\":\"%s\"}}"), mqtt_data, uids); -#endif // USE_PN532_DATA_FUNCTION - - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); - -#ifdef USE_PN532_CAUSE_EVENTS - - char command[71]; -#ifdef USE_PN532_DATA_FUNCTION - sprintf(command,"backlog event PN532_UID=%s;event PN532_DATA=%s",uids,card_datas); -#else - sprintf(command,"event PN532_UID=%s",uids); -#endif // USE_PN532_DATA_FUNCTION - ExecuteCommand(command, SRC_RULE); -#endif // USE_PN532_CAUSE_EVENTS - - pn532_i2c_scan_defer_report = 7; // Ignore tags found for two seconds - } - } else { - if (pn532_i2c_scan_defer_report > 0) { pn532_i2c_scan_defer_report--; } - } -} - -#ifdef USE_PN532_DATA_FUNCTION - -bool PN532_Command(void) -{ - bool serviced = true; - uint8_t paramcount = 0; - if (XdrvMailbox.data_len > 0) { - paramcount=1; - } else { - serviced = false; - return serviced; - } - char sub_string[XdrvMailbox.data_len]; - char sub_string_tmp[XdrvMailbox.data_len]; - for (uint8_t ca=0;ca 1) { - if (XdrvMailbox.data[XdrvMailbox.data_len-1] == ',') { - serviced = false; - return serviced; - } - sprintf(sub_string_tmp,subStr(sub_string, XdrvMailbox.data, ",", 2)); - pn532_i2c_newdata_len = strlen(sub_string_tmp); - if (pn532_i2c_newdata_len > 15) { pn532_i2c_newdata_len = 15; } - memcpy(&pn532_i2c_newdata,&sub_string_tmp,pn532_i2c_newdata_len); - pn532_i2c_newdata[pn532_i2c_newdata_len] = 0x00; // Null terminate the string - pn532_i2c_function = 2; - snprintf_P(log_data, sizeof(log_data),"I2C: PN532 NFC - Next scanned tag data block 1 will be set to '%s'",pn532_i2c_newdata); - AddLog(LOG_LEVEL_INFO); - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL).c_str()); - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"PN532\":{\"COMMAND\":\"S\"\"}}"), mqtt_data); - return serviced; - } - } -} - -#endif // USE_PN532_DATA_FUNCTION - -/*********************************************************************************************\ - * Interface -\*********************************************************************************************/ - -bool Xsns40(uint8_t function) -{ - bool result = false; - - if (i2c_flg) { - switch (function) { - case FUNC_EVERY_250_MSECOND: - if (pn532_i2c_detected) { - PN532_ScanForTag(); - } - break; - case FUNC_EVERY_SECOND: - PN532_Detect(); - break; - -#ifdef USE_PN532_DATA_FUNCTION - case FUNC_COMMAND: - if (XSNS_40 == XdrvMailbox.index) { - result = PN532_Command(); - } - break; -#endif // USE_PN532_DATA_FUNCTION - - case FUNC_SAVE_BEFORE_RESTART: - if (!pn532_i2c_disable) { - pn532_i2c_disable = 1; - snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "PN532 NFC Reader - Disabling for reboot", PN532_I2C_ADDRESS); - AddLog(LOG_LEVEL_DEBUG); - } - break; - default: - break; - } - } - return result; -} - -#endif // USE_PN532_I2C -#endif // USE_I2C From 707b51f292c08ef94ad9aa7908ead56e66d71ab9 Mon Sep 17 00:00:00 2001 From: andrethomas Date: Fri, 8 Feb 2019 01:06:54 +0200 Subject: [PATCH 18/24] PN532: Implement HSU (Serial) --- sonoff/language/bg-BG.h | 2 + sonoff/language/cs-CZ.h | 2 + sonoff/language/de-DE.h | 2 + sonoff/language/el-GR.h | 2 + sonoff/language/en-GB.h | 2 + sonoff/language/es-AR.h | 2 + sonoff/language/fr-FR.h | 2 + sonoff/language/he-HE.h | 2 + sonoff/language/hu-HU.h | 2 + sonoff/language/it-IT.h | 2 + sonoff/language/nl-NL.h | 2 + sonoff/language/pl-PL.h | 2 + sonoff/language/pt-BR.h | 2 + sonoff/language/pt-PT.h | 2 + sonoff/language/ru-RU.h | 2 + sonoff/language/sk-SK.h | 2 + sonoff/language/sv-SE.h | 2 + sonoff/language/tr-TR.h | 2 + sonoff/language/uk-UK.h | 2 + sonoff/language/zh-CN.h | 2 + sonoff/language/zh-TW.h | 2 + sonoff/my_user_config.h | 3 + sonoff/sonoff_template.h | 7 + sonoff/xsns_40_pn532.ino | 615 +++++++++++++++++++++++++++++++++++++++ 24 files changed, 667 insertions(+) diff --git a/sonoff/language/bg-BG.h b/sonoff/language/bg-BG.h index a490f8e6e..dec628ae1 100644 --- a/sonoff/language/bg-BG.h +++ b/sonoff/language/bg-BG.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/cs-CZ.h b/sonoff/language/cs-CZ.h index b16ccf37f..d6c73baa9 100644 --- a/sonoff/language/cs-CZ.h +++ b/sonoff/language/cs-CZ.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index 8ad86d173..a9d85ba3c 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/el-GR.h b/sonoff/language/el-GR.h index f5f281ca4..b6b9dfa9d 100644 --- a/sonoff/language/el-GR.h +++ b/sonoff/language/el-GR.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index 7c03e76f4..0a85d6a8b 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index 73ec924c8..4503c4e57 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h index 09b7ef831..89a863810 100644 --- a/sonoff/language/fr-FR.h +++ b/sonoff/language/fr-FR.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/he-HE.h b/sonoff/language/he-HE.h index 64e6aeae3..7e2deacab 100644 --- a/sonoff/language/he-HE.h +++ b/sonoff/language/he-HE.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h index 6a6a21020..a7db58513 100644 --- a/sonoff/language/hu-HU.h +++ b/sonoff/language/hu-HU.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h index 145b6064c..a5ffca743 100644 --- a/sonoff/language/it-IT.h +++ b/sonoff/language/it-IT.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index cef56fb2e..773442714 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index dba0726e4..63a15c5a5 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pt-BR.h b/sonoff/language/pt-BR.h index f8d037e83..1b0c34b16 100644 --- a/sonoff/language/pt-BR.h +++ b/sonoff/language/pt-BR.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pt-PT.h b/sonoff/language/pt-PT.h index aeed10329..b969449d2 100644 --- a/sonoff/language/pt-PT.h +++ b/sonoff/language/pt-PT.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/ru-RU.h b/sonoff/language/ru-RU.h index aaa457ec7..b2ad0a1d8 100644 --- a/sonoff/language/ru-RU.h +++ b/sonoff/language/ru-RU.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "А" diff --git a/sonoff/language/sk-SK.h b/sonoff/language/sk-SK.h index e1ecafd63..49430c31e 100644 --- a/sonoff/language/sk-SK.h +++ b/sonoff/language/sk-SK.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/sv-SE.h b/sonoff/language/sv-SE.h index 5a7934d71..61ab33b57 100644 --- a/sonoff/language/sv-SE.h +++ b/sonoff/language/sv-SE.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/tr-TR.h b/sonoff/language/tr-TR.h index 344e65b58..cfad17ca0 100755 --- a/sonoff/language/tr-TR.h +++ b/sonoff/language/tr-TR.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/uk-UK.h b/sonoff/language/uk-UK.h index be8f0530a..ce72f093f 100644 --- a/sonoff/language/uk-UK.h +++ b/sonoff/language/uk-UK.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "А" diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h index fbdc82207..a022f7939 100644 --- a/sonoff/language/zh-CN.h +++ b/sonoff/language/zh-CN.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "安" diff --git a/sonoff/language/zh-TW.h b/sonoff/language/zh-TW.h index 008c33a10..06274c41b 100644 --- a/sonoff/language/zh-TW.h +++ b/sonoff/language/zh-TW.h @@ -553,6 +553,8 @@ #define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" // Units #define D_UNIT_AMPERE "安" diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index f9aaf25d7..0d50b580b 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -375,6 +375,9 @@ #define USE_ARMTRONIX_DIMMERS // Add support for Armtronix Dimmers (+1k4 code) #define USE_PS_16_DZ // Add support for PS-16-DZ Dimmer //#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code) +//#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+3k7 code, 280 bytes mem) +// #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 356 bytes mem) +// #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (-0k2 code, -32 bytes ram) // Power monitoring sensors ----------------------- #define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 1e5e1a573..ff2ba6401 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -162,6 +162,8 @@ enum UserSelectablePins { GPIO_MCP39F5_TX, // MCP39F501 Serial interface (Shelly2) GPIO_MCP39F5_RX, // MCP39F501 Serial interface (Shelly2) GPIO_MCP39F5_RST, // MCP39F501 Reset (Shelly2) + GPIO_PN532_RXD, // PN532 NFC Serial Rx + GPIO_PN532_TXD, // PN532 NFC Serial Tx GPIO_SENSOR_END }; // Programmer selectable GPIO functionality offset by user selectable GPIOs @@ -227,6 +229,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_BUTTON "1in|" D_SENSOR_BUTTON "2in|" D_SENSOR_BUTTON "3in|" D_SENSOR_BUTTON "4in|" D_SENSOR_NRG_SEL "|" D_SENSOR_NRG_SEL "i|" D_SENSOR_NRG_CF1 "|" D_SENSOR_HLW_CF "|" D_SENSOR_HJL_CF "|" D_SENSOR_MCP39F5_TX "|" D_SENSOR_MCP39F5_RX "|" D_SENSOR_MCP39F5_RST + D_SENSOR_PN532_TX "|" D_SENSOR_PN532_RX ; /********************************************************************************************/ @@ -546,6 +549,10 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_MAX31855CLK, // MAX31855 Serial interface GPIO_MAX31855DO, // MAX31855 Serial interface #endif +#ifdef USE_PN532_HSU + GPIO_PN532_RXD, // PN532 HSU Rx + GPIO_PN532_TXD, // PN532 HSU Tx +#endif }; const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { diff --git a/sonoff/xsns_40_pn532.ino b/sonoff/xsns_40_pn532.ino index e69de29bb..af00720b2 100644 --- a/sonoff/xsns_40_pn532.ino +++ b/sonoff/xsns_40_pn532.ino @@ -0,0 +1,615 @@ +/* + xsns_40_pn532.ino - Support for PN532 (HSU) NFC Tag Reader + + Copyright (C) 2019 Andre Thomas 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 . +*/ + +#ifdef USE_PN532_HSU + +#define XSNS_40 40 + +#include + +TasmotaSerial *PN532_Serial; + +#define PN532_INVALID_ACK -1 +#define PN532_TIMEOUT -2 +#define PN532_INVALID_FRAME -3 +#define PN532_NO_SPACE -4 + +#define PN532_PREAMBLE 0x00 +#define PN532_STARTCODE1 0x00 +#define PN532_STARTCODE2 0xFF +#define PN532_POSTAMBLE 0x00 + +#define PN532_HOSTTOPN532 0xD4 +#define PN532_PN532TOHOST 0xD5 + +#define PN532_ACK_WAIT_TIME 0x0A + +#define PN532_COMMAND_GETFIRMWAREVERSION 0x02 +#define PN532_COMMAND_SAMCONFIGURATION 0x14 +#define PN532_COMMAND_RFCONFIGURATION 0x32 +#define PN532_COMMAND_INDATAEXCHANGE 0x40 +#define PN532_COMMAND_INLISTPASSIVETARGET 0x4A + +#define PN532_MIFARE_ISO14443A 0x00 +#define MIFARE_CMD_READ 0x30 +#define MIFARE_CMD_AUTH_A 0x60 +#define MIFARE_CMD_AUTH_B 0x61 +#define MIFARE_CMD_WRITE 0xA0 + +uint8_t pn532_model = 0; // Used to maintain detection flag +uint8_t pn532_command = 0; // Used to carry command code between functions +uint8_t pn532_scantimer = 0; // Used to prevent multiple successful reads within 2 second window + +uint8_t pn532_packetbuffer[64]; // Global buffer used to store packet + +#ifdef USE_PN532_DATA_FUNCTION +uint8_t pn532_function = 0; +uint8_t pn532_newdata[16]; +uint8_t pn532_newdata_len = 0; +#endif // USE_PN532_DATA_FUNCTION + +void PN532_Init(void) +{ + if ((pin[GPIO_PN532_RXD] < 99) && (pin[GPIO_PN532_TXD] < 99)) { + PN532_Serial = new TasmotaSerial(pin[GPIO_PN532_RXD], pin[GPIO_PN532_TXD], 1); + if (PN532_Serial->begin(115200)) { + if (PN532_Serial->hardwareSerial()) { ClaimSerial(); } + PN532_wakeup(); + uint32_t ver = PN532_getFirmwareVersion(); + if (ver) { + PN532_setPassiveActivationRetries(0xFF); + PN532_SAMConfig(); + pn532_model = 1; + snprintf_P(log_data, sizeof(log_data),"NFC: PN532 NFC Reader detected (V%u.%u)",(ver>>16) & 0xFF, (ver>>8) & 0xFF); + AddLog(LOG_LEVEL_INFO); + } + } + } +} + +int8_t PN532_receive(uint8_t *buf, int len, uint16_t timeout) +{ + int read_bytes = 0; + int ret; + unsigned long start_millis; + while (read_bytes < len) { + start_millis = millis(); + do { + ret = PN532_Serial->read(); + if (ret >= 0) { + break; + } + } while((timeout == 0) || ((millis()- start_millis ) < timeout)); + + if (ret < 0) { + if (read_bytes) { + return read_bytes; + } else { + return PN532_TIMEOUT; + } + } + buf[read_bytes] = (uint8_t)ret; + read_bytes++; + } + return read_bytes; +} + +int8_t PN532_readAckFrame(void) +{ + const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0}; + uint8_t ackBuf[sizeof(PN532_ACK)]; + + if (PN532_receive(ackBuf, sizeof(PN532_ACK), PN532_ACK_WAIT_TIME) <= 0) { + return PN532_TIMEOUT; + } + + if (memcmp(&ackBuf, &PN532_ACK, sizeof(PN532_ACK))) { + return PN532_INVALID_ACK; + } + return 0; +} + +int8_t PN532_writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body = 0, uint8_t blen = 0) +{ + // Clear the serial buffer just in case + while(PN532_Serial->available()) { PN532_Serial->read(); } + + pn532_command = header[0]; + PN532_Serial->write((uint8_t)PN532_PREAMBLE); + PN532_Serial->write((uint8_t)PN532_STARTCODE1); + PN532_Serial->write(PN532_STARTCODE2); + + uint8_t length = hlen + blen + 1; // length of data field: TFI + DATA + PN532_Serial->write(length); + PN532_Serial->write(~length + 1); // checksum of length + + PN532_Serial->write(PN532_HOSTTOPN532); + uint8_t sum = PN532_HOSTTOPN532; // sum of TFI + DATA + + PN532_Serial->write(header, hlen); + for (uint8_t i = 0; i < hlen; i++) { + sum += header[i]; + } + + PN532_Serial->write(body, blen); + for (uint8_t i = 0; i < blen; i++) { + sum += body[i]; + } + + uint8_t checksum = ~sum + 1; // checksum of TFI + DATA + PN532_Serial->write(checksum); + PN532_Serial->write((uint8_t)PN532_POSTAMBLE); + + return PN532_readAckFrame(); +} + +int16_t PN532_readResponse(uint8_t buf[], uint8_t len, uint16_t timeout = 50) +{ + uint8_t tmp[3]; + + // Read preamble and start code + if (PN532_receive(tmp, 3, timeout)<=0) { + return PN532_TIMEOUT; + } + if (0 != tmp[0] || 0!= tmp[1] || 0xFF != tmp[2]) { + return PN532_INVALID_FRAME; + } + + // Get length of data to be received + uint8_t length[2]; + if (PN532_receive(length, 2, timeout) <= 0) { + return PN532_TIMEOUT; + } + // Validate that frame is valid + if (0 != (uint8_t)(length[0] + length[1])) { + return PN532_INVALID_FRAME; + } + length[0] -= 2; + if (length[0] > len) { // If this happens, then pn532_packetbuffer is not large enough + return PN532_NO_SPACE; + } + + // Get the command byte + uint8_t cmd = pn532_command + 1; + if (PN532_receive(tmp, 2, timeout) <= 0) { // Time out while receiving + return PN532_TIMEOUT; + } + if (PN532_PN532TOHOST != tmp[0] || cmd != tmp[1]) { // Invalid frame received + return PN532_INVALID_FRAME; + } + + if (PN532_receive(buf, length[0], timeout) != length[0]) { // Timed out + return PN532_TIMEOUT; + } + + uint8_t sum = PN532_PN532TOHOST + cmd; + for (uint8_t i=0; i status) { + return 0; + } + + response = pn532_packetbuffer[0]; + response <<= 8; + response |= pn532_packetbuffer[1]; + response <<= 8; + response |= pn532_packetbuffer[2]; + response <<= 8; + response |= pn532_packetbuffer[3]; + + return response; +} + +void PN532_wakeup(void) +{ + uint8_t wakeup[5] = {0x55, 0x55, 0, 0, 0 }; + PN532_Serial->write(wakeup,sizeof(wakeup)); + + // Flush the serial buffer just in case there's garbage in there + while(PN532_Serial->available()) { PN532_Serial->read(); } +} + +bool PN532_readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout = 50) +{ + pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET; + pn532_packetbuffer[1] = 1; // max 1 cards at once (we can set this to 2 later) + pn532_packetbuffer[2] = cardbaudrate; + if (PN532_writeCommand(pn532_packetbuffer, 3)) { + return 0x0; // command failed + } + // read data packet + if (PN532_readResponse(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout) < 0) { + return 0x0; + } + + /* Check some basic stuff + b0 Tags Found + b1 Tag Number (only one used in this example) + b2..3 SENS_RES + b4 SEL_RES + b5 NFCID Length + b6..NFCIDLen NFCID + */ + + if (pn532_packetbuffer[0] != 1) { + return 0; + } + + uint16_t sens_res = pn532_packetbuffer[2]; + sens_res <<= 8; + sens_res |= pn532_packetbuffer[3]; + + /* Card appears to be Mifare Classic */ + *uidLength = pn532_packetbuffer[5]; + + for (uint8_t i = 0; i < pn532_packetbuffer[5]; i++) { + uid[i] = pn532_packetbuffer[6 + i]; + } + + return 1; +} + +bool PN532_setPassiveActivationRetries(uint8_t maxRetries) +{ + pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION; + pn532_packetbuffer[1] = 5; // Config item 5 (MaxRetries) + pn532_packetbuffer[2] = 0xFF; // MxRtyATR (default = 0xFF) + pn532_packetbuffer[3] = 0x01; // MxRtyPSL (default = 0x01) + pn532_packetbuffer[4] = maxRetries; + if (PN532_writeCommand(pn532_packetbuffer, 5)) { + return 0; // no ACK + } + return (0 < PN532_readResponse(pn532_packetbuffer, sizeof(pn532_packetbuffer))); +} + +bool PN532_SAMConfig(void) +{ + pn532_packetbuffer[0] = PN532_COMMAND_SAMCONFIGURATION; + pn532_packetbuffer[1] = 0x01; // normal mode + pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second + pn532_packetbuffer[3] = 0x00; // we don't need the external IRQ pin + if (PN532_writeCommand(pn532_packetbuffer, 4)) { + return false; + } + return (0 < PN532_readResponse(pn532_packetbuffer, sizeof(pn532_packetbuffer))); +} + +#ifdef USE_PN532_DATA_FUNCTION + +uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) +{ + uint8_t i; + uint8_t _key[6]; + uint8_t _uid[7]; + uint8_t _uidLen; + + // Hang on to the key and uid data + memcpy(&_key, keyData, 6); + memcpy(&_uid, uid, uidLen); + _uidLen = uidLen; + + // Prepare the authentication command // + pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; /* Data Exchange Header */ + pn532_packetbuffer[1] = 1; /* Max card numbers */ + pn532_packetbuffer[2] = (keyNumber) ? MIFARE_CMD_AUTH_B : MIFARE_CMD_AUTH_A; + pn532_packetbuffer[3] = blockNumber; /* Block Number (1K = 0..63, 4K = 0..255 */ + memcpy(&pn532_packetbuffer[4], &_key, 6); + for (i = 0; i < _uidLen; i++) { + pn532_packetbuffer[10 + i] = _uid[i]; /* 4 bytes card ID */ + } + + if (PN532_writeCommand(pn532_packetbuffer, 10 + _uidLen)) { return 0; } + + // Read the response packet + PN532_readResponse(pn532_packetbuffer, sizeof(pn532_packetbuffer)); + + // Check if the response is valid and we are authenticated??? + // for an auth success it should be bytes 5-7: 0xD5 0x41 0x00 + // Mifare auth error is technically byte 7: 0x14 but anything other and 0x00 is not good + if (pn532_packetbuffer[0] != 0x00) { + // Authentification failed + return 0; + } + + return 1; +} + +uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) +{ + /* Prepare the command */ + pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; + pn532_packetbuffer[1] = 1; /* Card number */ + pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */ + pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */ + + /* Send the command */ + if (PN532_writeCommand(pn532_packetbuffer, 4)) { + return 0; + } + + /* Read the response packet */ + PN532_readResponse(pn532_packetbuffer, sizeof(pn532_packetbuffer)); + + /* If byte 8 isn't 0x00 we probably have an error */ + if (pn532_packetbuffer[0] != 0x00) { + return 0; + } + + /* Copy the 16 data bytes to the output buffer */ + /* Block content starts at byte 9 of a valid response */ + memcpy (data, &pn532_packetbuffer[1], 16); + + return 1; +} + +uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) +{ + /* Prepare the first command */ + pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; + pn532_packetbuffer[1] = 1; /* Card number */ + pn532_packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */ + pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */ + memcpy(&pn532_packetbuffer[4], data, 16); /* Data Payload */ + + /* Send the command */ + if (PN532_writeCommand(pn532_packetbuffer, 20)) { + return 0; + } + + /* Read the response packet */ + return (0 < PN532_readResponse(pn532_packetbuffer, sizeof(pn532_packetbuffer))); +} + +#endif // USE_PN532_DATA_FUNCTION + +void PN532_ScanForTag(void) +{ + if (!pn532_model) { return; } + uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; + uint8_t uid_len = 0; + uint8_t card_data[16]; + bool erase_success = false; + bool set_success = false; + if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uid_len)) { + char uids[15]; + +#ifdef USE_PN532_DATA_FUNCTION + char card_datas[34]; +#endif // USE_PN532_DATA_FUNCTION + + sprintf(uids,""); + for (uint8_t i = 0;i < uid_len;i++) { + sprintf(uids,"%s%02X",uids,uid[i]); + } + +#ifdef USE_PN532_DATA_FUNCTION + if (uid_len == 4) { // Lets try to read block 1 of the mifare classic card for more information + uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) { + if (mifareclassic_ReadDataBlock(1, card_data)) { +#ifdef USE_PN532_DATA_RAW + memcpy(&card_datas,&card_data,sizeof(card_data)); +#else + for (uint8_t i = 0;i < sizeof(card_data);i++) { + if ((isalpha(card_data[i])) || ((isdigit(card_data[i])))) { + card_datas[i] = char(card_data[i]); + } else { + card_datas[i] = '\0'; + } + } +#endif // USE_PN532_DATA_RAW + } + if (pn532_function == 1) { // erase block 1 of card + for (uint8_t i = 0;i<16;i++) { + card_data[i] = 0x00; + } + if (mifareclassic_WriteDataBlock(1, card_data)) { + erase_success = true; + snprintf_P(log_data, sizeof(log_data),"NFC: PN532 NFC - Erase success"); + AddLog(LOG_LEVEL_INFO); + memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string + } + } + if (pn532_function == 2) { +#ifdef USE_PN532_DATA_RAW + memcpy(&card_data,&pn532_newdata,sizeof(card_data)); + if (mifareclassic_WriteDataBlock(1, card_data)) { + set_success = true; + snprintf_P(log_data, sizeof(log_data),"NFC: PN532 NFC - Data write successful"); + AddLog(LOG_LEVEL_INFO); + memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string + } +#else + bool IsAlphaNumeric = true; + for (uint8_t i = 0;i < pn532_newdata_len;i++) { + if ((!isalpha(pn532_newdata[i])) && (!isdigit(pn532_newdata[i]))) { + IsAlphaNumeric = false; + } + } + if (IsAlphaNumeric) { + memcpy(&card_data,&pn532_newdata,pn532_newdata_len); + card_data[pn532_newdata_len] = '\0'; // Enforce null termination + if (mifareclassic_WriteDataBlock(1, card_data)) { + set_success = true; + snprintf_P(log_data, sizeof(log_data),"NFC: PN532 NFC - Data write successful"); + AddLog(LOG_LEVEL_INFO); + memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string + } + } else { + snprintf_P(log_data, sizeof(log_data),"NFC: PN532 NFC - Data must be alphanumeric"); + AddLog(LOG_LEVEL_INFO); + } +#endif // USE_PN532_DATA_RAW + } + } else { + sprintf(card_datas,"AUTHFAIL"); + } + } + switch (pn532_function) { + case 0x01: + if (!erase_success) { + snprintf_P(log_data, sizeof(log_data),"NFC: PN532 NFC - Erase fail - exiting erase mode"); + AddLog(LOG_LEVEL_INFO); + } + break; + case 0x02: + if (!set_success) { + snprintf_P(log_data, sizeof(log_data),"NFC: PN532 NFC - Write failed - exiting set mode"); + AddLog(LOG_LEVEL_INFO); + } + default: + break; + } + pn532_function = 0; +#endif // USE_PN532_DATA_FUNCTION + + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL).c_str()); + +#ifdef USE_PN532_DATA_FUNCTION + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"PN532\":{\"UID\":\"%s\", \"DATA\":\"%s\"}}"), mqtt_data, uids, card_datas); +#else + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"PN532\":{\"UID\":\"%s\"}}"), mqtt_data, uids); +#endif // USE_PN532_DATA_FUNCTION + + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); + +#ifdef USE_PN532_CAUSE_EVENTS + + char command[71]; +#ifdef USE_PN532_DATA_FUNCTION + sprintf(command,"backlog event PN532_UID=%s;event PN532_DATA=%s",uids,card_datas); +#else + sprintf(command,"event PN532_UID=%s",uids); +#endif // USE_PN532_DATA_FUNCTION + ExecuteCommand(command, SRC_RULE); +#endif // USE_PN532_CAUSE_EVENTS + + pn532_scantimer = 7; // Ignore tags found for two seconds + } +} + +#ifdef USE_PN532_DATA_FUNCTION + +bool PN532_Command(void) +{ + bool serviced = true; + uint8_t paramcount = 0; + if (XdrvMailbox.data_len > 0) { + paramcount=1; + } else { + serviced = false; + return serviced; + } + char sub_string[XdrvMailbox.data_len]; + char sub_string_tmp[XdrvMailbox.data_len]; + for (uint8_t ca=0;ca 1) { + if (XdrvMailbox.data[XdrvMailbox.data_len-1] == ',') { + serviced = false; + return serviced; + } + sprintf(sub_string_tmp,subStr(sub_string, XdrvMailbox.data, ",", 2)); + pn532_newdata_len = strlen(sub_string_tmp); + if (pn532_newdata_len > 15) { pn532_newdata_len = 15; } + memcpy(&pn532_newdata,&sub_string_tmp,pn532_newdata_len); + pn532_newdata[pn532_newdata_len] = 0x00; // Null terminate the string + pn532_function = 2; + snprintf_P(log_data, sizeof(log_data),"NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'",pn532_newdata); + AddLog(LOG_LEVEL_INFO); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL).c_str()); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"PN532\":{\"COMMAND\":\"S\"\"}}"), mqtt_data); + return serviced; + } + } +} + +#endif // USE_PN532_DATA_FUNCTION + +bool Xsns40(uint8_t function) +{ + bool result = false; + + switch (function) { + case FUNC_INIT: + PN532_Init(); + result = true; + break; + case FUNC_EVERY_50_MSECOND: + break; + case FUNC_EVERY_100_MSECOND: + break; + case FUNC_EVERY_250_MSECOND: + if (pn532_scantimer > 0) { + pn532_scantimer--; + } else { + PN532_ScanForTag(); + } + break; + case FUNC_EVERY_SECOND: + break; +#ifdef USE_PN532_DATA_FUNCTION + case FUNC_COMMAND: + if (XSNS_40 == XdrvMailbox.index) { + result = PN532_Command(); + } + break; +#endif + } + return result; +} + +#endif // USE_PN532_HSU From 567b12e1ce4fe31351c6ff26e2a4640e9c542b9b Mon Sep 17 00:00:00 2001 From: Andre Thomas Date: Fri, 8 Feb 2019 09:59:33 +0200 Subject: [PATCH 19/24] PN532: Update resource requirements in config PN532: Update resource requirements in my_user_config.h --- sonoff/my_user_config.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index 0d50b580b..c719f3c40 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -375,9 +375,9 @@ #define USE_ARMTRONIX_DIMMERS // Add support for Armtronix Dimmers (+1k4 code) #define USE_PS_16_DZ // Add support for PS-16-DZ Dimmer //#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code) -//#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+3k7 code, 280 bytes mem) -// #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 356 bytes mem) -// #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (-0k2 code, -32 bytes ram) +//#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) +// #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem) +// #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (+ 80 bytes code, 48 bytes ram) // Power monitoring sensors ----------------------- #define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) From e7f67f9b88578e54e75b05af05b4815e220598bf Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 8 Feb 2019 12:46:07 +0100 Subject: [PATCH 20/24] Update sonoff_template.h Fix PN532 compile error --- sonoff/sonoff_template.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index ff2ba6401..f6ae3aced 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -162,8 +162,8 @@ enum UserSelectablePins { GPIO_MCP39F5_TX, // MCP39F501 Serial interface (Shelly2) GPIO_MCP39F5_RX, // MCP39F501 Serial interface (Shelly2) GPIO_MCP39F5_RST, // MCP39F501 Reset (Shelly2) - GPIO_PN532_RXD, // PN532 NFC Serial Rx GPIO_PN532_TXD, // PN532 NFC Serial Tx + GPIO_PN532_RXD, // PN532 NFC Serial Rx GPIO_SENSOR_END }; // Programmer selectable GPIO functionality offset by user selectable GPIOs @@ -228,7 +228,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_BUTTON "1i|" D_SENSOR_BUTTON "2i|" D_SENSOR_BUTTON "3i|" D_SENSOR_BUTTON "4i|" D_SENSOR_BUTTON "1in|" D_SENSOR_BUTTON "2in|" D_SENSOR_BUTTON "3in|" D_SENSOR_BUTTON "4in|" D_SENSOR_NRG_SEL "|" D_SENSOR_NRG_SEL "i|" D_SENSOR_NRG_CF1 "|" D_SENSOR_HLW_CF "|" D_SENSOR_HJL_CF "|" - D_SENSOR_MCP39F5_TX "|" D_SENSOR_MCP39F5_RX "|" D_SENSOR_MCP39F5_RST + D_SENSOR_MCP39F5_TX "|" D_SENSOR_MCP39F5_RX "|" D_SENSOR_MCP39F5_RST "|" D_SENSOR_PN532_TX "|" D_SENSOR_PN532_RX ; @@ -536,23 +536,23 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_TUYA_TX, // Tuya Serial interface GPIO_TUYA_RX, // Tuya Serial interface #endif -#ifdef USE_MGC3130 - GPIO_MGC3130_XFER, - GPIO_MGC3130_RESET, -#endif #ifdef USE_AZ7798 GPIO_AZ_TXD, // AZ-Instrument 7798 CO2 datalogger Serial interface GPIO_AZ_RXD, // AZ-Instrument 7798 CO2 datalogger Serial interface #endif +#ifdef USE_PN532_HSU + GPIO_PN532_TXD, // PN532 HSU Tx + GPIO_PN532_RXD, // PN532 HSU Rx +#endif +#ifdef USE_MGC3130 + GPIO_MGC3130_XFER, + GPIO_MGC3130_RESET, +#endif #ifdef USE_MAX31855 GPIO_MAX31855CS, // MAX31855 Serial interface GPIO_MAX31855CLK, // MAX31855 Serial interface GPIO_MAX31855DO, // MAX31855 Serial interface #endif -#ifdef USE_PN532_HSU - GPIO_PN532_RXD, // PN532 HSU Rx - GPIO_PN532_TXD, // PN532 HSU Tx -#endif }; const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { From 776486f390f4e28fe505b3e4636525f53095bedd Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 8 Feb 2019 13:00:11 +0100 Subject: [PATCH 21/24] Add MHZ19 Temperature to Domoticz Add MHZ19 Temperature as Domoticz Temperature selection (#5128) --- sonoff/_changelog.ino | 6 ++++++ sonoff/xsns_15_mhz19.ino | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 339ae2bfe..4b328ca2b 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -4,6 +4,12 @@ * Fix IR local echo * Add user configuration of HLW8012 and HJL-01/BL0937 Energy Monitoring as used in Sonoff S31, Pow Ra and many Tuya based devices * Add user configuration of MCP39F501 Energy Monitoring as used in Shelly2 + * Add support for multiple ADS1115 I2C devices (#5083) + * Add rule support for "==", "!=" ">=" and "<=" (#5122) + * Add Hass status sensor (#5139) + * Change GUI weblog solving possible empty screens (#5154) + * Change PN532 support from I2C to Serial for more stability (#5162) + * Add MHZ19 Temperature as Domoticz Temperature selection (#5128) * * 6.4.1.13 20190130 * Add command SetOption36 to control boot loop default restoration (#4645, #5063) diff --git a/sonoff/xsns_15_mhz19.ino b/sonoff/xsns_15_mhz19.ino index 747a8125f..8558a9cd9 100644 --- a/sonoff/xsns_15_mhz19.ino +++ b/sonoff/xsns_15_mhz19.ino @@ -345,7 +345,10 @@ void MhzShow(bool json) if (json) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_MODEL "\":\"%s\",\"" D_JSON_CO2 "\":%d,\"" D_JSON_TEMPERATURE "\":%s}"), mqtt_data, types, model, mhz_last_ppm, temperature); #ifdef USE_DOMOTICZ - if (0 == tele_period) DomoticzSensor(DZ_AIRQUALITY, mhz_last_ppm); + if (0 == tele_period) { + DomoticzSensor(DZ_AIRQUALITY, mhz_last_ppm); + DomoticzSensor(DZ_TEMP, temperature); + } #endif // USE_DOMOTICZ #ifdef USE_WEBSERVER } else { From bfcc35757349c1408c9edb839f2c5c5ceb733951 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 8 Feb 2019 14:25:46 +0100 Subject: [PATCH 22/24] Housekeeping Housekeeping --- sonoff/sonoff_post.h | 21 ++++++++++++--------- sonoff/support_features.ino | 4 ++-- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/sonoff/sonoff_post.h b/sonoff/sonoff_post.h index e6eb186a5..a9891385d 100644 --- a/sonoff/sonoff_post.h +++ b/sonoff/sonoff_post.h @@ -92,7 +92,6 @@ void KNX_CB_Action(message_t const &msg, void *arg); //#define USE_MPU6050 // Enable MPU6050 sensor (I2C address 0x68 AD0 low or 0x69 AD0 high) (+2k6 code) //#define USE_DS3231 // Enable DS3231 external RTC in case no Wifi is avaliable. See docs in the source file (+1k2 code) //#define USE_MGC3130 // Enable MGC3130 Electric Field Effect Sensor (I2C address 0x42) (+2k7 code, 0k3 mem) -//#define USE_PN532_I2C // Enable PN532 - Near Field Communication (NFC) controller (+1k6 code) //#define USE_MAX44009 // Enable MAX44009 Ambient Light sensor (I2C addresses 0x4A and 0x4B) (+0k8 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) @@ -114,6 +113,8 @@ void KNX_CB_Action(message_t const &msg, void *arg); #define TUYA_DIMMER_ID 0 // Default dimmer Id #endif #define USE_PS_16_DZ // Add support for PS-16-DZ Dimmer +//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger +#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) #define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) #define USE_PZEM_AC // Add support for PZEM014,016 Energy monitor (+1k1 code) #define USE_PZEM_DC // Add support for PZEM003,017 Energy monitor (+1k1 code) @@ -138,7 +139,6 @@ void KNX_CB_Action(message_t const &msg, void *arg); #define USE_RF_SENSOR // Add support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) // #define USE_THEO_V2 // Add support for decoding Theo V2 sensors as documented on https://sidweb.nl using 434MHz RF sensor receiver (+1k4 code) #define USE_ALECTO_V2 // Add support for decoding Alecto V2 sensors like ACH2010, WS3000 and DKW2012 using 868MHz RF sensor receiver (+1k7 code) -//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger #endif // USE_SENSORS /*********************************************************************************************\ @@ -174,10 +174,6 @@ void KNX_CB_Action(message_t const &msg, void *arg); #undef USE_SENSEAIR // Disable support for SenseAir K30, K70 and S8 CO2 sensor #undef USE_PMS5003 // Disable support for PMS5003 and PMS7003 particle concentration sensor #undef USE_NOVA_SDS // Disable support for SDS011 and SDS021 particle concentration sensor -#undef USE_PZEM004T // Disable PZEM004T energy sensor -#undef USE_PZEM_AC // Disable PZEM014,016 Energy monitor -#undef USE_PZEM_DC // Disable PZEM003,017 Energy monitor -#undef USE_MCP39F501 // Disable support for MCP39F501 Energy monitor as used in Shelly 2 (+3k1 code) #undef USE_SERIAL_BRIDGE // Disable support for software Serial Bridge #undef USE_SDM120 // Disable support for Eastron SDM120-Modbus energy meter #undef USE_SDM630 // Disable support for Eastron SDM630-Modbus energy meter @@ -185,6 +181,12 @@ void KNX_CB_Action(message_t const &msg, void *arg); #undef USE_TUYA_DIMMER // Disable support for Tuya Serial Dimmer #undef USE_ARMTRONIX_DIMMERS // Disable support for Armtronix Dimmers (+1k4 code) #undef USE_PS_16_DZ // Disable support for PS-16-DZ Dimmer +#undef USE_AZ7798 // Disable support for AZ-Instrument 7798 CO2 datalogger +#undef USE_PN532_HSU // Disable support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) +#undef USE_PZEM004T // Disable PZEM004T energy sensor +#undef USE_PZEM_AC // Disable PZEM014,016 Energy monitor +#undef USE_PZEM_DC // Disable PZEM003,017 Energy monitor +#undef USE_MCP39F501 // Disable support for MCP39F501 Energy monitor as used in Shelly 2 (+3k1 code) #undef USE_MAX31855 // Disable MAX31855 K-Type thermocouple sensor using softSPI #undef USE_IR_REMOTE // Disable IR remote commands using library IRremoteESP8266 and ArduinoJson #undef USE_IR_RECEIVE // Disable support for IR receiver @@ -198,7 +200,6 @@ void KNX_CB_Action(message_t const &msg, void *arg); #undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code -#undef USE_AZ7798 // Disable support for AZ-Instrument 7798 CO2 datalogger #endif // USE_CLASSIC /*********************************************************************************************\ @@ -307,6 +308,8 @@ void KNX_CB_Action(message_t const &msg, void *arg); //#undef USE_TUYA_DIMMER // Disable support for Tuya Serial Dimmer #undef USE_ARMTRONIX_DIMMERS // Disable support for Armtronix Dimmers (+1k4 code) #undef USE_PS_16_DZ // Disable support for PS-16-DZ Dimmer +#undef USE_AZ7798 // Disable support for AZ-Instrument 7798 CO2 datalogger +#undef USE_PN532_HSU // Disable support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) #undef USE_PZEM004T // Disable PZEM004T energy sensor #undef USE_PZEM_AC // Disable PZEM014,016 Energy monitor #undef USE_PZEM_DC // Disable PZEM003,017 Energy monitor @@ -324,7 +327,6 @@ void KNX_CB_Action(message_t const &msg, void *arg); #undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code -#undef USE_AZ7798 // Disable support for AZ-Instrument 7798 CO2 datalogger #endif // USE_BASIC /*********************************************************************************************\ @@ -371,6 +373,8 @@ void KNX_CB_Action(message_t const &msg, void *arg); #undef USE_TUYA_DIMMER // Disable support for Tuya Serial Dimmer #undef USE_ARMTRONIX_DIMMERS // Disable support for Armtronix Dimmers (+1k4 code) #undef USE_PS_16_DZ // Disable support for PS-16-DZ Dimmer +#undef USE_AZ7798 // Disable support for AZ-Instrument 7798 CO2 datalogger +#undef USE_PN532_HSU // Disable support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) #undef USE_PZEM004T // Disable PZEM004T energy sensor #undef USE_PZEM_AC // Disable PZEM014,016 Energy monitor #undef USE_PZEM_DC // Disable PZEM003,017 Energy monitor @@ -388,7 +392,6 @@ void KNX_CB_Action(message_t const &msg, void *arg); #undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code -#undef USE_AZ7798 // Disable support for AZ-Instrument 7798 CO2 datalogger #endif // BE_MINIMAL /*********************************************************************************************\ diff --git a/sonoff/support_features.ino b/sonoff/support_features.ino index 6c1abf97a..4c43f1dda 100644 --- a/sonoff/support_features.ino +++ b/sonoff/support_features.ino @@ -376,8 +376,8 @@ void GetFeatures(void) #ifdef USE_MAX31855 feature_sns2 |= 0x00080000; // xsns_39_max31855.ino #endif -#ifdef USE_PN532_I2C - feature_sns2 |= 0x00100000; // xsns_40_pn532_i2c.ino +#ifdef USE_PN532_HSU + feature_sns2 |= 0x00100000; // xsns_40_pn532.ino #endif #ifdef USE_MAX44009 feature_sns2 |= 0x00200000; From ae277f59cf38f208f7848aeee7e4d9848d3c0a14 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 8 Feb 2019 14:55:45 +0100 Subject: [PATCH 23/24] Change image defines 6.4.1.15 20190208 * Change image name BE_MINIMAL to FIRMWARE_MINIMAL (#5106) * Change image names USE_xyz to FIRMWARE_xyz (#5106) --- platformio.ini | 24 ++++++++++++------------ sonoff/_changelog.ino | 6 +++++- sonoff/my_user_config.h | 12 ++++++------ sonoff/settings.ino | 12 ++++++------ sonoff/sonoff.ino | 12 ++++++------ sonoff/sonoff_post.h | 26 +++++++++++++------------- sonoff/sonoff_version.h | 2 +- sonoff/support_features.ino | 8 ++++---- sonoff/support_wifi.ino | 4 ++-- sonoff/xdrv_01_webserver.ino | 20 ++++++++++---------- tools/decode-status.py | 4 ++-- 11 files changed, 67 insertions(+), 63 deletions(-) diff --git a/platformio.ini b/platformio.ini index 5631982dd..f5d958ebf 100644 --- a/platformio.ini +++ b/platformio.ini @@ -130,12 +130,12 @@ board_build.flash_mode = dout platform = ${core_active.platform} build_flags = ${core_active.build_flags} -; -DUSE_CLASSIC -; -DBE_MINIMAL -; -DUSE_SENSORS -; -DUSE_BASIC -; -DUSE_KNX_NO_EMULATION -; -DUSE_DISPLAYS +; -DFIRMWARE_CLASSIC +; -DFIRMWARE_MINIMAL +; -DFIRMWARE_SENSORS +; -DFIRMWARE_BASIC +; -DFIRMWARE_KNX_NO_EMULATION +; -DFIRMWARE_DISPLAYS ; -DUSE_CONFIG_OVERRIDE ; *** Fix espressif8266@1.7.0 induced undesired all warnings @@ -184,7 +184,7 @@ board = ${common.board} board_build.flash_mode = ${common.board_build.flash_mode} board_build.f_cpu = ${common.board_build.f_cpu} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags} -DBE_MINIMAL +build_flags = ${common.build_flags} -DFIRMWARE_MINIMAL monitor_speed = ${common.monitor_speed} upload_port = ${common.upload_port} upload_resetmethod = ${common.upload_resetmethod} @@ -198,7 +198,7 @@ board = ${common.board} board_build.flash_mode = ${common.board_build.flash_mode} board_build.f_cpu = ${common.board_build.f_cpu} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags} -DUSE_BASIC +build_flags = ${common.build_flags} -DFIRMWARE_BASIC monitor_speed = ${common.monitor_speed} upload_port = ${common.upload_port} upload_resetmethod = ${common.upload_resetmethod} @@ -212,7 +212,7 @@ board = ${common.board} board_build.flash_mode = ${common.board_build.flash_mode} board_build.f_cpu = ${common.board_build.f_cpu} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags} -DUSE_CLASSIC +build_flags = ${common.build_flags} -DFIRMWARE_CLASSIC monitor_speed = ${common.monitor_speed} upload_port = ${common.upload_port} upload_resetmethod = ${common.upload_resetmethod} @@ -226,7 +226,7 @@ board = ${common.board} board_build.flash_mode = ${common.board_build.flash_mode} board_build.f_cpu = ${common.board_build.f_cpu} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags} -DUSE_KNX_NO_EMULATION +build_flags = ${common.build_flags} -DFIRMWARE_KNX_NO_EMULATION monitor_speed = ${common.monitor_speed} upload_port = ${common.upload_port} upload_resetmethod = ${common.upload_resetmethod} @@ -240,7 +240,7 @@ board = ${common.board} board_build.flash_mode = ${common.board_build.flash_mode} board_build.f_cpu = ${common.board_build.f_cpu} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags} -DUSE_SENSORS +build_flags = ${common.build_flags} -DFIRMWARE_SENSORS monitor_speed = ${common.monitor_speed} upload_port = ${common.upload_port} upload_resetmethod = ${common.upload_resetmethod} @@ -254,7 +254,7 @@ board = ${common.board} board_build.flash_mode = ${common.board_build.flash_mode} board_build.f_cpu = ${common.board_build.f_cpu} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags} -DUSE_DISPLAYS +build_flags = ${common.build_flags} -DFIRMWARE_DISPLAYS monitor_speed = ${common.monitor_speed} upload_port = ${common.upload_port} upload_resetmethod = ${common.upload_resetmethod} diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 4b328ca2b..80c79746f 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,4 +1,8 @@ -/* 6.4.1.14 20190203 +/* 6.4.1.15 20190208 + * Change image name BE_MINIMAL to FIRMWARE_MINIMAL (#5106) + * Change image names USE_xyz to FIRMWARE_xyz (#5106) + * + * 6.4.1.14 20190203 * Add SetOption32 until SetOption49 diagnostic information to Status 3 report as replacement for second property value in SetOption property name * Add Resolution property to Status 3 report providing previous SetOption second value property * Fix IR local echo diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index c719f3c40..d782a9e2d 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -429,12 +429,12 @@ * See RELEASENOTES.md for selected features \*********************************************************************************************/ -//#define USE_CLASSIC // Create sonoff-classic with initial configuration tools WPS, SmartConfig and WifiManager -//#define USE_BASIC // Create sonoff-basic with no sensors -//#define USE_SENSORS // Create sonoff-sensors with useful sensors enabled -//#define USE_KNX_NO_EMULATION // Create sonoff-knx with KNX but without Emulation -//#define USE_DISPLAYS // Create sonoff-display with display drivers enabled -//#define BE_MINIMAL // Create sonoff-minimal as intermediate firmware for OTA-MAGIC +//#define FIRMWARE_CLASSIC // Create sonoff-classic with initial configuration tools WPS, SmartConfig and WifiManager +//#define FIRMWARE_BASIC // Create sonoff-basic with no sensors +//#define FIRMWARE_SENSORS // Create sonoff-sensors with useful sensors enabled +//#define FIRMWARE_KNX_NO_EMULATION // Create sonoff-knx with KNX but without Emulation +//#define FIRMWARE_DISPLAYS // Create sonoff-display with display drivers enabled +//#define FIRMWARE_MINIMAL // Create sonoff-minimal as intermediate firmware for OTA-MAGIC /*********************************************************************************************\ * No user configurable items below diff --git a/sonoff/settings.ino b/sonoff/settings.ino index 55a73fc56..b3192d50a 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -391,7 +391,7 @@ void SettingsSave(uint8_t rotate) * stop_flash_rotate 0 = Allow flash slot rotation (SetOption12 0) * stop_flash_rotate 1 = Allow only eeprom flash slot use (SetOption12 1) */ -#ifndef BE_MINIMAL +#ifndef FIRMWARE_MINIMAL if ((GetSettingsCrc() != settings_crc) || rotate) { if (1 == rotate) { // Use eeprom flash slot only and disable flash rotate from now on (upgrade) stop_flash_rotate = 1; @@ -441,7 +441,7 @@ void SettingsSave(uint8_t rotate) settings_crc = Settings.cfg_crc; } -#endif // BE_MINIMAL +#endif // FIRMWARE_MINIMAL RtcSettingsSave(); } @@ -487,12 +487,12 @@ void SettingsLoad(void) AddLog(LOG_LEVEL_DEBUG); } -#ifndef BE_MINIMAL +#ifndef FIRMWARE_MINIMAL if (!settings_location || (Settings.cfg_holder != (uint16_t)CFG_HOLDER)) { // Init defaults if cfg_holder differs from user settings in my_user_config.h SettingsDefault(); } settings_crc = GetSettingsCrc(); -#endif // BE_MINIMAL +#endif // FIRMWARE_MINIMAL RtcSettingsLoad(); } @@ -504,7 +504,7 @@ void SettingsErase(uint8_t type) 1 = Erase SDK parameter area at end of linker memory model (0x0FDxxx - 0x0FFFFF) solving possible wifi errors */ -#ifndef BE_MINIMAL +#ifndef FIRMWARE_MINIMAL bool result; uint32_t _sectorStart = (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 1; @@ -533,7 +533,7 @@ void SettingsErase(uint8_t type) } OsWatchLoop(); } -#endif // BE_MINIMAL +#endif // FIRMWARE_MINIMAL } // Copied from 2.4.0 as 2.3.0 is incomplete diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 0a96acd05..8f220eb7a 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -1957,7 +1957,7 @@ void Every250mSeconds(void) ota_retry_counter--; if (ota_retry_counter) { strlcpy(mqtt_data, GetOtaUrl(log_data, sizeof(log_data)), sizeof(mqtt_data)); -#ifndef BE_MINIMAL +#ifndef FIRMWARE_MINIMAL if (RtcSettings.ota_loader) { char *bch = strrchr(mqtt_data, '/'); // Only consider filename after last backslash prevent change of urls having "-" in it char *pch = strrchr((bch != NULL) ? bch : mqtt_data, '-'); // Change from filename-DE.bin into filename-minimal.bin @@ -1969,7 +1969,7 @@ void Every250mSeconds(void) snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s-" D_JSON_MINIMAL "%s"), mqtt_data, ech); // Minimal filename must be filename-minimal } } -#endif // BE_MINIMAL +#endif // FIRMWARE_MINIMAL snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD "%s"), mqtt_data); AddLog(LOG_LEVEL_DEBUG); #if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) @@ -1980,14 +1980,14 @@ void Every250mSeconds(void) ota_result = (HTTP_UPDATE_FAILED != ESPhttpUpdate.update(OTAclient, mqtt_data)); #endif if (!ota_result) { -#ifndef BE_MINIMAL +#ifndef FIRMWARE_MINIMAL int ota_error = ESPhttpUpdate.getLastError(); // snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD "Ota error %d"), ota_error); // AddLog(LOG_LEVEL_DEBUG); if ((HTTP_UE_TOO_LESS_SPACE == ota_error) || (HTTP_UE_BIN_FOR_WRONG_FLASH == ota_error)) { RtcSettings.ota_loader = 1; // Try minimal image next } -#endif // BE_MINIMAL +#endif // FIRMWARE_MINIMAL ota_state_flag = 2; // Upgrade failed - retry } } @@ -2584,10 +2584,10 @@ void setup(void) snprintf_P(log_data, sizeof(log_data), PSTR(D_PROJECT " %s %s " D_VERSION " %s%s-" ARDUINO_ESP8266_RELEASE), PROJECT, Settings.friendlyname[0], my_version, my_image); AddLog(LOG_LEVEL_INFO); -#ifdef BE_MINIMAL +#ifdef FIRMWARE_MINIMAL snprintf_P(log_data, sizeof(log_data), PSTR(D_WARNING_MINIMAL_VERSION)); AddLog(LOG_LEVEL_INFO); -#endif // BE_MINIMAL +#endif // FIRMWARE_MINIMAL RtcInit(); diff --git a/sonoff/sonoff_post.h b/sonoff/sonoff_post.h index a9891385d..06bd3688b 100644 --- a/sonoff/sonoff_post.h +++ b/sonoff/sonoff_post.h @@ -55,7 +55,7 @@ void KNX_CB_Action(message_t const &msg, void *arg); * Provide an image with useful supported sensors enabled \*********************************************************************************************/ -#ifdef USE_SENSORS +#ifdef FIRMWARE_SENSORS #undef CODE_IMAGE #define CODE_IMAGE 3 @@ -139,14 +139,14 @@ void KNX_CB_Action(message_t const &msg, void *arg); #define USE_RF_SENSOR // Add support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) // #define USE_THEO_V2 // Add support for decoding Theo V2 sensors as documented on https://sidweb.nl using 434MHz RF sensor receiver (+1k4 code) #define USE_ALECTO_V2 // Add support for decoding Alecto V2 sensors like ACH2010, WS3000 and DKW2012 using 868MHz RF sensor receiver (+1k7 code) -#endif // USE_SENSORS +#endif // FIRMWARE_SENSORS /*********************************************************************************************\ * [sonoff-classic.bin] * Provide an image close to version 5.12.0 but still within 499k program space to allow one time OTA \*********************************************************************************************/ -#ifdef USE_CLASSIC +#ifdef FIRMWARE_CLASSIC #undef CODE_IMAGE #define CODE_IMAGE 2 @@ -200,14 +200,14 @@ void KNX_CB_Action(message_t const &msg, void *arg); #undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code -#endif // USE_CLASSIC +#endif // FIRMWARE_CLASSIC /*********************************************************************************************\ * [sonoff-knx.bin] * Provide a dedicated KNX image allowing enough code and memory space \*********************************************************************************************/ -#ifdef USE_KNX_NO_EMULATION +#ifdef FIRMWARE_KNX_NO_EMULATION #undef CODE_IMAGE #define CODE_IMAGE 4 @@ -216,14 +216,14 @@ void KNX_CB_Action(message_t const &msg, void *arg); #define USE_KNX // Enable KNX IP Protocol Support (+23k code, +3k3 mem) #endif #undef USE_EMULATION // Disable Belkin WeMo and Hue Bridge emulation for Alexa (-16k code, -2k mem) -#endif // USE_KNX_NO_EMULATION +#endif // FIRMWARE_KNX_NO_EMULATION /*********************************************************************************************\ * [sonoff-display.bin] * Provide an image with display drivers enabled \*********************************************************************************************/ -#ifdef USE_DISPLAYS +#ifdef FIRMWARE_DISPLAYS #undef CODE_IMAGE #define CODE_IMAGE 6 @@ -250,7 +250,7 @@ void KNX_CB_Action(message_t const &msg, void *arg); #undef USE_ARILUX_RF // Remove support for Arilux RF remote controller (-0k8 code, 252 iram (non 2.3.0)) #undef USE_RF_FLASH // Remove support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB (-3k code) -#endif // USE_DISPLAYS +#endif // FIRMWARE_DISPLAYS /*********************************************************************************************\ * Mandatory define for DS18x20 if changed by above image selections @@ -266,13 +266,13 @@ void KNX_CB_Action(message_t const &msg, void *arg); * Provide an image without sensors \*********************************************************************************************/ -#ifdef USE_BASIC +#ifdef FIRMWARE_BASIC #undef CODE_IMAGE #define CODE_IMAGE 5 #undef APP_SLEEP -#define APP_SLEEP 1 // Default to sleep = 1 for USE_BASIC +#define APP_SLEEP 1 // Default to sleep = 1 for FIRMWARE_BASIC //#undef USE_ENERGY_SENSOR // Disable energy sensors #undef USE_ARDUINO_OTA // Disable support for Arduino OTA @@ -327,14 +327,14 @@ void KNX_CB_Action(message_t const &msg, void *arg); #undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code -#endif // USE_BASIC +#endif // FIRMWARE_BASIC /*********************************************************************************************\ * [sonoff-minimal.bin] * Provide the smallest image possible while still enabling a webserver for intermediate image load \*********************************************************************************************/ -#ifdef BE_MINIMAL +#ifdef FIRMWARE_MINIMAL #undef CODE_IMAGE #define CODE_IMAGE 1 @@ -392,7 +392,7 @@ void KNX_CB_Action(message_t const &msg, void *arg); #undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code -#endif // BE_MINIMAL +#endif // FIRMWARE_MINIMAL /*********************************************************************************************\ * Mandatory defines satisfying possible disabled defines diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index 5aaa62872..9afa3f2b2 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x0604010E +#define VERSION 0x0604010F #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" diff --git a/sonoff/support_features.ino b/sonoff/support_features.ino index 4c43f1dda..09d5d140c 100644 --- a/sonoff/support_features.ino +++ b/sonoff/support_features.ino @@ -126,16 +126,16 @@ void GetFeatures(void) #ifdef USE_CONFIG_OVERRIDE feature_drv2 |= 0x00000001; // user_config(_override).h #endif -#ifdef BE_MINIMAL +#ifdef FIRMWARE_MINIMAL feature_drv2 |= 0x00000002; // user_config(_override).h #endif -#ifdef USE_SENSORS +#ifdef FIRMWARE_SENSORS feature_drv2 |= 0x00000004; // user_config(_override).h #endif -#ifdef USE_CLASSIC +#ifdef FIRMWARE_CLASSIC feature_drv2 |= 0x00000008; // user_config(_override).h #endif -#ifdef USE_KNX_NO_EMULATION +#ifdef FIRMWARE_KNX_NO_EMULATION feature_drv2 |= 0x00000010; // user_config(_override).h #endif #ifdef USE_DISPLAY_MODES1TO5 diff --git a/sonoff/support_wifi.ino b/sonoff/support_wifi.ino index 730ac595f..90f0584b7 100644 --- a/sonoff/support_wifi.ino +++ b/sonoff/support_wifi.ino @@ -501,12 +501,12 @@ void WifiCheck(uint8_t param) } } -#ifdef BE_MINIMAL +#ifdef FIRMWARE_MINIMAL if (1 == RtcSettings.ota_loader) { RtcSettings.ota_loader = 0; ota_state_flag = 3; } -#endif // BE_MINIMAL +#endif // FIRMWARE_MINIMAL #ifdef USE_DISCOVERY if (Settings.flag3.mdns_enabled) { diff --git a/sonoff/xdrv_01_webserver.ino b/sonoff/xdrv_01_webserver.ino index 316553130..449ae6e35 100644 --- a/sonoff/xdrv_01_webserver.ino +++ b/sonoff/xdrv_01_webserver.ino @@ -208,7 +208,7 @@ const char HTTP_HEAD_STYLE[] PROGMEM = "" "" "
" -#ifdef BE_MINIMAL +#ifdef FIRMWARE_MINIMAL "

" D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "

" #endif "
" @@ -227,7 +227,7 @@ const char HTTP_MSG_SLIDER2[] PROGMEM = const char HTTP_MSG_RSTRT[] PROGMEM = "
" D_DEVICE_WILL_RESTART "

"; const char HTTP_BTN_MENU1[] PROGMEM = -#ifndef BE_MINIMAL +#ifndef FIRMWARE_MINIMAL "
" "
" #endif @@ -401,7 +401,7 @@ void StartWebserver(int type, IPAddress ipweb) WebServer->on("/ay", HandleAjaxStatusRefresh); WebServer->on("/cm", HandleHttpCommand); WebServer->onNotFound(HandleNotFound); -#ifndef BE_MINIMAL +#ifndef FIRMWARE_MINIMAL WebServer->on("/cn", HandleConfiguration); WebServer->on("/md", HandleModuleConfiguration); WebServer->on("/wi", HandleWifiConfiguration); @@ -416,7 +416,7 @@ void StartWebserver(int type, IPAddress ipweb) #endif // USE_EMULATION XdrvCall(FUNC_WEB_ADD_HANDLER); XsnsCall(FUNC_WEB_ADD_HANDLER); -#endif // Not BE_MINIMAL +#endif // Not FIRMWARE_MINIMAL } reset_web_log_flag = false; WebServer->begin(); // Web server start @@ -601,7 +601,7 @@ void HandleRoot(void) } if (HTTP_MANAGER == webserver_state) { -#ifndef BE_MINIMAL +#ifndef FIRMWARE_MINIMAL if ((Settings.web_password[0] != 0) && !(WebServer->hasArg("USER1")) && !(WebServer->hasArg("PASS1"))) { HandleWifiLogin(); } else { @@ -619,7 +619,7 @@ void HandleRoot(void) HandleWifiLogin(); } } -#endif // Not BE_MINIMAL +#endif // Not FIRMWARE_MINIMAL } else { char stemp[10]; String page = FPSTR(HTTP_HEAD); @@ -673,12 +673,12 @@ void HandleRoot(void) page += F(""); } -#ifndef BE_MINIMAL +#ifndef FIRMWARE_MINIMAL mqtt_data[0] = '\0'; XdrvCall(FUNC_WEB_ADD_MAIN_BUTTON); XsnsCall(FUNC_WEB_ADD_MAIN_BUTTON); page += String(mqtt_data); -#endif // Not BE_MINIMAL +#endif // Not FIRMWARE_MINIMAL if (HTTP_ADMIN == webserver_state) { page += FPSTR(HTTP_BTN_MENU1); @@ -773,7 +773,7 @@ bool HttpCheckPriviledgedAccess(bool autorequestauth = true) /*-------------------------------------------------------------------------------------------*/ -#ifndef BE_MINIMAL +#ifndef FIRMWARE_MINIMAL void HandleConfiguration(void) { @@ -1407,7 +1407,7 @@ void HandleInformation(void) page += FPSTR(HTTP_BTN_MAIN); ShowPage(page); } -#endif // Not BE_MINIMAL +#endif // Not FIRMWARE_MINIMAL /*-------------------------------------------------------------------------------------------*/ diff --git a/tools/decode-status.py b/tools/decode-status.py index 2d105bc96..dd90d1669 100644 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -123,8 +123,8 @@ a_features = [[ "USE_TIMERS","USE_SUNRISE","USE_TIMERS_WEB","USE_RULES", "USE_KNX","USE_WPS","USE_SMARTCONFIG","MQTT_ARDUINOMQTT" ],[ - "USE_CONFIG_OVERRIDE","BE_MINIMAL","USE_SENSORS","USE_CLASSIC", - "USE_KNX_NO_EMULATION","USE_DISPLAY_MODES1TO5","USE_DISPLAY_GRAPH","USE_DISPLAY_LCD", + "USE_CONFIG_OVERRIDE","FIRMWARE_MINIMAL","FIRMWARE_SENSORS","FIRMWARE_CLASSIC", + "FIRMWARE_KNX_NO_EMULATION","USE_DISPLAY_MODES1TO5","USE_DISPLAY_GRAPH","USE_DISPLAY_LCD", "USE_DISPLAY_SSD1306","USE_DISPLAY_MATRIX","USE_DISPLAY_ILI9341","USE_DISPLAY_EPAPER", "USE_DISPLAY_SH1106","USE_MP3_PLAYER","USE_PCA9685","USE_TUYA_DIMMER", "USE_RC_SWITCH","USE_ARMTRONIX_DIMMERS","","", From 953bcd26af4069094ea9a41299b0ca97c25f7edb Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 8 Feb 2019 15:35:28 +0100 Subject: [PATCH 24/24] Update xsns_40_pn532.ino Cleanup and use flush --- sonoff/xsns_40_pn532.ino | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/sonoff/xsns_40_pn532.ino b/sonoff/xsns_40_pn532.ino index af00720b2..c1daef96e 100644 --- a/sonoff/xsns_40_pn532.ino +++ b/sonoff/xsns_40_pn532.ino @@ -96,7 +96,7 @@ int8_t PN532_receive(uint8_t *buf, int len, uint16_t timeout) break; } } while((timeout == 0) || ((millis()- start_millis ) < timeout)); - + if (ret < 0) { if (read_bytes) { return read_bytes; @@ -114,7 +114,7 @@ int8_t PN532_readAckFrame(void) { const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0}; uint8_t ackBuf[sizeof(PN532_ACK)]; - + if (PN532_receive(ackBuf, sizeof(PN532_ACK), PN532_ACK_WAIT_TIME) <= 0) { return PN532_TIMEOUT; } @@ -128,7 +128,7 @@ int8_t PN532_readAckFrame(void) int8_t PN532_writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body = 0, uint8_t blen = 0) { // Clear the serial buffer just in case - while(PN532_Serial->available()) { PN532_Serial->read(); } + PN532_Serial->flush(); pn532_command = header[0]; PN532_Serial->write((uint8_t)PN532_PREAMBLE); @@ -155,7 +155,7 @@ int8_t PN532_writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *bo uint8_t checksum = ~sum + 1; // checksum of TFI + DATA PN532_Serial->write(checksum); PN532_Serial->write((uint8_t)PN532_POSTAMBLE); - + return PN532_readAckFrame(); } @@ -197,7 +197,7 @@ int16_t PN532_readResponse(uint8_t buf[], uint8_t len, uint16_t timeout = 50) if (PN532_receive(buf, length[0], timeout) != length[0]) { // Timed out return PN532_TIMEOUT; } - + uint8_t sum = PN532_PN532TOHOST + cmd; for (uint8_t i=0; iwrite(wakeup,sizeof(wakeup)); // Flush the serial buffer just in case there's garbage in there - while(PN532_Serial->available()) { PN532_Serial->read(); } + PN532_Serial->flush(); } bool PN532_readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout = 50) @@ -413,17 +413,17 @@ void PN532_ScanForTag(void) bool set_success = false; if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uid_len)) { char uids[15]; - -#ifdef USE_PN532_DATA_FUNCTION + +#ifdef USE_PN532_DATA_FUNCTION char card_datas[34]; -#endif // USE_PN532_DATA_FUNCTION +#endif // USE_PN532_DATA_FUNCTION sprintf(uids,""); for (uint8_t i = 0;i < uid_len;i++) { sprintf(uids,"%s%02X",uids,uid[i]); } - -#ifdef USE_PN532_DATA_FUNCTION + +#ifdef USE_PN532_DATA_FUNCTION if (uid_len == 4) { // Lets try to read block 1 of the mifare classic card for more information uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) { @@ -502,15 +502,15 @@ void PN532_ScanForTag(void) break; } pn532_function = 0; -#endif // USE_PN532_DATA_FUNCTION - +#endif // USE_PN532_DATA_FUNCTION + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL).c_str()); #ifdef USE_PN532_DATA_FUNCTION snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"PN532\":{\"UID\":\"%s\", \"DATA\":\"%s\"}}"), mqtt_data, uids, card_datas); #else snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"PN532\":{\"UID\":\"%s\"}}"), mqtt_data, uids); -#endif // USE_PN532_DATA_FUNCTION +#endif // USE_PN532_DATA_FUNCTION MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); @@ -521,10 +521,10 @@ void PN532_ScanForTag(void) sprintf(command,"backlog event PN532_UID=%s;event PN532_DATA=%s",uids,card_datas); #else sprintf(command,"event PN532_UID=%s",uids); -#endif // USE_PN532_DATA_FUNCTION +#endif // USE_PN532_DATA_FUNCTION ExecuteCommand(command, SRC_RULE); #endif // USE_PN532_CAUSE_EVENTS - + pn532_scantimer = 7; // Ignore tags found for two seconds } } @@ -582,7 +582,7 @@ bool PN532_Command(void) bool Xsns40(uint8_t function) { bool result = false; - + switch (function) { case FUNC_INIT: PN532_Init(); @@ -601,13 +601,13 @@ bool Xsns40(uint8_t function) break; case FUNC_EVERY_SECOND: break; -#ifdef USE_PN532_DATA_FUNCTION +#ifdef USE_PN532_DATA_FUNCTION case FUNC_COMMAND: if (XSNS_40 == XdrvMailbox.index) { result = PN532_Command(); } break; -#endif +#endif } return result; }