diff --git a/RELEASENOTES.md b/RELEASENOTES.md index f994be9c0..fd1d7e6b9 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -98,3 +98,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add BootCount Reset Time as BCResetTime to ``Status 1`` - Add ``ZbZNPReceived``and ``ZbZCLReceived`` being published to MQTT when ``SetOption66 1`` - Add optional Wifi AccessPoint passphrase define WIFI_AP_PASSPHRASE in my_user_config.h (#7690) +- Add support for FiF LE-01MR energy meter by saper-2 (#7584) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index ceef0a771..9108fe47d 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -11,6 +11,7 @@ - Add BootCount Reset Time as BCResetTime to ``Status 1`` - Add ``ZbZNPReceived``and ``ZbZCLReceived`` being published to MQTT when ``SetOption66 1`` - Add optional Wifi AccessPoint passphrase define WIFI_AP_PASSPHRASE in my_user_config.h (#7690) +- Add support for FiF LE-01MR energy meter by saper-2 (#7584) ### 8.1.0.5 20200126 diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 2ab81c4ee..753766839 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -563,9 +563,10 @@ //#define USE_SOLAX_X1 // Add support for Solax X1 series Modbus log info (+3k1 code) #define SOLAXX1_SPEED 9600 // Solax X1 Modbus RS485 serial speed (default: 9600 baud) #define SOLAXX1_PV2 // Solax X1 using second PV -//#define USE_LE01MR // Add support for F&F LE-01MR modbus energy meter - #define LE01MR_SPEED 9600 // LE-01MR modbus baudrate (9600 default) (+2k code, +36 RAM) - #define LE01MR_ADDR 1 // LE-01MR modbus address (0x01 default) +//#define USE_LE01MR // Add support for F&F LE-01MR Modbus energy monitor (+1k code) + #define LE01MR_SPEED 9600 // LE-01MR modbus baudrate (default: 9600) + #define LE01MR_ADDR 1 // LE-01MR modbus address (default: 0x01) + // -- Low level interface devices ----------------- #define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor (1k6 code) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 28e725930..df5abda86 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -411,10 +411,10 @@ void CmndStatus(void) if ((0 == payload) || (4 == payload)) { Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS4_MEMORY "\":{\"" D_JSON_PROGRAMSIZE "\":%d,\"" D_JSON_FREEMEMORY "\":%d,\"" D_JSON_HEAPSIZE "\":%d,\"" D_JSON_PROGRAMFLASHSIZE "\":%d,\"" D_JSON_FLASHSIZE "\":%d,\"" D_JSON_FLASHCHIPID "\":\"%06X\",\"" D_JSON_FLASHMODE "\":%d,\"" - D_JSON_FEATURES "\":[\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\"]"), + D_JSON_FEATURES "\":[\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\"]"), ESP.getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP.getFreeHeap()/1024, ESP.getFlashChipSize()/1024, ESP.getFlashChipRealSize()/1024, ESP.getFlashChipId(), ESP.getFlashChipMode(), - LANGUAGE_LCID, feature_drv1, feature_drv2, feature_sns1, feature_sns2, feature5); + LANGUAGE_LCID, feature_drv1, feature_drv2, feature_sns1, feature_sns2, feature5, feature6); XsnsDriverState(); ResponseAppend_P(PSTR(",\"Sensors\":")); XsnsSensorState(); diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index e69615773..2dc25b8e5 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -519,4 +519,48 @@ void GetFeatures(void) // feature5 |= 0x40000000; // feature5 |= 0x80000000; +/*********************************************************************************************/ + + feature6 = 0x00000000; + +// feature6 |= 0x00000001; +// feature6 |= 0x00000002; +// feature6 |= 0x00000004; +// feature6 |= 0x00000008; + +// feature6 |= 0x00000010; +// feature6 |= 0x00000020; +// feature6 |= 0x00000040; +// feature6 |= 0x00000080; + +// feature6 |= 0x00000100; +// feature6 |= 0x00000200; +// feature6 |= 0x00000400; +// feature6 |= 0x00000800; + +// feature6 |= 0x00001000; +// feature6 |= 0x00002000; +// feature6 |= 0x00004000; +// feature6 |= 0x00008000; + +// feature6 |= 0x00010000; +// feature6 |= 0x00020000; +// feature6 |= 0x00040000; +// feature6 |= 0x00080000; + +// feature6 |= 0x00100000; +// feature6 |= 0x00200000; +// feature6 |= 0x00400000; +// feature6 |= 0x00800000; + +// feature6 |= 0x01000000; +// feature6 |= 0x02000000; +// feature6 |= 0x04000000; +// feature6 |= 0x08000000; + +// feature6 |= 0x10000000; +// feature6 |= 0x20000000; +// feature6 |= 0x40000000; +// feature6 |= 0x80000000; + } diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 92ee55fdf..9383e0e8b 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -79,6 +79,7 @@ unsigned long feature_drv2; // Compiled driver feature map unsigned long feature_sns1; // Compiled sensor feature map unsigned long feature_sns2; // Compiled sensor feature map unsigned long feature5; // Compiled feature map +unsigned long feature6; // Compiled feature map unsigned long serial_polling_window = 0; // Serial polling window unsigned long state_second = 0; // State second timer unsigned long state_50msecond = 0; // State 50msecond timer diff --git a/tasmota/xnrg_13_fif_le01mr.ino b/tasmota/xnrg_13_fif_le01mr.ino index e99041c9c..18f45065c 100644 --- a/tasmota/xnrg_13_fif_le01mr.ino +++ b/tasmota/xnrg_13_fif_le01mr.ino @@ -16,29 +16,30 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ + #ifdef USE_ENERGY_SENSOR #ifdef USE_LE01MR /*********************************************************************************************\ - * F&F LE-01MR - This is a single phase energy meter with rs485 modbus interface + * F&F LE-01MR - This is a single phase energy meter with rs485 modbus interface * (and bidirectional energy counting - enabled by RS485). * It measure: Active energy imported AE+ [kWh] , Reactive energy imported RE+ [kvarh], * Voltage V [V], Current I [A], Frequency F [Hz], power factor (aka "cos-phi"), * Active power P [kW], Reactive power Q [kVAr], Apparent power S [kVA], - * *Active energy exported AE- [kWh] (when meter is switched to bi-directional counting then + * *Active energy exported AE- [kWh] (when meter is switched to bi-directional counting then * reactive energy imported register contains value of Active energy exported). * * Meter descriptions at manufacturer page (english version have some description errors): * EN: https://www.fif.com.pl/en/usage-electric-power-meters/517-electricity-consumption-meter-le-01mr.html * PL: https://www.fif.com.pl/pl/liczniki-zuzycia-energii-elektrycznej/517-licznik-zuzycia-energii-le-01mr.html - * - * Note about communication settings: The meter must be reconfigured to use baudrate 2400 (or 9600) *without* - * parity bit - by default the meter is configured to 9600 8E1 - * (Frame format: "EVEN 1") . To make those changes, use LE-Config + * + * Note about communication settings: The meter must be reconfigured to use baudrate 2400 (or 9600) *without* + * parity bit - by default the meter is configured to 9600 8E1 + * (Frame format: "EVEN 1") . To make those changes, use LE-Config * software (can be found in download tab in product page - link above) * and USB-RS485 dongle (those cheap ~2$ from ali works fine) - * + * * Register descriptions (not all, only those that are being read): - * + * * /----------------------------------- Register address * | /-------------------------- Registers count * | | /---------------------- Datatype and size @@ -54,14 +55,14 @@ * 0x0158 1 S16 0.001 - Power factor * 0xA000 2 U32 0.01 kWh Active energy imported * 0xA01E 2 U32 0.01 kvarh Reactive energy imported - * - * Datatype: S = signed int, U = unsigend int, - * U32 - the first (lower) register contains high word, + * + * Datatype: S = signed int, U = unsigend int, + * U32 - the first (lower) register contains high word, * second register contains lower word of 32bit dword: - * value_32bit = (register+0)<<16 | (register+1); + * value_32bit = (register+0)<<16 | (register+1); * /or/ val32bit = (reg+0)*65536 + (reg+1); - * - * Note about MQTT/JSON: In fields "ENERGY.TotalActive" and "ENERGY.TotalReactive" there are + * + * Note about MQTT/JSON: In fields "ENERGY.TotalActive" and "ENERGY.TotalReactive" there are * counters values directly from the meter (without Tasmota calculation, * energy used calculated by Tasmota is in Total/Today fields ). * Filed "ENERGY.Period" is always zero. @@ -87,7 +88,7 @@ const uint16_t le01mr_register_addresses[] { // IDX (reg count/datatype) [unit] 0x0130, // 00 . LE01MR_FREQUENCY (1/U16) [Hz] 0x0131, // 01 . LE01MR_VOLTAGE (1/U16) [V] - 0x0158, // 02 . LE01MR_POWER_FACTOR (1/S16) + 0x0158, // 02 . LE01MR_POWER_FACTOR (1/S16) 0x0139, // 03 . LE01MR_CURRENT (2/U32) [A] 0x0140, // 04 . LE01MR_ACTIVE_POWER (2/U32) [kW] 0x0148, // 05 . LE01MR_REACTIVE_POWER (2/U32) [kvar] @@ -143,8 +144,8 @@ void FifLEEvery250ms(void) // S16 - int16_t // everything drop into uint32 value, but depending on register ther will be 2 or 4 bytes uint32_t value_buff = 0; - // for register table items 0..2 use 2 bytes (U16) - if (Le01mr.read_state >= 0 && Le01mr.read_state < 3) { // + // for register table items 0..2 use 2 bytes (U16) + if (Le01mr.read_state >= 0 && Le01mr.read_state < 3) { // value_buff = ((uint32_t)buffer[3])<<8 | buffer[4]; } else { value_buff = ((uint32_t)buffer[3])<<24 | ((uint32_t)buffer[4])<<16 | ((uint32_t)buffer[5])<<8 | buffer[6]; @@ -166,7 +167,7 @@ void FifLEEvery250ms(void) case 3: Energy.current[0] = value_buff * 0.001f; // 114 => 0.114 A break; - + case 4: Energy.active_power[0] = value_buff * 1.0f; // P [W] break; @@ -247,7 +248,6 @@ void FifLEShow(bool json) dtostrfd(Le01mr.total_reactive, Settings.flag2.energy_resolution, total_reactive_chr); char total_active_chr[FLOATSZ]; dtostrfd(Le01mr.total_active, Settings.flag2.energy_resolution, total_active_chr); - if (json) { ResponseAppend_P(PSTR(",\"" D_JSON_TOTAL_ACTIVE "\":%s,\"" D_JSON_TOTAL_REACTIVE "\":%s"), @@ -270,7 +270,7 @@ bool Xnrg13(uint8_t function) switch (function) { case FUNC_EVERY_250_MSECOND: if (uptime > 4) { - FifLEEvery250ms(); + FifLEEvery250ms(); } break; case FUNC_JSON_APPEND: diff --git a/tools/decode-status.py b/tools/decode-status.py index 2acee4923..f4d00833a 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -192,7 +192,16 @@ a_features = [[ "USE_SONOFF_SC","USE_SONOFF_RF","USE_SONOFF_L1","USE_EXS_DIMMER", "USE_ARDUINO_SLAVE","USE_HIH6","USE_HPMA","USE_TSL2591", "USE_DHT12","USE_DS1624","USE_GPS","USE_HOTPLUG", - "USE_NRF24","USE_MIBLE","USE_HM10","", + "USE_NRF24","USE_MIBLE","USE_HM10","USE_LE01MR", + "","","","" + ],[ + "","","","", + "","","","", + "","","","", + "","","","", + "","","","", + "","","","", + "","","","", "","","","" ]] @@ -227,7 +236,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v20200207 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v20200210 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj))