mirror of https://github.com/arendst/Tasmota.git
v3.9.22
3.9.22 20170228 * Update web console * Fix Status 4 JSON message * Add Exception info during restart if available * Add osWatch service to detect loop hangs that might happen during (OTA) upgrades * Add WiOn support for relay and switch only (#82, #102) * Allow for user specified relay count up to four in sonoff_template.h (#109) * Add support for HTU21 compatible I2C sensors SI7013, SI7020 and SI7021 (#118) * Add NodeMCU or Wemos configuration option (#119)
This commit is contained in:
parent
3fefb9b931
commit
fc3b7e22ab
|
@ -1,7 +1,7 @@
|
|||
## 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 **3.9.21** - See ```sonoff/_releasenotes.ino``` for change information.
|
||||
Current version is **3.9.22** - See ```sonoff/_releasenotes.ino``` for change 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```.
|
||||
|
|
Binary file not shown.
|
@ -1,4 +1,14 @@
|
|||
/* 3.9.21 20170224
|
||||
/* 3.9.22 20170228
|
||||
* Update web console
|
||||
* Fix Status 4 JSON message
|
||||
* Add Exception info during restart if available
|
||||
* Add osWatch service to detect loop hangs that might happen during (OTA) upgrades
|
||||
* Add WiOn support for relay and switch only (#82, #102)
|
||||
* Allow for user specified relay count up to four in sonoff_template.h (#109)
|
||||
* Add support for HTU21 compatible I2C sensors SI7013, SI7020 and SI7021 (#118)
|
||||
* Add NodeMCU or Wemos configuration option (#119)
|
||||
*
|
||||
* 3.9.21 20170224
|
||||
* Add ajax to web root page and web console (#79)
|
||||
* Add commands SwitchMode1..4 and enable user switches 2, 3 and 4 (#84, #88)
|
||||
* Fix MQTT upgrade when webserver is active
|
||||
|
|
|
@ -189,3 +189,10 @@ struct SYSCFG {
|
|||
|
||||
} sysCfg;
|
||||
|
||||
struct RTCMEM {
|
||||
uint16_t valid;
|
||||
byte osw_flag;
|
||||
byte nu1;
|
||||
unsigned long hlw_kWhtoday;
|
||||
} rtcMem;
|
||||
|
||||
|
|
|
@ -23,6 +23,85 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*********************************************************************************************\
|
||||
* RTC memory
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define RTC_MEM_VALID 0xA55A
|
||||
|
||||
uint32_t _rtcHash = 0;
|
||||
|
||||
uint32_t getRtcHash()
|
||||
{
|
||||
uint32_t hash = 0;
|
||||
uint8_t *bytes = (uint8_t*)&rtcMem;
|
||||
|
||||
for (uint16_t i = 0; i < sizeof(RTCMEM); i++) hash += bytes[i]*(i+1);
|
||||
return hash;
|
||||
}
|
||||
|
||||
void RTC_Save()
|
||||
{
|
||||
if (getRtcHash() != _rtcHash) {
|
||||
rtcMem.valid = RTC_MEM_VALID;
|
||||
ESP.rtcUserMemoryWrite(100, (uint32_t*)&rtcMem, sizeof(RTCMEM));
|
||||
_rtcHash = getRtcHash();
|
||||
#ifdef DEBUG_THEO
|
||||
addLog_P(LOG_LEVEL_DEBUG, PSTR("Dump: Save"));
|
||||
RTC_Dump();
|
||||
#endif // DEBUG_THEO
|
||||
}
|
||||
}
|
||||
|
||||
void RTC_Load()
|
||||
{
|
||||
ESP.rtcUserMemoryRead(100, (uint32_t*)&rtcMem, sizeof(RTCMEM));
|
||||
#ifdef DEBUG_THEO
|
||||
addLog_P(LOG_LEVEL_DEBUG, PSTR("Dump: Load"));
|
||||
RTC_Dump();
|
||||
#endif // DEBUG_THEO
|
||||
if (rtcMem.valid != RTC_MEM_VALID) {
|
||||
memset(&rtcMem, 0x00, sizeof(RTCMEM));
|
||||
rtcMem.valid = RTC_MEM_VALID;
|
||||
RTC_Save();
|
||||
}
|
||||
_rtcHash = getRtcHash();
|
||||
}
|
||||
|
||||
boolean RTC_Valid()
|
||||
{
|
||||
return (rtcMem.valid == RTC_MEM_VALID);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_THEO
|
||||
void RTC_Dump()
|
||||
{
|
||||
#define CFG_COLS 16
|
||||
|
||||
char log[LOGSZ];
|
||||
uint16_t idx, maxrow, row, col;
|
||||
|
||||
uint8_t *buffer = (uint8_t *) &rtcMem;
|
||||
maxrow = ((sizeof(RTCMEM)+CFG_COLS)/CFG_COLS);
|
||||
|
||||
for (row = 0; row < maxrow; row++) {
|
||||
idx = row * CFG_COLS;
|
||||
snprintf_P(log, sizeof(log), PSTR("%04X:"), idx);
|
||||
for (col = 0; col < CFG_COLS; col++) {
|
||||
if (!(col%4)) snprintf_P(log, sizeof(log), PSTR("%s "), log);
|
||||
snprintf_P(log, sizeof(log), PSTR("%s %02X"), log, buffer[idx + col]);
|
||||
}
|
||||
snprintf_P(log, sizeof(log), PSTR("%s |"), log);
|
||||
for (col = 0; col < CFG_COLS; col++) {
|
||||
// if (!(col%4)) snprintf_P(log, sizeof(log), PSTR("%s "), log);
|
||||
snprintf_P(log, sizeof(log), PSTR("%s%c"), log, ((buffer[idx + col] > 0x20) && (buffer[idx + col] < 0x7F)) ? (char)buffer[idx + col] : ' ');
|
||||
}
|
||||
snprintf_P(log, sizeof(log), PSTR("%s|"), log);
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_THEO
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Config - Flash or Spiffs
|
||||
\*********************************************************************************************/
|
||||
|
@ -131,6 +210,7 @@ void CFG_Save()
|
|||
}
|
||||
_cfgHash = getHash();
|
||||
}
|
||||
RTC_Save();
|
||||
}
|
||||
|
||||
void CFG_Load()
|
||||
|
@ -177,6 +257,8 @@ void CFG_Load()
|
|||
}
|
||||
}
|
||||
_cfgHash = getHash();
|
||||
|
||||
RTC_Load();
|
||||
}
|
||||
|
||||
void CFG_Migrate()
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* ====================================================
|
||||
*/
|
||||
|
||||
#define VERSION 0x03091500 // 3.9.21
|
||||
#define VERSION 0x03091600 // 3.9.22
|
||||
|
||||
//#define BE_MINIMAL // Compile a minimal version if upgrade memory gets tight (still 404k)
|
||||
// To be used as step 1. Next step is compile and use desired version
|
||||
|
@ -45,6 +45,7 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
|
|||
#ifndef USE_DS18x20
|
||||
#define USE_DS18B20 // Default DS18B20 sensor needs no external library
|
||||
#endif
|
||||
//#define DEBUG_THEO // Add debug code
|
||||
|
||||
#ifdef BE_MINIMAL
|
||||
//#ifdef USE_MQTT_TLS
|
||||
|
@ -80,6 +81,9 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
|
|||
#ifdef USE_IR_REMOTE
|
||||
#undef USE_IR_REMOTE // Disable IR driver
|
||||
#endif
|
||||
#ifdef DEBUG_THEO
|
||||
#undef DEBUG_THEO // Disable debug code
|
||||
#endif
|
||||
#endif // BE_MINIMAL
|
||||
|
||||
#ifndef SWITCH_MODE
|
||||
|
@ -497,6 +501,9 @@ void mqtt_connected()
|
|||
mqtt_publish_topic_P(1, PSTR("INFO2"), svalue);
|
||||
}
|
||||
#endif // USE_WEBSERVER
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Started\":\"%s\"}"),
|
||||
(getResetReason() == "Exception") ? ESP.getResetInfo().c_str() : getResetReason().c_str());
|
||||
mqtt_publish_topic_P(1, PSTR("INFO3"), svalue);
|
||||
if (sysCfg.mqtt_enabled && (MQTT_MAX_PACKET_SIZE < (TOPSZ+MESSZ))) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Warning1\":\"Change MQTT_MAX_PACKET_SIZE in libraries/PubSubClient.h to at least %d\"}"), TOPSZ+MESSZ);
|
||||
mqtt_publish_topic_P(1, PSTR("WARNING1"), svalue);
|
||||
|
@ -1167,7 +1174,13 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
|||
else if ((pin[GPIO_IRSEND] < 99) && ir_send_command(type, index, dataBufUc, data_len, payload, svalue, sizeof(svalue))) {
|
||||
// Serviced
|
||||
}
|
||||
#endif // USE_IR_REMOTE
|
||||
#endif // USE_IR_REMOTE
|
||||
#ifdef DEBUG_THEO
|
||||
else if (!strcmp(type,"EXCEPTION")) {
|
||||
if (data_len > 0) exception_tst(payload);
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Exception\":\"Triggered\"}"));
|
||||
}
|
||||
#endif // DEBUG_THEO
|
||||
else {
|
||||
type = NULL;
|
||||
}
|
||||
|
@ -1369,7 +1382,7 @@ void publish_status(uint8_t payload)
|
|||
}
|
||||
|
||||
if ((payload == 0) || (payload == 4)) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusMEM\":{\"ProgramSize\":%d, \"Free\":%d, \"Heap\":%d, \"SpiffsStart\":%d, \"SpiffsSize\":%d, \"FlashSize\":%d, \"ProgramFlashSize\":%d, \"FlashChipMode\",%d}}"),
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusMEM\":{\"ProgramSize\":%d, \"Free\":%d, \"Heap\":%d, \"SpiffsStart\":%d, \"SpiffsSize\":%d, \"FlashSize\":%d, \"ProgramFlashSize\":%d, \"FlashChipMode\":%d}}"),
|
||||
ESP.getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP.getFreeHeap()/1024, ((uint32_t)&_SPIFFS_start - 0x40200000)/1024,
|
||||
(((uint32_t)&_SPIFFS_end - 0x40200000) - ((uint32_t)&_SPIFFS_start - 0x40200000))/1024, ESP.getFlashChipRealSize()/1024, ESP.getFlashChipSize()/1024, ESP.getFlashChipMode());
|
||||
mqtt_publish_topic_P(option, PSTR("STATUS4"), svalue);
|
||||
|
@ -1916,20 +1929,12 @@ void GPIO_init()
|
|||
}
|
||||
|
||||
Maxdevice = 1;
|
||||
switch (sysCfg.module) {
|
||||
case SONOFF_DUAL:
|
||||
case ELECTRODRAGON:
|
||||
Maxdevice = 2;
|
||||
break;
|
||||
case SONOFF_4CH:
|
||||
case CH4:
|
||||
Maxdevice = 4;
|
||||
break;
|
||||
if (sysCfg.module == SONOFF_DUAL) {
|
||||
Maxdevice = 2;
|
||||
Baudrate = 19200;
|
||||
}
|
||||
|
||||
swt_flg = ((pin[GPIO_SWT1] < 99) || (pin[GPIO_SWT2] < 99) || (pin[GPIO_SWT3] < 99) || (pin[GPIO_SWT4] < 99));
|
||||
|
||||
if ((sysCfg.module == SONOFF_DUAL) || (sysCfg.module == CH4)) {
|
||||
else if (sysCfg.module == CH4) {
|
||||
Maxdevice = 4;
|
||||
Baudrate = 19200;
|
||||
}
|
||||
else if (sysCfg.module == SONOFF_LED) {
|
||||
|
@ -1937,9 +1942,13 @@ void GPIO_init()
|
|||
sl_init();
|
||||
}
|
||||
else {
|
||||
Maxdevice = 0;
|
||||
for (byte i = 0; i < 4; i++) {
|
||||
if (pin[GPIO_REL1 +i] < 99) {
|
||||
pinMode(pin[GPIO_REL1 +i], OUTPUT);
|
||||
Maxdevice++;
|
||||
}
|
||||
if (pin[GPIO_KEY1 +i] < 99) pinMode(pin[GPIO_KEY1 +i], INPUT_PULLUP);
|
||||
if (pin[GPIO_REL1 +i] < 99) pinMode(pin[GPIO_REL1 +i], OUTPUT);
|
||||
}
|
||||
}
|
||||
for (byte i = 0; i < 4; i++) {
|
||||
|
@ -1948,6 +1957,7 @@ void GPIO_init()
|
|||
digitalWrite(pin[GPIO_LED1 +i], led_inverted[i]);
|
||||
}
|
||||
if (pin[GPIO_SWT1 +i] < 99) {
|
||||
swt_flg = 1;
|
||||
pinMode(pin[GPIO_SWT1 +i], INPUT_PULLUP);
|
||||
lastwallswitch[i] = digitalRead(pin[GPIO_SWT1 +i]); // set global now so doesn't change the saved power state on first switch check
|
||||
}
|
||||
|
@ -2007,6 +2017,8 @@ void setup()
|
|||
CFG_Load();
|
||||
CFG_Delta();
|
||||
|
||||
osw_init();
|
||||
|
||||
sysCfg.bootcount++;
|
||||
snprintf_P(log, sizeof(log), PSTR("APP: Bootcount %d"), sysCfg.bootcount);
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
|
@ -2073,6 +2085,8 @@ void setup()
|
|||
|
||||
void loop()
|
||||
{
|
||||
osw_loop();
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
pollDnsWeb();
|
||||
#endif // USE_WEBSERVER
|
||||
|
|
|
@ -90,6 +90,8 @@ enum module_t {
|
|||
MOTOR,
|
||||
ELECTRODRAGON,
|
||||
EXS_RELAY,
|
||||
WION,
|
||||
NODEMCU,
|
||||
USER_TEST,
|
||||
MAXMODULE };
|
||||
|
||||
|
@ -283,6 +285,34 @@ const mytmplt modules[MAXMODULE] PROGMEM = {
|
|||
0,
|
||||
GPIO_USER // GPIO16 Module Pin 4
|
||||
},
|
||||
{ "WiOn", // Indoor Tap https://www.amazon.com/gp/product/B00ZYLUBJU/ref=s9_acsd_al_bw_c_x_3_w
|
||||
GPIO_USER, // GPIO00 Optional sensor (pm clock)
|
||||
0,
|
||||
GPIO_LED1, // GPIO02 Green Led (1 = On, 0 = Off)
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
GPIO_USER, // GPIO12 Optional sensor (pm data)
|
||||
GPIO_KEY1, // GPIO13 Button
|
||||
0,
|
||||
GPIO_REL1, // GPIO15 Relay (0 = Off, 1 = On)
|
||||
0
|
||||
},
|
||||
{ "NodeMCU", // NodeMCU and Wemos hardware
|
||||
GPIO_KEY1, // GPIO00 Button
|
||||
GPIO_USER, // GPIO01 Serial RXD
|
||||
GPIO_USER, // GPIO02
|
||||
GPIO_USER, // GPIO03 Serial TXD and Optional sensor
|
||||
GPIO_USER, // GPIO04 Optional sensor
|
||||
GPIO_USER, // GPIO05
|
||||
0, 0, 0,
|
||||
GPIO_USER, // GPIO09
|
||||
GPIO_USER, // GPIO10
|
||||
0,
|
||||
GPIO_USER, // GPIO12
|
||||
GPIO_USER, // GPIO13
|
||||
GPIO_USER, // GPIO14
|
||||
GPIO_USER, // GPIO15
|
||||
0
|
||||
},
|
||||
{ "User Test", // Sonoff Basic User Test
|
||||
GPIO_KEY1, // GPIO00 Button
|
||||
0,
|
||||
|
|
|
@ -23,6 +23,127 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Watchdog extension (https://github.com/esp8266/Arduino/issues/1532)
|
||||
\*********************************************************************************************/
|
||||
|
||||
Ticker tickerOSWatch;
|
||||
|
||||
#define OSWATCH_RESET_TIME 30
|
||||
|
||||
static unsigned long osw_last_loop;
|
||||
byte osw_flag = 0;
|
||||
|
||||
void ICACHE_RAM_ATTR osw_osWatch(void)
|
||||
{
|
||||
unsigned long t = millis();
|
||||
unsigned long last_run = abs(t - osw_last_loop);
|
||||
|
||||
#ifdef DEBUG_THEO
|
||||
char log[LOGSZ];
|
||||
snprintf_P(log, sizeof(log), PSTR("osWatch: FreeRam %d, rssi %d, last_run %d"), ESP.getFreeHeap(), WIFI_getRSSIasQuality(WiFi.RSSI()), last_run);
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
#endif // DEBUG_THEO
|
||||
if(last_run >= (OSWATCH_RESET_TIME * 1000)) {
|
||||
addLog_P(LOG_LEVEL_INFO, PSTR("osWatch: Warning, loop blocked. Restart now"));
|
||||
rtcMem.osw_flag = 1;
|
||||
RTC_Save();
|
||||
// ESP.restart(); // normal reboot
|
||||
ESP.reset(); // hard reset
|
||||
}
|
||||
}
|
||||
|
||||
void osw_init()
|
||||
{
|
||||
osw_flag = rtcMem.osw_flag;
|
||||
rtcMem.osw_flag = 0;
|
||||
osw_last_loop = millis();
|
||||
tickerOSWatch.attach_ms(((OSWATCH_RESET_TIME / 3) * 1000), osw_osWatch);
|
||||
}
|
||||
|
||||
void osw_loop()
|
||||
{
|
||||
osw_last_loop = millis();
|
||||
// while(1) delay(1000); // this will trigger the os watch
|
||||
}
|
||||
|
||||
String getResetReason()
|
||||
{
|
||||
char buff[32];
|
||||
if (osw_flag) {
|
||||
strcpy_P(buff, PSTR("Blocked Loop"));
|
||||
return String(buff);
|
||||
} else {
|
||||
return ESP.getResetReason();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_THEO
|
||||
void exception_tst(byte type)
|
||||
{
|
||||
/*
|
||||
Exception (28):
|
||||
epc1=0x4000bf64 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000007 depc=0x00000000
|
||||
|
||||
ctx: cont
|
||||
sp: 3fff1f30 end: 3fff2840 offset: 01a0
|
||||
|
||||
>>>stack>>>
|
||||
3fff20d0: 202c3573 756f7247 2c302070 646e4920
|
||||
3fff20e0: 40236a6e 7954202c 45206570 00454358
|
||||
3fff20f0: 00000010 00000007 00000000 3fff2180
|
||||
3fff2100: 3fff2190 40107bfc 3fff3e4c 3fff22c0
|
||||
3fff2110: 40261934 000000f0 3fff22c0 401004d8
|
||||
3fff2120: 40238fcf 00000050 3fff2100 4021fc10
|
||||
3fff2130: 3fff32bc 4021680c 3ffeade1 4021ff7d
|
||||
3fff2140: 3fff2190 3fff2180 0000000c 7fffffff
|
||||
3fff2150: 00000019 00000000 00000000 3fff21c0
|
||||
3fff2160: 3fff23f3 3ffe8e08 00000000 4021ffb4
|
||||
3fff2170: 3fff2190 3fff2180 0000000c 40201118
|
||||
3fff2180: 3fff21c0 0000003c 3ffef840 00000007
|
||||
3fff2190: 00000000 00000000 00000000 40201128
|
||||
3fff21a0: 3fff23f3 000000f1 3fff23ec 4020fafb
|
||||
3fff21b0: 3fff23f3 3fff21c0 3fff21d0 3fff23f6
|
||||
3fff21c0: 00000000 3fff23fb 4022321b 00000000
|
||||
|
||||
Exception 28: LoadProhibited: A load referenced a page mapped with an attribute that does not permit loads
|
||||
Decoding 14 results
|
||||
0x40236a6e: ets_vsnprintf at ?? line ?
|
||||
0x40107bfc: vsnprintf at C:\Data2\Arduino\arduino-1.8.1-esp-2.3.0\portable\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/libc_replacements.c line 387
|
||||
0x40261934: bignum_exptmod at ?? line ?
|
||||
0x401004d8: malloc at C:\Data2\Arduino\arduino-1.8.1-esp-2.3.0\portable\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1664
|
||||
0x40238fcf: wifi_station_get_connect_status at ?? line ?
|
||||
0x4021fc10: operator new[](unsigned int) at C:\Data2\Arduino\arduino-1.8.1-esp-2.3.0\portable\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/abi.cpp line 57
|
||||
0x4021680c: ESP8266WiFiSTAClass::status() at C:\Data2\Arduino\arduino-1.8.1-esp-2.3.0\portable\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/ESP8266WiFiSTA.cpp line 569
|
||||
0x4021ff7d: vsnprintf_P(char*, unsigned int, char const*, __va_list_tag) at C:\Data2\Arduino\arduino-1.8.1-esp-2.3.0\portable\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/pgmspace.cpp line 146
|
||||
0x4021ffb4: snprintf_P(char*, unsigned int, char const*, ...) at C:\Data2\Arduino\arduino-1.8.1-esp-2.3.0\portable\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/pgmspace.cpp line 146
|
||||
0x40201118: atol at C:\Data2\Arduino\arduino-1.8.1-esp-2.3.0\portable\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/core_esp8266_noniso.c line 45
|
||||
0x40201128: atoi at C:\Data2\Arduino\arduino-1.8.1-esp-2.3.0\portable\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/core_esp8266_noniso.c line 45
|
||||
0x4020fafb: mqttDataCb(char*, unsigned char*, unsigned int) at R:\Arduino\Work-ESP8266\Theo\sonoff\sonoff-4\sonoff/sonoff.ino line 679 (discriminator 1)
|
||||
0x4022321b: pp_attach at ?? line ?
|
||||
|
||||
00:00:08 MQTT: tele/sonoff/INFO3 = {"Started":"Fatal exception:28 flag:2 (EXCEPTION) epc1:0x4000bf64 epc2:0x00000000 epc3:0x00000000 excvaddr:0x00000007 depc:0x00000000"}
|
||||
*/
|
||||
if (type == 1) {
|
||||
char svalue[10];
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("%s"), 7); // Exception 28 as number in string (7 in excvaddr)
|
||||
}
|
||||
/*
|
||||
14:50:52 osWatch: FreeRam 25896, rssi 68, last_run 0
|
||||
14:51:02 osWatch: FreeRam 25896, rssi 58, last_run 0
|
||||
14:51:03 CMND: exception 2
|
||||
14:51:12 osWatch: FreeRam 25360, rssi 60, last_run 8771
|
||||
14:51:22 osWatch: FreeRam 25360, rssi 62, last_run 18771
|
||||
14:51:32 osWatch: FreeRam 25360, rssi 62, last_run 28771
|
||||
14:51:42 osWatch: FreeRam 25360, rssi 62, last_run 38771
|
||||
14:51:42 osWatch: Warning, loop blocked. Restart now
|
||||
*/
|
||||
if (type == 2) {
|
||||
while(1) delay(1000); // this will trigger the os watch
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_THEO
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Wifi
|
||||
\*********************************************************************************************/
|
||||
|
@ -703,9 +824,6 @@ void addLog(byte loglevel, const char *line)
|
|||
|
||||
snprintf_P(mxtime, sizeof(mxtime), PSTR("%02d:%02d:%02d"), rtcTime.Hour, rtcTime.Minute, rtcTime.Second);
|
||||
|
||||
#ifdef DEBUG_ESP_PORT
|
||||
DEBUG_ESP_PORT.printf("%s %s\n", mxtime, line);
|
||||
#endif // DEBUG_ESP_PORT
|
||||
if (loglevel <= seriallog_level) Serial.printf("%s %s\n", mxtime, line);
|
||||
#ifdef USE_WEBSERVER
|
||||
if (sysCfg.webserver && (loglevel <= sysCfg.weblog_level)) {
|
||||
|
|
|
@ -124,7 +124,7 @@
|
|||
#define USE_I2C // I2C using library wire (+10k code, 0.2k mem) - Disable by //
|
||||
#define USE_BH1750 // Add I2C code for BH1750 sensor
|
||||
#define USE_BMP // Add I2C code for BMP/BME280 sensor
|
||||
#define USE_HTU // Add I2C code for HTU21 sensor
|
||||
#define USE_HTU // Add I2C code for HTU21/SI7013/SI7020/SI7021 sensor
|
||||
|
||||
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0.3k mem)
|
||||
|
||||
|
|
|
@ -70,13 +70,22 @@ const char HTTP_HEAD[] PROGMEM =
|
|||
"};"
|
||||
"x.open('GET','ay'+a,true);"
|
||||
"x.send();"
|
||||
"lt=setTimeout(la,2000);"
|
||||
"lt=setTimeout(la,2345);"
|
||||
"}"
|
||||
"var sn=0;" // Scroll position
|
||||
"var id=99;" // Get most of weblog initially
|
||||
"function l(){"
|
||||
"var e=document.getElementById('t1');"
|
||||
"if(e.scrollTop>=sn){" // User scrolled back so no updates
|
||||
"function l(p){" // Console log and command service
|
||||
"var c,o,t;"
|
||||
"clearTimeout(lt);"
|
||||
"o='';"
|
||||
"t=document.getElementById('t1');"
|
||||
"if(p==1){"
|
||||
"c=document.getElementById('c1');"
|
||||
"o='&c1='+c.value;"
|
||||
"c.value='';"
|
||||
"t.scrollTop=sn;"
|
||||
"}"
|
||||
"if(t.scrollTop>=sn){" // User scrolled back so no updates
|
||||
"if(x!=null){x.abort();}" // Abort if no response within 2 seconds (happens on restart 1)
|
||||
"x=new XMLHttpRequest();"
|
||||
"x.onreadystatechange=function(){"
|
||||
|
@ -84,25 +93,17 @@ const char HTTP_HEAD[] PROGMEM =
|
|||
"var z,d;"
|
||||
"d=x.responseXML;"
|
||||
"id=d.getElementsByTagName('i')[0].childNodes[0].nodeValue;"
|
||||
"if(d.getElementsByTagName('j')[0].childNodes[0].nodeValue==0){e.value=\"\";}"
|
||||
"if(d.getElementsByTagName('j')[0].childNodes[0].nodeValue==0){t.value='';}"
|
||||
"z=d.getElementsByTagName('l')[0].childNodes;"
|
||||
"if(z.length>0){e.value+=z[0].nodeValue;}"
|
||||
"e.scrollTop=99999;"
|
||||
"sn=e.scrollTop;"
|
||||
"if(z.length>0){t.value+=z[0].nodeValue;}"
|
||||
"t.scrollTop=99999;"
|
||||
"sn=t.scrollTop;"
|
||||
"}"
|
||||
"};"
|
||||
"x.open('GET','ax?c2='+id,true);"
|
||||
"x.open('GET','ax?c2='+id+o,true);"
|
||||
"x.send();"
|
||||
"}"
|
||||
"setTimeout(l,2000);"
|
||||
"}"
|
||||
"function lc(){"
|
||||
"var e=document.getElementById('c1');"
|
||||
// "if(x!=null){x.abort();}" // Abort if no response within 2 seconds (happens on restart 1)
|
||||
"var x=new XMLHttpRequest();"
|
||||
"x.open('GET','ax?c1='+e.value+'&c2='+id,true);"
|
||||
"x.send();"
|
||||
"e.value=\"\";"
|
||||
"lt=setTimeout(l,2345);"
|
||||
"return false;"
|
||||
"}"
|
||||
"</script>"
|
||||
|
@ -122,7 +123,7 @@ const char HTTP_HEAD[] PROGMEM =
|
|||
"</style>"
|
||||
"</head>"
|
||||
"<body>"
|
||||
"<div style='text-align:left;display:inline-block;min-width:260px;'>"
|
||||
"<div style='text-align:left;display:inline-block;min-width:320px;'>"
|
||||
"<div style='text-align:center;'><h3>{ha} Module</h3><h2>{h}</h2></div>";
|
||||
const char HTTP_MSG_RSTRT[] PROGMEM =
|
||||
"<br/><div style='text-align:center;'>Device will restart in a few seconds</div><br/>";
|
||||
|
@ -234,12 +235,18 @@ const char HTTP_FORM_UPG[] PROGMEM =
|
|||
"<div id='f2' name='f2' style='display:none;text-align:center;'><b>Upload started ...</b></div>";
|
||||
const char HTTP_FORM_CMND[] PROGMEM =
|
||||
"<br/><textarea readonly id='t1' name='t1' cols='99' wrap='off'></textarea><br/><br/>"
|
||||
"<form method='get' onsubmit='return lc();'>"
|
||||
"<form method='get' onsubmit='return l(1);'>"
|
||||
"<input style='width:98%' id='c1' name='c1' length='99' placeholder='Enter command' autofocus><br/>"
|
||||
// "<br/><button type='submit'>Send command</button>"
|
||||
"</form>";
|
||||
const char HTTP_COUNTER[] PROGMEM =
|
||||
"<br/><div id='t' name='t' style='text-align:center;'></div>";
|
||||
const char HTTP_SNS_TEMP[] PROGMEM =
|
||||
"<tr><th>%s Temperature</th><td>%s°%c</td></tr>";
|
||||
const char HTTP_SNS_HUM[] PROGMEM =
|
||||
"<tr><th>%s Humidity</th><td>%s%</td></tr>";
|
||||
const char HTTP_SNS_PRESSURE[] PROGMEM =
|
||||
"<tr><th>%s Pressure</th><td>%s hPa</td></tr>";
|
||||
const char HTTP_END[] PROGMEM =
|
||||
"</div>"
|
||||
"</body>"
|
||||
|
@ -1168,7 +1175,7 @@ void handleAjax()
|
|||
{
|
||||
if (httpUser()) return;
|
||||
char svalue[MESSZ], log[LOGSZ];
|
||||
byte counter = 99;
|
||||
byte cflg = 1, counter = 99;
|
||||
|
||||
if (strlen(webServer->arg("c1").c_str())) {
|
||||
snprintf_P(svalue, sizeof(svalue), webServer->arg("c1").c_str());
|
||||
|
@ -1189,10 +1196,13 @@ void handleAjax()
|
|||
}
|
||||
message += F("</j><l>");
|
||||
if (counter != logidx) {
|
||||
if (counter == 99) counter = logidx;
|
||||
if (counter == 99) {
|
||||
counter = logidx;
|
||||
cflg = 0;
|
||||
}
|
||||
do {
|
||||
if (Log[counter].length()) {
|
||||
message += F("\n");
|
||||
if (cflg) message += F("\n"); else cflg = 1;
|
||||
message += Log[counter];
|
||||
}
|
||||
counter++;
|
||||
|
@ -1227,7 +1237,7 @@ void handleInfo()
|
|||
page += F("<tr><th>Uptime</th><td>"); page += String(uptime); page += F(" Hours</td></tr>");
|
||||
page += F("<tr><th>Flash write count</th><td>"); page += String(sysCfg.saveFlag); page += F("</td></tr>");
|
||||
page += F("<tr><th>Boot count</th><td>"); page += String(sysCfg.bootcount); page += F("</td></tr>");
|
||||
page += F("<tr><th>Reset reason</th><td>"); page += ESP.getResetReason(); page += F("</td></tr>");
|
||||
page += F("<tr><th>Reset reason</th><td>"); page += getResetReason(); page += F("</td></tr>");
|
||||
for (byte i = 0; i < Maxdevice; i++) {
|
||||
page += F("<tr><th>Friendly name ");
|
||||
page += i +1;
|
||||
|
|
|
@ -67,7 +67,7 @@ boolean bh1750_detect()
|
|||
if (!status) {
|
||||
success = true;
|
||||
bh1750type = 1;
|
||||
snprintf_P(bh1750stype, sizeof(bh1750stype), PSTR("BH1750"));
|
||||
strcpy(bh1750stype, "BH1750");
|
||||
}
|
||||
if (success) {
|
||||
snprintf_P(log, sizeof(log), PSTR("I2C: %s found at address 0x%x"), bh1750stype, bh1750addr);
|
||||
|
@ -95,12 +95,16 @@ void bh1750_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
|
|||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_SNS_ILLUMINANCE[] PROGMEM =
|
||||
"<tr><th>BH1750 Illuminance</th><td>%d lx</td></tr>";
|
||||
|
||||
String bh1750_webPresent()
|
||||
{
|
||||
String page = "";
|
||||
if (bh1750type) {
|
||||
uint16_t l = bh1750_readLux();
|
||||
page += F("<tr><td>Illuminance: </td><td>"); page += String(l); page += F(" lx</td></tr>");
|
||||
char sensor[80];
|
||||
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_ILLUMINANCE, bh1750_readLux());
|
||||
page += sensor;
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
|
|
@ -397,19 +397,19 @@ boolean bmp_detect()
|
|||
bmpaddr--;
|
||||
bmptype = i2c_read8(bmpaddr, BMP_REGISTER_CHIPID);
|
||||
}
|
||||
snprintf_P(bmpstype, sizeof(bmpstype), PSTR("BMP"));
|
||||
strcpy_P(bmpstype, PSTR("BMP"));
|
||||
switch (bmptype) {
|
||||
case BMP180_CHIPID:
|
||||
success = bmp180_calibration();
|
||||
snprintf_P(bmpstype, sizeof(bmpstype), PSTR("BMP180"));
|
||||
strcpy_P(bmpstype, PSTR("BMP180"));
|
||||
break;
|
||||
case BMP280_CHIPID:
|
||||
success = bmp280_calibrate();
|
||||
snprintf_P(bmpstype, sizeof(bmpstype), PSTR("BMP280"));
|
||||
strcpy_P(bmpstype, PSTR("BMP280"));
|
||||
break;
|
||||
case BME280_CHIPID:
|
||||
success = bme280_calibrate();
|
||||
snprintf_P(bmpstype, sizeof(bmpstype), PSTR("BME280"));
|
||||
strcpy_P(bmpstype, PSTR("BME280"));
|
||||
}
|
||||
if (success) {
|
||||
snprintf_P(log, sizeof(log), PSTR("I2C: %s found at address 0x%x"), bmpstype, bmpaddr);
|
||||
|
@ -454,20 +454,22 @@ String bmp_webPresent()
|
|||
{
|
||||
String page = "";
|
||||
if (bmptype) {
|
||||
char itemp[10], iconv[10];
|
||||
char stemp[10], sensor[80];
|
||||
|
||||
snprintf_P(iconv, sizeof(iconv), PSTR("°%c"), (TEMP_CONVERSION) ? 'F' : 'C');
|
||||
double t_bmp = bmp_readTemperature(TEMP_CONVERSION);
|
||||
double p_bmp = bmp_readPressure();
|
||||
double h_bmp = bmp_readHumidity();
|
||||
dtostrf(t_bmp, 1, TEMP_RESOLUTION &3, itemp);
|
||||
page += F("<tr><td>BMP Temperature: </td><td>"); page += itemp; page += iconv; page += F("</td></tr>");
|
||||
dtostrf(t_bmp, 1, TEMP_RESOLUTION &3, stemp);
|
||||
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, bmpstype, stemp, (TEMP_CONVERSION) ? 'F' : 'C');
|
||||
page += sensor;
|
||||
if (!strcmp(bmpstype,"BME280")) {
|
||||
dtostrf(h_bmp, 1, HUMIDITY_RESOLUTION &3, itemp);
|
||||
page += F("<tr><td>BMP Humidity: </td><td>"); page += itemp; page += F("%</td></tr>");
|
||||
dtostrf(h_bmp, 1, HUMIDITY_RESOLUTION &3, stemp);
|
||||
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, bmpstype, stemp);
|
||||
page += sensor;
|
||||
}
|
||||
dtostrf(p_bmp, 1, PRESSURE_RESOLUTION &3, itemp);
|
||||
page += F("<tr><td>BMP Pressure: </td><td>"); page += itemp; page += F(" hPa</td></tr>");
|
||||
dtostrf(p_bmp, 1, PRESSURE_RESOLUTION &3, stemp);
|
||||
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_PRESSURE, bmpstype, stemp);
|
||||
page += sensor;
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define MIN_INTERVAL 2000
|
||||
|
||||
uint8_t data[5];
|
||||
char dhtstype[7];
|
||||
uint32_t _lastreadtime, _maxcycles;
|
||||
bool _lastresult;
|
||||
float mt, mh = 0;
|
||||
|
@ -170,6 +171,17 @@ void dht_init()
|
|||
pinMode(pin[GPIO_DHT11], INPUT_PULLUP);
|
||||
_lastreadtime = -MIN_INTERVAL;
|
||||
|
||||
switch (dht_type) {
|
||||
case GPIO_DHT11:
|
||||
strcpy(dhtstype, "DHT11");
|
||||
break;
|
||||
case GPIO_DHT21:
|
||||
strcpy(dhtstype, "AM2301");
|
||||
break;
|
||||
case GPIO_DHT22:
|
||||
strcpy(dhtstype, "DHT22");
|
||||
}
|
||||
|
||||
snprintf_P(log, sizeof(log), PSTR("DHT: Max clock cycles %d"), _maxcycles);
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
}
|
||||
|
@ -186,7 +198,8 @@ void dht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
|
|||
if (dht_readTempHum(TEMP_CONVERSION, t, h)) { // Read temperature
|
||||
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1);
|
||||
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp2);
|
||||
snprintf_P(svalue, ssvalue, PSTR("%s, \"DHT\":{\"Temperature\":%s, \"Humidity\":%s}"), svalue, stemp1, stemp2);
|
||||
snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":%s, \"Humidity\":%s}"),
|
||||
svalue, dhtstype, stemp1, stemp2);
|
||||
*djson = 1;
|
||||
#ifdef USE_DOMOTICZ
|
||||
domoticz_sensor2(stemp1, stemp2);
|
||||
|
@ -197,16 +210,18 @@ void dht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
|
|||
#ifdef USE_WEBSERVER
|
||||
String dht_webPresent()
|
||||
{
|
||||
char stemp[10], sconv[10];
|
||||
float t, h;
|
||||
String page = "";
|
||||
float t, h;
|
||||
|
||||
if (dht_readTempHum(TEMP_CONVERSION, t, h)) { // Read temperature as Celsius (the default)
|
||||
snprintf_P(sconv, sizeof(sconv), PSTR("°%c"), (TEMP_CONVERSION) ? 'F' : 'C');
|
||||
char stemp[10], sensor[128];
|
||||
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp);
|
||||
page += F("<tr><td>DHT Temperature: </td><td>"); page += stemp; page += sconv; page += F("</td></tr>");
|
||||
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, dhtstype, stemp, (TEMP_CONVERSION) ? 'F' : 'C');
|
||||
page += sensor;
|
||||
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp);
|
||||
page += F("<tr><td>DHT Humidity: </td><td>"); page += stemp; page += F("%</td></tr>");
|
||||
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, dhtstype, stemp);
|
||||
page += sensor;
|
||||
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
|
|
@ -191,14 +191,14 @@ void dsb_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
|
|||
String dsb_webPresent()
|
||||
{
|
||||
// Needs TelePeriod to refresh data (Do not do it here as it takes too much time)
|
||||
char stemp[10], sconv[10];
|
||||
float st;
|
||||
String page = "";
|
||||
float st;
|
||||
|
||||
if (dsb_readTemp(TEMP_CONVERSION, st)) { // Check if read failed
|
||||
snprintf_P(sconv, sizeof(sconv), PSTR("°%c"), (TEMP_CONVERSION) ? 'F' : 'C');
|
||||
char stemp[10], sensor[80];
|
||||
dtostrf(st, 1, TEMP_RESOLUTION &3, stemp);
|
||||
page += F("<tr><td>DSB Temperature: </td><td>"); page += stemp; page += sconv; page += F("</td></tr>");
|
||||
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, "DS18B20", stemp, (TEMP_CONVERSION) ? 'F' : 'C');
|
||||
page += sensor;
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ OneWire *ds = NULL;
|
|||
uint8_t ds18x20_addr[DS18X20_MAX_SENSORS][8];
|
||||
uint8_t ds18x20_idx[DS18X20_MAX_SENSORS];
|
||||
uint8_t ds18x20_snsrs = 0;
|
||||
char dsbstype[8];
|
||||
|
||||
void ds18x20_init()
|
||||
{
|
||||
|
@ -90,23 +91,6 @@ String ds18x20_address(uint8_t sensor)
|
|||
return String(addrStr);
|
||||
}
|
||||
|
||||
String ds18x20_type(uint8_t sensor)
|
||||
{
|
||||
char typeStr[10];
|
||||
|
||||
switch(ds18x20_addr[ds18x20_idx[sensor]][0]) {
|
||||
case 0x10:
|
||||
strcpy(typeStr, "DS18S20");
|
||||
break;
|
||||
case 0x28:
|
||||
strcpy(typeStr, "DS18B20");
|
||||
break;
|
||||
default:
|
||||
strcpy(typeStr, "DS18x20");
|
||||
}
|
||||
return String(typeStr);
|
||||
}
|
||||
|
||||
void ds18x20_convert()
|
||||
{
|
||||
ds->reset();
|
||||
|
@ -160,6 +144,19 @@ boolean ds18x20_read(uint8_t sensor, bool S, float &t)
|
|||
* Presentation
|
||||
\*********************************************************************************************/
|
||||
|
||||
void ds18x20_type(uint8_t sensor)
|
||||
{
|
||||
strcpy_P(dsbstype, PSTR("DS18x20"));
|
||||
switch(ds18x20_addr[ds18x20_idx[sensor]][0]) {
|
||||
case 0x10:
|
||||
strcpy_P(dsbstype, PSTR("DS18S20"));
|
||||
break;
|
||||
case 0x28:
|
||||
strcpy_P(dsbstype, PSTR("DS18B20"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ds18x20_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
|
||||
{
|
||||
char stemp1[10], stemp2[10];
|
||||
|
@ -168,6 +165,7 @@ void ds18x20_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
|
|||
byte dsxflg = 0;
|
||||
for (byte i = 0; i < ds18x20_sensors(); i++) {
|
||||
if (ds18x20_read(i, TEMP_CONVERSION, t)) { // Check if read failed
|
||||
ds18x20_type(i);
|
||||
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp2);
|
||||
if (!dsxflg) {
|
||||
snprintf_P(svalue, ssvalue, PSTR("%s, \"DS18x20\":{"), svalue);
|
||||
|
@ -176,7 +174,7 @@ void ds18x20_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
|
|||
}
|
||||
dsxflg++;
|
||||
snprintf_P(svalue, ssvalue, PSTR("%s%s\"DS%d\":{\"Type\":\"%s\", \"Address\":\"%s\", \"Temperature\":%s}"),
|
||||
svalue, stemp1, i +1, ds18x20_type(i).c_str(), ds18x20_address(i).c_str(), stemp2);
|
||||
svalue, stemp1, i +1, dsbstype, ds18x20_address(i).c_str(), stemp2);
|
||||
strcpy(stemp1, ", ");
|
||||
#ifdef USE_DOMOTICZ
|
||||
if (dsxflg == 1) domoticz_sensor1(stemp2);
|
||||
|
@ -189,15 +187,17 @@ void ds18x20_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
|
|||
#ifdef USE_WEBSERVER
|
||||
String ds18x20_webPresent()
|
||||
{
|
||||
char stemp[10], sconv[10];
|
||||
float t;
|
||||
String page = "";
|
||||
char stemp[10], stemp2[16], sensor[80];
|
||||
float t;
|
||||
|
||||
snprintf_P(sconv, sizeof(sconv), PSTR("°%c"), (TEMP_CONVERSION) ? 'F' : 'C');
|
||||
for (byte i = 0; i < ds18x20_sensors(); i++) {
|
||||
if (ds18x20_read(i, TEMP_CONVERSION, t)) { // Check if read failed
|
||||
ds18x20_type(i);
|
||||
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp);
|
||||
page += F("<tr><td>DS"); page += String(i +1); page += F(" Temperature: </td><td>"); page += stemp; page += sconv; page += F("</td></tr>");
|
||||
snprintf_P(stemp2, sizeof(stemp2), PSTR("%s-%d"), dsbstype, i +1);
|
||||
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, stemp2, stemp, (TEMP_CONVERSION) ? 'F' : 'C');
|
||||
page += sensor;
|
||||
}
|
||||
}
|
||||
return page;
|
||||
|
|
|
@ -102,11 +102,13 @@ void hlw_200mS()
|
|||
hlw_EDcntr = 0;
|
||||
hlw_temp = (HLW_PREF * sysCfg.hlw_pcal) / hlw_len;
|
||||
hlw_kWhtoday += (hlw_temp * 100) / 36;
|
||||
rtcMem.hlw_kWhtoday = hlw_kWhtoday;
|
||||
}
|
||||
if (rtcTime.Valid) {
|
||||
if (rtc_loctime() == rtc_midnight()) {
|
||||
sysCfg.hlw_kWhyesterday = hlw_kWhtoday;
|
||||
hlw_kWhtoday = 0;
|
||||
rtcMem.hlw_kWhtoday = hlw_kWhtoday;
|
||||
hlw_mkwh_state = 3;
|
||||
}
|
||||
if ((rtcTime.Hour == sysCfg.hlw_mkwhs) && (hlw_mkwh_state == 3)) {
|
||||
|
@ -114,6 +116,7 @@ void hlw_200mS()
|
|||
}
|
||||
if (hlw_startup && (rtcTime.DayOfYear == sysCfg.hlw_kWhdoy)) {
|
||||
hlw_kWhtoday = sysCfg.hlw_kWhtoday;
|
||||
rtcMem.hlw_kWhtoday = hlw_kWhtoday;
|
||||
hlw_startup = 0;
|
||||
}
|
||||
}
|
||||
|
@ -236,7 +239,7 @@ void hlw_init()
|
|||
|
||||
hlw_Ecntr = 0;
|
||||
hlw_EDcntr = 0;
|
||||
hlw_kWhtoday = 0;
|
||||
hlw_kWhtoday = (RTC_Valid()) ? rtcMem.hlw_kWhtoday : 0;
|
||||
|
||||
hlw_SELflag = 0; // Voltage;
|
||||
|
||||
|
@ -540,18 +543,16 @@ void hlw_mqttStat(byte option, char* svalue, uint16_t ssvalue)
|
|||
|
||||
void hlw_mqttPresent()
|
||||
{
|
||||
char svalue[MESSZ], stime[21];
|
||||
char svalue[MESSZ];
|
||||
|
||||
snprintf_P(stime, sizeof(stime), PSTR("%04d-%02d-%02dT%02d:%02d:%02d"),
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Time\":\"%04d-%02d-%02dT%02d:%02d:%02d\", "),
|
||||
rtcTime.Year, rtcTime.Month, rtcTime.Day, rtcTime.Hour, rtcTime.Minute, rtcTime.Second);
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Time\":\"%s\", "), stime);
|
||||
hlw_mqttStat(1, svalue, sizeof(svalue));
|
||||
|
||||
// snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/ENERGY"), PUB_PREFIX2, sysCfg.mqtt_topic);
|
||||
// mqtt_publish(stopic, svalue);
|
||||
|
||||
mqtt_publish_topic_P(1, PSTR("ENERGY"), svalue);
|
||||
|
||||
}
|
||||
|
||||
void hlw_mqttStatus(char* svalue, uint16_t ssvalue)
|
||||
|
@ -562,24 +563,29 @@ 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>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>"
|
||||
"<tr><th>Energy Today</th><td>%s kWh</td></tr>"
|
||||
"<tr><th>Energy Yesterday</th><td>%s kWh</td></tr>";
|
||||
|
||||
String hlw_webPresent()
|
||||
{
|
||||
char stemp[10];
|
||||
String page = "";
|
||||
char stemp[10], stemp2[10], stemp3[10], stemp4[10], sensor[300];
|
||||
float ped, pi, pc;
|
||||
uint16_t pe, pw, pu;
|
||||
String page = "";
|
||||
|
||||
hlw_readEnergy(0, ped, pe, pw, pu, pi, pc);
|
||||
page += F("<tr><td>Voltage: </td><td>"); page += String(pu); page += F(" V</td></tr>");
|
||||
|
||||
dtostrf(pi, 1, 3, stemp);
|
||||
page += F("<tr><td>Current: </td><td>"); page += stemp; page += F(" A</td></tr>");
|
||||
page += F("<tr><td>Power: </td><td>"); page += String(pw); page += F(" W</td></tr>");
|
||||
dtostrf(pc, 1, 2, stemp);
|
||||
page += F("<tr><td>Power Factor: </td><td>"); page += stemp; page += F("</td></tr>");
|
||||
dtostrf(ped, 1, 3, stemp);
|
||||
page += F("<tr><td>Energy Today: </td><td>"); page += stemp; page += F(" kWh</td></tr>");
|
||||
dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, 3, stemp);
|
||||
page += F("<tr><td>Energy Yesterday: </td><td>"); page += stemp; page += F(" kWh</td></tr>");
|
||||
dtostrf(pc, 1, 2, stemp2);
|
||||
dtostrf(ped, 1, 3, stemp3);
|
||||
dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, 3, stemp4);
|
||||
snprintf_P(sensor, sizeof(sensor), HTTP_ENERGY_SNS, pu, stemp, pw, stemp2, stemp3, stemp4);
|
||||
page += sensor;
|
||||
return page;
|
||||
}
|
||||
#endif // USE_WEBSERVER
|
||||
|
|
|
@ -33,6 +33,9 @@
|
|||
|
||||
#define HTU21_ADDR 0x40
|
||||
|
||||
#define SI7013_CHIPID 0x0D
|
||||
#define SI7020_CHIPID 0x14
|
||||
#define SI7021_CHIPID 0x15
|
||||
#define HTU21_CHIPID 0x32
|
||||
|
||||
#define HTU21_READTEMP 0xE3
|
||||
|
@ -48,17 +51,15 @@
|
|||
#define HTU21_HEATER_ON 0x04
|
||||
#define HTU21_HEATER_OFF 0xFB
|
||||
|
||||
#define HTU21_RES_RH12_T14 0x00 // Default
|
||||
#define HTU21_RES_RH12_T14 0x00 // Default
|
||||
#define HTU21_RES_RH8_T12 0x01
|
||||
#define HTU21_RES_RH10_T13 0x80
|
||||
#define HTU21_RES_RH11_T11 0x81
|
||||
|
||||
#define HTU21_MAX_HUM 16 // 16ms max time
|
||||
#define HTU21_MAX_TEMP 50 // 50ms max time
|
||||
|
||||
#define HTU21_CRC8_POLYNOM 0x13100
|
||||
|
||||
uint8_t htuaddr, htutype = 0;
|
||||
uint8_t delayT, delayH = 50;
|
||||
char htustype[7];
|
||||
|
||||
uint8_t check_crc8(uint16_t data)
|
||||
|
@ -149,7 +150,7 @@ float htu21_readHumidity(void)
|
|||
Wire.beginTransmission(HTU21_ADDR);
|
||||
Wire.write(HTU21_READHUM);
|
||||
if(Wire.endTransmission() != 0) return 0.0; // In case of error
|
||||
delay(HTU21_MAX_HUM); // HTU21 time at max resolution
|
||||
delay(delayH); // Sensor time at max resolution
|
||||
|
||||
Wire.requestFrom(HTU21_ADDR, 3);
|
||||
if(3 <= Wire.available())
|
||||
|
@ -163,8 +164,8 @@ float htu21_readHumidity(void)
|
|||
sensorval ^= 0x02; // clear status bits
|
||||
humidity = 0.001907 * (float)sensorval - 6;
|
||||
|
||||
if(humidity>100) return 100.0;
|
||||
if(humidity<0) return 0.01;
|
||||
if(humidity > 100) return 100.0;
|
||||
if(humidity < 0) return 0.01;
|
||||
|
||||
return humidity;
|
||||
}
|
||||
|
@ -178,7 +179,7 @@ float htu21_readTemperature(bool S)
|
|||
Wire.beginTransmission(HTU21_ADDR);
|
||||
Wire.write(HTU21_READTEMP);
|
||||
if(Wire.endTransmission() != 0) return 0.0; // In case of error
|
||||
delay(HTU21_MAX_TEMP); // HTU21 time at max resolution
|
||||
delay(delayT); // Sensor time at max resolution
|
||||
|
||||
Wire.requestFrom(HTU21_ADDR, 3);
|
||||
if(3 == Wire.available())
|
||||
|
@ -210,11 +211,32 @@ uint8_t htu_detect()
|
|||
|
||||
htuaddr = HTU21_ADDR;
|
||||
htutype = htu21_readDeviceID();
|
||||
snprintf_P(htustype, sizeof(htustype), PSTR("HTU"));
|
||||
success = htu21_init();
|
||||
switch (htutype) {
|
||||
case HTU21_CHIPID:
|
||||
success = htu21_init();
|
||||
snprintf_P(htustype, sizeof(htustype), PSTR("HTU21"));
|
||||
strcpy_P(htustype, PSTR("HTU21"));
|
||||
delayT=50;
|
||||
delayH=16;
|
||||
break;
|
||||
case SI7013_CHIPID:
|
||||
strcpy_P(htustype, PSTR("SI7013"));
|
||||
delayT=12;
|
||||
delayH=23;
|
||||
break;
|
||||
case SI7020_CHIPID:
|
||||
strcpy_P(htustype, PSTR("SI7020"));
|
||||
delayT=12;
|
||||
delayH=23;
|
||||
break;
|
||||
case SI7021_CHIPID:
|
||||
strcpy_P(htustype, PSTR("SI7021"));
|
||||
delayT=12;
|
||||
delayH=23;
|
||||
break;
|
||||
default:
|
||||
strcpy_P(htustype, PSTR("T/RH?"));
|
||||
delayT=50;
|
||||
delayH=23;
|
||||
}
|
||||
if (success) {
|
||||
snprintf_P(log, sizeof(log), PSTR("I2C: %s found at address 0x%x"), htustype, htuaddr);
|
||||
|
@ -240,7 +262,8 @@ void htu_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
|
|||
h = htu21_compensatedHumidity(h, t);
|
||||
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1);
|
||||
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp2);
|
||||
snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":%s, \"Humidity\":%s}"), svalue, htustype, stemp1, stemp2);
|
||||
snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":%s, \"Humidity\":%s}"),
|
||||
svalue, htustype, stemp1, stemp2);
|
||||
*djson = 1;
|
||||
#ifdef USE_DOMOTICZ
|
||||
domoticz_sensor2(stemp1, stemp2);
|
||||
|
@ -252,16 +275,17 @@ String htu_webPresent()
|
|||
{
|
||||
String page = "";
|
||||
if (htutype) {
|
||||
char itemp[10], iconv[10];
|
||||
char stemp[10], sensor[128];
|
||||
|
||||
snprintf_P(iconv, sizeof(iconv), PSTR("°%c"), (TEMP_CONVERSION) ? 'F' : 'C');
|
||||
float t_htu21 = htu21_readTemperature(TEMP_CONVERSION);
|
||||
float h_htu21 = htu21_readHumidity();
|
||||
h_htu21 = htu21_compensatedHumidity(h_htu21, t_htu21);
|
||||
dtostrf(t_htu21, 1, TEMP_RESOLUTION &3, itemp);
|
||||
page += F("<tr><td>HTU Temperature: </td><td>"); page += itemp; page += iconv; page += F("</td></tr>");
|
||||
dtostrf(h_htu21, 1, HUMIDITY_RESOLUTION &3, itemp);
|
||||
page += F("<tr><td>HTU Humidity: </td><td>"); page += itemp; page += F("%</td></tr>");
|
||||
dtostrf(t_htu21, 1, TEMP_RESOLUTION &3, stemp);
|
||||
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, htustype, stemp, (TEMP_CONVERSION) ? 'F' : 'C');
|
||||
page += sensor;
|
||||
dtostrf(h_htu21, 1, HUMIDITY_RESOLUTION &3, stemp);
|
||||
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, htustype, stemp);
|
||||
page += sensor;
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue