mirror of https://github.com/arendst/Tasmota.git
Merge branch 'development' into HP303B
# Conflicts: # tasmota/support_features.ino Resolved # tools/decode-status.py Resolved
This commit is contained in:
commit
601317d5f3
|
@ -75,3 +75,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
|
|||
- Add ``FlashFrequency`` to ``status 4``
|
||||
- Add support for up to two BH1750 sensors controlled by commands ``BH1750Resolution`` and ``BH1750MTime`` (#8139)
|
||||
- Add support for up to eight MCP9808 temperature sensors by device111 (#8594)
|
||||
- Add support for BL0940 energy monitor as used in Blitzwolf BW-SHP10 (#8175)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
- Add ``FlashFrequency`` to ``status 4``
|
||||
- Add support for up to two BH1750 sensors controlled by commands ``BH1750Resolution`` and ``BH1750MTime`` (#8139)
|
||||
- Add Zigbee auto-responder for common attributes
|
||||
- Add support for BL0940 energy monitor as used in Blitzwolf BW-SHP10 (#8175)
|
||||
|
||||
### 8.3.1.1 20200518
|
||||
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 - TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR - RX"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR - TX"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 - GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 - GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL - RX"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -672,6 +672,7 @@
|
|||
#define D_SENSOR_HM10_TX "HM10 TX"
|
||||
#define D_SENSOR_LE01MR_RX "LE-01MR Rx"
|
||||
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
|
||||
#define D_SENSOR_BL0940_RX "BL0940 Rx"
|
||||
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
|
||||
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
|
||||
#define D_SENSOR_HRXL_RX "HRXL Rx"
|
||||
|
|
|
@ -394,18 +394,18 @@
|
|||
// -- Ping ----------------------------------------
|
||||
// #define USE_PING // Enable Ping command (+2k code)
|
||||
|
||||
#define USE_UNISHOX_COMPRESSION // add support for string compression for RULES or SCRIPT
|
||||
// -- Compression ---------------------------------
|
||||
#define USE_UNISHOX_COMPRESSION // Add support for string compression in Rules or Scripts
|
||||
|
||||
// -- Rules or Script ----------------------------
|
||||
// Select none or only one of the below defines USE_RULES or USE_SCRIPT
|
||||
#define USE_RULES // Add support for rules (+8k code)
|
||||
// with USE_UNISHOX_COMPRESSION // Compresses rules in Flash at about ~50% (+3.3k code)
|
||||
//#define USE_SCRIPT // Add support for script (+17k code)
|
||||
// supports USE_UNISHOX_COMPRESSION
|
||||
//#define USE_SCRIPT_FATFS 4 // Script: Add FAT FileSystem Support
|
||||
|
||||
// #define USE_EXPRESSION // Add support for expression evaluation in rules (+3k2 code, +64 bytes mem)
|
||||
// #define SUPPORT_IF_STATEMENT // Add support for IF statement in rules (+4k2 code, -332 bytes mem)
|
||||
|
||||
//#define USE_SCRIPT // Add support for script (+17k code)
|
||||
//#define USE_SCRIPT_FATFS 4 // Script: Add FAT FileSystem Support
|
||||
|
||||
// #define SUPPORT_MQTT_EVENT // Support trigger event with MQTT subscriptions (+3k5 code)
|
||||
|
||||
// -- Optional modules ----------------------------
|
||||
|
@ -611,6 +611,7 @@
|
|||
//#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)
|
||||
#define USE_BL0940 // Add support for BL0940 Energy monitor as used in Blitzwolf SHP-10 (+1k6 code)
|
||||
|
||||
// -- Low level interface devices -----------------
|
||||
#define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor (1k6 code)
|
||||
|
|
|
@ -572,11 +572,12 @@ void GetFeatures(void)
|
|||
#ifdef USE_MCP9808
|
||||
feature6 |= 0x00002000; // xsns_72_mcp9808.ino
|
||||
#endif
|
||||
#ifdef USE_HP303B
|
||||
feature6 |= 0x00004000; // xsns_73_hp303b.ino
|
||||
#ifdef USE_BL0940
|
||||
feature6 |= 0x00004000; // xnrg_14_bl0940.ino
|
||||
#endif
|
||||
#ifdef USE_HP303B
|
||||
feature6 |= 0x00008000; // xsns_73_hp303b.ino
|
||||
#endif
|
||||
|
||||
// feature6 |= 0x00008000;
|
||||
|
||||
// feature6 |= 0x00010000;
|
||||
// feature6 |= 0x00020000;
|
||||
|
|
|
@ -293,6 +293,7 @@ enum SettingsTextIndex { SET_OTAURL,
|
|||
SET_TEMPLATE_NAME,
|
||||
SET_DEV_GROUP_NAME1, SET_DEV_GROUP_NAME2, SET_DEV_GROUP_NAME3, SET_DEV_GROUP_NAME4,
|
||||
SET_DEVICENAME,
|
||||
SET_TELEGRAMTOKEN,
|
||||
SET_MAX };
|
||||
|
||||
enum DevGroupMessageType { DGR_MSGTYP_FULL_STATUS, DGR_MSGTYP_PARTIAL_UPDATE, DGR_MSGTYP_UPDATE, DGR_MSGTYP_UPDATE_MORE_TO_COME, DGR_MSGTYP_UPDATE_DIRECT, DGR_MSGTYPE_UPDATE_COMMAND };
|
||||
|
|
|
@ -233,6 +233,7 @@ enum UserSelectablePins {
|
|||
GPIO_BOILER_OT_RX, // OpenTherm Boiler RX pin
|
||||
GPIO_BOILER_OT_TX, // OpenTherm Boiler TX pin
|
||||
GPIO_WINDMETER_SPEED, // WindMeter speed counter pin
|
||||
GPIO_BL0940_RX, // BL0940 serial interface
|
||||
GPIO_SENSOR_END };
|
||||
|
||||
// Programmer selectable GPIO functionality
|
||||
|
@ -322,7 +323,8 @@ const char kSensorNames[] PROGMEM =
|
|||
D_SENSOR_ELECTRIQ_MOODL "|"
|
||||
D_SENSOR_AS3935 "|" D_SENSOR_PMS5003_TX "|"
|
||||
D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|"
|
||||
D_SENSOR_WINDMETER_SPEED
|
||||
D_SENSOR_WINDMETER_SPEED "|"
|
||||
D_SENSOR_BL0940_RX
|
||||
;
|
||||
|
||||
const char kSensorNamesFixed[] PROGMEM =
|
||||
|
@ -553,15 +555,18 @@ const uint8_t kGpioNiceList[] PROGMEM = {
|
|||
#ifdef USE_DDSU666
|
||||
GPIO_DDSU666_TX, // DDSU666 Serial interface
|
||||
GPIO_DDSU666_RX, // DDSU666 Serial interface
|
||||
#endif // USE_DDSU666
|
||||
#endif
|
||||
#ifdef USE_SOLAX_X1
|
||||
GPIO_SOLAXX1_TX, // Solax Inverter tx pin
|
||||
GPIO_SOLAXX1_RX, // Solax Inverter rx pin
|
||||
#endif // USE_SOLAX_X1
|
||||
#endif
|
||||
#ifdef USE_LE01MR
|
||||
GPIO_LE01MR_RX, // F7F LE-01MR energy meter rx pin
|
||||
GPIO_LE01MR_TX, // F7F LE-01MR energy meter tx pin
|
||||
#endif // IFDEF:USE_LE01MR
|
||||
#endif
|
||||
#ifdef USE_BL0940
|
||||
GPIO_BL0940_RX, // BL0940 Serial interface
|
||||
#endif
|
||||
#endif // USE_ENERGY_SENSOR
|
||||
|
||||
// Serial
|
||||
|
|
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
xnrg_14_bl0940.ino - BL0940 energy sensor support for Tasmota
|
||||
|
||||
Copyright (C) 2020 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef USE_ENERGY_SENSOR
|
||||
#ifdef USE_BL0940
|
||||
/*********************************************************************************************\
|
||||
* BL0940 - Energy (Blitzwolf SHP10)
|
||||
*
|
||||
* Template {"NAME":"BW-SHP10","GPIO":[0,148,0,207,158,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18}
|
||||
*
|
||||
* Based on datasheet from http://www.belling.com.cn/media/file_object/bel_product/BL0940/datasheet/BL0940_V1.1_en.pdf
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XNRG_14 14
|
||||
|
||||
#define BL0940_PULSES_NOT_INITIALIZED -1
|
||||
|
||||
#define BL0940_BUFFER_SIZE 36
|
||||
|
||||
#define BL0940_WRITE_COMMAND 0xA0 // 0xA8 according to documentation
|
||||
#define BL0940_REG_I_FAST_RMS_CTRL 0x10
|
||||
#define BL0940_REG_MODE 0x18
|
||||
#define BL0940_REG_SOFT_RESET 0x19
|
||||
#define BL0940_REG_USR_WRPROT 0x1A
|
||||
#define BL0940_REG_TPS_CTRL 0x1B
|
||||
|
||||
#define BL0940_READ_COMMAND 0x50 // 0x58 according to documentation
|
||||
#define BL0940_FULL_PACKET 0xAA
|
||||
#define BL0940_PACKET_HEADER 0x55 // 0x58 according to documentation
|
||||
|
||||
#include <TasmotaSerial.h>
|
||||
|
||||
TasmotaSerial *Bl0940Serial = nullptr;
|
||||
|
||||
struct BL0940 {
|
||||
long voltage = 0;
|
||||
long current = 0;
|
||||
long power = 0;
|
||||
long power_cycle_first = 0;
|
||||
long cf_pulses = 0;
|
||||
long cf_pulses_last_time = BL0940_PULSES_NOT_INITIALIZED;
|
||||
float temperature;
|
||||
|
||||
int byte_counter = 0;
|
||||
uint8_t *rx_buffer = nullptr;
|
||||
uint8_t power_invalid = 0;
|
||||
bool received = false;
|
||||
} Bl0940;
|
||||
|
||||
const uint8_t bl0940_init[5][6] = {
|
||||
{ BL0940_WRITE_COMMAND, BL0940_REG_SOFT_RESET, 0x5A, 0x5A, 0x5A, 0x38 }, // Reset to default
|
||||
{ BL0940_WRITE_COMMAND, BL0940_REG_USR_WRPROT, 0x55, 0x00, 0x00, 0xF0 }, // Enable User Operation Write
|
||||
{ BL0940_WRITE_COMMAND, BL0940_REG_MODE, 0x00, 0x10, 0x00, 0x37 }, // 0x0100 = CF_UNABLE energy pulse, AC_FREQ_SEL 50Hz, RMS_UPDATE_SEL 800mS
|
||||
{ BL0940_WRITE_COMMAND, BL0940_REG_TPS_CTRL, 0xFF, 0x47, 0x00, 0xFE }, // 0x47FF = Over-current and leakage alarm on, Automatic temperature measurement, Interval 100mS
|
||||
{ BL0940_WRITE_COMMAND, BL0940_REG_I_FAST_RMS_CTRL, 0x1C, 0x18, 0x00, 0x1B }}; // 0x181C = Half cycle, Fast RMS threshold 6172
|
||||
|
||||
void Bl0940Received(void) {
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
||||
// 55 F2 03 00 00 00 00 7E 02 00 D4 B0 72 AC 01 00 00 00 00 02 01 00 00 00 00 00 00 00 BA 01 00 FE 03 00 83
|
||||
// 55 88 02 00 49 00 00 FE 02 00 AF EF 71 D2 01 00 EB FF FF 49 01 00 00 00 00 02 00 00 CF 01 00 FE 03 00 9F
|
||||
// 55 B9 33 00 DE 45 00 94 02 00 CF E4 70 63 02 00 6C 4C 00 13 01 00 09 00 00 00 00 00 E4 01 00 FE 03 00 72
|
||||
// Hd IFRms--- Current- Reserved Voltage- Reserved Power--- Reserved CF------ Reserved TPS1---- TPS2---- Ck
|
||||
|
||||
if (Bl0940.rx_buffer[0] != BL0940_PACKET_HEADER) {
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR("BL9: Invalid data"));
|
||||
return;
|
||||
}
|
||||
|
||||
Bl0940.voltage = Bl0940.rx_buffer[12] << 16 | Bl0940.rx_buffer[11] << 8 | Bl0940.rx_buffer[10];
|
||||
Bl0940.current = Bl0940.rx_buffer[6] << 16 | Bl0940.rx_buffer[5] << 8 | Bl0940.rx_buffer[4];
|
||||
Bl0940.power = Bl0940.rx_buffer[18] << 16 | Bl0940.rx_buffer[17] << 8 | Bl0940.rx_buffer[16];
|
||||
Bl0940.cf_pulses = Bl0940.rx_buffer[24] << 16 | Bl0940.rx_buffer[23] << 8 | Bl0940.rx_buffer[22];
|
||||
uint16_t tps1 = Bl0940.rx_buffer[29] << 8 | Bl0940.rx_buffer[28];
|
||||
Bl0940.temperature = ((170.0f/448.0f)*(((float)tps1/2.0f)-32.0f))-45.0f;
|
||||
|
||||
if (Energy.power_on) { // Powered on
|
||||
Energy.voltage[0] = (float)Bl0940.voltage / Settings.energy_voltage_calibration;
|
||||
if (power != 0) {
|
||||
Energy.active_power[0] = (float)Bl0940.power / Settings.energy_power_calibration;
|
||||
Energy.current[0] = (float)Bl0940.current / (Settings.energy_current_calibration * 100);
|
||||
} else {
|
||||
Energy.active_power[0] = 0;
|
||||
Energy.current[0] = 0;
|
||||
}
|
||||
} else { // Powered off
|
||||
Bl0940.power_cycle_first = 0;
|
||||
Energy.voltage[0] = 0;
|
||||
Energy.active_power[0] = 0;
|
||||
Energy.current[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool Bl0940SerialInput(void) {
|
||||
while (Bl0940Serial->available()) {
|
||||
yield();
|
||||
uint8_t serial_in_byte = Bl0940Serial->read();
|
||||
if (!Bl0940.received && (BL0940_PACKET_HEADER == serial_in_byte)) { // Packet header
|
||||
Bl0940.received = true;
|
||||
Bl0940.byte_counter = 0;
|
||||
}
|
||||
if (Bl0940.received) {
|
||||
Bl0940.rx_buffer[Bl0940.byte_counter++] = serial_in_byte;
|
||||
if (BL0940_BUFFER_SIZE == Bl0940.byte_counter) {
|
||||
|
||||
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, Bl0940.rx_buffer, BL0940_BUFFER_SIZE -1);
|
||||
|
||||
uint8_t checksum = BL0940_READ_COMMAND;
|
||||
for (uint32_t i = 0; i < BL0940_BUFFER_SIZE -2; i++) { checksum += Bl0940.rx_buffer[i]; }
|
||||
checksum ^= 0xFF;
|
||||
if (checksum == Bl0940.rx_buffer[34]) {
|
||||
Energy.data_valid[0] = 0;
|
||||
Bl0940Received();
|
||||
Bl0940.received = false;
|
||||
return true;
|
||||
} else {
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR("BL9: " D_CHECKSUM_FAILURE));
|
||||
do { // Sync buffer with data (issue #1907 and #3425)
|
||||
memmove(Bl0940.rx_buffer, Bl0940.rx_buffer +1, BL0940_BUFFER_SIZE -1);
|
||||
Bl0940.byte_counter--;
|
||||
} while ((Bl0940.byte_counter > 1) && (BL0940_PACKET_HEADER != Bl0940.rx_buffer[0]));
|
||||
if (BL0940_PACKET_HEADER != Bl0940.rx_buffer[0]) {
|
||||
Bl0940.received = false;
|
||||
Bl0940.byte_counter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
void Bl0940EverySecond(void) {
|
||||
if (Energy.data_valid[0] > ENERGY_WATCHDOG) {
|
||||
Bl0940.voltage = 0;
|
||||
Bl0940.current = 0;
|
||||
Bl0940.power = 0;
|
||||
} else {
|
||||
if (Energy.active_power[0]) {
|
||||
Energy.kWhtoday_delta += (Energy.active_power[0] * 1000) / 36;
|
||||
EnergyUpdateToday();
|
||||
}
|
||||
}
|
||||
|
||||
Bl0940Serial->flush();
|
||||
Bl0940Serial->write(BL0940_READ_COMMAND);
|
||||
Bl0940Serial->write(BL0940_FULL_PACKET);
|
||||
}
|
||||
|
||||
void Bl0940SnsInit(void) {
|
||||
// Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions
|
||||
Bl0940Serial = new TasmotaSerial(Pin(GPIO_BL0940_RX), Pin(GPIO_TXD), 1);
|
||||
if (Bl0940Serial->begin(4800, 2)) {
|
||||
if (Bl0940Serial->hardwareSerial()) {
|
||||
ClaimSerial();
|
||||
}
|
||||
if (HLW_UREF_PULSE == Settings.energy_voltage_calibration) {
|
||||
Settings.energy_voltage_calibration = 33003;
|
||||
Settings.energy_current_calibration = 2243;
|
||||
Settings.energy_power_calibration = 1414;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < 5; i++) {
|
||||
for (uint32_t j = 0; j < 6; j++) {
|
||||
Bl0940Serial->write(bl0940_init[i][j]);
|
||||
// Bl0940Serial->write(pgm_read_byte(bl0940_init + (6 * i) + j)); // Wrong byte order!
|
||||
}
|
||||
delay(1);
|
||||
}
|
||||
|
||||
} else {
|
||||
energy_flg = ENERGY_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
void Bl0940DrvInit(void) {
|
||||
if (PinUsed(GPIO_BL0940_RX) && PinUsed(GPIO_TXD)) {
|
||||
Bl0940.rx_buffer = (uint8_t*)(malloc(BL0940_BUFFER_SIZE));
|
||||
if (Bl0940.rx_buffer != nullptr) {
|
||||
energy_flg = XNRG_14;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Bl0940Command(void) {
|
||||
bool serviced = true;
|
||||
|
||||
uint32_t value = (uint32_t)(CharToFloat(XdrvMailbox.data) * 100); // 1.23 = 123
|
||||
|
||||
if (CMND_POWERSET == Energy.command_code) {
|
||||
if (XdrvMailbox.data_len && Bl0940.power) {
|
||||
Settings.energy_power_calibration = (Bl0940.power * 100) / value;
|
||||
}
|
||||
}
|
||||
else if (CMND_VOLTAGESET == Energy.command_code) {
|
||||
if (XdrvMailbox.data_len && Bl0940.voltage) {
|
||||
Settings.energy_voltage_calibration = (Bl0940.voltage * 100) / value;
|
||||
}
|
||||
}
|
||||
else if (CMND_CURRENTSET == Energy.command_code) {
|
||||
if (XdrvMailbox.data_len && Bl0940.current) {
|
||||
Settings.energy_current_calibration = Bl0940.current / value;
|
||||
}
|
||||
}
|
||||
else serviced = false; // Unknown command
|
||||
|
||||
return serviced;
|
||||
}
|
||||
|
||||
void Bl0940Show(bool json)
|
||||
{
|
||||
char temperature[33];
|
||||
dtostrfd(Bl0940.temperature, Settings.flag2.temperature_resolution, temperature);
|
||||
|
||||
if (json) {
|
||||
ResponseAppend_P(JSON_SNS_TEMP, "BL0940", temperature);
|
||||
if (0 == tele_period) {
|
||||
#ifdef USE_DOMOTICZ
|
||||
DomoticzSensor(DZ_TEMP, temperature);
|
||||
#endif // USE_DOMOTICZ
|
||||
#ifdef USE_KNX
|
||||
KnxSensor(KNX_TEMPERATURE, Bl0940.temperature);
|
||||
#endif // USE_KNX
|
||||
}
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
WSContentSend_PD(HTTP_SNS_TEMP, "", temperature, TempUnit());
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
bool Xnrg14(uint8_t function)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
switch (function) {
|
||||
case FUNC_LOOP:
|
||||
if (Bl0940Serial) { Bl0940SerialInput(); }
|
||||
break;
|
||||
case FUNC_ENERGY_EVERY_SECOND:
|
||||
Bl0940EverySecond();
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
Bl0940Show(1);
|
||||
break;
|
||||
#ifdef USE_WEBSERVER
|
||||
case FUNC_WEB_SENSOR:
|
||||
Bl0940Show(0);
|
||||
break;
|
||||
#endif // USE_WEBSERVER
|
||||
case FUNC_COMMAND:
|
||||
result = Bl0940Command();
|
||||
break;
|
||||
case FUNC_INIT:
|
||||
Bl0940SnsInit();
|
||||
break;
|
||||
case FUNC_PRE_INIT:
|
||||
Bl0940DrvInit();
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_BL0940
|
||||
#endif // USE_ENERGY_SENSOR
|
|
@ -148,7 +148,8 @@ a_setoption = [[
|
|||
"Enable light fading at start/power on",
|
||||
"Set PWM Mode from regular PWM to ColorTemp control","",
|
||||
"Keep uncompressed rules in memory to avoid CPU load of uncompressing at each tick",
|
||||
"","","",
|
||||
"Implement simpler MAX6675 protocol instead of MAX31855",
|
||||
"","",
|
||||
"","","","",
|
||||
"","","","",
|
||||
"","","","",
|
||||
|
@ -204,7 +205,7 @@ a_features = [[
|
|||
"USE_KEELOQ","USE_HRXL","USE_SONOFF_D1","USE_HDC1080",
|
||||
"USE_IAQ","USE_DISPLAY_SEVENSEG","USE_AS3935","USE_PING",
|
||||
"USE_WINDMETER","USE_OPENTHERM","USE_THERMOSTAT","USE_VEML6075",
|
||||
"USE_VEML7700","USE_MCP9808","USE_HP303B","",
|
||||
"USE_VEML7700","USE_MCP9808","USE_BL0940","USE_HP303B",
|
||||
"","","","",
|
||||
"","","","",
|
||||
"","","","",
|
||||
|
@ -242,7 +243,7 @@ else:
|
|||
obj = json.load(fp)
|
||||
|
||||
def StartDecode():
|
||||
print ("\n*** decode-status.py v20200510 by Theo Arends and Jacek Ziolkowski ***")
|
||||
print ("\n*** decode-status.py v20200607 by Theo Arends and Jacek Ziolkowski ***")
|
||||
|
||||
# print("Decoding\n{}".format(obj))
|
||||
|
||||
|
|
Loading…
Reference in New Issue