5.5.1 20170805
* Fix Sonoff Rf Bridge issues
* Add Sonoff RF Bridge MQTT messages on received and learned RF signal
* Add command VoltRes 0|1 to select voltage resolution to 0.1 V (#654)
* Add averaging to Analog input (#686)
* Add Energy tele data on Sonoff Pow Threshold change (#688)
* Fix inconsistent property names in Messages (#690)
This commit is contained in:
arendst 2017-08-05 15:11:50 +02:00
parent 0a9ec10b0a
commit 934d6e3f15
7 changed files with 100 additions and 33 deletions

View File

@ -1,9 +1,15 @@
## Sonoff-Tasmota
Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE.
Current version is **5.5.0** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
Current version is **5.5.1** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
### **** ATTENTION Version 5.x.x specific information ****
### ATTENTION All versions
Only Flash Mode DOUT is supported. Do not use Flash Mode DIO / QIO / QOUT as it might seem to brick your device.
See [Wiki](https://github.com/arendst/Sonoff-Tasmota/wiki/Theo's-Tasmota-Tips) for background information.
### ATTENTION Version 5.x.x specific information
This version uses a new linker script to free flash memory for future code additions. It moves the settings from Spiffs to Eeprom. If you compile your own firmware download the new linker to your IDE or Platformio base folder. See [Wiki > Prerequisite](https://github.com/arendst/Sonoff-Tasmota/wiki/Prerequisite).
@ -15,7 +21,7 @@ Best practice to implement is:
You should now have a device with 32k more code memory to play with.
### *********************************************************
### Version Information
- This version provides all (Sonoff) modules in one file and starts up with Sonoff Basic.
- Once uploaded select module using the configuration webpage or the commands ```Modules``` and ```Module```.

View File

@ -1,4 +1,12 @@
/* 5.5.0 20170730
/* 5.5.1 20170805
* Fix Sonoff Rf Bridge issues
* Add Sonoff RF Bridge MQTT messages on received and learned RF signal
* Add command VoltRes 0|1 to select voltage resolution to 0.1 V (#654)
* Add averaging to Analog input (#686)
* Add Energy tele data on Sonoff Pow Threshold change (#688)
* Fix inconsistent property names in Messages (#690)
*
* 5.5.0 20170730
* Reduce code space by removing the following commands as they are replaced by SetOption alternatives:
* SaveState = SetOption0
* ButtonRestrict = SetOption1

View File

@ -42,7 +42,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t spare17 : 1;
uint32_t spare18 : 1;
uint32_t spare19 : 1;
uint32_t spare20 : 1;
uint32_t voltage_resolution : 1;
uint32_t emulation : 2;
uint32_t energy_resolution : 3;
uint32_t pressure_resolution : 2;

View File

@ -366,6 +366,7 @@ void CFG_Dump(char* parms)
}
snprintf_P(log, sizeof(log), PSTR("%s|"), log);
addLog(LOG_LEVEL_INFO, log);
delay(1);
}
}

View File

@ -25,7 +25,7 @@
- Select IDE Tools - Flash Size: "1M (no SPIFFS)"
====================================================*/
#define VERSION 0x05050000 // 5.5.0
#define VERSION 0x05050100 // 5.5.1
enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
enum week_t {Last, First, Second, Third, Fourth};
@ -1129,6 +1129,12 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"PressRes\":%d}"), sysCfg.flag.pressure_resolution);
}
else if (!strcmp_P(type,PSTR("VOLTRES"))) {
if ((payload >= 0) && (payload <= 1)) {
sysCfg.flag.voltage_resolution = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"VoltRes\":%d}"), sysCfg.flag.voltage_resolution);
}
else if (!strcmp_P(type,PSTR("ENERGYRES"))) {
if ((payload >= 0) && (payload <= 5)) {
sysCfg.flag.energy_resolution = payload;
@ -1762,7 +1768,7 @@ void publish_status(uint8_t payload)
}
if ((0 == payload) || (3 == payload)) {
snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusLOG\":{\"Seriallog\":%d, \"Weblog\":%d, \"Syslog\":%d, \"LogHost\":\"%s\", \"SSId1\":\"%s\", \"SSId2\":\"%s\", \"TelePeriod\":%d, \"Option\":\"%X\"}}"),
snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusLOG\":{\"Seriallog\":%d, \"Weblog\":%d, \"Syslog\":%d, \"LogHost\":\"%s\", \"SSId1\":\"%s\", \"SSId2\":\"%s\", \"TelePeriod\":%d, \"Option\":\"%08X\"}}"),
sysCfg.seriallog_level, sysCfg.weblog_level, sysCfg.syslog_level, sysCfg.syslog_host, sysCfg.sta_ssid[0], sysCfg.sta_ssid[1], sysCfg.tele_period, sysCfg.flag.data);
mqtt_publish_topic_P(option, PSTR("STATUS3"), svalue);
}
@ -1774,7 +1780,7 @@ void publish_status(uint8_t payload)
}
if ((0 == payload) || (5 == payload)) {
snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusNET\":{\"Host\":\"%s\", \"IP\":\"%s\", \"Gateway\":\"%s\", \"Subnetmask\":\"%s\", \"DNSServer\":\"%s\", \"Mac\":\"%s\", \"Webserver\":%d, \"WifiConfig\":%d}}"),
snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusNET\":{\"Hostname\":\"%s\", \"IPaddress\":\"%s\", \"Gateway\":\"%s\", \"Subnetmask\":\"%s\", \"DNSServer\":\"%s\", \"Mac\":\"%s\", \"Webserver\":%d, \"WifiConfig\":%d}}"),
Hostname, WiFi.localIP().toString().c_str(), IPAddress(sysCfg.ip_address[1]).toString().c_str(), IPAddress(sysCfg.ip_address[2]).toString().c_str(), IPAddress(sysCfg.ip_address[3]).toString().c_str(),
WiFi.macAddress().c_str(), sysCfg.webserver, sysCfg.sta_config);
mqtt_publish_topic_P(option, PSTR("STATUS5"), svalue);
@ -1856,7 +1862,12 @@ void sensors_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
counter_mqttPresent(svalue, ssvalue, djson);
#ifndef USE_ADC_VCC
if (pin[GPIO_ADC0] < 99) {
snprintf_P(svalue, ssvalue, PSTR("%s, \"AnalogInput0\":%d"), svalue, analogRead(A0));
uint16_t alr = 0;
for (byte i = 0; i < 32; i++) {
alr += analogRead(A0);
delay(1);
}
snprintf_P(svalue, ssvalue, PSTR("%s, \"AnalogInput0\":%d"), svalue, alr >> 5);
*djson = 1;
}
#endif

View File

@ -21,46 +21,77 @@
Sonoff RF Bridge 433
\*********************************************************************************************/
uint8_t sfb_rcvflg = 0; // Sonoff RF Bridge communication
uint8_t sfb_rcvflg = 0;
uint8_t sfb_learnKey = 1;
uint8_t sfb_learnFlg = 0;
void sb_received()
{
char svalue[60];
uint8_t i = 0;
uint32_t sid = 0;
uint32_t rid = 0;
uint16_t rsy = 0;
uint16_t rlo = 0;
uint16_t rhi = 0;
char svalue[90];
char rfkey[8];
char log[LOGSZ];
svalue[0] = '\0';
for (byte i = 0; i < SerialInByteCounter; i++) {
for (i = 0; i < SerialInByteCounter; i++) {
snprintf_P(svalue, sizeof(svalue), PSTR("%s%02X "), svalue, serialInBuf[i]);
}
snprintf_P(log, sizeof(log), PSTR("BRDG: Received %s"), svalue);
addLog(LOG_LEVEL_DEBUG, log);
if (0xA2 == serialInBuf[0]) { // Learn failed
if (0xA2 == serialInBuf[0]) { // Learn timeout
sfb_learnFlg = 0;
snprintf_P(svalue, sizeof(svalue), PSTR("{\"RfKey%d\":\"Learn failed\"}"), sfb_learnKey);
mqtt_publish_topic_P(5, PSTR("RFKEY"), svalue);
}
if (0xA3 == serialInBuf[0]) { // Learn
else if (0xA3 == serialInBuf[0]) { // Learned A3 20 F8 01 18 03 3E 2E 1A 22 55
sfb_learnFlg = 0;
for (uint8_t i = 0; i < 9; i++) {
rlo = serialInBuf[3] << 8 | serialInBuf[4]; // Low time in uSec
rhi = serialInBuf[5] << 8 | serialInBuf[6]; // High time in uSec
if (rlo && rhi) {
for (i = 0; i < 9; i++) {
sysCfg.sfb_code[sfb_learnKey][i] = serialInBuf[i +1];
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"RfKey%d\":\"Learned\"}"), sfb_learnKey);
} else {
snprintf_P(svalue, sizeof(svalue), PSTR("{\"RfKey%d\":\"Learn failed\"}"), sfb_learnKey);
}
mqtt_publish_topic_P(5, PSTR("RFKEY"), svalue);
}
else if (0xA4 == serialInBuf[0]) { // Received RF data A4 20 EE 01 18 03 3E 2E 1A 22 55
rsy = serialInBuf[1] << 8 | serialInBuf[2]; // Sync time in uSec
rlo = serialInBuf[3] << 8 | serialInBuf[4]; // Low time in uSec
rhi = serialInBuf[5] << 8 | serialInBuf[6]; // High time in uSec
rid = serialInBuf[7] << 16 | serialInBuf[8] << 8 | serialInBuf[9];
strcpy_P(rfkey, PSTR("\"None\""));
for (i = 1; i <= 16; i++) {
if (sysCfg.sfb_code[i][0]) {
sid = sysCfg.sfb_code[i][6] << 16 | sysCfg.sfb_code[i][7] << 8 | sysCfg.sfb_code[i][8];
if (sid == rid) {
snprintf_P(rfkey, sizeof(rfkey), PSTR("%d"), i);
break;
}
}
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"RfReceived\":{\"Sync\":%d, \"Low\":%d, \"High\":%d, \"Data\":\"%06X\", \"RfKey\":%s}}"),
rsy, rlo, rhi, rid, rfkey);
mqtt_publish_topic_P(6, PSTR("RFRECEIVED"), svalue);
}
}
boolean sb_serial()
{
if (sfb_rcvflg) {
if (SerialInByte > 0) {
if (!((SerialInByteCounter == 0) && (SerialInByte == 0))) { // Skip leading 0
serialInBuf[SerialInByteCounter++] = SerialInByte;
if (0x55 == SerialInByte) {
// serialInBuf[SerialInByteCounter] = 0x55;
if (0x55 == SerialInByte) { // 0x55 - End of text
sb_received();
sfb_rcvflg = 0; // 0x55 - End of text
sfb_rcvflg = 0;
return 1;
}
}

View File

@ -173,7 +173,7 @@ void hlw_savestate()
sysCfg.hlw_kWhtotal = rtcMem.hlw_kWhtotal;
}
boolean hlw_readEnergy(byte option, float &et, float &ed, uint16_t &e, uint16_t &w, uint16_t &u, float &i, float &c)
boolean hlw_readEnergy(byte option, float &et, float &ed, uint16_t &e, uint16_t &w, float &u, float &i, float &c)
{
unsigned long cur_kWhtoday = hlw_kWhtoday;
unsigned long hlw_len;
@ -222,7 +222,7 @@ boolean hlw_readEnergy(byte option, float &et, float &ed, uint16_t &e, uint16_t
}
if (hlw_cf1u_plen && (w || (power &1))) {
hlw_u = (HLW_UREF * sysCfg.hlw_ucal) / hlw_cf1u_plen;
u = hlw_u / 10;
u = (float)hlw_u / 10;
} else {
u = 0;
}
@ -313,13 +313,14 @@ void hlw_margin_chk()
char svalue[200]; // was MESSZ
float pet;
float ped;
float pu;
float pi;
float pc;
uint16_t uped;
uint16_t puv;
uint16_t piv;
uint16_t pe;
uint16_t pw;
uint16_t pu;
boolean flag;
boolean jsonflg;
@ -330,6 +331,7 @@ void hlw_margin_chk()
hlw_readEnergy(0, pet, ped, pe, pw, pu, pi, pc);
if (power && (sysCfg.hlw_pmin || sysCfg.hlw_pmax || sysCfg.hlw_umin || sysCfg.hlw_umax || sysCfg.hlw_imin || sysCfg.hlw_imax)) {
puv = (uint16_t)(pu);
piv = (uint16_t)(pi * 1000);
// snprintf_P(log, sizeof(log), PSTR("HLW: W %d, U %d, I %d"), pw, pu, piv);
@ -345,11 +347,11 @@ void hlw_margin_chk()
snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"PowerHigh\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag));
jsonflg = 1;
}
if (hlw_margin(0, sysCfg.hlw_umin, pu, flag, hlw_uminflg)) {
if (hlw_margin(0, sysCfg.hlw_umin, puv, flag, hlw_uminflg)) {
snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"VoltageLow\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag));
jsonflg = 1;
}
if (hlw_margin(1, sysCfg.hlw_umax, pw, flag, hlw_umaxflg)) {
if (hlw_margin(1, sysCfg.hlw_umax, puv, flag, hlw_umaxflg)) {
snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"VoltageHigh\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag));
jsonflg = 1;
}
@ -364,6 +366,7 @@ void hlw_margin_chk()
if (jsonflg) {
snprintf_P(svalue, sizeof(svalue), PSTR("%s}"), svalue);
mqtt_publish_topic_P(2, PSTR("MARGINS"), svalue);
hlw_mqttPresent();
}
}
@ -378,6 +381,7 @@ void hlw_margin_chk()
if (!hlw_mplh_counter) {
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxPowerReached\":\"%d%s\"}"), pw, (sysCfg.flag.value_units) ? " W" : "");
mqtt_publish_topic_P(1, PSTR("WARNING"), svalue);
hlw_mqttPresent();
do_cmnd_power(1, 0);
if (!hlw_mplr_counter) {
hlw_mplr_counter = sysCfg.param[P_MAX_POWER_RETRY] +1;
@ -404,6 +408,7 @@ void hlw_margin_chk()
} else {
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxPowerReachedRetry\":\"%s\"}"), getStateText(0));
mqtt_publish_topic_P(1, PSTR("WARNING"), svalue);
hlw_mqttPresent();
}
}
}
@ -424,6 +429,7 @@ void hlw_margin_chk()
dtostrf(ped, 1, 3, svalue);
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxEnergyReached\":\"%s%s\"}"), svalue, (sysCfg.flag.value_units) ? " kWh" : "");
mqtt_publish_topic_P(1, PSTR("WARNING"), svalue);
hlw_mqttPresent();
do_cmnd_power(1, 0);
}
}
@ -615,14 +621,15 @@ void hlw_mqttStat(byte option, char* svalue, uint16_t ssvalue)
char stemp2[10];
char stemp3[10];
char stemp4[10];
char stemp5[10];
char speriod[20];
float pet;
float ped;
float pu;
float pi;
float pc;
uint16_t pe;
uint16_t pw;
uint16_t pu;
hlw_readEnergy(option, pet, ped, pe, pw, pu, pi, pc);
dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, stemp0);
@ -630,9 +637,10 @@ void hlw_mqttStat(byte option, char* svalue, uint16_t ssvalue)
dtostrf(pc, 1, 2, stemp2);
dtostrf(pi, 1, 3, stemp3);
dtostrf(pet, 1, sysCfg.flag.energy_resolution, stemp4);
dtostrf(pu, 1, sysCfg.flag.voltage_resolution, stemp5);
snprintf_P(speriod, sizeof(speriod), PSTR(", \"Period\":%d"), pe);
snprintf_P(svalue, ssvalue, PSTR("%s\"Total\":%s, \"Yesterday\":%s, \"Today\":%s%s, \"Power\":%d, \"Factor\":%s, \"Voltage\":%d, \"Current\":%s}"),
svalue, stemp4, stemp0, stemp1, (option) ? speriod : "", pw, stemp2, pu, stemp3);
snprintf_P(svalue, ssvalue, PSTR("%s\"Total\":%s, \"Yesterday\":%s, \"Today\":%s%s, \"Power\":%d, \"Factor\":%s, \"Voltage\":%s, \"Current\":%s}"),
svalue, stemp4, stemp0, stemp1, (option) ? speriod : "", pw, stemp2, stemp5, stemp3);
#ifdef USE_DOMOTICZ
dtostrf(pet * 1000, 1, 1, stemp1);
domoticz_sensor4(pw, stemp1);
@ -658,7 +666,7 @@ void hlw_mqttStatus(char* svalue, uint16_t ssvalue)
#ifdef USE_WEBSERVER
const char HTTP_ENERGY_SNS[] PROGMEM =
"<tr><th>Voltage</th><td>%d V</td></tr>"
"<tr><th>Voltage</th><td>%s V</td></tr>"
"<tr><th>Current</th><td>%s A</td></tr>"
"<tr><th>Power</th><td>%d W</td></tr>"
"<tr><th>Power Factor</th><td>%s</td></tr>"
@ -674,23 +682,25 @@ String hlw_webPresent()
char stemp3[10];
char stemp4[10];
char stemp5[10];
char stemp6[10];
char sensor[320];
float pet;
float ped;
float pu;
float pi;
float pc;
uint16_t pe;
uint16_t pw;
uint16_t pu;
hlw_readEnergy(0, pet, ped, pe, pw, pu, pi, pc);
dtostrf(pu, 1, sysCfg.flag.voltage_resolution, stemp6);
dtostrf(pi, 1, 3, stemp);
dtostrf(pc, 1, 2, stemp2);
dtostrf(ped, 1, sysCfg.flag.energy_resolution, stemp3);
dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, stemp4);
dtostrf(pet, 1, sysCfg.flag.energy_resolution, stemp5);
snprintf_P(sensor, sizeof(sensor), HTTP_ENERGY_SNS, pu, stemp, pw, stemp2, stemp3, stemp4, stemp5);
snprintf_P(sensor, sizeof(sensor), HTTP_ENERGY_SNS, stemp6, stemp, pw, stemp2, stemp3, stemp4, stemp5);
page += sensor;
return page;
}