Merge branch 'development' into HP303B

# Conflicts:
#	tasmota/support_features.ino Resolved
#	tools/decode-status.py Resolved
This commit is contained in:
Robert Jaakke 2020-06-08 09:01:43 +02:00
commit 601317d5f3
31 changed files with 336 additions and 17 deletions

View File

@ -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)

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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)

View File

@ -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;

View File

@ -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 };

View File

@ -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

285
tasmota/xnrg_14_bl0940.ino Normal file
View File

@ -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

View File

@ -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))